Re-implement bip39 (#966)
* Re-implement bip39 * Use pbkdf2 from subtle * Pull out and fix getSubtle() * Remove unused pbkdf2 dependency * Remove stream fallback (remove stream-browserify) * Pull out pbkdf2Sha512 * Pull out pbkdf2Sha512Subtle * Pull out pbkdf2Sha512Crypto * Disable "Test Case 4" because it takes a long time * Deactivate pbkdf2Sha512Subtle/pbkdf2Sha512Crypto tests when API unavailable * Let getCryptoModule detect fallback modules * Create noble implementation of pbkdf2Sha512 * Add CHANGELOG entry
This commit is contained in:
commit
1fa07030e4
148
.pnp.cjs
generated
148
.pnp.cjs
generated
@ -841,10 +841,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"bindings",
|
||||
"npm:1.5.0"
|
||||
],
|
||||
[
|
||||
"bip39",
|
||||
"npm:3.0.4"
|
||||
],
|
||||
[
|
||||
"bl",
|
||||
"npm:4.1.0"
|
||||
@ -929,10 +925,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"chrome-trace-event",
|
||||
"npm:1.0.3"
|
||||
],
|
||||
[
|
||||
"cipher-base",
|
||||
"npm:1.0.4"
|
||||
],
|
||||
[
|
||||
"clean-stack",
|
||||
"npm:2.2.0"
|
||||
@ -1037,14 +1029,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"cosmjs-types",
|
||||
"npm:0.4.0"
|
||||
],
|
||||
[
|
||||
"create-hash",
|
||||
"npm:1.2.0"
|
||||
],
|
||||
[
|
||||
"create-hmac",
|
||||
"npm:1.1.7"
|
||||
],
|
||||
[
|
||||
"cross-spawn",
|
||||
"npm:7.0.3"
|
||||
@ -1913,10 +1897,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"marked",
|
||||
"npm:4.0.10"
|
||||
],
|
||||
[
|
||||
"md5.js",
|
||||
"npm:1.3.5"
|
||||
],
|
||||
[
|
||||
"media-typer",
|
||||
"npm:0.3.0"
|
||||
@ -2181,10 +2161,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"path-type",
|
||||
"npm:4.0.0"
|
||||
],
|
||||
[
|
||||
"pbkdf2",
|
||||
"npm:3.1.2"
|
||||
],
|
||||
[
|
||||
"picomatch",
|
||||
"npm:2.2.3"
|
||||
@ -2379,7 +2355,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
],
|
||||
[
|
||||
"safe-buffer",
|
||||
"npm:5.2.1"
|
||||
"npm:5.1.2"
|
||||
],
|
||||
[
|
||||
"safer-buffer",
|
||||
@ -2409,10 +2385,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"setprototypeof",
|
||||
"npm:1.1.1"
|
||||
],
|
||||
[
|
||||
"sha.js",
|
||||
"npm:2.4.11"
|
||||
],
|
||||
[
|
||||
"shallow-clone",
|
||||
"npm:3.0.1"
|
||||
@ -2521,10 +2493,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"statuses",
|
||||
"npm:1.5.0"
|
||||
],
|
||||
[
|
||||
"stream-browserify",
|
||||
"npm:3.0.0"
|
||||
],
|
||||
[
|
||||
"streamroller",
|
||||
"npm:3.0.2"
|
||||
@ -3220,7 +3188,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["prettier", "npm:2.4.1"],
|
||||
["ses", "npm:0.11.1"],
|
||||
["source-map-support", "npm:0.5.19"],
|
||||
["stream-browserify", "npm:3.0.0"],
|
||||
["ts-node", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:8.10.2"],
|
||||
["typedoc", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:0.22.11"],
|
||||
["typescript", "patch:typescript@npm%3A4.4.4#~builtin<compat/typescript>::version=4.4.4&hash=ddd1e8"],
|
||||
@ -3328,7 +3295,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["readonly-date", "npm:1.0.0"],
|
||||
["ses", "npm:0.11.1"],
|
||||
["source-map-support", "npm:0.5.19"],
|
||||
["stream-browserify", "npm:3.0.0"],
|
||||
["ts-node", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:8.10.2"],
|
||||
["typedoc", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:0.22.11"],
|
||||
["typescript", "patch:typescript@npm%3A4.4.4#~builtin<compat/typescript>::version=4.4.4&hash=ddd1e8"],
|
||||
@ -3359,7 +3325,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["@types/node", "npm:15.3.1"],
|
||||
["@typescript-eslint/eslint-plugin", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:4.28.4"],
|
||||
["@typescript-eslint/parser", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:4.28.4"],
|
||||
["bip39", "npm:3.0.4"],
|
||||
["bn.js", "npm:5.2.0"],
|
||||
["buffer", "npm:6.0.3"],
|
||||
["elliptic", "npm:6.5.4"],
|
||||
@ -3384,7 +3349,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["prettier", "npm:2.4.1"],
|
||||
["ses", "npm:0.11.1"],
|
||||
["source-map-support", "npm:0.5.19"],
|
||||
["stream-browserify", "npm:3.0.0"],
|
||||
["ts-node", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:8.10.2"],
|
||||
["typedoc", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:0.22.11"],
|
||||
["typescript", "patch:typescript@npm%3A4.4.4#~builtin<compat/typescript>::version=4.4.4&hash=ddd1e8"],
|
||||
@ -3706,7 +3670,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["protobufjs", "npm:6.10.2"],
|
||||
["ses", "npm:0.11.1"],
|
||||
["source-map-support", "npm:0.5.19"],
|
||||
["stream-browserify", "npm:3.0.0"],
|
||||
["ts-node", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:8.10.2"],
|
||||
["typedoc", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:0.22.11"],
|
||||
["typescript", "patch:typescript@npm%3A4.4.4#~builtin<compat/typescript>::version=4.4.4&hash=ddd1e8"],
|
||||
@ -3811,7 +3774,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
["readonly-date", "npm:1.0.0"],
|
||||
["ses", "npm:0.11.1"],
|
||||
["source-map-support", "npm:0.5.19"],
|
||||
["stream-browserify", "npm:3.0.0"],
|
||||
["ts-node", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:8.10.2"],
|
||||
["typedoc", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:0.22.11"],
|
||||
["typescript", "patch:typescript@npm%3A4.4.4#~builtin<compat/typescript>::version=4.4.4&hash=ddd1e8"],
|
||||
@ -4716,13 +4678,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
}]
|
||||
]],
|
||||
["@types/node", [
|
||||
["npm:11.11.6", {
|
||||
"packageLocation": "./.yarn/cache/@types-node-npm-11.11.6-40abad0842-075f1c011c.zip/node_modules/@types/node/",
|
||||
"packageDependencies": [
|
||||
["@types/node", "npm:11.11.6"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}],
|
||||
["npm:13.13.52", {
|
||||
"packageLocation": "./.yarn/cache/@types-node-npm-13.13.52-95159539bb-8f1afff497.zip/node_modules/@types/node/",
|
||||
"packageDependencies": [
|
||||
@ -6287,19 +6242,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["bip39", [
|
||||
["npm:3.0.4", {
|
||||
"packageLocation": "./.yarn/cache/bip39-npm-3.0.4-7c69c9182f-79ce1600a0.zip/node_modules/bip39/",
|
||||
"packageDependencies": [
|
||||
["bip39", "npm:3.0.4"],
|
||||
["@types/node", "npm:11.11.6"],
|
||||
["create-hash", "npm:1.2.0"],
|
||||
["pbkdf2", "npm:3.1.2"],
|
||||
["randombytes", "npm:2.1.0"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["bl", [
|
||||
["npm:4.1.0", {
|
||||
"packageLocation": "./.yarn/cache/bl-npm-4.1.0-7f94cdcf3f-9e8521fa7e.zip/node_modules/bl/",
|
||||
@ -6580,17 +6522,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["cipher-base", [
|
||||
["npm:1.0.4", {
|
||||
"packageLocation": "./.yarn/cache/cipher-base-npm-1.0.4-2e98b97140-47d3568dbc.zip/node_modules/cipher-base/",
|
||||
"packageDependencies": [
|
||||
["cipher-base", "npm:1.0.4"],
|
||||
["inherits", "npm:2.0.4"],
|
||||
["safe-buffer", "npm:5.2.1"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["clean-stack", [
|
||||
["npm:2.2.0", {
|
||||
"packageLocation": "./.yarn/cache/clean-stack-npm-2.2.0-a8ce435a5c-2ac8cd2b2f.zip/node_modules/clean-stack/",
|
||||
@ -6900,35 +6831,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["create-hash", [
|
||||
["npm:1.2.0", {
|
||||
"packageLocation": "./.yarn/cache/create-hash-npm-1.2.0-afd048e1ce-02a6ae3bb9.zip/node_modules/create-hash/",
|
||||
"packageDependencies": [
|
||||
["create-hash", "npm:1.2.0"],
|
||||
["cipher-base", "npm:1.0.4"],
|
||||
["inherits", "npm:2.0.4"],
|
||||
["md5.js", "npm:1.3.5"],
|
||||
["ripemd160", "npm:2.0.2"],
|
||||
["sha.js", "npm:2.4.11"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["create-hmac", [
|
||||
["npm:1.1.7", {
|
||||
"packageLocation": "./.yarn/cache/create-hmac-npm-1.1.7-b4ef32668a-ba12bb2257.zip/node_modules/create-hmac/",
|
||||
"packageDependencies": [
|
||||
["create-hmac", "npm:1.1.7"],
|
||||
["cipher-base", "npm:1.0.4"],
|
||||
["create-hash", "npm:1.2.0"],
|
||||
["inherits", "npm:2.0.4"],
|
||||
["ripemd160", "npm:2.0.2"],
|
||||
["safe-buffer", "npm:5.2.1"],
|
||||
["sha.js", "npm:2.4.11"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["cross-spawn", [
|
||||
["npm:7.0.3", {
|
||||
"packageLocation": "./.yarn/cache/cross-spawn-npm-7.0.3-e4ff3e65b3-671cc7c728.zip/node_modules/cross-spawn/",
|
||||
@ -9615,18 +9517,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["md5.js", [
|
||||
["npm:1.3.5", {
|
||||
"packageLocation": "./.yarn/cache/md5.js-npm-1.3.5-130901125a-098494d885.zip/node_modules/md5.js/",
|
||||
"packageDependencies": [
|
||||
["md5.js", "npm:1.3.5"],
|
||||
["hash-base", "npm:3.1.0"],
|
||||
["inherits", "npm:2.0.4"],
|
||||
["safe-buffer", "npm:5.2.1"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["media-typer", [
|
||||
["npm:0.3.0", {
|
||||
"packageLocation": "./.yarn/cache/media-typer-npm-0.3.0-8674f8f0f5-af1b38516c.zip/node_modules/media-typer/",
|
||||
@ -10410,20 +10300,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["pbkdf2", [
|
||||
["npm:3.1.2", {
|
||||
"packageLocation": "./.yarn/cache/pbkdf2-npm-3.1.2-d67bbb584f-2c950a100b.zip/node_modules/pbkdf2/",
|
||||
"packageDependencies": [
|
||||
["pbkdf2", "npm:3.1.2"],
|
||||
["create-hash", "npm:1.2.0"],
|
||||
["create-hmac", "npm:1.1.7"],
|
||||
["ripemd160", "npm:2.0.2"],
|
||||
["safe-buffer", "npm:5.2.1"],
|
||||
["sha.js", "npm:2.4.11"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["picomatch", [
|
||||
["npm:2.2.3", {
|
||||
"packageLocation": "./.yarn/cache/picomatch-npm-2.2.3-3797e21cf0-45e2b882b5.zip/node_modules/picomatch/",
|
||||
@ -11134,17 +11010,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["sha.js", [
|
||||
["npm:2.4.11", {
|
||||
"packageLocation": "./.yarn/cache/sha.js-npm-2.4.11-14868df4ca-ebd3f59d4b.zip/node_modules/sha.js/",
|
||||
"packageDependencies": [
|
||||
["sha.js", "npm:2.4.11"],
|
||||
["inherits", "npm:2.0.4"],
|
||||
["safe-buffer", "npm:5.2.1"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["shallow-clone", [
|
||||
["npm:3.0.1", {
|
||||
"packageLocation": "./.yarn/cache/shallow-clone-npm-3.0.1-dab5873d0d-39b3dd9630.zip/node_modules/shallow-clone/",
|
||||
@ -11443,17 +11308,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["stream-browserify", [
|
||||
["npm:3.0.0", {
|
||||
"packageLocation": "./.yarn/cache/stream-browserify-npm-3.0.0-4c0bd97245-4c47ef64d6.zip/node_modules/stream-browserify/",
|
||||
"packageDependencies": [
|
||||
["stream-browserify", "npm:3.0.0"],
|
||||
["inherits", "npm:2.0.4"],
|
||||
["readable-stream", "npm:3.6.0"]
|
||||
],
|
||||
"linkType": "HARD",
|
||||
}]
|
||||
]],
|
||||
["streamroller", [
|
||||
["npm:3.0.2", {
|
||||
"packageLocation": "./.yarn/cache/streamroller-npm-3.0.2-6d7ba8035a-1f323824f0.zip/node_modules/streamroller/",
|
||||
|
||||
BIN
.yarn/cache/@types-node-npm-11.11.6-40abad0842-075f1c011c.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/@types-node-npm-11.11.6-40abad0842-075f1c011c.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/bip39-npm-3.0.4-7c69c9182f-79ce1600a0.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/bip39-npm-3.0.4-7c69c9182f-79ce1600a0.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/cipher-base-npm-1.0.4-2e98b97140-47d3568dbc.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/cipher-base-npm-1.0.4-2e98b97140-47d3568dbc.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/create-hash-npm-1.2.0-afd048e1ce-02a6ae3bb9.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/create-hash-npm-1.2.0-afd048e1ce-02a6ae3bb9.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/create-hmac-npm-1.1.7-b4ef32668a-ba12bb2257.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/create-hmac-npm-1.1.7-b4ef32668a-ba12bb2257.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/md5.js-npm-1.3.5-130901125a-098494d885.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/md5.js-npm-1.3.5-130901125a-098494d885.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/pbkdf2-npm-3.1.2-d67bbb584f-2c950a100b.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/pbkdf2-npm-3.1.2-d67bbb584f-2c950a100b.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/sha.js-npm-2.4.11-14868df4ca-ebd3f59d4b.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/sha.js-npm-2.4.11-14868df4ca-ebd3f59d4b.zip
(Stored with Git LFS)
vendored
Binary file not shown.
BIN
.yarn/cache/stream-browserify-npm-3.0.0-4c0bd97245-4c47ef64d6.zip
(Stored with Git LFS)
vendored
BIN
.yarn/cache/stream-browserify-npm-3.0.0-4c0bd97245-4c47ef64d6.zip
(Stored with Git LFS)
vendored
Binary file not shown.
@ -39,9 +39,13 @@ and this project adheres to
|
||||
- @cosmjs/ledger-amino: Renamed `LaunchpadLedger` to `LedgerConnector` ([#955])
|
||||
- @cosmjs/encoding: Created `toBech32()` and `fromBech32()`. Class Bech32 is now
|
||||
deprecated and should not longer be used. ([#1053])
|
||||
- @cosmjs/crypto: Use a custom BIP-39 implementation to reduce external
|
||||
dependencies. This should also reduce the bundle size as only the English
|
||||
wordlist is shipped. ([#966])
|
||||
|
||||
[#927]: https://github.com/cosmos/cosmjs/issues/927
|
||||
[#955]: https://github.com/cosmos/cosmjs/issues/955
|
||||
[#966]: https://github.com/cosmos/cosmjs/pull/966
|
||||
[#989]: https://github.com/cosmos/cosmjs/issues/989
|
||||
[#994]: https://github.com/cosmos/cosmjs/issues/994
|
||||
[#1011]: https://github.com/cosmos/cosmjs/issues/1011
|
||||
|
||||
3
NOTICE
3
NOTICE
@ -23,6 +23,9 @@ The code in packages/json-rpc was forked from https://github.com/iov-one/iov-cor
|
||||
|
||||
The code in packages/socket and scripts/socketserver was forked from the folders packages/iov-socket and scripts/socketserver respectively of https://github.com/iov-one/iov-core at tag v2.5.0 on 2020-06-24.
|
||||
|
||||
The code in packages/crypto/src/bip39.ts contains code forked from bitcoinjs/bip39 (https://github.com/bitcoinjs/bip39/blob/v3.0.4/LICENSE)
|
||||
on 2021-12-16. Copyright (c) 2014, Wei Lu and Daniel Cousens.
|
||||
|
||||
Copyright 2018-2020 IOV SAS
|
||||
Copyright 2020-2021 Confio OÜ
|
||||
Copyright 2020 Simon Warta
|
||||
|
||||
@ -74,7 +74,6 @@
|
||||
"prettier": "^2.4.1",
|
||||
"ses": "^0.11.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"ts-node": "^8",
|
||||
"typedoc": "^0.22",
|
||||
"typescript": "~4.4",
|
||||
|
||||
@ -26,7 +26,7 @@ module.exports = [
|
||||
crypto: false,
|
||||
events: false,
|
||||
path: false,
|
||||
stream: require.resolve("stream-browserify"),
|
||||
stream: false,
|
||||
string_decoder: false,
|
||||
},
|
||||
},
|
||||
|
||||
@ -84,7 +84,6 @@
|
||||
"readonly-date": "^1.0.0",
|
||||
"ses": "^0.11.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"ts-node": "^8",
|
||||
"typedoc": "^0.22",
|
||||
"typescript": "~4.4",
|
||||
|
||||
@ -29,7 +29,7 @@ module.exports = [
|
||||
crypto: false,
|
||||
events: false,
|
||||
path: false,
|
||||
stream: require.resolve("stream-browserify"),
|
||||
stream: false,
|
||||
string_decoder: false,
|
||||
},
|
||||
},
|
||||
|
||||
@ -45,7 +45,6 @@
|
||||
"@cosmjs/math": "workspace:packages/math",
|
||||
"@cosmjs/utils": "workspace:packages/utils",
|
||||
"@noble/hashes": "^1",
|
||||
"bip39": "^3.0.2",
|
||||
"bn.js": "^5.2.0",
|
||||
"elliptic": "^6.5.3",
|
||||
"libsodium-wrappers": "^0.7.6"
|
||||
@ -84,7 +83,6 @@
|
||||
"prettier": "^2.4.1",
|
||||
"ses": "^0.11.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"ts-node": "^8",
|
||||
"typedoc": "^0.22",
|
||||
"typescript": "~4.4",
|
||||
|
||||
@ -1,8 +1,49 @@
|
||||
import { fromHex } from "@cosmjs/encoding";
|
||||
import { fromAscii, fromBase64, fromHex } from "@cosmjs/encoding";
|
||||
|
||||
import { Bip39 } from "./bip39";
|
||||
import { EnglishMnemonic } from "./englishmnemonic";
|
||||
import { Bip39, EnglishMnemonic, entropyToMnemonic, mnemonicToEntropy } from "./bip39";
|
||||
import { sha256 } from "./sha";
|
||||
import bip39Vectors from "./testdata/bip39.json";
|
||||
import wordlists from "./testdata/bip39_wordlists.json";
|
||||
|
||||
describe("entropyToMnemonic", () => {
|
||||
it("works", () => {
|
||||
// From https://iancoleman.io/bip39/
|
||||
expect(entropyToMnemonic(fromHex("a323224e6b13d31942509dc4e2e579be3d5bb7f2"))).toEqual(
|
||||
"permit boil near stomach diamond million announce beauty shaft blame fury ladder stick swim slab",
|
||||
);
|
||||
});
|
||||
|
||||
it("works for all the test vectors", () => {
|
||||
// Test vectors from https://github.com/trezor/python-mnemonic/blob/b502451a33a440783926e04428115e0bed87d01f/vectors.json
|
||||
// plus similar vectors generated for the missing lengths 15 and 21 words
|
||||
const { "12": vec12, "15": vec15, "18": vec18, "21": vec21, "24": vec24 } = bip39Vectors.encoding;
|
||||
for (const vectors of [vec12, vec15, vec18, vec21, vec24]) {
|
||||
for (const { entropy, mnemonic } of vectors) {
|
||||
expect(entropyToMnemonic(fromHex(entropy)).toString()).toEqual(mnemonic);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("mnemonicToEntropy", () => {
|
||||
it("works", () => {
|
||||
// From https://iancoleman.io/bip39/
|
||||
expect(
|
||||
mnemonicToEntropy(
|
||||
"permit boil near stomach diamond million announce beauty shaft blame fury ladder stick swim slab",
|
||||
),
|
||||
).toEqual(fromHex("a323224e6b13d31942509dc4e2e579be3d5bb7f2"));
|
||||
});
|
||||
|
||||
it("works for all the test vectors", () => {
|
||||
const { "12": vec12, "15": vec15, "18": vec18, "21": vec21, "24": vec24 } = bip39Vectors.encoding;
|
||||
for (const vectors of [vec12, vec15, vec18, vec21, vec24]) {
|
||||
for (const { entropy, mnemonic } of vectors) {
|
||||
expect(mnemonicToEntropy(mnemonic)).toEqual(fromHex(entropy));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("Bip39", () => {
|
||||
describe("encode", () => {
|
||||
@ -414,3 +455,240 @@ describe("Bip39", () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe("EnglishMnemonic", () => {
|
||||
describe("wordlist", () => {
|
||||
it("matches the words from the bitcoin/bips/bip-0039 spec", () => {
|
||||
const lineFeed = 0x0a;
|
||||
const bip39EnglishTxt = fromBase64(wordlists.english);
|
||||
|
||||
// Ensure we loaded the correct english.txt from https://github.com/bitcoin/bips/tree/master/bip-0039
|
||||
const checksum = sha256(bip39EnglishTxt);
|
||||
expect(checksum).toEqual(fromHex("2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda"));
|
||||
|
||||
const wordsFromSpec: string[] = [];
|
||||
|
||||
let start = 0; // the start cursor marks the first byte of the word
|
||||
let end = 0; // the end cursor marks the line feed byte
|
||||
while (end < bip39EnglishTxt.length - 1) {
|
||||
end = start;
|
||||
while (bip39EnglishTxt[end] !== lineFeed) end++;
|
||||
const slice = bip39EnglishTxt.slice(start, end);
|
||||
wordsFromSpec.push(fromAscii(slice));
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
expect(EnglishMnemonic.wordlist).toEqual(wordsFromSpec);
|
||||
});
|
||||
});
|
||||
|
||||
it("works for valid inputs", () => {
|
||||
expect(() => {
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon address",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon admit",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("rejects invalid whitespacing", () => {
|
||||
// extra space (leading, middle, trailing)
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
" abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about ",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
|
||||
// newline, tab
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon\nabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon\tabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
});
|
||||
|
||||
it("rejects disallowed letters", () => {
|
||||
// Disallowed letters in words (capital, number, special char)
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"Abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon Abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"route66 abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon route66 abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"lötkolben abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon lötkolben abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
});
|
||||
|
||||
it("word counts other than 12, 15, 18, 21, 24", () => {
|
||||
// too few and too many words (11, 13, 17, 19, 23, 25)
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 11/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 13/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 17/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 19/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 23/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 25/i);
|
||||
});
|
||||
|
||||
it("rejects invalid checksums", () => {
|
||||
// 12x, 15x, 18x, 21x, 24x "zoo"
|
||||
expect(() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo")).toThrowError(
|
||||
/invalid mnemonic checksum/i,
|
||||
);
|
||||
expect(
|
||||
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
expect(
|
||||
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
});
|
||||
|
||||
it("rejects valid mnemonics of other languages", () => {
|
||||
// valid Spanish and Italian bip39 mnemonics
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"humo odio oriente colina taco fingir salto geranio glaciar academia suave vigor",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"yema folleto tos llave obtener natural fruta deseo laico sopa novato lazo imponer afinar vena hoja zarza cama",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"burla plaza arroz ronda pregunta vacuna veloz boina retiro exento prensa tortuga cabeza pilar anual molino molde fiesta masivo jefe leve fatiga clase plomo",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"braccio trincea armonia emiro svedese lepre stridulo metallo baldo rasente potassio rilassato",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"riparato arrosto globulo singolo bozzolo roba pirolisi ultimato padrone munto leggero avanzato monetario guanto lorenzo latino inoltrare modulo",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"promessa mercurio spessore snodo trave risata mecenate vichingo ceto orecchino vissuto risultato canino scarso futile fune epilogo uovo inedito apatico folata egoismo rifugio coma",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
});
|
||||
|
||||
describe("toString", () => {
|
||||
it("works", () => {
|
||||
const original =
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||
const mnemonic = new EnglishMnemonic(original);
|
||||
expect(mnemonic.toString()).toEqual(original);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,242 +0,0 @@
|
||||
import { fromAscii, fromBase64, fromHex } from "@cosmjs/encoding";
|
||||
|
||||
import { EnglishMnemonic } from "./englishmnemonic";
|
||||
import { sha256 } from "./sha";
|
||||
import wordlists from "./testdata/bip39_wordlists.json";
|
||||
|
||||
describe("EnglishMnemonic", () => {
|
||||
describe("wordlist", () => {
|
||||
it("matches the words from the bitcoin/bips/bip-0039 spec", () => {
|
||||
const lineFeed = 0x0a;
|
||||
const bip39EnglishTxt = fromBase64(wordlists.english);
|
||||
|
||||
// Ensure we loaded the correct english.txt from https://github.com/bitcoin/bips/tree/master/bip-0039
|
||||
const checksum = sha256(bip39EnglishTxt);
|
||||
expect(checksum).toEqual(fromHex("2f5eed53a4727b4bf8880d8f3f199efc90e58503646d9ff8eff3a2ed3b24dbda"));
|
||||
|
||||
const wordsFromSpec: string[] = [];
|
||||
|
||||
let start = 0; // the start cursor marks the first byte of the word
|
||||
let end = 0; // the end cursor marks the line feed byte
|
||||
while (end < bip39EnglishTxt.length - 1) {
|
||||
end = start;
|
||||
while (bip39EnglishTxt[end] !== lineFeed) end++;
|
||||
const slice = bip39EnglishTxt.slice(start, end);
|
||||
wordsFromSpec.push(fromAscii(slice));
|
||||
start = end + 1;
|
||||
}
|
||||
|
||||
expect(EnglishMnemonic.wordlist).toEqual(wordsFromSpec);
|
||||
});
|
||||
});
|
||||
|
||||
it("works for valid inputs", () => {
|
||||
expect(() => {
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon address",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon admit",
|
||||
);
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
);
|
||||
}).not.toThrow();
|
||||
});
|
||||
|
||||
it("rejects invalid whitespacing", () => {
|
||||
// extra space (leading, middle, trailing)
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
" abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about ",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
|
||||
// newline, tab
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon\nabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon\tabandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
});
|
||||
|
||||
it("rejects disallowed letters", () => {
|
||||
// Disallowed letters in words (capital, number, special char)
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"Abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon Abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"route66 abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon route66 abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"lötkolben abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon lötkolben abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic format/i);
|
||||
});
|
||||
|
||||
it("word counts other than 12, 15, 18, 21, 24", () => {
|
||||
// too few and too many words (11, 13, 17, 19, 23, 25)
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 11/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 13/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 17/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 19/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 23/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art",
|
||||
),
|
||||
).toThrowError(/invalid word count(.*)got: 25/i);
|
||||
});
|
||||
|
||||
it("rejects invalid checksums", () => {
|
||||
// 12x, 15x, 18x, 21x, 24x "zoo"
|
||||
expect(() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo")).toThrowError(
|
||||
/invalid mnemonic checksum/i,
|
||||
);
|
||||
expect(
|
||||
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
expect(
|
||||
() => new EnglishMnemonic("zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo"),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo",
|
||||
),
|
||||
).toThrowError(/invalid mnemonic checksum/i);
|
||||
});
|
||||
|
||||
it("rejects valid mnemonics of other languages", () => {
|
||||
// valid Spanish and Italian bip39 mnemonics
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"humo odio oriente colina taco fingir salto geranio glaciar academia suave vigor",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"yema folleto tos llave obtener natural fruta deseo laico sopa novato lazo imponer afinar vena hoja zarza cama",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"burla plaza arroz ronda pregunta vacuna veloz boina retiro exento prensa tortuga cabeza pilar anual molino molde fiesta masivo jefe leve fatiga clase plomo",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"braccio trincea armonia emiro svedese lepre stridulo metallo baldo rasente potassio rilassato",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"riparato arrosto globulo singolo bozzolo roba pirolisi ultimato padrone munto leggero avanzato monetario guanto lorenzo latino inoltrare modulo",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
expect(
|
||||
() =>
|
||||
new EnglishMnemonic(
|
||||
"promessa mercurio spessore snodo trave risata mecenate vichingo ceto orecchino vissuto risultato canino scarso futile fune epilogo uovo inedito apatico folata egoismo rifugio coma",
|
||||
),
|
||||
).toThrowError(/contains invalid word/i);
|
||||
});
|
||||
|
||||
describe("toString", () => {
|
||||
it("works", () => {
|
||||
const original =
|
||||
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
|
||||
const mnemonic = new EnglishMnemonic(original);
|
||||
expect(mnemonic.toString()).toEqual(original);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -1,39 +0,0 @@
|
||||
import * as bip39 from "bip39";
|
||||
|
||||
export class EnglishMnemonic {
|
||||
public static readonly wordlist: readonly string[] = bip39.wordlists.english;
|
||||
|
||||
// list of space separated lower case words (1 or more)
|
||||
private static readonly mnemonicMatcher = /^[a-z]+( [a-z]+)*$/;
|
||||
|
||||
private readonly data: string;
|
||||
|
||||
public constructor(mnemonic: string) {
|
||||
if (!EnglishMnemonic.mnemonicMatcher.test(mnemonic)) {
|
||||
throw new Error("Invalid mnemonic format");
|
||||
}
|
||||
|
||||
const words = mnemonic.split(" ");
|
||||
const allowedWordsLengths: readonly number[] = [12, 15, 18, 21, 24];
|
||||
if (allowedWordsLengths.indexOf(words.length) === -1) {
|
||||
throw new Error(
|
||||
`Invalid word count in mnemonic (allowed: ${allowedWordsLengths} got: ${words.length})`,
|
||||
);
|
||||
}
|
||||
|
||||
for (const word of words) {
|
||||
if (EnglishMnemonic.wordlist.indexOf(word) === -1) {
|
||||
throw new Error("Mnemonic contains invalid word");
|
||||
}
|
||||
}
|
||||
|
||||
// Throws with informative error message if mnemonic is not valid
|
||||
bip39.mnemonicToEntropy(mnemonic);
|
||||
|
||||
this.data = mnemonic;
|
||||
}
|
||||
|
||||
public toString(): string {
|
||||
return this.data;
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
export { Bip39 } from "./bip39";
|
||||
export { EnglishMnemonic } from "./englishmnemonic";
|
||||
export { Bip39, EnglishMnemonic } from "./bip39";
|
||||
export { HashFunction } from "./hash";
|
||||
export { Hmac } from "./hmac";
|
||||
export { Keccak256, keccak256 } from "./keccak";
|
||||
|
||||
183
packages/crypto/src/pbkdf2.spec.ts
Normal file
183
packages/crypto/src/pbkdf2.spec.ts
Normal file
@ -0,0 +1,183 @@
|
||||
import { fromHex, toAscii, toUtf8 } from "@cosmjs/encoding";
|
||||
|
||||
import {
|
||||
getCryptoModule,
|
||||
getSubtle,
|
||||
pbkdf2Sha512,
|
||||
pbkdf2Sha512Crypto,
|
||||
pbkdf2Sha512Noble,
|
||||
pbkdf2Sha512Subtle,
|
||||
} from "./pbkdf2";
|
||||
|
||||
interface TestVector {
|
||||
secret: Uint8Array;
|
||||
salt: Uint8Array;
|
||||
iterations: number;
|
||||
keylen: number;
|
||||
expected: Uint8Array;
|
||||
}
|
||||
|
||||
describe("pbkdf2", () => {
|
||||
// https://github.com/randombit/botan/blob/master/src/tests/data/pbkdf/pbkdf2.vec#L70-L74
|
||||
const botanTest: TestVector = {
|
||||
secret: toAscii("xyz"),
|
||||
salt: fromHex("0001020304050607"),
|
||||
iterations: 10000,
|
||||
keylen: 48,
|
||||
expected: fromHex(
|
||||
"DAF8A734327745EB63D19054DBD4018A682CEF11086A1BFB63FDBC16158C2F8B0742802F36AEF1B1DF92ACCBEA5D31A5",
|
||||
),
|
||||
};
|
||||
|
||||
// https://github.com/brycx/Test-Vector-Generation/blob/f88d152db/PBKDF2/pbkdf2-hmac-sha2-test-vectors.md
|
||||
const brycxTests: TestVector[] = [
|
||||
// Test Case 1
|
||||
{
|
||||
secret: toUtf8("password"),
|
||||
salt: toUtf8("salt"),
|
||||
iterations: 1,
|
||||
keylen: 20,
|
||||
expected: fromHex("867f70cf1ade02cff3752599a3a53dc4af34c7a6"),
|
||||
},
|
||||
// Test Case 2
|
||||
{
|
||||
secret: toUtf8("password"),
|
||||
salt: toUtf8("salt"),
|
||||
iterations: 2,
|
||||
keylen: 20,
|
||||
expected: fromHex("e1d9c16aa681708a45f5c7c4e215ceb66e011a2e"),
|
||||
},
|
||||
// Test Case 3
|
||||
{
|
||||
secret: toUtf8("password"),
|
||||
salt: toUtf8("salt"),
|
||||
iterations: 4096,
|
||||
keylen: 20,
|
||||
expected: fromHex("d197b1b33db0143e018b12f3d1d1479e6cdebdcc"),
|
||||
},
|
||||
// Test Case 4 (disabled by default because long running)
|
||||
// {
|
||||
// secret: toUtf8("password"),
|
||||
// salt: toUtf8("salt"),
|
||||
// iterations: 16777216,
|
||||
// keylen: 20,
|
||||
// expected: fromHex("6180a3ceabab45cc3964112c811e0131bca93a35"),
|
||||
// },
|
||||
// Test Case 5
|
||||
{
|
||||
secret: toUtf8("passwordPASSWORDpassword"),
|
||||
salt: toUtf8("saltSALTsaltSALTsaltSALTsaltSALTsalt"),
|
||||
iterations: 4096,
|
||||
keylen: 25,
|
||||
expected: fromHex("8c0511f4c6e597c6ac6315d8f0362e225f3c501495ba23b868"),
|
||||
},
|
||||
// Test Case 6
|
||||
{
|
||||
secret: toUtf8("pass\0word"),
|
||||
salt: toUtf8("sa\0lt"),
|
||||
iterations: 4096,
|
||||
keylen: 16,
|
||||
expected: fromHex("9d9e9c4cd21fe4be24d5b8244c759665"),
|
||||
},
|
||||
// Test Case 7
|
||||
{
|
||||
secret: toUtf8("passwd"),
|
||||
salt: toUtf8("salt"),
|
||||
iterations: 1,
|
||||
keylen: 128,
|
||||
expected: fromHex(
|
||||
"c74319d99499fc3e9013acff597c23c5baf0a0bec5634c46b8352b793e324723d55caa76b2b25c43402dcfdc06cdcf66f95b7d0429420b39520006749c51a04ef3eb99e576617395a178ba33214793e48045132928a9e9bf2661769fdc668f31798597aaf6da70dd996a81019726084d70f152baed8aafe2227c07636c6ddece",
|
||||
),
|
||||
},
|
||||
// Test Case 8
|
||||
{
|
||||
secret: toUtf8("Password"),
|
||||
salt: toUtf8("NaCl"),
|
||||
iterations: 80000,
|
||||
keylen: 128,
|
||||
expected: fromHex(
|
||||
"e6337d6fbeb645c794d4a9b5b75b7b30dac9ac50376a91df1f4460f6060d5addb2c1fd1f84409abacc67de7eb4056e6bb06c2d82c3ef4ccd1bded0f675ed97c65c33d39f81248454327aa6d03fd049fc5cbb2b5e6dac08e8ace996cdc960b1bd4530b7e754773d75f67a733fdb99baf6470e42ffcb753c15c352d4800fb6f9d6",
|
||||
),
|
||||
},
|
||||
// Test Case 9
|
||||
{
|
||||
secret: toUtf8("Password"),
|
||||
salt: toUtf8("sa\0lt"),
|
||||
iterations: 4096,
|
||||
keylen: 256,
|
||||
expected: fromHex(
|
||||
"10176fb32cb98cd7bb31e2bb5c8f6e425c103333a2e496058e3fd2bd88f657485c89ef92daa0668316bc23ebd1ef88f6dd14157b2320b5d54b5f26377c5dc279b1dcdec044bd6f91b166917c80e1e99ef861b1d2c7bce1b961178125fb86867f6db489a2eae0022e7bc9cf421f044319fac765d70cb89b45c214590e2ffb2c2b565ab3b9d07571fde0027b1dc57f8fd25afa842c1056dd459af4074d7510a0c020b914a5e202445d4d3f151070589dd6a2554fc506018c4f001df6239643dc86771286ae4910769d8385531bba57544d63c3640b90c98f1445ebdd129475e02086b600f0beb5b05cc6ca9b3633b452b7dad634e9336f56ec4c3ac0b4fe54ced8",
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
describe("pbkdf2Sha512", () => {
|
||||
it("works", async () => {
|
||||
{
|
||||
const { secret, salt, iterations, keylen, expected } = botanTest;
|
||||
const hash = await pbkdf2Sha512(secret, salt, iterations, keylen);
|
||||
expect(hash).toEqual(expected);
|
||||
}
|
||||
|
||||
for (const [index, test] of brycxTests.entries()) {
|
||||
const { secret, salt, iterations, keylen, expected } = test;
|
||||
const hash = await pbkdf2Sha512(secret, salt, iterations, keylen);
|
||||
expect(hash).withContext(`brycx tests index ${index}`).toEqual(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("pbkdf2Sha512Subtle", () => {
|
||||
it("works", async () => {
|
||||
const subtle = await getSubtle();
|
||||
if (!subtle) pending("Subtle is not available in this environment");
|
||||
|
||||
{
|
||||
const { secret, salt, iterations, keylen, expected } = botanTest;
|
||||
const hash = await pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
|
||||
expect(hash).toEqual(expected);
|
||||
}
|
||||
|
||||
for (const [index, test] of brycxTests.entries()) {
|
||||
const { secret, salt, iterations, keylen, expected } = test;
|
||||
const hash = await pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
|
||||
expect(hash).withContext(`brycx tests index ${index}`).toEqual(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("pbkdf2Sha512Crypto", () => {
|
||||
it("works", async () => {
|
||||
const crypto = await getCryptoModule();
|
||||
if (!crypto) pending("The crypto module is not available in this environment");
|
||||
|
||||
{
|
||||
const { secret, salt, iterations, keylen, expected } = botanTest;
|
||||
const hash = await pbkdf2Sha512Crypto(crypto, secret, salt, iterations, keylen);
|
||||
expect(hash).toEqual(expected);
|
||||
}
|
||||
|
||||
for (const [index, test] of brycxTests.entries()) {
|
||||
const { secret, salt, iterations, keylen, expected } = test;
|
||||
const hash = await pbkdf2Sha512Crypto(crypto, secret, salt, iterations, keylen);
|
||||
expect(hash).withContext(`brycx tests index ${index}`).toEqual(expected);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("pbkdf2Sha512Noble", () => {
|
||||
it("works", async () => {
|
||||
{
|
||||
const { secret, salt, iterations, keylen, expected } = botanTest;
|
||||
const hash = await pbkdf2Sha512Noble(secret, salt, iterations, keylen);
|
||||
expect(hash).toEqual(expected);
|
||||
}
|
||||
|
||||
for (const [index, test] of brycxTests.entries()) {
|
||||
const { secret, salt, iterations, keylen, expected } = test;
|
||||
const hash = await pbkdf2Sha512Noble(secret, salt, iterations, keylen);
|
||||
expect(hash).withContext(`brycx tests index ${index}`).toEqual(expected);
|
||||
}
|
||||
}, 120_000);
|
||||
});
|
||||
});
|
||||
119
packages/crypto/src/pbkdf2.ts
Normal file
119
packages/crypto/src/pbkdf2.ts
Normal file
@ -0,0 +1,119 @@
|
||||
import { assert } from "@cosmjs/utils";
|
||||
import { pbkdf2Async as noblePbkdf2Async } from "@noble/hashes/pbkdf2";
|
||||
import { sha512 as nobleSha512 } from "@noble/hashes/sha512";
|
||||
|
||||
/**
|
||||
* Returns the Node.js crypto module when available and `undefined`
|
||||
* otherwise.
|
||||
*
|
||||
* Detects an unimplemented fallback module from Webpack 5 and returns
|
||||
* `undefined` in that case.
|
||||
*/
|
||||
export async function getCryptoModule(): Promise<any | undefined> {
|
||||
try {
|
||||
const crypto = await import("crypto");
|
||||
// We get `Object{default: Object{}}` as a fallback when using
|
||||
// `crypto: false` in Webpack 5, which we interprete as unavailable.
|
||||
if (typeof crypto === "object" && Object.keys(crypto).length <= 1) {
|
||||
return undefined;
|
||||
}
|
||||
return crypto;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
export async function getSubtle(): Promise<any | undefined> {
|
||||
const g: any = globalThis;
|
||||
let subtle = g.crypto && g.crypto.subtle;
|
||||
if (!subtle) {
|
||||
const crypto = await getCryptoModule();
|
||||
if (crypto && crypto.webcrypto && crypto.webcrypto.subtle) {
|
||||
subtle = crypto.webcrypto.subtle;
|
||||
}
|
||||
}
|
||||
return subtle;
|
||||
}
|
||||
|
||||
export async function pbkdf2Sha512Subtle(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
subtle: any,
|
||||
secret: Uint8Array,
|
||||
salt: Uint8Array,
|
||||
iterations: number,
|
||||
keylen: number,
|
||||
): Promise<Uint8Array> {
|
||||
assert(subtle, "Argument subtle is falsy");
|
||||
assert(typeof subtle === "object", "Argument subtle is not of type object");
|
||||
assert(typeof subtle.importKey === "function", "subtle.importKey is not a function");
|
||||
assert(typeof subtle.deriveBits === "function", "subtle.deriveBits is not a function");
|
||||
|
||||
return subtle.importKey("raw", secret, { name: "PBKDF2" }, false, ["deriveBits"]).then((key: Uint8Array) =>
|
||||
subtle
|
||||
.deriveBits(
|
||||
{
|
||||
name: "PBKDF2",
|
||||
salt: salt,
|
||||
iterations: iterations,
|
||||
hash: { name: "SHA-512" },
|
||||
},
|
||||
key,
|
||||
keylen * 8,
|
||||
)
|
||||
.then((buffer: ArrayBuffer) => new Uint8Array(buffer)),
|
||||
);
|
||||
}
|
||||
|
||||
export async function pbkdf2Sha512Crypto(
|
||||
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
||||
crypto: any,
|
||||
secret: Uint8Array,
|
||||
salt: Uint8Array,
|
||||
iterations: number,
|
||||
keylen: number,
|
||||
): Promise<Uint8Array> {
|
||||
assert(crypto, "Argument crypto is falsy");
|
||||
assert(typeof crypto === "object", "Argument crypto is not of type object");
|
||||
assert(typeof crypto.pbkdf2 === "function", "crypto.pbkdf2 is not a function");
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
crypto.pbkdf2(secret, salt, iterations, keylen, "sha512", (error: any, result: any) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
} else {
|
||||
resolve(Uint8Array.from(result));
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
export async function pbkdf2Sha512Noble(
|
||||
secret: Uint8Array,
|
||||
salt: Uint8Array,
|
||||
iterations: number,
|
||||
keylen: number,
|
||||
): Promise<Uint8Array> {
|
||||
return noblePbkdf2Async(nobleSha512, secret, salt, { c: iterations, dkLen: keylen });
|
||||
}
|
||||
|
||||
/**
|
||||
* A pbkdf2 implementation for BIP39. This is not exported at package level and thus a private API.
|
||||
*/
|
||||
export async function pbkdf2Sha512(
|
||||
secret: Uint8Array,
|
||||
salt: Uint8Array,
|
||||
iterations: number,
|
||||
keylen: number,
|
||||
): Promise<Uint8Array> {
|
||||
const subtle = await getSubtle();
|
||||
if (subtle) {
|
||||
return pbkdf2Sha512Subtle(subtle, secret, salt, iterations, keylen);
|
||||
} else {
|
||||
const crypto = await getCryptoModule();
|
||||
if (crypto) {
|
||||
return pbkdf2Sha512Crypto(crypto, secret, salt, iterations, keylen);
|
||||
} else {
|
||||
return pbkdf2Sha512Noble(secret, salt, iterations, keylen);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,7 +26,7 @@ module.exports = [
|
||||
crypto: false,
|
||||
events: false,
|
||||
path: false,
|
||||
stream: require.resolve("stream-browserify"),
|
||||
stream: false,
|
||||
string_decoder: false,
|
||||
},
|
||||
},
|
||||
|
||||
@ -79,7 +79,6 @@
|
||||
"prettier": "^2.4.1",
|
||||
"ses": "^0.11.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"ts-node": "^8",
|
||||
"typedoc": "^0.22",
|
||||
"typescript": "~4.4",
|
||||
|
||||
@ -26,7 +26,7 @@ module.exports = [
|
||||
crypto: false,
|
||||
events: false,
|
||||
path: false,
|
||||
stream: require.resolve("stream-browserify"),
|
||||
stream: false,
|
||||
string_decoder: false,
|
||||
},
|
||||
},
|
||||
|
||||
@ -84,7 +84,6 @@
|
||||
"readonly-date": "^1.0.0",
|
||||
"ses": "^0.11.0",
|
||||
"source-map-support": "^0.5.19",
|
||||
"stream-browserify": "^3.0.0",
|
||||
"ts-node": "^8",
|
||||
"typedoc": "^0.22",
|
||||
"typescript": "~4.4",
|
||||
|
||||
@ -32,7 +32,7 @@ module.exports = [
|
||||
crypto: false,
|
||||
events: false,
|
||||
path: false,
|
||||
stream: require.resolve("stream-browserify"),
|
||||
stream: false,
|
||||
string_decoder: false,
|
||||
},
|
||||
},
|
||||
|
||||
118
yarn.lock
118
yarn.lock
@ -329,7 +329,6 @@ __metadata:
|
||||
prettier: ^2.4.1
|
||||
ses: ^0.11.0
|
||||
source-map-support: ^0.5.19
|
||||
stream-browserify: ^3.0.0
|
||||
ts-node: ^8
|
||||
typedoc: ^0.22
|
||||
typescript: ~4.4
|
||||
@ -435,7 +434,6 @@ __metadata:
|
||||
readonly-date: ^1.0.0
|
||||
ses: ^0.11.0
|
||||
source-map-support: ^0.5.19
|
||||
stream-browserify: ^3.0.0
|
||||
ts-node: ^8
|
||||
typedoc: ^0.22
|
||||
typescript: ~4.4
|
||||
@ -464,7 +462,6 @@ __metadata:
|
||||
"@types/node": ^15.0.1
|
||||
"@typescript-eslint/eslint-plugin": ^4.28
|
||||
"@typescript-eslint/parser": ^4.28
|
||||
bip39: ^3.0.2
|
||||
bn.js: ^5.2.0
|
||||
buffer: ^6.0.3
|
||||
elliptic: ^6.5.3
|
||||
@ -489,7 +486,6 @@ __metadata:
|
||||
prettier: ^2.4.1
|
||||
ses: ^0.11.0
|
||||
source-map-support: ^0.5.19
|
||||
stream-browserify: ^3.0.0
|
||||
ts-node: ^8
|
||||
typedoc: ^0.22
|
||||
typescript: ~4.4
|
||||
@ -799,7 +795,6 @@ __metadata:
|
||||
protobufjs: ~6.10.2
|
||||
ses: ^0.11.0
|
||||
source-map-support: ^0.5.19
|
||||
stream-browserify: ^3.0.0
|
||||
ts-node: ^8
|
||||
typedoc: ^0.22
|
||||
typescript: ~4.4
|
||||
@ -900,7 +895,6 @@ __metadata:
|
||||
readonly-date: ^1.0.0
|
||||
ses: ^0.11.0
|
||||
source-map-support: ^0.5.19
|
||||
stream-browserify: ^3.0.0
|
||||
ts-node: ^8
|
||||
typedoc: ^0.22
|
||||
typescript: ~4.4
|
||||
@ -1692,13 +1686,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:11.11.6":
|
||||
version: 11.11.6
|
||||
resolution: "@types/node@npm:11.11.6"
|
||||
checksum: 075f1c011cf568e49701419acbcb55c24906b3bb5a34d9412a3b88f228a7a78401a5ad4d3e1cd6855c99aaea5ef96e37fc86ca097e50f06da92cf822befc1fff
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:>=13.7.0":
|
||||
version: 15.9.0
|
||||
resolution: "@types/node@npm:15.9.0"
|
||||
@ -2401,18 +2388,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bip39@npm:^3.0.2":
|
||||
version: 3.0.4
|
||||
resolution: "bip39@npm:3.0.4"
|
||||
dependencies:
|
||||
"@types/node": 11.11.6
|
||||
create-hash: ^1.1.0
|
||||
pbkdf2: ^3.0.9
|
||||
randombytes: ^2.0.1
|
||||
checksum: 79ce1600a03d1ba5053bdd4e6323f9463ec340764c7e52918b6c6b9dca81221940f2d9a65656447f108f9bc2c8d9ae8df319cca83bbd1dad63f53ef2768d9bae
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"bl@npm:^4.0.3":
|
||||
version: 4.1.0
|
||||
resolution: "bl@npm:4.1.0"
|
||||
@ -2670,16 +2645,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cipher-base@npm:^1.0.1, cipher-base@npm:^1.0.3":
|
||||
version: 1.0.4
|
||||
resolution: "cipher-base@npm:1.0.4"
|
||||
dependencies:
|
||||
inherits: ^2.0.1
|
||||
safe-buffer: ^5.0.1
|
||||
checksum: 47d3568dbc17431a339bad1fe7dff83ac0891be8206911ace3d3b818fc695f376df809bea406e759cdea07fff4b454fa25f1013e648851bec790c1d75763032e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"clean-stack@npm:^2.0.0":
|
||||
version: 2.2.0
|
||||
resolution: "clean-stack@npm:2.2.0"
|
||||
@ -2948,33 +2913,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"create-hash@npm:^1.1.0, create-hash@npm:^1.1.2":
|
||||
version: 1.2.0
|
||||
resolution: "create-hash@npm:1.2.0"
|
||||
dependencies:
|
||||
cipher-base: ^1.0.1
|
||||
inherits: ^2.0.1
|
||||
md5.js: ^1.3.4
|
||||
ripemd160: ^2.0.1
|
||||
sha.js: ^2.4.0
|
||||
checksum: 02a6ae3bb9cd4afee3fabd846c1d8426a0e6b495560a977ba46120c473cb283be6aa1cace76b5f927cf4e499c6146fb798253e48e83d522feba807d6b722eaa9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"create-hmac@npm:^1.1.4":
|
||||
version: 1.1.7
|
||||
resolution: "create-hmac@npm:1.1.7"
|
||||
dependencies:
|
||||
cipher-base: ^1.0.3
|
||||
create-hash: ^1.1.0
|
||||
inherits: ^2.0.1
|
||||
ripemd160: ^2.0.0
|
||||
safe-buffer: ^5.0.1
|
||||
sha.js: ^2.4.8
|
||||
checksum: ba12bb2257b585a0396108c72830e85f882ab659c3320c83584b1037f8ab72415095167ced80dc4ce8e446a8ecc4b2acf36d87befe0707d73b26cf9dc77440ed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3":
|
||||
version: 7.0.3
|
||||
resolution: "cross-spawn@npm:7.0.3"
|
||||
@ -4394,7 +4332,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3, inherits@npm:~2.0.4":
|
||||
"inherits@npm:2, inherits@npm:2.0.4, inherits@npm:^2.0.1, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3":
|
||||
version: 2.0.4
|
||||
resolution: "inherits@npm:2.0.4"
|
||||
checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
|
||||
@ -5227,17 +5165,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"md5.js@npm:^1.3.4":
|
||||
version: 1.3.5
|
||||
resolution: "md5.js@npm:1.3.5"
|
||||
dependencies:
|
||||
hash-base: ^3.0.0
|
||||
inherits: ^2.0.1
|
||||
safe-buffer: ^5.1.2
|
||||
checksum: 098494d885684bcc4f92294b18ba61b7bd353c23147fbc4688c75b45cb8590f5a95fd4584d742415dcc52487f7a1ef6ea611cfa1543b0dc4492fe026357f3f0c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"media-typer@npm:0.3.0":
|
||||
version: 0.3.0
|
||||
resolution: "media-typer@npm:0.3.0"
|
||||
@ -5947,19 +5874,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pbkdf2@npm:^3.0.9":
|
||||
version: 3.1.2
|
||||
resolution: "pbkdf2@npm:3.1.2"
|
||||
dependencies:
|
||||
create-hash: ^1.1.2
|
||||
create-hmac: ^1.1.4
|
||||
ripemd160: ^2.0.1
|
||||
safe-buffer: ^5.0.1
|
||||
sha.js: ^2.4.8
|
||||
checksum: 2c950a100b1da72123449208e231afc188d980177d021d7121e96a2de7f2abbc96ead2b87d03d8fe5c318face097f203270d7e27908af9f471c165a4e8e69c92
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"picomatch@npm:^2.0.4, picomatch@npm:^2.2.1, picomatch@npm:^2.2.3":
|
||||
version: 2.2.3
|
||||
resolution: "picomatch@npm:2.2.3"
|
||||
@ -6210,7 +6124,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"randombytes@npm:^2.0.1, randombytes@npm:^2.1.0":
|
||||
"randombytes@npm:^2.1.0":
|
||||
version: 2.1.0
|
||||
resolution: "randombytes@npm:2.1.0"
|
||||
dependencies:
|
||||
@ -6300,7 +6214,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.5.0, readable-stream@npm:^3.6.0":
|
||||
"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0":
|
||||
version: 3.6.0
|
||||
resolution: "readable-stream@npm:3.6.0"
|
||||
dependencies:
|
||||
@ -6481,7 +6395,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ripemd160@npm:^2.0.0, ripemd160@npm:^2.0.1, ripemd160@npm:^2.0.2":
|
||||
"ripemd160@npm:^2.0.2":
|
||||
version: 2.0.2
|
||||
resolution: "ripemd160@npm:2.0.2"
|
||||
dependencies:
|
||||
@ -6516,7 +6430,7 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.1.2, safe-buffer@npm:^5.2.0, safe-buffer@npm:~5.2.0":
|
||||
"safe-buffer@npm:^5.0.1, safe-buffer@npm:^5.1.0, safe-buffer@npm:^5.2.0, safe-buffer@npm:~5.2.0":
|
||||
version: 5.2.1
|
||||
resolution: "safe-buffer@npm:5.2.1"
|
||||
checksum: b99c4b41fdd67a6aaf280fcd05e9ffb0813654894223afb78a31f14a19ad220bba8aba1cb14eddce1fcfb037155fe6de4e861784eb434f7d11ed58d1e70dd491
|
||||
@ -6611,18 +6525,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"sha.js@npm:^2.4.0, sha.js@npm:^2.4.8":
|
||||
version: 2.4.11
|
||||
resolution: "sha.js@npm:2.4.11"
|
||||
dependencies:
|
||||
inherits: ^2.0.1
|
||||
safe-buffer: ^5.0.1
|
||||
bin:
|
||||
sha.js: ./bin.js
|
||||
checksum: ebd3f59d4b799000699097dadb831c8e3da3eb579144fd7eb7a19484cbcbb7aca3c68ba2bb362242eb09e33217de3b4ea56e4678184c334323eca24a58e3ad07
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"shallow-clone@npm:^3.0.0":
|
||||
version: 3.0.1
|
||||
resolution: "shallow-clone@npm:3.0.1"
|
||||
@ -6882,16 +6784,6 @@ __metadata:
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"stream-browserify@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "stream-browserify@npm:3.0.0"
|
||||
dependencies:
|
||||
inherits: ~2.0.4
|
||||
readable-stream: ^3.5.0
|
||||
checksum: 4c47ef64d6f03815a9ca3874e2319805e8e8a85f3550776c47ce523b6f4c6cd57f40e46ec6a9ab8ad260fde61863c2718f250d3bedb3fe9052444eb9abfd9921
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"streamroller@npm:^3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "streamroller@npm:3.0.2"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user