@waku/enr 0.0.27-f599932.0 โ 0.0.28-00f2e75.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/CHANGELOG.md +8 -0
- package/bundle/index.js +1187 -1622
- 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 -1
- 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
@@ -241,11 +241,12 @@ class Decoder {
|
|
241
241
|
constructor(name, prefix, baseDecode) {
|
242
242
|
this.name = name;
|
243
243
|
this.prefix = prefix;
|
244
|
+
const prefixCodePoint = prefix.codePointAt(0);
|
244
245
|
/* c8 ignore next 3 */
|
245
|
-
if (
|
246
|
+
if (prefixCodePoint === undefined) {
|
246
247
|
throw new Error('Invalid prefix character');
|
247
248
|
}
|
248
|
-
this.prefixCodePoint =
|
249
|
+
this.prefixCodePoint = prefixCodePoint;
|
249
250
|
this.baseDecode = baseDecode;
|
250
251
|
}
|
251
252
|
decode(text) {
|
@@ -449,7 +450,14 @@ var base2$1 = /*#__PURE__*/Object.freeze({
|
|
449
450
|
|
450
451
|
const alphabet = Array.from('๐๐ชโ๐ฐ๐๐๐๐๐๐๐๐๐๐๐๐๐โ๐ป๐ฅ๐พ๐ฟ๐โค๐๐คฃ๐๐๐๐ญ๐๐๐
๐๐๐ฅ๐ฅฐ๐๐๐๐ข๐ค๐๐๐ช๐โบ๐๐ค๐๐๐๐๐น๐คฆ๐๐โโจ๐คท๐ฑ๐๐ธ๐๐๐๐๐๐๐๐๐คฉ๐๐๐ค๐๐ฏ๐๐๐ถ๐๐คญโฃ๐๐๐๐ช๐๐ฅ๐๐๐ฉ๐ก๐คช๐๐ฅณ๐ฅ๐คค๐๐๐ณโ๐๐๐ด๐๐ฌ๐๐๐ท๐ป๐โญโ
๐ฅบ๐๐๐ค๐ฆโ๐ฃ๐๐โน๐๐๐ โ๐๐บ๐๐ป๐๐๐๐๐น๐ฃ๐ซ๐๐๐ต๐ค๐๐ด๐ค๐ผ๐ซโฝ๐คโ๐๐คซ๐๐ฎ๐๐ป๐๐ถ๐๐ฒ๐ฟ๐งก๐โก๐๐โโ๐๐ฐ๐คจ๐ถ๐ค๐ถ๐ฐ๐๐ข๐ค๐๐จ๐จ๐คฌโ๐๐บ๐ค๐๐๐ฑ๐๐ถ๐ฅดโถโกโ๐๐ธโฌ๐จ๐๐ฆ๐ท๐บโ ๐
๐๐ต๐๐คฒ๐ค ๐คง๐๐ต๐
๐ง๐พ๐๐๐ค๐๐คฏ๐ทโ๐ง๐ฏ๐๐๐ค๐๐โ๐ด๐ฃ๐ธ๐๐๐ฅ๐คข๐
๐ก๐ฉ๐๐ธ๐ป๐ค๐คฎ๐ผ๐ฅต๐ฉ๐๐๐ผ๐๐ฃ๐ฅ');
|
451
452
|
const alphabetBytesToChars = (alphabet.reduce((p, c, i) => { p[i] = c; return p; }, ([])));
|
452
|
-
const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
|
453
|
+
const alphabetCharsToBytes = (alphabet.reduce((p, c, i) => {
|
454
|
+
const codePoint = c.codePointAt(0);
|
455
|
+
if (codePoint == null) {
|
456
|
+
throw new Error(`Invalid character: ${c}`);
|
457
|
+
}
|
458
|
+
p[codePoint] = i;
|
459
|
+
return p;
|
460
|
+
}, ([])));
|
453
461
|
function encode$4(data) {
|
454
462
|
return data.reduce((p, c) => {
|
455
463
|
p += alphabetBytesToChars[c];
|
@@ -459,8 +467,12 @@ function encode$4(data) {
|
|
459
467
|
function decode$5(str) {
|
460
468
|
const byts = [];
|
461
469
|
for (const char of str) {
|
462
|
-
const
|
463
|
-
if (
|
470
|
+
const codePoint = char.codePointAt(0);
|
471
|
+
if (codePoint == null) {
|
472
|
+
throw new Error(`Invalid character: ${char}`);
|
473
|
+
}
|
474
|
+
const byt = alphabetCharsToBytes[codePoint];
|
475
|
+
if (byt == null) {
|
464
476
|
throw new Error(`Non-base256emoji character: ${char}`);
|
465
477
|
}
|
466
478
|
byts.push(byt);
|
@@ -643,7 +655,7 @@ new TextDecoder();
|
|
643
655
|
|
644
656
|
/* eslint-disable */
|
645
657
|
var encode_1 = encode$3;
|
646
|
-
var MSB$1 = 0x80,
|
658
|
+
var MSB$1 = 0x80, MSBALL = -128, INT = Math.pow(2, 31);
|
647
659
|
/**
|
648
660
|
* @param {number} num
|
649
661
|
* @param {number[]} out
|
@@ -667,7 +679,7 @@ function encode$3(num, out, offset) {
|
|
667
679
|
return out;
|
668
680
|
}
|
669
681
|
var decode$4 = read$1;
|
670
|
-
var MSB$1$1 = 0x80, REST$1
|
682
|
+
var MSB$1$1 = 0x80, REST$1 = 0x7F;
|
671
683
|
/**
|
672
684
|
* @param {string | any[]} buf
|
673
685
|
* @param {number} offset
|
@@ -682,8 +694,8 @@ function read$1(buf, offset) {
|
|
682
694
|
}
|
683
695
|
b = buf[counter++];
|
684
696
|
res += shift < 28
|
685
|
-
? (b & REST$1
|
686
|
-
: (b & REST$1
|
697
|
+
? (b & REST$1) << shift
|
698
|
+
: (b & REST$1) * Math.pow(2, shift);
|
687
699
|
shift += 7;
|
688
700
|
} while (b >= MSB$1$1);
|
689
701
|
// @ts-ignore
|
@@ -733,7 +745,7 @@ function encodingLength$1(int) {
|
|
733
745
|
/**
|
734
746
|
* Creates a multihash digest.
|
735
747
|
*/
|
736
|
-
function create
|
748
|
+
function create(code, digest) {
|
737
749
|
const size = digest.byteLength;
|
738
750
|
const sizeOffset = encodingLength$1(code);
|
739
751
|
const digestOffset = sizeOffset + encodingLength$1(size);
|
@@ -792,7 +804,7 @@ const code = 0x0;
|
|
792
804
|
const name = 'identity';
|
793
805
|
const encode$2 = coerce;
|
794
806
|
function digest(input) {
|
795
|
-
return create
|
807
|
+
return create(code, encode$2(input));
|
796
808
|
}
|
797
809
|
const identity = { code, name, encode: encode$2, digest };
|
798
810
|
|
@@ -816,9 +828,9 @@ class Hasher {
|
|
816
828
|
if (input instanceof Uint8Array) {
|
817
829
|
const result = this.encode(input);
|
818
830
|
return result instanceof Uint8Array
|
819
|
-
? create
|
831
|
+
? create(this.code, result)
|
820
832
|
/* c8 ignore next 1 */
|
821
|
-
: result.then(digest => create
|
833
|
+
: result.then(digest => create(this.code, digest));
|
822
834
|
}
|
823
835
|
else {
|
824
836
|
throw Error('Unknown type, must be binary type');
|
@@ -918,7 +930,7 @@ class CID {
|
|
918
930
|
switch (this.version) {
|
919
931
|
case 0: {
|
920
932
|
const { code, digest } = this.multihash;
|
921
|
-
const multihash = create
|
933
|
+
const multihash = create(code, digest);
|
922
934
|
return (CID.createV1(this.code, multihash));
|
923
935
|
}
|
924
936
|
case 1: {
|
@@ -1148,9 +1160,13 @@ function parseCIDtoBytes(source, base) {
|
|
1148
1160
|
const decoder = base ?? base32;
|
1149
1161
|
return [base32.prefix, decoder.decode(source)];
|
1150
1162
|
}
|
1163
|
+
case base36.prefix: {
|
1164
|
+
const decoder = base ?? base36;
|
1165
|
+
return [base36.prefix, decoder.decode(source)];
|
1166
|
+
}
|
1151
1167
|
default: {
|
1152
1168
|
if (base == null) {
|
1153
|
-
throw Error('To parse non base32 or base58btc encoded CID multibase decoder must be provided');
|
1169
|
+
throw Error('To parse non base32, base36 or base58btc encoded CID multibase decoder must be provided');
|
1154
1170
|
}
|
1155
1171
|
return [source[0], base.decode(source)];
|
1156
1172
|
}
|
@@ -1570,10 +1586,10 @@ class JacobianPoint {
|
|
1570
1586
|
const cond1 = window % 2 !== 0;
|
1571
1587
|
const cond2 = wbits < 0;
|
1572
1588
|
if (wbits === 0) {
|
1573
|
-
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
|
1589
|
+
f = f.add(constTimeNegate$1(cond1, precomputes[offset1]));
|
1574
1590
|
}
|
1575
1591
|
else {
|
1576
|
-
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
|
1592
|
+
p = p.add(constTimeNegate$1(cond2, precomputes[offset2]));
|
1577
1593
|
}
|
1578
1594
|
}
|
1579
1595
|
return { p, f };
|
@@ -1586,8 +1602,8 @@ class JacobianPoint {
|
|
1586
1602
|
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
|
1587
1603
|
let { p: k1p, f: f1p } = this.wNAF(k1, affinePoint);
|
1588
1604
|
let { p: k2p, f: f2p } = this.wNAF(k2, affinePoint);
|
1589
|
-
k1p = constTimeNegate(k1neg, k1p);
|
1590
|
-
k2p = constTimeNegate(k2neg, k2p);
|
1605
|
+
k1p = constTimeNegate$1(k1neg, k1p);
|
1606
|
+
k2p = constTimeNegate$1(k2neg, k2p);
|
1591
1607
|
k2p = new JacobianPoint(mod$1(k2p.x * endo.beta), k2p.y, k2p.z);
|
1592
1608
|
point = k1p.add(k2p);
|
1593
1609
|
fake = f1p.add(f2p);
|
@@ -1619,7 +1635,7 @@ class JacobianPoint {
|
|
1619
1635
|
}
|
1620
1636
|
JacobianPoint.BASE = new JacobianPoint(CURVE.Gx, CURVE.Gy, _1n$7);
|
1621
1637
|
JacobianPoint.ZERO = new JacobianPoint(_0n$5, _1n$7, _0n$5);
|
1622
|
-
function constTimeNegate(condition, item) {
|
1638
|
+
function constTimeNegate$1(condition, item) {
|
1623
1639
|
const neg = item.negate();
|
1624
1640
|
return condition ? neg : item;
|
1625
1641
|
}
|
@@ -3056,7 +3072,7 @@ async function sign$1(message, privateKey) {
|
|
3056
3072
|
function keccak256(input) {
|
3057
3073
|
return new Uint8Array(sha3.keccak256.arrayBuffer(input));
|
3058
3074
|
}
|
3059
|
-
function compressPublicKey
|
3075
|
+
function compressPublicKey(publicKey) {
|
3060
3076
|
if (publicKey.length === 64) {
|
3061
3077
|
publicKey = concat$2([new Uint8Array([4]), publicKey], 65);
|
3062
3078
|
}
|
@@ -3076,43 +3092,55 @@ function verifySignature(signature, message, publicKey) {
|
|
3076
3092
|
}
|
3077
3093
|
}
|
3078
3094
|
|
3079
|
-
|
3095
|
+
/**
|
3096
|
+
* Internal assertion helpers.
|
3097
|
+
* @module
|
3098
|
+
*/
|
3099
|
+
/** Asserts something is positive integer. */
|
3100
|
+
function anumber(n) {
|
3080
3101
|
if (!Number.isSafeInteger(n) || n < 0)
|
3081
|
-
throw new Error(
|
3102
|
+
throw new Error('positive integer expected, got ' + n);
|
3082
3103
|
}
|
3083
|
-
|
3104
|
+
/** Is number an Uint8Array? Copied from utils for perf. */
|
3084
3105
|
function isBytes$2(a) {
|
3085
|
-
return
|
3086
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
3106
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
3087
3107
|
}
|
3088
|
-
|
3108
|
+
/** Asserts something is Uint8Array. */
|
3109
|
+
function abytes$1(b, ...lengths) {
|
3089
3110
|
if (!isBytes$2(b))
|
3090
3111
|
throw new Error('Uint8Array expected');
|
3091
3112
|
if (lengths.length > 0 && !lengths.includes(b.length))
|
3092
|
-
throw new Error(
|
3113
|
+
throw new Error('Uint8Array expected of length ' + lengths + ', got length=' + b.length);
|
3093
3114
|
}
|
3094
|
-
|
3115
|
+
/** Asserts something is hash */
|
3116
|
+
function ahash(h) {
|
3095
3117
|
if (typeof h !== 'function' || typeof h.create !== 'function')
|
3096
3118
|
throw new Error('Hash should be wrapped by utils.wrapConstructor');
|
3097
|
-
|
3098
|
-
|
3119
|
+
anumber(h.outputLen);
|
3120
|
+
anumber(h.blockLen);
|
3099
3121
|
}
|
3100
|
-
|
3122
|
+
/** Asserts a hash instance has not been destroyed / finished */
|
3123
|
+
function aexists(instance, checkFinished = true) {
|
3101
3124
|
if (instance.destroyed)
|
3102
3125
|
throw new Error('Hash instance has been destroyed');
|
3103
3126
|
if (checkFinished && instance.finished)
|
3104
3127
|
throw new Error('Hash#digest() has already been called');
|
3105
3128
|
}
|
3106
|
-
|
3107
|
-
|
3129
|
+
/** Asserts output is properly-sized byte array */
|
3130
|
+
function aoutput(out, instance) {
|
3131
|
+
abytes$1(out);
|
3108
3132
|
const min = instance.outputLen;
|
3109
3133
|
if (out.length < min) {
|
3110
|
-
throw new Error(
|
3134
|
+
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
3111
3135
|
}
|
3112
3136
|
}
|
3113
3137
|
|
3114
3138
|
const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? globalThis.crypto : undefined;
|
3115
3139
|
|
3140
|
+
/**
|
3141
|
+
* Utilities for hex, bytes, CSPRNG.
|
3142
|
+
* @module
|
3143
|
+
*/
|
3116
3144
|
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
3117
3145
|
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
3118
3146
|
// node.js versions earlier than v19 don't declare it in global scope.
|
@@ -3121,33 +3149,20 @@ const crypto$1 = typeof globalThis === 'object' && 'crypto' in globalThis ? glob
|
|
3121
3149
|
// Makes the utils un-importable in browsers without a bundler.
|
3122
3150
|
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
3123
3151
|
// Cast array to view
|
3124
|
-
|
3125
|
-
|
3126
|
-
|
3127
|
-
|
3128
|
-
|
3129
|
-
|
3130
|
-
// next scheduler queue processing step and this is exactly what we need.
|
3131
|
-
const nextTick = async () => { };
|
3132
|
-
// Returns control to thread each 'tick' ms to avoid blocking
|
3133
|
-
async function asyncLoop(iters, tick, cb) {
|
3134
|
-
let ts = Date.now();
|
3135
|
-
for (let i = 0; i < iters; i++) {
|
3136
|
-
cb(i);
|
3137
|
-
// Date.now() is not monotonic, so in case if clock goes backwards we return return control too
|
3138
|
-
const diff = Date.now() - ts;
|
3139
|
-
if (diff >= 0 && diff < tick)
|
3140
|
-
continue;
|
3141
|
-
await nextTick();
|
3142
|
-
ts += diff;
|
3143
|
-
}
|
3152
|
+
function createView(arr) {
|
3153
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
3154
|
+
}
|
3155
|
+
/** The rotate right (circular right shift) operation for uint32 */
|
3156
|
+
function rotr(word, shift) {
|
3157
|
+
return (word << (32 - shift)) | (word >>> shift);
|
3144
3158
|
}
|
3145
3159
|
/**
|
3160
|
+
* Convert JS string to byte array.
|
3146
3161
|
* @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
|
3147
3162
|
*/
|
3148
3163
|
function utf8ToBytes$1(str) {
|
3149
3164
|
if (typeof str !== 'string')
|
3150
|
-
throw new Error(
|
3165
|
+
throw new Error('utf8ToBytes expected string, got ' + typeof str);
|
3151
3166
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
3152
3167
|
}
|
3153
3168
|
/**
|
@@ -3158,7 +3173,7 @@ function utf8ToBytes$1(str) {
|
|
3158
3173
|
function toBytes$1(data) {
|
3159
3174
|
if (typeof data === 'string')
|
3160
3175
|
data = utf8ToBytes$1(data);
|
3161
|
-
|
3176
|
+
abytes$1(data);
|
3162
3177
|
return data;
|
3163
3178
|
}
|
3164
3179
|
/**
|
@@ -3168,7 +3183,7 @@ function concatBytes$1(...arrays) {
|
|
3168
3183
|
let sum = 0;
|
3169
3184
|
for (let i = 0; i < arrays.length; i++) {
|
3170
3185
|
const a = arrays[i];
|
3171
|
-
|
3186
|
+
abytes$1(a);
|
3172
3187
|
sum += a.length;
|
3173
3188
|
}
|
3174
3189
|
const res = new Uint8Array(sum);
|
@@ -3179,20 +3194,14 @@ function concatBytes$1(...arrays) {
|
|
3179
3194
|
}
|
3180
3195
|
return res;
|
3181
3196
|
}
|
3182
|
-
|
3197
|
+
/** For runtime check if class implements interface */
|
3183
3198
|
class Hash {
|
3184
3199
|
// Safe version that clones internal state
|
3185
3200
|
clone() {
|
3186
3201
|
return this._cloneInto();
|
3187
3202
|
}
|
3188
3203
|
}
|
3189
|
-
|
3190
|
-
function checkOpts(defaults, opts) {
|
3191
|
-
if (opts !== undefined && toStr.call(opts) !== '[object Object]')
|
3192
|
-
throw new Error('Options should be object or undefined');
|
3193
|
-
const merged = Object.assign(defaults, opts);
|
3194
|
-
return merged;
|
3195
|
-
}
|
3204
|
+
/** Wraps hash function, creating an interface on top of it */
|
3196
3205
|
function wrapConstructor(hashCons) {
|
3197
3206
|
const hashC = (msg) => hashCons().update(toBytes$1(msg)).digest();
|
3198
3207
|
const tmp = hashCons();
|
@@ -3201,17 +3210,23 @@ function wrapConstructor(hashCons) {
|
|
3201
3210
|
hashC.create = () => hashCons();
|
3202
3211
|
return hashC;
|
3203
3212
|
}
|
3204
|
-
/**
|
3205
|
-
|
3206
|
-
*/
|
3207
|
-
function randomBytes$1(bytesLength = 32) {
|
3213
|
+
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
3214
|
+
function randomBytes(bytesLength = 32) {
|
3208
3215
|
if (crypto$1 && typeof crypto$1.getRandomValues === 'function') {
|
3209
3216
|
return crypto$1.getRandomValues(new Uint8Array(bytesLength));
|
3210
3217
|
}
|
3218
|
+
// Legacy Node.js compatibility
|
3219
|
+
if (crypto$1 && typeof crypto$1.randomBytes === 'function') {
|
3220
|
+
return crypto$1.randomBytes(bytesLength);
|
3221
|
+
}
|
3211
3222
|
throw new Error('crypto.getRandomValues must be defined');
|
3212
3223
|
}
|
3213
3224
|
|
3214
|
-
|
3225
|
+
/**
|
3226
|
+
* Internal Merkle-Damgard hash utils.
|
3227
|
+
* @module
|
3228
|
+
*/
|
3229
|
+
/** Polyfill for Safari 14. https://caniuse.com/mdn-javascript_builtins_dataview_setbiguint64 */
|
3215
3230
|
function setBigUint64(view, byteOffset, value, isLE) {
|
3216
3231
|
if (typeof view.setBigUint64 === 'function')
|
3217
3232
|
return view.setBigUint64(byteOffset, value, isLE);
|
@@ -3224,10 +3239,14 @@ function setBigUint64(view, byteOffset, value, isLE) {
|
|
3224
3239
|
view.setUint32(byteOffset + h, wh, isLE);
|
3225
3240
|
view.setUint32(byteOffset + l, wl, isLE);
|
3226
3241
|
}
|
3227
|
-
|
3228
|
-
|
3229
|
-
|
3230
|
-
|
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
|
+
}
|
3231
3250
|
/**
|
3232
3251
|
* Merkle-Damgard hash construction base class.
|
3233
3252
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
@@ -3247,7 +3266,7 @@ class HashMD extends Hash {
|
|
3247
3266
|
this.view = createView(this.buffer);
|
3248
3267
|
}
|
3249
3268
|
update(data) {
|
3250
|
-
|
3269
|
+
aexists(this);
|
3251
3270
|
const { view, buffer, blockLen } = this;
|
3252
3271
|
data = toBytes$1(data);
|
3253
3272
|
const len = data.length;
|
@@ -3273,8 +3292,8 @@ class HashMD extends Hash {
|
|
3273
3292
|
return this;
|
3274
3293
|
}
|
3275
3294
|
digestInto(out) {
|
3276
|
-
|
3277
|
-
|
3295
|
+
aexists(this);
|
3296
|
+
aoutput(out, this);
|
3278
3297
|
this.finished = true;
|
3279
3298
|
// Padding
|
3280
3299
|
// We can avoid allocation of buffer for padding completely if it
|
@@ -3331,10 +3350,16 @@ class HashMD extends Hash {
|
|
3331
3350
|
}
|
3332
3351
|
}
|
3333
3352
|
|
3334
|
-
|
3335
|
-
|
3336
|
-
|
3337
|
-
|
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). */
|
3338
3363
|
// prettier-ignore
|
3339
3364
|
const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
3340
3365
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
@@ -3346,14 +3371,15 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
3346
3371
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
3347
3372
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
3348
3373
|
]);
|
3349
|
-
|
3350
|
-
// 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. */
|
3351
3375
|
// prettier-ignore
|
3352
3376
|
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
3353
3377
|
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
3354
3378
|
]);
|
3355
|
-
|
3356
|
-
|
3379
|
+
/**
|
3380
|
+
* Temporary buffer, not used to store anything between runs.
|
3381
|
+
* Named this way because it matches specification.
|
3382
|
+
*/
|
3357
3383
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
3358
3384
|
class SHA256 extends HashMD {
|
3359
3385
|
constructor() {
|
@@ -3430,10 +3456,7 @@ class SHA256 extends HashMD {
|
|
3430
3456
|
this.buffer.fill(0);
|
3431
3457
|
}
|
3432
3458
|
}
|
3433
|
-
/**
|
3434
|
-
* SHA2-256 hash function
|
3435
|
-
* @param message - data that would be hashed
|
3436
|
-
*/
|
3459
|
+
/** SHA2-256 hash function */
|
3437
3460
|
const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
3438
3461
|
|
3439
3462
|
var Protocols;
|
@@ -3445,43 +3468,24 @@ var Protocols;
|
|
3445
3468
|
})(Protocols || (Protocols = {}));
|
3446
3469
|
var ProtocolError;
|
3447
3470
|
(function (ProtocolError) {
|
3448
|
-
|
3471
|
+
//
|
3472
|
+
// GENERAL ERRORS SECTION
|
3473
|
+
//
|
3474
|
+
/**
|
3475
|
+
* Could not determine the origin of the fault. Best to check connectivity and try again
|
3476
|
+
* */
|
3449
3477
|
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
3450
3478
|
/**
|
3451
|
-
*
|
3452
|
-
*
|
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.
|
3453
3482
|
*/
|
3454
|
-
ProtocolError["
|
3483
|
+
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
3455
3484
|
/**
|
3456
3485
|
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
3457
3486
|
* ensuring that messages are sent via several peer enable mitigation of this error.
|
3458
3487
|
*/
|
3459
3488
|
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
3460
|
-
/**
|
3461
|
-
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
3462
|
-
* payload is set on the outgoing message.
|
3463
|
-
*/
|
3464
|
-
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
3465
|
-
/**
|
3466
|
-
* The message size is above the maximum message size allowed on the Waku Network.
|
3467
|
-
* Compressing the message or using an alternative strategy for large messages is recommended.
|
3468
|
-
*/
|
3469
|
-
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
3470
|
-
/**
|
3471
|
-
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
3472
|
-
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
3473
|
-
*/
|
3474
|
-
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
3475
|
-
/**
|
3476
|
-
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
3477
|
-
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
3478
|
-
*/
|
3479
|
-
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
3480
|
-
/**
|
3481
|
-
* The topics passed in the decoders do not match each other, or don't exist at all.
|
3482
|
-
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
3483
|
-
*/
|
3484
|
-
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
3485
3489
|
/**
|
3486
3490
|
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
3487
3491
|
* Mitigation can be: retrying after a given time period, display connectivity issue
|
@@ -3499,37 +3503,51 @@ var ProtocolError;
|
|
3499
3503
|
* or `DECODE_FAILED` can be used.
|
3500
3504
|
*/
|
3501
3505
|
ProtocolError["NO_RESPONSE"] = "No response received";
|
3506
|
+
//
|
3507
|
+
// SEND ERRORS SECTION
|
3508
|
+
//
|
3502
3509
|
/**
|
3503
|
-
*
|
3504
|
-
*
|
3505
|
-
* or `DECODE_FAILED` can be used.
|
3510
|
+
* Failure to protobuf encode the message. This is not recoverable and needs
|
3511
|
+
* further investigation.
|
3506
3512
|
*/
|
3507
|
-
ProtocolError["
|
3513
|
+
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
3508
3514
|
/**
|
3509
|
-
* The
|
3510
|
-
*
|
3515
|
+
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
3516
|
+
* payload is set on the outgoing message.
|
3511
3517
|
*/
|
3512
|
-
ProtocolError["
|
3518
|
+
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
3513
3519
|
/**
|
3514
|
-
*
|
3515
|
-
*
|
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.
|
3516
3522
|
*/
|
3517
|
-
ProtocolError["
|
3523
|
+
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
3518
3524
|
/**
|
3519
|
-
*
|
3520
|
-
*
|
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.
|
3521
3527
|
*/
|
3522
|
-
ProtocolError["
|
3528
|
+
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
3523
3529
|
/**
|
3524
|
-
*
|
3525
|
-
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L190
|
3530
|
+
* Fails when
|
3526
3531
|
*/
|
3527
|
-
ProtocolError["
|
3532
|
+
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
3528
3533
|
/**
|
3529
3534
|
* General proof generation error message.
|
3530
3535
|
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
3531
3536
|
*/
|
3532
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";
|
3533
3551
|
})(ProtocolError || (ProtocolError = {}));
|
3534
3552
|
|
3535
3553
|
var Tags;
|
@@ -3550,6 +3568,10 @@ var EConnectionStateEvents;
|
|
3550
3568
|
EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
|
3551
3569
|
})(EConnectionStateEvents || (EConnectionStateEvents = {}));
|
3552
3570
|
|
3571
|
+
var HealthStatusChangeEvents;
|
3572
|
+
(function (HealthStatusChangeEvents) {
|
3573
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
3574
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
3553
3575
|
var HealthStatus;
|
3554
3576
|
(function (HealthStatus) {
|
3555
3577
|
HealthStatus["Unhealthy"] = "Unhealthy";
|
@@ -3621,7 +3643,7 @@ function requireMs () {
|
|
3621
3643
|
* @api public
|
3622
3644
|
*/
|
3623
3645
|
|
3624
|
-
ms = function(val, options) {
|
3646
|
+
ms = function (val, options) {
|
3625
3647
|
options = options || {};
|
3626
3648
|
var type = typeof val;
|
3627
3649
|
if (type === 'string' && val.length > 0) {
|
@@ -3928,24 +3950,62 @@ function setup(env) {
|
|
3928
3950
|
createDebug.names = [];
|
3929
3951
|
createDebug.skips = [];
|
3930
3952
|
|
3931
|
-
|
3932
|
-
|
3933
|
-
|
3953
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
3954
|
+
.trim()
|
3955
|
+
.replace(' ', ',')
|
3956
|
+
.split(',')
|
3957
|
+
.filter(Boolean);
|
3934
3958
|
|
3935
|
-
for (
|
3936
|
-
if (
|
3937
|
-
|
3938
|
-
|
3959
|
+
for (const ns of split) {
|
3960
|
+
if (ns[0] === '-') {
|
3961
|
+
createDebug.skips.push(ns.slice(1));
|
3962
|
+
} else {
|
3963
|
+
createDebug.names.push(ns);
|
3939
3964
|
}
|
3965
|
+
}
|
3966
|
+
}
|
3940
3967
|
|
3941
|
-
|
3942
|
-
|
3943
|
-
|
3944
|
-
|
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;
|
3945
3998
|
} else {
|
3946
|
-
|
3999
|
+
return false; // No match
|
3947
4000
|
}
|
3948
4001
|
}
|
4002
|
+
|
4003
|
+
// Handle trailing '*' in template
|
4004
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
4005
|
+
templateIndex++;
|
4006
|
+
}
|
4007
|
+
|
4008
|
+
return templateIndex === template.length;
|
3949
4009
|
}
|
3950
4010
|
|
3951
4011
|
/**
|
@@ -3956,8 +4016,8 @@ function setup(env) {
|
|
3956
4016
|
*/
|
3957
4017
|
function disable() {
|
3958
4018
|
const namespaces = [
|
3959
|
-
...createDebug.names
|
3960
|
-
...createDebug.skips.map(
|
4019
|
+
...createDebug.names,
|
4020
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
3961
4021
|
].join(',');
|
3962
4022
|
createDebug.enable('');
|
3963
4023
|
return namespaces;
|
@@ -3971,21 +4031,14 @@ function setup(env) {
|
|
3971
4031
|
* @api public
|
3972
4032
|
*/
|
3973
4033
|
function enabled(name) {
|
3974
|
-
|
3975
|
-
|
3976
|
-
}
|
3977
|
-
|
3978
|
-
let i;
|
3979
|
-
let len;
|
3980
|
-
|
3981
|
-
for (i = 0, len = createDebug.skips.length; i < len; i++) {
|
3982
|
-
if (createDebug.skips[i].test(name)) {
|
4034
|
+
for (const skip of createDebug.skips) {
|
4035
|
+
if (matchesTemplate(name, skip)) {
|
3983
4036
|
return false;
|
3984
4037
|
}
|
3985
4038
|
}
|
3986
4039
|
|
3987
|
-
for (
|
3988
|
-
if (
|
4040
|
+
for (const ns of createDebug.names) {
|
4041
|
+
if (matchesTemplate(name, ns)) {
|
3989
4042
|
return true;
|
3990
4043
|
}
|
3991
4044
|
}
|
@@ -3993,19 +4046,6 @@ function setup(env) {
|
|
3993
4046
|
return false;
|
3994
4047
|
}
|
3995
4048
|
|
3996
|
-
/**
|
3997
|
-
* Convert regexp to namespace
|
3998
|
-
*
|
3999
|
-
* @param {RegExp} regxep
|
4000
|
-
* @return {String} namespace
|
4001
|
-
* @api private
|
4002
|
-
*/
|
4003
|
-
function toNamespace(regexp) {
|
4004
|
-
return regexp.toString()
|
4005
|
-
.substring(2, regexp.toString().length - 2)
|
4006
|
-
.replace(/\.\*\?$/, '*');
|
4007
|
-
}
|
4008
|
-
|
4009
4049
|
/**
|
4010
4050
|
* Coerce `val`.
|
4011
4051
|
*
|
@@ -4167,6 +4207,7 @@ var common = setup;
|
|
4167
4207
|
|
4168
4208
|
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
4169
4209
|
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
4210
|
+
// eslint-disable-next-line no-return-assign
|
4170
4211
|
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
4171
4212
|
// Is firebug? http://stackoverflow.com/a/398120/376773
|
4172
4213
|
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
@@ -4314,7 +4355,6 @@ var debug = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
|
|
4314
4355
|
|
4315
4356
|
const APP_NAME = "waku";
|
4316
4357
|
let Logger$1 = class Logger {
|
4317
|
-
_debug;
|
4318
4358
|
_info;
|
4319
4359
|
_warn;
|
4320
4360
|
_error;
|
@@ -4322,14 +4362,10 @@ let Logger$1 = class Logger {
|
|
4322
4362
|
return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
|
4323
4363
|
}
|
4324
4364
|
constructor(prefix) {
|
4325
|
-
this._debug = debug(Logger.createDebugNamespace("debug", prefix));
|
4326
4365
|
this._info = debug(Logger.createDebugNamespace("info", prefix));
|
4327
4366
|
this._warn = debug(Logger.createDebugNamespace("warn", prefix));
|
4328
4367
|
this._error = debug(Logger.createDebugNamespace("error", prefix));
|
4329
4368
|
}
|
4330
|
-
get debug() {
|
4331
|
-
return this._debug;
|
4332
|
-
}
|
4333
4369
|
get info() {
|
4334
4370
|
return this._info;
|
4335
4371
|
}
|
@@ -4345,34 +4381,6 @@ let Logger$1 = class Logger {
|
|
4345
4381
|
}
|
4346
4382
|
};
|
4347
4383
|
|
4348
|
-
const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
4349
|
-
|
4350
|
-
/**
|
4351
|
-
* When this error is thrown it means an operation was aborted,
|
4352
|
-
* usually in response to the `abort` event being emitted by an
|
4353
|
-
* AbortSignal.
|
4354
|
-
*/
|
4355
|
-
class CodeError extends Error {
|
4356
|
-
code;
|
4357
|
-
props;
|
4358
|
-
constructor(message, code, props) {
|
4359
|
-
super(message);
|
4360
|
-
this.code = code;
|
4361
|
-
this.name = props?.name ?? 'CodeError';
|
4362
|
-
this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
4363
|
-
}
|
4364
|
-
}
|
4365
|
-
class AggregateCodeError extends AggregateError {
|
4366
|
-
code;
|
4367
|
-
props;
|
4368
|
-
constructor(errors, message, code, props) {
|
4369
|
-
super(errors, message);
|
4370
|
-
this.code = code;
|
4371
|
-
this.name = props?.name ?? 'AggregateCodeError';
|
4372
|
-
this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
|
4373
|
-
}
|
4374
|
-
}
|
4375
|
-
|
4376
4384
|
/**
|
4377
4385
|
* Returns true if the two passed Uint8Arrays have the same content
|
4378
4386
|
*/
|
@@ -4864,7 +4872,7 @@ function parseIPv6(input) {
|
|
4864
4872
|
return parser.new(input).parseWith(() => parser.readIPv6Addr());
|
4865
4873
|
}
|
4866
4874
|
/** Parse `input` into IPv4 or IPv6 bytes. */
|
4867
|
-
function parseIP(input) {
|
4875
|
+
function parseIP(input, mapIPv4ToIPv6 = false) {
|
4868
4876
|
// strip zone index if it is present
|
4869
4877
|
if (input.includes("%")) {
|
4870
4878
|
input = input.split("%")[0];
|
@@ -4872,7 +4880,14 @@ function parseIP(input) {
|
|
4872
4880
|
if (input.length > MAX_IPV6_LENGTH) {
|
4873
4881
|
return undefined;
|
4874
4882
|
}
|
4875
|
-
|
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;
|
4876
4891
|
}
|
4877
4892
|
|
4878
4893
|
/** Check if `input` is IPv4. */
|
@@ -5060,17 +5075,13 @@ function getProtocol(proto) {
|
|
5060
5075
|
throw new Error(`invalid protocol id type: ${typeof proto}`);
|
5061
5076
|
}
|
5062
5077
|
|
5063
|
-
/**
|
5064
|
-
* @packageDocumentation
|
5065
|
-
*
|
5066
|
-
* Provides methods for converting
|
5067
|
-
*/
|
5068
5078
|
getProtocol('ip4');
|
5069
5079
|
getProtocol('ip6');
|
5070
5080
|
getProtocol('ipcidr');
|
5071
5081
|
/**
|
5072
5082
|
* Convert [code,Uint8Array] to string
|
5073
5083
|
*/
|
5084
|
+
// eslint-disable-next-line complexity
|
5074
5085
|
function convertToString(proto, buf) {
|
5075
5086
|
const protocol = getProtocol(proto);
|
5076
5087
|
switch (protocol.code) {
|
@@ -5079,6 +5090,8 @@ function convertToString(proto, buf) {
|
|
5079
5090
|
return bytes2ip(buf);
|
5080
5091
|
case 42: // ipv6zone
|
5081
5092
|
return bytes2str(buf);
|
5093
|
+
case 43: // ipcidr
|
5094
|
+
return toString$1(buf, 'base10');
|
5082
5095
|
case 6: // tcp
|
5083
5096
|
case 273: // udp
|
5084
5097
|
case 33: // dccp
|
@@ -5106,6 +5119,7 @@ function convertToString(proto, buf) {
|
|
5106
5119
|
return toString$1(buf, 'base16'); // no clue. convert to hex
|
5107
5120
|
}
|
5108
5121
|
}
|
5122
|
+
// eslint-disable-next-line complexity
|
5109
5123
|
function convertToBytes(proto, str) {
|
5110
5124
|
const protocol = getProtocol(proto);
|
5111
5125
|
switch (protocol.code) {
|
@@ -5115,6 +5129,8 @@ function convertToBytes(proto, str) {
|
|
5115
5129
|
return ip2bytes(str);
|
5116
5130
|
case 42: // ipv6zone
|
5117
5131
|
return str2bytes(str);
|
5132
|
+
case 43: // ipcidr
|
5133
|
+
return fromString(str, 'base10');
|
5118
5134
|
case 6: // tcp
|
5119
5135
|
case 273: // udp
|
5120
5136
|
case 33: // dccp
|
@@ -5409,19 +5425,6 @@ function ParseError(str) {
|
|
5409
5425
|
return new Error('Error parsing address: ' + str);
|
5410
5426
|
}
|
5411
5427
|
|
5412
|
-
/**
|
5413
|
-
* @packageDocumentation
|
5414
|
-
*
|
5415
|
-
* An implementation of a Multiaddr in JavaScript
|
5416
|
-
*
|
5417
|
-
* @example
|
5418
|
-
*
|
5419
|
-
* ```js
|
5420
|
-
* import { multiaddr } from '@multiformats/multiaddr'
|
5421
|
-
*
|
5422
|
-
* const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
|
5423
|
-
* ```
|
5424
|
-
*/
|
5425
5428
|
const inspect$1 = Symbol.for('nodejs.util.inspect.custom');
|
5426
5429
|
const symbol = Symbol.for('@multiformats/js-multiaddr/multiaddr');
|
5427
5430
|
const DNS_CODES = [
|
@@ -5430,6 +5433,12 @@ const DNS_CODES = [
|
|
5430
5433
|
getProtocol('dns6').code,
|
5431
5434
|
getProtocol('dnsaddr').code
|
5432
5435
|
];
|
5436
|
+
class NoAvailableResolverError extends Error {
|
5437
|
+
constructor(message = 'No available resolver') {
|
5438
|
+
super(message);
|
5439
|
+
this.name = 'NoAvailableResolverError';
|
5440
|
+
}
|
5441
|
+
}
|
5433
5442
|
/**
|
5434
5443
|
* Creates a {@link Multiaddr} from a {@link MultiaddrInput}
|
5435
5444
|
*/
|
@@ -5527,10 +5536,20 @@ class Multiaddr {
|
|
5527
5536
|
return this.#tuples.map(([code]) => getProtocol(code).name);
|
5528
5537
|
}
|
5529
5538
|
tuples() {
|
5530
|
-
return this.#tuples
|
5539
|
+
return this.#tuples.map(([code, value]) => {
|
5540
|
+
if (value == null) {
|
5541
|
+
return [code];
|
5542
|
+
}
|
5543
|
+
return [code, value];
|
5544
|
+
});
|
5531
5545
|
}
|
5532
5546
|
stringTuples() {
|
5533
|
-
return this.#stringTuples
|
5547
|
+
return this.#stringTuples.map(([code, value]) => {
|
5548
|
+
if (value == null) {
|
5549
|
+
return [code];
|
5550
|
+
}
|
5551
|
+
return [code, value];
|
5552
|
+
});
|
5534
5553
|
}
|
5535
5554
|
encapsulate(addr) {
|
5536
5555
|
addr = new Multiaddr(addr);
|
@@ -5599,7 +5618,7 @@ class Multiaddr {
|
|
5599
5618
|
}
|
5600
5619
|
const resolver = resolvers.get(resolvableProto.name);
|
5601
5620
|
if (resolver == null) {
|
5602
|
-
throw new
|
5621
|
+
throw new NoAvailableResolverError(`no available resolver for ${resolvableProto.name}`);
|
5603
5622
|
}
|
5604
5623
|
const result = await resolver(this, options);
|
5605
5624
|
return result.map(str => multiaddr(str));
|
@@ -5660,10 +5679,8 @@ class Multiaddr {
|
|
5660
5679
|
*
|
5661
5680
|
* ```TypeScript
|
5662
5681
|
* import { multiaddr } from '@multiformats/multiaddr'
|
5663
|
-
* const addr = multiaddr("/ip4/127.0.0.1/udp/1234")
|
5664
|
-
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5665
5682
|
*
|
5666
|
-
* const addr = multiaddr(
|
5683
|
+
* const addr = multiaddr('/ip4/127.0.0.1/udp/1234')
|
5667
5684
|
* // Multiaddr(/ip4/127.0.0.1/udp/1234)
|
5668
5685
|
*
|
5669
5686
|
* addr.bytes
|
@@ -5702,9 +5719,9 @@ class Multiaddr {
|
|
5702
5719
|
*
|
5703
5720
|
* ```TypeScript
|
5704
5721
|
* import { multiaddr, resolvers } from '@multiformats/multiaddr'
|
5705
|
-
* import {
|
5722
|
+
* import { dnsaddrResolver } from '@multiformats/multiaddr/resolvers'
|
5706
5723
|
*
|
5707
|
-
* resolvers.set('dnsaddr',
|
5724
|
+
* resolvers.set('dnsaddr', dnsaddrResolver)
|
5708
5725
|
*
|
5709
5726
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
5710
5727
|
*
|
@@ -5713,7 +5730,7 @@ class Multiaddr {
|
|
5713
5730
|
* signal: AbortSignal.timeout(5000)
|
5714
5731
|
* })
|
5715
5732
|
*
|
5716
|
-
* console.info(
|
5733
|
+
* console.info(resolved)
|
5717
5734
|
* // [Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...'), Multiaddr('/ip4/147.75...')...]
|
5718
5735
|
* ```
|
5719
5736
|
*
|
@@ -5727,7 +5744,9 @@ class Multiaddr {
|
|
5727
5744
|
* import { dnsJsonOverHttps } from '@multiformats/dns/resolvers'
|
5728
5745
|
*
|
5729
5746
|
* const resolver = dns({
|
5730
|
-
*
|
5747
|
+
* resolvers: {
|
5748
|
+
* '.': dnsJsonOverHttps('https://cloudflare-dns.com/dns-query')
|
5749
|
+
* }
|
5731
5750
|
* })
|
5732
5751
|
*
|
5733
5752
|
* const ma = multiaddr('/dnsaddr/bootstrap.libp2p.io')
|
@@ -5813,18 +5832,55 @@ function locationMultiaddrFromEnrFields(enr, protocol) {
|
|
5813
5832
|
return multiaddrFromFields(isIpv6 ? "ip6" : "ip4", protoName, ipVal, protoVal);
|
5814
5833
|
}
|
5815
5834
|
|
5816
|
-
|
5817
|
-
|
5818
|
-
|
5835
|
+
/**
|
5836
|
+
* All PeerId implementations must use this symbol as the name of a property
|
5837
|
+
* with a boolean `true` value
|
5838
|
+
*/
|
5839
|
+
const peerIdSymbol = Symbol.for('@libp2p/peer-id');
|
5840
|
+
|
5841
|
+
/**
|
5842
|
+
* When this error is thrown it means an operation was aborted,
|
5843
|
+
* usually in response to the `abort` event being emitted by an
|
5844
|
+
* AbortSignal.
|
5845
|
+
*/
|
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') {
|
5852
|
+
super(message);
|
5853
|
+
this.name = 'InvalidParametersError';
|
5854
|
+
}
|
5855
|
+
}
|
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';
|
5819
5874
|
}
|
5820
|
-
return typeof thing.then === 'function' &&
|
5821
|
-
typeof thing.catch === 'function' &&
|
5822
|
-
typeof thing.finally === 'function';
|
5823
5875
|
}
|
5824
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
|
+
*/
|
5825
5882
|
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
5826
5883
|
const _32n = /* @__PURE__ */ BigInt(32);
|
5827
|
-
// We are not using BigUint64Array, because they are extremely slow as per 2022
|
5828
5884
|
function fromBig(n, le = false) {
|
5829
5885
|
if (le)
|
5830
5886
|
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
|
@@ -5881,6 +5937,13 @@ const u64 = {
|
|
5881
5937
|
add, add3L, add3H, add4L, add4H, add5H, add5L,
|
5882
5938
|
};
|
5883
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
|
+
*/
|
5884
5947
|
// Round contants (first 32 bits of the fractional parts of the cube roots of the first 80 primes 2..409):
|
5885
5948
|
// prettier-ignore
|
5886
5949
|
const [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() => u64.split([
|
@@ -6035,8 +6098,13 @@ class SHA512 extends HashMD {
|
|
6035
6098
|
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
6036
6099
|
}
|
6037
6100
|
}
|
6101
|
+
/** SHA2-512 hash function. */
|
6038
6102
|
const sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
|
6039
6103
|
|
6104
|
+
/**
|
6105
|
+
* Hex, bytes and number utilities.
|
6106
|
+
* @module
|
6107
|
+
*/
|
6040
6108
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6041
6109
|
// 100 lines of code in the file are duplicated from noble-hashes (utils).
|
6042
6110
|
// This is OK: `abstract` directory does not use noble-hashes.
|
@@ -6046,8 +6114,7 @@ const _0n$4 = /* @__PURE__ */ BigInt(0);
|
|
6046
6114
|
const _1n$6 = /* @__PURE__ */ BigInt(1);
|
6047
6115
|
const _2n$4 = /* @__PURE__ */ BigInt(2);
|
6048
6116
|
function isBytes$1(a) {
|
6049
|
-
return
|
6050
|
-
(a != null && typeof a === 'object' && a.constructor.name === 'Uint8Array'));
|
6117
|
+
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
6051
6118
|
}
|
6052
6119
|
function abytes(item) {
|
6053
6120
|
if (!isBytes$1(item))
|
@@ -6055,7 +6122,7 @@ function abytes(item) {
|
|
6055
6122
|
}
|
6056
6123
|
function abool(title, value) {
|
6057
6124
|
if (typeof value !== 'boolean')
|
6058
|
-
throw new Error(
|
6125
|
+
throw new Error(title + ' boolean expected, got ' + value);
|
6059
6126
|
}
|
6060
6127
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
6061
6128
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
@@ -6073,23 +6140,22 @@ function bytesToHex(bytes) {
|
|
6073
6140
|
}
|
6074
6141
|
function numberToHexUnpadded(num) {
|
6075
6142
|
const hex = num.toString(16);
|
6076
|
-
return hex.length & 1 ?
|
6143
|
+
return hex.length & 1 ? '0' + hex : hex;
|
6077
6144
|
}
|
6078
6145
|
function hexToNumber(hex) {
|
6079
6146
|
if (typeof hex !== 'string')
|
6080
6147
|
throw new Error('hex string expected, got ' + typeof hex);
|
6081
|
-
// Big Endian
|
6082
|
-
return BigInt(hex === '' ? '0' : `0x${hex}`);
|
6148
|
+
return hex === '' ? _0n$4 : BigInt('0x' + hex); // Big Endian
|
6083
6149
|
}
|
6084
6150
|
// We use optimized technique to convert hex string to byte array
|
6085
|
-
const asciis = { _0: 48, _9: 57,
|
6086
|
-
function asciiToBase16(
|
6087
|
-
if (
|
6088
|
-
return
|
6089
|
-
if (
|
6090
|
-
return
|
6091
|
-
if (
|
6092
|
-
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)
|
6093
6159
|
return;
|
6094
6160
|
}
|
6095
6161
|
/**
|
@@ -6101,7 +6167,7 @@ function hexToBytes(hex) {
|
|
6101
6167
|
const hl = hex.length;
|
6102
6168
|
const al = hl / 2;
|
6103
6169
|
if (hl % 2)
|
6104
|
-
throw new Error('
|
6170
|
+
throw new Error('hex string expected, got unpadded hex of length ' + hl);
|
6105
6171
|
const array = new Uint8Array(al);
|
6106
6172
|
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
6107
6173
|
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
@@ -6110,7 +6176,7 @@ function hexToBytes(hex) {
|
|
6110
6176
|
const char = hex[hi] + hex[hi + 1];
|
6111
6177
|
throw new Error('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
6112
6178
|
}
|
6113
|
-
array[ai] = n1 * 16 + n2;
|
6179
|
+
array[ai] = n1 * 16 + n2; // multiply first octet, e.g. 'a3' => 10*16+3 => 160 + 3 => 163
|
6114
6180
|
}
|
6115
6181
|
return array;
|
6116
6182
|
}
|
@@ -6148,7 +6214,7 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6148
6214
|
res = hexToBytes(hex);
|
6149
6215
|
}
|
6150
6216
|
catch (e) {
|
6151
|
-
throw new Error(
|
6217
|
+
throw new Error(title + ' must be hex string or Uint8Array, cause: ' + e);
|
6152
6218
|
}
|
6153
6219
|
}
|
6154
6220
|
else if (isBytes$1(hex)) {
|
@@ -6157,11 +6223,11 @@ function ensureBytes(title, hex, expectedLength) {
|
|
6157
6223
|
res = Uint8Array.from(hex);
|
6158
6224
|
}
|
6159
6225
|
else {
|
6160
|
-
throw new Error(
|
6226
|
+
throw new Error(title + ' must be hex string or Uint8Array');
|
6161
6227
|
}
|
6162
6228
|
const len = res.length;
|
6163
6229
|
if (typeof expectedLength === 'number' && len !== expectedLength)
|
6164
|
-
throw new Error(
|
6230
|
+
throw new Error(title + ' of length ' + expectedLength + ' expected, got ' + len);
|
6165
6231
|
return res;
|
6166
6232
|
}
|
6167
6233
|
/**
|
@@ -6196,7 +6262,7 @@ function equalBytes(a, b) {
|
|
6196
6262
|
*/
|
6197
6263
|
function utf8ToBytes(str) {
|
6198
6264
|
if (typeof str !== 'string')
|
6199
|
-
throw new Error(
|
6265
|
+
throw new Error('string expected');
|
6200
6266
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
6201
6267
|
}
|
6202
6268
|
// Is positive bigint
|
@@ -6216,7 +6282,7 @@ function aInRange(title, n, min, max) {
|
|
6216
6282
|
// - b would commonly require subtraction: `inRange('x', x, 0n, P - 1n)`
|
6217
6283
|
// - our way is the cleanest: `inRange('x', x, 0n, P)
|
6218
6284
|
if (!inRange(n, min, max))
|
6219
|
-
throw new Error(
|
6285
|
+
throw new Error('expected valid ' + title + ': ' + min + ' <= n < ' + max + ', got ' + n);
|
6220
6286
|
}
|
6221
6287
|
// Bit operations
|
6222
6288
|
/**
|
@@ -6326,12 +6392,12 @@ function validateObject(object, validators, optValidators = {}) {
|
|
6326
6392
|
const checkField = (fieldName, type, isOptional) => {
|
6327
6393
|
const checkVal = validatorFns[type];
|
6328
6394
|
if (typeof checkVal !== 'function')
|
6329
|
-
throw new Error(
|
6395
|
+
throw new Error('invalid validator function');
|
6330
6396
|
const val = object[fieldName];
|
6331
6397
|
if (isOptional && val === undefined)
|
6332
6398
|
return;
|
6333
6399
|
if (!checkVal(val, object)) {
|
6334
|
-
throw new Error(
|
6400
|
+
throw new Error('param ' + String(fieldName) + ' is invalid. Expected ' + type + ', got ' + val);
|
6335
6401
|
}
|
6336
6402
|
};
|
6337
6403
|
for (const [fieldName, type] of Object.entries(validators))
|
@@ -6400,14 +6466,17 @@ var ut = /*#__PURE__*/Object.freeze({
|
|
6400
6466
|
validateObject: validateObject
|
6401
6467
|
});
|
6402
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
|
+
*/
|
6403
6475
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6404
|
-
// Utilities for modular arithmetics and finite fields
|
6405
6476
|
// prettier-ignore
|
6406
|
-
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = BigInt(2), _3n$1 = BigInt(3);
|
6477
|
+
const _0n$3 = BigInt(0), _1n$5 = BigInt(1), _2n$3 = /* @__PURE__ */ BigInt(2), _3n$1 = /* @__PURE__ */ BigInt(3);
|
6407
6478
|
// prettier-ignore
|
6408
|
-
const _4n = BigInt(4), _5n$1 = BigInt(5), _8n$2 = BigInt(8);
|
6409
|
-
// prettier-ignore
|
6410
|
-
BigInt(9); BigInt(16);
|
6479
|
+
const _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5), _8n$2 = /* @__PURE__ */ BigInt(8);
|
6411
6480
|
// Calculates a modulo b
|
6412
6481
|
function mod(a, b) {
|
6413
6482
|
const result = a % b;
|
@@ -6416,13 +6485,15 @@ function mod(a, b) {
|
|
6416
6485
|
/**
|
6417
6486
|
* Efficiently raise num to power and do modular division.
|
6418
6487
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
6488
|
+
* @todo use field version && remove
|
6419
6489
|
* @example
|
6420
6490
|
* pow(2n, 6n, 11n) // 64n % 11n == 9n
|
6421
6491
|
*/
|
6422
|
-
// TODO: use field version && remove
|
6423
6492
|
function pow(num, power, modulo) {
|
6424
|
-
if (
|
6425
|
-
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');
|
6426
6497
|
if (modulo === _1n$5)
|
6427
6498
|
return _0n$3;
|
6428
6499
|
let res = _1n$5;
|
@@ -6434,7 +6505,7 @@ function pow(num, power, modulo) {
|
|
6434
6505
|
}
|
6435
6506
|
return res;
|
6436
6507
|
}
|
6437
|
-
|
6508
|
+
/** Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)` */
|
6438
6509
|
function pow2(x, power, modulo) {
|
6439
6510
|
let res = x;
|
6440
6511
|
while (power-- > _0n$3) {
|
@@ -6443,12 +6514,15 @@ function pow2(x, power, modulo) {
|
|
6443
6514
|
}
|
6444
6515
|
return res;
|
6445
6516
|
}
|
6446
|
-
|
6517
|
+
/**
|
6518
|
+
* Inverses number over modulo.
|
6519
|
+
* Implemented using [Euclidean GCD](https://brilliant.org/wiki/extended-euclidean-algorithm/).
|
6520
|
+
*/
|
6447
6521
|
function invert(number, modulo) {
|
6448
|
-
if (number === _0n$3
|
6449
|
-
throw new Error(
|
6450
|
-
|
6451
|
-
|
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);
|
6452
6526
|
// Fermat's little theorem "CT-like" version inv(n) = n^(m-2) mod m is 30x slower.
|
6453
6527
|
let a = mod(number, modulo);
|
6454
6528
|
let b = modulo;
|
@@ -6488,8 +6562,11 @@ function tonelliShanks(P) {
|
|
6488
6562
|
for (Q = P - _1n$5, S = 0; Q % _2n$3 === _0n$3; Q /= _2n$3, S++)
|
6489
6563
|
;
|
6490
6564
|
// Step 2: Select a non-square z such that (z | p) โก -1 and set c โก zq
|
6491
|
-
for (Z = _2n$3; Z < P && pow(Z, legendreC, P) !== P - _1n$5; Z++)
|
6492
|
-
|
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
|
+
}
|
6493
6570
|
// Fast-path
|
6494
6571
|
if (S === 1) {
|
6495
6572
|
const p1div4 = (P + _1n$5) / _4n;
|
@@ -6531,9 +6608,18 @@ function tonelliShanks(P) {
|
|
6531
6608
|
return x;
|
6532
6609
|
};
|
6533
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
|
+
*/
|
6534
6622
|
function FpSqrt(P) {
|
6535
|
-
// NOTE: different algorithms can give different roots, it is up to user to decide which one they want.
|
6536
|
-
// For example there is FpSqrtOdd/FpSqrtEven to choice root based on oddness (used for hash-to-curve).
|
6537
6623
|
// P โก 3 (mod 4)
|
6538
6624
|
// โn = n^((P+1)/4)
|
6539
6625
|
if (P % _4n === _3n$1) {
|
@@ -6597,7 +6683,7 @@ function FpPow(f, num, power) {
|
|
6597
6683
|
// Should have same speed as pow for bigints
|
6598
6684
|
// TODO: benchmark!
|
6599
6685
|
if (power < _0n$3)
|
6600
|
-
throw new Error('
|
6686
|
+
throw new Error('invalid exponent, negatives unsupported');
|
6601
6687
|
if (power === _0n$3)
|
6602
6688
|
return f.ONE;
|
6603
6689
|
if (power === _1n$5)
|
@@ -6644,15 +6730,15 @@ function nLength(n, nBitLength) {
|
|
6644
6730
|
return { nBitLength: _nBitLength, nByteLength };
|
6645
6731
|
}
|
6646
6732
|
/**
|
6647
|
-
* Initializes a finite field over prime.
|
6648
|
-
* Do not init in loop: slow. Very fragile: always run a benchmark on a change.
|
6733
|
+
* Initializes a finite field over prime.
|
6649
6734
|
* Major performance optimizations:
|
6650
6735
|
* * a) denormalized operations like mulN instead of mul
|
6651
6736
|
* * b) same object shape: never add or remove keys
|
6652
6737
|
* * c) Object.freeze
|
6653
|
-
*
|
6738
|
+
* Fragile: always run a benchmark on a change.
|
6739
|
+
* Security note: operations don't check 'isValid' for all elements for performance reasons,
|
6654
6740
|
* it is caller responsibility to check this.
|
6655
|
-
* 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.
|
6656
6742
|
* @param ORDER prime positive bigint
|
6657
6743
|
* @param bitLen how many bits the field consumes
|
6658
6744
|
* @param isLE (def: false) if encoding / decoding should be in little-endian
|
@@ -6660,13 +6746,14 @@ function nLength(n, nBitLength) {
|
|
6660
6746
|
*/
|
6661
6747
|
function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
6662
6748
|
if (ORDER <= _0n$3)
|
6663
|
-
throw new Error(
|
6749
|
+
throw new Error('invalid field: expected ORDER > 0, got ' + ORDER);
|
6664
6750
|
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen);
|
6665
6751
|
if (BYTES > 2048)
|
6666
|
-
throw new Error('
|
6667
|
-
|
6752
|
+
throw new Error('invalid field: expected ORDER of <= 2048 bytes');
|
6753
|
+
let sqrtP; // cached sqrtP
|
6668
6754
|
const f = Object.freeze({
|
6669
6755
|
ORDER,
|
6756
|
+
isLE,
|
6670
6757
|
BITS,
|
6671
6758
|
BYTES,
|
6672
6759
|
MASK: bitMask(BITS),
|
@@ -6675,7 +6762,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6675
6762
|
create: (num) => mod(num, ORDER),
|
6676
6763
|
isValid: (num) => {
|
6677
6764
|
if (typeof num !== 'bigint')
|
6678
|
-
throw new Error(
|
6765
|
+
throw new Error('invalid field element: expected bigint, got ' + typeof num);
|
6679
6766
|
return _0n$3 <= num && num < ORDER; // 0 is valid element, but it's not invertible
|
6680
6767
|
},
|
6681
6768
|
is0: (num) => num === _0n$3,
|
@@ -6694,7 +6781,12 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6694
6781
|
subN: (lhs, rhs) => lhs - rhs,
|
6695
6782
|
mulN: (lhs, rhs) => lhs * rhs,
|
6696
6783
|
inv: (num) => invert(num, ORDER),
|
6697
|
-
sqrt: redef.sqrt ||
|
6784
|
+
sqrt: redef.sqrt ||
|
6785
|
+
((n) => {
|
6786
|
+
if (!sqrtP)
|
6787
|
+
sqrtP = FpSqrt(ORDER);
|
6788
|
+
return sqrtP(f, n);
|
6789
|
+
}),
|
6698
6790
|
invertBatch: (lst) => FpInvertBatch(f, lst),
|
6699
6791
|
// TODO: do we really need constant cmov?
|
6700
6792
|
// We don't have const-time bigints anyway, so probably will be not very useful
|
@@ -6702,7 +6794,7 @@ function Field(ORDER, bitLen, isLE = false, redef = {}) {
|
|
6702
6794
|
toBytes: (num) => (isLE ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES)),
|
6703
6795
|
fromBytes: (bytes) => {
|
6704
6796
|
if (bytes.length !== BYTES)
|
6705
|
-
throw new Error(
|
6797
|
+
throw new Error('Field.fromBytes: expected ' + BYTES + ' bytes, got ' + bytes.length);
|
6706
6798
|
return isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
6707
6799
|
},
|
6708
6800
|
});
|
@@ -6750,52 +6842,80 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
6750
6842
|
const minLen = getMinHashLength(fieldOrder);
|
6751
6843
|
// No small numbers: need to understand bias story. No huge numbers: easier to detect JS timings.
|
6752
6844
|
if (len < 16 || len < minLen || len > 1024)
|
6753
|
-
throw new Error(
|
6754
|
-
const num = isLE ?
|
6845
|
+
throw new Error('expected ' + minLen + '-1024 bytes of input, got ' + len);
|
6846
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
6755
6847
|
// `mod(x, 11)` can sometimes produce 0. `mod(x, 10) + 1` is the same, but no 0
|
6756
6848
|
const reduced = mod(num, fieldOrder - _1n$5) + _1n$5;
|
6757
6849
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
6758
6850
|
}
|
6759
6851
|
|
6852
|
+
/**
|
6853
|
+
* Methods for elliptic curve multiplication by scalars.
|
6854
|
+
* Contains wNAF, pippenger
|
6855
|
+
* @module
|
6856
|
+
*/
|
6760
6857
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6761
|
-
// Abelian group utilities
|
6762
6858
|
const _0n$2 = BigInt(0);
|
6763
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
|
+
}
|
6764
6890
|
// Since points in different groups cannot be equal (different object constructor),
|
6765
6891
|
// we can have single place to store precomputes
|
6766
6892
|
const pointPrecomputes = new WeakMap();
|
6767
6893
|
const pointWindowSizes = new WeakMap(); // This allows use make points immutable (nothing changes inside)
|
6768
|
-
|
6769
|
-
|
6770
|
-
|
6771
|
-
|
6772
|
-
|
6773
|
-
|
6774
|
-
|
6775
|
-
|
6776
|
-
|
6777
|
-
|
6778
|
-
|
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
|
+
*/
|
6779
6911
|
function wNAF(c, bits) {
|
6780
|
-
const constTimeNegate = (condition, item) => {
|
6781
|
-
const neg = item.negate();
|
6782
|
-
return condition ? neg : item;
|
6783
|
-
};
|
6784
|
-
const validateW = (W) => {
|
6785
|
-
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
6786
|
-
throw new Error(`Wrong window size=${W}, should be [1..${bits}]`);
|
6787
|
-
};
|
6788
|
-
const opts = (W) => {
|
6789
|
-
validateW(W);
|
6790
|
-
const windows = Math.ceil(bits / W) + 1; // +1, because
|
6791
|
-
const windowSize = 2 ** (W - 1); // -1 because we skip zero
|
6792
|
-
return { windows, windowSize };
|
6793
|
-
};
|
6794
6912
|
return {
|
6795
6913
|
constTimeNegate,
|
6914
|
+
hasPrecomputes(elm) {
|
6915
|
+
return getW(elm) !== 1;
|
6916
|
+
},
|
6796
6917
|
// non-const time multiplication ladder
|
6797
|
-
unsafeLadder(elm, n) {
|
6798
|
-
let p = c.ZERO;
|
6918
|
+
unsafeLadder(elm, n, p = c.ZERO) {
|
6799
6919
|
let d = elm;
|
6800
6920
|
while (n > _0n$2) {
|
6801
6921
|
if (n & _1n$4)
|
@@ -6813,10 +6933,12 @@ function wNAF(c, bits) {
|
|
6813
6933
|
* - ๐ is the window size
|
6814
6934
|
* - ๐ is the bitlength of the curve order.
|
6815
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
|
6816
6938
|
* @returns precomputed point tables flattened to a single array
|
6817
6939
|
*/
|
6818
6940
|
precomputeWindow(elm, W) {
|
6819
|
-
const { windows, windowSize } =
|
6941
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6820
6942
|
const points = [];
|
6821
6943
|
let p = elm;
|
6822
6944
|
let base = p;
|
@@ -6842,7 +6964,7 @@ function wNAF(c, bits) {
|
|
6842
6964
|
wNAF(W, precomputes, n) {
|
6843
6965
|
// TODO: maybe check that scalar is less than group order? wNAF behavious is undefined otherwise
|
6844
6966
|
// But need to carefully remove other checks before wNAF. ORDER == bits here
|
6845
|
-
const { windows, windowSize } =
|
6967
|
+
const { windows, windowSize } = calcWOpts(W, bits);
|
6846
6968
|
let p = c.ZERO;
|
6847
6969
|
let f = c.BASE;
|
6848
6970
|
const mask = BigInt(2 ** W - 1); // Create mask with W ones: 0b1111 for W=4 etc.
|
@@ -6886,8 +7008,44 @@ function wNAF(c, bits) {
|
|
6886
7008
|
// which makes it less const-time: around 1 bigint multiply.
|
6887
7009
|
return { p, f };
|
6888
7010
|
},
|
6889
|
-
|
6890
|
-
|
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) {
|
6891
7049
|
// Calculate precomputes on a first run, reuse them after
|
6892
7050
|
let comp = pointPrecomputes.get(P);
|
6893
7051
|
if (!comp) {
|
@@ -6895,18 +7053,76 @@ function wNAF(c, bits) {
|
|
6895
7053
|
if (W !== 1)
|
6896
7054
|
pointPrecomputes.set(P, transform(comp));
|
6897
7055
|
}
|
6898
|
-
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);
|
6899
7067
|
},
|
6900
7068
|
// We calculate precomputes for elliptic curve point multiplication
|
6901
7069
|
// using windowed method. This specifies window size and
|
6902
7070
|
// stores precomputed values. Usually only base point would be precomputed.
|
6903
7071
|
setWindowSize(P, W) {
|
6904
|
-
validateW(W);
|
7072
|
+
validateW(W, bits);
|
6905
7073
|
pointWindowSizes.set(P, W);
|
6906
7074
|
pointPrecomputes.delete(P);
|
6907
7075
|
},
|
6908
7076
|
};
|
6909
7077
|
}
|
7078
|
+
/**
|
7079
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
7080
|
+
* 30x faster vs naive addition on L=4096, 10x faster with precomputes.
|
7081
|
+
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
7082
|
+
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
7083
|
+
* @param c Curve Point constructor
|
7084
|
+
* @param fieldN field over CURVE.N - important that it's not over CURVE.P
|
7085
|
+
* @param points array of L curve points
|
7086
|
+
* @param scalars array of L scalars (aka private keys / bigints)
|
7087
|
+
*/
|
7088
|
+
function pippenger(c, fieldN, points, scalars) {
|
7089
|
+
// If we split scalars by some window (let's say 8 bits), every chunk will only
|
7090
|
+
// take 256 buckets even if there are 4096 scalars, also re-uses double.
|
7091
|
+
// TODO:
|
7092
|
+
// - https://eprint.iacr.org/2024/750.pdf
|
7093
|
+
// - https://tches.iacr.org/index.php/TCHES/article/view/10287
|
7094
|
+
// 0 is accepted in scalars
|
7095
|
+
validateMSMPoints(points, c);
|
7096
|
+
validateMSMScalars(scalars, fieldN);
|
7097
|
+
if (points.length !== scalars.length)
|
7098
|
+
throw new Error('arrays of points and scalars must have equal length');
|
7099
|
+
const zero = c.ZERO;
|
7100
|
+
const wbits = bitLen(BigInt(points.length));
|
7101
|
+
const windowSize = wbits > 12 ? wbits - 3 : wbits > 4 ? wbits - 2 : wbits ? 2 : 1; // in bits
|
7102
|
+
const MASK = (1 << windowSize) - 1;
|
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;
|
7106
|
+
for (let i = lastBits; i >= 0; i -= windowSize) {
|
7107
|
+
buckets.fill(zero);
|
7108
|
+
for (let j = 0; j < scalars.length; j++) {
|
7109
|
+
const scalar = scalars[j];
|
7110
|
+
const wbits = Number((scalar >> BigInt(i)) & BigInt(MASK));
|
7111
|
+
buckets[wbits] = buckets[wbits].add(points[j]);
|
7112
|
+
}
|
7113
|
+
let resI = zero; // not using this will do small speed-up, but will lose ct
|
7114
|
+
// Skip first bucket, because it is zero
|
7115
|
+
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
7116
|
+
sumI = sumI.add(buckets[j]);
|
7117
|
+
resI = resI.add(sumI);
|
7118
|
+
}
|
7119
|
+
sum = sum.add(resI);
|
7120
|
+
if (i !== 0)
|
7121
|
+
for (let j = 0; j < windowSize; j++)
|
7122
|
+
sum = sum.double();
|
7123
|
+
}
|
7124
|
+
return sum;
|
7125
|
+
}
|
6910
7126
|
function validateBasic(curve) {
|
6911
7127
|
validateField(curve.Fp);
|
6912
7128
|
validateObject(curve, {
|
@@ -6926,8 +7142,12 @@ function validateBasic(curve) {
|
|
6926
7142
|
});
|
6927
7143
|
}
|
6928
7144
|
|
6929
|
-
|
6930
|
-
|
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
|
+
*/
|
7150
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
6931
7151
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
6932
7152
|
// prettier-ignore
|
6933
7153
|
const _0n$1 = BigInt(0), _1n$3 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
@@ -6959,8 +7179,13 @@ function validateOpts$1(curve) {
|
|
6959
7179
|
function twistedEdwards(curveDef) {
|
6960
7180
|
const CURVE = validateOpts$1(curveDef);
|
6961
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.
|
6962
7186
|
const MASK = _2n$2 << (BigInt(nByteLength * 8) - _1n$3);
|
6963
7187
|
const modP = Fp.create; // Function overrides
|
7188
|
+
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
6964
7189
|
// sqrt(u/v)
|
6965
7190
|
const uvRatio = CURVE.uvRatio ||
|
6966
7191
|
((u, v) => {
|
@@ -7059,6 +7284,10 @@ function twistedEdwards(curveDef) {
|
|
7059
7284
|
const toInv = Fp.invertBatch(points.map((p) => p.ez));
|
7060
7285
|
return points.map((p, i) => p.toAffine(toInv[i])).map(Point.fromAffine);
|
7061
7286
|
}
|
7287
|
+
// Multiscalar Multiplication
|
7288
|
+
static msm(points, scalars) {
|
7289
|
+
return pippenger(Point, Fn, points, scalars);
|
7290
|
+
}
|
7062
7291
|
// "Private method", don't use it directly
|
7063
7292
|
_setWindowSize(windowSize) {
|
7064
7293
|
wnaf.setWindowSize(this, windowSize);
|
@@ -7167,16 +7396,15 @@ function twistedEdwards(curveDef) {
|
|
7167
7396
|
// It's faster, but should only be used when you don't care about
|
7168
7397
|
// an exposed private key e.g. sig verification.
|
7169
7398
|
// Does NOT allow scalars higher than CURVE.n.
|
7170
|
-
|
7399
|
+
// Accepts optional accumulator to merge with multiply (important for sparse scalars)
|
7400
|
+
multiplyUnsafe(scalar, acc = Point.ZERO) {
|
7171
7401
|
const n = scalar;
|
7172
7402
|
aInRange('scalar', n, _0n$1, CURVE_ORDER); // 0 <= scalar < L
|
7173
7403
|
if (n === _0n$1)
|
7174
7404
|
return I;
|
7175
|
-
if (this.
|
7405
|
+
if (this.is0() || n === _1n$3)
|
7176
7406
|
return this;
|
7177
|
-
|
7178
|
-
return this.wNAF(n).p;
|
7179
|
-
return wnaf.unsafeLadder(this, n);
|
7407
|
+
return wnaf.wNAFCachedUnsafe(this, n, Point.normalizeZ, acc);
|
7180
7408
|
}
|
7181
7409
|
// Checks if point is of small order.
|
7182
7410
|
// If you add something to small order point, you will have "dirty"
|
@@ -7210,8 +7438,9 @@ function twistedEdwards(curveDef) {
|
|
7210
7438
|
abool('zip215', zip215);
|
7211
7439
|
const normed = hex.slice(); // copy again, we'll manipulate it
|
7212
7440
|
const lastByte = hex[len - 1]; // select last byte
|
7213
|
-
normed[len - 1] = lastByte &
|
7441
|
+
normed[len - 1] = lastByte & -129; // clear last bit
|
7214
7442
|
const y = bytesToNumberLE(normed);
|
7443
|
+
// zip215=true is good for consensus-critical apps. =false follows RFC8032 / NIST186-5.
|
7215
7444
|
// RFC8032 prohibits >= p, but ZIP215 doesn't
|
7216
7445
|
// zip215=true: 0 <= y < MASK (2^256 for ed25519)
|
7217
7446
|
// zip215=false: 0 <= y < P (2^255-19 for ed25519)
|
@@ -7260,7 +7489,7 @@ function twistedEdwards(curveDef) {
|
|
7260
7489
|
}
|
7261
7490
|
/** Convenience method that creates public key and other stuff. RFC8032 5.1.5 */
|
7262
7491
|
function getExtendedPublicKey(key) {
|
7263
|
-
const len =
|
7492
|
+
const len = Fp.BYTES;
|
7264
7493
|
key = ensureBytes('private key', key, len);
|
7265
7494
|
// Hash private key with curve's hash function to produce uniformingly random input
|
7266
7495
|
// Check byte lengths: ensure(64, h(ensure(32, key)))
|
@@ -7293,23 +7522,29 @@ function twistedEdwards(curveDef) {
|
|
7293
7522
|
const s = modN(r + k * scalar); // S = (r + k * s) mod L
|
7294
7523
|
aInRange('signature.s', s, _0n$1, CURVE_ORDER); // 0 <= s < l
|
7295
7524
|
const res = concatBytes(R, numberToBytesLE(s, Fp.BYTES));
|
7296
|
-
return ensureBytes('result', res,
|
7525
|
+
return ensureBytes('result', res, Fp.BYTES * 2); // 64-byte signature
|
7297
7526
|
}
|
7298
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
|
+
*/
|
7299
7532
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
7300
7533
|
const { context, zip215 } = options;
|
7301
7534
|
const len = Fp.BYTES; // Verifies EdDSA signature against message and public key. RFC8032 5.1.7.
|
7302
7535
|
sig = ensureBytes('signature', sig, 2 * len); // An extended group equation is checked.
|
7303
7536
|
msg = ensureBytes('message', msg);
|
7537
|
+
publicKey = ensureBytes('publicKey', publicKey, len);
|
7304
7538
|
if (zip215 !== undefined)
|
7305
7539
|
abool('zip215', zip215);
|
7306
7540
|
if (prehash)
|
7307
7541
|
msg = prehash(msg); // for ed25519ph, etc
|
7308
7542
|
const s = bytesToNumberLE(sig.slice(len, 2 * len));
|
7309
|
-
// zip215: true is good for consensus-critical apps and allows points < 2^256
|
7310
|
-
// zip215: false follows RFC8032 / NIST186-5 and restricts points to CURVE.p
|
7311
7543
|
let A, R, SB;
|
7312
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)
|
7313
7548
|
A = Point.fromHex(publicKey, zip215);
|
7314
7549
|
R = Point.fromHex(sig.slice(0, len), zip215);
|
7315
7550
|
SB = G.multiplyUnsafe(s); // 0 <= s < l is done inside
|
@@ -7321,6 +7556,7 @@ function twistedEdwards(curveDef) {
|
|
7321
7556
|
return false;
|
7322
7557
|
const k = hashDomainToScalar(context, R.toRawBytes(), A.toRawBytes(), msg);
|
7323
7558
|
const RkA = R.add(A.multiplyUnsafe(k));
|
7559
|
+
// Extended group equation
|
7324
7560
|
// [8][S]B = [8]R + [8][k]A'
|
7325
7561
|
return RkA.subtract(SB).clearCofactor().equals(Point.ZERO);
|
7326
7562
|
}
|
@@ -7351,13 +7587,14 @@ function twistedEdwards(curveDef) {
|
|
7351
7587
|
};
|
7352
7588
|
}
|
7353
7589
|
|
7354
|
-
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7355
7590
|
/**
|
7356
7591
|
* ed25519 Twisted Edwards curve with following addons:
|
7357
7592
|
* - X25519 ECDH
|
7358
7593
|
* - Ristretto cofactor elimination
|
7359
7594
|
* - Elligator hash-to-group / point indistinguishability
|
7595
|
+
* @module
|
7360
7596
|
*/
|
7597
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
7361
7598
|
const ED25519_P = BigInt('57896044618658097711785492504343953926634992332820282019728792003956564819949');
|
7362
7599
|
// โ(-1) aka โ(a) aka 2^((p-1)/4)
|
7363
7600
|
const ED25519_SQRT_M1 = /* @__PURE__ */ BigInt('19681161376707505956807079304988542015446066515923890162744021073123829784752');
|
@@ -7416,7 +7653,7 @@ function uvRatio(u, v) {
|
|
7416
7653
|
x = mod(-x, P);
|
7417
7654
|
return { isValid: useRoot1 || useRoot2, value: x };
|
7418
7655
|
}
|
7419
|
-
const Fp
|
7656
|
+
const Fp = /* @__PURE__ */ (() => Field(ED25519_P, undefined, true))();
|
7420
7657
|
const ed25519Defaults = /* @__PURE__ */ (() => ({
|
7421
7658
|
// Param: a
|
7422
7659
|
a: BigInt(-1), // Fp.create(-1) is proper; our way still works and is faster
|
@@ -7424,7 +7661,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7424
7661
|
// Negative number is P - number, and division is invert(number, P)
|
7425
7662
|
d: BigInt('37095705934669439343138083508754565189542113879843219016388785533085940283555'),
|
7426
7663
|
// Finite field ๐ฝp over which we'll do calculations; 2n**255n - 19n
|
7427
|
-
Fp
|
7664
|
+
Fp,
|
7428
7665
|
// Subgroup order: how many points curve has
|
7429
7666
|
// 2n**252n + 27742317777372353535851937790883648493n;
|
7430
7667
|
n: BigInt('7237005577332262213973186563042994240857116359379907606001950938285454250989'),
|
@@ -7434,7 +7671,7 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7434
7671
|
Gx: BigInt('15112221349535400772501151409588531511454012693041857206046113283949847762202'),
|
7435
7672
|
Gy: BigInt('46316835694926478169428394003475163141307993866256225615783033603165251855960'),
|
7436
7673
|
hash: sha512,
|
7437
|
-
randomBytes
|
7674
|
+
randomBytes,
|
7438
7675
|
adjustScalarBytes,
|
7439
7676
|
// dom2
|
7440
7677
|
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
|
@@ -7443,180 +7680,58 @@ const ed25519Defaults = /* @__PURE__ */ (() => ({
|
|
7443
7680
|
}))();
|
7444
7681
|
/**
|
7445
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
|
7446
7691
|
*/
|
7447
7692
|
const ed25519 = /* @__PURE__ */ (() => twistedEdwards(ed25519Defaults))();
|
7448
7693
|
|
7449
7694
|
const PUBLIC_KEY_BYTE_LENGTH = 32;
|
7450
|
-
const PRIVATE_KEY_BYTE_LENGTH = 64; // private key is actually 32 bytes but for historical reasons we concat private and public keys
|
7451
|
-
const KEYS_BYTE_LENGTH = 32;
|
7452
|
-
function generateKey$2() {
|
7453
|
-
// the actual private key (32 bytes)
|
7454
|
-
const privateKeyRaw = ed25519.utils.randomPrivateKey();
|
7455
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7456
|
-
// concatenated the public key to the private key
|
7457
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7458
|
-
return {
|
7459
|
-
privateKey,
|
7460
|
-
publicKey
|
7461
|
-
};
|
7462
|
-
}
|
7463
|
-
/**
|
7464
|
-
* Generate keypair from a 32 byte uint8array
|
7465
|
-
*/
|
7466
|
-
function generateKeyFromSeed(seed) {
|
7467
|
-
if (seed.length !== KEYS_BYTE_LENGTH) {
|
7468
|
-
throw new TypeError('"seed" must be 32 bytes in length.');
|
7469
|
-
}
|
7470
|
-
else if (!(seed instanceof Uint8Array)) {
|
7471
|
-
throw new TypeError('"seed" must be a node.js Buffer, or Uint8Array.');
|
7472
|
-
}
|
7473
|
-
// based on node forges algorithm, the seed is used directly as private key
|
7474
|
-
const privateKeyRaw = seed;
|
7475
|
-
const publicKey = ed25519.getPublicKey(privateKeyRaw);
|
7476
|
-
const privateKey = concatKeys(privateKeyRaw, publicKey);
|
7477
|
-
return {
|
7478
|
-
privateKey,
|
7479
|
-
publicKey
|
7480
|
-
};
|
7481
|
-
}
|
7482
|
-
function hashAndSign$2(privateKey, msg) {
|
7483
|
-
const privateKeyRaw = privateKey.subarray(0, KEYS_BYTE_LENGTH);
|
7484
|
-
return ed25519.sign(msg instanceof Uint8Array ? msg : msg.subarray(), privateKeyRaw);
|
7485
|
-
}
|
7486
7695
|
function hashAndVerify$2(publicKey, sig, msg) {
|
7487
7696
|
return ed25519.verify(sig, msg instanceof Uint8Array ? msg : msg.subarray(), publicKey);
|
7488
7697
|
}
|
7489
|
-
function concatKeys(privateKeyRaw, publicKey) {
|
7490
|
-
const privateKey = new Uint8Array(PRIVATE_KEY_BYTE_LENGTH);
|
7491
|
-
for (let i = 0; i < KEYS_BYTE_LENGTH; i++) {
|
7492
|
-
privateKey[i] = privateKeyRaw[i];
|
7493
|
-
privateKey[KEYS_BYTE_LENGTH + i] = publicKey[i];
|
7494
|
-
}
|
7495
|
-
return privateKey;
|
7496
|
-
}
|
7497
7698
|
|
7498
|
-
|
7499
|
-
|
7500
|
-
|
7501
|
-
|
7502
|
-
|
7503
|
-
const nativeCrypto = win.crypto;
|
7504
|
-
if (nativeCrypto?.subtle == null) {
|
7505
|
-
throw Object.assign(new Error('Missing Web Crypto API. ' +
|
7506
|
-
'The most likely cause of this error is that this page is being accessed ' +
|
7507
|
-
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
7508
|
-
'possible resolutions see ' +
|
7509
|
-
'https://github.com/libp2p/js-libp2p/blob/main/packages/crypto/README.md#web-crypto-api'), { code: 'ERR_MISSING_WEB_CRYPTO' });
|
7510
|
-
}
|
7511
|
-
return nativeCrypto;
|
7699
|
+
class Ed25519PublicKey {
|
7700
|
+
type = 'Ed25519';
|
7701
|
+
raw;
|
7702
|
+
constructor(key) {
|
7703
|
+
this.raw = ensureEd25519Key(key, PUBLIC_KEY_BYTE_LENGTH);
|
7512
7704
|
}
|
7513
|
-
|
7514
|
-
|
7515
|
-
// WebKit on Linux does not support deriving a key from an empty PBKDF2 key.
|
7516
|
-
// So, as a workaround, we provide the generated key as a constant. We test that
|
7517
|
-
// this generated key is accurate in test/workaround.spec.ts
|
7518
|
-
// Generated via:
|
7519
|
-
// await crypto.subtle.exportKey('jwk',
|
7520
|
-
// await crypto.subtle.deriveKey(
|
7521
|
-
// { name: 'PBKDF2', salt: new Uint8Array(16), iterations: 32767, hash: { name: 'SHA-256' } },
|
7522
|
-
// await crypto.subtle.importKey('raw', new Uint8Array(0), { name: 'PBKDF2' }, false, ['deriveKey']),
|
7523
|
-
// { name: 'AES-GCM', length: 128 }, true, ['encrypt', 'decrypt'])
|
7524
|
-
// )
|
7525
|
-
const derivedEmptyPasswordKey = { alg: 'A128GCM', ext: true, k: 'scm9jmO_4BJAgdwWGVulLg', key_ops: ['encrypt', 'decrypt'], kty: 'oct' };
|
7526
|
-
// Based off of code from https://github.com/luke-park/SecureCompatibleEncryptionExamples
|
7527
|
-
function create(opts) {
|
7528
|
-
const algorithm = 'AES-GCM';
|
7529
|
-
let keyLength = 16;
|
7530
|
-
const nonceLength = 12;
|
7531
|
-
const digest = 'SHA-256';
|
7532
|
-
const saltLength = 16;
|
7533
|
-
const iterations = 32767;
|
7534
|
-
const crypto = webcrypto.get();
|
7535
|
-
keyLength *= 8; // Browser crypto uses bits instead of bytes
|
7536
|
-
/**
|
7537
|
-
* Uses the provided password to derive a pbkdf2 key. The key
|
7538
|
-
* will then be used to encrypt the data.
|
7539
|
-
*/
|
7540
|
-
async function encrypt(data, password) {
|
7541
|
-
const salt = crypto.getRandomValues(new Uint8Array(saltLength));
|
7542
|
-
const nonce = crypto.getRandomValues(new Uint8Array(nonceLength));
|
7543
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7544
|
-
if (typeof password === 'string') {
|
7545
|
-
password = fromString(password);
|
7546
|
-
}
|
7547
|
-
let cryptoKey;
|
7548
|
-
if (password.length === 0) {
|
7549
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7550
|
-
try {
|
7551
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7552
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7553
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7554
|
-
}
|
7555
|
-
catch {
|
7556
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['encrypt']);
|
7557
|
-
}
|
7558
|
-
}
|
7559
|
-
else {
|
7560
|
-
// Derive a key using PBKDF2.
|
7561
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7562
|
-
const rawKey = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7563
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, rawKey, { name: algorithm, length: keyLength }, true, ['encrypt']);
|
7564
|
-
}
|
7565
|
-
// Encrypt the string.
|
7566
|
-
const ciphertext = await crypto.subtle.encrypt(aesGcm, cryptoKey, data);
|
7567
|
-
return concat$1([salt, aesGcm.iv, new Uint8Array(ciphertext)]);
|
7705
|
+
toMultihash() {
|
7706
|
+
return identity.digest(publicKeyToProtobuf(this));
|
7568
7707
|
}
|
7569
|
-
|
7570
|
-
|
7571
|
-
|
7572
|
-
|
7573
|
-
|
7574
|
-
|
7575
|
-
|
7576
|
-
|
7577
|
-
|
7578
|
-
const ciphertext = data.subarray(saltLength + nonceLength);
|
7579
|
-
const aesGcm = { name: algorithm, iv: nonce };
|
7580
|
-
if (typeof password === 'string') {
|
7581
|
-
password = fromString(password);
|
7582
|
-
}
|
7583
|
-
let cryptoKey;
|
7584
|
-
if (password.length === 0) {
|
7585
|
-
try {
|
7586
|
-
const deriveParams = { name: 'PBKDF2', salt, iterations, hash: { name: digest } };
|
7587
|
-
const runtimeDerivedEmptyPassword = await crypto.subtle.importKey('raw', password, { name: 'PBKDF2' }, false, ['deriveKey']);
|
7588
|
-
cryptoKey = await crypto.subtle.deriveKey(deriveParams, runtimeDerivedEmptyPassword, { name: algorithm, length: keyLength }, true, ['decrypt']);
|
7589
|
-
}
|
7590
|
-
catch {
|
7591
|
-
cryptoKey = await crypto.subtle.importKey('jwk', derivedEmptyPasswordKey, { name: 'AES-GCM' }, true, ['decrypt']);
|
7592
|
-
}
|
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;
|
7593
7717
|
}
|
7594
|
-
|
7595
|
-
|
7596
|
-
|
7597
|
-
|
7598
|
-
|
7599
|
-
}
|
7600
|
-
// Decrypt the string.
|
7601
|
-
const plaintext = await crypto.subtle.decrypt(aesGcm, cryptoKey, ciphertext);
|
7602
|
-
return new Uint8Array(plaintext);
|
7603
|
-
}
|
7604
|
-
const cipher = {
|
7605
|
-
encrypt,
|
7606
|
-
decrypt
|
7607
|
-
};
|
7608
|
-
return cipher;
|
7718
|
+
return equals(this.raw, key.raw);
|
7719
|
+
}
|
7720
|
+
verify(data, sig) {
|
7721
|
+
return hashAndVerify$2(this.raw, sig, data);
|
7722
|
+
}
|
7609
7723
|
}
|
7610
7724
|
|
7611
|
-
|
7612
|
-
|
7613
|
-
|
7614
|
-
|
7615
|
-
|
7616
|
-
|
7617
|
-
|
7618
|
-
|
7619
|
-
|
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;
|
7620
7735
|
}
|
7621
7736
|
|
7622
7737
|
const f32 = new Float32Array([-0]);
|
@@ -8825,13 +8940,13 @@ var KeyType;
|
|
8825
8940
|
(function (KeyType) {
|
8826
8941
|
KeyType["RSA"] = "RSA";
|
8827
8942
|
KeyType["Ed25519"] = "Ed25519";
|
8828
|
-
KeyType["
|
8943
|
+
KeyType["secp256k1"] = "secp256k1";
|
8829
8944
|
})(KeyType || (KeyType = {}));
|
8830
8945
|
var __KeyTypeValues;
|
8831
8946
|
(function (__KeyTypeValues) {
|
8832
8947
|
__KeyTypeValues[__KeyTypeValues["RSA"] = 0] = "RSA";
|
8833
8948
|
__KeyTypeValues[__KeyTypeValues["Ed25519"] = 1] = "Ed25519";
|
8834
|
-
__KeyTypeValues[__KeyTypeValues["
|
8949
|
+
__KeyTypeValues[__KeyTypeValues["secp256k1"] = 2] = "secp256k1";
|
8835
8950
|
})(__KeyTypeValues || (__KeyTypeValues = {}));
|
8836
8951
|
(function (KeyType) {
|
8837
8952
|
KeyType.codec = () => {
|
@@ -8858,21 +8973,24 @@ var PublicKey;
|
|
8858
8973
|
if (opts.lengthDelimited !== false) {
|
8859
8974
|
w.ldelim();
|
8860
8975
|
}
|
8861
|
-
}, (reader, length) => {
|
8976
|
+
}, (reader, length, opts = {}) => {
|
8862
8977
|
const obj = {};
|
8863
8978
|
const end = length == null ? reader.len : reader.pos + length;
|
8864
8979
|
while (reader.pos < end) {
|
8865
8980
|
const tag = reader.uint32();
|
8866
8981
|
switch (tag >>> 3) {
|
8867
|
-
case 1:
|
8982
|
+
case 1: {
|
8868
8983
|
obj.Type = KeyType.codec().decode(reader);
|
8869
8984
|
break;
|
8870
|
-
|
8985
|
+
}
|
8986
|
+
case 2: {
|
8871
8987
|
obj.Data = reader.bytes();
|
8872
8988
|
break;
|
8873
|
-
|
8989
|
+
}
|
8990
|
+
default: {
|
8874
8991
|
reader.skipType(tag & 7);
|
8875
8992
|
break;
|
8993
|
+
}
|
8876
8994
|
}
|
8877
8995
|
}
|
8878
8996
|
return obj;
|
@@ -8883,8 +9001,8 @@ var PublicKey;
|
|
8883
9001
|
PublicKey.encode = (obj) => {
|
8884
9002
|
return encodeMessage(obj, PublicKey.codec());
|
8885
9003
|
};
|
8886
|
-
PublicKey.decode = (buf) => {
|
8887
|
-
return decodeMessage(buf, PublicKey.codec());
|
9004
|
+
PublicKey.decode = (buf, opts) => {
|
9005
|
+
return decodeMessage(buf, PublicKey.codec(), opts);
|
8888
9006
|
};
|
8889
9007
|
})(PublicKey || (PublicKey = {}));
|
8890
9008
|
var PrivateKey;
|
@@ -8907,21 +9025,24 @@ var PrivateKey;
|
|
8907
9025
|
if (opts.lengthDelimited !== false) {
|
8908
9026
|
w.ldelim();
|
8909
9027
|
}
|
8910
|
-
}, (reader, length) => {
|
9028
|
+
}, (reader, length, opts = {}) => {
|
8911
9029
|
const obj = {};
|
8912
9030
|
const end = length == null ? reader.len : reader.pos + length;
|
8913
9031
|
while (reader.pos < end) {
|
8914
9032
|
const tag = reader.uint32();
|
8915
9033
|
switch (tag >>> 3) {
|
8916
|
-
case 1:
|
9034
|
+
case 1: {
|
8917
9035
|
obj.Type = KeyType.codec().decode(reader);
|
8918
9036
|
break;
|
8919
|
-
|
9037
|
+
}
|
9038
|
+
case 2: {
|
8920
9039
|
obj.Data = reader.bytes();
|
8921
9040
|
break;
|
8922
|
-
|
9041
|
+
}
|
9042
|
+
default: {
|
8923
9043
|
reader.skipType(tag & 7);
|
8924
9044
|
break;
|
9045
|
+
}
|
8925
9046
|
}
|
8926
9047
|
}
|
8927
9048
|
return obj;
|
@@ -8932,286 +9053,15 @@ var PrivateKey;
|
|
8932
9053
|
PrivateKey.encode = (obj) => {
|
8933
9054
|
return encodeMessage(obj, PrivateKey.codec());
|
8934
9055
|
};
|
8935
|
-
PrivateKey.decode = (buf) => {
|
8936
|
-
return decodeMessage(buf, PrivateKey.codec());
|
9056
|
+
PrivateKey.decode = (buf, opts) => {
|
9057
|
+
return decodeMessage(buf, PrivateKey.codec(), opts);
|
8937
9058
|
};
|
8938
9059
|
})(PrivateKey || (PrivateKey = {}));
|
8939
9060
|
|
8940
|
-
class Ed25519PublicKey {
|
8941
|
-
_key;
|
8942
|
-
constructor(key) {
|
8943
|
-
this._key = ensureKey(key, PUBLIC_KEY_BYTE_LENGTH);
|
8944
|
-
}
|
8945
|
-
verify(data, sig) {
|
8946
|
-
return hashAndVerify$2(this._key, sig, data);
|
8947
|
-
}
|
8948
|
-
marshal() {
|
8949
|
-
return this._key;
|
8950
|
-
}
|
8951
|
-
get bytes() {
|
8952
|
-
return PublicKey.encode({
|
8953
|
-
Type: KeyType.Ed25519,
|
8954
|
-
Data: this.marshal()
|
8955
|
-
}).subarray();
|
8956
|
-
}
|
8957
|
-
equals(key) {
|
8958
|
-
return equals(this.bytes, key.bytes);
|
8959
|
-
}
|
8960
|
-
hash() {
|
8961
|
-
const p = sha256$1.digest(this.bytes);
|
8962
|
-
if (isPromise(p)) {
|
8963
|
-
return p.then(({ bytes }) => bytes);
|
8964
|
-
}
|
8965
|
-
return p.bytes;
|
8966
|
-
}
|
8967
|
-
}
|
8968
|
-
class Ed25519PrivateKey {
|
8969
|
-
_key;
|
8970
|
-
_publicKey;
|
8971
|
-
// key - 64 byte Uint8Array containing private key
|
8972
|
-
// publicKey - 32 byte Uint8Array containing public key
|
8973
|
-
constructor(key, publicKey) {
|
8974
|
-
this._key = ensureKey(key, PRIVATE_KEY_BYTE_LENGTH);
|
8975
|
-
this._publicKey = ensureKey(publicKey, PUBLIC_KEY_BYTE_LENGTH);
|
8976
|
-
}
|
8977
|
-
sign(message) {
|
8978
|
-
return hashAndSign$2(this._key, message);
|
8979
|
-
}
|
8980
|
-
get public() {
|
8981
|
-
return new Ed25519PublicKey(this._publicKey);
|
8982
|
-
}
|
8983
|
-
marshal() {
|
8984
|
-
return this._key;
|
8985
|
-
}
|
8986
|
-
get bytes() {
|
8987
|
-
return PrivateKey.encode({
|
8988
|
-
Type: KeyType.Ed25519,
|
8989
|
-
Data: this.marshal()
|
8990
|
-
}).subarray();
|
8991
|
-
}
|
8992
|
-
equals(key) {
|
8993
|
-
return equals(this.bytes, key.bytes);
|
8994
|
-
}
|
8995
|
-
async hash() {
|
8996
|
-
const p = sha256$1.digest(this.bytes);
|
8997
|
-
let bytes;
|
8998
|
-
if (isPromise(p)) {
|
8999
|
-
({ bytes } = await p);
|
9000
|
-
}
|
9001
|
-
else {
|
9002
|
-
bytes = p.bytes;
|
9003
|
-
}
|
9004
|
-
return bytes;
|
9005
|
-
}
|
9006
|
-
/**
|
9007
|
-
* Gets the ID of the key.
|
9008
|
-
*
|
9009
|
-
* The key id is the base58 encoding of the identity multihash containing its public key.
|
9010
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
9011
|
-
* of the PKCS SubjectPublicKeyInfo.
|
9012
|
-
*
|
9013
|
-
* @returns {Promise<string>}
|
9014
|
-
*/
|
9015
|
-
async id() {
|
9016
|
-
const encoding = identity.digest(this.public.bytes);
|
9017
|
-
return base58btc.encode(encoding.bytes).substring(1);
|
9018
|
-
}
|
9019
|
-
/**
|
9020
|
-
* Exports the key into a password protected `format`
|
9021
|
-
*/
|
9022
|
-
async export(password, format = 'libp2p-key') {
|
9023
|
-
if (format === 'libp2p-key') {
|
9024
|
-
return exporter(this.bytes, password);
|
9025
|
-
}
|
9026
|
-
else {
|
9027
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
9028
|
-
}
|
9029
|
-
}
|
9030
|
-
}
|
9031
|
-
function unmarshalEd25519PrivateKey(bytes) {
|
9032
|
-
// Try the old, redundant public key version
|
9033
|
-
if (bytes.length > PRIVATE_KEY_BYTE_LENGTH) {
|
9034
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH + PUBLIC_KEY_BYTE_LENGTH);
|
9035
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9036
|
-
const publicKeyBytes = bytes.subarray(PRIVATE_KEY_BYTE_LENGTH, bytes.length);
|
9037
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9038
|
-
}
|
9039
|
-
bytes = ensureKey(bytes, PRIVATE_KEY_BYTE_LENGTH);
|
9040
|
-
const privateKeyBytes = bytes.subarray(0, PRIVATE_KEY_BYTE_LENGTH);
|
9041
|
-
const publicKeyBytes = bytes.subarray(PUBLIC_KEY_BYTE_LENGTH);
|
9042
|
-
return new Ed25519PrivateKey(privateKeyBytes, publicKeyBytes);
|
9043
|
-
}
|
9044
|
-
function unmarshalEd25519PublicKey(bytes) {
|
9045
|
-
bytes = ensureKey(bytes, PUBLIC_KEY_BYTE_LENGTH);
|
9046
|
-
return new Ed25519PublicKey(bytes);
|
9047
|
-
}
|
9048
|
-
async function generateKeyPair$2() {
|
9049
|
-
const { privateKey, publicKey } = generateKey$2();
|
9050
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9051
|
-
}
|
9052
|
-
async function generateKeyPairFromSeed(seed) {
|
9053
|
-
const { privateKey, publicKey } = generateKeyFromSeed(seed);
|
9054
|
-
return new Ed25519PrivateKey(privateKey, publicKey);
|
9055
|
-
}
|
9056
|
-
function ensureKey(key, length) {
|
9057
|
-
key = Uint8Array.from(key ?? []);
|
9058
|
-
if (key.length !== length) {
|
9059
|
-
throw new CodeError(`Key must be a Uint8Array of length ${length}, got ${key.length}`, 'ERR_INVALID_KEY_TYPE');
|
9060
|
-
}
|
9061
|
-
return key;
|
9062
|
-
}
|
9063
|
-
|
9064
|
-
var Ed25519 = /*#__PURE__*/Object.freeze({
|
9065
|
-
__proto__: null,
|
9066
|
-
Ed25519PrivateKey: Ed25519PrivateKey,
|
9067
|
-
Ed25519PublicKey: Ed25519PublicKey,
|
9068
|
-
generateKeyPair: generateKeyPair$2,
|
9069
|
-
generateKeyPairFromSeed: generateKeyPairFromSeed,
|
9070
|
-
unmarshalEd25519PrivateKey: unmarshalEd25519PrivateKey,
|
9071
|
-
unmarshalEd25519PublicKey: unmarshalEd25519PublicKey
|
9072
|
-
});
|
9073
|
-
|
9074
|
-
/**
|
9075
|
-
* Generates a Uint8Array with length `number` populated by random bytes
|
9076
|
-
*/
|
9077
|
-
function randomBytes(length) {
|
9078
|
-
if (isNaN(length) || length <= 0) {
|
9079
|
-
throw new CodeError('random bytes length must be a Number bigger than 0', 'ERR_INVALID_LENGTH');
|
9080
|
-
}
|
9081
|
-
return randomBytes$1(length);
|
9082
|
-
}
|
9083
|
-
|
9084
|
-
// HMAC (RFC 2104)
|
9085
|
-
class HMAC extends Hash {
|
9086
|
-
constructor(hash$1, _key) {
|
9087
|
-
super();
|
9088
|
-
this.finished = false;
|
9089
|
-
this.destroyed = false;
|
9090
|
-
hash(hash$1);
|
9091
|
-
const key = toBytes$1(_key);
|
9092
|
-
this.iHash = hash$1.create();
|
9093
|
-
if (typeof this.iHash.update !== 'function')
|
9094
|
-
throw new Error('Expected instance of class which extends utils.Hash');
|
9095
|
-
this.blockLen = this.iHash.blockLen;
|
9096
|
-
this.outputLen = this.iHash.outputLen;
|
9097
|
-
const blockLen = this.blockLen;
|
9098
|
-
const pad = new Uint8Array(blockLen);
|
9099
|
-
// blockLen can be bigger than outputLen
|
9100
|
-
pad.set(key.length > blockLen ? hash$1.create().update(key).digest() : key);
|
9101
|
-
for (let i = 0; i < pad.length; i++)
|
9102
|
-
pad[i] ^= 0x36;
|
9103
|
-
this.iHash.update(pad);
|
9104
|
-
// By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
|
9105
|
-
this.oHash = hash$1.create();
|
9106
|
-
// Undo internal XOR && apply outer XOR
|
9107
|
-
for (let i = 0; i < pad.length; i++)
|
9108
|
-
pad[i] ^= 0x36 ^ 0x5c;
|
9109
|
-
this.oHash.update(pad);
|
9110
|
-
pad.fill(0);
|
9111
|
-
}
|
9112
|
-
update(buf) {
|
9113
|
-
exists(this);
|
9114
|
-
this.iHash.update(buf);
|
9115
|
-
return this;
|
9116
|
-
}
|
9117
|
-
digestInto(out) {
|
9118
|
-
exists(this);
|
9119
|
-
bytes(out, this.outputLen);
|
9120
|
-
this.finished = true;
|
9121
|
-
this.iHash.digestInto(out);
|
9122
|
-
this.oHash.update(out);
|
9123
|
-
this.oHash.digestInto(out);
|
9124
|
-
this.destroy();
|
9125
|
-
}
|
9126
|
-
digest() {
|
9127
|
-
const out = new Uint8Array(this.oHash.outputLen);
|
9128
|
-
this.digestInto(out);
|
9129
|
-
return out;
|
9130
|
-
}
|
9131
|
-
_cloneInto(to) {
|
9132
|
-
// Create new instance without calling constructor since key already in state and we don't know it.
|
9133
|
-
to || (to = Object.create(Object.getPrototypeOf(this), {}));
|
9134
|
-
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
9135
|
-
to = to;
|
9136
|
-
to.finished = finished;
|
9137
|
-
to.destroyed = destroyed;
|
9138
|
-
to.blockLen = blockLen;
|
9139
|
-
to.outputLen = outputLen;
|
9140
|
-
to.oHash = oHash._cloneInto(to.oHash);
|
9141
|
-
to.iHash = iHash._cloneInto(to.iHash);
|
9142
|
-
return to;
|
9143
|
-
}
|
9144
|
-
destroy() {
|
9145
|
-
this.destroyed = true;
|
9146
|
-
this.oHash.destroy();
|
9147
|
-
this.iHash.destroy();
|
9148
|
-
}
|
9149
|
-
}
|
9150
|
-
/**
|
9151
|
-
* HMAC: RFC2104 message authentication code.
|
9152
|
-
* @param hash - function that would be used e.g. sha256
|
9153
|
-
* @param key - message key
|
9154
|
-
* @param message - message data
|
9155
|
-
*/
|
9156
|
-
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
9157
|
-
hmac.create = (hash, key) => new HMAC(hash, key);
|
9158
|
-
|
9159
|
-
// Common prologue and epilogue for sync/async functions
|
9160
|
-
function pbkdf2Init(hash$1, _password, _salt, _opts) {
|
9161
|
-
hash(hash$1);
|
9162
|
-
const opts = checkOpts({ dkLen: 32, asyncTick: 10 }, _opts);
|
9163
|
-
const { c, dkLen, asyncTick } = opts;
|
9164
|
-
number(c);
|
9165
|
-
number(dkLen);
|
9166
|
-
number(asyncTick);
|
9167
|
-
if (c < 1)
|
9168
|
-
throw new Error('PBKDF2: iterations (c) should be >= 1');
|
9169
|
-
const password = toBytes$1(_password);
|
9170
|
-
const salt = toBytes$1(_salt);
|
9171
|
-
// DK = PBKDF2(PRF, Password, Salt, c, dkLen);
|
9172
|
-
const DK = new Uint8Array(dkLen);
|
9173
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9174
|
-
const PRF = hmac.create(hash$1, password);
|
9175
|
-
const PRFSalt = PRF._cloneInto().update(salt);
|
9176
|
-
return { c, dkLen, asyncTick, DK, PRF, PRFSalt };
|
9177
|
-
}
|
9178
|
-
function pbkdf2Output(PRF, PRFSalt, DK, prfW, u) {
|
9179
|
-
PRF.destroy();
|
9180
|
-
PRFSalt.destroy();
|
9181
|
-
if (prfW)
|
9182
|
-
prfW.destroy();
|
9183
|
-
u.fill(0);
|
9184
|
-
return DK;
|
9185
|
-
}
|
9186
|
-
async function pbkdf2Async(hash, password, salt, opts) {
|
9187
|
-
const { c, dkLen, asyncTick, DK, PRF, PRFSalt } = pbkdf2Init(hash, password, salt, opts);
|
9188
|
-
let prfW; // Working copy
|
9189
|
-
const arr = new Uint8Array(4);
|
9190
|
-
const view = createView(arr);
|
9191
|
-
const u = new Uint8Array(PRF.outputLen);
|
9192
|
-
// DK = T1 + T2 + โฏ + Tdklen/hlen
|
9193
|
-
for (let ti = 1, pos = 0; pos < dkLen; ti++, pos += PRF.outputLen) {
|
9194
|
-
// Ti = F(Password, Salt, c, i)
|
9195
|
-
const Ti = DK.subarray(pos, pos + PRF.outputLen);
|
9196
|
-
view.setInt32(0, ti, false);
|
9197
|
-
// F(Password, Salt, c, i) = U1 ^ U2 ^ โฏ ^ Uc
|
9198
|
-
// U1 = PRF(Password, Salt + INT_32_BE(i))
|
9199
|
-
(prfW = PRFSalt._cloneInto(prfW)).update(arr).digestInto(u);
|
9200
|
-
Ti.set(u.subarray(0, Ti.length));
|
9201
|
-
await asyncLoop(c - 1, asyncTick, () => {
|
9202
|
-
// Uc = PRF(Password, Ucโ1)
|
9203
|
-
PRF._cloneInto(prfW).update(u).digestInto(u);
|
9204
|
-
for (let i = 0; i < Ti.length; i++)
|
9205
|
-
Ti[i] ^= u[i];
|
9206
|
-
});
|
9207
|
-
}
|
9208
|
-
return pbkdf2Output(PRF, PRFSalt, DK, prfW, u);
|
9209
|
-
}
|
9210
|
-
|
9211
9061
|
/*!
|
9212
9062
|
* MIT License
|
9213
9063
|
*
|
9214
|
-
* Copyright (c) 2017-
|
9064
|
+
* Copyright (c) 2017-2024 Peculiar Ventures, LLC
|
9215
9065
|
*
|
9216
9066
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
9217
9067
|
* of this software and associated documentation files (the "Software"), to deal
|
@@ -9323,7 +9173,7 @@ class BufferSourceConverter {
|
|
9323
9173
|
}
|
9324
9174
|
|
9325
9175
|
const STRING_TYPE = "string";
|
9326
|
-
const HEX_REGEX = /^[0-9a-f]+$/i;
|
9176
|
+
const HEX_REGEX = /^[0-9a-f\s]+$/i;
|
9327
9177
|
const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
|
9328
9178
|
const BASE64URL_REGEX = /^[a-zA-Z0-9-_]+$/;
|
9329
9179
|
class Utf8Converter {
|
@@ -9557,7 +9407,7 @@ class Convert {
|
|
9557
9407
|
return base64;
|
9558
9408
|
}
|
9559
9409
|
static formatString(data) {
|
9560
|
-
return (data === null || data ===
|
9410
|
+
return (data === null || data === undefined ? undefined : data.replace(/[\n\r\t ]/g, "")) || "";
|
9561
9411
|
}
|
9562
9412
|
}
|
9563
9413
|
Convert.DEFAULT_UTF8_ENCODING = "utf8";
|
@@ -9813,7 +9663,7 @@ function HexBlock(BaseClass) {
|
|
9813
9663
|
var _a;
|
9814
9664
|
super(...args);
|
9815
9665
|
const params = args[0] || {};
|
9816
|
-
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !==
|
9666
|
+
this.isHexOnly = (_a = params.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9817
9667
|
this.valueHexView = params.valueHex ? BufferSourceConverter_1.toUint8Array(params.valueHex) : EMPTY_VIEW;
|
9818
9668
|
}
|
9819
9669
|
get valueHex() {
|
@@ -9903,11 +9753,11 @@ class LocalIdentificationBlock extends HexBlock(LocalBaseBlock) {
|
|
9903
9753
|
var _a, _b, _c, _d;
|
9904
9754
|
super();
|
9905
9755
|
if (idBlock) {
|
9906
|
-
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !==
|
9756
|
+
this.isHexOnly = (_a = idBlock.isHexOnly) !== null && _a !== undefined ? _a : false;
|
9907
9757
|
this.valueHexView = idBlock.valueHex ? BufferSourceConverter_1.toUint8Array(idBlock.valueHex) : EMPTY_VIEW;
|
9908
|
-
this.tagClass = (_b = idBlock.tagClass) !== null && _b !==
|
9909
|
-
this.tagNumber = (_c = idBlock.tagNumber) !== null && _c !==
|
9910
|
-
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;
|
9911
9761
|
}
|
9912
9762
|
else {
|
9913
9763
|
this.tagClass = -1;
|
@@ -10074,9 +9924,9 @@ class LocalLengthBlock extends LocalBaseBlock {
|
|
10074
9924
|
constructor({ lenBlock = {}, } = {}) {
|
10075
9925
|
var _a, _b, _c;
|
10076
9926
|
super();
|
10077
|
-
this.isIndefiniteForm = (_a = lenBlock.isIndefiniteForm) !== null && _a !==
|
10078
|
-
this.longFormUsed = (_b = lenBlock.longFormUsed) !== null && _b !==
|
10079
|
-
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;
|
10080
9930
|
}
|
10081
9931
|
fromBER(inputBuffer, inputOffset, inputLength) {
|
10082
9932
|
const view = BufferSourceConverter_1.toUint8Array(inputBuffer);
|
@@ -10848,7 +10698,7 @@ var _a$r;
|
|
10848
10698
|
class OctetString extends BaseBlock {
|
10849
10699
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
10850
10700
|
var _b, _c;
|
10851
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10701
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
10852
10702
|
super({
|
10853
10703
|
idBlock: {
|
10854
10704
|
isConstructed: parameters.isConstructed,
|
@@ -11009,7 +10859,7 @@ var _a$q;
|
|
11009
10859
|
class BitString extends BaseBlock {
|
11010
10860
|
constructor({ idBlock = {}, lenBlock = {}, ...parameters } = {}) {
|
11011
10861
|
var _b, _c;
|
11012
|
-
(_b = parameters.isConstructed) !== null && _b !==
|
10862
|
+
(_b = parameters.isConstructed) !== null && _b !== undefined ? _b : (parameters.isConstructed = !!((_c = parameters.value) === null || _c === undefined ? undefined : _c.length));
|
11013
10863
|
super({
|
11014
10864
|
idBlock: {
|
11015
10865
|
isConstructed: parameters.isConstructed,
|
@@ -12211,7 +12061,7 @@ class GeneralizedTime extends UTCTime {
|
|
12211
12061
|
constructor(parameters = {}) {
|
12212
12062
|
var _b;
|
12213
12063
|
super(parameters);
|
12214
|
-
(_b = this.millisecond) !== null && _b !==
|
12064
|
+
(_b = this.millisecond) !== null && _b !== undefined ? _b : (this.millisecond = 0);
|
12215
12065
|
this.idBlock.tagClass = 1;
|
12216
12066
|
this.idBlock.tagNumber = 24;
|
12217
12067
|
}
|
@@ -12459,272 +12309,44 @@ _a = TIME;
|
|
12459
12309
|
TIME.NAME = "TIME";
|
12460
12310
|
|
12461
12311
|
/**
|
12462
|
-
*
|
12312
|
+
* Signing a message failed
|
12463
12313
|
*/
|
12464
|
-
function pkcs1ToJwk(bytes) {
|
12465
|
-
const { result } = fromBER(bytes);
|
12466
|
-
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12467
|
-
// safe to have deeply property chains like this
|
12468
|
-
const values = result.valueBlock.value;
|
12469
|
-
const key = {
|
12470
|
-
n: toString$1(bnToBuf(values[1].toBigInt()), 'base64url'),
|
12471
|
-
e: toString$1(bnToBuf(values[2].toBigInt()), 'base64url'),
|
12472
|
-
d: toString$1(bnToBuf(values[3].toBigInt()), 'base64url'),
|
12473
|
-
p: toString$1(bnToBuf(values[4].toBigInt()), 'base64url'),
|
12474
|
-
q: toString$1(bnToBuf(values[5].toBigInt()), 'base64url'),
|
12475
|
-
dp: toString$1(bnToBuf(values[6].toBigInt()), 'base64url'),
|
12476
|
-
dq: toString$1(bnToBuf(values[7].toBigInt()), 'base64url'),
|
12477
|
-
qi: toString$1(bnToBuf(values[8].toBigInt()), 'base64url'),
|
12478
|
-
kty: 'RSA',
|
12479
|
-
alg: 'RS256'
|
12480
|
-
};
|
12481
|
-
return key;
|
12482
|
-
}
|
12483
12314
|
/**
|
12484
|
-
*
|
12315
|
+
* Verifying a message signature failed
|
12485
12316
|
*/
|
12486
|
-
|
12487
|
-
|
12488
|
-
|
12317
|
+
class VerificationError extends Error {
|
12318
|
+
constructor(message = 'An error occurred while verifying a message') {
|
12319
|
+
super(message);
|
12320
|
+
this.name = 'VerificationError';
|
12489
12321
|
}
|
12490
|
-
const root = new Sequence({
|
12491
|
-
value: [
|
12492
|
-
new Integer({ value: 0 }),
|
12493
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12494
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url'))),
|
12495
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.d, 'base64url'))),
|
12496
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.p, 'base64url'))),
|
12497
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.q, 'base64url'))),
|
12498
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dp, 'base64url'))),
|
12499
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.dq, 'base64url'))),
|
12500
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.qi, 'base64url')))
|
12501
|
-
]
|
12502
|
-
});
|
12503
|
-
const der = root.toBER();
|
12504
|
-
return new Uint8Array(der, 0, der.byteLength);
|
12505
|
-
}
|
12506
|
-
/**
|
12507
|
-
* Convert a PKCIX in ASN1 DER format to a JWK key
|
12508
|
-
*/
|
12509
|
-
function pkixToJwk(bytes) {
|
12510
|
-
const { result } = fromBER(bytes);
|
12511
|
-
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12512
|
-
// safe to have deeply property chains like this
|
12513
|
-
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12514
|
-
return {
|
12515
|
-
kty: 'RSA',
|
12516
|
-
n: toString$1(bnToBuf(values[0].toBigInt()), 'base64url'),
|
12517
|
-
e: toString$1(bnToBuf(values[1].toBigInt()), 'base64url')
|
12518
|
-
};
|
12519
12322
|
}
|
12520
12323
|
/**
|
12521
|
-
*
|
12324
|
+
* WebCrypto was not available in the current context
|
12522
12325
|
*/
|
12523
|
-
|
12524
|
-
|
12525
|
-
|
12326
|
+
class WebCryptoMissingError extends Error {
|
12327
|
+
constructor(message = 'Missing Web Crypto API') {
|
12328
|
+
super(message);
|
12329
|
+
this.name = 'WebCryptoMissingError';
|
12526
12330
|
}
|
12527
|
-
const root = new Sequence({
|
12528
|
-
value: [
|
12529
|
-
new Sequence({
|
12530
|
-
value: [
|
12531
|
-
// rsaEncryption
|
12532
|
-
new ObjectIdentifier({
|
12533
|
-
value: '1.2.840.113549.1.1.1'
|
12534
|
-
}),
|
12535
|
-
new Null()
|
12536
|
-
]
|
12537
|
-
}),
|
12538
|
-
// this appears to be a bug in asn1js.js - this should really be a Sequence
|
12539
|
-
// and not a BitString but it generates the same bytes as node-forge so ๐คทโโ๏ธ
|
12540
|
-
new BitString({
|
12541
|
-
valueHex: new Sequence({
|
12542
|
-
value: [
|
12543
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12544
|
-
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
|
12545
|
-
]
|
12546
|
-
}).toBER()
|
12547
|
-
})
|
12548
|
-
]
|
12549
|
-
});
|
12550
|
-
const der = root.toBER();
|
12551
|
-
return new Uint8Array(der, 0, der.byteLength);
|
12552
12331
|
}
|
12553
|
-
|
12554
|
-
|
12555
|
-
|
12556
|
-
|
12557
|
-
|
12558
|
-
|
12559
|
-
|
12560
|
-
|
12561
|
-
|
12562
|
-
|
12563
|
-
|
12564
|
-
|
12565
|
-
|
12566
|
-
}
|
12567
|
-
return u8;
|
12568
|
-
}
|
12569
|
-
function bufToBn(u8) {
|
12570
|
-
const hex = [];
|
12571
|
-
u8.forEach(function (i) {
|
12572
|
-
let h = i.toString(16);
|
12573
|
-
if (h.length % 2 > 0) {
|
12574
|
-
h = `0${h}`;
|
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');
|
12575
12345
|
}
|
12576
|
-
|
12577
|
-
}
|
12578
|
-
|
12579
|
-
}
|
12580
|
-
const SALT_LENGTH = 16;
|
12581
|
-
const KEY_SIZE = 32;
|
12582
|
-
const ITERATIONS = 10000;
|
12583
|
-
async function exportToPem(privateKey, password) {
|
12584
|
-
const crypto = webcrypto.get();
|
12585
|
-
// PrivateKeyInfo
|
12586
|
-
const keyWrapper = new Sequence({
|
12587
|
-
value: [
|
12588
|
-
// version (0)
|
12589
|
-
new Integer({ value: 0 }),
|
12590
|
-
// privateKeyAlgorithm
|
12591
|
-
new Sequence({
|
12592
|
-
value: [
|
12593
|
-
// rsaEncryption OID
|
12594
|
-
new ObjectIdentifier({
|
12595
|
-
value: '1.2.840.113549.1.1.1'
|
12596
|
-
}),
|
12597
|
-
new Null()
|
12598
|
-
]
|
12599
|
-
}),
|
12600
|
-
// PrivateKey
|
12601
|
-
new OctetString({
|
12602
|
-
valueHex: privateKey.marshal()
|
12603
|
-
})
|
12604
|
-
]
|
12605
|
-
});
|
12606
|
-
const keyBuf = keyWrapper.toBER();
|
12607
|
-
const keyArr = new Uint8Array(keyBuf, 0, keyBuf.byteLength);
|
12608
|
-
const salt = randomBytes(SALT_LENGTH);
|
12609
|
-
const encryptionKey = await pbkdf2Async(sha512, password, salt, {
|
12610
|
-
c: ITERATIONS,
|
12611
|
-
dkLen: KEY_SIZE
|
12612
|
-
});
|
12613
|
-
const iv = randomBytes(16);
|
12614
|
-
const cryptoKey = await crypto.subtle.importKey('raw', encryptionKey, 'AES-CBC', false, ['encrypt']);
|
12615
|
-
const encrypted = await crypto.subtle.encrypt({
|
12616
|
-
name: 'AES-CBC',
|
12617
|
-
iv
|
12618
|
-
}, cryptoKey, keyArr);
|
12619
|
-
const pbkdf2Params = new Sequence({
|
12620
|
-
value: [
|
12621
|
-
// salt
|
12622
|
-
new OctetString({ valueHex: salt }),
|
12623
|
-
// iteration count
|
12624
|
-
new Integer({ value: ITERATIONS }),
|
12625
|
-
// key length
|
12626
|
-
new Integer({ value: KEY_SIZE }),
|
12627
|
-
// AlgorithmIdentifier
|
12628
|
-
new Sequence({
|
12629
|
-
value: [
|
12630
|
-
// hmacWithSHA512
|
12631
|
-
new ObjectIdentifier({ value: '1.2.840.113549.2.11' }),
|
12632
|
-
new Null()
|
12633
|
-
]
|
12634
|
-
})
|
12635
|
-
]
|
12636
|
-
});
|
12637
|
-
const encryptionAlgorithm = new Sequence({
|
12638
|
-
value: [
|
12639
|
-
// pkcs5PBES2
|
12640
|
-
new ObjectIdentifier({
|
12641
|
-
value: '1.2.840.113549.1.5.13'
|
12642
|
-
}),
|
12643
|
-
new Sequence({
|
12644
|
-
value: [
|
12645
|
-
// keyDerivationFunc
|
12646
|
-
new Sequence({
|
12647
|
-
value: [
|
12648
|
-
// pkcs5PBKDF2
|
12649
|
-
new ObjectIdentifier({
|
12650
|
-
value: '1.2.840.113549.1.5.12'
|
12651
|
-
}),
|
12652
|
-
// PBKDF2-params
|
12653
|
-
pbkdf2Params
|
12654
|
-
]
|
12655
|
-
}),
|
12656
|
-
// encryptionScheme
|
12657
|
-
new Sequence({
|
12658
|
-
value: [
|
12659
|
-
// aes256-CBC
|
12660
|
-
new ObjectIdentifier({
|
12661
|
-
value: '2.16.840.1.101.3.4.1.42'
|
12662
|
-
}),
|
12663
|
-
// iv
|
12664
|
-
new OctetString({
|
12665
|
-
valueHex: iv
|
12666
|
-
})
|
12667
|
-
]
|
12668
|
-
})
|
12669
|
-
]
|
12670
|
-
})
|
12671
|
-
]
|
12672
|
-
});
|
12673
|
-
const finalWrapper = new Sequence({
|
12674
|
-
value: [
|
12675
|
-
encryptionAlgorithm,
|
12676
|
-
new OctetString({ valueHex: encrypted })
|
12677
|
-
]
|
12678
|
-
});
|
12679
|
-
const finalWrapperBuf = finalWrapper.toBER();
|
12680
|
-
const finalWrapperArr = new Uint8Array(finalWrapperBuf, 0, finalWrapperBuf.byteLength);
|
12681
|
-
return [
|
12682
|
-
'-----BEGIN ENCRYPTED PRIVATE KEY-----',
|
12683
|
-
...toString$1(finalWrapperArr, 'base64pad').split(/(.{64})/).filter(Boolean),
|
12684
|
-
'-----END ENCRYPTED PRIVATE KEY-----'
|
12685
|
-
].join('\n');
|
12686
|
-
}
|
12346
|
+
return nativeCrypto;
|
12347
|
+
}
|
12348
|
+
};
|
12687
12349
|
|
12688
|
-
async function generateKey$1(bits) {
|
12689
|
-
const pair = await webcrypto.get().subtle.generateKey({
|
12690
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12691
|
-
modulusLength: bits,
|
12692
|
-
publicExponent: new Uint8Array([0x01, 0x00, 0x01]),
|
12693
|
-
hash: { name: 'SHA-256' }
|
12694
|
-
}, true, ['sign', 'verify']);
|
12695
|
-
const keys = await exportKey(pair);
|
12696
|
-
return {
|
12697
|
-
privateKey: keys[0],
|
12698
|
-
publicKey: keys[1]
|
12699
|
-
};
|
12700
|
-
}
|
12701
|
-
// Takes a jwk key
|
12702
|
-
async function unmarshalPrivateKey$1(key) {
|
12703
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12704
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12705
|
-
hash: { name: 'SHA-256' }
|
12706
|
-
}, true, ['sign']);
|
12707
|
-
const pair = [
|
12708
|
-
privateKey,
|
12709
|
-
await derivePublicFromPrivate(key)
|
12710
|
-
];
|
12711
|
-
const keys = await exportKey({
|
12712
|
-
privateKey: pair[0],
|
12713
|
-
publicKey: pair[1]
|
12714
|
-
});
|
12715
|
-
return {
|
12716
|
-
privateKey: keys[0],
|
12717
|
-
publicKey: keys[1]
|
12718
|
-
};
|
12719
|
-
}
|
12720
|
-
async function hashAndSign$1(key, msg) {
|
12721
|
-
const privateKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12722
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12723
|
-
hash: { name: 'SHA-256' }
|
12724
|
-
}, false, ['sign']);
|
12725
|
-
const sig = await webcrypto.get().subtle.sign({ name: 'RSASSA-PKCS1-v1_5' }, privateKey, msg instanceof Uint8Array ? msg : msg.subarray());
|
12726
|
-
return new Uint8Array(sig, 0, sig.byteLength);
|
12727
|
-
}
|
12728
12350
|
async function hashAndVerify$1(key, sig, msg) {
|
12729
12351
|
const publicKey = await webcrypto.get().subtle.importKey('jwk', key, {
|
12730
12352
|
name: 'RSASSA-PKCS1-v1_5',
|
@@ -12732,176 +12354,245 @@ async function hashAndVerify$1(key, sig, msg) {
|
|
12732
12354
|
}, false, ['verify']);
|
12733
12355
|
return webcrypto.get().subtle.verify({ name: 'RSASSA-PKCS1-v1_5' }, publicKey, sig, msg instanceof Uint8Array ? msg : msg.subarray());
|
12734
12356
|
}
|
12735
|
-
|
12736
|
-
if (pair.privateKey == null || pair.publicKey == null) {
|
12737
|
-
throw new CodeError('Private and public key are required', 'ERR_INVALID_PARAMETERS');
|
12738
|
-
}
|
12739
|
-
return Promise.all([
|
12740
|
-
webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
|
12741
|
-
webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
|
12742
|
-
]);
|
12743
|
-
}
|
12744
|
-
async function derivePublicFromPrivate(jwKey) {
|
12745
|
-
return webcrypto.get().subtle.importKey('jwk', {
|
12746
|
-
kty: jwKey.kty,
|
12747
|
-
n: jwKey.n,
|
12748
|
-
e: jwKey.e
|
12749
|
-
}, {
|
12750
|
-
name: 'RSASSA-PKCS1-v1_5',
|
12751
|
-
hash: { name: 'SHA-256' }
|
12752
|
-
}, true, ['verify']);
|
12753
|
-
}
|
12754
|
-
function keySize(jwk) {
|
12357
|
+
function rsaKeySize(jwk) {
|
12755
12358
|
if (jwk.kty !== 'RSA') {
|
12756
|
-
throw new
|
12359
|
+
throw new InvalidParametersError('invalid key type');
|
12757
12360
|
}
|
12758
12361
|
else if (jwk.n == null) {
|
12759
|
-
throw new
|
12362
|
+
throw new InvalidParametersError('invalid key modulus');
|
12760
12363
|
}
|
12761
12364
|
const bytes = fromString(jwk.n, 'base64url');
|
12762
12365
|
return bytes.length * 8;
|
12763
12366
|
}
|
12764
12367
|
|
12765
|
-
|
12766
|
-
|
12368
|
+
class RSAPublicKey {
|
12369
|
+
type = 'RSA';
|
12767
12370
|
_key;
|
12768
|
-
|
12371
|
+
_raw;
|
12372
|
+
_multihash;
|
12373
|
+
constructor(key, digest) {
|
12769
12374
|
this._key = key;
|
12375
|
+
this._multihash = digest;
|
12770
12376
|
}
|
12771
|
-
|
12772
|
-
|
12773
|
-
|
12774
|
-
marshal() {
|
12775
|
-
return jwkToPkix(this._key);
|
12776
|
-
}
|
12777
|
-
get bytes() {
|
12778
|
-
return PublicKey.encode({
|
12779
|
-
Type: KeyType.RSA,
|
12780
|
-
Data: this.marshal()
|
12781
|
-
}).subarray();
|
12782
|
-
}
|
12783
|
-
equals(key) {
|
12784
|
-
return equals(this.bytes, key.bytes);
|
12785
|
-
}
|
12786
|
-
hash() {
|
12787
|
-
const p = sha256$1.digest(this.bytes);
|
12788
|
-
if (isPromise(p)) {
|
12789
|
-
return p.then(({ bytes }) => bytes);
|
12377
|
+
get raw() {
|
12378
|
+
if (this._raw == null) {
|
12379
|
+
this._raw = jwkToPkix(this._key);
|
12790
12380
|
}
|
12791
|
-
return
|
12792
|
-
}
|
12793
|
-
}
|
12794
|
-
class RsaPrivateKey {
|
12795
|
-
_key;
|
12796
|
-
_publicKey;
|
12797
|
-
constructor(key, publicKey) {
|
12798
|
-
this._key = key;
|
12799
|
-
this._publicKey = publicKey;
|
12800
|
-
}
|
12801
|
-
genSecret() {
|
12802
|
-
return randomBytes(16);
|
12803
|
-
}
|
12804
|
-
sign(message) {
|
12805
|
-
return hashAndSign$1(this._key, message);
|
12381
|
+
return this._raw;
|
12806
12382
|
}
|
12807
|
-
|
12808
|
-
|
12809
|
-
throw new CodeError('public key not provided', 'ERR_PUBKEY_NOT_PROVIDED');
|
12810
|
-
}
|
12811
|
-
return new RsaPublicKey(this._publicKey);
|
12383
|
+
toMultihash() {
|
12384
|
+
return this._multihash;
|
12812
12385
|
}
|
12813
|
-
|
12814
|
-
return
|
12386
|
+
toCID() {
|
12387
|
+
return CID.createV1(114, this._multihash);
|
12815
12388
|
}
|
12816
|
-
|
12817
|
-
return
|
12818
|
-
Type: KeyType.RSA,
|
12819
|
-
Data: this.marshal()
|
12820
|
-
}).subarray();
|
12389
|
+
toString() {
|
12390
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
12821
12391
|
}
|
12822
12392
|
equals(key) {
|
12823
|
-
|
12824
|
-
|
12825
|
-
hash() {
|
12826
|
-
const p = sha256$1.digest(this.bytes);
|
12827
|
-
if (isPromise(p)) {
|
12828
|
-
return p.then(({ bytes }) => bytes);
|
12393
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
12394
|
+
return false;
|
12829
12395
|
}
|
12830
|
-
return
|
12396
|
+
return equals(this.raw, key.raw);
|
12831
12397
|
}
|
12832
|
-
|
12833
|
-
|
12834
|
-
*
|
12835
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
12836
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
12837
|
-
* of the PKCS SubjectPublicKeyInfo.
|
12838
|
-
*/
|
12839
|
-
async id() {
|
12840
|
-
const hash = await this.public.hash();
|
12841
|
-
return toString$1(hash, 'base58btc');
|
12398
|
+
verify(data, sig) {
|
12399
|
+
return hashAndVerify$1(this._key, sig, data);
|
12842
12400
|
}
|
12843
|
-
|
12844
|
-
|
12845
|
-
|
12846
|
-
|
12847
|
-
|
12848
|
-
|
12849
|
-
|
12850
|
-
|
12851
|
-
|
12852
|
-
|
12853
|
-
|
12854
|
-
|
12855
|
-
|
12856
|
-
|
12857
|
-
|
12858
|
-
|
12859
|
-
|
12401
|
+
}
|
12402
|
+
|
12403
|
+
const MAX_RSA_KEY_SIZE = 8192;
|
12404
|
+
const SHA2_256_CODE = 0x12;
|
12405
|
+
/**
|
12406
|
+
* Convert a PKIX in ASN1 DER format to a JWK key
|
12407
|
+
*/
|
12408
|
+
function pkixToJwk(bytes) {
|
12409
|
+
const { result } = fromBER(bytes);
|
12410
|
+
// @ts-expect-error this looks fragile but DER is a canonical format so we are
|
12411
|
+
// safe to have deeply property chains like this
|
12412
|
+
const values = result.valueBlock.value[1].valueBlock.value[0].valueBlock.value;
|
12413
|
+
return {
|
12414
|
+
kty: 'RSA',
|
12415
|
+
n: asn1jsIntegerToBase64(values[0]),
|
12416
|
+
e: asn1jsIntegerToBase64(values[1])
|
12417
|
+
};
|
12418
|
+
}
|
12419
|
+
/**
|
12420
|
+
* Convert a JWK key to PKIX in ASN1 DER format
|
12421
|
+
*/
|
12422
|
+
function jwkToPkix(jwk) {
|
12423
|
+
if (jwk.n == null || jwk.e == null) {
|
12424
|
+
throw new InvalidParametersError('JWK was missing components');
|
12860
12425
|
}
|
12426
|
+
const root = new Sequence({
|
12427
|
+
value: [
|
12428
|
+
new Sequence({
|
12429
|
+
value: [
|
12430
|
+
// rsaEncryption
|
12431
|
+
new ObjectIdentifier({
|
12432
|
+
value: '1.2.840.113549.1.1.1'
|
12433
|
+
}),
|
12434
|
+
new Null()
|
12435
|
+
]
|
12436
|
+
}),
|
12437
|
+
// this appears to be a bug in asn1js.js - this should really be a Sequence
|
12438
|
+
// and not a BitString but it generates the same bytes as node-forge so ๐คทโโ๏ธ
|
12439
|
+
new BitString({
|
12440
|
+
valueHex: new Sequence({
|
12441
|
+
value: [
|
12442
|
+
Integer.fromBigInt(bufToBn(fromString(jwk.n, 'base64url'))),
|
12443
|
+
Integer.fromBigInt(bufToBn(fromString(jwk.e, 'base64url')))
|
12444
|
+
]
|
12445
|
+
}).toBER()
|
12446
|
+
})
|
12447
|
+
]
|
12448
|
+
});
|
12449
|
+
const der = root.toBER();
|
12450
|
+
return new Uint8Array(der, 0, der.byteLength);
|
12861
12451
|
}
|
12862
|
-
|
12863
|
-
|
12864
|
-
|
12865
|
-
|
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);
|
12866
12457
|
}
|
12867
|
-
|
12868
|
-
|
12458
|
+
return toString$1(buf, 'base64url');
|
12459
|
+
}
|
12460
|
+
function bufToBn(u8) {
|
12461
|
+
const hex = [];
|
12462
|
+
u8.forEach(function (i) {
|
12463
|
+
let h = i.toString(16);
|
12464
|
+
if (h.length % 2 > 0) {
|
12465
|
+
h = `0${h}`;
|
12466
|
+
}
|
12467
|
+
hex.push(h);
|
12468
|
+
});
|
12469
|
+
return BigInt('0x' + hex.join(''));
|
12869
12470
|
}
|
12870
|
-
|
12471
|
+
/**
|
12472
|
+
* Turn PKIX bytes to a PublicKey
|
12473
|
+
*/
|
12474
|
+
function pkixToRSAPublicKey(bytes) {
|
12871
12475
|
const jwk = pkixToJwk(bytes);
|
12872
|
-
if (
|
12873
|
-
throw new
|
12476
|
+
if (rsaKeySize(jwk) > MAX_RSA_KEY_SIZE) {
|
12477
|
+
throw new InvalidPublicKeyError('Key size is too large');
|
12874
12478
|
}
|
12875
|
-
|
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);
|
12876
12485
|
}
|
12877
|
-
|
12878
|
-
|
12879
|
-
|
12486
|
+
|
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);
|
12880
12517
|
}
|
12881
|
-
|
12882
|
-
|
12883
|
-
|
12884
|
-
|
12885
|
-
|
12886
|
-
|
12518
|
+
update(buf) {
|
12519
|
+
aexists(this);
|
12520
|
+
this.iHash.update(buf);
|
12521
|
+
return this;
|
12522
|
+
}
|
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();
|
12531
|
+
}
|
12532
|
+
digest() {
|
12533
|
+
const out = new Uint8Array(this.oHash.outputLen);
|
12534
|
+
this.digestInto(out);
|
12535
|
+
return out;
|
12536
|
+
}
|
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;
|
12549
|
+
}
|
12550
|
+
destroy() {
|
12551
|
+
this.destroyed = true;
|
12552
|
+
this.oHash.destroy();
|
12553
|
+
this.iHash.destroy();
|
12887
12554
|
}
|
12888
|
-
const keys = await generateKey$1(bits);
|
12889
|
-
return new RsaPrivateKey(keys.privateKey, keys.publicKey);
|
12890
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);
|
12891
12568
|
|
12892
|
-
|
12893
|
-
|
12894
|
-
|
12895
|
-
|
12896
|
-
|
12897
|
-
|
12898
|
-
|
12899
|
-
|
12900
|
-
|
12901
|
-
|
12902
|
-
|
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
|
+
*/
|
12903
12595
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
12904
|
-
// Short Weierstrass curve. The formula is: yยฒ = xยณ + ax + b
|
12905
12596
|
function validateSigVerOpts(opts) {
|
12906
12597
|
if (opts.lowS !== undefined)
|
12907
12598
|
abool('lowS', opts.lowS);
|
@@ -12925,73 +12616,132 @@ function validatePointOpts(curve) {
|
|
12925
12616
|
const { endo, Fp, a } = opts;
|
12926
12617
|
if (endo) {
|
12927
12618
|
if (!Fp.eql(a, Fp.ZERO)) {
|
12928
|
-
throw new Error('
|
12619
|
+
throw new Error('invalid endomorphism, can only be defined for Koblitz curves that have a=0');
|
12929
12620
|
}
|
12930
12621
|
if (typeof endo !== 'object' ||
|
12931
12622
|
typeof endo.beta !== 'bigint' ||
|
12932
12623
|
typeof endo.splitScalar !== 'function') {
|
12933
|
-
throw new Error('
|
12624
|
+
throw new Error('invalid endomorphism, expected beta: bigint and splitScalar: function');
|
12934
12625
|
}
|
12935
12626
|
}
|
12936
12627
|
return Object.freeze({ ...opts });
|
12937
12628
|
}
|
12938
|
-
// ASN.1 DER encoding utilities
|
12939
12629
|
const { bytesToNumberBE: b2n, hexToBytes: h2b } = ut;
|
12630
|
+
class DERErr extends Error {
|
12631
|
+
constructor(m = '') {
|
12632
|
+
super(m);
|
12633
|
+
}
|
12634
|
+
}
|
12635
|
+
/**
|
12636
|
+
* ASN.1 DER encoding utilities. ASN is very complex & fragile. Format:
|
12637
|
+
*
|
12638
|
+
* [0x30 (SEQUENCE), bytelength, 0x02 (INTEGER), intLength, R, 0x02 (INTEGER), intLength, S]
|
12639
|
+
*
|
12640
|
+
* Docs: https://letsencrypt.org/docs/a-warm-welcome-to-asn1-and-der/, https://luca.ntop.org/Teaching/Appunti/asn1.html
|
12641
|
+
*/
|
12940
12642
|
const DER = {
|
12941
12643
|
// asn.1 DER encoding utils
|
12942
|
-
Err:
|
12943
|
-
|
12944
|
-
|
12945
|
-
|
12644
|
+
Err: DERErr,
|
12645
|
+
// Basic building block is TLV (Tag-Length-Value)
|
12646
|
+
_tlv: {
|
12647
|
+
encode: (tag, data) => {
|
12648
|
+
const { Err: E } = DER;
|
12649
|
+
if (tag < 0 || tag > 256)
|
12650
|
+
throw new E('tlv.encode: wrong tag');
|
12651
|
+
if (data.length & 1)
|
12652
|
+
throw new E('tlv.encode: unpadded data');
|
12653
|
+
const dataLen = data.length / 2;
|
12654
|
+
const len = numberToHexUnpadded(dataLen);
|
12655
|
+
if ((len.length / 2) & 128)
|
12656
|
+
throw new E('tlv.encode: long form length too big');
|
12657
|
+
// length of length with long form flag
|
12658
|
+
const lenLen = dataLen > 127 ? numberToHexUnpadded((len.length / 2) | 128) : '';
|
12659
|
+
const t = numberToHexUnpadded(tag);
|
12660
|
+
return t + lenLen + len + data;
|
12661
|
+
},
|
12662
|
+
// v - value, l - left bytes (unparsed)
|
12663
|
+
decode(tag, data) {
|
12664
|
+
const { Err: E } = DER;
|
12665
|
+
let pos = 0;
|
12666
|
+
if (tag < 0 || tag > 256)
|
12667
|
+
throw new E('tlv.encode: wrong tag');
|
12668
|
+
if (data.length < 2 || data[pos++] !== tag)
|
12669
|
+
throw new E('tlv.decode: wrong tlv');
|
12670
|
+
const first = data[pos++];
|
12671
|
+
const isLong = !!(first & 128); // First bit of first length byte is flag for short/long form
|
12672
|
+
let length = 0;
|
12673
|
+
if (!isLong)
|
12674
|
+
length = first;
|
12675
|
+
else {
|
12676
|
+
// Long form: [longFlag(1bit), lengthLength(7bit), length (BE)]
|
12677
|
+
const lenLen = first & 127;
|
12678
|
+
if (!lenLen)
|
12679
|
+
throw new E('tlv.decode(long): indefinite length not supported');
|
12680
|
+
if (lenLen > 4)
|
12681
|
+
throw new E('tlv.decode(long): byte length is too big'); // this will overflow u32 in js
|
12682
|
+
const lengthBytes = data.subarray(pos, pos + lenLen);
|
12683
|
+
if (lengthBytes.length !== lenLen)
|
12684
|
+
throw new E('tlv.decode: length bytes not complete');
|
12685
|
+
if (lengthBytes[0] === 0)
|
12686
|
+
throw new E('tlv.decode(long): zero leftmost byte');
|
12687
|
+
for (const b of lengthBytes)
|
12688
|
+
length = (length << 8) | b;
|
12689
|
+
pos += lenLen;
|
12690
|
+
if (length < 128)
|
12691
|
+
throw new E('tlv.decode(long): not minimal encoding');
|
12692
|
+
}
|
12693
|
+
const v = data.subarray(pos, pos + length);
|
12694
|
+
if (v.length !== length)
|
12695
|
+
throw new E('tlv.decode: wrong value length');
|
12696
|
+
return { v, l: data.subarray(pos + length) };
|
12697
|
+
},
|
12946
12698
|
},
|
12947
|
-
|
12948
|
-
|
12949
|
-
|
12950
|
-
|
12951
|
-
|
12952
|
-
|
12953
|
-
|
12954
|
-
|
12955
|
-
|
12956
|
-
|
12957
|
-
|
12958
|
-
|
12959
|
-
|
12960
|
-
|
12961
|
-
|
12962
|
-
|
12963
|
-
|
12699
|
+
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
12700
|
+
// since we always use positive integers here. It must always be empty:
|
12701
|
+
// - add zero byte if exists
|
12702
|
+
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
12703
|
+
_int: {
|
12704
|
+
encode(num) {
|
12705
|
+
const { Err: E } = DER;
|
12706
|
+
if (num < _0n)
|
12707
|
+
throw new E('integer: negative integers are not allowed');
|
12708
|
+
let hex = numberToHexUnpadded(num);
|
12709
|
+
// Pad with zero byte if negative flag is present
|
12710
|
+
if (Number.parseInt(hex[0], 16) & 0b1000)
|
12711
|
+
hex = '00' + hex;
|
12712
|
+
if (hex.length & 1)
|
12713
|
+
throw new E('unexpected DER parsing assertion: unpadded hex');
|
12714
|
+
return hex;
|
12715
|
+
},
|
12716
|
+
decode(data) {
|
12717
|
+
const { Err: E } = DER;
|
12718
|
+
if (data[0] & 128)
|
12719
|
+
throw new E('invalid signature integer: negative');
|
12720
|
+
if (data[0] === 0x00 && !(data[1] & 128))
|
12721
|
+
throw new E('invalid signature integer: unnecessary leading zero');
|
12722
|
+
return b2n(data);
|
12723
|
+
},
|
12964
12724
|
},
|
12965
12725
|
toSig(hex) {
|
12966
12726
|
// parse DER signature
|
12967
|
-
const { Err: E } = DER;
|
12727
|
+
const { Err: E, _int: int, _tlv: tlv } = DER;
|
12968
12728
|
const data = typeof hex === 'string' ? h2b(hex) : hex;
|
12969
12729
|
abytes(data);
|
12970
|
-
|
12971
|
-
if (
|
12972
|
-
throw new E('
|
12973
|
-
|
12974
|
-
|
12975
|
-
|
12976
|
-
|
12977
|
-
|
12978
|
-
throw new E('Invalid signature: left bytes after parsing');
|
12979
|
-
return { r, s };
|
12730
|
+
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(0x30, data);
|
12731
|
+
if (seqLeftBytes.length)
|
12732
|
+
throw new E('invalid signature: left bytes after parsing');
|
12733
|
+
const { v: rBytes, l: rLeftBytes } = tlv.decode(0x02, seqBytes);
|
12734
|
+
const { v: sBytes, l: sLeftBytes } = tlv.decode(0x02, rLeftBytes);
|
12735
|
+
if (sLeftBytes.length)
|
12736
|
+
throw new E('invalid signature: left bytes after parsing');
|
12737
|
+
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
12980
12738
|
},
|
12981
12739
|
hexFromSig(sig) {
|
12982
|
-
|
12983
|
-
const
|
12984
|
-
const
|
12985
|
-
|
12986
|
-
|
12987
|
-
};
|
12988
|
-
const s = slice(h(sig.s));
|
12989
|
-
const r = slice(h(sig.r));
|
12990
|
-
const shl = s.length / 2;
|
12991
|
-
const rhl = r.length / 2;
|
12992
|
-
const sl = h(shl);
|
12993
|
-
const rl = h(rhl);
|
12994
|
-
return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
|
12740
|
+
const { _tlv: tlv, _int: int } = DER;
|
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;
|
12744
|
+
return tlv.encode(0x30, seq);
|
12995
12745
|
},
|
12996
12746
|
};
|
12997
12747
|
// Be friendly to bad ECMAScript parsers by not using bigint literals
|
@@ -13000,6 +12750,7 @@ const _0n = BigInt(0), _1n$1 = BigInt(1); BigInt(2); const _3n = BigInt(3); BigI
|
|
13000
12750
|
function weierstrassPoints(opts) {
|
13001
12751
|
const CURVE = validatePointOpts(opts);
|
13002
12752
|
const { Fp } = CURVE; // All curves has same field / group length as for now, but they can differ
|
12753
|
+
const Fn = Field(CURVE.n, CURVE.nBitLength);
|
13003
12754
|
const toBytes = CURVE.toBytes ||
|
13004
12755
|
((_c, point, _isCompressed) => {
|
13005
12756
|
const a = point.toAffine();
|
@@ -13043,7 +12794,7 @@ function weierstrassPoints(opts) {
|
|
13043
12794
|
key = bytesToHex(key);
|
13044
12795
|
// Normalize to hex string, pad. E.g. P521 would norm 130-132 char hex to 132-char bytes
|
13045
12796
|
if (typeof key !== 'string' || !lengths.includes(key.length))
|
13046
|
-
throw new Error('
|
12797
|
+
throw new Error('invalid private key');
|
13047
12798
|
key = key.padStart(nByteLength * 2, '0');
|
13048
12799
|
}
|
13049
12800
|
let num;
|
@@ -13054,7 +12805,7 @@ function weierstrassPoints(opts) {
|
|
13054
12805
|
: bytesToNumberBE(ensureBytes('private key', key, nByteLength));
|
13055
12806
|
}
|
13056
12807
|
catch (error) {
|
13057
|
-
throw new Error(
|
12808
|
+
throw new Error('invalid private key, expected hex or ' + nByteLength + ' bytes, got ' + typeof key);
|
13058
12809
|
}
|
13059
12810
|
if (wrapPrivateKey)
|
13060
12811
|
num = mod(num, N); // disabled by default, enabled for BLS
|
@@ -13094,7 +12845,7 @@ function weierstrassPoints(opts) {
|
|
13094
12845
|
if (p.is0()) {
|
13095
12846
|
// (0, 1, 0) aka ZERO is invalid in most contexts.
|
13096
12847
|
// In BLS, ZERO can be serialized, so we allow it.
|
13097
|
-
// (0, 0, 0) is
|
12848
|
+
// (0, 0, 0) is invalid representation of ZERO.
|
13098
12849
|
if (CURVE.allowInfinityPoint && !Fp.is0(p.py))
|
13099
12850
|
return;
|
13100
12851
|
throw new Error('bad point: ZERO');
|
@@ -13173,6 +12924,10 @@ function weierstrassPoints(opts) {
|
|
13173
12924
|
static fromPrivateKey(privateKey) {
|
13174
12925
|
return Point.BASE.multiply(normPrivateKeyToScalar(privateKey));
|
13175
12926
|
}
|
12927
|
+
// Multiscalar Multiplication
|
12928
|
+
static msm(points, scalars) {
|
12929
|
+
return pippenger(Point, Fn, points, scalars);
|
12930
|
+
}
|
13176
12931
|
// "Private method", don't use it directly
|
13177
12932
|
_setWindowSize(windowSize) {
|
13178
12933
|
wnaf.setWindowSize(this, windowSize);
|
@@ -13314,16 +13069,17 @@ function weierstrassPoints(opts) {
|
|
13314
13069
|
* an exposed private key e.g. sig verification, which works over *public* keys.
|
13315
13070
|
*/
|
13316
13071
|
multiplyUnsafe(sc) {
|
13317
|
-
|
13072
|
+
const { endo, n: N } = CURVE;
|
13073
|
+
aInRange('scalar', sc, _0n, N);
|
13318
13074
|
const I = Point.ZERO;
|
13319
13075
|
if (sc === _0n)
|
13320
13076
|
return I;
|
13321
|
-
if (sc === _1n$1)
|
13077
|
+
if (this.is0() || sc === _1n$1)
|
13322
13078
|
return this;
|
13323
|
-
|
13324
|
-
if (!endo)
|
13325
|
-
return wnaf.
|
13326
|
-
//
|
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
|
13327
13083
|
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(sc);
|
13328
13084
|
let k1p = I;
|
13329
13085
|
let k2p = I;
|
@@ -13509,7 +13265,9 @@ function weierstrass(curveDef) {
|
|
13509
13265
|
return { x, y };
|
13510
13266
|
}
|
13511
13267
|
else {
|
13512
|
-
|
13268
|
+
const cl = compressedLen;
|
13269
|
+
const ul = uncompressedLen;
|
13270
|
+
throw new Error('invalid Point, expected length of ' + cl + ', or uncompressed ' + ul + ', got ' + len);
|
13513
13271
|
}
|
13514
13272
|
},
|
13515
13273
|
});
|
@@ -13674,6 +13432,9 @@ function weierstrass(curveDef) {
|
|
13674
13432
|
// int2octets can't be used; pads small msgs with 0: unacceptatble for trunc as per RFC vectors
|
13675
13433
|
const bits2int = CURVE.bits2int ||
|
13676
13434
|
function (bytes) {
|
13435
|
+
// Our custom check "just in case"
|
13436
|
+
if (bytes.length > 8192)
|
13437
|
+
throw new Error('input is too large');
|
13677
13438
|
// For curves with nBitLength % 8 !== 0: bits2octets(bits2octets(m)) !== bits2octets(m)
|
13678
13439
|
// for some cases, since bytes.length * 8 is not actual bitLength.
|
13679
13440
|
const num = bytesToNumberBE(bytes); // check for == u8 done here
|
@@ -13690,15 +13451,15 @@ function weierstrass(curveDef) {
|
|
13690
13451
|
* Converts to bytes. Checks if num in `[0..ORDER_MASK-1]` e.g.: `[0..2^256-1]`.
|
13691
13452
|
*/
|
13692
13453
|
function int2octets(num) {
|
13693
|
-
aInRange(
|
13454
|
+
aInRange('num < 2^' + CURVE.nBitLength, num, _0n, ORDER_MASK);
|
13694
13455
|
// works with order, can have different size than numToField!
|
13695
13456
|
return numberToBytesBE(num, CURVE.nByteLength);
|
13696
13457
|
}
|
13697
13458
|
// Steps A, D of RFC6979 3.2
|
13698
13459
|
// Creates RFC6979 seed; converts msg/privKey to numbers.
|
13699
13460
|
// Used only in sign, not in verify.
|
13700
|
-
// NOTE: we cannot assume here that msgHash has same amount of bytes as curve order,
|
13701
|
-
// 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
|
13702
13463
|
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
|
13703
13464
|
if (['recovered', 'canonical'].some((k) => k in opts))
|
13704
13465
|
throw new Error('sign() legacy options not supported');
|
@@ -13792,39 +13553,48 @@ function weierstrass(curveDef) {
|
|
13792
13553
|
const sg = signature;
|
13793
13554
|
msgHash = ensureBytes('msgHash', msgHash);
|
13794
13555
|
publicKey = ensureBytes('publicKey', publicKey);
|
13556
|
+
const { lowS, prehash, format } = opts;
|
13557
|
+
// Verify opts, deduce signature format
|
13558
|
+
validateSigVerOpts(opts);
|
13795
13559
|
if ('strict' in opts)
|
13796
13560
|
throw new Error('options.strict was renamed to lowS');
|
13797
|
-
|
13798
|
-
|
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');
|
13799
13572
|
let _sig = undefined;
|
13800
13573
|
let P;
|
13801
13574
|
try {
|
13802
|
-
if (
|
13575
|
+
if (isObj)
|
13576
|
+
_sig = new Signature(sg.r, sg.s);
|
13577
|
+
if (isHex) {
|
13803
13578
|
// Signature can be represented in 2 ways: compact (2*nByteLength) & DER (variable-length).
|
13804
13579
|
// Since DER can also be 2*nByteLength bytes, we check for it first.
|
13805
13580
|
try {
|
13806
|
-
|
13581
|
+
if (format !== 'compact')
|
13582
|
+
_sig = Signature.fromDER(sg);
|
13807
13583
|
}
|
13808
13584
|
catch (derError) {
|
13809
13585
|
if (!(derError instanceof DER.Err))
|
13810
13586
|
throw derError;
|
13811
|
-
_sig = Signature.fromCompact(sg);
|
13812
13587
|
}
|
13813
|
-
|
13814
|
-
|
13815
|
-
const { r, s } = sg;
|
13816
|
-
_sig = new Signature(r, s);
|
13817
|
-
}
|
13818
|
-
else {
|
13819
|
-
throw new Error('PARSE');
|
13588
|
+
if (!_sig && format !== 'der')
|
13589
|
+
_sig = Signature.fromCompact(sg);
|
13820
13590
|
}
|
13821
13591
|
P = Point.fromHex(publicKey);
|
13822
13592
|
}
|
13823
13593
|
catch (error) {
|
13824
|
-
if (error.message === 'PARSE')
|
13825
|
-
throw new Error(`signature must be Signature instance, Uint8Array or hex string`);
|
13826
13594
|
return false;
|
13827
13595
|
}
|
13596
|
+
if (!_sig)
|
13597
|
+
return false;
|
13828
13598
|
if (lowS && _sig.hasHighS())
|
13829
13599
|
return false;
|
13830
13600
|
if (prehash)
|
@@ -13852,20 +13622,36 @@ function weierstrass(curveDef) {
|
|
13852
13622
|
};
|
13853
13623
|
}
|
13854
13624
|
|
13625
|
+
/**
|
13626
|
+
* Utilities for short weierstrass curves, combined with noble-hashes.
|
13627
|
+
* @module
|
13628
|
+
*/
|
13855
13629
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13856
|
-
|
13630
|
+
/** connects noble-curves to noble-hashes */
|
13857
13631
|
function getHash(hash) {
|
13858
13632
|
return {
|
13859
13633
|
hash,
|
13860
13634
|
hmac: (key, ...msgs) => hmac(hash, key, concatBytes$1(...msgs)),
|
13861
|
-
randomBytes
|
13635
|
+
randomBytes,
|
13862
13636
|
};
|
13863
13637
|
}
|
13864
13638
|
function createCurve(curveDef, defHash) {
|
13865
13639
|
const create = (hash) => weierstrass({ ...curveDef, ...getHash(hash) });
|
13866
|
-
return
|
13640
|
+
return { ...create(defHash), create };
|
13867
13641
|
}
|
13868
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
|
+
*/
|
13869
13655
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
13870
13656
|
const secp256k1P = BigInt('0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f');
|
13871
13657
|
const secp256k1N = BigInt('0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141');
|
@@ -13896,31 +13682,35 @@ function sqrtMod(y) {
|
|
13896
13682
|
const t1 = (pow2(b223, _23n, P) * b22) % P;
|
13897
13683
|
const t2 = (pow2(t1, _6n, P) * b2) % P;
|
13898
13684
|
const root = pow2(t2, _2n, P);
|
13899
|
-
if (!
|
13685
|
+
if (!Fpk1.eql(Fpk1.sqr(root), y))
|
13900
13686
|
throw new Error('Cannot find square root');
|
13901
13687
|
return root;
|
13902
13688
|
}
|
13903
|
-
const
|
13689
|
+
const Fpk1 = Field(secp256k1P, undefined, undefined, { sqrt: sqrtMod });
|
13904
13690
|
/**
|
13905
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;
|
13906
13701
|
*/
|
13907
13702
|
const secp256k1 = createCurve({
|
13908
13703
|
a: BigInt(0), // equation params: a, b
|
13909
|
-
b: BigInt(7),
|
13910
|
-
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
|
13911
13706
|
n: secp256k1N, // Curve order, total count of valid points in the field
|
13912
13707
|
// Base point (x, y) aka generator point
|
13913
13708
|
Gx: BigInt('55066263022277343669578718895168534326250603453777594175500187360389116729240'),
|
13914
13709
|
Gy: BigInt('32670510020758816978083085130507043184471273380659243275938904335757337482424'),
|
13915
13710
|
h: BigInt(1), // Cofactor
|
13916
13711
|
lowS: true, // Allow only low-S signatures by default in sign() and verify()
|
13917
|
-
/**
|
13918
|
-
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
|
13919
|
-
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
|
13920
|
-
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
|
13921
|
-
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
|
13922
|
-
*/
|
13923
13712
|
endo: {
|
13713
|
+
// Endomorphism, see above
|
13924
13714
|
beta: BigInt('0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee'),
|
13925
13715
|
splitScalar: (k) => {
|
13926
13716
|
const n = secp256k1N;
|
@@ -13951,27 +13741,15 @@ const secp256k1 = createCurve({
|
|
13951
13741
|
BigInt(0);
|
13952
13742
|
secp256k1.ProjectivePoint;
|
13953
13743
|
|
13954
|
-
function
|
13955
|
-
|
13956
|
-
|
13957
|
-
/**
|
13958
|
-
* Hash and sign message with private key
|
13959
|
-
*/
|
13960
|
-
function hashAndSign(key, msg) {
|
13961
|
-
const p = sha256$1.digest(msg instanceof Uint8Array ? msg : msg.subarray());
|
13962
|
-
if (isPromise(p)) {
|
13963
|
-
return p.then(({ digest }) => secp256k1.sign(digest, key).toDERRawBytes())
|
13964
|
-
.catch(err => {
|
13965
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
13966
|
-
});
|
13967
|
-
}
|
13968
|
-
try {
|
13969
|
-
return secp256k1.sign(p.digest, key).toDERRawBytes();
|
13970
|
-
}
|
13971
|
-
catch (err) {
|
13972
|
-
throw new CodeError(String(err), 'ERR_INVALID_INPUT');
|
13744
|
+
function isPromise(thing) {
|
13745
|
+
if (thing == null) {
|
13746
|
+
return false;
|
13973
13747
|
}
|
13748
|
+
return typeof thing.then === 'function' &&
|
13749
|
+
typeof thing.catch === 'function' &&
|
13750
|
+
typeof thing.finally === 'function';
|
13974
13751
|
}
|
13752
|
+
|
13975
13753
|
/**
|
13976
13754
|
* Hash message and verify signature with public key
|
13977
13755
|
*/
|
@@ -13980,208 +13758,93 @@ function hashAndVerify(key, sig, msg) {
|
|
13980
13758
|
if (isPromise(p)) {
|
13981
13759
|
return p.then(({ digest }) => secp256k1.verify(sig, digest, key))
|
13982
13760
|
.catch(err => {
|
13983
|
-
throw new
|
13761
|
+
throw new VerificationError(String(err));
|
13984
13762
|
});
|
13985
13763
|
}
|
13986
13764
|
try {
|
13987
13765
|
return secp256k1.verify(sig, p.digest, key);
|
13988
13766
|
}
|
13989
13767
|
catch (err) {
|
13990
|
-
throw new
|
13991
|
-
}
|
13992
|
-
}
|
13993
|
-
function compressPublicKey(key) {
|
13994
|
-
const point = secp256k1.ProjectivePoint.fromHex(key).toRawBytes(true);
|
13995
|
-
return point;
|
13996
|
-
}
|
13997
|
-
function validatePrivateKey(key) {
|
13998
|
-
try {
|
13999
|
-
secp256k1.getPublicKey(key, true);
|
14000
|
-
}
|
14001
|
-
catch (err) {
|
14002
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
14003
|
-
}
|
14004
|
-
}
|
14005
|
-
function validatePublicKey(key) {
|
14006
|
-
try {
|
14007
|
-
secp256k1.ProjectivePoint.fromHex(key);
|
14008
|
-
}
|
14009
|
-
catch (err) {
|
14010
|
-
throw new CodeError(String(err), 'ERR_INVALID_PUBLIC_KEY');
|
14011
|
-
}
|
14012
|
-
}
|
14013
|
-
function computePublicKey(privateKey) {
|
14014
|
-
try {
|
14015
|
-
return secp256k1.getPublicKey(privateKey, true);
|
14016
|
-
}
|
14017
|
-
catch (err) {
|
14018
|
-
throw new CodeError(String(err), 'ERR_INVALID_PRIVATE_KEY');
|
13768
|
+
throw new VerificationError(String(err));
|
14019
13769
|
}
|
14020
13770
|
}
|
14021
13771
|
|
14022
13772
|
class Secp256k1PublicKey {
|
13773
|
+
type = 'secp256k1';
|
13774
|
+
raw;
|
14023
13775
|
_key;
|
14024
13776
|
constructor(key) {
|
14025
|
-
|
14026
|
-
this.
|
14027
|
-
}
|
14028
|
-
verify(data, sig) {
|
14029
|
-
return hashAndVerify(this._key, sig, data);
|
14030
|
-
}
|
14031
|
-
marshal() {
|
14032
|
-
return compressPublicKey(this._key);
|
14033
|
-
}
|
14034
|
-
get bytes() {
|
14035
|
-
return PublicKey.encode({
|
14036
|
-
Type: KeyType.Secp256k1,
|
14037
|
-
Data: this.marshal()
|
14038
|
-
}).subarray();
|
14039
|
-
}
|
14040
|
-
equals(key) {
|
14041
|
-
return equals(this.bytes, key.bytes);
|
14042
|
-
}
|
14043
|
-
async hash() {
|
14044
|
-
const p = sha256$1.digest(this.bytes);
|
14045
|
-
let bytes;
|
14046
|
-
if (isPromise(p)) {
|
14047
|
-
({ bytes } = await p);
|
14048
|
-
}
|
14049
|
-
else {
|
14050
|
-
bytes = p.bytes;
|
14051
|
-
}
|
14052
|
-
return bytes;
|
13777
|
+
this._key = validateSecp256k1PublicKey(key);
|
13778
|
+
this.raw = compressSecp256k1PublicKey(this._key);
|
14053
13779
|
}
|
14054
|
-
|
14055
|
-
|
14056
|
-
_key;
|
14057
|
-
_publicKey;
|
14058
|
-
constructor(key, publicKey) {
|
14059
|
-
this._key = key;
|
14060
|
-
this._publicKey = publicKey ?? computePublicKey(key);
|
14061
|
-
validatePrivateKey(this._key);
|
14062
|
-
validatePublicKey(this._publicKey);
|
13780
|
+
toMultihash() {
|
13781
|
+
return identity.digest(publicKeyToProtobuf(this));
|
14063
13782
|
}
|
14064
|
-
|
14065
|
-
return
|
14066
|
-
}
|
14067
|
-
get public() {
|
14068
|
-
return new Secp256k1PublicKey(this._publicKey);
|
14069
|
-
}
|
14070
|
-
marshal() {
|
14071
|
-
return this._key;
|
13783
|
+
toCID() {
|
13784
|
+
return CID.createV1(114, this.toMultihash());
|
14072
13785
|
}
|
14073
|
-
|
14074
|
-
return
|
14075
|
-
Type: KeyType.Secp256k1,
|
14076
|
-
Data: this.marshal()
|
14077
|
-
}).subarray();
|
13786
|
+
toString() {
|
13787
|
+
return base58btc.encode(this.toMultihash().bytes).substring(1);
|
14078
13788
|
}
|
14079
13789
|
equals(key) {
|
14080
|
-
|
14081
|
-
|
14082
|
-
hash() {
|
14083
|
-
const p = sha256$1.digest(this.bytes);
|
14084
|
-
if (isPromise(p)) {
|
14085
|
-
return p.then(({ bytes }) => bytes);
|
13790
|
+
if (key == null || !(key.raw instanceof Uint8Array)) {
|
13791
|
+
return false;
|
14086
13792
|
}
|
14087
|
-
return
|
14088
|
-
}
|
14089
|
-
/**
|
14090
|
-
* Gets the ID of the key.
|
14091
|
-
*
|
14092
|
-
* The key id is the base58 encoding of the SHA-256 multihash of its public key.
|
14093
|
-
* The public key is a protobuf encoding containing a type and the DER encoding
|
14094
|
-
* of the PKCS SubjectPublicKeyInfo.
|
14095
|
-
*/
|
14096
|
-
async id() {
|
14097
|
-
const hash = await this.public.hash();
|
14098
|
-
return toString$1(hash, 'base58btc');
|
13793
|
+
return equals(this.raw, key.raw);
|
14099
13794
|
}
|
14100
|
-
|
14101
|
-
|
14102
|
-
*/
|
14103
|
-
async export(password, format = 'libp2p-key') {
|
14104
|
-
if (format === 'libp2p-key') {
|
14105
|
-
return exporter(this.bytes, password);
|
14106
|
-
}
|
14107
|
-
else {
|
14108
|
-
throw new CodeError(`export format '${format}' is not supported`, 'ERR_INVALID_EXPORT_FORMAT');
|
14109
|
-
}
|
13795
|
+
verify(data, sig) {
|
13796
|
+
return hashAndVerify(this._key, sig, data);
|
14110
13797
|
}
|
14111
13798
|
}
|
14112
|
-
|
14113
|
-
return new Secp256k1PrivateKey(bytes);
|
14114
|
-
}
|
13799
|
+
|
14115
13800
|
function unmarshalSecp256k1PublicKey(bytes) {
|
14116
13801
|
return new Secp256k1PublicKey(bytes);
|
14117
13802
|
}
|
14118
|
-
|
14119
|
-
const
|
14120
|
-
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
|
+
}
|
14121
13815
|
}
|
14122
|
-
|
14123
|
-
var Secp256k1 = /*#__PURE__*/Object.freeze({
|
14124
|
-
__proto__: null,
|
14125
|
-
Secp256k1PrivateKey: Secp256k1PrivateKey,
|
14126
|
-
Secp256k1PublicKey: Secp256k1PublicKey,
|
14127
|
-
generateKeyPair: generateKeyPair,
|
14128
|
-
unmarshalSecp256k1PrivateKey: unmarshalSecp256k1PrivateKey,
|
14129
|
-
unmarshalSecp256k1PublicKey: unmarshalSecp256k1PublicKey
|
14130
|
-
});
|
14131
13816
|
|
14132
13817
|
/**
|
14133
13818
|
* @packageDocumentation
|
14134
13819
|
*
|
14135
|
-
*
|
14136
|
-
*
|
14137
|
-
* The {@link generateKeyPair}, {@link marshalPublicKey}, and {@link marshalPrivateKey} functions accept a string `type` argument.
|
13820
|
+
* ## Supported Key Types
|
14138
13821
|
*
|
14139
13822
|
* Currently the `'RSA'`, `'ed25519'`, and `secp256k1` types are supported, although ed25519 and secp256k1 keys support only signing and verification of messages.
|
14140
13823
|
*
|
14141
13824
|
* For encryption / decryption support, RSA keys should be used.
|
14142
13825
|
*/
|
14143
|
-
const supportedKeys = {
|
14144
|
-
rsa: RSA,
|
14145
|
-
ed25519: Ed25519,
|
14146
|
-
secp256k1: Secp256k1
|
14147
|
-
};
|
14148
|
-
function unsupportedKey(type) {
|
14149
|
-
const supported = Object.keys(supportedKeys).join(' / ');
|
14150
|
-
return new CodeError(`invalid or unsupported key type ${type}. Must be ${supported}`, 'ERR_UNSUPPORTED_KEY_TYPE');
|
14151
|
-
}
|
14152
13826
|
/**
|
14153
|
-
*
|
13827
|
+
* Creates a public key from the raw key bytes
|
14154
13828
|
*/
|
14155
|
-
function
|
14156
|
-
|
14157
|
-
|
14158
|
-
|
14159
|
-
|
14160
|
-
|
14161
|
-
|
14162
|
-
|
14163
|
-
|
14164
|
-
return supportedKeys.secp256k1.unmarshalSecp256k1PublicKey(data);
|
14165
|
-
default:
|
14166
|
-
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);
|
14167
13838
|
}
|
14168
13839
|
}
|
14169
13840
|
/**
|
14170
|
-
* Converts a
|
13841
|
+
* Converts a public key object into a protobuf serialized public key
|
14171
13842
|
*/
|
14172
|
-
|
14173
|
-
|
14174
|
-
|
14175
|
-
|
14176
|
-
|
14177
|
-
return supportedKeys.rsa.unmarshalRsaPrivateKey(data);
|
14178
|
-
case KeyType.Ed25519:
|
14179
|
-
return supportedKeys.ed25519.unmarshalEd25519PrivateKey(data);
|
14180
|
-
case KeyType.Secp256k1:
|
14181
|
-
return supportedKeys.secp256k1.unmarshalSecp256k1PrivateKey(data);
|
14182
|
-
default:
|
14183
|
-
throw unsupportedKey(decoded.Type ?? 'RSA');
|
14184
|
-
}
|
13843
|
+
function publicKeyToProtobuf(key) {
|
13844
|
+
return PublicKey.encode({
|
13845
|
+
Type: KeyType[key.type],
|
13846
|
+
Data: key.raw
|
13847
|
+
});
|
14185
13848
|
}
|
14186
13849
|
|
14187
13850
|
/**
|
@@ -14200,25 +13863,16 @@ async function unmarshalPrivateKey(buf) {
|
|
14200
13863
|
* ```
|
14201
13864
|
*/
|
14202
13865
|
const inspect = Symbol.for('nodejs.util.inspect.custom');
|
14203
|
-
const baseDecoder = Object
|
14204
|
-
.values(bases)
|
14205
|
-
.map(codec => codec.decoder)
|
14206
|
-
// @ts-expect-error https://github.com/multiformats/js-multiformats/issues/141
|
14207
|
-
.reduce((acc, curr) => acc.or(curr), bases.identity.decoder);
|
14208
13866
|
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14209
13867
|
const LIBP2P_KEY_CODE = 0x72;
|
14210
|
-
const MARSHALLED_ED225519_PUBLIC_KEY_LENGTH = 36;
|
14211
|
-
const MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH = 37;
|
14212
13868
|
class PeerIdImpl {
|
14213
13869
|
type;
|
14214
13870
|
multihash;
|
14215
|
-
privateKey;
|
14216
13871
|
publicKey;
|
14217
13872
|
string;
|
14218
13873
|
constructor(init) {
|
14219
13874
|
this.type = init.type;
|
14220
13875
|
this.multihash = init.multihash;
|
14221
|
-
this.privateKey = init.privateKey;
|
14222
13876
|
// mark string cache as non-enumerable
|
14223
13877
|
Object.defineProperty(this, 'string', {
|
14224
13878
|
enumerable: false,
|
@@ -14235,17 +13889,14 @@ class PeerIdImpl {
|
|
14235
13889
|
}
|
14236
13890
|
return this.string;
|
14237
13891
|
}
|
13892
|
+
toMultihash() {
|
13893
|
+
return this.multihash;
|
13894
|
+
}
|
14238
13895
|
// return self-describing String representation
|
14239
13896
|
// in default format from RFC 0001: https://github.com/libp2p/specs/pull/209
|
14240
13897
|
toCID() {
|
14241
13898
|
return CID.createV1(LIBP2P_KEY_CODE, this.multihash);
|
14242
13899
|
}
|
14243
|
-
toBytes() {
|
14244
|
-
return this.multihash.bytes;
|
14245
|
-
}
|
14246
|
-
/**
|
14247
|
-
* Returns Multiaddr as a JSON string
|
14248
|
-
*/
|
14249
13900
|
toJSON() {
|
14250
13901
|
return this.toString();
|
14251
13902
|
}
|
@@ -14260,10 +13911,10 @@ class PeerIdImpl {
|
|
14260
13911
|
return equals(this.multihash.bytes, id);
|
14261
13912
|
}
|
14262
13913
|
else if (typeof id === 'string') {
|
14263
|
-
return
|
13914
|
+
return this.toString() === id;
|
14264
13915
|
}
|
14265
|
-
else if (id?.
|
14266
|
-
return equals(this.multihash.bytes, id.
|
13916
|
+
else if (id?.toMultihash()?.bytes != null) {
|
13917
|
+
return equals(this.multihash.bytes, id.toMultihash().bytes);
|
14267
13918
|
}
|
14268
13919
|
else {
|
14269
13920
|
throw new Error('not valid Id');
|
@@ -14285,7 +13936,7 @@ class PeerIdImpl {
|
|
14285
13936
|
return `PeerId(${this.toString()})`;
|
14286
13937
|
}
|
14287
13938
|
}
|
14288
|
-
class
|
13939
|
+
class RSAPeerId extends PeerIdImpl {
|
14289
13940
|
type = 'RSA';
|
14290
13941
|
publicKey;
|
14291
13942
|
constructor(init) {
|
@@ -14293,153 +13944,67 @@ class RSAPeerIdImpl extends PeerIdImpl {
|
|
14293
13944
|
this.publicKey = init.publicKey;
|
14294
13945
|
}
|
14295
13946
|
}
|
14296
|
-
class
|
13947
|
+
class Ed25519PeerId extends PeerIdImpl {
|
14297
13948
|
type = 'Ed25519';
|
14298
13949
|
publicKey;
|
14299
13950
|
constructor(init) {
|
14300
13951
|
super({ ...init, type: 'Ed25519' });
|
14301
|
-
this.publicKey = init.
|
13952
|
+
this.publicKey = init.publicKey;
|
14302
13953
|
}
|
14303
13954
|
}
|
14304
|
-
class
|
13955
|
+
class Secp256k1PeerId extends PeerIdImpl {
|
14305
13956
|
type = 'secp256k1';
|
14306
13957
|
publicKey;
|
14307
13958
|
constructor(init) {
|
14308
13959
|
super({ ...init, type: 'secp256k1' });
|
14309
|
-
this.publicKey = init.
|
14310
|
-
}
|
14311
|
-
}
|
14312
|
-
// these values are from https://github.com/multiformats/multicodec/blob/master/table.csv
|
14313
|
-
const TRANSPORT_IPFS_GATEWAY_HTTP_CODE = 0x0920;
|
14314
|
-
class URLPeerIdImpl {
|
14315
|
-
type = 'url';
|
14316
|
-
multihash;
|
14317
|
-
privateKey;
|
14318
|
-
publicKey;
|
14319
|
-
url;
|
14320
|
-
constructor(url) {
|
14321
|
-
this.url = url.toString();
|
14322
|
-
this.multihash = identity.digest(fromString(this.url));
|
14323
|
-
}
|
14324
|
-
[inspect]() {
|
14325
|
-
return `PeerId(${this.url})`;
|
14326
|
-
}
|
14327
|
-
[peerIdSymbol] = true;
|
14328
|
-
toString() {
|
14329
|
-
return this.toCID().toString();
|
14330
|
-
}
|
14331
|
-
toCID() {
|
14332
|
-
return CID.createV1(TRANSPORT_IPFS_GATEWAY_HTTP_CODE, this.multihash);
|
14333
|
-
}
|
14334
|
-
toBytes() {
|
14335
|
-
return this.toCID().bytes;
|
14336
|
-
}
|
14337
|
-
equals(other) {
|
14338
|
-
if (other == null) {
|
14339
|
-
return false;
|
14340
|
-
}
|
14341
|
-
if (other instanceof Uint8Array) {
|
14342
|
-
other = toString$1(other);
|
14343
|
-
}
|
14344
|
-
return other.toString() === this.toString();
|
14345
|
-
}
|
14346
|
-
}
|
14347
|
-
function peerIdFromString(str, decoder) {
|
14348
|
-
if (str.charAt(0) === '1' || str.charAt(0) === 'Q') {
|
14349
|
-
// identity hash ed25519/secp256k1 key or sha2-256 hash of
|
14350
|
-
// rsa public key - base58btc encoded either way
|
14351
|
-
const multihash = decode$2(base58btc.decode(`z${str}`));
|
14352
|
-
if (str.startsWith('12D')) {
|
14353
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14354
|
-
}
|
14355
|
-
else if (str.startsWith('16U')) {
|
14356
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14357
|
-
}
|
14358
|
-
else {
|
14359
|
-
return new RSAPeerIdImpl({ multihash });
|
14360
|
-
}
|
14361
|
-
}
|
14362
|
-
return peerIdFromBytes(baseDecoder.decode(str));
|
14363
|
-
}
|
14364
|
-
function peerIdFromBytes(buf) {
|
14365
|
-
try {
|
14366
|
-
const multihash = decode$2(buf);
|
14367
|
-
if (multihash.code === identity.code) {
|
14368
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14369
|
-
return new Ed25519PeerIdImpl({ multihash });
|
14370
|
-
}
|
14371
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14372
|
-
return new Secp256k1PeerIdImpl({ multihash });
|
14373
|
-
}
|
14374
|
-
}
|
14375
|
-
if (multihash.code === sha256$1.code) {
|
14376
|
-
return new RSAPeerIdImpl({ multihash });
|
14377
|
-
}
|
14378
|
-
}
|
14379
|
-
catch {
|
14380
|
-
return peerIdFromCID(CID.decode(buf));
|
14381
|
-
}
|
14382
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14383
|
-
}
|
14384
|
-
function peerIdFromCID(cid) {
|
14385
|
-
if (cid?.multihash == null || cid.version == null || (cid.version === 1 && (cid.code !== LIBP2P_KEY_CODE) && cid.code !== TRANSPORT_IPFS_GATEWAY_HTTP_CODE)) {
|
14386
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14387
|
-
}
|
14388
|
-
if (cid.code === TRANSPORT_IPFS_GATEWAY_HTTP_CODE) {
|
14389
|
-
const url = toString$1(cid.multihash.digest);
|
14390
|
-
return new URLPeerIdImpl(new URL(url));
|
14391
|
-
}
|
14392
|
-
const multihash = cid.multihash;
|
14393
|
-
if (multihash.code === sha256$1.code) {
|
14394
|
-
return new RSAPeerIdImpl({ multihash: cid.multihash });
|
14395
|
-
}
|
14396
|
-
else if (multihash.code === identity.code) {
|
14397
|
-
if (multihash.digest.length === MARSHALLED_ED225519_PUBLIC_KEY_LENGTH) {
|
14398
|
-
return new Ed25519PeerIdImpl({ multihash: cid.multihash });
|
14399
|
-
}
|
14400
|
-
else if (multihash.digest.length === MARSHALLED_SECP256K1_PUBLIC_KEY_LENGTH) {
|
14401
|
-
return new Secp256k1PeerIdImpl({ multihash: cid.multihash });
|
14402
|
-
}
|
13960
|
+
this.publicKey = init.publicKey;
|
14403
13961
|
}
|
14404
|
-
throw new Error('Supplied PeerID CID is invalid');
|
14405
13962
|
}
|
13963
|
+
|
14406
13964
|
/**
|
14407
|
-
* @
|
14408
|
-
*
|
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
|
+
* ```
|
14409
13978
|
*/
|
14410
|
-
|
14411
|
-
if (publicKey.
|
14412
|
-
return new
|
13979
|
+
function peerIdFromPublicKey(publicKey) {
|
13980
|
+
if (publicKey.type === 'Ed25519') {
|
13981
|
+
return new Ed25519PeerId({
|
13982
|
+
multihash: publicKey.toCID().multihash,
|
13983
|
+
publicKey
|
13984
|
+
});
|
13985
|
+
}
|
13986
|
+
else if (publicKey.type === 'secp256k1') {
|
13987
|
+
return new Secp256k1PeerId({
|
13988
|
+
multihash: publicKey.toCID().multihash,
|
13989
|
+
publicKey
|
13990
|
+
});
|
14413
13991
|
}
|
14414
|
-
if (publicKey.
|
14415
|
-
return new
|
13992
|
+
else if (publicKey.type === 'RSA') {
|
13993
|
+
return new RSAPeerId({
|
13994
|
+
multihash: publicKey.toCID().multihash,
|
13995
|
+
publicKey
|
13996
|
+
});
|
14416
13997
|
}
|
14417
|
-
|
13998
|
+
throw new UnsupportedKeyTypeError();
|
14418
13999
|
}
|
14419
14000
|
|
14001
|
+
const ERR_TYPE_NOT_IMPLEMENTED = "Keypair type not implemented";
|
14420
14002
|
function createPeerIdFromPublicKey(publicKey) {
|
14421
|
-
const
|
14422
|
-
|
14423
|
-
|
14424
|
-
function getPublicKeyFromPeerId(peerId) {
|
14425
|
-
if (peerId.type !== "secp256k1") {
|
14426
|
-
throw new Error("Unsupported peer id type");
|
14427
|
-
}
|
14428
|
-
if (!peerId.publicKey) {
|
14429
|
-
throw new Error("Public key not present on peer id");
|
14430
|
-
}
|
14431
|
-
return unmarshalPublicKey(peerId.publicKey).marshal();
|
14432
|
-
}
|
14433
|
-
// Only used in tests
|
14434
|
-
async function getPrivateKeyFromPeerId(peerId) {
|
14435
|
-
if (peerId.type !== "secp256k1") {
|
14436
|
-
throw new Error("Unsupported peer id type");
|
14437
|
-
}
|
14438
|
-
if (!peerId.privateKey) {
|
14439
|
-
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);
|
14440
14006
|
}
|
14441
|
-
|
14442
|
-
return privateKey.marshal();
|
14007
|
+
return peerIdFromPublicKey(pubKey);
|
14443
14008
|
}
|
14444
14009
|
|
14445
14010
|
function decodeMultiaddrs(bytes) {
|
@@ -14686,12 +14251,12 @@ var TransportProtocolPerIpVersion;
|
|
14686
14251
|
class ENR extends RawEnr {
|
14687
14252
|
static RECORD_PREFIX = "enr:";
|
14688
14253
|
peerId;
|
14689
|
-
static
|
14254
|
+
static create(kvs = {}, seq = BigInt(1), signature) {
|
14690
14255
|
const enr = new ENR(kvs, seq, signature);
|
14691
14256
|
try {
|
14692
14257
|
const publicKey = enr.publicKey;
|
14693
14258
|
if (publicKey) {
|
14694
|
-
enr.peerId =
|
14259
|
+
enr.peerId = createPeerIdFromPublicKey(publicKey);
|
14695
14260
|
}
|
14696
14261
|
}
|
14697
14262
|
catch (e) {
|
@@ -14813,7 +14378,7 @@ class EnrCreator {
|
|
14813
14378
|
static fromPublicKey(publicKey, kvs = {}) {
|
14814
14379
|
// EIP-778 specifies that the key must be in compressed format, 33 bytes
|
14815
14380
|
if (publicKey.length !== 33) {
|
14816
|
-
publicKey = compressPublicKey
|
14381
|
+
publicKey = compressPublicKey(publicKey);
|
14817
14382
|
}
|
14818
14383
|
return ENR.create({
|
14819
14384
|
...kvs,
|
@@ -14824,7 +14389,7 @@ class EnrCreator {
|
|
14824
14389
|
static async fromPeerId(peerId, kvs = {}) {
|
14825
14390
|
switch (peerId.type) {
|
14826
14391
|
case "secp256k1":
|
14827
|
-
return EnrCreator.fromPublicKey(
|
14392
|
+
return EnrCreator.fromPublicKey(peerId.publicKey.raw, kvs);
|
14828
14393
|
default:
|
14829
14394
|
throw new Error();
|
14830
14395
|
}
|
@@ -15478,7 +15043,7 @@ async function fromValues(values) {
|
|
15478
15043
|
}
|
15479
15044
|
}
|
15480
15045
|
const _seq = decodeSeq(seq);
|
15481
|
-
const enr =
|
15046
|
+
const enr = ENR.create(obj, _seq, signature);
|
15482
15047
|
checkSignature(seq, kvs, enr, signature);
|
15483
15048
|
return enr;
|
15484
15049
|
}
|
@@ -15511,4 +15076,4 @@ function checkSignature(seq, kvs, enr, signature) {
|
|
15511
15076
|
}
|
15512
15077
|
}
|
15513
15078
|
|
15514
|
-
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 };
|