@waku/enr 0.0.28-c43cec2.0 → 0.0.28-c86e056.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 +582 -340
- package/dist/.tsbuildinfo +1 -1
- package/package.json +1 -1
package/bundle/index.js
CHANGED
@@ -655,7 +655,7 @@ new TextDecoder();
|
|
655
655
|
|
656
656
|
/* eslint-disable */
|
657
657
|
var encode_1 = encode$3;
|
658
|
-
var MSB$1 = 0x80,
|
658
|
+
var MSB$1 = 0x80, MSBALL = -128, INT = Math.pow(2, 31);
|
659
659
|
/**
|
660
660
|
* @param {number} num
|
661
661
|
* @param {number[]} out
|
@@ -679,7 +679,7 @@ function encode$3(num, out, offset) {
|
|
679
679
|
return out;
|
680
680
|
}
|
681
681
|
var decode$4 = read$1;
|
682
|
-
var MSB$1$1 = 0x80, REST$1
|
682
|
+
var MSB$1$1 = 0x80, REST$1 = 0x7F;
|
683
683
|
/**
|
684
684
|
* @param {string | any[]} buf
|
685
685
|
* @param {number} offset
|
@@ -694,8 +694,8 @@ function read$1(buf, offset) {
|
|
694
694
|
}
|
695
695
|
b = buf[counter++];
|
696
696
|
res += shift < 28
|
697
|
-
? (b & REST$1
|
698
|
-
: (b & REST$1
|
697
|
+
? (b & REST$1) << shift
|
698
|
+
: (b & REST$1) * Math.pow(2, shift);
|
699
699
|
shift += 7;
|
700
700
|
} while (b >= MSB$1$1);
|
701
701
|
// @ts-ignore
|
@@ -1586,10 +1586,10 @@ class JacobianPoint {
|
|
1586
1586
|
const cond1 = window % 2 !== 0;
|
1587
1587
|
const cond2 = wbits < 0;
|
1588
1588
|
if (wbits === 0) {
|
1589
|
-
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
1589
|
+
f = f.add(constTimeNegate$1(cond1, precomputes[offset1]));
|
1590
1590
|
}
|
1591
1591
|
else {
|
1592
|
-
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
1592
|
+
p = p.add(constTimeNegate$1(cond2, precomputes[offset2]));
|
1593
1593
|
}
|
1594
1594
|
}
|
1595
1595
|
return { p, f };
|
@@ -1602,8 +1602,8 @@ class JacobianPoint {
|
|
1602
1602
|
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
1603
1603
|
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
1604
1604
|
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
1605
|
-
k1p = constTimeNegate(k1neg, k1p);
|
1606
|
-
k2p = constTimeNegate(k2neg, k2p);
|
1605
|
+
k1p = constTimeNegate$1(k1neg, k1p);
|
1606
|
+
k2p = constTimeNegate$1(k2neg, k2p);
|
1607
1607
|
k2p = new JacobianPoint(mod$1(k2p.x * endo.beta), k2p.y, k2p.z);
|
1608
1608
|
point = k1p.add(k2p);
|
1609
1609
|
fake = f1p.add(f2p);
|
@@ -1635,7 +1635,7 @@ class JacobianPoint {
|
|
1635
1635
|
}
|
1636
1636
|
JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n$7);
|
1637
1637
|
JacobianPoint.ZERO = new JacobianPoint(_0n$5, _1n$7, _0n$5);
|
1638
|
-
function constTimeNegate(condition, item) {
|
1638
|
+
function constTimeNegate$1(condition, item) {
|
1639
1639
|
const neg = item.negate();
|
1640
1640
|
return condition ? neg : item;
|
1641
1641
|
}
|
@@ -3092,43 +3092,55 @@ function verifySignature(signature, message, publicKey) {
|
|
3092
3092
|
}
|
3093
3093
|
}
|
3094
3094
|
|
3095
|
-
|
3095
|
+
/**
|
3096
|
+
* Internal assertion helpers.
|
3097
|
+
* @module
|
3098
|
+
*/
|
3099
|
+
/** Asserts something is positive integer. */
|
3100
|
+
function anumber(n) {
|
3096
3101
|
if (!Number.isSafeInteger(n) || n < 0)
|
3097
|
-
throw new Error(
|
3102
|
+
throw new Error('positive integer expected, got ' + n);
|
3098
3103
|
}
|
3099
|
-
|
3104
|
+
/** Is number an Uint8Array? Copied from utils for perf. */
|
3100
3105
|
function isBytes$2(a) {
|
3101
|
-
return
|
3102
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
3106
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
3103
3107
|
}
|
3104
|
-
|
3108
|
+
/** Asserts something is Uint8Array. */
|
3109
|
+
function abytes$1(b, ...lengths) {
|
3105
3110
|
if (!isBytes$2(b))
|
3106
3111
|
throw new Error('Uint8Array expected');
|
3107
3112
|
if (lengths.length > 0 && !lengths.includes(b.length))
|
3108
|
-
throw new Error(
|
3113
|
+
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
|
3109
3114
|
}
|
3110
|
-
|
3115
|
+
/** Asserts something is hash */
|
3116
|
+
function ahash(h) {
|
3111
3117
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
3112
3118
|
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
3113
|
-
|
3114
|
-
|
3119
|
+
anumber(h.outputLen);
|
3120
|
+
anumber(h.blockLen);
|
3115
3121
|
}
|
3116
|
-
|
3122
|
+
/** Asserts a hash instance has not been destroyed / finished */
|
3123
|
+
function aexists(instance, checkFinished = true) {
|
3117
3124
|
if (instance.destroyed)
|
3118
3125
|
throw new Error('Hash instance has been destroyed');
|
3119
3126
|
if (checkFinished && instance.finished)
|
3120
3127
|
throw new Error('Hash#digest() has already been called');
|
3121
3128
|
}
|
3122
|
-
|
3123
|
-
|
3129
|
+
/** Asserts output is properly-sized byte array */
|
3130
|
+
function aoutput(out, instance) {
|
3131
|
+
abytes$1(out);
|
3124
3132
|
const min = instance.outputLen;
|
3125
3133
|
if (out.length < min) {
|
3126
|
-
throw new Error(
|
3134
|
+
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
3127
3135
|
}
|
3128
3136
|
}
|
3129
3137
|
|
3130
3138
|
const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
3131
3139
|
|
3140
|
+
/**
|
3141
|
+
* Utilities for hex, bytes, CSPRNG.
|
3142
|
+
* @module
|
3143
|
+
*/
|
3132
3144
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
3133
3145
|
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
3134
3146
|
// node.js versions earlier than v19 don't declare it in global scope.
|
@@ -3137,16 +3149,20 @@ const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
|
|
3137
3149
|
// Makes the utils un-importable in browsers without a bundler.
|
3138
3150
|
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
3139
3151
|
// Cast array to view
|
3140
|
-
|
3141
|
-
|
3142
|
-
|
3143
|
-
|
3152
|
+
function createView(arr) {
|
3153
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
3154
|
+
}
|
3155
|
+
/** The rotate right (circular right shift) operation for uint32 */
|
3156
|
+
function rotr(word, shift) {
|
3157
|
+
return (word << (32 - shift)) | (word >>> shift);
|
3158
|
+
}
|
3144
3159
|
/**
|
3160
|
+
* Convert JS string to byte array.
|
3145
3161
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
3146
3162
|
*/
|
3147
3163
|
function utf8ToBytes$1(str) {
|
3148
3164
|
if (typeof str !== 'string')
|
3149
|
-
throw new Error(
|
3165
|
+
throw new Error('utf8ToBytes expected string, got ' + typeof str);
|
3150
3166
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
3151
3167
|
}
|
3152
3168
|
/**
|
@@ -3157,7 +3173,7 @@ function utf8ToBytes$1(str) {
|
|
3157
3173
|
function toBytes$1(data) {
|
3158
3174
|
if (typeof data === 'string')
|
3159
3175
|
data = utf8ToBytes$1(data);
|
3160
|
-
|
3176
|
+
abytes$1(data);
|
3161
3177
|
return data;
|
3162
3178
|
}
|
3163
3179
|
/**
|
@@ -3167,7 +3183,7 @@ function concatBytes$1(...arrays) {
|
|
3167
3183
|
let sum = 0;
|
3168
3184
|
for (let i = 0; i < arrays.length; i++) {
|
3169
3185
|
const a = arrays[i];
|
3170
|
-
|
3186
|
+
abytes$1(a);
|
3171
3187
|
sum += a.length;
|
3172
3188
|
}
|
3173
3189
|
const res = new Uint8Array(sum);
|
@@ -3178,13 +3194,14 @@ function concatBytes$1(...arrays) {
|
|
3178
3194
|
}
|
3179
3195
|
return res;
|
3180
3196
|
}
|
3181
|
-
|
3197
|
+
/** For runtime check if class implements interface */
|
3182
3198
|
class Hash {
|
3183
3199
|
// Safe version that clones internal state
|
3184
3200
|
clone() {
|
3185
3201
|
return this._cloneInto();
|
3186
3202
|
}
|
3187
3203
|
}
|
3204
|
+
/** Wraps hash function, creating an interface on top of it */
|
3188
3205
|
function wrapConstructor(hashCons) {
|
3189
3206
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
3190
3207
|
const tmp = hashCons();
|
@@ -3193,9 +3210,7 @@ function wrapConstructor(hashCons) {
|
|
3193
3210
|
hashC.create = () => hashCons();
|
3194
3211
|
return hashC;
|
3195
3212
|
}
|
3196
|
-
/**
|
3197
|
-
* Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
|
3198
|
-
*/
|
3213
|
+
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
3199
3214
|
function randomBytes(bytesLength = 32) {
|
3200
3215
|
if (crypto$1 && typeof crypto$1.getRandomValues === 'function') {
|
3201
3216
|
return crypto$1.getRandomValues(new Uint8Array(bytesLength));
|
@@ -3208,8 +3223,10 @@ function randomBytes(bytesLength = 32) {
|
|
3208
3223
|
}
|
3209
3224
|
|
3210
3225
|
/**
|
3211
|
-
*
|
3226
|
+
* Internal Merkle-Damgard hash utils.
|
3227
|
+
* @module
|
3212
3228
|
*/
|
3229
|
+
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
|
3213
3230
|
function setBigUint64(view, byteOffset, value, isLE) {
|
3214
3231
|
if (typeof view.setBigUint64 === 'function')
|
3215
3232
|
return view.setBigUint64(byteOffset, value, isLE);
|
@@ -3222,14 +3239,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
3222
3239
|
view.setUint32(byteOffset + h, wh, isLE);
|
3223
3240
|
view.setUint32(byteOffset + l, wl, isLE);
|
3224
3241
|
}
|
3225
|
-
/**
|
3226
|
-
|
3227
|
-
|
3228
|
-
|
3229
|
-
/**
|
3230
|
-
|
3231
|
-
|
3232
|
-
|
3242
|
+
/** Choice: a ? b : c */
|
3243
|
+
function Chi(a, b, c) {
|
3244
|
+
return (a & b) ^ (~a & c);
|
3245
|
+
}
|
3246
|
+
/** Majority function, true if any two inputs is true. */
|
3247
|
+
function Maj(a, b, c) {
|
3248
|
+
return (a & b) ^ (a & c) ^ (b & c);
|
3249
|
+
}
|
3233
3250
|
/**
|
3234
3251
|
* Merkle-Damgard hash construction base class.
|
3235
3252
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
@@ -3249,7 +3266,7 @@ class HashMD extends Hash {
|
|
3249
3266
|
this.view = createView(this.buffer);
|
3250
3267
|
}
|
3251
3268
|
update(data) {
|
3252
|
-
|
3269
|
+
aexists(this);
|
3253
3270
|
const { view, buffer, blockLen } = this;
|
3254
3271
|
data = toBytes$1(data);
|
3255
3272
|
const len = data.length;
|
@@ -3275,8 +3292,8 @@ class HashMD extends Hash {
|
|
3275
3292
|
return this;
|
3276
3293
|
}
|
3277
3294
|
digestInto(out) {
|
3278
|
-
|
3279
|
-
|
3295
|
+
aexists(this);
|
3296
|
+
aoutput(out, this);
|
3280
3297
|
this.finished = true;
|
3281
3298
|
// Padding
|
3282
3299
|
// We can avoid allocation of buffer for padding completely if it
|
@@ -3333,10 +3350,16 @@ class HashMD extends Hash {
|
|
3333
3350
|
}
|
3334
3351
|
}
|
3335
3352
|
|
3336
|
-
|
3337
|
-
|
3338
|
-
|
3339
|
-
|
3353
|
+
/**
|
3354
|
+
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
3355
|
+
*
|
3356
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
3357
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
3358
|
+
*
|
3359
|
+
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
3360
|
+
* @module
|
3361
|
+
*/
|
3362
|
+
/** Round constants: first 32 bits of fractional parts of the cube roots of the first 64 primes 2..311). */
|
3340
3363
|
// prettier-ignore
|
3341
3364
|
const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
3342
3365
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
@@ -3348,14 +3371,15 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
3348
3371
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
3349
3372
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
3350
3373
|
]);
|
3351
|
-
|
3352
|
-
// first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19
|
3374
|
+
/** Initial state: first 32 bits of fractional parts of the square roots of the first 8 primes 2..19. */
|
3353
3375
|
// prettier-ignore
|
3354
3376
|
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
3355
3377
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
3356
3378
|
]);
|
3357
|
-
|
3358
|
-
|
3379
|
+
/**
|
3380
|
+
* Temporary buffer, not used to store anything between runs.
|
3381
|
+
* Named this way because it matches specification.
|
3382
|
+
*/
|
3359
3383
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
3360
3384
|
class SHA256 extends HashMD {
|
3361
3385
|
constructor() {
|
@@ -3432,10 +3456,7 @@ class SHA256 extends HashMD {
|
|
3432
3456
|
this.buffer.fill(0);
|
3433
3457
|
}
|
3434
3458
|
}
|
3435
|
-
/**
|
3436
|
-
* SHA2-256 hash function
|
3437
|
-
* @param message - data that would be hashed
|
3438
|
-
*/
|
3459
|
+
/** SHA2-256 hash function */
|
3439
3460
|
const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
3440
3461
|
|
3441
3462
|
var Protocols;
|
@@ -3552,6 +3573,10 @@ var EConnectionStateEvents;
|
|
3552
3573
|
EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
|
3553
3574
|
})(EConnectionStateEvents || (EConnectionStateEvents = {}));
|
3554
3575
|
|
3576
|
+
var HealthStatusChangeEvents;
|
3577
|
+
(function (HealthStatusChangeEvents) {
|
3578
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
3579
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
3555
3580
|
var HealthStatus;
|
3556
3581
|
(function (HealthStatus) {
|
3557
3582
|
HealthStatus["Unhealthy"] = "Unhealthy";
|
@@ -3930,24 +3955,62 @@ function setup(env) {
|
|
3930
3955
|
createDebug.names = [];
|
3931
3956
|
createDebug.skips = [];
|
3932
3957
|
|
3933
|
-
|
3934
|
-
|
3935
|
-
|
3958
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
3959
|
+
.trim()
|
3960
|
+
.replace(' ', ',')
|
3961
|
+
.split(',')
|
3962
|
+
.filter(Boolean);
|
3936
3963
|
|
3937
|
-
for (
|
3938
|
-
if (
|
3939
|
-
|
3940
|
-
|
3964
|
+
for (const ns of split) {
|
3965
|
+
if (ns[0] === '-') {
|
3966
|
+
createDebug.skips.push(ns.slice(1));
|
3967
|
+
} else {
|
3968
|
+
createDebug.names.push(ns);
|
3941
3969
|
}
|
3970
|
+
}
|
3971
|
+
}
|
3942
3972
|
|
3943
|
-
|
3944
|
-
|
3945
|
-
|
3946
|
-
|
3973
|
+
/**
|
3974
|
+
* Checks if the given string matches a namespace template, honoring
|
3975
|
+
* asterisks as wildcards.
|
3976
|
+
*
|
3977
|
+
* @param {String} search
|
3978
|
+
* @param {String} template
|
3979
|
+
* @return {Boolean}
|
3980
|
+
*/
|
3981
|
+
function matchesTemplate(search, template) {
|
3982
|
+
let searchIndex = 0;
|
3983
|
+
let templateIndex = 0;
|
3984
|
+
let starIndex = -1;
|
3985
|
+
let matchIndex = 0;
|
3986
|
+
|
3987
|
+
while (searchIndex < search.length) {
|
3988
|
+
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
|
3989
|
+
// Match character or proceed with wildcard
|
3990
|
+
if (template[templateIndex] === '*') {
|
3991
|
+
starIndex = templateIndex;
|
3992
|
+
matchIndex = searchIndex;
|
3993
|
+
templateIndex++; // Skip the '*'
|
3994
|
+
} else {
|
3995
|
+
searchIndex++;
|
3996
|
+
templateIndex++;
|
3997
|
+
}
|
3998
|
+
} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
|
3999
|
+
// Backtrack to the last '*' and try to match more characters
|
4000
|
+
templateIndex = starIndex + 1;
|
4001
|
+
matchIndex++;
|
4002
|
+
searchIndex = matchIndex;
|
3947
4003
|
} else {
|
3948
|
-
|
4004
|
+
return false; // No match
|
3949
4005
|
}
|
3950
4006
|
}
|
4007
|
+
|
4008
|
+
// Handle trailing '*' in template
|
4009
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
4010
|
+
templateIndex++;
|
4011
|
+
}
|
4012
|
+
|
4013
|
+
return templateIndex === template.length;
|
3951
4014
|
}
|
3952
4015
|
|
3953
4016
|
/**
|
@@ -3958,8 +4021,8 @@ function setup(env) {
|
|
3958
4021
|
*/
|
3959
4022
|
function disable() {
|
3960
4023
|
const namespaces = [
|
3961
|
-
...createDebug.names
|
3962
|
-
...createDebug.skips.map(
|
4024
|
+
...createDebug.names,
|
4025
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
3963
4026
|
].join(',');
|
3964
4027
|
createDebug.enable('');
|
3965
4028
|
return namespaces;
|
@@ -3973,21 +4036,14 @@ function setup(env) {
|
|
3973
4036
|
* @api public
|
3974
4037
|
*/
|
3975
4038
|
function enabled(name) {
|
3976
|
-
|
3977
|
-
|
3978
|
-
}
|
3979
|
-
|
3980
|
-
let i;
|
3981
|
-
let len;
|
3982
|
-
|
3983
|
-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
3984
|
-
if (createDebug.skips[i].test(name)) {
|
4039
|
+
for (const skip of createDebug.skips) {
|
4040
|
+
if (matchesTemplate(name, skip)) {
|
3985
4041
|
return false;
|
3986
4042
|
}
|
3987
4043
|
}
|
3988
4044
|
|
3989
|
-
for (
|
3990
|
-
if (
|
4045
|
+
for (const ns of createDebug.names) {
|
4046
|
+
if (matchesTemplate(name, ns)) {
|
3991
4047
|
return true;
|
3992
4048
|
}
|
3993
4049
|
}
|
@@ -3995,19 +4051,6 @@ function setup(env) {
|
|
3995
4051
|
return false;
|
3996
4052
|
}
|
3997
4053
|
|
3998
|
-
/**
|
3999
|
-
* Convert regexp to namespace
|
4000
|
-
*
|
4001
|
-
* @param {RegExp} regxep
|
4002
|
-
* @return {String} namespace
|
4003
|
-
* @api private
|
4004
|
-
*/
|
4005
|
-
function toNamespace(regexp) {
|
4006
|
-
return regexp.toString()
|
4007
|
-
.substring(2, regexp.toString().length - 2)
|
4008
|
-
.replace(/\.\*\?$/, '*');
|
4009
|
-
}
|
4010
|
-
|
4011
4054
|
/**
|
4012
4055
|
* Coerce `val`.
|
4013
4056
|
*
|
@@ -4169,6 +4212,7 @@ var common = setup;
|
|
4169
4212
|
|
4170
4213
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
4171
4214
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
4215
|
+
// eslint-disable-next-line no-return-assign
|
4172
4216
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
4173
4217
|
// Is firebug? http://stackoverflow.com/a/398120/376773
|
4174
4218
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
@@ -4833,7 +4877,7 @@ function parseIPv6(input) {
|
|
4833
4877
|
return parser.new(input).parseWith(() => parser.readIPv6Addr());
|
4834
4878
|
}
|
4835
4879
|
/** Parse `input` into IPv4 or IPv6 bytes. */
|
4836
|
-
function parseIP(input) {
|
4880
|
+
function parseIP(input, mapIPv4ToIPv6 = false) {
|
4837
4881
|
// strip zone index if it is present
|
4838
4882
|
if (input.includes("%")) {
|
4839
4883
|
input = input.split("%")[0];
|
@@ -4841,7 +4885,14 @@ function parseIP(input) {
|
|
4841
4885
|
if (input.length > MAX_IPV6_LENGTH) {
|
4842
4886
|
return undefined;
|
4843
4887
|
}
|
4844
|
-
|
4888
|
+
const addr = parser.new(input).parseWith(() => parser.readIPAddr());
|
4889
|
+
if (!addr) {
|
4890
|
+
return undefined;
|
4891
|
+
}
|
4892
|
+
if (mapIPv4ToIPv6 && addr.length === 4) {
|
4893
|
+
return Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, addr[0], addr[1], addr[2], addr[3]]);
|
4894
|
+
}
|
4895
|
+
return addr;
|
4845
4896
|
}
|
4846
4897
|
|
4847
4898
|
/** Check if `input` is IPv4. */
|
@@ -5029,17 +5080,13 @@ function getProtocol(proto) {
|
|
5029
5080
|
throw new Error(`invalid protocol id type: ${typeof proto}`);
|
5030
5081
|
}
|
5031
5082
|
|
5032
|
-
/**
|
5033
|
-
* @packageDocumentation
|
5034
|
-
*
|
5035
|
-
* Provides methods for converting
|
5036
|
-
*/
|
5037
5083
|
getProtocol('ip4');
|
5038
5084
|
getProtocol('ip6');
|
5039
5085
|
getProtocol('ipcidr');
|
5040
5086
|
/**
|
5041
5087
|
* Convert [code,Uint8Array] to string
|
5042
5088
|
*/
|
5089
|
+
// eslint-disable-next-line complexity
|
5043
5090
|
function convertToString(proto, buf) {
|
5044
5091
|
const protocol = getProtocol(proto);
|
5045
5092
|
switch (protocol.code) {
|
@@ -5048,6 +5095,8 @@ function convertToString(proto, buf) {
|
|
5048
5095
|
return bytes2ip(buf);
|
5049
5096
|
case 42: // ipv6zone
|
5050
5097
|
return bytes2str(buf);
|
5098
|
+
case 43: // ipcidr
|
5099
|
+
return toString$1(buf, 'base10');
|
5051
5100
|
case 6: // tcp
|
5052
5101
|
case 273: // udp
|
5053
5102
|
case 33: // dccp
|
@@ -5075,6 +5124,7 @@ function convertToString(proto, buf) {
|
|
5075
5124
|
return toString$1(buf, 'base16'); // no clue. convert to hex
|
5076
5125
|
}
|
5077
5126
|
}
|
5127
|
+
// eslint-disable-next-line complexity
|
5078
5128
|
function convertToBytes(proto, str) {
|
5079
5129
|
const protocol = getProtocol(proto);
|
5080
5130
|
switch (protocol.code) {
|
@@ -5084,6 +5134,8 @@ function convertToBytes(proto, str) {
|
|
5084
5134
|
return ip2bytes(str);
|
5085
5135
|
case 42: // ipv6zone
|
5086
5136
|
return str2bytes(str);
|
5137
|
+
case 43: // ipcidr
|
5138
|
+
return fromString(str, 'base10');
|
5087
5139
|
case 6: // tcp
|
5088
5140
|
case 273: // udp
|
5089
5141
|
case 33: // dccp
|
@@ -5378,19 +5430,6 @@ function ParseError(str) {
|
|
5378
5430
|
return new Error('Error parsing address: ' + str);
|
5379
5431
|
}
|
5380
5432
|
|
5381
|
-
/**
|
5382
|
-
* @packageDocumentation
|
5383
|
-
*
|
5384
|
-
* An implementation of a Multiaddr in JavaScript
|
5385
|
-
*
|
5386
|
-
* @example
|
5387
|
-
*
|
5388
|
-
* ```js
|
5389
|
-
* import { multiaddr } from '@multiformats/multiaddr'
|
5390
|
-
*
|
5391
|
-
* const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
5392
|
-
* ```
|
5393
|
-
*/
|
5394
5433
|
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
5395
5434
|
const symbol = Symbol.for('@multiformats/js-multiaddr/multiaddr');
|
5396
5435
|
const DNS_CODES = [
|
@@ -5502,10 +5541,20 @@ class Multiaddr {
|
|
5502
5541
|
return this.#tuples.map(([code]) => getProtocol(code).name);
|
5503
5542
|
}
|
5504
5543
|
tuples() {
|
5505
|
-
return this.#tuples
|
5544
|
+
return this.#tuples.map(([code, value]) => {
|
5545
|
+
if (value == null) {
|
5546
|
+
return [code];
|
5547
|
+
}
|
5548
|
+
return [code, value];
|
5549
|
+
});
|
5506
5550
|
}
|
5507
5551
|
stringTuples() {
|
5508
|
-
return this.#stringTuples
|
5552
|
+
return this.#stringTuples.map(([code, value]) => {
|
5553
|
+
if (value == null) {
|
5554
|
+
return [code];
|
5555
|
+
}
|
5556
|
+
return [code, value];
|
5557
|
+
});
|
5509
5558
|
}
|
5510
5559
|
encapsulate(addr) {
|
5511
5560
|
addr = new Multiaddr(addr);
|
@@ -5635,10 +5684,8 @@ class Multiaddr {
|
|
5635
5684
|
*
|
5636
5685
|
* ```TypeScript
|
5637
5686
|
* import { multiaddr } from '@multiformats/multiaddr'
|
5638
|
-
* const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
|
5639
|
-
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5640
5687
|
*
|
5641
|
-
* const addr = multiaddr(
|
5688
|
+
* const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
|
5642
5689
|
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5643
5690
|
*
|
5644
5691
|
* addr.bytes
|
@@ -5677,9 +5724,9 @@ class Multiaddr {
|
|
5677
5724
|
*
|
5678
5725
|
* ```TypeScript
|
5679
5726
|
* import { multiaddr, resolvers } from '@multiformats/multiaddr'
|
5680
|
-
* import {
|
5727
|
+
* import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
5681
5728
|
*
|
5682
|
-
* resolvers.set('dnsaddr',
|
5729
|
+
* resolvers.set('dnsaddr', dnsaddrResolver)
|
5683
5730
|
*
|
5684
5731
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
5685
5732
|
*
|
@@ -5688,7 +5735,7 @@ class Multiaddr {
|
|
5688
5735
|
* signal: AbortSignal.timeout(5000)
|
5689
5736
|
* })
|
5690
5737
|
*
|
5691
|
-
* console.info(
|
5738
|
+
* console.info(resolved)
|
5692
5739
|
* // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
|
5693
5740
|
* ```
|
5694
5741
|
*
|
@@ -5702,7 +5749,9 @@ class Multiaddr {
|
|
5702
5749
|
* import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
5703
5750
|
*
|
5704
5751
|
* const resolver = dns({
|
5705
|
-
*
|
5752
|
+
* resolvers: {
|
5753
|
+
* '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
|
5754
|
+
* }
|
5706
5755
|
* })
|
5707
5756
|
*
|
5708
5757
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
@@ -5830,9 +5879,13 @@ class UnsupportedKeyTypeError extends Error {
|
|
5830
5879
|
}
|
5831
5880
|
}
|
5832
5881
|
|
5882
|
+
/**
|
5883
|
+
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
5884
|
+
* @todo re-check https://issues.chromium.org/issues/42212588
|
5885
|
+
* @module
|
5886
|
+
*/
|
5833
5887
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
5834
5888
|
const _32n = /* @__PURE__ */ BigInt(32);
|
5835
|
-
// We are not using BigUint64Array, because they are extremely slow as per 2022
|
5836
5889
|
function fromBig(n, le = false) {
|
5837
5890
|
if (le)
|
5838
5891
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
@@ -5889,6 +5942,13 @@ const u64 = {
|
|
5889
5942
|
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
5890
5943
|
};
|
5891
5944
|
|
5945
|
+
/**
|
5946
|
+
* SHA2-512 a.k.a. sha512 and sha384. It is slower than sha256 in js because u64 operations are slow.
|
5947
|
+
*
|
5948
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
5949
|
+
* [the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
|
5950
|
+
* @module
|
5951
|
+
*/
|
5892
5952
|
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
5893
5953
|
// prettier-ignore
|
5894
5954
|
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
@@ -6043,8 +6103,13 @@ class SHA512 extends HashMD {
|
|
6043
6103
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
6044
6104
|
}
|
6045
6105
|
}
|
6106
|
+
/** SHA2-512 hash function. */
|
6046
6107
|
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
6047
6108
|
|
6109
|
+
/**
|
6110
|
+
* Hex, bytes and number utilities.
|
6111
|
+
* @module
|
6112
|
+
*/
|
6048
6113
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6049
6114
|
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
6050
6115
|
// This is OK: `abstract` directory does not use noble-hashes.
|
@@ -6054,8 +6119,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
|
|
6054
6119
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6055
6120
|
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6056
6121
|
function isBytes$1(a) {
|
6057
|
-
return
|
6058
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
6122
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
6059
6123
|
}
|
6060
6124
|
function abytes(item) {
|
6061
6125
|
if (!isBytes$1(item))
|
@@ -6063,7 +6127,7 @@ function abytes(item) {
|
|
6063
6127
|
}
|
6064
6128
|
function abool(title, value) {
|
6065
6129
|
if (typeof value !== 'boolean')
|
6066
|
-
throw new Error(
|
6130
|
+
throw new Error(title + ' boolean expected, got ' + value);
|
6067
6131
|
}
|
6068
6132
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6069
6133
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
@@ -6081,23 +6145,22 @@ function bytesToHex(bytes) {
|
|
6081
6145
|
}
|
6082
6146
|
function numberToHexUnpadded(num) {
|
6083
6147
|
const hex = num.toString(16);
|
6084
|
-
return hex.length & 1 ?
|
6148
|
+
return hex.length & 1 ? '0' + hex : hex;
|
6085
6149
|
}
|
6086
6150
|
function hexToNumber(hex) {
|
6087
6151
|
if (typeof hex !== 'string')
|
6088
6152
|
throw new Error('hex string expected, got ' + typeof hex);
|
6089
|
-
// Big Endian
|
6090
|
-
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
6153
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
6091
6154
|
}
|
6092
6155
|
// We use optimized technique to convert hex string to byte array
|
6093
|
-
const asciis = { _0: 48, _9: 57,
|
6094
|
-
function asciiToBase16(
|
6095
|
-
if (
|
6096
|
-
return
|
6097
|
-
if (
|
6098
|
-
return
|
6099
|
-
if (
|
6100
|
-
return
|
6156
|
+
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
6157
|
+
function asciiToBase16(ch) {
|
6158
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
6159
|
+
return ch - asciis._0; // '2' => 50-48
|
6160
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
6161
|
+
return ch - (asciis.A - 10); // 'B' => 66-(65-10)
|
6162
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
6163
|
+
return ch - (asciis.a - 10); // 'b' => 98-(97-10)
|
6101
6164
|
return;
|
6102
6165
|
}
|
6103
6166
|
/**
|
@@ -6109,7 +6172,7 @@ function hexToBytes(hex) {
|
|
6109
6172
|
const hl = hex.length;
|
6110
6173
|
const al = hl / 2;
|
6111
6174
|
if (hl % 2)
|
6112
|
-
throw new Error('
|
6175
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
6113
6176
|
const array = new Uint8Array(al);
|
6114
6177
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
6115
6178
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
@@ -6118,7 +6181,7 @@ function hexToBytes(hex) {
|
|
6118
6181
|
const char = hex[hi] + hex[hi + 1];
|
6119
6182
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
6120
6183
|
}
|
6121
|
-
array[ai] = n1 * 16 + n2;
|
6184
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
6122
6185
|
}
|
6123
6186
|
return array;
|
6124
6187
|
}
|
@@ -6156,7 +6219,7 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6156
6219
|
res = hexToBytes(hex);
|
6157
6220
|
}
|
6158
6221
|
catch (e) {
|
6159
|
-
throw new Error(
|
6222
|
+
throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
|
6160
6223
|
}
|
6161
6224
|
}
|
6162
6225
|
else if (isBytes$1(hex)) {
|
@@ -6165,11 +6228,11 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6165
6228
|
res = Uint8Array.from(hex);
|
6166
6229
|
}
|
6167
6230
|
else {
|
6168
|
-
throw new Error(
|
6231
|
+
throw new Error(title + ' must be hex string or Uint8Array');
|
6169
6232
|
}
|
6170
6233
|
const len = res.length;
|
6171
6234
|
if (typeof expectedLength === 'number' && len !== expectedLength)
|
6172
|
-
throw new Error(
|
6235
|
+
throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
|
6173
6236
|
return res;
|
6174
6237
|
}
|
6175
6238
|
/**
|
@@ -6204,7 +6267,7 @@ function equalBytes(a, b) {
|
|
6204
6267
|
*/
|
6205
6268
|
function utf8ToBytes(str) {
|
6206
6269
|
if (typeof str !== 'string')
|
6207
|
-
throw new Error(
|
6270
|
+
throw new Error('string expected');
|
6208
6271
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6209
6272
|
}
|
6210
6273
|
// Is positive bigint
|
@@ -6224,7 +6287,7 @@ function aInRange(title, n, min, max) {
|
|
6224
6287
|
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6225
6288
|
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6226
6289
|
if (!inRange(n, min, max))
|
6227
|
-
throw new Error(
|
6290
|
+
throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
|
6228
6291
|
}
|
6229
6292
|
// Bit operations
|
6230
6293
|
/**
|
@@ -6334,12 +6397,12 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6334
6397
|
const checkField = (fieldName, type, isOptional) => {
|
6335
6398
|
const checkVal = validatorFns[type];
|
6336
6399
|
if (typeof checkVal !== 'function')
|
6337
|
-
throw new Error(
|
6400
|
+
throw new Error('invalid validator function');
|
6338
6401
|
const val = object[fieldName];
|
6339
6402
|
if (isOptional && val === undefined)
|
6340
6403
|
return;
|
6341
6404
|
if (!checkVal(val, object)) {
|
6342
|
-
throw new Error(
|
6405
|
+
throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
|
6343
6406
|
}
|
6344
6407
|
};
|
6345
6408
|
for (const [fieldName, type] of Object.entries(validators))
|
@@ -6408,14 +6471,17 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6408
6471
|
validateObject: validateObject
|
6409
6472
|
});
|
6410
6473
|
|
6474
|
+
/**
|
6475
|
+
* Utils for modular division and finite fields.
|
6476
|
+
* A finite field over 11 is integer number operations `mod 11`.
|
6477
|
+
* There is no division: it is replaced by modular multiplicative inverse.
|
6478
|
+
* @module
|
6479
|
+
*/
|
6411
6480
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6412
|
-
// Utilities for modular arithmetics and finite fields
|
6413
|
-
// prettier-ignore
|
6414
|
-
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6415
6481
|
// prettier-ignore
|
6416
|
-
const
|
6482
|
+
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = /* @__PURE__ */ BigInt(2), _3n$1 = /* @__PURE__ */ BigInt(3);
|
6417
6483
|
// prettier-ignore
|
6418
|
-
BigInt(
|
6484
|
+
const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
|
6419
6485
|
// Calculates a modulo b
|
6420
6486
|
function mod(a, b) {
|
6421
6487
|
const result = a % b;
|
@@ -6424,13 +6490,15 @@ function mod(a, b) {
|
|
6424
6490
|
/**
|
6425
6491
|
* Efficiently raise num to power and do modular division.
|
6426
6492
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
6493
|
+
* @todo use field version && remove
|
6427
6494
|
* @example
|
6428
6495
|
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
6429
6496
|
*/
|
6430
|
-
// TODO: use field version && remove
|
6431
6497
|
function pow(num, power, modulo) {
|
6432
|
-
if (
|
6433
|
-
throw new Error('
|
6498
|
+
if (power < _0n$3)
|
6499
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6500
|
+
if (modulo <= _0n$3)
|
6501
|
+
throw new Error('invalid modulus');
|
6434
6502
|
if (modulo === _1n$5)
|
6435
6503
|
return _0n$3;
|
6436
6504
|
let res = _1n$5;
|
@@ -6442,7 +6510,7 @@ function pow(num, power, modulo) {
|
|
6442
6510
|
}
|
6443
6511
|
return res;
|
6444
6512
|
}
|
6445
|
-
|
6513
|
+
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
6446
6514
|
function pow2(x, power, modulo) {
|
6447
6515
|
let res = x;
|
6448
6516
|
while (power-- > _0n$3) {
|
@@ -6451,12 +6519,15 @@ function pow2(x, power, modulo) {
|
|
6451
6519
|
}
|
6452
6520
|
return res;
|
6453
6521
|
}
|
6454
|
-
|
6522
|
+
/**
|
6523
|
+
* Inverses number over modulo.
|
6524
|
+
* Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
|
6525
|
+
*/
|
6455
6526
|
function invert(number, modulo) {
|
6456
|
-
if (number === _0n$3
|
6457
|
-
throw new Error(
|
6458
|
-
|
6459
|
-
|
6527
|
+
if (number === _0n$3)
|
6528
|
+
throw new Error('invert: expected non-zero number');
|
6529
|
+
if (modulo <= _0n$3)
|
6530
|
+
throw new Error('invert: expected positive modulus, got ' + modulo);
|
6460
6531
|
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
6461
6532
|
let a = mod(number, modulo);
|
6462
6533
|
let b = modulo;
|
@@ -6496,8 +6567,11 @@ function tonelliShanks(P) {
|
|
6496
6567
|
for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
|
6497
6568
|
;
|
6498
6569
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
6499
|
-
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
|
6500
|
-
|
6570
|
+
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++) {
|
6571
|
+
// Crash instead of infinity loop, we cannot reasonable count until P.
|
6572
|
+
if (Z > 1000)
|
6573
|
+
throw new Error('Cannot find square root: likely non-prime P');
|
6574
|
+
}
|
6501
6575
|
// Fast-path
|
6502
6576
|
if (S === 1) {
|
6503
6577
|
const p1div4 = (P + _1n$5) / _4n;
|
@@ -6539,9 +6613,18 @@ function tonelliShanks(P) {
|
|
6539
6613
|
return x;
|
6540
6614
|
};
|
6541
6615
|
}
|
6616
|
+
/**
|
6617
|
+
* Square root for a finite field. It will try to check if optimizations are applicable and fall back to 4:
|
6618
|
+
*
|
6619
|
+
* 1. P ≡ 3 (mod 4)
|
6620
|
+
* 2. P ≡ 5 (mod 8)
|
6621
|
+
* 3. P ≡ 9 (mod 16)
|
6622
|
+
* 4. Tonelli-Shanks algorithm
|
6623
|
+
*
|
6624
|
+
* Different algorithms can give different roots, it is up to user to decide which one they want.
|
6625
|
+
* For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6626
|
+
*/
|
6542
6627
|
function FpSqrt(P) {
|
6543
|
-
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
6544
|
-
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6545
6628
|
// P ≡ 3 (mod 4)
|
6546
6629
|
// √n = n^((P+1)/4)
|
6547
6630
|
if (P % _4n === _3n$1) {
|
@@ -6605,7 +6688,7 @@ function FpPow(f, num, power) {
|
|
6605
6688
|
// Should have same speed as pow for bigints
|
6606
6689
|
// TODO: benchmark!
|
6607
6690
|
if (power < _0n$3)
|
6608
|
-
throw new Error('
|
6691
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6609
6692
|
if (power === _0n$3)
|
6610
6693
|
return f.ONE;
|
6611
6694
|
if (power === _1n$5)
|
@@ -6652,15 +6735,15 @@ function nLength(n, nBitLength) {
|
|
6652
6735
|
return { nBitLength: _nBitLength, nByteLength };
|
6653
6736
|
}
|
6654
6737
|
/**
|
6655
|
-
* Initializes a finite field over prime.
|
6656
|
-
* Do not init in loop: slow. Very fragile: always run a benchmark on a change.
|
6738
|
+
* Initializes a finite field over prime.
|
6657
6739
|
* Major performance optimizations:
|
6658
6740
|
* * a) denormalized operations like mulN instead of mul
|
6659
6741
|
* * b) same object shape: never add or remove keys
|
6660
6742
|
* * c) Object.freeze
|
6661
|
-
*
|
6743
|
+
* Fragile: always run a benchmark on a change.
|
6744
|
+
* Security note: operations don't check 'isValid' for all elements for performance reasons,
|
6662
6745
|
* it is caller responsibility to check this.
|
6663
|
-
* This is low-level code, please make sure you know what you doing.
|
6746
|
+
* This is low-level code, please make sure you know what you're doing.
|
6664
6747
|
* @param ORDER prime positive bigint
|
6665
6748
|
* @param bitLen how many bits the field consumes
|
6666
6749
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6668,13 +6751,14 @@ function nLength(n, nBitLength) {
|
|
6668
6751
|
*/
|
6669
6752
|
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
6670
6753
|
if (ORDER <= _0n$3)
|
6671
|
-
throw new Error(
|
6754
|
+
throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
|
6672
6755
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
6673
6756
|
if (BYTES > 2048)
|
6674
|
-
throw new Error('
|
6675
|
-
|
6757
|
+
throw new Error('invalid field: expected ORDER of <= 2048 bytes');
|
6758
|
+
let sqrtP; // cached sqrtP
|
6676
6759
|
const f = Object.freeze({
|
6677
6760
|
ORDER,
|
6761
|
+
isLE,
|
6678
6762
|
BITS,
|
6679
6763
|
BYTES,
|
6680
6764
|
MASK: bitMask(BITS),
|
@@ -6683,7 +6767,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6683
6767
|
create: (num) => mod(num, ORDER),
|
6684
6768
|
isValid: (num) => {
|
6685
6769
|
if (typeof num !== 'bigint')
|
6686
|
-
throw new Error(
|
6770
|
+
throw new Error('invalid field element: expected bigint, got ' + typeof num);
|
6687
6771
|
return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
6688
6772
|
},
|
6689
6773
|
is0: (num) => num === _0n$3,
|
@@ -6702,7 +6786,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6702
6786
|
subN: (lhs, rhs) => lhs - rhs,
|
6703
6787
|
mulN: (lhs, rhs) => lhs * rhs,
|
6704
6788
|
inv: (num) => invert(num, ORDER),
|
6705
|
-
sqrt: redef.sqrt ||
|
6789
|
+
sqrt: redef.sqrt ||
|
6790
|
+
((n) => {
|
6791
|
+
if (!sqrtP)
|
6792
|
+
sqrtP = FpSqrt(ORDER);
|
6793
|
+
return sqrtP(f, n);
|
6794
|
+
}),
|
6706
6795
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
6707
6796
|
// TODO: do we really need constant cmov?
|
6708
6797
|
// We don't have const-time bigints anyway, so probably will be not very useful
|
@@ -6710,7 +6799,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6710
6799
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
6711
6800
|
fromBytes: (bytes) => {
|
6712
6801
|
if (bytes.length !== BYTES)
|
6713
|
-
throw new Error(
|
6802
|
+
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
6714
6803
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
6715
6804
|
},
|
6716
6805
|
});
|
@@ -6758,52 +6847,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6758
6847
|
const minLen = getMinHashLength(fieldOrder);
|
6759
6848
|
// No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
|
6760
6849
|
if (len < 16 || len < minLen || len > 1024)
|
6761
|
-
throw new Error(
|
6762
|
-
const num = isLE ?
|
6850
|
+
throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
|
6851
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
6763
6852
|
// `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
|
6764
6853
|
const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
|
6765
6854
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
6766
6855
|
}
|
6767
6856
|
|
6857
|
+
/**
|
6858
|
+
* Methods for elliptic curve multiplication by scalars.
|
6859
|
+
* Contains wNAF, pippenger
|
6860
|
+
* @module
|
6861
|
+
*/
|
6768
6862
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6769
|
-
// Abelian group utilities
|
6770
6863
|
const _0n$2 = BigInt(0);
|
6771
6864
|
const _1n$4 = BigInt(1);
|
6865
|
+
function constTimeNegate(condition, item) {
|
6866
|
+
const neg = item.negate();
|
6867
|
+
return condition ? neg : item;
|
6868
|
+
}
|
6869
|
+
function validateW(W, bits) {
|
6870
|
+
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6871
|
+
throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
|
6872
|
+
}
|
6873
|
+
function calcWOpts(W, bits) {
|
6874
|
+
validateW(W, bits);
|
6875
|
+
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6876
|
+
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6877
|
+
return { windows, windowSize };
|
6878
|
+
}
|
6879
|
+
function validateMSMPoints(points, c) {
|
6880
|
+
if (!Array.isArray(points))
|
6881
|
+
throw new Error('array expected');
|
6882
|
+
points.forEach((p, i) => {
|
6883
|
+
if (!(p instanceof c))
|
6884
|
+
throw new Error('invalid point at index ' + i);
|
6885
|
+
});
|
6886
|
+
}
|
6887
|
+
function validateMSMScalars(scalars, field) {
|
6888
|
+
if (!Array.isArray(scalars))
|
6889
|
+
throw new Error('array of scalars expected');
|
6890
|
+
scalars.forEach((s, i) => {
|
6891
|
+
if (!field.isValid(s))
|
6892
|
+
throw new Error('invalid scalar at index ' + i);
|
6893
|
+
});
|
6894
|
+
}
|
6772
6895
|
// Since points in different groups cannot be equal (different object constructor),
|
6773
6896
|
// we can have single place to store precomputes
|
6774
6897
|
const pointPrecomputes = new WeakMap();
|
6775
6898
|
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6776
|
-
|
6777
|
-
|
6778
|
-
|
6779
|
-
|
6780
|
-
|
6781
|
-
|
6782
|
-
|
6783
|
-
|
6784
|
-
|
6785
|
-
|
6786
|
-
|
6899
|
+
function getW(P) {
|
6900
|
+
return pointWindowSizes.get(P) || 1;
|
6901
|
+
}
|
6902
|
+
/**
|
6903
|
+
* Elliptic curve multiplication of Point by scalar. Fragile.
|
6904
|
+
* Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
6905
|
+
* Creates precomputation tables for fast multiplication:
|
6906
|
+
* - private scalar is split by fixed size windows of W bits
|
6907
|
+
* - every window point is collected from window's table & added to accumulator
|
6908
|
+
* - since windows are different, same point inside tables won't be accessed more than once per calc
|
6909
|
+
* - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)
|
6910
|
+
* - +1 window is neccessary for wNAF
|
6911
|
+
* - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
|
6912
|
+
*
|
6913
|
+
* @todo Research returning 2d JS array of windows, instead of a single window.
|
6914
|
+
* This would allow windows to be in different memory locations
|
6915
|
+
*/
|
6787
6916
|
function wNAF(c, bits) {
|
6788
|
-
const constTimeNegate = (condition, item) => {
|
6789
|
-
const neg = item.negate();
|
6790
|
-
return condition ? neg : item;
|
6791
|
-
};
|
6792
|
-
const validateW = (W) => {
|
6793
|
-
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6794
|
-
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6795
|
-
};
|
6796
|
-
const opts = (W) => {
|
6797
|
-
validateW(W);
|
6798
|
-
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6799
|
-
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6800
|
-
return { windows, windowSize };
|
6801
|
-
};
|
6802
6917
|
return {
|
6803
6918
|
constTimeNegate,
|
6919
|
+
hasPrecomputes(elm) {
|
6920
|
+
return getW(elm) !== 1;
|
6921
|
+
},
|
6804
6922
|
// non-const time multiplication ladder
|
6805
|
-
unsafeLadder(elm, n) {
|
6806
|
-
let p = c.ZERO;
|
6923
|
+
unsafeLadder(elm, n, p = c.ZERO) {
|
6807
6924
|
let d = elm;
|
6808
6925
|
while (n > _0n$2) {
|
6809
6926
|
if (n & _1n$4)
|
@@ -6821,10 +6938,12 @@ function wNAF(c, bits) {
|
|
6821
6938
|
* - 𝑊 is the window size
|
6822
6939
|
* - 𝑛 is the bitlength of the curve order.
|
6823
6940
|
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
6941
|
+
* @param elm Point instance
|
6942
|
+
* @param W window size
|
6824
6943
|
* @returns precomputed point tables flattened to a single array
|
6825
6944
|
*/
|
6826
6945
|
precomputeWindow(elm, W) {
|
6827
|
-
const { windows, windowSize } =
|
6946
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6828
6947
|
const points = [];
|
6829
6948
|
let p = elm;
|
6830
6949
|
let base = p;
|
@@ -6850,7 +6969,7 @@ function wNAF(c, bits) {
|
|
6850
6969
|
wNAF(W, precomputes, n) {
|
6851
6970
|
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
6852
6971
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
6853
|
-
const { windows, windowSize } =
|
6972
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6854
6973
|
let p = c.ZERO;
|
6855
6974
|
let f = c.BASE;
|
6856
6975
|
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
@@ -6894,8 +7013,44 @@ function wNAF(c, bits) {
|
|
6894
7013
|
// which makes it less const-time: around 1 bigint multiply.
|
6895
7014
|
return { p, f };
|
6896
7015
|
},
|
6897
|
-
|
6898
|
-
|
7016
|
+
/**
|
7017
|
+
* Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
|
7018
|
+
* @param W window size
|
7019
|
+
* @param precomputes precomputed tables
|
7020
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
7021
|
+
* @param acc accumulator point to add result of multiplication
|
7022
|
+
* @returns point
|
7023
|
+
*/
|
7024
|
+
wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
|
7025
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
7026
|
+
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
7027
|
+
const maxNumber = 2 ** W;
|
7028
|
+
const shiftBy = BigInt(W);
|
7029
|
+
for (let window = 0; window < windows; window++) {
|
7030
|
+
const offset = window * windowSize;
|
7031
|
+
if (n === _0n$2)
|
7032
|
+
break; // No need to go over empty scalar
|
7033
|
+
// Extract W bits.
|
7034
|
+
let wbits = Number(n & mask);
|
7035
|
+
// Shift number by W bits.
|
7036
|
+
n >>= shiftBy;
|
7037
|
+
// If the bits are bigger than max size, we'll split those.
|
7038
|
+
// +224 => 256 - 32
|
7039
|
+
if (wbits > windowSize) {
|
7040
|
+
wbits -= maxNumber;
|
7041
|
+
n += _1n$4;
|
7042
|
+
}
|
7043
|
+
if (wbits === 0)
|
7044
|
+
continue;
|
7045
|
+
let curr = precomputes[offset + Math.abs(wbits) - 1]; // -1 because we skip zero
|
7046
|
+
if (wbits < 0)
|
7047
|
+
curr = curr.negate();
|
7048
|
+
// NOTE: by re-using acc, we can save a lot of additions in case of MSM
|
7049
|
+
acc = acc.add(curr);
|
7050
|
+
}
|
7051
|
+
return acc;
|
7052
|
+
},
|
7053
|
+
getPrecomputes(W, P, transform) {
|
6899
7054
|
// Calculate precomputes on a first run, reuse them after
|
6900
7055
|
let comp = pointPrecomputes.get(P);
|
6901
7056
|
if (!comp) {
|
@@ -6903,62 +7058,66 @@ function wNAF(c, bits) {
|
|
6903
7058
|
if (W !== 1)
|
6904
7059
|
pointPrecomputes.set(P, transform(comp));
|
6905
7060
|
}
|
6906
|
-
return
|
7061
|
+
return comp;
|
7062
|
+
},
|
7063
|
+
wNAFCached(P, n, transform) {
|
7064
|
+
const W = getW(P);
|
7065
|
+
return this.wNAF(W, this.getPrecomputes(W, P, transform), n);
|
7066
|
+
},
|
7067
|
+
wNAFCachedUnsafe(P, n, transform, prev) {
|
7068
|
+
const W = getW(P);
|
7069
|
+
if (W === 1)
|
7070
|
+
return this.unsafeLadder(P, n, prev); // For W=1 ladder is ~x2 faster
|
7071
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, P, transform), n, prev);
|
6907
7072
|
},
|
6908
7073
|
// We calculate precomputes for elliptic curve point multiplication
|
6909
7074
|
// using windowed method. This specifies window size and
|
6910
7075
|
// stores precomputed values. Usually only base point would be precomputed.
|
6911
7076
|
setWindowSize(P, W) {
|
6912
|
-
validateW(W);
|
7077
|
+
validateW(W, bits);
|
6913
7078
|
pointWindowSizes.set(P, W);
|
6914
7079
|
pointPrecomputes.delete(P);
|
6915
7080
|
},
|
6916
7081
|
};
|
6917
7082
|
}
|
6918
7083
|
/**
|
6919
|
-
* Pippenger algorithm for multi-scalar multiplication (MSM).
|
6920
|
-
* MSM is basically (Pa + Qb + Rc + ...).
|
7084
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
6921
7085
|
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
6922
7086
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
6923
7087
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
6924
7088
|
* @param c Curve Point constructor
|
6925
|
-
* @param
|
7089
|
+
* @param fieldN field over CURVE.N - important that it's not over CURVE.P
|
6926
7090
|
* @param points array of L curve points
|
6927
7091
|
* @param scalars array of L scalars (aka private keys / bigints)
|
6928
7092
|
*/
|
6929
|
-
function pippenger(c,
|
7093
|
+
function pippenger(c, fieldN, points, scalars) {
|
6930
7094
|
// If we split scalars by some window (let's say 8 bits), every chunk will only
|
6931
7095
|
// take 256 buckets even if there are 4096 scalars, also re-uses double.
|
6932
7096
|
// TODO:
|
6933
7097
|
// - https://eprint.iacr.org/2024/750.pdf
|
6934
7098
|
// - https://tches.iacr.org/index.php/TCHES/article/view/10287
|
6935
7099
|
// 0 is accepted in scalars
|
6936
|
-
|
7100
|
+
validateMSMPoints(points, c);
|
7101
|
+
validateMSMScalars(scalars, fieldN);
|
7102
|
+
if (points.length !== scalars.length)
|
6937
7103
|
throw new Error('arrays of points and scalars must have equal length');
|
6938
|
-
|
6939
|
-
if (!field.isValid(s))
|
6940
|
-
throw new Error(`wrong scalar at index ${i}`);
|
6941
|
-
});
|
6942
|
-
points.forEach((p, i) => {
|
6943
|
-
if (!(p instanceof c))
|
6944
|
-
throw new Error(`wrong point at index ${i}`);
|
6945
|
-
});
|
7104
|
+
const zero = c.ZERO;
|
6946
7105
|
const wbits = bitLen(BigInt(points.length));
|
6947
7106
|
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
6948
7107
|
const MASK = (1 << windowSize) - 1;
|
6949
|
-
const buckets = new Array(MASK + 1).fill(
|
6950
|
-
const lastBits = Math.floor((
|
6951
|
-
let sum =
|
7108
|
+
const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
|
7109
|
+
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
7110
|
+
let sum = zero;
|
6952
7111
|
for (let i = lastBits; i >= 0; i -= windowSize) {
|
6953
|
-
buckets.fill(
|
7112
|
+
buckets.fill(zero);
|
6954
7113
|
for (let j = 0; j < scalars.length; j++) {
|
6955
7114
|
const scalar = scalars[j];
|
6956
7115
|
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
6957
7116
|
buckets[wbits] = buckets[wbits].add(points[j]);
|
6958
7117
|
}
|
6959
|
-
let resI =
|
7118
|
+
let resI = zero; // not using this will do small speed-up, but will lose ct
|
6960
7119
|
// Skip first bucket, because it is zero
|
6961
|
-
for (let j = buckets.length - 1, sumI =
|
7120
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
6962
7121
|
sumI = sumI.add(buckets[j]);
|
6963
7122
|
resI = resI.add(sumI);
|
6964
7123
|
}
|
@@ -6988,8 +7147,12 @@ function validateBasic(curve) {
|
|
6988
7147
|
});
|
6989
7148
|
}
|
6990
7149
|
|
7150
|
+
/**
|
7151
|
+
* Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y².
|
7152
|
+
* For design rationale of types / exports, see weierstrass module documentation.
|
7153
|
+
* @module
|
7154
|
+
*/
|
6991
7155
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6992
|
-
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
6993
7156
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
6994
7157
|
// prettier-ignore
|
6995
7158
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -7021,6 +7184,10 @@ function validateOpts$1(curve) {
|
|
7021
7184
|
function twistedEdwards(curveDef) {
|
7022
7185
|
const CURVE = validateOpts$1(curveDef);
|
7023
7186
|
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
7187
|
+
// Important:
|
7188
|
+
// There are some places where Fp.BYTES is used instead of nByteLength.
|
7189
|
+
// So far, everything has been tested with curves of Fp.BYTES == nByteLength.
|
7190
|
+
// TODO: test and find curves which behave otherwise.
|
7024
7191
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
7025
7192
|
const modP = Fp.create; // Function overrides
|
7026
7193
|
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
@@ -7234,16 +7401,15 @@ function twistedEdwards(curveDef) {
|
|
7234
7401
|
// It's faster, but should only be used when you don't care about
|
7235
7402
|
// an exposed private key e.g. sig verification.
|
7236
7403
|
// Does NOT allow scalars higher than CURVE.n.
|
7237
|
-
|
7404
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
7405
|
+
multiplyUnsafe(scalar, acc = Point.ZERO) {
|
7238
7406
|
const n = scalar;
|
7239
7407
|
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7240
7408
|
if (n === _0n$1)
|
7241
7409
|
return I;
|
7242
|
-
if (this.
|
7410
|
+
if (this.is0() || n === _1n$3)
|
7243
7411
|
return this;
|
7244
|
-
|
7245
|
-
return this.wNAF(n).p;
|
7246
|
-
return wnaf.unsafeLadder(this, n);
|
7412
|
+
return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
|
7247
7413
|
}
|
7248
7414
|
// Checks if point is of small order.
|
7249
7415
|
// If you add something to small order point, you will have "dirty"
|
@@ -7277,8 +7443,9 @@ function twistedEdwards(curveDef) {
|
|
7277
7443
|
abool('zip215', zip215);
|
7278
7444
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7279
7445
|
const lastByte = hex[len - 1]; // select last byte
|
7280
|
-
normed[len - 1] = lastByte &
|
7446
|
+
normed[len - 1] = lastByte & -129; // clear last bit
|
7281
7447
|
const y = bytesToNumberLE(normed);
|
7448
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7282
7449
|
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7283
7450
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7284
7451
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
@@ -7327,7 +7494,7 @@ function twistedEdwards(curveDef) {
|
|
7327
7494
|
}
|
7328
7495
|
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
7329
7496
|
function getExtendedPublicKey(key) {
|
7330
|
-
const len =
|
7497
|
+
const len = Fp.BYTES;
|
7331
7498
|
key = ensureBytes('private key', key, len);
|
7332
7499
|
// Hash private key with curve's hash function to produce uniformingly random input
|
7333
7500
|
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
@@ -7360,23 +7527,29 @@ function twistedEdwards(curveDef) {
|
|
7360
7527
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7361
7528
|
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7362
7529
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7363
|
-
return ensureBytes('result', res,
|
7530
|
+
return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
|
7364
7531
|
}
|
7365
7532
|
const verifyOpts = VERIFY_DEFAULT;
|
7533
|
+
/**
|
7534
|
+
* Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7535
|
+
* An extended group equation is checked.
|
7536
|
+
*/
|
7366
7537
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
7367
7538
|
const { context, zip215 } = options;
|
7368
7539
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7369
7540
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7370
7541
|
msg = ensureBytes('message', msg);
|
7542
|
+
publicKey = ensureBytes('publicKey', publicKey, len);
|
7371
7543
|
if (zip215 !== undefined)
|
7372
7544
|
abool('zip215', zip215);
|
7373
7545
|
if (prehash)
|
7374
7546
|
msg = prehash(msg); // for ed25519ph, etc
|
7375
7547
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
7376
|
-
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
7377
|
-
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
7378
7548
|
let A, R, SB;
|
7379
7549
|
try {
|
7550
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7551
|
+
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7552
|
+
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
7380
7553
|
A = Point.fromHex(publicKey, zip215);
|
7381
7554
|
R = Point.fromHex(sig.slice(0, len), zip215);
|
7382
7555
|
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
@@ -7388,6 +7561,7 @@ function twistedEdwards(curveDef) {
|
|
7388
7561
|
return false;
|
7389
7562
|
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
7390
7563
|
const RkA = R.add(A.multiplyUnsafe(k));
|
7564
|
+
// Extended group equation
|
7391
7565
|
// [8][S]B = [8]R + [8][k]A'
|
7392
7566
|
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
7393
7567
|
}
|
@@ -7418,13 +7592,14 @@ function twistedEdwards(curveDef) {
|
|
7418
7592
|
};
|
7419
7593
|
}
|
7420
7594
|
|
7421
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7422
7595
|
/**
|
7423
7596
|
* ed25519 Twisted Edwards curve with following addons:
|
7424
7597
|
* - X25519 ECDH
|
7425
7598
|
* - Ristretto cofactor elimination
|
7426
7599
|
* - Elligator hash-to-group / point indistinguishability
|
7600
|
+
* @module
|
7427
7601
|
*/
|
7602
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7428
7603
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7429
7604
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7430
7605
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
@@ -7483,7 +7658,7 @@ function uvRatio(u, v) {
|
|
7483
7658
|
x = mod(-x, P);
|
7484
7659
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7485
7660
|
}
|
7486
|
-
const Fp
|
7661
|
+
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7487
7662
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7488
7663
|
// Param: a
|
7489
7664
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
@@ -7491,7 +7666,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7491
7666
|
// Negative number is P - number, and division is invert(number, P)
|
7492
7667
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
7493
7668
|
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
7494
|
-
Fp
|
7669
|
+
Fp,
|
7495
7670
|
// Subgroup order: how many points curve has
|
7496
7671
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7497
7672
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
@@ -7510,6 +7685,14 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7510
7685
|
}))();
|
7511
7686
|
/**
|
7512
7687
|
* ed25519 curve with EdDSA signatures.
|
7688
|
+
* @example
|
7689
|
+
* import { ed25519 } from '@noble/curves/ed25519';
|
7690
|
+
* const priv = ed25519.utils.randomPrivateKey();
|
7691
|
+
* const pub = ed25519.getPublicKey(priv);
|
7692
|
+
* const msg = new TextEncoder().encode('hello');
|
7693
|
+
* const sig = ed25519.sign(msg, priv);
|
7694
|
+
* ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
|
7695
|
+
* ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
|
7513
7696
|
*/
|
7514
7697
|
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7515
7698
|
|
@@ -8883,7 +9066,7 @@ var PrivateKey;
|
|
8883
9066
|
/*!
|
8884
9067
|
* MIT License
|
8885
9068
|
*
|
8886
|
-
* Copyright (c) 2017-
|
9069
|
+
* Copyright (c) 2017-2024 Peculiar Ventures, LLC
|
8887
9070
|
*
|
8888
9071
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
8889
9072
|
* of this software and associated documentation files (the "Software"), to deal
|
@@ -8995,7 +9178,7 @@ class BufferSourceConverter {
|
|
8995
9178
|
}
|
8996
9179
|
|
8997
9180
|
const STRING_TYPE = "string";
|
8998
|
-
const HEX_REGEX = /^[0-9a-f]+$/i;
|
9181
|
+
const HEX_REGEX = /^[0-9a-f\s]+$/i;
|
8999
9182
|
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
9000
9183
|
const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
|
9001
9184
|
class Utf8Converter {
|
@@ -9229,7 +9412,7 @@ class Convert {
|
|
9229
9412
|
return base64;
|
9230
9413
|
}
|
9231
9414
|
static formatString(data) {
|
9232
|
-
return (data === null || data ===
|
9415
|
+
return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
|
9233
9416
|
}
|
9234
9417
|
}
|
9235
9418
|
Convert.DEFAULT_UTF8_ENCODING = "utf8";
|
@@ -9485,7 +9668,7 @@ function HexBlock(BaseClass) {
|
|
9485
9668
|
var _a;
|
9486
9669
|
super(...args);
|
9487
9670
|
const params = args[0] || {};
|
9488
|
-
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !==
|
9671
|
+
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9489
9672
|
this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
9490
9673
|
}
|
9491
9674
|
get valueHex() {
|
@@ -9575,11 +9758,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
|
|
9575
9758
|
var _a, _b, _c, _d;
|
9576
9759
|
super();
|
9577
9760
|
if (idBlock) {
|
9578
|
-
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !==
|
9761
|
+
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9579
9762
|
this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
|
9580
|
-
this.tagClass = (_b = idBlock.tagClass) !== null && _b !==
|
9581
|
-
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !==
|
9582
|
-
this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !==
|
9763
|
+
this.tagClass = (_b = idBlock.tagClass) !== null && _b !== undefined ? _b : -1;
|
9764
|
+
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== undefined ? _c : -1;
|
9765
|
+
this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== undefined ? _d : false;
|
9583
9766
|
}
|
9584
9767
|
else {
|
9585
9768
|
this.tagClass = -1;
|
@@ -9746,9 +9929,9 @@ class LocalLengthBlock extends LocalBaseBlock {
|
|
9746
9929
|
constructor({ lenBlock = {}, } = {}) {
|
9747
9930
|
var _a, _b, _c;
|
9748
9931
|
super();
|
9749
|
-
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !==
|
9750
|
-
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !==
|
9751
|
-
this.length = (_c = lenBlock.length) !== null && _c !==
|
9932
|
+
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== undefined ? _a : false;
|
9933
|
+
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== undefined ? _b : false;
|
9934
|
+
this.length = (_c = lenBlock.length) !== null && _c !== undefined ? _c : 0;
|
9752
9935
|
}
|
9753
9936
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
9754
9937
|
const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
|
@@ -10520,7 +10703,7 @@ var _a$r;
|
|
10520
10703
|
class OctetString extends BaseBlock {
|
10521
10704
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
10522
10705
|
var _b, _c;
|
10523
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10706
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
10524
10707
|
super({
|
10525
10708
|
idBlock: {
|
10526
10709
|
isConstructed: parameters.isConstructed,
|
@@ -10681,7 +10864,7 @@ var _a$q;
|
|
10681
10864
|
class BitString extends BaseBlock {
|
10682
10865
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
10683
10866
|
var _b, _c;
|
10684
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10867
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
10685
10868
|
super({
|
10686
10869
|
idBlock: {
|
10687
10870
|
isConstructed: parameters.isConstructed,
|
@@ -11883,7 +12066,7 @@ class GeneralizedTime extends UTCTime {
|
|
11883
12066
|
constructor(parameters = {}) {
|
11884
12067
|
var _b;
|
11885
12068
|
super(parameters);
|
11886
|
-
(_b = this.millisecond) !== null && _b !==
|
12069
|
+
(_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
|
11887
12070
|
this.idBlock.tagClass = 1;
|
11888
12071
|
this.idBlock.tagNumber = 24;
|
11889
12072
|
}
|
@@ -12234,8 +12417,8 @@ function pkixToJwk(bytes) {
|
|
12234
12417
|
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12235
12418
|
return {
|
12236
12419
|
kty: 'RSA',
|
12237
|
-
n:
|
12238
|
-
e:
|
12420
|
+
n: asn1jsIntegerToBase64(values[0]),
|
12421
|
+
e: asn1jsIntegerToBase64(values[1])
|
12239
12422
|
};
|
12240
12423
|
}
|
12241
12424
|
/**
|
@@ -12271,21 +12454,13 @@ function jwkToPkix(jwk) {
|
|
12271
12454
|
const der = root.toBER();
|
12272
12455
|
return new Uint8Array(der, 0, der.byteLength);
|
12273
12456
|
}
|
12274
|
-
function
|
12275
|
-
let
|
12276
|
-
|
12277
|
-
|
12457
|
+
function asn1jsIntegerToBase64(int) {
|
12458
|
+
let buf = int.valueBlock.valueHexView;
|
12459
|
+
// chrome rejects values with leading 0s
|
12460
|
+
while (buf[0] === 0) {
|
12461
|
+
buf = buf.subarray(1);
|
12278
12462
|
}
|
12279
|
-
|
12280
|
-
const u8 = new Uint8Array(len);
|
12281
|
-
let i = 0;
|
12282
|
-
let j = 0;
|
12283
|
-
while (i < len) {
|
12284
|
-
u8[i] = parseInt(hex.slice(j, j + 2), 16);
|
12285
|
-
i += 1;
|
12286
|
-
j += 2;
|
12287
|
-
}
|
12288
|
-
return u8;
|
12463
|
+
return toString$1(buf, 'base64url');
|
12289
12464
|
}
|
12290
12465
|
function bufToBn(u8) {
|
12291
12466
|
const hex = [];
|
@@ -12314,15 +12489,18 @@ function pkixToRSAPublicKey(bytes) {
|
|
12314
12489
|
return new RSAPublicKey(jwk, digest);
|
12315
12490
|
}
|
12316
12491
|
|
12317
|
-
|
12492
|
+
/**
|
12493
|
+
* HMAC: RFC2104 message authentication code.
|
12494
|
+
* @module
|
12495
|
+
*/
|
12318
12496
|
class HMAC extends Hash {
|
12319
|
-
constructor(hash
|
12497
|
+
constructor(hash, _key) {
|
12320
12498
|
super();
|
12321
12499
|
this.finished = false;
|
12322
12500
|
this.destroyed = false;
|
12323
|
-
|
12501
|
+
ahash(hash);
|
12324
12502
|
const key = toBytes$1(_key);
|
12325
|
-
this.iHash = hash
|
12503
|
+
this.iHash = hash.create();
|
12326
12504
|
if (typeof this.iHash.update !== 'function')
|
12327
12505
|
throw new Error('Expected instance of class which extends utils.Hash');
|
12328
12506
|
this.blockLen = this.iHash.blockLen;
|
@@ -12330,12 +12508,12 @@ class HMAC extends Hash {
|
|
12330
12508
|
const blockLen = this.blockLen;
|
12331
12509
|
const pad = new Uint8Array(blockLen);
|
12332
12510
|
// blockLen can be bigger than outputLen
|
12333
|
-
pad.set(key.length > blockLen ? hash
|
12511
|
+
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
12334
12512
|
for (let i = 0; i < pad.length; i++)
|
12335
12513
|
pad[i] ^= 0x36;
|
12336
12514
|
this.iHash.update(pad);
|
12337
12515
|
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
12338
|
-
this.oHash = hash
|
12516
|
+
this.oHash = hash.create();
|
12339
12517
|
// Undo internal XOR && apply outer XOR
|
12340
12518
|
for (let i = 0; i < pad.length; i++)
|
12341
12519
|
pad[i] ^= 0x36 ^ 0x5c;
|
@@ -12343,13 +12521,13 @@ class HMAC extends Hash {
|
|
12343
12521
|
pad.fill(0);
|
12344
12522
|
}
|
12345
12523
|
update(buf) {
|
12346
|
-
|
12524
|
+
aexists(this);
|
12347
12525
|
this.iHash.update(buf);
|
12348
12526
|
return this;
|
12349
12527
|
}
|
12350
12528
|
digestInto(out) {
|
12351
|
-
|
12352
|
-
|
12529
|
+
aexists(this);
|
12530
|
+
abytes$1(out, this.outputLen);
|
12353
12531
|
this.finished = true;
|
12354
12532
|
this.iHash.digestInto(out);
|
12355
12533
|
this.oHash.update(out);
|
@@ -12393,8 +12571,33 @@ class HMAC extends Hash {
|
|
12393
12571
|
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
12394
12572
|
hmac.create = (hash, key) => new HMAC(hash, key);
|
12395
12573
|
|
12574
|
+
/**
|
12575
|
+
* Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
|
12576
|
+
*
|
12577
|
+
* ### Design rationale for types
|
12578
|
+
*
|
12579
|
+
* * Interaction between classes from different curves should fail:
|
12580
|
+
* `k256.Point.BASE.add(p256.Point.BASE)`
|
12581
|
+
* * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
|
12582
|
+
* * Different calls of `curve()` would return different classes -
|
12583
|
+
* `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
|
12584
|
+
* it won't affect others
|
12585
|
+
*
|
12586
|
+
* TypeScript can't infer types for classes created inside a function. Classes is one instance
|
12587
|
+
* of nominative types in TypeScript and interfaces only check for shape, so it's hard to create
|
12588
|
+
* unique type for every function call.
|
12589
|
+
*
|
12590
|
+
* We can use generic types via some param, like curve opts, but that would:
|
12591
|
+
* 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
|
12592
|
+
* which is hard to debug.
|
12593
|
+
* 2. Params can be generic and we can't enforce them to be constant value:
|
12594
|
+
* if somebody creates curve from non-constant params,
|
12595
|
+
* it would be allowed to interact with other curves with non-constant params
|
12596
|
+
*
|
12597
|
+
* @todo https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
|
12598
|
+
* @module
|
12599
|
+
*/
|
12396
12600
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
12397
|
-
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
12398
12601
|
function validateSigVerOpts(opts) {
|
12399
12602
|
if (opts.lowS !== undefined)
|
12400
12603
|
abool('lowS', opts.lowS);
|
@@ -12418,17 +12621,22 @@ function validatePointOpts(curve) {
|
|
12418
12621
|
const { endo, Fp, a } = opts;
|
12419
12622
|
if (endo) {
|
12420
12623
|
if (!Fp.eql(a, Fp.ZERO)) {
|
12421
|
-
throw new Error('
|
12624
|
+
throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
|
12422
12625
|
}
|
12423
12626
|
if (typeof endo !== 'object' ||
|
12424
12627
|
typeof endo.beta !== 'bigint' ||
|
12425
12628
|
typeof endo.splitScalar !== 'function') {
|
12426
|
-
throw new Error('
|
12629
|
+
throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
|
12427
12630
|
}
|
12428
12631
|
}
|
12429
12632
|
return Object.freeze({ ...opts });
|
12430
12633
|
}
|
12431
12634
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
12635
|
+
class DERErr extends Error {
|
12636
|
+
constructor(m = '') {
|
12637
|
+
super(m);
|
12638
|
+
}
|
12639
|
+
}
|
12432
12640
|
/**
|
12433
12641
|
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
12434
12642
|
*
|
@@ -12438,11 +12646,7 @@ const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
|
12438
12646
|
*/
|
12439
12647
|
const DER = {
|
12440
12648
|
// asn.1 DER encoding utils
|
12441
|
-
Err:
|
12442
|
-
constructor(m = '') {
|
12443
|
-
super(m);
|
12444
|
-
}
|
12445
|
-
},
|
12649
|
+
Err: DERErr,
|
12446
12650
|
// Basic building block is TLV (Tag-Length-Value)
|
12447
12651
|
_tlv: {
|
12448
12652
|
encode: (tag, data) => {
|
@@ -12457,7 +12661,8 @@ const DER = {
|
|
12457
12661
|
throw new E('tlv.encode: long form length too big');
|
12458
12662
|
// length of length with long form flag
|
12459
12663
|
const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
|
12460
|
-
|
12664
|
+
const t = numberToHexUnpadded(tag);
|
12665
|
+
return t + lenLen + len + data;
|
12461
12666
|
},
|
12462
12667
|
// v - value, l - left bytes (unparsed)
|
12463
12668
|
decode(tag, data) {
|
@@ -12510,15 +12715,15 @@ const DER = {
|
|
12510
12715
|
if (Number.parseInt(hex[0], 16) & 0b1000)
|
12511
12716
|
hex = '00' + hex;
|
12512
12717
|
if (hex.length & 1)
|
12513
|
-
throw new E('unexpected assertion');
|
12718
|
+
throw new E('unexpected DER parsing assertion: unpadded hex');
|
12514
12719
|
return hex;
|
12515
12720
|
},
|
12516
12721
|
decode(data) {
|
12517
12722
|
const { Err: E } = DER;
|
12518
12723
|
if (data[0] & 128)
|
12519
|
-
throw new E('
|
12724
|
+
throw new E('invalid signature integer: negative');
|
12520
12725
|
if (data[0] === 0x00 && !(data[1] & 128))
|
12521
|
-
throw new E('
|
12726
|
+
throw new E('invalid signature integer: unnecessary leading zero');
|
12522
12727
|
return b2n(data);
|
12523
12728
|
},
|
12524
12729
|
},
|
@@ -12529,16 +12734,18 @@ const DER = {
|
|
12529
12734
|
abytes(data);
|
12530
12735
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
12531
12736
|
if (seqLeftBytes.length)
|
12532
|
-
throw new E('
|
12737
|
+
throw new E('invalid signature: left bytes after parsing');
|
12533
12738
|
const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
|
12534
12739
|
const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
|
12535
12740
|
if (sLeftBytes.length)
|
12536
|
-
throw new E('
|
12741
|
+
throw new E('invalid signature: left bytes after parsing');
|
12537
12742
|
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
12538
12743
|
},
|
12539
12744
|
hexFromSig(sig) {
|
12540
12745
|
const { _tlv: tlv, _int: int } = DER;
|
12541
|
-
const
|
12746
|
+
const rs = tlv.encode(0x02, int.encode(sig.r));
|
12747
|
+
const ss = tlv.encode(0x02, int.encode(sig.s));
|
12748
|
+
const seq = rs + ss;
|
12542
12749
|
return tlv.encode(0x30, seq);
|
12543
12750
|
},
|
12544
12751
|
};
|
@@ -12592,7 +12799,7 @@ function weierstrassPoints(opts) {
|
|
12592
12799
|
key = bytesToHex(key);
|
12593
12800
|
// Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
|
12594
12801
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
12595
|
-
throw new Error('
|
12802
|
+
throw new Error('invalid private key');
|
12596
12803
|
key = key.padStart(nByteLength * 2, '0');
|
12597
12804
|
}
|
12598
12805
|
let num;
|
@@ -12603,7 +12810,7 @@ function weierstrassPoints(opts) {
|
|
12603
12810
|
: bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
12604
12811
|
}
|
12605
12812
|
catch (error) {
|
12606
|
-
throw new Error(
|
12813
|
+
throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
|
12607
12814
|
}
|
12608
12815
|
if (wrapPrivateKey)
|
12609
12816
|
num = mod(num, N); // disabled by default, enabled for BLS
|
@@ -12643,7 +12850,7 @@ function weierstrassPoints(opts) {
|
|
12643
12850
|
if (p.is0()) {
|
12644
12851
|
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
12645
12852
|
// In BLS, ZERO can be serialized, so we allow it.
|
12646
|
-
// (0, 0, 0) is
|
12853
|
+
// (0, 0, 0) is invalid representation of ZERO.
|
12647
12854
|
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
12648
12855
|
return;
|
12649
12856
|
throw new Error('bad point: ZERO');
|
@@ -12867,16 +13074,17 @@ function weierstrassPoints(opts) {
|
|
12867
13074
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
12868
13075
|
*/
|
12869
13076
|
multiplyUnsafe(sc) {
|
12870
|
-
|
13077
|
+
const { endo, n: N } = CURVE;
|
13078
|
+
aInRange('scalar', sc, _0n, N);
|
12871
13079
|
const I = Point.ZERO;
|
12872
13080
|
if (sc === _0n)
|
12873
13081
|
return I;
|
12874
|
-
if (sc === _1n$1)
|
13082
|
+
if (this.is0() || sc === _1n$1)
|
12875
13083
|
return this;
|
12876
|
-
|
12877
|
-
if (!endo)
|
12878
|
-
return wnaf.
|
12879
|
-
//
|
13084
|
+
// Case a: no endomorphism. Case b: has precomputes.
|
13085
|
+
if (!endo || wnaf.hasPrecomputes(this))
|
13086
|
+
return wnaf.wNAFCachedUnsafe(this, sc, Point.normalizeZ);
|
13087
|
+
// Case c: endomorphism
|
12880
13088
|
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
12881
13089
|
let k1p = I;
|
12882
13090
|
let k2p = I;
|
@@ -13062,7 +13270,9 @@ function weierstrass(curveDef) {
|
|
13062
13270
|
return { x, y };
|
13063
13271
|
}
|
13064
13272
|
else {
|
13065
|
-
|
13273
|
+
const cl = compressedLen;
|
13274
|
+
const ul = uncompressedLen;
|
13275
|
+
throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
|
13066
13276
|
}
|
13067
13277
|
},
|
13068
13278
|
});
|
@@ -13227,6 +13437,9 @@ function weierstrass(curveDef) {
|
|
13227
13437
|
// int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
|
13228
13438
|
const bits2int = CURVE.bits2int ||
|
13229
13439
|
function (bytes) {
|
13440
|
+
// Our custom check "just in case"
|
13441
|
+
if (bytes.length > 8192)
|
13442
|
+
throw new Error('input is too large');
|
13230
13443
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
13231
13444
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
13232
13445
|
const num = bytesToNumberBE(bytes); // check for == u8 done here
|
@@ -13243,15 +13456,15 @@ function weierstrass(curveDef) {
|
|
13243
13456
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13244
13457
|
*/
|
13245
13458
|
function int2octets(num) {
|
13246
|
-
aInRange(
|
13459
|
+
aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
13247
13460
|
// works with order, can have different size than numToField!
|
13248
13461
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13249
13462
|
}
|
13250
13463
|
// Steps A, D of RFC6979 3.2
|
13251
13464
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
13252
13465
|
// Used only in sign, not in verify.
|
13253
|
-
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13254
|
-
// Also it can be bigger for P224 + SHA256
|
13466
|
+
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13467
|
+
// this will be invalid at least for P521. Also it can be bigger for P224 + SHA256
|
13255
13468
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
13256
13469
|
if (['recovered', 'canonical'].some((k) => k in opts))
|
13257
13470
|
throw new Error('sign() legacy options not supported');
|
@@ -13345,39 +13558,48 @@ function weierstrass(curveDef) {
|
|
13345
13558
|
const sg = signature;
|
13346
13559
|
msgHash = ensureBytes('msgHash', msgHash);
|
13347
13560
|
publicKey = ensureBytes('publicKey', publicKey);
|
13561
|
+
const { lowS, prehash, format } = opts;
|
13562
|
+
// Verify opts, deduce signature format
|
13563
|
+
validateSigVerOpts(opts);
|
13348
13564
|
if ('strict' in opts)
|
13349
13565
|
throw new Error('options.strict was renamed to lowS');
|
13350
|
-
|
13351
|
-
|
13566
|
+
if (format !== undefined && format !== 'compact' && format !== 'der')
|
13567
|
+
throw new Error('format must be compact or der');
|
13568
|
+
const isHex = typeof sg === 'string' || isBytes$1(sg);
|
13569
|
+
const isObj = !isHex &&
|
13570
|
+
!format &&
|
13571
|
+
typeof sg === 'object' &&
|
13572
|
+
sg !== null &&
|
13573
|
+
typeof sg.r === 'bigint' &&
|
13574
|
+
typeof sg.s === 'bigint';
|
13575
|
+
if (!isHex && !isObj)
|
13576
|
+
throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
|
13352
13577
|
let _sig = undefined;
|
13353
13578
|
let P;
|
13354
13579
|
try {
|
13355
|
-
if (
|
13580
|
+
if (isObj)
|
13581
|
+
_sig = new Signature(sg.r, sg.s);
|
13582
|
+
if (isHex) {
|
13356
13583
|
// Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
|
13357
13584
|
// Since DER can also be 2*nByteLength bytes, we check for it first.
|
13358
13585
|
try {
|
13359
|
-
|
13586
|
+
if (format !== 'compact')
|
13587
|
+
_sig = Signature.fromDER(sg);
|
13360
13588
|
}
|
13361
13589
|
catch (derError) {
|
13362
13590
|
if (!(derError instanceof DER.Err))
|
13363
13591
|
throw derError;
|
13364
|
-
_sig = Signature.fromCompact(sg);
|
13365
13592
|
}
|
13366
|
-
|
13367
|
-
|
13368
|
-
const { r, s } = sg;
|
13369
|
-
_sig = new Signature(r, s);
|
13370
|
-
}
|
13371
|
-
else {
|
13372
|
-
throw new Error('PARSE');
|
13593
|
+
if (!_sig && format !== 'der')
|
13594
|
+
_sig = Signature.fromCompact(sg);
|
13373
13595
|
}
|
13374
13596
|
P = Point.fromHex(publicKey);
|
13375
13597
|
}
|
13376
13598
|
catch (error) {
|
13377
|
-
if (error.message === 'PARSE')
|
13378
|
-
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
13379
13599
|
return false;
|
13380
13600
|
}
|
13601
|
+
if (!_sig)
|
13602
|
+
return false;
|
13381
13603
|
if (lowS && _sig.hasHighS())
|
13382
13604
|
return false;
|
13383
13605
|
if (prehash)
|
@@ -13405,8 +13627,12 @@ function weierstrass(curveDef) {
|
|
13405
13627
|
};
|
13406
13628
|
}
|
13407
13629
|
|
13630
|
+
/**
|
13631
|
+
* Utilities for short weierstrass curves, combined with noble-hashes.
|
13632
|
+
* @module
|
13633
|
+
*/
|
13408
13634
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13409
|
-
|
13635
|
+
/** connects noble-curves to noble-hashes */
|
13410
13636
|
function getHash(hash) {
|
13411
13637
|
return {
|
13412
13638
|
hash,
|
@@ -13416,9 +13642,21 @@ function getHash(hash) {
|
|
13416
13642
|
}
|
13417
13643
|
function createCurve(curveDef, defHash) {
|
13418
13644
|
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
13419
|
-
return
|
13645
|
+
return { ...create(defHash), create };
|
13420
13646
|
}
|
13421
13647
|
|
13648
|
+
/**
|
13649
|
+
* NIST secp256k1. See [pdf](https://www.secg.org/sec2-v2.pdf).
|
13650
|
+
*
|
13651
|
+
* Seems to be rigid (not backdoored)
|
13652
|
+
* [as per discussion](https://bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975).
|
13653
|
+
*
|
13654
|
+
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
13655
|
+
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
13656
|
+
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
13657
|
+
* [See explanation](https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066).
|
13658
|
+
* @module
|
13659
|
+
*/
|
13422
13660
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13423
13661
|
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
13424
13662
|
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
@@ -13449,31 +13687,35 @@ function sqrtMod(y) {
|
|
13449
13687
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
13450
13688
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
13451
13689
|
const root = pow2(t2, _2n, P);
|
13452
|
-
if (!
|
13690
|
+
if (!Fpk1.eql(Fpk1.sqr(root), y))
|
13453
13691
|
throw new Error('Cannot find square root');
|
13454
13692
|
return root;
|
13455
13693
|
}
|
13456
|
-
const
|
13694
|
+
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
13457
13695
|
/**
|
13458
13696
|
* secp256k1 short weierstrass curve and ECDSA signatures over it.
|
13697
|
+
*
|
13698
|
+
* @example
|
13699
|
+
* import { secp256k1 } from '@noble/curves/secp256k1';
|
13700
|
+
*
|
13701
|
+
* const priv = secp256k1.utils.randomPrivateKey();
|
13702
|
+
* const pub = secp256k1.getPublicKey(priv);
|
13703
|
+
* const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
|
13704
|
+
* const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
|
13705
|
+
* const isValid = secp256k1.verify(sig, msg, pub) === true;
|
13459
13706
|
*/
|
13460
13707
|
const secp256k1 = createCurve({
|
13461
13708
|
a: BigInt(0), // equation params: a, b
|
13462
|
-
b: BigInt(7),
|
13463
|
-
Fp, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
13709
|
+
b: BigInt(7),
|
13710
|
+
Fp: Fpk1, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
13464
13711
|
n: secp256k1N, // Curve order, total count of valid points in the field
|
13465
13712
|
// Base point (x, y) aka generator point
|
13466
13713
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
13467
13714
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
13468
13715
|
h: BigInt(1), // Cofactor
|
13469
13716
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
13470
|
-
/**
|
13471
|
-
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
13472
|
-
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
13473
|
-
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
13474
|
-
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
13475
|
-
*/
|
13476
13717
|
endo: {
|
13718
|
+
// Endomorphism, see above
|
13477
13719
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
13478
13720
|
splitScalar: (k) => {
|
13479
13721
|
const n = secp256k1N;
|