@waku/enr 0.0.27 → 0.0.28-09108d9.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 +983 -1558
- package/dist/.tsbuildinfo +1 -1
- package/dist/creator.d.ts +1 -1
- package/dist/creator.js +1 -2
- package/dist/creator.js.map +1 -1
- package/dist/decoder.js +1 -1
- package/dist/decoder.js.map +1 -1
- package/dist/enr.d.ts +1 -1
- package/dist/enr.js +2 -2
- package/dist/enr.js.map +1 -1
- package/dist/peer_id.d.ts +3 -4
- package/dist/peer_id.js +7 -24
- package/dist/peer_id.js.map +1 -1
- package/package.json +1 -99
- package/src/creator.ts +2 -3
- package/src/decoder.ts +1 -1
- package/src/enr.ts +3 -3
- package/src/peer_id.ts +9 -34
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
|
@@ -745,7 +745,7 @@ function encodingLength$1(int) {
|
|
745
745
|
/**
|
746
746
|
* Creates a multihash digest.
|
747
747
|
*/
|
748
|
-
function create
|
748
|
+
function create(code, digest) {
|
749
749
|
const size = digest.byteLength;
|
750
750
|
const sizeOffset = encodingLength$1(code);
|
751
751
|
const digestOffset = sizeOffset + encodingLength$1(size);
|
@@ -804,7 +804,7 @@ const code = 0x0;
|
|
804
804
|
const name = 'identity';
|
805
805
|
const encode$2 = coerce;
|
806
806
|
function digest(input) {
|
807
|
-
return create
|
807
|
+
return create(code, encode$2(input));
|
808
808
|
}
|
809
809
|
const identity = { code, name, encode: encode$2, digest };
|
810
810
|
|
@@ -828,9 +828,9 @@ class Hasher {
|
|
828
828
|
if (input instanceof Uint8Array) {
|
829
829
|
const result = this.encode(input);
|
830
830
|
return result instanceof Uint8Array
|
831
|
-
? create
|
831
|
+
? create(this.code, result)
|
832
832
|
/* c8 ignore next 1 */
|
833
|
-
: result.then(digest => create
|
833
|
+
: result.then(digest => create(this.code, digest));
|
834
834
|
}
|
835
835
|
else {
|
836
836
|
throw Error('Unknown type, must be binary type');
|
@@ -930,7 +930,7 @@ class CID {
|
|
930
930
|
switch (this.version) {
|
931
931
|
case 0: {
|
932
932
|
const { code, digest } = this.multihash;
|
933
|
-
const multihash = create
|
933
|
+
const multihash = create(code, digest);
|
934
934
|
return (CID.createV1(this.code, multihash));
|
935
935
|
}
|
936
936
|
case 1: {
|
@@ -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
|
}
|
@@ -3072,7 +3072,7 @@ async function sign$1(message, privateKey) {
|
|
3072
3072
|
function keccak256(input) {
|
3073
3073
|
return new Uint8Array(sha3.keccak256.arrayBuffer(input));
|
3074
3074
|
}
|
3075
|
-
function compressPublicKey
|
3075
|
+
function compressPublicKey(publicKey) {
|
3076
3076
|
if (publicKey.length === 64) {
|
3077
3077
|
publicKey = concat$2([new Uint8Array([4]), publicKey], 65);
|
3078
3078
|
}
|
@@ -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,33 +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
|
-
|
3144
|
-
|
3145
|
-
|
3146
|
-
// next scheduler queue processing step and this is exactly what we need.
|
3147
|
-
const nextTick = async () => { };
|
3148
|
-
// Returns control to thread each 'tick' ms to avoid blocking
|
3149
|
-
async function asyncLoop(iters, tick, cb) {
|
3150
|
-
let ts = Date.now();
|
3151
|
-
for (let i = 0; i < iters; i++) {
|
3152
|
-
cb(i);
|
3153
|
-
// Date.now() is not monotonic, so in case if clock goes backwards we return return control too
|
3154
|
-
const diff = Date.now() - ts;
|
3155
|
-
if (diff >= 0 && diff < tick)
|
3156
|
-
continue;
|
3157
|
-
await nextTick();
|
3158
|
-
ts += diff;
|
3159
|
-
}
|
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);
|
3160
3158
|
}
|
3161
3159
|
/**
|
3160
|
+
* Convert JS string to byte array.
|
3162
3161
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
3163
3162
|
*/
|
3164
3163
|
function utf8ToBytes$1(str) {
|
3165
3164
|
if (typeof str !== 'string')
|
3166
|
-
throw new Error(
|
3165
|
+
throw new Error('utf8ToBytes expected string, got ' + typeof str);
|
3167
3166
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
3168
3167
|
}
|
3169
3168
|
/**
|
@@ -3174,7 +3173,7 @@ function utf8ToBytes$1(str) {
|
|
3174
3173
|
function toBytes$1(data) {
|
3175
3174
|
if (typeof data === 'string')
|
3176
3175
|
data = utf8ToBytes$1(data);
|
3177
|
-
|
3176
|
+
abytes$1(data);
|
3178
3177
|
return data;
|
3179
3178
|
}
|
3180
3179
|
/**
|
@@ -3184,7 +3183,7 @@ function concatBytes$1(...arrays) {
|
|
3184
3183
|
let sum = 0;
|
3185
3184
|
for (let i = 0; i < arrays.length; i++) {
|
3186
3185
|
const a = arrays[i];
|
3187
|
-
|
3186
|
+
abytes$1(a);
|
3188
3187
|
sum += a.length;
|
3189
3188
|
}
|
3190
3189
|
const res = new Uint8Array(sum);
|
@@ -3195,20 +3194,14 @@ function concatBytes$1(...arrays) {
|
|
3195
3194
|
}
|
3196
3195
|
return res;
|
3197
3196
|
}
|
3198
|
-
|
3197
|
+
/** For runtime check if class implements interface */
|
3199
3198
|
class Hash {
|
3200
3199
|
// Safe version that clones internal state
|
3201
3200
|
clone() {
|
3202
3201
|
return this._cloneInto();
|
3203
3202
|
}
|
3204
3203
|
}
|
3205
|
-
|
3206
|
-
function checkOpts(defaults, opts) {
|
3207
|
-
if (opts !== undefined && toStr.call(opts) !== '[object Object]')
|
3208
|
-
throw new Error('Options should be object or undefined');
|
3209
|
-
const merged = Object.assign(defaults, opts);
|
3210
|
-
return merged;
|
3211
|
-
}
|
3204
|
+
/** Wraps hash function, creating an interface on top of it */
|
3212
3205
|
function wrapConstructor(hashCons) {
|
3213
3206
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
3214
3207
|
const tmp = hashCons();
|
@@ -3217,10 +3210,8 @@ function wrapConstructor(hashCons) {
|
|
3217
3210
|
hashC.create = () => hashCons();
|
3218
3211
|
return hashC;
|
3219
3212
|
}
|
3220
|
-
/**
|
3221
|
-
|
3222
|
-
*/
|
3223
|
-
function randomBytes$1(bytesLength = 32) {
|
3213
|
+
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
3214
|
+
function randomBytes(bytesLength = 32) {
|
3224
3215
|
if (crypto$1 && typeof crypto$1.getRandomValues === 'function') {
|
3225
3216
|
return crypto$1.getRandomValues(new Uint8Array(bytesLength));
|
3226
3217
|
}
|
@@ -3232,8 +3223,10 @@ function randomBytes$1(bytesLength = 32) {
|
|
3232
3223
|
}
|
3233
3224
|
|
3234
3225
|
/**
|
3235
|
-
*
|
3226
|
+
* Internal Merkle-Damgard hash utils.
|
3227
|
+
* @module
|
3236
3228
|
*/
|
3229
|
+
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
|
3237
3230
|
function setBigUint64(view, byteOffset, value, isLE) {
|
3238
3231
|
if (typeof view.setBigUint64 === 'function')
|
3239
3232
|
return view.setBigUint64(byteOffset, value, isLE);
|
@@ -3246,14 +3239,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
3246
3239
|
view.setUint32(byteOffset + h, wh, isLE);
|
3247
3240
|
view.setUint32(byteOffset + l, wl, isLE);
|
3248
3241
|
}
|
3249
|
-
/**
|
3250
|
-
|
3251
|
-
|
3252
|
-
|
3253
|
-
/**
|
3254
|
-
|
3255
|
-
|
3256
|
-
|
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
|
+
}
|
3257
3250
|
/**
|
3258
3251
|
* Merkle-Damgard hash construction base class.
|
3259
3252
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
@@ -3273,7 +3266,7 @@ class HashMD extends Hash {
|
|
3273
3266
|
this.view = createView(this.buffer);
|
3274
3267
|
}
|
3275
3268
|
update(data) {
|
3276
|
-
|
3269
|
+
aexists(this);
|
3277
3270
|
const { view, buffer, blockLen } = this;
|
3278
3271
|
data = toBytes$1(data);
|
3279
3272
|
const len = data.length;
|
@@ -3299,8 +3292,8 @@ class HashMD extends Hash {
|
|
3299
3292
|
return this;
|
3300
3293
|
}
|
3301
3294
|
digestInto(out) {
|
3302
|
-
|
3303
|
-
|
3295
|
+
aexists(this);
|
3296
|
+
aoutput(out, this);
|
3304
3297
|
this.finished = true;
|
3305
3298
|
// Padding
|
3306
3299
|
// We can avoid allocation of buffer for padding completely if it
|
@@ -3357,10 +3350,16 @@ class HashMD extends Hash {
|
|
3357
3350
|
}
|
3358
3351
|
}
|
3359
3352
|
|
3360
|
-
|
3361
|
-
|
3362
|
-
|
3363
|
-
|
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). */
|
3364
3363
|
// prettier-ignore
|
3365
3364
|
const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
3366
3365
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
@@ -3372,14 +3371,15 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
3372
3371
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
3373
3372
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
3374
3373
|
]);
|
3375
|
-
|
3376
|
-
// 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. */
|
3377
3375
|
// prettier-ignore
|
3378
3376
|
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
3379
3377
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
3380
3378
|
]);
|
3381
|
-
|
3382
|
-
|
3379
|
+
/**
|
3380
|
+
* Temporary buffer, not used to store anything between runs.
|
3381
|
+
* Named this way because it matches specification.
|
3382
|
+
*/
|
3383
3383
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
3384
3384
|
class SHA256 extends HashMD {
|
3385
3385
|
constructor() {
|
@@ -3456,10 +3456,7 @@ class SHA256 extends HashMD {
|
|
3456
3456
|
this.buffer.fill(0);
|
3457
3457
|
}
|
3458
3458
|
}
|
3459
|
-
/**
|
3460
|
-
* SHA2-256 hash function
|
3461
|
-
* @param message - data that would be hashed
|
3462
|
-
*/
|
3459
|
+
/** SHA2-256 hash function */
|
3463
3460
|
const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
3464
3461
|
|
3465
3462
|
var Protocols;
|
@@ -3471,43 +3468,24 @@ var Protocols;
|
|
3471
3468
|
})(Protocols || (Protocols = {}));
|
3472
3469
|
var ProtocolError;
|
3473
3470
|
(function (ProtocolError) {
|
3474
|
-
|
3471
|
+
//
|
3472
|
+
// GENERAL ERRORS SECTION
|
3473
|
+
//
|
3474
|
+
/**
|
3475
|
+
* Could not determine the origin of the fault. Best to check connectivity and try again
|
3476
|
+
* */
|
3475
3477
|
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
3476
3478
|
/**
|
3477
|
-
*
|
3478
|
-
*
|
3479
|
+
* The remote peer rejected the message. Information provided by the remote peer
|
3480
|
+
* is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
|
3481
|
+
* or `DECODE_FAILED` can be used.
|
3479
3482
|
*/
|
3480
|
-
ProtocolError["
|
3483
|
+
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
3481
3484
|
/**
|
3482
3485
|
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
3483
3486
|
* ensuring that messages are sent via several peer enable mitigation of this error.
|
3484
3487
|
*/
|
3485
3488
|
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
3486
|
-
/**
|
3487
|
-
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
3488
|
-
* payload is set on the outgoing message.
|
3489
|
-
*/
|
3490
|
-
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
3491
|
-
/**
|
3492
|
-
* The message size is above the maximum message size allowed on the Waku Network.
|
3493
|
-
* Compressing the message or using an alternative strategy for large messages is recommended.
|
3494
|
-
*/
|
3495
|
-
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
3496
|
-
/**
|
3497
|
-
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
3498
|
-
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
3499
|
-
*/
|
3500
|
-
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
3501
|
-
/**
|
3502
|
-
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
3503
|
-
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
3504
|
-
*/
|
3505
|
-
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
3506
|
-
/**
|
3507
|
-
* The topics passed in the decoders do not match each other, or don't exist at all.
|
3508
|
-
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
3509
|
-
*/
|
3510
|
-
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
3511
3489
|
/**
|
3512
3490
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
3513
3491
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
@@ -3525,37 +3503,51 @@ var ProtocolError;
|
|
3525
3503
|
* or `DECODE_FAILED` can be used.
|
3526
3504
|
*/
|
3527
3505
|
ProtocolError["NO_RESPONSE"] = "No response received";
|
3506
|
+
//
|
3507
|
+
// SEND ERRORS SECTION
|
3508
|
+
//
|
3528
3509
|
/**
|
3529
|
-
*
|
3530
|
-
*
|
3531
|
-
* or `DECODE_FAILED` can be used.
|
3510
|
+
* Failure to protobuf encode the message. This is not recoverable and needs
|
3511
|
+
* further investigation.
|
3532
3512
|
*/
|
3533
|
-
ProtocolError["
|
3513
|
+
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
3534
3514
|
/**
|
3535
|
-
* The
|
3536
|
-
*
|
3515
|
+
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
3516
|
+
* payload is set on the outgoing message.
|
3537
3517
|
*/
|
3538
|
-
ProtocolError["
|
3518
|
+
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
3539
3519
|
/**
|
3540
|
-
*
|
3541
|
-
*
|
3520
|
+
* The message size is above the maximum message size allowed on the Waku Network.
|
3521
|
+
* Compressing the message or using an alternative strategy for large messages is recommended.
|
3542
3522
|
*/
|
3543
|
-
ProtocolError["
|
3523
|
+
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
3544
3524
|
/**
|
3545
|
-
*
|
3546
|
-
*
|
3525
|
+
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
3526
|
+
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
3547
3527
|
*/
|
3548
|
-
ProtocolError["
|
3528
|
+
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
3549
3529
|
/**
|
3550
|
-
*
|
3551
|
-
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
|
3530
|
+
* Fails when
|
3552
3531
|
*/
|
3553
|
-
ProtocolError["
|
3532
|
+
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
3554
3533
|
/**
|
3555
3534
|
* General proof generation error message.
|
3556
3535
|
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
3557
3536
|
*/
|
3558
3537
|
ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
|
3538
|
+
//
|
3539
|
+
// RECEIVE ERRORS SECTION
|
3540
|
+
//
|
3541
|
+
/**
|
3542
|
+
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
3543
|
+
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
3544
|
+
*/
|
3545
|
+
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
3546
|
+
/**
|
3547
|
+
* The topics passed in the decoders do not match each other, or don't exist at all.
|
3548
|
+
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
3549
|
+
*/
|
3550
|
+
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
3559
3551
|
})(ProtocolError || (ProtocolError = {}));
|
3560
3552
|
|
3561
3553
|
var Tags;
|
@@ -3576,6 +3568,10 @@ var EConnectionStateEvents;
|
|
3576
3568
|
EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
|
3577
3569
|
})(EConnectionStateEvents || (EConnectionStateEvents = {}));
|
3578
3570
|
|
3571
|
+
var HealthStatusChangeEvents;
|
3572
|
+
(function (HealthStatusChangeEvents) {
|
3573
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
3574
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
3579
3575
|
var HealthStatus;
|
3580
3576
|
(function (HealthStatus) {
|
3581
3577
|
HealthStatus["Unhealthy"] = "Unhealthy";
|
@@ -3954,24 +3950,62 @@ function setup(env) {
|
|
3954
3950
|
createDebug.names = [];
|
3955
3951
|
createDebug.skips = [];
|
3956
3952
|
|
3957
|
-
|
3958
|
-
|
3959
|
-
|
3953
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
3954
|
+
.trim()
|
3955
|
+
.replace(' ', ',')
|
3956
|
+
.split(',')
|
3957
|
+
.filter(Boolean);
|
3960
3958
|
|
3961
|
-
for (
|
3962
|
-
if (
|
3963
|
-
|
3964
|
-
|
3959
|
+
for (const ns of split) {
|
3960
|
+
if (ns[0] === '-') {
|
3961
|
+
createDebug.skips.push(ns.slice(1));
|
3962
|
+
} else {
|
3963
|
+
createDebug.names.push(ns);
|
3965
3964
|
}
|
3965
|
+
}
|
3966
|
+
}
|
3966
3967
|
|
3967
|
-
|
3968
|
-
|
3969
|
-
|
3970
|
-
|
3968
|
+
/**
|
3969
|
+
* Checks if the given string matches a namespace template, honoring
|
3970
|
+
* asterisks as wildcards.
|
3971
|
+
*
|
3972
|
+
* @param {String} search
|
3973
|
+
* @param {String} template
|
3974
|
+
* @return {Boolean}
|
3975
|
+
*/
|
3976
|
+
function matchesTemplate(search, template) {
|
3977
|
+
let searchIndex = 0;
|
3978
|
+
let templateIndex = 0;
|
3979
|
+
let starIndex = -1;
|
3980
|
+
let matchIndex = 0;
|
3981
|
+
|
3982
|
+
while (searchIndex < search.length) {
|
3983
|
+
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
|
3984
|
+
// Match character or proceed with wildcard
|
3985
|
+
if (template[templateIndex] === '*') {
|
3986
|
+
starIndex = templateIndex;
|
3987
|
+
matchIndex = searchIndex;
|
3988
|
+
templateIndex++; // Skip the '*'
|
3989
|
+
} else {
|
3990
|
+
searchIndex++;
|
3991
|
+
templateIndex++;
|
3992
|
+
}
|
3993
|
+
} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
|
3994
|
+
// Backtrack to the last '*' and try to match more characters
|
3995
|
+
templateIndex = starIndex + 1;
|
3996
|
+
matchIndex++;
|
3997
|
+
searchIndex = matchIndex;
|
3971
3998
|
} else {
|
3972
|
-
|
3999
|
+
return false; // No match
|
3973
4000
|
}
|
3974
4001
|
}
|
4002
|
+
|
4003
|
+
// Handle trailing '*' in template
|
4004
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
4005
|
+
templateIndex++;
|
4006
|
+
}
|
4007
|
+
|
4008
|
+
return templateIndex === template.length;
|
3975
4009
|
}
|
3976
4010
|
|
3977
4011
|
/**
|
@@ -3982,8 +4016,8 @@ function setup(env) {
|
|
3982
4016
|
*/
|
3983
4017
|
function disable() {
|
3984
4018
|
const namespaces = [
|
3985
|
-
...createDebug.names
|
3986
|
-
...createDebug.skips.map(
|
4019
|
+
...createDebug.names,
|
4020
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
3987
4021
|
].join(',');
|
3988
4022
|
createDebug.enable('');
|
3989
4023
|
return namespaces;
|
@@ -3997,21 +4031,14 @@ function setup(env) {
|
|
3997
4031
|
* @api public
|
3998
4032
|
*/
|
3999
4033
|
function enabled(name) {
|
4000
|
-
|
4001
|
-
|
4002
|
-
}
|
4003
|
-
|
4004
|
-
let i;
|
4005
|
-
let len;
|
4006
|
-
|
4007
|
-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
4008
|
-
if (createDebug.skips[i].test(name)) {
|
4034
|
+
for (const skip of createDebug.skips) {
|
4035
|
+
if (matchesTemplate(name, skip)) {
|
4009
4036
|
return false;
|
4010
4037
|
}
|
4011
4038
|
}
|
4012
4039
|
|
4013
|
-
for (
|
4014
|
-
if (
|
4040
|
+
for (const ns of createDebug.names) {
|
4041
|
+
if (matchesTemplate(name, ns)) {
|
4015
4042
|
return true;
|
4016
4043
|
}
|
4017
4044
|
}
|
@@ -4019,19 +4046,6 @@ function setup(env) {
|
|
4019
4046
|
return false;
|
4020
4047
|
}
|
4021
4048
|
|
4022
|
-
/**
|
4023
|
-
* Convert regexp to namespace
|
4024
|
-
*
|
4025
|
-
* @param {RegExp} regxep
|
4026
|
-
* @return {String} namespace
|
4027
|
-
* @api private
|
4028
|
-
*/
|
4029
|
-
function toNamespace(regexp) {
|
4030
|
-
return regexp.toString()
|
4031
|
-
.substring(2, regexp.toString().length - 2)
|
4032
|
-
.replace(/\.\*\?$/, '*');
|
4033
|
-
}
|
4034
|
-
|
4035
4049
|
/**
|
4036
4050
|
* Coerce `val`.
|
4037
4051
|
*
|
@@ -4193,6 +4207,7 @@ var common = setup;
|
|
4193
4207
|
|
4194
4208
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
4195
4209
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
4210
|
+
// eslint-disable-next-line no-return-assign
|
4196
4211
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
4197
4212
|
// Is firebug? http://stackoverflow.com/a/398120/376773
|
4198
4213
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
@@ -4857,7 +4872,7 @@ function parseIPv6(input) {
|
|
4857
4872
|
return parser.new(input).parseWith(() => parser.readIPv6Addr());
|
4858
4873
|
}
|
4859
4874
|
/** Parse `input` into IPv4 or IPv6 bytes. */
|
4860
|
-
function parseIP(input) {
|
4875
|
+
function parseIP(input, mapIPv4ToIPv6 = false) {
|
4861
4876
|
// strip zone index if it is present
|
4862
4877
|
if (input.includes("%")) {
|
4863
4878
|
input = input.split("%")[0];
|
@@ -4865,7 +4880,14 @@ function parseIP(input) {
|
|
4865
4880
|
if (input.length > MAX_IPV6_LENGTH) {
|
4866
4881
|
return undefined;
|
4867
4882
|
}
|
4868
|
-
|
4883
|
+
const addr = parser.new(input).parseWith(() => parser.readIPAddr());
|
4884
|
+
if (!addr) {
|
4885
|
+
return undefined;
|
4886
|
+
}
|
4887
|
+
if (mapIPv4ToIPv6 && addr.length === 4) {
|
4888
|
+
return Uint8Array.from([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, addr[0], addr[1], addr[2], addr[3]]);
|
4889
|
+
}
|
4890
|
+
return addr;
|
4869
4891
|
}
|
4870
4892
|
|
4871
4893
|
/** Check if `input` is IPv4. */
|
@@ -5053,17 +5075,13 @@ function getProtocol(proto) {
|
|
5053
5075
|
throw new Error(`invalid protocol id type: ${typeof proto}`);
|
5054
5076
|
}
|
5055
5077
|
|
5056
|
-
/**
|
5057
|
-
* @packageDocumentation
|
5058
|
-
*
|
5059
|
-
* Provides methods for converting
|
5060
|
-
*/
|
5061
5078
|
getProtocol('ip4');
|
5062
5079
|
getProtocol('ip6');
|
5063
5080
|
getProtocol('ipcidr');
|
5064
5081
|
/**
|
5065
5082
|
* Convert [code,Uint8Array] to string
|
5066
5083
|
*/
|
5084
|
+
// eslint-disable-next-line complexity
|
5067
5085
|
function convertToString(proto, buf) {
|
5068
5086
|
const protocol = getProtocol(proto);
|
5069
5087
|
switch (protocol.code) {
|
@@ -5072,6 +5090,8 @@ function convertToString(proto, buf) {
|
|
5072
5090
|
return bytes2ip(buf);
|
5073
5091
|
case 42: // ipv6zone
|
5074
5092
|
return bytes2str(buf);
|
5093
|
+
case 43: // ipcidr
|
5094
|
+
return toString$1(buf, 'base10');
|
5075
5095
|
case 6: // tcp
|
5076
5096
|
case 273: // udp
|
5077
5097
|
case 33: // dccp
|
@@ -5099,6 +5119,7 @@ function convertToString(proto, buf) {
|
|
5099
5119
|
return toString$1(buf, 'base16'); // no clue. convert to hex
|
5100
5120
|
}
|
5101
5121
|
}
|
5122
|
+
// eslint-disable-next-line complexity
|
5102
5123
|
function convertToBytes(proto, str) {
|
5103
5124
|
const protocol = getProtocol(proto);
|
5104
5125
|
switch (protocol.code) {
|
@@ -5108,6 +5129,8 @@ function convertToBytes(proto, str) {
|
|
5108
5129
|
return ip2bytes(str);
|
5109
5130
|
case 42: // ipv6zone
|
5110
5131
|
return str2bytes(str);
|
5132
|
+
case 43: // ipcidr
|
5133
|
+
return fromString(str, 'base10');
|
5111
5134
|
case 6: // tcp
|
5112
5135
|
case 273: // udp
|
5113
5136
|
case 33: // dccp
|
@@ -5402,19 +5425,6 @@ function ParseError(str) {
|
|
5402
5425
|
return new Error('Error parsing address: ' + str);
|
5403
5426
|
}
|
5404
5427
|
|
5405
|
-
/**
|
5406
|
-
* @packageDocumentation
|
5407
|
-
*
|
5408
|
-
* An implementation of a Multiaddr in JavaScript
|
5409
|
-
*
|
5410
|
-
* @example
|
5411
|
-
*
|
5412
|
-
* ```js
|
5413
|
-
* import { multiaddr } from '@multiformats/multiaddr'
|
5414
|
-
*
|
5415
|
-
* const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
5416
|
-
* ```
|
5417
|
-
*/
|
5418
5428
|
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
5419
5429
|
const symbol = Symbol.for('@multiformats/js-multiaddr/multiaddr');
|
5420
5430
|
const DNS_CODES = [
|
@@ -5526,10 +5536,20 @@ class Multiaddr {
|
|
5526
5536
|
return this.#tuples.map(([code]) => getProtocol(code).name);
|
5527
5537
|
}
|
5528
5538
|
tuples() {
|
5529
|
-
return this.#tuples
|
5539
|
+
return this.#tuples.map(([code, value]) => {
|
5540
|
+
if (value == null) {
|
5541
|
+
return [code];
|
5542
|
+
}
|
5543
|
+
return [code, value];
|
5544
|
+
});
|
5530
5545
|
}
|
5531
5546
|
stringTuples() {
|
5532
|
-
return this.#stringTuples
|
5547
|
+
return this.#stringTuples.map(([code, value]) => {
|
5548
|
+
if (value == null) {
|
5549
|
+
return [code];
|
5550
|
+
}
|
5551
|
+
return [code, value];
|
5552
|
+
});
|
5533
5553
|
}
|
5534
5554
|
encapsulate(addr) {
|
5535
5555
|
addr = new Multiaddr(addr);
|
@@ -5659,10 +5679,8 @@ class Multiaddr {
|
|
5659
5679
|
*
|
5660
5680
|
* ```TypeScript
|
5661
5681
|
* import { multiaddr } from '@multiformats/multiaddr'
|
5662
|
-
* const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
|
5663
|
-
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5664
5682
|
*
|
5665
|
-
* const addr = multiaddr(
|
5683
|
+
* const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
|
5666
5684
|
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5667
5685
|
*
|
5668
5686
|
* addr.bytes
|
@@ -5701,9 +5719,9 @@ class Multiaddr {
|
|
5701
5719
|
*
|
5702
5720
|
* ```TypeScript
|
5703
5721
|
* import { multiaddr, resolvers } from '@multiformats/multiaddr'
|
5704
|
-
* import {
|
5722
|
+
* import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
5705
5723
|
*
|
5706
|
-
* resolvers.set('dnsaddr',
|
5724
|
+
* resolvers.set('dnsaddr', dnsaddrResolver)
|
5707
5725
|
*
|
5708
5726
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
5709
5727
|
*
|
@@ -5712,7 +5730,7 @@ class Multiaddr {
|
|
5712
5730
|
* signal: AbortSignal.timeout(5000)
|
5713
5731
|
* })
|
5714
5732
|
*
|
5715
|
-
* console.info(
|
5733
|
+
* console.info(resolved)
|
5716
5734
|
* // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
|
5717
5735
|
* ```
|
5718
5736
|
*
|
@@ -5726,7 +5744,9 @@ class Multiaddr {
|
|
5726
5744
|
* import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
5727
5745
|
*
|
5728
5746
|
* const resolver = dns({
|
5729
|
-
*
|
5747
|
+
* resolvers: {
|
5748
|
+
* '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
|
5749
|
+
* }
|
5730
5750
|
* })
|
5731
5751
|
*
|
5732
5752
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
@@ -5812,6 +5832,10 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
|
|
5812
5832
|
return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
|
5813
5833
|
}
|
5814
5834
|
|
5835
|
+
/**
|
5836
|
+
* All PeerId implementations must use this symbol as the name of a property
|
5837
|
+
* with a boolean `true` value
|
5838
|
+
*/
|
5815
5839
|
const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
5816
5840
|
|
5817
5841
|
/**
|
@@ -5819,29 +5843,44 @@ const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
|
5819
5843
|
* usually in response to the `abort` event being emitted by an
|
5820
5844
|
* AbortSignal.
|
5821
5845
|
*/
|
5822
|
-
|
5823
|
-
|
5824
|
-
|
5825
|
-
|
5846
|
+
/**
|
5847
|
+
* Thrown when invalid parameters are passed to a function or method call
|
5848
|
+
*/
|
5849
|
+
class InvalidParametersError extends Error {
|
5850
|
+
static name = 'InvalidParametersError';
|
5851
|
+
constructor(message = 'Invalid parameters') {
|
5826
5852
|
super(message);
|
5827
|
-
this.
|
5828
|
-
this.name = props?.name ?? 'CodeError';
|
5829
|
-
this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
5853
|
+
this.name = 'InvalidParametersError';
|
5830
5854
|
}
|
5831
5855
|
}
|
5832
|
-
|
5833
|
-
|
5834
|
-
|
5835
|
-
|
5856
|
+
/**
|
5857
|
+
* Thrown when a public key is invalid
|
5858
|
+
*/
|
5859
|
+
class InvalidPublicKeyError extends Error {
|
5860
|
+
static name = 'InvalidPublicKeyError';
|
5861
|
+
constructor(message = 'Invalid public key') {
|
5862
|
+
super(message);
|
5863
|
+
this.name = 'InvalidPublicKeyError';
|
5864
|
+
}
|
5865
|
+
}
|
5866
|
+
/**
|
5867
|
+
* Thrown when and attempt to operate on an unsupported key was made
|
5868
|
+
*/
|
5869
|
+
class UnsupportedKeyTypeError extends Error {
|
5870
|
+
static name = 'UnsupportedKeyTypeError';
|
5871
|
+
constructor(message = 'Unsupported key type') {
|
5872
|
+
super(message);
|
5873
|
+
this.name = 'UnsupportedKeyTypeError';
|
5836
5874
|
}
|
5837
|
-
return typeof thing.then === 'function' &&
|
5838
|
-
typeof thing.catch === 'function' &&
|
5839
|
-
typeof thing.finally === 'function';
|
5840
5875
|
}
|
5841
5876
|
|
5877
|
+
/**
|
5878
|
+
* Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
|
5879
|
+
* @todo re-check https://issues.chromium.org/issues/42212588
|
5880
|
+
* @module
|
5881
|
+
*/
|
5842
5882
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
5843
5883
|
const _32n = /* @__PURE__ */ BigInt(32);
|
5844
|
-
// We are not using BigUint64Array, because they are extremely slow as per 2022
|
5845
5884
|
function fromBig(n, le = false) {
|
5846
5885
|
if (le)
|
5847
5886
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
@@ -5898,6 +5937,13 @@ const u64 = {
|
|
5898
5937
|
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
5899
5938
|
};
|
5900
5939
|
|
5940
|
+
/**
|
5941
|
+
* SHA2-512 a.k.a. sha512 and sha384. It is slower than sha256 in js because u64 operations are slow.
|
5942
|
+
*
|
5943
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
5944
|
+
* [the paper on truncated SHA512/256](https://eprint.iacr.org/2010/548.pdf).
|
5945
|
+
* @module
|
5946
|
+
*/
|
5901
5947
|
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
5902
5948
|
// prettier-ignore
|
5903
5949
|
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
@@ -6052,8 +6098,13 @@ class SHA512 extends HashMD {
|
|
6052
6098
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
6053
6099
|
}
|
6054
6100
|
}
|
6101
|
+
/** SHA2-512 hash function. */
|
6055
6102
|
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
6056
6103
|
|
6104
|
+
/**
|
6105
|
+
* Hex, bytes and number utilities.
|
6106
|
+
* @module
|
6107
|
+
*/
|
6057
6108
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6058
6109
|
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
6059
6110
|
// This is OK: `abstract` directory does not use noble-hashes.
|
@@ -6063,8 +6114,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
|
|
6063
6114
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6064
6115
|
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6065
6116
|
function isBytes$1(a) {
|
6066
|
-
return
|
6067
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
6117
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
6068
6118
|
}
|
6069
6119
|
function abytes(item) {
|
6070
6120
|
if (!isBytes$1(item))
|
@@ -6072,7 +6122,7 @@ function abytes(item) {
|
|
6072
6122
|
}
|
6073
6123
|
function abool(title, value) {
|
6074
6124
|
if (typeof value !== 'boolean')
|
6075
|
-
throw new Error(
|
6125
|
+
throw new Error(title + ' boolean expected, got ' + value);
|
6076
6126
|
}
|
6077
6127
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6078
6128
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
@@ -6090,23 +6140,22 @@ function bytesToHex(bytes) {
|
|
6090
6140
|
}
|
6091
6141
|
function numberToHexUnpadded(num) {
|
6092
6142
|
const hex = num.toString(16);
|
6093
|
-
return hex.length & 1 ?
|
6143
|
+
return hex.length & 1 ? '0' + hex : hex;
|
6094
6144
|
}
|
6095
6145
|
function hexToNumber(hex) {
|
6096
6146
|
if (typeof hex !== 'string')
|
6097
6147
|
throw new Error('hex string expected, got ' + typeof hex);
|
6098
|
-
// Big Endian
|
6099
|
-
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
6148
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
6100
6149
|
}
|
6101
6150
|
// We use optimized technique to convert hex string to byte array
|
6102
|
-
const asciis = { _0: 48, _9: 57,
|
6103
|
-
function asciiToBase16(
|
6104
|
-
if (
|
6105
|
-
return
|
6106
|
-
if (
|
6107
|
-
return
|
6108
|
-
if (
|
6109
|
-
return
|
6151
|
+
const asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
6152
|
+
function asciiToBase16(ch) {
|
6153
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
6154
|
+
return ch - asciis._0; // '2' => 50-48
|
6155
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
6156
|
+
return ch - (asciis.A - 10); // 'B' => 66-(65-10)
|
6157
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
6158
|
+
return ch - (asciis.a - 10); // 'b' => 98-(97-10)
|
6110
6159
|
return;
|
6111
6160
|
}
|
6112
6161
|
/**
|
@@ -6118,7 +6167,7 @@ function hexToBytes(hex) {
|
|
6118
6167
|
const hl = hex.length;
|
6119
6168
|
const al = hl / 2;
|
6120
6169
|
if (hl % 2)
|
6121
|
-
throw new Error('
|
6170
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
6122
6171
|
const array = new Uint8Array(al);
|
6123
6172
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
6124
6173
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
@@ -6127,7 +6176,7 @@ function hexToBytes(hex) {
|
|
6127
6176
|
const char = hex[hi] + hex[hi + 1];
|
6128
6177
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
6129
6178
|
}
|
6130
|
-
array[ai] = n1 * 16 + n2;
|
6179
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
6131
6180
|
}
|
6132
6181
|
return array;
|
6133
6182
|
}
|
@@ -6165,7 +6214,7 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6165
6214
|
res = hexToBytes(hex);
|
6166
6215
|
}
|
6167
6216
|
catch (e) {
|
6168
|
-
throw new Error(
|
6217
|
+
throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
|
6169
6218
|
}
|
6170
6219
|
}
|
6171
6220
|
else if (isBytes$1(hex)) {
|
@@ -6174,11 +6223,11 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6174
6223
|
res = Uint8Array.from(hex);
|
6175
6224
|
}
|
6176
6225
|
else {
|
6177
|
-
throw new Error(
|
6226
|
+
throw new Error(title + ' must be hex string or Uint8Array');
|
6178
6227
|
}
|
6179
6228
|
const len = res.length;
|
6180
6229
|
if (typeof expectedLength === 'number' && len !== expectedLength)
|
6181
|
-
throw new Error(
|
6230
|
+
throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
|
6182
6231
|
return res;
|
6183
6232
|
}
|
6184
6233
|
/**
|
@@ -6213,7 +6262,7 @@ function equalBytes(a, b) {
|
|
6213
6262
|
*/
|
6214
6263
|
function utf8ToBytes(str) {
|
6215
6264
|
if (typeof str !== 'string')
|
6216
|
-
throw new Error(
|
6265
|
+
throw new Error('string expected');
|
6217
6266
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6218
6267
|
}
|
6219
6268
|
// Is positive bigint
|
@@ -6233,7 +6282,7 @@ function aInRange(title, n, min, max) {
|
|
6233
6282
|
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6234
6283
|
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6235
6284
|
if (!inRange(n, min, max))
|
6236
|
-
throw new Error(
|
6285
|
+
throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
|
6237
6286
|
}
|
6238
6287
|
// Bit operations
|
6239
6288
|
/**
|
@@ -6343,12 +6392,12 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6343
6392
|
const checkField = (fieldName, type, isOptional) => {
|
6344
6393
|
const checkVal = validatorFns[type];
|
6345
6394
|
if (typeof checkVal !== 'function')
|
6346
|
-
throw new Error(
|
6395
|
+
throw new Error('invalid validator function');
|
6347
6396
|
const val = object[fieldName];
|
6348
6397
|
if (isOptional && val === undefined)
|
6349
6398
|
return;
|
6350
6399
|
if (!checkVal(val, object)) {
|
6351
|
-
throw new Error(
|
6400
|
+
throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
|
6352
6401
|
}
|
6353
6402
|
};
|
6354
6403
|
for (const [fieldName, type] of Object.entries(validators))
|
@@ -6417,14 +6466,17 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6417
6466
|
validateObject: validateObject
|
6418
6467
|
});
|
6419
6468
|
|
6469
|
+
/**
|
6470
|
+
* Utils for modular division and finite fields.
|
6471
|
+
* A finite field over 11 is integer number operations `mod 11`.
|
6472
|
+
* There is no division: it is replaced by modular multiplicative inverse.
|
6473
|
+
* @module
|
6474
|
+
*/
|
6420
6475
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6421
|
-
// Utilities for modular arithmetics and finite fields
|
6422
|
-
// prettier-ignore
|
6423
|
-
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6424
6476
|
// prettier-ignore
|
6425
|
-
const
|
6477
|
+
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = /* @__PURE__ */ BigInt(2), _3n$1 = /* @__PURE__ */ BigInt(3);
|
6426
6478
|
// prettier-ignore
|
6427
|
-
BigInt(
|
6479
|
+
const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
|
6428
6480
|
// Calculates a modulo b
|
6429
6481
|
function mod(a, b) {
|
6430
6482
|
const result = a % b;
|
@@ -6433,13 +6485,15 @@ function mod(a, b) {
|
|
6433
6485
|
/**
|
6434
6486
|
* Efficiently raise num to power and do modular division.
|
6435
6487
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
6488
|
+
* @todo use field version && remove
|
6436
6489
|
* @example
|
6437
6490
|
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
6438
6491
|
*/
|
6439
|
-
// TODO: use field version && remove
|
6440
6492
|
function pow(num, power, modulo) {
|
6441
|
-
if (
|
6442
|
-
throw new Error('
|
6493
|
+
if (power < _0n$3)
|
6494
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6495
|
+
if (modulo <= _0n$3)
|
6496
|
+
throw new Error('invalid modulus');
|
6443
6497
|
if (modulo === _1n$5)
|
6444
6498
|
return _0n$3;
|
6445
6499
|
let res = _1n$5;
|
@@ -6451,7 +6505,7 @@ function pow(num, power, modulo) {
|
|
6451
6505
|
}
|
6452
6506
|
return res;
|
6453
6507
|
}
|
6454
|
-
|
6508
|
+
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
6455
6509
|
function pow2(x, power, modulo) {
|
6456
6510
|
let res = x;
|
6457
6511
|
while (power-- > _0n$3) {
|
@@ -6460,12 +6514,15 @@ function pow2(x, power, modulo) {
|
|
6460
6514
|
}
|
6461
6515
|
return res;
|
6462
6516
|
}
|
6463
|
-
|
6517
|
+
/**
|
6518
|
+
* Inverses number over modulo.
|
6519
|
+
* Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
|
6520
|
+
*/
|
6464
6521
|
function invert(number, modulo) {
|
6465
|
-
if (number === _0n$3
|
6466
|
-
throw new Error(
|
6467
|
-
|
6468
|
-
|
6522
|
+
if (number === _0n$3)
|
6523
|
+
throw new Error('invert: expected non-zero number');
|
6524
|
+
if (modulo <= _0n$3)
|
6525
|
+
throw new Error('invert: expected positive modulus, got ' + modulo);
|
6469
6526
|
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
6470
6527
|
let a = mod(number, modulo);
|
6471
6528
|
let b = modulo;
|
@@ -6505,8 +6562,11 @@ function tonelliShanks(P) {
|
|
6505
6562
|
for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
|
6506
6563
|
;
|
6507
6564
|
// Step 2: Select a non-square z such that (z | p) ≡ -1 and set c ≡ zq
|
6508
|
-
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
|
6509
|
-
|
6565
|
+
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++) {
|
6566
|
+
// Crash instead of infinity loop, we cannot reasonable count until P.
|
6567
|
+
if (Z > 1000)
|
6568
|
+
throw new Error('Cannot find square root: likely non-prime P');
|
6569
|
+
}
|
6510
6570
|
// Fast-path
|
6511
6571
|
if (S === 1) {
|
6512
6572
|
const p1div4 = (P + _1n$5) / _4n;
|
@@ -6548,9 +6608,18 @@ function tonelliShanks(P) {
|
|
6548
6608
|
return x;
|
6549
6609
|
};
|
6550
6610
|
}
|
6611
|
+
/**
|
6612
|
+
* Square root for a finite field. It will try to check if optimizations are applicable and fall back to 4:
|
6613
|
+
*
|
6614
|
+
* 1. P ≡ 3 (mod 4)
|
6615
|
+
* 2. P ≡ 5 (mod 8)
|
6616
|
+
* 3. P ≡ 9 (mod 16)
|
6617
|
+
* 4. Tonelli-Shanks algorithm
|
6618
|
+
*
|
6619
|
+
* Different algorithms can give different roots, it is up to user to decide which one they want.
|
6620
|
+
* For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6621
|
+
*/
|
6551
6622
|
function FpSqrt(P) {
|
6552
|
-
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
6553
|
-
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6554
6623
|
// P ≡ 3 (mod 4)
|
6555
6624
|
// √n = n^((P+1)/4)
|
6556
6625
|
if (P % _4n === _3n$1) {
|
@@ -6614,7 +6683,7 @@ function FpPow(f, num, power) {
|
|
6614
6683
|
// Should have same speed as pow for bigints
|
6615
6684
|
// TODO: benchmark!
|
6616
6685
|
if (power < _0n$3)
|
6617
|
-
throw new Error('
|
6686
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6618
6687
|
if (power === _0n$3)
|
6619
6688
|
return f.ONE;
|
6620
6689
|
if (power === _1n$5)
|
@@ -6661,15 +6730,15 @@ function nLength(n, nBitLength) {
|
|
6661
6730
|
return { nBitLength: _nBitLength, nByteLength };
|
6662
6731
|
}
|
6663
6732
|
/**
|
6664
|
-
* Initializes a finite field over prime.
|
6665
|
-
* Do not init in loop: slow. Very fragile: always run a benchmark on a change.
|
6733
|
+
* Initializes a finite field over prime.
|
6666
6734
|
* Major performance optimizations:
|
6667
6735
|
* * a) denormalized operations like mulN instead of mul
|
6668
6736
|
* * b) same object shape: never add or remove keys
|
6669
6737
|
* * c) Object.freeze
|
6670
|
-
*
|
6738
|
+
* Fragile: always run a benchmark on a change.
|
6739
|
+
* Security note: operations don't check 'isValid' for all elements for performance reasons,
|
6671
6740
|
* it is caller responsibility to check this.
|
6672
|
-
* This is low-level code, please make sure you know what you doing.
|
6741
|
+
* This is low-level code, please make sure you know what you're doing.
|
6673
6742
|
* @param ORDER prime positive bigint
|
6674
6743
|
* @param bitLen how many bits the field consumes
|
6675
6744
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6677,13 +6746,14 @@ function nLength(n, nBitLength) {
|
|
6677
6746
|
*/
|
6678
6747
|
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
6679
6748
|
if (ORDER <= _0n$3)
|
6680
|
-
throw new Error(
|
6749
|
+
throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
|
6681
6750
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
6682
6751
|
if (BYTES > 2048)
|
6683
|
-
throw new Error('
|
6684
|
-
|
6752
|
+
throw new Error('invalid field: expected ORDER of <= 2048 bytes');
|
6753
|
+
let sqrtP; // cached sqrtP
|
6685
6754
|
const f = Object.freeze({
|
6686
6755
|
ORDER,
|
6756
|
+
isLE,
|
6687
6757
|
BITS,
|
6688
6758
|
BYTES,
|
6689
6759
|
MASK: bitMask(BITS),
|
@@ -6692,7 +6762,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6692
6762
|
create: (num) => mod(num, ORDER),
|
6693
6763
|
isValid: (num) => {
|
6694
6764
|
if (typeof num !== 'bigint')
|
6695
|
-
throw new Error(
|
6765
|
+
throw new Error('invalid field element: expected bigint, got ' + typeof num);
|
6696
6766
|
return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
6697
6767
|
},
|
6698
6768
|
is0: (num) => num === _0n$3,
|
@@ -6711,7 +6781,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6711
6781
|
subN: (lhs, rhs) => lhs - rhs,
|
6712
6782
|
mulN: (lhs, rhs) => lhs * rhs,
|
6713
6783
|
inv: (num) => invert(num, ORDER),
|
6714
|
-
sqrt: redef.sqrt ||
|
6784
|
+
sqrt: redef.sqrt ||
|
6785
|
+
((n) => {
|
6786
|
+
if (!sqrtP)
|
6787
|
+
sqrtP = FpSqrt(ORDER);
|
6788
|
+
return sqrtP(f, n);
|
6789
|
+
}),
|
6715
6790
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
6716
6791
|
// TODO: do we really need constant cmov?
|
6717
6792
|
// We don't have const-time bigints anyway, so probably will be not very useful
|
@@ -6719,7 +6794,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6719
6794
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
6720
6795
|
fromBytes: (bytes) => {
|
6721
6796
|
if (bytes.length !== BYTES)
|
6722
|
-
throw new Error(
|
6797
|
+
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
6723
6798
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
6724
6799
|
},
|
6725
6800
|
});
|
@@ -6767,52 +6842,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6767
6842
|
const minLen = getMinHashLength(fieldOrder);
|
6768
6843
|
// No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
|
6769
6844
|
if (len < 16 || len < minLen || len > 1024)
|
6770
|
-
throw new Error(
|
6771
|
-
const num = isLE ?
|
6845
|
+
throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
|
6846
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
6772
6847
|
// `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
|
6773
6848
|
const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
|
6774
6849
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
6775
6850
|
}
|
6776
6851
|
|
6852
|
+
/**
|
6853
|
+
* Methods for elliptic curve multiplication by scalars.
|
6854
|
+
* Contains wNAF, pippenger
|
6855
|
+
* @module
|
6856
|
+
*/
|
6777
6857
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6778
|
-
// Abelian group utilities
|
6779
6858
|
const _0n$2 = BigInt(0);
|
6780
6859
|
const _1n$4 = BigInt(1);
|
6860
|
+
function constTimeNegate(condition, item) {
|
6861
|
+
const neg = item.negate();
|
6862
|
+
return condition ? neg : item;
|
6863
|
+
}
|
6864
|
+
function validateW(W, bits) {
|
6865
|
+
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6866
|
+
throw new Error('invalid window size, expected [1..' + bits + '], got W=' + W);
|
6867
|
+
}
|
6868
|
+
function calcWOpts(W, bits) {
|
6869
|
+
validateW(W, bits);
|
6870
|
+
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6871
|
+
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6872
|
+
return { windows, windowSize };
|
6873
|
+
}
|
6874
|
+
function validateMSMPoints(points, c) {
|
6875
|
+
if (!Array.isArray(points))
|
6876
|
+
throw new Error('array expected');
|
6877
|
+
points.forEach((p, i) => {
|
6878
|
+
if (!(p instanceof c))
|
6879
|
+
throw new Error('invalid point at index ' + i);
|
6880
|
+
});
|
6881
|
+
}
|
6882
|
+
function validateMSMScalars(scalars, field) {
|
6883
|
+
if (!Array.isArray(scalars))
|
6884
|
+
throw new Error('array of scalars expected');
|
6885
|
+
scalars.forEach((s, i) => {
|
6886
|
+
if (!field.isValid(s))
|
6887
|
+
throw new Error('invalid scalar at index ' + i);
|
6888
|
+
});
|
6889
|
+
}
|
6781
6890
|
// Since points in different groups cannot be equal (different object constructor),
|
6782
6891
|
// we can have single place to store precomputes
|
6783
6892
|
const pointPrecomputes = new WeakMap();
|
6784
6893
|
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6785
|
-
|
6786
|
-
|
6787
|
-
|
6788
|
-
|
6789
|
-
|
6790
|
-
|
6791
|
-
|
6792
|
-
|
6793
|
-
|
6794
|
-
|
6795
|
-
|
6894
|
+
function getW(P) {
|
6895
|
+
return pointWindowSizes.get(P) || 1;
|
6896
|
+
}
|
6897
|
+
/**
|
6898
|
+
* Elliptic curve multiplication of Point by scalar. Fragile.
|
6899
|
+
* Scalars should always be less than curve order: this should be checked inside of a curve itself.
|
6900
|
+
* Creates precomputation tables for fast multiplication:
|
6901
|
+
* - private scalar is split by fixed size windows of W bits
|
6902
|
+
* - every window point is collected from window's table & added to accumulator
|
6903
|
+
* - since windows are different, same point inside tables won't be accessed more than once per calc
|
6904
|
+
* - each multiplication is 'Math.ceil(CURVE_ORDER / 𝑊) + 1' point additions (fixed for any scalar)
|
6905
|
+
* - +1 window is neccessary for wNAF
|
6906
|
+
* - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
|
6907
|
+
*
|
6908
|
+
* @todo Research returning 2d JS array of windows, instead of a single window.
|
6909
|
+
* This would allow windows to be in different memory locations
|
6910
|
+
*/
|
6796
6911
|
function wNAF(c, bits) {
|
6797
|
-
const constTimeNegate = (condition, item) => {
|
6798
|
-
const neg = item.negate();
|
6799
|
-
return condition ? neg : item;
|
6800
|
-
};
|
6801
|
-
const validateW = (W) => {
|
6802
|
-
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6803
|
-
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6804
|
-
};
|
6805
|
-
const opts = (W) => {
|
6806
|
-
validateW(W);
|
6807
|
-
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6808
|
-
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6809
|
-
return { windows, windowSize };
|
6810
|
-
};
|
6811
6912
|
return {
|
6812
6913
|
constTimeNegate,
|
6914
|
+
hasPrecomputes(elm) {
|
6915
|
+
return getW(elm) !== 1;
|
6916
|
+
},
|
6813
6917
|
// non-const time multiplication ladder
|
6814
|
-
unsafeLadder(elm, n) {
|
6815
|
-
let p = c.ZERO;
|
6918
|
+
unsafeLadder(elm, n, p = c.ZERO) {
|
6816
6919
|
let d = elm;
|
6817
6920
|
while (n > _0n$2) {
|
6818
6921
|
if (n & _1n$4)
|
@@ -6830,10 +6933,12 @@ function wNAF(c, bits) {
|
|
6830
6933
|
* - 𝑊 is the window size
|
6831
6934
|
* - 𝑛 is the bitlength of the curve order.
|
6832
6935
|
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
6936
|
+
* @param elm Point instance
|
6937
|
+
* @param W window size
|
6833
6938
|
* @returns precomputed point tables flattened to a single array
|
6834
6939
|
*/
|
6835
6940
|
precomputeWindow(elm, W) {
|
6836
|
-
const { windows, windowSize } =
|
6941
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6837
6942
|
const points = [];
|
6838
6943
|
let p = elm;
|
6839
6944
|
let base = p;
|
@@ -6859,7 +6964,7 @@ function wNAF(c, bits) {
|
|
6859
6964
|
wNAF(W, precomputes, n) {
|
6860
6965
|
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
6861
6966
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
6862
|
-
const { windows, windowSize } =
|
6967
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6863
6968
|
let p = c.ZERO;
|
6864
6969
|
let f = c.BASE;
|
6865
6970
|
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
@@ -6903,8 +7008,44 @@ function wNAF(c, bits) {
|
|
6903
7008
|
// which makes it less const-time: around 1 bigint multiply.
|
6904
7009
|
return { p, f };
|
6905
7010
|
},
|
6906
|
-
|
6907
|
-
|
7011
|
+
/**
|
7012
|
+
* Implements ec unsafe (non const-time) multiplication using precomputed tables and w-ary non-adjacent form.
|
7013
|
+
* @param W window size
|
7014
|
+
* @param precomputes precomputed tables
|
7015
|
+
* @param n scalar (we don't check here, but should be less than curve order)
|
7016
|
+
* @param acc accumulator point to add result of multiplication
|
7017
|
+
* @returns point
|
7018
|
+
*/
|
7019
|
+
wNAFUnsafe(W, precomputes, n, acc = c.ZERO) {
|
7020
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
7021
|
+
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
7022
|
+
const maxNumber = 2 ** W;
|
7023
|
+
const shiftBy = BigInt(W);
|
7024
|
+
for (let window = 0; window < windows; window++) {
|
7025
|
+
const offset = window * windowSize;
|
7026
|
+
if (n === _0n$2)
|
7027
|
+
break; // No need to go over empty scalar
|
7028
|
+
// Extract W bits.
|
7029
|
+
let wbits = Number(n & mask);
|
7030
|
+
// Shift number by W bits.
|
7031
|
+
n >>= shiftBy;
|
7032
|
+
// If the bits are bigger than max size, we'll split those.
|
7033
|
+
// +224 => 256 - 32
|
7034
|
+
if (wbits > windowSize) {
|
7035
|
+
wbits -= maxNumber;
|
7036
|
+
n += _1n$4;
|
7037
|
+
}
|
7038
|
+
if (wbits === 0)
|
7039
|
+
continue;
|
7040
|
+
let curr = precomputes[offset + Math.abs(wbits) - 1]; // -1 because we skip zero
|
7041
|
+
if (wbits < 0)
|
7042
|
+
curr = curr.negate();
|
7043
|
+
// NOTE: by re-using acc, we can save a lot of additions in case of MSM
|
7044
|
+
acc = acc.add(curr);
|
7045
|
+
}
|
7046
|
+
return acc;
|
7047
|
+
},
|
7048
|
+
getPrecomputes(W, P, transform) {
|
6908
7049
|
// Calculate precomputes on a first run, reuse them after
|
6909
7050
|
let comp = pointPrecomputes.get(P);
|
6910
7051
|
if (!comp) {
|
@@ -6912,62 +7053,66 @@ function wNAF(c, bits) {
|
|
6912
7053
|
if (W !== 1)
|
6913
7054
|
pointPrecomputes.set(P, transform(comp));
|
6914
7055
|
}
|
6915
|
-
return
|
7056
|
+
return comp;
|
7057
|
+
},
|
7058
|
+
wNAFCached(P, n, transform) {
|
7059
|
+
const W = getW(P);
|
7060
|
+
return this.wNAF(W, this.getPrecomputes(W, P, transform), n);
|
7061
|
+
},
|
7062
|
+
wNAFCachedUnsafe(P, n, transform, prev) {
|
7063
|
+
const W = getW(P);
|
7064
|
+
if (W === 1)
|
7065
|
+
return this.unsafeLadder(P, n, prev); // For W=1 ladder is ~x2 faster
|
7066
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, P, transform), n, prev);
|
6916
7067
|
},
|
6917
7068
|
// We calculate precomputes for elliptic curve point multiplication
|
6918
7069
|
// using windowed method. This specifies window size and
|
6919
7070
|
// stores precomputed values. Usually only base point would be precomputed.
|
6920
7071
|
setWindowSize(P, W) {
|
6921
|
-
validateW(W);
|
7072
|
+
validateW(W, bits);
|
6922
7073
|
pointWindowSizes.set(P, W);
|
6923
7074
|
pointPrecomputes.delete(P);
|
6924
7075
|
},
|
6925
7076
|
};
|
6926
7077
|
}
|
6927
7078
|
/**
|
6928
|
-
* Pippenger algorithm for multi-scalar multiplication (MSM).
|
6929
|
-
* MSM is basically (Pa + Qb + Rc + ...).
|
7079
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
6930
7080
|
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
6931
7081
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
6932
7082
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
6933
7083
|
* @param c Curve Point constructor
|
6934
|
-
* @param
|
7084
|
+
* @param fieldN field over CURVE.N - important that it's not over CURVE.P
|
6935
7085
|
* @param points array of L curve points
|
6936
7086
|
* @param scalars array of L scalars (aka private keys / bigints)
|
6937
7087
|
*/
|
6938
|
-
function pippenger(c,
|
7088
|
+
function pippenger(c, fieldN, points, scalars) {
|
6939
7089
|
// If we split scalars by some window (let's say 8 bits), every chunk will only
|
6940
7090
|
// take 256 buckets even if there are 4096 scalars, also re-uses double.
|
6941
7091
|
// TODO:
|
6942
7092
|
// - https://eprint.iacr.org/2024/750.pdf
|
6943
7093
|
// - https://tches.iacr.org/index.php/TCHES/article/view/10287
|
6944
7094
|
// 0 is accepted in scalars
|
6945
|
-
|
7095
|
+
validateMSMPoints(points, c);
|
7096
|
+
validateMSMScalars(scalars, fieldN);
|
7097
|
+
if (points.length !== scalars.length)
|
6946
7098
|
throw new Error('arrays of points and scalars must have equal length');
|
6947
|
-
|
6948
|
-
if (!field.isValid(s))
|
6949
|
-
throw new Error(`wrong scalar at index ${i}`);
|
6950
|
-
});
|
6951
|
-
points.forEach((p, i) => {
|
6952
|
-
if (!(p instanceof c))
|
6953
|
-
throw new Error(`wrong point at index ${i}`);
|
6954
|
-
});
|
7099
|
+
const zero = c.ZERO;
|
6955
7100
|
const wbits = bitLen(BigInt(points.length));
|
6956
7101
|
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
6957
7102
|
const MASK = (1 << windowSize) - 1;
|
6958
|
-
const buckets = new Array(MASK + 1).fill(
|
6959
|
-
const lastBits = Math.floor((
|
6960
|
-
let sum =
|
7103
|
+
const buckets = new Array(MASK + 1).fill(zero); // +1 for zero array
|
7104
|
+
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
7105
|
+
let sum = zero;
|
6961
7106
|
for (let i = lastBits; i >= 0; i -= windowSize) {
|
6962
|
-
buckets.fill(
|
7107
|
+
buckets.fill(zero);
|
6963
7108
|
for (let j = 0; j < scalars.length; j++) {
|
6964
7109
|
const scalar = scalars[j];
|
6965
7110
|
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
6966
7111
|
buckets[wbits] = buckets[wbits].add(points[j]);
|
6967
7112
|
}
|
6968
|
-
let resI =
|
7113
|
+
let resI = zero; // not using this will do small speed-up, but will lose ct
|
6969
7114
|
// Skip first bucket, because it is zero
|
6970
|
-
for (let j = buckets.length - 1, sumI =
|
7115
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
6971
7116
|
sumI = sumI.add(buckets[j]);
|
6972
7117
|
resI = resI.add(sumI);
|
6973
7118
|
}
|
@@ -6997,8 +7142,12 @@ function validateBasic(curve) {
|
|
6997
7142
|
});
|
6998
7143
|
}
|
6999
7144
|
|
7145
|
+
/**
|
7146
|
+
* Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y².
|
7147
|
+
* For design rationale of types / exports, see weierstrass module documentation.
|
7148
|
+
* @module
|
7149
|
+
*/
|
7000
7150
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7001
|
-
// Twisted Edwards curve. The formula is: ax² + y² = 1 + dx²y²
|
7002
7151
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
7003
7152
|
// prettier-ignore
|
7004
7153
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -7030,6 +7179,10 @@ function validateOpts$1(curve) {
|
|
7030
7179
|
function twistedEdwards(curveDef) {
|
7031
7180
|
const CURVE = validateOpts$1(curveDef);
|
7032
7181
|
const { Fp, n: CURVE_ORDER, prehash: prehash, hash: cHash, randomBytes, nByteLength, h: cofactor, } = CURVE;
|
7182
|
+
// Important:
|
7183
|
+
// There are some places where Fp.BYTES is used instead of nByteLength.
|
7184
|
+
// So far, everything has been tested with curves of Fp.BYTES == nByteLength.
|
7185
|
+
// TODO: test and find curves which behave otherwise.
|
7033
7186
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
7034
7187
|
const modP = Fp.create; // Function overrides
|
7035
7188
|
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
@@ -7243,16 +7396,15 @@ function twistedEdwards(curveDef) {
|
|
7243
7396
|
// It's faster, but should only be used when you don't care about
|
7244
7397
|
// an exposed private key e.g. sig verification.
|
7245
7398
|
// Does NOT allow scalars higher than CURVE.n.
|
7246
|
-
|
7399
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
7400
|
+
multiplyUnsafe(scalar, acc = Point.ZERO) {
|
7247
7401
|
const n = scalar;
|
7248
7402
|
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7249
7403
|
if (n === _0n$1)
|
7250
7404
|
return I;
|
7251
|
-
if (this.
|
7405
|
+
if (this.is0() || n === _1n$3)
|
7252
7406
|
return this;
|
7253
|
-
|
7254
|
-
return this.wNAF(n).p;
|
7255
|
-
return wnaf.unsafeLadder(this, n);
|
7407
|
+
return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
|
7256
7408
|
}
|
7257
7409
|
// Checks if point is of small order.
|
7258
7410
|
// If you add something to small order point, you will have "dirty"
|
@@ -7286,8 +7438,9 @@ function twistedEdwards(curveDef) {
|
|
7286
7438
|
abool('zip215', zip215);
|
7287
7439
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7288
7440
|
const lastByte = hex[len - 1]; // select last byte
|
7289
|
-
normed[len - 1] = lastByte &
|
7441
|
+
normed[len - 1] = lastByte & -129; // clear last bit
|
7290
7442
|
const y = bytesToNumberLE(normed);
|
7443
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7291
7444
|
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7292
7445
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7293
7446
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
@@ -7336,7 +7489,7 @@ function twistedEdwards(curveDef) {
|
|
7336
7489
|
}
|
7337
7490
|
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
7338
7491
|
function getExtendedPublicKey(key) {
|
7339
|
-
const len =
|
7492
|
+
const len = Fp.BYTES;
|
7340
7493
|
key = ensureBytes('private key', key, len);
|
7341
7494
|
// Hash private key with curve's hash function to produce uniformingly random input
|
7342
7495
|
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
@@ -7369,23 +7522,29 @@ function twistedEdwards(curveDef) {
|
|
7369
7522
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7370
7523
|
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7371
7524
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7372
|
-
return ensureBytes('result', res,
|
7525
|
+
return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
|
7373
7526
|
}
|
7374
7527
|
const verifyOpts = VERIFY_DEFAULT;
|
7528
|
+
/**
|
7529
|
+
* Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7530
|
+
* An extended group equation is checked.
|
7531
|
+
*/
|
7375
7532
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
7376
7533
|
const { context, zip215 } = options;
|
7377
7534
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7378
7535
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7379
7536
|
msg = ensureBytes('message', msg);
|
7537
|
+
publicKey = ensureBytes('publicKey', publicKey, len);
|
7380
7538
|
if (zip215 !== undefined)
|
7381
7539
|
abool('zip215', zip215);
|
7382
7540
|
if (prehash)
|
7383
7541
|
msg = prehash(msg); // for ed25519ph, etc
|
7384
7542
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
7385
|
-
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
7386
|
-
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
7387
7543
|
let A, R, SB;
|
7388
7544
|
try {
|
7545
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7546
|
+
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7547
|
+
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
7389
7548
|
A = Point.fromHex(publicKey, zip215);
|
7390
7549
|
R = Point.fromHex(sig.slice(0, len), zip215);
|
7391
7550
|
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
@@ -7397,6 +7556,7 @@ function twistedEdwards(curveDef) {
|
|
7397
7556
|
return false;
|
7398
7557
|
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
7399
7558
|
const RkA = R.add(A.multiplyUnsafe(k));
|
7559
|
+
// Extended group equation
|
7400
7560
|
// [8][S]B = [8]R + [8][k]A'
|
7401
7561
|
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
7402
7562
|
}
|
@@ -7427,13 +7587,14 @@ function twistedEdwards(curveDef) {
|
|
7427
7587
|
};
|
7428
7588
|
}
|
7429
7589
|
|
7430
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7431
7590
|
/**
|
7432
7591
|
* ed25519 Twisted Edwards curve with following addons:
|
7433
7592
|
* - X25519 ECDH
|
7434
7593
|
* - Ristretto cofactor elimination
|
7435
7594
|
* - Elligator hash-to-group / point indistinguishability
|
7595
|
+
* @module
|
7436
7596
|
*/
|
7597
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7437
7598
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7438
7599
|
// √(-1) aka √(a) aka 2^((p-1)/4)
|
7439
7600
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
@@ -7492,7 +7653,7 @@ function uvRatio(u, v) {
|
|
7492
7653
|
x = mod(-x, P);
|
7493
7654
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7494
7655
|
}
|
7495
|
-
const Fp
|
7656
|
+
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7496
7657
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7497
7658
|
// Param: a
|
7498
7659
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
@@ -7500,7 +7661,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7500
7661
|
// Negative number is P - number, and division is invert(number, P)
|
7501
7662
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
7502
7663
|
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
|
7503
|
-
Fp
|
7664
|
+
Fp,
|
7504
7665
|
// Subgroup order: how many points curve has
|
7505
7666
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7506
7667
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
@@ -7510,7 +7671,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7510
7671
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7511
7672
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
7512
7673
|
hash: sha512,
|
7513
|
-
randomBytes
|
7674
|
+
randomBytes,
|
7514
7675
|
adjustScalarBytes,
|
7515
7676
|
// dom2
|
7516
7677
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
@@ -7519,180 +7680,58 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7519
7680
|
}))();
|
7520
7681
|
/**
|
7521
7682
|
* ed25519 curve with EdDSA signatures.
|
7683
|
+
* @example
|
7684
|
+
* import { ed25519 } from '@noble/curves/ed25519';
|
7685
|
+
* const priv = ed25519.utils.randomPrivateKey();
|
7686
|
+
* const pub = ed25519.getPublicKey(priv);
|
7687
|
+
* const msg = new TextEncoder().encode('hello');
|
7688
|
+
* const sig = ed25519.sign(msg, priv);
|
7689
|
+
* ed25519.verify(sig, msg, pub); // Default mode: follows ZIP215
|
7690
|
+
* ed25519.verify(sig, msg, pub, { zip215: false }); // RFC8032 / FIPS 186-5
|
7522
7691
|
*/
|
7523
7692
|
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7524
7693
|
|
7525
7694
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7526
|
-
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
7527
|
-
const KEYS_BYTE_LENGTH = 32;
|
7528
|
-
function generateKey$2() {
|
7529
|
-
// the actual private key (32 bytes)
|
7530
|
-
const privateKeyRaw = ed25519.utils.randomPrivateKey();
|
7531
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7532
|
-
// concatenated the public key to the private key
|
7533
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7534
|
-
return {
|
7535
|
-
privateKey,
|
7536
|
-
publicKey
|
7537
|
-
};
|
7538
|
-
}
|
7539
|
-
/**
|
7540
|
-
* Generate keypair from a 32 byte uint8array
|
7541
|
-
*/
|
7542
|
-
function generateKeyFromSeed(seed) {
|
7543
|
-
if (seed.length !== KEYS_BYTE_LENGTH) {
|
7544
|
-
throw new TypeError('"seed" must be 32 bytes in length.');
|
7545
|
-
}
|
7546
|
-
else if (!(seed instanceof Uint8Array)) {
|
7547
|
-
throw new TypeError('"seed" must be a node.js Buffer, or Uint8Array.');
|
7548
|
-
}
|
7549
|
-
// based on node forges algorithm, the seed is used directly as private key
|
7550
|
-
const privateKeyRaw = seed;
|
7551
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7552
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7553
|
-
return {
|
7554
|
-
privateKey,
|
7555
|
-
publicKey
|
7556
|
-
};
|
7557
|
-
}
|
7558
|
-
function hashAndSign$2(privateKey, msg) {
|
7559
|
-
const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH);
|
7560
|
-
return ed25519.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw);
|
7561
|
-
}
|
7562
7695
|
function hashAndVerify$2(publicKey, sig, msg) {
|
7563
7696
|
return ed25519.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey);
|
7564
7697
|
}
|
7565
|
-
function concatKeys(privateKeyRaw, publicKey) {
|
7566
|
-
const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH);
|
7567
|
-
for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
|
7568
|
-
privateKey[i] = privateKeyRaw[i];
|
7569
|
-
privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i];
|
7570
|
-
}
|
7571
|
-
return privateKey;
|
7572
|
-
}
|
7573
7698
|
|
7574
|
-
|
7575
|
-
|
7576
|
-
|
7577
|
-
|
7578
|
-
|
7579
|
-
const nativeCrypto = win.crypto;
|
7580
|
-
if (nativeCrypto?.subtle == null) {
|
7581
|
-
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7582
|
-
'The most likely cause of this error is that this page is being accessed ' +
|
7583
|
-
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
7584
|
-
'possible resolutions see ' +
|
7585
|
-
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api'), { code: 'ERR_MISSING_WEB_CRYPTO' });
|
7586
|
-
}
|
7587
|
-
return nativeCrypto;
|
7699
|
+
class Ed25519PublicKey {
|
7700
|
+
type = 'Ed25519';
|
7701
|
+
raw;
|
7702
|
+
constructor(key) {
|
7703
|
+
this.raw = ensureEd25519Key(key, PUBLIC_KEY_BYTE_LENGTH);
|
7588
7704
|
}
|
7589
|
-
|
7590
|
-
|
7591
|
-
// WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
|
7592
|
-
// So, as a workaround, we provide the generated key as a constant. We test that
|
7593
|
-
// this generated key is accurate in test/workaround.spec.ts
|
7594
|
-
// Generated via:
|
7595
|
-
// await crypto.subtle.exportKey('jwk',
|
7596
|
-
// await crypto.subtle.deriveKey(
|
7597
|
-
// { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } },
|
7598
|
-
// await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']),
|
7599
|
-
// { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt'])
|
7600
|
-
// )
|
7601
|
-
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7602
|
-
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7603
|
-
function create(opts) {
|
7604
|
-
const algorithm = 'AES-GCM';
|
7605
|
-
let keyLength = 16;
|
7606
|
-
const nonceLength = 12;
|
7607
|
-
const digest = 'SHA-256';
|
7608
|
-
const saltLength = 16;
|
7609
|
-
const iterations = 32767;
|
7610
|
-
const crypto = webcrypto.get();
|
7611
|
-
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7612
|
-
/**
|
7613
|
-
* Uses the provided password to derive a pbkdf2 key. The key
|
7614
|
-
* will then be used to encrypt the data.
|
7615
|
-
*/
|
7616
|
-
async function encrypt(data, password) {
|
7617
|
-
const salt = crypto.getRandomValues(new Uint8Array(saltLength));
|
7618
|
-
const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
|
7619
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7620
|
-
if (typeof password === 'string') {
|
7621
|
-
password = fromString(password);
|
7622
|
-
}
|
7623
|
-
let cryptoKey;
|
7624
|
-
if (password.length === 0) {
|
7625
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7626
|
-
try {
|
7627
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7628
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7629
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7630
|
-
}
|
7631
|
-
catch {
|
7632
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7633
|
-
}
|
7634
|
-
}
|
7635
|
-
else {
|
7636
|
-
// Derive a key using PBKDF2.
|
7637
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7638
|
-
const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7639
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7640
|
-
}
|
7641
|
-
// Encrypt the string.
|
7642
|
-
const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
|
7643
|
-
return concat$1([salt, aesGcm.iv, new Uint8Array(ciphertext)]);
|
7705
|
+
toMultihash() {
|
7706
|
+
return identity.digest(publicKeyToProtobuf(this));
|
7644
7707
|
}
|
7645
|
-
|
7646
|
-
|
7647
|
-
|
7648
|
-
|
7649
|
-
|
7650
|
-
|
7651
|
-
|
7652
|
-
|
7653
|
-
|
7654
|
-
const ciphertext = data.subarray(saltLength + nonceLength);
|
7655
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7656
|
-
if (typeof password === 'string') {
|
7657
|
-
password = fromString(password);
|
7658
|
-
}
|
7659
|
-
let cryptoKey;
|
7660
|
-
if (password.length === 0) {
|
7661
|
-
try {
|
7662
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7663
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7664
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt']);
|
7665
|
-
}
|
7666
|
-
catch {
|
7667
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']);
|
7668
|
-
}
|
7708
|
+
toCID() {
|
7709
|
+
return CID.createV1(114, this.toMultihash());
|
7710
|
+
}
|
7711
|
+
toString() {
|
7712
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
7713
|
+
}
|
7714
|
+
equals(key) {
|
7715
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
7716
|
+
return false;
|
7669
7717
|
}
|
7670
|
-
|
7671
|
-
|
7672
|
-
|
7673
|
-
|
7674
|
-
|
7675
|
-
}
|
7676
|
-
// Decrypt the string.
|
7677
|
-
const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
|
7678
|
-
return new Uint8Array(plaintext);
|
7679
|
-
}
|
7680
|
-
const cipher = {
|
7681
|
-
encrypt,
|
7682
|
-
decrypt
|
7683
|
-
};
|
7684
|
-
return cipher;
|
7718
|
+
return equals(this.raw, key.raw);
|
7719
|
+
}
|
7720
|
+
verify(data, sig) {
|
7721
|
+
return hashAndVerify$2(this.raw, sig, data);
|
7722
|
+
}
|
7685
7723
|
}
|
7686
7724
|
|
7687
|
-
|
7688
|
-
|
7689
|
-
|
7690
|
-
|
7691
|
-
|
7692
|
-
|
7693
|
-
|
7694
|
-
|
7695
|
-
|
7725
|
+
function unmarshalEd25519PublicKey(bytes) {
|
7726
|
+
bytes = ensureEd25519Key(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
7727
|
+
return new Ed25519PublicKey(bytes);
|
7728
|
+
}
|
7729
|
+
function ensureEd25519Key(key, length) {
|
7730
|
+
key = Uint8Array.from(key ?? []);
|
7731
|
+
if (key.length !== length) {
|
7732
|
+
throw new InvalidParametersError(`Key must be a Uint8Array of length ${length}, got ${key.length}`);
|
7733
|
+
}
|
7734
|
+
return key;
|
7696
7735
|
}
|
7697
7736
|
|
7698
7737
|
const f32 = new Float32Array([-0]);
|
@@ -8901,13 +8940,13 @@ var KeyType;
|
|
8901
8940
|
(function (KeyType) {
|
8902
8941
|
KeyType["RSA"] = "RSA";
|
8903
8942
|
KeyType["Ed25519"] = "Ed25519";
|
8904
|
-
KeyType["
|
8943
|
+
KeyType["secp256k1"] = "secp256k1";
|
8905
8944
|
})(KeyType || (KeyType = {}));
|
8906
8945
|
var __KeyTypeValues;
|
8907
8946
|
(function (__KeyTypeValues) {
|
8908
8947
|
__KeyTypeValues[__KeyTypeValues["RSA"] = 0] = "RSA";
|
8909
8948
|
__KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519";
|
8910
|
-
__KeyTypeValues[__KeyTypeValues["
|
8949
|
+
__KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
|
8911
8950
|
})(__KeyTypeValues || (__KeyTypeValues = {}));
|
8912
8951
|
(function (KeyType) {
|
8913
8952
|
KeyType.codec = () => {
|
@@ -8934,21 +8973,24 @@ var PublicKey;
|
|
8934
8973
|
if (opts.lengthDelimited !== false) {
|
8935
8974
|
w.ldelim();
|
8936
8975
|
}
|
8937
|
-
}, (reader, length) => {
|
8976
|
+
}, (reader, length, opts = {}) => {
|
8938
8977
|
const obj = {};
|
8939
8978
|
const end = length == null ? reader.len : reader.pos + length;
|
8940
8979
|
while (reader.pos < end) {
|
8941
8980
|
const tag = reader.uint32();
|
8942
8981
|
switch (tag >>> 3) {
|
8943
|
-
case 1:
|
8982
|
+
case 1: {
|
8944
8983
|
obj.Type = KeyType.codec().decode(reader);
|
8945
8984
|
break;
|
8946
|
-
|
8985
|
+
}
|
8986
|
+
case 2: {
|
8947
8987
|
obj.Data = reader.bytes();
|
8948
8988
|
break;
|
8949
|
-
|
8989
|
+
}
|
8990
|
+
default: {
|
8950
8991
|
reader.skipType(tag & 7);
|
8951
8992
|
break;
|
8993
|
+
}
|
8952
8994
|
}
|
8953
8995
|
}
|
8954
8996
|
return obj;
|
@@ -8959,8 +9001,8 @@ var PublicKey;
|
|
8959
9001
|
PublicKey.encode = (obj) => {
|
8960
9002
|
return encodeMessage(obj, PublicKey.codec());
|
8961
9003
|
};
|
8962
|
-
PublicKey.decode = (buf) => {
|
8963
|
-
return decodeMessage(buf, PublicKey.codec());
|
9004
|
+
PublicKey.decode = (buf, opts) => {
|
9005
|
+
return decodeMessage(buf, PublicKey.codec(), opts);
|
8964
9006
|
};
|
8965
9007
|
})(PublicKey || (PublicKey = {}));
|
8966
9008
|
var PrivateKey;
|
@@ -8983,21 +9025,24 @@ var PrivateKey;
|
|
8983
9025
|
if (opts.lengthDelimited !== false) {
|
8984
9026
|
w.ldelim();
|
8985
9027
|
}
|
8986
|
-
}, (reader, length) => {
|
9028
|
+
}, (reader, length, opts = {}) => {
|
8987
9029
|
const obj = {};
|
8988
9030
|
const end = length == null ? reader.len : reader.pos + length;
|
8989
9031
|
while (reader.pos < end) {
|
8990
9032
|
const tag = reader.uint32();
|
8991
9033
|
switch (tag >>> 3) {
|
8992
|
-
case 1:
|
9034
|
+
case 1: {
|
8993
9035
|
obj.Type = KeyType.codec().decode(reader);
|
8994
9036
|
break;
|
8995
|
-
|
9037
|
+
}
|
9038
|
+
case 2: {
|
8996
9039
|
obj.Data = reader.bytes();
|
8997
9040
|
break;
|
8998
|
-
|
9041
|
+
}
|
9042
|
+
default: {
|
8999
9043
|
reader.skipType(tag & 7);
|
9000
9044
|
break;
|
9045
|
+
}
|
9001
9046
|
}
|
9002
9047
|
}
|
9003
9048
|
return obj;
|
@@ -9008,290 +9053,15 @@ var PrivateKey;
|
|
9008
9053
|
PrivateKey.encode = (obj) => {
|
9009
9054
|
return encodeMessage(obj, PrivateKey.codec());
|
9010
9055
|
};
|
9011
|
-
PrivateKey.decode = (buf) => {
|
9012
|
-
return decodeMessage(buf, PrivateKey.codec());
|
9056
|
+
PrivateKey.decode = (buf, opts) => {
|
9057
|
+
return decodeMessage(buf, PrivateKey.codec(), opts);
|
9013
9058
|
};
|
9014
9059
|
})(PrivateKey || (PrivateKey = {}));
|
9015
9060
|
|
9016
|
-
class Ed25519PublicKey {
|
9017
|
-
_key;
|
9018
|
-
constructor(key) {
|
9019
|
-
this._key = ensureKey(key, PUBLIC_KEY_BYTE_LENGTH);
|
9020
|
-
}
|
9021
|
-
verify(data, sig) {
|
9022
|
-
return hashAndVerify$2(this._key, sig, data);
|
9023
|
-
}
|
9024
|
-
marshal() {
|
9025
|
-
return this._key;
|
9026
|
-
}
|
9027
|
-
get bytes() {
|
9028
|
-
return PublicKey.encode({
|
9029
|
-
Type: KeyType.Ed25519,
|
9030
|
-
Data: this.marshal()
|
9031
|
-
}).subarray();
|
9032
|
-
}
|
9033
|
-
equals(key) {
|
9034
|
-
return equals(this.bytes, key.bytes);
|
9035
|
-
}
|
9036
|
-
hash() {
|
9037
|
-
const p = sha256$1.digest(this.bytes);
|
9038
|
-
if (isPromise(p)) {
|
9039
|
-
return p.then(({ bytes }) => bytes);
|
9040
|
-
}
|
9041
|
-
return p.bytes;
|
9042
|
-
}
|
9043
|
-
}
|
9044
|
-
class Ed25519PrivateKey {
|
9045
|
-
_key;
|
9046
|
-
_publicKey;
|
9047
|
-
// key - 64 byte Uint8Array containing private key
|
9048
|
-
// publicKey - 32 byte Uint8Array containing public key
|
9049
|
-
constructor(key, publicKey) {
|
9050
|
-
this._key = ensureKey(key, PRIVATE_KEY_BYTE_LENGTH);
|
9051
|
-
this._publicKey = ensureKey(publicKey, PUBLIC_KEY_BYTE_LENGTH);
|
9052
|
-
}
|
9053
|
-
sign(message) {
|
9054
|
-
return hashAndSign$2(this._key, message);
|
9055
|
-
}
|
9056
|
-
get public() {
|
9057
|
-
return new Ed25519PublicKey(this._publicKey);
|
9058
|
-
}
|
9059
|
-
marshal() {
|
9060
|
-
return this._key;
|
9061
|
-
}
|
9062
|
-
get bytes() {
|
9063
|
-
return PrivateKey.encode({
|
9064
|
-
Type: KeyType.Ed25519,
|
9065
|
-
Data: this.marshal()
|
9066
|
-
}).subarray();
|
9067
|
-
}
|
9068
|
-
equals(key) {
|
9069
|
-
return equals(this.bytes, key.bytes);
|
9070
|
-
}
|
9071
|
-
async hash() {
|
9072
|
-
const p = sha256$1.digest(this.bytes);
|
9073
|
-
let bytes;
|
9074
|
-
if (isPromise(p)) {
|
9075
|
-
({ bytes } = await p);
|
9076
|
-
}
|
9077
|
-
else {
|
9078
|
-
bytes = p.bytes;
|
9079
|
-
}
|
9080
|
-
return bytes;
|
9081
|
-
}
|
9082
|
-
/**
|
9083
|
-
* Gets the ID of the key.
|
9084
|
-
*
|
9085
|
-
* The key id is the base58 encoding of the identity multihash containing its public key.
|
9086
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
9087
|
-
* of the PKCS SubjectPublicKeyInfo.
|
9088
|
-
*
|
9089
|
-
* @returns {Promise<string>}
|
9090
|
-
*/
|
9091
|
-
async id() {
|
9092
|
-
const encoding = identity.digest(this.public.bytes);
|
9093
|
-
return base58btc.encode(encoding.bytes).substring(1);
|
9094
|
-
}
|
9095
|
-
/**
|
9096
|
-
* Exports the key into a password protected `format`
|
9097
|
-
*/
|
9098
|
-
async export(password, format = 'libp2p-key') {
|
9099
|
-
if (format === 'libp2p-key') {
|
9100
|
-
return exporter(this.bytes, password);
|
9101
|
-
}
|
9102
|
-
else {
|
9103
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
9104
|
-
}
|
9105
|
-
}
|
9106
|
-
}
|
9107
|
-
function unmarshalEd25519PrivateKey(bytes) {
|
9108
|
-
// Try the old, redundant public key version
|
9109
|
-
if (bytes.length > PRIVATE_KEY_BYTE_LENGTH) {
|
9110
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH + PUBLIC_KEY_BYTE_LENGTH);
|
9111
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9112
|
-
const publicKeyBytes = bytes.subarray(PRIVATE_KEY_BYTE_LENGTH, bytes.length);
|
9113
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9114
|
-
}
|
9115
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH);
|
9116
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9117
|
-
const publicKeyBytes = bytes.subarray(PUBLIC_KEY_BYTE_LENGTH);
|
9118
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9119
|
-
}
|
9120
|
-
function unmarshalEd25519PublicKey(bytes) {
|
9121
|
-
bytes = ensureKey(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
9122
|
-
return new Ed25519PublicKey(bytes);
|
9123
|
-
}
|
9124
|
-
async function generateKeyPair$2() {
|
9125
|
-
const { privateKey, publicKey } = generateKey$2();
|
9126
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9127
|
-
}
|
9128
|
-
async function generateKeyPairFromSeed(seed) {
|
9129
|
-
const { privateKey, publicKey } = generateKeyFromSeed(seed);
|
9130
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9131
|
-
}
|
9132
|
-
function ensureKey(key, length) {
|
9133
|
-
key = Uint8Array.from(key ?? []);
|
9134
|
-
if (key.length !== length) {
|
9135
|
-
throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
|
9136
|
-
}
|
9137
|
-
return key;
|
9138
|
-
}
|
9139
|
-
|
9140
|
-
var Ed25519 = /*#__PURE__*/Object.freeze({
|
9141
|
-
__proto__: null,
|
9142
|
-
Ed25519PrivateKey: Ed25519PrivateKey,
|
9143
|
-
Ed25519PublicKey: Ed25519PublicKey,
|
9144
|
-
generateKeyPair: generateKeyPair$2,
|
9145
|
-
generateKeyPairFromSeed: generateKeyPairFromSeed,
|
9146
|
-
unmarshalEd25519PrivateKey: unmarshalEd25519PrivateKey,
|
9147
|
-
unmarshalEd25519PublicKey: unmarshalEd25519PublicKey
|
9148
|
-
});
|
9149
|
-
|
9150
|
-
/**
|
9151
|
-
* Generates a Uint8Array with length `number` populated by random bytes
|
9152
|
-
*/
|
9153
|
-
function randomBytes(length) {
|
9154
|
-
if (isNaN(length) || length <= 0) {
|
9155
|
-
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
|
9156
|
-
}
|
9157
|
-
return randomBytes$1(length);
|
9158
|
-
}
|
9159
|
-
|
9160
|
-
// HMAC (RFC 2104)
|
9161
|
-
class HMAC extends Hash {
|
9162
|
-
constructor(hash$1, _key) {
|
9163
|
-
super();
|
9164
|
-
this.finished = false;
|
9165
|
-
this.destroyed = false;
|
9166
|
-
hash(hash$1);
|
9167
|
-
const key = toBytes$1(_key);
|
9168
|
-
this.iHash = hash$1.create();
|
9169
|
-
if (typeof this.iHash.update !== 'function')
|
9170
|
-
throw new Error('Expected instance of class which extends utils.Hash');
|
9171
|
-
this.blockLen = this.iHash.blockLen;
|
9172
|
-
this.outputLen = this.iHash.outputLen;
|
9173
|
-
const blockLen = this.blockLen;
|
9174
|
-
const pad = new Uint8Array(blockLen);
|
9175
|
-
// blockLen can be bigger than outputLen
|
9176
|
-
pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
|
9177
|
-
for (let i = 0; i < pad.length; i++)
|
9178
|
-
pad[i] ^= 0x36;
|
9179
|
-
this.iHash.update(pad);
|
9180
|
-
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
9181
|
-
this.oHash = hash$1.create();
|
9182
|
-
// Undo internal XOR && apply outer XOR
|
9183
|
-
for (let i = 0; i < pad.length; i++)
|
9184
|
-
pad[i] ^= 0x36 ^ 0x5c;
|
9185
|
-
this.oHash.update(pad);
|
9186
|
-
pad.fill(0);
|
9187
|
-
}
|
9188
|
-
update(buf) {
|
9189
|
-
exists(this);
|
9190
|
-
this.iHash.update(buf);
|
9191
|
-
return this;
|
9192
|
-
}
|
9193
|
-
digestInto(out) {
|
9194
|
-
exists(this);
|
9195
|
-
bytes(out, this.outputLen);
|
9196
|
-
this.finished = true;
|
9197
|
-
this.iHash.digestInto(out);
|
9198
|
-
this.oHash.update(out);
|
9199
|
-
this.oHash.digestInto(out);
|
9200
|
-
this.destroy();
|
9201
|
-
}
|
9202
|
-
digest() {
|
9203
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
9204
|
-
this.digestInto(out);
|
9205
|
-
return out;
|
9206
|
-
}
|
9207
|
-
_cloneInto(to) {
|
9208
|
-
// Create new instance without calling constructor since key already in state and we don't know it.
|
9209
|
-
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
9210
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
9211
|
-
to = to;
|
9212
|
-
to.finished = finished;
|
9213
|
-
to.destroyed = destroyed;
|
9214
|
-
to.blockLen = blockLen;
|
9215
|
-
to.outputLen = outputLen;
|
9216
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
9217
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
9218
|
-
return to;
|
9219
|
-
}
|
9220
|
-
destroy() {
|
9221
|
-
this.destroyed = true;
|
9222
|
-
this.oHash.destroy();
|
9223
|
-
this.iHash.destroy();
|
9224
|
-
}
|
9225
|
-
}
|
9226
|
-
/**
|
9227
|
-
* HMAC: RFC2104 message authentication code.
|
9228
|
-
* @param hash - function that would be used e.g. sha256
|
9229
|
-
* @param key - message key
|
9230
|
-
* @param message - message data
|
9231
|
-
* @example
|
9232
|
-
* import { hmac } from '@noble/hashes/hmac';
|
9233
|
-
* import { sha256 } from '@noble/hashes/sha2';
|
9234
|
-
* const mac1 = hmac(sha256, 'key', 'message');
|
9235
|
-
*/
|
9236
|
-
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
9237
|
-
hmac.create = (hash, key) => new HMAC(hash, key);
|
9238
|
-
|
9239
|
-
// Common prologue and epilogue for sync/async functions
|
9240
|
-
function pbkdf2Init(hash$1, _password, _salt, _opts) {
|
9241
|
-
hash(hash$1);
|
9242
|
-
const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
|
9243
|
-
const { c, dkLen, asyncTick } = opts;
|
9244
|
-
number(c);
|
9245
|
-
number(dkLen);
|
9246
|
-
number(asyncTick);
|
9247
|
-
if (c < 1)
|
9248
|
-
throw new Error('PBKDF2: iterations (c) should be >= 1');
|
9249
|
-
const password = toBytes$1(_password);
|
9250
|
-
const salt = toBytes$1(_salt);
|
9251
|
-
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
9252
|
-
const DK = new Uint8Array(dkLen);
|
9253
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9254
|
-
const PRF = hmac.create(hash$1, password);
|
9255
|
-
const PRFSalt = PRF._cloneInto().update(salt);
|
9256
|
-
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
|
9257
|
-
}
|
9258
|
-
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
9259
|
-
PRF.destroy();
|
9260
|
-
PRFSalt.destroy();
|
9261
|
-
if (prfW)
|
9262
|
-
prfW.destroy();
|
9263
|
-
u.fill(0);
|
9264
|
-
return DK;
|
9265
|
-
}
|
9266
|
-
async function pbkdf2Async(hash, password, salt, opts) {
|
9267
|
-
const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
9268
|
-
let prfW; // Working copy
|
9269
|
-
const arr = new Uint8Array(4);
|
9270
|
-
const view = createView(arr);
|
9271
|
-
const u = new Uint8Array(PRF.outputLen);
|
9272
|
-
// DK = T1 + T2 + ⋯ + Tdklen/hlen
|
9273
|
-
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
9274
|
-
// Ti = F(Password, Salt, c, i)
|
9275
|
-
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
9276
|
-
view.setInt32(0, ti, false);
|
9277
|
-
// F(Password, Salt, c, i) = U1 ^ U2 ^ ⋯ ^ Uc
|
9278
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9279
|
-
(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
|
9280
|
-
Ti.set(u.subarray(0, Ti.length));
|
9281
|
-
await asyncLoop(c - 1, asyncTick, () => {
|
9282
|
-
// Uc = PRF(Password, Uc−1)
|
9283
|
-
PRF._cloneInto(prfW).update(u).digestInto(u);
|
9284
|
-
for (let i = 0; i < Ti.length; i++)
|
9285
|
-
Ti[i] ^= u[i];
|
9286
|
-
});
|
9287
|
-
}
|
9288
|
-
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
9289
|
-
}
|
9290
|
-
|
9291
9061
|
/*!
|
9292
9062
|
* MIT License
|
9293
9063
|
*
|
9294
|
-
* Copyright (c) 2017-
|
9064
|
+
* Copyright (c) 2017-2024 Peculiar Ventures, LLC
|
9295
9065
|
*
|
9296
9066
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9297
9067
|
* of this software and associated documentation files (the "Software"), to deal
|
@@ -9403,7 +9173,7 @@ class BufferSourceConverter {
|
|
9403
9173
|
}
|
9404
9174
|
|
9405
9175
|
const STRING_TYPE = "string";
|
9406
|
-
const HEX_REGEX = /^[0-9a-f]+$/i;
|
9176
|
+
const HEX_REGEX = /^[0-9a-f\s]+$/i;
|
9407
9177
|
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
9408
9178
|
const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
|
9409
9179
|
class Utf8Converter {
|
@@ -9637,7 +9407,7 @@ class Convert {
|
|
9637
9407
|
return base64;
|
9638
9408
|
}
|
9639
9409
|
static formatString(data) {
|
9640
|
-
return (data === null || data ===
|
9410
|
+
return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
|
9641
9411
|
}
|
9642
9412
|
}
|
9643
9413
|
Convert.DEFAULT_UTF8_ENCODING = "utf8";
|
@@ -9893,7 +9663,7 @@ function HexBlock(BaseClass) {
|
|
9893
9663
|
var _a;
|
9894
9664
|
super(...args);
|
9895
9665
|
const params = args[0] || {};
|
9896
|
-
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !==
|
9666
|
+
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9897
9667
|
this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
9898
9668
|
}
|
9899
9669
|
get valueHex() {
|
@@ -9983,11 +9753,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
|
|
9983
9753
|
var _a, _b, _c, _d;
|
9984
9754
|
super();
|
9985
9755
|
if (idBlock) {
|
9986
|
-
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !==
|
9756
|
+
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9987
9757
|
this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
|
9988
|
-
this.tagClass = (_b = idBlock.tagClass) !== null && _b !==
|
9989
|
-
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !==
|
9990
|
-
this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !==
|
9758
|
+
this.tagClass = (_b = idBlock.tagClass) !== null && _b !== undefined ? _b : -1;
|
9759
|
+
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !== undefined ? _c : -1;
|
9760
|
+
this.isConstructed = (_d = idBlock.isConstructed) !== null && _d !== undefined ? _d : false;
|
9991
9761
|
}
|
9992
9762
|
else {
|
9993
9763
|
this.tagClass = -1;
|
@@ -10154,9 +9924,9 @@ class LocalLengthBlock extends LocalBaseBlock {
|
|
10154
9924
|
constructor({ lenBlock = {}, } = {}) {
|
10155
9925
|
var _a, _b, _c;
|
10156
9926
|
super();
|
10157
|
-
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !==
|
10158
|
-
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !==
|
10159
|
-
this.length = (_c = lenBlock.length) !== null && _c !==
|
9927
|
+
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !== undefined ? _a : false;
|
9928
|
+
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !== undefined ? _b : false;
|
9929
|
+
this.length = (_c = lenBlock.length) !== null && _c !== undefined ? _c : 0;
|
10160
9930
|
}
|
10161
9931
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
10162
9932
|
const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
|
@@ -10928,7 +10698,7 @@ var _a$r;
|
|
10928
10698
|
class OctetString extends BaseBlock {
|
10929
10699
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
10930
10700
|
var _b, _c;
|
10931
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10701
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
10932
10702
|
super({
|
10933
10703
|
idBlock: {
|
10934
10704
|
isConstructed: parameters.isConstructed,
|
@@ -11089,7 +10859,7 @@ var _a$q;
|
|
11089
10859
|
class BitString extends BaseBlock {
|
11090
10860
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
11091
10861
|
var _b, _c;
|
11092
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10862
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
11093
10863
|
super({
|
11094
10864
|
idBlock: {
|
11095
10865
|
isConstructed: parameters.isConstructed,
|
@@ -12291,7 +12061,7 @@ class GeneralizedTime extends UTCTime {
|
|
12291
12061
|
constructor(parameters = {}) {
|
12292
12062
|
var _b;
|
12293
12063
|
super(parameters);
|
12294
|
-
(_b = this.millisecond) !== null && _b !==
|
12064
|
+
(_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
|
12295
12065
|
this.idBlock.tagClass = 1;
|
12296
12066
|
this.idBlock.tagNumber = 24;
|
12297
12067
|
}
|
@@ -12539,52 +12309,101 @@ _a = TIME;
|
|
12539
12309
|
TIME.NAME = "TIME";
|
12540
12310
|
|
12541
12311
|
/**
|
12542
|
-
*
|
12312
|
+
* Signing a message failed
|
12543
12313
|
*/
|
12544
|
-
|
12545
|
-
|
12546
|
-
|
12547
|
-
|
12548
|
-
|
12549
|
-
|
12550
|
-
|
12551
|
-
|
12552
|
-
d: toString$1(bnToBuf(values[3].toBigInt()), 'base64url'),
|
12553
|
-
p: toString$1(bnToBuf(values[4].toBigInt()), 'base64url'),
|
12554
|
-
q: toString$1(bnToBuf(values[5].toBigInt()), 'base64url'),
|
12555
|
-
dp: toString$1(bnToBuf(values[6].toBigInt()), 'base64url'),
|
12556
|
-
dq: toString$1(bnToBuf(values[7].toBigInt()), 'base64url'),
|
12557
|
-
qi: toString$1(bnToBuf(values[8].toBigInt()), 'base64url'),
|
12558
|
-
kty: 'RSA',
|
12559
|
-
alg: 'RS256'
|
12560
|
-
};
|
12561
|
-
return key;
|
12314
|
+
/**
|
12315
|
+
* Verifying a message signature failed
|
12316
|
+
*/
|
12317
|
+
class VerificationError extends Error {
|
12318
|
+
constructor(message = 'An error occurred while verifying a message') {
|
12319
|
+
super(message);
|
12320
|
+
this.name = 'VerificationError';
|
12321
|
+
}
|
12562
12322
|
}
|
12563
12323
|
/**
|
12564
|
-
*
|
12324
|
+
* WebCrypto was not available in the current context
|
12565
12325
|
*/
|
12566
|
-
|
12567
|
-
|
12568
|
-
|
12326
|
+
class WebCryptoMissingError extends Error {
|
12327
|
+
constructor(message = 'Missing Web Crypto API') {
|
12328
|
+
super(message);
|
12329
|
+
this.name = 'WebCryptoMissingError';
|
12330
|
+
}
|
12331
|
+
}
|
12332
|
+
|
12333
|
+
/* eslint-env browser */
|
12334
|
+
// Check native crypto exists and is enabled (In insecure context `self.crypto`
|
12335
|
+
// exists but `self.crypto.subtle` does not).
|
12336
|
+
var webcrypto = {
|
12337
|
+
get(win = globalThis) {
|
12338
|
+
const nativeCrypto = win.crypto;
|
12339
|
+
if (nativeCrypto?.subtle == null) {
|
12340
|
+
throw new WebCryptoMissingError('Missing Web Crypto API. ' +
|
12341
|
+
'The most likely cause of this error is that this page is being accessed ' +
|
12342
|
+
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
12343
|
+
'possible resolutions see ' +
|
12344
|
+
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api');
|
12345
|
+
}
|
12346
|
+
return nativeCrypto;
|
12347
|
+
}
|
12348
|
+
};
|
12349
|
+
|
12350
|
+
async function hashAndVerify$1(key, sig, msg) {
|
12351
|
+
const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12352
|
+
name: 'RSASSA-PKCS1-v1_5',
|
12353
|
+
hash: { name: 'SHA-256' }
|
12354
|
+
}, false, ['verify']);
|
12355
|
+
return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
|
12356
|
+
}
|
12357
|
+
function rsaKeySize(jwk) {
|
12358
|
+
if (jwk.kty !== 'RSA') {
|
12359
|
+
throw new InvalidParametersError('invalid key type');
|
12360
|
+
}
|
12361
|
+
else if (jwk.n == null) {
|
12362
|
+
throw new InvalidParametersError('invalid key modulus');
|
12363
|
+
}
|
12364
|
+
const bytes = fromString(jwk.n, 'base64url');
|
12365
|
+
return bytes.length * 8;
|
12366
|
+
}
|
12367
|
+
|
12368
|
+
class RSAPublicKey {
|
12369
|
+
type = 'RSA';
|
12370
|
+
_key;
|
12371
|
+
_raw;
|
12372
|
+
_multihash;
|
12373
|
+
constructor(key, digest) {
|
12374
|
+
this._key = key;
|
12375
|
+
this._multihash = digest;
|
12376
|
+
}
|
12377
|
+
get raw() {
|
12378
|
+
if (this._raw == null) {
|
12379
|
+
this._raw = jwkToPkix(this._key);
|
12380
|
+
}
|
12381
|
+
return this._raw;
|
12382
|
+
}
|
12383
|
+
toMultihash() {
|
12384
|
+
return this._multihash;
|
12385
|
+
}
|
12386
|
+
toCID() {
|
12387
|
+
return CID.createV1(114, this._multihash);
|
12388
|
+
}
|
12389
|
+
toString() {
|
12390
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
12391
|
+
}
|
12392
|
+
equals(key) {
|
12393
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
12394
|
+
return false;
|
12395
|
+
}
|
12396
|
+
return equals(this.raw, key.raw);
|
12397
|
+
}
|
12398
|
+
verify(data, sig) {
|
12399
|
+
return hashAndVerify$1(this._key, sig, data);
|
12569
12400
|
}
|
12570
|
-
const root = new Sequence({
|
12571
|
-
value: [
|
12572
|
-
new Integer({ value: 0 }),
|
12573
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12574
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url'))),
|
12575
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.d, 'base64url'))),
|
12576
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.p, 'base64url'))),
|
12577
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.q, 'base64url'))),
|
12578
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dp, 'base64url'))),
|
12579
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dq, 'base64url'))),
|
12580
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.qi, 'base64url')))
|
12581
|
-
]
|
12582
|
-
});
|
12583
|
-
const der = root.toBER();
|
12584
|
-
return new Uint8Array(der, 0, der.byteLength);
|
12585
12401
|
}
|
12402
|
+
|
12403
|
+
const MAX_RSA_KEY_SIZE = 8192;
|
12404
|
+
const SHA2_256_CODE = 0x12;
|
12586
12405
|
/**
|
12587
|
-
* Convert a
|
12406
|
+
* Convert a PKIX in ASN1 DER format to a JWK key
|
12588
12407
|
*/
|
12589
12408
|
function pkixToJwk(bytes) {
|
12590
12409
|
const { result } = fromBER(bytes);
|
@@ -12593,16 +12412,16 @@ function pkixToJwk(bytes) {
|
|
12593
12412
|
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12594
12413
|
return {
|
12595
12414
|
kty: 'RSA',
|
12596
|
-
n:
|
12597
|
-
e:
|
12415
|
+
n: asn1jsIntegerToBase64(values[0]),
|
12416
|
+
e: asn1jsIntegerToBase64(values[1])
|
12598
12417
|
};
|
12599
12418
|
}
|
12600
12419
|
/**
|
12601
|
-
* Convert a JWK key to
|
12420
|
+
* Convert a JWK key to PKIX in ASN1 DER format
|
12602
12421
|
*/
|
12603
12422
|
function jwkToPkix(jwk) {
|
12604
12423
|
if (jwk.n == null || jwk.e == null) {
|
12605
|
-
throw new
|
12424
|
+
throw new InvalidParametersError('JWK was missing components');
|
12606
12425
|
}
|
12607
12426
|
const root = new Sequence({
|
12608
12427
|
value: [
|
@@ -12630,21 +12449,13 @@ function jwkToPkix(jwk) {
|
|
12630
12449
|
const der = root.toBER();
|
12631
12450
|
return new Uint8Array(der, 0, der.byteLength);
|
12632
12451
|
}
|
12633
|
-
function
|
12634
|
-
let
|
12635
|
-
|
12636
|
-
|
12637
|
-
|
12638
|
-
const len = hex.length / 2;
|
12639
|
-
const u8 = new Uint8Array(len);
|
12640
|
-
let i = 0;
|
12641
|
-
let j = 0;
|
12642
|
-
while (i < len) {
|
12643
|
-
u8[i] = parseInt(hex.slice(j, j + 2), 16);
|
12644
|
-
i += 1;
|
12645
|
-
j += 2;
|
12452
|
+
function asn1jsIntegerToBase64(int) {
|
12453
|
+
let buf = int.valueBlock.valueHexView;
|
12454
|
+
// chrome rejects values with leading 0s
|
12455
|
+
while (buf[0] === 0) {
|
12456
|
+
buf = buf.subarray(1);
|
12646
12457
|
}
|
12647
|
-
return
|
12458
|
+
return toString$1(buf, 'base64url');
|
12648
12459
|
}
|
12649
12460
|
function bufToBn(u8) {
|
12650
12461
|
const hex = [];
|
@@ -12657,331 +12468,131 @@ function bufToBn(u8) {
|
|
12657
12468
|
});
|
12658
12469
|
return BigInt('0x' + hex.join(''));
|
12659
12470
|
}
|
12660
|
-
|
12661
|
-
|
12662
|
-
|
12663
|
-
|
12664
|
-
const
|
12665
|
-
|
12666
|
-
|
12667
|
-
value: [
|
12668
|
-
// version (0)
|
12669
|
-
new Integer({ value: 0 }),
|
12670
|
-
// privateKeyAlgorithm
|
12671
|
-
new Sequence({
|
12672
|
-
value: [
|
12673
|
-
// rsaEncryption OID
|
12674
|
-
new ObjectIdentifier({
|
12675
|
-
value: '1.2.840.113549.1.1.1'
|
12676
|
-
}),
|
12677
|
-
new Null()
|
12678
|
-
]
|
12679
|
-
}),
|
12680
|
-
// PrivateKey
|
12681
|
-
new OctetString({
|
12682
|
-
valueHex: privateKey.marshal()
|
12683
|
-
})
|
12684
|
-
]
|
12685
|
-
});
|
12686
|
-
const keyBuf = keyWrapper.toBER();
|
12687
|
-
const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
|
12688
|
-
const salt = randomBytes(SALT_LENGTH);
|
12689
|
-
const encryptionKey = await pbkdf2Async(sha512, password, salt, {
|
12690
|
-
c: ITERATIONS,
|
12691
|
-
dkLen: KEY_SIZE
|
12692
|
-
});
|
12693
|
-
const iv = randomBytes(16);
|
12694
|
-
const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
|
12695
|
-
const encrypted = await crypto.subtle.encrypt({
|
12696
|
-
name: 'AES-CBC',
|
12697
|
-
iv
|
12698
|
-
}, cryptoKey, keyArr);
|
12699
|
-
const pbkdf2Params = new Sequence({
|
12700
|
-
value: [
|
12701
|
-
// salt
|
12702
|
-
new OctetString({ valueHex: salt }),
|
12703
|
-
// iteration count
|
12704
|
-
new Integer({ value: ITERATIONS }),
|
12705
|
-
// key length
|
12706
|
-
new Integer({ value: KEY_SIZE }),
|
12707
|
-
// AlgorithmIdentifier
|
12708
|
-
new Sequence({
|
12709
|
-
value: [
|
12710
|
-
// hmacWithSHA512
|
12711
|
-
new ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
|
12712
|
-
new Null()
|
12713
|
-
]
|
12714
|
-
})
|
12715
|
-
]
|
12716
|
-
});
|
12717
|
-
const encryptionAlgorithm = new Sequence({
|
12718
|
-
value: [
|
12719
|
-
// pkcs5PBES2
|
12720
|
-
new ObjectIdentifier({
|
12721
|
-
value: '1.2.840.113549.1.5.13'
|
12722
|
-
}),
|
12723
|
-
new Sequence({
|
12724
|
-
value: [
|
12725
|
-
// keyDerivationFunc
|
12726
|
-
new Sequence({
|
12727
|
-
value: [
|
12728
|
-
// pkcs5PBKDF2
|
12729
|
-
new ObjectIdentifier({
|
12730
|
-
value: '1.2.840.113549.1.5.12'
|
12731
|
-
}),
|
12732
|
-
// PBKDF2-params
|
12733
|
-
pbkdf2Params
|
12734
|
-
]
|
12735
|
-
}),
|
12736
|
-
// encryptionScheme
|
12737
|
-
new Sequence({
|
12738
|
-
value: [
|
12739
|
-
// aes256-CBC
|
12740
|
-
new ObjectIdentifier({
|
12741
|
-
value: '2.16.840.1.101.3.4.1.42'
|
12742
|
-
}),
|
12743
|
-
// iv
|
12744
|
-
new OctetString({
|
12745
|
-
valueHex: iv
|
12746
|
-
})
|
12747
|
-
]
|
12748
|
-
})
|
12749
|
-
]
|
12750
|
-
})
|
12751
|
-
]
|
12752
|
-
});
|
12753
|
-
const finalWrapper = new Sequence({
|
12754
|
-
value: [
|
12755
|
-
encryptionAlgorithm,
|
12756
|
-
new OctetString({ valueHex: encrypted })
|
12757
|
-
]
|
12758
|
-
});
|
12759
|
-
const finalWrapperBuf = finalWrapper.toBER();
|
12760
|
-
const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
|
12761
|
-
return [
|
12762
|
-
'-----BEGIN ENCRYPTED PRIVATE KEY-----',
|
12763
|
-
...toString$1(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
|
12764
|
-
'-----END ENCRYPTED PRIVATE KEY-----'
|
12765
|
-
].join('\n');
|
12766
|
-
}
|
12767
|
-
|
12768
|
-
async function generateKey$1(bits) {
|
12769
|
-
const pair = await webcrypto.get().subtle.generateKey({
|
12770
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12771
|
-
modulusLength: bits,
|
12772
|
-
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
12773
|
-
hash: { name: 'SHA-256' }
|
12774
|
-
}, true, ['sign', 'verify']);
|
12775
|
-
const keys = await exportKey(pair);
|
12776
|
-
return {
|
12777
|
-
privateKey: keys[0],
|
12778
|
-
publicKey: keys[1]
|
12779
|
-
};
|
12780
|
-
}
|
12781
|
-
// Takes a jwk key
|
12782
|
-
async function unmarshalPrivateKey$1(key) {
|
12783
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12784
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12785
|
-
hash: { name: 'SHA-256' }
|
12786
|
-
}, true, ['sign']);
|
12787
|
-
const pair = [
|
12788
|
-
privateKey,
|
12789
|
-
await derivePublicFromPrivate(key)
|
12790
|
-
];
|
12791
|
-
const keys = await exportKey({
|
12792
|
-
privateKey: pair[0],
|
12793
|
-
publicKey: pair[1]
|
12794
|
-
});
|
12795
|
-
return {
|
12796
|
-
privateKey: keys[0],
|
12797
|
-
publicKey: keys[1]
|
12798
|
-
};
|
12799
|
-
}
|
12800
|
-
async function hashAndSign$1(key, msg) {
|
12801
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12802
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12803
|
-
hash: { name: 'SHA-256' }
|
12804
|
-
}, false, ['sign']);
|
12805
|
-
const sig = await webcrypto.get().subtle.sign({ name: 'RSASSA-PKCS1-v1_5' }, privateKey, msg instanceof Uint8Array ? msg : msg.subarray());
|
12806
|
-
return new Uint8Array(sig, 0, sig.byteLength);
|
12807
|
-
}
|
12808
|
-
async function hashAndVerify$1(key, sig, msg) {
|
12809
|
-
const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12810
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12811
|
-
hash: { name: 'SHA-256' }
|
12812
|
-
}, false, ['verify']);
|
12813
|
-
return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
|
12814
|
-
}
|
12815
|
-
async function exportKey(pair) {
|
12816
|
-
if (pair.privateKey == null || pair.publicKey == null) {
|
12817
|
-
throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
|
12818
|
-
}
|
12819
|
-
return Promise.all([
|
12820
|
-
webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
|
12821
|
-
webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
|
12822
|
-
]);
|
12823
|
-
}
|
12824
|
-
async function derivePublicFromPrivate(jwKey) {
|
12825
|
-
return webcrypto.get().subtle.importKey('jwk', {
|
12826
|
-
kty: jwKey.kty,
|
12827
|
-
n: jwKey.n,
|
12828
|
-
e: jwKey.e
|
12829
|
-
}, {
|
12830
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12831
|
-
hash: { name: 'SHA-256' }
|
12832
|
-
}, true, ['verify']);
|
12833
|
-
}
|
12834
|
-
function keySize(jwk) {
|
12835
|
-
if (jwk.kty !== 'RSA') {
|
12836
|
-
throw new CodeError('invalid key type', 'ERR_INVALID_KEY_TYPE');
|
12837
|
-
}
|
12838
|
-
else if (jwk.n == null) {
|
12839
|
-
throw new CodeError('invalid key modulus', 'ERR_INVALID_KEY_MODULUS');
|
12471
|
+
/**
|
12472
|
+
* Turn PKIX bytes to a PublicKey
|
12473
|
+
*/
|
12474
|
+
function pkixToRSAPublicKey(bytes) {
|
12475
|
+
const jwk = pkixToJwk(bytes);
|
12476
|
+
if (rsaKeySize(jwk) > MAX_RSA_KEY_SIZE) {
|
12477
|
+
throw new InvalidPublicKeyError('Key size is too large');
|
12840
12478
|
}
|
12841
|
-
const
|
12842
|
-
|
12479
|
+
const hash = sha256(PublicKey.encode({
|
12480
|
+
Type: KeyType.RSA,
|
12481
|
+
Data: bytes
|
12482
|
+
}));
|
12483
|
+
const digest = create(SHA2_256_CODE, hash);
|
12484
|
+
return new RSAPublicKey(jwk, digest);
|
12843
12485
|
}
|
12844
12486
|
|
12845
|
-
|
12846
|
-
|
12847
|
-
|
12848
|
-
|
12849
|
-
|
12850
|
-
|
12851
|
-
|
12852
|
-
|
12853
|
-
|
12854
|
-
|
12855
|
-
|
12856
|
-
|
12857
|
-
|
12858
|
-
|
12859
|
-
|
12860
|
-
|
12861
|
-
|
12862
|
-
|
12863
|
-
|
12864
|
-
|
12865
|
-
|
12866
|
-
|
12867
|
-
|
12868
|
-
|
12869
|
-
|
12870
|
-
|
12871
|
-
|
12872
|
-
|
12873
|
-
|
12874
|
-
|
12875
|
-
_key;
|
12876
|
-
_publicKey;
|
12877
|
-
constructor(key, publicKey) {
|
12878
|
-
this._key = key;
|
12879
|
-
this._publicKey = publicKey;
|
12880
|
-
}
|
12881
|
-
genSecret() {
|
12882
|
-
return randomBytes(16);
|
12883
|
-
}
|
12884
|
-
sign(message) {
|
12885
|
-
return hashAndSign$1(this._key, message);
|
12886
|
-
}
|
12887
|
-
get public() {
|
12888
|
-
if (this._publicKey == null) {
|
12889
|
-
throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
|
12890
|
-
}
|
12891
|
-
return new RsaPublicKey(this._publicKey);
|
12892
|
-
}
|
12893
|
-
marshal() {
|
12894
|
-
return jwkToPkcs1(this._key);
|
12895
|
-
}
|
12896
|
-
get bytes() {
|
12897
|
-
return PrivateKey.encode({
|
12898
|
-
Type: KeyType.RSA,
|
12899
|
-
Data: this.marshal()
|
12900
|
-
}).subarray();
|
12901
|
-
}
|
12902
|
-
equals(key) {
|
12903
|
-
return equals(this.bytes, key.bytes);
|
12904
|
-
}
|
12905
|
-
hash() {
|
12906
|
-
const p = sha256$1.digest(this.bytes);
|
12907
|
-
if (isPromise(p)) {
|
12908
|
-
return p.then(({ bytes }) => bytes);
|
12909
|
-
}
|
12910
|
-
return p.bytes;
|
12911
|
-
}
|
12912
|
-
/**
|
12913
|
-
* Gets the ID of the key.
|
12914
|
-
*
|
12915
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
12916
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
12917
|
-
* of the PKCS SubjectPublicKeyInfo.
|
12918
|
-
*/
|
12919
|
-
async id() {
|
12920
|
-
const hash = await this.public.hash();
|
12921
|
-
return toString$1(hash, 'base58btc');
|
12487
|
+
/**
|
12488
|
+
* HMAC: RFC2104 message authentication code.
|
12489
|
+
* @module
|
12490
|
+
*/
|
12491
|
+
class HMAC extends Hash {
|
12492
|
+
constructor(hash, _key) {
|
12493
|
+
super();
|
12494
|
+
this.finished = false;
|
12495
|
+
this.destroyed = false;
|
12496
|
+
ahash(hash);
|
12497
|
+
const key = toBytes$1(_key);
|
12498
|
+
this.iHash = hash.create();
|
12499
|
+
if (typeof this.iHash.update !== 'function')
|
12500
|
+
throw new Error('Expected instance of class which extends utils.Hash');
|
12501
|
+
this.blockLen = this.iHash.blockLen;
|
12502
|
+
this.outputLen = this.iHash.outputLen;
|
12503
|
+
const blockLen = this.blockLen;
|
12504
|
+
const pad = new Uint8Array(blockLen);
|
12505
|
+
// blockLen can be bigger than outputLen
|
12506
|
+
pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
|
12507
|
+
for (let i = 0; i < pad.length; i++)
|
12508
|
+
pad[i] ^= 0x36;
|
12509
|
+
this.iHash.update(pad);
|
12510
|
+
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
12511
|
+
this.oHash = hash.create();
|
12512
|
+
// Undo internal XOR && apply outer XOR
|
12513
|
+
for (let i = 0; i < pad.length; i++)
|
12514
|
+
pad[i] ^= 0x36 ^ 0x5c;
|
12515
|
+
this.oHash.update(pad);
|
12516
|
+
pad.fill(0);
|
12922
12517
|
}
|
12923
|
-
|
12924
|
-
|
12925
|
-
|
12926
|
-
|
12927
|
-
* To export it as a password protected PEM file, please use the `exportPEM`
|
12928
|
-
* function from `@libp2p/rsa`.
|
12929
|
-
*/
|
12930
|
-
async export(password, format = 'pkcs-8') {
|
12931
|
-
if (format === 'pkcs-8') {
|
12932
|
-
return exportToPem(this, password);
|
12933
|
-
}
|
12934
|
-
else if (format === 'libp2p-key') {
|
12935
|
-
return exporter(this.bytes, password);
|
12936
|
-
}
|
12937
|
-
else {
|
12938
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
12939
|
-
}
|
12518
|
+
update(buf) {
|
12519
|
+
aexists(this);
|
12520
|
+
this.iHash.update(buf);
|
12521
|
+
return this;
|
12940
12522
|
}
|
12941
|
-
|
12942
|
-
|
12943
|
-
|
12944
|
-
|
12945
|
-
|
12523
|
+
digestInto(out) {
|
12524
|
+
aexists(this);
|
12525
|
+
abytes$1(out, this.outputLen);
|
12526
|
+
this.finished = true;
|
12527
|
+
this.iHash.digestInto(out);
|
12528
|
+
this.oHash.update(out);
|
12529
|
+
this.oHash.digestInto(out);
|
12530
|
+
this.destroy();
|
12946
12531
|
}
|
12947
|
-
|
12948
|
-
|
12949
|
-
|
12950
|
-
|
12951
|
-
const jwk = pkixToJwk(bytes);
|
12952
|
-
if (keySize(jwk) > MAX_RSA_KEY_SIZE) {
|
12953
|
-
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
12532
|
+
digest() {
|
12533
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
12534
|
+
this.digestInto(out);
|
12535
|
+
return out;
|
12954
12536
|
}
|
12955
|
-
|
12956
|
-
|
12957
|
-
|
12958
|
-
|
12959
|
-
|
12537
|
+
_cloneInto(to) {
|
12538
|
+
// Create new instance without calling constructor since key already in state and we don't know it.
|
12539
|
+
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
12540
|
+
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
12541
|
+
to = to;
|
12542
|
+
to.finished = finished;
|
12543
|
+
to.destroyed = destroyed;
|
12544
|
+
to.blockLen = blockLen;
|
12545
|
+
to.outputLen = outputLen;
|
12546
|
+
to.oHash = oHash._cloneInto(to.oHash);
|
12547
|
+
to.iHash = iHash._cloneInto(to.iHash);
|
12548
|
+
return to;
|
12960
12549
|
}
|
12961
|
-
|
12962
|
-
|
12963
|
-
|
12964
|
-
|
12965
|
-
if (bits > MAX_RSA_KEY_SIZE) {
|
12966
|
-
throw new CodeError('key size is too large', 'ERR_KEY_SIZE_TOO_LARGE');
|
12550
|
+
destroy() {
|
12551
|
+
this.destroyed = true;
|
12552
|
+
this.oHash.destroy();
|
12553
|
+
this.iHash.destroy();
|
12967
12554
|
}
|
12968
|
-
const keys = await generateKey$1(bits);
|
12969
|
-
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
12970
12555
|
}
|
12556
|
+
/**
|
12557
|
+
* HMAC: RFC2104 message authentication code.
|
12558
|
+
* @param hash - function that would be used e.g. sha256
|
12559
|
+
* @param key - message key
|
12560
|
+
* @param message - message data
|
12561
|
+
* @example
|
12562
|
+
* import { hmac } from '@noble/hashes/hmac';
|
12563
|
+
* import { sha256 } from '@noble/hashes/sha2';
|
12564
|
+
* const mac1 = hmac(sha256, 'key', 'message');
|
12565
|
+
*/
|
12566
|
+
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
12567
|
+
hmac.create = (hash, key) => new HMAC(hash, key);
|
12971
12568
|
|
12972
|
-
|
12973
|
-
|
12974
|
-
|
12975
|
-
|
12976
|
-
|
12977
|
-
|
12978
|
-
|
12979
|
-
|
12980
|
-
|
12981
|
-
|
12982
|
-
|
12569
|
+
/**
|
12570
|
+
* Short Weierstrass curve methods. The formula is: y² = x³ + ax + b.
|
12571
|
+
*
|
12572
|
+
* ### Design rationale for types
|
12573
|
+
*
|
12574
|
+
* * Interaction between classes from different curves should fail:
|
12575
|
+
* `k256.Point.BASE.add(p256.Point.BASE)`
|
12576
|
+
* * For this purpose we want to use `instanceof` operator, which is fast and works during runtime
|
12577
|
+
* * Different calls of `curve()` would return different classes -
|
12578
|
+
* `curve(params) !== curve(params)`: if somebody decided to monkey-patch their curve,
|
12579
|
+
* it won't affect others
|
12580
|
+
*
|
12581
|
+
* TypeScript can't infer types for classes created inside a function. Classes is one instance
|
12582
|
+
* of nominative types in TypeScript and interfaces only check for shape, so it's hard to create
|
12583
|
+
* unique type for every function call.
|
12584
|
+
*
|
12585
|
+
* We can use generic types via some param, like curve opts, but that would:
|
12586
|
+
* 1. Enable interaction between `curve(params)` and `curve(params)` (curves of same params)
|
12587
|
+
* which is hard to debug.
|
12588
|
+
* 2. Params can be generic and we can't enforce them to be constant value:
|
12589
|
+
* if somebody creates curve from non-constant params,
|
12590
|
+
* it would be allowed to interact with other curves with non-constant params
|
12591
|
+
*
|
12592
|
+
* @todo https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#unique-symbol
|
12593
|
+
* @module
|
12594
|
+
*/
|
12983
12595
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
12984
|
-
// Short Weierstrass curve. The formula is: y² = x³ + ax + b
|
12985
12596
|
function validateSigVerOpts(opts) {
|
12986
12597
|
if (opts.lowS !== undefined)
|
12987
12598
|
abool('lowS', opts.lowS);
|
@@ -13005,17 +12616,22 @@ function validatePointOpts(curve) {
|
|
13005
12616
|
const { endo, Fp, a } = opts;
|
13006
12617
|
if (endo) {
|
13007
12618
|
if (!Fp.eql(a, Fp.ZERO)) {
|
13008
|
-
throw new Error('
|
12619
|
+
throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
|
13009
12620
|
}
|
13010
12621
|
if (typeof endo !== 'object' ||
|
13011
12622
|
typeof endo.beta !== 'bigint' ||
|
13012
12623
|
typeof endo.splitScalar !== 'function') {
|
13013
|
-
throw new Error('
|
12624
|
+
throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
|
13014
12625
|
}
|
13015
12626
|
}
|
13016
12627
|
return Object.freeze({ ...opts });
|
13017
12628
|
}
|
13018
12629
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
12630
|
+
class DERErr extends Error {
|
12631
|
+
constructor(m = '') {
|
12632
|
+
super(m);
|
12633
|
+
}
|
12634
|
+
}
|
13019
12635
|
/**
|
13020
12636
|
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
13021
12637
|
*
|
@@ -13025,11 +12641,7 @@ const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
|
13025
12641
|
*/
|
13026
12642
|
const DER = {
|
13027
12643
|
// asn.1 DER encoding utils
|
13028
|
-
Err:
|
13029
|
-
constructor(m = '') {
|
13030
|
-
super(m);
|
13031
|
-
}
|
13032
|
-
},
|
12644
|
+
Err: DERErr,
|
13033
12645
|
// Basic building block is TLV (Tag-Length-Value)
|
13034
12646
|
_tlv: {
|
13035
12647
|
encode: (tag, data) => {
|
@@ -13044,7 +12656,8 @@ const DER = {
|
|
13044
12656
|
throw new E('tlv.encode: long form length too big');
|
13045
12657
|
// length of length with long form flag
|
13046
12658
|
const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
|
13047
|
-
|
12659
|
+
const t = numberToHexUnpadded(tag);
|
12660
|
+
return t + lenLen + len + data;
|
13048
12661
|
},
|
13049
12662
|
// v - value, l - left bytes (unparsed)
|
13050
12663
|
decode(tag, data) {
|
@@ -13097,15 +12710,15 @@ const DER = {
|
|
13097
12710
|
if (Number.parseInt(hex[0], 16) & 0b1000)
|
13098
12711
|
hex = '00' + hex;
|
13099
12712
|
if (hex.length & 1)
|
13100
|
-
throw new E('unexpected assertion');
|
12713
|
+
throw new E('unexpected DER parsing assertion: unpadded hex');
|
13101
12714
|
return hex;
|
13102
12715
|
},
|
13103
12716
|
decode(data) {
|
13104
12717
|
const { Err: E } = DER;
|
13105
12718
|
if (data[0] & 128)
|
13106
|
-
throw new E('
|
12719
|
+
throw new E('invalid signature integer: negative');
|
13107
12720
|
if (data[0] === 0x00 && !(data[1] & 128))
|
13108
|
-
throw new E('
|
12721
|
+
throw new E('invalid signature integer: unnecessary leading zero');
|
13109
12722
|
return b2n(data);
|
13110
12723
|
},
|
13111
12724
|
},
|
@@ -13116,16 +12729,18 @@ const DER = {
|
|
13116
12729
|
abytes(data);
|
13117
12730
|
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
13118
12731
|
if (seqLeftBytes.length)
|
13119
|
-
throw new E('
|
12732
|
+
throw new E('invalid signature: left bytes after parsing');
|
13120
12733
|
const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
|
13121
12734
|
const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
|
13122
12735
|
if (sLeftBytes.length)
|
13123
|
-
throw new E('
|
12736
|
+
throw new E('invalid signature: left bytes after parsing');
|
13124
12737
|
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
13125
12738
|
},
|
13126
12739
|
hexFromSig(sig) {
|
13127
12740
|
const { _tlv: tlv, _int: int } = DER;
|
13128
|
-
const
|
12741
|
+
const rs = tlv.encode(0x02, int.encode(sig.r));
|
12742
|
+
const ss = tlv.encode(0x02, int.encode(sig.s));
|
12743
|
+
const seq = rs + ss;
|
13129
12744
|
return tlv.encode(0x30, seq);
|
13130
12745
|
},
|
13131
12746
|
};
|
@@ -13179,7 +12794,7 @@ function weierstrassPoints(opts) {
|
|
13179
12794
|
key = bytesToHex(key);
|
13180
12795
|
// Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
|
13181
12796
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
13182
|
-
throw new Error('
|
12797
|
+
throw new Error('invalid private key');
|
13183
12798
|
key = key.padStart(nByteLength * 2, '0');
|
13184
12799
|
}
|
13185
12800
|
let num;
|
@@ -13190,7 +12805,7 @@ function weierstrassPoints(opts) {
|
|
13190
12805
|
: bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
13191
12806
|
}
|
13192
12807
|
catch (error) {
|
13193
|
-
throw new Error(
|
12808
|
+
throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
|
13194
12809
|
}
|
13195
12810
|
if (wrapPrivateKey)
|
13196
12811
|
num = mod(num, N); // disabled by default, enabled for BLS
|
@@ -13230,7 +12845,7 @@ function weierstrassPoints(opts) {
|
|
13230
12845
|
if (p.is0()) {
|
13231
12846
|
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13232
12847
|
// In BLS, ZERO can be serialized, so we allow it.
|
13233
|
-
// (0, 0, 0) is
|
12848
|
+
// (0, 0, 0) is invalid representation of ZERO.
|
13234
12849
|
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
13235
12850
|
return;
|
13236
12851
|
throw new Error('bad point: ZERO');
|
@@ -13454,16 +13069,17 @@ function weierstrassPoints(opts) {
|
|
13454
13069
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13455
13070
|
*/
|
13456
13071
|
multiplyUnsafe(sc) {
|
13457
|
-
|
13072
|
+
const { endo, n: N } = CURVE;
|
13073
|
+
aInRange('scalar', sc, _0n, N);
|
13458
13074
|
const I = Point.ZERO;
|
13459
13075
|
if (sc === _0n)
|
13460
13076
|
return I;
|
13461
|
-
if (sc === _1n$1)
|
13077
|
+
if (this.is0() || sc === _1n$1)
|
13462
13078
|
return this;
|
13463
|
-
|
13464
|
-
if (!endo)
|
13465
|
-
return wnaf.
|
13466
|
-
//
|
13079
|
+
// Case a: no endomorphism. Case b: has precomputes.
|
13080
|
+
if (!endo || wnaf.hasPrecomputes(this))
|
13081
|
+
return wnaf.wNAFCachedUnsafe(this, sc, Point.normalizeZ);
|
13082
|
+
// Case c: endomorphism
|
13467
13083
|
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13468
13084
|
let k1p = I;
|
13469
13085
|
let k2p = I;
|
@@ -13649,7 +13265,9 @@ function weierstrass(curveDef) {
|
|
13649
13265
|
return { x, y };
|
13650
13266
|
}
|
13651
13267
|
else {
|
13652
|
-
|
13268
|
+
const cl = compressedLen;
|
13269
|
+
const ul = uncompressedLen;
|
13270
|
+
throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
|
13653
13271
|
}
|
13654
13272
|
},
|
13655
13273
|
});
|
@@ -13814,6 +13432,9 @@ function weierstrass(curveDef) {
|
|
13814
13432
|
// int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
|
13815
13433
|
const bits2int = CURVE.bits2int ||
|
13816
13434
|
function (bytes) {
|
13435
|
+
// Our custom check "just in case"
|
13436
|
+
if (bytes.length > 8192)
|
13437
|
+
throw new Error('input is too large');
|
13817
13438
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
13818
13439
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
13819
13440
|
const num = bytesToNumberBE(bytes); // check for == u8 done here
|
@@ -13830,15 +13451,15 @@ function weierstrass(curveDef) {
|
|
13830
13451
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13831
13452
|
*/
|
13832
13453
|
function int2octets(num) {
|
13833
|
-
aInRange(
|
13454
|
+
aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
13834
13455
|
// works with order, can have different size than numToField!
|
13835
13456
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13836
13457
|
}
|
13837
13458
|
// Steps A, D of RFC6979 3.2
|
13838
13459
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
13839
13460
|
// Used only in sign, not in verify.
|
13840
|
-
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13841
|
-
// Also it can be bigger for P224 + SHA256
|
13461
|
+
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13462
|
+
// this will be invalid at least for P521. Also it can be bigger for P224 + SHA256
|
13842
13463
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
13843
13464
|
if (['recovered', 'canonical'].some((k) => k in opts))
|
13844
13465
|
throw new Error('sign() legacy options not supported');
|
@@ -13932,39 +13553,48 @@ function weierstrass(curveDef) {
|
|
13932
13553
|
const sg = signature;
|
13933
13554
|
msgHash = ensureBytes('msgHash', msgHash);
|
13934
13555
|
publicKey = ensureBytes('publicKey', publicKey);
|
13556
|
+
const { lowS, prehash, format } = opts;
|
13557
|
+
// Verify opts, deduce signature format
|
13558
|
+
validateSigVerOpts(opts);
|
13935
13559
|
if ('strict' in opts)
|
13936
13560
|
throw new Error('options.strict was renamed to lowS');
|
13937
|
-
|
13938
|
-
|
13561
|
+
if (format !== undefined && format !== 'compact' && format !== 'der')
|
13562
|
+
throw new Error('format must be compact or der');
|
13563
|
+
const isHex = typeof sg === 'string' || isBytes$1(sg);
|
13564
|
+
const isObj = !isHex &&
|
13565
|
+
!format &&
|
13566
|
+
typeof sg === 'object' &&
|
13567
|
+
sg !== null &&
|
13568
|
+
typeof sg.r === 'bigint' &&
|
13569
|
+
typeof sg.s === 'bigint';
|
13570
|
+
if (!isHex && !isObj)
|
13571
|
+
throw new Error('invalid signature, expected Uint8Array, hex string or Signature instance');
|
13939
13572
|
let _sig = undefined;
|
13940
13573
|
let P;
|
13941
13574
|
try {
|
13942
|
-
if (
|
13575
|
+
if (isObj)
|
13576
|
+
_sig = new Signature(sg.r, sg.s);
|
13577
|
+
if (isHex) {
|
13943
13578
|
// Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
|
13944
13579
|
// Since DER can also be 2*nByteLength bytes, we check for it first.
|
13945
13580
|
try {
|
13946
|
-
|
13581
|
+
if (format !== 'compact')
|
13582
|
+
_sig = Signature.fromDER(sg);
|
13947
13583
|
}
|
13948
13584
|
catch (derError) {
|
13949
13585
|
if (!(derError instanceof DER.Err))
|
13950
13586
|
throw derError;
|
13951
|
-
_sig = Signature.fromCompact(sg);
|
13952
13587
|
}
|
13953
|
-
|
13954
|
-
|
13955
|
-
const { r, s } = sg;
|
13956
|
-
_sig = new Signature(r, s);
|
13957
|
-
}
|
13958
|
-
else {
|
13959
|
-
throw new Error('PARSE');
|
13588
|
+
if (!_sig && format !== 'der')
|
13589
|
+
_sig = Signature.fromCompact(sg);
|
13960
13590
|
}
|
13961
13591
|
P = Point.fromHex(publicKey);
|
13962
13592
|
}
|
13963
13593
|
catch (error) {
|
13964
|
-
if (error.message === 'PARSE')
|
13965
|
-
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
13966
13594
|
return false;
|
13967
13595
|
}
|
13596
|
+
if (!_sig)
|
13597
|
+
return false;
|
13968
13598
|
if (lowS && _sig.hasHighS())
|
13969
13599
|
return false;
|
13970
13600
|
if (prehash)
|
@@ -13992,20 +13622,36 @@ function weierstrass(curveDef) {
|
|
13992
13622
|
};
|
13993
13623
|
}
|
13994
13624
|
|
13625
|
+
/**
|
13626
|
+
* Utilities for short weierstrass curves, combined with noble-hashes.
|
13627
|
+
* @module
|
13628
|
+
*/
|
13995
13629
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13996
|
-
|
13630
|
+
/** connects noble-curves to noble-hashes */
|
13997
13631
|
function getHash(hash) {
|
13998
13632
|
return {
|
13999
13633
|
hash,
|
14000
13634
|
hmac: (key, ...msgs) => hmac(hash, key, concatBytes$1(...msgs)),
|
14001
|
-
randomBytes
|
13635
|
+
randomBytes,
|
14002
13636
|
};
|
14003
13637
|
}
|
14004
13638
|
function createCurve(curveDef, defHash) {
|
14005
13639
|
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
14006
|
-
return
|
13640
|
+
return { ...create(defHash), create };
|
14007
13641
|
}
|
14008
13642
|
|
13643
|
+
/**
|
13644
|
+
* NIST secp256k1. See [pdf](https://www.secg.org/sec2-v2.pdf).
|
13645
|
+
*
|
13646
|
+
* Seems to be rigid (not backdoored)
|
13647
|
+
* [as per discussion](https://bitcointalk.org/index.php?topic=289795.msg3183975#msg3183975).
|
13648
|
+
*
|
13649
|
+
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
13650
|
+
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
13651
|
+
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
13652
|
+
* [See explanation](https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066).
|
13653
|
+
* @module
|
13654
|
+
*/
|
14009
13655
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
14010
13656
|
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
14011
13657
|
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
@@ -14036,31 +13682,35 @@ function sqrtMod(y) {
|
|
14036
13682
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
14037
13683
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
14038
13684
|
const root = pow2(t2, _2n, P);
|
14039
|
-
if (!
|
13685
|
+
if (!Fpk1.eql(Fpk1.sqr(root), y))
|
14040
13686
|
throw new Error('Cannot find square root');
|
14041
13687
|
return root;
|
14042
13688
|
}
|
14043
|
-
const
|
13689
|
+
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
14044
13690
|
/**
|
14045
13691
|
* secp256k1 short weierstrass curve and ECDSA signatures over it.
|
13692
|
+
*
|
13693
|
+
* @example
|
13694
|
+
* import { secp256k1 } from '@noble/curves/secp256k1';
|
13695
|
+
*
|
13696
|
+
* const priv = secp256k1.utils.randomPrivateKey();
|
13697
|
+
* const pub = secp256k1.getPublicKey(priv);
|
13698
|
+
* const msg = new Uint8Array(32).fill(1); // message hash (not message) in ecdsa
|
13699
|
+
* const sig = secp256k1.sign(msg, priv); // `{prehash: true}` option is available
|
13700
|
+
* const isValid = secp256k1.verify(sig, msg, pub) === true;
|
14046
13701
|
*/
|
14047
13702
|
const secp256k1 = createCurve({
|
14048
13703
|
a: BigInt(0), // equation params: a, b
|
14049
|
-
b: BigInt(7),
|
14050
|
-
Fp, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
13704
|
+
b: BigInt(7),
|
13705
|
+
Fp: Fpk1, // Field's prime: 2n**256n - 2n**32n - 2n**9n - 2n**8n - 2n**7n - 2n**6n - 2n**4n - 1n
|
14051
13706
|
n: secp256k1N, // Curve order, total count of valid points in the field
|
14052
13707
|
// Base point (x, y) aka generator point
|
14053
13708
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
14054
13709
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
14055
13710
|
h: BigInt(1), // Cofactor
|
14056
13711
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
14057
|
-
/**
|
14058
|
-
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
14059
|
-
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
14060
|
-
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
14061
|
-
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
14062
|
-
*/
|
14063
13712
|
endo: {
|
13713
|
+
// Endomorphism, see above
|
14064
13714
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
14065
13715
|
splitScalar: (k) => {
|
14066
13716
|
const n = secp256k1N;
|
@@ -14091,27 +13741,15 @@ const secp256k1 = createCurve({
|
|
14091
13741
|
BigInt(0);
|
14092
13742
|
secp256k1.ProjectivePoint;
|
14093
13743
|
|
14094
|
-
function
|
14095
|
-
|
14096
|
-
|
14097
|
-
/**
|
14098
|
-
* Hash and sign message with private key
|
14099
|
-
*/
|
14100
|
-
function hashAndSign(key, msg) {
|
14101
|
-
const p = sha256$1.digest(msg instanceof Uint8Array ? msg : msg.subarray());
|
14102
|
-
if (isPromise(p)) {
|
14103
|
-
return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
|
14104
|
-
.catch(err => {
|
14105
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
14106
|
-
});
|
14107
|
-
}
|
14108
|
-
try {
|
14109
|
-
return secp256k1.sign(p.digest, key).toDERRawBytes();
|
14110
|
-
}
|
14111
|
-
catch (err) {
|
14112
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
13744
|
+
function isPromise(thing) {
|
13745
|
+
if (thing == null) {
|
13746
|
+
return false;
|
14113
13747
|
}
|
13748
|
+
return typeof thing.then === 'function' &&
|
13749
|
+
typeof thing.catch === 'function' &&
|
13750
|
+
typeof thing.finally === 'function';
|
14114
13751
|
}
|
13752
|
+
|
14115
13753
|
/**
|
14116
13754
|
* Hash message and verify signature with public key
|
14117
13755
|
*/
|
@@ -14120,208 +13758,93 @@ function hashAndVerify(key, sig, msg) {
|
|
14120
13758
|
if (isPromise(p)) {
|
14121
13759
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
14122
13760
|
.catch(err => {
|
14123
|
-
throw new
|
13761
|
+
throw new VerificationError(String(err));
|
14124
13762
|
});
|
14125
13763
|
}
|
14126
13764
|
try {
|
14127
13765
|
return secp256k1.verify(sig, p.digest, key);
|
14128
13766
|
}
|
14129
13767
|
catch (err) {
|
14130
|
-
throw new
|
14131
|
-
}
|
14132
|
-
}
|
14133
|
-
function compressPublicKey(key) {
|
14134
|
-
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
14135
|
-
return point;
|
14136
|
-
}
|
14137
|
-
function validatePrivateKey(key) {
|
14138
|
-
try {
|
14139
|
-
secp256k1.getPublicKey(key, true);
|
14140
|
-
}
|
14141
|
-
catch (err) {
|
14142
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
14143
|
-
}
|
14144
|
-
}
|
14145
|
-
function validatePublicKey(key) {
|
14146
|
-
try {
|
14147
|
-
secp256k1.ProjectivePoint.fromHex(key);
|
14148
|
-
}
|
14149
|
-
catch (err) {
|
14150
|
-
throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
|
14151
|
-
}
|
14152
|
-
}
|
14153
|
-
function computePublicKey(privateKey) {
|
14154
|
-
try {
|
14155
|
-
return secp256k1.getPublicKey(privateKey, true);
|
14156
|
-
}
|
14157
|
-
catch (err) {
|
14158
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
13768
|
+
throw new VerificationError(String(err));
|
14159
13769
|
}
|
14160
13770
|
}
|
14161
13771
|
|
14162
13772
|
class Secp256k1PublicKey {
|
13773
|
+
type = 'secp256k1';
|
13774
|
+
raw;
|
14163
13775
|
_key;
|
14164
13776
|
constructor(key) {
|
14165
|
-
|
14166
|
-
this.
|
14167
|
-
}
|
14168
|
-
verify(data, sig) {
|
14169
|
-
return hashAndVerify(this._key, sig, data);
|
14170
|
-
}
|
14171
|
-
marshal() {
|
14172
|
-
return compressPublicKey(this._key);
|
14173
|
-
}
|
14174
|
-
get bytes() {
|
14175
|
-
return PublicKey.encode({
|
14176
|
-
Type: KeyType.Secp256k1,
|
14177
|
-
Data: this.marshal()
|
14178
|
-
}).subarray();
|
14179
|
-
}
|
14180
|
-
equals(key) {
|
14181
|
-
return equals(this.bytes, key.bytes);
|
13777
|
+
this._key = validateSecp256k1PublicKey(key);
|
13778
|
+
this.raw = compressSecp256k1PublicKey(this._key);
|
14182
13779
|
}
|
14183
|
-
|
14184
|
-
|
14185
|
-
let bytes;
|
14186
|
-
if (isPromise(p)) {
|
14187
|
-
({ bytes } = await p);
|
14188
|
-
}
|
14189
|
-
else {
|
14190
|
-
bytes = p.bytes;
|
14191
|
-
}
|
14192
|
-
return bytes;
|
14193
|
-
}
|
14194
|
-
}
|
14195
|
-
class Secp256k1PrivateKey {
|
14196
|
-
_key;
|
14197
|
-
_publicKey;
|
14198
|
-
constructor(key, publicKey) {
|
14199
|
-
this._key = key;
|
14200
|
-
this._publicKey = publicKey ?? computePublicKey(key);
|
14201
|
-
validatePrivateKey(this._key);
|
14202
|
-
validatePublicKey(this._publicKey);
|
14203
|
-
}
|
14204
|
-
sign(message) {
|
14205
|
-
return hashAndSign(this._key, message);
|
13780
|
+
toMultihash() {
|
13781
|
+
return identity.digest(publicKeyToProtobuf(this));
|
14206
13782
|
}
|
14207
|
-
|
14208
|
-
return
|
14209
|
-
}
|
14210
|
-
marshal() {
|
14211
|
-
return this._key;
|
13783
|
+
toCID() {
|
13784
|
+
return CID.createV1(114, this.toMultihash());
|
14212
13785
|
}
|
14213
|
-
|
14214
|
-
return
|
14215
|
-
Type: KeyType.Secp256k1,
|
14216
|
-
Data: this.marshal()
|
14217
|
-
}).subarray();
|
13786
|
+
toString() {
|
13787
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
14218
13788
|
}
|
14219
13789
|
equals(key) {
|
14220
|
-
|
14221
|
-
|
14222
|
-
hash() {
|
14223
|
-
const p = sha256$1.digest(this.bytes);
|
14224
|
-
if (isPromise(p)) {
|
14225
|
-
return p.then(({ bytes }) => bytes);
|
13790
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
13791
|
+
return false;
|
14226
13792
|
}
|
14227
|
-
return
|
14228
|
-
}
|
14229
|
-
/**
|
14230
|
-
* Gets the ID of the key.
|
14231
|
-
*
|
14232
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
14233
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
14234
|
-
* of the PKCS SubjectPublicKeyInfo.
|
14235
|
-
*/
|
14236
|
-
async id() {
|
14237
|
-
const hash = await this.public.hash();
|
14238
|
-
return toString$1(hash, 'base58btc');
|
13793
|
+
return equals(this.raw, key.raw);
|
14239
13794
|
}
|
14240
|
-
|
14241
|
-
|
14242
|
-
*/
|
14243
|
-
async export(password, format = 'libp2p-key') {
|
14244
|
-
if (format === 'libp2p-key') {
|
14245
|
-
return exporter(this.bytes, password);
|
14246
|
-
}
|
14247
|
-
else {
|
14248
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
14249
|
-
}
|
13795
|
+
verify(data, sig) {
|
13796
|
+
return hashAndVerify(this._key, sig, data);
|
14250
13797
|
}
|
14251
13798
|
}
|
14252
|
-
|
14253
|
-
return new Secp256k1PrivateKey(bytes);
|
14254
|
-
}
|
13799
|
+
|
14255
13800
|
function unmarshalSecp256k1PublicKey(bytes) {
|
14256
13801
|
return new Secp256k1PublicKey(bytes);
|
14257
13802
|
}
|
14258
|
-
|
14259
|
-
const
|
14260
|
-
return
|
13803
|
+
function compressSecp256k1PublicKey(key) {
|
13804
|
+
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
13805
|
+
return point;
|
13806
|
+
}
|
13807
|
+
function validateSecp256k1PublicKey(key) {
|
13808
|
+
try {
|
13809
|
+
secp256k1.ProjectivePoint.fromHex(key);
|
13810
|
+
return key;
|
13811
|
+
}
|
13812
|
+
catch (err) {
|
13813
|
+
throw new InvalidPublicKeyError(String(err));
|
13814
|
+
}
|
14261
13815
|
}
|
14262
|
-
|
14263
|
-
var Secp256k1 = /*#__PURE__*/Object.freeze({
|
14264
|
-
__proto__: null,
|
14265
|
-
Secp256k1PrivateKey: Secp256k1PrivateKey,
|
14266
|
-
Secp256k1PublicKey: Secp256k1PublicKey,
|
14267
|
-
generateKeyPair: generateKeyPair,
|
14268
|
-
unmarshalSecp256k1PrivateKey: unmarshalSecp256k1PrivateKey,
|
14269
|
-
unmarshalSecp256k1PublicKey: unmarshalSecp256k1PublicKey
|
14270
|
-
});
|
14271
13816
|
|
14272
13817
|
/**
|
14273
13818
|
* @packageDocumentation
|
14274
13819
|
*
|
14275
|
-
*
|
14276
|
-
*
|
14277
|
-
* The {@link generateKeyPair}, {@link marshalPublicKey}, and {@link marshalPrivateKey} functions accept a string `type` argument.
|
13820
|
+
* ## Supported Key Types
|
14278
13821
|
*
|
14279
13822
|
* Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages.
|
14280
13823
|
*
|
14281
13824
|
* For encryption / decryption support, RSA keys should be used.
|
14282
13825
|
*/
|
14283
|
-
const supportedKeys = {
|
14284
|
-
rsa: RSA,
|
14285
|
-
ed25519: Ed25519,
|
14286
|
-
secp256k1: Secp256k1
|
14287
|
-
};
|
14288
|
-
function unsupportedKey(type) {
|
14289
|
-
const supported = Object.keys(supportedKeys).join(' / ');
|
14290
|
-
return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
|
14291
|
-
}
|
14292
13826
|
/**
|
14293
|
-
*
|
13827
|
+
* Creates a public key from the raw key bytes
|
14294
13828
|
*/
|
14295
|
-
function
|
14296
|
-
|
14297
|
-
|
14298
|
-
|
14299
|
-
|
14300
|
-
|
14301
|
-
|
14302
|
-
|
14303
|
-
|
14304
|
-
return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data);
|
14305
|
-
default:
|
14306
|
-
throw unsupportedKey(decoded.Type ?? 'unknown');
|
13829
|
+
function publicKeyFromRaw(buf) {
|
13830
|
+
if (buf.byteLength === 32) {
|
13831
|
+
return unmarshalEd25519PublicKey(buf);
|
13832
|
+
}
|
13833
|
+
else if (buf.byteLength === 33) {
|
13834
|
+
return unmarshalSecp256k1PublicKey(buf);
|
13835
|
+
}
|
13836
|
+
else {
|
13837
|
+
return pkixToRSAPublicKey(buf);
|
14307
13838
|
}
|
14308
13839
|
}
|
14309
13840
|
/**
|
14310
|
-
* Converts a
|
13841
|
+
* Converts a public key object into a protobuf serialized public key
|
14311
13842
|
*/
|
14312
|
-
|
14313
|
-
|
14314
|
-
|
14315
|
-
|
14316
|
-
|
14317
|
-
return supportedKeys.rsa.unmarshalRsaPrivateKey(data);
|
14318
|
-
case KeyType.Ed25519:
|
14319
|
-
return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data);
|
14320
|
-
case KeyType.Secp256k1:
|
14321
|
-
return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data);
|
14322
|
-
default:
|
14323
|
-
throw unsupportedKey(decoded.Type ?? 'RSA');
|
14324
|
-
}
|
13843
|
+
function publicKeyToProtobuf(key) {
|
13844
|
+
return PublicKey.encode({
|
13845
|
+
Type: KeyType[key.type],
|
13846
|
+
Data: key.raw
|
13847
|
+
});
|
14325
13848
|
}
|
14326
13849
|
|
14327
13850
|
/**
|
@@ -14340,25 +13863,16 @@ async function unmarshalPrivateKey(buf) {
|
|
14340
13863
|
* ```
|
14341
13864
|
*/
|
14342
13865
|
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
14343
|
-
const baseDecoder = Object
|
14344
|
-
.values(bases)
|
14345
|
-
.map(codec => codec.decoder)
|
14346
|
-
// @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
|
14347
|
-
.reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
|
14348
13866
|
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14349
13867
|
const LIBP2P_KEY_CODE = 0x72;
|
14350
|
-
const MARSHALLED_ED225519_PUBLIC_KEY_LENGTH = 36;
|
14351
|
-
const MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH = 37;
|
14352
13868
|
class PeerIdImpl {
|
14353
13869
|
type;
|
14354
13870
|
multihash;
|
14355
|
-
privateKey;
|
14356
13871
|
publicKey;
|
14357
13872
|
string;
|
14358
13873
|
constructor(init) {
|
14359
13874
|
this.type = init.type;
|
14360
13875
|
this.multihash = init.multihash;
|
14361
|
-
this.privateKey = init.privateKey;
|
14362
13876
|
// mark string cache as non-enumerable
|
14363
13877
|
Object.defineProperty(this, 'string', {
|
14364
13878
|
enumerable: false,
|
@@ -14375,17 +13889,14 @@ class PeerIdImpl {
|
|
14375
13889
|
}
|
14376
13890
|
return this.string;
|
14377
13891
|
}
|
13892
|
+
toMultihash() {
|
13893
|
+
return this.multihash;
|
13894
|
+
}
|
14378
13895
|
// return self-describing String representation
|
14379
13896
|
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
14380
13897
|
toCID() {
|
14381
13898
|
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
14382
13899
|
}
|
14383
|
-
toBytes() {
|
14384
|
-
return this.multihash.bytes;
|
14385
|
-
}
|
14386
|
-
/**
|
14387
|
-
* Returns Multiaddr as a JSON string
|
14388
|
-
*/
|
14389
13900
|
toJSON() {
|
14390
13901
|
return this.toString();
|
14391
13902
|
}
|
@@ -14400,10 +13911,10 @@ class PeerIdImpl {
|
|
14400
13911
|
return equals(this.multihash.bytes, id);
|
14401
13912
|
}
|
14402
13913
|
else if (typeof id === 'string') {
|
14403
|
-
return
|
13914
|
+
return this.toString() === id;
|
14404
13915
|
}
|
14405
|
-
else if (id?.
|
14406
|
-
return equals(this.multihash.bytes, id.
|
13916
|
+
else if (id?.toMultihash()?.bytes != null) {
|
13917
|
+
return equals(this.multihash.bytes, id.toMultihash().bytes);
|
14407
13918
|
}
|
14408
13919
|
else {
|
14409
13920
|
throw new Error('not valid Id');
|
@@ -14425,7 +13936,7 @@ class PeerIdImpl {
|
|
14425
13936
|
return `PeerId(${this.toString()})`;
|
14426
13937
|
}
|
14427
13938
|
}
|
14428
|
-
class
|
13939
|
+
class RSAPeerId extends PeerIdImpl {
|
14429
13940
|
type = 'RSA';
|
14430
13941
|
publicKey;
|
14431
13942
|
constructor(init) {
|
@@ -14433,153 +13944,67 @@ class RSAPeerIdImpl extends PeerIdImpl {
|
|
14433
13944
|
this.publicKey = init.publicKey;
|
14434
13945
|
}
|
14435
13946
|
}
|
14436
|
-
class
|
13947
|
+
class Ed25519PeerId extends PeerIdImpl {
|
14437
13948
|
type = 'Ed25519';
|
14438
13949
|
publicKey;
|
14439
13950
|
constructor(init) {
|
14440
13951
|
super({ ...init, type: 'Ed25519' });
|
14441
|
-
this.publicKey = init.
|
13952
|
+
this.publicKey = init.publicKey;
|
14442
13953
|
}
|
14443
13954
|
}
|
14444
|
-
class
|
13955
|
+
class Secp256k1PeerId extends PeerIdImpl {
|
14445
13956
|
type = 'secp256k1';
|
14446
13957
|
publicKey;
|
14447
13958
|
constructor(init) {
|
14448
13959
|
super({ ...init, type: 'secp256k1' });
|
14449
|
-
this.publicKey = init.
|
14450
|
-
}
|
14451
|
-
}
|
14452
|
-
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14453
|
-
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
14454
|
-
class URLPeerIdImpl {
|
14455
|
-
type = 'url';
|
14456
|
-
multihash;
|
14457
|
-
privateKey;
|
14458
|
-
publicKey;
|
14459
|
-
url;
|
14460
|
-
constructor(url) {
|
14461
|
-
this.url = url.toString();
|
14462
|
-
this.multihash = identity.digest(fromString(this.url));
|
14463
|
-
}
|
14464
|
-
[inspect]() {
|
14465
|
-
return `PeerId(${this.url})`;
|
14466
|
-
}
|
14467
|
-
[peerIdSymbol] = true;
|
14468
|
-
toString() {
|
14469
|
-
return this.toCID().toString();
|
14470
|
-
}
|
14471
|
-
toCID() {
|
14472
|
-
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
|
14473
|
-
}
|
14474
|
-
toBytes() {
|
14475
|
-
return this.toCID().bytes;
|
14476
|
-
}
|
14477
|
-
equals(other) {
|
14478
|
-
if (other == null) {
|
14479
|
-
return false;
|
14480
|
-
}
|
14481
|
-
if (other instanceof Uint8Array) {
|
14482
|
-
other = toString$1(other);
|
14483
|
-
}
|
14484
|
-
return other.toString() === this.toString();
|
14485
|
-
}
|
14486
|
-
}
|
14487
|
-
function peerIdFromString(str, decoder) {
|
14488
|
-
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14489
|
-
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
14490
|
-
// rsa public key - base58btc encoded either way
|
14491
|
-
const multihash = decode$2(base58btc.decode(`z${str}`));
|
14492
|
-
if (str.startsWith('12D')) {
|
14493
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14494
|
-
}
|
14495
|
-
else if (str.startsWith('16U')) {
|
14496
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14497
|
-
}
|
14498
|
-
else {
|
14499
|
-
return new RSAPeerIdImpl({ multihash });
|
14500
|
-
}
|
14501
|
-
}
|
14502
|
-
return peerIdFromBytes(baseDecoder.decode(str));
|
14503
|
-
}
|
14504
|
-
function peerIdFromBytes(buf) {
|
14505
|
-
try {
|
14506
|
-
const multihash = decode$2(buf);
|
14507
|
-
if (multihash.code === identity.code) {
|
14508
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14509
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14510
|
-
}
|
14511
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14512
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14513
|
-
}
|
14514
|
-
}
|
14515
|
-
if (multihash.code === sha256$1.code) {
|
14516
|
-
return new RSAPeerIdImpl({ multihash });
|
14517
|
-
}
|
14518
|
-
}
|
14519
|
-
catch {
|
14520
|
-
return peerIdFromCID(CID.decode(buf));
|
14521
|
-
}
|
14522
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14523
|
-
}
|
14524
|
-
function peerIdFromCID(cid) {
|
14525
|
-
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
|
14526
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14527
|
-
}
|
14528
|
-
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
|
14529
|
-
const url = toString$1(cid.multihash.digest);
|
14530
|
-
return new URLPeerIdImpl(new URL(url));
|
14531
|
-
}
|
14532
|
-
const multihash = cid.multihash;
|
14533
|
-
if (multihash.code === sha256$1.code) {
|
14534
|
-
return new RSAPeerIdImpl({ multihash: cid.multihash });
|
14535
|
-
}
|
14536
|
-
else if (multihash.code === identity.code) {
|
14537
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14538
|
-
return new Ed25519PeerIdImpl({ multihash: cid.multihash });
|
14539
|
-
}
|
14540
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14541
|
-
return new Secp256k1PeerIdImpl({ multihash: cid.multihash });
|
14542
|
-
}
|
13960
|
+
this.publicKey = init.publicKey;
|
14543
13961
|
}
|
14544
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14545
13962
|
}
|
13963
|
+
|
14546
13964
|
/**
|
14547
|
-
* @
|
14548
|
-
*
|
13965
|
+
* @packageDocumentation
|
13966
|
+
*
|
13967
|
+
* An implementation of a peer id
|
13968
|
+
*
|
13969
|
+
* @example
|
13970
|
+
*
|
13971
|
+
* ```TypeScript
|
13972
|
+
* import { peerIdFromString } from '@libp2p/peer-id'
|
13973
|
+
* const peer = peerIdFromString('12D3KooWKnDdG3iXw9eTFijk3EWSunZcFi54Zka4wmtqtt6rPxc8')
|
13974
|
+
*
|
13975
|
+
* console.log(peer.toCID()) // CID(bafzaa...)
|
13976
|
+
* console.log(peer.toString()) // "12D3K..."
|
13977
|
+
* ```
|
14549
13978
|
*/
|
14550
|
-
|
14551
|
-
if (publicKey.
|
14552
|
-
return new
|
13979
|
+
function peerIdFromPublicKey(publicKey) {
|
13980
|
+
if (publicKey.type === 'Ed25519') {
|
13981
|
+
return new Ed25519PeerId({
|
13982
|
+
multihash: publicKey.toCID().multihash,
|
13983
|
+
publicKey
|
13984
|
+
});
|
14553
13985
|
}
|
14554
|
-
if (publicKey.
|
14555
|
-
return new
|
13986
|
+
else if (publicKey.type === 'secp256k1') {
|
13987
|
+
return new Secp256k1PeerId({
|
13988
|
+
multihash: publicKey.toCID().multihash,
|
13989
|
+
publicKey
|
13990
|
+
});
|
13991
|
+
}
|
13992
|
+
else if (publicKey.type === 'RSA') {
|
13993
|
+
return new RSAPeerId({
|
13994
|
+
multihash: publicKey.toCID().multihash,
|
13995
|
+
publicKey
|
13996
|
+
});
|
14556
13997
|
}
|
14557
|
-
|
13998
|
+
throw new UnsupportedKeyTypeError();
|
14558
13999
|
}
|
14559
14000
|
|
14001
|
+
const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented";
|
14560
14002
|
function createPeerIdFromPublicKey(publicKey) {
|
14561
|
-
const
|
14562
|
-
|
14563
|
-
|
14564
|
-
function getPublicKeyFromPeerId(peerId) {
|
14565
|
-
if (peerId.type !== "secp256k1") {
|
14566
|
-
throw new Error("Unsupported peer id type");
|
14567
|
-
}
|
14568
|
-
if (!peerId.publicKey) {
|
14569
|
-
throw new Error("Public key not present on peer id");
|
14570
|
-
}
|
14571
|
-
return unmarshalPublicKey(peerId.publicKey).marshal();
|
14572
|
-
}
|
14573
|
-
// Only used in tests
|
14574
|
-
async function getPrivateKeyFromPeerId(peerId) {
|
14575
|
-
if (peerId.type !== "secp256k1") {
|
14576
|
-
throw new Error("Unsupported peer id type");
|
14577
|
-
}
|
14578
|
-
if (!peerId.privateKey) {
|
14579
|
-
throw new Error("Private key not present on peer id");
|
14003
|
+
const pubKey = publicKeyFromRaw(publicKey);
|
14004
|
+
if (pubKey.type !== "secp256k1") {
|
14005
|
+
throw new Error(ERR_TYPE_NOT_IMPLEMENTED);
|
14580
14006
|
}
|
14581
|
-
|
14582
|
-
return privateKey.marshal();
|
14007
|
+
return peerIdFromPublicKey(pubKey);
|
14583
14008
|
}
|
14584
14009
|
|
14585
14010
|
function decodeMultiaddrs(bytes) {
|
@@ -14826,12 +14251,12 @@ var TransportProtocolPerIpVersion;
|
|
14826
14251
|
class ENR extends RawEnr {
|
14827
14252
|
static RECORD_PREFIX = "enr:";
|
14828
14253
|
peerId;
|
14829
|
-
static
|
14254
|
+
static create(kvs = {}, seq = BigInt(1), signature) {
|
14830
14255
|
const enr = new ENR(kvs, seq, signature);
|
14831
14256
|
try {
|
14832
14257
|
const publicKey = enr.publicKey;
|
14833
14258
|
if (publicKey) {
|
14834
|
-
enr.peerId =
|
14259
|
+
enr.peerId = createPeerIdFromPublicKey(publicKey);
|
14835
14260
|
}
|
14836
14261
|
}
|
14837
14262
|
catch (e) {
|
@@ -14953,7 +14378,7 @@ class EnrCreator {
|
|
14953
14378
|
static fromPublicKey(publicKey, kvs = {}) {
|
14954
14379
|
// EIP-778 specifies that the key must be in compressed format, 33 bytes
|
14955
14380
|
if (publicKey.length !== 33) {
|
14956
|
-
publicKey = compressPublicKey
|
14381
|
+
publicKey = compressPublicKey(publicKey);
|
14957
14382
|
}
|
14958
14383
|
return ENR.create({
|
14959
14384
|
...kvs,
|
@@ -14964,7 +14389,7 @@ class EnrCreator {
|
|
14964
14389
|
static async fromPeerId(peerId, kvs = {}) {
|
14965
14390
|
switch (peerId.type) {
|
14966
14391
|
case "secp256k1":
|
14967
|
-
return EnrCreator.fromPublicKey(
|
14392
|
+
return EnrCreator.fromPublicKey(peerId.publicKey.raw, kvs);
|
14968
14393
|
default:
|
14969
14394
|
throw new Error();
|
14970
14395
|
}
|
@@ -15618,7 +15043,7 @@ async function fromValues(values) {
|
|
15618
15043
|
}
|
15619
15044
|
}
|
15620
15045
|
const _seq = decodeSeq(seq);
|
15621
|
-
const enr =
|
15046
|
+
const enr = ENR.create(obj, _seq, signature);
|
15622
15047
|
checkSignature(seq, kvs, enr, signature);
|
15623
15048
|
return enr;
|
15624
15049
|
}
|
@@ -15651,4 +15076,4 @@ function checkSignature(seq, kvs, enr, signature) {
|
|
15651
15076
|
}
|
15652
15077
|
}
|
15653
15078
|
|
15654
|
-
export { ENR, ERR_INVALID_ID, ERR_NO_SIGNATURE, EnrCreator, EnrDecoder, MAX_RECORD_SIZE, MULTIADDR_LENGTH_SIZE, TransportProtocol, TransportProtocolPerIpVersion, compressPublicKey
|
15079
|
+
export { ENR, ERR_INVALID_ID, ERR_NO_SIGNATURE, ERR_TYPE_NOT_IMPLEMENTED, EnrCreator, EnrDecoder, MAX_RECORD_SIZE, MULTIADDR_LENGTH_SIZE, TransportProtocol, TransportProtocolPerIpVersion, compressPublicKey, createPeerIdFromPublicKey, decodeWaku2, encodeWaku2, keccak256, sign$1 as sign, verifySignature };
|