@pezkuwi/util-crypto 14.0.1
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/README.md +17 -0
- package/package.json +45 -0
- package/src/address/addressToEvm.spec.ts +16 -0
- package/src/address/addressToEvm.ts +12 -0
- package/src/address/check.spec.ts +44 -0
- package/src/address/check.ts +34 -0
- package/src/address/checksum.spec.ts +45 -0
- package/src/address/checksum.ts +25 -0
- package/src/address/decode.spec.ts +138 -0
- package/src/address/decode.ts +41 -0
- package/src/address/defaults.ts +12 -0
- package/src/address/derive.spec.ts +26 -0
- package/src/address/derive.ts +36 -0
- package/src/address/encode.spec.ts +177 -0
- package/src/address/encode.ts +43 -0
- package/src/address/encodeDerived.spec.ts +14 -0
- package/src/address/encodeDerived.ts +19 -0
- package/src/address/encodeMulti.spec.ts +18 -0
- package/src/address/encodeMulti.ts +18 -0
- package/src/address/eq.spec.ts +45 -0
- package/src/address/eq.ts +24 -0
- package/src/address/evmToAddress.spec.ts +20 -0
- package/src/address/evmToAddress.ts +24 -0
- package/src/address/index.ts +21 -0
- package/src/address/is.spec.ts +113 -0
- package/src/address/is.ts +14 -0
- package/src/address/keyDerived.spec.ts +24 -0
- package/src/address/keyDerived.ts +22 -0
- package/src/address/keyMulti.spec.ts +20 -0
- package/src/address/keyMulti.ts +23 -0
- package/src/address/setSS58Format.spec.ts +21 -0
- package/src/address/setSS58Format.ts +20 -0
- package/src/address/sort.spec.ts +22 -0
- package/src/address/sort.ts +17 -0
- package/src/address/sshash.ts +12 -0
- package/src/address/types.ts +6 -0
- package/src/address/util.ts +8 -0
- package/src/address/validate.spec.ts +113 -0
- package/src/address/validate.ts +10 -0
- package/src/base32/bs32.ts +53 -0
- package/src/base32/decode.spec.ts +34 -0
- package/src/base32/encode.spec.ts +30 -0
- package/src/base32/helpers.ts +93 -0
- package/src/base32/index.ts +8 -0
- package/src/base32/is.spec.ts +32 -0
- package/src/base32/validate.spec.ts +44 -0
- package/src/base58/bs58.ts +43 -0
- package/src/base58/decode.spec.ts +31 -0
- package/src/base58/encode.spec.ts +26 -0
- package/src/base58/index.ts +8 -0
- package/src/base58/validate.spec.ts +20 -0
- package/src/base64/bs64.ts +43 -0
- package/src/base64/decode.spec.ts +42 -0
- package/src/base64/encode.spec.ts +14 -0
- package/src/base64/index.ts +10 -0
- package/src/base64/pad.spec.ts +14 -0
- package/src/base64/pad.ts +10 -0
- package/src/base64/trim.spec.ts +14 -0
- package/src/base64/trim.ts +14 -0
- package/src/base64/validate.spec.ts +32 -0
- package/src/blake2/asHex.spec.ts +57 -0
- package/src/blake2/asU8a.spec.ts +74 -0
- package/src/blake2/asU8a.ts +40 -0
- package/src/blake2/index.ts +8 -0
- package/src/bn.ts +15 -0
- package/src/bundle.ts +33 -0
- package/src/bundleInit.ts +11 -0
- package/src/crypto.spec.ts +18 -0
- package/src/crypto.ts +18 -0
- package/src/ed25519/deriveHard.ts +18 -0
- package/src/ed25519/index.ts +13 -0
- package/src/ed25519/pair/fromRandom.spec.ts +28 -0
- package/src/ed25519/pair/fromRandom.ts +25 -0
- package/src/ed25519/pair/fromSecret.spec.ts +33 -0
- package/src/ed25519/pair/fromSecret.ts +29 -0
- package/src/ed25519/pair/fromSeed.spec.ts +42 -0
- package/src/ed25519/pair/fromSeed.ts +41 -0
- package/src/ed25519/pair/fromString.spec.ts +17 -0
- package/src/ed25519/pair/fromString.ts +31 -0
- package/src/ed25519/sign.spec.ts +40 -0
- package/src/ed25519/sign.ts +38 -0
- package/src/ed25519/verify.spec.ts +84 -0
- package/src/ed25519/verify.ts +41 -0
- package/src/ethereum/encode.spec.ts +59 -0
- package/src/ethereum/encode.ts +39 -0
- package/src/ethereum/index.ts +6 -0
- package/src/ethereum/isAddress.spec.ts +34 -0
- package/src/ethereum/isAddress.ts +16 -0
- package/src/ethereum/isChecksum.ts +27 -0
- package/src/ethereum/isCheksum.spec.ts +30 -0
- package/src/hd/ethereum/index.spec.ts +54 -0
- package/src/hd/ethereum/index.ts +69 -0
- package/src/hd/index.ts +6 -0
- package/src/hd/ledger/derivePrivate.ts +34 -0
- package/src/hd/ledger/index.spec.ts +64 -0
- package/src/hd/ledger/index.ts +42 -0
- package/src/hd/ledger/master.spec.ts +19 -0
- package/src/hd/ledger/master.ts +26 -0
- package/src/hd/validatePath.spec.ts +30 -0
- package/src/hd/validatePath.ts +24 -0
- package/src/helpers.ts +38 -0
- package/src/hmac/index.ts +4 -0
- package/src/hmac/shaAsU8a.spec.ts +45 -0
- package/src/hmac/shaAsU8a.ts +48 -0
- package/src/index.ts +6 -0
- package/src/json/constants.ts +11 -0
- package/src/json/decrypt.ts +25 -0
- package/src/json/decryptData.ts +45 -0
- package/src/json/encrypt.ts +25 -0
- package/src/json/encryptFormat.ts +20 -0
- package/src/json/index.ts +7 -0
- package/src/json/types.ts +22 -0
- package/src/keccak/asHex.spec.ts +30 -0
- package/src/keccak/asU8a.spec.ts +56 -0
- package/src/keccak/asU8a.ts +45 -0
- package/src/keccak/index.ts +8 -0
- package/src/key/DeriveJunction.ts +79 -0
- package/src/key/extractPath.spec.ts +51 -0
- package/src/key/extractPath.ts +37 -0
- package/src/key/extractSuri.spec.ts +147 -0
- package/src/key/extractSuri.ts +40 -0
- package/src/key/fromPath.ts +28 -0
- package/src/key/hdkdDerive.ts +17 -0
- package/src/key/hdkdEcdsa.ts +8 -0
- package/src/key/hdkdEd25519.ts +7 -0
- package/src/key/hdkdSr25519.ts +14 -0
- package/src/key/index.ts +12 -0
- package/src/mnemonic/bip39.spec.ts +80 -0
- package/src/mnemonic/bip39.ts +127 -0
- package/src/mnemonic/generate.spec.ts +58 -0
- package/src/mnemonic/generate.ts +25 -0
- package/src/mnemonic/index.ts +11 -0
- package/src/mnemonic/toEntropy.spec.ts +36 -0
- package/src/mnemonic/toEntropy.ts +13 -0
- package/src/mnemonic/toLegacySeed.spec.ts +52 -0
- package/src/mnemonic/toLegacySeed.ts +39 -0
- package/src/mnemonic/toMiniSecret.spec.ts +67 -0
- package/src/mnemonic/toMiniSecret.ts +23 -0
- package/src/mnemonic/toMiniSecretCmp.spec.ts +64 -0
- package/src/mnemonic/validate.spec.ts +39 -0
- package/src/mnemonic/validate.ts +26 -0
- package/src/mnemonic/wordlists/en.ts +7 -0
- package/src/mnemonic/wordlists/es.ts +7 -0
- package/src/mnemonic/wordlists/fr.ts +7 -0
- package/src/mnemonic/wordlists/index.ts +11 -0
- package/src/mnemonic/wordlists/it.ts +7 -0
- package/src/mnemonic/wordlists/jp.ts +7 -0
- package/src/mnemonic/wordlists/ko.ts +7 -0
- package/src/mnemonic/wordlists/zh-s.ts +7 -0
- package/src/mnemonic/wordlists/zh-t.ts +7 -0
- package/src/mod.ts +4 -0
- package/src/nacl/decrypt.spec.ts +26 -0
- package/src/nacl/decrypt.ts +22 -0
- package/src/nacl/encrypt.spec.ts +20 -0
- package/src/nacl/encrypt.ts +31 -0
- package/src/nacl/index.ts +8 -0
- package/src/nacl/tweetnacl-secretbox-data.spec.ts +4629 -0
- package/src/nacl/tweetnacl-secretbox.spec.ts +161 -0
- package/src/nacl/tweetnacl.ts +1159 -0
- package/src/networks.ts +5 -0
- package/src/packageDetect.ts +14 -0
- package/src/packageInfo.ts +6 -0
- package/src/pbkdf2/encode.spec.ts +54 -0
- package/src/pbkdf2/encode.ts +29 -0
- package/src/pbkdf2/index.ts +4 -0
- package/src/random/asHex.spec.ts +38 -0
- package/src/random/asNumber.spec.ts +16 -0
- package/src/random/asNumber.ts +28 -0
- package/src/random/asU8a.spec.ts +36 -0
- package/src/random/asU8a.ts +30 -0
- package/src/random/index.ts +9 -0
- package/src/scrypt/defaults.ts +19 -0
- package/src/scrypt/encode.spec.ts +43 -0
- package/src/scrypt/encode.ts +30 -0
- package/src/scrypt/fromU8a.ts +44 -0
- package/src/scrypt/index.ts +6 -0
- package/src/scrypt/toU8a.ts +17 -0
- package/src/scrypt/types.ts +9 -0
- package/src/secp256k1/compress.spec.ts +47 -0
- package/src/secp256k1/compress.ts +21 -0
- package/src/secp256k1/deriveHard.ts +17 -0
- package/src/secp256k1/expand.spec.ts +47 -0
- package/src/secp256k1/expand.ts +30 -0
- package/src/secp256k1/hasher.spec.ts +24 -0
- package/src/secp256k1/hasher.ts +13 -0
- package/src/secp256k1/index.ts +10 -0
- package/src/secp256k1/pair/fromSeed.spec.ts +75 -0
- package/src/secp256k1/pair/fromSeed.ts +42 -0
- package/src/secp256k1/recover.spec.ts +35 -0
- package/src/secp256k1/recover.ts +36 -0
- package/src/secp256k1/sign.spec.ts +39 -0
- package/src/secp256k1/sign.ts +37 -0
- package/src/secp256k1/signVerify.spec.ts +94 -0
- package/src/secp256k1/tweakAdd.spec.ts +35 -0
- package/src/secp256k1/tweakAdd.ts +65 -0
- package/src/secp256k1/types.ts +4 -0
- package/src/secp256k1/verify.spec.ts +81 -0
- package/src/secp256k1/verify.ts +32 -0
- package/src/sha/asU8a.ts +30 -0
- package/src/sha/asU8a256.spec.ts +55 -0
- package/src/sha/asU8a512.spec.ts +33 -0
- package/src/sha/index.ts +8 -0
- package/src/signature/index.ts +8 -0
- package/src/signature/verify.spec.ts +230 -0
- package/src/signature/verify.ts +114 -0
- package/src/sr25519/agreement.spec.ts +31 -0
- package/src/sr25519/agreement.ts +23 -0
- package/src/sr25519/derive.ts +21 -0
- package/src/sr25519/deriveHard.ts +9 -0
- package/src/sr25519/derivePublic.ts +18 -0
- package/src/sr25519/deriveSoft.ts +9 -0
- package/src/sr25519/index.ts +12 -0
- package/src/sr25519/pair/fromSeed.spec.ts +35 -0
- package/src/sr25519/pair/fromSeed.ts +28 -0
- package/src/sr25519/pair/fromU8a.ts +23 -0
- package/src/sr25519/pair/testing.spec.ts +161 -0
- package/src/sr25519/pair/toU8a.ts +10 -0
- package/src/sr25519/sign.spec.ts +28 -0
- package/src/sr25519/sign.ts +22 -0
- package/src/sr25519/verify.spec.ts +42 -0
- package/src/sr25519/verify.ts +23 -0
- package/src/sr25519/vrfSign.ts +24 -0
- package/src/sr25519/vrfSignVerify.spec.ts +73 -0
- package/src/sr25519/vrfVerify.ts +25 -0
- package/src/test/index.ts +8 -0
- package/src/test/performance.ts +17 -0
- package/src/types.ts +33 -0
- package/src/xxhash/asHex.spec.ts +36 -0
- package/src/xxhash/asU8a.spec.ts +48 -0
- package/src/xxhash/asU8a.ts +45 -0
- package/src/xxhash/index.ts +8 -0
- package/src/xxhash/xxhash64.ts +155 -0
- package/tsconfig.build.json +18 -0
- package/tsconfig.spec.json +20 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { stringToU8a } from '@pezkuwi/util';
|
|
7
|
+
import { waitReady } from '@pezkuwi/wasm-crypto';
|
|
8
|
+
|
|
9
|
+
import { perfWasm } from '../test/index.js';
|
|
10
|
+
import { ed25519PairFromSeed, ed25519Sign } from './index.js';
|
|
11
|
+
|
|
12
|
+
const PAIR = ed25519PairFromSeed(
|
|
13
|
+
stringToU8a('12345678901234567890123456789012')
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
describe('ed25519Sign', (): void => {
|
|
17
|
+
beforeEach(async (): Promise<void> => {
|
|
18
|
+
await waitReady();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
for (const onlyJs of [false, true]) {
|
|
22
|
+
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
|
23
|
+
it('returns a valid signature for the message', (): void => {
|
|
24
|
+
expect(
|
|
25
|
+
ed25519Sign(
|
|
26
|
+
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
|
27
|
+
PAIR,
|
|
28
|
+
onlyJs
|
|
29
|
+
)
|
|
30
|
+
).toEqual(
|
|
31
|
+
new Uint8Array([28, 58, 206, 239, 249, 70, 59, 191, 166, 40, 219, 218, 235, 170, 25, 79, 10, 94, 9, 197, 34, 126, 1, 150, 246, 68, 28, 238, 36, 26, 172, 163, 168, 90, 202, 211, 126, 246, 57, 212, 43, 24, 88, 197, 240, 113, 118, 76, 37, 81, 91, 110, 236, 50, 144, 134, 100, 223, 220, 238, 34, 185, 211, 7])
|
|
32
|
+
);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
perfWasm('ed25519Sign', 250, (input, onlyJs) =>
|
|
38
|
+
ed25519Sign(input, PAIR, onlyJs)
|
|
39
|
+
);
|
|
40
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Keypair } from '../types.js';
|
|
5
|
+
|
|
6
|
+
import { ed25519 } from '@noble/curves/ed25519';
|
|
7
|
+
|
|
8
|
+
import { hasBigInt, u8aToU8a } from '@pezkuwi/util';
|
|
9
|
+
import { ed25519Sign as wasmSign, isReady } from '@pezkuwi/wasm-crypto';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @name ed25519Sign
|
|
13
|
+
* @summary Signs a message using the supplied secretKey
|
|
14
|
+
* @description
|
|
15
|
+
* Returns message signature of `message`, using the `secretKey`.
|
|
16
|
+
* @example
|
|
17
|
+
* <BR>
|
|
18
|
+
*
|
|
19
|
+
* ```javascript
|
|
20
|
+
* import { ed25519Sign } from '@pezkuwi/util-crypto';
|
|
21
|
+
*
|
|
22
|
+
* ed25519Sign([...], [...]); // => [...]
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export function ed25519Sign (message: string | Uint8Array, { publicKey, secretKey }: Partial<Keypair>, onlyJs?: boolean): Uint8Array {
|
|
26
|
+
if (!secretKey) {
|
|
27
|
+
throw new Error('Expected a valid secretKey');
|
|
28
|
+
} else if (!publicKey) {
|
|
29
|
+
throw new Error('Expected a valid publicKey');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const messageU8a = u8aToU8a(message);
|
|
33
|
+
const privateU8a = secretKey.subarray(0, 32);
|
|
34
|
+
|
|
35
|
+
return !hasBigInt || (!onlyJs && isReady())
|
|
36
|
+
? wasmSign(publicKey, privateU8a, messageU8a)
|
|
37
|
+
: ed25519.sign(messageU8a, privateU8a);
|
|
38
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { stringToU8a } from '@pezkuwi/util';
|
|
7
|
+
import { waitReady } from '@pezkuwi/wasm-crypto';
|
|
8
|
+
|
|
9
|
+
import { ed25519PairFromSeed, ed25519Verify } from './index.js';
|
|
10
|
+
|
|
11
|
+
describe('ed25519Verify', (): void => {
|
|
12
|
+
let publicKey: Uint8Array;
|
|
13
|
+
let signature: Uint8Array;
|
|
14
|
+
|
|
15
|
+
beforeEach(async (): Promise<void> => {
|
|
16
|
+
await waitReady();
|
|
17
|
+
|
|
18
|
+
publicKey = ed25519PairFromSeed(
|
|
19
|
+
stringToU8a('12345678901234567890123456789012')
|
|
20
|
+
).publicKey;
|
|
21
|
+
signature = new Uint8Array([28, 58, 206, 239, 249, 70, 59, 191, 166, 40, 219, 218, 235, 170, 25, 79, 10, 94, 9, 197, 34, 126, 1, 150, 246, 68, 28, 238, 36, 26, 172, 163, 168, 90, 202, 211, 126, 246, 57, 212, 43, 24, 88, 197, 240, 113, 118, 76, 37, 81, 91, 110, 236, 50, 144, 134, 100, 223, 220, 238, 34, 185, 211, 7]);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
for (const onlyJs of [false, true]) {
|
|
25
|
+
describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
|
|
26
|
+
it('validates a correctly signed message', (): void => {
|
|
27
|
+
expect(
|
|
28
|
+
ed25519Verify(
|
|
29
|
+
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
|
30
|
+
signature,
|
|
31
|
+
publicKey,
|
|
32
|
+
onlyJs
|
|
33
|
+
)
|
|
34
|
+
).toEqual(true);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('fails a correctly signed message (message changed)', (): void => {
|
|
38
|
+
expect(
|
|
39
|
+
ed25519Verify(
|
|
40
|
+
new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]),
|
|
41
|
+
signature,
|
|
42
|
+
publicKey,
|
|
43
|
+
onlyJs
|
|
44
|
+
)
|
|
45
|
+
).toEqual(false);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('fails a correctly signed message (signature changed)', (): void => {
|
|
49
|
+
signature[0] = 0xff;
|
|
50
|
+
|
|
51
|
+
expect(
|
|
52
|
+
ed25519Verify(
|
|
53
|
+
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
|
54
|
+
signature,
|
|
55
|
+
publicKey,
|
|
56
|
+
onlyJs
|
|
57
|
+
)
|
|
58
|
+
).toEqual(false);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it('throws error when publicKey lengths do not match', (): void => {
|
|
62
|
+
expect(
|
|
63
|
+
() => ed25519Verify(
|
|
64
|
+
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
|
65
|
+
signature,
|
|
66
|
+
new Uint8Array([1, 2]),
|
|
67
|
+
onlyJs
|
|
68
|
+
)
|
|
69
|
+
).toThrow(/Invalid publicKey/);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('throws error when signature lengths do not match', (): void => {
|
|
73
|
+
expect(
|
|
74
|
+
() => ed25519Verify(
|
|
75
|
+
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
|
76
|
+
new Uint8Array([1, 2]),
|
|
77
|
+
publicKey,
|
|
78
|
+
onlyJs
|
|
79
|
+
)
|
|
80
|
+
).toThrow(/Invalid signature/);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { ed25519 } from '@noble/curves/ed25519';
|
|
5
|
+
|
|
6
|
+
import { hasBigInt, u8aToU8a } from '@pezkuwi/util';
|
|
7
|
+
import { ed25519Verify as wasmVerify, isReady } from '@pezkuwi/wasm-crypto';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @name ed25519Sign
|
|
11
|
+
* @summary Verifies the signature on the supplied message.
|
|
12
|
+
* @description
|
|
13
|
+
* Verifies the `signature` on `message` with the supplied `publicKey`. Returns `true` on sucess, `false` otherwise.
|
|
14
|
+
* @example
|
|
15
|
+
* <BR>
|
|
16
|
+
*
|
|
17
|
+
* ```javascript
|
|
18
|
+
* import { ed25519Verify } from '@pezkuwi/util-crypto';
|
|
19
|
+
*
|
|
20
|
+
* ed25519Verify([...], [...], [...]); // => true/false
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function ed25519Verify (message: string | Uint8Array, signature: string | Uint8Array, publicKey: string | Uint8Array, onlyJs?: boolean): boolean {
|
|
24
|
+
const messageU8a = u8aToU8a(message);
|
|
25
|
+
const publicKeyU8a = u8aToU8a(publicKey);
|
|
26
|
+
const signatureU8a = u8aToU8a(signature);
|
|
27
|
+
|
|
28
|
+
if (publicKeyU8a.length !== 32) {
|
|
29
|
+
throw new Error(`Invalid publicKey, received ${publicKeyU8a.length}, expected 32`);
|
|
30
|
+
} else if (signatureU8a.length !== 64) {
|
|
31
|
+
throw new Error(`Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
try {
|
|
35
|
+
return !hasBigInt || (!onlyJs && isReady())
|
|
36
|
+
? wasmVerify(signatureU8a, messageU8a, publicKeyU8a)
|
|
37
|
+
: ed25519.verify(signatureU8a, messageU8a, publicKeyU8a);
|
|
38
|
+
} catch {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { keccakAsU8a } from '../keccak/index.js';
|
|
7
|
+
import { ethereumEncode } from './index.js';
|
|
8
|
+
|
|
9
|
+
describe('formatAddress', () => {
|
|
10
|
+
describe('address to address encoding', (): void => {
|
|
11
|
+
const ADDRESS = '0x00a329c0648769A73afAc7F9381E08FB43dBEA72';
|
|
12
|
+
|
|
13
|
+
it('returns 0x for no address', () => {
|
|
14
|
+
expect(ethereumEncode()).toBe('0x');
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('returns fails on invalid address', () => {
|
|
18
|
+
expect(
|
|
19
|
+
() => ethereumEncode('0xnotaddress')
|
|
20
|
+
).toThrow(/Invalid address or publicKey provided/);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('converts lowercase to the checksummed address', () => {
|
|
24
|
+
expect(ethereumEncode(ADDRESS.toLowerCase())).toBe(ADDRESS);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('converts uppercase to the checksummed address', () => {
|
|
28
|
+
expect(ethereumEncode(ADDRESS.toUpperCase().replace('0X', '0x'))).toBe(ADDRESS);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('returns formatted address on checksum input', () => {
|
|
32
|
+
expect(ethereumEncode(ADDRESS)).toBe(ADDRESS);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
describe('from publicKey', (): void => {
|
|
37
|
+
const ADDRESS = '0x4119b2e6c3Cb618F4f0B93ac77f9BeeC7FF02887';
|
|
38
|
+
|
|
39
|
+
it('encodes a compressed publicKey', (): void => {
|
|
40
|
+
expect(
|
|
41
|
+
ethereumEncode('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077')
|
|
42
|
+
).toEqual(ADDRESS);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('encodes an expanded publicKey', (): void => {
|
|
46
|
+
expect(
|
|
47
|
+
ethereumEncode('0x04b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af')
|
|
48
|
+
).toEqual(ADDRESS);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('encodes a pre-hashed key', (): void => {
|
|
52
|
+
expect(
|
|
53
|
+
ethereumEncode(
|
|
54
|
+
keccakAsU8a('0xb9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af')
|
|
55
|
+
)
|
|
56
|
+
).toEqual(ADDRESS);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { HexString } from '@pezkuwi/util/types';
|
|
5
|
+
|
|
6
|
+
import { u8aToHex, u8aToU8a } from '@pezkuwi/util';
|
|
7
|
+
|
|
8
|
+
import { keccakAsU8a } from '../keccak/index.js';
|
|
9
|
+
import { secp256k1Expand } from '../secp256k1/index.js';
|
|
10
|
+
|
|
11
|
+
function getH160 (u8a: Uint8Array): Uint8Array {
|
|
12
|
+
if ([33, 65].includes(u8a.length)) {
|
|
13
|
+
u8a = keccakAsU8a(secp256k1Expand(u8a));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return u8a.slice(-20);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function ethereumEncode (addressOrPublic?: string | Uint8Array): HexString {
|
|
20
|
+
if (!addressOrPublic) {
|
|
21
|
+
return '0x';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const u8aAddress = u8aToU8a(addressOrPublic);
|
|
25
|
+
|
|
26
|
+
if (![20, 32, 33, 65].includes(u8aAddress.length)) {
|
|
27
|
+
throw new Error(`Invalid address or publicKey provided, received ${u8aAddress.length} bytes input`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const address = u8aToHex(getH160(u8aAddress), -1, false);
|
|
31
|
+
const hash = u8aToHex(keccakAsU8a(address), -1, false);
|
|
32
|
+
let result = '';
|
|
33
|
+
|
|
34
|
+
for (let i = 0; i < 40; i++) {
|
|
35
|
+
result = `${result}${parseInt(hash[i], 16) > 7 ? address[i].toUpperCase() : address[i]}`;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return `0x${result}`;
|
|
39
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { isEthereumAddress } from './index.js';
|
|
7
|
+
|
|
8
|
+
const ADDRESS = '0x00a329c0648769A73afAc7F9381E08FB43dBEA72';
|
|
9
|
+
|
|
10
|
+
describe('isEthereumAddress', () => {
|
|
11
|
+
it('returns true when fully lowercase', () => {
|
|
12
|
+
expect(isEthereumAddress(ADDRESS.toLowerCase())).toBe(true);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns true when fully uppercase', () => {
|
|
16
|
+
expect(isEthereumAddress(ADDRESS.toUpperCase().replace('0X', '0x'))).toBe(true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('returns true when checksummed', () => {
|
|
20
|
+
expect(isEthereumAddress(ADDRESS)).toBe(true);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('returns false when empty address', () => {
|
|
24
|
+
expect(isEthereumAddress()).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('returns false when invalid address', () => {
|
|
28
|
+
expect(isEthereumAddress('0xinvalid')).toBe(false);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('returns false when invalid address of correct length', () => {
|
|
32
|
+
expect(isEthereumAddress('0xinvalid000123456789012345678901234567890')).toBe(false);
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { isHex } from '@pezkuwi/util';
|
|
5
|
+
|
|
6
|
+
import { isEthereumChecksum } from './isChecksum.js';
|
|
7
|
+
|
|
8
|
+
export function isEthereumAddress (address?: string): boolean {
|
|
9
|
+
if (!address || address.length !== 42 || !isHex(address)) {
|
|
10
|
+
return false;
|
|
11
|
+
} else if (/^(0x)?[0-9a-f]{40}$/.test(address) || /^(0x)?[0-9A-F]{40}$/.test(address)) {
|
|
12
|
+
return true;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return isEthereumChecksum(address);
|
|
16
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { u8aToHex } from '@pezkuwi/util';
|
|
5
|
+
|
|
6
|
+
import { keccakAsU8a } from '../keccak/index.js';
|
|
7
|
+
|
|
8
|
+
function isInvalidChar (char: string, byte: number): boolean {
|
|
9
|
+
return char !== (
|
|
10
|
+
byte > 7
|
|
11
|
+
? char.toUpperCase()
|
|
12
|
+
: char.toLowerCase()
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function isEthereumChecksum (_address: string): boolean {
|
|
17
|
+
const address = _address.replace('0x', '');
|
|
18
|
+
const hash = u8aToHex(keccakAsU8a(address.toLowerCase()), -1, false);
|
|
19
|
+
|
|
20
|
+
for (let i = 0; i < 40; i++) {
|
|
21
|
+
if (isInvalidChar(address[i], parseInt(hash[i], 16))) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { isEthereumChecksum } from './index.js';
|
|
7
|
+
|
|
8
|
+
const ADDRESS = '0x00a329c0648769A73afAc7F9381E08FB43dBEA72';
|
|
9
|
+
|
|
10
|
+
describe('isEthereumChecksum', () => {
|
|
11
|
+
it('returns false on invalid address', () => {
|
|
12
|
+
expect(isEthereumChecksum('0x00a329c0648769')).toBe(false);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
it('returns false on non-checksum address', () => {
|
|
16
|
+
expect(isEthereumChecksum('0x1234567890abcdeedcba1234567890abcdeedcba')).toBe(false);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('returns false when fully lowercase', () => {
|
|
20
|
+
expect(isEthereumChecksum(ADDRESS.toLowerCase())).toBe(false);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
it('returns false when fully uppercase', () => {
|
|
24
|
+
expect(isEthereumChecksum(ADDRESS.toUpperCase().replace('0X', '0x'))).toBe(false);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('returns true on a checksummed address', () => {
|
|
28
|
+
expect(isEthereumChecksum(ADDRESS)).toBe(true);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { mnemonicToLegacySeed } from '@pezkuwi/util-crypto';
|
|
7
|
+
|
|
8
|
+
import { hdEthereum } from './index.js';
|
|
9
|
+
|
|
10
|
+
describe('hdEthereum', (): void => {
|
|
11
|
+
const PHRASE = 'seed sock milk update focus rotate barely fade car face mechanic mercy';
|
|
12
|
+
const derivationPath = 'm/44\'/60\'/0\'/0/0';
|
|
13
|
+
const PUBLIC = new Uint8Array([
|
|
14
|
+
3, 118, 64, 77, 247, 27, 4, 157,
|
|
15
|
+
236, 206, 251, 221, 230, 244, 154, 147,
|
|
16
|
+
189, 131, 249, 169, 102, 78, 3, 185,
|
|
17
|
+
153, 19, 89, 40, 24, 25, 139, 131,
|
|
18
|
+
93
|
|
19
|
+
]);
|
|
20
|
+
const SECRET = new Uint8Array([
|
|
21
|
+
166, 162, 203, 17, 2, 206, 110, 176,
|
|
22
|
+
18, 102, 230, 144, 90, 158, 25, 232,
|
|
23
|
+
43, 180, 176, 49, 189, 149, 3, 71,
|
|
24
|
+
243, 228, 223, 104, 125, 132, 58, 228
|
|
25
|
+
]
|
|
26
|
+
);
|
|
27
|
+
const PUBLICDERIVED = new Uint8Array([
|
|
28
|
+
3, 129, 53, 27, 27, 70, 210, 96,
|
|
29
|
+
43, 9, 146, 187, 93, 85, 49, 249,
|
|
30
|
+
193, 105, 107, 8, 18, 254, 178, 83,
|
|
31
|
+
75, 104, 132, 173, 196, 126, 46, 29,
|
|
32
|
+
139
|
|
33
|
+
]);
|
|
34
|
+
const SECRETDERIVED = new Uint8Array([
|
|
35
|
+
7, 13, 195, 17, 115, 0, 1, 25,
|
|
36
|
+
24, 226, 107, 2, 23, 105, 69, 204,
|
|
37
|
+
21, 195, 213, 72, 207, 73, 253, 132,
|
|
38
|
+
24, 217, 127, 147, 175, 105, 158, 70
|
|
39
|
+
]);
|
|
40
|
+
|
|
41
|
+
it('derives the right key pair from a mnemonic', (): void => {
|
|
42
|
+
const key = hdEthereum(mnemonicToLegacySeed(PHRASE, '', false, 64));
|
|
43
|
+
|
|
44
|
+
expect(key.publicKey).toEqual(PUBLIC);
|
|
45
|
+
expect(key.secretKey).toEqual(SECRET);
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('derives the right key pair from a mnemonic and a derivation path', (): void => {
|
|
49
|
+
const key = hdEthereum(mnemonicToLegacySeed(PHRASE, '', false, 64), derivationPath);
|
|
50
|
+
|
|
51
|
+
expect(key.publicKey).toEqual(PUBLICDERIVED);
|
|
52
|
+
expect(key.secretKey).toEqual(SECRETDERIVED);
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import type { Keypair } from '../../types.js';
|
|
5
|
+
|
|
6
|
+
import { bnToU8a, stringToU8a, u8aConcat } from '@pezkuwi/util';
|
|
7
|
+
|
|
8
|
+
import { BN_BE_32_OPTS } from '../../bn.js';
|
|
9
|
+
import { hmacShaAsU8a } from '../../hmac/index.js';
|
|
10
|
+
import { secp256k1PairFromSeed, secp256k1PrivateKeyTweakAdd } from '../../secp256k1/index.js';
|
|
11
|
+
import { HARDENED, hdValidatePath } from '../validatePath.js';
|
|
12
|
+
|
|
13
|
+
interface CodedKeypair extends Keypair {
|
|
14
|
+
chainCode: Uint8Array;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const MASTER_SECRET = stringToU8a('Bitcoin seed');
|
|
18
|
+
|
|
19
|
+
function createCoded (secretKey: Uint8Array, chainCode: Uint8Array): CodedKeypair {
|
|
20
|
+
return {
|
|
21
|
+
chainCode,
|
|
22
|
+
publicKey: secp256k1PairFromSeed(secretKey).publicKey,
|
|
23
|
+
secretKey
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function deriveChild (hd: CodedKeypair, index: number): CodedKeypair {
|
|
28
|
+
const indexBuffer = bnToU8a(index, BN_BE_32_OPTS);
|
|
29
|
+
const data = index >= HARDENED
|
|
30
|
+
? u8aConcat(new Uint8Array(1), hd.secretKey, indexBuffer)
|
|
31
|
+
: u8aConcat(hd.publicKey, indexBuffer);
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
const I = hmacShaAsU8a(hd.chainCode, data, 512);
|
|
35
|
+
|
|
36
|
+
return createCoded(
|
|
37
|
+
secp256k1PrivateKeyTweakAdd(hd.secretKey, I.slice(0, 32)),
|
|
38
|
+
I.slice(32)
|
|
39
|
+
);
|
|
40
|
+
} catch {
|
|
41
|
+
// In case parse256(IL) >= n or ki == 0, proceed with the next value for i
|
|
42
|
+
return deriveChild(hd, index + 1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function hdEthereum (seed: Uint8Array, path = ''): Keypair {
|
|
47
|
+
const I = hmacShaAsU8a(MASTER_SECRET, seed, 512);
|
|
48
|
+
let hd = createCoded(I.slice(0, 32), I.slice(32));
|
|
49
|
+
|
|
50
|
+
if (!path || path === 'm' || path === 'M' || path === "m'" || path === "M'") {
|
|
51
|
+
return hd;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (!hdValidatePath(path)) {
|
|
55
|
+
throw new Error('Invalid derivation path');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const parts = path.split('/').slice(1);
|
|
59
|
+
|
|
60
|
+
for (const p of parts) {
|
|
61
|
+
hd = deriveChild(hd, parseInt(p, 10) + (
|
|
62
|
+
(p.length > 1) && p.endsWith("'")
|
|
63
|
+
? HARDENED
|
|
64
|
+
: 0
|
|
65
|
+
));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return hd;
|
|
69
|
+
}
|
package/src/hd/index.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { BN_EIGHT, bnToU8a, u8aConcat, u8aToBn } from '@pezkuwi/util';
|
|
5
|
+
|
|
6
|
+
import { BN_LE_32_OPTS, BN_LE_512_OPTS, BN_LE_OPTS } from '../../bn.js';
|
|
7
|
+
import { hmacShaAsU8a } from '../../hmac/index.js';
|
|
8
|
+
|
|
9
|
+
// performs hard-only derivation on the xprv
|
|
10
|
+
export function ledgerDerivePrivate (xprv: Uint8Array, index: number): Uint8Array {
|
|
11
|
+
const kl = xprv.subarray(0, 32);
|
|
12
|
+
const kr = xprv.subarray(32, 64);
|
|
13
|
+
const cc = xprv.subarray(64, 96);
|
|
14
|
+
const data = u8aConcat([0], kl, kr, bnToU8a(index, BN_LE_32_OPTS));
|
|
15
|
+
const z = hmacShaAsU8a(cc, data, 512);
|
|
16
|
+
|
|
17
|
+
data[0] = 0x01;
|
|
18
|
+
|
|
19
|
+
return u8aConcat(
|
|
20
|
+
bnToU8a(
|
|
21
|
+
u8aToBn(kl, BN_LE_OPTS).iadd(
|
|
22
|
+
u8aToBn(z.subarray(0, 28), BN_LE_OPTS).imul(BN_EIGHT)
|
|
23
|
+
),
|
|
24
|
+
BN_LE_512_OPTS
|
|
25
|
+
).subarray(0, 32),
|
|
26
|
+
bnToU8a(
|
|
27
|
+
u8aToBn(kr, BN_LE_OPTS).iadd(
|
|
28
|
+
u8aToBn(z.subarray(32, 64), BN_LE_OPTS)
|
|
29
|
+
),
|
|
30
|
+
BN_LE_512_OPTS
|
|
31
|
+
).subarray(0, 32),
|
|
32
|
+
hmacShaAsU8a(cc, data, 512).subarray(32, 64)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Copyright 2017-2025 @polkadot/util-crypto authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
/// <reference types="@polkadot/dev-test/globals.d.ts" />
|
|
5
|
+
|
|
6
|
+
import { u8aToHex } from '@pezkuwi/util';
|
|
7
|
+
|
|
8
|
+
import { hdLedger } from '../index.js';
|
|
9
|
+
|
|
10
|
+
const MNE_0 = 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about';
|
|
11
|
+
const MNE_1 = 'open jelly jeans corn ketchup supreme brief element armed lens vault weather original scissors rug priority vicious lesson raven spot gossip powder person volcano';
|
|
12
|
+
const MNE_P = `${MNE_1} testing`;
|
|
13
|
+
|
|
14
|
+
const TESTS = {
|
|
15
|
+
Kusama: {
|
|
16
|
+
slip44: 0x01b2,
|
|
17
|
+
tests: [
|
|
18
|
+
{
|
|
19
|
+
ed25519: '0x98cb4e14e0e08ea876f88d728545ea7572dc07dbbe69f1731c418fb827e69d41',
|
|
20
|
+
index: [0, 0],
|
|
21
|
+
mnemonic: MNE_0
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
ed25519: '0x70e9010e84c81095aaa5f63b1c5a6a66a1dcbec017a23c2f3b7a1b08fe5ea65a',
|
|
25
|
+
index: [0, 0],
|
|
26
|
+
mnemonic: MNE_1
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
ed25519: '0xf06730efb1e6ea59ac752a7c3620fade3909062fb88597856cc3af72045fa65a',
|
|
30
|
+
index: [5, 7],
|
|
31
|
+
mnemonic: MNE_1
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
Polkadot: {
|
|
36
|
+
slip44: 0x0162,
|
|
37
|
+
tests: [
|
|
38
|
+
{
|
|
39
|
+
ed25519: '0xe8c68348586d53e4e8d1a864b0e4e17c75e4eb06e0c63c1432bef2ba29e69d41',
|
|
40
|
+
index: [0, 0],
|
|
41
|
+
mnemonic: MNE_0
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
ed25519: '0x3890e8db837eba3f8f25215c753e1091062298ce671a51441e7ef89a7adc4f48',
|
|
45
|
+
index: [0, 0],
|
|
46
|
+
mnemonic: MNE_P
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
describe('ledgerDerive', (): void => {
|
|
53
|
+
Object.entries(TESTS).forEach(([network, { slip44, tests }]): void => {
|
|
54
|
+
tests.forEach(({ ed25519, index: [account, address], mnemonic }, index): void => {
|
|
55
|
+
it(`derives a known ed25519 seed for ${network} (${index})`, (): void => {
|
|
56
|
+
expect(u8aToHex(
|
|
57
|
+
hdLedger(mnemonic, `m/44'/${slip44}'/${account}'/0'/${address}'`)
|
|
58
|
+
.secretKey
|
|
59
|
+
.slice(0, 32)
|
|
60
|
+
)).toEqual(ed25519);
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
});
|