@waku/enr 0.0.30-16328a3.0 → 0.0.30-383e0b2.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 +671 -635
- package/dist/.tsbuildinfo +1 -1
- package/package.json +1 -1
package/bundle/index.js
CHANGED
@@ -843,7 +843,7 @@ class Hasher {
|
|
843
843
|
function sha(name) {
|
844
844
|
return async (data) => new Uint8Array(await crypto.subtle.digest(name, data));
|
845
845
|
}
|
846
|
-
const sha256$
|
846
|
+
const sha256$1 = from({
|
847
847
|
name: 'sha2-256',
|
848
848
|
code: 0x12,
|
849
849
|
encode: sha('SHA-256')
|
@@ -1330,7 +1330,7 @@ const bytesToUtf8 = (b) => toString$1(b, "utf8");
|
|
1330
1330
|
/**
|
1331
1331
|
* Encode utf-8 string to byte array.
|
1332
1332
|
*/
|
1333
|
-
const utf8ToBytes$
|
1333
|
+
const utf8ToBytes$2 = (s) => fromString(s, "utf8");
|
1334
1334
|
/**
|
1335
1335
|
* Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView`
|
1336
1336
|
*/
|
@@ -1355,7 +1355,7 @@ var nodeCrypto = /*#__PURE__*/Object.freeze({
|
|
1355
1355
|
/*! noble-secp256k1 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
|
1356
1356
|
const _0n$5 = BigInt(0);
|
1357
1357
|
const _1n$7 = BigInt(1);
|
1358
|
-
const _2n$
|
1358
|
+
const _2n$5 = BigInt(2);
|
1359
1359
|
const _3n$2 = BigInt(3);
|
1360
1360
|
const _8n$3 = BigInt(8);
|
1361
1361
|
const CURVE = Object.freeze({
|
@@ -1368,7 +1368,7 @@ const CURVE = Object.freeze({
|
|
1368
1368
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
1369
1369
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
1370
1370
|
});
|
1371
|
-
const divNearest$1 = (a, b) => (a + b / _2n$
|
1371
|
+
const divNearest$1 = (a, b) => (a + b / _2n$5) / b;
|
1372
1372
|
const endo = {
|
1373
1373
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
1374
1374
|
splitScalar(k) {
|
@@ -1457,12 +1457,12 @@ class JacobianPoint {
|
|
1457
1457
|
const B = mod$1(Y1 * Y1);
|
1458
1458
|
const C = mod$1(B * B);
|
1459
1459
|
const x1b = X1 + B;
|
1460
|
-
const D = mod$1(_2n$
|
1460
|
+
const D = mod$1(_2n$5 * (mod$1(x1b * x1b) - A - C));
|
1461
1461
|
const E = mod$1(_3n$2 * A);
|
1462
1462
|
const F = mod$1(E * E);
|
1463
|
-
const X3 = mod$1(F - _2n$
|
1463
|
+
const X3 = mod$1(F - _2n$5 * D);
|
1464
1464
|
const Y3 = mod$1(E * (D - X3) - _8n$3 * C);
|
1465
|
-
const Z3 = mod$1(_2n$
|
1465
|
+
const Z3 = mod$1(_2n$5 * Y1 * Z1);
|
1466
1466
|
return new JacobianPoint(X3, Y3, Z3);
|
1467
1467
|
}
|
1468
1468
|
add(other) {
|
@@ -1492,7 +1492,7 @@ class JacobianPoint {
|
|
1492
1492
|
const HH = mod$1(H * H);
|
1493
1493
|
const HHH = mod$1(H * HH);
|
1494
1494
|
const V = mod$1(U1 * HH);
|
1495
|
-
const X3 = mod$1(r * r - HHH - _2n$
|
1495
|
+
const X3 = mod$1(r * r - HHH - _2n$5 * V);
|
1496
1496
|
const Y3 = mod$1(r * (V - X3) - S1 * HHH);
|
1497
1497
|
const Z3 = mod$1(Z1 * Z2 * H);
|
1498
1498
|
return new JacobianPoint(X3, Y3, Z3);
|
@@ -1653,7 +1653,7 @@ class Point {
|
|
1653
1653
|
pointPrecomputes$1.delete(this);
|
1654
1654
|
}
|
1655
1655
|
hasEvenY() {
|
1656
|
-
return this.y % _2n$
|
1656
|
+
return this.y % _2n$5 === _0n$5;
|
1657
1657
|
}
|
1658
1658
|
static fromCompressedHex(bytes) {
|
1659
1659
|
const isShort = bytes.length === 32;
|
@@ -1812,7 +1812,7 @@ class Signature {
|
|
1812
1812
|
this.assertValidity();
|
1813
1813
|
}
|
1814
1814
|
static fromCompact(hex) {
|
1815
|
-
const arr =
|
1815
|
+
const arr = hex instanceof Uint8Array;
|
1816
1816
|
const name = 'Signature.fromCompact';
|
1817
1817
|
if (typeof hex !== 'string' && !arr)
|
1818
1818
|
throw new TypeError(`${name}: Expected string or Uint8Array`);
|
@@ -1822,7 +1822,7 @@ class Signature {
|
|
1822
1822
|
return new Signature(hexToNumber$1(str.slice(0, 64)), hexToNumber$1(str.slice(64, 128)));
|
1823
1823
|
}
|
1824
1824
|
static fromDER(hex) {
|
1825
|
-
const arr =
|
1825
|
+
const arr = hex instanceof Uint8Array;
|
1826
1826
|
if (typeof hex !== 'string' && !arr)
|
1827
1827
|
throw new TypeError(`Signature.fromDER: Expected string or Uint8Array`);
|
1828
1828
|
const { r, s } = parseDERSignature(arr ? hex : hexToBytes$1(hex));
|
@@ -1871,15 +1871,9 @@ class Signature {
|
|
1871
1871
|
return numTo32bStr(this.r) + numTo32bStr(this.s);
|
1872
1872
|
}
|
1873
1873
|
}
|
1874
|
-
function isBytes$3(a) {
|
1875
|
-
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
1876
|
-
}
|
1877
|
-
function abytes$2(item) {
|
1878
|
-
if (!isBytes$3(item))
|
1879
|
-
throw new Error('Uint8Array expected');
|
1880
|
-
}
|
1881
1874
|
function concatBytes$2(...arrays) {
|
1882
|
-
arrays.every(
|
1875
|
+
if (!arrays.every((b) => b instanceof Uint8Array))
|
1876
|
+
throw new Error('Uint8Array list expected');
|
1883
1877
|
if (arrays.length === 1)
|
1884
1878
|
return arrays[0];
|
1885
1879
|
const length = arrays.reduce((a, arr) => a + arr.length, 0);
|
@@ -1891,44 +1885,16 @@ function concatBytes$2(...arrays) {
|
|
1891
1885
|
}
|
1892
1886
|
return result;
|
1893
1887
|
}
|
1894
|
-
const hexes$1 = Array.from({ length: 256 }, (
|
1895
|
-
function bytesToHex$1(
|
1896
|
-
|
1888
|
+
const hexes$1 = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
|
1889
|
+
function bytesToHex$1(uint8a) {
|
1890
|
+
if (!(uint8a instanceof Uint8Array))
|
1891
|
+
throw new Error('Expected Uint8Array');
|
1897
1892
|
let hex = '';
|
1898
|
-
for (let i = 0; i <
|
1899
|
-
hex += hexes$1[
|
1893
|
+
for (let i = 0; i < uint8a.length; i++) {
|
1894
|
+
hex += hexes$1[uint8a[i]];
|
1900
1895
|
}
|
1901
1896
|
return hex;
|
1902
1897
|
}
|
1903
|
-
const asciis$1 = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
1904
|
-
function asciiToBase16$1(ch) {
|
1905
|
-
if (ch >= asciis$1._0 && ch <= asciis$1._9)
|
1906
|
-
return ch - asciis$1._0;
|
1907
|
-
if (ch >= asciis$1.A && ch <= asciis$1.F)
|
1908
|
-
return ch - (asciis$1.A - 10);
|
1909
|
-
if (ch >= asciis$1.a && ch <= asciis$1.f)
|
1910
|
-
return ch - (asciis$1.a - 10);
|
1911
|
-
return;
|
1912
|
-
}
|
1913
|
-
function hexToBytes$1(hex) {
|
1914
|
-
if (typeof hex !== 'string')
|
1915
|
-
throw new Error('hex string expected, got ' + typeof hex);
|
1916
|
-
const hl = hex.length;
|
1917
|
-
const al = hl / 2;
|
1918
|
-
if (hl % 2)
|
1919
|
-
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
1920
|
-
const array = new Uint8Array(al);
|
1921
|
-
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
1922
|
-
const n1 = asciiToBase16$1(hex.charCodeAt(hi));
|
1923
|
-
const n2 = asciiToBase16$1(hex.charCodeAt(hi + 1));
|
1924
|
-
if (n1 === undefined || n2 === undefined) {
|
1925
|
-
const char = hex[hi] + hex[hi + 1];
|
1926
|
-
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
1927
|
-
}
|
1928
|
-
array[ai] = n1 * 16 + n2;
|
1929
|
-
}
|
1930
|
-
return array;
|
1931
|
-
}
|
1932
1898
|
const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');
|
1933
1899
|
function numTo32bStr(num) {
|
1934
1900
|
if (typeof num !== 'bigint')
|
@@ -1953,11 +1919,28 @@ function hexToNumber$1(hex) {
|
|
1953
1919
|
}
|
1954
1920
|
return BigInt(`0x${hex}`);
|
1955
1921
|
}
|
1922
|
+
function hexToBytes$1(hex) {
|
1923
|
+
if (typeof hex !== 'string') {
|
1924
|
+
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
|
1925
|
+
}
|
1926
|
+
if (hex.length % 2)
|
1927
|
+
throw new Error('hexToBytes: received invalid unpadded hex' + hex.length);
|
1928
|
+
const array = new Uint8Array(hex.length / 2);
|
1929
|
+
for (let i = 0; i < array.length; i++) {
|
1930
|
+
const j = i * 2;
|
1931
|
+
const hexByte = hex.slice(j, j + 2);
|
1932
|
+
const byte = Number.parseInt(hexByte, 16);
|
1933
|
+
if (Number.isNaN(byte) || byte < 0)
|
1934
|
+
throw new Error('Invalid byte sequence');
|
1935
|
+
array[i] = byte;
|
1936
|
+
}
|
1937
|
+
return array;
|
1938
|
+
}
|
1956
1939
|
function bytesToNumber(bytes) {
|
1957
1940
|
return hexToNumber$1(bytesToHex$1(bytes));
|
1958
1941
|
}
|
1959
1942
|
function ensureBytes$1(hex) {
|
1960
|
-
return
|
1943
|
+
return hex instanceof Uint8Array ? Uint8Array.from(hex) : hexToBytes$1(hex);
|
1961
1944
|
}
|
1962
1945
|
function normalizeScalar(num) {
|
1963
1946
|
if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0)
|
@@ -1991,7 +1974,7 @@ function sqrtMod$1(x) {
|
|
1991
1974
|
const b3 = (b2 * b2 * x) % P;
|
1992
1975
|
const b6 = (pow2$1(b3, _3n$2) * b3) % P;
|
1993
1976
|
const b9 = (pow2$1(b6, _3n$2) * b3) % P;
|
1994
|
-
const b11 = (pow2$1(b9, _2n$
|
1977
|
+
const b11 = (pow2$1(b9, _2n$5) * b2) % P;
|
1995
1978
|
const b22 = (pow2$1(b11, _11n) * b11) % P;
|
1996
1979
|
const b44 = (pow2$1(b22, _22n) * b22) % P;
|
1997
1980
|
const b88 = (pow2$1(b44, _44n) * b44) % P;
|
@@ -2000,7 +1983,7 @@ function sqrtMod$1(x) {
|
|
2000
1983
|
const b223 = (pow2$1(b220, _3n$2) * b3) % P;
|
2001
1984
|
const t1 = (pow2$1(b223, _23n) * b22) % P;
|
2002
1985
|
const t2 = (pow2$1(t1, _6n) * b2) % P;
|
2003
|
-
const rt = pow2$1(t2, _2n$
|
1986
|
+
const rt = pow2$1(t2, _2n$5);
|
2004
1987
|
const xc = (rt * rt) % P;
|
2005
1988
|
if (xc !== x)
|
2006
1989
|
throw new Error('Cannot find square root');
|
@@ -2165,7 +2148,7 @@ function normalizePrivateKey(key) {
|
|
2165
2148
|
throw new Error('Expected 32 bytes of private key');
|
2166
2149
|
num = hexToNumber$1(key);
|
2167
2150
|
}
|
2168
|
-
else if (
|
2151
|
+
else if (key instanceof Uint8Array) {
|
2169
2152
|
if (key.length !== groupLen)
|
2170
2153
|
throw new Error('Expected 32 bytes of private key');
|
2171
2154
|
num = bytesToNumber(key);
|
@@ -3112,28 +3095,19 @@ function verifySignature(signature, message, publicKey) {
|
|
3112
3095
|
}
|
3113
3096
|
}
|
3114
3097
|
|
3115
|
-
const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
3116
|
-
|
3117
3098
|
/**
|
3118
|
-
*
|
3099
|
+
* Internal assertion helpers.
|
3119
3100
|
* @module
|
3120
3101
|
*/
|
3121
|
-
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
3122
|
-
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
3123
|
-
// node.js versions earlier than v19 don't declare it in global scope.
|
3124
|
-
// For node.js, package.json#exports field mapping rewrites import
|
3125
|
-
// from `crypto` to `cryptoNode`, which imports native module.
|
3126
|
-
// Makes the utils un-importable in browsers without a bundler.
|
3127
|
-
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
3128
|
-
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
3129
|
-
function isBytes$2(a) {
|
3130
|
-
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
3131
|
-
}
|
3132
3102
|
/** Asserts something is positive integer. */
|
3133
3103
|
function anumber(n) {
|
3134
3104
|
if (!Number.isSafeInteger(n) || n < 0)
|
3135
3105
|
throw new Error('positive integer expected, got ' + n);
|
3136
3106
|
}
|
3107
|
+
/** Is number an Uint8Array? Copied from utils for perf. */
|
3108
|
+
function isBytes$2(a) {
|
3109
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
3110
|
+
}
|
3137
3111
|
/** Asserts something is Uint8Array. */
|
3138
3112
|
function abytes$1(b, ...lengths) {
|
3139
3113
|
if (!isBytes$2(b))
|
@@ -3144,7 +3118,7 @@ function abytes$1(b, ...lengths) {
|
|
3144
3118
|
/** Asserts something is hash */
|
3145
3119
|
function ahash(h) {
|
3146
3120
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
3147
|
-
throw new Error('Hash should be wrapped by utils.
|
3121
|
+
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
3148
3122
|
anumber(h.outputLen);
|
3149
3123
|
anumber(h.blockLen);
|
3150
3124
|
}
|
@@ -3163,13 +3137,21 @@ function aoutput(out, instance) {
|
|
3163
3137
|
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
3164
3138
|
}
|
3165
3139
|
}
|
3166
|
-
|
3167
|
-
|
3168
|
-
|
3169
|
-
|
3170
|
-
|
3171
|
-
|
3172
|
-
|
3140
|
+
|
3141
|
+
const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
3142
|
+
|
3143
|
+
/**
|
3144
|
+
* Utilities for hex, bytes, CSPRNG.
|
3145
|
+
* @module
|
3146
|
+
*/
|
3147
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
3148
|
+
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
3149
|
+
// node.js versions earlier than v19 don't declare it in global scope.
|
3150
|
+
// For node.js, package.json#exports field mapping rewrites import
|
3151
|
+
// from `crypto` to `cryptoNode`, which imports native module.
|
3152
|
+
// Makes the utils un-importable in browsers without a bundler.
|
3153
|
+
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
3154
|
+
// Cast array to view
|
3173
3155
|
function createView(arr) {
|
3174
3156
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
3175
3157
|
}
|
@@ -3178,12 +3160,12 @@ function rotr(word, shift) {
|
|
3178
3160
|
return (word << (32 - shift)) | (word >>> shift);
|
3179
3161
|
}
|
3180
3162
|
/**
|
3181
|
-
*
|
3182
|
-
* @example utf8ToBytes('abc') // Uint8Array
|
3163
|
+
* Convert JS string to byte array.
|
3164
|
+
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
3183
3165
|
*/
|
3184
|
-
function utf8ToBytes(str) {
|
3166
|
+
function utf8ToBytes$1(str) {
|
3185
3167
|
if (typeof str !== 'string')
|
3186
|
-
throw new Error('string
|
3168
|
+
throw new Error('utf8ToBytes expected string, got ' + typeof str);
|
3187
3169
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
3188
3170
|
}
|
3189
3171
|
/**
|
@@ -3193,11 +3175,13 @@ function utf8ToBytes(str) {
|
|
3193
3175
|
*/
|
3194
3176
|
function toBytes$1(data) {
|
3195
3177
|
if (typeof data === 'string')
|
3196
|
-
data = utf8ToBytes(data);
|
3178
|
+
data = utf8ToBytes$1(data);
|
3197
3179
|
abytes$1(data);
|
3198
3180
|
return data;
|
3199
3181
|
}
|
3200
|
-
/**
|
3182
|
+
/**
|
3183
|
+
* Copies several Uint8Arrays into one.
|
3184
|
+
*/
|
3201
3185
|
function concatBytes$1(...arrays) {
|
3202
3186
|
let sum = 0;
|
3203
3187
|
for (let i = 0; i < arrays.length; i++) {
|
@@ -3215,9 +3199,13 @@ function concatBytes$1(...arrays) {
|
|
3215
3199
|
}
|
3216
3200
|
/** For runtime check if class implements interface */
|
3217
3201
|
class Hash {
|
3202
|
+
// Safe version that clones internal state
|
3203
|
+
clone() {
|
3204
|
+
return this._cloneInto();
|
3205
|
+
}
|
3218
3206
|
}
|
3219
3207
|
/** Wraps hash function, creating an interface on top of it */
|
3220
|
-
function
|
3208
|
+
function wrapConstructor(hashCons) {
|
3221
3209
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
3222
3210
|
const tmp = hashCons();
|
3223
3211
|
hashC.outputLen = tmp.outputLen;
|
@@ -3232,7 +3220,7 @@ function randomBytes(bytesLength = 32) {
|
|
3232
3220
|
}
|
3233
3221
|
// Legacy Node.js compatibility
|
3234
3222
|
if (crypto$1 && typeof crypto$1.randomBytes === 'function') {
|
3235
|
-
return
|
3223
|
+
return crypto$1.randomBytes(bytesLength);
|
3236
3224
|
}
|
3237
3225
|
throw new Error('crypto.getRandomValues must be defined');
|
3238
3226
|
}
|
@@ -3269,22 +3257,21 @@ function Maj(a, b, c) {
|
|
3269
3257
|
class HashMD extends Hash {
|
3270
3258
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
3271
3259
|
super();
|
3272
|
-
this.finished = false;
|
3273
|
-
this.length = 0;
|
3274
|
-
this.pos = 0;
|
3275
|
-
this.destroyed = false;
|
3276
3260
|
this.blockLen = blockLen;
|
3277
3261
|
this.outputLen = outputLen;
|
3278
3262
|
this.padOffset = padOffset;
|
3279
3263
|
this.isLE = isLE;
|
3264
|
+
this.finished = false;
|
3265
|
+
this.length = 0;
|
3266
|
+
this.pos = 0;
|
3267
|
+
this.destroyed = false;
|
3280
3268
|
this.buffer = new Uint8Array(blockLen);
|
3281
3269
|
this.view = createView(this.buffer);
|
3282
3270
|
}
|
3283
3271
|
update(data) {
|
3284
3272
|
aexists(this);
|
3285
|
-
data = toBytes$1(data);
|
3286
|
-
abytes$1(data);
|
3287
3273
|
const { view, buffer, blockLen } = this;
|
3274
|
+
data = toBytes$1(data);
|
3288
3275
|
const len = data.length;
|
3289
3276
|
for (let pos = 0; pos < len;) {
|
3290
3277
|
const take = Math.min(blockLen - this.pos, len - pos);
|
@@ -3318,7 +3305,7 @@ class HashMD extends Hash {
|
|
3318
3305
|
let { pos } = this;
|
3319
3306
|
// append the bit '1' to the message
|
3320
3307
|
buffer[pos++] = 0b10000000;
|
3321
|
-
|
3308
|
+
this.buffer.subarray(pos).fill(0);
|
3322
3309
|
// we have less than padOffset left in buffer, so we cannot put length in
|
3323
3310
|
// current block, need process it and pad again
|
3324
3311
|
if (this.padOffset > blockLen - pos) {
|
@@ -3356,90 +3343,28 @@ class HashMD extends Hash {
|
|
3356
3343
|
to || (to = new this.constructor());
|
3357
3344
|
to.set(...this.get());
|
3358
3345
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
3359
|
-
to.destroyed = destroyed;
|
3360
|
-
to.finished = finished;
|
3361
3346
|
to.length = length;
|
3362
3347
|
to.pos = pos;
|
3348
|
+
to.finished = finished;
|
3349
|
+
to.destroyed = destroyed;
|
3363
3350
|
if (length % blockLen)
|
3364
3351
|
to.buffer.set(buffer);
|
3365
3352
|
return to;
|
3366
3353
|
}
|
3367
|
-
clone() {
|
3368
|
-
return this._cloneInto();
|
3369
|
-
}
|
3370
3354
|
}
|
3371
|
-
/**
|
3372
|
-
* Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
|
3373
|
-
* Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
|
3374
|
-
*/
|
3375
|
-
/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
|
3376
|
-
const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
3377
|
-
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
3378
|
-
]);
|
3379
|
-
/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */
|
3380
|
-
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
3381
|
-
0x6a09e667, 0xf3bcc908, 0xbb67ae85, 0x84caa73b, 0x3c6ef372, 0xfe94f82b, 0xa54ff53a, 0x5f1d36f1,
|
3382
|
-
0x510e527f, 0xade682d1, 0x9b05688c, 0x2b3e6c1f, 0x1f83d9ab, 0xfb41bd6b, 0x5be0cd19, 0x137e2179,
|
3383
|
-
]);
|
3384
3355
|
|
3385
3356
|
/**
|
3386
|
-
*
|
3387
|
-
*
|
3388
|
-
*
|
3389
|
-
|
3390
|
-
|
3391
|
-
|
3392
|
-
function fromBig(n, le = false) {
|
3393
|
-
if (le)
|
3394
|
-
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
3395
|
-
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
3396
|
-
}
|
3397
|
-
function split(lst, le = false) {
|
3398
|
-
const len = lst.length;
|
3399
|
-
let Ah = new Uint32Array(len);
|
3400
|
-
let Al = new Uint32Array(len);
|
3401
|
-
for (let i = 0; i < len; i++) {
|
3402
|
-
const { h, l } = fromBig(lst[i], le);
|
3403
|
-
[Ah[i], Al[i]] = [h, l];
|
3404
|
-
}
|
3405
|
-
return [Ah, Al];
|
3406
|
-
}
|
3407
|
-
// for Shift in [0, 32)
|
3408
|
-
const shrSH = (h, _l, s) => h >>> s;
|
3409
|
-
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
3410
|
-
// Right rotate for Shift in [1, 32)
|
3411
|
-
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
3412
|
-
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
3413
|
-
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
|
3414
|
-
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
3415
|
-
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
3416
|
-
// JS uses 32-bit signed integers for bitwise operations which means we cannot
|
3417
|
-
// simple take carry out of low bit sum by shift, we need to use division.
|
3418
|
-
function add(Ah, Al, Bh, Bl) {
|
3419
|
-
const l = (Al >>> 0) + (Bl >>> 0);
|
3420
|
-
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
3421
|
-
}
|
3422
|
-
// Addition with more than 2 elements
|
3423
|
-
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
3424
|
-
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
3425
|
-
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
3426
|
-
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
3427
|
-
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
3428
|
-
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
3429
|
-
|
3430
|
-
/**
|
3431
|
-
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
3432
|
-
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
3433
|
-
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
3434
|
-
* [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
3357
|
+
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
3358
|
+
*
|
3359
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
3360
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
3361
|
+
*
|
3362
|
+
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
3435
3363
|
* @module
|
3436
3364
|
*/
|
3437
|
-
/**
|
3438
|
-
* Round constants:
|
3439
|
-
* First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
|
3440
|
-
*/
|
3365
|
+
/** Round constants: first 32 bits of fractional parts of the cube roots of the first 64 primes 2..311). */
|
3441
3366
|
// prettier-ignore
|
3442
|
-
const SHA256_K = /* @__PURE__ */ Uint32Array
|
3367
|
+
const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
3443
3368
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
3444
3369
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
3445
3370
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
@@ -3449,11 +3374,19 @@ const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
3449
3374
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
3450
3375
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
3451
3376
|
]);
|
3452
|
-
/**
|
3377
|
+
/** Initial state: first 32 bits of fractional parts of the square roots of the first 8 primes 2..19. */
|
3378
|
+
// prettier-ignore
|
3379
|
+
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
3380
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
3381
|
+
]);
|
3382
|
+
/**
|
3383
|
+
* Temporary buffer, not used to store anything between runs.
|
3384
|
+
* Named this way because it matches specification.
|
3385
|
+
*/
|
3453
3386
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
3454
3387
|
class SHA256 extends HashMD {
|
3455
|
-
constructor(
|
3456
|
-
super(64,
|
3388
|
+
constructor() {
|
3389
|
+
super(64, 32, 8, false);
|
3457
3390
|
// We cannot use array here since array allows indexing by variable
|
3458
3391
|
// which means optimizer/compiler cannot use registers.
|
3459
3392
|
this.A = SHA256_IV[0] | 0;
|
@@ -3519,192 +3452,15 @@ class SHA256 extends HashMD {
|
|
3519
3452
|
this.set(A, B, C, D, E, F, G, H);
|
3520
3453
|
}
|
3521
3454
|
roundClean() {
|
3522
|
-
|
3455
|
+
SHA256_W.fill(0);
|
3523
3456
|
}
|
3524
3457
|
destroy() {
|
3525
3458
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
3526
|
-
|
3527
|
-
}
|
3528
|
-
}
|
3529
|
-
// SHA2-512 is slower than sha256 in js because u64 operations are slow.
|
3530
|
-
// Round contants
|
3531
|
-
// First 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409
|
3532
|
-
// prettier-ignore
|
3533
|
-
const K512 = /* @__PURE__ */ (() => split([
|
3534
|
-
'0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
|
3535
|
-
'0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
|
3536
|
-
'0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
|
3537
|
-
'0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
|
3538
|
-
'0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
|
3539
|
-
'0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
|
3540
|
-
'0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
|
3541
|
-
'0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
|
3542
|
-
'0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
|
3543
|
-
'0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
|
3544
|
-
'0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
|
3545
|
-
'0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
|
3546
|
-
'0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
|
3547
|
-
'0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
|
3548
|
-
'0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
|
3549
|
-
'0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
|
3550
|
-
'0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
|
3551
|
-
'0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
|
3552
|
-
'0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
|
3553
|
-
'0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
|
3554
|
-
].map(n => BigInt(n))))();
|
3555
|
-
const SHA512_Kh = /* @__PURE__ */ (() => K512[0])();
|
3556
|
-
const SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
3557
|
-
// Reusable temporary buffers
|
3558
|
-
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
3559
|
-
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
3560
|
-
class SHA512 extends HashMD {
|
3561
|
-
constructor(outputLen = 64) {
|
3562
|
-
super(128, outputLen, 16, false);
|
3563
|
-
// We cannot use array here since array allows indexing by variable
|
3564
|
-
// which means optimizer/compiler cannot use registers.
|
3565
|
-
// h -- high 32 bits, l -- low 32 bits
|
3566
|
-
this.Ah = SHA512_IV[0] | 0;
|
3567
|
-
this.Al = SHA512_IV[1] | 0;
|
3568
|
-
this.Bh = SHA512_IV[2] | 0;
|
3569
|
-
this.Bl = SHA512_IV[3] | 0;
|
3570
|
-
this.Ch = SHA512_IV[4] | 0;
|
3571
|
-
this.Cl = SHA512_IV[5] | 0;
|
3572
|
-
this.Dh = SHA512_IV[6] | 0;
|
3573
|
-
this.Dl = SHA512_IV[7] | 0;
|
3574
|
-
this.Eh = SHA512_IV[8] | 0;
|
3575
|
-
this.El = SHA512_IV[9] | 0;
|
3576
|
-
this.Fh = SHA512_IV[10] | 0;
|
3577
|
-
this.Fl = SHA512_IV[11] | 0;
|
3578
|
-
this.Gh = SHA512_IV[12] | 0;
|
3579
|
-
this.Gl = SHA512_IV[13] | 0;
|
3580
|
-
this.Hh = SHA512_IV[14] | 0;
|
3581
|
-
this.Hl = SHA512_IV[15] | 0;
|
3582
|
-
}
|
3583
|
-
// prettier-ignore
|
3584
|
-
get() {
|
3585
|
-
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
3586
|
-
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
3587
|
-
}
|
3588
|
-
// prettier-ignore
|
3589
|
-
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
3590
|
-
this.Ah = Ah | 0;
|
3591
|
-
this.Al = Al | 0;
|
3592
|
-
this.Bh = Bh | 0;
|
3593
|
-
this.Bl = Bl | 0;
|
3594
|
-
this.Ch = Ch | 0;
|
3595
|
-
this.Cl = Cl | 0;
|
3596
|
-
this.Dh = Dh | 0;
|
3597
|
-
this.Dl = Dl | 0;
|
3598
|
-
this.Eh = Eh | 0;
|
3599
|
-
this.El = El | 0;
|
3600
|
-
this.Fh = Fh | 0;
|
3601
|
-
this.Fl = Fl | 0;
|
3602
|
-
this.Gh = Gh | 0;
|
3603
|
-
this.Gl = Gl | 0;
|
3604
|
-
this.Hh = Hh | 0;
|
3605
|
-
this.Hl = Hl | 0;
|
3606
|
-
}
|
3607
|
-
process(view, offset) {
|
3608
|
-
// Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
|
3609
|
-
for (let i = 0; i < 16; i++, offset += 4) {
|
3610
|
-
SHA512_W_H[i] = view.getUint32(offset);
|
3611
|
-
SHA512_W_L[i] = view.getUint32((offset += 4));
|
3612
|
-
}
|
3613
|
-
for (let i = 16; i < 80; i++) {
|
3614
|
-
// s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
|
3615
|
-
const W15h = SHA512_W_H[i - 15] | 0;
|
3616
|
-
const W15l = SHA512_W_L[i - 15] | 0;
|
3617
|
-
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
3618
|
-
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
3619
|
-
// s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
|
3620
|
-
const W2h = SHA512_W_H[i - 2] | 0;
|
3621
|
-
const W2l = SHA512_W_L[i - 2] | 0;
|
3622
|
-
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
3623
|
-
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
3624
|
-
// SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
|
3625
|
-
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
3626
|
-
const SUMh = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
3627
|
-
SHA512_W_H[i] = SUMh | 0;
|
3628
|
-
SHA512_W_L[i] = SUMl | 0;
|
3629
|
-
}
|
3630
|
-
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
3631
|
-
// Compression function main loop, 80 rounds
|
3632
|
-
for (let i = 0; i < 80; i++) {
|
3633
|
-
// S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
|
3634
|
-
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
3635
|
-
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
3636
|
-
//const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
|
3637
|
-
const CHIh = (Eh & Fh) ^ (~Eh & Gh);
|
3638
|
-
const CHIl = (El & Fl) ^ (~El & Gl);
|
3639
|
-
// T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
|
3640
|
-
// prettier-ignore
|
3641
|
-
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
3642
|
-
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
3643
|
-
const T1l = T1ll | 0;
|
3644
|
-
// S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
|
3645
|
-
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
3646
|
-
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
3647
|
-
const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
|
3648
|
-
const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
|
3649
|
-
Hh = Gh | 0;
|
3650
|
-
Hl = Gl | 0;
|
3651
|
-
Gh = Fh | 0;
|
3652
|
-
Gl = Fl | 0;
|
3653
|
-
Fh = Eh | 0;
|
3654
|
-
Fl = El | 0;
|
3655
|
-
({ h: Eh, l: El } = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
3656
|
-
Dh = Ch | 0;
|
3657
|
-
Dl = Cl | 0;
|
3658
|
-
Ch = Bh | 0;
|
3659
|
-
Cl = Bl | 0;
|
3660
|
-
Bh = Ah | 0;
|
3661
|
-
Bl = Al | 0;
|
3662
|
-
const All = add3L(T1l, sigma0l, MAJl);
|
3663
|
-
Ah = add3H(All, T1h, sigma0h, MAJh);
|
3664
|
-
Al = All | 0;
|
3665
|
-
}
|
3666
|
-
// Add the compressed chunk to the current hash value
|
3667
|
-
({ h: Ah, l: Al } = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
3668
|
-
({ h: Bh, l: Bl } = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
3669
|
-
({ h: Ch, l: Cl } = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
3670
|
-
({ h: Dh, l: Dl } = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
3671
|
-
({ h: Eh, l: El } = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
3672
|
-
({ h: Fh, l: Fl } = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
3673
|
-
({ h: Gh, l: Gl } = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
3674
|
-
({ h: Hh, l: Hl } = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
3675
|
-
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
3676
|
-
}
|
3677
|
-
roundClean() {
|
3678
|
-
clean(SHA512_W_H, SHA512_W_L);
|
3679
|
-
}
|
3680
|
-
destroy() {
|
3681
|
-
clean(this.buffer);
|
3682
|
-
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
3459
|
+
this.buffer.fill(0);
|
3683
3460
|
}
|
3684
3461
|
}
|
3685
|
-
/**
|
3686
|
-
|
3687
|
-
*
|
3688
|
-
* It is the fastest JS hash, even faster than Blake3.
|
3689
|
-
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
3690
|
-
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
3691
|
-
*/
|
3692
|
-
const sha256$1 = /* @__PURE__ */ createHasher(() => new SHA256());
|
3693
|
-
/** SHA2-512 hash function from RFC 4634. */
|
3694
|
-
const sha512 = /* @__PURE__ */ createHasher(() => new SHA512());
|
3695
|
-
|
3696
|
-
/**
|
3697
|
-
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
3698
|
-
*
|
3699
|
-
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
3700
|
-
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
3701
|
-
*
|
3702
|
-
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
3703
|
-
* @module
|
3704
|
-
* @deprecated
|
3705
|
-
*/
|
3706
|
-
/** @deprecated Use import from `noble/hashes/sha2` module */
|
3707
|
-
const sha256 = sha256$1;
|
3462
|
+
/** SHA2-256 hash function */
|
3463
|
+
const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
3708
3464
|
|
3709
3465
|
var Protocols;
|
3710
3466
|
(function (Protocols) {
|
@@ -6973,38 +6729,265 @@ function getOID(curve) {
|
|
6973
6729
|
throw new InvalidParametersError(`Invalid curve ${curve}`);
|
6974
6730
|
}
|
6975
6731
|
|
6976
|
-
class ECDSAPublicKey {
|
6977
|
-
type = 'ECDSA';
|
6978
|
-
jwk;
|
6979
|
-
_raw;
|
6980
|
-
constructor(jwk) {
|
6981
|
-
this.jwk = jwk;
|
6982
|
-
}
|
6983
|
-
get raw() {
|
6984
|
-
if (this._raw == null) {
|
6985
|
-
this._raw = publicKeyToPKIMessage(this.jwk);
|
6986
|
-
}
|
6987
|
-
return this._raw;
|
6988
|
-
}
|
6989
|
-
toMultihash() {
|
6990
|
-
return identity.digest(publicKeyToProtobuf(this));
|
6732
|
+
class ECDSAPublicKey {
|
6733
|
+
type = 'ECDSA';
|
6734
|
+
jwk;
|
6735
|
+
_raw;
|
6736
|
+
constructor(jwk) {
|
6737
|
+
this.jwk = jwk;
|
6738
|
+
}
|
6739
|
+
get raw() {
|
6740
|
+
if (this._raw == null) {
|
6741
|
+
this._raw = publicKeyToPKIMessage(this.jwk);
|
6742
|
+
}
|
6743
|
+
return this._raw;
|
6744
|
+
}
|
6745
|
+
toMultihash() {
|
6746
|
+
return identity.digest(publicKeyToProtobuf(this));
|
6747
|
+
}
|
6748
|
+
toCID() {
|
6749
|
+
return CID.createV1(114, this.toMultihash());
|
6750
|
+
}
|
6751
|
+
toString() {
|
6752
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
6753
|
+
}
|
6754
|
+
equals(key) {
|
6755
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
6756
|
+
return false;
|
6757
|
+
}
|
6758
|
+
return equals(this.raw, key.raw);
|
6759
|
+
}
|
6760
|
+
async verify(data, sig) {
|
6761
|
+
return hashAndVerify$3(this.jwk, sig, data);
|
6762
|
+
}
|
6763
|
+
}
|
6764
|
+
|
6765
|
+
/**
|
6766
|
+
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
6767
|
+
* @todo re-check https://issues.chromium.org/issues/42212588
|
6768
|
+
* @module
|
6769
|
+
*/
|
6770
|
+
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
6771
|
+
const _32n = /* @__PURE__ */ BigInt(32);
|
6772
|
+
function fromBig(n, le = false) {
|
6773
|
+
if (le)
|
6774
|
+
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
6775
|
+
return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
6776
|
+
}
|
6777
|
+
function split(lst, le = false) {
|
6778
|
+
let Ah = new Uint32Array(lst.length);
|
6779
|
+
let Al = new Uint32Array(lst.length);
|
6780
|
+
for (let i = 0; i < lst.length; i++) {
|
6781
|
+
const { h, l } = fromBig(lst[i], le);
|
6782
|
+
[Ah[i], Al[i]] = [h, l];
|
6783
|
+
}
|
6784
|
+
return [Ah, Al];
|
6785
|
+
}
|
6786
|
+
const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
|
6787
|
+
// for Shift in [0, 32)
|
6788
|
+
const shrSH = (h, _l, s) => h >>> s;
|
6789
|
+
const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
6790
|
+
// Right rotate for Shift in [1, 32)
|
6791
|
+
const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
|
6792
|
+
const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
|
6793
|
+
// Right rotate for Shift in (32, 64), NOTE: 32 is special case.
|
6794
|
+
const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
|
6795
|
+
const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
|
6796
|
+
// Right rotate for shift===32 (just swaps l&h)
|
6797
|
+
const rotr32H = (_h, l) => l;
|
6798
|
+
const rotr32L = (h, _l) => h;
|
6799
|
+
// Left rotate for Shift in [1, 32)
|
6800
|
+
const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
|
6801
|
+
const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
|
6802
|
+
// Left rotate for Shift in (32, 64), NOTE: 32 is special case.
|
6803
|
+
const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
|
6804
|
+
const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
|
6805
|
+
// JS uses 32-bit signed integers for bitwise operations which means we cannot
|
6806
|
+
// simple take carry out of low bit sum by shift, we need to use division.
|
6807
|
+
function add(Ah, Al, Bh, Bl) {
|
6808
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
6809
|
+
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
|
6810
|
+
}
|
6811
|
+
// Addition with more than 2 elements
|
6812
|
+
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
6813
|
+
const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
|
6814
|
+
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
6815
|
+
const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
|
6816
|
+
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
6817
|
+
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
|
6818
|
+
// prettier-ignore
|
6819
|
+
const u64 = {
|
6820
|
+
fromBig, split, toBig,
|
6821
|
+
shrSH, shrSL,
|
6822
|
+
rotrSH, rotrSL, rotrBH, rotrBL,
|
6823
|
+
rotr32H, rotr32L,
|
6824
|
+
rotlSH, rotlSL, rotlBH, rotlBL,
|
6825
|
+
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
6826
|
+
};
|
6827
|
+
|
6828
|
+
/**
|
6829
|
+
* SHA2-512 a.k.a. sha512 and sha384. It is slower than sha256 in js because u64 operations are slow.
|
6830
|
+
*
|
6831
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
6832
|
+
* [the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
|
6833
|
+
* @module
|
6834
|
+
*/
|
6835
|
+
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
6836
|
+
// prettier-ignore
|
6837
|
+
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
6838
|
+
'0x428a2f98d728ae22', '0x7137449123ef65cd', '0xb5c0fbcfec4d3b2f', '0xe9b5dba58189dbbc',
|
6839
|
+
'0x3956c25bf348b538', '0x59f111f1b605d019', '0x923f82a4af194f9b', '0xab1c5ed5da6d8118',
|
6840
|
+
'0xd807aa98a3030242', '0x12835b0145706fbe', '0x243185be4ee4b28c', '0x550c7dc3d5ffb4e2',
|
6841
|
+
'0x72be5d74f27b896f', '0x80deb1fe3b1696b1', '0x9bdc06a725c71235', '0xc19bf174cf692694',
|
6842
|
+
'0xe49b69c19ef14ad2', '0xefbe4786384f25e3', '0x0fc19dc68b8cd5b5', '0x240ca1cc77ac9c65',
|
6843
|
+
'0x2de92c6f592b0275', '0x4a7484aa6ea6e483', '0x5cb0a9dcbd41fbd4', '0x76f988da831153b5',
|
6844
|
+
'0x983e5152ee66dfab', '0xa831c66d2db43210', '0xb00327c898fb213f', '0xbf597fc7beef0ee4',
|
6845
|
+
'0xc6e00bf33da88fc2', '0xd5a79147930aa725', '0x06ca6351e003826f', '0x142929670a0e6e70',
|
6846
|
+
'0x27b70a8546d22ffc', '0x2e1b21385c26c926', '0x4d2c6dfc5ac42aed', '0x53380d139d95b3df',
|
6847
|
+
'0x650a73548baf63de', '0x766a0abb3c77b2a8', '0x81c2c92e47edaee6', '0x92722c851482353b',
|
6848
|
+
'0xa2bfe8a14cf10364', '0xa81a664bbc423001', '0xc24b8b70d0f89791', '0xc76c51a30654be30',
|
6849
|
+
'0xd192e819d6ef5218', '0xd69906245565a910', '0xf40e35855771202a', '0x106aa07032bbd1b8',
|
6850
|
+
'0x19a4c116b8d2d0c8', '0x1e376c085141ab53', '0x2748774cdf8eeb99', '0x34b0bcb5e19b48a8',
|
6851
|
+
'0x391c0cb3c5c95a63', '0x4ed8aa4ae3418acb', '0x5b9cca4f7763e373', '0x682e6ff3d6b2b8a3',
|
6852
|
+
'0x748f82ee5defb2fc', '0x78a5636f43172f60', '0x84c87814a1f0ab72', '0x8cc702081a6439ec',
|
6853
|
+
'0x90befffa23631e28', '0xa4506cebde82bde9', '0xbef9a3f7b2c67915', '0xc67178f2e372532b',
|
6854
|
+
'0xca273eceea26619c', '0xd186b8c721c0c207', '0xeada7dd6cde0eb1e', '0xf57d4f7fee6ed178',
|
6855
|
+
'0x06f067aa72176fba', '0x0a637dc5a2c898a6', '0x113f9804bef90dae', '0x1b710b35131c471b',
|
6856
|
+
'0x28db77f523047d84', '0x32caab7b40c72493', '0x3c9ebe0a15c9bebc', '0x431d67c49c100d4c',
|
6857
|
+
'0x4cc5d4becb3e42b6', '0x597f299cfc657e2a', '0x5fcb6fab3ad6faec', '0x6c44198c4a475817'
|
6858
|
+
].map(n => BigInt(n))))();
|
6859
|
+
// Temporary buffer, not used to store anything between runs
|
6860
|
+
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
6861
|
+
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
6862
|
+
class SHA512 extends HashMD {
|
6863
|
+
constructor() {
|
6864
|
+
super(128, 64, 16, false);
|
6865
|
+
// We cannot use array here since array allows indexing by variable which means optimizer/compiler cannot use registers.
|
6866
|
+
// Also looks cleaner and easier to verify with spec.
|
6867
|
+
// Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
|
6868
|
+
// h -- high 32 bits, l -- low 32 bits
|
6869
|
+
this.Ah = 0x6a09e667 | 0;
|
6870
|
+
this.Al = 0xf3bcc908 | 0;
|
6871
|
+
this.Bh = 0xbb67ae85 | 0;
|
6872
|
+
this.Bl = 0x84caa73b | 0;
|
6873
|
+
this.Ch = 0x3c6ef372 | 0;
|
6874
|
+
this.Cl = 0xfe94f82b | 0;
|
6875
|
+
this.Dh = 0xa54ff53a | 0;
|
6876
|
+
this.Dl = 0x5f1d36f1 | 0;
|
6877
|
+
this.Eh = 0x510e527f | 0;
|
6878
|
+
this.El = 0xade682d1 | 0;
|
6879
|
+
this.Fh = 0x9b05688c | 0;
|
6880
|
+
this.Fl = 0x2b3e6c1f | 0;
|
6881
|
+
this.Gh = 0x1f83d9ab | 0;
|
6882
|
+
this.Gl = 0xfb41bd6b | 0;
|
6883
|
+
this.Hh = 0x5be0cd19 | 0;
|
6884
|
+
this.Hl = 0x137e2179 | 0;
|
6991
6885
|
}
|
6992
|
-
|
6993
|
-
|
6886
|
+
// prettier-ignore
|
6887
|
+
get() {
|
6888
|
+
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
6889
|
+
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
|
6994
6890
|
}
|
6995
|
-
|
6996
|
-
|
6891
|
+
// prettier-ignore
|
6892
|
+
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
6893
|
+
this.Ah = Ah | 0;
|
6894
|
+
this.Al = Al | 0;
|
6895
|
+
this.Bh = Bh | 0;
|
6896
|
+
this.Bl = Bl | 0;
|
6897
|
+
this.Ch = Ch | 0;
|
6898
|
+
this.Cl = Cl | 0;
|
6899
|
+
this.Dh = Dh | 0;
|
6900
|
+
this.Dl = Dl | 0;
|
6901
|
+
this.Eh = Eh | 0;
|
6902
|
+
this.El = El | 0;
|
6903
|
+
this.Fh = Fh | 0;
|
6904
|
+
this.Fl = Fl | 0;
|
6905
|
+
this.Gh = Gh | 0;
|
6906
|
+
this.Gl = Gl | 0;
|
6907
|
+
this.Hh = Hh | 0;
|
6908
|
+
this.Hl = Hl | 0;
|
6997
6909
|
}
|
6998
|
-
|
6999
|
-
|
7000
|
-
|
6910
|
+
process(view, offset) {
|
6911
|
+
// Extend the first 16 words into the remaining 64 words w[16..79] of the message schedule array
|
6912
|
+
for (let i = 0; i < 16; i++, offset += 4) {
|
6913
|
+
SHA512_W_H[i] = view.getUint32(offset);
|
6914
|
+
SHA512_W_L[i] = view.getUint32((offset += 4));
|
7001
6915
|
}
|
7002
|
-
|
6916
|
+
for (let i = 16; i < 80; i++) {
|
6917
|
+
// s0 := (w[i-15] rightrotate 1) xor (w[i-15] rightrotate 8) xor (w[i-15] rightshift 7)
|
6918
|
+
const W15h = SHA512_W_H[i - 15] | 0;
|
6919
|
+
const W15l = SHA512_W_L[i - 15] | 0;
|
6920
|
+
const s0h = u64.rotrSH(W15h, W15l, 1) ^ u64.rotrSH(W15h, W15l, 8) ^ u64.shrSH(W15h, W15l, 7);
|
6921
|
+
const s0l = u64.rotrSL(W15h, W15l, 1) ^ u64.rotrSL(W15h, W15l, 8) ^ u64.shrSL(W15h, W15l, 7);
|
6922
|
+
// s1 := (w[i-2] rightrotate 19) xor (w[i-2] rightrotate 61) xor (w[i-2] rightshift 6)
|
6923
|
+
const W2h = SHA512_W_H[i - 2] | 0;
|
6924
|
+
const W2l = SHA512_W_L[i - 2] | 0;
|
6925
|
+
const s1h = u64.rotrSH(W2h, W2l, 19) ^ u64.rotrBH(W2h, W2l, 61) ^ u64.shrSH(W2h, W2l, 6);
|
6926
|
+
const s1l = u64.rotrSL(W2h, W2l, 19) ^ u64.rotrBL(W2h, W2l, 61) ^ u64.shrSL(W2h, W2l, 6);
|
6927
|
+
// SHA256_W[i] = s0 + s1 + SHA256_W[i - 7] + SHA256_W[i - 16];
|
6928
|
+
const SUMl = u64.add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
6929
|
+
const SUMh = u64.add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]);
|
6930
|
+
SHA512_W_H[i] = SUMh | 0;
|
6931
|
+
SHA512_W_L[i] = SUMl | 0;
|
6932
|
+
}
|
6933
|
+
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
6934
|
+
// Compression function main loop, 80 rounds
|
6935
|
+
for (let i = 0; i < 80; i++) {
|
6936
|
+
// S1 := (e rightrotate 14) xor (e rightrotate 18) xor (e rightrotate 41)
|
6937
|
+
const sigma1h = u64.rotrSH(Eh, El, 14) ^ u64.rotrSH(Eh, El, 18) ^ u64.rotrBH(Eh, El, 41);
|
6938
|
+
const sigma1l = u64.rotrSL(Eh, El, 14) ^ u64.rotrSL(Eh, El, 18) ^ u64.rotrBL(Eh, El, 41);
|
6939
|
+
//const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
|
6940
|
+
const CHIh = (Eh & Fh) ^ (~Eh & Gh);
|
6941
|
+
const CHIl = (El & Fl) ^ (~El & Gl);
|
6942
|
+
// T1 = H + sigma1 + Chi(E, F, G) + SHA512_K[i] + SHA512_W[i]
|
6943
|
+
// prettier-ignore
|
6944
|
+
const T1ll = u64.add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
6945
|
+
const T1h = u64.add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
6946
|
+
const T1l = T1ll | 0;
|
6947
|
+
// S0 := (a rightrotate 28) xor (a rightrotate 34) xor (a rightrotate 39)
|
6948
|
+
const sigma0h = u64.rotrSH(Ah, Al, 28) ^ u64.rotrBH(Ah, Al, 34) ^ u64.rotrBH(Ah, Al, 39);
|
6949
|
+
const sigma0l = u64.rotrSL(Ah, Al, 28) ^ u64.rotrBL(Ah, Al, 34) ^ u64.rotrBL(Ah, Al, 39);
|
6950
|
+
const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
|
6951
|
+
const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
|
6952
|
+
Hh = Gh | 0;
|
6953
|
+
Hl = Gl | 0;
|
6954
|
+
Gh = Fh | 0;
|
6955
|
+
Gl = Fl | 0;
|
6956
|
+
Fh = Eh | 0;
|
6957
|
+
Fl = El | 0;
|
6958
|
+
({ h: Eh, l: El } = u64.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
6959
|
+
Dh = Ch | 0;
|
6960
|
+
Dl = Cl | 0;
|
6961
|
+
Ch = Bh | 0;
|
6962
|
+
Cl = Bl | 0;
|
6963
|
+
Bh = Ah | 0;
|
6964
|
+
Bl = Al | 0;
|
6965
|
+
const All = u64.add3L(T1l, sigma0l, MAJl);
|
6966
|
+
Ah = u64.add3H(All, T1h, sigma0h, MAJh);
|
6967
|
+
Al = All | 0;
|
6968
|
+
}
|
6969
|
+
// Add the compressed chunk to the current hash value
|
6970
|
+
({ h: Ah, l: Al } = u64.add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
6971
|
+
({ h: Bh, l: Bl } = u64.add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
6972
|
+
({ h: Ch, l: Cl } = u64.add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
6973
|
+
({ h: Dh, l: Dl } = u64.add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
6974
|
+
({ h: Eh, l: El } = u64.add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
6975
|
+
({ h: Fh, l: Fl } = u64.add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
6976
|
+
({ h: Gh, l: Gl } = u64.add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
6977
|
+
({ h: Hh, l: Hl } = u64.add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
6978
|
+
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
7003
6979
|
}
|
7004
|
-
|
7005
|
-
|
6980
|
+
roundClean() {
|
6981
|
+
SHA512_W_H.fill(0);
|
6982
|
+
SHA512_W_L.fill(0);
|
6983
|
+
}
|
6984
|
+
destroy() {
|
6985
|
+
this.buffer.fill(0);
|
6986
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
7006
6987
|
}
|
7007
6988
|
}
|
6989
|
+
/** SHA2-512 hash function. */
|
6990
|
+
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
7008
6991
|
|
7009
6992
|
/**
|
7010
6993
|
* Hex, bytes and number utilities.
|
@@ -7017,6 +7000,7 @@ class ECDSAPublicKey {
|
|
7017
7000
|
// won't be included into their bundle.
|
7018
7001
|
const _0n$4 = /* @__PURE__ */ BigInt(0);
|
7019
7002
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
7003
|
+
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
7020
7004
|
function isBytes$1(a) {
|
7021
7005
|
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
7022
7006
|
}
|
@@ -7028,31 +7012,13 @@ function abool(title, value) {
|
|
7028
7012
|
if (typeof value !== 'boolean')
|
7029
7013
|
throw new Error(title + ' boolean expected, got ' + value);
|
7030
7014
|
}
|
7031
|
-
// Used in weierstrass, der
|
7032
|
-
function numberToHexUnpadded(num) {
|
7033
|
-
const hex = num.toString(16);
|
7034
|
-
return hex.length & 1 ? '0' + hex : hex;
|
7035
|
-
}
|
7036
|
-
function hexToNumber(hex) {
|
7037
|
-
if (typeof hex !== 'string')
|
7038
|
-
throw new Error('hex string expected, got ' + typeof hex);
|
7039
|
-
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
7040
|
-
}
|
7041
|
-
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
|
7042
|
-
const hasHexBuiltin =
|
7043
|
-
// @ts-ignore
|
7044
|
-
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function';
|
7045
7015
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
7046
7016
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
7047
7017
|
/**
|
7048
|
-
* Convert byte array to hex string. Uses built-in function, when available.
|
7049
7018
|
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
7050
7019
|
*/
|
7051
7020
|
function bytesToHex(bytes) {
|
7052
7021
|
abytes(bytes);
|
7053
|
-
// @ts-ignore
|
7054
|
-
if (hasHexBuiltin)
|
7055
|
-
return bytes.toHex();
|
7056
7022
|
// pre-caching improves the speed 6x
|
7057
7023
|
let hex = '';
|
7058
7024
|
for (let i = 0; i < bytes.length; i++) {
|
@@ -7060,6 +7026,15 @@ function bytesToHex(bytes) {
|
|
7060
7026
|
}
|
7061
7027
|
return hex;
|
7062
7028
|
}
|
7029
|
+
function numberToHexUnpadded(num) {
|
7030
|
+
const hex = num.toString(16);
|
7031
|
+
return hex.length & 1 ? '0' + hex : hex;
|
7032
|
+
}
|
7033
|
+
function hexToNumber(hex) {
|
7034
|
+
if (typeof hex !== 'string')
|
7035
|
+
throw new Error('hex string expected, got ' + typeof hex);
|
7036
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
7037
|
+
}
|
7063
7038
|
// We use optimized technique to convert hex string to byte array
|
7064
7039
|
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
7065
7040
|
function asciiToBase16(ch) {
|
@@ -7072,15 +7047,11 @@ function asciiToBase16(ch) {
|
|
7072
7047
|
return;
|
7073
7048
|
}
|
7074
7049
|
/**
|
7075
|
-
* Convert hex string to byte array. Uses built-in function, when available.
|
7076
7050
|
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
7077
7051
|
*/
|
7078
7052
|
function hexToBytes(hex) {
|
7079
7053
|
if (typeof hex !== 'string')
|
7080
7054
|
throw new Error('hex string expected, got ' + typeof hex);
|
7081
|
-
// @ts-ignore
|
7082
|
-
if (hasHexBuiltin)
|
7083
|
-
return Uint8Array.fromHex(hex);
|
7084
7055
|
const hl = hex.length;
|
7085
7056
|
const al = hl / 2;
|
7086
7057
|
if (hl % 2)
|
@@ -7111,6 +7082,10 @@ function numberToBytesBE(n, len) {
|
|
7111
7082
|
function numberToBytesLE(n, len) {
|
7112
7083
|
return numberToBytesBE(n, len).reverse();
|
7113
7084
|
}
|
7085
|
+
// Unpadded, rarely used
|
7086
|
+
function numberToVarBytesBE(n) {
|
7087
|
+
return hexToBytes(numberToHexUnpadded(n));
|
7088
|
+
}
|
7114
7089
|
/**
|
7115
7090
|
* Takes hex string or Uint8Array, converts to Uint8Array.
|
7116
7091
|
* Validates output length.
|
@@ -7161,6 +7136,23 @@ function concatBytes(...arrays) {
|
|
7161
7136
|
}
|
7162
7137
|
return res;
|
7163
7138
|
}
|
7139
|
+
// Compares 2 u8a-s in kinda constant time
|
7140
|
+
function equalBytes(a, b) {
|
7141
|
+
if (a.length !== b.length)
|
7142
|
+
return false;
|
7143
|
+
let diff = 0;
|
7144
|
+
for (let i = 0; i < a.length; i++)
|
7145
|
+
diff |= a[i] ^ b[i];
|
7146
|
+
return diff === 0;
|
7147
|
+
}
|
7148
|
+
/**
|
7149
|
+
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
7150
|
+
*/
|
7151
|
+
function utf8ToBytes(str) {
|
7152
|
+
if (typeof str !== 'string')
|
7153
|
+
throw new Error('string expected');
|
7154
|
+
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
7155
|
+
}
|
7164
7156
|
// Is positive bigint
|
7165
7157
|
const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
|
7166
7158
|
function inRange(n, min, max) {
|
@@ -7184,7 +7176,6 @@ function aInRange(title, n, min, max) {
|
|
7184
7176
|
/**
|
7185
7177
|
* Calculates amount of bits in a bigint.
|
7186
7178
|
* Same as `n.toString(2).length`
|
7187
|
-
* TODO: merge with nLength in modular
|
7188
7179
|
*/
|
7189
7180
|
function bitLen(n) {
|
7190
7181
|
let len;
|
@@ -7192,13 +7183,27 @@ function bitLen(n) {
|
|
7192
7183
|
;
|
7193
7184
|
return len;
|
7194
7185
|
}
|
7186
|
+
/**
|
7187
|
+
* Gets single bit at position.
|
7188
|
+
* NOTE: first bit position is 0 (same as arrays)
|
7189
|
+
* Same as `!!+Array.from(n.toString(2)).reverse()[pos]`
|
7190
|
+
*/
|
7191
|
+
function bitGet(n, pos) {
|
7192
|
+
return (n >> BigInt(pos)) & _1n$6;
|
7193
|
+
}
|
7194
|
+
/**
|
7195
|
+
* Sets single bit at position.
|
7196
|
+
*/
|
7197
|
+
function bitSet(n, pos, value) {
|
7198
|
+
return n | ((value ? _1n$6 : _0n$4) << BigInt(pos));
|
7199
|
+
}
|
7195
7200
|
/**
|
7196
7201
|
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
7197
7202
|
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
7198
7203
|
*/
|
7199
|
-
const bitMask = (n) => (
|
7204
|
+
const bitMask = (n) => (_2n$4 << BigInt(n - 1)) - _1n$6;
|
7200
7205
|
// DRBG
|
7201
|
-
const u8n = (
|
7206
|
+
const u8n = (data) => new Uint8Array(data); // creates Uint8Array
|
7202
7207
|
const u8fr = (arr) => Uint8Array.from(arr); // another shortcut
|
7203
7208
|
/**
|
7204
7209
|
* Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
@@ -7224,7 +7229,7 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
7224
7229
|
i = 0;
|
7225
7230
|
};
|
7226
7231
|
const h = (...b) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)
|
7227
|
-
const reseed = (seed = u8n(
|
7232
|
+
const reseed = (seed = u8n()) => {
|
7228
7233
|
// HMAC-DRBG reseed() function. Steps D-G
|
7229
7234
|
k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)
|
7230
7235
|
v = h(); // v = hmac(k || v)
|
@@ -7289,6 +7294,20 @@ function validateObject(object, validators, optValidators = {}) {
|
|
7289
7294
|
checkField(fieldName, type, true);
|
7290
7295
|
return object;
|
7291
7296
|
}
|
7297
|
+
// validate type tests
|
7298
|
+
// const o: { a: number; b: number; c: number } = { a: 1, b: 5, c: 6 };
|
7299
|
+
// const z0 = validateObject(o, { a: 'isSafeInteger' }, { c: 'bigint' }); // Ok!
|
7300
|
+
// // Should fail type-check
|
7301
|
+
// const z1 = validateObject(o, { a: 'tmp' }, { c: 'zz' });
|
7302
|
+
// const z2 = validateObject(o, { a: 'isSafeInteger' }, { c: 'zz' });
|
7303
|
+
// const z3 = validateObject(o, { test: 'boolean', z: 'bug' });
|
7304
|
+
// const z4 = validateObject(o, { a: 'boolean', z: 'bug' });
|
7305
|
+
/**
|
7306
|
+
* throws not implemented error
|
7307
|
+
*/
|
7308
|
+
const notImplemented = () => {
|
7309
|
+
throw new Error('not implemented');
|
7310
|
+
};
|
7292
7311
|
/**
|
7293
7312
|
* Memoizes (caches) computation result.
|
7294
7313
|
* Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
|
@@ -7305,6 +7324,36 @@ function memoized(fn) {
|
|
7305
7324
|
};
|
7306
7325
|
}
|
7307
7326
|
|
7327
|
+
var ut = /*#__PURE__*/Object.freeze({
|
7328
|
+
__proto__: null,
|
7329
|
+
aInRange: aInRange,
|
7330
|
+
abool: abool,
|
7331
|
+
abytes: abytes,
|
7332
|
+
bitGet: bitGet,
|
7333
|
+
bitLen: bitLen,
|
7334
|
+
bitMask: bitMask,
|
7335
|
+
bitSet: bitSet,
|
7336
|
+
bytesToHex: bytesToHex,
|
7337
|
+
bytesToNumberBE: bytesToNumberBE,
|
7338
|
+
bytesToNumberLE: bytesToNumberLE,
|
7339
|
+
concatBytes: concatBytes,
|
7340
|
+
createHmacDrbg: createHmacDrbg,
|
7341
|
+
ensureBytes: ensureBytes,
|
7342
|
+
equalBytes: equalBytes,
|
7343
|
+
hexToBytes: hexToBytes,
|
7344
|
+
hexToNumber: hexToNumber,
|
7345
|
+
inRange: inRange,
|
7346
|
+
isBytes: isBytes$1,
|
7347
|
+
memoized: memoized,
|
7348
|
+
notImplemented: notImplemented,
|
7349
|
+
numberToBytesBE: numberToBytesBE,
|
7350
|
+
numberToBytesLE: numberToBytesLE,
|
7351
|
+
numberToHexUnpadded: numberToHexUnpadded,
|
7352
|
+
numberToVarBytesBE: numberToVarBytesBE,
|
7353
|
+
utf8ToBytes: utf8ToBytes,
|
7354
|
+
validateObject: validateObject
|
7355
|
+
});
|
7356
|
+
|
7308
7357
|
/**
|
7309
7358
|
* Utils for modular division and finite fields.
|
7310
7359
|
* A finite field over 11 is integer number operations `mod 11`.
|
@@ -7321,6 +7370,29 @@ function mod(a, b) {
|
|
7321
7370
|
const result = a % b;
|
7322
7371
|
return result >= _0n$3 ? result : b + result;
|
7323
7372
|
}
|
7373
|
+
/**
|
7374
|
+
* Efficiently raise num to power and do modular division.
|
7375
|
+
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
7376
|
+
* @todo use field version && remove
|
7377
|
+
* @example
|
7378
|
+
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
7379
|
+
*/
|
7380
|
+
function pow(num, power, modulo) {
|
7381
|
+
if (power < _0n$3)
|
7382
|
+
throw new Error('invalid exponent, negatives unsupported');
|
7383
|
+
if (modulo <= _0n$3)
|
7384
|
+
throw new Error('invalid modulus');
|
7385
|
+
if (modulo === _1n$5)
|
7386
|
+
return _0n$3;
|
7387
|
+
let res = _1n$5;
|
7388
|
+
while (power > _0n$3) {
|
7389
|
+
if (power & _1n$5)
|
7390
|
+
res = (res * num) % modulo;
|
7391
|
+
num = (num * num) % modulo;
|
7392
|
+
power >>= _1n$5;
|
7393
|
+
}
|
7394
|
+
return res;
|
7395
|
+
}
|
7324
7396
|
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
7325
7397
|
function pow2(x, power, modulo) {
|
7326
7398
|
let res = x;
|
@@ -7361,25 +7433,27 @@ function invert(number, modulo) {
|
|
7361
7433
|
* Tonelli-Shanks square root search algorithm.
|
7362
7434
|
* 1. https://eprint.iacr.org/2012/685.pdf (page 12)
|
7363
7435
|
* 2. Square Roots from 1; 24, 51, 10 to Dan Shanks
|
7436
|
+
* Will start an infinite loop if field order P is not prime.
|
7364
7437
|
* @param P field order
|
7365
7438
|
* @returns function that takes field Fp (created from P) and number n
|
7366
7439
|
*/
|
7367
7440
|
function tonelliShanks(P) {
|
7368
|
-
//
|
7441
|
+
// Legendre constant: used to calculate Legendre symbol (a | p),
|
7442
|
+
// which denotes the value of a^((p-1)/2) (mod p).
|
7443
|
+
// (a | p) ≡ 1 if a is a square (mod p)
|
7444
|
+
// (a | p) ≡ -1 if a is not a square (mod p)
|
7445
|
+
// (a | p) ≡ 0 if a ≡ 0 (mod p)
|
7446
|
+
const legendreC = (P - _1n$5) / _2n$3;
|
7447
|
+
let Q, S, Z;
|
7369
7448
|
// Step 1: By factoring out powers of 2 from p - 1,
|
7370
|
-
// find q and s such that p-1
|
7371
|
-
|
7372
|
-
|
7373
|
-
while (Q % _2n$3 === _0n$3) {
|
7374
|
-
Q /= _2n$3;
|
7375
|
-
S++;
|
7376
|
-
}
|
7449
|
+
// find q and s such that p - 1 = q*(2^s) with q odd
|
7450
|
+
for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
|
7451
|
+
;
|
7377
7452
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
7378
|
-
|
7379
|
-
|
7380
|
-
|
7381
|
-
|
7382
|
-
throw new Error('Cannot find square root: probably non-prime P');
|
7453
|
+
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++) {
|
7454
|
+
// Crash instead of infinity loop, we cannot reasonable count until P.
|
7455
|
+
if (Z > 1000)
|
7456
|
+
throw new Error('Cannot find square root: likely non-prime P');
|
7383
7457
|
}
|
7384
7458
|
// Fast-path
|
7385
7459
|
if (S === 1) {
|
@@ -7395,18 +7469,16 @@ function tonelliShanks(P) {
|
|
7395
7469
|
const Q1div2 = (Q + _1n$5) / _2n$3;
|
7396
7470
|
return function tonelliSlow(Fp, n) {
|
7397
7471
|
// Step 0: Check that n is indeed a square: (n | p) should not be ≡ -1
|
7398
|
-
if (
|
7472
|
+
if (Fp.pow(n, legendreC) === Fp.neg(Fp.ONE))
|
7399
7473
|
throw new Error('Cannot find square root');
|
7400
7474
|
let r = S;
|
7401
|
-
// TODO:
|
7475
|
+
// TODO: will fail at Fp2/etc
|
7402
7476
|
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q); // will update both x and b
|
7403
7477
|
let x = Fp.pow(n, Q1div2); // first guess at the square root
|
7404
7478
|
let b = Fp.pow(n, Q); // first guess at the fudge factor
|
7405
7479
|
while (!Fp.eql(b, Fp.ONE)) {
|
7406
|
-
// (4. If t = 0, return r = 0)
|
7407
|
-
// https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm
|
7408
7480
|
if (Fp.eql(b, Fp.ZERO))
|
7409
|
-
return Fp.ZERO;
|
7481
|
+
return Fp.ZERO; // https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm (4. If t = 0, return r = 0)
|
7410
7482
|
// Find m such b^(2^m)==1
|
7411
7483
|
let m = 1;
|
7412
7484
|
for (let t2 = Fp.sqr(b); m < r; m++) {
|
@@ -7414,8 +7486,7 @@ function tonelliShanks(P) {
|
|
7414
7486
|
break;
|
7415
7487
|
t2 = Fp.sqr(t2); // t2 *= t2
|
7416
7488
|
}
|
7417
|
-
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift,
|
7418
|
-
// otherwise there will be overflow.
|
7489
|
+
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift, otherwise there will be overflow
|
7419
7490
|
const ge = Fp.pow(g, _1n$5 << BigInt(r - m - 1)); // ge = 2^(r-m-1)
|
7420
7491
|
g = Fp.sqr(ge); // g = ge * ge
|
7421
7492
|
x = Fp.mul(x, ge); // x *= ge
|
@@ -7444,8 +7515,8 @@ function FpSqrt(P) {
|
|
7444
7515
|
// const ORDER =
|
7445
7516
|
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
7446
7517
|
// const NUM = 72057594037927816n;
|
7518
|
+
const p1div4 = (P + _1n$5) / _4n;
|
7447
7519
|
return function sqrt3mod4(Fp, n) {
|
7448
|
-
const p1div4 = (P + _1n$5) / _4n;
|
7449
7520
|
const root = Fp.pow(n, p1div4);
|
7450
7521
|
// Throw if root**2 != n
|
7451
7522
|
if (!Fp.eql(Fp.sqr(root), n))
|
@@ -7455,9 +7526,9 @@ function FpSqrt(P) {
|
|
7455
7526
|
}
|
7456
7527
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
7457
7528
|
if (P % _8n$2 === _5n$1) {
|
7529
|
+
const c1 = (P - _5n$1) / _8n$2;
|
7458
7530
|
return function sqrt5mod8(Fp, n) {
|
7459
7531
|
const n2 = Fp.mul(n, _2n$3);
|
7460
|
-
const c1 = (P - _5n$1) / _8n$2;
|
7461
7532
|
const v = Fp.pow(n2, c1);
|
7462
7533
|
const nv = Fp.mul(n, v);
|
7463
7534
|
const i = Fp.mul(Fp.mul(nv, _2n$3), v);
|
@@ -7496,78 +7567,52 @@ function validateField(field) {
|
|
7496
7567
|
* Same as `pow` but for Fp: non-constant-time.
|
7497
7568
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
7498
7569
|
*/
|
7499
|
-
function FpPow(
|
7570
|
+
function FpPow(f, num, power) {
|
7571
|
+
// Should have same speed as pow for bigints
|
7572
|
+
// TODO: benchmark!
|
7500
7573
|
if (power < _0n$3)
|
7501
7574
|
throw new Error('invalid exponent, negatives unsupported');
|
7502
7575
|
if (power === _0n$3)
|
7503
|
-
return
|
7576
|
+
return f.ONE;
|
7504
7577
|
if (power === _1n$5)
|
7505
7578
|
return num;
|
7506
|
-
|
7507
|
-
let p = Fp.ONE;
|
7579
|
+
let p = f.ONE;
|
7508
7580
|
let d = num;
|
7509
7581
|
while (power > _0n$3) {
|
7510
7582
|
if (power & _1n$5)
|
7511
|
-
p =
|
7512
|
-
d =
|
7583
|
+
p = f.mul(p, d);
|
7584
|
+
d = f.sqr(d);
|
7513
7585
|
power >>= _1n$5;
|
7514
7586
|
}
|
7515
7587
|
return p;
|
7516
7588
|
}
|
7517
7589
|
/**
|
7518
7590
|
* Efficiently invert an array of Field elements.
|
7519
|
-
*
|
7520
|
-
* @param passZero map 0 to 0 (instead of undefined)
|
7591
|
+
* `inv(0)` will return `undefined` here: make sure to throw an error.
|
7521
7592
|
*/
|
7522
|
-
function FpInvertBatch(
|
7523
|
-
const
|
7593
|
+
function FpInvertBatch(f, nums) {
|
7594
|
+
const tmp = new Array(nums.length);
|
7524
7595
|
// Walk from first to last, multiply them by each other MOD p
|
7525
|
-
const
|
7526
|
-
if (
|
7596
|
+
const lastMultiplied = nums.reduce((acc, num, i) => {
|
7597
|
+
if (f.is0(num))
|
7527
7598
|
return acc;
|
7528
|
-
|
7529
|
-
return
|
7530
|
-
},
|
7599
|
+
tmp[i] = acc;
|
7600
|
+
return f.mul(acc, num);
|
7601
|
+
}, f.ONE);
|
7531
7602
|
// Invert last element
|
7532
|
-
const
|
7603
|
+
const inverted = f.inv(lastMultiplied);
|
7533
7604
|
// Walk from last to first, multiply them by inverted each other MOD p
|
7534
7605
|
nums.reduceRight((acc, num, i) => {
|
7535
|
-
if (
|
7606
|
+
if (f.is0(num))
|
7536
7607
|
return acc;
|
7537
|
-
|
7538
|
-
return
|
7539
|
-
},
|
7540
|
-
return
|
7541
|
-
}
|
7542
|
-
/**
|
7543
|
-
* Legendre symbol.
|
7544
|
-
* Legendre constant is used to calculate Legendre symbol (a | p)
|
7545
|
-
* which denotes the value of a^((p-1)/2) (mod p)..
|
7546
|
-
*
|
7547
|
-
* * (a | p) ≡ 1 if a is a square (mod p), quadratic residue
|
7548
|
-
* * (a | p) ≡ -1 if a is not a square (mod p), quadratic non residue
|
7549
|
-
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
|
7550
|
-
*/
|
7551
|
-
function FpLegendre(Fp, n) {
|
7552
|
-
const legc = (Fp.ORDER - _1n$5) / _2n$3;
|
7553
|
-
const powered = Fp.pow(n, legc);
|
7554
|
-
const yes = Fp.eql(powered, Fp.ONE);
|
7555
|
-
const zero = Fp.eql(powered, Fp.ZERO);
|
7556
|
-
const no = Fp.eql(powered, Fp.neg(Fp.ONE));
|
7557
|
-
if (!yes && !zero && !no)
|
7558
|
-
throw new Error('Cannot find square root: probably non-prime P');
|
7559
|
-
return yes ? 1 : zero ? 0 : -1;
|
7560
|
-
}
|
7561
|
-
// This function returns True whenever the value x is a square in the field F.
|
7562
|
-
function FpIsSquare(Fp, n) {
|
7563
|
-
const l = FpLegendre(Fp, n);
|
7564
|
-
return l === 0 || l === 1;
|
7608
|
+
tmp[i] = f.mul(acc, tmp[i]);
|
7609
|
+
return f.mul(acc, num);
|
7610
|
+
}, inverted);
|
7611
|
+
return tmp;
|
7565
7612
|
}
|
7566
7613
|
// CURVE.n lengths
|
7567
7614
|
function nLength(n, nBitLength) {
|
7568
7615
|
// Bit size, byte size of CURVE.n
|
7569
|
-
if (nBitLength !== undefined)
|
7570
|
-
anumber(nBitLength);
|
7571
7616
|
const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
|
7572
7617
|
const nByteLength = Math.ceil(_nBitLength / 8);
|
7573
7618
|
return { nBitLength: _nBitLength, nByteLength };
|
@@ -7630,17 +7675,16 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
7630
7675
|
sqrtP = FpSqrt(ORDER);
|
7631
7676
|
return sqrtP(f, n);
|
7632
7677
|
}),
|
7678
|
+
invertBatch: (lst) => FpInvertBatch(f, lst),
|
7679
|
+
// TODO: do we really need constant cmov?
|
7680
|
+
// We don't have const-time bigints anyway, so probably will be not very useful
|
7681
|
+
cmov: (a, b, c) => (c ? b : a),
|
7633
7682
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
7634
7683
|
fromBytes: (bytes) => {
|
7635
7684
|
if (bytes.length !== BYTES)
|
7636
7685
|
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
7637
7686
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
7638
7687
|
},
|
7639
|
-
// TODO: we don't need it here, move out to separate fn
|
7640
|
-
invertBatch: (lst) => FpInvertBatch(f, lst),
|
7641
|
-
// We can't move this out because Fp6, Fp12 implement it
|
7642
|
-
// and it's unclear what to return in there.
|
7643
|
-
cmov: (a, b, c) => (c ? b : a),
|
7644
7688
|
});
|
7645
7689
|
return Object.freeze(f);
|
7646
7690
|
}
|
@@ -7709,36 +7753,11 @@ function validateW(W, bits) {
|
|
7709
7753
|
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
7710
7754
|
throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
|
7711
7755
|
}
|
7712
|
-
function calcWOpts(W,
|
7713
|
-
validateW(W,
|
7714
|
-
const windows = Math.ceil(
|
7715
|
-
const windowSize = 2 ** (W - 1); //
|
7716
|
-
|
7717
|
-
const mask = bitMask(W); // W=8 255 == mask 0b11111111
|
7718
|
-
const shiftBy = BigInt(W); // W=8 8
|
7719
|
-
return { windows, windowSize, mask, maxNumber, shiftBy };
|
7720
|
-
}
|
7721
|
-
function calcOffsets(n, window, wOpts) {
|
7722
|
-
const { windowSize, mask, maxNumber, shiftBy } = wOpts;
|
7723
|
-
let wbits = Number(n & mask); // extract W bits.
|
7724
|
-
let nextN = n >> shiftBy; // shift number by W bits.
|
7725
|
-
// What actually happens here:
|
7726
|
-
// const highestBit = Number(mask ^ (mask >> 1n));
|
7727
|
-
// let wbits2 = wbits - 1; // skip zero
|
7728
|
-
// if (wbits2 & highestBit) { wbits2 ^= Number(mask); // (~);
|
7729
|
-
// split if bits > max: +224 => 256-32
|
7730
|
-
if (wbits > windowSize) {
|
7731
|
-
// we skip zero, which means instead of `>= size-1`, we do `> size`
|
7732
|
-
wbits -= maxNumber; // -32, can be maxNumber - wbits, but then we need to set isNeg here.
|
7733
|
-
nextN += _1n$4; // +256 (carry)
|
7734
|
-
}
|
7735
|
-
const offsetStart = window * windowSize;
|
7736
|
-
const offset = offsetStart + Math.abs(wbits) - 1; // -1 because we skip zero
|
7737
|
-
const isZero = wbits === 0; // is current window slice a 0?
|
7738
|
-
const isNeg = wbits < 0; // is current window slice negative?
|
7739
|
-
const isNegF = window % 2 !== 0; // fake random statement for noise
|
7740
|
-
const offsetF = offsetStart; // fake offset for noise
|
7741
|
-
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
7756
|
+
function calcWOpts(W, bits) {
|
7757
|
+
validateW(W, bits);
|
7758
|
+
const windows = Math.ceil(bits / W) + 1; // +1, because
|
7759
|
+
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
7760
|
+
return { windows, windowSize };
|
7742
7761
|
}
|
7743
7762
|
function validateMSMPoints(points, c) {
|
7744
7763
|
if (!Array.isArray(points))
|
@@ -7757,10 +7776,9 @@ function validateMSMScalars(scalars, field) {
|
|
7757
7776
|
});
|
7758
7777
|
}
|
7759
7778
|
// Since points in different groups cannot be equal (different object constructor),
|
7760
|
-
// we can have single place to store precomputes
|
7761
|
-
// Allows to make points frozen / immutable.
|
7779
|
+
// we can have single place to store precomputes
|
7762
7780
|
const pointPrecomputes = new WeakMap();
|
7763
|
-
const pointWindowSizes = new WeakMap();
|
7781
|
+
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
7764
7782
|
function getW(P) {
|
7765
7783
|
return pointWindowSizes.get(P) || 1;
|
7766
7784
|
}
|
@@ -7815,7 +7833,7 @@ function wNAF(c, bits) {
|
|
7815
7833
|
for (let window = 0; window < windows; window++) {
|
7816
7834
|
base = p;
|
7817
7835
|
points.push(base);
|
7818
|
-
//
|
7836
|
+
// =1, because we skip zero
|
7819
7837
|
for (let i = 1; i < windowSize; i++) {
|
7820
7838
|
base = base.add(p);
|
7821
7839
|
points.push(base);
|
@@ -7832,35 +7850,48 @@ function wNAF(c, bits) {
|
|
7832
7850
|
* @returns real and fake (for const-time) points
|
7833
7851
|
*/
|
7834
7852
|
wNAF(W, precomputes, n) {
|
7835
|
-
//
|
7836
|
-
//
|
7837
|
-
|
7838
|
-
// wNAF behavior is undefined otherwise. But have to carefully remove
|
7839
|
-
// other checks before wNAF. ORDER == bits here.
|
7840
|
-
// Accumulators
|
7853
|
+
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
7854
|
+
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
7855
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
7841
7856
|
let p = c.ZERO;
|
7842
7857
|
let f = c.BASE;
|
7843
|
-
|
7844
|
-
|
7845
|
-
|
7846
|
-
|
7847
|
-
|
7848
|
-
|
7849
|
-
|
7850
|
-
//
|
7851
|
-
|
7852
|
-
|
7853
|
-
|
7854
|
-
|
7855
|
-
|
7856
|
-
|
7858
|
+
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
7859
|
+
const maxNumber = 2 ** W;
|
7860
|
+
const shiftBy = BigInt(W);
|
7861
|
+
for (let window = 0; window < windows; window++) {
|
7862
|
+
const offset = window * windowSize;
|
7863
|
+
// Extract W bits.
|
7864
|
+
let wbits = Number(n & mask);
|
7865
|
+
// Shift number by W bits.
|
7866
|
+
n >>= shiftBy;
|
7867
|
+
// If the bits are bigger than max size, we'll split those.
|
7868
|
+
// +224 => 256 - 32
|
7869
|
+
if (wbits > windowSize) {
|
7870
|
+
wbits -= maxNumber;
|
7871
|
+
n += _1n$4;
|
7872
|
+
}
|
7873
|
+
// This code was first written with assumption that 'f' and 'p' will never be infinity point:
|
7874
|
+
// since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
|
7875
|
+
// there is negate now: it is possible that negated element from low value
|
7876
|
+
// would be the same as high element, which will create carry into next window.
|
7877
|
+
// It's not obvious how this can fail, but still worth investigating later.
|
7878
|
+
// Check if we're onto Zero point.
|
7879
|
+
// Add random point inside current window to f.
|
7880
|
+
const offset1 = offset;
|
7881
|
+
const offset2 = offset + Math.abs(wbits) - 1; // -1 because we skip zero
|
7882
|
+
const cond1 = window % 2 !== 0;
|
7883
|
+
const cond2 = wbits < 0;
|
7884
|
+
if (wbits === 0) {
|
7885
|
+
// The most important part for const-time getPublicKey
|
7886
|
+
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
7857
7887
|
}
|
7858
7888
|
else {
|
7859
|
-
|
7860
|
-
p = p.add(constTimeNegate(isNeg, precomputes[offset]));
|
7889
|
+
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
7861
7890
|
}
|
7862
7891
|
}
|
7863
|
-
//
|
7892
|
+
// JIT-compiler should not eliminate f here, since it will later be used in normalizeZ()
|
7893
|
+
// Even if the variable is still unused, there are some checks which will
|
7894
|
+
// throw an exception, so compiler needs to prove they won't happen, which is hard.
|
7864
7895
|
// At this point there is a way to F be infinity-point even if p is not,
|
7865
7896
|
// which makes it less const-time: around 1 bigint multiply.
|
7866
7897
|
return { p, f };
|
@@ -7874,21 +7905,31 @@ function wNAF(c, bits) {
|
|
7874
7905
|
* @returns point
|
7875
7906
|
*/
|
7876
7907
|
wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
|
7877
|
-
const
|
7878
|
-
|
7908
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
7909
|
+
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
7910
|
+
const maxNumber = 2 ** W;
|
7911
|
+
const shiftBy = BigInt(W);
|
7912
|
+
for (let window = 0; window < windows; window++) {
|
7913
|
+
const offset = window * windowSize;
|
7879
7914
|
if (n === _0n$2)
|
7880
|
-
break; //
|
7881
|
-
|
7882
|
-
|
7883
|
-
|
7884
|
-
|
7885
|
-
|
7886
|
-
|
7887
|
-
|
7888
|
-
|
7889
|
-
|
7890
|
-
acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM
|
7915
|
+
break; // No need to go over empty scalar
|
7916
|
+
// Extract W bits.
|
7917
|
+
let wbits = Number(n & mask);
|
7918
|
+
// Shift number by W bits.
|
7919
|
+
n >>= shiftBy;
|
7920
|
+
// If the bits are bigger than max size, we'll split those.
|
7921
|
+
// +224 => 256 - 32
|
7922
|
+
if (wbits > windowSize) {
|
7923
|
+
wbits -= maxNumber;
|
7924
|
+
n += _1n$4;
|
7891
7925
|
}
|
7926
|
+
if (wbits === 0)
|
7927
|
+
continue;
|
7928
|
+
let curr = precomputes[offset + Math.abs(wbits) - 1]; // -1 because we skip zero
|
7929
|
+
if (wbits < 0)
|
7930
|
+
curr = curr.negate();
|
7931
|
+
// NOTE: by re-using acc, we can save a lot of additions in case of MSM
|
7932
|
+
acc = acc.add(curr);
|
7892
7933
|
}
|
7893
7934
|
return acc;
|
7894
7935
|
},
|
@@ -7924,7 +7965,7 @@ function wNAF(c, bits) {
|
|
7924
7965
|
}
|
7925
7966
|
/**
|
7926
7967
|
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
7927
|
-
* 30x faster vs naive addition on L=4096, 10x faster
|
7968
|
+
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
7928
7969
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
7929
7970
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
7930
7971
|
* @param c Curve Point constructor
|
@@ -7946,15 +7987,15 @@ function pippenger(c, fieldN, points, scalars) {
|
|
7946
7987
|
const zero = c.ZERO;
|
7947
7988
|
const wbits = bitLen(BigInt(points.length));
|
7948
7989
|
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
7949
|
-
const MASK =
|
7950
|
-
const buckets = new Array(
|
7990
|
+
const MASK = (1 << windowSize) - 1;
|
7991
|
+
const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
|
7951
7992
|
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
7952
7993
|
let sum = zero;
|
7953
7994
|
for (let i = lastBits; i >= 0; i -= windowSize) {
|
7954
7995
|
buckets.fill(zero);
|
7955
7996
|
for (let j = 0; j < scalars.length; j++) {
|
7956
7997
|
const scalar = scalars[j];
|
7957
|
-
const wbits = Number((scalar >> BigInt(i)) & MASK);
|
7998
|
+
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
7958
7999
|
buckets[wbits] = buckets[wbits].add(points[j]);
|
7959
8000
|
}
|
7960
8001
|
let resI = zero; // not using this will do small speed-up, but will lose ct
|
@@ -7995,7 +8036,6 @@ function validateBasic(curve) {
|
|
7995
8036
|
* @module
|
7996
8037
|
*/
|
7997
8038
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7998
|
-
// prettier-ignore
|
7999
8039
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
8000
8040
|
// prettier-ignore
|
8001
8041
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -8054,11 +8094,10 @@ function twistedEdwards(curveDef) {
|
|
8054
8094
|
}); // NOOP
|
8055
8095
|
// 0 <= n < MASK
|
8056
8096
|
// Coordinates larger than Fp.ORDER are allowed for zip215
|
8057
|
-
function aCoordinate(title, n
|
8058
|
-
|
8059
|
-
aInRange('coordinate ' + title, n, min, MASK);
|
8097
|
+
function aCoordinate(title, n) {
|
8098
|
+
aInRange('coordinate ' + title, n, _0n$1, MASK);
|
8060
8099
|
}
|
8061
|
-
function
|
8100
|
+
function assertPoint(other) {
|
8062
8101
|
if (!(other instanceof Point))
|
8063
8102
|
throw new Error('ExtendedPoint expected');
|
8064
8103
|
}
|
@@ -8105,14 +8144,14 @@ function twistedEdwards(curveDef) {
|
|
8105
8144
|
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
8106
8145
|
class Point {
|
8107
8146
|
constructor(ex, ey, ez, et) {
|
8108
|
-
aCoordinate('x', ex);
|
8109
|
-
aCoordinate('y', ey);
|
8110
|
-
aCoordinate('z', ez, true);
|
8111
|
-
aCoordinate('t', et);
|
8112
8147
|
this.ex = ex;
|
8113
8148
|
this.ey = ey;
|
8114
8149
|
this.ez = ez;
|
8115
8150
|
this.et = et;
|
8151
|
+
aCoordinate('x', ex);
|
8152
|
+
aCoordinate('y', ey);
|
8153
|
+
aCoordinate('z', ez);
|
8154
|
+
aCoordinate('t', et);
|
8116
8155
|
Object.freeze(this);
|
8117
8156
|
}
|
8118
8157
|
get x() {
|
@@ -8130,7 +8169,7 @@ function twistedEdwards(curveDef) {
|
|
8130
8169
|
return new Point(x, y, _1n$3, modP(x * y));
|
8131
8170
|
}
|
8132
8171
|
static normalizeZ(points) {
|
8133
|
-
const toInv =
|
8172
|
+
const toInv = Fp.invertBatch(points.map((p) => p.ez));
|
8134
8173
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
8135
8174
|
}
|
8136
8175
|
// Multiscalar Multiplication
|
@@ -8148,7 +8187,7 @@ function twistedEdwards(curveDef) {
|
|
8148
8187
|
}
|
8149
8188
|
// Compare one point to another.
|
8150
8189
|
equals(other) {
|
8151
|
-
|
8190
|
+
assertPoint(other);
|
8152
8191
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
8153
8192
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
8154
8193
|
const X1Z2 = modP(X1 * Z2);
|
@@ -8189,10 +8228,31 @@ function twistedEdwards(curveDef) {
|
|
8189
8228
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
8190
8229
|
// Cost: 9M + 1*a + 1*d + 7add.
|
8191
8230
|
add(other) {
|
8192
|
-
|
8231
|
+
assertPoint(other);
|
8193
8232
|
const { a, d } = CURVE;
|
8194
8233
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
8195
8234
|
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
|
8235
|
+
// Faster algo for adding 2 Extended Points when curve's a=-1.
|
8236
|
+
// http://hyperelliptic.org/EFD/g1p/auto-twisted-extended-1.html#addition-add-2008-hwcd-4
|
8237
|
+
// Cost: 8M + 8add + 2*2.
|
8238
|
+
// Note: It does not check whether the `other` point is valid.
|
8239
|
+
if (a === BigInt(-1)) {
|
8240
|
+
const A = modP((Y1 - X1) * (Y2 + X2));
|
8241
|
+
const B = modP((Y1 + X1) * (Y2 - X2));
|
8242
|
+
const F = modP(B - A);
|
8243
|
+
if (F === _0n$1)
|
8244
|
+
return this.double(); // Same point. Tests say it doesn't affect timing
|
8245
|
+
const C = modP(Z1 * _2n$2 * T2);
|
8246
|
+
const D = modP(T1 * _2n$2 * Z2);
|
8247
|
+
const E = D + C;
|
8248
|
+
const G = B + A;
|
8249
|
+
const H = D - C;
|
8250
|
+
const X3 = modP(E * F);
|
8251
|
+
const Y3 = modP(G * H);
|
8252
|
+
const T3 = modP(E * H);
|
8253
|
+
const Z3 = modP(F * G);
|
8254
|
+
return new Point(X3, Y3, Z3, T3);
|
8255
|
+
}
|
8196
8256
|
const A = modP(X1 * X2); // A = X1*X2
|
8197
8257
|
const B = modP(Y1 * Y2); // B = Y1*Y2
|
8198
8258
|
const C = modP(T1 * d * T2); // C = T1*d*T2
|
@@ -8292,8 +8352,7 @@ function twistedEdwards(curveDef) {
|
|
8292
8352
|
return Point.fromAffine({ x, y });
|
8293
8353
|
}
|
8294
8354
|
static fromPrivateKey(privKey) {
|
8295
|
-
|
8296
|
-
return G.multiply(scalar); // reduced one call of `toRawBytes`
|
8355
|
+
return getExtendedPublicKey(privKey).point;
|
8297
8356
|
}
|
8298
8357
|
toRawBytes() {
|
8299
8358
|
const { x, y } = this.toAffine();
|
@@ -8316,8 +8375,8 @@ function twistedEdwards(curveDef) {
|
|
8316
8375
|
function modN_LE(hash) {
|
8317
8376
|
return modN(bytesToNumberLE(hash));
|
8318
8377
|
}
|
8319
|
-
|
8320
|
-
function
|
8378
|
+
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
8379
|
+
function getExtendedPublicKey(key) {
|
8321
8380
|
const len = Fp.BYTES;
|
8322
8381
|
key = ensureBytes('private key', key, len);
|
8323
8382
|
// Hash private key with curve's hash function to produce uniformingly random input
|
@@ -8326,11 +8385,6 @@ function twistedEdwards(curveDef) {
|
|
8326
8385
|
const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE
|
8327
8386
|
const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)
|
8328
8387
|
const scalar = modN_LE(head); // The actual private scalar
|
8329
|
-
return { head, prefix, scalar };
|
8330
|
-
}
|
8331
|
-
// Convenience method that creates public key from scalar. RFC8032 5.1.5
|
8332
|
-
function getExtendedPublicKey(key) {
|
8333
|
-
const { head, prefix, scalar } = getPrivateScalar(key);
|
8334
8388
|
const point = G.multiply(scalar); // Point on Edwards curve aka public key
|
8335
8389
|
const pointBytes = point.toRawBytes(); // Uint8Array representation
|
8336
8390
|
return { head, prefix, scalar, point, pointBytes };
|
@@ -8340,7 +8394,7 @@ function twistedEdwards(curveDef) {
|
|
8340
8394
|
return getExtendedPublicKey(privKey).pointBytes;
|
8341
8395
|
}
|
8342
8396
|
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
8343
|
-
function hashDomainToScalar(context = Uint8Array
|
8397
|
+
function hashDomainToScalar(context = new Uint8Array(), ...msgs) {
|
8344
8398
|
const msg = concatBytes(...msgs);
|
8345
8399
|
return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));
|
8346
8400
|
}
|
@@ -8397,7 +8451,7 @@ function twistedEdwards(curveDef) {
|
|
8397
8451
|
G._setWindowSize(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
|
8398
8452
|
const utils = {
|
8399
8453
|
getExtendedPublicKey,
|
8400
|
-
|
8454
|
+
// ed25519 private keys are uniform 32b. No need to check for modulo bias, like in secp256k1.
|
8401
8455
|
randomPrivateKey: () => randomBytes(Fp.BYTES),
|
8402
8456
|
/**
|
8403
8457
|
* We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
|
@@ -8429,10 +8483,8 @@ function twistedEdwards(curveDef) {
|
|
8429
8483
|
* @module
|
8430
8484
|
*/
|
8431
8485
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
8432
|
-
// 2n**255n - 19n
|
8433
8486
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
8434
8487
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
8435
|
-
// Fp.sqrt(Fp.neg(1))
|
8436
8488
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
8437
8489
|
// prettier-ignore
|
8438
8490
|
BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
|
@@ -8491,15 +8543,19 @@ function uvRatio(u, v) {
|
|
8491
8543
|
}
|
8492
8544
|
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
8493
8545
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
8494
|
-
//
|
8495
|
-
a: Fp.create(
|
8496
|
-
// d is -121665/121666
|
8546
|
+
// Param: a
|
8547
|
+
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
8548
|
+
// d is equal to -121665/121666 over finite field.
|
8549
|
+
// Negative number is P - number, and division is invert(number, P)
|
8497
8550
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
8498
|
-
// Finite field 2n**255n - 19n
|
8551
|
+
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
8499
8552
|
Fp,
|
8500
|
-
// Subgroup order
|
8553
|
+
// Subgroup order: how many points curve has
|
8554
|
+
// 2n**252n + 27742317777372353535851937790883648493n;
|
8501
8555
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
8556
|
+
// Cofactor
|
8502
8557
|
h: _8n,
|
8558
|
+
// Base point (x, y) aka generator point
|
8503
8559
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
8504
8560
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
8505
8561
|
hash: sha512,
|
@@ -10048,7 +10104,7 @@ class HMAC extends Hash {
|
|
10048
10104
|
for (let i = 0; i < pad.length; i++)
|
10049
10105
|
pad[i] ^= 0x36 ^ 0x5c;
|
10050
10106
|
this.oHash.update(pad);
|
10051
|
-
|
10107
|
+
pad.fill(0);
|
10052
10108
|
}
|
10053
10109
|
update(buf) {
|
10054
10110
|
aexists(this);
|
@@ -10082,9 +10138,6 @@ class HMAC extends Hash {
|
|
10082
10138
|
to.iHash = iHash._cloneInto(to.iHash);
|
10083
10139
|
return to;
|
10084
10140
|
}
|
10085
|
-
clone() {
|
10086
|
-
return this._cloneInto();
|
10087
|
-
}
|
10088
10141
|
destroy() {
|
10089
10142
|
this.destroyed = true;
|
10090
10143
|
this.oHash.destroy();
|
@@ -10107,19 +10160,6 @@ hmac.create = (hash, key) => new HMAC(hash, key);
|
|
10107
10160
|
/**
|
10108
10161
|
* Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
|
10109
10162
|
*
|
10110
|
-
* ### Parameters
|
10111
|
-
*
|
10112
|
-
* To initialize a weierstrass curve, one needs to pass following params:
|
10113
|
-
*
|
10114
|
-
* * a: formula param
|
10115
|
-
* * b: formula param
|
10116
|
-
* * Fp: finite Field over which we'll do calculations. Can be complex (Fp2, Fp12)
|
10117
|
-
* * n: Curve prime subgroup order, total count of valid points in the field
|
10118
|
-
* * Gx: Base point (x, y) aka generator point x coordinate
|
10119
|
-
* * Gy: ...y coordinate
|
10120
|
-
* * h: cofactor, usually 1. h*n = curve group order (n is only subgroup order)
|
10121
|
-
* * lowS: whether to enable (default) or disable "low-s" non-malleable signatures
|
10122
|
-
*
|
10123
10163
|
* ### Design rationale for types
|
10124
10164
|
*
|
10125
10165
|
* * Interaction between classes from different curves should fail:
|
@@ -10144,7 +10184,6 @@ hmac.create = (hash, key) => new HMAC(hash, key);
|
|
10144
10184
|
* @module
|
10145
10185
|
*/
|
10146
10186
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
10147
|
-
// prettier-ignore
|
10148
10187
|
function validateSigVerOpts(opts) {
|
10149
10188
|
if (opts.lowS !== undefined)
|
10150
10189
|
abool('lowS', opts.lowS);
|
@@ -10178,6 +10217,7 @@ function validatePointOpts(curve) {
|
|
10178
10217
|
}
|
10179
10218
|
return Object.freeze({ ...opts });
|
10180
10219
|
}
|
10220
|
+
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
10181
10221
|
class DERErr extends Error {
|
10182
10222
|
constructor(m = '') {
|
10183
10223
|
super(m);
|
@@ -10270,13 +10310,14 @@ const DER = {
|
|
10270
10310
|
throw new E('invalid signature integer: negative');
|
10271
10311
|
if (data[0] === 0x00 && !(data[1] & 128))
|
10272
10312
|
throw new E('invalid signature integer: unnecessary leading zero');
|
10273
|
-
return
|
10313
|
+
return b2n(data);
|
10274
10314
|
},
|
10275
10315
|
},
|
10276
10316
|
toSig(hex) {
|
10277
10317
|
// parse DER signature
|
10278
10318
|
const { Err: E, _int: int, _tlv: tlv } = DER;
|
10279
|
-
const data =
|
10319
|
+
const data = typeof hex === 'string' ? h2b(hex) : hex;
|
10320
|
+
abytes(data);
|
10280
10321
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
10281
10322
|
if (seqLeftBytes.length)
|
10282
10323
|
throw new E('invalid signature: left bytes after parsing');
|
@@ -10316,7 +10357,7 @@ function weierstrassPoints(opts) {
|
|
10316
10357
|
return { x, y };
|
10317
10358
|
});
|
10318
10359
|
/**
|
10319
|
-
* y² = x³ + ax + b: Short weierstrass curve formula
|
10360
|
+
* y² = x³ + ax + b: Short weierstrass curve formula
|
10320
10361
|
* @returns y²
|
10321
10362
|
*/
|
10322
10363
|
function weierstrassEquation(x) {
|
@@ -10362,7 +10403,7 @@ function weierstrassPoints(opts) {
|
|
10362
10403
|
aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
|
10363
10404
|
return num;
|
10364
10405
|
}
|
10365
|
-
function
|
10406
|
+
function assertPrjPoint(other) {
|
10366
10407
|
if (!(other instanceof Point))
|
10367
10408
|
throw new Error('ProjectivePoint expected');
|
10368
10409
|
}
|
@@ -10420,15 +10461,15 @@ function weierstrassPoints(opts) {
|
|
10420
10461
|
*/
|
10421
10462
|
class Point {
|
10422
10463
|
constructor(px, py, pz) {
|
10464
|
+
this.px = px;
|
10465
|
+
this.py = py;
|
10466
|
+
this.pz = pz;
|
10423
10467
|
if (px == null || !Fp.isValid(px))
|
10424
10468
|
throw new Error('x required');
|
10425
|
-
if (py == null || !Fp.isValid(py)
|
10469
|
+
if (py == null || !Fp.isValid(py))
|
10426
10470
|
throw new Error('y required');
|
10427
10471
|
if (pz == null || !Fp.isValid(pz))
|
10428
10472
|
throw new Error('z required');
|
10429
|
-
this.px = px;
|
10430
|
-
this.py = py;
|
10431
|
-
this.pz = pz;
|
10432
10473
|
Object.freeze(this);
|
10433
10474
|
}
|
10434
10475
|
// Does not validate if the point is on-curve.
|
@@ -10458,7 +10499,7 @@ function weierstrassPoints(opts) {
|
|
10458
10499
|
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
10459
10500
|
*/
|
10460
10501
|
static normalizeZ(points) {
|
10461
|
-
const toInv =
|
10502
|
+
const toInv = Fp.invertBatch(points.map((p) => p.pz));
|
10462
10503
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
10463
10504
|
}
|
10464
10505
|
/**
|
@@ -10496,7 +10537,7 @@ function weierstrassPoints(opts) {
|
|
10496
10537
|
* Compare one point to another.
|
10497
10538
|
*/
|
10498
10539
|
equals(other) {
|
10499
|
-
|
10540
|
+
assertPrjPoint(other);
|
10500
10541
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
10501
10542
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
10502
10543
|
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
@@ -10556,7 +10597,7 @@ function weierstrassPoints(opts) {
|
|
10556
10597
|
// https://eprint.iacr.org/2015/1060, algorithm 1
|
10557
10598
|
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
10558
10599
|
add(other) {
|
10559
|
-
|
10600
|
+
assertPrjPoint(other);
|
10560
10601
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
10561
10602
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
10562
10603
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
@@ -10727,9 +10768,10 @@ function weierstrassPoints(opts) {
|
|
10727
10768
|
}
|
10728
10769
|
}
|
10729
10770
|
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
10730
|
-
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
10771
|
+
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
10731
10772
|
const _bits = CURVE.nBitLength;
|
10732
10773
|
const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
10774
|
+
// Validate if generator point is on curve
|
10733
10775
|
return {
|
10734
10776
|
CURVE,
|
10735
10777
|
ProjectivePoint: Point,
|
@@ -10820,7 +10862,7 @@ function weierstrass(curveDef) {
|
|
10820
10862
|
}
|
10821
10863
|
},
|
10822
10864
|
});
|
10823
|
-
const
|
10865
|
+
const numToNByteStr = (num) => bytesToHex(numberToBytesBE(num, CURVE.nByteLength));
|
10824
10866
|
function isBiggerThanHalfOrder(number) {
|
10825
10867
|
const HALF = CURVE_ORDER >> _1n$1;
|
10826
10868
|
return number > HALF;
|
@@ -10835,13 +10877,10 @@ function weierstrass(curveDef) {
|
|
10835
10877
|
*/
|
10836
10878
|
class Signature {
|
10837
10879
|
constructor(r, s, recovery) {
|
10838
|
-
aInRange('r', r, _1n$1, CURVE_ORDER); // r in [1..N]
|
10839
|
-
aInRange('s', s, _1n$1, CURVE_ORDER); // s in [1..N]
|
10840
10880
|
this.r = r;
|
10841
10881
|
this.s = s;
|
10842
|
-
|
10843
|
-
|
10844
|
-
Object.freeze(this);
|
10882
|
+
this.recovery = recovery;
|
10883
|
+
this.assertValidity();
|
10845
10884
|
}
|
10846
10885
|
// pair (bytes of r, bytes of s)
|
10847
10886
|
static fromCompact(hex) {
|
@@ -10855,11 +10894,10 @@ function weierstrass(curveDef) {
|
|
10855
10894
|
const { r, s } = DER.toSig(ensureBytes('DER', hex));
|
10856
10895
|
return new Signature(r, s);
|
10857
10896
|
}
|
10858
|
-
|
10859
|
-
|
10860
|
-
|
10861
|
-
|
10862
|
-
assertValidity() { }
|
10897
|
+
assertValidity() {
|
10898
|
+
aInRange('r', this.r, _1n$1, CURVE_ORDER); // r in [1..N]
|
10899
|
+
aInRange('s', this.s, _1n$1, CURVE_ORDER); // s in [1..N]
|
10900
|
+
}
|
10863
10901
|
addRecoveryBit(recovery) {
|
10864
10902
|
return new Signature(this.r, this.s, recovery);
|
10865
10903
|
}
|
@@ -10872,7 +10910,7 @@ function weierstrass(curveDef) {
|
|
10872
10910
|
if (radj >= Fp.ORDER)
|
10873
10911
|
throw new Error('recovery id 2 or 3 invalid');
|
10874
10912
|
const prefix = (rec & 1) === 0 ? '02' : '03';
|
10875
|
-
const R = Point.fromHex(prefix +
|
10913
|
+
const R = Point.fromHex(prefix + numToNByteStr(radj));
|
10876
10914
|
const ir = invN(radj); // r^-1
|
10877
10915
|
const u1 = modN(-h * ir); // -hr^-1
|
10878
10916
|
const u2 = modN(s * ir); // sr^-1
|
@@ -10894,14 +10932,14 @@ function weierstrass(curveDef) {
|
|
10894
10932
|
return hexToBytes(this.toDERHex());
|
10895
10933
|
}
|
10896
10934
|
toDERHex() {
|
10897
|
-
return DER.hexFromSig(this);
|
10935
|
+
return DER.hexFromSig({ r: this.r, s: this.s });
|
10898
10936
|
}
|
10899
10937
|
// padded bytes of r, then padded bytes of s
|
10900
10938
|
toCompactRawBytes() {
|
10901
10939
|
return hexToBytes(this.toCompactHex());
|
10902
10940
|
}
|
10903
10941
|
toCompactHex() {
|
10904
|
-
return
|
10942
|
+
return numToNByteStr(this.r) + numToNByteStr(this.s);
|
10905
10943
|
}
|
10906
10944
|
}
|
10907
10945
|
const utils = {
|
@@ -11241,28 +11279,26 @@ function sqrtMod(y) {
|
|
11241
11279
|
}
|
11242
11280
|
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
11243
11281
|
/**
|
11244
|
-
* secp256k1 curve
|
11245
|
-
*
|
11246
|
-
* Field: `2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n`
|
11282
|
+
* secp256k1 short weierstrass curve and ECDSA signatures over it.
|
11247
11283
|
*
|
11248
11284
|
* @example
|
11249
|
-
* ```js
|
11250
11285
|
* import { secp256k1 } from '@noble/curves/secp256k1';
|
11286
|
+
*
|
11251
11287
|
* const priv = secp256k1.utils.randomPrivateKey();
|
11252
11288
|
* const pub = secp256k1.getPublicKey(priv);
|
11253
11289
|
* const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
|
11254
11290
|
* const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
|
11255
11291
|
* const isValid = secp256k1.verify(sig, msg, pub) === true;
|
11256
|
-
* ```
|
11257
11292
|
*/
|
11258
11293
|
const secp256k1 = createCurve({
|
11259
|
-
a: BigInt(0),
|
11294
|
+
a: BigInt(0), // equation params: a, b
|
11260
11295
|
b: BigInt(7),
|
11261
|
-
Fp: Fpk1,
|
11262
|
-
n: secp256k1N,
|
11296
|
+
Fp: Fpk1, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
11297
|
+
n: secp256k1N, // Curve order, total count of valid points in the field
|
11298
|
+
// Base point (x, y) aka generator point
|
11263
11299
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
11264
11300
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
11265
|
-
h: BigInt(1),
|
11301
|
+
h: BigInt(1), // Cofactor
|
11266
11302
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
11267
11303
|
endo: {
|
11268
11304
|
// Endomorphism, see above
|
@@ -11290,7 +11326,7 @@ const secp256k1 = createCurve({
|
|
11290
11326
|
return { k1neg, k1, k2neg, k2 };
|
11291
11327
|
},
|
11292
11328
|
},
|
11293
|
-
}, sha256
|
11329
|
+
}, sha256);
|
11294
11330
|
// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.
|
11295
11331
|
// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
|
11296
11332
|
BigInt(0);
|
@@ -11310,7 +11346,7 @@ const PUBLIC_KEY_BYTE_LENGTH = 33;
|
|
11310
11346
|
* Hash message and verify signature with public key
|
11311
11347
|
*/
|
11312
11348
|
function hashAndVerify(key, sig, msg) {
|
11313
|
-
const p = sha256$
|
11349
|
+
const p = sha256$1.digest(msg instanceof Uint8Array ? msg : msg.subarray());
|
11314
11350
|
if (isPromise(p)) {
|
11315
11351
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
11316
11352
|
.catch(err => {
|
@@ -11944,7 +11980,7 @@ class EnrCreator {
|
|
11944
11980
|
}
|
11945
11981
|
return ENR.create({
|
11946
11982
|
...kvs,
|
11947
|
-
id: utf8ToBytes$
|
11983
|
+
id: utf8ToBytes$2("v4"),
|
11948
11984
|
secp256k1: publicKey
|
11949
11985
|
});
|
11950
11986
|
}
|