@waku/discovery 0.0.9-383e0b2.0 → 0.0.9-4997440.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/index.js +654 -682
- package/dist/.tsbuildinfo +1 -1
- package/package.json +1 -1
package/bundle/index.js
CHANGED
@@ -249,22 +249,31 @@ function isDefined(value) {
|
|
249
249
|
return Boolean(value);
|
250
250
|
}
|
251
251
|
|
252
|
+
const crypto$2 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
253
|
+
|
252
254
|
/**
|
253
|
-
*
|
255
|
+
* Utilities for hex, bytes, CSPRNG.
|
254
256
|
* @module
|
255
257
|
*/
|
258
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
259
|
+
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
260
|
+
// node.js versions earlier than v19 don't declare it in global scope.
|
261
|
+
// For node.js, package.json#exports field mapping rewrites import
|
262
|
+
// from `crypto` to `cryptoNode`, which imports native module.
|
263
|
+
// Makes the utils un-importable in browsers without a bundler.
|
264
|
+
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
265
|
+
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
266
|
+
function isBytes$3(a) {
|
267
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
268
|
+
}
|
256
269
|
/** Asserts something is positive integer. */
|
257
270
|
function anumber(n) {
|
258
271
|
if (!Number.isSafeInteger(n) || n < 0)
|
259
272
|
throw new Error('positive integer expected, got ' + n);
|
260
273
|
}
|
261
|
-
/** Is number an Uint8Array? Copied from utils for perf. */
|
262
|
-
function isBytes$2(a) {
|
263
|
-
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
264
|
-
}
|
265
274
|
/** Asserts something is Uint8Array. */
|
266
|
-
function abytes$
|
267
|
-
if (!isBytes$
|
275
|
+
function abytes$2(b, ...lengths) {
|
276
|
+
if (!isBytes$3(b))
|
268
277
|
throw new Error('Uint8Array expected');
|
269
278
|
if (lengths.length > 0 && !lengths.includes(b.length))
|
270
279
|
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
|
@@ -272,7 +281,7 @@ function abytes$1(b, ...lengths) {
|
|
272
281
|
/** Asserts something is hash */
|
273
282
|
function ahash(h) {
|
274
283
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
275
|
-
throw new Error('Hash should be wrapped by utils.
|
284
|
+
throw new Error('Hash should be wrapped by utils.createHasher');
|
276
285
|
anumber(h.outputLen);
|
277
286
|
anumber(h.blockLen);
|
278
287
|
}
|
@@ -285,27 +294,19 @@ function aexists(instance, checkFinished = true) {
|
|
285
294
|
}
|
286
295
|
/** Asserts output is properly-sized byte array */
|
287
296
|
function aoutput(out, instance) {
|
288
|
-
abytes$
|
297
|
+
abytes$2(out);
|
289
298
|
const min = instance.outputLen;
|
290
299
|
if (out.length < min) {
|
291
300
|
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
292
301
|
}
|
293
302
|
}
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
*/
|
301
|
-
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
302
|
-
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
303
|
-
// node.js versions earlier than v19 don't declare it in global scope.
|
304
|
-
// For node.js, package.json#exports field mapping rewrites import
|
305
|
-
// from `crypto` to `cryptoNode`, which imports native module.
|
306
|
-
// Makes the utils un-importable in browsers without a bundler.
|
307
|
-
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
308
|
-
// Cast array to view
|
303
|
+
/** Zeroize a byte array. Warning: JS provides no guarantees. */
|
304
|
+
function clean(...arrays) {
|
305
|
+
for (let i = 0; i < arrays.length; i++) {
|
306
|
+
arrays[i].fill(0);
|
307
|
+
}
|
308
|
+
}
|
309
|
+
/** Create DataView of an array for easy byte-level manipulation. */
|
309
310
|
function createView(arr) {
|
310
311
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
311
312
|
}
|
@@ -314,12 +315,12 @@ function rotr(word, shift) {
|
|
314
315
|
return (word << (32 - shift)) | (word >>> shift);
|
315
316
|
}
|
316
317
|
/**
|
317
|
-
*
|
318
|
-
* @example utf8ToBytes('abc') //
|
318
|
+
* Converts string to bytes using UTF8 encoding.
|
319
|
+
* @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
|
319
320
|
*/
|
320
|
-
function utf8ToBytes$
|
321
|
+
function utf8ToBytes$1(str) {
|
321
322
|
if (typeof str !== 'string')
|
322
|
-
throw new Error('
|
323
|
+
throw new Error('string expected');
|
323
324
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
324
325
|
}
|
325
326
|
/**
|
@@ -329,18 +330,16 @@ function utf8ToBytes$2(str) {
|
|
329
330
|
*/
|
330
331
|
function toBytes$1(data) {
|
331
332
|
if (typeof data === 'string')
|
332
|
-
data = utf8ToBytes$
|
333
|
-
abytes$
|
333
|
+
data = utf8ToBytes$1(data);
|
334
|
+
abytes$2(data);
|
334
335
|
return data;
|
335
336
|
}
|
336
|
-
/**
|
337
|
-
* Copies several Uint8Arrays into one.
|
338
|
-
*/
|
337
|
+
/** Copies several Uint8Arrays into one. */
|
339
338
|
function concatBytes$2(...arrays) {
|
340
339
|
let sum = 0;
|
341
340
|
for (let i = 0; i < arrays.length; i++) {
|
342
341
|
const a = arrays[i];
|
343
|
-
abytes$
|
342
|
+
abytes$2(a);
|
344
343
|
sum += a.length;
|
345
344
|
}
|
346
345
|
const res = new Uint8Array(sum);
|
@@ -353,13 +352,9 @@ function concatBytes$2(...arrays) {
|
|
353
352
|
}
|
354
353
|
/** For runtime check if class implements interface */
|
355
354
|
class Hash {
|
356
|
-
// Safe version that clones internal state
|
357
|
-
clone() {
|
358
|
-
return this._cloneInto();
|
359
|
-
}
|
360
355
|
}
|
361
356
|
/** Wraps hash function, creating an interface on top of it */
|
362
|
-
function
|
357
|
+
function createHasher(hashCons) {
|
363
358
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
364
359
|
const tmp = hashCons();
|
365
360
|
hashC.outputLen = tmp.outputLen;
|
@@ -374,7 +369,7 @@ function randomBytes(bytesLength = 32) {
|
|
374
369
|
}
|
375
370
|
// Legacy Node.js compatibility
|
376
371
|
if (crypto$2 && typeof crypto$2.randomBytes === 'function') {
|
377
|
-
return crypto$2.randomBytes(bytesLength);
|
372
|
+
return Uint8Array.from(crypto$2.randomBytes(bytesLength));
|
378
373
|
}
|
379
374
|
throw new Error('crypto.getRandomValues must be defined');
|
380
375
|
}
|
@@ -411,21 +406,22 @@ function Maj(a, b, c) {
|
|
411
406
|
class HashMD extends Hash {
|
412
407
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
413
408
|
super();
|
414
|
-
this.blockLen = blockLen;
|
415
|
-
this.outputLen = outputLen;
|
416
|
-
this.padOffset = padOffset;
|
417
|
-
this.isLE = isLE;
|
418
409
|
this.finished = false;
|
419
410
|
this.length = 0;
|
420
411
|
this.pos = 0;
|
421
412
|
this.destroyed = false;
|
413
|
+
this.blockLen = blockLen;
|
414
|
+
this.outputLen = outputLen;
|
415
|
+
this.padOffset = padOffset;
|
416
|
+
this.isLE = isLE;
|
422
417
|
this.buffer = new Uint8Array(blockLen);
|
423
418
|
this.view = createView(this.buffer);
|
424
419
|
}
|
425
420
|
update(data) {
|
426
421
|
aexists(this);
|
427
|
-
const { view, buffer, blockLen } = this;
|
428
422
|
data = toBytes$1(data);
|
423
|
+
abytes$2(data);
|
424
|
+
const { view, buffer, blockLen } = this;
|
429
425
|
const len = data.length;
|
430
426
|
for (let pos = 0; pos < len;) {
|
431
427
|
const take = Math.min(blockLen - this.pos, len - pos);
|
@@ -459,7 +455,7 @@ class HashMD extends Hash {
|
|
459
455
|
let { pos } = this;
|
460
456
|
// append the bit '1' to the message
|
461
457
|
buffer[pos++] = 0b10000000;
|
462
|
-
this.buffer.subarray(pos)
|
458
|
+
clean(this.buffer.subarray(pos));
|
463
459
|
// we have less than padOffset left in buffer, so we cannot put length in
|
464
460
|
// current block, need process it and pad again
|
465
461
|
if (this.padOffset > blockLen - pos) {
|
@@ -497,28 +493,90 @@ class HashMD extends Hash {
|
|
497
493
|
to || (to = new this.constructor());
|
498
494
|
to.set(...this.get());
|
499
495
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
496
|
+
to.destroyed = destroyed;
|
497
|
+
to.finished = finished;
|
500
498
|
to.length = length;
|
501
499
|
to.pos = pos;
|
502
|
-
to.finished = finished;
|
503
|
-
to.destroyed = destroyed;
|
504
500
|
if (length % blockLen)
|
505
501
|
to.buffer.set(buffer);
|
506
502
|
return to;
|
507
503
|
}
|
504
|
+
clone() {
|
505
|
+
return this._cloneInto();
|
506
|
+
}
|
508
507
|
}
|
508
|
+
/**
|
509
|
+
* Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
|
510
|
+
* Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
|
511
|
+
*/
|
512
|
+
/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
|
513
|
+
const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
514
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
515
|
+
]);
|
516
|
+
/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */
|
517
|
+
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
518
|
+
0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
|
519
|
+
0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
|
520
|
+
]);
|
509
521
|
|
510
522
|
/**
|
511
|
-
*
|
512
|
-
*
|
513
|
-
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
514
|
-
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
515
|
-
*
|
516
|
-
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
523
|
+
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
524
|
+
* @todo re-check https://issues.chromium.org/issues/42212588
|
517
525
|
* @module
|
518
526
|
*/
|
519
|
-
|
527
|
+
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
528
|
+
const _32n = /* @__PURE__ */ BigInt(32);
|
529
|
+
function fromBig(n, le = false) {
|
530
|
+
if (le)
|
531
|
+
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
532
|
+
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
533
|
+
}
|
534
|
+
function split(lst, le = false) {
|
535
|
+
const len = lst.length;
|
536
|
+
let Ah = new Uint32Array(len);
|
537
|
+
let Al = new Uint32Array(len);
|
538
|
+
for (let i = 0; i < len; i++) {
|
539
|
+
const { h, l } = fromBig(lst[i], le);
|
540
|
+
[Ah[i], Al[i]] = [h, l];
|
541
|
+
}
|
542
|
+
return [Ah, Al];
|
543
|
+
}
|
544
|
+
// for Shift in [0, 32)
|
545
|
+
const shrSH = (h, _l, s) => h >>> s;
|
546
|
+
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
547
|
+
// Right rotate for Shift in [1, 32)
|
548
|
+
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
549
|
+
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
550
|
+
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
|
551
|
+
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
552
|
+
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
553
|
+
// JS uses 32-bit signed integers for bitwise operations which means we cannot
|
554
|
+
// simple take carry out of low bit sum by shift, we need to use division.
|
555
|
+
function add(Ah, Al, Bh, Bl) {
|
556
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
557
|
+
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
558
|
+
}
|
559
|
+
// Addition with more than 2 elements
|
560
|
+
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
561
|
+
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
562
|
+
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
563
|
+
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
564
|
+
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
565
|
+
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
566
|
+
|
567
|
+
/**
|
568
|
+
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
569
|
+
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
570
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
571
|
+
* [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
572
|
+
* @module
|
573
|
+
*/
|
574
|
+
/**
|
575
|
+
* Round constants:
|
576
|
+
* First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
|
577
|
+
*/
|
520
578
|
// prettier-ignore
|
521
|
-
const SHA256_K = /* @__PURE__ */
|
579
|
+
const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
522
580
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
523
581
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
524
582
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
@@ -528,19 +586,11 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
528
586
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
529
587
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
530
588
|
]);
|
531
|
-
/**
|
532
|
-
// prettier-ignore
|
533
|
-
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
534
|
-
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
535
|
-
]);
|
536
|
-
/**
|
537
|
-
* Temporary buffer, not used to store anything between runs.
|
538
|
-
* Named this way because it matches specification.
|
539
|
-
*/
|
589
|
+
/** Reusable temporary buffer. "W" comes straight from spec. */
|
540
590
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
541
591
|
class SHA256 extends HashMD {
|
542
|
-
constructor() {
|
543
|
-
super(64,
|
592
|
+
constructor(outputLen = 32) {
|
593
|
+
super(64, outputLen, 8, false);
|
544
594
|
// We cannot use array here since array allows indexing by variable
|
545
595
|
// which means optimizer/compiler cannot use registers.
|
546
596
|
this.A = SHA256_IV[0] | 0;
|
@@ -606,15 +656,192 @@ class SHA256 extends HashMD {
|
|
606
656
|
this.set(A, B, C, D, E, F, G, H);
|
607
657
|
}
|
608
658
|
roundClean() {
|
609
|
-
SHA256_W
|
659
|
+
clean(SHA256_W);
|
610
660
|
}
|
611
661
|
destroy() {
|
612
662
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
613
|
-
this.buffer
|
663
|
+
clean(this.buffer);
|
664
|
+
}
|
665
|
+
}
|
666
|
+
// SHA2-512 is slower than sha256 in js because u64 operations are slow.
|
667
|
+
// Round contants
|
668
|
+
// First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409
|
669
|
+
// prettier-ignore
|
670
|
+
const K512 = /* @__PURE__ */ (() => split([
|
671
|
+
'0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
|
672
|
+
'0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
|
673
|
+
'0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
|
674
|
+
'0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
|
675
|
+
'0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
|
676
|
+
'0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
|
677
|
+
'0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
|
678
|
+
'0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
|
679
|
+
'0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
|
680
|
+
'0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
|
681
|
+
'0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
|
682
|
+
'0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
|
683
|
+
'0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
|
684
|
+
'0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
|
685
|
+
'0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
|
686
|
+
'0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
|
687
|
+
'0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
|
688
|
+
'0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
|
689
|
+
'0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
|
690
|
+
'0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
|
691
|
+
].map(n => BigInt(n))))();
|
692
|
+
const SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
693
|
+
const SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
694
|
+
// Reusable temporary buffers
|
695
|
+
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
696
|
+
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
697
|
+
class SHA512 extends HashMD {
|
698
|
+
constructor(outputLen = 64) {
|
699
|
+
super(128, outputLen, 16, false);
|
700
|
+
// We cannot use array here since array allows indexing by variable
|
701
|
+
// which means optimizer/compiler cannot use registers.
|
702
|
+
// h -- high 32 bits, l -- low 32 bits
|
703
|
+
this.Ah = SHA512_IV[0] | 0;
|
704
|
+
this.Al = SHA512_IV[1] | 0;
|
705
|
+
this.Bh = SHA512_IV[2] | 0;
|
706
|
+
this.Bl = SHA512_IV[3] | 0;
|
707
|
+
this.Ch = SHA512_IV[4] | 0;
|
708
|
+
this.Cl = SHA512_IV[5] | 0;
|
709
|
+
this.Dh = SHA512_IV[6] | 0;
|
710
|
+
this.Dl = SHA512_IV[7] | 0;
|
711
|
+
this.Eh = SHA512_IV[8] | 0;
|
712
|
+
this.El = SHA512_IV[9] | 0;
|
713
|
+
this.Fh = SHA512_IV[10] | 0;
|
714
|
+
this.Fl = SHA512_IV[11] | 0;
|
715
|
+
this.Gh = SHA512_IV[12] | 0;
|
716
|
+
this.Gl = SHA512_IV[13] | 0;
|
717
|
+
this.Hh = SHA512_IV[14] | 0;
|
718
|
+
this.Hl = SHA512_IV[15] | 0;
|
719
|
+
}
|
720
|
+
// prettier-ignore
|
721
|
+
get() {
|
722
|
+
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
723
|
+
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
724
|
+
}
|
725
|
+
// prettier-ignore
|
726
|
+
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
727
|
+
this.Ah = Ah | 0;
|
728
|
+
this.Al = Al | 0;
|
729
|
+
this.Bh = Bh | 0;
|
730
|
+
this.Bl = Bl | 0;
|
731
|
+
this.Ch = Ch | 0;
|
732
|
+
this.Cl = Cl | 0;
|
733
|
+
this.Dh = Dh | 0;
|
734
|
+
this.Dl = Dl | 0;
|
735
|
+
this.Eh = Eh | 0;
|
736
|
+
this.El = El | 0;
|
737
|
+
this.Fh = Fh | 0;
|
738
|
+
this.Fl = Fl | 0;
|
739
|
+
this.Gh = Gh | 0;
|
740
|
+
this.Gl = Gl | 0;
|
741
|
+
this.Hh = Hh | 0;
|
742
|
+
this.Hl = Hl | 0;
|
743
|
+
}
|
744
|
+
process(view, offset) {
|
745
|
+
// Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
|
746
|
+
for (let i = 0; i < 16; i++, offset += 4) {
|
747
|
+
SHA512_W_H[i] = view.getUint32(offset);
|
748
|
+
SHA512_W_L[i] = view.getUint32((offset += 4));
|
749
|
+
}
|
750
|
+
for (let i = 16; i < 80; i++) {
|
751
|
+
// s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
|
752
|
+
const W15h = SHA512_W_H[i - 15] | 0;
|
753
|
+
const W15l = SHA512_W_L[i - 15] | 0;
|
754
|
+
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
755
|
+
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
756
|
+
// s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
|
757
|
+
const W2h = SHA512_W_H[i - 2] | 0;
|
758
|
+
const W2l = SHA512_W_L[i - 2] | 0;
|
759
|
+
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
760
|
+
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
761
|
+
// SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
|
762
|
+
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
763
|
+
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
764
|
+
SHA512_W_H[i] = SUMh | 0;
|
765
|
+
SHA512_W_L[i] = SUMl | 0;
|
766
|
+
}
|
767
|
+
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
768
|
+
// Compression function main loop, 80 rounds
|
769
|
+
for (let i = 0; i < 80; i++) {
|
770
|
+
// S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
|
771
|
+
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
772
|
+
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
773
|
+
//const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
|
774
|
+
const CHIh = (Eh & Fh) ^ (~Eh & Gh);
|
775
|
+
const CHIl = (El & Fl) ^ (~El & Gl);
|
776
|
+
// T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
|
777
|
+
// prettier-ignore
|
778
|
+
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
779
|
+
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
780
|
+
const T1l = T1ll | 0;
|
781
|
+
// S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
|
782
|
+
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
783
|
+
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
784
|
+
const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
|
785
|
+
const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
|
786
|
+
Hh = Gh | 0;
|
787
|
+
Hl = Gl | 0;
|
788
|
+
Gh = Fh | 0;
|
789
|
+
Gl = Fl | 0;
|
790
|
+
Fh = Eh | 0;
|
791
|
+
Fl = El | 0;
|
792
|
+
({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
793
|
+
Dh = Ch | 0;
|
794
|
+
Dl = Cl | 0;
|
795
|
+
Ch = Bh | 0;
|
796
|
+
Cl = Bl | 0;
|
797
|
+
Bh = Ah | 0;
|
798
|
+
Bl = Al | 0;
|
799
|
+
const All = add3L(T1l, sigma0l, MAJl);
|
800
|
+
Ah = add3H(All, T1h, sigma0h, MAJh);
|
801
|
+
Al = All | 0;
|
802
|
+
}
|
803
|
+
// Add the compressed chunk to the current hash value
|
804
|
+
({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
805
|
+
({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
806
|
+
({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
807
|
+
({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
808
|
+
({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
809
|
+
({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
810
|
+
({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
811
|
+
({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
812
|
+
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
813
|
+
}
|
814
|
+
roundClean() {
|
815
|
+
clean(SHA512_W_H, SHA512_W_L);
|
816
|
+
}
|
817
|
+
destroy() {
|
818
|
+
clean(this.buffer);
|
819
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
614
820
|
}
|
615
821
|
}
|
616
|
-
/**
|
617
|
-
|
822
|
+
/**
|
823
|
+
* SHA2-256 hash function from RFC 4634.
|
824
|
+
*
|
825
|
+
* It is the fastest JS hash, even faster than Blake3.
|
826
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
827
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
828
|
+
*/
|
829
|
+
const sha256$2 = /* @__PURE__ */ createHasher(() => new SHA256());
|
830
|
+
/** SHA2-512 hash function from RFC 4634. */
|
831
|
+
const sha512 = /* @__PURE__ */ createHasher(() => new SHA512());
|
832
|
+
|
833
|
+
/**
|
834
|
+
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
835
|
+
*
|
836
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
837
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
838
|
+
*
|
839
|
+
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
840
|
+
* @module
|
841
|
+
* @deprecated
|
842
|
+
*/
|
843
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
844
|
+
const sha256$1 = sha256$2;
|
618
845
|
|
619
846
|
function equals$2(aa, bb) {
|
620
847
|
if (aa === bb)
|
@@ -1940,7 +2167,7 @@ const bytesToUtf8 = (b) => toString$1(b, "utf8");
|
|
1940
2167
|
/**
|
1941
2168
|
* Encode utf-8 string to byte array.
|
1942
2169
|
*/
|
1943
|
-
const utf8ToBytes
|
2170
|
+
const utf8ToBytes = (s) => fromString(s, "utf8");
|
1944
2171
|
|
1945
2172
|
const decodeRelayShard = (bytes) => {
|
1946
2173
|
// explicitly converting to Uint8Array to avoid Buffer
|
@@ -2814,7 +3041,7 @@ var nodeCrypto = /*#__PURE__*/Object.freeze({
|
|
2814
3041
|
/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
|
2815
3042
|
const _0n$5 = BigInt(0);
|
2816
3043
|
const _1n$7 = BigInt(1);
|
2817
|
-
const _2n$
|
3044
|
+
const _2n$4 = BigInt(2);
|
2818
3045
|
const _3n$2 = BigInt(3);
|
2819
3046
|
const _8n$3 = BigInt(8);
|
2820
3047
|
const CURVE = Object.freeze({
|
@@ -2827,7 +3054,7 @@ const CURVE = Object.freeze({
|
|
2827
3054
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
2828
3055
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
2829
3056
|
});
|
2830
|
-
const divNearest$1 = (a, b) => (a + b / _2n$
|
3057
|
+
const divNearest$1 = (a, b) => (a + b / _2n$4) / b;
|
2831
3058
|
const endo = {
|
2832
3059
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
2833
3060
|
splitScalar(k) {
|
@@ -2916,12 +3143,12 @@ class JacobianPoint {
|
|
2916
3143
|
const B = mod$1(Y1 * Y1);
|
2917
3144
|
const C = mod$1(B * B);
|
2918
3145
|
const x1b = X1 + B;
|
2919
|
-
const D = mod$1(_2n$
|
3146
|
+
const D = mod$1(_2n$4 * (mod$1(x1b * x1b) - A - C));
|
2920
3147
|
const E = mod$1(_3n$2 * A);
|
2921
3148
|
const F = mod$1(E * E);
|
2922
|
-
const X3 = mod$1(F - _2n$
|
3149
|
+
const X3 = mod$1(F - _2n$4 * D);
|
2923
3150
|
const Y3 = mod$1(E * (D - X3) - _8n$3 * C);
|
2924
|
-
const Z3 = mod$1(_2n$
|
3151
|
+
const Z3 = mod$1(_2n$4 * Y1 * Z1);
|
2925
3152
|
return new JacobianPoint(X3, Y3, Z3);
|
2926
3153
|
}
|
2927
3154
|
add(other) {
|
@@ -2951,7 +3178,7 @@ class JacobianPoint {
|
|
2951
3178
|
const HH = mod$1(H * H);
|
2952
3179
|
const HHH = mod$1(H * HH);
|
2953
3180
|
const V = mod$1(U1 * HH);
|
2954
|
-
const X3 = mod$1(r * r - HHH - _2n$
|
3181
|
+
const X3 = mod$1(r * r - HHH - _2n$4 * V);
|
2955
3182
|
const Y3 = mod$1(r * (V - X3) - S1 * HHH);
|
2956
3183
|
const Z3 = mod$1(Z1 * Z2 * H);
|
2957
3184
|
return new JacobianPoint(X3, Y3, Z3);
|
@@ -3112,7 +3339,7 @@ class Point {
|
|
3112
3339
|
pointPrecomputes$1.delete(this);
|
3113
3340
|
}
|
3114
3341
|
hasEvenY() {
|
3115
|
-
return this.y % _2n$
|
3342
|
+
return this.y % _2n$4 === _0n$5;
|
3116
3343
|
}
|
3117
3344
|
static fromCompressedHex(bytes) {
|
3118
3345
|
const isShort = bytes.length === 32;
|
@@ -3271,7 +3498,7 @@ class Signature {
|
|
3271
3498
|
this.assertValidity();
|
3272
3499
|
}
|
3273
3500
|
static fromCompact(hex) {
|
3274
|
-
const arr = hex
|
3501
|
+
const arr = isBytes$2(hex);
|
3275
3502
|
const name = 'Signature.fromCompact';
|
3276
3503
|
if (typeof hex !== 'string' && !arr)
|
3277
3504
|
throw new TypeError(`${name}: Expected string or Uint8Array`);
|
@@ -3281,7 +3508,7 @@ class Signature {
|
|
3281
3508
|
return new Signature(hexToNumber$1(str.slice(0, 64)), hexToNumber$1(str.slice(64, 128)));
|
3282
3509
|
}
|
3283
3510
|
static fromDER(hex) {
|
3284
|
-
const arr = hex
|
3511
|
+
const arr = isBytes$2(hex);
|
3285
3512
|
if (typeof hex !== 'string' && !arr)
|
3286
3513
|
throw new TypeError(`Signature.fromDER: Expected string or Uint8Array`);
|
3287
3514
|
const { r, s } = parseDERSignature(arr ? hex : hexToBytes$1(hex));
|
@@ -3330,9 +3557,15 @@ class Signature {
|
|
3330
3557
|
return numTo32bStr(this.r) + numTo32bStr(this.s);
|
3331
3558
|
}
|
3332
3559
|
}
|
3560
|
+
function isBytes$2(a) {
|
3561
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
3562
|
+
}
|
3563
|
+
function abytes$1(item) {
|
3564
|
+
if (!isBytes$2(item))
|
3565
|
+
throw new Error('Uint8Array expected');
|
3566
|
+
}
|
3333
3567
|
function concatBytes$1(...arrays) {
|
3334
|
-
|
3335
|
-
throw new Error('Uint8Array list expected');
|
3568
|
+
arrays.every(abytes$1);
|
3336
3569
|
if (arrays.length === 1)
|
3337
3570
|
return arrays[0];
|
3338
3571
|
const length = arrays.reduce((a, arr) => a + arr.length, 0);
|
@@ -3344,16 +3577,44 @@ function concatBytes$1(...arrays) {
|
|
3344
3577
|
}
|
3345
3578
|
return result;
|
3346
3579
|
}
|
3347
|
-
const hexes$1 = Array.from({ length: 256 }, (
|
3348
|
-
function bytesToHex$1(
|
3349
|
-
|
3350
|
-
throw new Error('Expected Uint8Array');
|
3580
|
+
const hexes$1 = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
3581
|
+
function bytesToHex$1(bytes) {
|
3582
|
+
abytes$1(bytes);
|
3351
3583
|
let hex = '';
|
3352
|
-
for (let i = 0; i <
|
3353
|
-
hex += hexes$1[
|
3584
|
+
for (let i = 0; i < bytes.length; i++) {
|
3585
|
+
hex += hexes$1[bytes[i]];
|
3354
3586
|
}
|
3355
3587
|
return hex;
|
3356
3588
|
}
|
3589
|
+
const asciis$1 = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
3590
|
+
function asciiToBase16$1(ch) {
|
3591
|
+
if (ch >= asciis$1._0 && ch <= asciis$1._9)
|
3592
|
+
return ch - asciis$1._0;
|
3593
|
+
if (ch >= asciis$1.A && ch <= asciis$1.F)
|
3594
|
+
return ch - (asciis$1.A - 10);
|
3595
|
+
if (ch >= asciis$1.a && ch <= asciis$1.f)
|
3596
|
+
return ch - (asciis$1.a - 10);
|
3597
|
+
return;
|
3598
|
+
}
|
3599
|
+
function hexToBytes$1(hex) {
|
3600
|
+
if (typeof hex !== 'string')
|
3601
|
+
throw new Error('hex string expected, got ' + typeof hex);
|
3602
|
+
const hl = hex.length;
|
3603
|
+
const al = hl / 2;
|
3604
|
+
if (hl % 2)
|
3605
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
3606
|
+
const array = new Uint8Array(al);
|
3607
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
3608
|
+
const n1 = asciiToBase16$1(hex.charCodeAt(hi));
|
3609
|
+
const n2 = asciiToBase16$1(hex.charCodeAt(hi + 1));
|
3610
|
+
if (n1 === undefined || n2 === undefined) {
|
3611
|
+
const char = hex[hi] + hex[hi + 1];
|
3612
|
+
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
3613
|
+
}
|
3614
|
+
array[ai] = n1 * 16 + n2;
|
3615
|
+
}
|
3616
|
+
return array;
|
3617
|
+
}
|
3357
3618
|
const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');
|
3358
3619
|
function numTo32bStr(num) {
|
3359
3620
|
if (typeof num !== 'bigint')
|
@@ -3378,28 +3639,11 @@ function hexToNumber$1(hex) {
|
|
3378
3639
|
}
|
3379
3640
|
return BigInt(`0x${hex}`);
|
3380
3641
|
}
|
3381
|
-
function hexToBytes$1(hex) {
|
3382
|
-
if (typeof hex !== 'string') {
|
3383
|
-
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
|
3384
|
-
}
|
3385
|
-
if (hex.length % 2)
|
3386
|
-
throw new Error('hexToBytes: received invalid unpadded hex' + hex.length);
|
3387
|
-
const array = new Uint8Array(hex.length / 2);
|
3388
|
-
for (let i = 0; i < array.length; i++) {
|
3389
|
-
const j = i * 2;
|
3390
|
-
const hexByte = hex.slice(j, j + 2);
|
3391
|
-
const byte = Number.parseInt(hexByte, 16);
|
3392
|
-
if (Number.isNaN(byte) || byte < 0)
|
3393
|
-
throw new Error('Invalid byte sequence');
|
3394
|
-
array[i] = byte;
|
3395
|
-
}
|
3396
|
-
return array;
|
3397
|
-
}
|
3398
3642
|
function bytesToNumber(bytes) {
|
3399
3643
|
return hexToNumber$1(bytesToHex$1(bytes));
|
3400
3644
|
}
|
3401
3645
|
function ensureBytes$1(hex) {
|
3402
|
-
return hex
|
3646
|
+
return isBytes$2(hex) ? Uint8Array.from(hex) : hexToBytes$1(hex);
|
3403
3647
|
}
|
3404
3648
|
function normalizeScalar(num) {
|
3405
3649
|
if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0)
|
@@ -3433,7 +3677,7 @@ function sqrtMod$1(x) {
|
|
3433
3677
|
const b3 = (b2 * b2 * x) % P;
|
3434
3678
|
const b6 = (pow2$1(b3, _3n$2) * b3) % P;
|
3435
3679
|
const b9 = (pow2$1(b6, _3n$2) * b3) % P;
|
3436
|
-
const b11 = (pow2$1(b9, _2n$
|
3680
|
+
const b11 = (pow2$1(b9, _2n$4) * b2) % P;
|
3437
3681
|
const b22 = (pow2$1(b11, _11n) * b11) % P;
|
3438
3682
|
const b44 = (pow2$1(b22, _22n) * b22) % P;
|
3439
3683
|
const b88 = (pow2$1(b44, _44n) * b44) % P;
|
@@ -3442,7 +3686,7 @@ function sqrtMod$1(x) {
|
|
3442
3686
|
const b223 = (pow2$1(b220, _3n$2) * b3) % P;
|
3443
3687
|
const t1 = (pow2$1(b223, _23n) * b22) % P;
|
3444
3688
|
const t2 = (pow2$1(t1, _6n) * b2) % P;
|
3445
|
-
const rt = pow2$1(t2, _2n$
|
3689
|
+
const rt = pow2$1(t2, _2n$4);
|
3446
3690
|
const xc = (rt * rt) % P;
|
3447
3691
|
if (xc !== x)
|
3448
3692
|
throw new Error('Cannot find square root');
|
@@ -3607,7 +3851,7 @@ function normalizePrivateKey(key) {
|
|
3607
3851
|
throw new Error('Expected 32 bytes of private key');
|
3608
3852
|
num = hexToNumber$1(key);
|
3609
3853
|
}
|
3610
|
-
else if (key
|
3854
|
+
else if (isBytes$2(key)) {
|
3611
3855
|
if (key.length !== groupLen)
|
3612
3856
|
throw new Error('Expected 32 bytes of private key');
|
3613
3857
|
num = bytesToNumber(key);
|
@@ -6825,273 +7069,46 @@ function getOID(curve) {
|
|
6825
7069
|
return OID_256;
|
6826
7070
|
}
|
6827
7071
|
if (curve === 'P-384') {
|
6828
|
-
return OID_384;
|
6829
|
-
}
|
6830
|
-
if (curve === 'P-521') {
|
6831
|
-
return OID_521;
|
6832
|
-
}
|
6833
|
-
throw new InvalidParametersError(`Invalid curve ${curve}`);
|
6834
|
-
}
|
6835
|
-
|
6836
|
-
class ECDSAPublicKey {
|
6837
|
-
type = 'ECDSA';
|
6838
|
-
jwk;
|
6839
|
-
_raw;
|
6840
|
-
constructor(jwk) {
|
6841
|
-
this.jwk = jwk;
|
6842
|
-
}
|
6843
|
-
get raw() {
|
6844
|
-
if (this._raw == null) {
|
6845
|
-
this._raw = publicKeyToPKIMessage(this.jwk);
|
6846
|
-
}
|
6847
|
-
return this._raw;
|
6848
|
-
}
|
6849
|
-
toMultihash() {
|
6850
|
-
return identity.digest(publicKeyToProtobuf(this));
|
6851
|
-
}
|
6852
|
-
toCID() {
|
6853
|
-
return CID.createV1(114, this.toMultihash());
|
6854
|
-
}
|
6855
|
-
toString() {
|
6856
|
-
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
6857
|
-
}
|
6858
|
-
equals(key) {
|
6859
|
-
if (key == null || !(key.raw instanceof Uint8Array)) {
|
6860
|
-
return false;
|
6861
|
-
}
|
6862
|
-
return equals(this.raw, key.raw);
|
6863
|
-
}
|
6864
|
-
async verify(data, sig) {
|
6865
|
-
return hashAndVerify$3(this.jwk, sig, data);
|
6866
|
-
}
|
6867
|
-
}
|
6868
|
-
|
6869
|
-
/**
|
6870
|
-
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
6871
|
-
* @todo re-check https://issues.chromium.org/issues/42212588
|
6872
|
-
* @module
|
6873
|
-
*/
|
6874
|
-
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
6875
|
-
const _32n = /* @__PURE__ */ BigInt(32);
|
6876
|
-
function fromBig(n, le = false) {
|
6877
|
-
if (le)
|
6878
|
-
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
6879
|
-
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
6880
|
-
}
|
6881
|
-
function split(lst, le = false) {
|
6882
|
-
let Ah = new Uint32Array(lst.length);
|
6883
|
-
let Al = new Uint32Array(lst.length);
|
6884
|
-
for (let i = 0; i < lst.length; i++) {
|
6885
|
-
const { h, l } = fromBig(lst[i], le);
|
6886
|
-
[Ah[i], Al[i]] = [h, l];
|
6887
|
-
}
|
6888
|
-
return [Ah, Al];
|
6889
|
-
}
|
6890
|
-
const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
|
6891
|
-
// for Shift in [0, 32)
|
6892
|
-
const shrSH = (h, _l, s) => h >>> s;
|
6893
|
-
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
6894
|
-
// Right rotate for Shift in [1, 32)
|
6895
|
-
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
6896
|
-
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
6897
|
-
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
|
6898
|
-
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
6899
|
-
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
6900
|
-
// Right rotate for shift===32 (just swaps l&h)
|
6901
|
-
const rotr32H = (_h, l) => l;
|
6902
|
-
const rotr32L = (h, _l) => h;
|
6903
|
-
// Left rotate for Shift in [1, 32)
|
6904
|
-
const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
|
6905
|
-
const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
|
6906
|
-
// Left rotate for Shift in (32, 64), NOTE: 32 is special case.
|
6907
|
-
const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
|
6908
|
-
const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
|
6909
|
-
// JS uses 32-bit signed integers for bitwise operations which means we cannot
|
6910
|
-
// simple take carry out of low bit sum by shift, we need to use division.
|
6911
|
-
function add(Ah, Al, Bh, Bl) {
|
6912
|
-
const l = (Al >>> 0) + (Bl >>> 0);
|
6913
|
-
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
7072
|
+
return OID_384;
|
7073
|
+
}
|
7074
|
+
if (curve === 'P-521') {
|
7075
|
+
return OID_521;
|
7076
|
+
}
|
7077
|
+
throw new InvalidParametersError(`Invalid curve ${curve}`);
|
6914
7078
|
}
|
6915
|
-
// Addition with more than 2 elements
|
6916
|
-
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
6917
|
-
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
6918
|
-
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
6919
|
-
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
6920
|
-
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
6921
|
-
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
6922
|
-
// prettier-ignore
|
6923
|
-
const u64 = {
|
6924
|
-
fromBig, split, toBig,
|
6925
|
-
shrSH, shrSL,
|
6926
|
-
rotrSH, rotrSL, rotrBH, rotrBL,
|
6927
|
-
rotr32H, rotr32L,
|
6928
|
-
rotlSH, rotlSL, rotlBH, rotlBL,
|
6929
|
-
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
6930
|
-
};
|
6931
7079
|
|
6932
|
-
|
6933
|
-
|
6934
|
-
|
6935
|
-
|
6936
|
-
|
6937
|
-
|
6938
|
-
*/
|
6939
|
-
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
6940
|
-
// prettier-ignore
|
6941
|
-
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
6942
|
-
'0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
|
6943
|
-
'0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
|
6944
|
-
'0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
|
6945
|
-
'0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
|
6946
|
-
'0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
|
6947
|
-
'0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
|
6948
|
-
'0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
|
6949
|
-
'0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
|
6950
|
-
'0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
|
6951
|
-
'0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
|
6952
|
-
'0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
|
6953
|
-
'0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
|
6954
|
-
'0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
|
6955
|
-
'0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
|
6956
|
-
'0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
|
6957
|
-
'0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
|
6958
|
-
'0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
|
6959
|
-
'0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
|
6960
|
-
'0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
|
6961
|
-
'0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
|
6962
|
-
].map(n => BigInt(n))))();
|
6963
|
-
// Temporary buffer, not used to store anything between runs
|
6964
|
-
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
6965
|
-
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
6966
|
-
class SHA512 extends HashMD {
|
6967
|
-
constructor() {
|
6968
|
-
super(128, 64, 16, false);
|
6969
|
-
// We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers.
|
6970
|
-
// Also looks cleaner and easier to verify with spec.
|
6971
|
-
// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
|
6972
|
-
// h -- high 32 bits, l -- low 32 bits
|
6973
|
-
this.Ah = 0x6a09e667 | 0;
|
6974
|
-
this.Al = 0xf3bcc908 | 0;
|
6975
|
-
this.Bh = 0xbb67ae85 | 0;
|
6976
|
-
this.Bl = 0x84caa73b | 0;
|
6977
|
-
this.Ch = 0x3c6ef372 | 0;
|
6978
|
-
this.Cl = 0xfe94f82b | 0;
|
6979
|
-
this.Dh = 0xa54ff53a | 0;
|
6980
|
-
this.Dl = 0x5f1d36f1 | 0;
|
6981
|
-
this.Eh = 0x510e527f | 0;
|
6982
|
-
this.El = 0xade682d1 | 0;
|
6983
|
-
this.Fh = 0x9b05688c | 0;
|
6984
|
-
this.Fl = 0x2b3e6c1f | 0;
|
6985
|
-
this.Gh = 0x1f83d9ab | 0;
|
6986
|
-
this.Gl = 0xfb41bd6b | 0;
|
6987
|
-
this.Hh = 0x5be0cd19 | 0;
|
6988
|
-
this.Hl = 0x137e2179 | 0;
|
7080
|
+
class ECDSAPublicKey {
|
7081
|
+
type = 'ECDSA';
|
7082
|
+
jwk;
|
7083
|
+
_raw;
|
7084
|
+
constructor(jwk) {
|
7085
|
+
this.jwk = jwk;
|
6989
7086
|
}
|
6990
|
-
|
6991
|
-
|
6992
|
-
|
6993
|
-
|
7087
|
+
get raw() {
|
7088
|
+
if (this._raw == null) {
|
7089
|
+
this._raw = publicKeyToPKIMessage(this.jwk);
|
7090
|
+
}
|
7091
|
+
return this._raw;
|
6994
7092
|
}
|
6995
|
-
|
6996
|
-
|
6997
|
-
this.Ah = Ah | 0;
|
6998
|
-
this.Al = Al | 0;
|
6999
|
-
this.Bh = Bh | 0;
|
7000
|
-
this.Bl = Bl | 0;
|
7001
|
-
this.Ch = Ch | 0;
|
7002
|
-
this.Cl = Cl | 0;
|
7003
|
-
this.Dh = Dh | 0;
|
7004
|
-
this.Dl = Dl | 0;
|
7005
|
-
this.Eh = Eh | 0;
|
7006
|
-
this.El = El | 0;
|
7007
|
-
this.Fh = Fh | 0;
|
7008
|
-
this.Fl = Fl | 0;
|
7009
|
-
this.Gh = Gh | 0;
|
7010
|
-
this.Gl = Gl | 0;
|
7011
|
-
this.Hh = Hh | 0;
|
7012
|
-
this.Hl = Hl | 0;
|
7093
|
+
toMultihash() {
|
7094
|
+
return identity.digest(publicKeyToProtobuf(this));
|
7013
7095
|
}
|
7014
|
-
|
7015
|
-
|
7016
|
-
for (let i = 0; i < 16; i++, offset += 4) {
|
7017
|
-
SHA512_W_H[i] = view.getUint32(offset);
|
7018
|
-
SHA512_W_L[i] = view.getUint32((offset += 4));
|
7019
|
-
}
|
7020
|
-
for (let i = 16; i < 80; i++) {
|
7021
|
-
// s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
|
7022
|
-
const W15h = SHA512_W_H[i - 15] | 0;
|
7023
|
-
const W15l = SHA512_W_L[i - 15] | 0;
|
7024
|
-
const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);
|
7025
|
-
const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);
|
7026
|
-
// s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
|
7027
|
-
const W2h = SHA512_W_H[i - 2] | 0;
|
7028
|
-
const W2l = SHA512_W_L[i - 2] | 0;
|
7029
|
-
const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);
|
7030
|
-
const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);
|
7031
|
-
// SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
|
7032
|
-
const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
7033
|
-
const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
7034
|
-
SHA512_W_H[i] = SUMh | 0;
|
7035
|
-
SHA512_W_L[i] = SUMl | 0;
|
7036
|
-
}
|
7037
|
-
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
7038
|
-
// Compression function main loop, 80 rounds
|
7039
|
-
for (let i = 0; i < 80; i++) {
|
7040
|
-
// S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
|
7041
|
-
const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);
|
7042
|
-
const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);
|
7043
|
-
//const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
|
7044
|
-
const CHIh = (Eh & Fh) ^ (~Eh & Gh);
|
7045
|
-
const CHIl = (El & Fl) ^ (~El & Gl);
|
7046
|
-
// T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
|
7047
|
-
// prettier-ignore
|
7048
|
-
const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
7049
|
-
const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
7050
|
-
const T1l = T1ll | 0;
|
7051
|
-
// S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
|
7052
|
-
const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);
|
7053
|
-
const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);
|
7054
|
-
const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
|
7055
|
-
const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
|
7056
|
-
Hh = Gh | 0;
|
7057
|
-
Hl = Gl | 0;
|
7058
|
-
Gh = Fh | 0;
|
7059
|
-
Gl = Fl | 0;
|
7060
|
-
Fh = Eh | 0;
|
7061
|
-
Fl = El | 0;
|
7062
|
-
({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
7063
|
-
Dh = Ch | 0;
|
7064
|
-
Dl = Cl | 0;
|
7065
|
-
Ch = Bh | 0;
|
7066
|
-
Cl = Bl | 0;
|
7067
|
-
Bh = Ah | 0;
|
7068
|
-
Bl = Al | 0;
|
7069
|
-
const All = u64.add3L(T1l, sigma0l, MAJl);
|
7070
|
-
Ah = u64.add3H(All, T1h, sigma0h, MAJh);
|
7071
|
-
Al = All | 0;
|
7072
|
-
}
|
7073
|
-
// Add the compressed chunk to the current hash value
|
7074
|
-
({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
7075
|
-
({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
7076
|
-
({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
7077
|
-
({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
7078
|
-
({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
7079
|
-
({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
7080
|
-
({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
7081
|
-
({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
7082
|
-
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
7096
|
+
toCID() {
|
7097
|
+
return CID.createV1(114, this.toMultihash());
|
7083
7098
|
}
|
7084
|
-
|
7085
|
-
|
7086
|
-
SHA512_W_L.fill(0);
|
7099
|
+
toString() {
|
7100
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
7087
7101
|
}
|
7088
|
-
|
7089
|
-
|
7090
|
-
|
7102
|
+
equals(key) {
|
7103
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
7104
|
+
return false;
|
7105
|
+
}
|
7106
|
+
return equals(this.raw, key.raw);
|
7107
|
+
}
|
7108
|
+
async verify(data, sig) {
|
7109
|
+
return hashAndVerify$3(this.jwk, sig, data);
|
7091
7110
|
}
|
7092
7111
|
}
|
7093
|
-
/** SHA2-512 hash function. */
|
7094
|
-
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
7095
7112
|
|
7096
7113
|
/**
|
7097
7114
|
* Hex, bytes and number utilities.
|
@@ -7104,7 +7121,6 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
|
7104
7121
|
// won't be included into their bundle.
|
7105
7122
|
const _0n$4 = /* @__PURE__ */ BigInt(0);
|
7106
7123
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
7107
|
-
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
7108
7124
|
function isBytes$1(a) {
|
7109
7125
|
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
7110
7126
|
}
|
@@ -7116,13 +7132,31 @@ function abool(title, value) {
|
|
7116
7132
|
if (typeof value !== 'boolean')
|
7117
7133
|
throw new Error(title + ' boolean expected, got ' + value);
|
7118
7134
|
}
|
7135
|
+
// Used in weierstrass, der
|
7136
|
+
function numberToHexUnpadded(num) {
|
7137
|
+
const hex = num.toString(16);
|
7138
|
+
return hex.length & 1 ? '0' + hex : hex;
|
7139
|
+
}
|
7140
|
+
function hexToNumber(hex) {
|
7141
|
+
if (typeof hex !== 'string')
|
7142
|
+
throw new Error('hex string expected, got ' + typeof hex);
|
7143
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
7144
|
+
}
|
7145
|
+
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
|
7146
|
+
const hasHexBuiltin =
|
7147
|
+
// @ts-ignore
|
7148
|
+
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function';
|
7119
7149
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
7120
7150
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
7121
7151
|
/**
|
7152
|
+
* Convert byte array to hex string. Uses built-in function, when available.
|
7122
7153
|
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
7123
7154
|
*/
|
7124
7155
|
function bytesToHex(bytes) {
|
7125
7156
|
abytes(bytes);
|
7157
|
+
// @ts-ignore
|
7158
|
+
if (hasHexBuiltin)
|
7159
|
+
return bytes.toHex();
|
7126
7160
|
// pre-caching improves the speed 6x
|
7127
7161
|
let hex = '';
|
7128
7162
|
for (let i = 0; i < bytes.length; i++) {
|
@@ -7130,15 +7164,6 @@ function bytesToHex(bytes) {
|
|
7130
7164
|
}
|
7131
7165
|
return hex;
|
7132
7166
|
}
|
7133
|
-
function numberToHexUnpadded(num) {
|
7134
|
-
const hex = num.toString(16);
|
7135
|
-
return hex.length & 1 ? '0' + hex : hex;
|
7136
|
-
}
|
7137
|
-
function hexToNumber(hex) {
|
7138
|
-
if (typeof hex !== 'string')
|
7139
|
-
throw new Error('hex string expected, got ' + typeof hex);
|
7140
|
-
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
7141
|
-
}
|
7142
7167
|
// We use optimized technique to convert hex string to byte array
|
7143
7168
|
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
7144
7169
|
function asciiToBase16(ch) {
|
@@ -7151,11 +7176,15 @@ function asciiToBase16(ch) {
|
|
7151
7176
|
return;
|
7152
7177
|
}
|
7153
7178
|
/**
|
7179
|
+
* Convert hex string to byte array. Uses built-in function, when available.
|
7154
7180
|
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
7155
7181
|
*/
|
7156
7182
|
function hexToBytes(hex) {
|
7157
7183
|
if (typeof hex !== 'string')
|
7158
7184
|
throw new Error('hex string expected, got ' + typeof hex);
|
7185
|
+
// @ts-ignore
|
7186
|
+
if (hasHexBuiltin)
|
7187
|
+
return Uint8Array.fromHex(hex);
|
7159
7188
|
const hl = hex.length;
|
7160
7189
|
const al = hl / 2;
|
7161
7190
|
if (hl % 2)
|
@@ -7186,10 +7215,6 @@ function numberToBytesBE(n, len) {
|
|
7186
7215
|
function numberToBytesLE(n, len) {
|
7187
7216
|
return numberToBytesBE(n, len).reverse();
|
7188
7217
|
}
|
7189
|
-
// Unpadded, rarely used
|
7190
|
-
function numberToVarBytesBE(n) {
|
7191
|
-
return hexToBytes(numberToHexUnpadded(n));
|
7192
|
-
}
|
7193
7218
|
/**
|
7194
7219
|
* Takes hex string or Uint8Array, converts to Uint8Array.
|
7195
7220
|
* Validates output length.
|
@@ -7240,23 +7265,6 @@ function concatBytes(...arrays) {
|
|
7240
7265
|
}
|
7241
7266
|
return res;
|
7242
7267
|
}
|
7243
|
-
// Compares 2 u8a-s in kinda constant time
|
7244
|
-
function equalBytes(a, b) {
|
7245
|
-
if (a.length !== b.length)
|
7246
|
-
return false;
|
7247
|
-
let diff = 0;
|
7248
|
-
for (let i = 0; i < a.length; i++)
|
7249
|
-
diff |= a[i] ^ b[i];
|
7250
|
-
return diff === 0;
|
7251
|
-
}
|
7252
|
-
/**
|
7253
|
-
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
7254
|
-
*/
|
7255
|
-
function utf8ToBytes(str) {
|
7256
|
-
if (typeof str !== 'string')
|
7257
|
-
throw new Error('string expected');
|
7258
|
-
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
7259
|
-
}
|
7260
7268
|
// Is positive bigint
|
7261
7269
|
const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
|
7262
7270
|
function inRange(n, min, max) {
|
@@ -7280,6 +7288,7 @@ function aInRange(title, n, min, max) {
|
|
7280
7288
|
/**
|
7281
7289
|
* Calculates amount of bits in a bigint.
|
7282
7290
|
* Same as `n.toString(2).length`
|
7291
|
+
* TODO: merge with nLength in modular
|
7283
7292
|
*/
|
7284
7293
|
function bitLen(n) {
|
7285
7294
|
let len;
|
@@ -7287,27 +7296,13 @@ function bitLen(n) {
|
|
7287
7296
|
;
|
7288
7297
|
return len;
|
7289
7298
|
}
|
7290
|
-
/**
|
7291
|
-
* Gets single bit at position.
|
7292
|
-
* NOTE: first bit position is 0 (same as arrays)
|
7293
|
-
* Same as `!!+Array.from(n.toString(2)).reverse()[pos]`
|
7294
|
-
*/
|
7295
|
-
function bitGet(n, pos) {
|
7296
|
-
return (n >> BigInt(pos)) & _1n$6;
|
7297
|
-
}
|
7298
|
-
/**
|
7299
|
-
* Sets single bit at position.
|
7300
|
-
*/
|
7301
|
-
function bitSet(n, pos, value) {
|
7302
|
-
return n | ((value ? _1n$6 : _0n$4) << BigInt(pos));
|
7303
|
-
}
|
7304
7299
|
/**
|
7305
7300
|
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
7306
7301
|
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
7307
7302
|
*/
|
7308
|
-
const bitMask = (n) => (
|
7303
|
+
const bitMask = (n) => (_1n$6 << BigInt(n)) - _1n$6;
|
7309
7304
|
// DRBG
|
7310
|
-
const u8n = (
|
7305
|
+
const u8n = (len) => new Uint8Array(len); // creates Uint8Array
|
7311
7306
|
const u8fr = (arr) => Uint8Array.from(arr); // another shortcut
|
7312
7307
|
/**
|
7313
7308
|
* Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
@@ -7333,7 +7328,7 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
7333
7328
|
i = 0;
|
7334
7329
|
};
|
7335
7330
|
const h = (...b) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)
|
7336
|
-
const reseed = (seed = u8n()) => {
|
7331
|
+
const reseed = (seed = u8n(0)) => {
|
7337
7332
|
// HMAC-DRBG reseed() function. Steps D-G
|
7338
7333
|
k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)
|
7339
7334
|
v = h(); // v = hmac(k || v)
|
@@ -7398,20 +7393,6 @@ function validateObject(object, validators, optValidators = {}) {
|
|
7398
7393
|
checkField(fieldName, type, true);
|
7399
7394
|
return object;
|
7400
7395
|
}
|
7401
|
-
// validate type tests
|
7402
|
-
// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };
|
7403
|
-
// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!
|
7404
|
-
// // Should fail type-check
|
7405
|
-
// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });
|
7406
|
-
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
7407
|
-
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
7408
|
-
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
7409
|
-
/**
|
7410
|
-
* throws not implemented error
|
7411
|
-
*/
|
7412
|
-
const notImplemented = () => {
|
7413
|
-
throw new Error('not implemented');
|
7414
|
-
};
|
7415
7396
|
/**
|
7416
7397
|
* Memoizes (caches) computation result.
|
7417
7398
|
* Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
|
@@ -7428,36 +7409,6 @@ function memoized(fn) {
|
|
7428
7409
|
};
|
7429
7410
|
}
|
7430
7411
|
|
7431
|
-
var ut = /*#__PURE__*/Object.freeze({
|
7432
|
-
__proto__: null,
|
7433
|
-
aInRange: aInRange,
|
7434
|
-
abool: abool,
|
7435
|
-
abytes: abytes,
|
7436
|
-
bitGet: bitGet,
|
7437
|
-
bitLen: bitLen,
|
7438
|
-
bitMask: bitMask,
|
7439
|
-
bitSet: bitSet,
|
7440
|
-
bytesToHex: bytesToHex,
|
7441
|
-
bytesToNumberBE: bytesToNumberBE,
|
7442
|
-
bytesToNumberLE: bytesToNumberLE,
|
7443
|
-
concatBytes: concatBytes,
|
7444
|
-
createHmacDrbg: createHmacDrbg,
|
7445
|
-
ensureBytes: ensureBytes,
|
7446
|
-
equalBytes: equalBytes,
|
7447
|
-
hexToBytes: hexToBytes,
|
7448
|
-
hexToNumber: hexToNumber,
|
7449
|
-
inRange: inRange,
|
7450
|
-
isBytes: isBytes$1,
|
7451
|
-
memoized: memoized,
|
7452
|
-
notImplemented: notImplemented,
|
7453
|
-
numberToBytesBE: numberToBytesBE,
|
7454
|
-
numberToBytesLE: numberToBytesLE,
|
7455
|
-
numberToHexUnpadded: numberToHexUnpadded,
|
7456
|
-
numberToVarBytesBE: numberToVarBytesBE,
|
7457
|
-
utf8ToBytes: utf8ToBytes,
|
7458
|
-
validateObject: validateObject
|
7459
|
-
});
|
7460
|
-
|
7461
7412
|
/**
|
7462
7413
|
* Utils for modular division and finite fields.
|
7463
7414
|
* A finite field over 11 is integer number operations `mod 11`.
|
@@ -7474,29 +7425,6 @@ function mod(a, b) {
|
|
7474
7425
|
const result = a % b;
|
7475
7426
|
return result >= _0n$3 ? result : b + result;
|
7476
7427
|
}
|
7477
|
-
/**
|
7478
|
-
* Efficiently raise num to power and do modular division.
|
7479
|
-
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
7480
|
-
* @todo use field version && remove
|
7481
|
-
* @example
|
7482
|
-
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
7483
|
-
*/
|
7484
|
-
function pow(num, power, modulo) {
|
7485
|
-
if (power < _0n$3)
|
7486
|
-
throw new Error('invalid exponent, negatives unsupported');
|
7487
|
-
if (modulo <= _0n$3)
|
7488
|
-
throw new Error('invalid modulus');
|
7489
|
-
if (modulo === _1n$5)
|
7490
|
-
return _0n$3;
|
7491
|
-
let res = _1n$5;
|
7492
|
-
while (power > _0n$3) {
|
7493
|
-
if (power & _1n$5)
|
7494
|
-
res = (res * num) % modulo;
|
7495
|
-
num = (num * num) % modulo;
|
7496
|
-
power >>= _1n$5;
|
7497
|
-
}
|
7498
|
-
return res;
|
7499
|
-
}
|
7500
7428
|
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
7501
7429
|
function pow2(x, power, modulo) {
|
7502
7430
|
let res = x;
|
@@ -7537,27 +7465,25 @@ function invert(number, modulo) {
|
|
7537
7465
|
* Tonelli-Shanks square root search algorithm.
|
7538
7466
|
* 1. https://eprint.iacr.org/2012/685.pdf (page 12)
|
7539
7467
|
* 2. Square Roots from 1; 24, 51, 10 to Dan Shanks
|
7540
|
-
* Will start an infinite loop if field order P is not prime.
|
7541
7468
|
* @param P field order
|
7542
7469
|
* @returns function that takes field Fp (created from P) and number n
|
7543
7470
|
*/
|
7544
7471
|
function tonelliShanks(P) {
|
7545
|
-
//
|
7546
|
-
// which denotes the value of a^((p-1)/2) (mod p).
|
7547
|
-
// (a | p) ≡ 1 if a is a square (mod p)
|
7548
|
-
// (a | p) ≡ -1 if a is not a square (mod p)
|
7549
|
-
// (a | p) ≡ 0 if a ≡ 0 (mod p)
|
7550
|
-
const legendreC = (P - _1n$5) / _2n$3;
|
7551
|
-
let Q, S, Z;
|
7472
|
+
// Do expensive precomputation step
|
7552
7473
|
// Step 1: By factoring out powers of 2 from p - 1,
|
7553
|
-
// find q and s such that p
|
7554
|
-
|
7555
|
-
|
7474
|
+
// find q and s such that p-1 == q*(2^s) with q odd
|
7475
|
+
let Q = P - _1n$5;
|
7476
|
+
let S = 0;
|
7477
|
+
while (Q % _2n$3 === _0n$3) {
|
7478
|
+
Q /= _2n$3;
|
7479
|
+
S++;
|
7480
|
+
}
|
7556
7481
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
7557
|
-
|
7558
|
-
|
7559
|
-
|
7560
|
-
|
7482
|
+
let Z = _2n$3;
|
7483
|
+
const _Fp = Field(P);
|
7484
|
+
while (Z < P && FpIsSquare(_Fp, Z)) {
|
7485
|
+
if (Z++ > 1000)
|
7486
|
+
throw new Error('Cannot find square root: probably non-prime P');
|
7561
7487
|
}
|
7562
7488
|
// Fast-path
|
7563
7489
|
if (S === 1) {
|
@@ -7573,16 +7499,18 @@ function tonelliShanks(P) {
|
|
7573
7499
|
const Q1div2 = (Q + _1n$5) / _2n$3;
|
7574
7500
|
return function tonelliSlow(Fp, n) {
|
7575
7501
|
// Step 0: Check that n is indeed a square: (n | p) should not be ≡ -1
|
7576
|
-
if (Fp
|
7502
|
+
if (!FpIsSquare(Fp, n))
|
7577
7503
|
throw new Error('Cannot find square root');
|
7578
7504
|
let r = S;
|
7579
|
-
// TODO:
|
7505
|
+
// TODO: test on Fp2 and others
|
7580
7506
|
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q); // will update both x and b
|
7581
7507
|
let x = Fp.pow(n, Q1div2); // first guess at the square root
|
7582
7508
|
let b = Fp.pow(n, Q); // first guess at the fudge factor
|
7583
7509
|
while (!Fp.eql(b, Fp.ONE)) {
|
7510
|
+
// (4. If t = 0, return r = 0)
|
7511
|
+
// https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm
|
7584
7512
|
if (Fp.eql(b, Fp.ZERO))
|
7585
|
-
return Fp.ZERO;
|
7513
|
+
return Fp.ZERO;
|
7586
7514
|
// Find m such b^(2^m)==1
|
7587
7515
|
let m = 1;
|
7588
7516
|
for (let t2 = Fp.sqr(b); m < r; m++) {
|
@@ -7590,7 +7518,8 @@ function tonelliShanks(P) {
|
|
7590
7518
|
break;
|
7591
7519
|
t2 = Fp.sqr(t2); // t2 *= t2
|
7592
7520
|
}
|
7593
|
-
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift,
|
7521
|
+
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift,
|
7522
|
+
// otherwise there will be overflow.
|
7594
7523
|
const ge = Fp.pow(g, _1n$5 << BigInt(r - m - 1)); // ge = 2^(r-m-1)
|
7595
7524
|
g = Fp.sqr(ge); // g = ge * ge
|
7596
7525
|
x = Fp.mul(x, ge); // x *= ge
|
@@ -7619,8 +7548,8 @@ function FpSqrt(P) {
|
|
7619
7548
|
// const ORDER =
|
7620
7549
|
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
7621
7550
|
// const NUM = 72057594037927816n;
|
7622
|
-
const p1div4 = (P + _1n$5) / _4n;
|
7623
7551
|
return function sqrt3mod4(Fp, n) {
|
7552
|
+
const p1div4 = (P + _1n$5) / _4n;
|
7624
7553
|
const root = Fp.pow(n, p1div4);
|
7625
7554
|
// Throw if root**2 != n
|
7626
7555
|
if (!Fp.eql(Fp.sqr(root), n))
|
@@ -7630,9 +7559,9 @@ function FpSqrt(P) {
|
|
7630
7559
|
}
|
7631
7560
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
7632
7561
|
if (P % _8n$2 === _5n$1) {
|
7633
|
-
const c1 = (P - _5n$1) / _8n$2;
|
7634
7562
|
return function sqrt5mod8(Fp, n) {
|
7635
7563
|
const n2 = Fp.mul(n, _2n$3);
|
7564
|
+
const c1 = (P - _5n$1) / _8n$2;
|
7636
7565
|
const v = Fp.pow(n2, c1);
|
7637
7566
|
const nv = Fp.mul(n, v);
|
7638
7567
|
const i = Fp.mul(Fp.mul(nv, _2n$3), v);
|
@@ -7671,52 +7600,78 @@ function validateField(field) {
|
|
7671
7600
|
* Same as `pow` but for Fp: non-constant-time.
|
7672
7601
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
7673
7602
|
*/
|
7674
|
-
function FpPow(
|
7675
|
-
// Should have same speed as pow for bigints
|
7676
|
-
// TODO: benchmark!
|
7603
|
+
function FpPow(Fp, num, power) {
|
7677
7604
|
if (power < _0n$3)
|
7678
7605
|
throw new Error('invalid exponent, negatives unsupported');
|
7679
7606
|
if (power === _0n$3)
|
7680
|
-
return
|
7607
|
+
return Fp.ONE;
|
7681
7608
|
if (power === _1n$5)
|
7682
7609
|
return num;
|
7683
|
-
|
7610
|
+
// @ts-ignore
|
7611
|
+
let p = Fp.ONE;
|
7684
7612
|
let d = num;
|
7685
7613
|
while (power > _0n$3) {
|
7686
7614
|
if (power & _1n$5)
|
7687
|
-
p =
|
7688
|
-
d =
|
7615
|
+
p = Fp.mul(p, d);
|
7616
|
+
d = Fp.sqr(d);
|
7689
7617
|
power >>= _1n$5;
|
7690
7618
|
}
|
7691
7619
|
return p;
|
7692
7620
|
}
|
7693
7621
|
/**
|
7694
7622
|
* Efficiently invert an array of Field elements.
|
7695
|
-
*
|
7623
|
+
* Exception-free. Will return `undefined` for 0 elements.
|
7624
|
+
* @param passZero map 0 to 0 (instead of undefined)
|
7696
7625
|
*/
|
7697
|
-
function FpInvertBatch(
|
7698
|
-
const
|
7626
|
+
function FpInvertBatch(Fp, nums, passZero = false) {
|
7627
|
+
const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : undefined);
|
7699
7628
|
// Walk from first to last, multiply them by each other MOD p
|
7700
|
-
const
|
7701
|
-
if (
|
7629
|
+
const multipliedAcc = nums.reduce((acc, num, i) => {
|
7630
|
+
if (Fp.is0(num))
|
7702
7631
|
return acc;
|
7703
|
-
|
7704
|
-
return
|
7705
|
-
},
|
7632
|
+
inverted[i] = acc;
|
7633
|
+
return Fp.mul(acc, num);
|
7634
|
+
}, Fp.ONE);
|
7706
7635
|
// Invert last element
|
7707
|
-
const
|
7636
|
+
const invertedAcc = Fp.inv(multipliedAcc);
|
7708
7637
|
// Walk from last to first, multiply them by inverted each other MOD p
|
7709
7638
|
nums.reduceRight((acc, num, i) => {
|
7710
|
-
if (
|
7639
|
+
if (Fp.is0(num))
|
7711
7640
|
return acc;
|
7712
|
-
|
7713
|
-
return
|
7714
|
-
},
|
7715
|
-
return
|
7641
|
+
inverted[i] = Fp.mul(acc, inverted[i]);
|
7642
|
+
return Fp.mul(acc, num);
|
7643
|
+
}, invertedAcc);
|
7644
|
+
return inverted;
|
7645
|
+
}
|
7646
|
+
/**
|
7647
|
+
* Legendre symbol.
|
7648
|
+
* Legendre constant is used to calculate Legendre symbol (a | p)
|
7649
|
+
* which denotes the value of a^((p-1)/2) (mod p)..
|
7650
|
+
*
|
7651
|
+
* * (a | p) ≡ 1 if a is a square (mod p), quadratic residue
|
7652
|
+
* * (a | p) ≡ -1 if a is not a square (mod p), quadratic non residue
|
7653
|
+
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
|
7654
|
+
*/
|
7655
|
+
function FpLegendre(Fp, n) {
|
7656
|
+
const legc = (Fp.ORDER - _1n$5) / _2n$3;
|
7657
|
+
const powered = Fp.pow(n, legc);
|
7658
|
+
const yes = Fp.eql(powered, Fp.ONE);
|
7659
|
+
const zero = Fp.eql(powered, Fp.ZERO);
|
7660
|
+
const no = Fp.eql(powered, Fp.neg(Fp.ONE));
|
7661
|
+
if (!yes && !zero && !no)
|
7662
|
+
throw new Error('Cannot find square root: probably non-prime P');
|
7663
|
+
return yes ? 1 : zero ? 0 : -1;
|
7664
|
+
}
|
7665
|
+
// This function returns True whenever the value x is a square in the field F.
|
7666
|
+
function FpIsSquare(Fp, n) {
|
7667
|
+
const l = FpLegendre(Fp, n);
|
7668
|
+
return l === 0 || l === 1;
|
7716
7669
|
}
|
7717
7670
|
// CURVE.n lengths
|
7718
7671
|
function nLength(n, nBitLength) {
|
7719
7672
|
// Bit size, byte size of CURVE.n
|
7673
|
+
if (nBitLength !== undefined)
|
7674
|
+
anumber(nBitLength);
|
7720
7675
|
const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
|
7721
7676
|
const nByteLength = Math.ceil(_nBitLength / 8);
|
7722
7677
|
return { nBitLength: _nBitLength, nByteLength };
|
@@ -7779,16 +7734,17 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
7779
7734
|
sqrtP = FpSqrt(ORDER);
|
7780
7735
|
return sqrtP(f, n);
|
7781
7736
|
}),
|
7782
|
-
invertBatch: (lst) => FpInvertBatch(f, lst),
|
7783
|
-
// TODO: do we really need constant cmov?
|
7784
|
-
// We don't have const-time bigints anyway, so probably will be not very useful
|
7785
|
-
cmov: (a, b, c) => (c ? b : a),
|
7786
7737
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
7787
7738
|
fromBytes: (bytes) => {
|
7788
7739
|
if (bytes.length !== BYTES)
|
7789
7740
|
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
7790
7741
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
7791
7742
|
},
|
7743
|
+
// TODO: we don't need it here, move out to separate fn
|
7744
|
+
invertBatch: (lst) => FpInvertBatch(f, lst),
|
7745
|
+
// We can't move this out because Fp6, Fp12 implement it
|
7746
|
+
// and it's unclear what to return in there.
|
7747
|
+
cmov: (a, b, c) => (c ? b : a),
|
7792
7748
|
});
|
7793
7749
|
return Object.freeze(f);
|
7794
7750
|
}
|
@@ -7857,11 +7813,36 @@ function validateW(W, bits) {
|
|
7857
7813
|
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
7858
7814
|
throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
|
7859
7815
|
}
|
7860
|
-
function calcWOpts(W,
|
7861
|
-
validateW(W,
|
7862
|
-
const windows = Math.ceil(
|
7863
|
-
const windowSize = 2 ** (W - 1); //
|
7864
|
-
|
7816
|
+
function calcWOpts(W, scalarBits) {
|
7817
|
+
validateW(W, scalarBits);
|
7818
|
+
const windows = Math.ceil(scalarBits / W) + 1; // W=8 33. Not 32, because we skip zero
|
7819
|
+
const windowSize = 2 ** (W - 1); // W=8 128. Not 256, because we skip zero
|
7820
|
+
const maxNumber = 2 ** W; // W=8 256
|
7821
|
+
const mask = bitMask(W); // W=8 255 == mask 0b11111111
|
7822
|
+
const shiftBy = BigInt(W); // W=8 8
|
7823
|
+
return { windows, windowSize, mask, maxNumber, shiftBy };
|
7824
|
+
}
|
7825
|
+
function calcOffsets(n, window, wOpts) {
|
7826
|
+
const { windowSize, mask, maxNumber, shiftBy } = wOpts;
|
7827
|
+
let wbits = Number(n & mask); // extract W bits.
|
7828
|
+
let nextN = n >> shiftBy; // shift number by W bits.
|
7829
|
+
// What actually happens here:
|
7830
|
+
// const highestBit = Number(mask ^ (mask >> 1n));
|
7831
|
+
// let wbits2 = wbits - 1; // skip zero
|
7832
|
+
// if (wbits2 & highestBit) { wbits2 ^= Number(mask); // (~);
|
7833
|
+
// split if bits > max: +224 => 256-32
|
7834
|
+
if (wbits > windowSize) {
|
7835
|
+
// we skip zero, which means instead of `>= size-1`, we do `> size`
|
7836
|
+
wbits -= maxNumber; // -32, can be maxNumber - wbits, but then we need to set isNeg here.
|
7837
|
+
nextN += _1n$4; // +256 (carry)
|
7838
|
+
}
|
7839
|
+
const offsetStart = window * windowSize;
|
7840
|
+
const offset = offsetStart + Math.abs(wbits) - 1; // -1 because we skip zero
|
7841
|
+
const isZero = wbits === 0; // is current window slice a 0?
|
7842
|
+
const isNeg = wbits < 0; // is current window slice negative?
|
7843
|
+
const isNegF = window % 2 !== 0; // fake random statement for noise
|
7844
|
+
const offsetF = offsetStart; // fake offset for noise
|
7845
|
+
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
7865
7846
|
}
|
7866
7847
|
function validateMSMPoints(points, c) {
|
7867
7848
|
if (!Array.isArray(points))
|
@@ -7880,9 +7861,10 @@ function validateMSMScalars(scalars, field) {
|
|
7880
7861
|
});
|
7881
7862
|
}
|
7882
7863
|
// Since points in different groups cannot be equal (different object constructor),
|
7883
|
-
// we can have single place to store precomputes
|
7864
|
+
// we can have single place to store precomputes.
|
7865
|
+
// Allows to make points frozen / immutable.
|
7884
7866
|
const pointPrecomputes = new WeakMap();
|
7885
|
-
const pointWindowSizes = new WeakMap();
|
7867
|
+
const pointWindowSizes = new WeakMap();
|
7886
7868
|
function getW(P) {
|
7887
7869
|
return pointWindowSizes.get(P) || 1;
|
7888
7870
|
}
|
@@ -7937,7 +7919,7 @@ function wNAF(c, bits) {
|
|
7937
7919
|
for (let window = 0; window < windows; window++) {
|
7938
7920
|
base = p;
|
7939
7921
|
points.push(base);
|
7940
|
-
// =1,
|
7922
|
+
// i=1, bc we skip 0
|
7941
7923
|
for (let i = 1; i < windowSize; i++) {
|
7942
7924
|
base = base.add(p);
|
7943
7925
|
points.push(base);
|
@@ -7954,48 +7936,35 @@ function wNAF(c, bits) {
|
|
7954
7936
|
* @returns real and fake (for const-time) points
|
7955
7937
|
*/
|
7956
7938
|
wNAF(W, precomputes, n) {
|
7957
|
-
//
|
7958
|
-
//
|
7959
|
-
|
7939
|
+
// Smaller version:
|
7940
|
+
// https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
7941
|
+
// TODO: check the scalar is less than group order?
|
7942
|
+
// wNAF behavior is undefined otherwise. But have to carefully remove
|
7943
|
+
// other checks before wNAF. ORDER == bits here.
|
7944
|
+
// Accumulators
|
7960
7945
|
let p = c.ZERO;
|
7961
7946
|
let f = c.BASE;
|
7962
|
-
|
7963
|
-
|
7964
|
-
|
7965
|
-
|
7966
|
-
|
7967
|
-
|
7968
|
-
|
7969
|
-
//
|
7970
|
-
n
|
7971
|
-
|
7972
|
-
|
7973
|
-
|
7974
|
-
|
7975
|
-
|
7976
|
-
}
|
7977
|
-
// This code was first written with assumption that 'f' and 'p' will never be infinity point:
|
7978
|
-
// since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
|
7979
|
-
// there is negate now: it is possible that negated element from low value
|
7980
|
-
// would be the same as high element, which will create carry into next window.
|
7981
|
-
// It's not obvious how this can fail, but still worth investigating later.
|
7982
|
-
// Check if we're onto Zero point.
|
7983
|
-
// Add random point inside current window to f.
|
7984
|
-
const offset1 = offset;
|
7985
|
-
const offset2 = offset + Math.abs(wbits) - 1; // -1 because we skip zero
|
7986
|
-
const cond1 = window % 2 !== 0;
|
7987
|
-
const cond2 = wbits < 0;
|
7988
|
-
if (wbits === 0) {
|
7989
|
-
// The most important part for const-time getPublicKey
|
7990
|
-
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
7947
|
+
// This code was first written with assumption that 'f' and 'p' will never be infinity point:
|
7948
|
+
// since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
|
7949
|
+
// there is negate now: it is possible that negated element from low value
|
7950
|
+
// would be the same as high element, which will create carry into next window.
|
7951
|
+
// It's not obvious how this can fail, but still worth investigating later.
|
7952
|
+
const wo = calcWOpts(W, bits);
|
7953
|
+
for (let window = 0; window < wo.windows; window++) {
|
7954
|
+
// (n === _0n) is handled and not early-exited. isEven and offsetF are used for noise
|
7955
|
+
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
7956
|
+
n = nextN;
|
7957
|
+
if (isZero) {
|
7958
|
+
// bits are 0: add garbage to fake point
|
7959
|
+
// Important part for const-time getPublicKey: add random "noise" point to f.
|
7960
|
+
f = f.add(constTimeNegate(isNegF, precomputes[offsetF]));
|
7991
7961
|
}
|
7992
7962
|
else {
|
7993
|
-
|
7963
|
+
// bits are 1: add to result point
|
7964
|
+
p = p.add(constTimeNegate(isNeg, precomputes[offset]));
|
7994
7965
|
}
|
7995
7966
|
}
|
7996
|
-
//
|
7997
|
-
// Even if the variable is still unused, there are some checks which will
|
7998
|
-
// throw an exception, so compiler needs to prove they won't happen, which is hard.
|
7967
|
+
// Return both real and fake points: JIT won't eliminate f.
|
7999
7968
|
// At this point there is a way to F be infinity-point even if p is not,
|
8000
7969
|
// which makes it less const-time: around 1 bigint multiply.
|
8001
7970
|
return { p, f };
|
@@ -8009,31 +7978,21 @@ function wNAF(c, bits) {
|
|
8009
7978
|
* @returns point
|
8010
7979
|
*/
|
8011
7980
|
wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
|
8012
|
-
const
|
8013
|
-
|
8014
|
-
const maxNumber = 2 ** W;
|
8015
|
-
const shiftBy = BigInt(W);
|
8016
|
-
for (let window = 0; window < windows; window++) {
|
8017
|
-
const offset = window * windowSize;
|
7981
|
+
const wo = calcWOpts(W, bits);
|
7982
|
+
for (let window = 0; window < wo.windows; window++) {
|
8018
7983
|
if (n === _0n$2)
|
8019
|
-
break; //
|
8020
|
-
|
8021
|
-
|
8022
|
-
|
8023
|
-
|
8024
|
-
|
8025
|
-
// +224 => 256 - 32
|
8026
|
-
if (wbits > windowSize) {
|
8027
|
-
wbits -= maxNumber;
|
8028
|
-
n += _1n$4;
|
8029
|
-
}
|
8030
|
-
if (wbits === 0)
|
7984
|
+
break; // Early-exit, skip 0 value
|
7985
|
+
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
7986
|
+
n = nextN;
|
7987
|
+
if (isZero) {
|
7988
|
+
// Window bits are 0: skip processing.
|
7989
|
+
// Move to next window.
|
8031
7990
|
continue;
|
8032
|
-
|
8033
|
-
|
8034
|
-
|
8035
|
-
|
8036
|
-
|
7991
|
+
}
|
7992
|
+
else {
|
7993
|
+
const item = precomputes[offset];
|
7994
|
+
acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM
|
7995
|
+
}
|
8037
7996
|
}
|
8038
7997
|
return acc;
|
8039
7998
|
},
|
@@ -8069,7 +8028,7 @@ function wNAF(c, bits) {
|
|
8069
8028
|
}
|
8070
8029
|
/**
|
8071
8030
|
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
8072
|
-
* 30x faster vs naive addition on L=4096, 10x faster
|
8031
|
+
* 30x faster vs naive addition on L=4096, 10x faster than precomputes.
|
8073
8032
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
8074
8033
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
8075
8034
|
* @param c Curve Point constructor
|
@@ -8091,15 +8050,15 @@ function pippenger(c, fieldN, points, scalars) {
|
|
8091
8050
|
const zero = c.ZERO;
|
8092
8051
|
const wbits = bitLen(BigInt(points.length));
|
8093
8052
|
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
8094
|
-
const MASK = (
|
8095
|
-
const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
|
8053
|
+
const MASK = bitMask(windowSize);
|
8054
|
+
const buckets = new Array(Number(MASK) + 1).fill(zero); // +1 for zero array
|
8096
8055
|
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
8097
8056
|
let sum = zero;
|
8098
8057
|
for (let i = lastBits; i >= 0; i -= windowSize) {
|
8099
8058
|
buckets.fill(zero);
|
8100
8059
|
for (let j = 0; j < scalars.length; j++) {
|
8101
8060
|
const scalar = scalars[j];
|
8102
|
-
const wbits = Number((scalar >> BigInt(i)) &
|
8061
|
+
const wbits = Number((scalar >> BigInt(i)) & MASK);
|
8103
8062
|
buckets[wbits] = buckets[wbits].add(points[j]);
|
8104
8063
|
}
|
8105
8064
|
let resI = zero; // not using this will do small speed-up, but will lose ct
|
@@ -8140,6 +8099,7 @@ function validateBasic(curve) {
|
|
8140
8099
|
* @module
|
8141
8100
|
*/
|
8142
8101
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
8102
|
+
// prettier-ignore
|
8143
8103
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
8144
8104
|
// prettier-ignore
|
8145
8105
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -8198,10 +8158,11 @@ function twistedEdwards(curveDef) {
|
|
8198
8158
|
}); // NOOP
|
8199
8159
|
// 0 <= n < MASK
|
8200
8160
|
// Coordinates larger than Fp.ORDER are allowed for zip215
|
8201
|
-
function aCoordinate(title, n) {
|
8202
|
-
|
8161
|
+
function aCoordinate(title, n, banZero = false) {
|
8162
|
+
const min = banZero ? _1n$3 : _0n$1;
|
8163
|
+
aInRange('coordinate ' + title, n, min, MASK);
|
8203
8164
|
}
|
8204
|
-
function
|
8165
|
+
function aextpoint(other) {
|
8205
8166
|
if (!(other instanceof Point))
|
8206
8167
|
throw new Error('ExtendedPoint expected');
|
8207
8168
|
}
|
@@ -8248,14 +8209,14 @@ function twistedEdwards(curveDef) {
|
|
8248
8209
|
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
8249
8210
|
class Point {
|
8250
8211
|
constructor(ex, ey, ez, et) {
|
8212
|
+
aCoordinate('x', ex);
|
8213
|
+
aCoordinate('y', ey);
|
8214
|
+
aCoordinate('z', ez, true);
|
8215
|
+
aCoordinate('t', et);
|
8251
8216
|
this.ex = ex;
|
8252
8217
|
this.ey = ey;
|
8253
8218
|
this.ez = ez;
|
8254
8219
|
this.et = et;
|
8255
|
-
aCoordinate('x', ex);
|
8256
|
-
aCoordinate('y', ey);
|
8257
|
-
aCoordinate('z', ez);
|
8258
|
-
aCoordinate('t', et);
|
8259
8220
|
Object.freeze(this);
|
8260
8221
|
}
|
8261
8222
|
get x() {
|
@@ -8273,7 +8234,7 @@ function twistedEdwards(curveDef) {
|
|
8273
8234
|
return new Point(x, y, _1n$3, modP(x * y));
|
8274
8235
|
}
|
8275
8236
|
static normalizeZ(points) {
|
8276
|
-
const toInv = Fp
|
8237
|
+
const toInv = FpInvertBatch(Fp, points.map((p) => p.ez));
|
8277
8238
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
8278
8239
|
}
|
8279
8240
|
// Multiscalar Multiplication
|
@@ -8291,7 +8252,7 @@ function twistedEdwards(curveDef) {
|
|
8291
8252
|
}
|
8292
8253
|
// Compare one point to another.
|
8293
8254
|
equals(other) {
|
8294
|
-
|
8255
|
+
aextpoint(other);
|
8295
8256
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
8296
8257
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
8297
8258
|
const X1Z2 = modP(X1 * Z2);
|
@@ -8332,31 +8293,10 @@ function twistedEdwards(curveDef) {
|
|
8332
8293
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
8333
8294
|
// Cost: 9M + 1*a + 1*d + 7add.
|
8334
8295
|
add(other) {
|
8335
|
-
|
8296
|
+
aextpoint(other);
|
8336
8297
|
const { a, d } = CURVE;
|
8337
8298
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
8338
8299
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
8339
|
-
// Faster algo for adding 2 Extended Points when curve's a=-1.
|
8340
|
-
// http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-4
|
8341
|
-
// Cost: 8M + 8add + 2*2.
|
8342
|
-
// Note: It does not check whether the `other` point is valid.
|
8343
|
-
if (a === BigInt(-1)) {
|
8344
|
-
const A = modP((Y1 - X1) * (Y2 + X2));
|
8345
|
-
const B = modP((Y1 + X1) * (Y2 - X2));
|
8346
|
-
const F = modP(B - A);
|
8347
|
-
if (F === _0n$1)
|
8348
|
-
return this.double(); // Same point. Tests say it doesn't affect timing
|
8349
|
-
const C = modP(Z1 * _2n$2 * T2);
|
8350
|
-
const D = modP(T1 * _2n$2 * Z2);
|
8351
|
-
const E = D + C;
|
8352
|
-
const G = B + A;
|
8353
|
-
const H = D - C;
|
8354
|
-
const X3 = modP(E * F);
|
8355
|
-
const Y3 = modP(G * H);
|
8356
|
-
const T3 = modP(E * H);
|
8357
|
-
const Z3 = modP(F * G);
|
8358
|
-
return new Point(X3, Y3, Z3, T3);
|
8359
|
-
}
|
8360
8300
|
const A = modP(X1 * X2); // A = X1*X2
|
8361
8301
|
const B = modP(Y1 * Y2); // B = Y1*Y2
|
8362
8302
|
const C = modP(T1 * d * T2); // C = T1*d*T2
|
@@ -8456,7 +8396,8 @@ function twistedEdwards(curveDef) {
|
|
8456
8396
|
return Point.fromAffine({ x, y });
|
8457
8397
|
}
|
8458
8398
|
static fromPrivateKey(privKey) {
|
8459
|
-
|
8399
|
+
const { scalar } = getPrivateScalar(privKey);
|
8400
|
+
return G.multiply(scalar); // reduced one call of `toRawBytes`
|
8460
8401
|
}
|
8461
8402
|
toRawBytes() {
|
8462
8403
|
const { x, y } = this.toAffine();
|
@@ -8479,8 +8420,8 @@ function twistedEdwards(curveDef) {
|
|
8479
8420
|
function modN_LE(hash) {
|
8480
8421
|
return modN(bytesToNumberLE(hash));
|
8481
8422
|
}
|
8482
|
-
|
8483
|
-
function
|
8423
|
+
// Get the hashed private scalar per RFC8032 5.1.5
|
8424
|
+
function getPrivateScalar(key) {
|
8484
8425
|
const len = Fp.BYTES;
|
8485
8426
|
key = ensureBytes('private key', key, len);
|
8486
8427
|
// Hash private key with curve's hash function to produce uniformingly random input
|
@@ -8489,6 +8430,11 @@ function twistedEdwards(curveDef) {
|
|
8489
8430
|
const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE
|
8490
8431
|
const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)
|
8491
8432
|
const scalar = modN_LE(head); // The actual private scalar
|
8433
|
+
return { head, prefix, scalar };
|
8434
|
+
}
|
8435
|
+
// Convenience method that creates public key from scalar. RFC8032 5.1.5
|
8436
|
+
function getExtendedPublicKey(key) {
|
8437
|
+
const { head, prefix, scalar } = getPrivateScalar(key);
|
8492
8438
|
const point = G.multiply(scalar); // Point on Edwards curve aka public key
|
8493
8439
|
const pointBytes = point.toRawBytes(); // Uint8Array representation
|
8494
8440
|
return { head, prefix, scalar, point, pointBytes };
|
@@ -8498,7 +8444,7 @@ function twistedEdwards(curveDef) {
|
|
8498
8444
|
return getExtendedPublicKey(privKey).pointBytes;
|
8499
8445
|
}
|
8500
8446
|
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
8501
|
-
function hashDomainToScalar(context =
|
8447
|
+
function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
|
8502
8448
|
const msg = concatBytes(...msgs);
|
8503
8449
|
return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));
|
8504
8450
|
}
|
@@ -8555,7 +8501,7 @@ function twistedEdwards(curveDef) {
|
|
8555
8501
|
G._setWindowSize(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
|
8556
8502
|
const utils = {
|
8557
8503
|
getExtendedPublicKey,
|
8558
|
-
|
8504
|
+
/** ed25519 priv keys are uniform 32b. No need to check for modulo bias, like in secp256k1. */
|
8559
8505
|
randomPrivateKey: () => randomBytes(Fp.BYTES),
|
8560
8506
|
/**
|
8561
8507
|
* We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
|
@@ -8587,8 +8533,10 @@ function twistedEdwards(curveDef) {
|
|
8587
8533
|
* @module
|
8588
8534
|
*/
|
8589
8535
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
8536
|
+
// 2n**255n - 19n
|
8590
8537
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
8591
8538
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
8539
|
+
// Fp.sqrt(Fp.neg(1))
|
8592
8540
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
8593
8541
|
// prettier-ignore
|
8594
8542
|
BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
|
@@ -8647,19 +8595,15 @@ function uvRatio(u, v) {
|
|
8647
8595
|
}
|
8648
8596
|
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
8649
8597
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
8650
|
-
//
|
8651
|
-
a:
|
8652
|
-
// d is
|
8653
|
-
// Negative number is P - number, and division is invert(number, P)
|
8598
|
+
// Removing Fp.create() will still work, and is 10% faster on sign
|
8599
|
+
a: Fp.create(BigInt(-1)),
|
8600
|
+
// d is -121665/121666 a.k.a. Fp.neg(121665 * Fp.inv(121666))
|
8654
8601
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
8655
|
-
// Finite field
|
8602
|
+
// Finite field 2n**255n - 19n
|
8656
8603
|
Fp,
|
8657
|
-
// Subgroup order
|
8658
|
-
// 2n**252n + 27742317777372353535851937790883648493n;
|
8604
|
+
// Subgroup order 2n**252n + 27742317777372353535851937790883648493n;
|
8659
8605
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
8660
|
-
// Cofactor
|
8661
8606
|
h: _8n,
|
8662
|
-
// Base point (x, y) aka generator point
|
8663
8607
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
8664
8608
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
8665
8609
|
hash: sha512,
|
@@ -10232,7 +10176,7 @@ class HMAC extends Hash {
|
|
10232
10176
|
for (let i = 0; i < pad.length; i++)
|
10233
10177
|
pad[i] ^= 0x36 ^ 0x5c;
|
10234
10178
|
this.oHash.update(pad);
|
10235
|
-
pad
|
10179
|
+
clean(pad);
|
10236
10180
|
}
|
10237
10181
|
update(buf) {
|
10238
10182
|
aexists(this);
|
@@ -10241,7 +10185,7 @@ class HMAC extends Hash {
|
|
10241
10185
|
}
|
10242
10186
|
digestInto(out) {
|
10243
10187
|
aexists(this);
|
10244
|
-
abytes$
|
10188
|
+
abytes$2(out, this.outputLen);
|
10245
10189
|
this.finished = true;
|
10246
10190
|
this.iHash.digestInto(out);
|
10247
10191
|
this.oHash.update(out);
|
@@ -10266,6 +10210,9 @@ class HMAC extends Hash {
|
|
10266
10210
|
to.iHash = iHash._cloneInto(to.iHash);
|
10267
10211
|
return to;
|
10268
10212
|
}
|
10213
|
+
clone() {
|
10214
|
+
return this._cloneInto();
|
10215
|
+
}
|
10269
10216
|
destroy() {
|
10270
10217
|
this.destroyed = true;
|
10271
10218
|
this.oHash.destroy();
|
@@ -10288,6 +10235,19 @@ hmac.create = (hash, key) => new HMAC(hash, key);
|
|
10288
10235
|
/**
|
10289
10236
|
* Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
|
10290
10237
|
*
|
10238
|
+
* ### Parameters
|
10239
|
+
*
|
10240
|
+
* To initialize a weierstrass curve, one needs to pass following params:
|
10241
|
+
*
|
10242
|
+
* * a: formula param
|
10243
|
+
* * b: formula param
|
10244
|
+
* * Fp: finite Field over which we'll do calculations. Can be complex (Fp2, Fp12)
|
10245
|
+
* * n: Curve prime subgroup order, total count of valid points in the field
|
10246
|
+
* * Gx: Base point (x, y) aka generator point x coordinate
|
10247
|
+
* * Gy: ...y coordinate
|
10248
|
+
* * h: cofactor, usually 1. h*n = curve group order (n is only subgroup order)
|
10249
|
+
* * lowS: whether to enable (default) or disable "low-s" non-malleable signatures
|
10250
|
+
*
|
10291
10251
|
* ### Design rationale for types
|
10292
10252
|
*
|
10293
10253
|
* * Interaction between classes from different curves should fail:
|
@@ -10312,6 +10272,7 @@ hmac.create = (hash, key) => new HMAC(hash, key);
|
|
10312
10272
|
* @module
|
10313
10273
|
*/
|
10314
10274
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
10275
|
+
// prettier-ignore
|
10315
10276
|
function validateSigVerOpts(opts) {
|
10316
10277
|
if (opts.lowS !== undefined)
|
10317
10278
|
abool('lowS', opts.lowS);
|
@@ -10345,7 +10306,6 @@ function validatePointOpts(curve) {
|
|
10345
10306
|
}
|
10346
10307
|
return Object.freeze({ ...opts });
|
10347
10308
|
}
|
10348
|
-
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
10349
10309
|
class DERErr extends Error {
|
10350
10310
|
constructor(m = '') {
|
10351
10311
|
super(m);
|
@@ -10438,14 +10398,13 @@ const DER = {
|
|
10438
10398
|
throw new E('invalid signature integer: negative');
|
10439
10399
|
if (data[0] === 0x00 && !(data[1] & 128))
|
10440
10400
|
throw new E('invalid signature integer: unnecessary leading zero');
|
10441
|
-
return
|
10401
|
+
return bytesToNumberBE(data);
|
10442
10402
|
},
|
10443
10403
|
},
|
10444
10404
|
toSig(hex) {
|
10445
10405
|
// parse DER signature
|
10446
10406
|
const { Err: E, _int: int, _tlv: tlv } = DER;
|
10447
|
-
const data =
|
10448
|
-
abytes(data);
|
10407
|
+
const data = ensureBytes('signature', hex);
|
10449
10408
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
10450
10409
|
if (seqLeftBytes.length)
|
10451
10410
|
throw new E('invalid signature: left bytes after parsing');
|
@@ -10485,7 +10444,7 @@ function weierstrassPoints(opts) {
|
|
10485
10444
|
return { x, y };
|
10486
10445
|
});
|
10487
10446
|
/**
|
10488
|
-
* y² = x³ + ax + b: Short weierstrass curve formula
|
10447
|
+
* y² = x³ + ax + b: Short weierstrass curve formula. Takes x, returns y².
|
10489
10448
|
* @returns y²
|
10490
10449
|
*/
|
10491
10450
|
function weierstrassEquation(x) {
|
@@ -10531,7 +10490,7 @@ function weierstrassPoints(opts) {
|
|
10531
10490
|
aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
|
10532
10491
|
return num;
|
10533
10492
|
}
|
10534
|
-
function
|
10493
|
+
function aprjpoint(other) {
|
10535
10494
|
if (!(other instanceof Point))
|
10536
10495
|
throw new Error('ProjectivePoint expected');
|
10537
10496
|
}
|
@@ -10589,15 +10548,15 @@ function weierstrassPoints(opts) {
|
|
10589
10548
|
*/
|
10590
10549
|
class Point {
|
10591
10550
|
constructor(px, py, pz) {
|
10592
|
-
this.px = px;
|
10593
|
-
this.py = py;
|
10594
|
-
this.pz = pz;
|
10595
10551
|
if (px == null || !Fp.isValid(px))
|
10596
10552
|
throw new Error('x required');
|
10597
|
-
if (py == null || !Fp.isValid(py))
|
10553
|
+
if (py == null || !Fp.isValid(py) || Fp.is0(py))
|
10598
10554
|
throw new Error('y required');
|
10599
10555
|
if (pz == null || !Fp.isValid(pz))
|
10600
10556
|
throw new Error('z required');
|
10557
|
+
this.px = px;
|
10558
|
+
this.py = py;
|
10559
|
+
this.pz = pz;
|
10601
10560
|
Object.freeze(this);
|
10602
10561
|
}
|
10603
10562
|
// Does not validate if the point is on-curve.
|
@@ -10627,7 +10586,7 @@ function weierstrassPoints(opts) {
|
|
10627
10586
|
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
10628
10587
|
*/
|
10629
10588
|
static normalizeZ(points) {
|
10630
|
-
const toInv = Fp
|
10589
|
+
const toInv = FpInvertBatch(Fp, points.map((p) => p.pz));
|
10631
10590
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
10632
10591
|
}
|
10633
10592
|
/**
|
@@ -10665,7 +10624,7 @@ function weierstrassPoints(opts) {
|
|
10665
10624
|
* Compare one point to another.
|
10666
10625
|
*/
|
10667
10626
|
equals(other) {
|
10668
|
-
|
10627
|
+
aprjpoint(other);
|
10669
10628
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
10670
10629
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
10671
10630
|
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
@@ -10725,7 +10684,7 @@ function weierstrassPoints(opts) {
|
|
10725
10684
|
// https://eprint.iacr.org/2015/1060, algorithm 1
|
10726
10685
|
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
10727
10686
|
add(other) {
|
10728
|
-
|
10687
|
+
aprjpoint(other);
|
10729
10688
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
10730
10689
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
10731
10690
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
@@ -10896,10 +10855,9 @@ function weierstrassPoints(opts) {
|
|
10896
10855
|
}
|
10897
10856
|
}
|
10898
10857
|
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
10899
|
-
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
10858
|
+
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); // 0, 1, 0
|
10900
10859
|
const _bits = CURVE.nBitLength;
|
10901
10860
|
const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
10902
|
-
// Validate if generator point is on curve
|
10903
10861
|
return {
|
10904
10862
|
CURVE,
|
10905
10863
|
ProjectivePoint: Point,
|
@@ -10990,7 +10948,7 @@ function weierstrass(curveDef) {
|
|
10990
10948
|
}
|
10991
10949
|
},
|
10992
10950
|
});
|
10993
|
-
const
|
10951
|
+
const numToNByteHex = (num) => bytesToHex(numberToBytesBE(num, CURVE.nByteLength));
|
10994
10952
|
function isBiggerThanHalfOrder(number) {
|
10995
10953
|
const HALF = CURVE_ORDER >> _1n$1;
|
10996
10954
|
return number > HALF;
|
@@ -11005,10 +10963,13 @@ function weierstrass(curveDef) {
|
|
11005
10963
|
*/
|
11006
10964
|
class Signature {
|
11007
10965
|
constructor(r, s, recovery) {
|
10966
|
+
aInRange('r', r, _1n$1, CURVE_ORDER); // r in [1..N]
|
10967
|
+
aInRange('s', s, _1n$1, CURVE_ORDER); // s in [1..N]
|
11008
10968
|
this.r = r;
|
11009
10969
|
this.s = s;
|
11010
|
-
|
11011
|
-
|
10970
|
+
if (recovery != null)
|
10971
|
+
this.recovery = recovery;
|
10972
|
+
Object.freeze(this);
|
11012
10973
|
}
|
11013
10974
|
// pair (bytes of r, bytes of s)
|
11014
10975
|
static fromCompact(hex) {
|
@@ -11022,10 +10983,11 @@ function weierstrass(curveDef) {
|
|
11022
10983
|
const { r, s } = DER.toSig(ensureBytes('DER', hex));
|
11023
10984
|
return new Signature(r, s);
|
11024
10985
|
}
|
11025
|
-
|
11026
|
-
|
11027
|
-
|
11028
|
-
|
10986
|
+
/**
|
10987
|
+
* @todo remove
|
10988
|
+
* @deprecated
|
10989
|
+
*/
|
10990
|
+
assertValidity() { }
|
11029
10991
|
addRecoveryBit(recovery) {
|
11030
10992
|
return new Signature(this.r, this.s, recovery);
|
11031
10993
|
}
|
@@ -11038,7 +11000,7 @@ function weierstrass(curveDef) {
|
|
11038
11000
|
if (radj >= Fp.ORDER)
|
11039
11001
|
throw new Error('recovery id 2 or 3 invalid');
|
11040
11002
|
const prefix = (rec & 1) === 0 ? '02' : '03';
|
11041
|
-
const R = Point.fromHex(prefix +
|
11003
|
+
const R = Point.fromHex(prefix + numToNByteHex(radj));
|
11042
11004
|
const ir = invN(radj); // r^-1
|
11043
11005
|
const u1 = modN(-h * ir); // -hr^-1
|
11044
11006
|
const u2 = modN(s * ir); // sr^-1
|
@@ -11060,14 +11022,14 @@ function weierstrass(curveDef) {
|
|
11060
11022
|
return hexToBytes(this.toDERHex());
|
11061
11023
|
}
|
11062
11024
|
toDERHex() {
|
11063
|
-
return DER.hexFromSig(
|
11025
|
+
return DER.hexFromSig(this);
|
11064
11026
|
}
|
11065
11027
|
// padded bytes of r, then padded bytes of s
|
11066
11028
|
toCompactRawBytes() {
|
11067
11029
|
return hexToBytes(this.toCompactHex());
|
11068
11030
|
}
|
11069
11031
|
toCompactHex() {
|
11070
|
-
return
|
11032
|
+
return numToNByteHex(this.r) + numToNByteHex(this.s);
|
11071
11033
|
}
|
11072
11034
|
}
|
11073
11035
|
const utils = {
|
@@ -11407,26 +11369,28 @@ function sqrtMod(y) {
|
|
11407
11369
|
}
|
11408
11370
|
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
11409
11371
|
/**
|
11410
|
-
* secp256k1
|
11372
|
+
* secp256k1 curve, ECDSA and ECDH methods.
|
11373
|
+
*
|
11374
|
+
* Field: `2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n`
|
11411
11375
|
*
|
11412
11376
|
* @example
|
11377
|
+
* ```js
|
11413
11378
|
* import { secp256k1 } from '@noble/curves/secp256k1';
|
11414
|
-
*
|
11415
11379
|
* const priv = secp256k1.utils.randomPrivateKey();
|
11416
11380
|
* const pub = secp256k1.getPublicKey(priv);
|
11417
11381
|
* const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
|
11418
11382
|
* const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
|
11419
11383
|
* const isValid = secp256k1.verify(sig, msg, pub) === true;
|
11384
|
+
* ```
|
11420
11385
|
*/
|
11421
11386
|
const secp256k1 = createCurve({
|
11422
|
-
a: BigInt(0),
|
11387
|
+
a: BigInt(0),
|
11423
11388
|
b: BigInt(7),
|
11424
|
-
Fp: Fpk1,
|
11425
|
-
n: secp256k1N,
|
11426
|
-
// Base point (x, y) aka generator point
|
11389
|
+
Fp: Fpk1,
|
11390
|
+
n: secp256k1N,
|
11427
11391
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
11428
11392
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
11429
|
-
h: BigInt(1),
|
11393
|
+
h: BigInt(1),
|
11430
11394
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
11431
11395
|
endo: {
|
11432
11396
|
// Endomorphism, see above
|
@@ -11454,7 +11418,7 @@ const secp256k1 = createCurve({
|
|
11454
11418
|
return { k1neg, k1, k2neg, k2 };
|
11455
11419
|
},
|
11456
11420
|
},
|
11457
|
-
}, sha256$
|
11421
|
+
}, sha256$2);
|
11458
11422
|
// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.
|
11459
11423
|
// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
|
11460
11424
|
BigInt(0);
|
@@ -13091,7 +13055,15 @@ class QuickLRU extends Map {
|
|
13091
13055
|
}
|
13092
13056
|
|
13093
13057
|
get [Symbol.toStringTag]() {
|
13094
|
-
return
|
13058
|
+
return 'QuickLRU';
|
13059
|
+
}
|
13060
|
+
|
13061
|
+
toString() {
|
13062
|
+
return `QuickLRU(${this.size}/${this.maxSize})`;
|
13063
|
+
}
|
13064
|
+
|
13065
|
+
[Symbol.for('nodejs.util.inspect.custom')]() {
|
13066
|
+
return this.toString();
|
13095
13067
|
}
|
13096
13068
|
}
|
13097
13069
|
|
@@ -14464,7 +14436,7 @@ class ENRTree {
|
|
14464
14436
|
// of the record content, excluding the `sig=` part, encoded as URL-safe base64 string
|
14465
14437
|
// (Trailing recovery bit must be trimmed to pass `ecdsaVerify` method)
|
14466
14438
|
const signedComponent = root.split(" sig")[0];
|
14467
|
-
const signedComponentBuffer = utf8ToBytes
|
14439
|
+
const signedComponentBuffer = utf8ToBytes(signedComponent);
|
14468
14440
|
const signatureBuffer = fromString(rootValues.signature, "base64url").slice(0, 64);
|
14469
14441
|
const isVerified = verifySignature(signatureBuffer, keccak256(signedComponentBuffer), new Uint8Array(decodedPublicKey));
|
14470
14442
|
if (!isVerified)
|