@noble/post-quantum 0.6.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +45 -32
- package/_crystals.d.ts +17 -15
- package/_crystals.d.ts.map +1 -1
- package/_crystals.js +13 -3
- package/_crystals.js.map +1 -1
- package/falcon.d.ts +7 -7
- package/falcon.d.ts.map +1 -1
- package/falcon.js +27 -20
- package/falcon.js.map +1 -1
- package/hybrid.d.ts +23 -23
- package/hybrid.d.ts.map +1 -1
- package/hybrid.js +37 -28
- package/hybrid.js.map +1 -1
- package/index.js +8 -0
- package/index.js.map +1 -1
- package/ml-dsa.d.ts +7 -7
- package/ml-dsa.d.ts.map +1 -1
- package/ml-dsa.js +54 -28
- package/ml-dsa.js.map +1 -1
- package/ml-kem.d.ts +4 -4
- package/ml-kem.d.ts.map +1 -1
- package/ml-kem.js +43 -26
- package/ml-kem.js.map +1 -1
- package/package.json +5 -5
- package/slh-dsa.d.ts +21 -21
- package/slh-dsa.d.ts.map +1 -1
- package/slh-dsa.js +57 -35
- package/slh-dsa.js.map +1 -1
- package/src/_crystals.ts +44 -27
- package/src/falcon.ts +150 -117
- package/src/hybrid.ts +145 -96
- package/src/index.ts +8 -0
- package/src/ml-dsa.ts +124 -69
- package/src/ml-kem.ts +114 -85
- package/src/slh-dsa.ts +211 -132
- package/src/utils.ts +174 -34
- package/utils.d.ts +81 -22
- package/utils.d.ts.map +1 -1
- package/utils.js +30 -8
- package/utils.js.map +1 -1
package/src/slh-dsa.ts
CHANGED
|
@@ -53,6 +53,8 @@ import {
|
|
|
53
53
|
vecCoder,
|
|
54
54
|
type Signer,
|
|
55
55
|
type SigOpts,
|
|
56
|
+
type TArg,
|
|
57
|
+
type TRet,
|
|
56
58
|
type VerOpts,
|
|
57
59
|
} from './utils.ts';
|
|
58
60
|
|
|
@@ -96,14 +98,14 @@ export type SphincsHashOpts = {
|
|
|
96
98
|
* stay derived at the export layer.
|
|
97
99
|
*/
|
|
98
100
|
export const PARAMS: Record<string, SphincsOpts> = /* @__PURE__ */ (() =>
|
|
99
|
-
({
|
|
100
|
-
'128f': { W: 16, N: 16, H: 66, D: 22, K: 33, A: 6, securityLevel: 128 },
|
|
101
|
-
'128s': { W: 16, N: 16, H: 63, D: 7, K: 14, A: 12, securityLevel: 128 },
|
|
102
|
-
'192f': { W: 16, N: 24, H: 66, D: 22, K: 33, A: 8, securityLevel: 192 },
|
|
103
|
-
'192s': { W: 16, N: 24, H: 63, D: 7, K: 17, A: 14, securityLevel: 192 },
|
|
104
|
-
'256f': { W: 16, N: 32, H: 68, D: 17, K: 35, A: 9, securityLevel: 256 },
|
|
105
|
-
'256s': { W: 16, N: 32, H: 64, D: 8, K: 22, A: 14, securityLevel: 256 },
|
|
106
|
-
}
|
|
101
|
+
Object.freeze({
|
|
102
|
+
'128f': Object.freeze({ W: 16, N: 16, H: 66, D: 22, K: 33, A: 6, securityLevel: 128 }),
|
|
103
|
+
'128s': Object.freeze({ W: 16, N: 16, H: 63, D: 7, K: 14, A: 12, securityLevel: 128 }),
|
|
104
|
+
'192f': Object.freeze({ W: 16, N: 24, H: 66, D: 22, K: 33, A: 8, securityLevel: 192 }),
|
|
105
|
+
'192s': Object.freeze({ W: 16, N: 24, H: 63, D: 7, K: 17, A: 14, securityLevel: 192 }),
|
|
106
|
+
'256f': Object.freeze({ W: 16, N: 32, H: 68, D: 17, K: 35, A: 9, securityLevel: 256 }),
|
|
107
|
+
'256s': Object.freeze({ W: 16, N: 32, H: 64, D: 8, K: 22, A: 14, securityLevel: 256 }),
|
|
108
|
+
} as const))();
|
|
107
109
|
|
|
108
110
|
// FIPS 205 `ADRS.setTypeAndClear(...)` selectors. Local names shorten the spec labels
|
|
109
111
|
// (`WOTS_HASH` -> `WOTS`, `TREE` -> `HASHTREE`, `FORS_ROOTS` -> `FORSPK`), and `setAddr({ type })`
|
|
@@ -128,7 +130,7 @@ export type Context = {
|
|
|
128
130
|
* @param addr - Address bytes.
|
|
129
131
|
* @returns PRF output bytes.
|
|
130
132
|
*/
|
|
131
|
-
PRFaddr: (addr: ADRS) => Uint8Array
|
|
133
|
+
PRFaddr: (addr: TArg<ADRS>) => TRet<Uint8Array>;
|
|
132
134
|
/**
|
|
133
135
|
* Derive the randomized message hash prefix.
|
|
134
136
|
* @param skPRF - Secret PRF seed.
|
|
@@ -136,7 +138,11 @@ export type Context = {
|
|
|
136
138
|
* @param msg - Message bytes.
|
|
137
139
|
* @returns PRF output bytes.
|
|
138
140
|
*/
|
|
139
|
-
PRFmsg: (
|
|
141
|
+
PRFmsg: (
|
|
142
|
+
skPRF: TArg<Uint8Array>,
|
|
143
|
+
random: TArg<Uint8Array>,
|
|
144
|
+
msg: TArg<Uint8Array>
|
|
145
|
+
) => TRet<Uint8Array>;
|
|
140
146
|
/**
|
|
141
147
|
* Hash one randomized message transcript.
|
|
142
148
|
* @param R - Randomized message prefix.
|
|
@@ -145,14 +151,19 @@ export type Context = {
|
|
|
145
151
|
* @param outLen - Output length in bytes.
|
|
146
152
|
* @returns Transcript hash bytes.
|
|
147
153
|
*/
|
|
148
|
-
Hmsg: (
|
|
154
|
+
Hmsg: (
|
|
155
|
+
R: TArg<Uint8Array>,
|
|
156
|
+
pk: TArg<Uint8Array>,
|
|
157
|
+
m: TArg<Uint8Array>,
|
|
158
|
+
outLen: number
|
|
159
|
+
) => TRet<Uint8Array>;
|
|
149
160
|
/**
|
|
150
161
|
* Tweakable hash over one input block.
|
|
151
162
|
* @param input - Input block.
|
|
152
163
|
* @param addr - Address bytes.
|
|
153
164
|
* @returns Hash output bytes.
|
|
154
165
|
*/
|
|
155
|
-
thash1: (input: Uint8Array
|
|
166
|
+
thash1: (input: TArg<Uint8Array>, addr: TArg<ADRS>) => TRet<Uint8Array>;
|
|
156
167
|
/**
|
|
157
168
|
* Tweakable hash over multiple input blocks.
|
|
158
169
|
* @param blocks - Number of input blocks.
|
|
@@ -160,14 +171,14 @@ export type Context = {
|
|
|
160
171
|
* @param addr - Address bytes.
|
|
161
172
|
* @returns Hash output bytes.
|
|
162
173
|
*/
|
|
163
|
-
thashN: (blocks: number, input: Uint8Array
|
|
174
|
+
thashN: (blocks: number, input: TArg<Uint8Array>, addr: TArg<ADRS>) => TRet<Uint8Array>;
|
|
164
175
|
/** Wipe any buffered hash state for the current context. */
|
|
165
176
|
clean: () => void;
|
|
166
177
|
};
|
|
167
178
|
/** Factory that creates a context generator for one SLH-DSA parameter set. */
|
|
168
179
|
export type GetContext = (
|
|
169
180
|
opts: SphincsOpts
|
|
170
|
-
) => (pub_seed: Uint8Array
|
|
181
|
+
) => (pub_seed: TArg<Uint8Array>, sk_seed?: TArg<Uint8Array>) => TRet<Context>;
|
|
171
182
|
|
|
172
183
|
function hexToNumber(hex: string): bigint {
|
|
173
184
|
if (typeof hex !== 'string') throw new Error('hex string expected, got ' + typeof hex);
|
|
@@ -175,12 +186,12 @@ function hexToNumber(hex: string): bigint {
|
|
|
175
186
|
}
|
|
176
187
|
|
|
177
188
|
// BE: Big Endian, LE: Little Endian. This is the local FIPS 205 `toInt(...)` equivalent.
|
|
178
|
-
function bytesToNumberBE(bytes: Uint8Array): bigint {
|
|
189
|
+
function bytesToNumberBE(bytes: TArg<Uint8Array>): bigint {
|
|
179
190
|
return hexToNumber(bytesToHex(bytes));
|
|
180
191
|
}
|
|
181
192
|
|
|
182
193
|
// Local in-range FIPS 205 `toByte(x, n)` equivalent; callers must keep `n < 256^len`.
|
|
183
|
-
function numberToBytesBE(n: number | bigint, len: number): Uint8Array {
|
|
194
|
+
function numberToBytesBE(n: number | bigint, len: number): TRet<Uint8Array> {
|
|
184
195
|
return hexToBytes(n.toString(16).padStart(len * 2, '0'));
|
|
185
196
|
}
|
|
186
197
|
|
|
@@ -189,7 +200,7 @@ function numberToBytesBE(n: number | bigint, len: number): Uint8Array {
|
|
|
189
200
|
// short inputs are not rejected and would zero-extend implicitly.
|
|
190
201
|
const base2b = (outLen: number, b: number) => {
|
|
191
202
|
const mask = getMask(b);
|
|
192
|
-
return (bytes: Uint8Array) => {
|
|
203
|
+
return (bytes: TArg<Uint8Array>): TRet<Uint32Array> => {
|
|
193
204
|
const baseB = new Uint32Array(outLen);
|
|
194
205
|
for (let out = 0, pos = 0, bits = 0, total = 0; out < outLen; out++) {
|
|
195
206
|
while (bits < b) {
|
|
@@ -199,7 +210,7 @@ const base2b = (outLen: number, b: number) => {
|
|
|
199
210
|
bits -= b;
|
|
200
211
|
baseB[out] = (total >>> bits) & mask;
|
|
201
212
|
}
|
|
202
|
-
return baseB
|
|
213
|
+
return baseB as TRet<Uint32Array>;
|
|
203
214
|
};
|
|
204
215
|
};
|
|
205
216
|
|
|
@@ -209,9 +220,9 @@ function getMaskBig(bits: number) {
|
|
|
209
220
|
|
|
210
221
|
/** Public SLH-DSA signer with prehash customization. */
|
|
211
222
|
export type SphincsSigner = Signer & {
|
|
212
|
-
internal: Signer
|
|
223
|
+
internal: TRet<Signer>;
|
|
213
224
|
securityLevel: number;
|
|
214
|
-
prehash: (hash: CHash) => Signer
|
|
225
|
+
prehash: (hash: TArg<CHash>) => TRet<Signer>;
|
|
215
226
|
};
|
|
216
227
|
|
|
217
228
|
/** One parameter/hash instantiation of the public SLH-DSA API.
|
|
@@ -219,7 +230,8 @@ export type SphincsSigner = Signer & {
|
|
|
219
230
|
* and `getPublicKey(secretKey)` only extracts the embedded public key
|
|
220
231
|
* instead of recomputing `PK.root`.
|
|
221
232
|
*/
|
|
222
|
-
function gen(opts: SphincsOpts,
|
|
233
|
+
function gen(opts: SphincsOpts, hashOpts_: TArg<SphincsHashOpts>): TRet<SphincsSigner> {
|
|
234
|
+
const hashOpts = hashOpts_ as SphincsHashOpts;
|
|
223
235
|
const { N, W, H, D, K, A, securityLevel: securityLevel } = opts;
|
|
224
236
|
const getContext = hashOpts.getContext(opts);
|
|
225
237
|
if (W !== 16) throw new Error('Unsupported Winternitz parameter');
|
|
@@ -256,7 +268,7 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
256
268
|
// `height` / `chain` and `index` / `hash` share the same spec words, so callers must use the
|
|
257
269
|
// address-type-specific combinations instead of mixing both meanings in one call.
|
|
258
270
|
const setAddr = (
|
|
259
|
-
opts: {
|
|
271
|
+
opts: TArg<{
|
|
260
272
|
type?: (typeof AddressType)[keyof typeof AddressType];
|
|
261
273
|
height?: number;
|
|
262
274
|
tree?: bigint;
|
|
@@ -267,8 +279,8 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
267
279
|
keypair?: number;
|
|
268
280
|
subtreeAddr?: ADRS;
|
|
269
281
|
keypairAddr?: ADRS;
|
|
270
|
-
}
|
|
271
|
-
addr: ADRS = new Uint8Array(ADDR_BYTES)
|
|
282
|
+
}>,
|
|
283
|
+
addr: TArg<ADRS> = new Uint8Array(ADDR_BYTES)
|
|
272
284
|
) => {
|
|
273
285
|
const { type, height, tree, layer, index, chain, hash, keypair } = opts;
|
|
274
286
|
const { subtreeAddr, keypairAddr } = opts;
|
|
@@ -295,7 +307,7 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
295
307
|
};
|
|
296
308
|
|
|
297
309
|
const chainCoder = base2b(WOTS_LEN2, WOTS_LOGW);
|
|
298
|
-
const chainLengths = (msg: Uint8Array) => {
|
|
310
|
+
const chainLengths = (msg: TArg<Uint8Array>) => {
|
|
299
311
|
const W1 = base2b(WOTS_LEN1, WOTS_LOGW)(msg);
|
|
300
312
|
let csum = 0;
|
|
301
313
|
for (let i = 0; i < W1.length; i++) csum += W - 1 - W1[i]; // ▷ Compute checksum
|
|
@@ -321,9 +333,15 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
321
333
|
);
|
|
322
334
|
// `pkSeed` is the full public key byte string `PK.seed || PK.root`; after splitting `Hmsg`,
|
|
323
335
|
// mask away any spare high bits so `idx_tree` / `idx_leaf` match the spec's final mod-2^k steps.
|
|
324
|
-
const hashMessage = (
|
|
336
|
+
const hashMessage = (
|
|
337
|
+
R: TArg<Uint8Array>,
|
|
338
|
+
pkSeed: TArg<Uint8Array>,
|
|
339
|
+
msg: TArg<Uint8Array>,
|
|
340
|
+
context: TArg<Context>
|
|
341
|
+
) => {
|
|
342
|
+
const rawContext = context as Context;
|
|
325
343
|
// digest ← Hmsg(R, PK.seed, PK.root, M)
|
|
326
|
-
const digest =
|
|
344
|
+
const digest = rawContext.Hmsg(R, pkSeed, msg, hashMsgCoder.bytesLen);
|
|
327
345
|
const [md, tmpIdxTree, tmpIdxLeaf] = hashMsgCoder.decode(digest);
|
|
328
346
|
const tree = bytesToNumberBE(tmpIdxTree) & getMaskBig(TREE_BITS);
|
|
329
347
|
const leafIdx = Number(bytesToNumberBE(tmpIdxLeaf)) & getMask(LEAF_BITS);
|
|
@@ -335,15 +353,22 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
335
353
|
// neighbor of the target leaf at that height.
|
|
336
354
|
const treehash = <T>(
|
|
337
355
|
height: number,
|
|
338
|
-
fn: (leafIdx: number, addrOffset: number, context: Context, info: T) => Uint8Array
|
|
356
|
+
fn: TArg<(leafIdx: number, addrOffset: number, context: Context, info: T) => Uint8Array>
|
|
339
357
|
) =>
|
|
340
358
|
function treehash_i(
|
|
341
|
-
context: Context
|
|
359
|
+
context: TArg<Context>,
|
|
342
360
|
leafIdx: number,
|
|
343
361
|
idxOffset: number,
|
|
344
|
-
treeAddr: ADRS
|
|
362
|
+
treeAddr: TArg<ADRS>,
|
|
345
363
|
info: T
|
|
346
364
|
) {
|
|
365
|
+
const rawContext = context as Context;
|
|
366
|
+
const leafFn = fn as (
|
|
367
|
+
leafIdx: number,
|
|
368
|
+
addrOffset: number,
|
|
369
|
+
context: Context,
|
|
370
|
+
info: T
|
|
371
|
+
) => Uint8Array;
|
|
347
372
|
const maxIdx = (1 << height) - 1;
|
|
348
373
|
const stack = new Uint8Array(height * N);
|
|
349
374
|
const authPath = new Uint8Array(height * N);
|
|
@@ -352,7 +377,7 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
352
377
|
const cur0 = current.subarray(0, N);
|
|
353
378
|
const cur1 = current.subarray(N);
|
|
354
379
|
const addrOffset = idx + idxOffset;
|
|
355
|
-
cur1.set(
|
|
380
|
+
cur1.set(leafFn(leafIdx, addrOffset, rawContext, info));
|
|
356
381
|
let h = 0;
|
|
357
382
|
for (let i = idx, o = idxOffset, l = leafIdx; ; h++, i >>>= 1, l >>>= 1, o >>>= 1) {
|
|
358
383
|
if (h === height) return { root: cur1, authPath }; // Returns from here
|
|
@@ -360,7 +385,7 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
360
385
|
if ((i & 1) === 0 && idx < maxIdx) break;
|
|
361
386
|
setAddr({ height: h + 1, index: (i >> 1) + (o >> 1) }, treeAddr);
|
|
362
387
|
cur0.set(stack.subarray(h * N).subarray(0, N));
|
|
363
|
-
cur1.set(
|
|
388
|
+
cur1.set(rawContext.thashN(2, current, treeAddr));
|
|
364
389
|
}
|
|
365
390
|
stack.subarray(h * N).set(cur1); // stack.push(cur1)
|
|
366
391
|
}
|
|
@@ -374,45 +399,53 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
374
399
|
leafAddr: ADRS;
|
|
375
400
|
pkAddr: ADRS;
|
|
376
401
|
};
|
|
377
|
-
const wotsTreehash = treehash(
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
402
|
+
const wotsTreehash = treehash(
|
|
403
|
+
TREE_HEIGHT,
|
|
404
|
+
(leafIdx: number, addrOffset: number, context: TArg<Context>, info: TArg<LeafInfo>) => {
|
|
405
|
+
const rawContext = context as Context;
|
|
406
|
+
const wotsPk = new Uint8Array(WOTS_LEN * N);
|
|
407
|
+
// `keygen()` passes `leafIdx = ~0 >>> 0`, so no real XMSS leaf matches and this suppresses
|
|
408
|
+
// WOTS signature capture while still hashing every chain to its public-key endpoint.
|
|
409
|
+
const wotsKmask = addrOffset === leafIdx ? 0 : ~0 >>> 0;
|
|
410
|
+
setAddr({ keypair: addrOffset }, info.leafAddr);
|
|
411
|
+
setAddr({ keypair: addrOffset }, info.pkAddr);
|
|
412
|
+
for (let i = 0; i < WOTS_LEN; i++) {
|
|
413
|
+
const wotsK = info.wotsSteps[i] | wotsKmask;
|
|
414
|
+
const pk = wotsPk.subarray(i * N, (i + 1) * N);
|
|
415
|
+
setAddr({ chain: i, hash: 0, type: AddressType.WOTSPRF }, info.leafAddr);
|
|
416
|
+
pk.set(rawContext.PRFaddr(info.leafAddr));
|
|
417
|
+
setAddr({ type: AddressType.WOTS }, info.leafAddr);
|
|
418
|
+
for (let k = 0; ; k++) {
|
|
419
|
+
if (k === wotsK) info.wotsSig.subarray(i * N).set(pk); //wotsSig.push()
|
|
420
|
+
if (k === W - 1) break;
|
|
421
|
+
setAddr({ hash: k }, info.leafAddr);
|
|
422
|
+
pk.set(rawContext.thash1(pk, info.leafAddr));
|
|
423
|
+
}
|
|
395
424
|
}
|
|
425
|
+
return rawContext.thashN(WOTS_LEN, wotsPk, info.pkAddr);
|
|
396
426
|
}
|
|
397
|
-
|
|
398
|
-
});
|
|
427
|
+
);
|
|
399
428
|
|
|
400
|
-
const forsTreehash = treehash(
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
429
|
+
const forsTreehash = treehash(
|
|
430
|
+
A,
|
|
431
|
+
(_: number, addrOffset: number, context: TArg<Context>, forsLeafAddr: TArg<ForsLeafInfo>) => {
|
|
432
|
+
const rawContext = context as Context;
|
|
433
|
+
setAddr({ type: AddressType.FORSPRF, index: addrOffset }, forsLeafAddr);
|
|
434
|
+
const prf = rawContext.PRFaddr(forsLeafAddr);
|
|
435
|
+
setAddr({ type: AddressType.FORSTREE }, forsLeafAddr);
|
|
436
|
+
return rawContext.thash1(prf, forsLeafAddr);
|
|
437
|
+
}
|
|
438
|
+
);
|
|
406
439
|
|
|
407
440
|
// Fuse `xmss_sign` with the subtree-root computation needed by `ht_sign`, so one tree walk
|
|
408
441
|
// yields both the WOTS/auth-path signature and the root that the next hypertree layer signs.
|
|
409
442
|
const merkleSign = (
|
|
410
|
-
context: Context
|
|
411
|
-
wotsAddr: ADRS
|
|
412
|
-
treeAddr: ADRS
|
|
443
|
+
context: TArg<Context>,
|
|
444
|
+
wotsAddr: TArg<ADRS>,
|
|
445
|
+
treeAddr: TArg<ADRS>,
|
|
413
446
|
leafIdx: number,
|
|
414
|
-
prevRoot: Uint8Array = new Uint8Array(N)
|
|
415
|
-
) => {
|
|
447
|
+
prevRoot: TArg<Uint8Array> = new Uint8Array(N)
|
|
448
|
+
): TRet<{ root: Uint8Array; sigWots: Uint8Array; sigAuth: Uint8Array }> => {
|
|
416
449
|
setAddr({ type: AddressType.HASHTREE }, treeAddr);
|
|
417
450
|
// State variables
|
|
418
451
|
const info = {
|
|
@@ -426,20 +459,21 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
426
459
|
root,
|
|
427
460
|
sigWots: info.wotsSig.subarray(0, WOTS_LEN * N),
|
|
428
461
|
sigAuth: authPath,
|
|
429
|
-
};
|
|
462
|
+
} as TRet<{ root: Uint8Array; sigWots: Uint8Array; sigAuth: Uint8Array }>;
|
|
430
463
|
};
|
|
431
464
|
|
|
432
465
|
type ForsLeafInfo = ADRS;
|
|
433
466
|
|
|
434
467
|
const computeRoot = (
|
|
435
|
-
leaf: Uint8Array
|
|
468
|
+
leaf: TArg<Uint8Array>,
|
|
436
469
|
leafIdx: number,
|
|
437
470
|
idxOffset: number,
|
|
438
|
-
authPath: Uint8Array
|
|
471
|
+
authPath: TArg<Uint8Array>,
|
|
439
472
|
treeHeight: number,
|
|
440
|
-
context: Context
|
|
441
|
-
addr: ADRS
|
|
473
|
+
context: TArg<Context>,
|
|
474
|
+
addr: TArg<ADRS>
|
|
442
475
|
) => {
|
|
476
|
+
const rawContext = context as Context;
|
|
443
477
|
const buffer = new Uint8Array(2 * N);
|
|
444
478
|
const b0 = buffer.subarray(0, N);
|
|
445
479
|
const b1 = buffer.subarray(N, 2 * N);
|
|
@@ -462,16 +496,16 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
462
496
|
setAddr({ height: i + 1, index: leafIdx + idxOffset }, addr);
|
|
463
497
|
const a = authPath.subarray((i + 1) * N, (i + 2) * N);
|
|
464
498
|
if ((leafIdx & 1) !== 0) {
|
|
465
|
-
b1.set(
|
|
499
|
+
b1.set(rawContext.thashN(2, buffer, addr));
|
|
466
500
|
b0.set(a);
|
|
467
501
|
} else {
|
|
468
|
-
buffer.set(
|
|
502
|
+
buffer.set(rawContext.thashN(2, buffer, addr));
|
|
469
503
|
b1.set(a);
|
|
470
504
|
}
|
|
471
505
|
}
|
|
472
506
|
// Root
|
|
473
507
|
setAddr({ height: treeHeight, index: leafIdx + idxOffset }, addr);
|
|
474
|
-
return
|
|
508
|
+
return rawContext.thashN(2, buffer, addr);
|
|
475
509
|
};
|
|
476
510
|
|
|
477
511
|
const seedCoder = splitCoder('seed', N, N, N);
|
|
@@ -480,16 +514,16 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
480
514
|
const forsCoder = vecCoder(splitCoder('fors', N, N * A), K);
|
|
481
515
|
const wotsCoder = vecCoder(splitCoder('wots', WOTS_LEN * N, TREE_HEIGHT * N), D);
|
|
482
516
|
const sigCoder = splitCoder('signature', N, forsCoder, wotsCoder); // random || fors || wots
|
|
483
|
-
const internal: Signer = {
|
|
484
|
-
info: { type: 'internal-slh-dsa' },
|
|
485
|
-
lengths: {
|
|
517
|
+
const internal: TRet<Signer> = Object.freeze({
|
|
518
|
+
info: Object.freeze({ type: 'internal-slh-dsa' }),
|
|
519
|
+
lengths: Object.freeze({
|
|
486
520
|
publicKey: publicCoder.bytesLen,
|
|
487
521
|
secretKey: secretCoder.bytesLen,
|
|
488
522
|
signature: sigCoder.bytesLen,
|
|
489
523
|
seed: seedCoder.bytesLen,
|
|
490
524
|
signRand: N,
|
|
491
|
-
},
|
|
492
|
-
keygen(seed?: Uint8Array) {
|
|
525
|
+
}),
|
|
526
|
+
keygen(seed?: TArg<Uint8Array>) {
|
|
493
527
|
if (seed !== undefined) abytes(seed, seedCoder.bytesLen, 'seed');
|
|
494
528
|
seed = seed === undefined ? randomBytes(seedCoder.bytesLen) : copyBytes(seed);
|
|
495
529
|
// Set SK.seed, SK.prf, and PK.seed to random n-byte
|
|
@@ -504,13 +538,16 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
504
538
|
const secretKey = secretCoder.encode([secretSeed, secretPRF, publicKey]);
|
|
505
539
|
context.clean();
|
|
506
540
|
cleanBytes(secretSeed, secretPRF, root, wotsAddr, topTreeAddr);
|
|
507
|
-
return {
|
|
541
|
+
return {
|
|
542
|
+
publicKey: publicKey as TRet<Uint8Array>,
|
|
543
|
+
secretKey: secretKey as TRet<Uint8Array>,
|
|
544
|
+
};
|
|
508
545
|
},
|
|
509
|
-
getPublicKey: (secretKey: Uint8Array) => {
|
|
546
|
+
getPublicKey: (secretKey: TArg<Uint8Array>): TRet<Uint8Array> => {
|
|
510
547
|
const [_skSeed, _skPRF, pk] = secretCoder.decode(secretKey);
|
|
511
|
-
return Uint8Array.from(pk)
|
|
548
|
+
return Uint8Array.from(pk) as TRet<Uint8Array>;
|
|
512
549
|
},
|
|
513
|
-
sign: (msg: Uint8Array
|
|
550
|
+
sign: (msg: TArg<Uint8Array>, sk: TArg<Uint8Array>, opts: TArg<SigOpts> = {}) => {
|
|
514
551
|
validateSigOpts(opts);
|
|
515
552
|
let { extraEntropy: random } = opts;
|
|
516
553
|
const [skSeed, skPRF, pk] = secretCoder.decode(sk); // todo: fix
|
|
@@ -581,9 +618,9 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
581
618
|
context.clean();
|
|
582
619
|
const SIG = sigCoder.encode([R, fors, wots]);
|
|
583
620
|
cleanBytes(R, random, treeAddr, wotsAddr, forsLeaf, forsTreeAddr, indices, roots);
|
|
584
|
-
return SIG
|
|
621
|
+
return SIG as TRet<Uint8Array>;
|
|
585
622
|
},
|
|
586
|
-
verify: (sig: Uint8Array
|
|
623
|
+
verify: (sig: TArg<Uint8Array>, msg: TArg<Uint8Array>, publicKey: TArg<Uint8Array>) => {
|
|
587
624
|
const [pkSeed, pubRoot] = publicCoder.decode(publicKey);
|
|
588
625
|
const [random, forsVec, wotsVec] = sigCoder.decode(sig);
|
|
589
626
|
const pk = publicKey;
|
|
@@ -642,78 +679,106 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
|
|
|
642
679
|
}
|
|
643
680
|
return equalBytes(root, pubRoot);
|
|
644
681
|
},
|
|
645
|
-
};
|
|
646
|
-
return {
|
|
647
|
-
info: { type: 'slh-dsa' },
|
|
682
|
+
});
|
|
683
|
+
return Object.freeze({
|
|
684
|
+
info: Object.freeze({ type: 'slh-dsa' }),
|
|
648
685
|
internal,
|
|
649
686
|
securityLevel: securityLevel,
|
|
650
687
|
lengths: internal.lengths,
|
|
651
688
|
keygen: internal.keygen,
|
|
652
689
|
getPublicKey: internal.getPublicKey,
|
|
653
|
-
sign: (msg: Uint8Array
|
|
690
|
+
sign: (msg: TArg<Uint8Array>, secretKey: TArg<Uint8Array>, opts: TArg<SigOpts> = {}) => {
|
|
654
691
|
validateSigOpts(opts);
|
|
655
692
|
const M = getMessage(msg, opts.context);
|
|
656
693
|
const res = internal.sign(M, secretKey, opts);
|
|
657
694
|
cleanBytes(M);
|
|
658
|
-
return res
|
|
695
|
+
return res as TRet<Uint8Array>;
|
|
659
696
|
},
|
|
660
|
-
verify: (
|
|
697
|
+
verify: (
|
|
698
|
+
sig: TArg<Uint8Array>,
|
|
699
|
+
msg: TArg<Uint8Array>,
|
|
700
|
+
publicKey: TArg<Uint8Array>,
|
|
701
|
+
opts: TArg<VerOpts> = {}
|
|
702
|
+
) => {
|
|
661
703
|
validateVerOpts(opts);
|
|
662
704
|
return internal.verify(sig, getMessage(msg, opts.context), publicKey);
|
|
663
705
|
},
|
|
664
|
-
prehash: (hash: CHash) => {
|
|
665
|
-
checkHash(hash, securityLevel);
|
|
666
|
-
|
|
667
|
-
|
|
706
|
+
prehash: (hash: TArg<CHash>): TRet<Signer> => {
|
|
707
|
+
checkHash(hash as CHash, securityLevel);
|
|
708
|
+
const rawHash = hash as CHash;
|
|
709
|
+
return Object.freeze({
|
|
710
|
+
info: Object.freeze({ type: 'hashslh-dsa' }),
|
|
668
711
|
lengths: internal.lengths,
|
|
669
712
|
keygen: internal.keygen,
|
|
670
713
|
getPublicKey: internal.getPublicKey,
|
|
671
|
-
sign: (msg: Uint8Array
|
|
714
|
+
sign: (msg: TArg<Uint8Array>, secretKey: TArg<Uint8Array>, opts: TArg<SigOpts> = {}) => {
|
|
672
715
|
validateSigOpts(opts);
|
|
673
|
-
const M = getMessagePrehash(
|
|
716
|
+
const M = getMessagePrehash(rawHash, msg, opts.context);
|
|
674
717
|
const res = internal.sign(M, secretKey, opts);
|
|
675
718
|
cleanBytes(M);
|
|
676
|
-
return res
|
|
719
|
+
return res as TRet<Uint8Array>;
|
|
677
720
|
},
|
|
678
|
-
verify: (
|
|
721
|
+
verify: (
|
|
722
|
+
sig: TArg<Uint8Array>,
|
|
723
|
+
msg: TArg<Uint8Array>,
|
|
724
|
+
publicKey: TArg<Uint8Array>,
|
|
725
|
+
opts: TArg<VerOpts> = {}
|
|
726
|
+
) => {
|
|
679
727
|
validateVerOpts(opts);
|
|
680
|
-
return internal.verify(sig, getMessagePrehash(
|
|
728
|
+
return internal.verify(sig, getMessagePrehash(rawHash, msg, opts.context), publicKey);
|
|
681
729
|
},
|
|
682
|
-
};
|
|
730
|
+
});
|
|
683
731
|
},
|
|
684
|
-
};
|
|
732
|
+
});
|
|
685
733
|
}
|
|
686
734
|
|
|
687
735
|
// FIPS 205 §11.1 SHAKE instantiation: this path hashes the full uncompressed address bytes,
|
|
688
736
|
// unlike the compressed 22-byte SHA2 path in §11.2.
|
|
689
737
|
const genShake =
|
|
690
|
-
(): GetContext =>
|
|
738
|
+
(): TRet<GetContext> =>
|
|
739
|
+
(opts: SphincsOpts) =>
|
|
740
|
+
(pubSeed: TArg<Uint8Array>, skSeed?: TArg<Uint8Array>): TRet<Context> => {
|
|
691
741
|
const { N } = opts;
|
|
692
742
|
const stats = { prf: 0, thash: 0, hmsg: 0, gen_message_random: 0 };
|
|
693
743
|
// §11.1 prefixes PRF/F/H/T_l with `PK.seed`, so cache that absorbed prefix once and clone it
|
|
694
744
|
// for each address-bound call instead of reabsorbing the same seed every time.
|
|
695
745
|
const h0 = shake256.create({}).update(pubSeed);
|
|
696
746
|
const h0tmp = h0.clone();
|
|
697
|
-
const thash = (blocks: number, input: Uint8Array
|
|
747
|
+
const thash = (blocks: number, input: TArg<Uint8Array>, addr: TArg<ADRS>): TRet<Uint8Array> => {
|
|
698
748
|
stats.thash++;
|
|
699
749
|
return h0
|
|
700
750
|
._cloneInto(h0tmp)
|
|
701
751
|
.update(addr)
|
|
702
752
|
.update(input.subarray(0, blocks * N))
|
|
703
|
-
.xof(N)
|
|
753
|
+
.xof(N) as TRet<Uint8Array>;
|
|
704
754
|
};
|
|
705
755
|
return {
|
|
706
|
-
PRFaddr: (addr: ADRS) => {
|
|
756
|
+
PRFaddr: (addr: TArg<ADRS>): TRet<Uint8Array> => {
|
|
707
757
|
if (!skSeed) throw new Error('no sk seed');
|
|
708
758
|
stats.prf++;
|
|
709
759
|
const res = h0._cloneInto(h0tmp).update(addr).update(skSeed).xof(N);
|
|
710
|
-
return res
|
|
760
|
+
return res as TRet<Uint8Array>;
|
|
711
761
|
},
|
|
712
|
-
PRFmsg: (
|
|
762
|
+
PRFmsg: (
|
|
763
|
+
skPRF: TArg<Uint8Array>,
|
|
764
|
+
random: TArg<Uint8Array>,
|
|
765
|
+
msg: TArg<Uint8Array>
|
|
766
|
+
): TRet<Uint8Array> => {
|
|
713
767
|
stats.gen_message_random++;
|
|
714
|
-
return shake256
|
|
768
|
+
return shake256
|
|
769
|
+
.create({})
|
|
770
|
+
.update(skPRF)
|
|
771
|
+
.update(random)
|
|
772
|
+
.update(msg)
|
|
773
|
+
.digest()
|
|
774
|
+
.subarray(0, N) as TRet<Uint8Array>;
|
|
715
775
|
},
|
|
716
|
-
Hmsg: (
|
|
776
|
+
Hmsg: (
|
|
777
|
+
R: TArg<Uint8Array>,
|
|
778
|
+
pk: TArg<Uint8Array>,
|
|
779
|
+
m: TArg<Uint8Array>,
|
|
780
|
+
outLen
|
|
781
|
+
): TRet<Uint8Array> => {
|
|
717
782
|
stats.hmsg++;
|
|
718
783
|
return shake256.create({}).update(R.subarray(0, N)).update(pk).update(m).xof(outLen);
|
|
719
784
|
},
|
|
@@ -724,7 +789,7 @@ const genShake =
|
|
|
724
789
|
h0tmp.destroy();
|
|
725
790
|
//console.log(stats);
|
|
726
791
|
},
|
|
727
|
-
}
|
|
792
|
+
} as TRet<Context>;
|
|
728
793
|
};
|
|
729
794
|
|
|
730
795
|
const SHAKE_SIMPLE = /* @__PURE__ */ (() => ({ getContext: genShake() }))();
|
|
@@ -734,42 +799,42 @@ const SHAKE_SIMPLE = /* @__PURE__ */ (() => ({ getContext: genShake() }))();
|
|
|
734
799
|
* lengths `publicKey=32`, `secretKey=64`, `signature=17088`, `seed=48`, `signRand=16`.
|
|
735
800
|
* Also exposes `.prehash(...)`.
|
|
736
801
|
*/
|
|
737
|
-
export const slh_dsa_shake_128f: SphincsSigner = /* @__PURE__ */ (() =>
|
|
802
|
+
export const slh_dsa_shake_128f: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
738
803
|
gen(PARAMS['128f'], SHAKE_SIMPLE))();
|
|
739
804
|
/**
|
|
740
805
|
* SLH-DSA-SHAKE-128s: Table 2 row `n=16, h=63, d=7, h'=9, a=12, k=14, lg w=4, m=30`;
|
|
741
806
|
* lengths `publicKey=32`, `secretKey=64`, `signature=7856`, `seed=48`, `signRand=16`.
|
|
742
807
|
* Also exposes `.prehash(...)`.
|
|
743
808
|
*/
|
|
744
|
-
export const slh_dsa_shake_128s: SphincsSigner = /* @__PURE__ */ (() =>
|
|
809
|
+
export const slh_dsa_shake_128s: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
745
810
|
gen(PARAMS['128s'], SHAKE_SIMPLE))();
|
|
746
811
|
/**
|
|
747
812
|
* SLH-DSA-SHAKE-192f: Table 2 row `n=24, h=66, d=22, h'=3, a=8, k=33, lg w=4, m=42`;
|
|
748
813
|
* lengths `publicKey=48`, `secretKey=96`, `signature=35664`, `seed=72`, `signRand=24`.
|
|
749
814
|
* Also exposes `.prehash(...)`.
|
|
750
815
|
*/
|
|
751
|
-
export const slh_dsa_shake_192f: SphincsSigner = /* @__PURE__ */ (() =>
|
|
816
|
+
export const slh_dsa_shake_192f: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
752
817
|
gen(PARAMS['192f'], SHAKE_SIMPLE))();
|
|
753
818
|
/**
|
|
754
819
|
* SLH-DSA-SHAKE-192s: Table 2 row `n=24, h=63, d=7, h'=9, a=14, k=17, lg w=4, m=39`;
|
|
755
820
|
* lengths `publicKey=48`, `secretKey=96`, `signature=16224`, `seed=72`, `signRand=24`.
|
|
756
821
|
* Also exposes `.prehash(...)`.
|
|
757
822
|
*/
|
|
758
|
-
export const slh_dsa_shake_192s: SphincsSigner = /* @__PURE__ */ (() =>
|
|
823
|
+
export const slh_dsa_shake_192s: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
759
824
|
gen(PARAMS['192s'], SHAKE_SIMPLE))();
|
|
760
825
|
/**
|
|
761
826
|
* SLH-DSA-SHAKE-256f: Table 2 row `n=32, h=68, d=17, h'=4, a=9, k=35, lg w=4, m=49`;
|
|
762
827
|
* lengths `publicKey=64`, `secretKey=128`, `signature=49856`, `seed=96`, `signRand=32`.
|
|
763
828
|
* Also exposes `.prehash(...)`.
|
|
764
829
|
*/
|
|
765
|
-
export const slh_dsa_shake_256f: SphincsSigner = /* @__PURE__ */ (() =>
|
|
830
|
+
export const slh_dsa_shake_256f: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
766
831
|
gen(PARAMS['256f'], SHAKE_SIMPLE))();
|
|
767
832
|
/**
|
|
768
833
|
* SLH-DSA-SHAKE-256s: Table 2 row `n=32, h=64, d=8, h'=8, a=14, k=22, lg w=4, m=47`;
|
|
769
834
|
* lengths `publicKey=64`, `secretKey=128`, `signature=29792`, `seed=96`, `signRand=32`.
|
|
770
835
|
* Also exposes `.prehash(...)`.
|
|
771
836
|
*/
|
|
772
|
-
export const slh_dsa_shake_256s: SphincsSigner = /* @__PURE__ */ (() =>
|
|
837
|
+
export const slh_dsa_shake_256s: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
773
838
|
gen(PARAMS['256s'], SHAKE_SIMPLE))();
|
|
774
839
|
|
|
775
840
|
type ShaType = typeof sha256 | typeof sha512;
|
|
@@ -777,9 +842,9 @@ type ShaType = typeof sha256 | typeof sha512;
|
|
|
777
842
|
// category-1 keeps everything on SHA-256, while category-3/5 keep `PRFaddr` / `thash1`
|
|
778
843
|
// on SHA-256 but switch `PRFmsg`, `Hmsg`, and multi-block `thashN` to SHA-512.
|
|
779
844
|
const genSha =
|
|
780
|
-
(h0: ShaType, h1: ShaType): GetContext =>
|
|
845
|
+
(h0: ShaType, h1: ShaType): TRet<GetContext> =>
|
|
781
846
|
(opts) =>
|
|
782
|
-
(pub_seed
|
|
847
|
+
(pub_seed: TArg<Uint8Array>, sk_seed?: TArg<Uint8Array>): TRet<Context> => {
|
|
783
848
|
const { N } = opts;
|
|
784
849
|
/*
|
|
785
850
|
Perf debug stats, how much hashes we call?
|
|
@@ -809,7 +874,7 @@ const genSha =
|
|
|
809
874
|
// This local helper is intentionally stricter than generic MGF1 reuse: current SLH-DSA callers
|
|
810
875
|
// only request tiny `m`-byte outputs, but the guard below rejects `length > 2^32` instead of
|
|
811
876
|
// RFC 8017's broader `maskLen > 2^32 * hLen` bound.
|
|
812
|
-
function mgf1(seed: Uint8Array
|
|
877
|
+
function mgf1(seed: TArg<Uint8Array>, length: number, hash: ShaType): TRet<Uint8Array> {
|
|
813
878
|
stats.mgf1++;
|
|
814
879
|
const out = new Uint8Array(Math.ceil(length / hash.outputLen) * hash.outputLen);
|
|
815
880
|
// NOT 2^32-1
|
|
@@ -820,22 +885,22 @@ const genSha =
|
|
|
820
885
|
o = o.subarray(hash.outputLen);
|
|
821
886
|
}
|
|
822
887
|
cleanBytes(out.subarray(length));
|
|
823
|
-
return out.subarray(0, length)
|
|
888
|
+
return out.subarray(0, length) as TRet<Uint8Array>;
|
|
824
889
|
}
|
|
825
890
|
|
|
826
891
|
const thash =
|
|
827
892
|
(_: ShaType, h: typeof h0ps, hTmp: typeof h0ps) =>
|
|
828
|
-
(blocks: number, input: Uint8Array
|
|
893
|
+
(blocks: number, input: TArg<Uint8Array>, addr: TArg<ADRS>): TRet<Uint8Array> => {
|
|
829
894
|
stats.thash++;
|
|
830
895
|
const d = h
|
|
831
896
|
._cloneInto(hTmp as any)
|
|
832
897
|
.update(addr)
|
|
833
898
|
.update(input.subarray(0, blocks * N))
|
|
834
899
|
.digest();
|
|
835
|
-
return d.subarray(0, N)
|
|
900
|
+
return d.subarray(0, N) as TRet<Uint8Array>;
|
|
836
901
|
};
|
|
837
902
|
return {
|
|
838
|
-
PRFaddr: (addr: ADRS) => {
|
|
903
|
+
PRFaddr: (addr: TArg<ADRS>): TRet<Uint8Array> => {
|
|
839
904
|
if (!sk_seed) throw new Error('No sk seed');
|
|
840
905
|
stats.prf++;
|
|
841
906
|
const res = h0ps
|
|
@@ -844,13 +909,27 @@ const genSha =
|
|
|
844
909
|
.update(sk_seed)
|
|
845
910
|
.digest()
|
|
846
911
|
.subarray(0, N);
|
|
847
|
-
return res
|
|
912
|
+
return res as TRet<Uint8Array>;
|
|
848
913
|
},
|
|
849
|
-
PRFmsg: (
|
|
914
|
+
PRFmsg: (
|
|
915
|
+
skPRF: TArg<Uint8Array>,
|
|
916
|
+
random: TArg<Uint8Array>,
|
|
917
|
+
msg: TArg<Uint8Array>
|
|
918
|
+
): TRet<Uint8Array> => {
|
|
850
919
|
stats.gen_message_random++;
|
|
851
|
-
return hmac
|
|
920
|
+
return hmac
|
|
921
|
+
.create(h1, skPRF)
|
|
922
|
+
.update(random)
|
|
923
|
+
.update(msg)
|
|
924
|
+
.digest()
|
|
925
|
+
.subarray(0, N) as TRet<Uint8Array>;
|
|
852
926
|
},
|
|
853
|
-
Hmsg: (
|
|
927
|
+
Hmsg: (
|
|
928
|
+
R: TArg<Uint8Array>,
|
|
929
|
+
pk: TArg<Uint8Array>,
|
|
930
|
+
m: TArg<Uint8Array>,
|
|
931
|
+
outLen
|
|
932
|
+
): TRet<Uint8Array> => {
|
|
854
933
|
stats.hmsg++;
|
|
855
934
|
const seed = concatBytes(
|
|
856
935
|
R.subarray(0, N),
|
|
@@ -868,7 +947,7 @@ const genSha =
|
|
|
868
947
|
h1tmp.destroy();
|
|
869
948
|
//console.log(stats);
|
|
870
949
|
},
|
|
871
|
-
}
|
|
950
|
+
} as TRet<Context>;
|
|
872
951
|
};
|
|
873
952
|
|
|
874
953
|
const SHA256_SIMPLE = /* @__PURE__ */ (() => ({
|
|
@@ -885,40 +964,40 @@ const SHA512_SIMPLE = /* @__PURE__ */ (() => ({
|
|
|
885
964
|
* lengths `publicKey=32`, `secretKey=64`, `signature=17088`, `seed=48`, `signRand=16`.
|
|
886
965
|
* Also exposes `.prehash(...)`.
|
|
887
966
|
*/
|
|
888
|
-
export const slh_dsa_sha2_128f: SphincsSigner = /* @__PURE__ */ (() =>
|
|
967
|
+
export const slh_dsa_sha2_128f: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
889
968
|
gen(PARAMS['128f'], SHA256_SIMPLE))();
|
|
890
969
|
/**
|
|
891
970
|
* SLH-DSA-SHA2-128s: Table 2 row `n=16, h=63, d=7, h'=9, a=12, k=14, lg w=4, m=30`;
|
|
892
971
|
* lengths `publicKey=32`, `secretKey=64`, `signature=7856`, `seed=48`, `signRand=16`.
|
|
893
972
|
* Also exposes `.prehash(...)`.
|
|
894
973
|
*/
|
|
895
|
-
export const slh_dsa_sha2_128s: SphincsSigner = /* @__PURE__ */ (() =>
|
|
974
|
+
export const slh_dsa_sha2_128s: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
896
975
|
gen(PARAMS['128s'], SHA256_SIMPLE))();
|
|
897
976
|
/**
|
|
898
977
|
* SLH-DSA-SHA2-192f: Table 2 row `n=24, h=66, d=22, h'=3, a=8, k=33, lg w=4, m=42`;
|
|
899
978
|
* lengths `publicKey=48`, `secretKey=96`, `signature=35664`, `seed=72`, `signRand=24`.
|
|
900
979
|
* Also exposes `.prehash(...)`.
|
|
901
980
|
*/
|
|
902
|
-
export const slh_dsa_sha2_192f: SphincsSigner = /* @__PURE__ */ (() =>
|
|
981
|
+
export const slh_dsa_sha2_192f: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
903
982
|
gen(PARAMS['192f'], SHA512_SIMPLE))();
|
|
904
983
|
/**
|
|
905
984
|
* SLH-DSA-SHA2-192s: Table 2 row `n=24, h=63, d=7, h'=9, a=14, k=17, lg w=4, m=39`;
|
|
906
985
|
* lengths `publicKey=48`, `secretKey=96`, `signature=16224`, `seed=72`, `signRand=24`.
|
|
907
986
|
* Also exposes `.prehash(...)`.
|
|
908
987
|
*/
|
|
909
|
-
export const slh_dsa_sha2_192s: SphincsSigner = /* @__PURE__ */ (() =>
|
|
988
|
+
export const slh_dsa_sha2_192s: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
910
989
|
gen(PARAMS['192s'], SHA512_SIMPLE))();
|
|
911
990
|
/**
|
|
912
991
|
* SLH-DSA-SHA2-256f: Table 2 row `n=32, h=68, d=17, h'=4, a=9, k=35, lg w=4, m=49`;
|
|
913
992
|
* lengths `publicKey=64`, `secretKey=128`, `signature=49856`, `seed=96`, `signRand=32`.
|
|
914
993
|
* Also exposes `.prehash(...)`.
|
|
915
994
|
*/
|
|
916
|
-
export const slh_dsa_sha2_256f: SphincsSigner = /* @__PURE__ */ (() =>
|
|
995
|
+
export const slh_dsa_sha2_256f: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
917
996
|
gen(PARAMS['256f'], SHA512_SIMPLE))();
|
|
918
997
|
/**
|
|
919
998
|
* SLH-DSA-SHA2-256s: Table 2 row `n=32, h=64, d=8, h'=8, a=14, k=22, lg w=4, m=47`;
|
|
920
999
|
* lengths `publicKey=64`, `secretKey=128`, `signature=29792`, `seed=96`, `signRand=32`.
|
|
921
1000
|
* Also exposes `.prehash(...)`.
|
|
922
1001
|
*/
|
|
923
|
-
export const slh_dsa_sha2_256s: SphincsSigner = /* @__PURE__ */ (() =>
|
|
1002
|
+
export const slh_dsa_sha2_256s: TRet<SphincsSigner> = /* @__PURE__ */ (() =>
|
|
924
1003
|
gen(PARAMS['256s'], SHA512_SIMPLE))();
|