@totemsdk/core 1.0.9 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +5 -5
- package/dist/Streamable.js +54 -31
- package/dist/adapters/index.js +18 -8
- package/dist/adapters/types.js +19 -8
- package/dist/binio.js +5 -1
- package/dist/bip39.js +24 -14
- package/dist/derive.js +11 -7
- package/dist/index.js +130 -22
- package/dist/javaStreamables.js +49 -30
- package/dist/lease/LeaseMonitor.js +7 -3
- package/dist/lease/LeaseStore.js +7 -3
- package/dist/lease/WatermarkStore.js +7 -3
- package/dist/lease/index.js +13 -4
- package/dist/lease-client.js +8 -3
- package/dist/minima32.js +22 -13
- package/dist/minimaWireSerializer.js +20 -14
- package/dist/mmr.js +35 -23
- package/dist/mx.js +10 -1
- package/dist/params.js +9 -5
- package/dist/script.js +12 -7
- package/dist/scripts/contract-helpers.js +37 -26
- package/dist/scripts/dapp-types.js +11 -6
- package/dist/scripts/index.js +38 -4
- package/dist/scripts/types.js +26 -12
- package/dist/scripts/witness-serializer.js +48 -30
- package/dist/transaction.js +55 -46
- package/dist/treekey.js +74 -58
- package/dist/tx/TransactionLifecycle.js +11 -5
- package/dist/tx/TransactionReceiptStore.js +7 -3
- package/dist/tx/TransactionService.js +14 -10
- package/dist/tx/index.js +11 -3
- package/dist/tx/types.js +2 -1
- package/dist/util.js +5 -1
- package/dist/utils.js +12 -5
- package/dist/verify.js +36 -25
- package/dist/version.js +5 -2
- package/dist/wots.d.ts +2 -2
- package/dist/wots.js +94 -64
- package/package.json +50 -6
- package/src/Streamable.d.ts +0 -268
- package/src/Streamable.js +0 -416
- package/src/Streamable.ts +0 -567
- package/src/__tests__/Streamable.parity.test.ts +0 -422
- package/src/__tests__/perAddressDerivation.parity.test.ts +0 -152
- package/src/__tests__/roottree-prepare.test.ts +0 -101
- package/src/__tests__/wots-parity.test.ts +0 -289
- package/src/adapters/index.d.ts +0 -190
- package/src/adapters/index.js +0 -117
- package/src/adapters/index.ts +0 -301
- package/src/adapters/types.ts +0 -235
- package/src/addr.oracle.test.ts +0 -25
- package/src/address.test.ts +0 -55
- package/src/binio.ts +0 -21
- package/src/bip39.d.ts +0 -91
- package/src/bip39.js +0 -427
- package/src/bip39.ts +0 -432
- package/src/derive.d.ts +0 -2
- package/src/derive.js +0 -13
- package/src/derive.ts +0 -11
- package/src/index.d.ts +0 -26
- package/src/index.js +0 -128
- package/src/index.test.ts +0 -5
- package/src/index.ts +0 -221
- package/src/javaStreamables.d.ts +0 -233
- package/src/javaStreamables.js +0 -332
- package/src/javaStreamables.ts +0 -403
- package/src/lease/LeaseMonitor.d.ts +0 -44
- package/src/lease/LeaseMonitor.js +0 -111
- package/src/lease/LeaseMonitor.ts +0 -157
- package/src/lease/LeaseStore.d.ts +0 -57
- package/src/lease/LeaseStore.js +0 -148
- package/src/lease/LeaseStore.ts +0 -203
- package/src/lease/WatermarkStore.d.ts +0 -61
- package/src/lease/WatermarkStore.js +0 -206
- package/src/lease/WatermarkStore.ts +0 -270
- package/src/lease/index.d.ts +0 -14
- package/src/lease/index.js +0 -22
- package/src/lease/index.ts +0 -41
- package/src/lease-client.d.ts +0 -31
- package/src/lease-client.js +0 -44
- package/src/lease-client.ts +0 -69
- package/src/minima32.d.ts +0 -10
- package/src/minima32.js +0 -113
- package/src/minima32.test.ts +0 -11
- package/src/minima32.ts +0 -127
- package/src/minimaWireSerializer.d.ts +0 -189
- package/src/minimaWireSerializer.js +0 -311
- package/src/minimaWireSerializer.test.ts +0 -466
- package/src/minimaWireSerializer.ts +0 -117
- package/src/mmr.d.ts +0 -157
- package/src/mmr.js +0 -340
- package/src/mmr.oracle.test.ts +0 -28
- package/src/mmr.ts +0 -429
- package/src/mx.test.ts +0 -25
- package/src/mx.ts +0 -1
- package/src/params.d.ts +0 -29
- package/src/params.d.ts.map +0 -1
- package/src/params.js +0 -20
- package/src/params.js.map +0 -1
- package/src/params.ts +0 -44
- package/src/script.d.ts +0 -7
- package/src/script.js +0 -27
- package/src/script.ts +0 -24
- package/src/scripts/contract-helpers.ts +0 -609
- package/src/scripts/dapp-types.ts +0 -240
- package/src/scripts/index.ts +0 -22
- package/src/scripts/types.d.ts +0 -81
- package/src/scripts/types.js +0 -145
- package/src/scripts/types.ts +0 -247
- package/src/scripts/witness-serializer.ts +0 -384
- package/src/transaction.ts +0 -430
- package/src/treekey.d.ts +0 -383
- package/src/treekey.js +0 -774
- package/src/treekey.parity.test.ts +0 -459
- package/src/treekey.ts +0 -975
- package/src/tx/TransactionLifecycle.d.ts +0 -55
- package/src/tx/TransactionLifecycle.js +0 -188
- package/src/tx/TransactionLifecycle.ts +0 -280
- package/src/tx/TransactionReceiptStore.d.ts +0 -36
- package/src/tx/TransactionReceiptStore.js +0 -89
- package/src/tx/TransactionReceiptStore.ts +0 -112
- package/src/tx/TransactionService.d.ts +0 -31
- package/src/tx/TransactionService.js +0 -140
- package/src/tx/TransactionService.ts +0 -252
- package/src/tx/index.d.ts +0 -13
- package/src/tx/index.js +0 -20
- package/src/tx/index.ts +0 -44
- package/src/tx/types.d.ts +0 -80
- package/src/tx/types.js +0 -6
- package/src/tx/types.ts +0 -130
- package/src/util.d.ts +0 -1
- package/src/util.js +0 -5
- package/src/util.ts +0 -1
- package/src/utils.d.ts +0 -8
- package/src/utils.js +0 -42
- package/src/utils.ts +0 -38
- package/src/verify.ts +0 -210
- package/src/version.ts +0 -13
- package/src/wots.d.ts +0 -224
- package/src/wots.d.ts.map +0 -1
- package/src/wots.js +0 -565
- package/src/wots.js.map +0 -1
- package/src/wots.ts +0 -651
- package/test-vectors.json +0 -45
package/dist/verify.js
CHANGED
|
@@ -1,15 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.normalizeHex = normalizeHex;
|
|
4
|
+
exports.hexToBytes = hexToBytes;
|
|
5
|
+
exports.bytesToHex = bytesToHex;
|
|
6
|
+
exports.deriveAddressFromPublicKey = deriveAddressFromPublicKey;
|
|
7
|
+
exports.verifyTreeSignatureDetailed = verifyTreeSignatureDetailed;
|
|
8
|
+
exports.verifySignature = verifySignature;
|
|
9
|
+
exports.verifySignatureDetailed = verifySignatureDetailed;
|
|
10
|
+
exports.createChallenge = createChallenge;
|
|
11
|
+
exports.validateChallenge = validateChallenge;
|
|
12
|
+
const sha3_js_1 = require("@noble/hashes/sha3.js");
|
|
13
|
+
const treekey_js_1 = require("./treekey.js");
|
|
14
|
+
const derive_js_1 = require("./derive.js");
|
|
15
|
+
const script_js_1 = require("./script.js");
|
|
16
|
+
const treekey_js_2 = require("./treekey.js");
|
|
17
|
+
const wots_js_1 = require("./wots.js");
|
|
18
|
+
const params_js_1 = require("./params.js");
|
|
19
|
+
function normalizeHex(hex) {
|
|
9
20
|
const stripped = hex.startsWith('0x') ? hex.slice(2) : hex;
|
|
10
21
|
return stripped.toLowerCase();
|
|
11
22
|
}
|
|
12
|
-
|
|
23
|
+
function hexToBytes(hex) {
|
|
13
24
|
const h = normalizeHex(hex);
|
|
14
25
|
if (h.length % 2 !== 0)
|
|
15
26
|
throw new Error('Invalid hex string: odd length');
|
|
@@ -19,28 +30,28 @@ export function hexToBytes(hex) {
|
|
|
19
30
|
}
|
|
20
31
|
return bytes;
|
|
21
32
|
}
|
|
22
|
-
|
|
33
|
+
function bytesToHex(bytes) {
|
|
23
34
|
return Array.from(bytes)
|
|
24
35
|
.map(b => b.toString(16).padStart(2, '0'))
|
|
25
36
|
.join('');
|
|
26
37
|
}
|
|
27
|
-
|
|
38
|
+
function deriveAddressFromPublicKey(publicKeyHex) {
|
|
28
39
|
const pkBytes = hexToBytes(publicKeyHex);
|
|
29
40
|
if (pkBytes.length !== 32) {
|
|
30
41
|
throw new Error(`Public key must be 32 bytes (64 hex chars), got ${pkBytes.length} bytes`);
|
|
31
42
|
}
|
|
32
|
-
const script = scriptFromWotsPk(pkBytes);
|
|
33
|
-
return scriptToAddress(script);
|
|
43
|
+
const script = (0, script_js_1.scriptFromWotsPk)(pkBytes);
|
|
44
|
+
return (0, derive_js_1.scriptToAddress)(script);
|
|
34
45
|
}
|
|
35
|
-
|
|
46
|
+
function verifyTreeSignatureDetailed(expectedPubkey, data, signature) {
|
|
36
47
|
const { proofs } = signature;
|
|
37
48
|
if (proofs.length === 0) {
|
|
38
49
|
return { valid: false, error: 'Signature contains no proofs' };
|
|
39
50
|
}
|
|
40
|
-
const paramSet = getParamSet();
|
|
51
|
+
const paramSet = (0, params_js_1.getParamSet)();
|
|
41
52
|
for (let depth = 0; depth < proofs.length; depth++) {
|
|
42
53
|
const proof = proofs[depth];
|
|
43
|
-
const rootPubkey = getRootPublicKey(proof);
|
|
54
|
+
const rootPubkey = (0, treekey_js_2.getRootPublicKey)(proof);
|
|
44
55
|
if (depth === 0) {
|
|
45
56
|
if (!timingSafeEqual(expectedPubkey, rootPubkey)) {
|
|
46
57
|
return {
|
|
@@ -54,9 +65,9 @@ export function verifyTreeSignatureDetailed(expectedPubkey, data, signature) {
|
|
|
54
65
|
signedData = data;
|
|
55
66
|
}
|
|
56
67
|
else {
|
|
57
|
-
signedData = getRootPublicKey(proofs[depth + 1]);
|
|
68
|
+
signedData = (0, treekey_js_2.getRootPublicKey)(proofs[depth + 1]);
|
|
58
69
|
}
|
|
59
|
-
if (!wotsVerifyDigest(proof.signature, signedData, proof.leafPubkey, paramSet)) {
|
|
70
|
+
if (!(0, wots_js_1.wotsVerifyDigest)(proof.signature, signedData, proof.leafPubkey, paramSet)) {
|
|
60
71
|
return {
|
|
61
72
|
valid: false,
|
|
62
73
|
error: `WOTS signature verification failed at depth ${depth} (digest mismatch or corrupted signature)`,
|
|
@@ -65,11 +76,11 @@ export function verifyTreeSignatureDetailed(expectedPubkey, data, signature) {
|
|
|
65
76
|
}
|
|
66
77
|
return { valid: true };
|
|
67
78
|
}
|
|
68
|
-
|
|
79
|
+
function verifySignature(address, message, signatureHex, publicKeyHex) {
|
|
69
80
|
const result = verifySignatureDetailed(address, message, signatureHex, publicKeyHex);
|
|
70
81
|
return result.valid;
|
|
71
82
|
}
|
|
72
|
-
|
|
83
|
+
function verifySignatureDetailed(address, message, signatureHex, publicKeyHex) {
|
|
73
84
|
try {
|
|
74
85
|
const pkBytes = hexToBytes(publicKeyHex);
|
|
75
86
|
if (pkBytes.length !== 32) {
|
|
@@ -88,7 +99,7 @@ export function verifySignatureDetailed(address, message, signatureHex, publicKe
|
|
|
88
99
|
const sigBytes = hexToBytes(signatureHex);
|
|
89
100
|
let treeSignature;
|
|
90
101
|
try {
|
|
91
|
-
treeSignature = deserializeTreeSignature(sigBytes);
|
|
102
|
+
treeSignature = (0, treekey_js_1.deserializeTreeSignature)(sigBytes);
|
|
92
103
|
}
|
|
93
104
|
catch (e) {
|
|
94
105
|
return {
|
|
@@ -96,7 +107,7 @@ export function verifySignatureDetailed(address, message, signatureHex, publicKe
|
|
|
96
107
|
error: `Malformed signature: ${e.message}`,
|
|
97
108
|
};
|
|
98
109
|
}
|
|
99
|
-
const digest = sha3_256(new TextEncoder().encode(message));
|
|
110
|
+
const digest = (0, sha3_js_1.sha3_256)(new TextEncoder().encode(message));
|
|
100
111
|
return verifyTreeSignatureDetailed(pkBytes, digest, treeSignature);
|
|
101
112
|
}
|
|
102
113
|
catch (e) {
|
|
@@ -132,12 +143,12 @@ function cryptoRandomBytes(length) {
|
|
|
132
143
|
}
|
|
133
144
|
return buf;
|
|
134
145
|
}
|
|
135
|
-
|
|
146
|
+
function createChallenge(domain, nonce) {
|
|
136
147
|
const ts = Date.now();
|
|
137
|
-
const n = nonce || bytesToHex(sha3_256(new Uint8Array([...new TextEncoder().encode(`${domain}:${ts}:`), ...cryptoRandomBytes(16)]))).slice(0, 16);
|
|
148
|
+
const n = nonce || bytesToHex((0, sha3_js_1.sha3_256)(new Uint8Array([...new TextEncoder().encode(`${domain}:${ts}:`), ...cryptoRandomBytes(16)]))).slice(0, 16);
|
|
138
149
|
return JSON.stringify({ domain, nonce: n, issuedAt: ts });
|
|
139
150
|
}
|
|
140
|
-
|
|
151
|
+
function validateChallenge(challenge, options) {
|
|
141
152
|
try {
|
|
142
153
|
const parsed = JSON.parse(challenge);
|
|
143
154
|
const { domain, nonce, issuedAt } = parsed;
|
package/dist/version.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* SDK Core Version Information
|
|
3
4
|
*
|
|
@@ -8,5 +9,7 @@
|
|
|
8
9
|
* If you see different CORE_BUILD_IDs logged from wallet creation
|
|
9
10
|
* vs signing modules, there's a bundling issue.
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.CORE_VERSION = exports.CORE_BUILD_ID = void 0;
|
|
14
|
+
exports.CORE_BUILD_ID = '2026.02.05-v1';
|
|
15
|
+
exports.CORE_VERSION = '1.0.0';
|
package/dist/wots.d.ts
CHANGED
|
@@ -31,14 +31,14 @@ export declare function disableWotsLogger(): void;
|
|
|
31
31
|
* Check if WOTS debug logging is enabled
|
|
32
32
|
*/
|
|
33
33
|
export declare function isWotsDebugEnabled(): boolean;
|
|
34
|
-
export declare const F: (x: Uint8Array) => Uint8Array<ArrayBufferLike>;
|
|
34
|
+
export declare const F: (x: Uint8Array) => Uint8Array<ArrayBufferLike> & Uint8Array<ArrayBuffer>;
|
|
35
35
|
export declare const hex: (u: Uint8Array) => string;
|
|
36
36
|
export declare const fromHex: (h: string) => Uint8Array;
|
|
37
37
|
export declare const concatBytes: (...arrs: Uint8Array[]) => Uint8Array<ArrayBuffer>;
|
|
38
38
|
export declare const u16be: (n: number) => Uint8Array<ArrayBuffer>;
|
|
39
39
|
export declare const u32be: (n: number) => Uint8Array<ArrayBuffer>;
|
|
40
40
|
export declare function assert32(u: Uint8Array, label?: string): void;
|
|
41
|
-
export declare const h: (x: Uint8Array) => Uint8Array<ArrayBufferLike>;
|
|
41
|
+
export declare const h: (x: Uint8Array) => Uint8Array<ArrayBufferLike> & Uint8Array<ArrayBuffer>;
|
|
42
42
|
/**
|
|
43
43
|
* GMSSRandom - BouncyCastle's stateful PRNG for WOTS chain seed derivation
|
|
44
44
|
*
|
package/dist/wots.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* WOTS Implementation - BouncyCastle Compatible
|
|
3
4
|
*
|
|
@@ -12,12 +13,34 @@
|
|
|
12
13
|
*
|
|
13
14
|
* Source: org.bouncycastle.pqc.crypto.gmss.util.{WinternitzOTSignature, WinternitzOTSVerify, GMSSRandom}
|
|
14
15
|
*/
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.GMSSRandom = exports.h = exports.u32be = exports.u16be = exports.concatBytes = exports.fromHex = exports.hex = exports.F = void 0;
|
|
18
|
+
exports.setWotsLogger = setWotsLogger;
|
|
19
|
+
exports.disableWotsLogger = disableWotsLogger;
|
|
20
|
+
exports.isWotsDebugEnabled = isWotsDebugEnabled;
|
|
21
|
+
exports.assert32 = assert32;
|
|
22
|
+
exports.getLog = getLog;
|
|
23
|
+
exports.expandPrivateKey = expandPrivateKey;
|
|
24
|
+
exports.toWinternitzDigits = toWinternitzDigits;
|
|
25
|
+
exports.baseWWithChecksum = baseWWithChecksum;
|
|
26
|
+
exports.hashChain = hashChain;
|
|
27
|
+
exports.deriveIndexedSeed = deriveIndexedSeed;
|
|
28
|
+
exports.derivePKdigest = derivePKdigest;
|
|
29
|
+
exports.deriveFullPublicKey = deriveFullPublicKey;
|
|
30
|
+
exports.wotsKeypairFromSeed = wotsKeypairFromSeed;
|
|
31
|
+
exports.wotsSign = wotsSign;
|
|
32
|
+
exports.wotsSignLegacy = wotsSignLegacy;
|
|
33
|
+
exports.wotsPkFromSig = wotsPkFromSig;
|
|
34
|
+
exports.wotsVerify = wotsVerify;
|
|
35
|
+
exports.wotsVerifyDigest = wotsVerifyDigest;
|
|
36
|
+
exports.wotsPublicKeyFromSeed = wotsPublicKeyFromSeed;
|
|
37
|
+
exports.prfChainSeed = prfChainSeed;
|
|
38
|
+
const sha3_js_1 = require("@noble/hashes/sha3.js");
|
|
39
|
+
const params_js_1 = require("./params.js");
|
|
40
|
+
const javaStreamables_js_1 = require("./javaStreamables.js");
|
|
41
|
+
const index_js_1 = require("./adapters/index.js");
|
|
19
42
|
// Module-level debug logger - can be set externally for parity testing
|
|
20
|
-
let wotsLogger = new NoopLogger();
|
|
43
|
+
let wotsLogger = new index_js_1.NoopLogger();
|
|
21
44
|
let wotsDebugEnabled = false;
|
|
22
45
|
/**
|
|
23
46
|
* Enable WOTS debug logging with a custom logger
|
|
@@ -27,39 +50,42 @@ let wotsDebugEnabled = false;
|
|
|
27
50
|
* private key chains and seeds. NEVER enable in production builds.
|
|
28
51
|
* This is intended for development/testing parity verification only.
|
|
29
52
|
*/
|
|
30
|
-
|
|
53
|
+
function setWotsLogger(logger) {
|
|
31
54
|
wotsLogger = logger;
|
|
32
55
|
wotsDebugEnabled = true;
|
|
33
56
|
}
|
|
34
57
|
/**
|
|
35
58
|
* Disable WOTS debug logging
|
|
36
59
|
*/
|
|
37
|
-
|
|
38
|
-
wotsLogger = new NoopLogger();
|
|
60
|
+
function disableWotsLogger() {
|
|
61
|
+
wotsLogger = new index_js_1.NoopLogger();
|
|
39
62
|
wotsDebugEnabled = false;
|
|
40
63
|
}
|
|
41
64
|
/**
|
|
42
65
|
* Check if WOTS debug logging is enabled
|
|
43
66
|
*/
|
|
44
|
-
|
|
67
|
+
function isWotsDebugEnabled() {
|
|
45
68
|
return wotsDebugEnabled;
|
|
46
69
|
}
|
|
47
70
|
// === Canonical helpers ===
|
|
48
|
-
|
|
49
|
-
|
|
71
|
+
const F = (x) => (0, sha3_js_1.sha3_256)(x);
|
|
72
|
+
exports.F = F;
|
|
73
|
+
const hex = (u) => {
|
|
50
74
|
let s = '';
|
|
51
75
|
for (let i = 0; i < u.length; i++)
|
|
52
76
|
s += u[i].toString(16).padStart(2, '0');
|
|
53
77
|
return s;
|
|
54
78
|
};
|
|
55
|
-
|
|
79
|
+
exports.hex = hex;
|
|
80
|
+
const fromHex = (h) => {
|
|
56
81
|
const s = h.replace(/^0x/, '');
|
|
57
82
|
const out = new Uint8Array(s.length >> 1);
|
|
58
83
|
for (let i = 0; i < out.length; i++)
|
|
59
84
|
out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);
|
|
60
85
|
return out;
|
|
61
86
|
};
|
|
62
|
-
|
|
87
|
+
exports.fromHex = fromHex;
|
|
88
|
+
const concatBytes = (...arrs) => {
|
|
63
89
|
const len = arrs.reduce((n, a) => n + a.length, 0);
|
|
64
90
|
const out = new Uint8Array(len);
|
|
65
91
|
let o = 0;
|
|
@@ -69,9 +95,12 @@ export const concatBytes = (...arrs) => {
|
|
|
69
95
|
}
|
|
70
96
|
return out;
|
|
71
97
|
};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
98
|
+
exports.concatBytes = concatBytes;
|
|
99
|
+
const u16be = (n) => new Uint8Array([(n >>> 8) & 0xff, n & 0xff]);
|
|
100
|
+
exports.u16be = u16be;
|
|
101
|
+
const u32be = (n) => new Uint8Array([(n >>> 24) & 255, (n >>> 16) & 255, (n >>> 8) & 255, n & 255]);
|
|
102
|
+
exports.u32be = u32be;
|
|
103
|
+
function assert32(u, label = 'value') {
|
|
75
104
|
if (!(u instanceof Uint8Array))
|
|
76
105
|
throw new Error(`${label} must be a Uint8Array`);
|
|
77
106
|
if (u.length !== 32)
|
|
@@ -79,9 +108,9 @@ export function assert32(u, label = 'value') {
|
|
|
79
108
|
}
|
|
80
109
|
// Legacy aliases
|
|
81
110
|
const u8 = (len) => new Uint8Array(len);
|
|
82
|
-
|
|
83
|
-
const concat = concatBytes;
|
|
84
|
-
const defaultParamSet = getParamSet();
|
|
111
|
+
exports.h = exports.F;
|
|
112
|
+
const concat = exports.concatBytes;
|
|
113
|
+
const defaultParamSet = (0, params_js_1.getParamSet)();
|
|
85
114
|
/**
|
|
86
115
|
* GMSSRandom - BouncyCastle's stateful PRNG for WOTS chain seed derivation
|
|
87
116
|
*
|
|
@@ -92,7 +121,7 @@ const defaultParamSet = getParamSet();
|
|
|
92
121
|
*
|
|
93
122
|
* The state is MUTATED in place after each call.
|
|
94
123
|
*/
|
|
95
|
-
|
|
124
|
+
class GMSSRandom {
|
|
96
125
|
/**
|
|
97
126
|
* Generate next random value and update state
|
|
98
127
|
*
|
|
@@ -102,7 +131,7 @@ export class GMSSRandom {
|
|
|
102
131
|
static nextSeed(state) {
|
|
103
132
|
assert32(state, 'state');
|
|
104
133
|
// rand = H(state)
|
|
105
|
-
const rand = F(state);
|
|
134
|
+
const rand = (0, exports.F)(state);
|
|
106
135
|
// state = state + rand (byte-wise addition with carry, little-endian)
|
|
107
136
|
GMSSRandom.addByteArrays(state, rand);
|
|
108
137
|
// state = state + 1
|
|
@@ -136,6 +165,7 @@ export class GMSSRandom {
|
|
|
136
165
|
}
|
|
137
166
|
}
|
|
138
167
|
}
|
|
168
|
+
exports.GMSSRandom = GMSSRandom;
|
|
139
169
|
/**
|
|
140
170
|
* getLog - Calculate ceil(log2(x))
|
|
141
171
|
*
|
|
@@ -145,7 +175,7 @@ export class GMSSRandom {
|
|
|
145
175
|
* while (i < intValue) { i <<= 1; log++; }
|
|
146
176
|
* return log;
|
|
147
177
|
*/
|
|
148
|
-
|
|
178
|
+
function getLog(intValue) {
|
|
149
179
|
let log = 1;
|
|
150
180
|
let i = 2;
|
|
151
181
|
while (i < intValue) {
|
|
@@ -164,13 +194,13 @@ export function getLog(intValue) {
|
|
|
164
194
|
* privateKeyOTS[i] = gmssRandom.nextSeed(dummy);
|
|
165
195
|
* }
|
|
166
196
|
*/
|
|
167
|
-
|
|
197
|
+
function expandPrivateKey(seed, ps = (0, params_js_1.getParamSet)()) {
|
|
168
198
|
assert32(seed, 'seed');
|
|
169
199
|
// Copy seed to mutable state
|
|
170
200
|
const state = new Uint8Array(seed);
|
|
171
201
|
if (wotsDebugEnabled) {
|
|
172
|
-
wotsLogger.debug(`[expandPrivateKey] Input seed: ${hex(seed).substring(0, 64)}...`);
|
|
173
|
-
wotsLogger.debug(`[expandPrivateKey] Initial state: ${hex(state).substring(0, 64)}...`);
|
|
202
|
+
wotsLogger.debug(`[expandPrivateKey] Input seed: ${(0, exports.hex)(seed).substring(0, 64)}...`);
|
|
203
|
+
wotsLogger.debug(`[expandPrivateKey] Initial state: ${(0, exports.hex)(state).substring(0, 64)}...`);
|
|
174
204
|
}
|
|
175
205
|
// Generate L chain seeds using stateful PRNG
|
|
176
206
|
const privateKeys = [];
|
|
@@ -179,13 +209,13 @@ export function expandPrivateKey(seed, ps = getParamSet()) {
|
|
|
179
209
|
privateKeys.push(pk);
|
|
180
210
|
// Log first few private keys for debugging
|
|
181
211
|
if (wotsDebugEnabled && i < 3) {
|
|
182
|
-
wotsLogger.debug(`[expandPrivateKey] pk[${i}]: ${hex(pk)}`);
|
|
183
|
-
wotsLogger.debug(`[expandPrivateKey] state after pk[${i}]: ${hex(state).substring(0, 32)}...`);
|
|
212
|
+
wotsLogger.debug(`[expandPrivateKey] pk[${i}]: ${(0, exports.hex)(pk)}`);
|
|
213
|
+
wotsLogger.debug(`[expandPrivateKey] state after pk[${i}]: ${(0, exports.hex)(state).substring(0, 32)}...`);
|
|
184
214
|
}
|
|
185
215
|
}
|
|
186
216
|
if (wotsDebugEnabled) {
|
|
187
217
|
wotsLogger.debug(`[expandPrivateKey] Generated ${privateKeys.length} private keys`);
|
|
188
|
-
wotsLogger.debug(`[expandPrivateKey] pk[33] (last): ${hex(privateKeys[33])}`);
|
|
218
|
+
wotsLogger.debug(`[expandPrivateKey] pk[33] (last): ${(0, exports.hex)(privateKeys[33])}`);
|
|
189
219
|
}
|
|
190
220
|
return privateKeys;
|
|
191
221
|
}
|
|
@@ -200,7 +230,7 @@ export function expandPrivateKey(seed, ps = getParamSet()) {
|
|
|
200
230
|
*
|
|
201
231
|
* Matches WinternitzOTSignature.getSignature() for w=8 case
|
|
202
232
|
*/
|
|
203
|
-
|
|
233
|
+
function toWinternitzDigits(hash32, ps = (0, params_js_1.getParamSet)()) {
|
|
204
234
|
assert32(hash32, 'hash');
|
|
205
235
|
if (ps.w !== 8) {
|
|
206
236
|
throw new Error(`Only w=8 is supported. Got w=${ps.w}`);
|
|
@@ -228,7 +258,7 @@ export function toWinternitzDigits(hash32, ps = getParamSet()) {
|
|
|
228
258
|
c >>>= ps.w;
|
|
229
259
|
}
|
|
230
260
|
if (wotsDebugEnabled) {
|
|
231
|
-
wotsLogger.debug(`[toWinternitzDigits] Input hash: ${hex(hash32)}`);
|
|
261
|
+
wotsLogger.debug(`[toWinternitzDigits] Input hash: ${(0, exports.hex)(hash32)}`);
|
|
232
262
|
wotsLogger.debug(`[toWinternitzDigits] First 5 message digits: [${digits.slice(0, 5).join(', ')}]`);
|
|
233
263
|
wotsLogger.debug(`[toWinternitzDigits] Last 5 message digits: [${digits.slice(-5).join(', ')}]`);
|
|
234
264
|
wotsLogger.debug(`[toWinternitzDigits] Digit sum: ${digitSum}`);
|
|
@@ -246,7 +276,7 @@ export function toWinternitzDigits(hash32, ps = getParamSet()) {
|
|
|
246
276
|
* Decompose digest into base-w digits + checksum
|
|
247
277
|
* Returns flat array of all L digits
|
|
248
278
|
*/
|
|
249
|
-
|
|
279
|
+
function baseWWithChecksum(msgHash, paramSet) {
|
|
250
280
|
const ps = paramSet || defaultParamSet;
|
|
251
281
|
const { digits, checksumDigits } = toWinternitzDigits(msgHash, ps);
|
|
252
282
|
const result = digits.concat(checksumDigits);
|
|
@@ -262,13 +292,13 @@ export function baseWWithChecksum(msgHash, paramSet) {
|
|
|
262
292
|
* - If rounds < 1: return input unchanged
|
|
263
293
|
* - Otherwise: hash `rounds` times
|
|
264
294
|
*/
|
|
265
|
-
|
|
295
|
+
function hashChain(x, rounds) {
|
|
266
296
|
if (rounds < 1) {
|
|
267
297
|
return new Uint8Array(x);
|
|
268
298
|
}
|
|
269
|
-
let result = F(x);
|
|
299
|
+
let result = (0, exports.F)(x);
|
|
270
300
|
for (let i = 1; i < rounds; i++) {
|
|
271
|
-
result = F(result);
|
|
301
|
+
result = (0, exports.F)(result);
|
|
272
302
|
}
|
|
273
303
|
return result;
|
|
274
304
|
}
|
|
@@ -284,12 +314,12 @@ export function hashChain(x, rounds) {
|
|
|
284
314
|
* This old implementation used H(seed || u32be(i)) which is NOT Java compatible.
|
|
285
315
|
* @deprecated Use deriveChainSeedJava from javaStreamables.ts
|
|
286
316
|
*/
|
|
287
|
-
|
|
317
|
+
function deriveIndexedSeed(seed, keyIndex) {
|
|
288
318
|
assert32(seed, 'seed');
|
|
289
319
|
// Use Java-compatible derivation: hashAllObjects(MiniNumber(i), MiniData(seed))
|
|
290
|
-
const result = deriveChainSeedJava(seed, keyIndex);
|
|
320
|
+
const result = (0, javaStreamables_js_1.deriveChainSeedJava)(seed, keyIndex);
|
|
291
321
|
if (wotsDebugEnabled) {
|
|
292
|
-
wotsLogger.debug(`[deriveIndexedSeed] seed=${hex(seed).substring(0, 32)}..., keyIndex=${keyIndex} => ${hex(result)}`);
|
|
322
|
+
wotsLogger.debug(`[deriveIndexedSeed] seed=${(0, exports.hex)(seed).substring(0, 32)}..., keyIndex=${keyIndex} => ${(0, exports.hex)(result)}`);
|
|
293
323
|
}
|
|
294
324
|
return result;
|
|
295
325
|
}
|
|
@@ -306,7 +336,7 @@ export function deriveIndexedSeed(seed, keyIndex) {
|
|
|
306
336
|
* }
|
|
307
337
|
* return H(buf);
|
|
308
338
|
*/
|
|
309
|
-
|
|
339
|
+
function derivePKdigest(seed, i, ps = (0, params_js_1.getParamSet)()) {
|
|
310
340
|
assert32(seed, 'seed');
|
|
311
341
|
// Derive unique seed for this key index
|
|
312
342
|
const indexedSeed = deriveIndexedSeed(seed, i);
|
|
@@ -320,7 +350,7 @@ export function derivePKdigest(seed, i, ps = getParamSet()) {
|
|
|
320
350
|
buf.set(top, j * 32);
|
|
321
351
|
}
|
|
322
352
|
// Return H(all chain tops)
|
|
323
|
-
return F(buf);
|
|
353
|
+
return (0, exports.F)(buf);
|
|
324
354
|
}
|
|
325
355
|
/**
|
|
326
356
|
* Derive full WOTS public key (L × 32 bytes) without final hash
|
|
@@ -328,16 +358,16 @@ export function derivePKdigest(seed, i, ps = getParamSet()) {
|
|
|
328
358
|
* Returns the concatenation of all chain tops BEFORE hashing.
|
|
329
359
|
* Required by Minima's SignatureProof which expects the full public key.
|
|
330
360
|
*/
|
|
331
|
-
|
|
361
|
+
function deriveFullPublicKey(seed, i, ps = (0, params_js_1.getParamSet)()) {
|
|
332
362
|
assert32(seed, 'seed');
|
|
333
363
|
if (wotsDebugEnabled) {
|
|
334
364
|
wotsLogger.debug(`[deriveFullPublicKey] ========== PK DERIVATION START ==========`);
|
|
335
|
-
wotsLogger.debug(`[deriveFullPublicKey] Master seed: ${hex(seed).substring(0, 32)}..., keyIndex: ${i}`);
|
|
365
|
+
wotsLogger.debug(`[deriveFullPublicKey] Master seed: ${(0, exports.hex)(seed).substring(0, 32)}..., keyIndex: ${i}`);
|
|
336
366
|
}
|
|
337
367
|
// Derive unique seed for this key index
|
|
338
368
|
const indexedSeed = deriveIndexedSeed(seed, i);
|
|
339
369
|
if (wotsDebugEnabled) {
|
|
340
|
-
wotsLogger.debug(`[deriveFullPublicKey] Indexed seed: ${hex(indexedSeed)}`);
|
|
370
|
+
wotsLogger.debug(`[deriveFullPublicKey] Indexed seed: ${(0, exports.hex)(indexedSeed)}`);
|
|
341
371
|
}
|
|
342
372
|
const privateKeys = expandPrivateKey(indexedSeed, ps);
|
|
343
373
|
const rounds = ps.maxDigit; // 255
|
|
@@ -347,16 +377,16 @@ export function deriveFullPublicKey(seed, i, ps = getParamSet()) {
|
|
|
347
377
|
buf.set(top, j * 32);
|
|
348
378
|
// Log first few chain tops for debugging
|
|
349
379
|
if (wotsDebugEnabled && j < 3) {
|
|
350
|
-
wotsLogger.debug(`[deriveFullPublicKey] chain[${j}]: pk=${hex(privateKeys[j]).substring(0, 16)}... rounds=${rounds} => top=${hex(top).substring(0, 16)}...`);
|
|
380
|
+
wotsLogger.debug(`[deriveFullPublicKey] chain[${j}]: pk=${(0, exports.hex)(privateKeys[j]).substring(0, 16)}... rounds=${rounds} => top=${(0, exports.hex)(top).substring(0, 16)}...`);
|
|
351
381
|
}
|
|
352
382
|
}
|
|
353
383
|
if (wotsDebugEnabled) {
|
|
354
|
-
wotsLogger.debug(`[deriveFullPublicKey] Full public key (${buf.length}B): ${hex(buf).substring(0, 64)}...${hex(buf).substring(hex(buf).length - 32)}`);
|
|
384
|
+
wotsLogger.debug(`[deriveFullPublicKey] Full public key (${buf.length}B): ${(0, exports.hex)(buf).substring(0, 64)}...${(0, exports.hex)(buf).substring((0, exports.hex)(buf).length - 32)}`);
|
|
355
385
|
wotsLogger.debug(`[deriveFullPublicKey] ========== PK DERIVATION END ==========`);
|
|
356
386
|
}
|
|
357
387
|
return buf; // L * 32 = 1088 bytes
|
|
358
388
|
}
|
|
359
|
-
|
|
389
|
+
function wotsKeypairFromSeed(seed, index, paramSet) {
|
|
360
390
|
assert32(seed, 'seed');
|
|
361
391
|
const ps = paramSet || defaultParamSet;
|
|
362
392
|
const pkDigest = derivePKdigest(seed, index, ps);
|
|
@@ -378,25 +408,25 @@ export function wotsKeypairFromSeed(seed, index, paramSet) {
|
|
|
378
408
|
* @param ps - WOTS parameter set (default: minima)
|
|
379
409
|
* @returns Flat signature (L × 32 = 1088 bytes)
|
|
380
410
|
*/
|
|
381
|
-
|
|
411
|
+
function wotsSign(seed, i, message, ps = (0, params_js_1.getParamSet)()) {
|
|
382
412
|
assert32(seed, 'seed');
|
|
383
413
|
assert32(message, 'message');
|
|
384
414
|
if (wotsDebugEnabled) {
|
|
385
415
|
wotsLogger.debug(`[wotsSign] ========== WOTS SIGN START ==========`);
|
|
386
|
-
wotsLogger.debug(`[wotsSign] Master seed: ${hex(seed)}`);
|
|
416
|
+
wotsLogger.debug(`[wotsSign] Master seed: ${(0, exports.hex)(seed)}`);
|
|
387
417
|
wotsLogger.debug(`[wotsSign] Key index: ${i}`);
|
|
388
|
-
wotsLogger.debug(`[wotsSign] Message (raw): ${hex(message)}`);
|
|
418
|
+
wotsLogger.debug(`[wotsSign] Message (raw): ${(0, exports.hex)(message)}`);
|
|
389
419
|
}
|
|
390
420
|
// Derive unique seed for this key index
|
|
391
421
|
const indexedSeed = deriveIndexedSeed(seed, i);
|
|
392
422
|
if (wotsDebugEnabled) {
|
|
393
|
-
wotsLogger.debug(`[wotsSign] Indexed seed (after deriveIndexedSeed): ${hex(indexedSeed)}`);
|
|
423
|
+
wotsLogger.debug(`[wotsSign] Indexed seed (after deriveIndexedSeed): ${(0, exports.hex)(indexedSeed)}`);
|
|
394
424
|
}
|
|
395
425
|
const privateKeys = expandPrivateKey(indexedSeed, ps);
|
|
396
426
|
// CRITICAL: Hash the message internally to match Java/BouncyCastle Winternitz behavior
|
|
397
427
|
// Java's WinternitzOTSignature.getSignature() always hashes the message first
|
|
398
428
|
// Callers pass RAW 32-byte data (tx digest, child root), NOT pre-hashed!
|
|
399
|
-
const hashedMsg = F(message);
|
|
429
|
+
const hashedMsg = (0, exports.F)(message);
|
|
400
430
|
const { digits, checksumDigits } = toWinternitzDigits(hashedMsg, ps);
|
|
401
431
|
const allDigits = digits.concat(checksumDigits);
|
|
402
432
|
if (allDigits.length !== ps.L) {
|
|
@@ -412,11 +442,11 @@ export function wotsSign(seed, i, message, ps = getParamSet()) {
|
|
|
412
442
|
out.set(sigPart, j * 32);
|
|
413
443
|
// Log first few and last signature chains for debugging
|
|
414
444
|
if (wotsDebugEnabled && (j < 3 || j >= ps.L - 2)) {
|
|
415
|
-
wotsLogger.debug(`[wotsSign] chain[${j}]: pk=${hex(privateKeys[j]).substring(0, 16)}... rounds=${rounds} => sig=${hex(sigPart).substring(0, 16)}...`);
|
|
445
|
+
wotsLogger.debug(`[wotsSign] chain[${j}]: pk=${(0, exports.hex)(privateKeys[j]).substring(0, 16)}... rounds=${rounds} => sig=${(0, exports.hex)(sigPart).substring(0, 16)}...`);
|
|
416
446
|
}
|
|
417
447
|
}
|
|
418
448
|
if (wotsDebugEnabled) {
|
|
419
|
-
wotsLogger.debug(`[wotsSign] Signature output (${out.length} bytes): ${hex(out).substring(0, 64)}...${hex(out).substring(hex(out).length - 64)}`);
|
|
449
|
+
wotsLogger.debug(`[wotsSign] Signature output (${out.length} bytes): ${(0, exports.hex)(out).substring(0, 64)}...${(0, exports.hex)(out).substring((0, exports.hex)(out).length - 64)}`);
|
|
420
450
|
wotsLogger.debug(`[wotsSign] ========== WOTS SIGN END ==========`);
|
|
421
451
|
}
|
|
422
452
|
return out;
|
|
@@ -424,8 +454,8 @@ export function wotsSign(seed, i, message, ps = getParamSet()) {
|
|
|
424
454
|
/**
|
|
425
455
|
* Legacy wrapper returning structured signature
|
|
426
456
|
*/
|
|
427
|
-
|
|
428
|
-
const ps = paramSet || getParamSet();
|
|
457
|
+
function wotsSignLegacy(msgHash, seed, index, paramSet) {
|
|
458
|
+
const ps = paramSet || (0, params_js_1.getParamSet)();
|
|
429
459
|
const sig = wotsSign(seed, index, msgHash, ps);
|
|
430
460
|
const chunks = [];
|
|
431
461
|
for (let i = 0; i < ps.L; i++) {
|
|
@@ -445,10 +475,10 @@ export function wotsSignLegacy(msgHash, seed, index, paramSet) {
|
|
|
445
475
|
* CRITICAL: This function hashes the message internally to match Java/BouncyCastle
|
|
446
476
|
* Winternitz behavior. Both wotsSign and wotsPkFromSig hash internally for parity.
|
|
447
477
|
*/
|
|
448
|
-
|
|
478
|
+
function wotsPkFromSig(message, signature, paramSet) {
|
|
449
479
|
const ps = paramSet || defaultParamSet;
|
|
450
480
|
// CRITICAL: Hash the message internally to match Java/BouncyCastle Winternitz behavior
|
|
451
|
-
const hashedMsg = F(message);
|
|
481
|
+
const hashedMsg = (0, exports.F)(message);
|
|
452
482
|
const allDigits = baseWWithChecksum(hashedMsg, ps);
|
|
453
483
|
if (signature.sig.length !== ps.L) {
|
|
454
484
|
throw new Error(`Wrong signature length: expected ${ps.L}, got ${signature.sig.length}`);
|
|
@@ -459,7 +489,7 @@ export function wotsPkFromSig(message, signature, paramSet) {
|
|
|
459
489
|
const top = hashChain(signature.sig[i], stepsUp);
|
|
460
490
|
buf.set(top, i * 32);
|
|
461
491
|
}
|
|
462
|
-
return F(buf);
|
|
492
|
+
return (0, exports.F)(buf);
|
|
463
493
|
}
|
|
464
494
|
/**
|
|
465
495
|
* Verify WOTS signature against a FULL 1088-byte public key
|
|
@@ -480,7 +510,7 @@ export function wotsPkFromSig(message, signature, paramSet) {
|
|
|
480
510
|
* @param pkFull - The FULL 1088-byte WOTS public key (L=34 × 32 bytes)
|
|
481
511
|
* @param ps - WOTS parameter set (default: minima)
|
|
482
512
|
*/
|
|
483
|
-
|
|
513
|
+
function wotsVerify(sig, message, pkFull, ps = (0, params_js_1.getParamSet)()) {
|
|
484
514
|
// CRITICAL: Java verifies against FULL 1088-byte public key, not 32-byte digest
|
|
485
515
|
const expectedLen = ps.L * 32;
|
|
486
516
|
if (pkFull.length !== expectedLen) {
|
|
@@ -490,7 +520,7 @@ export function wotsVerify(sig, message, pkFull, ps = getParamSet()) {
|
|
|
490
520
|
return false;
|
|
491
521
|
}
|
|
492
522
|
// CRITICAL: Hash the message internally to match Java/BouncyCastle Winternitz behavior
|
|
493
|
-
const hashedMsg = F(message);
|
|
523
|
+
const hashedMsg = (0, exports.F)(message);
|
|
494
524
|
const allDigits = baseWWithChecksum(hashedMsg, ps);
|
|
495
525
|
const buf = new Uint8Array(expectedLen);
|
|
496
526
|
for (let j = 0; j < ps.L; j++) {
|
|
@@ -512,13 +542,13 @@ export function wotsVerify(sig, message, pkFull, ps = getParamSet()) {
|
|
|
512
542
|
* Legacy verify function that accepts a 32-byte digest
|
|
513
543
|
* @deprecated Use wotsVerify with full 1088-byte public key instead
|
|
514
544
|
*/
|
|
515
|
-
|
|
545
|
+
function wotsVerifyDigest(sig, message, pkDigest, ps = (0, params_js_1.getParamSet)()) {
|
|
516
546
|
assert32(pkDigest, 'pkDigest');
|
|
517
547
|
const expectedLen = ps.L * 32;
|
|
518
548
|
if (sig.length !== expectedLen) {
|
|
519
549
|
return false;
|
|
520
550
|
}
|
|
521
|
-
const msgHash = F(message);
|
|
551
|
+
const msgHash = (0, exports.F)(message);
|
|
522
552
|
const allDigits = baseWWithChecksum(msgHash, ps);
|
|
523
553
|
const buf = new Uint8Array(expectedLen);
|
|
524
554
|
for (let j = 0; j < ps.L; j++) {
|
|
@@ -527,7 +557,7 @@ export function wotsVerifyDigest(sig, message, pkDigest, ps = getParamSet()) {
|
|
|
527
557
|
const top = hashChain(sigPart, stepsUp);
|
|
528
558
|
buf.set(top, j * 32);
|
|
529
559
|
}
|
|
530
|
-
const recomputed = F(buf);
|
|
560
|
+
const recomputed = (0, exports.F)(buf);
|
|
531
561
|
if (recomputed.length !== pkDigest.length)
|
|
532
562
|
return false;
|
|
533
563
|
let diff = 0;
|
|
@@ -538,7 +568,7 @@ export function wotsVerifyDigest(sig, message, pkDigest, ps = getParamSet()) {
|
|
|
538
568
|
/**
|
|
539
569
|
* Generate WOTS public key from seed (convenience wrapper)
|
|
540
570
|
*/
|
|
541
|
-
|
|
571
|
+
function wotsPublicKeyFromSeed(seed, index = 0, paramSet) {
|
|
542
572
|
assert32(seed, 'seed');
|
|
543
573
|
const keypair = wotsKeypairFromSeed(seed, index, paramSet);
|
|
544
574
|
return keypair.pk;
|
|
@@ -548,7 +578,7 @@ export function wotsPublicKeyFromSeed(seed, index = 0, paramSet) {
|
|
|
548
578
|
/**
|
|
549
579
|
* @deprecated Use expandPrivateKey instead
|
|
550
580
|
*/
|
|
551
|
-
|
|
581
|
+
function prfChainSeed(seed, i, j, _paramSet) {
|
|
552
582
|
// This function no longer makes sense with stateful PRNG
|
|
553
583
|
// For compatibility, derive the j-th chain seed for key i
|
|
554
584
|
const privateKeys = expandPrivateKey(seed, _paramSet);
|