@waku/enr 0.0.30-006cd41.0 → 0.0.30-10590da.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 +642 -678
- 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$2 = 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$1 = (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$4 = 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$4) / 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$4 * (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$4 * 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$4 * 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$4 * 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$4 === _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 = hex
|
1815
|
+
const arr = isBytes$3(hex);
|
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 = hex
|
1825
|
+
const arr = isBytes$3(hex);
|
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,9 +1871,15 @@ 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
|
+
}
|
1874
1881
|
function concatBytes$2(...arrays) {
|
1875
|
-
|
1876
|
-
throw new Error('Uint8Array list expected');
|
1882
|
+
arrays.every(abytes$2);
|
1877
1883
|
if (arrays.length === 1)
|
1878
1884
|
return arrays[0];
|
1879
1885
|
const length = arrays.reduce((a, arr) => a + arr.length, 0);
|
@@ -1885,16 +1891,44 @@ function concatBytes$2(...arrays) {
|
|
1885
1891
|
}
|
1886
1892
|
return result;
|
1887
1893
|
}
|
1888
|
-
const hexes$1 = Array.from({ length: 256 }, (
|
1889
|
-
function bytesToHex$1(
|
1890
|
-
|
1891
|
-
throw new Error('Expected Uint8Array');
|
1894
|
+
const hexes$1 = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
1895
|
+
function bytesToHex$1(bytes) {
|
1896
|
+
abytes$2(bytes);
|
1892
1897
|
let hex = '';
|
1893
|
-
for (let i = 0; i <
|
1894
|
-
hex += hexes$1[
|
1898
|
+
for (let i = 0; i < bytes.length; i++) {
|
1899
|
+
hex += hexes$1[bytes[i]];
|
1895
1900
|
}
|
1896
1901
|
return hex;
|
1897
1902
|
}
|
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
|
+
}
|
1898
1932
|
const POW_2_256 = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000');
|
1899
1933
|
function numTo32bStr(num) {
|
1900
1934
|
if (typeof num !== 'bigint')
|
@@ -1919,28 +1953,11 @@ function hexToNumber$1(hex) {
|
|
1919
1953
|
}
|
1920
1954
|
return BigInt(`0x${hex}`);
|
1921
1955
|
}
|
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
|
-
}
|
1939
1956
|
function bytesToNumber(bytes) {
|
1940
1957
|
return hexToNumber$1(bytesToHex$1(bytes));
|
1941
1958
|
}
|
1942
1959
|
function ensureBytes$1(hex) {
|
1943
|
-
return hex
|
1960
|
+
return isBytes$3(hex) ? Uint8Array.from(hex) : hexToBytes$1(hex);
|
1944
1961
|
}
|
1945
1962
|
function normalizeScalar(num) {
|
1946
1963
|
if (typeof num === 'number' && Number.isSafeInteger(num) && num > 0)
|
@@ -1974,7 +1991,7 @@ function sqrtMod$1(x) {
|
|
1974
1991
|
const b3 = (b2 * b2 * x) % P;
|
1975
1992
|
const b6 = (pow2$1(b3, _3n$2) * b3) % P;
|
1976
1993
|
const b9 = (pow2$1(b6, _3n$2) * b3) % P;
|
1977
|
-
const b11 = (pow2$1(b9, _2n$
|
1994
|
+
const b11 = (pow2$1(b9, _2n$4) * b2) % P;
|
1978
1995
|
const b22 = (pow2$1(b11, _11n) * b11) % P;
|
1979
1996
|
const b44 = (pow2$1(b22, _22n) * b22) % P;
|
1980
1997
|
const b88 = (pow2$1(b44, _44n) * b44) % P;
|
@@ -1983,7 +2000,7 @@ function sqrtMod$1(x) {
|
|
1983
2000
|
const b223 = (pow2$1(b220, _3n$2) * b3) % P;
|
1984
2001
|
const t1 = (pow2$1(b223, _23n) * b22) % P;
|
1985
2002
|
const t2 = (pow2$1(t1, _6n) * b2) % P;
|
1986
|
-
const rt = pow2$1(t2, _2n$
|
2003
|
+
const rt = pow2$1(t2, _2n$4);
|
1987
2004
|
const xc = (rt * rt) % P;
|
1988
2005
|
if (xc !== x)
|
1989
2006
|
throw new Error('Cannot find square root');
|
@@ -2148,7 +2165,7 @@ function normalizePrivateKey(key) {
|
|
2148
2165
|
throw new Error('Expected 32 bytes of private key');
|
2149
2166
|
num = hexToNumber$1(key);
|
2150
2167
|
}
|
2151
|
-
else if (key
|
2168
|
+
else if (isBytes$3(key)) {
|
2152
2169
|
if (key.length !== groupLen)
|
2153
2170
|
throw new Error('Expected 32 bytes of private key');
|
2154
2171
|
num = bytesToNumber(key);
|
@@ -3095,19 +3112,28 @@ function verifySignature(signature, message, publicKey) {
|
|
3095
3112
|
}
|
3096
3113
|
}
|
3097
3114
|
|
3115
|
+
const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
3116
|
+
|
3098
3117
|
/**
|
3099
|
-
*
|
3118
|
+
* Utilities for hex, bytes, CSPRNG.
|
3100
3119
|
* @module
|
3101
3120
|
*/
|
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
|
+
}
|
3102
3132
|
/** Asserts something is positive integer. */
|
3103
3133
|
function anumber(n) {
|
3104
3134
|
if (!Number.isSafeInteger(n) || n < 0)
|
3105
3135
|
throw new Error('positive integer expected, got ' + n);
|
3106
3136
|
}
|
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
|
-
}
|
3111
3137
|
/** Asserts something is Uint8Array. */
|
3112
3138
|
function abytes$1(b, ...lengths) {
|
3113
3139
|
if (!isBytes$2(b))
|
@@ -3118,7 +3144,7 @@ function abytes$1(b, ...lengths) {
|
|
3118
3144
|
/** Asserts something is hash */
|
3119
3145
|
function ahash(h) {
|
3120
3146
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
3121
|
-
throw new Error('Hash should be wrapped by utils.
|
3147
|
+
throw new Error('Hash should be wrapped by utils.createHasher');
|
3122
3148
|
anumber(h.outputLen);
|
3123
3149
|
anumber(h.blockLen);
|
3124
3150
|
}
|
@@ -3137,21 +3163,13 @@ function aoutput(out, instance) {
|
|
3137
3163
|
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
3138
3164
|
}
|
3139
3165
|
}
|
3140
|
-
|
3141
|
-
|
3142
|
-
|
3143
|
-
|
3144
|
-
|
3145
|
-
|
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
|
3166
|
+
/** Zeroize a byte array. Warning: JS provides no guarantees. */
|
3167
|
+
function clean(...arrays) {
|
3168
|
+
for (let i = 0; i < arrays.length; i++) {
|
3169
|
+
arrays[i].fill(0);
|
3170
|
+
}
|
3171
|
+
}
|
3172
|
+
/** Create DataView of an array for easy byte-level manipulation. */
|
3155
3173
|
function createView(arr) {
|
3156
3174
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
3157
3175
|
}
|
@@ -3160,12 +3178,12 @@ function rotr(word, shift) {
|
|
3160
3178
|
return (word << (32 - shift)) | (word >>> shift);
|
3161
3179
|
}
|
3162
3180
|
/**
|
3163
|
-
*
|
3164
|
-
* @example utf8ToBytes('abc') //
|
3181
|
+
* Converts string to bytes using UTF8 encoding.
|
3182
|
+
* @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
|
3165
3183
|
*/
|
3166
|
-
function utf8ToBytes
|
3184
|
+
function utf8ToBytes(str) {
|
3167
3185
|
if (typeof str !== 'string')
|
3168
|
-
throw new Error('
|
3186
|
+
throw new Error('string expected');
|
3169
3187
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
3170
3188
|
}
|
3171
3189
|
/**
|
@@ -3175,13 +3193,11 @@ function utf8ToBytes$1(str) {
|
|
3175
3193
|
*/
|
3176
3194
|
function toBytes$1(data) {
|
3177
3195
|
if (typeof data === 'string')
|
3178
|
-
data = utf8ToBytes
|
3196
|
+
data = utf8ToBytes(data);
|
3179
3197
|
abytes$1(data);
|
3180
3198
|
return data;
|
3181
3199
|
}
|
3182
|
-
/**
|
3183
|
-
* Copies several Uint8Arrays into one.
|
3184
|
-
*/
|
3200
|
+
/** Copies several Uint8Arrays into one. */
|
3185
3201
|
function concatBytes$1(...arrays) {
|
3186
3202
|
let sum = 0;
|
3187
3203
|
for (let i = 0; i < arrays.length; i++) {
|
@@ -3199,13 +3215,9 @@ function concatBytes$1(...arrays) {
|
|
3199
3215
|
}
|
3200
3216
|
/** For runtime check if class implements interface */
|
3201
3217
|
class Hash {
|
3202
|
-
// Safe version that clones internal state
|
3203
|
-
clone() {
|
3204
|
-
return this._cloneInto();
|
3205
|
-
}
|
3206
3218
|
}
|
3207
3219
|
/** Wraps hash function, creating an interface on top of it */
|
3208
|
-
function
|
3220
|
+
function createHasher(hashCons) {
|
3209
3221
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
3210
3222
|
const tmp = hashCons();
|
3211
3223
|
hashC.outputLen = tmp.outputLen;
|
@@ -3220,7 +3232,7 @@ function randomBytes(bytesLength = 32) {
|
|
3220
3232
|
}
|
3221
3233
|
// Legacy Node.js compatibility
|
3222
3234
|
if (crypto$1 && typeof crypto$1.randomBytes === 'function') {
|
3223
|
-
return crypto$1.randomBytes(bytesLength);
|
3235
|
+
return Uint8Array.from(crypto$1.randomBytes(bytesLength));
|
3224
3236
|
}
|
3225
3237
|
throw new Error('crypto.getRandomValues must be defined');
|
3226
3238
|
}
|
@@ -3257,21 +3269,22 @@ function Maj(a, b, c) {
|
|
3257
3269
|
class HashMD extends Hash {
|
3258
3270
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
3259
3271
|
super();
|
3260
|
-
this.blockLen = blockLen;
|
3261
|
-
this.outputLen = outputLen;
|
3262
|
-
this.padOffset = padOffset;
|
3263
|
-
this.isLE = isLE;
|
3264
3272
|
this.finished = false;
|
3265
3273
|
this.length = 0;
|
3266
3274
|
this.pos = 0;
|
3267
3275
|
this.destroyed = false;
|
3276
|
+
this.blockLen = blockLen;
|
3277
|
+
this.outputLen = outputLen;
|
3278
|
+
this.padOffset = padOffset;
|
3279
|
+
this.isLE = isLE;
|
3268
3280
|
this.buffer = new Uint8Array(blockLen);
|
3269
3281
|
this.view = createView(this.buffer);
|
3270
3282
|
}
|
3271
3283
|
update(data) {
|
3272
3284
|
aexists(this);
|
3273
|
-
const { view, buffer, blockLen } = this;
|
3274
3285
|
data = toBytes$1(data);
|
3286
|
+
abytes$1(data);
|
3287
|
+
const { view, buffer, blockLen } = this;
|
3275
3288
|
const len = data.length;
|
3276
3289
|
for (let pos = 0; pos < len;) {
|
3277
3290
|
const take = Math.min(blockLen - this.pos, len - pos);
|
@@ -3305,7 +3318,7 @@ class HashMD extends Hash {
|
|
3305
3318
|
let { pos } = this;
|
3306
3319
|
// append the bit '1' to the message
|
3307
3320
|
buffer[pos++] = 0b10000000;
|
3308
|
-
this.buffer.subarray(pos)
|
3321
|
+
clean(this.buffer.subarray(pos));
|
3309
3322
|
// we have less than padOffset left in buffer, so we cannot put length in
|
3310
3323
|
// current block, need process it and pad again
|
3311
3324
|
if (this.padOffset > blockLen - pos) {
|
@@ -3343,28 +3356,90 @@ class HashMD extends Hash {
|
|
3343
3356
|
to || (to = new this.constructor());
|
3344
3357
|
to.set(...this.get());
|
3345
3358
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
3359
|
+
to.destroyed = destroyed;
|
3360
|
+
to.finished = finished;
|
3346
3361
|
to.length = length;
|
3347
3362
|
to.pos = pos;
|
3348
|
-
to.finished = finished;
|
3349
|
-
to.destroyed = destroyed;
|
3350
3363
|
if (length % blockLen)
|
3351
3364
|
to.buffer.set(buffer);
|
3352
3365
|
return to;
|
3353
3366
|
}
|
3367
|
+
clone() {
|
3368
|
+
return this._cloneInto();
|
3369
|
+
}
|
3354
3370
|
}
|
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
|
+
]);
|
3355
3384
|
|
3356
3385
|
/**
|
3357
|
-
*
|
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).
|
3386
|
+
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
3387
|
+
* @todo re-check https://issues.chromium.org/issues/42212588
|
3363
3388
|
* @module
|
3364
3389
|
*/
|
3365
|
-
|
3390
|
+
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
3391
|
+
const _32n = /* @__PURE__ */ BigInt(32);
|
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).
|
3435
|
+
* @module
|
3436
|
+
*/
|
3437
|
+
/**
|
3438
|
+
* Round constants:
|
3439
|
+
* First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
|
3440
|
+
*/
|
3366
3441
|
// prettier-ignore
|
3367
|
-
const SHA256_K = /* @__PURE__ */
|
3442
|
+
const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
3368
3443
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
3369
3444
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
3370
3445
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
@@ -3374,19 +3449,11 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
3374
3449
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
3375
3450
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
3376
3451
|
]);
|
3377
|
-
/**
|
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
|
-
*/
|
3452
|
+
/** Reusable temporary buffer. "W" comes straight from spec. */
|
3386
3453
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
3387
3454
|
class SHA256 extends HashMD {
|
3388
|
-
constructor() {
|
3389
|
-
super(64,
|
3455
|
+
constructor(outputLen = 32) {
|
3456
|
+
super(64, outputLen, 8, false);
|
3390
3457
|
// We cannot use array here since array allows indexing by variable
|
3391
3458
|
// which means optimizer/compiler cannot use registers.
|
3392
3459
|
this.A = SHA256_IV[0] | 0;
|
@@ -3452,15 +3519,192 @@ class SHA256 extends HashMD {
|
|
3452
3519
|
this.set(A, B, C, D, E, F, G, H);
|
3453
3520
|
}
|
3454
3521
|
roundClean() {
|
3455
|
-
SHA256_W
|
3522
|
+
clean(SHA256_W);
|
3456
3523
|
}
|
3457
3524
|
destroy() {
|
3458
3525
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
3459
|
-
this.buffer
|
3526
|
+
clean(this.buffer);
|
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);
|
3460
3683
|
}
|
3461
3684
|
}
|
3462
|
-
/**
|
3463
|
-
|
3685
|
+
/**
|
3686
|
+
* SHA2-256 hash function from RFC 4634.
|
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;
|
3464
3708
|
|
3465
3709
|
var Protocols;
|
3466
3710
|
(function (Protocols) {
|
@@ -6720,274 +6964,47 @@ function getOID(curve) {
|
|
6720
6964
|
if (curve === 'P-256') {
|
6721
6965
|
return OID_256;
|
6722
6966
|
}
|
6723
|
-
if (curve === 'P-384') {
|
6724
|
-
return OID_384;
|
6725
|
-
}
|
6726
|
-
if (curve === 'P-521') {
|
6727
|
-
return OID_521;
|
6728
|
-
}
|
6729
|
-
throw new InvalidParametersError(`Invalid curve ${curve}`);
|
6730
|
-
}
|
6731
|
-
|
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 };
|
6967
|
+
if (curve === 'P-384') {
|
6968
|
+
return OID_384;
|
6969
|
+
}
|
6970
|
+
if (curve === 'P-521') {
|
6971
|
+
return OID_521;
|
6972
|
+
}
|
6973
|
+
throw new InvalidParametersError(`Invalid curve ${curve}`);
|
6810
6974
|
}
|
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
6975
|
|
6828
|
-
|
6829
|
-
|
6830
|
-
|
6831
|
-
|
6832
|
-
|
6833
|
-
|
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;
|
6976
|
+
class ECDSAPublicKey {
|
6977
|
+
type = 'ECDSA';
|
6978
|
+
jwk;
|
6979
|
+
_raw;
|
6980
|
+
constructor(jwk) {
|
6981
|
+
this.jwk = jwk;
|
6885
6982
|
}
|
6886
|
-
|
6887
|
-
|
6888
|
-
|
6889
|
-
|
6983
|
+
get raw() {
|
6984
|
+
if (this._raw == null) {
|
6985
|
+
this._raw = publicKeyToPKIMessage(this.jwk);
|
6986
|
+
}
|
6987
|
+
return this._raw;
|
6890
6988
|
}
|
6891
|
-
|
6892
|
-
|
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;
|
6989
|
+
toMultihash() {
|
6990
|
+
return identity.digest(publicKeyToProtobuf(this));
|
6909
6991
|
}
|
6910
|
-
|
6911
|
-
|
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));
|
6915
|
-
}
|
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);
|
6992
|
+
toCID() {
|
6993
|
+
return CID.createV1(114, this.toMultihash());
|
6979
6994
|
}
|
6980
|
-
|
6981
|
-
|
6982
|
-
SHA512_W_L.fill(0);
|
6995
|
+
toString() {
|
6996
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
6983
6997
|
}
|
6984
|
-
|
6985
|
-
|
6986
|
-
|
6998
|
+
equals(key) {
|
6999
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
7000
|
+
return false;
|
7001
|
+
}
|
7002
|
+
return equals(this.raw, key.raw);
|
7003
|
+
}
|
7004
|
+
async verify(data, sig) {
|
7005
|
+
return hashAndVerify$3(this.jwk, sig, data);
|
6987
7006
|
}
|
6988
7007
|
}
|
6989
|
-
/** SHA2-512 hash function. */
|
6990
|
-
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
6991
7008
|
|
6992
7009
|
/**
|
6993
7010
|
* Hex, bytes and number utilities.
|
@@ -7000,7 +7017,6 @@ const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
|
7000
7017
|
// won't be included into their bundle.
|
7001
7018
|
const _0n$4 = /* @__PURE__ */ BigInt(0);
|
7002
7019
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
7003
|
-
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
7004
7020
|
function isBytes$1(a) {
|
7005
7021
|
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
7006
7022
|
}
|
@@ -7012,13 +7028,31 @@ function abool(title, value) {
|
|
7012
7028
|
if (typeof value !== 'boolean')
|
7013
7029
|
throw new Error(title + ' boolean expected, got ' + value);
|
7014
7030
|
}
|
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';
|
7015
7045
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
7016
7046
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
7017
7047
|
/**
|
7048
|
+
* Convert byte array to hex string. Uses built-in function, when available.
|
7018
7049
|
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
7019
7050
|
*/
|
7020
7051
|
function bytesToHex(bytes) {
|
7021
7052
|
abytes(bytes);
|
7053
|
+
// @ts-ignore
|
7054
|
+
if (hasHexBuiltin)
|
7055
|
+
return bytes.toHex();
|
7022
7056
|
// pre-caching improves the speed 6x
|
7023
7057
|
let hex = '';
|
7024
7058
|
for (let i = 0; i < bytes.length; i++) {
|
@@ -7026,15 +7060,6 @@ function bytesToHex(bytes) {
|
|
7026
7060
|
}
|
7027
7061
|
return hex;
|
7028
7062
|
}
|
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
|
-
}
|
7038
7063
|
// We use optimized technique to convert hex string to byte array
|
7039
7064
|
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
7040
7065
|
function asciiToBase16(ch) {
|
@@ -7047,11 +7072,15 @@ function asciiToBase16(ch) {
|
|
7047
7072
|
return;
|
7048
7073
|
}
|
7049
7074
|
/**
|
7075
|
+
* Convert hex string to byte array. Uses built-in function, when available.
|
7050
7076
|
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
7051
7077
|
*/
|
7052
7078
|
function hexToBytes(hex) {
|
7053
7079
|
if (typeof hex !== 'string')
|
7054
7080
|
throw new Error('hex string expected, got ' + typeof hex);
|
7081
|
+
// @ts-ignore
|
7082
|
+
if (hasHexBuiltin)
|
7083
|
+
return Uint8Array.fromHex(hex);
|
7055
7084
|
const hl = hex.length;
|
7056
7085
|
const al = hl / 2;
|
7057
7086
|
if (hl % 2)
|
@@ -7082,10 +7111,6 @@ function numberToBytesBE(n, len) {
|
|
7082
7111
|
function numberToBytesLE(n, len) {
|
7083
7112
|
return numberToBytesBE(n, len).reverse();
|
7084
7113
|
}
|
7085
|
-
// Unpadded, rarely used
|
7086
|
-
function numberToVarBytesBE(n) {
|
7087
|
-
return hexToBytes(numberToHexUnpadded(n));
|
7088
|
-
}
|
7089
7114
|
/**
|
7090
7115
|
* Takes hex string or Uint8Array, converts to Uint8Array.
|
7091
7116
|
* Validates output length.
|
@@ -7136,23 +7161,6 @@ function concatBytes(...arrays) {
|
|
7136
7161
|
}
|
7137
7162
|
return res;
|
7138
7163
|
}
|
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
|
-
}
|
7156
7164
|
// Is positive bigint
|
7157
7165
|
const isPosBig = (n) => typeof n === 'bigint' && _0n$4 <= n;
|
7158
7166
|
function inRange(n, min, max) {
|
@@ -7176,6 +7184,7 @@ function aInRange(title, n, min, max) {
|
|
7176
7184
|
/**
|
7177
7185
|
* Calculates amount of bits in a bigint.
|
7178
7186
|
* Same as `n.toString(2).length`
|
7187
|
+
* TODO: merge with nLength in modular
|
7179
7188
|
*/
|
7180
7189
|
function bitLen(n) {
|
7181
7190
|
let len;
|
@@ -7183,27 +7192,13 @@ function bitLen(n) {
|
|
7183
7192
|
;
|
7184
7193
|
return len;
|
7185
7194
|
}
|
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
|
-
}
|
7200
7195
|
/**
|
7201
7196
|
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
7202
7197
|
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
7203
7198
|
*/
|
7204
|
-
const bitMask = (n) => (
|
7199
|
+
const bitMask = (n) => (_1n$6 << BigInt(n)) - _1n$6;
|
7205
7200
|
// DRBG
|
7206
|
-
const u8n = (
|
7201
|
+
const u8n = (len) => new Uint8Array(len); // creates Uint8Array
|
7207
7202
|
const u8fr = (arr) => Uint8Array.from(arr); // another shortcut
|
7208
7203
|
/**
|
7209
7204
|
* Minimal HMAC-DRBG from NIST 800-90 for RFC6979 sigs.
|
@@ -7229,7 +7224,7 @@ function createHmacDrbg(hashLen, qByteLen, hmacFn) {
|
|
7229
7224
|
i = 0;
|
7230
7225
|
};
|
7231
7226
|
const h = (...b) => hmacFn(k, v, ...b); // hmac(k)(v, ...values)
|
7232
|
-
const reseed = (seed = u8n()) => {
|
7227
|
+
const reseed = (seed = u8n(0)) => {
|
7233
7228
|
// HMAC-DRBG reseed() function. Steps D-G
|
7234
7229
|
k = h(u8fr([0x00]), seed); // k = hmac(k || v || 0x00 || seed)
|
7235
7230
|
v = h(); // v = hmac(k || v)
|
@@ -7294,20 +7289,6 @@ function validateObject(object, validators, optValidators = {}) {
|
|
7294
7289
|
checkField(fieldName, type, true);
|
7295
7290
|
return object;
|
7296
7291
|
}
|
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
|
-
};
|
7311
7292
|
/**
|
7312
7293
|
* Memoizes (caches) computation result.
|
7313
7294
|
* Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
|
@@ -7324,36 +7305,6 @@ function memoized(fn) {
|
|
7324
7305
|
};
|
7325
7306
|
}
|
7326
7307
|
|
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
|
-
|
7357
7308
|
/**
|
7358
7309
|
* Utils for modular division and finite fields.
|
7359
7310
|
* A finite field over 11 is integer number operations `mod 11`.
|
@@ -7370,29 +7321,6 @@ function mod(a, b) {
|
|
7370
7321
|
const result = a % b;
|
7371
7322
|
return result >= _0n$3 ? result : b + result;
|
7372
7323
|
}
|
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
|
-
}
|
7396
7324
|
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
7397
7325
|
function pow2(x, power, modulo) {
|
7398
7326
|
let res = x;
|
@@ -7433,27 +7361,25 @@ function invert(number, modulo) {
|
|
7433
7361
|
* Tonelli-Shanks square root search algorithm.
|
7434
7362
|
* 1. https://eprint.iacr.org/2012/685.pdf (page 12)
|
7435
7363
|
* 2. Square Roots from 1; 24, 51, 10 to Dan Shanks
|
7436
|
-
* Will start an infinite loop if field order P is not prime.
|
7437
7364
|
* @param P field order
|
7438
7365
|
* @returns function that takes field Fp (created from P) and number n
|
7439
7366
|
*/
|
7440
7367
|
function tonelliShanks(P) {
|
7441
|
-
//
|
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;
|
7368
|
+
// Do expensive precomputation step
|
7448
7369
|
// Step 1: By factoring out powers of 2 from p - 1,
|
7449
|
-
// find q and s such that p
|
7450
|
-
|
7451
|
-
|
7370
|
+
// find q and s such that p-1 == q*(2^s) with q odd
|
7371
|
+
let Q = P - _1n$5;
|
7372
|
+
let S = 0;
|
7373
|
+
while (Q % _2n$3 === _0n$3) {
|
7374
|
+
Q /= _2n$3;
|
7375
|
+
S++;
|
7376
|
+
}
|
7452
7377
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
7453
|
-
|
7454
|
-
|
7455
|
-
|
7456
|
-
|
7378
|
+
let Z = _2n$3;
|
7379
|
+
const _Fp = Field(P);
|
7380
|
+
while (Z < P && FpIsSquare(_Fp, Z)) {
|
7381
|
+
if (Z++ > 1000)
|
7382
|
+
throw new Error('Cannot find square root: probably non-prime P');
|
7457
7383
|
}
|
7458
7384
|
// Fast-path
|
7459
7385
|
if (S === 1) {
|
@@ -7469,16 +7395,18 @@ function tonelliShanks(P) {
|
|
7469
7395
|
const Q1div2 = (Q + _1n$5) / _2n$3;
|
7470
7396
|
return function tonelliSlow(Fp, n) {
|
7471
7397
|
// Step 0: Check that n is indeed a square: (n | p) should not be ≡ -1
|
7472
|
-
if (Fp
|
7398
|
+
if (!FpIsSquare(Fp, n))
|
7473
7399
|
throw new Error('Cannot find square root');
|
7474
7400
|
let r = S;
|
7475
|
-
// TODO:
|
7401
|
+
// TODO: test on Fp2 and others
|
7476
7402
|
let g = Fp.pow(Fp.mul(Fp.ONE, Z), Q); // will update both x and b
|
7477
7403
|
let x = Fp.pow(n, Q1div2); // first guess at the square root
|
7478
7404
|
let b = Fp.pow(n, Q); // first guess at the fudge factor
|
7479
7405
|
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
|
7480
7408
|
if (Fp.eql(b, Fp.ZERO))
|
7481
|
-
return Fp.ZERO;
|
7409
|
+
return Fp.ZERO;
|
7482
7410
|
// Find m such b^(2^m)==1
|
7483
7411
|
let m = 1;
|
7484
7412
|
for (let t2 = Fp.sqr(b); m < r; m++) {
|
@@ -7486,7 +7414,8 @@ function tonelliShanks(P) {
|
|
7486
7414
|
break;
|
7487
7415
|
t2 = Fp.sqr(t2); // t2 *= t2
|
7488
7416
|
}
|
7489
|
-
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift,
|
7417
|
+
// NOTE: r-m-1 can be bigger than 32, need to convert to bigint before shift,
|
7418
|
+
// otherwise there will be overflow.
|
7490
7419
|
const ge = Fp.pow(g, _1n$5 << BigInt(r - m - 1)); // ge = 2^(r-m-1)
|
7491
7420
|
g = Fp.sqr(ge); // g = ge * ge
|
7492
7421
|
x = Fp.mul(x, ge); // x *= ge
|
@@ -7515,8 +7444,8 @@ function FpSqrt(P) {
|
|
7515
7444
|
// const ORDER =
|
7516
7445
|
// 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn;
|
7517
7446
|
// const NUM = 72057594037927816n;
|
7518
|
-
const p1div4 = (P + _1n$5) / _4n;
|
7519
7447
|
return function sqrt3mod4(Fp, n) {
|
7448
|
+
const p1div4 = (P + _1n$5) / _4n;
|
7520
7449
|
const root = Fp.pow(n, p1div4);
|
7521
7450
|
// Throw if root**2 != n
|
7522
7451
|
if (!Fp.eql(Fp.sqr(root), n))
|
@@ -7526,9 +7455,9 @@ function FpSqrt(P) {
|
|
7526
7455
|
}
|
7527
7456
|
// Atkin algorithm for q ≡ 5 (mod 8), https://eprint.iacr.org/2012/685.pdf (page 10)
|
7528
7457
|
if (P % _8n$2 === _5n$1) {
|
7529
|
-
const c1 = (P - _5n$1) / _8n$2;
|
7530
7458
|
return function sqrt5mod8(Fp, n) {
|
7531
7459
|
const n2 = Fp.mul(n, _2n$3);
|
7460
|
+
const c1 = (P - _5n$1) / _8n$2;
|
7532
7461
|
const v = Fp.pow(n2, c1);
|
7533
7462
|
const nv = Fp.mul(n, v);
|
7534
7463
|
const i = Fp.mul(Fp.mul(nv, _2n$3), v);
|
@@ -7567,52 +7496,78 @@ function validateField(field) {
|
|
7567
7496
|
* Same as `pow` but for Fp: non-constant-time.
|
7568
7497
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
7569
7498
|
*/
|
7570
|
-
function FpPow(
|
7571
|
-
// Should have same speed as pow for bigints
|
7572
|
-
// TODO: benchmark!
|
7499
|
+
function FpPow(Fp, num, power) {
|
7573
7500
|
if (power < _0n$3)
|
7574
7501
|
throw new Error('invalid exponent, negatives unsupported');
|
7575
7502
|
if (power === _0n$3)
|
7576
|
-
return
|
7503
|
+
return Fp.ONE;
|
7577
7504
|
if (power === _1n$5)
|
7578
7505
|
return num;
|
7579
|
-
|
7506
|
+
// @ts-ignore
|
7507
|
+
let p = Fp.ONE;
|
7580
7508
|
let d = num;
|
7581
7509
|
while (power > _0n$3) {
|
7582
7510
|
if (power & _1n$5)
|
7583
|
-
p =
|
7584
|
-
d =
|
7511
|
+
p = Fp.mul(p, d);
|
7512
|
+
d = Fp.sqr(d);
|
7585
7513
|
power >>= _1n$5;
|
7586
7514
|
}
|
7587
7515
|
return p;
|
7588
7516
|
}
|
7589
7517
|
/**
|
7590
7518
|
* Efficiently invert an array of Field elements.
|
7591
|
-
*
|
7519
|
+
* Exception-free. Will return `undefined` for 0 elements.
|
7520
|
+
* @param passZero map 0 to 0 (instead of undefined)
|
7592
7521
|
*/
|
7593
|
-
function FpInvertBatch(
|
7594
|
-
const
|
7522
|
+
function FpInvertBatch(Fp, nums, passZero = false) {
|
7523
|
+
const inverted = new Array(nums.length).fill(passZero ? Fp.ZERO : undefined);
|
7595
7524
|
// Walk from first to last, multiply them by each other MOD p
|
7596
|
-
const
|
7597
|
-
if (
|
7525
|
+
const multipliedAcc = nums.reduce((acc, num, i) => {
|
7526
|
+
if (Fp.is0(num))
|
7598
7527
|
return acc;
|
7599
|
-
|
7600
|
-
return
|
7601
|
-
},
|
7528
|
+
inverted[i] = acc;
|
7529
|
+
return Fp.mul(acc, num);
|
7530
|
+
}, Fp.ONE);
|
7602
7531
|
// Invert last element
|
7603
|
-
const
|
7532
|
+
const invertedAcc = Fp.inv(multipliedAcc);
|
7604
7533
|
// Walk from last to first, multiply them by inverted each other MOD p
|
7605
7534
|
nums.reduceRight((acc, num, i) => {
|
7606
|
-
if (
|
7535
|
+
if (Fp.is0(num))
|
7607
7536
|
return acc;
|
7608
|
-
|
7609
|
-
return
|
7610
|
-
},
|
7611
|
-
return
|
7537
|
+
inverted[i] = Fp.mul(acc, inverted[i]);
|
7538
|
+
return Fp.mul(acc, num);
|
7539
|
+
}, invertedAcc);
|
7540
|
+
return inverted;
|
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;
|
7612
7565
|
}
|
7613
7566
|
// CURVE.n lengths
|
7614
7567
|
function nLength(n, nBitLength) {
|
7615
7568
|
// Bit size, byte size of CURVE.n
|
7569
|
+
if (nBitLength !== undefined)
|
7570
|
+
anumber(nBitLength);
|
7616
7571
|
const _nBitLength = nBitLength !== undefined ? nBitLength : n.toString(2).length;
|
7617
7572
|
const nByteLength = Math.ceil(_nBitLength / 8);
|
7618
7573
|
return { nBitLength: _nBitLength, nByteLength };
|
@@ -7675,16 +7630,17 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
7675
7630
|
sqrtP = FpSqrt(ORDER);
|
7676
7631
|
return sqrtP(f, n);
|
7677
7632
|
}),
|
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),
|
7682
7633
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
7683
7634
|
fromBytes: (bytes) => {
|
7684
7635
|
if (bytes.length !== BYTES)
|
7685
7636
|
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
7686
7637
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
7687
7638
|
},
|
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),
|
7688
7644
|
});
|
7689
7645
|
return Object.freeze(f);
|
7690
7646
|
}
|
@@ -7753,11 +7709,36 @@ function validateW(W, bits) {
|
|
7753
7709
|
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
7754
7710
|
throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
|
7755
7711
|
}
|
7756
|
-
function calcWOpts(W,
|
7757
|
-
validateW(W,
|
7758
|
-
const windows = Math.ceil(
|
7759
|
-
const windowSize = 2 ** (W - 1); //
|
7760
|
-
|
7712
|
+
function calcWOpts(W, scalarBits) {
|
7713
|
+
validateW(W, scalarBits);
|
7714
|
+
const windows = Math.ceil(scalarBits / W) + 1; // W=8 33. Not 32, because we skip zero
|
7715
|
+
const windowSize = 2 ** (W - 1); // W=8 128. Not 256, because we skip zero
|
7716
|
+
const maxNumber = 2 ** W; // W=8 256
|
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 };
|
7761
7742
|
}
|
7762
7743
|
function validateMSMPoints(points, c) {
|
7763
7744
|
if (!Array.isArray(points))
|
@@ -7776,9 +7757,10 @@ function validateMSMScalars(scalars, field) {
|
|
7776
7757
|
});
|
7777
7758
|
}
|
7778
7759
|
// Since points in different groups cannot be equal (different object constructor),
|
7779
|
-
// we can have single place to store precomputes
|
7760
|
+
// we can have single place to store precomputes.
|
7761
|
+
// Allows to make points frozen / immutable.
|
7780
7762
|
const pointPrecomputes = new WeakMap();
|
7781
|
-
const pointWindowSizes = new WeakMap();
|
7763
|
+
const pointWindowSizes = new WeakMap();
|
7782
7764
|
function getW(P) {
|
7783
7765
|
return pointWindowSizes.get(P) || 1;
|
7784
7766
|
}
|
@@ -7833,7 +7815,7 @@ function wNAF(c, bits) {
|
|
7833
7815
|
for (let window = 0; window < windows; window++) {
|
7834
7816
|
base = p;
|
7835
7817
|
points.push(base);
|
7836
|
-
// =1,
|
7818
|
+
// i=1, bc we skip 0
|
7837
7819
|
for (let i = 1; i < windowSize; i++) {
|
7838
7820
|
base = base.add(p);
|
7839
7821
|
points.push(base);
|
@@ -7850,48 +7832,35 @@ function wNAF(c, bits) {
|
|
7850
7832
|
* @returns real and fake (for const-time) points
|
7851
7833
|
*/
|
7852
7834
|
wNAF(W, precomputes, n) {
|
7853
|
-
//
|
7854
|
-
//
|
7855
|
-
|
7835
|
+
// Smaller version:
|
7836
|
+
// https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
7837
|
+
// TODO: check the scalar is less than group order?
|
7838
|
+
// wNAF behavior is undefined otherwise. But have to carefully remove
|
7839
|
+
// other checks before wNAF. ORDER == bits here.
|
7840
|
+
// Accumulators
|
7856
7841
|
let p = c.ZERO;
|
7857
7842
|
let f = c.BASE;
|
7858
|
-
|
7859
|
-
|
7860
|
-
|
7861
|
-
|
7862
|
-
|
7863
|
-
|
7864
|
-
|
7865
|
-
//
|
7866
|
-
n
|
7867
|
-
|
7868
|
-
|
7869
|
-
|
7870
|
-
|
7871
|
-
|
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]));
|
7843
|
+
// This code was first written with assumption that 'f' and 'p' will never be infinity point:
|
7844
|
+
// since each addition is multiplied by 2 ** W, it cannot cancel each other. However,
|
7845
|
+
// there is negate now: it is possible that negated element from low value
|
7846
|
+
// would be the same as high element, which will create carry into next window.
|
7847
|
+
// It's not obvious how this can fail, but still worth investigating later.
|
7848
|
+
const wo = calcWOpts(W, bits);
|
7849
|
+
for (let window = 0; window < wo.windows; window++) {
|
7850
|
+
// (n === _0n) is handled and not early-exited. isEven and offsetF are used for noise
|
7851
|
+
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
7852
|
+
n = nextN;
|
7853
|
+
if (isZero) {
|
7854
|
+
// bits are 0: add garbage to fake point
|
7855
|
+
// Important part for const-time getPublicKey: add random "noise" point to f.
|
7856
|
+
f = f.add(constTimeNegate(isNegF, precomputes[offsetF]));
|
7887
7857
|
}
|
7888
7858
|
else {
|
7889
|
-
|
7859
|
+
// bits are 1: add to result point
|
7860
|
+
p = p.add(constTimeNegate(isNeg, precomputes[offset]));
|
7890
7861
|
}
|
7891
7862
|
}
|
7892
|
-
//
|
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.
|
7863
|
+
// Return both real and fake points: JIT won't eliminate f.
|
7895
7864
|
// At this point there is a way to F be infinity-point even if p is not,
|
7896
7865
|
// which makes it less const-time: around 1 bigint multiply.
|
7897
7866
|
return { p, f };
|
@@ -7905,31 +7874,21 @@ function wNAF(c, bits) {
|
|
7905
7874
|
* @returns point
|
7906
7875
|
*/
|
7907
7876
|
wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
|
7908
|
-
const
|
7909
|
-
|
7910
|
-
const maxNumber = 2 ** W;
|
7911
|
-
const shiftBy = BigInt(W);
|
7912
|
-
for (let window = 0; window < windows; window++) {
|
7913
|
-
const offset = window * windowSize;
|
7877
|
+
const wo = calcWOpts(W, bits);
|
7878
|
+
for (let window = 0; window < wo.windows; window++) {
|
7914
7879
|
if (n === _0n$2)
|
7915
|
-
break; //
|
7916
|
-
|
7917
|
-
|
7918
|
-
|
7919
|
-
|
7920
|
-
|
7921
|
-
// +224 => 256 - 32
|
7922
|
-
if (wbits > windowSize) {
|
7923
|
-
wbits -= maxNumber;
|
7924
|
-
n += _1n$4;
|
7925
|
-
}
|
7926
|
-
if (wbits === 0)
|
7880
|
+
break; // Early-exit, skip 0 value
|
7881
|
+
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
7882
|
+
n = nextN;
|
7883
|
+
if (isZero) {
|
7884
|
+
// Window bits are 0: skip processing.
|
7885
|
+
// Move to next window.
|
7927
7886
|
continue;
|
7928
|
-
|
7929
|
-
|
7930
|
-
|
7931
|
-
|
7932
|
-
|
7887
|
+
}
|
7888
|
+
else {
|
7889
|
+
const item = precomputes[offset];
|
7890
|
+
acc = acc.add(isNeg ? item.negate() : item); // Re-using acc allows to save adds in MSM
|
7891
|
+
}
|
7933
7892
|
}
|
7934
7893
|
return acc;
|
7935
7894
|
},
|
@@ -7965,7 +7924,7 @@ function wNAF(c, bits) {
|
|
7965
7924
|
}
|
7966
7925
|
/**
|
7967
7926
|
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
7968
|
-
* 30x faster vs naive addition on L=4096, 10x faster
|
7927
|
+
* 30x faster vs naive addition on L=4096, 10x faster than precomputes.
|
7969
7928
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
7970
7929
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
7971
7930
|
* @param c Curve Point constructor
|
@@ -7987,15 +7946,15 @@ function pippenger(c, fieldN, points, scalars) {
|
|
7987
7946
|
const zero = c.ZERO;
|
7988
7947
|
const wbits = bitLen(BigInt(points.length));
|
7989
7948
|
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
7990
|
-
const MASK = (
|
7991
|
-
const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
|
7949
|
+
const MASK = bitMask(windowSize);
|
7950
|
+
const buckets = new Array(Number(MASK) + 1).fill(zero); // +1 for zero array
|
7992
7951
|
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
7993
7952
|
let sum = zero;
|
7994
7953
|
for (let i = lastBits; i >= 0; i -= windowSize) {
|
7995
7954
|
buckets.fill(zero);
|
7996
7955
|
for (let j = 0; j < scalars.length; j++) {
|
7997
7956
|
const scalar = scalars[j];
|
7998
|
-
const wbits = Number((scalar >> BigInt(i)) &
|
7957
|
+
const wbits = Number((scalar >> BigInt(i)) & MASK);
|
7999
7958
|
buckets[wbits] = buckets[wbits].add(points[j]);
|
8000
7959
|
}
|
8001
7960
|
let resI = zero; // not using this will do small speed-up, but will lose ct
|
@@ -8036,6 +7995,7 @@ function validateBasic(curve) {
|
|
8036
7995
|
* @module
|
8037
7996
|
*/
|
8038
7997
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7998
|
+
// prettier-ignore
|
8039
7999
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
8040
8000
|
// prettier-ignore
|
8041
8001
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -8094,10 +8054,11 @@ function twistedEdwards(curveDef) {
|
|
8094
8054
|
}); // NOOP
|
8095
8055
|
// 0 <= n < MASK
|
8096
8056
|
// Coordinates larger than Fp.ORDER are allowed for zip215
|
8097
|
-
function aCoordinate(title, n) {
|
8098
|
-
|
8057
|
+
function aCoordinate(title, n, banZero = false) {
|
8058
|
+
const min = banZero ? _1n$3 : _0n$1;
|
8059
|
+
aInRange('coordinate ' + title, n, min, MASK);
|
8099
8060
|
}
|
8100
|
-
function
|
8061
|
+
function aextpoint(other) {
|
8101
8062
|
if (!(other instanceof Point))
|
8102
8063
|
throw new Error('ExtendedPoint expected');
|
8103
8064
|
}
|
@@ -8144,14 +8105,14 @@ function twistedEdwards(curveDef) {
|
|
8144
8105
|
// https://en.wikipedia.org/wiki/Twisted_Edwards_curve#Extended_coordinates
|
8145
8106
|
class Point {
|
8146
8107
|
constructor(ex, ey, ez, et) {
|
8108
|
+
aCoordinate('x', ex);
|
8109
|
+
aCoordinate('y', ey);
|
8110
|
+
aCoordinate('z', ez, true);
|
8111
|
+
aCoordinate('t', et);
|
8147
8112
|
this.ex = ex;
|
8148
8113
|
this.ey = ey;
|
8149
8114
|
this.ez = ez;
|
8150
8115
|
this.et = et;
|
8151
|
-
aCoordinate('x', ex);
|
8152
|
-
aCoordinate('y', ey);
|
8153
|
-
aCoordinate('z', ez);
|
8154
|
-
aCoordinate('t', et);
|
8155
8116
|
Object.freeze(this);
|
8156
8117
|
}
|
8157
8118
|
get x() {
|
@@ -8169,7 +8130,7 @@ function twistedEdwards(curveDef) {
|
|
8169
8130
|
return new Point(x, y, _1n$3, modP(x * y));
|
8170
8131
|
}
|
8171
8132
|
static normalizeZ(points) {
|
8172
|
-
const toInv = Fp
|
8133
|
+
const toInv = FpInvertBatch(Fp, points.map((p) => p.ez));
|
8173
8134
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
8174
8135
|
}
|
8175
8136
|
// Multiscalar Multiplication
|
@@ -8187,7 +8148,7 @@ function twistedEdwards(curveDef) {
|
|
8187
8148
|
}
|
8188
8149
|
// Compare one point to another.
|
8189
8150
|
equals(other) {
|
8190
|
-
|
8151
|
+
aextpoint(other);
|
8191
8152
|
const { ex: X1, ey: Y1, ez: Z1 } = this;
|
8192
8153
|
const { ex: X2, ey: Y2, ez: Z2 } = other;
|
8193
8154
|
const X1Z2 = modP(X1 * Z2);
|
@@ -8228,31 +8189,10 @@ function twistedEdwards(curveDef) {
|
|
8228
8189
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
|
8229
8190
|
// Cost: 9M + 1*a + 1*d + 7add.
|
8230
8191
|
add(other) {
|
8231
|
-
|
8192
|
+
aextpoint(other);
|
8232
8193
|
const { a, d } = CURVE;
|
8233
8194
|
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
|
8234
8195
|
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
|
-
}
|
8256
8196
|
const A = modP(X1 * X2); // A = X1*X2
|
8257
8197
|
const B = modP(Y1 * Y2); // B = Y1*Y2
|
8258
8198
|
const C = modP(T1 * d * T2); // C = T1*d*T2
|
@@ -8352,7 +8292,8 @@ function twistedEdwards(curveDef) {
|
|
8352
8292
|
return Point.fromAffine({ x, y });
|
8353
8293
|
}
|
8354
8294
|
static fromPrivateKey(privKey) {
|
8355
|
-
|
8295
|
+
const { scalar } = getPrivateScalar(privKey);
|
8296
|
+
return G.multiply(scalar); // reduced one call of `toRawBytes`
|
8356
8297
|
}
|
8357
8298
|
toRawBytes() {
|
8358
8299
|
const { x, y } = this.toAffine();
|
@@ -8375,8 +8316,8 @@ function twistedEdwards(curveDef) {
|
|
8375
8316
|
function modN_LE(hash) {
|
8376
8317
|
return modN(bytesToNumberLE(hash));
|
8377
8318
|
}
|
8378
|
-
|
8379
|
-
function
|
8319
|
+
// Get the hashed private scalar per RFC8032 5.1.5
|
8320
|
+
function getPrivateScalar(key) {
|
8380
8321
|
const len = Fp.BYTES;
|
8381
8322
|
key = ensureBytes('private key', key, len);
|
8382
8323
|
// Hash private key with curve's hash function to produce uniformingly random input
|
@@ -8385,6 +8326,11 @@ function twistedEdwards(curveDef) {
|
|
8385
8326
|
const head = adjustScalarBytes(hashed.slice(0, len)); // clear first half bits, produce FE
|
8386
8327
|
const prefix = hashed.slice(len, 2 * len); // second half is called key prefix (5.1.6)
|
8387
8328
|
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);
|
8388
8334
|
const point = G.multiply(scalar); // Point on Edwards curve aka public key
|
8389
8335
|
const pointBytes = point.toRawBytes(); // Uint8Array representation
|
8390
8336
|
return { head, prefix, scalar, point, pointBytes };
|
@@ -8394,7 +8340,7 @@ function twistedEdwards(curveDef) {
|
|
8394
8340
|
return getExtendedPublicKey(privKey).pointBytes;
|
8395
8341
|
}
|
8396
8342
|
// int('LE', SHA512(dom2(F, C) || msgs)) mod N
|
8397
|
-
function hashDomainToScalar(context =
|
8343
|
+
function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
|
8398
8344
|
const msg = concatBytes(...msgs);
|
8399
8345
|
return modN_LE(cHash(domain(msg, ensureBytes('context', context), !!prehash)));
|
8400
8346
|
}
|
@@ -8451,7 +8397,7 @@ function twistedEdwards(curveDef) {
|
|
8451
8397
|
G._setWindowSize(8); // Enable precomputes. Slows down first publicKey computation by 20ms.
|
8452
8398
|
const utils = {
|
8453
8399
|
getExtendedPublicKey,
|
8454
|
-
|
8400
|
+
/** ed25519 priv keys are uniform 32b. No need to check for modulo bias, like in secp256k1. */
|
8455
8401
|
randomPrivateKey: () => randomBytes(Fp.BYTES),
|
8456
8402
|
/**
|
8457
8403
|
* We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
|
@@ -8483,8 +8429,10 @@ function twistedEdwards(curveDef) {
|
|
8483
8429
|
* @module
|
8484
8430
|
*/
|
8485
8431
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
8432
|
+
// 2n**255n - 19n
|
8486
8433
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
8487
8434
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
8435
|
+
// Fp.sqrt(Fp.neg(1))
|
8488
8436
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
8489
8437
|
// prettier-ignore
|
8490
8438
|
BigInt(0); const _1n$2 = BigInt(1), _2n$1 = BigInt(2); BigInt(3);
|
@@ -8543,19 +8491,15 @@ function uvRatio(u, v) {
|
|
8543
8491
|
}
|
8544
8492
|
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
8545
8493
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
8546
|
-
//
|
8547
|
-
a:
|
8548
|
-
// d is
|
8549
|
-
// Negative number is P - number, and division is invert(number, P)
|
8494
|
+
// Removing Fp.create() will still work, and is 10% faster on sign
|
8495
|
+
a: Fp.create(BigInt(-1)),
|
8496
|
+
// d is -121665/121666 a.k.a. Fp.neg(121665 * Fp.inv(121666))
|
8550
8497
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
8551
|
-
// Finite field
|
8498
|
+
// Finite field 2n**255n - 19n
|
8552
8499
|
Fp,
|
8553
|
-
// Subgroup order
|
8554
|
-
// 2n**252n + 27742317777372353535851937790883648493n;
|
8500
|
+
// Subgroup order 2n**252n + 27742317777372353535851937790883648493n;
|
8555
8501
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
8556
|
-
// Cofactor
|
8557
8502
|
h: _8n,
|
8558
|
-
// Base point (x, y) aka generator point
|
8559
8503
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
8560
8504
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
8561
8505
|
hash: sha512,
|
@@ -10104,7 +10048,7 @@ class HMAC extends Hash {
|
|
10104
10048
|
for (let i = 0; i < pad.length; i++)
|
10105
10049
|
pad[i] ^= 0x36 ^ 0x5c;
|
10106
10050
|
this.oHash.update(pad);
|
10107
|
-
pad
|
10051
|
+
clean(pad);
|
10108
10052
|
}
|
10109
10053
|
update(buf) {
|
10110
10054
|
aexists(this);
|
@@ -10138,6 +10082,9 @@ class HMAC extends Hash {
|
|
10138
10082
|
to.iHash = iHash._cloneInto(to.iHash);
|
10139
10083
|
return to;
|
10140
10084
|
}
|
10085
|
+
clone() {
|
10086
|
+
return this._cloneInto();
|
10087
|
+
}
|
10141
10088
|
destroy() {
|
10142
10089
|
this.destroyed = true;
|
10143
10090
|
this.oHash.destroy();
|
@@ -10160,6 +10107,19 @@ hmac.create = (hash, key) => new HMAC(hash, key);
|
|
10160
10107
|
/**
|
10161
10108
|
* Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
|
10162
10109
|
*
|
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
|
+
*
|
10163
10123
|
* ### Design rationale for types
|
10164
10124
|
*
|
10165
10125
|
* * Interaction between classes from different curves should fail:
|
@@ -10184,6 +10144,7 @@ hmac.create = (hash, key) => new HMAC(hash, key);
|
|
10184
10144
|
* @module
|
10185
10145
|
*/
|
10186
10146
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
10147
|
+
// prettier-ignore
|
10187
10148
|
function validateSigVerOpts(opts) {
|
10188
10149
|
if (opts.lowS !== undefined)
|
10189
10150
|
abool('lowS', opts.lowS);
|
@@ -10217,7 +10178,6 @@ function validatePointOpts(curve) {
|
|
10217
10178
|
}
|
10218
10179
|
return Object.freeze({ ...opts });
|
10219
10180
|
}
|
10220
|
-
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
10221
10181
|
class DERErr extends Error {
|
10222
10182
|
constructor(m = '') {
|
10223
10183
|
super(m);
|
@@ -10310,14 +10270,13 @@ const DER = {
|
|
10310
10270
|
throw new E('invalid signature integer: negative');
|
10311
10271
|
if (data[0] === 0x00 && !(data[1] & 128))
|
10312
10272
|
throw new E('invalid signature integer: unnecessary leading zero');
|
10313
|
-
return
|
10273
|
+
return bytesToNumberBE(data);
|
10314
10274
|
},
|
10315
10275
|
},
|
10316
10276
|
toSig(hex) {
|
10317
10277
|
// parse DER signature
|
10318
10278
|
const { Err: E, _int: int, _tlv: tlv } = DER;
|
10319
|
-
const data =
|
10320
|
-
abytes(data);
|
10279
|
+
const data = ensureBytes('signature', hex);
|
10321
10280
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
10322
10281
|
if (seqLeftBytes.length)
|
10323
10282
|
throw new E('invalid signature: left bytes after parsing');
|
@@ -10357,7 +10316,7 @@ function weierstrassPoints(opts) {
|
|
10357
10316
|
return { x, y };
|
10358
10317
|
});
|
10359
10318
|
/**
|
10360
|
-
* y² = x³ + ax + b: Short weierstrass curve formula
|
10319
|
+
* y² = x³ + ax + b: Short weierstrass curve formula. Takes x, returns y².
|
10361
10320
|
* @returns y²
|
10362
10321
|
*/
|
10363
10322
|
function weierstrassEquation(x) {
|
@@ -10403,7 +10362,7 @@ function weierstrassPoints(opts) {
|
|
10403
10362
|
aInRange('private key', num, _1n$1, N); // num in range [1..N-1]
|
10404
10363
|
return num;
|
10405
10364
|
}
|
10406
|
-
function
|
10365
|
+
function aprjpoint(other) {
|
10407
10366
|
if (!(other instanceof Point))
|
10408
10367
|
throw new Error('ProjectivePoint expected');
|
10409
10368
|
}
|
@@ -10461,15 +10420,15 @@ function weierstrassPoints(opts) {
|
|
10461
10420
|
*/
|
10462
10421
|
class Point {
|
10463
10422
|
constructor(px, py, pz) {
|
10464
|
-
this.px = px;
|
10465
|
-
this.py = py;
|
10466
|
-
this.pz = pz;
|
10467
10423
|
if (px == null || !Fp.isValid(px))
|
10468
10424
|
throw new Error('x required');
|
10469
|
-
if (py == null || !Fp.isValid(py))
|
10425
|
+
if (py == null || !Fp.isValid(py) || Fp.is0(py))
|
10470
10426
|
throw new Error('y required');
|
10471
10427
|
if (pz == null || !Fp.isValid(pz))
|
10472
10428
|
throw new Error('z required');
|
10429
|
+
this.px = px;
|
10430
|
+
this.py = py;
|
10431
|
+
this.pz = pz;
|
10473
10432
|
Object.freeze(this);
|
10474
10433
|
}
|
10475
10434
|
// Does not validate if the point is on-curve.
|
@@ -10499,7 +10458,7 @@ function weierstrassPoints(opts) {
|
|
10499
10458
|
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
10500
10459
|
*/
|
10501
10460
|
static normalizeZ(points) {
|
10502
|
-
const toInv = Fp
|
10461
|
+
const toInv = FpInvertBatch(Fp, points.map((p) => p.pz));
|
10503
10462
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
10504
10463
|
}
|
10505
10464
|
/**
|
@@ -10537,7 +10496,7 @@ function weierstrassPoints(opts) {
|
|
10537
10496
|
* Compare one point to another.
|
10538
10497
|
*/
|
10539
10498
|
equals(other) {
|
10540
|
-
|
10499
|
+
aprjpoint(other);
|
10541
10500
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
10542
10501
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
10543
10502
|
const U1 = Fp.eql(Fp.mul(X1, Z2), Fp.mul(X2, Z1));
|
@@ -10597,7 +10556,7 @@ function weierstrassPoints(opts) {
|
|
10597
10556
|
// https://eprint.iacr.org/2015/1060, algorithm 1
|
10598
10557
|
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
10599
10558
|
add(other) {
|
10600
|
-
|
10559
|
+
aprjpoint(other);
|
10601
10560
|
const { px: X1, py: Y1, pz: Z1 } = this;
|
10602
10561
|
const { px: X2, py: Y2, pz: Z2 } = other;
|
10603
10562
|
let X3 = Fp.ZERO, Y3 = Fp.ZERO, Z3 = Fp.ZERO; // prettier-ignore
|
@@ -10768,10 +10727,9 @@ function weierstrassPoints(opts) {
|
|
10768
10727
|
}
|
10769
10728
|
}
|
10770
10729
|
Point.BASE = new Point(CURVE.Gx, CURVE.Gy, Fp.ONE);
|
10771
|
-
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO);
|
10730
|
+
Point.ZERO = new Point(Fp.ZERO, Fp.ONE, Fp.ZERO); // 0, 1, 0
|
10772
10731
|
const _bits = CURVE.nBitLength;
|
10773
10732
|
const wnaf = wNAF(Point, CURVE.endo ? Math.ceil(_bits / 2) : _bits);
|
10774
|
-
// Validate if generator point is on curve
|
10775
10733
|
return {
|
10776
10734
|
CURVE,
|
10777
10735
|
ProjectivePoint: Point,
|
@@ -10862,7 +10820,7 @@ function weierstrass(curveDef) {
|
|
10862
10820
|
}
|
10863
10821
|
},
|
10864
10822
|
});
|
10865
|
-
const
|
10823
|
+
const numToNByteHex = (num) => bytesToHex(numberToBytesBE(num, CURVE.nByteLength));
|
10866
10824
|
function isBiggerThanHalfOrder(number) {
|
10867
10825
|
const HALF = CURVE_ORDER >> _1n$1;
|
10868
10826
|
return number > HALF;
|
@@ -10877,10 +10835,13 @@ function weierstrass(curveDef) {
|
|
10877
10835
|
*/
|
10878
10836
|
class Signature {
|
10879
10837
|
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]
|
10880
10840
|
this.r = r;
|
10881
10841
|
this.s = s;
|
10882
|
-
|
10883
|
-
|
10842
|
+
if (recovery != null)
|
10843
|
+
this.recovery = recovery;
|
10844
|
+
Object.freeze(this);
|
10884
10845
|
}
|
10885
10846
|
// pair (bytes of r, bytes of s)
|
10886
10847
|
static fromCompact(hex) {
|
@@ -10894,10 +10855,11 @@ function weierstrass(curveDef) {
|
|
10894
10855
|
const { r, s } = DER.toSig(ensureBytes('DER', hex));
|
10895
10856
|
return new Signature(r, s);
|
10896
10857
|
}
|
10897
|
-
|
10898
|
-
|
10899
|
-
|
10900
|
-
|
10858
|
+
/**
|
10859
|
+
* @todo remove
|
10860
|
+
* @deprecated
|
10861
|
+
*/
|
10862
|
+
assertValidity() { }
|
10901
10863
|
addRecoveryBit(recovery) {
|
10902
10864
|
return new Signature(this.r, this.s, recovery);
|
10903
10865
|
}
|
@@ -10910,7 +10872,7 @@ function weierstrass(curveDef) {
|
|
10910
10872
|
if (radj >= Fp.ORDER)
|
10911
10873
|
throw new Error('recovery id 2 or 3 invalid');
|
10912
10874
|
const prefix = (rec & 1) === 0 ? '02' : '03';
|
10913
|
-
const R = Point.fromHex(prefix +
|
10875
|
+
const R = Point.fromHex(prefix + numToNByteHex(radj));
|
10914
10876
|
const ir = invN(radj); // r^-1
|
10915
10877
|
const u1 = modN(-h * ir); // -hr^-1
|
10916
10878
|
const u2 = modN(s * ir); // sr^-1
|
@@ -10932,14 +10894,14 @@ function weierstrass(curveDef) {
|
|
10932
10894
|
return hexToBytes(this.toDERHex());
|
10933
10895
|
}
|
10934
10896
|
toDERHex() {
|
10935
|
-
return DER.hexFromSig(
|
10897
|
+
return DER.hexFromSig(this);
|
10936
10898
|
}
|
10937
10899
|
// padded bytes of r, then padded bytes of s
|
10938
10900
|
toCompactRawBytes() {
|
10939
10901
|
return hexToBytes(this.toCompactHex());
|
10940
10902
|
}
|
10941
10903
|
toCompactHex() {
|
10942
|
-
return
|
10904
|
+
return numToNByteHex(this.r) + numToNByteHex(this.s);
|
10943
10905
|
}
|
10944
10906
|
}
|
10945
10907
|
const utils = {
|
@@ -11279,26 +11241,28 @@ function sqrtMod(y) {
|
|
11279
11241
|
}
|
11280
11242
|
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
11281
11243
|
/**
|
11282
|
-
* secp256k1
|
11244
|
+
* secp256k1 curve, ECDSA and ECDH methods.
|
11245
|
+
*
|
11246
|
+
* Field: `2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n`
|
11283
11247
|
*
|
11284
11248
|
* @example
|
11249
|
+
* ```js
|
11285
11250
|
* import { secp256k1 } from '@noble/curves/secp256k1';
|
11286
|
-
*
|
11287
11251
|
* const priv = secp256k1.utils.randomPrivateKey();
|
11288
11252
|
* const pub = secp256k1.getPublicKey(priv);
|
11289
11253
|
* const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
|
11290
11254
|
* const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
|
11291
11255
|
* const isValid = secp256k1.verify(sig, msg, pub) === true;
|
11256
|
+
* ```
|
11292
11257
|
*/
|
11293
11258
|
const secp256k1 = createCurve({
|
11294
|
-
a: BigInt(0),
|
11259
|
+
a: BigInt(0),
|
11295
11260
|
b: BigInt(7),
|
11296
|
-
Fp: Fpk1,
|
11297
|
-
n: secp256k1N,
|
11298
|
-
// Base point (x, y) aka generator point
|
11261
|
+
Fp: Fpk1,
|
11262
|
+
n: secp256k1N,
|
11299
11263
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
11300
11264
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
11301
|
-
h: BigInt(1),
|
11265
|
+
h: BigInt(1),
|
11302
11266
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
11303
11267
|
endo: {
|
11304
11268
|
// Endomorphism, see above
|
@@ -11326,7 +11290,7 @@ const secp256k1 = createCurve({
|
|
11326
11290
|
return { k1neg, k1, k2neg, k2 };
|
11327
11291
|
},
|
11328
11292
|
},
|
11329
|
-
}, sha256);
|
11293
|
+
}, sha256$1);
|
11330
11294
|
// Schnorr signatures are superior to ECDSA from above. Below is Schnorr-specific BIP0340 code.
|
11331
11295
|
// https://github.com/bitcoin/bips/blob/master/bip-0340.mediawiki
|
11332
11296
|
BigInt(0);
|
@@ -11346,7 +11310,7 @@ const PUBLIC_KEY_BYTE_LENGTH = 33;
|
|
11346
11310
|
* Hash message and verify signature with public key
|
11347
11311
|
*/
|
11348
11312
|
function hashAndVerify(key, sig, msg) {
|
11349
|
-
const p = sha256$
|
11313
|
+
const p = sha256$2.digest(msg instanceof Uint8Array ? msg : msg.subarray());
|
11350
11314
|
if (isPromise(p)) {
|
11351
11315
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
11352
11316
|
.catch(err => {
|
@@ -11980,7 +11944,7 @@ class EnrCreator {
|
|
11980
11944
|
}
|
11981
11945
|
return ENR.create({
|
11982
11946
|
...kvs,
|
11983
|
-
id: utf8ToBytes$
|
11947
|
+
id: utf8ToBytes$1("v4"),
|
11984
11948
|
secp256k1: publicKey
|
11985
11949
|
});
|
11986
11950
|
}
|