@noble/post-quantum 0.5.4 → 0.6.0

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/src/slh-dsa.ts CHANGED
@@ -62,30 +62,52 @@ import {
62
62
  * * K: FORS trees numbers. A: FORS trees height
63
63
  */
64
64
  export type SphincsOpts = {
65
+ /** Security parameter in bytes. */
65
66
  N: number;
67
+ /** Winternitz parameter. */
66
68
  W: number;
69
+ /** Total hypertree height. */
67
70
  H: number;
71
+ /** Number of hypertree layers. */
68
72
  D: number;
73
+ /** Number of FORS trees. */
69
74
  K: number;
75
+ /** Height of each FORS tree. */
70
76
  A: number;
77
+ /** Target security level in bits. */
71
78
  securityLevel: number;
72
79
  };
73
80
 
81
+ /** Hash customization options for SLH-DSA context creation. */
74
82
  export type SphincsHashOpts = {
83
+ /** Whether to use the compressed-address variant from the standard. */
75
84
  isCompressed?: boolean;
85
+ /** Factory that binds one parameter set to one per-key hash context generator. */
76
86
  getContext: GetContext;
77
87
  };
78
88
 
79
89
  /** Winternitz signature params. */
80
- export const PARAMS: Record<string, SphincsOpts> = {
81
- '128f': { W: 16, N: 16, H: 66, D: 22, K: 33, A: 6, securityLevel: 128 },
82
- '128s': { W: 16, N: 16, H: 63, D: 7, K: 14, A: 12, securityLevel: 128 },
83
- '192f': { W: 16, N: 24, H: 66, D: 22, K: 33, A: 8, securityLevel: 192 },
84
- '192s': { W: 16, N: 24, H: 63, D: 7, K: 17, A: 14, securityLevel: 192 },
85
- '256f': { W: 16, N: 32, H: 68, D: 17, K: 35, A: 9, securityLevel: 256 },
86
- '256s': { W: 16, N: 32, H: 64, D: 8, K: 22, A: 14, securityLevel: 256 },
87
- } as const;
88
-
90
+ /**
91
+ * Built-in SLH-DSA Table 2 subset keyed by strength/profile.
92
+ * SHA2 and SHAKE pairs share the same numeric rows here, so the hash family is chosen separately.
93
+ * `securityLevel` stores 128/192/256-bit strengths for `checkHash(...)`,
94
+ * not Table 2's category labels 1/3/5.
95
+ * Other Table 2 columns such as `m`, public-key bytes, and signature bytes
96
+ * stay derived at the export layer.
97
+ */
98
+ 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
+ }) as const)();
107
+
108
+ // FIPS 205 `ADRS.setTypeAndClear(...)` selectors. Local names shorten the spec labels
109
+ // (`WOTS_HASH` -> `WOTS`, `TREE` -> `HASHTREE`, `FORS_ROOTS` -> `FORSPK`), and `setAddr({ type })`
110
+ // below only writes the type word; callers still need to preserve or overwrite the trailing words.
89
111
  const AddressType = {
90
112
  WOTS: 0,
91
113
  WOTSPK: 1,
@@ -96,17 +118,53 @@ const AddressType = {
96
118
  FORSPRF: 6,
97
119
  } as const;
98
120
 
99
- /** Address, byte array of size ADDR_BYTES */
121
+ /** Address byte array of size `ADDR_BYTES`. */
100
122
  export type ADRS = Uint8Array;
101
123
 
124
+ /** Hash and tweakable-hash callbacks bound to one SLH-DSA keypair context. */
102
125
  export type Context = {
126
+ /**
127
+ * Derive a PRF output for one address.
128
+ * @param addr - Address bytes.
129
+ * @returns PRF output bytes.
130
+ */
103
131
  PRFaddr: (addr: ADRS) => Uint8Array;
132
+ /**
133
+ * Derive the randomized message hash prefix.
134
+ * @param skPRF - Secret PRF seed.
135
+ * @param random - Per-signature randomness.
136
+ * @param msg - Message bytes.
137
+ * @returns PRF output bytes.
138
+ */
104
139
  PRFmsg: (skPRF: Uint8Array, random: Uint8Array, msg: Uint8Array) => Uint8Array;
140
+ /**
141
+ * Hash one randomized message transcript.
142
+ * @param R - Randomized message prefix.
143
+ * @param pk - Public key bytes.
144
+ * @param m - Message bytes.
145
+ * @param outLen - Output length in bytes.
146
+ * @returns Transcript hash bytes.
147
+ */
105
148
  Hmsg: (R: Uint8Array, pk: Uint8Array, m: Uint8Array, outLen: number) => Uint8Array;
149
+ /**
150
+ * Tweakable hash over one input block.
151
+ * @param input - Input block.
152
+ * @param addr - Address bytes.
153
+ * @returns Hash output bytes.
154
+ */
106
155
  thash1: (input: Uint8Array, addr: ADRS) => Uint8Array;
156
+ /**
157
+ * Tweakable hash over multiple input blocks.
158
+ * @param blocks - Number of input blocks.
159
+ * @param input - Concatenated input bytes.
160
+ * @param addr - Address bytes.
161
+ * @returns Hash output bytes.
162
+ */
107
163
  thashN: (blocks: number, input: Uint8Array, addr: ADRS) => Uint8Array;
164
+ /** Wipe any buffered hash state for the current context. */
108
165
  clean: () => void;
109
166
  };
167
+ /** Factory that creates a context generator for one SLH-DSA parameter set. */
110
168
  export type GetContext = (
111
169
  opts: SphincsOpts
112
170
  ) => (pub_seed: Uint8Array, sk_seed?: Uint8Array) => Context;
@@ -116,16 +174,19 @@ function hexToNumber(hex: string): bigint {
116
174
  return BigInt(hex === '' ? '0' : '0x' + hex); // Big Endian
117
175
  }
118
176
 
119
- // BE: Big Endian, LE: Little Endian
177
+ // BE: Big Endian, LE: Little Endian. This is the local FIPS 205 `toInt(...)` equivalent.
120
178
  function bytesToNumberBE(bytes: Uint8Array): bigint {
121
179
  return hexToNumber(bytesToHex(bytes));
122
180
  }
123
181
 
182
+ // Local in-range FIPS 205 `toByte(x, n)` equivalent; callers must keep `n < 256^len`.
124
183
  function numberToBytesBE(n: number | bigint, len: number): Uint8Array {
125
184
  return hexToBytes(n.toString(16).padStart(len * 2, '0'));
126
185
  }
127
186
 
128
- // Same as bitsCoder.decode, but maybe spec will change and unify with base2bBE.
187
+ // Local FIPS 205 Algorithm 4 `base_2^b(...)` implementation. Bits are consumed in big-endian
188
+ // order within each input byte, and callers must provide at least `ceil(outLen * b / 8)` bytes;
189
+ // short inputs are not rejected and would zero-extend implicitly.
129
190
  const base2b = (outLen: number, b: number) => {
130
191
  const mask = getMask(b);
131
192
  return (bytes: Uint8Array) => {
@@ -146,12 +207,18 @@ function getMaskBig(bits: number) {
146
207
  return (1n << BigInt(bits)) - 1n; // 4 -> 0b1111
147
208
  }
148
209
 
210
+ /** Public SLH-DSA signer with prehash customization. */
149
211
  export type SphincsSigner = Signer & {
150
212
  internal: Signer;
151
213
  securityLevel: number;
152
214
  prehash: (hash: CHash) => Signer;
153
215
  };
154
216
 
217
+ /** One parameter/hash instantiation of the public SLH-DSA API.
218
+ * `keygen(seed)` is a deterministic 3N-byte library hook around the internal keygen flow,
219
+ * and `getPublicKey(secretKey)` only extracts the embedded public key
220
+ * instead of recomputing `PK.root`.
221
+ */
155
222
  function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
156
223
  const { N, W, H, D, K, A, securityLevel: securityLevel } = opts;
157
224
  const getContext = hashOpts.getContext(opts);
@@ -183,6 +250,11 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
183
250
  OFFSET_HASH_ADDR += 10;
184
251
  }
185
252
 
253
+ // Mutates and returns `addr` in place. For the built-in parameter sets, the layer / chain /
254
+ // hash / height / keypair values fit in the low byte(s), and the tree value fits in 64 bits,
255
+ // so the untouched leading bytes in the wider FIPS 205 ADRS / ADRS_c fields stay zero.
256
+ // `height` / `chain` and `index` / `hash` share the same spec words, so callers must use the
257
+ // address-type-specific combinations instead of mixing both meanings in one call.
186
258
  const setAddr = (
187
259
  opts: {
188
260
  type?: (typeof AddressType)[keyof typeof AddressType];
@@ -227,7 +299,8 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
227
299
  const W1 = base2b(WOTS_LEN1, WOTS_LOGW)(msg);
228
300
  let csum = 0;
229
301
  for (let i = 0; i < W1.length; i++) csum += W - 1 - W1[i]; // ▷ Compute checksum
230
- csum <<= (8 - ((WOTS_LEN2 * WOTS_LOGW) % 8)) % 8; // csum ← csum ≪ ((8 − ((len2 · lg(w)) mod 8)) mod 8
302
+ // csum ← csum ≪ ((8 − ((len2 · lg(w)) mod 8)) mod 8
303
+ csum <<= (8 - ((WOTS_LEN2 * WOTS_LOGW) % 8)) % 8;
231
304
  // Checksum to base(LOG_W)
232
305
  const W2 = chainCoder(numberToBytesBE(csum, Math.ceil((WOTS_LEN2 * WOTS_LOGW) / 8)));
233
306
  // W1 || W2 (concatBytes cannot concat TypedArrays)
@@ -246,14 +319,20 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
246
319
  Math.ceil(TREE_BITS / 8),
247
320
  Math.ceil(TREE_HEIGHT / 8)
248
321
  );
322
+ // `pkSeed` is the full public key byte string `PK.seed || PK.root`; after splitting `Hmsg`,
323
+ // mask away any spare high bits so `idx_tree` / `idx_leaf` match the spec's final mod-2^k steps.
249
324
  const hashMessage = (R: Uint8Array, pkSeed: Uint8Array, msg: Uint8Array, context: Context) => {
250
- const digest = context.Hmsg(R, pkSeed, msg, hashMsgCoder.bytesLen); // digest ← Hmsg(R, PK.seed, PK.root, M)
325
+ // digest ← Hmsg(R, PK.seed, PK.root, M)
326
+ const digest = context.Hmsg(R, pkSeed, msg, hashMsgCoder.bytesLen);
251
327
  const [md, tmpIdxTree, tmpIdxLeaf] = hashMsgCoder.decode(digest);
252
328
  const tree = bytesToNumberBE(tmpIdxTree) & getMaskBig(TREE_BITS);
253
329
  const leafIdx = Number(bytesToNumberBE(tmpIdxLeaf)) & getMask(LEAF_BITS);
254
330
  return { tree, leafIdx, md };
255
331
  };
256
332
 
333
+ // Iterative `xmss_node` / `xmss_sign` core: mutate `treeAddr` in place, collapse completed
334
+ // sibling pairs on `stack`, and record the sibling whenever the current subtree is the auth-path
335
+ // neighbor of the target leaf at that height.
257
336
  const treehash = <T>(
258
337
  height: number,
259
338
  fn: (leafIdx: number, addrOffset: number, context: Context, info: T) => Uint8Array
@@ -297,6 +376,8 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
297
376
  };
298
377
  const wotsTreehash = treehash(TREE_HEIGHT, (leafIdx, addrOffset, context, info: LeafInfo) => {
299
378
  const wotsPk = new Uint8Array(WOTS_LEN * N);
379
+ // `keygen()` passes `leafIdx = ~0 >>> 0`, so no real XMSS leaf matches and this suppresses
380
+ // WOTS signature capture while still hashing every chain to its public-key endpoint.
300
381
  const wotsKmask = addrOffset === leafIdx ? 0 : ~0 >>> 0;
301
382
  setAddr({ keypair: addrOffset }, info.leafAddr);
302
383
  setAddr({ keypair: addrOffset }, info.pkAddr);
@@ -323,6 +404,8 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
323
404
  return context.thash1(prf, forsLeafAddr);
324
405
  });
325
406
 
407
+ // Fuse `xmss_sign` with the subtree-root computation needed by `ht_sign`, so one tree walk
408
+ // yields both the WOTS/auth-path signature and the root that the next hypertree layer signs.
326
409
  const merkleSign = (
327
410
  context: Context,
328
411
  wotsAddr: ADRS,
@@ -360,6 +443,10 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
360
443
  const buffer = new Uint8Array(2 * N);
361
444
  const b0 = buffer.subarray(0, N);
362
445
  const b1 = buffer.subarray(N, 2 * N);
446
+ // Algorithm 11 hashes `node || AUTH[k]` for even nodes and `AUTH[k] || node` for odd ones,
447
+ // so reuse one `2N` buffer and just swap which half receives the sibling at each level.
448
+ // `idxOffset` carries the subtree base for the shared FORS path, so `leafIdx + idxOffset`
449
+ // tracks the same tree-global index updates that Algorithms 11 and 17 apply to ADRS.
363
450
  // First iter
364
451
  if ((leafIdx & 1) !== 0) {
365
452
  b1.set(leaf.subarray(0, N));
@@ -597,10 +684,14 @@ function gen(opts: SphincsOpts, hashOpts: SphincsHashOpts): SphincsSigner {
597
684
  };
598
685
  }
599
686
 
687
+ // FIPS 205 §11.1 SHAKE instantiation: this path hashes the full uncompressed address bytes,
688
+ // unlike the compressed 22-byte SHA2 path in §11.2.
600
689
  const genShake =
601
690
  (): GetContext => (opts: SphincsOpts) => (pubSeed: Uint8Array, skSeed?: Uint8Array) => {
602
691
  const { N } = opts;
603
692
  const stats = { prf: 0, thash: 0, hmsg: 0, gen_message_random: 0 };
693
+ // §11.1 prefixes PRF/F/H/T_l with `PK.seed`, so cache that absorbed prefix once and clone it
694
+ // for each address-bound call instead of reabsorbing the same seed every time.
604
695
  const h0 = shake256.create({}).update(pubSeed);
605
696
  const h0tmp = h0.clone();
606
697
  const thash = (blocks: number, input: Uint8Array, addr: ADRS) => {
@@ -636,22 +727,55 @@ const genShake =
636
727
  };
637
728
  };
638
729
 
639
- const SHAKE_SIMPLE = { getContext: genShake() };
640
-
641
- /** SLH-DSA: 128-bit fast SHAKE version. */
642
- export const slh_dsa_shake_128f: SphincsSigner = /* @__PURE__ */ gen(PARAMS['128f'], SHAKE_SIMPLE);
643
- /** SLH-DSA: 128-bit short SHAKE version. */
644
- export const slh_dsa_shake_128s: SphincsSigner = /* @__PURE__ */ gen(PARAMS['128s'], SHAKE_SIMPLE);
645
- /** SLH-DSA: 192-bit fast SHAKE version. */
646
- export const slh_dsa_shake_192f: SphincsSigner = /* @__PURE__ */ gen(PARAMS['192f'], SHAKE_SIMPLE);
647
- /** SLH-DSA: 192-bit short SHAKE version. */
648
- export const slh_dsa_shake_192s: SphincsSigner = /* @__PURE__ */ gen(PARAMS['192s'], SHAKE_SIMPLE);
649
- /** SLH-DSA: 256-bit fast SHAKE version. */
650
- export const slh_dsa_shake_256f: SphincsSigner = /* @__PURE__ */ gen(PARAMS['256f'], SHAKE_SIMPLE);
651
- /** SLH-DSA: 256-bit short SHAKE version. */
652
- export const slh_dsa_shake_256s: SphincsSigner = /* @__PURE__ */ gen(PARAMS['256s'], SHAKE_SIMPLE);
730
+ const SHAKE_SIMPLE = /* @__PURE__ */ (() => ({ getContext: genShake() }))();
731
+
732
+ /**
733
+ * SLH-DSA-SHAKE-128f: Table 2 row `n=16, h=66, d=22, h'=3, a=6, k=33, lg w=4, m=34`;
734
+ * lengths `publicKey=32`, `secretKey=64`, `signature=17088`, `seed=48`, `signRand=16`.
735
+ * Also exposes `.prehash(...)`.
736
+ */
737
+ export const slh_dsa_shake_128f: SphincsSigner = /* @__PURE__ */ (() =>
738
+ gen(PARAMS['128f'], SHAKE_SIMPLE))();
739
+ /**
740
+ * 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
+ * lengths `publicKey=32`, `secretKey=64`, `signature=7856`, `seed=48`, `signRand=16`.
742
+ * Also exposes `.prehash(...)`.
743
+ */
744
+ export const slh_dsa_shake_128s: SphincsSigner = /* @__PURE__ */ (() =>
745
+ gen(PARAMS['128s'], SHAKE_SIMPLE))();
746
+ /**
747
+ * 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
+ * lengths `publicKey=48`, `secretKey=96`, `signature=35664`, `seed=72`, `signRand=24`.
749
+ * Also exposes `.prehash(...)`.
750
+ */
751
+ export const slh_dsa_shake_192f: SphincsSigner = /* @__PURE__ */ (() =>
752
+ gen(PARAMS['192f'], SHAKE_SIMPLE))();
753
+ /**
754
+ * 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
+ * lengths `publicKey=48`, `secretKey=96`, `signature=16224`, `seed=72`, `signRand=24`.
756
+ * Also exposes `.prehash(...)`.
757
+ */
758
+ export const slh_dsa_shake_192s: SphincsSigner = /* @__PURE__ */ (() =>
759
+ gen(PARAMS['192s'], SHAKE_SIMPLE))();
760
+ /**
761
+ * 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
+ * lengths `publicKey=64`, `secretKey=128`, `signature=49856`, `seed=96`, `signRand=32`.
763
+ * Also exposes `.prehash(...)`.
764
+ */
765
+ export const slh_dsa_shake_256f: SphincsSigner = /* @__PURE__ */ (() =>
766
+ gen(PARAMS['256f'], SHAKE_SIMPLE))();
767
+ /**
768
+ * 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
+ * lengths `publicKey=64`, `secretKey=128`, `signature=29792`, `seed=96`, `signRand=32`.
770
+ * Also exposes `.prehash(...)`.
771
+ */
772
+ export const slh_dsa_shake_256s: SphincsSigner = /* @__PURE__ */ (() =>
773
+ gen(PARAMS['256s'], SHAKE_SIMPLE))();
653
774
 
654
775
  type ShaType = typeof sha256 | typeof sha512;
776
+ // FIPS 205 §11.2 SHA2 instantiation. The `h0` / `h1` split is intentional:
777
+ // category-1 keeps everything on SHA-256, while category-3/5 keep `PRFaddr` / `thash1`
778
+ // on SHA-256 but switch `PRFmsg`, `Hmsg`, and multi-block `thashN` to SHA-512.
655
779
  const genSha =
656
780
  (h0: ShaType, h1: ShaType): GetContext =>
657
781
  (opts) =>
@@ -667,6 +791,8 @@ const genSha =
667
791
 
668
792
  const counterB = new Uint8Array(4);
669
793
  const counterV = createView(counterB);
794
+ // §11.2 prefixes SHA2 PRF/F/H/T_l with `PK.seed || toByte(0, blockLen-N)`, so cache the
795
+ // zero-padded seed block once for the SHA-256 lane and once for the SHA-512 lane.
670
796
  const h0ps = h0
671
797
  .create()
672
798
  .update(pub_seed)
@@ -680,6 +806,9 @@ const genSha =
680
806
  const h1tmp = h1ps.clone();
681
807
 
682
808
  // https://www.rfc-editor.org/rfc/rfc8017.html#appendix-B.2.1
809
+ // This local helper is intentionally stricter than generic MGF1 reuse: current SLH-DSA callers
810
+ // only request tiny `m`-byte outputs, but the guard below rejects `length > 2^32` instead of
811
+ // RFC 8017's broader `maskLen > 2^32 * hLen` bound.
683
812
  function mgf1(seed: Uint8Array, length: number, hash: ShaType) {
684
813
  stats.mgf1++;
685
814
  const out = new Uint8Array(Math.ceil(length / hash.outputLen) * hash.outputLen);
@@ -742,24 +871,54 @@ const genSha =
742
871
  };
743
872
  };
744
873
 
745
- const SHA256_SIMPLE = {
874
+ const SHA256_SIMPLE = /* @__PURE__ */ (() => ({
746
875
  isCompressed: true,
747
876
  getContext: genSha(sha256, sha256),
748
- };
749
- const SHA512_SIMPLE = {
877
+ }))();
878
+ const SHA512_SIMPLE = /* @__PURE__ */ (() => ({
750
879
  isCompressed: true,
751
880
  getContext: genSha(sha256, sha512),
752
- };
881
+ }))();
753
882
 
754
- /** SLH-DSA: 128-bit fast SHA2 version. */
755
- export const slh_dsa_sha2_128f: SphincsSigner = /* @__PURE__ */ gen(PARAMS['128f'], SHA256_SIMPLE);
756
- /** SLH-DSA: 128-bit small SHA2 version. */
757
- export const slh_dsa_sha2_128s: SphincsSigner = /* @__PURE__ */ gen(PARAMS['128s'], SHA256_SIMPLE);
758
- /** SLH-DSA: 192-bit fast SHA2 version. */
759
- export const slh_dsa_sha2_192f: SphincsSigner = /* @__PURE__ */ gen(PARAMS['192f'], SHA512_SIMPLE);
760
- /** SLH-DSA: 192-bit small SHA2 version. */
761
- export const slh_dsa_sha2_192s: SphincsSigner = /* @__PURE__ */ gen(PARAMS['192s'], SHA512_SIMPLE);
762
- /** SLH-DSA: 256-bit fast SHA2 version. */
763
- export const slh_dsa_sha2_256f: SphincsSigner = /* @__PURE__ */ gen(PARAMS['256f'], SHA512_SIMPLE);
764
- /** SLH-DSA: 256-bit small SHA2 version. */
765
- export const slh_dsa_sha2_256s: SphincsSigner = /* @__PURE__ */ gen(PARAMS['256s'], SHA512_SIMPLE);
883
+ /**
884
+ * SLH-DSA-SHA2-128f: Table 2 row `n=16, h=66, d=22, h'=3, a=6, k=33, lg w=4, m=34`;
885
+ * lengths `publicKey=32`, `secretKey=64`, `signature=17088`, `seed=48`, `signRand=16`.
886
+ * Also exposes `.prehash(...)`.
887
+ */
888
+ export const slh_dsa_sha2_128f: SphincsSigner = /* @__PURE__ */ (() =>
889
+ gen(PARAMS['128f'], SHA256_SIMPLE))();
890
+ /**
891
+ * 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
+ * lengths `publicKey=32`, `secretKey=64`, `signature=7856`, `seed=48`, `signRand=16`.
893
+ * Also exposes `.prehash(...)`.
894
+ */
895
+ export const slh_dsa_sha2_128s: SphincsSigner = /* @__PURE__ */ (() =>
896
+ gen(PARAMS['128s'], SHA256_SIMPLE))();
897
+ /**
898
+ * 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
+ * lengths `publicKey=48`, `secretKey=96`, `signature=35664`, `seed=72`, `signRand=24`.
900
+ * Also exposes `.prehash(...)`.
901
+ */
902
+ export const slh_dsa_sha2_192f: SphincsSigner = /* @__PURE__ */ (() =>
903
+ gen(PARAMS['192f'], SHA512_SIMPLE))();
904
+ /**
905
+ * 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
+ * lengths `publicKey=48`, `secretKey=96`, `signature=16224`, `seed=72`, `signRand=24`.
907
+ * Also exposes `.prehash(...)`.
908
+ */
909
+ export const slh_dsa_sha2_192s: SphincsSigner = /* @__PURE__ */ (() =>
910
+ gen(PARAMS['192s'], SHA512_SIMPLE))();
911
+ /**
912
+ * 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
+ * lengths `publicKey=64`, `secretKey=128`, `signature=49856`, `seed=96`, `signRand=32`.
914
+ * Also exposes `.prehash(...)`.
915
+ */
916
+ export const slh_dsa_sha2_256f: SphincsSigner = /* @__PURE__ */ (() =>
917
+ gen(PARAMS['256f'], SHA512_SIMPLE))();
918
+ /**
919
+ * 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
+ * lengths `publicKey=64`, `secretKey=128`, `signature=29792`, `seed=96`, `signRand=32`.
921
+ * Also exposes `.prehash(...)`.
922
+ */
923
+ export const slh_dsa_sha2_256s: SphincsSigner = /* @__PURE__ */ (() =>
924
+ gen(PARAMS['256s'], SHA512_SIMPLE))();