@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.
Files changed (234) hide show
  1. package/README.md +17 -0
  2. package/package.json +45 -0
  3. package/src/address/addressToEvm.spec.ts +16 -0
  4. package/src/address/addressToEvm.ts +12 -0
  5. package/src/address/check.spec.ts +44 -0
  6. package/src/address/check.ts +34 -0
  7. package/src/address/checksum.spec.ts +45 -0
  8. package/src/address/checksum.ts +25 -0
  9. package/src/address/decode.spec.ts +138 -0
  10. package/src/address/decode.ts +41 -0
  11. package/src/address/defaults.ts +12 -0
  12. package/src/address/derive.spec.ts +26 -0
  13. package/src/address/derive.ts +36 -0
  14. package/src/address/encode.spec.ts +177 -0
  15. package/src/address/encode.ts +43 -0
  16. package/src/address/encodeDerived.spec.ts +14 -0
  17. package/src/address/encodeDerived.ts +19 -0
  18. package/src/address/encodeMulti.spec.ts +18 -0
  19. package/src/address/encodeMulti.ts +18 -0
  20. package/src/address/eq.spec.ts +45 -0
  21. package/src/address/eq.ts +24 -0
  22. package/src/address/evmToAddress.spec.ts +20 -0
  23. package/src/address/evmToAddress.ts +24 -0
  24. package/src/address/index.ts +21 -0
  25. package/src/address/is.spec.ts +113 -0
  26. package/src/address/is.ts +14 -0
  27. package/src/address/keyDerived.spec.ts +24 -0
  28. package/src/address/keyDerived.ts +22 -0
  29. package/src/address/keyMulti.spec.ts +20 -0
  30. package/src/address/keyMulti.ts +23 -0
  31. package/src/address/setSS58Format.spec.ts +21 -0
  32. package/src/address/setSS58Format.ts +20 -0
  33. package/src/address/sort.spec.ts +22 -0
  34. package/src/address/sort.ts +17 -0
  35. package/src/address/sshash.ts +12 -0
  36. package/src/address/types.ts +6 -0
  37. package/src/address/util.ts +8 -0
  38. package/src/address/validate.spec.ts +113 -0
  39. package/src/address/validate.ts +10 -0
  40. package/src/base32/bs32.ts +53 -0
  41. package/src/base32/decode.spec.ts +34 -0
  42. package/src/base32/encode.spec.ts +30 -0
  43. package/src/base32/helpers.ts +93 -0
  44. package/src/base32/index.ts +8 -0
  45. package/src/base32/is.spec.ts +32 -0
  46. package/src/base32/validate.spec.ts +44 -0
  47. package/src/base58/bs58.ts +43 -0
  48. package/src/base58/decode.spec.ts +31 -0
  49. package/src/base58/encode.spec.ts +26 -0
  50. package/src/base58/index.ts +8 -0
  51. package/src/base58/validate.spec.ts +20 -0
  52. package/src/base64/bs64.ts +43 -0
  53. package/src/base64/decode.spec.ts +42 -0
  54. package/src/base64/encode.spec.ts +14 -0
  55. package/src/base64/index.ts +10 -0
  56. package/src/base64/pad.spec.ts +14 -0
  57. package/src/base64/pad.ts +10 -0
  58. package/src/base64/trim.spec.ts +14 -0
  59. package/src/base64/trim.ts +14 -0
  60. package/src/base64/validate.spec.ts +32 -0
  61. package/src/blake2/asHex.spec.ts +57 -0
  62. package/src/blake2/asU8a.spec.ts +74 -0
  63. package/src/blake2/asU8a.ts +40 -0
  64. package/src/blake2/index.ts +8 -0
  65. package/src/bn.ts +15 -0
  66. package/src/bundle.ts +33 -0
  67. package/src/bundleInit.ts +11 -0
  68. package/src/crypto.spec.ts +18 -0
  69. package/src/crypto.ts +18 -0
  70. package/src/ed25519/deriveHard.ts +18 -0
  71. package/src/ed25519/index.ts +13 -0
  72. package/src/ed25519/pair/fromRandom.spec.ts +28 -0
  73. package/src/ed25519/pair/fromRandom.ts +25 -0
  74. package/src/ed25519/pair/fromSecret.spec.ts +33 -0
  75. package/src/ed25519/pair/fromSecret.ts +29 -0
  76. package/src/ed25519/pair/fromSeed.spec.ts +42 -0
  77. package/src/ed25519/pair/fromSeed.ts +41 -0
  78. package/src/ed25519/pair/fromString.spec.ts +17 -0
  79. package/src/ed25519/pair/fromString.ts +31 -0
  80. package/src/ed25519/sign.spec.ts +40 -0
  81. package/src/ed25519/sign.ts +38 -0
  82. package/src/ed25519/verify.spec.ts +84 -0
  83. package/src/ed25519/verify.ts +41 -0
  84. package/src/ethereum/encode.spec.ts +59 -0
  85. package/src/ethereum/encode.ts +39 -0
  86. package/src/ethereum/index.ts +6 -0
  87. package/src/ethereum/isAddress.spec.ts +34 -0
  88. package/src/ethereum/isAddress.ts +16 -0
  89. package/src/ethereum/isChecksum.ts +27 -0
  90. package/src/ethereum/isCheksum.spec.ts +30 -0
  91. package/src/hd/ethereum/index.spec.ts +54 -0
  92. package/src/hd/ethereum/index.ts +69 -0
  93. package/src/hd/index.ts +6 -0
  94. package/src/hd/ledger/derivePrivate.ts +34 -0
  95. package/src/hd/ledger/index.spec.ts +64 -0
  96. package/src/hd/ledger/index.ts +42 -0
  97. package/src/hd/ledger/master.spec.ts +19 -0
  98. package/src/hd/ledger/master.ts +26 -0
  99. package/src/hd/validatePath.spec.ts +30 -0
  100. package/src/hd/validatePath.ts +24 -0
  101. package/src/helpers.ts +38 -0
  102. package/src/hmac/index.ts +4 -0
  103. package/src/hmac/shaAsU8a.spec.ts +45 -0
  104. package/src/hmac/shaAsU8a.ts +48 -0
  105. package/src/index.ts +6 -0
  106. package/src/json/constants.ts +11 -0
  107. package/src/json/decrypt.ts +25 -0
  108. package/src/json/decryptData.ts +45 -0
  109. package/src/json/encrypt.ts +25 -0
  110. package/src/json/encryptFormat.ts +20 -0
  111. package/src/json/index.ts +7 -0
  112. package/src/json/types.ts +22 -0
  113. package/src/keccak/asHex.spec.ts +30 -0
  114. package/src/keccak/asU8a.spec.ts +56 -0
  115. package/src/keccak/asU8a.ts +45 -0
  116. package/src/keccak/index.ts +8 -0
  117. package/src/key/DeriveJunction.ts +79 -0
  118. package/src/key/extractPath.spec.ts +51 -0
  119. package/src/key/extractPath.ts +37 -0
  120. package/src/key/extractSuri.spec.ts +147 -0
  121. package/src/key/extractSuri.ts +40 -0
  122. package/src/key/fromPath.ts +28 -0
  123. package/src/key/hdkdDerive.ts +17 -0
  124. package/src/key/hdkdEcdsa.ts +8 -0
  125. package/src/key/hdkdEd25519.ts +7 -0
  126. package/src/key/hdkdSr25519.ts +14 -0
  127. package/src/key/index.ts +12 -0
  128. package/src/mnemonic/bip39.spec.ts +80 -0
  129. package/src/mnemonic/bip39.ts +127 -0
  130. package/src/mnemonic/generate.spec.ts +58 -0
  131. package/src/mnemonic/generate.ts +25 -0
  132. package/src/mnemonic/index.ts +11 -0
  133. package/src/mnemonic/toEntropy.spec.ts +36 -0
  134. package/src/mnemonic/toEntropy.ts +13 -0
  135. package/src/mnemonic/toLegacySeed.spec.ts +52 -0
  136. package/src/mnemonic/toLegacySeed.ts +39 -0
  137. package/src/mnemonic/toMiniSecret.spec.ts +67 -0
  138. package/src/mnemonic/toMiniSecret.ts +23 -0
  139. package/src/mnemonic/toMiniSecretCmp.spec.ts +64 -0
  140. package/src/mnemonic/validate.spec.ts +39 -0
  141. package/src/mnemonic/validate.ts +26 -0
  142. package/src/mnemonic/wordlists/en.ts +7 -0
  143. package/src/mnemonic/wordlists/es.ts +7 -0
  144. package/src/mnemonic/wordlists/fr.ts +7 -0
  145. package/src/mnemonic/wordlists/index.ts +11 -0
  146. package/src/mnemonic/wordlists/it.ts +7 -0
  147. package/src/mnemonic/wordlists/jp.ts +7 -0
  148. package/src/mnemonic/wordlists/ko.ts +7 -0
  149. package/src/mnemonic/wordlists/zh-s.ts +7 -0
  150. package/src/mnemonic/wordlists/zh-t.ts +7 -0
  151. package/src/mod.ts +4 -0
  152. package/src/nacl/decrypt.spec.ts +26 -0
  153. package/src/nacl/decrypt.ts +22 -0
  154. package/src/nacl/encrypt.spec.ts +20 -0
  155. package/src/nacl/encrypt.ts +31 -0
  156. package/src/nacl/index.ts +8 -0
  157. package/src/nacl/tweetnacl-secretbox-data.spec.ts +4629 -0
  158. package/src/nacl/tweetnacl-secretbox.spec.ts +161 -0
  159. package/src/nacl/tweetnacl.ts +1159 -0
  160. package/src/networks.ts +5 -0
  161. package/src/packageDetect.ts +14 -0
  162. package/src/packageInfo.ts +6 -0
  163. package/src/pbkdf2/encode.spec.ts +54 -0
  164. package/src/pbkdf2/encode.ts +29 -0
  165. package/src/pbkdf2/index.ts +4 -0
  166. package/src/random/asHex.spec.ts +38 -0
  167. package/src/random/asNumber.spec.ts +16 -0
  168. package/src/random/asNumber.ts +28 -0
  169. package/src/random/asU8a.spec.ts +36 -0
  170. package/src/random/asU8a.ts +30 -0
  171. package/src/random/index.ts +9 -0
  172. package/src/scrypt/defaults.ts +19 -0
  173. package/src/scrypt/encode.spec.ts +43 -0
  174. package/src/scrypt/encode.ts +30 -0
  175. package/src/scrypt/fromU8a.ts +44 -0
  176. package/src/scrypt/index.ts +6 -0
  177. package/src/scrypt/toU8a.ts +17 -0
  178. package/src/scrypt/types.ts +9 -0
  179. package/src/secp256k1/compress.spec.ts +47 -0
  180. package/src/secp256k1/compress.ts +21 -0
  181. package/src/secp256k1/deriveHard.ts +17 -0
  182. package/src/secp256k1/expand.spec.ts +47 -0
  183. package/src/secp256k1/expand.ts +30 -0
  184. package/src/secp256k1/hasher.spec.ts +24 -0
  185. package/src/secp256k1/hasher.ts +13 -0
  186. package/src/secp256k1/index.ts +10 -0
  187. package/src/secp256k1/pair/fromSeed.spec.ts +75 -0
  188. package/src/secp256k1/pair/fromSeed.ts +42 -0
  189. package/src/secp256k1/recover.spec.ts +35 -0
  190. package/src/secp256k1/recover.ts +36 -0
  191. package/src/secp256k1/sign.spec.ts +39 -0
  192. package/src/secp256k1/sign.ts +37 -0
  193. package/src/secp256k1/signVerify.spec.ts +94 -0
  194. package/src/secp256k1/tweakAdd.spec.ts +35 -0
  195. package/src/secp256k1/tweakAdd.ts +65 -0
  196. package/src/secp256k1/types.ts +4 -0
  197. package/src/secp256k1/verify.spec.ts +81 -0
  198. package/src/secp256k1/verify.ts +32 -0
  199. package/src/sha/asU8a.ts +30 -0
  200. package/src/sha/asU8a256.spec.ts +55 -0
  201. package/src/sha/asU8a512.spec.ts +33 -0
  202. package/src/sha/index.ts +8 -0
  203. package/src/signature/index.ts +8 -0
  204. package/src/signature/verify.spec.ts +230 -0
  205. package/src/signature/verify.ts +114 -0
  206. package/src/sr25519/agreement.spec.ts +31 -0
  207. package/src/sr25519/agreement.ts +23 -0
  208. package/src/sr25519/derive.ts +21 -0
  209. package/src/sr25519/deriveHard.ts +9 -0
  210. package/src/sr25519/derivePublic.ts +18 -0
  211. package/src/sr25519/deriveSoft.ts +9 -0
  212. package/src/sr25519/index.ts +12 -0
  213. package/src/sr25519/pair/fromSeed.spec.ts +35 -0
  214. package/src/sr25519/pair/fromSeed.ts +28 -0
  215. package/src/sr25519/pair/fromU8a.ts +23 -0
  216. package/src/sr25519/pair/testing.spec.ts +161 -0
  217. package/src/sr25519/pair/toU8a.ts +10 -0
  218. package/src/sr25519/sign.spec.ts +28 -0
  219. package/src/sr25519/sign.ts +22 -0
  220. package/src/sr25519/verify.spec.ts +42 -0
  221. package/src/sr25519/verify.ts +23 -0
  222. package/src/sr25519/vrfSign.ts +24 -0
  223. package/src/sr25519/vrfSignVerify.spec.ts +73 -0
  224. package/src/sr25519/vrfVerify.ts +25 -0
  225. package/src/test/index.ts +8 -0
  226. package/src/test/performance.ts +17 -0
  227. package/src/types.ts +33 -0
  228. package/src/xxhash/asHex.spec.ts +36 -0
  229. package/src/xxhash/asU8a.spec.ts +48 -0
  230. package/src/xxhash/asU8a.ts +45 -0
  231. package/src/xxhash/index.ts +8 -0
  232. package/src/xxhash/xxhash64.ts +155 -0
  233. package/tsconfig.build.json +18 -0
  234. package/tsconfig.spec.json +20 -0
@@ -0,0 +1,5 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Don't use a export * since we don't want to duplicate packageInfo
5
+ export { allNetworks, availableNetworks, selectableNetworks } from '@pezkuwi/networks';
@@ -0,0 +1,14 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Do not edit, auto-generated by @polkadot/dev
5
+ // (packageInfo imports will be kept as-is, user-editable)
6
+
7
+ import { packageInfo as netInfo } from '@pezkuwi/networks/packageInfo';
8
+ import { detectPackage } from '@pezkuwi/util';
9
+ import { packageInfo as utilInfo } from '@pezkuwi/util/packageInfo';
10
+ import { packageInfo as randomInfo } from '@pezkuwi/x-randomvalues';
11
+
12
+ import { packageInfo } from './packageInfo.js';
13
+
14
+ detectPackage(packageInfo, null, [netInfo, randomInfo, utilInfo]);
@@ -0,0 +1,6 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Do not edit, auto-generated by @polkadot/dev
5
+
6
+ export const packageInfo = { name: '@polkadot/util-crypto', path: 'auto', type: 'auto', version: '14.0.1' };
@@ -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 { u8aEq, u8aToHex } from '@pezkuwi/util';
7
+ import { waitReady } from '@pezkuwi/wasm-crypto';
8
+
9
+ import { randomAsU8a } from '../random/asU8a.js';
10
+ import { perfWasm } from '../test/index.js';
11
+ import { pbkdf2Encode } from './index.js';
12
+
13
+ const KNOWN_SALT = new Uint8Array([
14
+ 1, 2, 3, 4, 5, 6, 7, 8,
15
+ 9, 10, 11, 12, 13, 14, 15, 16,
16
+ 17, 18, 19, 20, 21, 22, 23, 24,
17
+ 25, 26, 27, 28, 29, 30, 31, 32
18
+ ]);
19
+ const TEST_PASSWORD = 'test password';
20
+
21
+ describe('pbkdf2Encode', (): void => {
22
+ beforeEach(async (): Promise<void> => {
23
+ await waitReady();
24
+ });
25
+
26
+ for (const rounds of [256, 1024, 2048] as const) {
27
+ it(`has equivalent Wasm & JS results (${rounds} rounds)`, (): void => {
28
+ const salt = randomAsU8a();
29
+
30
+ expect(
31
+ u8aEq(
32
+ pbkdf2Encode(TEST_PASSWORD, salt, rounds, false).password,
33
+ pbkdf2Encode(TEST_PASSWORD, salt, rounds, true).password
34
+ )
35
+ ).toBe(true);
36
+ });
37
+ }
38
+
39
+ for (const onlyJs of [false, true]) {
40
+ describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
41
+ it('creates known iterations', (): void => {
42
+ expect(
43
+ u8aToHex(pbkdf2Encode(TEST_PASSWORD, KNOWN_SALT, 2048, onlyJs).password)
44
+ ).toEqual(
45
+ '0x600ba9ad65e4294d112e028fdad5dd8fce0a6a6e6b89fb36ed006785ccc3b3aec46831b3105c24237293e6cfa1a0ef6717c113f87ff9237a3f73d210adfa6634'
46
+ );
47
+ });
48
+ });
49
+ }
50
+
51
+ perfWasm('pbkdf2Encode', 8, (input, onlyJs) =>
52
+ pbkdf2Encode(input, input, undefined, onlyJs)
53
+ );
54
+ });
@@ -0,0 +1,29 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { pbkdf2 as pbkdf2Js } from '@noble/hashes/pbkdf2';
5
+ import { sha512 } from '@noble/hashes/sha512';
6
+
7
+ import { hasBigInt, u8aToU8a } from '@pezkuwi/util';
8
+ import { isReady, pbkdf2 } from '@pezkuwi/wasm-crypto';
9
+
10
+ import { randomAsU8a } from '../random/asU8a.js';
11
+
12
+ interface Result {
13
+ password: Uint8Array;
14
+ rounds: number;
15
+ salt: Uint8Array;
16
+ }
17
+
18
+ export function pbkdf2Encode (passphrase?: string | Uint8Array, salt: Uint8Array = randomAsU8a(), rounds = 2048, onlyJs?: boolean): Result {
19
+ const u8aPass = u8aToU8a(passphrase);
20
+ const u8aSalt = u8aToU8a(salt);
21
+
22
+ return {
23
+ password: !hasBigInt || (!onlyJs && isReady())
24
+ ? pbkdf2(u8aPass, u8aSalt, rounds)
25
+ : pbkdf2Js(sha512, u8aPass, u8aSalt, { c: rounds, dkLen: 64 }),
26
+ rounds,
27
+ salt
28
+ };
29
+ }
@@ -0,0 +1,4 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { pbkdf2Encode } from './encode.js';
@@ -0,0 +1,38 @@
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 { isHex } from '@pezkuwi/util';
7
+
8
+ import { randomAsHex } from './index.js';
9
+
10
+ describe('randomAsBuffer', (): void => {
11
+ it('generated results does not match', (): void => {
12
+ expect(
13
+ randomAsHex()
14
+ ).not.toEqual(
15
+ randomAsHex()
16
+ );
17
+ });
18
+
19
+ it('is a valid hex number', (): void => {
20
+ expect(
21
+ isHex(
22
+ randomAsHex()
23
+ )
24
+ ).toEqual(true);
25
+ });
26
+
27
+ it('generates 32 bytes by default', (): void => {
28
+ expect(
29
+ randomAsHex()
30
+ ).toHaveLength(32 * 2 + 2);
31
+ });
32
+
33
+ it('generates with the supplied length', (): void => {
34
+ expect(
35
+ randomAsHex(66)
36
+ ).toHaveLength(66 * 2 + 2);
37
+ });
38
+ });
@@ -0,0 +1,16 @@
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 { randomAsNumber } from './index.js';
7
+
8
+ describe('randomAsNumber', (): void => {
9
+ it('generates subsequent non-matching numbers', (): void => {
10
+ expect(
11
+ randomAsNumber()
12
+ ).not.toEqual(
13
+ randomAsNumber()
14
+ );
15
+ });
16
+ });
@@ -0,0 +1,28 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { BN, hexToBn } from '@pezkuwi/util';
5
+
6
+ import { randomAsHex } from './asU8a.js';
7
+
8
+ const BN_53 = new BN(0b11111111111111111111111111111111111111111111111111111);
9
+
10
+ /**
11
+ * @name randomAsNumber
12
+ * @summary Creates a random number from random bytes.
13
+ * @description
14
+ * Returns a random number generated from the secure bytes.
15
+ * @example
16
+ * <BR>
17
+ *
18
+ * ```javascript
19
+ * import { randomAsNumber } from '@pezkuwi/util-crypto';
20
+ *
21
+ * randomAsNumber(); // => <random number>
22
+ * ```
23
+ */
24
+ export function randomAsNumber (): number {
25
+ return hexToBn(
26
+ randomAsHex(8)
27
+ ).and(BN_53).toNumber();
28
+ }
@@ -0,0 +1,36 @@
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 { isU8a } from '@pezkuwi/util';
7
+
8
+ import { randomAsU8a } from './index.js';
9
+
10
+ describe('randomAsU8a', (): void => {
11
+ it('generates a Uint8Array', (): void => {
12
+ expect(
13
+ isU8a(randomAsU8a())
14
+ ).toEqual(true);
15
+ });
16
+
17
+ it('generated results does not match', (): void => {
18
+ expect(
19
+ randomAsU8a()
20
+ ).not.toEqual(
21
+ randomAsU8a()
22
+ );
23
+ });
24
+
25
+ it('generates 32 bytes by default', (): void => {
26
+ expect(
27
+ randomAsU8a()
28
+ ).toHaveLength(32);
29
+ });
30
+
31
+ it('generates with the suuplied length', (): void => {
32
+ expect(
33
+ randomAsU8a(66)
34
+ ).toHaveLength(66);
35
+ });
36
+ });
@@ -0,0 +1,30 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { getRandomValues } from '@pezkuwi/x-randomvalues';
5
+
6
+ import { createAsHex } from '../helpers.js';
7
+
8
+ /**
9
+ * @name randomAsU8a
10
+ * @summary Creates a Uint8Array filled with random bytes.
11
+ * @description
12
+ * Returns a `Uint8Array` with the specified (optional) length filled with random bytes.
13
+ * @example
14
+ * <BR>
15
+ *
16
+ * ```javascript
17
+ * import { randomAsU8a } from '@pezkuwi/util-crypto';
18
+ *
19
+ * randomAsU8a(); // => Uint8Array([...])
20
+ * ```
21
+ */
22
+ export function randomAsU8a (length = 32): Uint8Array {
23
+ return getRandomValues(new Uint8Array(length));
24
+ }
25
+
26
+ /**
27
+ * @name randomAsHex
28
+ * @description Creates a hex string filled with random bytes.
29
+ */
30
+ export const randomAsHex = /*#__PURE__*/ createAsHex(randomAsU8a);
@@ -0,0 +1,9 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /**
5
+ * @summary Returns a sequence of secure random bytes in a variety of formats
6
+ */
7
+
8
+ export { randomAsNumber } from './asNumber.js';
9
+ export { randomAsHex, randomAsU8a } from './asU8a.js';
@@ -0,0 +1,19 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { ScryptParams } from './types.js';
5
+
6
+ export const ALLOWED_PARAMS: ScryptParams[] = [
7
+ { N: 1 << 13, p: 10, r: 8 },
8
+ { N: 1 << 14, p: 5, r: 8 },
9
+ { N: 1 << 15, p: 3, r: 8 },
10
+ { N: 1 << 15, p: 1, r: 8 },
11
+ { N: 1 << 16, p: 2, r: 8 },
12
+ { N: 1 << 17, p: 1, r: 8 }
13
+ ];
14
+
15
+ export const DEFAULT_PARAMS: ScryptParams = {
16
+ N: 1 << 17,
17
+ p: 1,
18
+ r: 8
19
+ };
@@ -0,0 +1,43 @@
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 { waitReady } from '@pezkuwi/wasm-crypto';
7
+
8
+ import { perfWasm } from '../test/index.js';
9
+ import { DEFAULT_PARAMS } from './defaults.js';
10
+ import { scryptEncode } from './index.js';
11
+
12
+ // eslint-disable-next-line jest/no-export
13
+ export const KNOWN_TEST = 'testing, 123';
14
+
15
+ // eslint-disable-next-line jest/no-export
16
+ export const KNOWN_PASS = new Uint8Array([225, 18, 85, 30, 46, 178, 200, 63, 147, 225, 37, 46, 88, 224, 151, 132, 48, 206, 104, 234, 120, 112, 243, 198, 92, 52, 101, 127, 242, 22, 116, 55, 74, 29, 17, 197, 38, 191, 128, 39, 255, 119, 175, 113, 180, 252, 171, 10, 78, 93, 226, 7, 166, 120, 99, 198, 225, 158, 107, 132, 226, 73, 129, 35]);
17
+
18
+ // eslint-disable-next-line jest/no-export
19
+ export const KNOWN_SALT = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]);
20
+
21
+ describe('scryptEncode', (): void => {
22
+ beforeEach(async (): Promise<void> => {
23
+ await waitReady();
24
+ });
25
+
26
+ for (const onlyJs of [false, true]) {
27
+ describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
28
+ it('generates a known output', (): void => {
29
+ expect(
30
+ scryptEncode(KNOWN_TEST, KNOWN_SALT, undefined, onlyJs)
31
+ ).toEqual({
32
+ params: DEFAULT_PARAMS,
33
+ password: KNOWN_PASS,
34
+ salt: KNOWN_SALT
35
+ });
36
+ });
37
+ });
38
+ }
39
+
40
+ perfWasm('scryptEncode', 4, (input, onlyJs) =>
41
+ scryptEncode(input, input, undefined, onlyJs)
42
+ );
43
+ });
@@ -0,0 +1,30 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { ScryptParams } from './types.js';
5
+
6
+ import { scrypt as scryptJs } from '@noble/hashes/scrypt';
7
+
8
+ import { hasBigInt, objectSpread, u8aToU8a } from '@pezkuwi/util';
9
+ import { isReady, scrypt } from '@pezkuwi/wasm-crypto';
10
+
11
+ import { randomAsU8a } from '../random/asU8a.js';
12
+ import { DEFAULT_PARAMS } from './defaults.js';
13
+
14
+ interface Result {
15
+ params: ScryptParams,
16
+ password: Uint8Array;
17
+ salt: Uint8Array;
18
+ }
19
+
20
+ export function scryptEncode (passphrase?: string | Uint8Array, salt = randomAsU8a(), params = DEFAULT_PARAMS, onlyJs?: boolean): Result {
21
+ const u8a = u8aToU8a(passphrase);
22
+
23
+ return {
24
+ params,
25
+ password: !hasBigInt || (!onlyJs && isReady())
26
+ ? scrypt(u8a, salt, Math.log2(params.N), params.r, params.p)
27
+ : scryptJs(u8a, salt, objectSpread({ dkLen: 64 }, params)),
28
+ salt
29
+ };
30
+ }
@@ -0,0 +1,44 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { ScryptParams } from './types.js';
5
+
6
+ import { u8aToBn } from '@pezkuwi/util';
7
+
8
+ import { BN_LE_OPTS } from '../bn.js';
9
+ import { ALLOWED_PARAMS } from './defaults.js';
10
+
11
+ interface Result {
12
+ params: ScryptParams,
13
+ salt: Uint8Array;
14
+ }
15
+
16
+ export function scryptFromU8a (data: Uint8Array): Result {
17
+ if (!(data instanceof Uint8Array)) {
18
+ throw new Error('Expected input to be a Uint8Array');
19
+ }
20
+
21
+ // Ensure the input is exactly 44 bytes: 32 for salt + 3 * 4 for N, p, r
22
+ if (data.length < 32 + 12) {
23
+ throw new Error(`Invalid input length: expected 44 bytes, found ${data.length}`);
24
+ }
25
+
26
+ const salt = data.subarray(0, 32);
27
+ const N = u8aToBn(data.subarray(32, 36), BN_LE_OPTS).toNumber();
28
+ const p = u8aToBn(data.subarray(36, 40), BN_LE_OPTS).toNumber();
29
+ const r = u8aToBn(data.subarray(40, 44), BN_LE_OPTS).toNumber();
30
+
31
+ if (N > (1 << 20) || p > 4 || r > 16) {
32
+ throw new Error('Scrypt parameters exceed safe limits');
33
+ }
34
+
35
+ const isAllowed = ALLOWED_PARAMS.some((preset) =>
36
+ preset.N === N && preset.p === p && preset.r === r
37
+ );
38
+
39
+ if (!isAllowed) {
40
+ throw new Error('Invalid injected scrypt params found');
41
+ }
42
+
43
+ return { params: { N, p, r }, salt };
44
+ }
@@ -0,0 +1,6 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ export { scryptEncode } from './encode.js';
5
+ export { scryptFromU8a } from './fromU8a.js';
6
+ export { scryptToU8a } from './toU8a.js';
@@ -0,0 +1,17 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { ScryptParams } from './types.js';
5
+
6
+ import { bnToU8a, u8aConcat } from '@pezkuwi/util';
7
+
8
+ import { BN_LE_32_OPTS } from '../bn.js';
9
+
10
+ export function scryptToU8a (salt: Uint8Array, { N, p, r }: ScryptParams): Uint8Array {
11
+ return u8aConcat(
12
+ salt,
13
+ bnToU8a(N, BN_LE_32_OPTS),
14
+ bnToU8a(p, BN_LE_32_OPTS),
15
+ bnToU8a(r, BN_LE_32_OPTS)
16
+ );
17
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ /** The params that control scrypt generation */
5
+ export interface ScryptParams {
6
+ N: number;
7
+ p: number;
8
+ r: number;
9
+ }
@@ -0,0 +1,47 @@
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 { hexToU8a } from '@pezkuwi/util';
7
+ import { waitReady } from '@pezkuwi/wasm-crypto';
8
+
9
+ import { perfWasm } from '../test/index.js';
10
+ import { secp256k1Compress } from './index.js';
11
+
12
+ describe('secp256k1Compress', (): void => {
13
+ beforeEach(async (): Promise<void> => {
14
+ await waitReady();
15
+ });
16
+
17
+ for (const onlyJs of [false, true]) {
18
+ describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
19
+ it('returns a compressed key as-is', (): void => {
20
+ expect(
21
+ secp256k1Compress(
22
+ hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077'),
23
+ onlyJs
24
+ )
25
+ ).toEqual(
26
+ hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077')
27
+ );
28
+ });
29
+
30
+ it('compresses a known key', (): void => {
31
+ expect(
32
+ secp256k1Compress(
33
+ hexToU8a('0x04b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af'),
34
+ onlyJs
35
+ )
36
+ ).toEqual(
37
+ hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077')
38
+ );
39
+ });
40
+ });
41
+ }
42
+
43
+ perfWasm('secp256k1Compress', 100000, (input, onlyJs) => secp256k1Compress(input, onlyJs), [[
44
+ hexToU8a('0x04b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af')
45
+ ]]
46
+ );
47
+ });
@@ -0,0 +1,21 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { secp256k1 } from '@noble/curves/secp256k1';
5
+
6
+ import { hasBigInt } from '@pezkuwi/util';
7
+ import { isReady, secp256k1Compress as wasm } from '@pezkuwi/wasm-crypto';
8
+
9
+ export function secp256k1Compress (publicKey: Uint8Array, onlyJs?: boolean): Uint8Array {
10
+ if (![33, 65].includes(publicKey.length)) {
11
+ throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`);
12
+ }
13
+
14
+ if (publicKey.length === 33) {
15
+ return publicKey;
16
+ }
17
+
18
+ return !hasBigInt || (!onlyJs && isReady())
19
+ ? wasm(publicKey)
20
+ : secp256k1.ProjectivePoint.fromHex(publicKey).toRawBytes(true);
21
+ }
@@ -0,0 +1,17 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { compactAddLength, isU8a, stringToU8a, u8aConcat } from '@pezkuwi/util';
5
+
6
+ import { blake2AsU8a } from '../blake2/asU8a.js';
7
+
8
+ const HDKD = compactAddLength(stringToU8a('Secp256k1HDKD'));
9
+
10
+ export function secp256k1DeriveHard (seed: Uint8Array, chainCode: Uint8Array): Uint8Array {
11
+ if (!isU8a(chainCode) || chainCode.length !== 32) {
12
+ throw new Error('Invalid chainCode passed to derive');
13
+ }
14
+
15
+ // NOTE This is specific to the Substrate HDD derivation, so always use the blake2 hasher
16
+ return blake2AsU8a(u8aConcat(HDKD, seed, chainCode), 256);
17
+ }
@@ -0,0 +1,47 @@
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 { hexToU8a } from '@pezkuwi/util';
7
+ import { waitReady } from '@pezkuwi/wasm-crypto';
8
+
9
+ import { perfWasm } from '../test/index.js';
10
+ import { secp256k1Expand } from './index.js';
11
+
12
+ describe('secp256k1Expand', (): void => {
13
+ beforeEach(async (): Promise<void> => {
14
+ await waitReady();
15
+ });
16
+
17
+ for (const onlyJs of [false, true]) {
18
+ describe(`onlyJs=${(onlyJs && 'true') || 'false'}`, (): void => {
19
+ it('expands a known key', (): void => {
20
+ expect(
21
+ secp256k1Expand(
22
+ hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077'),
23
+ onlyJs
24
+ )
25
+ ).toEqual(
26
+ hexToU8a('0xb9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af')
27
+ );
28
+ });
29
+
30
+ it('expands a known full key', (): void => {
31
+ expect(
32
+ secp256k1Expand(
33
+ hexToU8a('0x04b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af'),
34
+ onlyJs
35
+ )
36
+ ).toEqual(
37
+ hexToU8a('0xb9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb1307763fe926c273235fd979a134076d00fd1683cbd35868cb485d4a3a640e52184af')
38
+ );
39
+ });
40
+ });
41
+ }
42
+
43
+ perfWasm('secp256k1Expand', 2000, (input, onlyJs) => secp256k1Expand(input, onlyJs), [[
44
+ hexToU8a('0x03b9dc646dd71118e5f7fda681ad9eca36eb3ee96f344f582fbe7b5bcdebb13077')
45
+ ]]
46
+ );
47
+ });
@@ -0,0 +1,30 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { secp256k1 } from '@noble/curves/secp256k1';
5
+
6
+ import { bnToU8a, hasBigInt, u8aConcat } from '@pezkuwi/util';
7
+ import { isReady, secp256k1Expand as wasm } from '@pezkuwi/wasm-crypto';
8
+
9
+ import { BN_BE_256_OPTS } from '../bn.js';
10
+
11
+ export function secp256k1Expand (publicKey: Uint8Array, onlyJs?: boolean): Uint8Array {
12
+ if (![33, 65].includes(publicKey.length)) {
13
+ throw new Error(`Invalid publicKey provided, received ${publicKey.length} bytes input`);
14
+ }
15
+
16
+ if (publicKey.length === 65) {
17
+ return publicKey.subarray(1);
18
+ }
19
+
20
+ if (!hasBigInt || (!onlyJs && isReady())) {
21
+ return wasm(publicKey).subarray(1);
22
+ }
23
+
24
+ const { px, py } = secp256k1.ProjectivePoint.fromHex(publicKey);
25
+
26
+ return u8aConcat(
27
+ bnToU8a(px, BN_BE_256_OPTS),
28
+ bnToU8a(py, BN_BE_256_OPTS)
29
+ );
30
+ }
@@ -0,0 +1,24 @@
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 { hasher } from './hasher.js';
7
+
8
+ describe('hasher', (): void => {
9
+ it('creates a blake2 hash', (): void => {
10
+ expect(
11
+ hasher('blake2', 'abc')
12
+ ).toEqual(
13
+ new Uint8Array([189, 221, 129, 60, 99, 66, 57, 114, 49, 113, 239, 63, 238, 152, 87, 155, 148, 150, 78, 59, 177, 203, 62, 66, 114, 98, 200, 192, 104, 213, 35, 25])
14
+ );
15
+ });
16
+
17
+ it('creates a keccak hash', (): void => {
18
+ expect(
19
+ hasher('keccak', 'abc')
20
+ ).toEqual(
21
+ new Uint8Array([78, 3, 101, 122, 234, 69, 169, 79, 199, 212, 123, 168, 38, 200, 214, 103, 192, 209, 230, 227, 58, 100, 160, 54, 236, 68, 245, 143, 161, 45, 108, 69])
22
+ );
23
+ });
24
+ });
@@ -0,0 +1,13 @@
1
+ // Copyright 2017-2025 @polkadot/util-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { HashType } from './types.js';
5
+
6
+ import { blake2AsU8a } from '../blake2/index.js';
7
+ import { keccakAsU8a } from '../keccak/index.js';
8
+
9
+ export function hasher (hashType: HashType, data: Uint8Array | string, onlyJs?: boolean): Uint8Array {
10
+ return hashType === 'keccak'
11
+ ? keccakAsU8a(data, undefined, onlyJs)
12
+ : blake2AsU8a(data, undefined, undefined, onlyJs);
13
+ }