@pezkuwi/wasm-crypto 7.5.13 → 7.5.15

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 (122) hide show
  1. package/Cargo.toml +50 -0
  2. package/Xargo.toml +2 -0
  3. package/build/README.md +29 -0
  4. package/build/bundle-pezkuwi-wasm-crypto.js +2092 -0
  5. package/build/bundle.d.ts +40 -0
  6. package/build/bundle.js +505 -0
  7. package/build/cjs/bundle.d.ts +40 -0
  8. package/build/cjs/bundle.js +544 -0
  9. package/{index.d.ts → build/cjs/index.d.ts} +0 -1
  10. package/build/cjs/index.js +4 -0
  11. package/build/cjs/init.js +21 -0
  12. package/build/cjs/initNone.js +20 -0
  13. package/build/cjs/initOnlyAsm.js +20 -0
  14. package/build/cjs/initOnlyWasm.js +20 -0
  15. package/build/cjs/initWasmAsm.js +20 -0
  16. package/build/cjs/packageInfo.js +4 -0
  17. package/build/index.d.ts +1 -0
  18. package/build/index.js +1 -0
  19. package/build/init.d.ts +16 -0
  20. package/build/init.js +17 -0
  21. package/build/initNone.d.ts +10 -0
  22. package/build/initNone.js +17 -0
  23. package/build/initOnlyAsm.d.ts +10 -0
  24. package/build/initOnlyAsm.js +17 -0
  25. package/build/initOnlyWasm.d.ts +10 -0
  26. package/build/initOnlyWasm.js +17 -0
  27. package/build/initWasmAsm.d.ts +10 -0
  28. package/build/initWasmAsm.js +17 -0
  29. package/build/package.json +208 -0
  30. package/build/packageDetect.d.ts +1 -0
  31. package/build/packageDetect.js +8 -0
  32. package/build/packageInfo.d.ts +6 -0
  33. package/build/packageInfo.js +1 -0
  34. package/build-deno/README.md +25 -0
  35. package/build-deno/bundle.ts +597 -0
  36. package/build-deno/index.ts +2 -0
  37. package/build-deno/init.ts +23 -0
  38. package/build-deno/initNone.ts +21 -0
  39. package/build-deno/initOnlyAsm.ts +21 -0
  40. package/build-deno/initOnlyWasm.ts +21 -0
  41. package/build-deno/initWasmAsm.ts +21 -0
  42. package/build-deno/mod.ts +2 -0
  43. package/build-deno/packageDetect.ts +12 -0
  44. package/build-deno/packageInfo.ts +3 -0
  45. package/build-deno/rs/.editorconfig +10 -0
  46. package/build-tsc/bundle.d.ts +40 -0
  47. package/{cjs → build-tsc}/index.d.ts +0 -1
  48. package/build-tsc-cjs/bundle.js +544 -0
  49. package/{cjs → build-tsc-cjs}/index.js +0 -1
  50. package/build-tsc-cjs/packageDetect.js +10 -0
  51. package/{cjs → build-tsc-cjs}/packageInfo.js +1 -1
  52. package/build-tsc-esm/bundle.js +505 -0
  53. package/{index.js → build-tsc-esm/index.js} +0 -1
  54. package/{packageInfo.js → build-tsc-esm/packageInfo.js} +1 -1
  55. package/package.json +89 -87
  56. package/src/bundle.ts +613 -0
  57. package/src/index.ts +5 -0
  58. package/src/init.ts +25 -0
  59. package/src/initNone.ts +23 -0
  60. package/src/initOnlyAsm.ts +23 -0
  61. package/src/initOnlyWasm.ts +23 -0
  62. package/src/initWasmAsm.ts +23 -0
  63. package/src/lib.rs +24 -0
  64. package/src/mod.ts +4 -0
  65. package/src/packageDetect.ts +16 -0
  66. package/src/packageInfo.ts +6 -0
  67. package/src/rs/.editorconfig +10 -0
  68. package/src/rs/bip39.rs +139 -0
  69. package/src/rs/ed25519.rs +142 -0
  70. package/src/rs/hashing.rs +322 -0
  71. package/src/rs/secp256k1.rs +150 -0
  72. package/src/rs/sr25519.rs +331 -0
  73. package/src/rs/vrf.rs +144 -0
  74. package/test/all/bip39.js +86 -0
  75. package/test/all/ed25519.js +84 -0
  76. package/test/all/hashing.js +138 -0
  77. package/test/all/index.js +126 -0
  78. package/test/all/secp256k1.js +105 -0
  79. package/test/all/sr25519.js +211 -0
  80. package/test/all/vrf.js +74 -0
  81. package/test/asm.js +10 -0
  82. package/test/deno.ts +38 -0
  83. package/test/jest.spec.ts +25 -0
  84. package/test/loader-build.js +39 -0
  85. package/test/wasm.js +8 -0
  86. package/tsconfig.build.json +19 -0
  87. package/tsconfig.build.tsbuildinfo +1 -0
  88. package/tsconfig.spec.json +16 -0
  89. package/tsconfig.spec.tsbuildinfo +1 -0
  90. package/bundle-pezkuwi-wasm-crypto.js +0 -825
  91. package/bundle.d.ts +0 -37
  92. package/bundle.js +0 -165
  93. package/cjs/bundle.d.ts +0 -37
  94. package/cjs/bundle.js +0 -171
  95. /package/{LICENSE → build/LICENSE} +0 -0
  96. /package/{init.d.ts → build/cjs/init.d.ts} +0 -0
  97. /package/{initNone.d.ts → build/cjs/initNone.d.ts} +0 -0
  98. /package/{initOnlyAsm.d.ts → build/cjs/initOnlyAsm.d.ts} +0 -0
  99. /package/{initOnlyWasm.d.ts → build/cjs/initOnlyWasm.d.ts} +0 -0
  100. /package/{initWasmAsm.d.ts → build/cjs/initWasmAsm.d.ts} +0 -0
  101. /package/{cjs → build/cjs}/package.json +0 -0
  102. /package/{packageDetect.d.ts → build/cjs/packageDetect.d.ts} +0 -0
  103. /package/{cjs → build/cjs}/packageDetect.js +0 -0
  104. /package/{packageInfo.d.ts → build/cjs/packageInfo.d.ts} +0 -0
  105. /package/{cjs → build-tsc}/init.d.ts +0 -0
  106. /package/{cjs → build-tsc}/initNone.d.ts +0 -0
  107. /package/{cjs → build-tsc}/initOnlyAsm.d.ts +0 -0
  108. /package/{cjs → build-tsc}/initOnlyWasm.d.ts +0 -0
  109. /package/{cjs → build-tsc}/initWasmAsm.d.ts +0 -0
  110. /package/{cjs → build-tsc}/packageDetect.d.ts +0 -0
  111. /package/{cjs → build-tsc}/packageInfo.d.ts +0 -0
  112. /package/{cjs → build-tsc-cjs}/init.js +0 -0
  113. /package/{cjs → build-tsc-cjs}/initNone.js +0 -0
  114. /package/{cjs → build-tsc-cjs}/initOnlyAsm.js +0 -0
  115. /package/{cjs → build-tsc-cjs}/initOnlyWasm.js +0 -0
  116. /package/{cjs → build-tsc-cjs}/initWasmAsm.js +0 -0
  117. /package/{init.js → build-tsc-esm/init.js} +0 -0
  118. /package/{initNone.js → build-tsc-esm/initNone.js} +0 -0
  119. /package/{initOnlyAsm.js → build-tsc-esm/initOnlyAsm.js} +0 -0
  120. /package/{initOnlyWasm.js → build-tsc-esm/initOnlyWasm.js} +0 -0
  121. /package/{initWasmAsm.js → build-tsc-esm/initWasmAsm.js} +0 -0
  122. /package/{packageDetect.js → build-tsc-esm/packageDetect.js} +0 -0
package/src/bundle.ts ADDED
@@ -0,0 +1,613 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Direct wrapper around bizinikiwi WASM (compiled with wasm-bindgen externref)
5
+ // Uses bizinikiwi signing context for PezkuwiChain SR25519 signatures
6
+
7
+ import { wasmBytes } from '@pezkuwi/wasm-crypto-wasm';
8
+
9
+ export { packageInfo } from './packageInfo.js';
10
+
11
+ // WASM instance and memory
12
+ let wasm: Record<string, unknown> | null = null;
13
+ let cachedUint8ArrayMemory: Uint8Array | null = null;
14
+ let cachedTextDecoder: TextDecoder | null = null;
15
+ let _isReady = false;
16
+ let initPromise: Promise<boolean> | null = null;
17
+ let WASM_VECTOR_LEN = 0;
18
+
19
+ // Memory helpers
20
+ function getUint8ArrayMemory(): Uint8Array {
21
+ if (cachedUint8ArrayMemory === null || cachedUint8ArrayMemory.byteLength === 0) {
22
+ cachedUint8ArrayMemory = new Uint8Array((wasm!['memory'] as WebAssembly.Memory).buffer);
23
+ }
24
+ return cachedUint8ArrayMemory;
25
+ }
26
+
27
+ function getStringFromWasm(ptr: number, len: number): string {
28
+ if (!cachedTextDecoder) {
29
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
30
+ cachedTextDecoder.decode();
31
+ }
32
+ ptr = ptr >>> 0;
33
+ return cachedTextDecoder.decode(getUint8ArrayMemory().subarray(ptr, ptr + len));
34
+ }
35
+
36
+ function getArrayU8FromWasm(ptr: number, len: number): Uint8Array {
37
+ ptr = ptr >>> 0;
38
+ return getUint8ArrayMemory().subarray(ptr / 1, ptr / 1 + len);
39
+ }
40
+
41
+ function passArray8ToWasm(arg: Uint8Array, malloc: (size: number, align: number) => number): number {
42
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
43
+ getUint8ArrayMemory().set(arg, ptr / 1);
44
+ WASM_VECTOR_LEN = arg.length;
45
+ return ptr;
46
+ }
47
+
48
+ // Externref table helpers
49
+ function addToExternrefTable(obj: unknown): number {
50
+ const idx = (wasm!['__externref_table_alloc'] as () => number)();
51
+ (wasm!['__wbindgen_externrefs'] as WebAssembly.Table).set(idx, obj);
52
+ return idx;
53
+ }
54
+
55
+ function takeFromExternrefTable(idx: number): unknown {
56
+ const value = (wasm!['__wbindgen_externrefs'] as WebAssembly.Table).get(idx);
57
+ (wasm!['__externref_table_dealloc'] as (idx: number) => void)(idx);
58
+ return value;
59
+ }
60
+
61
+ function isLikeNone(x: unknown): boolean {
62
+ return x === undefined || x === null;
63
+ }
64
+
65
+ function handleError<T extends unknown[]>(f: (...args: T) => unknown, args: IArguments): unknown {
66
+ try {
67
+ return f.apply(null, args as unknown as T);
68
+ } catch (e) {
69
+ const idx = addToExternrefTable(e);
70
+ (wasm!['__wbindgen_exn_store'] as (idx: number) => void)(idx);
71
+ return undefined;
72
+ }
73
+ }
74
+
75
+ // WASM imports - matches pezkuwi_wasm_crypto.js __wbg_get_imports()
76
+ function createImports(): WebAssembly.Imports {
77
+ const import0: Record<string, unknown> = {
78
+ __proto__: null,
79
+
80
+ __wbg___wbindgen_is_function_0095a73b8b156f76: function(arg0: unknown): boolean {
81
+ return typeof(arg0) === 'function';
82
+ },
83
+
84
+ __wbg___wbindgen_is_object_5ae8e5880f2c1fbd: function(arg0: unknown): boolean {
85
+ const val = arg0;
86
+ return typeof(val) === 'object' && val !== null;
87
+ },
88
+
89
+ __wbg___wbindgen_is_string_cd444516edc5b180: function(arg0: unknown): boolean {
90
+ return typeof(arg0) === 'string';
91
+ },
92
+
93
+ __wbg___wbindgen_is_undefined_9e4d92534c42d778: function(arg0: unknown): boolean {
94
+ return arg0 === undefined;
95
+ },
96
+
97
+ __wbg___wbindgen_throw_be289d5034ed271b: function(arg0: number, arg1: number): never {
98
+ throw new Error(getStringFromWasm(arg0, arg1));
99
+ },
100
+
101
+ __wbg_call_389efe28435a9388: function(): unknown {
102
+ return handleError(function(arg0: { call: (thisArg: unknown) => unknown }, arg1: unknown) {
103
+ return arg0.call(arg1);
104
+ }, arguments);
105
+ },
106
+
107
+ __wbg_call_4708e0c13bdc8e95: function(): unknown {
108
+ return handleError(function(arg0: { call: (thisArg: unknown, arg: unknown) => unknown }, arg1: unknown, arg2: unknown) {
109
+ return arg0.call(arg1, arg2);
110
+ }, arguments);
111
+ },
112
+
113
+ __wbg_crypto_86f2631e91b51511: function(arg0: { crypto?: Crypto }): Crypto | undefined {
114
+ return arg0.crypto;
115
+ },
116
+
117
+ __wbg_getRandomValues_b3f15fcbfabb0f8b: function(): void {
118
+ return handleError(function(arg0: { getRandomValues: (arr: Uint8Array) => void }, arg1: Uint8Array) {
119
+ arg0.getRandomValues(arg1);
120
+ }, arguments) as void;
121
+ },
122
+
123
+ __wbg_length_32ed9a279acd054c: function(arg0: { length: number }): number {
124
+ return arg0.length;
125
+ },
126
+
127
+ __wbg_msCrypto_d562bbe83e0d4b91: function(arg0: { msCrypto?: unknown }): unknown {
128
+ return arg0.msCrypto;
129
+ },
130
+
131
+ __wbg_new_no_args_1c7c842f08d00ebb: function(arg0: number, arg1: number): Function {
132
+ return new Function(getStringFromWasm(arg0, arg1));
133
+ },
134
+
135
+ __wbg_new_with_length_a2c39cbe88fd8ff1: function(arg0: number): Uint8Array {
136
+ return new Uint8Array(arg0 >>> 0);
137
+ },
138
+
139
+ __wbg_node_e1f24f89a7336c2e: function(arg0: { node?: unknown }): unknown {
140
+ return arg0.node;
141
+ },
142
+
143
+ __wbg_process_3975fd6c72f520aa: function(arg0: { process?: unknown }): unknown {
144
+ return arg0.process;
145
+ },
146
+
147
+ __wbg_prototypesetcall_bdcdcc5842e4d77d: function(arg0: number, arg1: number, arg2: Uint8Array): void {
148
+ Uint8Array.prototype.set.call(getArrayU8FromWasm(arg0, arg1), arg2);
149
+ },
150
+
151
+ __wbg_randomFillSync_f8c153b79f285817: function(): void {
152
+ return handleError(function(arg0: { randomFillSync: (arr: Uint8Array) => void }, arg1: Uint8Array) {
153
+ arg0.randomFillSync(arg1);
154
+ }, arguments) as void;
155
+ },
156
+
157
+ __wbg_require_b74f47fc2d022fd6: function(): unknown {
158
+ return handleError(function() {
159
+ return typeof module !== 'undefined' ? (module as NodeModule & { require?: unknown }).require : undefined;
160
+ }, arguments);
161
+ },
162
+
163
+ __wbg_static_accessor_GLOBAL_12837167ad935116: function(): number {
164
+ const ret = typeof global === 'undefined' ? null : global;
165
+ return isLikeNone(ret) ? 0 : addToExternrefTable(ret);
166
+ },
167
+
168
+ __wbg_static_accessor_GLOBAL_THIS_e628e89ab3b1c95f: function(): number {
169
+ const ret = typeof globalThis === 'undefined' ? null : globalThis;
170
+ return isLikeNone(ret) ? 0 : addToExternrefTable(ret);
171
+ },
172
+
173
+ __wbg_static_accessor_SELF_a621d3dfbb60d0ce: function(): number {
174
+ const ret = typeof self === 'undefined' ? null : self;
175
+ return isLikeNone(ret) ? 0 : addToExternrefTable(ret);
176
+ },
177
+
178
+ __wbg_static_accessor_WINDOW_f8727f0cf888e0bd: function(): number {
179
+ const ret = typeof window === 'undefined' ? null : window;
180
+ return isLikeNone(ret) ? 0 : addToExternrefTable(ret);
181
+ },
182
+
183
+ __wbg_subarray_a96e1fef17ed23cb: function(arg0: Uint8Array, arg1: number, arg2: number): Uint8Array {
184
+ return arg0.subarray(arg1 >>> 0, arg2 >>> 0);
185
+ },
186
+
187
+ __wbg_versions_4e31226f5e8dc909: function(arg0: { versions?: unknown }): unknown {
188
+ return arg0.versions;
189
+ },
190
+
191
+ __wbindgen_cast_0000000000000001: function(arg0: number, arg1: number): Uint8Array {
192
+ return getArrayU8FromWasm(arg0, arg1);
193
+ },
194
+
195
+ __wbindgen_cast_0000000000000002: function(arg0: number, arg1: number): string {
196
+ return getStringFromWasm(arg0, arg1);
197
+ },
198
+
199
+ __wbindgen_init_externref_table: function(): void {
200
+ const table = wasm!['__wbindgen_externrefs'] as WebAssembly.Table;
201
+ const offset = table.grow(4);
202
+ table.set(0, undefined);
203
+ table.set(offset + 0, undefined);
204
+ table.set(offset + 1, null);
205
+ table.set(offset + 2, true);
206
+ table.set(offset + 3, false);
207
+ },
208
+ };
209
+
210
+ return {
211
+ __proto__: null,
212
+ './pezkuwi_wasm_crypto_bg.js': import0,
213
+ } as unknown as WebAssembly.Imports;
214
+ }
215
+
216
+ // Initialize WASM
217
+ async function initWasm(): Promise<boolean> {
218
+ if (_isReady) return true;
219
+
220
+ try {
221
+ // wasmBytes is already decompressed by @pezkuwi/wasm-crypto-wasm
222
+ const imports = createImports();
223
+ const result = await WebAssembly.instantiate(wasmBytes as BufferSource, imports);
224
+
225
+ wasm = (result as WebAssembly.WebAssemblyInstantiatedSource).instance.exports as Record<string, unknown>;
226
+
227
+ // Initialize the module
228
+ if (typeof wasm['__wbindgen_start'] === 'function') {
229
+ (wasm['__wbindgen_start'] as () => void)();
230
+ }
231
+
232
+ _isReady = true;
233
+ return true;
234
+ } catch (error) {
235
+ console.error('FATAL: Unable to initialize @pezkuwi/wasm-crypto:', (error as Error).message);
236
+ return false;
237
+ }
238
+ }
239
+
240
+ // Public API - backward compatible with @polkadot/wasm-crypto
241
+
242
+ export const bridge = {
243
+ wasm: null as unknown,
244
+ type: 'wasm' as const
245
+ };
246
+
247
+ export function isReady(): boolean {
248
+ return _isReady;
249
+ }
250
+
251
+ export async function waitReady(): Promise<boolean> {
252
+ if (!initPromise) {
253
+ initPromise = initWasm();
254
+ }
255
+ return initPromise;
256
+ }
257
+
258
+ // Get signing context (should return "bizinikiwi")
259
+ export function getSigningContext(): string {
260
+ if (!wasm) throw new Error('WASM not initialized');
261
+ const ret = (wasm['get_signing_context'] as () => [number, number])();
262
+ const str = getStringFromWasm(ret[0], ret[1]);
263
+ (wasm['__wbindgen_free'] as (ptr: number, len: number, align: number) => void)(ret[0], ret[1], 1);
264
+ return str;
265
+ }
266
+
267
+ // SR25519 - Uses bizinikiwi signing context
268
+
269
+ export function sr25519KeypairFromSeed(seed: Uint8Array): Uint8Array {
270
+ if (!wasm) throw new Error('WASM not initialized');
271
+ const ptr0 = passArray8ToWasm(seed, wasm['__wbindgen_malloc'] as (size: number, align: number) => number);
272
+ const len0 = WASM_VECTOR_LEN;
273
+ const ret = (wasm['sr25519_keypair_from_seed'] as (ptr: number, len: number) => [number, number, number, number])(ptr0, len0);
274
+ if (ret[3]) {
275
+ throw takeFromExternrefTable(ret[2]) as Error;
276
+ }
277
+ const v2 = getArrayU8FromWasm(ret[0], ret[1]).slice();
278
+ (wasm['__wbindgen_free'] as (ptr: number, len: number, align: number) => void)(ret[0], ret[1] * 1, 1);
279
+ return v2;
280
+ }
281
+
282
+ export function sr25519Sign(publicKey: Uint8Array, secretKey: Uint8Array, message: Uint8Array): Uint8Array {
283
+ if (!wasm) throw new Error('WASM not initialized');
284
+ const ptr0 = passArray8ToWasm(publicKey, wasm['__wbindgen_malloc'] as (size: number, align: number) => number);
285
+ const len0 = WASM_VECTOR_LEN;
286
+ const ptr1 = passArray8ToWasm(secretKey, wasm['__wbindgen_malloc'] as (size: number, align: number) => number);
287
+ const len1 = WASM_VECTOR_LEN;
288
+ const ptr2 = passArray8ToWasm(message, wasm['__wbindgen_malloc'] as (size: number, align: number) => number);
289
+ const len2 = WASM_VECTOR_LEN;
290
+ const ret = (wasm['sr25519_sign'] as (p0: number, l0: number, p1: number, l1: number, p2: number, l2: number) => [number, number, number, number])(ptr0, len0, ptr1, len1, ptr2, len2);
291
+ if (ret[3]) {
292
+ throw takeFromExternrefTable(ret[2]) as Error;
293
+ }
294
+ const v4 = getArrayU8FromWasm(ret[0], ret[1]).slice();
295
+ (wasm['__wbindgen_free'] as (ptr: number, len: number, align: number) => void)(ret[0], ret[1] * 1, 1);
296
+ return v4;
297
+ }
298
+
299
+ export function sr25519Verify(signature: Uint8Array, message: Uint8Array, publicKey: Uint8Array): boolean {
300
+ if (!wasm) throw new Error('WASM not initialized');
301
+ const ptr0 = passArray8ToWasm(signature, wasm['__wbindgen_malloc'] as (size: number, align: number) => number);
302
+ const len0 = WASM_VECTOR_LEN;
303
+ const ptr1 = passArray8ToWasm(message, wasm['__wbindgen_malloc'] as (size: number, align: number) => number);
304
+ const len1 = WASM_VECTOR_LEN;
305
+ const ptr2 = passArray8ToWasm(publicKey, wasm['__wbindgen_malloc'] as (size: number, align: number) => number);
306
+ const len2 = WASM_VECTOR_LEN;
307
+ const ret = (wasm['sr25519_verify'] as (p0: number, l0: number, p1: number, l1: number, p2: number, l2: number) => number)(ptr0, len0, ptr1, len1, ptr2, len2);
308
+ return ret !== 0;
309
+ }
310
+
311
+ // BIP39 JavaScript implementations (not in bizinikiwi WASM)
312
+ // Using minimal implementations compatible with original wasm-crypto
313
+
314
+ import { sha256 as nobleSha256 } from '@noble/hashes/sha256';
315
+ import { sha512 as nobleSha512 } from '@noble/hashes/sha512';
316
+ import { pbkdf2 as noblePbkdf2 } from '@noble/hashes/pbkdf2';
317
+ import { blake2b as nobleBlake2b } from '@noble/hashes/blake2b';
318
+ import { hmac } from '@noble/hashes/hmac';
319
+ import { keccak_256, keccak_512 } from '@noble/hashes/sha3';
320
+
321
+ function normalizeString(str: string): string {
322
+ return (str || '').normalize('NFKD');
323
+ }
324
+
325
+ // Basic validation - check word count only
326
+ // Full validation with wordlist happens in util-crypto's JS fallback
327
+ export function bip39Validate(phrase: string): boolean {
328
+ try {
329
+ const words = normalizeString(phrase).split(' ');
330
+ return [12, 15, 18, 21, 24].includes(words.length);
331
+ } catch {
332
+ return false;
333
+ }
334
+ }
335
+
336
+ // BIP39 English wordlist
337
+ const BIP39_WORDLIST = 'abandon|ability|able|about|above|absent|absorb|abstract|absurd|abuse|access|accident|account|accuse|achieve|acid|acoustic|acquire|across|act|action|actor|actress|actual|adapt|add|addict|address|adjust|admit|adult|advance|advice|aerobic|affair|afford|afraid|again|age|agent|agree|ahead|aim|air|airport|aisle|alarm|album|alcohol|alert|alien|all|alley|allow|almost|alone|alpha|already|also|alter|always|amateur|amazing|among|amount|amused|analyst|anchor|ancient|anger|angle|angry|animal|ankle|announce|annual|another|answer|antenna|antique|anxiety|any|apart|apology|appear|apple|approve|april|arch|arctic|area|arena|argue|arm|armed|armor|army|around|arrange|arrest|arrive|arrow|art|artefact|artist|artwork|ask|aspect|assault|asset|assist|assume|asthma|athlete|atom|attack|attend|attitude|attract|auction|audit|august|aunt|author|auto|autumn|average|avocado|avoid|awake|aware|away|awesome|awful|awkward|axis|baby|bachelor|bacon|badge|bag|balance|balcony|ball|bamboo|banana|banner|bar|barely|bargain|barrel|base|basic|basket|battle|beach|bean|beauty|because|become|beef|before|begin|behave|behind|believe|below|belt|bench|benefit|best|betray|better|between|beyond|bicycle|bid|bike|bind|biology|bird|birth|bitter|black|blade|blame|blanket|blast|bleak|bless|blind|blood|blossom|blouse|blue|blur|blush|board|boat|body|boil|bomb|bone|bonus|book|boost|border|boring|borrow|boss|bottom|bounce|box|boy|bracket|brain|brand|brass|brave|bread|breeze|brick|bridge|brief|bright|bring|brisk|broccoli|broken|bronze|broom|brother|brown|brush|bubble|buddy|budget|buffalo|build|bulb|bulk|bullet|bundle|bunker|burden|burger|burst|bus|business|busy|butter|buyer|buzz|cabbage|cabin|cable|cactus|cage|cake|call|calm|camera|camp|can|canal|cancel|candy|cannon|canoe|canvas|canyon|capable|capital|captain|car|carbon|card|cargo|carpet|carry|cart|case|cash|casino|castle|casual|cat|catalog|catch|category|cattle|caught|cause|caution|cave|ceiling|celery|cement|census|century|cereal|certain|chair|chalk|champion|change|chaos|chapter|charge|chase|chat|cheap|check|cheese|chef|cherry|chest|chicken|chief|child|chimney|choice|choose|chronic|chuckle|chunk|churn|cigar|cinnamon|circle|citizen|city|civil|claim|clap|clarify|claw|clay|clean|clerk|clever|click|client|cliff|climb|clinic|clip|clock|clog|close|cloth|cloud|clown|club|clump|cluster|clutch|coach|coast|coconut|code|coffee|coil|coin|collect|color|column|combine|come|comfort|comic|common|company|concert|conduct|confirm|congress|connect|consider|control|convince|cook|cool|copper|copy|coral|core|corn|correct|cost|cotton|couch|country|couple|course|cousin|cover|coyote|crack|cradle|craft|cram|crane|crash|crater|crawl|crazy|cream|credit|creek|crew|cricket|crime|crisp|critic|crop|cross|crouch|crowd|crucial|cruel|cruise|crumble|crunch|crush|cry|crystal|cube|culture|cup|cupboard|curious|current|curtain|curve|cushion|custom|cute|cycle|dad|damage|damp|dance|danger|daring|dash|daughter|dawn|day|deal|debate|debris|decade|december|decide|decline|decorate|decrease|deer|defense|define|defy|degree|delay|deliver|demand|demise|denial|dentist|deny|depart|depend|deposit|depth|deputy|derive|describe|desert|design|desk|despair|destroy|detail|detect|develop|device|devote|diagram|dial|diamond|diary|dice|diesel|diet|differ|digital|dignity|dilemma|dinner|dinosaur|direct|dirt|disagree|discover|disease|dish|dismiss|disorder|display|distance|divert|divide|divorce|dizzy|doctor|document|dog|doll|dolphin|domain|donate|donkey|donor|door|dose|double|dove|draft|dragon|drama|drastic|draw|dream|dress|drift|drill|drink|drip|drive|drop|drum|dry|duck|dumb|dune|during|dust|dutch|duty|dwarf|dynamic|eager|eagle|early|earn|earth|easily|east|easy|echo|ecology|economy|edge|edit|educate|effort|egg|eight|either|elbow|elder|electric|elegant|element|elephant|elevator|elite|else|embark|embody|embrace|emerge|emotion|employ|empower|empty|enable|enact|end|endless|endorse|enemy|energy|enforce|engage|engine|enhance|enjoy|enlist|enough|enrich|enroll|ensure|enter|entire|entry|envelope|episode|equal|equip|era|erase|erode|erosion|error|erupt|escape|essay|essence|estate|eternal|ethics|evidence|evil|evoke|evolve|exact|example|excess|exchange|excite|exclude|excuse|execute|exercise|exhaust|exhibit|exile|exist|exit|exotic|expand|expect|expire|explain|expose|express|extend|extra|eye|eyebrow|fabric|face|faculty|fade|faint|faith|fall|false|fame|family|famous|fan|fancy|fantasy|farm|fashion|fat|fatal|father|fatigue|fault|favorite|feature|february|federal|fee|feed|feel|female|fence|festival|fetch|fever|few|fiber|fiction|field|figure|file|film|filter|final|find|fine|finger|finish|fire|firm|first|fiscal|fish|fit|fitness|fix|flag|flame|flash|flat|flavor|flee|flight|flip|float|flock|floor|flower|fluid|flush|fly|foam|focus|fog|foil|fold|follow|food|foot|force|forest|forget|fork|fortune|forum|forward|fossil|foster|found|fox|fragile|frame|frequent|fresh|friend|fringe|frog|front|frost|frown|frozen|fruit|fuel|fun|funny|furnace|fury|future|gadget|gain|galaxy|gallery|game|gap|garage|garbage|garden|garlic|garment|gas|gasp|gate|gather|gauge|gaze|general|genius|genre|gentle|genuine|gesture|ghost|giant|gift|giggle|ginger|giraffe|girl|give|glad|glance|glare|glass|glide|glimpse|globe|gloom|glory|glove|glow|glue|goat|goddess|gold|good|goose|gorilla|gospel|gossip|govern|gown|grab|grace|grain|grant|grape|grass|gravity|great|green|grid|grief|grit|grocery|group|grow|grunt|guard|guess|guide|guilt|guitar|gun|gym|habit|hair|half|hammer|hamster|hand|happy|harbor|hard|harsh|harvest|hat|have|hawk|hazard|head|health|heart|heavy|hedgehog|height|hello|helmet|help|hen|hero|hidden|high|hill|hint|hip|hire|history|hobby|hockey|hold|hole|holiday|hollow|home|honey|hood|hope|horn|horror|horse|hospital|host|hotel|hour|hover|hub|huge|human|humble|humor|hundred|hungry|hunt|hurdle|hurry|hurt|husband|hybrid|ice|icon|idea|identify|idle|ignore|ill|illegal|illness|image|imitate|immense|immune|impact|impose|improve|impulse|inch|include|income|increase|index|indicate|indoor|industry|infant|inflict|inform|inhale|inherit|initial|inject|injury|inmate|inner|innocent|input|inquiry|insane|insect|inside|inspire|install|intact|interest|into|invest|invite|involve|iron|island|isolate|issue|item|ivory|jacket|jaguar|jar|jazz|jealous|jeans|jelly|jewel|job|join|joke|journey|joy|judge|juice|jump|jungle|junior|junk|just|kangaroo|keen|keep|ketchup|key|kick|kid|kidney|kind|kingdom|kiss|kit|kitchen|kite|kitten|kiwi|knee|knife|knock|know|lab|label|labor|ladder|lady|lake|lamp|language|laptop|large|later|latin|laugh|laundry|lava|law|lawn|lawsuit|layer|lazy|leader|leaf|learn|leave|lecture|left|leg|legal|legend|leisure|lemon|lend|length|lens|leopard|lesson|letter|level|liar|liberty|library|license|life|lift|light|like|limb|limit|link|lion|liquid|list|little|live|lizard|load|loan|lobster|local|lock|logic|lonely|long|loop|lottery|loud|lounge|love|loyal|lucky|luggage|lumber|lunar|lunch|luxury|lyrics|machine|mad|magic|magnet|maid|mail|main|major|make|mammal|man|manage|mandate|mango|mansion|manual|maple|marble|march|margin|marine|market|marriage|mask|mass|master|match|material|math|matrix|matter|maximum|maze|meadow|mean|measure|meat|mechanic|medal|media|melody|melt|member|memory|mention|menu|mercy|merge|merit|merry|mesh|message|metal|method|middle|midnight|milk|million|mimic|mind|minimum|minor|minute|miracle|mirror|misery|miss|mistake|mix|mixed|mixture|mobile|model|modify|mom|moment|monitor|monkey|monster|month|moon|moral|more|morning|mosquito|mother|motion|motor|mountain|mouse|move|movie|much|muffin|mule|multiply|muscle|museum|mushroom|music|must|mutual|myself|mystery|myth|naive|name|napkin|narrow|nasty|nation|nature|near|neck|need|negative|neglect|neither|nephew|nerve|nest|net|network|neutral|never|news|next|nice|night|noble|noise|nominee|noodle|normal|north|nose|notable|note|nothing|notice|novel|now|nuclear|number|nurse|nut|oak|obey|object|oblige|obscure|observe|obtain|obvious|occur|ocean|october|odor|off|offer|office|often|oil|okay|old|olive|olympic|omit|once|one|onion|online|only|open|opera|opinion|oppose|option|orange|orbit|orchard|order|ordinary|organ|orient|original|orphan|ostrich|other|outdoor|outer|output|outside|oval|oven|over|own|owner|oxygen|oyster|ozone|pact|paddle|page|pair|palace|palm|panda|panel|panic|panther|paper|parade|parent|park|parrot|party|pass|patch|path|patient|patrol|pattern|pause|pave|payment|peace|peanut|pear|peasant|pelican|pen|penalty|pencil|people|pepper|perfect|permit|person|pet|phone|photo|phrase|physical|piano|picnic|picture|piece|pig|pigeon|pill|pilot|pink|pioneer|pipe|pistol|pitch|pizza|place|planet|plastic|plate|play|please|pledge|pluck|plug|plunge|poem|poet|point|polar|pole|police|pond|pony|pool|popular|portion|position|possible|post|potato|pottery|poverty|powder|power|practice|praise|predict|prefer|prepare|present|pretty|prevent|price|pride|primary|print|priority|prison|private|prize|problem|process|produce|profit|program|project|promote|proof|property|prosper|protect|proud|provide|public|pudding|pull|pulp|pulse|pumpkin|punch|pupil|puppy|purchase|purity|purpose|purse|push|put|puzzle|pyramid|quality|quantum|quarter|question|quick|quit|quiz|quote|rabbit|raccoon|race|rack|radar|radio|rail|rain|raise|rally|ramp|ranch|random|range|rapid|rare|rate|rather|raven|raw|razor|ready|real|reason|rebel|rebuild|recall|receive|recipe|record|recycle|reduce|reflect|reform|refuse|region|regret|regular|reject|relax|release|relief|rely|remain|remember|remind|remove|render|renew|rent|reopen|repair|repeat|replace|report|require|rescue|resemble|resist|resource|response|result|retire|retreat|return|reunion|reveal|review|reward|rhythm|rib|ribbon|rice|rich|ride|ridge|rifle|right|rigid|ring|riot|ripple|risk|ritual|rival|river|road|roast|robot|robust|rocket|romance|roof|rookie|room|rose|rotate|rough|round|route|royal|rubber|rude|rug|rule|run|runway|rural|sad|saddle|sadness|safe|sail|salad|salmon|salon|salt|salute|same|sample|sand|satisfy|satoshi|sauce|sausage|save|say|scale|scan|scare|scatter|scene|scheme|school|science|scissors|scorpion|scout|scrap|screen|script|scrub|sea|search|season|seat|second|secret|section|security|seed|seek|segment|select|sell|seminar|senior|sense|sentence|series|service|session|settle|setup|seven|shadow|shaft|shallow|share|shed|shell|sheriff|shield|shift|shine|ship|shiver|shock|shoe|shoot|shop|short|shoulder|shove|shrimp|shrug|shuffle|shy|sibling|sick|side|siege|sight|sign|silent|silk|silly|silver|similar|simple|since|sing|siren|sister|situate|six|size|skate|sketch|ski|skill|skin|skirt|skull|slab|slam|sleep|slender|slice|slide|slight|slim|slogan|slot|slow|slush|small|smart|smile|smoke|smooth|snack|snake|snap|sniff|snow|soap|soccer|social|sock|soda|soft|solar|soldier|solid|solution|solve|someone|song|soon|sorry|sort|soul|sound|soup|source|south|space|spare|spatial|spawn|speak|special|speed|spell|spend|sphere|spice|spider|spike|spin|spirit|split|spoil|sponsor|spoon|sport|spot|spray|spread|spring|spy|square|squeeze|squirrel|stable|stadium|staff|stage|stairs|stamp|stand|start|state|stay|steak|steel|stem|step|stereo|stick|still|sting|stock|stomach|stone|stool|story|stove|strategy|street|strike|strong|struggle|student|stuff|stumble|style|subject|submit|subway|success|such|sudden|suffer|sugar|suggest|suit|summer|sun|sunny|sunset|super|supply|supreme|sure|surface|surge|surprise|surround|survey|suspect|sustain|swallow|swamp|swap|swarm|swear|sweet|swift|swim|swing|switch|sword|symbol|symptom|syrup|system|table|tackle|tag|tail|talent|talk|tank|tape|target|task|taste|tattoo|taxi|teach|team|tell|ten|tenant|tennis|tent|term|test|text|thank|that|theme|then|theory|there|they|thing|this|thought|three|thrive|throw|thumb|thunder|ticket|tide|tiger|tilt|timber|time|tiny|tip|tired|tissue|title|toast|tobacco|today|toddler|toe|together|toilet|token|tomato|tomorrow|tone|tongue|tonight|tool|tooth|top|topic|topple|torch|tornado|tortoise|toss|total|tourist|toward|tower|town|toy|track|trade|traffic|tragic|train|transfer|trap|trash|travel|tray|treat|tree|trend|trial|tribe|trick|trigger|trim|trip|trophy|trouble|truck|true|truly|trumpet|trust|truth|try|tube|tuition|tumble|tuna|tunnel|turkey|turn|turtle|twelve|twenty|twice|twin|twist|two|type|typical|ugly|umbrella|unable|unaware|uncle|uncover|under|undo|unfair|unfold|unhappy|uniform|unique|unit|universe|unknown|unlock|until|unusual|unveil|update|upgrade|uphold|upon|upper|upset|urban|urge|usage|use|used|useful|useless|usual|utility|vacant|vacuum|vague|valid|valley|valve|van|vanish|vapor|various|vast|vault|vehicle|velvet|vendor|venture|venue|verb|verify|version|very|vessel|veteran|viable|vibrant|vicious|victory|video|view|village|vintage|violin|virtual|virus|visa|visit|visual|vital|vivid|vocal|voice|void|volcano|volume|vote|voyage|wage|wagon|wait|walk|wall|walnut|want|warfare|warm|warrior|wash|wasp|waste|water|wave|way|wealth|weapon|wear|weasel|weather|web|wedding|weekend|weird|welcome|west|wet|whale|what|wheat|wheel|when|where|whip|whisper|wide|width|wife|wild|will|win|window|wine|wing|wink|winner|winter|wire|wisdom|wise|wish|witness|wolf|woman|wonder|wood|wool|word|work|world|worry|worth|wrap|wreck|wrestle|wrist|write|wrong|yard|year|yellow|you|young|youth|zebra|zero|zone|zoo'.split('|');
338
+
339
+ function binaryToByte(bin: string): number {
340
+ return parseInt(bin, 2);
341
+ }
342
+
343
+ function bytesToBinary(bytes: number[]): string {
344
+ return bytes.map((x) => x.toString(2).padStart(8, '0')).join('');
345
+ }
346
+
347
+ function deriveChecksumBits(entropyBuffer: Uint8Array): string {
348
+ const hash = nobleSha256(entropyBuffer);
349
+ return bytesToBinary(Array.from(hash)).slice(0, (entropyBuffer.length * 8) / 32);
350
+ }
351
+
352
+ export function bip39Generate(_words: 12 | 15 | 18 | 21 | 24): string {
353
+ throw new Error('bip39Generate: use @pezkuwi/util-crypto mnemonicGenerate instead');
354
+ }
355
+
356
+ export function bip39ToEntropy(phrase: string): Uint8Array {
357
+ const words = normalizeString(phrase).split(' ');
358
+ if (words.length % 3 !== 0) {
359
+ throw new Error('Invalid mnemonic');
360
+ }
361
+ // convert word indices to 11 bit binary strings
362
+ const bits = words
363
+ .map((word) => {
364
+ const index = BIP39_WORDLIST.indexOf(word);
365
+ if (index === -1) {
366
+ throw new Error('Invalid mnemonic');
367
+ }
368
+ return index.toString(2).padStart(11, '0');
369
+ })
370
+ .join('');
371
+ // split the binary string into ENT/CS
372
+ const dividerIndex = Math.floor(bits.length / 33) * 32;
373
+ const entropyBits = bits.slice(0, dividerIndex);
374
+ const checksumBits = bits.slice(dividerIndex);
375
+ // calculate the checksum and compare
376
+ const matched = entropyBits.match(/(.{1,8})/g);
377
+ const entropyBytes = matched?.map(binaryToByte);
378
+ if (!entropyBytes || (entropyBytes.length % 4 !== 0) || (entropyBytes.length < 16) || (entropyBytes.length > 32)) {
379
+ throw new Error('Invalid entropy');
380
+ }
381
+ const entropy = new Uint8Array(entropyBytes);
382
+ if (deriveChecksumBits(entropy) !== checksumBits) {
383
+ throw new Error('Invalid mnemonic checksum');
384
+ }
385
+ return entropy;
386
+ }
387
+
388
+ export function bip39ToMiniSecret(phrase: string, password: string): Uint8Array {
389
+ // Substrate uses entropy-based derivation (not BIP39's mnemonic string PBKDF2)
390
+ const entropy = bip39ToEntropy(phrase);
391
+ const salt = new TextEncoder().encode(`mnemonic${normalizeString(password)}`);
392
+ // PBKDF2 on the entropy, not the mnemonic string
393
+ return noblePbkdf2(nobleSha512, entropy, salt, { c: 2048, dkLen: 64 }).slice(0, 32);
394
+ }
395
+
396
+ export function bip39ToSeed(phrase: string, password: string): Uint8Array {
397
+ const salt = new TextEncoder().encode(`mnemonic${normalizeString(password)}`);
398
+ const input = new TextEncoder().encode(normalizeString(phrase));
399
+ return noblePbkdf2(nobleSha256, input, salt, { c: 2048, dkLen: 64 });
400
+ }
401
+
402
+ export function ed25519KeypairFromSeed(_seed: Uint8Array): Uint8Array {
403
+ throw new Error('ed25519KeypairFromSeed not yet implemented');
404
+ }
405
+
406
+ export function ed25519Sign(_publicKey: Uint8Array, _secretKey: Uint8Array, _message: Uint8Array): Uint8Array {
407
+ throw new Error('ed25519Sign not yet implemented');
408
+ }
409
+
410
+ export function ed25519Verify(_signature: Uint8Array, _message: Uint8Array, _publicKey: Uint8Array): boolean {
411
+ throw new Error('ed25519Verify not yet implemented');
412
+ }
413
+
414
+ export function sr25519Agree(_publicKey: Uint8Array, _secretKey: Uint8Array): Uint8Array {
415
+ throw new Error('sr25519Agree not yet implemented');
416
+ }
417
+
418
+ export function sr25519DeriveKeypairHard(_pair: Uint8Array, _cc: Uint8Array): Uint8Array {
419
+ throw new Error('sr25519DeriveKeypairHard not yet implemented');
420
+ }
421
+
422
+ export function sr25519DeriveKeypairSoft(_pair: Uint8Array, _cc: Uint8Array): Uint8Array {
423
+ throw new Error('sr25519DeriveKeypairSoft not yet implemented');
424
+ }
425
+
426
+ export function sr25519DerivePublicSoft(_publicKey: Uint8Array, _cc: Uint8Array): Uint8Array {
427
+ throw new Error('sr25519DerivePublicSoft not yet implemented');
428
+ }
429
+
430
+ export function vrfSign(_secretKey: Uint8Array, _context: Uint8Array, _message: Uint8Array, _extra: Uint8Array): Uint8Array {
431
+ throw new Error('vrfSign not yet implemented');
432
+ }
433
+
434
+ export function vrfVerify(_publicKey: Uint8Array, _context: Uint8Array, _message: Uint8Array, _extra: Uint8Array, _outAndProof: Uint8Array): boolean {
435
+ throw new Error('vrfVerify not yet implemented');
436
+ }
437
+
438
+ export function secp256k1FromSeed(_seed: Uint8Array): Uint8Array {
439
+ throw new Error('secp256k1FromSeed not yet implemented');
440
+ }
441
+
442
+ export function secp256k1Compress(_publicKey: Uint8Array): Uint8Array {
443
+ throw new Error('secp256k1Compress not yet implemented');
444
+ }
445
+
446
+ export function secp256k1Expand(_publicKey: Uint8Array): Uint8Array {
447
+ throw new Error('secp256k1Expand not yet implemented');
448
+ }
449
+
450
+ export function secp256k1Recover(_msgHash: Uint8Array, _signature: Uint8Array, _recoveryId: number): Uint8Array {
451
+ throw new Error('secp256k1Recover not yet implemented');
452
+ }
453
+
454
+ export function secp256k1Sign(_msgHash: Uint8Array, _secretKey: Uint8Array): Uint8Array {
455
+ throw new Error('secp256k1Sign not yet implemented');
456
+ }
457
+
458
+ export function blake2b(data: Uint8Array, key: Uint8Array, size: number): Uint8Array {
459
+ // size is already in bytes (passed by util-crypto's blake2AsU8a)
460
+ if (key && key.length > 0) {
461
+ return nobleBlake2b(data, { dkLen: size, key });
462
+ }
463
+ return nobleBlake2b(data, { dkLen: size });
464
+ }
465
+
466
+ export function hmacSha256(key: Uint8Array, data: Uint8Array): Uint8Array {
467
+ return hmac(nobleSha256, key, data);
468
+ }
469
+
470
+ export function hmacSha512(key: Uint8Array, data: Uint8Array): Uint8Array {
471
+ return hmac(nobleSha512, key, data);
472
+ }
473
+
474
+ export function keccak256(data: Uint8Array): Uint8Array {
475
+ return keccak_256(data);
476
+ }
477
+
478
+ export function keccak512(data: Uint8Array): Uint8Array {
479
+ return keccak_512(data);
480
+ }
481
+
482
+ export function pbkdf2(data: Uint8Array, salt: Uint8Array, rounds: number): Uint8Array {
483
+ return noblePbkdf2(nobleSha512, data, salt, { c: rounds, dkLen: 64 });
484
+ }
485
+
486
+ export function scrypt(_password: Uint8Array, _salt: Uint8Array, _log2n: number, _r: number, _p: number): Uint8Array {
487
+ // scrypt is rarely used - defer to @noble/hashes/scrypt if needed
488
+ throw new Error('scrypt not yet implemented - use @pezkuwi/util-crypto scryptSync instead');
489
+ }
490
+
491
+ export function sha256(data: Uint8Array): Uint8Array {
492
+ return nobleSha256(data);
493
+ }
494
+
495
+ export function sha512(data: Uint8Array): Uint8Array {
496
+ return nobleSha512(data);
497
+ }
498
+
499
+ // xxhash64 implementation
500
+ const P64_1 = BigInt('11400714785074694791');
501
+ const P64_2 = BigInt('14029467366897019727');
502
+ const P64_3 = BigInt('1609587929392839161');
503
+ const P64_4 = BigInt('9650029242287828579');
504
+ const P64_5 = BigInt('2870177450012600261');
505
+ const U64 = BigInt('0xffffffffffffffff');
506
+ const _0n = BigInt(0);
507
+ const _1n = BigInt(1);
508
+ const _7n = BigInt(7);
509
+ const _11n = BigInt(11);
510
+ const _12n = BigInt(12);
511
+ const _16n = BigInt(16);
512
+ const _18n = BigInt(18);
513
+ const _23n = BigInt(23);
514
+ const _27n = BigInt(27);
515
+ const _29n = BigInt(29);
516
+ const _31n = BigInt(31);
517
+ const _32n = BigInt(32);
518
+ const _33n = BigInt(33);
519
+ const _64n = BigInt(64);
520
+ const _256n = BigInt(256);
521
+
522
+ function rotl(a: bigint, b: bigint): bigint {
523
+ const c = a & U64;
524
+ return ((c << b) | (c >> (_64n - b))) & U64;
525
+ }
526
+
527
+ function fromU8a(u8a: Uint8Array, p: number, count: number): bigint {
528
+ const bigints = new Array<bigint>(count);
529
+ let offset = 0;
530
+ for (let i = 0; i < count; i++, offset += 2) {
531
+ bigints[i] = BigInt(u8a[p + offset] | (u8a[p + 1 + offset] << 8));
532
+ }
533
+ let result = _0n;
534
+ for (let i = count - 1; i >= 0; i--) {
535
+ result = (result << _16n) + bigints[i];
536
+ }
537
+ return result;
538
+ }
539
+
540
+ function xxhashInit(seed: bigint, input: Uint8Array): { seed: bigint; u8a: Uint8Array; u8asize: number; v1: bigint; v2: bigint; v3: bigint; v4: bigint } {
541
+ const state = {
542
+ seed,
543
+ u8a: new Uint8Array(32),
544
+ u8asize: 0,
545
+ v1: seed + P64_1 + P64_2,
546
+ v2: seed + P64_2,
547
+ v3: seed,
548
+ v4: seed - P64_1
549
+ };
550
+
551
+ if (input.length < 32) {
552
+ state.u8a.set(input);
553
+ state.u8asize = input.length;
554
+ return state;
555
+ }
556
+
557
+ const limit = input.length - 32;
558
+ let p = 0;
559
+ if (limit >= 0) {
560
+ const adjustV = (v: bigint) => P64_1 * rotl(v + P64_2 * fromU8a(input, p, 4), _31n);
561
+ do {
562
+ state.v1 = adjustV(state.v1); p += 8;
563
+ state.v2 = adjustV(state.v2); p += 8;
564
+ state.v3 = adjustV(state.v3); p += 8;
565
+ state.v4 = adjustV(state.v4); p += 8;
566
+ } while (p <= limit);
567
+ }
568
+
569
+ if (p < input.length) {
570
+ state.u8a.set(input.subarray(p, input.length));
571
+ state.u8asize = input.length - p;
572
+ }
573
+
574
+ return state;
575
+ }
576
+
577
+ function xxhash64(input: Uint8Array, initSeed: number): Uint8Array {
578
+ const { seed, u8a, u8asize, v1, v2, v3, v4 } = xxhashInit(BigInt(initSeed), input);
579
+ let p = 0;
580
+ let h64 = U64 & (BigInt(input.length) + (input.length >= 32
581
+ ? (((((((((rotl(v1, _1n) + rotl(v2, _7n) + rotl(v3, _12n) + rotl(v4, _18n)) ^ (P64_1 * rotl(v1 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v2 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v3 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v4 * P64_2, _31n))) * P64_1 + P64_4)
582
+ : (seed + P64_5)));
583
+
584
+ while (p <= (u8asize - 8)) {
585
+ h64 = U64 & (P64_4 + P64_1 * rotl(h64 ^ (P64_1 * rotl(P64_2 * fromU8a(u8a, p, 4), _31n)), _27n));
586
+ p += 8;
587
+ }
588
+ if ((p + 4) <= u8asize) {
589
+ h64 = U64 & (P64_3 + P64_2 * rotl(h64 ^ (P64_1 * fromU8a(u8a, p, 2)), _23n));
590
+ p += 4;
591
+ }
592
+ while (p < u8asize) {
593
+ h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * BigInt(u8a[p++])), _11n));
594
+ }
595
+ h64 = U64 & (P64_2 * (h64 ^ (h64 >> _33n)));
596
+ h64 = U64 & (P64_3 * (h64 ^ (h64 >> _29n)));
597
+ h64 = U64 & (h64 ^ (h64 >> _32n));
598
+
599
+ const result = new Uint8Array(8);
600
+ for (let i = 7; i >= 0; i--) {
601
+ result[i] = Number(h64 % _256n);
602
+ h64 = h64 / _256n;
603
+ }
604
+ return result;
605
+ }
606
+
607
+ export function twox(data: Uint8Array, rounds: number): Uint8Array {
608
+ const result = new Uint8Array(rounds * 8);
609
+ for (let seed = 0; seed < rounds; seed++) {
610
+ result.set(xxhash64(data, seed).reverse(), seed * 8);
611
+ }
612
+ return result;
613
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ // Re-export everything from bundle
5
+ export * from './bundle.js';
package/src/init.ts ADDED
@@ -0,0 +1,25 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import type { InitFn } from '@pezkuwi/wasm-bridge/types';
5
+ import type { WasmCryptoInstance } from '@pezkuwi/wasm-crypto-init/types';
6
+
7
+ import { Bridge } from '@pezkuwi/wasm-bridge';
8
+ import { createWasm } from '@pezkuwi/wasm-crypto-init';
9
+
10
+ /**
11
+ * @name bridge
12
+ * @description
13
+ * The JS <-> WASM bridge that is in operation. For the specific package
14
+ * it is a global, i.e. all operations happens on this specific bridge
15
+ */
16
+ export const bridge = new Bridge<WasmCryptoInstance>(createWasm);
17
+
18
+ /**
19
+ * @name initBridge
20
+ * @description
21
+ * Creates a new bridge interface with the (optional) initialization function
22
+ */
23
+ export async function initBridge (createWasm?: InitFn<WasmCryptoInstance>): Promise<WasmCryptoInstance | null> {
24
+ return bridge.init(createWasm);
25
+ }
@@ -0,0 +1,23 @@
1
+ // Copyright 2019-2026 @pezkuwi/wasm-crypto authors & contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+
4
+ import { createWasm } from '@pezkuwi/wasm-crypto-init/none';
5
+
6
+ import { initBridge } from './init.js';
7
+
8
+ /**
9
+ * @name initWasm
10
+ * @description
11
+ * For historic purposes and for tighter control on init, specifically performing
12
+ * a WASM initialization with no interface whatsoever (no WASM, no ASM.js)
13
+ *
14
+ * Generally should not be used unless you want explicit control over which
15
+ * interfaces are initialized.
16
+ */
17
+ export async function initWasm (): Promise<void> {
18
+ await initBridge(createWasm);
19
+ }
20
+
21
+ initWasm().catch((): void => {
22
+ // cannot happen, initWasm doesn't throw
23
+ });