@attocash/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +28 -0
- package/README.md +707 -0
- package/dist/application/app.d.ts +138 -0
- package/dist/application/app.js +654 -0
- package/dist/application/operations.d.ts +9 -0
- package/dist/application/operations.js +96 -0
- package/dist/cli/cli.d.ts +1 -0
- package/dist/cli/cli.js +460 -0
- package/dist/cli/help.d.ts +4 -0
- package/dist/cli/help.js +49 -0
- package/dist/cli/main.d.ts +2 -0
- package/dist/cli/main.js +13 -0
- package/dist/cli/onboarding.d.ts +14 -0
- package/dist/cli/onboarding.js +144 -0
- package/dist/cli/output.d.ts +2 -0
- package/dist/cli/output.js +231 -0
- package/dist/cli/terminal.d.ts +6 -0
- package/dist/cli/terminal.js +92 -0
- package/dist/cli/update-check.d.ts +1 -0
- package/dist/cli/update-check.js +12 -0
- package/dist/cli/updates.d.ts +2 -0
- package/dist/cli/updates.js +98 -0
- package/dist/core.d.ts +14 -0
- package/dist/core.js +14 -0
- package/dist/doctor/credential-probe.d.ts +7 -0
- package/dist/doctor/credential-probe.js +49 -0
- package/dist/doctor/doctor.d.ts +4 -0
- package/dist/doctor/doctor.js +213 -0
- package/dist/doctor/keyring.d.ts +7 -0
- package/dist/doctor/keyring.js +150 -0
- package/dist/doctor/profile.d.ts +19 -0
- package/dist/doctor/profile.js +73 -0
- package/dist/doctor/types.d.ts +40 -0
- package/dist/doctor/types.js +1 -0
- package/dist/domain/amount.d.ts +6 -0
- package/dist/domain/amount.js +27 -0
- package/dist/domain/errors.d.ts +10 -0
- package/dist/domain/errors.js +16 -0
- package/dist/labels/directory.d.ts +87 -0
- package/dist/labels/directory.js +140 -0
- package/dist/labels/personal.d.ts +17 -0
- package/dist/labels/personal.js +56 -0
- package/dist/labels/presentation.d.ts +154 -0
- package/dist/labels/presentation.js +90 -0
- package/dist/network/reader.d.ts +31 -0
- package/dist/network/reader.js +370 -0
- package/dist/network/retry.d.ts +7 -0
- package/dist/network/retry.js +53 -0
- package/dist/network/work.d.ts +3 -0
- package/dist/network/work.js +66 -0
- package/dist/pricing/market.d.ts +29 -0
- package/dist/pricing/market.js +150 -0
- package/dist/pricing/terms.d.ts +6 -0
- package/dist/pricing/terms.js +12 -0
- package/dist/spending/destination.d.ts +16 -0
- package/dist/spending/destination.js +42 -0
- package/dist/spending/journal.d.ts +28 -0
- package/dist/spending/journal.js +69 -0
- package/dist/spending/ledger.d.ts +118 -0
- package/dist/spending/ledger.js +444 -0
- package/dist/spending/payments.d.ts +67 -0
- package/dist/spending/payments.js +424 -0
- package/dist/spending/pool.d.ts +13 -0
- package/dist/spending/pool.js +38 -0
- package/dist/spending/reconcile.d.ts +18 -0
- package/dist/spending/reconcile.js +64 -0
- package/dist/storage/profiles.d.ts +13 -0
- package/dist/storage/profiles.js +86 -0
- package/dist/storage/secrets.d.ts +16 -0
- package/dist/storage/secrets.js +104 -0
- package/dist/storage/state.d.ts +32 -0
- package/dist/storage/state.js +255 -0
- package/dist/wallet/auto-receive.d.ts +57 -0
- package/dist/wallet/auto-receive.js +140 -0
- package/dist/wallet/defaults.d.ts +3 -0
- package/dist/wallet/defaults.js +26 -0
- package/dist/wallet/signing.d.ts +17 -0
- package/dist/wallet/signing.js +128 -0
- package/dist/wallet/types.d.ts +65 -0
- package/dist/wallet/types.js +1 -0
- package/dist/wallet/work.d.ts +29 -0
- package/dist/wallet/work.js +154 -0
- package/dist/watches/manager.d.ts +75 -0
- package/dist/watches/manager.js +197 -0
- package/node_modules/@attocash/commons-core/Kotlin-DateTime-library-kotlinx-datetime.mjs +6678 -0
- package/node_modules/@attocash/commons-core/Kotlin-DateTime-library-kotlinx-datetime.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/LICENSE +28 -0
- package/node_modules/@attocash/commons-core/README.md +118 -0
- package/node_modules/@attocash/commons-core/commons-commons-core.d.mts +1036 -0
- package/node_modules/@attocash/commons-core/commons-commons-core.mjs +7701 -0
- package/node_modules/@attocash/commons-core/commons-commons-core.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/kotlin-kotlin-stdlib.mjs +17681 -0
- package/node_modules/@attocash/commons-core/kotlin-kotlin-stdlib.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/kotlin_org_jetbrains_kotlin_kotlin_dom_api_compat.mjs +4 -0
- package/node_modules/@attocash/commons-core/kotlin_org_jetbrains_kotlin_kotlin_dom_api_compat.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-bytestring.mjs +209 -0
- package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-bytestring.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-core.mjs +2284 -0
- package/node_modules/@attocash/commons-core/kotlinx-io-kotlinx-io-core.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-core.mjs +6042 -0
- package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-core.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
- package/node_modules/@attocash/commons-core/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
- package/node_modules/@attocash/commons-core/package.json +27 -0
- package/node_modules/@attocash/commons-node/LICENSE +28 -0
- package/node_modules/@attocash/commons-node/README.md +92 -0
- package/node_modules/@attocash/commons-node/commons-commons-node.d.mts +255 -0
- package/node_modules/@attocash/commons-node/commons-commons-node.mjs +2977 -0
- package/node_modules/@attocash/commons-node/commons-commons-node.mjs.map +1 -0
- package/node_modules/@attocash/commons-node/kotlin-logging.mjs +432 -0
- package/node_modules/@attocash/commons-node/kotlin-logging.mjs.map +1 -0
- package/node_modules/@attocash/commons-node/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
- package/node_modules/@attocash/commons-node/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
- package/node_modules/@attocash/commons-node/package.json +29 -0
- package/node_modules/@attocash/commons-node-remote/LICENSE +28 -0
- package/node_modules/@attocash/commons-node-remote/README.md +61 -0
- package/node_modules/@attocash/commons-node-remote/commons-commons-node-remote.d.mts +122 -0
- package/node_modules/@attocash/commons-node-remote/commons-commons-node-remote.mjs +1810 -0
- package/node_modules/@attocash/commons-node-remote/commons-commons-node-remote.mjs.map +1 -0
- package/node_modules/@attocash/commons-node-remote/kotlin-logging.mjs +432 -0
- package/node_modules/@attocash/commons-node-remote/kotlin-logging.mjs.map +1 -0
- package/node_modules/@attocash/commons-node-remote/kotlinx-browser.mjs +8 -0
- package/node_modules/@attocash/commons-node-remote/kotlinx-browser.mjs.map +1 -0
- package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs +4 -0
- package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs.map +1 -0
- package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
- package/node_modules/@attocash/commons-node-remote/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
- package/node_modules/@attocash/commons-node-remote/package.json +31 -0
- package/node_modules/@attocash/commons-transport/LICENSE +28 -0
- package/node_modules/@attocash/commons-transport/README.md +5 -0
- package/node_modules/@attocash/commons-transport/commons-commons-transport.d.mts +64 -0
- package/node_modules/@attocash/commons-transport/commons-commons-transport.mjs +249 -0
- package/node_modules/@attocash/commons-transport/commons-commons-transport.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/kotlinx-atomicfu.mjs +263 -0
- package/node_modules/@attocash/commons-transport/kotlinx-atomicfu.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/kotlinx-browser.mjs +8 -0
- package/node_modules/@attocash/commons-transport/kotlinx-browser.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/kotlinx-coroutines-core.mjs +11604 -0
- package/node_modules/@attocash/commons-transport/kotlinx-coroutines-core.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json-io.mjs +4 -0
- package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json-io.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
- package/node_modules/@attocash/commons-transport/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-client-content-negotiation.mjs +499 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-client-content-negotiation.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-client-core.mjs +6456 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-client-core.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-events.mjs +83 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-events.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-http-cio.mjs +1714 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-http-cio.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-http.mjs +3197 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-http.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-io.mjs +2290 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-io.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx-json.mjs +46 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx-json.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx.mjs +482 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-serialization-kotlinx.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-serialization.mjs +165 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-serialization.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-sse.mjs +4 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-sse.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-utils.mjs +3222 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-utils.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-websocket-serialization.mjs +4 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-websocket-serialization.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-websockets.mjs +1485 -0
- package/node_modules/@attocash/commons-transport/ktor-ktor-websockets.mjs.map +1 -0
- package/node_modules/@attocash/commons-transport/package.json +29 -0
- package/node_modules/@attocash/commons-worker/LICENSE +28 -0
- package/node_modules/@attocash/commons-worker/README.md +48 -0
- package/node_modules/@attocash/commons-worker/commons-commons-worker.d.mts +73 -0
- package/node_modules/@attocash/commons-worker/commons-commons-worker.mjs +702 -0
- package/node_modules/@attocash/commons-worker/commons-commons-worker.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker/kotlin-logging.mjs +432 -0
- package/node_modules/@attocash/commons-worker/kotlin-logging.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
- package/node_modules/@attocash/commons-worker/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker/package.json +29 -0
- package/node_modules/@attocash/commons-worker-remote/LICENSE +28 -0
- package/node_modules/@attocash/commons-worker-remote/README.md +60 -0
- package/node_modules/@attocash/commons-worker-remote/commons-commons-worker-remote.d.mts +93 -0
- package/node_modules/@attocash/commons-worker-remote/commons-commons-worker-remote.mjs +289 -0
- package/node_modules/@attocash/commons-worker-remote/commons-commons-worker-remote.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker-remote/kotlin-logging.mjs +432 -0
- package/node_modules/@attocash/commons-worker-remote/kotlin-logging.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker-remote/kotlinx-browser.mjs +8 -0
- package/node_modules/@attocash/commons-worker-remote/kotlinx-browser.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs +4 -0
- package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json-io.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json.mjs +5294 -0
- package/node_modules/@attocash/commons-worker-remote/kotlinx-serialization-kotlinx-serialization-json.mjs.map +1 -0
- package/node_modules/@attocash/commons-worker-remote/package.json +31 -0
- package/node_modules/@js-joda/core/CHANGELOG.md +363 -0
- package/node_modules/@js-joda/core/CheatSheet.md +947 -0
- package/node_modules/@js-joda/core/LICENSE +34 -0
- package/node_modules/@js-joda/core/README.md +155 -0
- package/node_modules/@js-joda/core/bower.json +21 -0
- package/node_modules/@js-joda/core/dist/js-joda.d.ts +2452 -0
- package/node_modules/@js-joda/core/dist/js-joda.esm.js +13564 -0
- package/node_modules/@js-joda/core/dist/js-joda.flow.js +949 -0
- package/node_modules/@js-joda/core/dist/js-joda.js +13630 -0
- package/node_modules/@js-joda/core/dist/js-joda.js.map +1 -0
- package/node_modules/@js-joda/core/dist/js-joda.min.js +5 -0
- package/node_modules/@js-joda/core/package.json +76 -0
- package/node_modules/@js-joda/core/src/Clock.js +330 -0
- package/node_modules/@js-joda/core/src/DayOfWeek.js +451 -0
- package/node_modules/@js-joda/core/src/Duration.js +1205 -0
- package/node_modules/@js-joda/core/src/Enum.js +30 -0
- package/node_modules/@js-joda/core/src/Instant.js +1012 -0
- package/node_modules/@js-joda/core/src/LocalDate.js +1703 -0
- package/node_modules/@js-joda/core/src/LocalDateTime.js +1686 -0
- package/node_modules/@js-joda/core/src/LocalTime.js +1415 -0
- package/node_modules/@js-joda/core/src/MathUtil.js +236 -0
- package/node_modules/@js-joda/core/src/Month.js +600 -0
- package/node_modules/@js-joda/core/src/MonthDay.js +730 -0
- package/node_modules/@js-joda/core/src/OffsetDateTime.js +757 -0
- package/node_modules/@js-joda/core/src/OffsetTime.js +621 -0
- package/node_modules/@js-joda/core/src/Period.js +933 -0
- package/node_modules/@js-joda/core/src/StringUtil.js +43 -0
- package/node_modules/@js-joda/core/src/Year.js +1015 -0
- package/node_modules/@js-joda/core/src/YearConstants.js +21 -0
- package/node_modules/@js-joda/core/src/YearMonth.js +1096 -0
- package/node_modules/@js-joda/core/src/ZoneId.js +236 -0
- package/node_modules/@js-joda/core/src/ZoneIdFactory.js +201 -0
- package/node_modules/@js-joda/core/src/ZoneOffset.js +486 -0
- package/node_modules/@js-joda/core/src/ZoneRegion.js +72 -0
- package/node_modules/@js-joda/core/src/ZonedDateTime.js +2007 -0
- package/node_modules/@js-joda/core/src/_init.js +68 -0
- package/node_modules/@js-joda/core/src/assert.js +33 -0
- package/node_modules/@js-joda/core/src/chrono/ChronoLocalDate.js +230 -0
- package/node_modules/@js-joda/core/src/chrono/ChronoLocalDateTime.js +130 -0
- package/node_modules/@js-joda/core/src/chrono/ChronoZonedDateTime.js +194 -0
- package/node_modules/@js-joda/core/src/chrono/IsoChronology.js +235 -0
- package/node_modules/@js-joda/core/src/convert.js +83 -0
- package/node_modules/@js-joda/core/src/errors.js +54 -0
- package/node_modules/@js-joda/core/src/format/DateTimeBuilder.js +535 -0
- package/node_modules/@js-joda/core/src/format/DateTimeFormatter.js +728 -0
- package/node_modules/@js-joda/core/src/format/DateTimeFormatterBuilder.js +1545 -0
- package/node_modules/@js-joda/core/src/format/DateTimeParseContext.js +297 -0
- package/node_modules/@js-joda/core/src/format/DateTimePrintContext.js +138 -0
- package/node_modules/@js-joda/core/src/format/DecimalStyle.js +113 -0
- package/node_modules/@js-joda/core/src/format/EnumMap.js +70 -0
- package/node_modules/@js-joda/core/src/format/ParsePosition.js +31 -0
- package/node_modules/@js-joda/core/src/format/ResolverStyle.js +93 -0
- package/node_modules/@js-joda/core/src/format/SignStyle.js +38 -0
- package/node_modules/@js-joda/core/src/format/StringBuilder.js +47 -0
- package/node_modules/@js-joda/core/src/format/TextStyle.js +114 -0
- package/node_modules/@js-joda/core/src/format/parser/CharLiteralPrinterParser.js +46 -0
- package/node_modules/@js-joda/core/src/format/parser/CompositePrinterParser.js +89 -0
- package/node_modules/@js-joda/core/src/format/parser/FractionPrinterParser.js +162 -0
- package/node_modules/@js-joda/core/src/format/parser/NumberPrinterParser.js +367 -0
- package/node_modules/@js-joda/core/src/format/parser/OffsetIdPrinterParser.js +177 -0
- package/node_modules/@js-joda/core/src/format/parser/PadPrinterParserDecorator.js +81 -0
- package/node_modules/@js-joda/core/src/format/parser/SettingsParser.js +44 -0
- package/node_modules/@js-joda/core/src/format/parser/StringLiteralPrinterParser.js +39 -0
- package/node_modules/@js-joda/core/src/format/parser/ZoneIdPrinterParser.js +218 -0
- package/node_modules/@js-joda/core/src/js-joda.js +210 -0
- package/node_modules/@js-joda/core/src/license-preamble.js +3 -0
- package/node_modules/@js-joda/core/src/temporal/ChronoField.js +470 -0
- package/node_modules/@js-joda/core/src/temporal/ChronoUnit.js +310 -0
- package/node_modules/@js-joda/core/src/temporal/DefaultInterfaceTemporal.js +118 -0
- package/node_modules/@js-joda/core/src/temporal/IsoFields.js +859 -0
- package/node_modules/@js-joda/core/src/temporal/NativeJsTemporal.js +105 -0
- package/node_modules/@js-joda/core/src/temporal/Temporal.js +346 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalAccessor.js +125 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalAdjuster.js +92 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalAdjusters.js +464 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalAmount.js +166 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalField.js +248 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalQueries.js +223 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalQueriesFactory.js +77 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalQuery.js +107 -0
- package/node_modules/@js-joda/core/src/temporal/TemporalUnit.js +179 -0
- package/node_modules/@js-joda/core/src/temporal/ValueRange.js +257 -0
- package/node_modules/@js-joda/core/src/use.js +20 -0
- package/node_modules/@js-joda/core/src/zone/SystemDefaultZoneId.js +31 -0
- package/node_modules/@js-joda/core/src/zone/SystemDefaultZoneRules.js +162 -0
- package/node_modules/@js-joda/core/src/zone/ZoneOffsetTransition.js +289 -0
- package/node_modules/@js-joda/core/src/zone/ZoneRules.js +464 -0
- package/node_modules/@js-joda/core/src/zone/ZoneRulesProvider.js +36 -0
- package/node_modules/@noble/hashes/LICENSE +21 -0
- package/node_modules/@noble/hashes/README.md +563 -0
- package/node_modules/@noble/hashes/_blake.d.ts +21 -0
- package/node_modules/@noble/hashes/_blake.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_blake.js +52 -0
- package/node_modules/@noble/hashes/_blake.js.map +1 -0
- package/node_modules/@noble/hashes/_md.d.ts +99 -0
- package/node_modules/@noble/hashes/_md.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_md.js +202 -0
- package/node_modules/@noble/hashes/_md.js.map +1 -0
- package/node_modules/@noble/hashes/_u64.d.ts +63 -0
- package/node_modules/@noble/hashes/_u64.d.ts.map +1 -0
- package/node_modules/@noble/hashes/_u64.js +84 -0
- package/node_modules/@noble/hashes/_u64.js.map +1 -0
- package/node_modules/@noble/hashes/argon2.d.ts +112 -0
- package/node_modules/@noble/hashes/argon2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/argon2.js +517 -0
- package/node_modules/@noble/hashes/argon2.js.map +1 -0
- package/node_modules/@noble/hashes/blake1.d.ts +156 -0
- package/node_modules/@noble/hashes/blake1.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake1.js +560 -0
- package/node_modules/@noble/hashes/blake1.js.map +1 -0
- package/node_modules/@noble/hashes/blake2.d.ts +184 -0
- package/node_modules/@noble/hashes/blake2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake2.js +501 -0
- package/node_modules/@noble/hashes/blake2.js.map +1 -0
- package/node_modules/@noble/hashes/blake3.d.ts +68 -0
- package/node_modules/@noble/hashes/blake3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/blake3.js +284 -0
- package/node_modules/@noble/hashes/blake3.js.map +1 -0
- package/node_modules/@noble/hashes/eskdf.d.ts +92 -0
- package/node_modules/@noble/hashes/eskdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/eskdf.js +218 -0
- package/node_modules/@noble/hashes/eskdf.js.map +1 -0
- package/node_modules/@noble/hashes/hkdf.d.ts +64 -0
- package/node_modules/@noble/hashes/hkdf.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hkdf.js +120 -0
- package/node_modules/@noble/hashes/hkdf.js.map +1 -0
- package/node_modules/@noble/hashes/hmac.d.ts +47 -0
- package/node_modules/@noble/hashes/hmac.d.ts.map +1 -0
- package/node_modules/@noble/hashes/hmac.js +93 -0
- package/node_modules/@noble/hashes/hmac.js.map +1 -0
- package/node_modules/@noble/hashes/index.d.ts +2 -0
- package/node_modules/@noble/hashes/index.d.ts.map +1 -0
- package/node_modules/@noble/hashes/index.js +35 -0
- package/node_modules/@noble/hashes/index.js.map +1 -0
- package/node_modules/@noble/hashes/legacy.d.ts +102 -0
- package/node_modules/@noble/hashes/legacy.d.ts.map +1 -0
- package/node_modules/@noble/hashes/legacy.js +327 -0
- package/node_modules/@noble/hashes/legacy.js.map +1 -0
- package/node_modules/@noble/hashes/package.json +97 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts +56 -0
- package/node_modules/@noble/hashes/pbkdf2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/pbkdf2.js +135 -0
- package/node_modules/@noble/hashes/pbkdf2.js.map +1 -0
- package/node_modules/@noble/hashes/scrypt.d.ts +65 -0
- package/node_modules/@noble/hashes/scrypt.d.ts.map +1 -0
- package/node_modules/@noble/hashes/scrypt.js +257 -0
- package/node_modules/@noble/hashes/scrypt.js.map +1 -0
- package/node_modules/@noble/hashes/sha2.d.ts +249 -0
- package/node_modules/@noble/hashes/sha2.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha2.js +458 -0
- package/node_modules/@noble/hashes/sha2.js.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts +461 -0
- package/node_modules/@noble/hashes/sha3-addons.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3-addons.js +783 -0
- package/node_modules/@noble/hashes/sha3-addons.js.map +1 -0
- package/node_modules/@noble/hashes/sha3.d.ts +199 -0
- package/node_modules/@noble/hashes/sha3.d.ts.map +1 -0
- package/node_modules/@noble/hashes/sha3.js +431 -0
- package/node_modules/@noble/hashes/sha3.js.map +1 -0
- package/node_modules/@noble/hashes/src/_blake.ts +57 -0
- package/node_modules/@noble/hashes/src/_md.ts +222 -0
- package/node_modules/@noble/hashes/src/_u64.ts +117 -0
- package/node_modules/@noble/hashes/src/argon2.ts +667 -0
- package/node_modules/@noble/hashes/src/blake1.ts +614 -0
- package/node_modules/@noble/hashes/src/blake2.ts +582 -0
- package/node_modules/@noble/hashes/src/blake3.ts +317 -0
- package/node_modules/@noble/hashes/src/eskdf.ts +259 -0
- package/node_modules/@noble/hashes/src/hkdf.ts +133 -0
- package/node_modules/@noble/hashes/src/hmac.ts +126 -0
- package/node_modules/@noble/hashes/src/index.ts +33 -0
- package/node_modules/@noble/hashes/src/legacy.ts +339 -0
- package/node_modules/@noble/hashes/src/pbkdf2.ts +175 -0
- package/node_modules/@noble/hashes/src/scrypt.ts +315 -0
- package/node_modules/@noble/hashes/src/sha2.ts +530 -0
- package/node_modules/@noble/hashes/src/sha3-addons.ts +983 -0
- package/node_modules/@noble/hashes/src/sha3.ts +485 -0
- package/node_modules/@noble/hashes/src/utils.ts +848 -0
- package/node_modules/@noble/hashes/src/webcrypto.ts +239 -0
- package/node_modules/@noble/hashes/utils.d.ts +519 -0
- package/node_modules/@noble/hashes/utils.d.ts.map +1 -0
- package/node_modules/@noble/hashes/utils.js +578 -0
- package/node_modules/@noble/hashes/utils.js.map +1 -0
- package/node_modules/@noble/hashes/webcrypto.d.ts +120 -0
- package/node_modules/@noble/hashes/webcrypto.d.ts.map +1 -0
- package/node_modules/@noble/hashes/webcrypto.js +165 -0
- package/node_modules/@noble/hashes/webcrypto.js.map +1 -0
- package/node_modules/ws/LICENSE +20 -0
- package/node_modules/ws/README.md +548 -0
- package/node_modules/ws/browser.js +8 -0
- package/node_modules/ws/index.js +22 -0
- package/node_modules/ws/lib/buffer-util.js +131 -0
- package/node_modules/ws/lib/constants.js +19 -0
- package/node_modules/ws/lib/event-target.js +292 -0
- package/node_modules/ws/lib/extension.js +203 -0
- package/node_modules/ws/lib/limiter.js +55 -0
- package/node_modules/ws/lib/permessage-deflate.js +530 -0
- package/node_modules/ws/lib/receiver.js +743 -0
- package/node_modules/ws/lib/sender.js +607 -0
- package/node_modules/ws/lib/stream.js +161 -0
- package/node_modules/ws/lib/subprotocol.js +62 -0
- package/node_modules/ws/lib/validation.js +152 -0
- package/node_modules/ws/lib/websocket-server.js +562 -0
- package/node_modules/ws/lib/websocket.js +1407 -0
- package/node_modules/ws/package.json +74 -0
- package/node_modules/ws/wrapper.mjs +21 -0
- package/package.json +53 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Blake3 fast hash is Blake2 with reduced security (round count). Can also be used as MAC & KDF.
|
|
3
|
+
*
|
|
4
|
+
* It is advertised as "the fastest cryptographic hash". However, it isn't true in JS.
|
|
5
|
+
* Why is this so slow? While it must be 6x faster than blake2b, perf diff is only 20%:
|
|
6
|
+
*
|
|
7
|
+
* * There is only 30% reduction in number of rounds from blake2s
|
|
8
|
+
* * Speed-up comes from tree structure, which is parallelized using SIMD & threading.
|
|
9
|
+
* These features are not present in JS, so we only get overhead from trees.
|
|
10
|
+
* * Parallelization only happens on 1024-byte chunks: there is no benefit for small inputs.
|
|
11
|
+
* * It is still possible to make it faster using: a) loop unrolling b) web workers c) wasm
|
|
12
|
+
* @module
|
|
13
|
+
*/
|
|
14
|
+
import { SHA256_IV } from './_md.ts';
|
|
15
|
+
import { fromBig } from './_u64.ts';
|
|
16
|
+
import { _BLAKE2, compress } from './blake2.ts';
|
|
17
|
+
// prettier-ignore
|
|
18
|
+
import {
|
|
19
|
+
abytes, aexists, anumber, aoutput,
|
|
20
|
+
clean,
|
|
21
|
+
copyBytes,
|
|
22
|
+
createHasher, swap32IfBE,
|
|
23
|
+
u32, u8,
|
|
24
|
+
type CHashXOF,
|
|
25
|
+
type HashXOF,
|
|
26
|
+
type TArg,
|
|
27
|
+
type TRet
|
|
28
|
+
} from './utils.ts';
|
|
29
|
+
|
|
30
|
+
// Constructor-time mode flags (`KEYED_HASH`, `DERIVE_*`) plus per-node tree
|
|
31
|
+
// flags (`CHUNK_*`, `PARENT`, `ROOT`).
|
|
32
|
+
const B3_Flags = {
|
|
33
|
+
CHUNK_START: 0b1,
|
|
34
|
+
CHUNK_END: 0b10,
|
|
35
|
+
PARENT: 0b100,
|
|
36
|
+
ROOT: 0b1000,
|
|
37
|
+
KEYED_HASH: 0b10000,
|
|
38
|
+
DERIVE_KEY_CONTEXT: 0b100000,
|
|
39
|
+
DERIVE_KEY_MATERIAL: 0b1000000,
|
|
40
|
+
} as const;
|
|
41
|
+
|
|
42
|
+
// Default BLAKE3 IV, cloned from the shared BLAKE2s / SHA-256 IV basis.
|
|
43
|
+
const B3_IV = /* @__PURE__ */ SHA256_IV.slice();
|
|
44
|
+
|
|
45
|
+
// Seven 16-word rounds of BLAKE3 message schedule, generated by repeatedly
|
|
46
|
+
// permuting the identity row.
|
|
47
|
+
const B3_SIGMA: TRet<Uint8Array> = /* @__PURE__ */ (() => {
|
|
48
|
+
const Id = Array.from({ length: 16 }, (_, i) => i);
|
|
49
|
+
const permute = (arr: number[]) =>
|
|
50
|
+
[2, 6, 3, 10, 7, 0, 4, 13, 1, 11, 12, 5, 9, 14, 15, 8].map((i) => arr[i]);
|
|
51
|
+
const res: number[] = [];
|
|
52
|
+
for (let i = 0, v = Id; i < 7; i++, v = permute(v)) res.push(...v);
|
|
53
|
+
return Uint8Array.from(res);
|
|
54
|
+
})();
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Ensure to use EITHER `key` OR `context`, not both.
|
|
58
|
+
*
|
|
59
|
+
* * `key`: 32-byte MAC key.
|
|
60
|
+
* * `context`: caller-encoded KDF context bytes. If your protocol defines a
|
|
61
|
+
* string context, encode it before passing it here.
|
|
62
|
+
* A good default format for the original context string is
|
|
63
|
+
* "[application] [commit timestamp] [purpose]".
|
|
64
|
+
*/
|
|
65
|
+
export type Blake3Opts = {
|
|
66
|
+
/** Desired digest length in bytes. The BLAKE3 spec allows 0..2^64-1 bytes of output. */
|
|
67
|
+
dkLen?: number;
|
|
68
|
+
/** Optional 32-byte MAC key. */
|
|
69
|
+
key?: Uint8Array;
|
|
70
|
+
/** Optional KDF context bytes. */
|
|
71
|
+
context?: Uint8Array;
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
/** Blake3 hash. Can be used as MAC and KDF with caller-encoded context bytes. */
|
|
75
|
+
export class _BLAKE3 extends _BLAKE2<_BLAKE3> implements HashXOF<_BLAKE3> {
|
|
76
|
+
readonly canXOF = true;
|
|
77
|
+
private chunkPos = 0; // Position of current block in chunk
|
|
78
|
+
// How many chunks we already have; exact while this stays within
|
|
79
|
+
// JS's safe-integer range.
|
|
80
|
+
private chunksDone = 0;
|
|
81
|
+
private flags = 0 | 0;
|
|
82
|
+
private IV: Uint32Array;
|
|
83
|
+
private state: Uint32Array;
|
|
84
|
+
private stack: Uint32Array[] = [];
|
|
85
|
+
// Output
|
|
86
|
+
private posOut = 0;
|
|
87
|
+
private bufferOut32 = new Uint32Array(16);
|
|
88
|
+
private bufferOut: Uint8Array;
|
|
89
|
+
// Index of output chunk; exact while this stays within JS's
|
|
90
|
+
// safe-integer range.
|
|
91
|
+
private chunkOut = 0;
|
|
92
|
+
private enableXOF = true;
|
|
93
|
+
|
|
94
|
+
constructor(opts: Blake3Opts = {}, flags = 0) {
|
|
95
|
+
super(64, opts.dkLen === undefined ? 32 : opts.dkLen);
|
|
96
|
+
const { key, context } = opts;
|
|
97
|
+
const hasContext = context !== undefined;
|
|
98
|
+
if (key !== undefined) {
|
|
99
|
+
if (hasContext) throw new Error('Only "key" or "context" can be specified at same time');
|
|
100
|
+
abytes(key, 32, 'key');
|
|
101
|
+
const k = copyBytes(key);
|
|
102
|
+
this.IV = u32(k);
|
|
103
|
+
swap32IfBE(this.IV);
|
|
104
|
+
this.flags = flags | B3_Flags.KEYED_HASH;
|
|
105
|
+
} else if (hasContext) {
|
|
106
|
+
abytes(context, undefined, 'context');
|
|
107
|
+
const ctx = context;
|
|
108
|
+
const contextKey = new _BLAKE3({ dkLen: 32 }, B3_Flags.DERIVE_KEY_CONTEXT)
|
|
109
|
+
.update(ctx)
|
|
110
|
+
.digest();
|
|
111
|
+
this.IV = u32(contextKey);
|
|
112
|
+
swap32IfBE(this.IV);
|
|
113
|
+
this.flags = flags | B3_Flags.DERIVE_KEY_MATERIAL;
|
|
114
|
+
} else {
|
|
115
|
+
this.IV = B3_IV.slice();
|
|
116
|
+
this.flags = flags;
|
|
117
|
+
}
|
|
118
|
+
this.state = this.IV.slice();
|
|
119
|
+
this.bufferOut = u8(this.bufferOut32);
|
|
120
|
+
}
|
|
121
|
+
// _BLAKE2's scalar-state hooks are unused here: BLAKE3 keeps its tree/XOF state in arrays and
|
|
122
|
+
// copies it directly in _cloneInto().
|
|
123
|
+
protected get(): [] {
|
|
124
|
+
return [];
|
|
125
|
+
}
|
|
126
|
+
protected set(): void {}
|
|
127
|
+
// Truncated chunk/parent compression: seed v8..v15 as IV[0..3], t0, t1,
|
|
128
|
+
// block length, and flags, then keep only the first 8 output words.
|
|
129
|
+
private b2Compress(counter: number, flags: number, buf: Uint32Array, bufPos: number = 0) {
|
|
130
|
+
const { state: s, pos } = this;
|
|
131
|
+
const { h, l } = fromBig(BigInt(counter), true);
|
|
132
|
+
// prettier-ignore
|
|
133
|
+
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } =
|
|
134
|
+
compress(
|
|
135
|
+
B3_SIGMA, bufPos, buf, 7,
|
|
136
|
+
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
|
|
137
|
+
B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], h, l, pos, flags
|
|
138
|
+
);
|
|
139
|
+
s[0] = v0 ^ v8;
|
|
140
|
+
s[1] = v1 ^ v9;
|
|
141
|
+
s[2] = v2 ^ v10;
|
|
142
|
+
s[3] = v3 ^ v11;
|
|
143
|
+
s[4] = v4 ^ v12;
|
|
144
|
+
s[5] = v5 ^ v13;
|
|
145
|
+
s[6] = v6 ^ v14;
|
|
146
|
+
s[7] = v7 ^ v15;
|
|
147
|
+
}
|
|
148
|
+
protected compress(buf: Uint32Array, bufPos: number = 0, isLast: boolean = false): void {
|
|
149
|
+
// Compress last block
|
|
150
|
+
let flags = this.flags;
|
|
151
|
+
if (!this.chunkPos) flags |= B3_Flags.CHUNK_START;
|
|
152
|
+
if (this.chunkPos === 15 || isLast) flags |= B3_Flags.CHUNK_END;
|
|
153
|
+
if (!isLast) this.pos = this.blockLen;
|
|
154
|
+
this.b2Compress(this.chunksDone, flags, buf, bufPos);
|
|
155
|
+
this.chunkPos += 1;
|
|
156
|
+
// If current block is last in chunk (16 blocks), then compress chunks
|
|
157
|
+
if (this.chunkPos === 16 || isLast) {
|
|
158
|
+
let chunk = this.state;
|
|
159
|
+
this.state = this.IV.slice();
|
|
160
|
+
// If not the last one, compress only when there are trailing zeros in chunk counter
|
|
161
|
+
// Chunks are used as a binary tree where the current stack is the path.
|
|
162
|
+
// Zero means the current leaf is finished and can be compressed.
|
|
163
|
+
// 1 (001) - leaf not finished (just push current chunk to stack)
|
|
164
|
+
// 2 (010) - leaf finished at depth=1 (merge with last elm on stack and push back)
|
|
165
|
+
// 3 (011) - last leaf not finished
|
|
166
|
+
// 4 (100) - leafs finished at depth=1 and depth=2
|
|
167
|
+
for (let last, chunks = this.chunksDone + 1; isLast || !(chunks & 1); chunks >>= 1) {
|
|
168
|
+
if (!(last = this.stack.pop())) break;
|
|
169
|
+
this.buffer32.set(last, 0);
|
|
170
|
+
this.buffer32.set(chunk, 8);
|
|
171
|
+
this.pos = this.blockLen;
|
|
172
|
+
this.b2Compress(0, this.flags | B3_Flags.PARENT, this.buffer32, 0);
|
|
173
|
+
chunk = this.state;
|
|
174
|
+
this.state = this.IV.slice();
|
|
175
|
+
}
|
|
176
|
+
this.chunksDone++;
|
|
177
|
+
this.chunkPos = 0;
|
|
178
|
+
this.stack.push(chunk);
|
|
179
|
+
}
|
|
180
|
+
this.pos = 0;
|
|
181
|
+
}
|
|
182
|
+
_cloneInto(to?: _BLAKE3): _BLAKE3 {
|
|
183
|
+
to = super._cloneInto(to) as _BLAKE3;
|
|
184
|
+
const { IV, flags, state, chunkPos, posOut, chunkOut, stack, chunksDone } = this;
|
|
185
|
+
to.state.set(state.slice());
|
|
186
|
+
// Clone each CV stack entry by value so extending or destroying the clone
|
|
187
|
+
// cannot alias the source tree state.
|
|
188
|
+
to.stack = stack.map((i) => Uint32Array.from(i));
|
|
189
|
+
to.IV.set(IV);
|
|
190
|
+
to.flags = flags;
|
|
191
|
+
to.chunkPos = chunkPos;
|
|
192
|
+
to.chunksDone = chunksDone;
|
|
193
|
+
to.posOut = posOut;
|
|
194
|
+
to.chunkOut = chunkOut;
|
|
195
|
+
to.enableXOF = this.enableXOF;
|
|
196
|
+
to.bufferOut32.set(this.bufferOut32);
|
|
197
|
+
return to;
|
|
198
|
+
}
|
|
199
|
+
destroy(): void {
|
|
200
|
+
this.destroyed = true;
|
|
201
|
+
clean(this.state, this.buffer32, this.IV, this.bufferOut32);
|
|
202
|
+
clean(...this.stack);
|
|
203
|
+
}
|
|
204
|
+
// Root/XOF compression: rerun the same ROOT inputs with incrementing output
|
|
205
|
+
// counter `t` and materialize all 16 output words.
|
|
206
|
+
// Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8)
|
|
207
|
+
private b2CompressOut() {
|
|
208
|
+
const { state: s, pos, flags, buffer32, bufferOut32: out32 } = this;
|
|
209
|
+
const { h, l } = fromBig(BigInt(this.chunkOut++));
|
|
210
|
+
swap32IfBE(buffer32);
|
|
211
|
+
// prettier-ignore
|
|
212
|
+
const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } =
|
|
213
|
+
compress(
|
|
214
|
+
B3_SIGMA, 0, buffer32, 7,
|
|
215
|
+
s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7],
|
|
216
|
+
B3_IV[0], B3_IV[1], B3_IV[2], B3_IV[3], l, h, pos, flags
|
|
217
|
+
);
|
|
218
|
+
out32[0] = v0 ^ v8;
|
|
219
|
+
out32[1] = v1 ^ v9;
|
|
220
|
+
out32[2] = v2 ^ v10;
|
|
221
|
+
out32[3] = v3 ^ v11;
|
|
222
|
+
out32[4] = v4 ^ v12;
|
|
223
|
+
out32[5] = v5 ^ v13;
|
|
224
|
+
out32[6] = v6 ^ v14;
|
|
225
|
+
out32[7] = v7 ^ v15;
|
|
226
|
+
out32[8] = s[0] ^ v8;
|
|
227
|
+
out32[9] = s[1] ^ v9;
|
|
228
|
+
out32[10] = s[2] ^ v10;
|
|
229
|
+
out32[11] = s[3] ^ v11;
|
|
230
|
+
out32[12] = s[4] ^ v12;
|
|
231
|
+
out32[13] = s[5] ^ v13;
|
|
232
|
+
out32[14] = s[6] ^ v14;
|
|
233
|
+
out32[15] = s[7] ^ v15;
|
|
234
|
+
swap32IfBE(buffer32);
|
|
235
|
+
swap32IfBE(out32);
|
|
236
|
+
this.posOut = 0;
|
|
237
|
+
}
|
|
238
|
+
protected finish(): void {
|
|
239
|
+
if (this.finished) return;
|
|
240
|
+
this.finished = true;
|
|
241
|
+
// Padding
|
|
242
|
+
clean(this.buffer.subarray(this.pos));
|
|
243
|
+
// Process last chunk
|
|
244
|
+
let flags = this.flags | B3_Flags.ROOT;
|
|
245
|
+
if (this.stack.length) {
|
|
246
|
+
// Finalize the current chunk first, then rerun the last parent
|
|
247
|
+
// compression as ROOT with t = 0 and b = 64.
|
|
248
|
+
flags |= B3_Flags.PARENT;
|
|
249
|
+
swap32IfBE(this.buffer32);
|
|
250
|
+
this.compress(this.buffer32, 0, true);
|
|
251
|
+
swap32IfBE(this.buffer32);
|
|
252
|
+
this.chunksDone = 0;
|
|
253
|
+
this.pos = this.blockLen;
|
|
254
|
+
} else {
|
|
255
|
+
flags |= (!this.chunkPos ? B3_Flags.CHUNK_START : 0) | B3_Flags.CHUNK_END;
|
|
256
|
+
}
|
|
257
|
+
this.flags = flags;
|
|
258
|
+
this.b2CompressOut();
|
|
259
|
+
}
|
|
260
|
+
private writeInto(out: TArg<Uint8Array>): TRet<Uint8Array> {
|
|
261
|
+
aexists(this, false);
|
|
262
|
+
abytes(out);
|
|
263
|
+
this.finish();
|
|
264
|
+
const { blockLen, bufferOut } = this;
|
|
265
|
+
for (let pos = 0, len = out.length; pos < len; ) {
|
|
266
|
+
if (this.posOut >= blockLen) this.b2CompressOut();
|
|
267
|
+
const take = Math.min(blockLen - this.posOut, len - pos);
|
|
268
|
+
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
|
|
269
|
+
this.posOut += take;
|
|
270
|
+
pos += take;
|
|
271
|
+
}
|
|
272
|
+
return out as TRet<Uint8Array>;
|
|
273
|
+
}
|
|
274
|
+
xofInto(out: TArg<Uint8Array>): TRet<Uint8Array> {
|
|
275
|
+
if (!this.enableXOF) throw new Error('XOF is not possible after digest call');
|
|
276
|
+
return this.writeInto(out);
|
|
277
|
+
}
|
|
278
|
+
xof(bytes: number): TRet<Uint8Array> {
|
|
279
|
+
anumber(bytes);
|
|
280
|
+
return this.xofInto(new Uint8Array(bytes));
|
|
281
|
+
}
|
|
282
|
+
digestInto(out: TArg<Uint8Array>): void {
|
|
283
|
+
aoutput(out, this);
|
|
284
|
+
if (this.finished) throw new Error('digest() was already called');
|
|
285
|
+
this.enableXOF = false;
|
|
286
|
+
// `aoutput(...)` allows oversized buffers; digestInto() must fill only the configured digest.
|
|
287
|
+
this.writeInto(out.subarray(0, this.outputLen));
|
|
288
|
+
this.destroy();
|
|
289
|
+
}
|
|
290
|
+
digest(): TRet<Uint8Array> {
|
|
291
|
+
const out = new Uint8Array(this.outputLen);
|
|
292
|
+
this.digestInto(out);
|
|
293
|
+
return out as TRet<Uint8Array>;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* BLAKE3 hash function. Can be used as MAC and KDF.
|
|
299
|
+
* @param msg - message that would be hashed
|
|
300
|
+
* @param opts - Optional output, MAC, or KDF configuration. `key` must be
|
|
301
|
+
* exactly 32 bytes, `context` is caller-encoded bytes, and `dkLen` can be
|
|
302
|
+
* 0..2^64-1 via the XOF-backed output path. See {@link Blake3Opts}.
|
|
303
|
+
* @returns Digest bytes.
|
|
304
|
+
* @example
|
|
305
|
+
* Hash, MAC, or derive key material with BLAKE3.
|
|
306
|
+
* ```ts
|
|
307
|
+
* import { blake3 } from '@noble/hashes/blake3.js';
|
|
308
|
+
* import { utf8ToBytes } from '@noble/hashes/utils.js';
|
|
309
|
+
* const data = new Uint8Array(32);
|
|
310
|
+
* const hash = blake3(data);
|
|
311
|
+
* const mac = blake3(data, { key: new Uint8Array(32) });
|
|
312
|
+
* const kdf = blake3(data, { context: utf8ToBytes('application name') });
|
|
313
|
+
* ```
|
|
314
|
+
*/
|
|
315
|
+
export const blake3: TRet<CHashXOF<_BLAKE3, Blake3Opts>> = /* @__PURE__ */ createHasher(
|
|
316
|
+
(opts = {}) => new _BLAKE3(opts)
|
|
317
|
+
);
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Experimental KDF for AES.
|
|
3
|
+
* @module
|
|
4
|
+
*/
|
|
5
|
+
import { hkdf } from './hkdf.ts';
|
|
6
|
+
import { pbkdf2 as _pbkdf2 } from './pbkdf2.ts';
|
|
7
|
+
import { scrypt as _scrypt } from './scrypt.ts';
|
|
8
|
+
import { sha256 } from './sha2.ts';
|
|
9
|
+
import {
|
|
10
|
+
abytes,
|
|
11
|
+
bytesToHex,
|
|
12
|
+
clean,
|
|
13
|
+
createView,
|
|
14
|
+
hexToBytes,
|
|
15
|
+
kdfInputToBytes,
|
|
16
|
+
type TArg,
|
|
17
|
+
type TRet,
|
|
18
|
+
} from './utils.ts';
|
|
19
|
+
|
|
20
|
+
// A tiny KDF for various applications like AES key-gen.
|
|
21
|
+
// Uses HKDF in a non-standard way, so it's not "KDF-secure", only "PRF-secure".
|
|
22
|
+
// Which is good enough: assume sha2-256 retained preimage resistance.
|
|
23
|
+
|
|
24
|
+
// Fixed ESKDF scrypt work factor: interactive-latency target with about 512 MiB RAM per derivation.
|
|
25
|
+
const SCRYPT_FACTOR = /* @__PURE__ */ (() => 2 ** 19)();
|
|
26
|
+
// Fixed ESKDF PBKDF2 work factor: CPU-only companion branch in the same rough
|
|
27
|
+
// interactive-latency range.
|
|
28
|
+
const PBKDF2_FACTOR = /* @__PURE__ */ (() => 2 ** 17)();
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Scrypt KDF with the fixed ESKDF policy tuple `{ N: 2^19, r: 8, p: 1, dkLen: 32 }`.
|
|
32
|
+
* @param password - user password string, UTF-8 encoded before entering RFC 7914
|
|
33
|
+
* @param salt - unique salt string, UTF-8 encoded before entering RFC 7914
|
|
34
|
+
* @returns Derived 32-byte key.
|
|
35
|
+
* @example
|
|
36
|
+
* Derive the 32-byte scrypt key used by ESKDF.
|
|
37
|
+
* ```ts
|
|
38
|
+
* scrypt('password123', 'user@example.com');
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function scrypt(password: string, salt: string): TRet<Uint8Array> {
|
|
42
|
+
return _scrypt(password, salt, { N: SCRYPT_FACTOR, r: 8, p: 1, dkLen: 32 });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* PBKDF2-HMAC-SHA256 with the fixed ESKDF policy tuple `{ sha256, c: 2^17, dkLen: 32 }`.
|
|
47
|
+
* @param password - user password string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256
|
|
48
|
+
* @param salt - unique salt string, UTF-8 encoded before entering PBKDF2-HMAC-SHA-256
|
|
49
|
+
* @returns Derived 32-byte key.
|
|
50
|
+
* @example
|
|
51
|
+
* Derive the 32-byte PBKDF2 key used by ESKDF.
|
|
52
|
+
* ```ts
|
|
53
|
+
* pbkdf2('password123', 'user@example.com');
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function pbkdf2(password: string, salt: string): TRet<Uint8Array> {
|
|
57
|
+
return _pbkdf2(sha256, password, salt, { c: PBKDF2_FACTOR, dkLen: 32 });
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Combines two 32-byte byte arrays into a fresh 32-byte result without aliasing either input.
|
|
61
|
+
function xor32(a: TArg<Uint8Array>, b: TArg<Uint8Array>): TRet<Uint8Array> {
|
|
62
|
+
abytes(a, 32);
|
|
63
|
+
abytes(b, 32);
|
|
64
|
+
const arr = new Uint8Array(32);
|
|
65
|
+
for (let i = 0; i < 32; i++) {
|
|
66
|
+
arr[i] = a[i] ^ b[i];
|
|
67
|
+
}
|
|
68
|
+
return arr as TRet<Uint8Array>;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// All local string length checks are in JS UTF-16 code units, not UTF-8 bytes.
|
|
72
|
+
function strHasLength(str: string, min: number, max: number): boolean {
|
|
73
|
+
return typeof str === 'string' && str.length >= min && str.length <= max;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Derives main seed. Takes a lot of time; prefer the higher-level `eskdf(...)`
|
|
78
|
+
* flow unless you specifically need the raw main seed.
|
|
79
|
+
* Derives the main seed by xor'ing two branches:
|
|
80
|
+
* the scrypt branch uses a `0x01` separator byte on username/password,
|
|
81
|
+
* and the PBKDF2 branch uses `0x02`.
|
|
82
|
+
* Username and password strings are encoded by the underlying KDFs after the
|
|
83
|
+
* local separator bytes are appended.
|
|
84
|
+
* @param username - account identifier used as public salt
|
|
85
|
+
* @param password - user password string
|
|
86
|
+
* @returns Main 32-byte seed for the account.
|
|
87
|
+
* @throws If the username or password length is invalid. {@link Error}
|
|
88
|
+
* @example
|
|
89
|
+
* Derive the main ESKDF seed from username and password.
|
|
90
|
+
* ```ts
|
|
91
|
+
* deriveMainSeed('example-user', 'example-password');
|
|
92
|
+
* ```
|
|
93
|
+
*/
|
|
94
|
+
export function deriveMainSeed(username: string, password: string): TRet<Uint8Array> {
|
|
95
|
+
if (!strHasLength(username, 8, 255)) throw new Error('invalid username');
|
|
96
|
+
if (!strHasLength(password, 8, 255)) throw new Error('invalid password');
|
|
97
|
+
// Keep the protocol separators as the literal bytes 0x01 / 0x02 even after minification.
|
|
98
|
+
// Embedding them as non-printable characters directly can be awkward across
|
|
99
|
+
// JS tooling and environments.
|
|
100
|
+
const codes = { _1: 1, _2: 2 };
|
|
101
|
+
const sep = { s: String.fromCharCode(codes._1), p: String.fromCharCode(codes._2) };
|
|
102
|
+
const scr = scrypt(password + sep.s, username + sep.s);
|
|
103
|
+
const pbk = pbkdf2(password + sep.p, username + sep.p);
|
|
104
|
+
const res = xor32(scr, pbk);
|
|
105
|
+
clean(scr, pbk);
|
|
106
|
+
return res;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
type AccountID = number | string;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Converts protocol & accountId pair to HKDF params:
|
|
113
|
+
* `info` is UTF-8 protocol bytes, numeric ids become 4-byte BE `salt`,
|
|
114
|
+
* and string ids become UTF-8 `salt` bytes.
|
|
115
|
+
*/
|
|
116
|
+
function getSaltInfo(protocol: string, accountId: AccountID = 0) {
|
|
117
|
+
// Note that length here also repeats two lines below
|
|
118
|
+
// We do an additional length check here to reduce the scope of DoS attacks
|
|
119
|
+
if (!(strHasLength(protocol, 3, 15) && /^[a-z0-9]{3,15}$/.test(protocol))) {
|
|
120
|
+
throw new Error('invalid protocol');
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// Exact-match only: substring matches like `assh` / `mentor` must not widen the public whitelist.
|
|
124
|
+
const allowsStr = /^(password\d{0,3}|ssh|tor|file)$/.test(protocol);
|
|
125
|
+
let salt: Uint8Array; // Assigned below: either 4-byte BE account bytes or UTF-8 account bytes.
|
|
126
|
+
if (typeof accountId === 'string') {
|
|
127
|
+
if (!allowsStr) throw new Error('accountId must be a number');
|
|
128
|
+
if (!strHasLength(accountId, 1, 255))
|
|
129
|
+
throw new Error('accountId must be string of length 1..255');
|
|
130
|
+
salt = kdfInputToBytes(accountId);
|
|
131
|
+
} else if (Number.isSafeInteger(accountId)) {
|
|
132
|
+
if (accountId < 0 || accountId > Math.pow(2, 32) - 1) throw new Error('invalid accountId');
|
|
133
|
+
// Convert to Big Endian Uint32
|
|
134
|
+
salt = new Uint8Array(4);
|
|
135
|
+
createView(salt).setUint32(0, accountId, false);
|
|
136
|
+
} else {
|
|
137
|
+
throw new Error('accountId must be a number' + (allowsStr ? ' or string' : ''));
|
|
138
|
+
}
|
|
139
|
+
const info = kdfInputToBytes(protocol);
|
|
140
|
+
return { salt, info };
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
type OptsLength = { keyLength: number };
|
|
144
|
+
type OptsMod = { modulus: bigint };
|
|
145
|
+
type KeyOpts = undefined | OptsLength | OptsMod;
|
|
146
|
+
|
|
147
|
+
// Local modulus-size helper, not a general bigint-byte-length primitive:
|
|
148
|
+
// `<= 128n` is rejected by ESKDF policy.
|
|
149
|
+
function countBytes(num: bigint): number {
|
|
150
|
+
if (typeof num !== 'bigint' || num <= BigInt(128)) throw new Error('invalid number');
|
|
151
|
+
return Math.ceil(num.toString(2).length / 8);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Parses keyLength and modulus options to extract length of result key.
|
|
156
|
+
* If modulus is used, adds 64 bits to it per the FIPS 186-5 Appendix A.3.1 /
|
|
157
|
+
* A.4.1 extra-bits guidance.
|
|
158
|
+
*/
|
|
159
|
+
function getKeyLength(options: KeyOpts): number {
|
|
160
|
+
if (!options || typeof options !== 'object') return 32;
|
|
161
|
+
const hasLen = 'keyLength' in options;
|
|
162
|
+
const hasMod = 'modulus' in options;
|
|
163
|
+
if (hasLen && hasMod) throw new Error('cannot combine keyLength and modulus options');
|
|
164
|
+
if (!hasLen && !hasMod) throw new Error('must have either keyLength or modulus option');
|
|
165
|
+
// FIPS 186-5 Appendix A.3.1 / A.4.1 calls for at least 64 extra bits.
|
|
166
|
+
const l = hasMod ? countBytes(options.modulus) + 8 : options.keyLength;
|
|
167
|
+
if (!(typeof l === 'number' && l >= 16 && l <= 8192)) throw new Error('invalid keyLength');
|
|
168
|
+
return l;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Converts key to bigint and divides it by modulus. Big Endian.
|
|
173
|
+
* Adapts FIPS 186-5 Appendix A.4.1: `getKeyLength()` already requested the
|
|
174
|
+
* extra 64-bit margin, and this step maps the result into `1..modulus-1`.
|
|
175
|
+
*/
|
|
176
|
+
function modReduceKey(key: TArg<Uint8Array>, modulus: bigint): TRet<Uint8Array> {
|
|
177
|
+
const _1 = BigInt(1);
|
|
178
|
+
const num = BigInt('0x' + bytesToHex(key)); // check for ui8a, then bytesToNumber()
|
|
179
|
+
const res = (num % (modulus - _1)) + _1; // Remove 0 from output
|
|
180
|
+
if (res < _1) throw new Error('expected positive number'); // Guard against bad values
|
|
181
|
+
// Strip the extra 64-bit margin that `getKeyLength()` requested
|
|
182
|
+
// for bias reduction.
|
|
183
|
+
const len = key.length - 8;
|
|
184
|
+
const hex = res.toString(16).padStart(len * 2, '0'); // numberToHex()
|
|
185
|
+
const bytes = hexToBytes(hex);
|
|
186
|
+
if (bytes.length !== len) throw new Error('invalid length of result key');
|
|
187
|
+
return bytes;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/** Not using classes because constructor cannot be async. */
|
|
191
|
+
export interface ESKDF {
|
|
192
|
+
/**
|
|
193
|
+
* Derives a child key. Child key will not be associated with any
|
|
194
|
+
* other child key because of properties of underlying KDF.
|
|
195
|
+
*
|
|
196
|
+
* @param protocol - 3-15 character protocol name
|
|
197
|
+
* @param accountId - numeric account identifier, or a string id for
|
|
198
|
+
* `password\d{0,3}`, `ssh`, `tor`, or `file`
|
|
199
|
+
* @param options - Optional child-key shaping parameters. See {@link KeyOpts}.
|
|
200
|
+
* @returns Derived child key bytes.
|
|
201
|
+
*/
|
|
202
|
+
deriveChildKey: (protocol: string, accountId: AccountID, options?: KeyOpts) => TRet<Uint8Array>;
|
|
203
|
+
/** Deletes the main seed from the ESKDF instance. */
|
|
204
|
+
expire: () => void;
|
|
205
|
+
/**
|
|
206
|
+
* Human-readable fingerprint: first 6 bytes of
|
|
207
|
+
* `deriveChildKey('fingerprint', 0)`, formatted as uppercase
|
|
208
|
+
* colon-separated hex.
|
|
209
|
+
*/
|
|
210
|
+
fingerprint: string;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* ESKDF
|
|
215
|
+
* @param username - username, email, or identifier, min: 8 characters, should have enough entropy
|
|
216
|
+
* @param password - password, min: 8 characters, should have enough entropy
|
|
217
|
+
* @returns Frozen API that derives child keys and exposes the account fingerprint.
|
|
218
|
+
* @throws If the username or password length is invalid. {@link Error}
|
|
219
|
+
* @example
|
|
220
|
+
* Derive account-specific child keys from the main ESKDF seed.
|
|
221
|
+
* ```ts
|
|
222
|
+
* const kdf = await eskdf('example-university', 'beginning-new-example');
|
|
223
|
+
* const key = kdf.deriveChildKey('aes', 0);
|
|
224
|
+
* const fingerprint = kdf.fingerprint;
|
|
225
|
+
* kdf.expire();
|
|
226
|
+
* ```
|
|
227
|
+
*/
|
|
228
|
+
export async function eskdf(username: string, password: string): Promise<TRet<ESKDF>> {
|
|
229
|
+
// We are using closure + object instead of class because
|
|
230
|
+
// we want to make `seed` non-accessible for any external function.
|
|
231
|
+
let seed: Uint8Array | undefined = deriveMainSeed(username, password);
|
|
232
|
+
|
|
233
|
+
function deriveCK(
|
|
234
|
+
protocol: string,
|
|
235
|
+
accountId: AccountID = 0,
|
|
236
|
+
options?: KeyOpts
|
|
237
|
+
): TRet<Uint8Array> {
|
|
238
|
+
// Reject expired instances before deriving any HKDF inputs from the closure-held seed.
|
|
239
|
+
abytes(seed!, 32);
|
|
240
|
+
const { salt, info } = getSaltInfo(protocol, accountId); // validate protocol & accountId
|
|
241
|
+
// Validate option shape and coarse length bounds;
|
|
242
|
+
// `hkdf()` still rejects non-integer lengths.
|
|
243
|
+
const keyLength = getKeyLength(options);
|
|
244
|
+
const key = hkdf(sha256, seed!, salt, info, keyLength);
|
|
245
|
+
// Modulus has already been validated
|
|
246
|
+
return options && 'modulus' in options ? modReduceKey(key, options.modulus) : key;
|
|
247
|
+
}
|
|
248
|
+
function expire() {
|
|
249
|
+
// Overwrite the closure-held seed before dropping the reference.
|
|
250
|
+
if (seed) seed.fill(1);
|
|
251
|
+
seed = undefined;
|
|
252
|
+
}
|
|
253
|
+
// prettier-ignore
|
|
254
|
+
const fingerprint = Array.from(deriveCK('fingerprint', 0))
|
|
255
|
+
.slice(0, 6)
|
|
256
|
+
.map((char) => char.toString(16).padStart(2, '0').toUpperCase())
|
|
257
|
+
.join(':');
|
|
258
|
+
return Object.freeze({ deriveChildKey: deriveCK, expire, fingerprint });
|
|
259
|
+
}
|