@taquito/signer 25.0.0 → 25.1.0-beta0

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.
@@ -1,5 +1,5 @@
1
1
  import { openSecretBox } from '@stablelib/nacl';
2
- import { b58DecodeAndCheckPrefix, PrefixV2, b58Encode, compareArrays, InvalidPublicKeyError, BLS12_381_DST, POP_DST, hex2buf, mergebuf, buf2hex } from '@taquito/utils';
2
+ import { b58DecodeAndCheckPrefix, PrefixV2, b58Encode, compareArrays, InvalidPublicKeyError, BLS12_381_DST, POP_DST, payloadLength, mergebuf, hex2buf, buf2hex } from '@taquito/utils';
3
3
  import { ed25519 as ed25519$1 } from '@noble/curves/ed25519';
4
4
  import { secp256k1 } from '@noble/curves/secp256k1';
5
5
  import { p256 } from '@noble/curves/nist.js';
@@ -53,7 +53,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
53
53
  * isBytes(new Uint8Array([1, 2, 3]));
54
54
  * ```
55
55
  */
56
- function isBytes$1(a) {
56
+ function isBytes$2(a) {
57
57
  // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.
58
58
  // The fallback still requires a real ArrayBuffer view, so plain
59
59
  // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and
@@ -76,7 +76,7 @@ function isBytes$1(a) {
76
76
  * anumber(32, 'length');
77
77
  * ```
78
78
  */
79
- function anumber$1(n, title = '') {
79
+ function anumber$2(n, title = '') {
80
80
  if (typeof n !== 'number') {
81
81
  const prefix = title && `"${title}" `;
82
82
  throw new TypeError(`${prefix}expected number, got ${typeof n}`);
@@ -100,8 +100,8 @@ function anumber$1(n, title = '') {
100
100
  * abytes(new Uint8Array([1, 2, 3]));
101
101
  * ```
102
102
  */
103
- function abytes(value, length, title = '') {
104
- const bytes = isBytes$1(value);
103
+ function abytes$1(value, length, title = '') {
104
+ const bytes = isBytes$2(value);
105
105
  const len = value?.length;
106
106
  const needsLen = length !== undefined;
107
107
  if (!bytes || (needsLen && len !== length)) {
@@ -129,11 +129,11 @@ function abytes(value, length, title = '') {
129
129
  * ahash(sha256);
130
130
  * ```
131
131
  */
132
- function ahash(h) {
132
+ function ahash$1(h) {
133
133
  if (typeof h !== 'function' || typeof h.create !== 'function')
134
134
  throw new TypeError('Hash must wrapped by utils.createHasher');
135
- anumber$1(h.outputLen);
136
- anumber$1(h.blockLen);
135
+ anumber$2(h.outputLen);
136
+ anumber$2(h.blockLen);
137
137
  // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass
138
138
  // validation and can produce empty outputs instead of failing fast.
139
139
  if (h.outputLen < 1)
@@ -155,7 +155,7 @@ function ahash(h) {
155
155
  * aexists(hash);
156
156
  * ```
157
157
  */
158
- function aexists(instance, checkFinished = true) {
158
+ function aexists$1(instance, checkFinished = true) {
159
159
  if (instance.destroyed)
160
160
  throw new Error('Hash instance has been destroyed');
161
161
  if (checkFinished && instance.finished)
@@ -177,8 +177,8 @@ function aexists(instance, checkFinished = true) {
177
177
  * aoutput(new Uint8Array(hash.outputLen), hash);
178
178
  * ```
179
179
  */
180
- function aoutput(out, instance) {
181
- abytes(out, undefined, 'digestInto() output');
180
+ function aoutput$1(out, instance) {
181
+ abytes$1(out, undefined, 'digestInto() output');
182
182
  const min = instance.outputLen;
183
183
  if (out.length < min) {
184
184
  throw new RangeError('"digestInto() output" expected to be of length >=' + min);
@@ -196,7 +196,7 @@ function aoutput(out, instance) {
196
196
  * u32(new Uint8Array(8));
197
197
  * ```
198
198
  */
199
- function u32(arr) {
199
+ function u32$1(arr) {
200
200
  return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
201
201
  }
202
202
  /**
@@ -208,7 +208,7 @@ function u32(arr) {
208
208
  * clean(new Uint8Array([1, 2, 3]));
209
209
  * ```
210
210
  */
211
- function clean(...arrays) {
211
+ function clean$1(...arrays) {
212
212
  for (let i = 0; i < arrays.length; i++) {
213
213
  arrays[i].fill(0);
214
214
  }
@@ -241,7 +241,7 @@ function rotr(word, shift) {
241
241
  return (word << (32 - shift)) | (word >>> shift);
242
242
  }
243
243
  /** Whether the current platform is little-endian. */
244
- const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
244
+ const isLE$1 = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
245
245
  /**
246
246
  * Byte-swap operation for uint32 values.
247
247
  * @param word - source word
@@ -252,7 +252,7 @@ const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344])
252
252
  * byteSwap(0x11223344);
253
253
  * ```
254
254
  */
255
- function byteSwap(word) {
255
+ function byteSwap$1(word) {
256
256
  return (((word << 24) & 0xff000000) |
257
257
  ((word << 8) & 0xff0000) |
258
258
  ((word >>> 8) & 0xff00) |
@@ -268,9 +268,9 @@ function byteSwap(word) {
268
268
  * swap8IfBE(0x11223344);
269
269
  * ```
270
270
  */
271
- const swap8IfBE = isLE
271
+ const swap8IfBE = isLE$1
272
272
  ? (n) => n
273
- : (n) => byteSwap(n) >>> 0;
273
+ : (n) => byteSwap$1(n) >>> 0;
274
274
  /**
275
275
  * Byte-swaps every word of a Uint32Array in place.
276
276
  * @param arr - array to mutate
@@ -281,9 +281,9 @@ const swap8IfBE = isLE
281
281
  * byteSwap32(new Uint32Array([0x11223344]));
282
282
  * ```
283
283
  */
284
- function byteSwap32(arr) {
284
+ function byteSwap32$1(arr) {
285
285
  for (let i = 0; i < arr.length; i++) {
286
- arr[i] = byteSwap(arr[i]);
286
+ arr[i] = byteSwap$1(arr[i]);
287
287
  }
288
288
  return arr;
289
289
  }
@@ -298,9 +298,9 @@ function byteSwap32(arr) {
298
298
  * swap32IfBE(new Uint32Array([0x11223344]));
299
299
  * ```
300
300
  */
301
- const swap32IfBE = isLE
301
+ const swap32IfBE$1 = isLE$1
302
302
  ? (u) => u
303
- : byteSwap32;
303
+ : byteSwap32$1;
304
304
  /**
305
305
  * Converts string to bytes using UTF8 encoding.
306
306
  * Built-in doesn't validate input to be string: we do the check.
@@ -335,7 +335,7 @@ function utf8ToBytes(str) {
335
335
  function kdfInputToBytes(data, errorTitle = '') {
336
336
  if (typeof data === 'string')
337
337
  return utf8ToBytes(data);
338
- return abytes(data, undefined, errorTitle);
338
+ return abytes$1(data, undefined, errorTitle);
339
339
  }
340
340
  /**
341
341
  * Merges default options and passed options.
@@ -349,7 +349,7 @@ function kdfInputToBytes(data, errorTitle = '') {
349
349
  * checkOpts({ dkLen: 32 }, { asyncTick: 10 });
350
350
  * ```
351
351
  */
352
- function checkOpts(defaults, opts) {
352
+ function checkOpts$1(defaults, opts) {
353
353
  if (opts !== undefined && {}.toString.call(opts) !== '[object Object]')
354
354
  throw new TypeError('options must be object or undefined');
355
355
  const merged = Object.assign(defaults, opts);
@@ -372,7 +372,7 @@ function checkOpts(defaults, opts) {
372
372
  * wrapped(new Uint8Array([1]));
373
373
  * ```
374
374
  */
375
- function createHasher(hashCons, info = {}) {
375
+ function createHasher$1(hashCons, info = {}) {
376
376
  const hashC = (msg, opts) => hashCons(opts)
377
377
  .update(msg)
378
378
  .digest();
@@ -396,7 +396,7 @@ function createHasher(hashCons, info = {}) {
396
396
  * oidNist(0x01);
397
397
  * ```
398
398
  */
399
- const oidNist = (suffix) => ({
399
+ const oidNist$1 = (suffix) => ({
400
400
  // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.
401
401
  // Larger suffix values would need base-128 OID encoding and a different length byte.
402
402
  oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),
@@ -511,8 +511,8 @@ class HashMD {
511
511
  this.view = createView(this.buffer);
512
512
  }
513
513
  update(data) {
514
- aexists(this);
515
- abytes(data);
514
+ aexists$1(this);
515
+ abytes$1(data);
516
516
  const { view, buffer, blockLen } = this;
517
517
  const len = data.length;
518
518
  for (let pos = 0; pos < len;) {
@@ -538,8 +538,8 @@ class HashMD {
538
538
  return this;
539
539
  }
540
540
  digestInto(out) {
541
- aexists(this);
542
- aoutput(out, this);
541
+ aexists$1(this);
542
+ aoutput$1(out, this);
543
543
  this.finished = true;
544
544
  // Padding
545
545
  // We can avoid allocation of buffer for padding completely if it
@@ -548,7 +548,7 @@ class HashMD {
548
548
  let { pos } = this;
549
549
  // append the bit '1' to the message
550
550
  buffer[pos++] = 0b10000000;
551
- clean(this.buffer.subarray(pos));
551
+ clean$1(this.buffer.subarray(pos));
552
552
  // we have less than padOffset left in buffer, so we cannot put length in
553
553
  // current block, need process it and pad again
554
554
  if (this.padOffset > blockLen - pos) {
@@ -621,23 +621,23 @@ const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
621
621
  0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
622
622
  ]);
623
623
 
624
- const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
625
- const _32n = /* @__PURE__ */ BigInt(32);
624
+ const U32_MASK64$1 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
625
+ const _32n$1 = /* @__PURE__ */ BigInt(32);
626
626
  // Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high
627
627
  // }` to match little-endian word order rather than the property names.
628
- function fromBig(n, le = false) {
628
+ function fromBig$1(n, le = false) {
629
629
  if (le)
630
- return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
631
- return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
630
+ return { h: Number(n & U32_MASK64$1), l: Number((n >> _32n$1) & U32_MASK64$1) };
631
+ return { h: Number((n >> _32n$1) & U32_MASK64$1) | 0, l: Number(n & U32_MASK64$1) | 0 };
632
632
  }
633
633
  // Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array
634
634
  // holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`.
635
- function split(lst, le = false) {
635
+ function split$1(lst, le = false) {
636
636
  const len = lst.length;
637
637
  let Ah = new Uint32Array(len);
638
638
  let Al = new Uint32Array(len);
639
639
  for (let i = 0; i < len; i++) {
640
- const { h, l } = fromBig(lst[i], le);
640
+ const { h, l } = fromBig$1(lst[i], le);
641
641
  [Ah[i], Al[i]] = [h, l];
642
642
  }
643
643
  return [Ah, Al];
@@ -743,7 +743,7 @@ function G2b(a, b, c, d, msg, x) {
743
743
  ((BBUF[2 * d] = Dl), (BBUF[2 * d + 1] = Dh));
744
744
  }
745
745
  function checkBlake2Opts(outputLen, opts = {}, keyLen, saltLen, persLen) {
746
- anumber$1(keyLen);
746
+ anumber$2(keyLen);
747
747
  // RFC 7693 §2.1 requires digest length nn in 1..keyLen.
748
748
  if (outputLen <= 0 || outputLen > keyLen)
749
749
  throw new Error('outputLen bigger than keyLen');
@@ -752,9 +752,9 @@ function checkBlake2Opts(outputLen, opts = {}, keyLen, saltLen, persLen) {
752
752
  if (key !== undefined && (key.length < 1 || key.length > keyLen))
753
753
  throw new Error('"key" expected to be undefined or of length=1..' + keyLen);
754
754
  if (salt !== undefined)
755
- abytes(salt, saltLen, 'salt');
755
+ abytes$1(salt, saltLen, 'salt');
756
756
  if (personalization !== undefined)
757
- abytes(personalization, persLen, 'personalization');
757
+ abytes$1(personalization, persLen, 'personalization');
758
758
  }
759
759
  /** Internal base class for BLAKE2. */
760
760
  class _BLAKE2 {
@@ -768,16 +768,16 @@ class _BLAKE2 {
768
768
  outputLen;
769
769
  canXOF = false;
770
770
  constructor(blockLen, outputLen) {
771
- anumber$1(blockLen);
772
- anumber$1(outputLen);
771
+ anumber$2(blockLen);
772
+ anumber$2(outputLen);
773
773
  this.blockLen = blockLen;
774
774
  this.outputLen = outputLen;
775
775
  this.buffer = new Uint8Array(blockLen);
776
- this.buffer32 = u32(this.buffer);
776
+ this.buffer32 = u32$1(this.buffer);
777
777
  }
778
778
  update(data) {
779
- aexists(this);
780
- abytes(data);
779
+ aexists$1(this);
780
+ abytes$1(data);
781
781
  // Main difference with other hashes: there is flag for last block,
782
782
  // so we cannot process current block before we know that there
783
783
  // is the next one. This significantly complicates logic and reduces ability
@@ -789,9 +789,9 @@ class _BLAKE2 {
789
789
  for (let pos = 0; pos < len;) {
790
790
  // If buffer is full and we still have input (don't process last block, same as blake2s)
791
791
  if (this.pos === blockLen) {
792
- swap32IfBE(buffer32);
792
+ swap32IfBE$1(buffer32);
793
793
  this.compress(buffer32, 0, false);
794
- swap32IfBE(buffer32);
794
+ swap32IfBE$1(buffer32);
795
795
  this.pos = 0;
796
796
  }
797
797
  const take = Math.min(blockLen - this.pos, len - pos);
@@ -799,12 +799,12 @@ class _BLAKE2 {
799
799
  // Zero-copy only for full, 4-byte-aligned, non-final blocks.
800
800
  if (take === blockLen && !(dataOffset % 4) && pos + take < len) {
801
801
  const data32 = new Uint32Array(buf, dataOffset, Math.floor((len - pos) / 4));
802
- swap32IfBE(data32);
802
+ swap32IfBE$1(data32);
803
803
  for (let pos32 = 0; pos + blockLen < len; pos32 += buffer32.length, pos += blockLen) {
804
804
  this.length += blockLen;
805
805
  this.compress(data32, pos32, false);
806
806
  }
807
- swap32IfBE(data32);
807
+ swap32IfBE$1(data32);
808
808
  continue;
809
809
  }
810
810
  buffer.set(data.subarray(pos, pos + take), this.pos);
@@ -815,20 +815,20 @@ class _BLAKE2 {
815
815
  return this;
816
816
  }
817
817
  digestInto(out) {
818
- aexists(this);
819
- aoutput(out, this);
818
+ aexists$1(this);
819
+ aoutput$1(out, this);
820
820
  const { pos, buffer32 } = this;
821
821
  this.finished = true;
822
822
  // Padding
823
- clean(this.buffer.subarray(pos));
824
- swap32IfBE(buffer32);
823
+ clean$1(this.buffer.subarray(pos));
824
+ swap32IfBE$1(buffer32);
825
825
  this.compress(buffer32, 0, true);
826
- swap32IfBE(buffer32);
826
+ swap32IfBE$1(buffer32);
827
827
  // Reject unaligned views explicitly instead of hiding them behind a full scratch copy.
828
828
  if (out.byteOffset & 3)
829
829
  throw new RangeError('"digestInto() output" expected 4-byte aligned byteOffset, got ' + out.byteOffset);
830
830
  const state = this.get();
831
- const out32 = u32(out);
831
+ const out32 = u32$1(out);
832
832
  const full = Math.floor(this.outputLen / 4);
833
833
  for (let i = 0; i < full; i++)
834
834
  out32[i] = swap8IfBE(state[i]);
@@ -892,23 +892,23 @@ class _BLAKE2b extends _BLAKE2 {
892
892
  let { key, personalization, salt } = opts;
893
893
  let keyLength = 0;
894
894
  if (key !== undefined) {
895
- abytes(key, undefined, 'key');
895
+ abytes$1(key, undefined, 'key');
896
896
  keyLength = key.length;
897
897
  }
898
898
  // RFC 7693 §2.5: xor `p[0] = 0x0101kknn` into the low 32 bits of `h[0]`;
899
899
  // the high 32 bits stay at `IV[0]`.
900
900
  this.v0l ^= this.outputLen | (keyLength << 8) | (0x01 << 16) | (0x01 << 24);
901
901
  if (salt !== undefined) {
902
- abytes(salt, undefined, 'salt');
903
- const slt = u32(salt);
902
+ abytes$1(salt, undefined, 'salt');
903
+ const slt = u32$1(salt);
904
904
  this.v4l ^= swap8IfBE(slt[0]);
905
905
  this.v4h ^= swap8IfBE(slt[1]);
906
906
  this.v5l ^= swap8IfBE(slt[2]);
907
907
  this.v5h ^= swap8IfBE(slt[3]);
908
908
  }
909
909
  if (personalization !== undefined) {
910
- abytes(personalization, undefined, 'personalization');
911
- const pers = u32(personalization);
910
+ abytes$1(personalization, undefined, 'personalization');
911
+ const pers = u32$1(personalization);
912
912
  this.v6l ^= swap8IfBE(pers[0]);
913
913
  this.v6h ^= swap8IfBE(pers[1]);
914
914
  this.v7l ^= swap8IfBE(pers[2]);
@@ -948,7 +948,7 @@ class _BLAKE2b extends _BLAKE2 {
948
948
  compress(msg, offset, isLast) {
949
949
  this.get().forEach((v, i) => (BBUF[i] = v)); // First half from state.
950
950
  BBUF.set(B2B_IV, 16); // Second half from IV.
951
- let { h, l } = fromBig(BigInt(this.length));
951
+ let { h, l } = fromBig$1(BigInt(this.length));
952
952
  BBUF[24] = B2B_IV[8] ^ l; // Low word of the offset.
953
953
  BBUF[25] = B2B_IV[9] ^ h; // High word.
954
954
  // Invert all bits for last block
@@ -994,11 +994,11 @@ class _BLAKE2b extends _BLAKE2 {
994
994
  this.v6h ^= BBUF[13] ^ BBUF[29];
995
995
  this.v7l ^= BBUF[14] ^ BBUF[30];
996
996
  this.v7h ^= BBUF[15] ^ BBUF[31];
997
- clean(BBUF);
997
+ clean$1(BBUF);
998
998
  }
999
999
  destroy() {
1000
1000
  this.destroyed = true;
1001
- clean(this.buffer32);
1001
+ clean$1(this.buffer32);
1002
1002
  this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1003
1003
  }
1004
1004
  }
@@ -1015,7 +1015,7 @@ class _BLAKE2b extends _BLAKE2 {
1015
1015
  * blake2b(new Uint8Array([97, 98, 99]));
1016
1016
  * ```
1017
1017
  */
1018
- const blake2b = /* @__PURE__ */ createHasher((opts) => new _BLAKE2b(opts));
1018
+ const blake2b = /* @__PURE__ */ createHasher$1((opts) => new _BLAKE2b(opts));
1019
1019
 
1020
1020
  var _EdKey_keyPair, _EdPublicKey_key;
1021
1021
  function generateKeyPairFromSeed$1(seed) {
@@ -1391,8 +1391,8 @@ class _HMAC {
1391
1391
  finished = false;
1392
1392
  destroyed = false;
1393
1393
  constructor(hash, key) {
1394
- ahash(hash);
1395
- abytes(key, undefined, 'key');
1394
+ ahash$1(hash);
1395
+ abytes$1(key, undefined, 'key');
1396
1396
  this.iHash = hash.create();
1397
1397
  if (typeof this.iHash.update !== 'function')
1398
1398
  throw new Error('Expected instance of class which extends utils.Hash');
@@ -1412,16 +1412,16 @@ class _HMAC {
1412
1412
  for (let i = 0; i < pad.length; i++)
1413
1413
  pad[i] ^= 0x36 ^ 0x5c;
1414
1414
  this.oHash.update(pad);
1415
- clean(pad);
1415
+ clean$1(pad);
1416
1416
  }
1417
1417
  update(buf) {
1418
- aexists(this);
1418
+ aexists$1(this);
1419
1419
  this.iHash.update(buf);
1420
1420
  return this;
1421
1421
  }
1422
1422
  digestInto(out) {
1423
- aexists(this);
1424
- aoutput(out, this);
1423
+ aexists$1(this);
1424
+ aoutput$1(out, this);
1425
1425
  this.finished = true;
1426
1426
  const buf = out.subarray(0, this.outputLen);
1427
1427
  // Reuse the first outputLen bytes for the inner digest; the outer hash consumes them before
@@ -1471,12 +1471,12 @@ const hmac = /* @__PURE__ */ (() => {
1471
1471
  */
1472
1472
  // Common start and end for sync/async functions
1473
1473
  function pbkdf2Init(hash, _password, _salt, _opts) {
1474
- ahash(hash);
1475
- const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
1474
+ ahash$1(hash);
1475
+ const opts = checkOpts$1({ dkLen: 32, asyncTick: 10 }, _opts);
1476
1476
  const { c, dkLen, asyncTick } = opts;
1477
- anumber$1(c, 'c');
1478
- anumber$1(dkLen, 'dkLen');
1479
- anumber$1(asyncTick, 'asyncTick');
1477
+ anumber$2(c, 'c');
1478
+ anumber$2(dkLen, 'dkLen');
1479
+ anumber$2(asyncTick, 'asyncTick');
1480
1480
  if (c < 1)
1481
1481
  throw new Error('iterations (c) must be >= 1');
1482
1482
  // RFC 8018 §5.2 defines `dkLen` as "a positive integer".
@@ -1503,7 +1503,7 @@ function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
1503
1503
  PRFSalt.destroy();
1504
1504
  if (prfW)
1505
1505
  prfW.destroy();
1506
- clean(u);
1506
+ clean$1(u);
1507
1507
  return DK;
1508
1508
  }
1509
1509
  /**
@@ -1634,14 +1634,14 @@ class SHA2_32B extends HashMD {
1634
1634
  this.set(A, B, C, D, E, F, G, H);
1635
1635
  }
1636
1636
  roundClean() {
1637
- clean(SHA256_W);
1637
+ clean$1(SHA256_W);
1638
1638
  }
1639
1639
  destroy() {
1640
1640
  // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves
1641
1641
  // update()/digest() callable on reused instances.
1642
1642
  this.destroyed = true;
1643
1643
  this.set(0, 0, 0, 0, 0, 0, 0, 0);
1644
- clean(this.buffer);
1644
+ clean$1(this.buffer);
1645
1645
  }
1646
1646
  }
1647
1647
  /** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */
@@ -1664,7 +1664,7 @@ class _SHA256 extends SHA2_32B {
1664
1664
  // SHA-384 / SHA-512 round constants from RFC 6234 §5.2:
1665
1665
  // 80 full 64-bit words split into high/low halves.
1666
1666
  // prettier-ignore
1667
- const K512 = /* @__PURE__ */ (() => split([
1667
+ const K512 = /* @__PURE__ */ (() => split$1([
1668
1668
  '0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
1669
1669
  '0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
1670
1670
  '0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
@@ -1792,13 +1792,13 @@ class SHA2_64B extends HashMD {
1792
1792
  this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
1793
1793
  }
1794
1794
  roundClean() {
1795
- clean(SHA512_W_H, SHA512_W_L);
1795
+ clean$1(SHA512_W_H, SHA512_W_L);
1796
1796
  }
1797
1797
  destroy() {
1798
1798
  // HashMD callers route post-destroy usability through `destroyed`; zeroizing alone still leaves
1799
1799
  // update()/digest() callable on reused instances.
1800
1800
  this.destroyed = true;
1801
- clean(this.buffer);
1801
+ clean$1(this.buffer);
1802
1802
  this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
1803
1803
  }
1804
1804
  }
@@ -1839,8 +1839,8 @@ class _SHA512 extends SHA2_64B {
1839
1839
  * sha256(new Uint8Array([97, 98, 99]));
1840
1840
  * ```
1841
1841
  */
1842
- const sha256 = /* @__PURE__ */ createHasher(() => new _SHA256(),
1843
- /* @__PURE__ */ oidNist(0x01));
1842
+ const sha256 = /* @__PURE__ */ createHasher$1(() => new _SHA256(),
1843
+ /* @__PURE__ */ oidNist$1(0x01));
1844
1844
  /**
1845
1845
  * SHA2-512 hash function from RFC 4634.
1846
1846
  * @param msg - message bytes to hash
@@ -1851,11 +1851,11 @@ const sha256 = /* @__PURE__ */ createHasher(() => new _SHA256(),
1851
1851
  * sha512(new Uint8Array([97, 98, 99]));
1852
1852
  * ```
1853
1853
  */
1854
- const sha512 = /* @__PURE__ */ createHasher(() => new _SHA512(),
1855
- /* @__PURE__ */ oidNist(0x03));
1854
+ const sha512 = /* @__PURE__ */ createHasher$1(() => new _SHA512(),
1855
+ /* @__PURE__ */ oidNist$1(0x03));
1856
1856
 
1857
1857
  /*! scure-base - MIT License (c) 2022 Paul Miller (paulmillr.com) */
1858
- function isBytes(a) {
1858
+ function isBytes$1(a) {
1859
1859
  // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases. The
1860
1860
  // fallback still requires a real ArrayBuffer view, so plain JSON-deserialized
1861
1861
  // `{ constructor: ... }` spoofing is rejected. `BYTES_PER_ELEMENT === 1` keeps the
@@ -1888,7 +1888,7 @@ function astr(label, input) {
1888
1888
  throw new TypeError(`${label}: string expected`);
1889
1889
  return true;
1890
1890
  }
1891
- function anumber(n) {
1891
+ function anumber$1(n) {
1892
1892
  if (typeof n !== 'number')
1893
1893
  throw new TypeError(`number expected, got ${typeof n}`);
1894
1894
  if (!Number.isSafeInteger(n))
@@ -1975,7 +1975,7 @@ function join(separator = '') {
1975
1975
  * @__NO_SIDE_EFFECTS__
1976
1976
  */
1977
1977
  function padding(bits, chr = '=') {
1978
- anumber(bits);
1978
+ anumber$1(bits);
1979
1979
  astr('padding', chr);
1980
1980
  return {
1981
1981
  encode(data) {
@@ -2016,7 +2016,7 @@ function convertRadix(data, from, to) {
2016
2016
  let pos = 0;
2017
2017
  const res = [];
2018
2018
  const digits = Array.from(data, (d) => {
2019
- anumber(d);
2019
+ anumber$1(d);
2020
2020
  if (d < 0 || d >= from)
2021
2021
  throw new Error(`invalid integer: ${d}`);
2022
2022
  return d;
@@ -2084,7 +2084,7 @@ function convertRadix2(data, from, to, padding) {
2084
2084
  const mask = powers[to] - 1;
2085
2085
  const res = [];
2086
2086
  for (const n of data) {
2087
- anumber(n);
2087
+ anumber$1(n);
2088
2088
  if (n >= max)
2089
2089
  throw new Error(`convertRadix2: invalid data word=${n} from=${from}`);
2090
2090
  carry = (carry << from) | n;
@@ -2113,12 +2113,12 @@ function convertRadix2(data, from, to, padding) {
2113
2113
  * @__NO_SIDE_EFFECTS__
2114
2114
  */
2115
2115
  function radix(num) {
2116
- anumber(num);
2116
+ anumber$1(num);
2117
2117
  const _256 = 2 ** 8;
2118
2118
  // Base-range and carry-overflow checks live in convertRadix so encode/decode reject unsupported bases symmetrically.
2119
2119
  return {
2120
2120
  encode: (bytes) => {
2121
- if (!isBytes(bytes))
2121
+ if (!isBytes$1(bytes))
2122
2122
  throw new TypeError('radix.encode input should be Uint8Array');
2123
2123
  return convertRadix(Array.from(bytes), _256, num);
2124
2124
  },
@@ -2134,7 +2134,7 @@ function radix(num) {
2134
2134
  * @__NO_SIDE_EFFECTS__
2135
2135
  */
2136
2136
  function radix2(bits, revPadding = false) {
2137
- anumber(bits);
2137
+ anumber$1(bits);
2138
2138
  if (bits <= 0 || bits > 32)
2139
2139
  throw new RangeError('radix2: bits should be in (0..32]');
2140
2140
  if (radix2carry(8, bits) > 32 || radix2carry(bits, 8) > 32)
@@ -2143,7 +2143,7 @@ function radix2(bits, revPadding = false) {
2143
2143
  // Default pads 8->bits and rejects extra bits on bits->8; `true` does the opposite.
2144
2144
  return {
2145
2145
  encode: (bytes) => {
2146
- if (!isBytes(bytes))
2146
+ if (!isBytes$1(bytes))
2147
2147
  throw new TypeError('radix2.encode input should be Uint8Array');
2148
2148
  return convertRadix2(Array.from(bytes), 8, bits, !revPadding);
2149
2149
  },
@@ -2154,7 +2154,7 @@ function radix2(bits, revPadding = false) {
2154
2154
  };
2155
2155
  }
2156
2156
  function checksum(len, fn) {
2157
- anumber(len);
2157
+ anumber$1(len);
2158
2158
  // Reject degenerate zero-byte checksums up front so callers don't accidentally
2159
2159
  // build a no-op checksum stage.
2160
2160
  if (len <= 0)
@@ -2165,7 +2165,7 @@ function checksum(len, fn) {
2165
2165
  // Current call sites rely on `len > 0` and checksum functions that return at least that many bytes.
2166
2166
  return {
2167
2167
  encode(data) {
2168
- if (!isBytes(data))
2168
+ if (!isBytes$1(data))
2169
2169
  throw new TypeError('checksum.encode: input should be Uint8Array');
2170
2170
  const sum = _fn(data).slice(0, len);
2171
2171
  const res = new Uint8Array(data.length + len);
@@ -2174,7 +2174,7 @@ function checksum(len, fn) {
2174
2174
  return res;
2175
2175
  },
2176
2176
  decode(data) {
2177
- if (!isBytes(data))
2177
+ if (!isBytes$1(data))
2178
2178
  throw new TypeError('checksum.decode: input should be Uint8Array');
2179
2179
  const payload = data.slice(0, -len);
2180
2180
  const oldChecksum = data.slice(-len);
@@ -2223,7 +2223,7 @@ function normalize(str) {
2223
2223
  }
2224
2224
  // BIP-39 entropy payloads are 128-256 bits in 32-bit increments, i.e. 16/20/24/28/32 bytes.
2225
2225
  function aentropy(ent) {
2226
- abytes(ent);
2226
+ abytes$1(ent);
2227
2227
  if (![16, 20, 24, 28, 32].includes(ent.length))
2228
2228
  throw new RangeError('invalid entropy length');
2229
2229
  }
@@ -4772,60 +4772,2576 @@ class BLSPublicKey {
4772
4772
  }
4773
4773
  _BLSPublicKey_key = new WeakMap();
4774
4774
 
4775
- var _InMemorySigner_key;
4776
4775
  /**
4777
- * A local implementation of the signer. Will represent a Tezos account and be able to produce signature in its behalf
4778
- *
4779
- * @remarks If running in production and dealing with tokens that have real value, it is strongly recommended to use a HSM backed signer so that private key material is not stored in memory or on disk
4780
- * @throws InvalidMnemonicError
4776
+ * Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.
4777
+ * @param a - value to test
4778
+ * @returns `true` when the value is a Uint8Array-compatible view.
4779
+ * @example
4780
+ * Check whether a value is a Uint8Array-compatible view.
4781
+ * ```ts
4782
+ * isBytes(new Uint8Array([1, 2, 3]));
4783
+ * ```
4781
4784
  */
4782
- class InMemorySigner {
4783
- static fromFundraiser(email, password, mnemonic) {
4784
- if (!validateMnemonic(mnemonic, wordlist)) {
4785
- throw new InvalidMnemonicError();
4786
- }
4787
- const seed = mnemonicToSeedSync(mnemonic, `${email}${password}`);
4788
- const key = b58Encode(seed.subarray(0, 32), PrefixV2.Ed25519Seed);
4789
- return new InMemorySigner(key);
4785
+ function isBytes(a) {
4786
+ // Plain `instanceof Uint8Array` is too strict for some Buffer / proxy / cross-realm cases.
4787
+ // The fallback still requires a real ArrayBuffer view, so plain
4788
+ // JSON-deserialized `{ constructor: ... }` spoofing is rejected, and
4789
+ // `BYTES_PER_ELEMENT === 1` keeps the fallback on byte-oriented views.
4790
+ return (a instanceof Uint8Array ||
4791
+ (ArrayBuffer.isView(a) &&
4792
+ a.constructor.name === 'Uint8Array' &&
4793
+ 'BYTES_PER_ELEMENT' in a &&
4794
+ a.BYTES_PER_ELEMENT === 1));
4795
+ }
4796
+ // Shared error-message prefix builder. Only called on throw paths, so assert
4797
+ // success paths never pay for the string concatenation.
4798
+ const atitle$1 = (title) => (title ? `"${title}" ` : '');
4799
+ /**
4800
+ * Asserts something is a non-negative integer.
4801
+ * @param n - number to validate
4802
+ * @param title - label included in thrown errors
4803
+ * @returns The validated number.
4804
+ * @throws On wrong argument types. {@link TypeError}
4805
+ * @throws On wrong argument ranges or values. {@link RangeError}
4806
+ * @example
4807
+ * Validate a non-negative integer option.
4808
+ * ```ts
4809
+ * anumber(32, 'length');
4810
+ * ```
4811
+ */
4812
+ function anumber(n, title = '') {
4813
+ if (typeof n !== 'number')
4814
+ throw new TypeError(atitle$1(title) + 'expected number, got ' + typeof n);
4815
+ if (!Number.isSafeInteger(n) || n < 0)
4816
+ throw new RangeError(atitle$1(title) + 'expected integer >= 0, got ' + n);
4817
+ return n;
4818
+ }
4819
+ /**
4820
+ * Asserts something is a boolean.
4821
+ * @param value - value to validate
4822
+ * @param title - label included in thrown errors
4823
+ * @returns The validated boolean.
4824
+ * @throws On wrong argument types. {@link TypeError}
4825
+ * @example
4826
+ * Validate a boolean option.
4827
+ * ```ts
4828
+ * abool(true, 'enableXOF');
4829
+ * ```
4830
+ */
4831
+ function abool$1(value, title = '') {
4832
+ if (typeof value !== 'boolean')
4833
+ throw new TypeError(atitle$1(title) + 'expected boolean, got type=' + typeof value);
4834
+ return value;
4835
+ }
4836
+ /**
4837
+ * Asserts something is Uint8Array.
4838
+ * @param value - value to validate
4839
+ * @param length - optional exact length constraint
4840
+ * @param title - label included in thrown errors
4841
+ * @returns The validated byte array.
4842
+ * @throws On wrong argument types. {@link TypeError}
4843
+ * @throws On wrong argument ranges or values. {@link RangeError}
4844
+ * @example
4845
+ * Validate that a value is a byte array.
4846
+ * ```ts
4847
+ * abytes(new Uint8Array([1, 2, 3]));
4848
+ * ```
4849
+ */
4850
+ function abytes(value, length, title = '') {
4851
+ // Success path first: this runs at the start of every update() / digestInto(), and the
4852
+ // common `abytes(data)` form must not pay for length handling it does not use.
4853
+ if (isBytes(value) && (length === undefined || value.length === length))
4854
+ return value;
4855
+ // Error path: recompute freely to build the exact message.
4856
+ if (length !== undefined)
4857
+ anumber(length, 'length');
4858
+ const bytes = isBytes(value);
4859
+ const ofLen = length !== undefined ? ` of length ${length}` : '';
4860
+ const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
4861
+ const message = atitle$1(title) + 'expected Uint8Array' + ofLen + ', got ' + got;
4862
+ if (!bytes)
4863
+ throw new TypeError(message);
4864
+ throw new RangeError(message);
4865
+ }
4866
+ /**
4867
+ * Asserts something is a wrapped hash constructor.
4868
+ * @param h - hash constructor to validate
4869
+ * @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError}
4870
+ * @throws On invalid hash metadata ranges or values. {@link RangeError}
4871
+ * @throws If the hash metadata allows empty outputs or block sizes. {@link Error}
4872
+ * @example
4873
+ * Validate a callable hash wrapper.
4874
+ * ```ts
4875
+ * import { ahash } from '@noble/hashes/utils.js';
4876
+ * import { sha256 } from '@noble/hashes/sha2.js';
4877
+ * ahash(sha256);
4878
+ * ```
4879
+ */
4880
+ function ahash(h) {
4881
+ if (typeof h !== 'function' || typeof h.create !== 'function')
4882
+ throw new TypeError('expected hash wrapped by utils.createHasher');
4883
+ anumber(h.outputLen);
4884
+ anumber(h.blockLen);
4885
+ // HMAC and KDF callers treat these as real byte lengths; allowing zero lets fake wrappers pass
4886
+ // validation and can produce empty outputs instead of failing fast.
4887
+ if (h.outputLen < 1 || h.blockLen < 1)
4888
+ throw new Error('hash blockLen / outputLen must be >= 1');
4889
+ }
4890
+ const aobject$2 = (value, label) => {
4891
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
4892
+ throw new TypeError((label === 'object' ? '' : `"${label}" `) + 'expected object, got type=' + typeof value);
4893
+ };
4894
+ const aopts = (value, label) => {
4895
+ aobject$2(value, label);
4896
+ const proto = Object.getPrototypeOf(value);
4897
+ if (proto !== Object.prototype && proto !== null)
4898
+ throw new TypeError(`"${label}" expected plain object`);
4899
+ // Object.assign() treats an own "__proto__" source key as a write to the target's legacy
4900
+ // prototype setter. Reject it before merging so inherited option values cannot be injected.
4901
+ if (Object.hasOwn(value, '__proto__'))
4902
+ throw new TypeError(`"${label}.__proto__" is not allowed`);
4903
+ };
4904
+ /**
4905
+ * Asserts a hash instance has not been destroyed or finished.
4906
+ * @param instance - hash instance to validate
4907
+ * @param checkFinished - whether to reject finalized instances
4908
+ * @throws If the hash instance has already been destroyed or finalized. {@link Error}
4909
+ * @example
4910
+ * Validate that a hash instance is still usable.
4911
+ * ```ts
4912
+ * import { aexists } from '@noble/hashes/utils.js';
4913
+ * import { sha256 } from '@noble/hashes/sha2.js';
4914
+ * const hash = sha256.create();
4915
+ * aexists(hash);
4916
+ * ```
4917
+ */
4918
+ function aexists(instance, checkFinished = true) {
4919
+ // Runs on every update()/digestInto(); the flags are library-owned booleans, so only their
4920
+ // truthiness is checked - re-validating their type per call was pure hot-path overhead.
4921
+ if (instance.destroyed)
4922
+ throw new Error('hash was destroyed');
4923
+ if (checkFinished && instance.finished)
4924
+ throw new Error('digest() was already called');
4925
+ }
4926
+ /**
4927
+ * Asserts output is a sufficiently-sized byte array.
4928
+ * @param out - destination buffer
4929
+ * @param instance - hash instance providing output length
4930
+ * Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.
4931
+ * @throws On wrong argument types. {@link TypeError}
4932
+ * @throws On wrong argument ranges or values. {@link RangeError}
4933
+ * @example
4934
+ * Validate a caller-provided digest buffer.
4935
+ * ```ts
4936
+ * import { aoutput } from '@noble/hashes/utils.js';
4937
+ * import { sha256 } from '@noble/hashes/sha2.js';
4938
+ * const hash = sha256.create();
4939
+ * aoutput(new Uint8Array(hash.outputLen), hash);
4940
+ * ```
4941
+ */
4942
+ function aoutput(out, instance) {
4943
+ abytes(out, undefined, 'output');
4944
+ // `outputLen` is a library-owned readonly number; the negated comparison keeps failing fast
4945
+ // when it is missing/NaN (comparisons with undefined/NaN are false) without an anumber() call.
4946
+ const min = instance.outputLen;
4947
+ if (!(out.length >= min)) {
4948
+ throw new RangeError('"output" expected length >= ' + min);
4790
4949
  }
4791
- static async fromSecretKey(key, passphrase) {
4792
- return new InMemorySigner(key, passphrase);
4950
+ }
4951
+ /**
4952
+ * Casts a typed array view to Uint32Array.
4953
+ * `arr.byteOffset` must already be 4-byte aligned or the platform
4954
+ * Uint32Array constructor will throw.
4955
+ * @param arr - source typed array
4956
+ * @returns Uint32Array view over the same buffer.
4957
+ * @example
4958
+ * Reinterpret a byte array as 32-bit words.
4959
+ * ```ts
4960
+ * u32(new Uint8Array(8));
4961
+ * ```
4962
+ */
4963
+ function u32(arr) {
4964
+ return new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
4965
+ }
4966
+ /**
4967
+ * Zeroizes typed arrays in place. Warning: JS provides no guarantees.
4968
+ * @param arrays - arrays to overwrite with zeros
4969
+ * @example
4970
+ * Zeroize sensitive buffers in place.
4971
+ * ```ts
4972
+ * clean(new Uint8Array([1, 2, 3]));
4973
+ * ```
4974
+ */
4975
+ function clean(...arrays) {
4976
+ for (let i = 0; i < arrays.length; i++) {
4977
+ arrays[i].fill(0);
4793
4978
  }
4794
- /**
4795
- *
4796
- * Instantiation of an InMemorySigner instance from a mnemonic
4797
- * @returns InMemorySigner
4798
- * @throws InvalidMnemonicError
4799
- */
4800
- static fromMnemonic({ mnemonic, password = '', derivationPath = "44'/1729'/0'/0'", curve = 'ed25519', }) {
4801
- // check if curve is defined if not default tz1
4802
- if (!validateMnemonic(mnemonic, wordlist)) {
4803
- // avoiding exposing mnemonic again in case of mistake making invalid
4804
- throw new InvalidMnemonicError();
4805
- }
4806
- const seed = mnemonicToSeedSync(mnemonic, password);
4807
- const sk = generateSecretKey(seed, derivationPath, curve);
4808
- return new InMemorySigner(sk);
4979
+ }
4980
+ /** Whether the current platform is little-endian. */
4981
+ const isLE = /* @__PURE__ */ (() => new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44)();
4982
+ /**
4983
+ * Byte-swap operation for uint32 values.
4984
+ * @param word - source word
4985
+ * @returns Word with reversed byte order.
4986
+ * @example
4987
+ * Reverse the byte order of a 32-bit word.
4988
+ * ```ts
4989
+ * byteSwap(0x11223344);
4990
+ * ```
4991
+ */
4992
+ function byteSwap(word) {
4993
+ return (((word << 24) & 0xff000000) |
4994
+ ((word << 8) & 0xff0000) |
4995
+ ((word >>> 8) & 0xff00) |
4996
+ ((word >>> 24) & 0xff));
4997
+ }
4998
+ /**
4999
+ * Byte-swaps every word of a Uint32Array in place.
5000
+ * @param arr - array to mutate
5001
+ * @returns The same array after mutation; callers pass live state arrays here.
5002
+ * @example
5003
+ * Reverse the byte order of every word in place.
5004
+ * ```ts
5005
+ * byteSwap32(new Uint32Array([0x11223344]));
5006
+ * ```
5007
+ */
5008
+ function byteSwap32(arr) {
5009
+ for (let i = 0; i < arr.length; i++) {
5010
+ arr[i] = byteSwap(arr[i]);
4809
5011
  }
4810
- /**
4811
- *
4812
- * @param key Encoded private key
4813
- * @param passphrase Passphrase to decrypt the private key if it is encrypted
4814
- * @throws InvalidKeyError
4815
- *
4816
- */
4817
- constructor(key, passphrase) {
4818
- _InMemorySigner_key.set(this, void 0);
4819
- const keyPrefixes = [
4820
- PrefixV2.Ed25519EncryptedSeed,
4821
- PrefixV2.Ed25519Seed,
4822
- PrefixV2.Ed25519SecretKey,
4823
- PrefixV2.Secp256k1EncryptedSecretKey,
4824
- PrefixV2.Secp256k1SecretKey,
5012
+ return arr;
5013
+ }
5014
+ /**
5015
+ * Conditionally byte-swaps a Uint32Array on big-endian platforms.
5016
+ * @param u - array to normalize for host endianness
5017
+ * @returns Original or byte-swapped array depending on platform endianness.
5018
+ * On big-endian runtimes this mutates `u` in place via `byteSwap32(...)`.
5019
+ * @example
5020
+ * Normalize a word array for host endianness.
5021
+ * ```ts
5022
+ * swap32IfBE(new Uint32Array([0x11223344]));
5023
+ * ```
5024
+ */
5025
+ const swap32IfBE = isLE
5026
+ ? (u) => u
5027
+ : byteSwap32;
5028
+ // Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
5029
+ const hasHexBuiltin = /* @__PURE__ */ (() =>
5030
+ // @ts-ignore
5031
+ typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();
5032
+ // Array where index 0xf0 (240) is mapped to string 'f0'
5033
+ const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
5034
+ /**
5035
+ * Convert byte array to hex string.
5036
+ * Uses the built-in function when available and assumes it matches the tested
5037
+ * fallback semantics.
5038
+ * @param bytes - bytes to encode
5039
+ * @returns Lowercase hexadecimal string.
5040
+ * @throws On wrong argument types. {@link TypeError}
5041
+ * @example
5042
+ * Convert bytes to lowercase hexadecimal.
5043
+ * ```ts
5044
+ * bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'
5045
+ * ```
5046
+ */
5047
+ function bytesToHex(bytes) {
5048
+ abytes(bytes);
5049
+ // @ts-ignore
5050
+ if (hasHexBuiltin)
5051
+ return bytes.toHex();
5052
+ // pre-caching improves the speed 6x
5053
+ let hex = '';
5054
+ for (let i = 0; i < bytes.length; i++) {
5055
+ hex += hexes[bytes[i]];
5056
+ }
5057
+ return hex;
5058
+ }
5059
+ /**
5060
+ * Copies several Uint8Arrays into one.
5061
+ * @param arrays - arrays to concatenate
5062
+ * @returns Concatenated byte array.
5063
+ * @throws On wrong argument types. {@link TypeError}
5064
+ * @example
5065
+ * Concatenate multiple byte arrays.
5066
+ * ```ts
5067
+ * concatBytes(new Uint8Array([1]), new Uint8Array([2]));
5068
+ * ```
5069
+ */
5070
+ function concatBytes(...arrays) {
5071
+ let sum = 0;
5072
+ for (let i = 0; i < arrays.length; i++) {
5073
+ const a = arrays[i];
5074
+ abytes(a);
5075
+ sum += a.length;
5076
+ }
5077
+ const res = new Uint8Array(sum);
5078
+ for (let i = 0, pad = 0; i < arrays.length; i++) {
5079
+ const a = arrays[i];
5080
+ res.set(a, pad);
5081
+ pad += a.length;
5082
+ }
5083
+ return res;
5084
+ }
5085
+ /**
5086
+ * Merges default options and passed options.
5087
+ * @param defaults - base option object
5088
+ * @param opts - user overrides
5089
+ * @param title - label included in thrown override errors
5090
+ * @returns Fresh merged option object with a null prototype.
5091
+ * @throws On wrong argument types. {@link TypeError}
5092
+ * @example
5093
+ * Merge user overrides onto default options.
5094
+ * ```ts
5095
+ * checkOpts({ dkLen: 32 }, { asyncTick: 10 });
5096
+ * ```
5097
+ */
5098
+ function checkOpts(defaults, opts, title = 'opts') {
5099
+ aopts(defaults, 'defaults');
5100
+ if (opts !== undefined)
5101
+ aopts(opts, title);
5102
+ // Callers read optional fields directly, so omitted values must not fall through to ambient
5103
+ // Object.prototype pollution (for example a forged `dkLen` changing SHAKE's default output).
5104
+ const merged = Object.assign(Object.create(null), defaults, opts);
5105
+ return merged;
5106
+ }
5107
+ /**
5108
+ * Creates a callable hash function from a stateful class constructor.
5109
+ * @param hashCons - hash constructor or factory
5110
+ * @param info - optional metadata such as DER OID
5111
+ * @returns Frozen callable hash wrapper with `.create()`.
5112
+ * Wrapper construction eagerly calls `hashCons(undefined)` once to read
5113
+ * `outputLen` / `blockLen`, so constructor side effects happen at module
5114
+ * init time.
5115
+ * @throws On wrong argument types. {@link TypeError}
5116
+ * @example
5117
+ * Wrap a stateful hash constructor into a callable helper.
5118
+ * ```ts
5119
+ * import { createHasher } from '@noble/hashes/utils.js';
5120
+ * import { sha256 } from '@noble/hashes/sha2.js';
5121
+ * const wrapped = createHasher(sha256.create, { oid: sha256.oid });
5122
+ * wrapped(new Uint8Array([1]));
5123
+ * ```
5124
+ */
5125
+ function createHasher(hashCons, info = {}) {
5126
+ if (typeof hashCons !== 'function')
5127
+ throw new TypeError('"hashCons" expected function, got type=' + typeof hashCons);
5128
+ info = checkOpts({}, info, 'info');
5129
+ const hashC = (msg, opts) => hashCons(opts)
5130
+ .update(msg)
5131
+ .digest();
5132
+ const tmp = hashCons(undefined);
5133
+ hashC.outputLen = tmp.outputLen;
5134
+ hashC.blockLen = tmp.blockLen;
5135
+ hashC.canXOF = tmp.canXOF;
5136
+ hashC.create = (opts) => hashCons(opts);
5137
+ Object.assign(hashC, info);
5138
+ return Object.freeze(hashC);
5139
+ }
5140
+ /**
5141
+ * Cryptographically secure PRNG backed by `crypto.getRandomValues`.
5142
+ * @param bytesLength - number of random bytes to generate
5143
+ * @returns Random bytes.
5144
+ * The platform `getRandomValues()` implementation still defines any
5145
+ * single-call length cap, and this helper rejects oversize requests
5146
+ * with a stable library `RangeError` instead of host-specific errors.
5147
+ * @throws On wrong argument types. {@link TypeError}
5148
+ * @throws On wrong argument ranges or values. {@link RangeError}
5149
+ * @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error}
5150
+ * @example
5151
+ * Generate a fresh random key or nonce.
5152
+ * ```ts
5153
+ * const key = randomBytes(16);
5154
+ * ```
5155
+ */
5156
+ function randomBytes$1(bytesLength = 32) {
5157
+ // Match the repo's other length-taking helpers instead of relying on Uint8Array coercion.
5158
+ anumber(bytesLength, 'bytesLength');
5159
+ const cr = typeof globalThis === 'object' ? globalThis.crypto : null;
5160
+ if (typeof cr?.getRandomValues !== 'function')
5161
+ throw new Error('crypto.getRandomValues must be defined');
5162
+ // Web Cryptography API Level 2 §10.1.1:
5163
+ // if `byteLength > 65536`, throw `QuotaExceededError`.
5164
+ // Keep the guard explicit so callers can see the quota in code
5165
+ // instead of discovering it by reading the spec or host errors.
5166
+ // This wrapper surfaces the same quota as a stable library RangeError.
5167
+ if (bytesLength > 65536)
5168
+ throw new RangeError(`"bytesLength" expected <= 65536, got ${bytesLength}`);
5169
+ return cr.getRandomValues(new Uint8Array(bytesLength));
5170
+ }
5171
+ /**
5172
+ * Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.
5173
+ * @param suffix - final OID byte for the selected hash.
5174
+ * The helper accepts any byte even though only the documented NIST hash
5175
+ * suffixes are meaningful downstream.
5176
+ * @returns Object containing the DER-encoded OID.
5177
+ * @example
5178
+ * Build OID metadata for a NIST hash.
5179
+ * ```ts
5180
+ * oidNist(0x01);
5181
+ * ```
5182
+ */
5183
+ const oidNist = (suffix) => ({
5184
+ // Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.
5185
+ // Larger suffix values would need base-128 OID encoding and a different length byte.
5186
+ oid: Uint8Array.from([0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, suffix]),
5187
+ });
5188
+
5189
+ /**
5190
+ * Hex, bytes and number utilities.
5191
+ * @module
5192
+ */
5193
+ /*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5194
+ /**
5195
+ * Asserts something is a plain object-ish value, not null or array.
5196
+ * @param value - Value to validate.
5197
+ * @param title - Label included in thrown errors.
5198
+ * @returns The validated object.
5199
+ * @throws On wrong argument types. {@link TypeError}
5200
+ * @example
5201
+ * Validate an options object before checking fields.
5202
+ *
5203
+ * ```ts
5204
+ * aobject({ flag: true });
5205
+ * ```
5206
+ */
5207
+ function aobject$1(value, title = 'object') {
5208
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
5209
+ throw new TypeError(title === 'object'
5210
+ ? 'expected valid options object'
5211
+ : `"${title}" expected object, got type=${typeof value}`);
5212
+ return value;
5213
+ }
5214
+ // Shared error-message prefix builder. Only called on throw paths, so assert
5215
+ // success paths never pay for the string concatenation.
5216
+ const atitle = (title) => (title ? `"${title}" ` : '');
5217
+ /**
5218
+ * Validates that a flag is boolean.
5219
+ * @param value - Value to validate.
5220
+ * @param title - Optional field name.
5221
+ * @returns Original value.
5222
+ * @throws On wrong argument types. {@link TypeError}
5223
+ * @example
5224
+ * Reject non-boolean option flags early.
5225
+ *
5226
+ * ```ts
5227
+ * abool(true);
5228
+ * ```
5229
+ */
5230
+ function abool(value, title = '') {
5231
+ if (typeof value !== 'boolean')
5232
+ throw new TypeError(atitle(title) + 'expected boolean, got type=' + typeof value);
5233
+ return value;
5234
+ }
5235
+ /**
5236
+ * Validates declared required and optional field types on a plain object.
5237
+ * Extra keys are intentionally ignored because many callers validate only the subset they use from
5238
+ * richer option bags or runtime objects.
5239
+ * This walks field schemas and formats detailed errors, so avoid it on hot paths; use direct
5240
+ * one-line guards such as `aobject()`, `afunction()`, `abool()`, or `asafenumber()` instead.
5241
+ * @param object - Object to validate.
5242
+ * @param fields - Required field types.
5243
+ * @param optFields - Optional field types.
5244
+ * @param title - Object label included in thrown errors.
5245
+ * @throws On wrong argument types. {@link TypeError}
5246
+ * @example
5247
+ * Check user options before building a curve helper.
5248
+ *
5249
+ * ```ts
5250
+ * validateObject({ flag: true }, { flag: 'boolean' });
5251
+ * ```
5252
+ */
5253
+ function validateObject(object, fields = {}, optFields = {}, title = 'object') {
5254
+ aobject$1(object, title);
5255
+ aobject$1(fields, 'fields');
5256
+ aobject$1(optFields, 'optFields');
5257
+ function checkField(fieldName, expectedType, isOpt) {
5258
+ const label = title === 'object' ? `param "${String(fieldName)}"` : `"${title}.${String(fieldName)}"`;
5259
+ // Config fields must be explicit own properties. Optional inherited values are rejected too
5260
+ // because callers keep reading the same options object after validation.
5261
+ const val = object[fieldName];
5262
+ // Runtime objects such as Field instances intentionally satisfy required method slots
5263
+ // via their shared prototype.
5264
+ if (!Object.hasOwn(object, fieldName) &&
5265
+ (isOpt ? val !== undefined : expectedType !== 'function')) {
5266
+ throw new TypeError(`${label} is invalid: expected own property`);
5267
+ }
5268
+ if (isOpt && val === undefined)
5269
+ return;
5270
+ const current = typeof val;
5271
+ if (current !== expectedType || val === null)
5272
+ throw new TypeError(`${label} is invalid: expected ${expectedType}, got ${current}`);
5273
+ }
5274
+ const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
5275
+ iter(fields, false);
5276
+ iter(optFields, true);
5277
+ }
5278
+
5279
+ const U32_MASK64 = /* @__PURE__ */ (() => BigInt(2 ** 32 - 1))();
5280
+ const _32n = /* @__PURE__ */ BigInt(32);
5281
+ // Split bigint into two 32-bit halves. With `le=true`, returned fields become `{ h: low, l: high
5282
+ // }` to match little-endian word order rather than the property names.
5283
+ function fromBig(n, le = false) {
5284
+ if (le)
5285
+ return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
5286
+ return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
5287
+ }
5288
+ // Split bigint list into `[highWords, lowWords]` when `le=false`; with `le=true`, the first array
5289
+ // holds the low halves because `fromBig(...)` swaps the semantic meaning of `h` and `l`.
5290
+ function split(lst, le = false) {
5291
+ const len = lst.length;
5292
+ let Ah = new Uint32Array(len);
5293
+ let Al = new Uint32Array(len);
5294
+ for (let i = 0; i < len; i++) {
5295
+ const { h, l } = fromBig(lst[i], le);
5296
+ [Ah[i], Al[i]] = [h, l];
5297
+ }
5298
+ return [Ah, Al];
5299
+ }
5300
+
5301
+ /**
5302
+ * SHA3 (keccak) hash function, based on a new "Sponge function" design.
5303
+ * Different from older hashes, the internal state is bigger than output size.
5304
+ *
5305
+ * Check out
5306
+ * {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf | FIPS-202},
5307
+ * {@link https://keccak.team/keccak.html | Website}, and
5308
+ * {@link https://crypto.stackexchange.com/q/15727 | the differences between
5309
+ * SHA-3 and Keccak}.
5310
+ *
5311
+ * Check out `sha3-addons` module for cSHAKE, k12, and others.
5312
+ * @module
5313
+ */
5314
+ // No __PURE__ annotations in sha3 header:
5315
+ // EVERYTHING is in fact used on every export.
5316
+ // Various per round constants calculations
5317
+ const _0n = BigInt(0);
5318
+ const _1n = BigInt(1);
5319
+ const _2n = BigInt(2);
5320
+ const _7n = BigInt(7);
5321
+ const _256n = BigInt(256);
5322
+ // FIPS 202 Algorithm 5 rc(): when the outgoing bit is 1, the 8-bit LFSR xors
5323
+ // taps 0, 4, 5, and 6, which compresses to the feedback mask `0x71`.
5324
+ const _0x71n = BigInt(0x71);
5325
+ const SHA3_PI = [];
5326
+ const SHA3_ROTL = [];
5327
+ const _SHA3_IOTA = []; // no pure annotation: var is always used
5328
+ for (let round = 0, R = _1n, x = 1, y = 0; round < 24; round++) {
5329
+ // Pi
5330
+ [x, y] = [y, (2 * x + 3 * y) % 5];
5331
+ SHA3_PI.push(2 * (5 * y + x));
5332
+ // Rotational
5333
+ SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);
5334
+ // Iota
5335
+ let t = _0n;
5336
+ for (let j = 0; j < 7; j++) {
5337
+ R = ((R << _1n) ^ ((R >> _7n) * _0x71n)) % _256n;
5338
+ if (R & _2n)
5339
+ t ^= _1n << ((_1n << BigInt(j)) - _1n);
5340
+ }
5341
+ _SHA3_IOTA.push(t);
5342
+ }
5343
+ const IOTAS = split(_SHA3_IOTA, true);
5344
+ // `split(..., true)` keeps the local little-endian lane-word layout used by
5345
+ // `state32`, so these `H` / `L` tables follow the file's first-word /
5346
+ // second-word lane slots rather than `_u64.ts`'s usual high/low naming.
5347
+ const SHA3_IOTA_H = IOTAS[0];
5348
+ const SHA3_IOTA_L = IOTAS[1];
5349
+ // 64-bit left rotates as u32 pairs. Inlined here (not imported from _u64) so V8 can
5350
+ // inline them into keccakP — the import path costs ~24% on sha3_256. SHA3 is the only
5351
+ // consumer of left-rotates; other hashes use right-rotates from _u64.
5352
+ // Valid for s in 1..31 (SH/SL) and 33..63 (BH/BL); keccak never rotates by 0/32/64.
5353
+ const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
5354
+ const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
5355
+ const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
5356
+ const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
5357
+ const rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));
5358
+ const rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));
5359
+ // Reused Theta scratch buffer (column parities), same pattern as SHA256_W in sha2.
5360
+ // keccakP never calls user code, so the shared buffer cannot be observed mid-permutation.
5361
+ const B = new Uint32Array(5 * 2);
5362
+ /**
5363
+ * `keccakf1600` internal permutation, additionally allows adjusting the round count.
5364
+ * @param s - 5x5 Keccak state encoded as 25 lanes split into 50 uint32 words
5365
+ * in this file's local little-endian lane-word order
5366
+ * @param rounds - number of rounds to execute
5367
+ * @throws On wrong argument types. {@link TypeError}
5368
+ * @throws On wrong argument ranges or values. {@link RangeError}
5369
+ * @throws If `rounds` is outside the supported `1..24` range. {@link Error}
5370
+ * @example
5371
+ * Permute a Keccak state with the default 24 rounds.
5372
+ * ```ts
5373
+ * keccakP(new Uint32Array(50));
5374
+ * ```
5375
+ */
5376
+ function keccakP(s, rounds = 24) {
5377
+ if (!(s instanceof Uint32Array))
5378
+ throw new TypeError('"s" expected Uint32Array(50), got type=' + typeof s);
5379
+ if (s.length !== 50)
5380
+ throw new RangeError('"s" expected Uint32Array(50), got length=' + s.length);
5381
+ anumber(rounds, 'rounds');
5382
+ // This implementation precomputes only the standard Keccak-f[1600] 24-round Iota table.
5383
+ if (rounds < 1 || rounds > 24)
5384
+ throw new Error('"rounds" expected integer 1..24');
5385
+ // NOTE: all indices are x2 since we store state as u32 instead of u64 (bigints to slow in js)
5386
+ for (let round = 24 - rounds; round < 24; round++) {
5387
+ // Theta θ
5388
+ for (let x = 0; x < 10; x++)
5389
+ B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
5390
+ for (let x = 0; x < 10; x += 2) {
5391
+ const idx1 = (x + 8) % 10;
5392
+ const idx0 = (x + 2) % 10;
5393
+ const B0 = B[idx0];
5394
+ const B1 = B[idx0 + 1];
5395
+ const Th = rotlH(B0, B1, 1) ^ B[idx1];
5396
+ const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
5397
+ for (let y = 0; y < 50; y += 10) {
5398
+ s[x + y] ^= Th;
5399
+ s[x + y + 1] ^= Tl;
5400
+ }
5401
+ }
5402
+ // Rho (ρ) and Pi (π)
5403
+ let curH = s[2];
5404
+ let curL = s[3];
5405
+ for (let t = 0; t < 24; t++) {
5406
+ const shift = SHA3_ROTL[t];
5407
+ const Th = rotlH(curH, curL, shift);
5408
+ const Tl = rotlL(curH, curL, shift);
5409
+ const PI = SHA3_PI[t];
5410
+ curH = s[PI];
5411
+ curL = s[PI + 1];
5412
+ s[PI] = Th;
5413
+ s[PI + 1] = Tl;
5414
+ }
5415
+ // Chi (χ)
5416
+ // Same as:
5417
+ // for (let x = 0; x < 10; x++) B[x] = s[y + x];
5418
+ // for (let x = 0; x < 10; x++) s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
5419
+ for (let y = 0; y < 50; y += 10) {
5420
+ const b0 = s[y], b1 = s[y + 1], b2 = s[y + 2], b3 = s[y + 3];
5421
+ s[y] ^= ~s[y + 2] & s[y + 4];
5422
+ s[y + 1] ^= ~s[y + 3] & s[y + 5];
5423
+ s[y + 2] ^= ~s[y + 4] & s[y + 6];
5424
+ s[y + 3] ^= ~s[y + 5] & s[y + 7];
5425
+ s[y + 4] ^= ~s[y + 6] & s[y + 8];
5426
+ s[y + 5] ^= ~s[y + 7] & s[y + 9];
5427
+ s[y + 6] ^= ~s[y + 8] & b0;
5428
+ s[y + 7] ^= ~s[y + 9] & b1;
5429
+ s[y + 8] ^= ~b0 & b2;
5430
+ s[y + 9] ^= ~b1 & b3;
5431
+ }
5432
+ // Iota (ι)
5433
+ s[0] ^= SHA3_IOTA_H[round];
5434
+ s[1] ^= SHA3_IOTA_L[round];
5435
+ }
5436
+ clean(B);
5437
+ }
5438
+ /**
5439
+ * Keccak sponge function.
5440
+ * @param blockLen - absorb/squeeze rate in bytes
5441
+ * @param suffix - domain separation suffix byte
5442
+ * @param outputLen - default digest length in bytes. This base sponge only
5443
+ * requires a non-negative integer; wrappers that need positive output
5444
+ * lengths must enforce that themselves.
5445
+ * @param enableXOF - whether XOF output is allowed
5446
+ * @param rounds - number of Keccak-f rounds
5447
+ * @example
5448
+ * Build a sponge state, absorb bytes, then finalize a digest.
5449
+ * ```ts
5450
+ * const hash = new Keccak(136, 0x06, 32);
5451
+ * hash.update(new Uint8Array([1, 2, 3]));
5452
+ * hash.digest();
5453
+ * ```
5454
+ */
5455
+ class Keccak {
5456
+ state;
5457
+ pos = 0;
5458
+ posOut = 0;
5459
+ finished = false;
5460
+ state32;
5461
+ destroyed = false;
5462
+ blockLen;
5463
+ suffix;
5464
+ outputLen;
5465
+ canXOF;
5466
+ enableXOF = false;
5467
+ rounds;
5468
+ // NOTE: we accept arguments in bytes instead of bits here.
5469
+ constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
5470
+ anumber(blockLen, 'blockLen');
5471
+ anumber(suffix, 'suffix');
5472
+ anumber(rounds, 'rounds');
5473
+ abool$1(enableXOF, 'enableXOF');
5474
+ this.blockLen = blockLen;
5475
+ this.suffix = suffix;
5476
+ this.outputLen = outputLen;
5477
+ this.enableXOF = enableXOF;
5478
+ this.canXOF = enableXOF;
5479
+ this.rounds = rounds;
5480
+ // Can be passed from user as dkLen
5481
+ anumber(outputLen, 'outputLen');
5482
+ // Only keccak-f1600 is supported: 1600 bits (5x5 matrix of 64bit) === 200 bytes of state.
5483
+ if (!(0 < blockLen && blockLen < 200))
5484
+ throw new Error('"blockLen" must be 1..199');
5485
+ this.state = new Uint8Array(200);
5486
+ this.state32 = u32(this.state);
5487
+ }
5488
+ clone() {
5489
+ return this._cloneInto();
5490
+ }
5491
+ keccak() {
5492
+ swap32IfBE(this.state32);
5493
+ keccakP(this.state32, this.rounds);
5494
+ swap32IfBE(this.state32);
5495
+ this.posOut = 0;
5496
+ this.pos = 0;
5497
+ }
5498
+ update(data) {
5499
+ aexists(this);
5500
+ abytes(data);
5501
+ const { blockLen, state, state32 } = this;
5502
+ const len = data.length;
5503
+ // Absorb full blocks with u32 XORs when both sides are 4-byte aligned.
5504
+ // XOR of same-position words equals XOR of same-position bytes, so this is endianness-safe.
5505
+ const canUseU32 = blockLen % 4 === 0 && data.byteOffset % 4 === 0;
5506
+ const blockLen32 = blockLen / 4;
5507
+ const data32 = canUseU32 && len >= blockLen ? u32(data) : undefined;
5508
+ for (let pos = 0; pos < len;) {
5509
+ if (data32 !== undefined && this.pos === 0 && pos % 4 === 0 && len - pos >= blockLen) {
5510
+ for (let i = 0, o = pos / 4; i < blockLen32; i++)
5511
+ state32[i] ^= data32[o + i];
5512
+ pos += blockLen;
5513
+ // Subclasses (_KeccakPRG) read `this.pos` inside their `keccak()` override,
5514
+ // so it must reflect the fully-absorbed block before the permutation fires.
5515
+ this.pos = blockLen;
5516
+ this.keccak();
5517
+ continue;
5518
+ }
5519
+ const take = Math.min(blockLen - this.pos, len - pos);
5520
+ for (let i = 0; i < take; i++)
5521
+ state[this.pos++] ^= data[pos++];
5522
+ if (this.pos === blockLen)
5523
+ this.keccak();
5524
+ }
5525
+ return this;
5526
+ }
5527
+ finish() {
5528
+ if (this.finished)
5529
+ return;
5530
+ this.finished = true;
5531
+ const { state, suffix, pos, blockLen } = this;
5532
+ // FIPS 202 appends the SHA3/SHAKE domain-separation suffix before pad10*1.
5533
+ // These byte values already include the first padding bit, while the
5534
+ // final `0x80` below supplies the closing `1` bit in the last rate byte.
5535
+ state[pos] ^= suffix;
5536
+ // If that combined suffix lands in the last rate byte and already sets
5537
+ // bit 7, absorb it first so the final pad10*1 bit can be xored into a
5538
+ // fresh block.
5539
+ if ((suffix & 0x80) !== 0 && pos === blockLen - 1)
5540
+ this.keccak();
5541
+ state[blockLen - 1] ^= 0x80;
5542
+ this.keccak();
5543
+ }
5544
+ writeInto(out) {
5545
+ aexists(this, false);
5546
+ abytes(out);
5547
+ this.finish();
5548
+ const bufferOut = this.state;
5549
+ const { blockLen } = this;
5550
+ for (let pos = 0, len = out.length; pos < len;) {
5551
+ if (this.posOut >= blockLen)
5552
+ this.keccak();
5553
+ const take = Math.min(blockLen - this.posOut, len - pos);
5554
+ out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
5555
+ this.posOut += take;
5556
+ pos += take;
5557
+ }
5558
+ return out;
5559
+ }
5560
+ xofInto(out) {
5561
+ // Plain SHA3/Keccak usage with XOF is probably a mistake, but this base
5562
+ // class is also reused by SHAKE/cSHAKE/KMAC/TupleHash/ParallelHash/
5563
+ // TurboSHAKE/KangarooTwelve wrappers that intentionally enable XOF.
5564
+ if (!this.enableXOF)
5565
+ throw new Error('XOF is not enabled');
5566
+ return this.writeInto(out);
5567
+ }
5568
+ xof(bytes) {
5569
+ anumber(bytes);
5570
+ return this.xofInto(new Uint8Array(bytes));
5571
+ }
5572
+ digestInto(out) {
5573
+ aoutput(out, this);
5574
+ if (this.finished)
5575
+ throw new Error('digest() was already called');
5576
+ // `aoutput(...)` allows oversized buffers; digestInto() must fill only the advertised digest.
5577
+ this.writeInto(out.length === this.outputLen ? out : out.subarray(0, this.outputLen));
5578
+ this.destroy();
5579
+ }
5580
+ digest() {
5581
+ const out = new Uint8Array(this.outputLen);
5582
+ this.digestInto(out);
5583
+ return out;
5584
+ }
5585
+ destroy() {
5586
+ this.destroyed = true;
5587
+ clean(this.state);
5588
+ }
5589
+ _cloneInto(to) {
5590
+ const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
5591
+ to ||= new Keccak(blockLen, suffix, outputLen, enableXOF, rounds);
5592
+ // Reused destinations can come from a different rate/capacity variant, so clone must rewrite
5593
+ // the sponge geometry as well as the state words.
5594
+ to.blockLen = blockLen;
5595
+ to.state32.set(this.state32);
5596
+ // Sponge padding and XOF output are positional, so both offsets are part of the clone state.
5597
+ to.pos = this.pos;
5598
+ to.posOut = this.posOut;
5599
+ to.finished = this.finished;
5600
+ to.rounds = rounds;
5601
+ // Suffix can change in cSHAKE
5602
+ to.suffix = suffix;
5603
+ to.outputLen = outputLen;
5604
+ to.enableXOF = enableXOF;
5605
+ // Clones must preserve the public capability bit too; `_KMAC` reuses this path and deep clone
5606
+ // tests compare instance fields directly, so leaving `canXOF` behind makes the clone lie.
5607
+ to.canXOF = this.canXOF;
5608
+ to.destroyed = this.destroyed;
5609
+ return to;
5610
+ }
5611
+ }
5612
+ const genShake = (suffix, blockLen, outputLen, info = {}) => createHasher((opts = {}) => {
5613
+ opts = checkOpts({}, opts);
5614
+ return new Keccak(blockLen, suffix, opts.dkLen === undefined ? outputLen : opts.dkLen, true);
5615
+ }, info);
5616
+ /**
5617
+ * SHAKE128 XOF with 128-bit security and a 16-byte default output.
5618
+ * @param msg - message bytes to hash
5619
+ * @param opts - Optional output-length override. See {@link ShakeOpts}.
5620
+ * @returns Digest bytes.
5621
+ * @example
5622
+ * Hash a message with SHAKE128.
5623
+ * ```ts
5624
+ * shake128(new Uint8Array([97, 98, 99]), { dkLen: 32 });
5625
+ * ```
5626
+ */
5627
+ const shake128 =
5628
+ /* @__PURE__ */
5629
+ genShake(0x1f, 168, 16, /* @__PURE__ */ oidNist(0x0b));
5630
+ /**
5631
+ * SHAKE256 XOF with 256-bit security and a 32-byte default output.
5632
+ * @param msg - message bytes to hash
5633
+ * @param opts - Optional output-length override. See {@link ShakeOpts}.
5634
+ * @returns Digest bytes.
5635
+ * @example
5636
+ * Hash a message with SHAKE256.
5637
+ * ```ts
5638
+ * shake256(new Uint8Array([97, 98, 99]), { dkLen: 64 });
5639
+ * ```
5640
+ */
5641
+ const shake256 =
5642
+ /* @__PURE__ */
5643
+ genShake(0x1f, 136, 32, /* @__PURE__ */ oidNist(0x0c));
5644
+
5645
+ /**
5646
+ * Experimental implementation of NTT / FFT (Fast Fourier Transform) over finite fields.
5647
+ * API may change at any time. The code has not been audited. Feature requests are welcome.
5648
+ * @module
5649
+ */
5650
+ function checkU32(n, title = 'n') {
5651
+ // 0xff_ff_ff_ff
5652
+ if (typeof n !== 'number')
5653
+ throw new TypeError(`wrong u32 integer "${title}": expected number, got type=${typeof n}`);
5654
+ if (!Number.isSafeInteger(n) || n < 0 || n > 0xffffffff)
5655
+ throw new RangeError(`wrong u32 integer "${title}": expected 0..4294967295, got ${n}`);
5656
+ return n;
5657
+ }
5658
+ /**
5659
+ * Checks if integer is in form of `1 << X`.
5660
+ * @param x - Integer to inspect.
5661
+ * @returns `true` when the value is a power of two.
5662
+ * @example
5663
+ * Validate that an FFT size is a power of two.
5664
+ *
5665
+ * ```ts
5666
+ * isPowerOfTwo(8);
5667
+ * ```
5668
+ */
5669
+ function isPowerOfTwo(x) {
5670
+ checkU32(x, 'x');
5671
+ return (x & (x - 1)) === 0 && x !== 0;
5672
+ }
5673
+ /**
5674
+ * @param n - Value to reverse.
5675
+ * @param bits - Number of bits to use.
5676
+ * @returns Bit-reversed integer.
5677
+ * @throws If `n` is not a valid unsigned 32-bit integer. {@link Error}
5678
+ * @example
5679
+ * Reverse the low `bits` bits of one index.
5680
+ *
5681
+ * ```ts
5682
+ * reverseBits(3, 3);
5683
+ * ```
5684
+ */
5685
+ function reverseBits(n, bits) {
5686
+ checkU32(n);
5687
+ if (typeof bits !== 'number')
5688
+ throw new TypeError('"bits" expected number, got type=' + typeof bits);
5689
+ if (!Number.isSafeInteger(bits) || bits < 0 || bits > 32)
5690
+ throw new Error(`expected integer 0 <= bits <= 32, got ${bits}`);
5691
+ let reversed = 0;
5692
+ for (let i = 0; i < bits; i++, n >>>= 1)
5693
+ reversed = (reversed << 1) | (n & 1);
5694
+ // JS bitwise ops are signed i32; cast back so 32-bit reversals stay in the unsigned u32 domain.
5695
+ return reversed >>> 0;
5696
+ }
5697
+ /**
5698
+ * Similar to `bitLen(x)-1` but much faster for small integers, like indices.
5699
+ * @param n - Input value.
5700
+ * @returns Base-2 logarithm. For `n = 0`, the current implementation returns `-1`.
5701
+ * @example
5702
+ * Compute the radix-2 stage count for one transform size.
5703
+ *
5704
+ * ```ts
5705
+ * log2(8);
5706
+ * ```
5707
+ */
5708
+ function log2(n) {
5709
+ checkU32(n);
5710
+ return 31 - Math.clz32(n);
5711
+ }
5712
+ /**
5713
+ * Moves lowest bit to highest position, which at first step splits
5714
+ * array on even and odd indices, then it applied again to each part,
5715
+ * which is core of fft
5716
+ * @param values - Mutable coefficient array.
5717
+ * @returns Mutated input array.
5718
+ * @throws If the array length is not a positive power of two. {@link Error}
5719
+ * @example
5720
+ * Reorder coefficients into bit-reversed order in place.
5721
+ *
5722
+ * ```ts
5723
+ * const values = Uint8Array.from([0, 1, 2, 3]);
5724
+ * bitReversalInplace(values);
5725
+ * ```
5726
+ */
5727
+ function bitReversalInplace(values) {
5728
+ if (!values ||
5729
+ typeof values !== 'object' ||
5730
+ typeof values.length !== 'number')
5731
+ throw new TypeError('"values" expected array-like, got type=' + typeof values);
5732
+ const n = values.length;
5733
+ // Size-1 FFT is the identity, so bit-reversal must stay a no-op there instead of rejecting it.
5734
+ if (!isPowerOfTwo(n))
5735
+ throw new Error('expected positive power-of-two length, got ' + n);
5736
+ const bits = log2(n);
5737
+ for (let i = 0; i < n; i++) {
5738
+ const j = reverseBits(i, bits);
5739
+ if (i < j) {
5740
+ const tmp = values[i];
5741
+ values[i] = values[j];
5742
+ values[j] = tmp;
5743
+ }
5744
+ }
5745
+ return values;
5746
+ }
5747
+ /**
5748
+ * Constructs different flavors of FFT. radix2 implementation of low level mutating API. Flavors:
5749
+ *
5750
+ * - DIT (Decimation-in-Time): Bottom-Up (leaves to root), Cooley-Tukey
5751
+ * - DIF (Decimation-in-Frequency): Top-Down (root to leaves), Gentleman-Sande
5752
+ *
5753
+ * DIT takes brp input, returns natural output.
5754
+ * DIF takes natural input, returns brp output.
5755
+ *
5756
+ * The output is actually identical. Time / frequence distinction is not meaningful
5757
+ * for Polynomial multiplication in fields.
5758
+ * Which means if protocol supports/needs brp output/inputs, then we can skip this step.
5759
+ *
5760
+ * Cyclic NTT: Rq = Zq[x]/(x^n-1). butterfly_DIT+loop_DIT OR butterfly_DIF+loop_DIT, roots are omega
5761
+ * Negacyclic NTT: Rq = Zq[x]/(x^n+1). butterfly_DIT+loop_DIF, at least for mlkem / mldsa
5762
+ *
5763
+ * `invertButterflies` indexes roots by a per-butterfly-group counter (`grp`): forward
5764
+ * (`dit: false`) reads `roots[grp]` with grp = 1..; inverse (`dit: true`) reads `roots[N - grp]`
5765
+ * with grp restarting at 1. With `skipStages: 0` one table serves both directions (ωᴺ = 1 makes
5766
+ * the reversed walk self-inverse). With `skipStages > 0` the inverse walk starts at `N - 1`
5767
+ * instead of continuing where the skipped stages would have left off, so the caller must supply
5768
+ * a table shaped for that (ML-KEM: `ζ^BitRev7(i)` over all N=256 indices, whose aliased upper
5769
+ * half is exactly the FIPS 203 inverse walk).
5770
+ * @param F - Field operations.
5771
+ * @param coreOpts - FFT configuration. See {@link FFTCoreOpts}:
5772
+ * - `N`: Transform size. Must be a power of two.
5773
+ * - `roots`: Stage roots for the selected transform size.
5774
+ * - `dit`: Whether to run the DIT variant instead of DIF.
5775
+ * - `invertButterflies` (optional): Whether to invert butterfly placement.
5776
+ * - `skipStages` (optional): Number of initial stages to skip.
5777
+ * - `brp` (optional): Whether to apply bit-reversal permutation at the boundary.
5778
+ * @returns Low-level FFT loop.
5779
+ * @throws If the FFT options or cached roots are invalid for the requested size. {@link Error}
5780
+ * @example
5781
+ * Constructs different flavors of FFT.
5782
+ *
5783
+ * ```ts
5784
+ * import { FFTCore, rootsOfUnity } from '@noble/curves/abstract/fft.js';
5785
+ * import { Field } from '@noble/curves/abstract/modular.js';
5786
+ * const Fp = Field(17n);
5787
+ * const roots = rootsOfUnity(Fp).roots(2);
5788
+ * const loop = FFTCore(Fp, { N: 4, roots, dit: true });
5789
+ * const values = loop([1n, 2n, 3n, 4n]);
5790
+ * ```
5791
+ */
5792
+ const FFTCore = (F, coreOpts) => {
5793
+ validateObject(coreOpts, { N: 'number', roots: 'object', dit: 'boolean' }, { invertButterflies: 'boolean', skipStages: 'number', brp: 'boolean' }, 'coreOpts');
5794
+ const { N, roots, dit, invertButterflies = false, skipStages = 0, brp = true } = coreOpts;
5795
+ checkU32(N, 'coreOpts.N');
5796
+ const bits = log2(N);
5797
+ if (!isPowerOfTwo(N))
5798
+ throw new Error('FFT: Polynomial size should be power of two');
5799
+ checkU32(skipStages, 'coreOpts.skipStages');
5800
+ const maxSkipStages = bits === 0 ? 0 : bits - 1;
5801
+ // Skipping every stage leaves only boundary layout changes, not a valid FFT loop shape.
5802
+ if (skipStages > maxSkipStages)
5803
+ throw new Error(`FFT: wrong skipStages: expected 0 <= skipStages <= ${maxSkipStages}`);
5804
+ // Wrong-sized root tables can stay in-bounds for some loop shapes and silently compute nonsense.
5805
+ if (roots.length !== N)
5806
+ throw new Error(`FFT: wrong roots length: expected ${N}, got ${roots.length}`);
5807
+ const isDit = dit !== invertButterflies;
5808
+ return (values) => {
5809
+ if (values.length !== N)
5810
+ throw new Error('FFT: wrong Polynomial length');
5811
+ if (dit && brp)
5812
+ bitReversalInplace(values);
5813
+ for (let i = 0, g = 1; i < bits - skipStages; i++) {
5814
+ // For each stage s (sub-FFT length m = 2^s)
5815
+ const s = dit ? i + 1 + skipStages : bits - i;
5816
+ const m = 1 << s;
5817
+ const m2 = m >> 1;
5818
+ const stride = N >> s;
5819
+ // Loop over each subarray of length m
5820
+ for (let k = 0; k < N; k += m) {
5821
+ // Loop over each butterfly within the subarray
5822
+ for (let j = 0, grp = g++; j < m2; j++) {
5823
+ const rootPos = invertButterflies ? (dit ? N - grp : grp) : j * stride;
5824
+ const i0 = k + j;
5825
+ const i1 = k + j + m2;
5826
+ const omega = roots[rootPos];
5827
+ const b = values[i1];
5828
+ const a = values[i0];
5829
+ // Inlining gives us 10% perf in kyber vs functions
5830
+ if (isDit) {
5831
+ const t = F.mul(b, omega); // Standard DIT butterfly
5832
+ values[i0] = F.add(a, t);
5833
+ values[i1] = F.sub(a, t);
5834
+ }
5835
+ else if (invertButterflies) {
5836
+ values[i0] = F.add(b, a); // DIT loop + inverted butterflies (Kyber decode)
5837
+ values[i1] = F.mul(F.sub(b, a), omega);
5838
+ }
5839
+ else {
5840
+ values[i0] = F.add(a, b); // Standard DIF butterfly
5841
+ values[i1] = F.mul(F.sub(a, b), omega);
5842
+ }
5843
+ }
5844
+ }
5845
+ }
5846
+ if (!dit && brp)
5847
+ bitReversalInplace(values);
5848
+ return values;
5849
+ };
5850
+ };
5851
+
5852
+ /**
5853
+ * Utilities for hex, bytearray and number handling.
5854
+ * @module
5855
+ */
5856
+ /*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */
5857
+ /**
5858
+ * Asserts that a value is a byte array and optionally checks its length.
5859
+ * Returns the original reference unchanged on success, and currently also accepts Node `Buffer`
5860
+ * values through the upstream validator.
5861
+ * This helper throws on malformed input, so APIs that must return `false` need to guard lengths
5862
+ * before decoding or before calling it.
5863
+ * @example
5864
+ * Validate that a value is a byte array with the expected length.
5865
+ * ```ts
5866
+ * abytes(new Uint8Array([1]), 1);
5867
+ * ```
5868
+ */
5869
+ const abytesDoc = abytes;
5870
+ /**
5871
+ * Returns cryptographically secure random bytes.
5872
+ * Requires `globalThis.crypto.getRandomValues` and throws if that API is unavailable.
5873
+ * `bytesLength` is validated by the upstream helper as a non-negative integer before allocation,
5874
+ * so negative and fractional values both throw instead of truncating through JS `ToIndex`.
5875
+ * @param bytesLength - Number of random bytes to generate.
5876
+ * @returns Fresh random bytes.
5877
+ * @example
5878
+ * Generate a fresh random seed.
5879
+ * ```ts
5880
+ * const seed = randomBytes(4);
5881
+ * ```
5882
+ */
5883
+ const randomBytes = randomBytes$1;
5884
+ function aarray(item, title, inner = () => { }) {
5885
+ if (!Array.isArray(item))
5886
+ throw new TypeError(`"${title}" expected array, got type=${typeof item}`);
5887
+ for (let i = 0; i < item.length; i++)
5888
+ inner(item[i], `${title}[${i}]`);
5889
+ return item;
5890
+ }
5891
+ function aobject(value, title = 'object') {
5892
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
5893
+ throw new TypeError(title === 'object'
5894
+ ? 'expected valid options object'
5895
+ : `"${title}" expected object, got type=${typeof value}`);
5896
+ return value;
5897
+ }
5898
+ /**
5899
+ * Compares two byte arrays in a length-constant way for equal lengths.
5900
+ * Inputs are validated as byte arrays; unequal lengths return `false` immediately.
5901
+ * @param a - First byte array.
5902
+ * @param b - Second byte array.
5903
+ * @returns Whether both arrays contain the same bytes.
5904
+ * @example
5905
+ * Compare two byte arrays for equality.
5906
+ * ```ts
5907
+ * equalBytes(new Uint8Array([1]), new Uint8Array([1]));
5908
+ * ```
5909
+ */
5910
+ function equalBytes(a, b) {
5911
+ a = abytes(a);
5912
+ b = abytes(b);
5913
+ if (a.length !== b.length)
5914
+ return false;
5915
+ let diff = 0;
5916
+ for (let i = 0; i < a.length; i++)
5917
+ diff |= a[i] ^ b[i];
5918
+ return diff === 0;
5919
+ }
5920
+ /**
5921
+ * Validates that an options bag is a plain object.
5922
+ * @param opts - Options object to validate.
5923
+ * @throws On wrong argument types. {@link TypeError}
5924
+ * @example
5925
+ * Validate that an options bag is a plain object.
5926
+ * ```ts
5927
+ * validateOpts({});
5928
+ * ```
5929
+ */
5930
+ function validateOpts(opts) {
5931
+ // Arrays silently passed here before, but these call sites expect named option-bag fields.
5932
+ if (isBytes(opts))
5933
+ throw new TypeError('"opts" expected object, got Uint8Array');
5934
+ aobject(opts, 'opts');
5935
+ const proto = Object.getPrototypeOf(opts);
5936
+ // Options are security parameters, not general class instances. Restricting the bag to own
5937
+ // properties prevents values injected through Object.prototype (or a custom shared prototype)
5938
+ // from silently changing signing behavior. Null-prototype records remain supported.
5939
+ if (proto !== null && proto !== Object.prototype)
5940
+ throw new TypeError('"opts" expected a plain object');
5941
+ }
5942
+ // Frozen because they are exported: an unfrozen array export lets anything in the
5943
+ // process push a key onto the accepted set and silently re-open exactly the hole this
5944
+ // validation closes.
5945
+ /** Keys accepted by `verify`. */
5946
+ const VER_OPT_KEYS = /* @__PURE__ */ Object.freeze([
5947
+ 'context',
5948
+ ]);
5949
+ /** Keys accepted by `sign`. */
5950
+ const SIG_OPT_KEYS = /* @__PURE__ */ Object.freeze([
5951
+ 'context',
5952
+ 'extraEntropy',
5953
+ ]);
5954
+ /**
5955
+ * Rejects option keys the caller did not mean to set.
5956
+ *
5957
+ * Validating the types of known keys while ignoring unknown ones makes a typo
5958
+ * indistinguishable from an omission, and for these options an omission is a
5959
+ * security downgrade rather than a no-op: `{ ctx }` instead of `{ context }` signs
5960
+ * with no domain separation, succeeds, and verifies for anyone who also supplies
5961
+ * none. Nothing at any layer reports it. TypeScript catches this through excess
5962
+ * property checks, so the exposure is JavaScript callers specifically.
5963
+ *
5964
+ * @param opts - Options object to check.
5965
+ * @param allowed - The keys this call site accepts.
5966
+ * Returns a frozen null-prototype snapshot so later reads cannot fall through to a polluted
5967
+ * prototype. Like `checkOpts()` in noble-hashes, only enumerable own properties are copied.
5968
+ * @throws If any other copied key is present or the bag has a custom prototype. {@link TypeError}
5969
+ * @returns Sanitized snapshot of the enumerable own options.
5970
+ * @example
5971
+ * Accept a known option key. A key the list does not name, such as `ctx`, throws instead.
5972
+ * ```ts
5973
+ * import { checkOptKeys } from '@noble/post-quantum/utils.js';
5974
+ * checkOptKeys({ context: new Uint8Array() }, ['context']);
5975
+ * ```
5976
+ */
5977
+ function checkOptKeys(opts, allowed) {
5978
+ validateOpts(opts);
5979
+ // Snapshot once before validation: Object.assign follows the same own-enumerable option-bag
5980
+ // semantics as noble-hashes, while the null prototype keeps omitted fields immune to pollution.
5981
+ const normalized = Object.assign(Object.create(null), opts);
5982
+ for (const [k, v] of Object.entries(normalized)) {
5983
+ // `undefined` means unset everywhere else in these validators, and building an options bag by
5984
+ // spread is a normal way to reach these calls, so present-but-undefined stays equivalent to
5985
+ // omission.
5986
+ if (v === undefined)
5987
+ continue;
5988
+ if (!allowed.includes(k))
5989
+ throw new TypeError('unexpected option "' + String(k) + '"; expected one of: ' + allowed.join(', '));
5990
+ }
5991
+ return Object.freeze(normalized);
5992
+ }
5993
+ /**
5994
+ * Validates common verification options.
5995
+ * `context` itself is validated with `abytes(...)`, and individual algorithms may narrow support
5996
+ * further after this shared plain-object gate.
5997
+ * @param opts - Verification options. See {@link VerOpts}.
5998
+ * @param allowed - Keys this call site accepts. Defaults to {@link VER_OPT_KEYS}; surfaces that
5999
+ * take extra keys, or take fewer, pass their own list.
6000
+ * @throws On wrong argument types. {@link TypeError}
6001
+ * @returns Frozen null-prototype snapshot of the validated options.
6002
+ * @example
6003
+ * Validate common verification options.
6004
+ * ```ts
6005
+ * validateVerOpts({ context: new Uint8Array([1]) });
6006
+ * ```
6007
+ */
6008
+ function validateVerOpts(opts, allowed = VER_OPT_KEYS) {
6009
+ const normalized = checkOptKeys(opts, allowed);
6010
+ if (normalized.context !== undefined)
6011
+ abytes(normalized.context, undefined, 'opts.context');
6012
+ return normalized;
6013
+ }
6014
+ /**
6015
+ * Validates common signing options.
6016
+ * `extraEntropy` is validated with `abytes(...)`; exact lengths and extra algorithm-specific
6017
+ * restrictions are enforced later by callers.
6018
+ * @param opts - Signing options. See {@link SigOpts}.
6019
+ * @param allowed - Keys this call site accepts. Defaults to {@link SIG_OPT_KEYS}; surfaces that
6020
+ * take extra keys, or take fewer, pass their own list.
6021
+ * @throws On wrong argument types. {@link TypeError}
6022
+ * @returns Frozen null-prototype snapshot of the validated options.
6023
+ * @example
6024
+ * Validate common signing options.
6025
+ * ```ts
6026
+ * validateSigOpts({ extraEntropy: new Uint8Array([1]) });
6027
+ * ```
6028
+ */
6029
+ function validateSigOpts(opts, allowed = SIG_OPT_KEYS) {
6030
+ const normalized = checkOptKeys(opts, allowed);
6031
+ if (normalized.context !== undefined)
6032
+ abytes(normalized.context, undefined, 'opts.context');
6033
+ if (normalized.extraEntropy !== false && normalized.extraEntropy !== undefined)
6034
+ abytes(normalized.extraEntropy, undefined, 'opts.extraEntropy');
6035
+ return normalized;
6036
+ }
6037
+ /**
6038
+ * Builds a fixed-layout coder from byte lengths and nested coders.
6039
+ * Raw-length fields decode as zero-copy `subarray(...)` views, and nested coders may preserve that
6040
+ * aliasing too. Nested coder `encode(...)` results are treated as owned scratch: `splitCoder`
6041
+ * copies them into the output and then zeroizes them with `fill(0)`. If a nested encoder forwards
6042
+ * caller-owned bytes, it must do so only after detaching them into a disposable copy.
6043
+ * @param label - Label used in validation errors.
6044
+ * @param lengths - Field lengths or nested coders.
6045
+ * @returns Composite fixed-length coder.
6046
+ * @example
6047
+ * Build a fixed-layout coder from byte lengths and nested coders.
6048
+ * ```ts
6049
+ * splitCoder('demo', 1, 2).encode([new Uint8Array([1]), new Uint8Array([2, 3])]);
6050
+ * ```
6051
+ */
6052
+ function splitCoder(label, ...lengths) {
6053
+ const getLength = (c) => typeof c === 'number' ? c : c.bytesLen;
6054
+ const bytesLen = lengths.reduce((sum, a) => sum + getLength(a), 0);
6055
+ return {
6056
+ bytesLen,
6057
+ encode: (bufs) => {
6058
+ const res = new Uint8Array(bytesLen);
6059
+ for (let i = 0, pos = 0; i < lengths.length; i++) {
6060
+ const c = lengths[i];
6061
+ const l = getLength(c);
6062
+ const b = typeof c === 'number' ? bufs[i] : c.encode(bufs[i]);
6063
+ abytes(b, l, label);
6064
+ res.set(b, pos);
6065
+ if (typeof c !== 'number')
6066
+ b.fill(0); // clean
6067
+ pos += l;
6068
+ }
6069
+ return res;
6070
+ },
6071
+ decode: (buf) => {
6072
+ abytes(buf, bytesLen, label);
6073
+ const res = [];
6074
+ for (const c of lengths) {
6075
+ const l = getLength(c);
6076
+ const b = buf.subarray(0, l);
6077
+ res.push(typeof c === 'number' ? b : c.decode(b));
6078
+ buf = buf.subarray(l);
6079
+ }
6080
+ return res;
6081
+ },
6082
+ };
6083
+ }
6084
+ // nano-packed.array (fixed size)
6085
+ /**
6086
+ * Builds a fixed-length vector coder from another fixed-length coder.
6087
+ * Element decoding receives `subarray(...)` views, so aliasing depends on the element coder.
6088
+ * Element coder `encode(...)` results are treated as owned scratch: `vecCoder` copies them into
6089
+ * the output and then zeroizes them with `fill(0)`. If an element encoder forwards caller-owned
6090
+ * bytes, it must do so only after detaching them into a disposable copy. `vecCoder` also trusts
6091
+ * the `BytesCoderLen` contract: each encoded element must already be exactly `c.bytesLen` bytes.
6092
+ * @param c - Element coder.
6093
+ * @param vecLen - Number of elements in the vector.
6094
+ * @returns Fixed-length vector coder.
6095
+ * @example
6096
+ * Build a fixed-length vector coder from another fixed-length coder.
6097
+ * ```ts
6098
+ * vecCoder(
6099
+ * { bytesLen: 1, encode: (n: number) => Uint8Array.of(n), decode: (b: Uint8Array) => b[0] || 0 },
6100
+ * 2
6101
+ * ).encode([1, 2]);
6102
+ * ```
6103
+ */
6104
+ function vecCoder(c, vecLen) {
6105
+ const coder = c;
6106
+ const bytesLen = vecLen * coder.bytesLen;
6107
+ return {
6108
+ bytesLen,
6109
+ encode: (u) => {
6110
+ const uArr = aarray(u, 'u');
6111
+ if (uArr.length !== vecLen)
6112
+ throw new RangeError(`vecCoder.encode: wrong length=${uArr.length}. Expected: ${vecLen}`);
6113
+ const res = new Uint8Array(bytesLen);
6114
+ for (let i = 0, pos = 0; i < uArr.length; i++) {
6115
+ const b = coder.encode(uArr[i]);
6116
+ res.set(b, pos);
6117
+ b.fill(0); // clean
6118
+ pos += b.length;
6119
+ }
6120
+ return res;
6121
+ },
6122
+ decode: (a) => {
6123
+ abytes(a, bytesLen);
6124
+ const r = [];
6125
+ for (let i = 0; i < a.length; i += coder.bytesLen)
6126
+ r.push(coder.decode(a.subarray(i, i + coder.bytesLen)));
6127
+ return r;
6128
+ },
6129
+ };
6130
+ }
6131
+ /**
6132
+ * Overwrites supported typed-array inputs with zeroes in place.
6133
+ * Accepts direct typed arrays and one-level arrays of them.
6134
+ * @param list - Typed arrays or one-level lists of typed arrays to clear.
6135
+ * @example
6136
+ * Overwrite typed arrays with zeroes.
6137
+ * ```ts
6138
+ * const buf = Uint8Array.of(1, 2, 3);
6139
+ * cleanBytes(buf);
6140
+ * ```
6141
+ */
6142
+ function cleanBytes(...list) {
6143
+ for (const t of list) {
6144
+ if (Array.isArray(t))
6145
+ for (const b of t)
6146
+ b.fill(0);
6147
+ else
6148
+ t.fill(0);
6149
+ }
6150
+ }
6151
+ /**
6152
+ * Creates a 32-bit mask with the lowest `bits` bits set.
6153
+ * @param bits - Number of low bits to keep.
6154
+ * @returns Bit mask with `bits` ones.
6155
+ * @throws On wrong argument types. {@link TypeError}
6156
+ * @throws On wrong argument ranges or values. {@link RangeError}
6157
+ * @example
6158
+ * Create a low-bit mask for packed-field operations.
6159
+ * ```ts
6160
+ * const mask = getMask(4);
6161
+ * ```
6162
+ */
6163
+ function getMask(bits) {
6164
+ anumber(bits, 'bits');
6165
+ if (bits > 32)
6166
+ throw new RangeError('"bits" expected <= 32, got ' + bits);
6167
+ // JS shifts are modulo 32, so bit 32 needs an explicit full-width mask.
6168
+ return bits === 32 ? 0xffffffff : ~(-1 << bits) >>> 0;
6169
+ }
6170
+ /** Shared empty byte array used as the default context. */
6171
+ const EMPTY = /* @__PURE__ */ Uint8Array.of();
6172
+ /**
6173
+ * Builds the domain-separated message payload for the pure sign/verify paths.
6174
+ * Context length `255` is valid; only `ctx.length > 255` is rejected.
6175
+ * @param msg - Message bytes.
6176
+ * @param ctx - Optional context bytes.
6177
+ * @returns Domain-separated message payload.
6178
+ * @throws On wrong argument ranges or values. {@link RangeError}
6179
+ * @example
6180
+ * Build the domain-separated payload before direct signing.
6181
+ * ```ts
6182
+ * const payload = getMessage(new Uint8Array([1, 2]));
6183
+ * ```
6184
+ */
6185
+ function getMessage(msg, ctx = EMPTY) {
6186
+ abytes(msg, undefined, 'msg');
6187
+ abytes(ctx, undefined, 'ctx');
6188
+ if (ctx.length > 255)
6189
+ throw new RangeError('context should be 255 bytes or less');
6190
+ return concatBytes(new Uint8Array([0, ctx.length]), ctx, msg);
6191
+ }
6192
+ // DER tag+length plus the shared NIST hash OID arc 2.16.840.1.101.3.4.2.* used by the
6193
+ // FIPS 204 / FIPS 205 pre-hash wrappers; the final byte selects SHA-256, SHA-512, SHAKE128,
6194
+ // SHAKE256, or another approved hash/XOF under that subtree.
6195
+ // 06 09 60 86 48 01 65 03 04 02
6196
+ const oidNistP = /* @__PURE__ */ Uint8Array.from([6, 9, 0x60, 0x86, 0x48, 1, 0x65, 3, 4, 2]);
6197
+ /**
6198
+ * Output length, in bytes, that each XOF OID under this arc denotes.
6199
+ *
6200
+ * Unlike a fixed hash, an XOF's OID is a promise about the digest length: RFC 8702
6201
+ * defines id-shake128 as SHAKE128 with 256-bit output and id-shake256 as SHAKE256 with
6202
+ * 512-bit output, and FIPS 204 / FIPS 205 use exactly those pairings for pre-hash. Both
6203
+ * bare noble-hashes defaults are half these values, so neither can be signed under its
6204
+ * own OID.
6205
+ */
6206
+ const XOF_OID_OUTPUT_LEN = /* @__PURE__ */ (() => ({
6207
+ '060960864801650304020b': 32, // id-shake128, SHAKE128(M, 256)
6208
+ '060960864801650304020c': 64, // id-shake256, SHAKE256(M, 512)
6209
+ }))();
6210
+ /**
6211
+ * Validates that a hash exposes a NIST hash OID and enough collision resistance.
6212
+ * Current accepted surface is broader than the FIPS algorithm tables: any hash/XOF under the NIST
6213
+ * `2.16.840.1.101.3.4.2.*` subtree is accepted if its effective `outputLen` is strong enough.
6214
+ * XOF callers must pass a callable whose `outputLen` matches the digest length they actually intend
6215
+ * to sign; bare `shake128` / `shake256` defaults are too short for the stronger prehash modes.
6216
+ * @param hash - Hash function to validate.
6217
+ * @param requiredStrength - Minimum required collision-resistance strength in bits.
6218
+ * @throws If the hash metadata or collision resistance is insufficient. {@link Error}
6219
+ * @example
6220
+ * Validate that a hash exposes a NIST hash OID and enough collision resistance.
6221
+ * ```ts
6222
+ * import { sha256 } from '@noble/hashes/sha2.js';
6223
+ * import { checkHash } from '@noble/post-quantum/utils.js';
6224
+ * checkHash(sha256, 128);
6225
+ * ```
6226
+ */
6227
+ function checkHash(hash, requiredStrength = 0) {
6228
+ if (typeof hash !== 'function' || typeof hash.create !== 'function')
6229
+ throw new TypeError('"hash" expected hash function, got type=' + typeof hash);
6230
+ ahash(hash);
6231
+ anumber(requiredStrength, 'requiredStrength');
6232
+ const oid = hash.oid;
6233
+ abytes(oid, undefined, 'hash.oid');
6234
+ if (!equalBytes(oid.subarray(0, 10), oidNistP))
6235
+ throw new Error('"hash.oid" is invalid: expected NIST hash');
6236
+ // FIPS 204 / FIPS 205 require both collision and second-preimage strength; for approved NIST
6237
+ // hashes/XOFs under this OID subtree, the collision bound from the configured digest length is
6238
+ // the tighter runtime check, so enforce that lower bound here.
6239
+ // XOFs under this arc are identified by an OID that fixes their output length:
6240
+ // FIPS 204 §5.4.1 (SHAKE128) and FIPS 205 §10.2.2 (both SHAKEs), matching RFC 8702, pair
6241
+ // id-shake128 with SHAKE128(M, 256) and id-shake256 with SHAKE256(M, 512). getMessagePrehash embeds
6242
+ // hash.oid beside hash(msg), so a shorter digest signs an M' that claims a length
6243
+ // it does not have: noble-hashes' bare shake256 defaults to 32 bytes and cleared
6244
+ // the collision bound at the 128-bit level, producing signatures a conformant
6245
+ // verifier rejects because it recomputes 512 bits. Check the length the OID
6246
+ // denotes rather than the generic bound.
6247
+ const xofLen = XOF_OID_OUTPUT_LEN[bytesToHex(oid)];
6248
+ if (xofLen !== undefined && hash.outputLen !== xofLen) {
6249
+ throw new Error('Pre-hash XOF output length must be ' + xofLen + ' bytes for this OID, got: ' + hash.outputLen);
6250
+ }
6251
+ const collisionResistance = (hash.outputLen * 8) / 2;
6252
+ if (requiredStrength > collisionResistance) {
6253
+ throw new Error('Pre-hash security strength too low: ' +
6254
+ collisionResistance +
6255
+ ', required: ' +
6256
+ requiredStrength);
6257
+ }
6258
+ }
6259
+ /**
6260
+ * Builds the domain-separated prehash payload for the prehash sign/verify paths.
6261
+ * Callers are expected to vet `hash.oid` first, e.g. via `checkHash(...)`; calling this helper
6262
+ * directly with a hash object that lacks `oid` currently throws later inside `concatBytes(...)`.
6263
+ * Context length `255` is valid; only `ctx.length > 255` is rejected.
6264
+ * @param hash - Prehash function.
6265
+ * @param msg - Message bytes.
6266
+ * @param ctx - Optional context bytes.
6267
+ * @returns Domain-separated prehash payload.
6268
+ * @throws On wrong argument ranges or values. {@link RangeError}
6269
+ * @example
6270
+ * Build the domain-separated prehash payload for external hashing.
6271
+ * ```ts
6272
+ * import { sha256 } from '@noble/hashes/sha2.js';
6273
+ * import { getMessagePrehash } from '@noble/post-quantum/utils.js';
6274
+ * getMessagePrehash(sha256, new Uint8Array([1, 2]));
6275
+ * ```
6276
+ */
6277
+ function getMessagePrehash(hash, msg, ctx = EMPTY) {
6278
+ checkHash(hash);
6279
+ abytes(msg, undefined, 'msg');
6280
+ abytes(ctx, undefined, 'ctx');
6281
+ if (ctx.length > 255)
6282
+ throw new RangeError('context should be 255 bytes or less');
6283
+ const hashed = hash(msg);
6284
+ return concatBytes(new Uint8Array([1, ctx.length]), ctx, hash.oid, hashed);
6285
+ }
6286
+
6287
+ /**
6288
+ * Internal methods for lattice-based ML-KEM and ML-DSA.
6289
+ * @module
6290
+ */
6291
+ /*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */
6292
+ /**
6293
+ * Creates shared modular arithmetic, NTT, and packing helpers for CRYSTALS schemes.
6294
+ * @param opts - Polynomial and transform parameters. See {@link CrystalOpts}.
6295
+ * @returns CRYSTALS arithmetic and encoding helpers.
6296
+ * @example
6297
+ * Create shared modular arithmetic and NTT helpers for a CRYSTALS parameter set.
6298
+ * ```ts
6299
+ * const crystals = genCrystals({
6300
+ * newPoly: (n) => new Uint16Array(n),
6301
+ * N: 256,
6302
+ * Q: 3329,
6303
+ * F: 3303,
6304
+ * ROOT_OF_UNITY: 17,
6305
+ * brvBits: 7,
6306
+ * isKyber: true,
6307
+ * });
6308
+ * const reduced = crystals.mod(-1);
6309
+ * ```
6310
+ */
6311
+ const genCrystals = (opts) => {
6312
+ // isKyber: true means Kyber, false means Dilithium
6313
+ const { newPoly, N, Q, F, ROOT_OF_UNITY, brvBits} = opts;
6314
+ // Normalize JS `%` into the canonical Z_m representative `[0, modulo-1]` expected by
6315
+ // FIPS 203 §2.3 / FIPS 204 §2.3 before downstream mod-q arithmetic.
6316
+ const mod = (a, modulo = Q) => {
6317
+ const result = (a % modulo) | 0;
6318
+ return (result >= 0 ? result | 0 : (modulo + result) | 0) | 0;
6319
+ };
6320
+ // FIPS 204 §7.4 uses the centered `mod ±` representative for low bits, keeping the
6321
+ // positive midpoint when `modulo` is even.
6322
+ // Center to `[-floor((modulo-1)/2), floor(modulo/2)]`.
6323
+ const smod = (a, modulo = Q) => {
6324
+ const r = mod(a, modulo) | 0;
6325
+ return (r > modulo >> 1 ? (r - modulo) | 0 : r) | 0;
6326
+ };
6327
+ // Kyber uses the FIPS 203 Appendix A `BitRev_7` table here via the first 128 entries, while
6328
+ // Dilithium uses the FIPS 204 §7.5 / Appendix B `BitRev_8` zetas table over all 256 entries.
6329
+ function getZettas() {
6330
+ const out = newPoly(N);
6331
+ for (let i = 0; i < N; i++) {
6332
+ const b = reverseBits(i, brvBits);
6333
+ const p = BigInt(ROOT_OF_UNITY) ** BigInt(b) % BigInt(Q);
6334
+ out[i] = Number(p) | 0;
6335
+ }
6336
+ return out;
6337
+ }
6338
+ const nttZetas = getZettas();
6339
+ // Number-Theoretic Transform
6340
+ // Explained: https://electricdusk.com/ntt.html
6341
+ // Kyber has slightly different params, since there is no 512th primitive root of unity mod q,
6342
+ // only 256th primitive root of unity mod. Which also complicates MultiplyNTT.
6343
+ const inv = (_a) => {
6344
+ throw new Error('not implemented');
6345
+ };
6346
+ // ML-KEM (Kyber) polynomials always enter the transform reduced to [0, Q), so add/sub only
6347
+ // need one conditional correction instead of `%`; measured ~20% faster NTT there.
6348
+ // ML-DSA keeps the generic mod() path on purpose: its first forward stage sees centered
6349
+ // (negative) coefficients, and `sub(a, t)` can drop below -Q (t is a mul output in [0, Q)),
6350
+ // so a single correction is not enough. A guarded fast path with mod() fallback was measured
6351
+ // slower than plain `%` for the 23-bit Q (V8 int32 modulo is one div; the branches lose).
6352
+ const field = {
6353
+ add: (a, b) => mod((a | 0) + (b | 0)) | 0,
6354
+ sub: (a, b) => mod((a | 0) - (b | 0)) | 0,
6355
+ mul: (a, b) => mod((a | 0) * (b | 0)) | 0,
6356
+ inv,
6357
+ };
6358
+ const nttOpts = {
6359
+ N,
6360
+ roots: nttZetas,
6361
+ invertButterflies: true,
6362
+ skipStages: 0,
6363
+ brp: false,
6364
+ };
6365
+ const dif = FFTCore(field, { dit: false, ...nttOpts });
6366
+ const dit = FFTCore(field, { dit: true, ...nttOpts });
6367
+ const NTT = {
6368
+ encode: (r) => {
6369
+ return dif(r);
6370
+ },
6371
+ decode: (r) => {
6372
+ dit(r);
6373
+ // The inverse-NTT normalization factor is family-specific: FIPS 203 Algorithm 10 line 14
6374
+ // uses `128^-1 mod q` for Kyber, while FIPS 204 Algorithm 42 lines 21-23 use `256^-1 mod q`.
6375
+ // kyber uses 128 here, because brv && stuff
6376
+ for (let i = 0; i < r.length; i++)
6377
+ r[i] = mod(F * r[i]);
6378
+ return r;
6379
+ },
6380
+ };
6381
+ // Pack one little-endian `d`-bit word per coefficient, matching FIPS 203 ByteEncode /
6382
+ // ByteDecode and the FIPS 204 BitsToBytes-based polynomial packing helpers.
6383
+ const bitsCoder = (d, c) => {
6384
+ // Validate the carry shape once: JS bitwise operations silently truncate wider accumulators.
6385
+ for (let i = 0, bufLen = 0; i < N; i++) {
6386
+ bufLen += d;
6387
+ if (bufLen > 32)
6388
+ getMask(bufLen);
6389
+ bufLen %= 8;
6390
+ }
6391
+ const mask = getMask(d);
6392
+ const bytesLen = d * (N / 8);
6393
+ return {
6394
+ bytesLen,
6395
+ encode: (poly_) => {
6396
+ const poly = poly_;
6397
+ const r = new Uint8Array(bytesLen);
6398
+ for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < poly.length; i++) {
6399
+ buf |= (c.encode(poly[i]) & mask) << bufLen;
6400
+ bufLen += d;
6401
+ // Take the low byte directly: `& 0xff` matches the previous getMask(bufLen) result
6402
+ // after Uint8Array truncation, without a validated function call per output byte.
6403
+ for (; bufLen >= 8; bufLen -= 8, buf >>= 8)
6404
+ r[pos++] = buf & 0xff;
6405
+ }
6406
+ return r;
6407
+ },
6408
+ decode: (bytes) => {
6409
+ const r = newPoly(N);
6410
+ for (let i = 0, buf = 0, bufLen = 0, pos = 0; i < bytes.length; i++) {
6411
+ buf |= bytes[i] << bufLen;
6412
+ bufLen += 8;
6413
+ for (; bufLen >= d; bufLen -= d, buf >>= d)
6414
+ r[pos++] = c.decode(buf & mask);
6415
+ }
6416
+ return r;
6417
+ },
6418
+ };
6419
+ };
6420
+ return {
6421
+ mod,
6422
+ smod,
6423
+ nttZetas: nttZetas,
6424
+ NTT: {
6425
+ encode: (r) => NTT.encode(r),
6426
+ decode: (r) => NTT.decode(r),
6427
+ },
6428
+ bitsCoder: bitsCoder,
6429
+ };
6430
+ };
6431
+ const createXofShake = (shake) => (seed, blockLen) => {
6432
+ if (!blockLen)
6433
+ blockLen = shake.blockLen;
6434
+ // Optimizations that won't mater:
6435
+ // - cached seed update (two .update(), on start and on the end)
6436
+ // - another cache which cloned into working copy
6437
+ // Faster than multiple updates, since seed less than blockLen
6438
+ const _seed = new Uint8Array(seed.length + 2);
6439
+ _seed.set(seed);
6440
+ const seedLen = seed.length;
6441
+ const buf = new Uint8Array(blockLen); // == shake128.blockLen
6442
+ let h = shake.create({});
6443
+ let calls = 0;
6444
+ let xofs = 0;
6445
+ return {
6446
+ stats: () => ({ calls, xofs }),
6447
+ get: (x, y) => {
6448
+ // Rebind to `seed || x || y` so callers can implement the spec's per-coordinate
6449
+ // SHAKE inputs like `rho || j || i` and `rho || IntegerToBytes(counter, 2)`.
6450
+ _seed[seedLen + 0] = x;
6451
+ _seed[seedLen + 1] = y;
6452
+ h.destroy();
6453
+ h = shake.create({}).update(_seed);
6454
+ calls++;
6455
+ return () => {
6456
+ xofs++;
6457
+ return h.xofInto(buf);
6458
+ };
6459
+ },
6460
+ clean: () => {
6461
+ h.destroy();
6462
+ cleanBytes(buf, _seed);
6463
+ },
6464
+ };
6465
+ };
6466
+ /**
6467
+ * SHAKE128-based extendable-output reader factory used by ML-KEM.
6468
+ * `get(x, y)` selects one coordinate pair at a time; calling it again invalidates previously
6469
+ * returned readers, and each squeeze reuses one mutable internal output buffer.
6470
+ * @param seed - Seed bytes for the reader.
6471
+ * @param blockLen - Optional output block length.
6472
+ * @returns Stateful XOF reader.
6473
+ * @example
6474
+ * Build the ML-KEM SHAKE128 matrix expander and read one block.
6475
+ * ```ts
6476
+ * import { randomBytes } from '@noble/post-quantum/utils.js';
6477
+ * import { XOF128 } from '@noble/post-quantum/_crystals.js';
6478
+ * const reader = XOF128(randomBytes(32));
6479
+ * const block = reader.get(0, 0)();
6480
+ * ```
6481
+ */
6482
+ const XOF128 = /* @__PURE__ */ createXofShake(shake128);
6483
+ /**
6484
+ * SHAKE256-based extendable-output reader factory used by ML-DSA.
6485
+ * `get(x, y)` appends raw one-byte coordinates to the seed, invalidates previously returned
6486
+ * readers, and reuses one mutable internal output buffer for each squeeze.
6487
+ * @param seed - Seed bytes for the reader.
6488
+ * @param blockLen - Optional output block length.
6489
+ * @returns Stateful XOF reader.
6490
+ * @example
6491
+ * Build the ML-DSA SHAKE256 coefficient expander and read one block.
6492
+ * ```ts
6493
+ * import { randomBytes } from '@noble/post-quantum/utils.js';
6494
+ * import { XOF256 } from '@noble/post-quantum/_crystals.js';
6495
+ * const reader = XOF256(randomBytes(32));
6496
+ * const block = reader.get(0, 0)();
6497
+ * ```
6498
+ */
6499
+ const XOF256 = /* @__PURE__ */ createXofShake(shake256);
6500
+
6501
+ /**
6502
+ * ML-DSA: Module Lattice-based Digital Signature Algorithm from
6503
+ * [FIPS-204](https://csrc.nist.gov/pubs/fips/204/ipd). A.k.a. CRYSTALS-Dilithium.
6504
+ *
6505
+ * Has similar internals to ML-KEM, but their keys and params are different.
6506
+ * Check out [official site](https://www.pq-crystals.org/dilithium/index.shtml),
6507
+ * [repo](https://github.com/pq-crystals/dilithium).
6508
+ * @module
6509
+ */
6510
+ /*! noble-post-quantum - MIT License (c) 2024 Paul Miller (paulmillr.com) */
6511
+ /**
6512
+ * Keys each internal surface accepts.
6513
+ *
6514
+ * `context` is deliberately absent from both. The internal functions never read it: the
6515
+ * public wrappers consume it when they format `M'` and must not pass it down, because a
6516
+ * key that is accepted and then not acted on is the same silent downgrade this validation
6517
+ * exists to prevent. `externalMu` is the mirror case, existing here and rejected above.
6518
+ * `extraEntropy` is signing-only, so verification does not take it either.
6519
+ */
6520
+ const INTERNAL_SIG_OPT_KEYS = /* @__PURE__ */ Object.freeze([
6521
+ 'extraEntropy',
6522
+ 'externalMu',
6523
+ ]);
6524
+ const INTERNAL_VER_OPT_KEYS = /* @__PURE__ */ Object.freeze(['externalMu']);
6525
+ function validateInternalOpts(opts, allowed) {
6526
+ const normalized = checkOptKeys(opts, allowed);
6527
+ if (normalized.externalMu !== undefined)
6528
+ abool(normalized.externalMu, 'opts.externalMu');
6529
+ return normalized;
6530
+ }
6531
+ // Constants
6532
+ // FIPS 204 fixes ML-DSA over R = Z[X]/(X^256 + 1), so every polynomial has 256 coefficients.
6533
+ const N = 256;
6534
+ // 2**23 − 2**13 + 1, 23 bits: multiply will be 46. We have enough precision in JS to avoid bigints
6535
+ const Q = 8380417;
6536
+ // FIPS 204 §2.5 / Table 1 fixes zeta = 1753 as the 512th root of unity used by ML-DSA's NTT.
6537
+ const ROOT_OF_UNITY = 1753;
6538
+ // f = 256**−1 mod q, pow(256, -1, q) = 8347681 (python3)
6539
+ const F = 8347681;
6540
+ // FIPS 204 Table 1 / §7.4 fixes d = 13 dropped low bits for Power2Round on t.
6541
+ const D = 13;
6542
+ // FIPS 204 Table 1 fixes gamma2 to (q-1)/88 for ML-DSA-44 and (q-1)/32 for ML-DSA-65/87;
6543
+ // §7.4 then uses alpha = 2*gamma2 for Decompose / MakeHint / UseHint.
6544
+ // Dilithium is kinda parametrized over GAMMA2, but everything will break with any other value.
6545
+ const GAMMA2_1 = Math.floor((Q - 1) / 88) | 0;
6546
+ const GAMMA2_2 = Math.floor((Q - 1) / 32) | 0;
6547
+ /** Internal params for different versions of ML-DSA */
6548
+ // prettier-ignore
6549
+ /** Built-in ML-DSA parameter presets keyed by security categories `2/3/5`
6550
+ * for `ml_dsa44` / `ml_dsa65` / `ml_dsa87`.
6551
+ * This is only the Table 1 subset used directly here: `BETA = TAU * ETA` is derived later,
6552
+ * while `C_TILDE_BYTES`, `TR_BYTES`, `CRH_BYTES`, and `securityLevel` live in the preset wrappers.
6553
+ */
6554
+ const PARAMS = /* @__PURE__ */ (() => Object.freeze({
6555
+ 2: Object.freeze({
6556
+ K: 4, L: 4, D, GAMMA1: 2 ** 17, GAMMA2: GAMMA2_1, TAU: 39, ETA: 2, OMEGA: 80
6557
+ }),
6558
+ 3: Object.freeze({
6559
+ K: 6, L: 5, D, GAMMA1: 2 ** 19, GAMMA2: GAMMA2_2, TAU: 49, ETA: 4, OMEGA: 55
6560
+ }),
6561
+ 5: Object.freeze({
6562
+ K: 8, L: 7, D, GAMMA1: 2 ** 19, GAMMA2: GAMMA2_2, TAU: 60, ETA: 2, OMEGA: 75
6563
+ }),
6564
+ }))();
6565
+ const newPoly = (n) => new Int32Array(n);
6566
+ // Shared CRYSTALS helper in the ML-DSA branch: non-Kyber mode, 8-bit bit-reversal,
6567
+ // and Int32Array polys because ordinary-form coefficients can be negative / centered.
6568
+ const crystals = /* @__PURE__ */ genCrystals({
6569
+ N,
6570
+ Q,
6571
+ F,
6572
+ ROOT_OF_UNITY,
6573
+ newPoly,
6574
+ brvBits: 8,
6575
+ });
6576
+ const id = (n) => n;
6577
+ // compress()/verify() must be compatible in both directions:
6578
+ // wrap the shared d-bit packer with the FIPS 204 SimpleBitPack / BitPack coefficient maps.
6579
+ // malformed-input rejection only happens through the optional verify hook.
6580
+ const polyCoder = (d, compress = id, verify = id) => crystals.bitsCoder(d, {
6581
+ encode: (i) => compress(verify(i)),
6582
+ decode: (i) => verify(compress(i)),
6583
+ });
6584
+ // Mutates `a` in place; callers must pass same-length polynomials.
6585
+ // NOTE: conditional-reduction variants (as in ml-kem) were measured performance-neutral here —
6586
+ // int32 `%` with 23-bit Q is already cheap — so the simpler mod() form is kept for audit.
6587
+ const polyAdd = (a_, b_) => {
6588
+ const a = a_;
6589
+ const b = b_;
6590
+ for (let i = 0; i < a.length; i++)
6591
+ a[i] = crystals.mod(a[i] + b[i]);
6592
+ return a;
6593
+ };
6594
+ // Mutates `a` in place; callers must pass same-length polynomials.
6595
+ const polySub = (a_, b_) => {
6596
+ const a = a_;
6597
+ const b = b_;
6598
+ for (let i = 0; i < a.length; i++)
6599
+ a[i] = crystals.mod(a[i] - b[i]);
6600
+ return a;
6601
+ };
6602
+ // Mutates `p` in place and assumes it is a decoded `t1`-range polynomial.
6603
+ const polyShiftl = (p_) => {
6604
+ const p = p_;
6605
+ for (let i = 0; i < N; i++)
6606
+ p[i] <<= D;
6607
+ return p;
6608
+ };
6609
+ const polyChknorm = (p_, B) => {
6610
+ const p = p_;
6611
+ // FIPS 204 Algorithms 7 and 8 express the same centered-norm check with explicit inequalities.
6612
+ for (let i = 0; i < N; i++)
6613
+ if (Math.abs(crystals.smod(p[i])) >= B)
6614
+ return true;
6615
+ return false;
6616
+ };
6617
+ // Both inputs must already be in NTT / `T_q` form.
6618
+ const MultiplyNTTs = (a_, b_) => {
6619
+ const a = a_;
6620
+ const b = b_;
6621
+ // NOTE: we don't use montgomery reduction in code, since it requires 64 bit ints,
6622
+ // which is not available in JS. mod(a[i] * b[i]) is ok, since Q is 23 bit,
6623
+ // which means a[i] * b[i] is 46 bit, which is safe to use in JS. (number is 53 bits).
6624
+ // Barrett reduction is slower than mod :(
6625
+ const c = newPoly(N);
6626
+ for (let i = 0; i < a.length; i++)
6627
+ c[i] = crystals.mod(a[i] * b[i]);
6628
+ return c;
6629
+ };
6630
+ // Return poly in NTT representation
6631
+ function RejNTTPoly(xof_) {
6632
+ const xof = xof_;
6633
+ // Samples a polynomial ∈ Tq. xof() must return byte lengths divisible by 3.
6634
+ const r = newPoly(N);
6635
+ // NOTE: we can represent 3xu24 as 4xu32, but it doesn't improve perf :(
6636
+ for (let j = 0; j < N;) {
6637
+ const b = xof();
6638
+ if (b.length % 3)
6639
+ throw new Error('RejNTTPoly: unaligned block');
6640
+ for (let i = 0; j < N && i <= b.length - 3; i += 3) {
6641
+ // FIPS 204 Algorithm 14 clears the top bit of b2 before forming the 23-bit candidate.
6642
+ const t = (b[i + 0] | (b[i + 1] << 8) | (b[i + 2] << 16)) & 0x7fffff; // 3 bytes
6643
+ if (t < Q)
6644
+ r[j++] = t;
6645
+ }
6646
+ }
6647
+ return r;
6648
+ }
6649
+ // Instantiate one ML-DSA parameter set from the Table 1 lattice constants plus the
6650
+ // Table 2 byte lengths / hash-width choices used by the public wrappers below.
6651
+ function getDilithium(opts_) {
6652
+ const opts = opts_;
6653
+ const { K, L, GAMMA1, GAMMA2, TAU, ETA, OMEGA } = opts;
6654
+ const { CRH_BYTES, TR_BYTES, C_TILDE_BYTES, XOF128, XOF256, securityLevel } = opts;
6655
+ if (![2, 4].includes(ETA))
6656
+ throw new Error('Wrong ETA');
6657
+ if (![1 << 17, 1 << 19].includes(GAMMA1))
6658
+ throw new Error('Wrong GAMMA1');
6659
+ if (![GAMMA2_1, GAMMA2_2].includes(GAMMA2))
6660
+ throw new Error('Wrong GAMMA2');
6661
+ const BETA = TAU * ETA;
6662
+ const decompose = (r) => {
6663
+ // Decomposes r into (r1, r0) such that r ≡ r1(2γ2) + r0 mod q.
6664
+ const rPlus = crystals.mod(r);
6665
+ const r0 = crystals.smod(rPlus, 2 * GAMMA2) | 0;
6666
+ // FIPS 204 Algorithm 36 folds the top bucket `q-1` back to `(r1, r0) = (0, r0-1)`.
6667
+ if (rPlus - r0 === Q - 1)
6668
+ return { r1: 0 | 0, r0: (r0 - 1) | 0 };
6669
+ const r1 = Math.floor((rPlus - r0) / (2 * GAMMA2)) | 0;
6670
+ return { r1, r0 }; // r1 = HighBits, r0 = LowBits
6671
+ };
6672
+ const HighBits = (r) => decompose(r).r1;
6673
+ const LowBits = (r) => decompose(r).r0;
6674
+ const MakeHint = (z, r) => {
6675
+ // Compute hint bit indicating whether adding z to r alters the high bits of r.
6676
+ // FIPS 204 §6.2 also permits the Section 5.1 alternative from [6], which uses the
6677
+ // transformed low-bits/high-bits state at this call site instead of Algorithm 39 literally.
6678
+ // This optimized predicate only applies to those transformed Section 5.1 inputs; it is
6679
+ // not a drop-in replacement for Algorithm 39 on arbitrary `(z, r)` pairs.
6680
+ // From dilithium code
6681
+ const res0 = z <= GAMMA2 || z > Q - GAMMA2 || (z === Q - GAMMA2 && r === 0) ? 0 : 1;
6682
+ // from FIPS204:
6683
+ // // const r1 = HighBits(r);
6684
+ // // const v1 = HighBits(r + z);
6685
+ // // const res1 = +(r1 !== v1);
6686
+ // But they return different results! However, decompose is same.
6687
+ // So, either there is a bug in Dilithium ref implementation or in FIPS204.
6688
+ // For now, lets use dilithium one, so test vectors can be passed.
6689
+ // The round-3 Dilithium / ML-DSA code uses the same low-bits / high-bits convention after
6690
+ // `r0 += ct0`.
6691
+ // See dilithium-py README section "Optimising decomposition and making hints".
6692
+ return res0;
6693
+ };
6694
+ // m = (q-1)/(2γ2): 44 for ML-DSA-44, 16 for 65/87. Hoisted out of UseHint, which runs
6695
+ // per coefficient during verification.
6696
+ const HINT_M = Math.floor((Q - 1) / (2 * GAMMA2));
6697
+ const UseHint = (h, r) => {
6698
+ // Returns the high bits of r adjusted according to hint h
6699
+ const { r1, r0 } = decompose(r);
6700
+ // 3: if h = 1 and r0 > 0 return (r1 + 1) mod m
6701
+ // 4: if h = 1 and r0 ≤ 0 return (r1 − 1) mod m
6702
+ if (h === 1)
6703
+ return r0 > 0 ? crystals.mod(r1 + 1, HINT_M) | 0 : crystals.mod(r1 - 1, HINT_M) | 0;
6704
+ return r1 | 0;
6705
+ };
6706
+ const Power2Round = (r) => {
6707
+ // Decomposes r into (r1, r0) such that r ≡ r1*(2**d) + r0 mod q.
6708
+ const rPlus = crystals.mod(r);
6709
+ const r0 = crystals.smod(rPlus, 2 ** D) | 0;
6710
+ return { r1: Math.floor((rPlus - r0) / 2 ** D) | 0, r0 };
6711
+ };
6712
+ const hintCoder = {
6713
+ bytesLen: OMEGA + K,
6714
+ encode: (h_) => {
6715
+ const h = h_;
6716
+ if (h === false)
6717
+ throw new Error('hint.encode: hint is false'); // should never happen
6718
+ const res = new Uint8Array(OMEGA + K);
6719
+ for (let i = 0, k = 0; i < K; i++) {
6720
+ for (let j = 0; j < N; j++)
6721
+ if (h[i][j] !== 0)
6722
+ res[k++] = j;
6723
+ res[OMEGA + i] = k;
6724
+ }
6725
+ return res;
6726
+ },
6727
+ decode: (buf) => {
6728
+ const h = [];
6729
+ let k = 0;
6730
+ for (let i = 0; i < K; i++) {
6731
+ const hi = newPoly(N);
6732
+ if (buf[OMEGA + i] < k || buf[OMEGA + i] > OMEGA)
6733
+ return false;
6734
+ for (let j = k; j < buf[OMEGA + i]; j++) {
6735
+ if (j > k && buf[j] <= buf[j - 1])
6736
+ return false;
6737
+ hi[buf[j]] = 1;
6738
+ }
6739
+ k = buf[OMEGA + i];
6740
+ h.push(hi);
6741
+ }
6742
+ for (let j = k; j < OMEGA; j++)
6743
+ if (buf[j] !== 0)
6744
+ return false;
6745
+ return h;
6746
+ },
6747
+ };
6748
+ const ETACoder = polyCoder(ETA === 2 ? 3 : 4, (i) => ETA - i, (i) => {
6749
+ if (!(-ETA <= i && i <= ETA))
6750
+ throw new Error(`malformed key s1/s3 ${i} outside of ETA range [${-ETA}, ${ETA}]`);
6751
+ return i;
6752
+ });
6753
+ const T0Coder = polyCoder(13, (i) => (1 << (D - 1)) - i);
6754
+ const T1Coder = polyCoder(10);
6755
+ // Requires smod. Need to fix!
6756
+ const ZCoder = polyCoder(GAMMA1 === 1 << 17 ? 18 : 20, (i) => crystals.smod(GAMMA1 - i));
6757
+ const W1Coder = polyCoder(GAMMA2 === GAMMA2_1 ? 6 : 4);
6758
+ const W1Vec = vecCoder(W1Coder, K);
6759
+ // Main structures
6760
+ const publicCoder = splitCoder('publicKey', 32, vecCoder(T1Coder, K));
6761
+ const secretCoder = splitCoder('secretKey', 32, 32, TR_BYTES, vecCoder(ETACoder, L), vecCoder(ETACoder, K), vecCoder(T0Coder, K));
6762
+ const sigCoder = splitCoder('signature', C_TILDE_BYTES, vecCoder(ZCoder, L), hintCoder);
6763
+ const CoefFromHalfByte = ETA === 2
6764
+ ? (n) => (n < 15 ? 2 - (n % 5) : false)
6765
+ : (n) => (n < 9 ? 4 - n : false);
6766
+ // Return poly in ordinary representation.
6767
+ // This helper returns ordinary-form `[-ETA, ETA]` coefficients for ExpandS; callers apply
6768
+ // `NTT.encode()` later when needed.
6769
+ function RejBoundedPoly(xof_) {
6770
+ const xof = xof_;
6771
+ // Samples an element a ∈ Rq with coeffcients in [−η, η] computed via rejection sampling from ρ.
6772
+ const r = newPoly(N);
6773
+ for (let j = 0; j < N;) {
6774
+ const b = xof();
6775
+ for (let i = 0; j < N && i < b.length; i += 1) {
6776
+ // half byte. Should be superfast with vector instructions. But very slow with js :(
6777
+ const d1 = CoefFromHalfByte(b[i] & 0x0f);
6778
+ const d2 = CoefFromHalfByte((b[i] >> 4) & 0x0f);
6779
+ if (d1 !== false)
6780
+ r[j++] = d1;
6781
+ if (j < N && d2 !== false)
6782
+ r[j++] = d2;
6783
+ }
6784
+ }
6785
+ return r;
6786
+ }
6787
+ const SampleInBall = (seed) => {
6788
+ // Samples a polynomial c ∈ Rq with coeffcients from {−1, 0, 1} and Hamming weight τ
6789
+ const pre = newPoly(N);
6790
+ const s = shake256.create({}).update(seed);
6791
+ const buf = new Uint8Array(shake256.blockLen);
6792
+ s.xofInto(buf);
6793
+ // FIPS 204 Algorithm 29 uses the first 8 squeezed bytes as the 64 sign bits `h`,
6794
+ // then rejection-samples coefficient positions from the remaining XOF stream.
6795
+ const masks = buf.slice(0, 8);
6796
+ for (let i = N - TAU, pos = 8, maskPos = 0, maskBit = 0; i < N; i++) {
6797
+ let b = i + 1;
6798
+ for (; b > i;) {
6799
+ b = buf[pos++];
6800
+ if (pos < shake256.blockLen)
6801
+ continue;
6802
+ s.xofInto(buf);
6803
+ pos = 0;
6804
+ }
6805
+ pre[i] = pre[b];
6806
+ pre[b] = 1 - (((masks[maskPos] >> maskBit++) & 1) << 1);
6807
+ if (maskBit >= 8) {
6808
+ maskPos++;
6809
+ maskBit = 0;
6810
+ }
6811
+ }
6812
+ return pre;
6813
+ };
6814
+ const polyPowerRound = (p_) => {
6815
+ const p = p_;
6816
+ const res0 = newPoly(N);
6817
+ const res1 = newPoly(N);
6818
+ for (let i = 0; i < p.length; i++) {
6819
+ const { r0, r1 } = Power2Round(p[i]);
6820
+ res0[i] = r0;
6821
+ res1[i] = r1;
6822
+ }
6823
+ return { r0: res0, r1: res1 };
6824
+ };
6825
+ const polyUseHint = (u_, h_) => {
6826
+ const u = u_;
6827
+ const h = h_;
6828
+ // In-place on `u`: verification only needs the recovered high bits, so reuse the
6829
+ // temporary `wApprox` buffer instead of allocating another polynomial.
6830
+ for (let i = 0; i < N; i++)
6831
+ u[i] = UseHint(h[i], u[i]);
6832
+ return u;
6833
+ };
6834
+ const polyMakeHint = (a_, b_) => {
6835
+ const a = a_;
6836
+ const b = b_;
6837
+ const v = newPoly(N);
6838
+ let cnt = 0;
6839
+ for (let i = 0; i < N; i++) {
6840
+ const h = MakeHint(a[i], b[i]);
6841
+ v[i] = h;
6842
+ cnt += h;
6843
+ }
6844
+ return { v, cnt };
6845
+ };
6846
+ const signRandBytes = 32;
6847
+ const seedCoder = splitCoder('seed', 32, 64, 32);
6848
+ // API & argument positions are exactly as in FIPS204.
6849
+ const internal = Object.freeze({
6850
+ info: Object.freeze({ type: 'internal-ml-dsa' }),
6851
+ lengths: Object.freeze({
6852
+ secretKey: secretCoder.bytesLen,
6853
+ publicKey: publicCoder.bytesLen,
6854
+ seed: 32,
6855
+ signature: sigCoder.bytesLen,
6856
+ signRand: signRandBytes,
6857
+ }),
6858
+ keygen: (seed) => {
6859
+ // H(𝜉||IntegerToBytes(𝑘, 1)||IntegerToBytes(ℓ, 1), 128) 2: ▷ expand seed
6860
+ const seedDst = new Uint8Array(32 + 2);
6861
+ const randSeed = seed === undefined;
6862
+ if (randSeed)
6863
+ seed = randomBytes(32);
6864
+ abytesDoc(seed, 32, 'seed');
6865
+ seedDst.set(seed);
6866
+ if (randSeed)
6867
+ cleanBytes(seed);
6868
+ seedDst[32] = K;
6869
+ seedDst[33] = L;
6870
+ const [rho, rhoPrime, K_] = seedCoder.decode(shake256(seedDst, { dkLen: seedCoder.bytesLen }));
6871
+ const xofPrime = XOF256(rhoPrime);
6872
+ const s1 = [];
6873
+ for (let i = 0; i < L; i++)
6874
+ s1.push(RejBoundedPoly(xofPrime.get(i & 0xff, (i >> 8) & 0xff)));
6875
+ const s2 = [];
6876
+ for (let i = L; i < L + K; i++)
6877
+ s2.push(RejBoundedPoly(xofPrime.get(i & 0xff, (i >> 8) & 0xff)));
6878
+ const s1Hat = s1.map((i) => crystals.NTT.encode(i.slice()));
6879
+ const t0 = [];
6880
+ const t1 = [];
6881
+ const xof = XOF128(rho);
6882
+ const t = newPoly(N);
6883
+ for (let i = 0; i < K; i++) {
6884
+ // t ← NTT−1(A*NTT(s1)) + s2
6885
+ cleanBytes(t); // don't-reallocate
6886
+ for (let j = 0; j < L; j++) {
6887
+ const aij = RejNTTPoly(xof.get(j, i)); // super slow!
6888
+ polyAdd(t, MultiplyNTTs(aij, s1Hat[j]));
6889
+ }
6890
+ crystals.NTT.decode(t);
6891
+ const { r0, r1 } = polyPowerRound(polyAdd(t, s2[i])); // (t1, t0) ← Power2Round(t, d)
6892
+ t0.push(r0);
6893
+ t1.push(r1);
6894
+ }
6895
+ const publicKey = publicCoder.encode([rho, t1]); // pk ← pkEncode(ρ, t1)
6896
+ const tr = shake256(publicKey, { dkLen: TR_BYTES }); // tr ← H(BytesToBits(pk), 512)
6897
+ // sk ← skEncode(ρ, K,tr, s1, s2, t0)
6898
+ const secretKey = secretCoder.encode([rho, K_, tr, s1, s2, t0]);
6899
+ xof.clean();
6900
+ xofPrime.clean();
6901
+ // STATS
6902
+ // Kyber512: { calls: 4, xofs: 12 }, Kyber768: { calls: 9, xofs: 27 },
6903
+ // Kyber1024: { calls: 16, xofs: 48 }
6904
+ // DSA44: { calls: 24, xofs: 24 }, DSA65: { calls: 41, xofs: 41 },
6905
+ // DSA87: { calls: 71, xofs: 71 }
6906
+ cleanBytes(rho, rhoPrime, K_, s1, s2, s1Hat, t, t0, t1, tr, seedDst);
6907
+ return {
6908
+ publicKey: publicKey,
6909
+ secretKey: secretKey,
6910
+ };
6911
+ },
6912
+ getPublicKey: (secretKey) => {
6913
+ // (ρ, K,tr, s1, s2, t0) ← skDecode(sk)
6914
+ const [rho, _K, _tr, s1, s2, _t0] = secretCoder.decode(secretKey);
6915
+ const xof = XOF128(rho);
6916
+ const s1Hat = s1.map((p) => crystals.NTT.encode(p.slice()));
6917
+ const t1 = [];
6918
+ const tmp = newPoly(N);
6919
+ for (let i = 0; i < K; i++) {
6920
+ tmp.fill(0);
6921
+ for (let j = 0; j < L; j++) {
6922
+ const aij = RejNTTPoly(xof.get(j, i)); // A_ij in NTT
6923
+ polyAdd(tmp, MultiplyNTTs(aij, s1Hat[j])); // += A_ij * s1_j
6924
+ }
6925
+ crystals.NTT.decode(tmp); // NTT⁻¹
6926
+ polyAdd(tmp, s2[i]); // t_i = A·s1 + s2
6927
+ const { r1 } = polyPowerRound(tmp); // r1 = t1, r0 ≈ t0
6928
+ t1.push(r1);
6929
+ }
6930
+ xof.clean();
6931
+ cleanBytes(tmp, s1Hat, _t0, s1, s2);
6932
+ return publicCoder.encode([rho, t1]);
6933
+ },
6934
+ // NOTE: random is optional.
6935
+ sign: (msg, secretKey, opts = {}) => {
6936
+ opts = validateSigOpts(opts, INTERNAL_SIG_OPT_KEYS);
6937
+ opts = validateInternalOpts(opts, INTERNAL_SIG_OPT_KEYS);
6938
+ const { extraEntropy: random, externalMu = false } = opts;
6939
+ // FIPS 204 external-mu mode expects the 64-byte message representative µ = H(tr || M).
6940
+ if (externalMu)
6941
+ abytesDoc(msg, CRH_BYTES, 'mu');
6942
+ // Prepare entropy before touching decoded secrets: randomBytes() may throw, and an RNG
6943
+ // failure must not leave expanded secret-polynomial copies behind.
6944
+ const ownRnd = random === false || random === undefined;
6945
+ const rnd = random === false
6946
+ ? new Uint8Array(32)
6947
+ : random === undefined
6948
+ ? randomBytes(signRandBytes)
6949
+ : random;
6950
+ abytesDoc(rnd, 32, 'extraEntropy');
6951
+ // This part can be pre-cached per secretKey, but there is only minor performance improvement,
6952
+ // since we re-use a lot of variables to computation.
6953
+ // (ρ, K,tr, s1, s2, t0) ← skDecode(sk)
6954
+ const decoded = (() => {
6955
+ try {
6956
+ return secretCoder.decode(secretKey);
6957
+ }
6958
+ catch (error) {
6959
+ // A malformed key must not strand entropy owned by the library.
6960
+ if (ownRnd)
6961
+ cleanBytes(rnd);
6962
+ throw error;
6963
+ }
6964
+ })();
6965
+ const [rho, _K, tr, s1, s2, t0] = decoded;
6966
+ // Cache matrix to avoid re-compute later
6967
+ const A = []; // A ← ExpandA(ρ)
6968
+ const xof = XOF128(rho);
6969
+ for (let i = 0; i < K; i++) {
6970
+ const pv = [];
6971
+ for (let j = 0; j < L; j++)
6972
+ pv.push(RejNTTPoly(xof.get(j, i)));
6973
+ A.push(pv);
6974
+ }
6975
+ xof.clean();
6976
+ for (let i = 0; i < L; i++)
6977
+ crystals.NTT.encode(s1[i]); // sˆ1 ← NTT(s1)
6978
+ for (let i = 0; i < K; i++) {
6979
+ crystals.NTT.encode(s2[i]); // sˆ2 ← NTT(s2)
6980
+ crystals.NTT.encode(t0[i]); // tˆ0 ← NTT(t0)
6981
+ }
6982
+ // This part is per msg
6983
+ const mu = externalMu
6984
+ ? msg
6985
+ : // 6: µ ← H(tr||M, 512)
6986
+ // ▷ Compute message representative µ
6987
+ shake256.create({ dkLen: CRH_BYTES }).update(tr).update(msg).digest();
6988
+ const rhoprime = shake256
6989
+ .create({ dkLen: CRH_BYTES })
6990
+ .update(_K)
6991
+ .update(rnd)
6992
+ .update(mu)
6993
+ .digest(); // ρ′← H(K||rnd||µ, 512)
6994
+ // Only wipe entropy we generated; caller-provided extraEntropy stays caller-owned.
6995
+ if (ownRnd)
6996
+ cleanBytes(rnd);
6997
+ abytesDoc(rhoprime, CRH_BYTES);
6998
+ const x256 = XOF256(rhoprime, ZCoder.bytesLen);
6999
+ // Rejection sampling loop
7000
+ main_loop: for (let kappa = 0;;) {
7001
+ const y = [];
7002
+ // y ← ExpandMask(ρ , κ)
7003
+ for (let i = 0; i < L; i++, kappa++)
7004
+ y.push(ZCoder.decode(x256.get(kappa & 0xff, kappa >> 8)()));
7005
+ const z = y.map((i) => crystals.NTT.encode(i.slice()));
7006
+ const w = [];
7007
+ for (let i = 0; i < K; i++) {
7008
+ // w ← NTT−1(A ◦ NTT(y))
7009
+ const wi = newPoly(N);
7010
+ for (let j = 0; j < L; j++)
7011
+ polyAdd(wi, MultiplyNTTs(A[i][j], z[j]));
7012
+ crystals.NTT.decode(wi);
7013
+ w.push(wi);
7014
+ }
7015
+ const w1 = w.map((j) => j.map(HighBits)); // w1 ← HighBits(w)
7016
+ // Commitment hash: c˜ ∈{0, 1 2λ } ← H(µ||w1Encode(w1), 2λ)
7017
+ const cTilde = shake256
7018
+ .create({ dkLen: C_TILDE_BYTES })
7019
+ .update(mu)
7020
+ .update(W1Vec.encode(w1))
7021
+ .digest();
7022
+ // Verifer’s challenge
7023
+ // c ← SampleInBall(c˜1); cˆ ← NTT(c)
7024
+ const cHat = crystals.NTT.encode(SampleInBall(cTilde));
7025
+ // ⟨⟨cs1⟩⟩ ← NTT−1(cˆ◦ sˆ1)
7026
+ const cs1 = s1.map((i) => MultiplyNTTs(i, cHat));
7027
+ for (let i = 0; i < L; i++) {
7028
+ polyAdd(crystals.NTT.decode(cs1[i]), y[i]); // z ← y + ⟨⟨cs1⟩⟩
7029
+ if (polyChknorm(cs1[i], GAMMA1 - BETA)) {
7030
+ // Rejected. Wipe this iteration's secret-derived buffers before retrying; the
7031
+ // accepted path wipes the same set, and only the persistent key material (s1, s2,
7032
+ // t0, A, rhoprime) is kept for the next iteration and cleaned at the very end.
7033
+ cleanBytes(cTilde, cs1, cHat, w1, w, z, y);
7034
+ continue main_loop; // ||z||∞ ≥ γ1 − β
7035
+ }
7036
+ }
7037
+ // cs1 is now z (▷ Signer’s response)
7038
+ let cnt = 0;
7039
+ const h = [];
7040
+ for (let i = 0; i < K; i++) {
7041
+ const cs2 = crystals.NTT.decode(MultiplyNTTs(s2[i], cHat)); // ⟨⟨cs2⟩⟩ ← NTT−1(cˆ◦ sˆ2)
7042
+ const r0 = polySub(w[i], cs2).map(LowBits); // r0 ← LowBits(w − ⟨⟨cs2⟩⟩)
7043
+ if (polyChknorm(r0, GAMMA2 - BETA)) {
7044
+ cleanBytes(cTilde, cs1, cHat, w1, w, z, y, h, cs2, r0);
7045
+ continue main_loop; // ||r0||∞ ≥ γ2 − β
7046
+ }
7047
+ const ct0 = crystals.NTT.decode(MultiplyNTTs(t0[i], cHat)); // ⟨⟨ct0⟩⟩ ← NTT−1(cˆ◦ tˆ0)
7048
+ if (polyChknorm(ct0, GAMMA2)) {
7049
+ cleanBytes(cTilde, cs1, cHat, w1, w, z, y, h, cs2, r0, ct0);
7050
+ continue main_loop;
7051
+ }
7052
+ polyAdd(r0, ct0);
7053
+ // ▷ Signer’s hint
7054
+ const hint = polyMakeHint(r0, w1[i]); // h ← MakeHint(−⟨⟨ct0⟩⟩, w− ⟨⟨cs2⟩⟩ + ⟨⟨ct0⟩⟩)
7055
+ h.push(hint.v);
7056
+ cnt += hint.cnt;
7057
+ }
7058
+ if (cnt > OMEGA) {
7059
+ cleanBytes(cTilde, cs1, cHat, w1, w, z, y, h);
7060
+ continue; // the number of 1’s in h is greater than ω
7061
+ }
7062
+ x256.clean();
7063
+ const res = sigCoder.encode([cTilde, cs1, h]); // σ ← sigEncode(c˜, z mod±q, h)
7064
+ // rho, _K, tr is subarray of secretKey, cannot clean.
7065
+ cleanBytes(cTilde, cs1, h, cHat, w1, w, z, y, rhoprime, s1, s2, t0, ...A);
7066
+ // `externalMu` hands ownership of `mu` to the caller,
7067
+ // so only wipe the internally derived digest form here;
7068
+ // zeroizing caller memory would break the caller's own reuse / verify path.
7069
+ if (!externalMu)
7070
+ cleanBytes(mu);
7071
+ return res;
7072
+ }
7073
+ // @ts-ignore
7074
+ throw new Error('Unreachable code path reached, report this error');
7075
+ },
7076
+ verify: (sig, msg, publicKey, opts = {}) => {
7077
+ opts = validateInternalOpts(opts, INTERNAL_VER_OPT_KEYS);
7078
+ const { externalMu = false } = opts;
7079
+ // FIPS 204 external-mu mode expects the 64-byte message representative µ = H(tr || M).
7080
+ if (externalMu)
7081
+ abytesDoc(msg, CRH_BYTES, 'mu');
7082
+ // ML-DSA.Verify(pk, M, σ): Verifes a signature σ for a message M.
7083
+ const [rho, t1] = publicCoder.decode(publicKey); // (ρ, t1) ← pkDecode(pk)
7084
+ const tr = shake256(publicKey, { dkLen: TR_BYTES }); // 6: tr ← H(BytesToBits(pk), 512)
7085
+ if (sig.length !== sigCoder.bytesLen)
7086
+ return false; // return false instead of exception
7087
+ // (c˜, z, h) ← sigDecode(σ)
7088
+ // ▷ Signer’s commitment hash c ˜, response z and hint
7089
+ const [cTilde, z, h] = sigCoder.decode(sig);
7090
+ if (h === false)
7091
+ return false; // if h = ⊥ then return false
7092
+ for (let i = 0; i < L; i++)
7093
+ if (polyChknorm(z[i], GAMMA1 - BETA))
7094
+ return false;
7095
+ const mu = externalMu
7096
+ ? msg
7097
+ : // 7: µ ← H(tr||M, 512)
7098
+ shake256.create({ dkLen: CRH_BYTES }).update(tr).update(msg).digest();
7099
+ // Compute verifer’s challenge from c˜
7100
+ const c = crystals.NTT.encode(SampleInBall(cTilde)); // c ← SampleInBall(c˜1)
7101
+ const zNtt = z.map((i) => i.slice()); // zNtt = NTT(z)
7102
+ for (let i = 0; i < L; i++)
7103
+ crystals.NTT.encode(zNtt[i]);
7104
+ const wTick1 = [];
7105
+ const xof = XOF128(rho);
7106
+ for (let i = 0; i < K; i++) {
7107
+ const ct12d = MultiplyNTTs(crystals.NTT.encode(polyShiftl(t1[i])), c); //c * t1 * (2**d)
7108
+ const Az = newPoly(N); // // A * z
7109
+ for (let j = 0; j < L; j++) {
7110
+ const aij = RejNTTPoly(xof.get(j, i)); // A[i][j] inplace
7111
+ polyAdd(Az, MultiplyNTTs(aij, zNtt[j]));
7112
+ }
7113
+ // wApprox = A*z - c*t1 * (2**d)
7114
+ const wApprox = crystals.NTT.decode(polySub(Az, ct12d));
7115
+ // Reconstruction of signer’s commitment
7116
+ wTick1.push(polyUseHint(wApprox, h[i])); // w ′ ← UseHint(h, w'approx )
7117
+ }
7118
+ xof.clean();
7119
+ // c˜′← H (µ||w1Encode(w′1), 2λ), Hash it; this should match c˜
7120
+ const c2 = shake256
7121
+ .create({ dkLen: C_TILDE_BYTES })
7122
+ .update(mu)
7123
+ .update(W1Vec.encode(wTick1))
7124
+ .digest();
7125
+ // Additional checks in FIPS-204:
7126
+ // [[ ||z||∞ < γ1 − β ]] and [[c ˜ = c˜′]] and [[number of 1’s in h is ≤ ω]]
7127
+ for (const t of h) {
7128
+ const sum = t.reduce((acc, i) => acc + i, 0);
7129
+ if (!(sum <= OMEGA))
7130
+ return false;
7131
+ }
7132
+ for (const t of z)
7133
+ if (polyChknorm(t, GAMMA1 - BETA))
7134
+ return false;
7135
+ return equalBytes(cTilde, c2);
7136
+ },
7137
+ });
7138
+ return Object.freeze({
7139
+ info: Object.freeze({ type: 'ml-dsa' }),
7140
+ internal,
7141
+ securityLevel: securityLevel,
7142
+ keygen: internal.keygen,
7143
+ lengths: internal.lengths,
7144
+ getPublicKey: internal.getPublicKey,
7145
+ sign: (msg, secretKey, opts = {}) => {
7146
+ opts = validateSigOpts(opts);
7147
+ const M = getMessage(msg, opts.context);
7148
+ // `context` is consumed by getMessage() above; forwarding it would make the internal
7149
+ // surface accept a key it never reads.
7150
+ const res = internal.sign(M, secretKey, {
7151
+ extraEntropy: opts.extraEntropy,
7152
+ externalMu: false,
7153
+ });
7154
+ cleanBytes(M);
7155
+ return res;
7156
+ },
7157
+ verify: (sig, msg, publicKey, opts = {}) => {
7158
+ opts = validateVerOpts(opts);
7159
+ abytesDoc(sig, undefined, 'signature');
7160
+ return internal.verify(sig, getMessage(msg, opts.context), publicKey, { externalMu: false });
7161
+ },
7162
+ prehash: (hash) => {
7163
+ checkHash(hash, securityLevel);
7164
+ const rawHash = hash;
7165
+ return Object.freeze({
7166
+ info: Object.freeze({ type: 'hashml-dsa' }),
7167
+ securityLevel: securityLevel,
7168
+ lengths: internal.lengths,
7169
+ keygen: internal.keygen,
7170
+ getPublicKey: internal.getPublicKey,
7171
+ sign: (msg, secretKey, opts = {}) => {
7172
+ opts = validateSigOpts(opts);
7173
+ const M = getMessagePrehash(rawHash, msg, opts.context);
7174
+ // As above: getMessagePrehash() consumes `context`, so it must not travel further.
7175
+ const res = internal.sign(M, secretKey, {
7176
+ extraEntropy: opts.extraEntropy,
7177
+ externalMu: false,
7178
+ });
7179
+ cleanBytes(M);
7180
+ return res;
7181
+ },
7182
+ verify: (sig, msg, publicKey, opts = {}) => {
7183
+ opts = validateVerOpts(opts);
7184
+ abytesDoc(sig, undefined, 'signature');
7185
+ return internal.verify(sig, getMessagePrehash(rawHash, msg, opts.context), publicKey, {
7186
+ externalMu: false,
7187
+ });
7188
+ },
7189
+ });
7190
+ },
7191
+ });
7192
+ }
7193
+ /**
7194
+ * ML-DSA-44 for 128-bit security level. Not recommended after 2030, as per ASD.
7195
+ * @example
7196
+ * Generate deterministic ML-DSA-44 keys, sign one message, and verify the signature.
7197
+ * ```ts
7198
+ * import { sha256 } from '@noble/hashes/sha2.js';
7199
+ * import { ml_dsa44 } from '@noble/post-quantum/ml-dsa.js';
7200
+ * const seed = new Uint8Array(ml_dsa44.lengths.seed!);
7201
+ * const { secretKey, publicKey } = ml_dsa44.keygen(seed);
7202
+ * const msg = new TextEncoder().encode('hello noble');
7203
+ * const sig = ml_dsa44.sign(msg, secretKey);
7204
+ * const isValid = ml_dsa44.verify(sig, msg, publicKey);
7205
+ * const recovered = ml_dsa44.getPublicKey(secretKey);
7206
+ * const context = new Uint8Array([1, 2, 3]);
7207
+ * const prehash = ml_dsa44.prehash(sha256);
7208
+ * const preSig = prehash.sign(msg, secretKey, { context });
7209
+ * const preValid = prehash.verify(preSig, msg, publicKey, { context });
7210
+ * const internalSig = ml_dsa44.internal.sign(msg, secretKey);
7211
+ * ```
7212
+ */
7213
+ const ml_dsa44 = /* @__PURE__ */ (() => getDilithium({
7214
+ ...PARAMS[2],
7215
+ CRH_BYTES: 64,
7216
+ TR_BYTES: 64,
7217
+ C_TILDE_BYTES: 32,
7218
+ XOF128,
7219
+ XOF256,
7220
+ securityLevel: 128,
7221
+ }))();
7222
+
7223
+ var _MLDSAKey_key, _MLDSAPublicKey_key;
7224
+ // Octez stores the 2560-byte ML-DSA-44 secret followed by its 1312-byte public key.
7225
+ const SECRET_KEY_SIZE = 2560;
7226
+ class MLDSAKey {
7227
+ constructor(key, decrypt) {
7228
+ _MLDSAKey_key.set(this, void 0);
7229
+ const [encoded, prefix] = b58DecodeAndCheckPrefix(key, [
7230
+ PrefixV2.MLDSA44SecretKey,
7231
+ PrefixV2.MLDSA44EncryptedSecretKey,
7232
+ ]);
7233
+ let data = encoded;
7234
+ if (prefix === PrefixV2.MLDSA44EncryptedSecretKey) {
7235
+ if (!decrypt)
7236
+ throw new Error('decryption function is not provided');
7237
+ data = decrypt(data);
7238
+ }
7239
+ if (data.length !== payloadLength[PrefixV2.MLDSA44SecretKey]) {
7240
+ throw new InvalidKeyError('Invalid ML-DSA-44 secret key length');
7241
+ }
7242
+ __classPrivateFieldSet(this, _MLDSAKey_key, Uint8Array.from(data), "f");
7243
+ }
7244
+ sign(message) {
7245
+ // Octez uses pure ML-DSA with an empty context over Blake2b-256(message),
7246
+ // not HashML-DSA. InMemorySigner has already prepended any watermark.
7247
+ const rawSignature = ml_dsa44.sign(blake2b(message, { dkLen: 32 }), __classPrivateFieldGet(this, _MLDSAKey_key, "f").subarray(0, SECRET_KEY_SIZE));
7248
+ const encoded = b58Encode(rawSignature, PrefixV2.MLDSA44Signature);
7249
+ return { rawSignature, sig: encoded, prefixSig: encoded };
7250
+ }
7251
+ publicKey() {
7252
+ return new MLDSAPublicKey(__classPrivateFieldGet(this, _MLDSAKey_key, "f").subarray(SECRET_KEY_SIZE));
7253
+ }
7254
+ secretKey() {
7255
+ return b58Encode(__classPrivateFieldGet(this, _MLDSAKey_key, "f"), PrefixV2.MLDSA44SecretKey);
7256
+ }
7257
+ }
7258
+ _MLDSAKey_key = new WeakMap();
7259
+ class MLDSAPublicKey {
7260
+ constructor(src) {
7261
+ _MLDSAPublicKey_key.set(this, void 0);
7262
+ const key = typeof src === 'string' ? b58DecodeAndCheckPrefix(src, [PrefixV2.MLDSA44PublicKey])[0] : src;
7263
+ if (key.length !== payloadLength[PrefixV2.MLDSA44PublicKey]) {
7264
+ throw new InvalidPublicKeyError('Invalid ML-DSA-44 public key length');
7265
+ }
7266
+ __classPrivateFieldSet(this, _MLDSAPublicKey_key, Uint8Array.from(key), "f");
7267
+ }
7268
+ compare(other) {
7269
+ if (!(other instanceof MLDSAPublicKey)) {
7270
+ throw new InvalidPublicKeyError('ML-DSA-44 key expected');
7271
+ }
7272
+ return compareArrays(__classPrivateFieldGet(this, _MLDSAPublicKey_key, "f"), __classPrivateFieldGet(other, _MLDSAPublicKey_key, "f"));
7273
+ }
7274
+ hash() {
7275
+ return b58Encode(blake2b(__classPrivateFieldGet(this, _MLDSAPublicKey_key, "f"), { dkLen: 20 }), PrefixV2.MLDSA44PublicKeyHash);
7276
+ }
7277
+ bytes() {
7278
+ return __classPrivateFieldGet(this, _MLDSAPublicKey_key, "f").slice();
7279
+ }
7280
+ toProtocol() {
7281
+ return mergebuf(new Uint8Array([4]), __classPrivateFieldGet(this, _MLDSAPublicKey_key, "f"));
7282
+ }
7283
+ toString() {
7284
+ return b58Encode(__classPrivateFieldGet(this, _MLDSAPublicKey_key, "f"), PrefixV2.MLDSA44PublicKey);
7285
+ }
7286
+ }
7287
+ _MLDSAPublicKey_key = new WeakMap();
7288
+
7289
+ var _InMemorySigner_key;
7290
+ /**
7291
+ * A local implementation of the signer. Will represent a Tezos account and be able to produce signature in its behalf
7292
+ *
7293
+ * @remarks If running in production and dealing with tokens that have real value, it is strongly recommended to use a HSM backed signer so that private key material is not stored in memory or on disk
7294
+ * @throws InvalidMnemonicError
7295
+ */
7296
+ class InMemorySigner {
7297
+ static fromFundraiser(email, password, mnemonic) {
7298
+ if (!validateMnemonic(mnemonic, wordlist)) {
7299
+ throw new InvalidMnemonicError();
7300
+ }
7301
+ const seed = mnemonicToSeedSync(mnemonic, `${email}${password}`);
7302
+ const key = b58Encode(seed.subarray(0, 32), PrefixV2.Ed25519Seed);
7303
+ return new InMemorySigner(key);
7304
+ }
7305
+ static async fromSecretKey(key, passphrase) {
7306
+ return new InMemorySigner(key, passphrase);
7307
+ }
7308
+ /**
7309
+ *
7310
+ * Instantiation of an InMemorySigner instance from a mnemonic
7311
+ * @returns InMemorySigner
7312
+ * @throws InvalidMnemonicError
7313
+ */
7314
+ static fromMnemonic({ mnemonic, password = '', derivationPath = "44'/1729'/0'/0'", curve = 'ed25519', }) {
7315
+ // check if curve is defined if not default tz1
7316
+ if (!validateMnemonic(mnemonic, wordlist)) {
7317
+ // avoiding exposing mnemonic again in case of mistake making invalid
7318
+ throw new InvalidMnemonicError();
7319
+ }
7320
+ const seed = mnemonicToSeedSync(mnemonic, password);
7321
+ const sk = generateSecretKey(seed, derivationPath, curve);
7322
+ return new InMemorySigner(sk);
7323
+ }
7324
+ /**
7325
+ *
7326
+ * @param key Encoded private key
7327
+ * @param passphrase Passphrase to decrypt the private key if it is encrypted
7328
+ * @throws InvalidKeyError
7329
+ *
7330
+ */
7331
+ constructor(key, passphrase) {
7332
+ _InMemorySigner_key.set(this, void 0);
7333
+ const keyPrefixes = [
7334
+ PrefixV2.Ed25519EncryptedSeed,
7335
+ PrefixV2.Ed25519Seed,
7336
+ PrefixV2.Ed25519SecretKey,
7337
+ PrefixV2.Secp256k1EncryptedSecretKey,
7338
+ PrefixV2.Secp256k1SecretKey,
4825
7339
  PrefixV2.P256EncryptedSecretKey,
4826
7340
  PrefixV2.P256SecretKey,
4827
7341
  PrefixV2.BLS12_381EncryptedSecretKey,
4828
7342
  PrefixV2.BLS12_381SecretKey,
7343
+ PrefixV2.MLDSA44EncryptedSecretKey,
7344
+ PrefixV2.MLDSA44SecretKey,
4829
7345
  ];
4830
7346
  const pre = (() => {
4831
7347
  try {
@@ -4839,7 +7355,8 @@ class InMemorySigner {
4839
7355
  const encrypted = pre === PrefixV2.Ed25519EncryptedSeed ||
4840
7356
  pre === PrefixV2.Secp256k1EncryptedSecretKey ||
4841
7357
  pre === PrefixV2.P256EncryptedSecretKey ||
4842
- pre === PrefixV2.BLS12_381EncryptedSecretKey;
7358
+ pre === PrefixV2.BLS12_381EncryptedSecretKey ||
7359
+ pre === PrefixV2.MLDSA44EncryptedSecretKey;
4843
7360
  let decrypt;
4844
7361
  if (encrypted) {
4845
7362
  if (!passphrase) {
@@ -4878,6 +7395,10 @@ class InMemorySigner {
4878
7395
  case PrefixV2.BLS12_381SecretKey:
4879
7396
  __classPrivateFieldSet(this, _InMemorySigner_key, new BLSKey(key, decrypt), "f");
4880
7397
  break;
7398
+ case PrefixV2.MLDSA44EncryptedSecretKey:
7399
+ case PrefixV2.MLDSA44SecretKey:
7400
+ __classPrivateFieldSet(this, _InMemorySigner_key, new MLDSAKey(key, decrypt), "f");
7401
+ break;
4881
7402
  }
4882
7403
  }
4883
7404
  /**
@@ -4889,13 +7410,17 @@ class InMemorySigner {
4889
7410
  const msg = typeof message == 'string' ? hex2buf(message) : message;
4890
7411
  const watermarkMsg = watermark !== undefined ? mergebuf(watermark, msg) : msg;
4891
7412
  const { rawSignature, sig: signature, prefixSig: prefixedSignature, } = await __classPrivateFieldGet(this, _InMemorySigner_key, "f").sign(watermarkMsg);
7413
+ // Variable-length operation signatures carry the signature-prefix marker
7414
+ // and scheme tag before the complete signature payload (Octez signature_v3).
7415
+ const signatureTag = __classPrivateFieldGet(this, _InMemorySigner_key, "f") instanceof MLDSAKey ? 4 : __classPrivateFieldGet(this, _InMemorySigner_key, "f") instanceof BLSKey ? 3 : undefined;
7416
+ const signatureBytes = signatureTag === undefined
7417
+ ? rawSignature
7418
+ : mergebuf(new Uint8Array([255, signatureTag]), rawSignature);
4892
7419
  return {
4893
7420
  bytes: buf2hex(msg),
4894
7421
  sig: signature,
4895
7422
  prefixSig: prefixedSignature,
4896
- sbytes: buf2hex(mergebuf(msg,
4897
- // bls only Signature_prefix ff03 ref:https://octez.tezos.com/docs/shell/p2p_api.html#signature-prefix-tag-255 & https://octez.tezos.com/docs/shell/p2p_api.html#bls-prefix-tag-3
4898
- isPOP(__classPrivateFieldGet(this, _InMemorySigner_key, "f")) ? mergebuf(new Uint8Array([255, 3]), rawSignature) : rawSignature)),
7423
+ sbytes: buf2hex(mergebuf(msg, signatureBytes)),
4899
7424
  };
4900
7425
  }
4901
7426
  async provePossession() {
@@ -4935,6 +7460,7 @@ function publicKeyFromString(src) {
4935
7460
  PrefixV2.Secp256k1PublicKey,
4936
7461
  PrefixV2.P256PublicKey,
4937
7462
  PrefixV2.BLS12_381PublicKey,
7463
+ PrefixV2.MLDSA44PublicKey,
4938
7464
  ]);
4939
7465
  switch (pre) {
4940
7466
  case PrefixV2.Ed25519PublicKey:
@@ -4945,13 +7471,15 @@ function publicKeyFromString(src) {
4945
7471
  return new ECPublicKey(keyData, 'p256');
4946
7472
  case PrefixV2.BLS12_381PublicKey:
4947
7473
  return new BLSPublicKey(keyData);
7474
+ case PrefixV2.MLDSA44PublicKey:
7475
+ return new MLDSAPublicKey(keyData);
4948
7476
  }
4949
7477
  }
4950
7478
 
4951
7479
  // IMPORTANT: THIS FILE IS AUTO GENERATED! DO NOT MANUALLY EDIT!
4952
7480
  const VERSION = {
4953
- "commitHash": "13f62cd47ea018312f100b660d0225604c757afa",
4954
- "version": "25.0.0"
7481
+ "commitHash": "a1d45363559ba27998bbc263b69c961710e4710a",
7482
+ "version": "25.1.0-beta0"
4955
7483
  };
4956
7484
 
4957
7485
  export { ecdsa as ECDSA, ed25519 as Ed25519, Hard, InMemorySigner, InvalidPassphraseError, Path, VERSION, generateSecretKey, publicKeyFromString };