@totemsdk/core 1.2.5 → 1.2.7
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/dist/MiniNumber.js +19 -21
- package/dist/Streamable.js +31 -54
- package/dist/adapters/index.js +9 -18
- package/dist/adapters/types.js +11 -19
- package/dist/binio.js +7 -20
- package/dist/bip39.js +14 -24
- package/dist/canonical.d.ts +3 -0
- package/dist/canonical.js +22 -0
- package/dist/cjs/MiniNumber.d.ts +47 -0
- package/dist/cjs/MiniNumber.js +302 -0
- package/dist/cjs/Streamable.d.ts +268 -0
- package/dist/cjs/Streamable.js +439 -0
- package/dist/cjs/adapters/index.d.ts +190 -0
- package/dist/cjs/adapters/index.js +118 -0
- package/dist/cjs/adapters/types.d.ts +150 -0
- package/dist/cjs/adapters/types.js +81 -0
- package/dist/cjs/binio.d.ts +9 -0
- package/dist/cjs/binio.js +25 -0
- package/dist/cjs/bip39.d.ts +91 -0
- package/dist/cjs/bip39.js +434 -0
- package/dist/cjs/canonical.d.ts +3 -0
- package/dist/cjs/canonical.js +27 -0
- package/dist/cjs/derive.d.ts +2 -0
- package/dist/cjs/derive.js +13 -0
- package/dist/cjs/index.d.ts +49 -0
- package/dist/cjs/index.js +231 -0
- package/dist/cjs/javaStreamables.d.ts +254 -0
- package/dist/cjs/javaStreamables.js +391 -0
- package/dist/cjs/lease/LeaseMonitor.d.ts +44 -0
- package/dist/cjs/lease/LeaseMonitor.js +115 -0
- package/dist/cjs/lease/LeaseStore.d.ts +58 -0
- package/dist/cjs/lease/LeaseStore.js +151 -0
- package/dist/cjs/lease/WatermarkStore.d.ts +61 -0
- package/dist/cjs/lease/WatermarkStore.js +209 -0
- package/dist/cjs/lease/index.d.ts +14 -0
- package/dist/cjs/lease/index.js +22 -0
- package/dist/cjs/lease-client.d.ts +31 -0
- package/dist/cjs/lease-client.js +44 -0
- package/dist/cjs/legacy.d.ts +23 -0
- package/dist/cjs/legacy.js +163 -0
- package/dist/cjs/minima32.d.ts +18 -0
- package/dist/cjs/minima32.js +121 -0
- package/dist/cjs/minimaWireSerializer.d.ts +60 -0
- package/dist/cjs/minimaWireSerializer.js +77 -0
- package/dist/cjs/mmr.d.ts +157 -0
- package/dist/cjs/mmr.js +352 -0
- package/dist/cjs/mx.d.ts +1 -0
- package/dist/cjs/mx.js +10 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/params.d.ts +29 -0
- package/dist/cjs/params.js +20 -0
- package/dist/cjs/script.d.ts +7 -0
- package/dist/cjs/script.js +27 -0
- package/dist/cjs/scripts/contract-helpers.d.ts +252 -0
- package/dist/cjs/scripts/contract-helpers.js +407 -0
- package/dist/cjs/scripts/dapp-types.d.ts +119 -0
- package/dist/cjs/scripts/dapp-types.js +77 -0
- package/dist/cjs/scripts/index.d.ts +4 -0
- package/dist/cjs/scripts/index.js +38 -0
- package/dist/cjs/scripts/types.d.ts +81 -0
- package/dist/cjs/scripts/types.js +159 -0
- package/dist/cjs/scripts/witness-serializer.d.ts +29 -0
- package/dist/cjs/scripts/witness-serializer.js +306 -0
- package/dist/cjs/transaction.d.ts +106 -0
- package/dist/cjs/transaction.js +293 -0
- package/dist/cjs/treekey.d.ts +399 -0
- package/dist/cjs/treekey.js +827 -0
- package/dist/cjs/tx/TransactionLifecycle.d.ts +55 -0
- package/dist/cjs/tx/TransactionLifecycle.js +205 -0
- package/dist/cjs/tx/TransactionReceiptStore.d.ts +36 -0
- package/dist/cjs/tx/TransactionReceiptStore.js +93 -0
- package/dist/cjs/tx/TransactionService.d.ts +50 -0
- package/dist/cjs/tx/TransactionService.js +186 -0
- package/dist/cjs/tx/index.d.ts +13 -0
- package/dist/cjs/tx/index.js +20 -0
- package/dist/cjs/tx/types.d.ts +115 -0
- package/dist/cjs/tx/types.js +6 -0
- package/dist/cjs/util.d.ts +1 -0
- package/dist/cjs/util.js +5 -0
- package/dist/cjs/utils.d.ts +8 -0
- package/dist/cjs/utils.js +42 -0
- package/dist/cjs/verify.d.ts +18 -0
- package/dist/cjs/verify.js +174 -0
- package/dist/cjs/version.d.ts +12 -0
- package/dist/cjs/version.js +15 -0
- package/dist/cjs/wasm-sync.d.ts +71 -0
- package/dist/cjs/wasm-sync.js +97 -0
- package/dist/cjs/wots.d.ts +232 -0
- package/dist/cjs/wots.js +589 -0
- package/dist/derive.js +7 -11
- package/dist/index.d.ts +8 -2
- package/dist/index.js +50 -143
- package/dist/javaStreamables.js +34 -55
- package/dist/lease/LeaseMonitor.js +10 -10
- package/dist/lease/LeaseStore.js +8 -9
- package/dist/lease/WatermarkStore.js +8 -9
- package/dist/lease/index.js +4 -13
- package/dist/lease-client.js +3 -8
- package/dist/legacy.js +13 -140
- package/dist/minima32.js +13 -22
- package/dist/minimaWireSerializer.js +14 -20
- package/dist/mmr.js +27 -41
- package/dist/mx.js +1 -10
- package/dist/params.js +5 -9
- package/dist/script.js +7 -12
- package/dist/scripts/contract-helpers.js +25 -36
- package/dist/scripts/dapp-types.js +6 -11
- package/dist/scripts/index.js +4 -38
- package/dist/scripts/types.js +12 -26
- package/dist/scripts/witness-serializer.js +30 -48
- package/dist/transaction.js +46 -55
- package/dist/treekey.js +96 -89
- package/dist/tx/TransactionLifecycle.js +15 -11
- package/dist/tx/TransactionReceiptStore.js +9 -9
- package/dist/tx/TransactionService.js +14 -14
- package/dist/tx/index.js +3 -11
- package/dist/tx/types.js +1 -2
- package/dist/util.js +1 -5
- package/dist/utils.js +5 -12
- package/dist/verify.js +25 -36
- package/dist/version.js +2 -5
- package/dist/wasm-sync.d.ts +2 -2
- package/dist/wasm-sync.js +58 -61
- package/dist/wots.js +64 -94
- package/package.json +84 -45
- package/dist/wasm-bridge.d.ts +0 -54
- package/dist/wasm-bridge.js +0 -303
package/dist/wots.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* WOTS Implementation - BouncyCastle Compatible
|
|
4
3
|
*
|
|
@@ -13,34 +12,12 @@
|
|
|
13
12
|
*
|
|
14
13
|
* Source: org.bouncycastle.pqc.crypto.gmss.util.{WinternitzOTSignature, WinternitzOTSVerify, GMSSRandom}
|
|
15
14
|
*/
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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 wasm_sync_js_1 = require("./wasm-sync.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");
|
|
15
|
+
import { sha3_256 } from './wasm-sync.js';
|
|
16
|
+
import { getParamSet } from "./params.js";
|
|
17
|
+
import { deriveChainSeedJava } from "./javaStreamables.js";
|
|
18
|
+
import { NoopLogger } from "./adapters/index.js";
|
|
42
19
|
// Module-level debug logger - can be set externally for parity testing
|
|
43
|
-
let wotsLogger = new
|
|
20
|
+
let wotsLogger = new NoopLogger();
|
|
44
21
|
let wotsDebugEnabled = false;
|
|
45
22
|
/**
|
|
46
23
|
* Enable WOTS debug logging with a custom logger
|
|
@@ -50,42 +27,39 @@ let wotsDebugEnabled = false;
|
|
|
50
27
|
* private key chains and seeds. NEVER enable in production builds.
|
|
51
28
|
* This is intended for development/testing parity verification only.
|
|
52
29
|
*/
|
|
53
|
-
function setWotsLogger(logger) {
|
|
30
|
+
export function setWotsLogger(logger) {
|
|
54
31
|
wotsLogger = logger;
|
|
55
32
|
wotsDebugEnabled = true;
|
|
56
33
|
}
|
|
57
34
|
/**
|
|
58
35
|
* Disable WOTS debug logging
|
|
59
36
|
*/
|
|
60
|
-
function disableWotsLogger() {
|
|
61
|
-
wotsLogger = new
|
|
37
|
+
export function disableWotsLogger() {
|
|
38
|
+
wotsLogger = new NoopLogger();
|
|
62
39
|
wotsDebugEnabled = false;
|
|
63
40
|
}
|
|
64
41
|
/**
|
|
65
42
|
* Check if WOTS debug logging is enabled
|
|
66
43
|
*/
|
|
67
|
-
function isWotsDebugEnabled() {
|
|
44
|
+
export function isWotsDebugEnabled() {
|
|
68
45
|
return wotsDebugEnabled;
|
|
69
46
|
}
|
|
70
47
|
// === Canonical helpers ===
|
|
71
|
-
const F = (x) =>
|
|
72
|
-
|
|
73
|
-
const hex = (u) => {
|
|
48
|
+
export const F = (x) => sha3_256(x);
|
|
49
|
+
export const hex = (u) => {
|
|
74
50
|
let s = '';
|
|
75
51
|
for (let i = 0; i < u.length; i++)
|
|
76
52
|
s += u[i].toString(16).padStart(2, '0');
|
|
77
53
|
return s;
|
|
78
54
|
};
|
|
79
|
-
|
|
80
|
-
const fromHex = (h) => {
|
|
55
|
+
export const fromHex = (h) => {
|
|
81
56
|
const s = h.replace(/^0x/, '');
|
|
82
57
|
const out = new Uint8Array(s.length >> 1);
|
|
83
58
|
for (let i = 0; i < out.length; i++)
|
|
84
59
|
out[i] = parseInt(s.slice(i * 2, i * 2 + 2), 16);
|
|
85
60
|
return out;
|
|
86
61
|
};
|
|
87
|
-
|
|
88
|
-
const concatBytes = (...arrs) => {
|
|
62
|
+
export const concatBytes = (...arrs) => {
|
|
89
63
|
const len = arrs.reduce((n, a) => n + a.length, 0);
|
|
90
64
|
const out = new Uint8Array(len);
|
|
91
65
|
let o = 0;
|
|
@@ -95,12 +69,9 @@ const concatBytes = (...arrs) => {
|
|
|
95
69
|
}
|
|
96
70
|
return out;
|
|
97
71
|
};
|
|
98
|
-
|
|
99
|
-
const
|
|
100
|
-
|
|
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') {
|
|
72
|
+
export const u16be = (n) => new Uint8Array([(n >>> 8) & 0xff, n & 0xff]);
|
|
73
|
+
export const u32be = (n) => new Uint8Array([(n >>> 24) & 255, (n >>> 16) & 255, (n >>> 8) & 255, n & 255]);
|
|
74
|
+
export function assert32(u, label = 'value') {
|
|
104
75
|
if (!(u instanceof Uint8Array))
|
|
105
76
|
throw new Error(`${label} must be a Uint8Array`);
|
|
106
77
|
if (u.length !== 32)
|
|
@@ -108,9 +79,9 @@ function assert32(u, label = 'value') {
|
|
|
108
79
|
}
|
|
109
80
|
// Legacy aliases
|
|
110
81
|
const u8 = (len) => new Uint8Array(len);
|
|
111
|
-
|
|
112
|
-
const concat =
|
|
113
|
-
const defaultParamSet =
|
|
82
|
+
export const h = F;
|
|
83
|
+
const concat = concatBytes;
|
|
84
|
+
const defaultParamSet = getParamSet();
|
|
114
85
|
/**
|
|
115
86
|
* GMSSRandom - BouncyCastle's stateful PRNG for WOTS chain seed derivation
|
|
116
87
|
*
|
|
@@ -121,7 +92,7 @@ const defaultParamSet = (0, params_js_1.getParamSet)();
|
|
|
121
92
|
*
|
|
122
93
|
* The state is MUTATED in place after each call.
|
|
123
94
|
*/
|
|
124
|
-
class GMSSRandom {
|
|
95
|
+
export class GMSSRandom {
|
|
125
96
|
/**
|
|
126
97
|
* Generate next random value and update state
|
|
127
98
|
*
|
|
@@ -131,7 +102,7 @@ class GMSSRandom {
|
|
|
131
102
|
static nextSeed(state) {
|
|
132
103
|
assert32(state, 'state');
|
|
133
104
|
// rand = H(state)
|
|
134
|
-
const rand =
|
|
105
|
+
const rand = F(state);
|
|
135
106
|
// state = state + rand (byte-wise addition with carry, little-endian)
|
|
136
107
|
GMSSRandom.addByteArrays(state, rand);
|
|
137
108
|
// state = state + 1
|
|
@@ -165,7 +136,6 @@ class GMSSRandom {
|
|
|
165
136
|
}
|
|
166
137
|
}
|
|
167
138
|
}
|
|
168
|
-
exports.GMSSRandom = GMSSRandom;
|
|
169
139
|
/**
|
|
170
140
|
* getLog - Calculate ceil(log2(x))
|
|
171
141
|
*
|
|
@@ -175,7 +145,7 @@ exports.GMSSRandom = GMSSRandom;
|
|
|
175
145
|
* while (i < intValue) { i <<= 1; log++; }
|
|
176
146
|
* return log;
|
|
177
147
|
*/
|
|
178
|
-
function getLog(intValue) {
|
|
148
|
+
export function getLog(intValue) {
|
|
179
149
|
let log = 1;
|
|
180
150
|
let i = 2;
|
|
181
151
|
while (i < intValue) {
|
|
@@ -194,13 +164,13 @@ function getLog(intValue) {
|
|
|
194
164
|
* privateKeyOTS[i] = gmssRandom.nextSeed(dummy);
|
|
195
165
|
* }
|
|
196
166
|
*/
|
|
197
|
-
function expandPrivateKey(seed, ps =
|
|
167
|
+
export function expandPrivateKey(seed, ps = getParamSet()) {
|
|
198
168
|
assert32(seed, 'seed');
|
|
199
169
|
// Copy seed to mutable state
|
|
200
170
|
const state = new Uint8Array(seed);
|
|
201
171
|
if (wotsDebugEnabled) {
|
|
202
|
-
wotsLogger.debug(`[expandPrivateKey] Input seed: ${
|
|
203
|
-
wotsLogger.debug(`[expandPrivateKey] Initial state: ${
|
|
172
|
+
wotsLogger.debug(`[expandPrivateKey] Input seed: ${hex(seed).substring(0, 64)}...`);
|
|
173
|
+
wotsLogger.debug(`[expandPrivateKey] Initial state: ${hex(state).substring(0, 64)}...`);
|
|
204
174
|
}
|
|
205
175
|
// Generate L chain seeds using stateful PRNG
|
|
206
176
|
const privateKeys = [];
|
|
@@ -209,13 +179,13 @@ function expandPrivateKey(seed, ps = (0, params_js_1.getParamSet)()) {
|
|
|
209
179
|
privateKeys.push(pk);
|
|
210
180
|
// Log first few private keys for debugging
|
|
211
181
|
if (wotsDebugEnabled && i < 3) {
|
|
212
|
-
wotsLogger.debug(`[expandPrivateKey] pk[${i}]: ${
|
|
213
|
-
wotsLogger.debug(`[expandPrivateKey] state after pk[${i}]: ${
|
|
182
|
+
wotsLogger.debug(`[expandPrivateKey] pk[${i}]: ${hex(pk)}`);
|
|
183
|
+
wotsLogger.debug(`[expandPrivateKey] state after pk[${i}]: ${hex(state).substring(0, 32)}...`);
|
|
214
184
|
}
|
|
215
185
|
}
|
|
216
186
|
if (wotsDebugEnabled) {
|
|
217
187
|
wotsLogger.debug(`[expandPrivateKey] Generated ${privateKeys.length} private keys`);
|
|
218
|
-
wotsLogger.debug(`[expandPrivateKey] pk[33] (last): ${
|
|
188
|
+
wotsLogger.debug(`[expandPrivateKey] pk[33] (last): ${hex(privateKeys[33])}`);
|
|
219
189
|
}
|
|
220
190
|
return privateKeys;
|
|
221
191
|
}
|
|
@@ -230,7 +200,7 @@ function expandPrivateKey(seed, ps = (0, params_js_1.getParamSet)()) {
|
|
|
230
200
|
*
|
|
231
201
|
* Matches WinternitzOTSignature.getSignature() for w=8 case
|
|
232
202
|
*/
|
|
233
|
-
function toWinternitzDigits(hash32, ps =
|
|
203
|
+
export function toWinternitzDigits(hash32, ps = getParamSet()) {
|
|
234
204
|
assert32(hash32, 'hash');
|
|
235
205
|
if (ps.w !== 8) {
|
|
236
206
|
throw new Error(`Only w=8 is supported. Got w=${ps.w}`);
|
|
@@ -258,7 +228,7 @@ function toWinternitzDigits(hash32, ps = (0, params_js_1.getParamSet)()) {
|
|
|
258
228
|
c >>>= ps.w;
|
|
259
229
|
}
|
|
260
230
|
if (wotsDebugEnabled) {
|
|
261
|
-
wotsLogger.debug(`[toWinternitzDigits] Input hash: ${
|
|
231
|
+
wotsLogger.debug(`[toWinternitzDigits] Input hash: ${hex(hash32)}`);
|
|
262
232
|
wotsLogger.debug(`[toWinternitzDigits] First 5 message digits: [${digits.slice(0, 5).join(', ')}]`);
|
|
263
233
|
wotsLogger.debug(`[toWinternitzDigits] Last 5 message digits: [${digits.slice(-5).join(', ')}]`);
|
|
264
234
|
wotsLogger.debug(`[toWinternitzDigits] Digit sum: ${digitSum}`);
|
|
@@ -276,7 +246,7 @@ function toWinternitzDigits(hash32, ps = (0, params_js_1.getParamSet)()) {
|
|
|
276
246
|
* Decompose digest into base-w digits + checksum
|
|
277
247
|
* Returns flat array of all L digits
|
|
278
248
|
*/
|
|
279
|
-
function baseWWithChecksum(msgHash, paramSet) {
|
|
249
|
+
export function baseWWithChecksum(msgHash, paramSet) {
|
|
280
250
|
const ps = paramSet || defaultParamSet;
|
|
281
251
|
const { digits, checksumDigits } = toWinternitzDigits(msgHash, ps);
|
|
282
252
|
const result = digits.concat(checksumDigits);
|
|
@@ -292,13 +262,13 @@ function baseWWithChecksum(msgHash, paramSet) {
|
|
|
292
262
|
* - If rounds < 1: return input unchanged
|
|
293
263
|
* - Otherwise: hash `rounds` times
|
|
294
264
|
*/
|
|
295
|
-
function hashChain(x, rounds) {
|
|
265
|
+
export function hashChain(x, rounds) {
|
|
296
266
|
if (rounds < 1) {
|
|
297
267
|
return new Uint8Array(x);
|
|
298
268
|
}
|
|
299
|
-
let result =
|
|
269
|
+
let result = F(x);
|
|
300
270
|
for (let i = 1; i < rounds; i++) {
|
|
301
|
-
result =
|
|
271
|
+
result = F(result);
|
|
302
272
|
}
|
|
303
273
|
return result;
|
|
304
274
|
}
|
|
@@ -314,12 +284,12 @@ function hashChain(x, rounds) {
|
|
|
314
284
|
* This old implementation used H(seed || u32be(i)) which is NOT Java compatible.
|
|
315
285
|
* @deprecated Use deriveChainSeedJava from javaStreamables.ts
|
|
316
286
|
*/
|
|
317
|
-
function deriveIndexedSeed(seed, keyIndex) {
|
|
287
|
+
export function deriveIndexedSeed(seed, keyIndex) {
|
|
318
288
|
assert32(seed, 'seed');
|
|
319
289
|
// Use Java-compatible derivation: hashAllObjects(MiniNumber(i), MiniData(seed))
|
|
320
|
-
const result =
|
|
290
|
+
const result = deriveChainSeedJava(seed, keyIndex);
|
|
321
291
|
if (wotsDebugEnabled) {
|
|
322
|
-
wotsLogger.debug(`[deriveIndexedSeed] seed=${
|
|
292
|
+
wotsLogger.debug(`[deriveIndexedSeed] seed=${hex(seed).substring(0, 32)}..., keyIndex=${keyIndex} => ${hex(result)}`);
|
|
323
293
|
}
|
|
324
294
|
return result;
|
|
325
295
|
}
|
|
@@ -336,7 +306,7 @@ function deriveIndexedSeed(seed, keyIndex) {
|
|
|
336
306
|
* }
|
|
337
307
|
* return H(buf);
|
|
338
308
|
*/
|
|
339
|
-
function derivePKdigest(seed, i, ps =
|
|
309
|
+
export function derivePKdigest(seed, i, ps = getParamSet()) {
|
|
340
310
|
assert32(seed, 'seed');
|
|
341
311
|
// Derive unique seed for this key index
|
|
342
312
|
const indexedSeed = deriveIndexedSeed(seed, i);
|
|
@@ -350,7 +320,7 @@ function derivePKdigest(seed, i, ps = (0, params_js_1.getParamSet)()) {
|
|
|
350
320
|
buf.set(top, j * 32);
|
|
351
321
|
}
|
|
352
322
|
// Return H(all chain tops)
|
|
353
|
-
return
|
|
323
|
+
return F(buf);
|
|
354
324
|
}
|
|
355
325
|
/**
|
|
356
326
|
* Derive full WOTS public key (L × 32 bytes) without final hash
|
|
@@ -358,16 +328,16 @@ function derivePKdigest(seed, i, ps = (0, params_js_1.getParamSet)()) {
|
|
|
358
328
|
* Returns the concatenation of all chain tops BEFORE hashing.
|
|
359
329
|
* Required by Minima's SignatureProof which expects the full public key.
|
|
360
330
|
*/
|
|
361
|
-
function deriveFullPublicKey(seed, i, ps =
|
|
331
|
+
export function deriveFullPublicKey(seed, i, ps = getParamSet()) {
|
|
362
332
|
assert32(seed, 'seed');
|
|
363
333
|
if (wotsDebugEnabled) {
|
|
364
334
|
wotsLogger.debug(`[deriveFullPublicKey] ========== PK DERIVATION START ==========`);
|
|
365
|
-
wotsLogger.debug(`[deriveFullPublicKey] Master seed: ${
|
|
335
|
+
wotsLogger.debug(`[deriveFullPublicKey] Master seed: ${hex(seed).substring(0, 32)}..., keyIndex: ${i}`);
|
|
366
336
|
}
|
|
367
337
|
// Derive unique seed for this key index
|
|
368
338
|
const indexedSeed = deriveIndexedSeed(seed, i);
|
|
369
339
|
if (wotsDebugEnabled) {
|
|
370
|
-
wotsLogger.debug(`[deriveFullPublicKey] Indexed seed: ${
|
|
340
|
+
wotsLogger.debug(`[deriveFullPublicKey] Indexed seed: ${hex(indexedSeed)}`);
|
|
371
341
|
}
|
|
372
342
|
const privateKeys = expandPrivateKey(indexedSeed, ps);
|
|
373
343
|
const rounds = ps.maxDigit; // 255
|
|
@@ -377,16 +347,16 @@ function deriveFullPublicKey(seed, i, ps = (0, params_js_1.getParamSet)()) {
|
|
|
377
347
|
buf.set(top, j * 32);
|
|
378
348
|
// Log first few chain tops for debugging
|
|
379
349
|
if (wotsDebugEnabled && j < 3) {
|
|
380
|
-
wotsLogger.debug(`[deriveFullPublicKey] chain[${j}]: pk=${
|
|
350
|
+
wotsLogger.debug(`[deriveFullPublicKey] chain[${j}]: pk=${hex(privateKeys[j]).substring(0, 16)}... rounds=${rounds} => top=${hex(top).substring(0, 16)}...`);
|
|
381
351
|
}
|
|
382
352
|
}
|
|
383
353
|
if (wotsDebugEnabled) {
|
|
384
|
-
wotsLogger.debug(`[deriveFullPublicKey] Full public key (${buf.length}B): ${
|
|
354
|
+
wotsLogger.debug(`[deriveFullPublicKey] Full public key (${buf.length}B): ${hex(buf).substring(0, 64)}...${hex(buf).substring(hex(buf).length - 32)}`);
|
|
385
355
|
wotsLogger.debug(`[deriveFullPublicKey] ========== PK DERIVATION END ==========`);
|
|
386
356
|
}
|
|
387
357
|
return buf; // L * 32 = 1088 bytes
|
|
388
358
|
}
|
|
389
|
-
function wotsKeypairFromSeed(seed, index, paramSet) {
|
|
359
|
+
export function wotsKeypairFromSeed(seed, index, paramSet) {
|
|
390
360
|
assert32(seed, 'seed');
|
|
391
361
|
const ps = paramSet || defaultParamSet;
|
|
392
362
|
const pkDigest = derivePKdigest(seed, index, ps);
|
|
@@ -408,25 +378,25 @@ function wotsKeypairFromSeed(seed, index, paramSet) {
|
|
|
408
378
|
* @param ps - WOTS parameter set (default: minima)
|
|
409
379
|
* @returns Flat signature (L × 32 = 1088 bytes)
|
|
410
380
|
*/
|
|
411
|
-
function wotsSign(seed, i, message, ps =
|
|
381
|
+
export function wotsSign(seed, i, message, ps = getParamSet()) {
|
|
412
382
|
assert32(seed, 'seed');
|
|
413
383
|
assert32(message, 'message');
|
|
414
384
|
if (wotsDebugEnabled) {
|
|
415
385
|
wotsLogger.debug(`[wotsSign] ========== WOTS SIGN START ==========`);
|
|
416
|
-
wotsLogger.debug(`[wotsSign] Master seed: ${
|
|
386
|
+
wotsLogger.debug(`[wotsSign] Master seed: ${hex(seed)}`);
|
|
417
387
|
wotsLogger.debug(`[wotsSign] Key index: ${i}`);
|
|
418
|
-
wotsLogger.debug(`[wotsSign] Message (raw): ${
|
|
388
|
+
wotsLogger.debug(`[wotsSign] Message (raw): ${hex(message)}`);
|
|
419
389
|
}
|
|
420
390
|
// Derive unique seed for this key index
|
|
421
391
|
const indexedSeed = deriveIndexedSeed(seed, i);
|
|
422
392
|
if (wotsDebugEnabled) {
|
|
423
|
-
wotsLogger.debug(`[wotsSign] Indexed seed (after deriveIndexedSeed): ${
|
|
393
|
+
wotsLogger.debug(`[wotsSign] Indexed seed (after deriveIndexedSeed): ${hex(indexedSeed)}`);
|
|
424
394
|
}
|
|
425
395
|
const privateKeys = expandPrivateKey(indexedSeed, ps);
|
|
426
396
|
// CRITICAL: Hash the message internally to match Java/BouncyCastle Winternitz behavior
|
|
427
397
|
// Java's WinternitzOTSignature.getSignature() always hashes the message first
|
|
428
398
|
// Callers pass RAW 32-byte data (tx digest, child root), NOT pre-hashed!
|
|
429
|
-
const hashedMsg =
|
|
399
|
+
const hashedMsg = F(message);
|
|
430
400
|
const { digits, checksumDigits } = toWinternitzDigits(hashedMsg, ps);
|
|
431
401
|
const allDigits = digits.concat(checksumDigits);
|
|
432
402
|
if (allDigits.length !== ps.L) {
|
|
@@ -442,11 +412,11 @@ function wotsSign(seed, i, message, ps = (0, params_js_1.getParamSet)()) {
|
|
|
442
412
|
out.set(sigPart, j * 32);
|
|
443
413
|
// Log first few and last signature chains for debugging
|
|
444
414
|
if (wotsDebugEnabled && (j < 3 || j >= ps.L - 2)) {
|
|
445
|
-
wotsLogger.debug(`[wotsSign] chain[${j}]: pk=${
|
|
415
|
+
wotsLogger.debug(`[wotsSign] chain[${j}]: pk=${hex(privateKeys[j]).substring(0, 16)}... rounds=${rounds} => sig=${hex(sigPart).substring(0, 16)}...`);
|
|
446
416
|
}
|
|
447
417
|
}
|
|
448
418
|
if (wotsDebugEnabled) {
|
|
449
|
-
wotsLogger.debug(`[wotsSign] Signature output (${out.length} bytes): ${
|
|
419
|
+
wotsLogger.debug(`[wotsSign] Signature output (${out.length} bytes): ${hex(out).substring(0, 64)}...${hex(out).substring(hex(out).length - 64)}`);
|
|
450
420
|
wotsLogger.debug(`[wotsSign] ========== WOTS SIGN END ==========`);
|
|
451
421
|
}
|
|
452
422
|
return out;
|
|
@@ -454,8 +424,8 @@ function wotsSign(seed, i, message, ps = (0, params_js_1.getParamSet)()) {
|
|
|
454
424
|
/**
|
|
455
425
|
* Legacy wrapper returning structured signature
|
|
456
426
|
*/
|
|
457
|
-
function wotsSignLegacy(msgHash, seed, index, paramSet) {
|
|
458
|
-
const ps = paramSet ||
|
|
427
|
+
export function wotsSignLegacy(msgHash, seed, index, paramSet) {
|
|
428
|
+
const ps = paramSet || getParamSet();
|
|
459
429
|
const sig = wotsSign(seed, index, msgHash, ps);
|
|
460
430
|
const chunks = [];
|
|
461
431
|
for (let i = 0; i < ps.L; i++) {
|
|
@@ -475,10 +445,10 @@ function wotsSignLegacy(msgHash, seed, index, paramSet) {
|
|
|
475
445
|
* CRITICAL: This function hashes the message internally to match Java/BouncyCastle
|
|
476
446
|
* Winternitz behavior. Both wotsSign and wotsPkFromSig hash internally for parity.
|
|
477
447
|
*/
|
|
478
|
-
function wotsPkFromSig(message, signature, paramSet) {
|
|
448
|
+
export function wotsPkFromSig(message, signature, paramSet) {
|
|
479
449
|
const ps = paramSet || defaultParamSet;
|
|
480
450
|
// CRITICAL: Hash the message internally to match Java/BouncyCastle Winternitz behavior
|
|
481
|
-
const hashedMsg =
|
|
451
|
+
const hashedMsg = F(message);
|
|
482
452
|
const allDigits = baseWWithChecksum(hashedMsg, ps);
|
|
483
453
|
if (signature.sig.length !== ps.L) {
|
|
484
454
|
throw new Error(`Wrong signature length: expected ${ps.L}, got ${signature.sig.length}`);
|
|
@@ -489,7 +459,7 @@ function wotsPkFromSig(message, signature, paramSet) {
|
|
|
489
459
|
const top = hashChain(signature.sig[i], stepsUp);
|
|
490
460
|
buf.set(top, i * 32);
|
|
491
461
|
}
|
|
492
|
-
return
|
|
462
|
+
return F(buf);
|
|
493
463
|
}
|
|
494
464
|
/**
|
|
495
465
|
* Verify WOTS signature against a FULL 1088-byte public key
|
|
@@ -510,7 +480,7 @@ function wotsPkFromSig(message, signature, paramSet) {
|
|
|
510
480
|
* @param pkFull - The FULL 1088-byte WOTS public key (L=34 × 32 bytes)
|
|
511
481
|
* @param ps - WOTS parameter set (default: minima)
|
|
512
482
|
*/
|
|
513
|
-
function wotsVerify(sig, message, pkFull, ps =
|
|
483
|
+
export function wotsVerify(sig, message, pkFull, ps = getParamSet()) {
|
|
514
484
|
// CRITICAL: Java verifies against FULL 1088-byte public key, not 32-byte digest
|
|
515
485
|
const expectedLen = ps.L * 32;
|
|
516
486
|
if (pkFull.length !== expectedLen) {
|
|
@@ -520,7 +490,7 @@ function wotsVerify(sig, message, pkFull, ps = (0, params_js_1.getParamSet)()) {
|
|
|
520
490
|
return false;
|
|
521
491
|
}
|
|
522
492
|
// CRITICAL: Hash the message internally to match Java/BouncyCastle Winternitz behavior
|
|
523
|
-
const hashedMsg =
|
|
493
|
+
const hashedMsg = F(message);
|
|
524
494
|
const allDigits = baseWWithChecksum(hashedMsg, ps);
|
|
525
495
|
const buf = new Uint8Array(expectedLen);
|
|
526
496
|
for (let j = 0; j < ps.L; j++) {
|
|
@@ -542,13 +512,13 @@ function wotsVerify(sig, message, pkFull, ps = (0, params_js_1.getParamSet)()) {
|
|
|
542
512
|
* Legacy verify function that accepts a 32-byte digest
|
|
543
513
|
* @deprecated Use wotsVerify with full 1088-byte public key instead
|
|
544
514
|
*/
|
|
545
|
-
function wotsVerifyDigest(sig, message, pkDigest, ps =
|
|
515
|
+
export function wotsVerifyDigest(sig, message, pkDigest, ps = getParamSet()) {
|
|
546
516
|
assert32(pkDigest, 'pkDigest');
|
|
547
517
|
const expectedLen = ps.L * 32;
|
|
548
518
|
if (sig.length !== expectedLen) {
|
|
549
519
|
return false;
|
|
550
520
|
}
|
|
551
|
-
const msgHash =
|
|
521
|
+
const msgHash = F(message);
|
|
552
522
|
const allDigits = baseWWithChecksum(msgHash, ps);
|
|
553
523
|
const buf = new Uint8Array(expectedLen);
|
|
554
524
|
for (let j = 0; j < ps.L; j++) {
|
|
@@ -557,7 +527,7 @@ function wotsVerifyDigest(sig, message, pkDigest, ps = (0, params_js_1.getParamS
|
|
|
557
527
|
const top = hashChain(sigPart, stepsUp);
|
|
558
528
|
buf.set(top, j * 32);
|
|
559
529
|
}
|
|
560
|
-
const recomputed =
|
|
530
|
+
const recomputed = F(buf);
|
|
561
531
|
if (recomputed.length !== pkDigest.length)
|
|
562
532
|
return false;
|
|
563
533
|
let diff = 0;
|
|
@@ -568,7 +538,7 @@ function wotsVerifyDigest(sig, message, pkDigest, ps = (0, params_js_1.getParamS
|
|
|
568
538
|
/**
|
|
569
539
|
* Generate WOTS public key from seed (convenience wrapper)
|
|
570
540
|
*/
|
|
571
|
-
function wotsPublicKeyFromSeed(seed, index = 0, paramSet) {
|
|
541
|
+
export function wotsPublicKeyFromSeed(seed, index = 0, paramSet) {
|
|
572
542
|
assert32(seed, 'seed');
|
|
573
543
|
const keypair = wotsKeypairFromSeed(seed, index, paramSet);
|
|
574
544
|
return keypair.pk;
|
|
@@ -578,7 +548,7 @@ function wotsPublicKeyFromSeed(seed, index = 0, paramSet) {
|
|
|
578
548
|
/**
|
|
579
549
|
* @deprecated Use expandPrivateKey instead
|
|
580
550
|
*/
|
|
581
|
-
function prfChainSeed(seed, i, j, _paramSet) {
|
|
551
|
+
export function prfChainSeed(seed, i, j, _paramSet) {
|
|
582
552
|
// This function no longer makes sense with stateful PRNG
|
|
583
553
|
// For compatibility, derive the j-th chain seed for key i
|
|
584
554
|
const privateKeys = expandPrivateKey(seed, _paramSet);
|
package/package.json
CHANGED
|
@@ -1,84 +1,118 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@totemsdk/core",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.7",
|
|
4
4
|
"description": "Core cryptographic primitives for Totem SDK — backed by Rust/WASM",
|
|
5
|
-
"
|
|
6
|
-
"
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/cjs/index.js",
|
|
7
|
+
"types": "dist/cjs/index.d.ts",
|
|
7
8
|
"exports": {
|
|
8
9
|
".": {
|
|
9
|
-
"
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
"import": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"require": {
|
|
15
|
+
"types": "./dist/cjs/index.d.ts",
|
|
16
|
+
"default": "./dist/cjs/index.js"
|
|
17
|
+
}
|
|
12
18
|
},
|
|
13
19
|
"./wasm": {
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
20
|
+
"import": {
|
|
21
|
+
"types": "./dist/wasm-sync.d.ts",
|
|
22
|
+
"default": "./dist/wasm-sync.js"
|
|
23
|
+
},
|
|
24
|
+
"require": {
|
|
25
|
+
"types": "./dist/cjs/wasm-sync.d.ts",
|
|
26
|
+
"default": "./dist/cjs/wasm-sync.js"
|
|
27
|
+
}
|
|
17
28
|
},
|
|
18
29
|
"./legacy": {
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
"import": {
|
|
31
|
+
"types": "./dist/legacy.d.ts",
|
|
32
|
+
"default": "./dist/legacy.js"
|
|
33
|
+
},
|
|
34
|
+
"require": {
|
|
35
|
+
"types": "./dist/cjs/legacy.d.ts",
|
|
36
|
+
"default": "./dist/cjs/legacy.js"
|
|
37
|
+
}
|
|
22
38
|
},
|
|
23
39
|
"./adapters": {
|
|
24
|
-
"
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
"import": {
|
|
41
|
+
"types": "./dist/adapters/index.d.ts",
|
|
42
|
+
"default": "./dist/adapters/index.js"
|
|
43
|
+
},
|
|
44
|
+
"require": {
|
|
45
|
+
"types": "./dist/cjs/adapters/index.d.ts",
|
|
46
|
+
"default": "./dist/cjs/adapters/index.js"
|
|
47
|
+
}
|
|
27
48
|
},
|
|
28
49
|
"./adapters/types": {
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
50
|
+
"import": {
|
|
51
|
+
"types": "./dist/adapters/types.d.ts",
|
|
52
|
+
"default": "./dist/adapters/types.js"
|
|
53
|
+
},
|
|
54
|
+
"require": {
|
|
55
|
+
"types": "./dist/cjs/adapters/types.d.ts",
|
|
56
|
+
"default": "./dist/cjs/adapters/types.js"
|
|
57
|
+
}
|
|
32
58
|
},
|
|
33
59
|
"./lease": {
|
|
34
|
-
"
|
|
35
|
-
|
|
36
|
-
|
|
60
|
+
"import": {
|
|
61
|
+
"types": "./dist/lease/index.d.ts",
|
|
62
|
+
"default": "./dist/lease/index.js"
|
|
63
|
+
},
|
|
64
|
+
"require": {
|
|
65
|
+
"types": "./dist/cjs/lease/index.d.ts",
|
|
66
|
+
"default": "./dist/cjs/lease/index.js"
|
|
67
|
+
}
|
|
37
68
|
},
|
|
38
69
|
"./tx": {
|
|
39
|
-
"
|
|
40
|
-
|
|
41
|
-
|
|
70
|
+
"import": {
|
|
71
|
+
"types": "./dist/tx/index.d.ts",
|
|
72
|
+
"default": "./dist/tx/index.js"
|
|
73
|
+
},
|
|
74
|
+
"require": {
|
|
75
|
+
"types": "./dist/cjs/tx/index.d.ts",
|
|
76
|
+
"default": "./dist/cjs/tx/index.js"
|
|
77
|
+
}
|
|
42
78
|
},
|
|
43
79
|
"./scripts": {
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
80
|
+
"import": {
|
|
81
|
+
"types": "./dist/scripts/index.d.ts",
|
|
82
|
+
"default": "./dist/scripts/index.js"
|
|
83
|
+
},
|
|
84
|
+
"require": {
|
|
85
|
+
"types": "./dist/cjs/scripts/index.d.ts",
|
|
86
|
+
"default": "./dist/cjs/scripts/index.js"
|
|
87
|
+
}
|
|
47
88
|
},
|
|
48
89
|
"./test-vectors.json": "./test-vectors.json"
|
|
49
90
|
},
|
|
50
91
|
"typesVersions": {
|
|
51
92
|
"*": {
|
|
52
93
|
"wasm": [
|
|
53
|
-
"./dist/wasm-sync.d.ts"
|
|
94
|
+
"./dist/cjs/wasm-sync.d.ts"
|
|
54
95
|
],
|
|
55
96
|
"legacy": [
|
|
56
|
-
"./dist/legacy.d.ts"
|
|
97
|
+
"./dist/cjs/legacy.d.ts"
|
|
57
98
|
],
|
|
58
99
|
"adapters": [
|
|
59
|
-
"./dist/adapters/index.d.ts"
|
|
100
|
+
"./dist/cjs/adapters/index.d.ts"
|
|
60
101
|
],
|
|
61
102
|
"adapters/types": [
|
|
62
|
-
"./dist/adapters/types.d.ts"
|
|
103
|
+
"./dist/cjs/adapters/types.d.ts"
|
|
63
104
|
],
|
|
64
105
|
"lease": [
|
|
65
|
-
"./dist/lease/index.d.ts"
|
|
106
|
+
"./dist/cjs/lease/index.d.ts"
|
|
66
107
|
],
|
|
67
108
|
"tx": [
|
|
68
|
-
"./dist/tx/index.d.ts"
|
|
109
|
+
"./dist/cjs/tx/index.d.ts"
|
|
69
110
|
],
|
|
70
111
|
"scripts": [
|
|
71
|
-
"./dist/scripts/index.d.ts"
|
|
112
|
+
"./dist/cjs/scripts/index.d.ts"
|
|
72
113
|
]
|
|
73
114
|
}
|
|
74
115
|
},
|
|
75
|
-
"scripts": {
|
|
76
|
-
"build": "tsc",
|
|
77
|
-
"prepare": "tsc",
|
|
78
|
-
"clean": "rm -rf dist",
|
|
79
|
-
"test": "jest --passWithNoTests",
|
|
80
|
-
"gen:pkdigest": "node scripts/gen_wots_pkdigest_vectors.cjs"
|
|
81
|
-
},
|
|
82
116
|
"files": [
|
|
83
117
|
"dist",
|
|
84
118
|
"README.md",
|
|
@@ -109,7 +143,7 @@
|
|
|
109
143
|
"repository": {
|
|
110
144
|
"type": "git",
|
|
111
145
|
"url": "git+https://github.com/totem-sdk/totem-sdk.git",
|
|
112
|
-
"directory": "packages/
|
|
146
|
+
"directory": "packages/core"
|
|
113
147
|
},
|
|
114
148
|
"keywords": [
|
|
115
149
|
"totem",
|
|
@@ -118,7 +152,12 @@
|
|
|
118
152
|
"blockchain",
|
|
119
153
|
"quantum-resistant",
|
|
120
154
|
"wots",
|
|
121
|
-
"kissvm",
|
|
122
155
|
"utxo"
|
|
123
|
-
]
|
|
124
|
-
|
|
156
|
+
],
|
|
157
|
+
"scripts": {
|
|
158
|
+
"build": "tsc && tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('dist/cjs/package.json', JSON.stringify({type:'commonjs'})+'\\n')\"",
|
|
159
|
+
"clean": "rm -rf dist",
|
|
160
|
+
"test": "jest",
|
|
161
|
+
"gen:pkdigest": "node scripts/gen_wots_pkdigest_vectors.cjs"
|
|
162
|
+
}
|
|
163
|
+
}
|