@abraca/dabra 2.0.2 → 2.0.4
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/dist/abracadabra-provider.cjs +2694 -1014
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +2694 -1014
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +8 -2
- package/package.json +5 -5
- package/src/AbracadabraClient.ts +11 -2
- package/src/CryptoIdentityKeystore.ts +7 -2
- package/src/DocKeyManager.ts +2 -2
- package/src/IdentityDoc.ts +1 -1
- package/src/MnemonicKeyDerivation.ts +7 -3
- package/src/webrtc/DevicePairingChannel.ts +1 -1
- package/src/webrtc/E2EEChannel.ts +2 -2
|
@@ -1206,7 +1206,7 @@ var AbracadabraWS = class extends EventEmitter {
|
|
|
1206
1206
|
this.receivedOnOpenPayload = void 0;
|
|
1207
1207
|
this.closeTries = 0;
|
|
1208
1208
|
this.setConfiguration(configuration);
|
|
1209
|
-
this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill ? configuration.WebSocketPolyfill : WebSocket;
|
|
1209
|
+
this.configuration.WebSocketPolyfill = configuration.WebSocketPolyfill ? configuration.WebSocketPolyfill : globalThis.WebSocket;
|
|
1210
1210
|
this.on("open", this.configuration.onOpen);
|
|
1211
1211
|
this.on("open", this.onOpen.bind(this));
|
|
1212
1212
|
this.on("connect", this.configuration.onConnect);
|
|
@@ -3140,136 +3140,447 @@ var AbracadabraProvider = class AbracadabraProvider extends AbracadabraBaseProvi
|
|
|
3140
3140
|
};
|
|
3141
3141
|
|
|
3142
3142
|
//#endregion
|
|
3143
|
-
//#region node_modules/@noble/hashes/
|
|
3144
|
-
/**
|
|
3143
|
+
//#region node_modules/@noble/hashes/utils.js
|
|
3144
|
+
/**
|
|
3145
|
+
* Checks if something is Uint8Array. Be careful: nodejs Buffer will return true.
|
|
3146
|
+
* @param a - value to test
|
|
3147
|
+
* @returns `true` when the value is a Uint8Array-compatible view.
|
|
3148
|
+
* @example
|
|
3149
|
+
* Check whether a value is a Uint8Array-compatible view.
|
|
3150
|
+
* ```ts
|
|
3151
|
+
* isBytes(new Uint8Array([1, 2, 3]));
|
|
3152
|
+
* ```
|
|
3153
|
+
*/
|
|
3145
3154
|
function isBytes$1(a) {
|
|
3146
|
-
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array";
|
|
3155
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
3147
3156
|
}
|
|
3148
|
-
/**
|
|
3149
|
-
|
|
3150
|
-
|
|
3157
|
+
/**
|
|
3158
|
+
* Asserts something is a non-negative integer.
|
|
3159
|
+
* @param n - number to validate
|
|
3160
|
+
* @param title - label included in thrown errors
|
|
3161
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3162
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3163
|
+
* @example
|
|
3164
|
+
* Validate a non-negative integer option.
|
|
3165
|
+
* ```ts
|
|
3166
|
+
* anumber(32, 'length');
|
|
3167
|
+
* ```
|
|
3168
|
+
*/
|
|
3169
|
+
function anumber$1(n, title = "") {
|
|
3170
|
+
if (typeof n !== "number") {
|
|
3171
|
+
const prefix = title && `"${title}" `;
|
|
3172
|
+
throw new TypeError(`${prefix}expected number, got ${typeof n}`);
|
|
3173
|
+
}
|
|
3174
|
+
if (!Number.isSafeInteger(n) || n < 0) {
|
|
3175
|
+
const prefix = title && `"${title}" `;
|
|
3176
|
+
throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);
|
|
3177
|
+
}
|
|
3151
3178
|
}
|
|
3152
|
-
/**
|
|
3153
|
-
|
|
3154
|
-
|
|
3155
|
-
|
|
3179
|
+
/**
|
|
3180
|
+
* Asserts something is Uint8Array.
|
|
3181
|
+
* @param value - value to validate
|
|
3182
|
+
* @param length - optional exact length constraint
|
|
3183
|
+
* @param title - label included in thrown errors
|
|
3184
|
+
* @returns The validated byte array.
|
|
3185
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3186
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3187
|
+
* @example
|
|
3188
|
+
* Validate that a value is a byte array.
|
|
3189
|
+
* ```ts
|
|
3190
|
+
* abytes(new Uint8Array([1, 2, 3]));
|
|
3191
|
+
* ```
|
|
3192
|
+
*/
|
|
3193
|
+
function abytes$1(value, length, title = "") {
|
|
3194
|
+
const bytes = isBytes$1(value);
|
|
3195
|
+
const len = value?.length;
|
|
3196
|
+
const needsLen = length !== void 0;
|
|
3197
|
+
if (!bytes || needsLen && len !== length) {
|
|
3198
|
+
const prefix = title && `"${title}" `;
|
|
3199
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
3200
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
3201
|
+
const message = prefix + "expected Uint8Array" + ofLen + ", got " + got;
|
|
3202
|
+
if (!bytes) throw new TypeError(message);
|
|
3203
|
+
throw new RangeError(message);
|
|
3204
|
+
}
|
|
3205
|
+
return value;
|
|
3156
3206
|
}
|
|
3157
|
-
/**
|
|
3207
|
+
/**
|
|
3208
|
+
* Asserts something is a wrapped hash constructor.
|
|
3209
|
+
* @param h - hash constructor to validate
|
|
3210
|
+
* @throws On wrong argument types or invalid hash wrapper shape. {@link TypeError}
|
|
3211
|
+
* @throws On invalid hash metadata ranges or values. {@link RangeError}
|
|
3212
|
+
* @throws If the hash metadata allows empty outputs or block sizes. {@link Error}
|
|
3213
|
+
* @example
|
|
3214
|
+
* Validate a callable hash wrapper.
|
|
3215
|
+
* ```ts
|
|
3216
|
+
* import { ahash } from '@noble/hashes/utils.js';
|
|
3217
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3218
|
+
* ahash(sha256);
|
|
3219
|
+
* ```
|
|
3220
|
+
*/
|
|
3158
3221
|
function ahash(h) {
|
|
3159
|
-
if (typeof h !== "function" || typeof h.create !== "function") throw new
|
|
3222
|
+
if (typeof h !== "function" || typeof h.create !== "function") throw new TypeError("Hash must wrapped by utils.createHasher");
|
|
3160
3223
|
anumber$1(h.outputLen);
|
|
3161
3224
|
anumber$1(h.blockLen);
|
|
3225
|
+
if (h.outputLen < 1) throw new Error("\"outputLen\" must be >= 1");
|
|
3226
|
+
if (h.blockLen < 1) throw new Error("\"blockLen\" must be >= 1");
|
|
3162
3227
|
}
|
|
3163
|
-
/**
|
|
3164
|
-
|
|
3228
|
+
/**
|
|
3229
|
+
* Asserts a hash instance has not been destroyed or finished.
|
|
3230
|
+
* @param instance - hash instance to validate
|
|
3231
|
+
* @param checkFinished - whether to reject finalized instances
|
|
3232
|
+
* @throws If the hash instance has already been destroyed or finalized. {@link Error}
|
|
3233
|
+
* @example
|
|
3234
|
+
* Validate that a hash instance is still usable.
|
|
3235
|
+
* ```ts
|
|
3236
|
+
* import { aexists } from '@noble/hashes/utils.js';
|
|
3237
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3238
|
+
* const hash = sha256.create();
|
|
3239
|
+
* aexists(hash);
|
|
3240
|
+
* ```
|
|
3241
|
+
*/
|
|
3242
|
+
function aexists(instance, checkFinished = true) {
|
|
3165
3243
|
if (instance.destroyed) throw new Error("Hash instance has been destroyed");
|
|
3166
3244
|
if (checkFinished && instance.finished) throw new Error("Hash#digest() has already been called");
|
|
3167
3245
|
}
|
|
3168
|
-
/**
|
|
3169
|
-
|
|
3170
|
-
|
|
3246
|
+
/**
|
|
3247
|
+
* Asserts output is a sufficiently-sized byte array.
|
|
3248
|
+
* @param out - destination buffer
|
|
3249
|
+
* @param instance - hash instance providing output length
|
|
3250
|
+
* Oversized buffers are allowed; downstream code only promises to fill the first `outputLen` bytes.
|
|
3251
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3252
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3253
|
+
* @example
|
|
3254
|
+
* Validate a caller-provided digest buffer.
|
|
3255
|
+
* ```ts
|
|
3256
|
+
* import { aoutput } from '@noble/hashes/utils.js';
|
|
3257
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3258
|
+
* const hash = sha256.create();
|
|
3259
|
+
* aoutput(new Uint8Array(hash.outputLen), hash);
|
|
3260
|
+
* ```
|
|
3261
|
+
*/
|
|
3262
|
+
function aoutput(out, instance) {
|
|
3263
|
+
abytes$1(out, void 0, "digestInto() output");
|
|
3171
3264
|
const min = instance.outputLen;
|
|
3172
|
-
if (out.length < min) throw new
|
|
3265
|
+
if (out.length < min) throw new RangeError("\"digestInto() output\" expected to be of length >=" + min);
|
|
3173
3266
|
}
|
|
3174
|
-
/**
|
|
3175
|
-
|
|
3267
|
+
/**
|
|
3268
|
+
* Zeroizes typed arrays in place. Warning: JS provides no guarantees.
|
|
3269
|
+
* @param arrays - arrays to overwrite with zeros
|
|
3270
|
+
* @example
|
|
3271
|
+
* Zeroize sensitive buffers in place.
|
|
3272
|
+
* ```ts
|
|
3273
|
+
* clean(new Uint8Array([1, 2, 3]));
|
|
3274
|
+
* ```
|
|
3275
|
+
*/
|
|
3276
|
+
function clean(...arrays) {
|
|
3176
3277
|
for (let i = 0; i < arrays.length; i++) arrays[i].fill(0);
|
|
3177
3278
|
}
|
|
3178
|
-
/**
|
|
3179
|
-
|
|
3279
|
+
/**
|
|
3280
|
+
* Creates a DataView for byte-level manipulation.
|
|
3281
|
+
* @param arr - source typed array
|
|
3282
|
+
* @returns DataView over the same buffer region.
|
|
3283
|
+
* @example
|
|
3284
|
+
* Create a DataView over an existing buffer.
|
|
3285
|
+
* ```ts
|
|
3286
|
+
* createView(new Uint8Array(4));
|
|
3287
|
+
* ```
|
|
3288
|
+
*/
|
|
3289
|
+
function createView(arr) {
|
|
3180
3290
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
3181
3291
|
}
|
|
3182
|
-
/**
|
|
3292
|
+
/**
|
|
3293
|
+
* Rotate-right operation for uint32 values.
|
|
3294
|
+
* @param word - source word
|
|
3295
|
+
* @param shift - shift amount in bits
|
|
3296
|
+
* @returns Rotated word.
|
|
3297
|
+
* @example
|
|
3298
|
+
* Rotate a 32-bit word to the right.
|
|
3299
|
+
* ```ts
|
|
3300
|
+
* rotr(0x12345678, 8);
|
|
3301
|
+
* ```
|
|
3302
|
+
*/
|
|
3183
3303
|
function rotr(word, shift) {
|
|
3184
3304
|
return word << 32 - shift | word >>> shift;
|
|
3185
3305
|
}
|
|
3186
|
-
/**
|
|
3187
|
-
const isLE
|
|
3188
|
-
const hasHexBuiltin
|
|
3306
|
+
/** Whether the current platform is little-endian. */
|
|
3307
|
+
const isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
|
|
3308
|
+
const hasHexBuiltin = typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function";
|
|
3309
|
+
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
3310
|
+
/**
|
|
3311
|
+
* Convert byte array to hex string.
|
|
3312
|
+
* Uses the built-in function when available and assumes it matches the tested
|
|
3313
|
+
* fallback semantics.
|
|
3314
|
+
* @param bytes - bytes to encode
|
|
3315
|
+
* @returns Lowercase hexadecimal string.
|
|
3316
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3317
|
+
* @example
|
|
3318
|
+
* Convert bytes to lowercase hexadecimal.
|
|
3319
|
+
* ```ts
|
|
3320
|
+
* bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])); // 'cafe0123'
|
|
3321
|
+
* ```
|
|
3322
|
+
*/
|
|
3323
|
+
function bytesToHex$2(bytes) {
|
|
3324
|
+
abytes$1(bytes);
|
|
3325
|
+
if (hasHexBuiltin) return bytes.toHex();
|
|
3326
|
+
let hex = "";
|
|
3327
|
+
for (let i = 0; i < bytes.length; i++) hex += hexes[bytes[i]];
|
|
3328
|
+
return hex;
|
|
3329
|
+
}
|
|
3330
|
+
const asciis = {
|
|
3331
|
+
_0: 48,
|
|
3332
|
+
_9: 57,
|
|
3333
|
+
A: 65,
|
|
3334
|
+
F: 70,
|
|
3335
|
+
a: 97,
|
|
3336
|
+
f: 102
|
|
3337
|
+
};
|
|
3338
|
+
function asciiToBase16(ch) {
|
|
3339
|
+
if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0;
|
|
3340
|
+
if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10);
|
|
3341
|
+
if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10);
|
|
3342
|
+
}
|
|
3343
|
+
/**
|
|
3344
|
+
* Convert hex string to byte array. Uses built-in function, when available.
|
|
3345
|
+
* @param hex - hexadecimal string to decode
|
|
3346
|
+
* @returns Decoded bytes.
|
|
3347
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3348
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3349
|
+
* @example
|
|
3350
|
+
* Decode lowercase hexadecimal into bytes.
|
|
3351
|
+
* ```ts
|
|
3352
|
+
* hexToBytes('cafe0123'); // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
|
3353
|
+
* ```
|
|
3354
|
+
*/
|
|
3355
|
+
function hexToBytes$2(hex) {
|
|
3356
|
+
if (typeof hex !== "string") throw new TypeError("hex string expected, got " + typeof hex);
|
|
3357
|
+
if (hasHexBuiltin) try {
|
|
3358
|
+
return Uint8Array.fromHex(hex);
|
|
3359
|
+
} catch (error) {
|
|
3360
|
+
if (error instanceof SyntaxError) throw new RangeError(error.message);
|
|
3361
|
+
throw error;
|
|
3362
|
+
}
|
|
3363
|
+
const hl = hex.length;
|
|
3364
|
+
const al = hl / 2;
|
|
3365
|
+
if (hl % 2) throw new RangeError("hex string expected, got unpadded hex of length " + hl);
|
|
3366
|
+
const array = new Uint8Array(al);
|
|
3367
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
3368
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
3369
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
3370
|
+
if (n1 === void 0 || n2 === void 0) {
|
|
3371
|
+
const char = hex[hi] + hex[hi + 1];
|
|
3372
|
+
throw new RangeError("hex string expected, got non-hex character \"" + char + "\" at index " + hi);
|
|
3373
|
+
}
|
|
3374
|
+
array[ai] = n1 * 16 + n2;
|
|
3375
|
+
}
|
|
3376
|
+
return array;
|
|
3377
|
+
}
|
|
3189
3378
|
/**
|
|
3190
3379
|
* Converts string to bytes using UTF8 encoding.
|
|
3191
|
-
*
|
|
3380
|
+
* Built-in doesn't validate input to be string: we do the check.
|
|
3381
|
+
* Non-ASCII details are delegated to the platform `TextEncoder`.
|
|
3382
|
+
* @param str - string to encode
|
|
3383
|
+
* @returns UTF-8 encoded bytes.
|
|
3384
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3385
|
+
* @example
|
|
3386
|
+
* Encode a string as UTF-8 bytes.
|
|
3387
|
+
* ```ts
|
|
3388
|
+
* utf8ToBytes('abc'); // Uint8Array.from([97, 98, 99])
|
|
3389
|
+
* ```
|
|
3192
3390
|
*/
|
|
3193
3391
|
function utf8ToBytes(str) {
|
|
3194
|
-
if (typeof str !== "string") throw new
|
|
3392
|
+
if (typeof str !== "string") throw new TypeError("string expected");
|
|
3195
3393
|
return new Uint8Array(new TextEncoder().encode(str));
|
|
3196
3394
|
}
|
|
3197
3395
|
/**
|
|
3198
|
-
*
|
|
3199
|
-
*
|
|
3200
|
-
*
|
|
3396
|
+
* Copies several Uint8Arrays into one.
|
|
3397
|
+
* @param arrays - arrays to concatenate
|
|
3398
|
+
* @returns Concatenated byte array.
|
|
3399
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3400
|
+
* @example
|
|
3401
|
+
* Concatenate multiple byte arrays.
|
|
3402
|
+
* ```ts
|
|
3403
|
+
* concatBytes(new Uint8Array([1]), new Uint8Array([2]));
|
|
3404
|
+
* ```
|
|
3201
3405
|
*/
|
|
3202
|
-
function
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3406
|
+
function concatBytes$1(...arrays) {
|
|
3407
|
+
let sum = 0;
|
|
3408
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
3409
|
+
const a = arrays[i];
|
|
3410
|
+
abytes$1(a);
|
|
3411
|
+
sum += a.length;
|
|
3412
|
+
}
|
|
3413
|
+
const res = new Uint8Array(sum);
|
|
3414
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
3415
|
+
const a = arrays[i];
|
|
3416
|
+
res.set(a, pad);
|
|
3417
|
+
pad += a.length;
|
|
3418
|
+
}
|
|
3419
|
+
return res;
|
|
3206
3420
|
}
|
|
3207
|
-
/**
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3421
|
+
/**
|
|
3422
|
+
* Creates a callable hash function from a stateful class constructor.
|
|
3423
|
+
* @param hashCons - hash constructor or factory
|
|
3424
|
+
* @param info - optional metadata such as DER OID
|
|
3425
|
+
* @returns Frozen callable hash wrapper with `.create()`.
|
|
3426
|
+
* Wrapper construction eagerly calls `hashCons(undefined)` once to read
|
|
3427
|
+
* `outputLen` / `blockLen`, so constructor side effects happen at module
|
|
3428
|
+
* init time.
|
|
3429
|
+
* @example
|
|
3430
|
+
* Wrap a stateful hash constructor into a callable helper.
|
|
3431
|
+
* ```ts
|
|
3432
|
+
* import { createHasher } from '@noble/hashes/utils.js';
|
|
3433
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
3434
|
+
* const wrapped = createHasher(sha256.create, { oid: sha256.oid });
|
|
3435
|
+
* wrapped(new Uint8Array([1]));
|
|
3436
|
+
* ```
|
|
3437
|
+
*/
|
|
3438
|
+
function createHasher$1(hashCons, info = {}) {
|
|
3439
|
+
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
3440
|
+
const tmp = hashCons(void 0);
|
|
3213
3441
|
hashC.outputLen = tmp.outputLen;
|
|
3214
3442
|
hashC.blockLen = tmp.blockLen;
|
|
3215
|
-
hashC.
|
|
3216
|
-
|
|
3443
|
+
hashC.canXOF = tmp.canXOF;
|
|
3444
|
+
hashC.create = (opts) => hashCons(opts);
|
|
3445
|
+
Object.assign(hashC, info);
|
|
3446
|
+
return Object.freeze(hashC);
|
|
3447
|
+
}
|
|
3448
|
+
/**
|
|
3449
|
+
* Cryptographically secure PRNG backed by `crypto.getRandomValues`.
|
|
3450
|
+
* @param bytesLength - number of random bytes to generate
|
|
3451
|
+
* @returns Random bytes.
|
|
3452
|
+
* The platform `getRandomValues()` implementation still defines any
|
|
3453
|
+
* single-call length cap, and this helper rejects oversize requests
|
|
3454
|
+
* with a stable library `RangeError` instead of host-specific errors.
|
|
3455
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
3456
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
3457
|
+
* @throws If the current runtime does not provide `crypto.getRandomValues`. {@link Error}
|
|
3458
|
+
* @example
|
|
3459
|
+
* Generate a fresh random key or nonce.
|
|
3460
|
+
* ```ts
|
|
3461
|
+
* const key = randomBytes(16);
|
|
3462
|
+
* ```
|
|
3463
|
+
*/
|
|
3464
|
+
function randomBytes$1(bytesLength = 32) {
|
|
3465
|
+
anumber$1(bytesLength, "bytesLength");
|
|
3466
|
+
const cr = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
3467
|
+
if (typeof cr?.getRandomValues !== "function") throw new Error("crypto.getRandomValues must be defined");
|
|
3468
|
+
if (bytesLength > 65536) throw new RangeError(`"bytesLength" expected <= 65536, got ${bytesLength}`);
|
|
3469
|
+
return cr.getRandomValues(new Uint8Array(bytesLength));
|
|
3217
3470
|
}
|
|
3471
|
+
/**
|
|
3472
|
+
* Creates OID metadata for NIST hashes with prefix `06 09 60 86 48 01 65 03 04 02`.
|
|
3473
|
+
* @param suffix - final OID byte for the selected hash.
|
|
3474
|
+
* The helper accepts any byte even though only the documented NIST hash
|
|
3475
|
+
* suffixes are meaningful downstream.
|
|
3476
|
+
* @returns Object containing the DER-encoded OID.
|
|
3477
|
+
* @example
|
|
3478
|
+
* Build OID metadata for a NIST hash.
|
|
3479
|
+
* ```ts
|
|
3480
|
+
* oidNist(0x01);
|
|
3481
|
+
* ```
|
|
3482
|
+
*/
|
|
3483
|
+
const oidNist = (suffix) => ({ oid: Uint8Array.from([
|
|
3484
|
+
6,
|
|
3485
|
+
9,
|
|
3486
|
+
96,
|
|
3487
|
+
134,
|
|
3488
|
+
72,
|
|
3489
|
+
1,
|
|
3490
|
+
101,
|
|
3491
|
+
3,
|
|
3492
|
+
4,
|
|
3493
|
+
2,
|
|
3494
|
+
suffix
|
|
3495
|
+
]) });
|
|
3218
3496
|
|
|
3219
3497
|
//#endregion
|
|
3220
|
-
//#region node_modules/@noble/hashes/
|
|
3498
|
+
//#region node_modules/@noble/hashes/_md.js
|
|
3221
3499
|
/**
|
|
3222
3500
|
* Internal Merkle-Damgard hash utils.
|
|
3223
3501
|
* @module
|
|
3224
3502
|
*/
|
|
3225
|
-
/**
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3503
|
+
/**
|
|
3504
|
+
* Shared 32-bit conditional boolean primitive reused by SHA-256, SHA-1, and MD5 `F`.
|
|
3505
|
+
* Returns bits from `b` when `a` is set, otherwise from `c`.
|
|
3506
|
+
* The XOR form is equivalent to MD5's `F(X,Y,Z) = XY v not(X)Z` because the masked terms never
|
|
3507
|
+
* set the same bit.
|
|
3508
|
+
* @param a - selector word
|
|
3509
|
+
* @param b - word chosen when selector bit is set
|
|
3510
|
+
* @param c - word chosen when selector bit is clear
|
|
3511
|
+
* @returns Mixed 32-bit word.
|
|
3512
|
+
* @example
|
|
3513
|
+
* Combine three words with the shared 32-bit choice primitive.
|
|
3514
|
+
* ```ts
|
|
3515
|
+
* Chi(0xffffffff, 0x12345678, 0x87654321);
|
|
3516
|
+
* ```
|
|
3517
|
+
*/
|
|
3238
3518
|
function Chi(a, b, c) {
|
|
3239
3519
|
return a & b ^ ~a & c;
|
|
3240
3520
|
}
|
|
3241
|
-
/**
|
|
3521
|
+
/**
|
|
3522
|
+
* Shared 32-bit majority primitive reused by SHA-256 and SHA-1.
|
|
3523
|
+
* Returns bits shared by at least two inputs.
|
|
3524
|
+
* @param a - first input word
|
|
3525
|
+
* @param b - second input word
|
|
3526
|
+
* @param c - third input word
|
|
3527
|
+
* @returns Mixed 32-bit word.
|
|
3528
|
+
* @example
|
|
3529
|
+
* Combine three words with the shared 32-bit majority primitive.
|
|
3530
|
+
* ```ts
|
|
3531
|
+
* Maj(0xffffffff, 0x12345678, 0x87654321);
|
|
3532
|
+
* ```
|
|
3533
|
+
*/
|
|
3242
3534
|
function Maj(a, b, c) {
|
|
3243
3535
|
return a & b ^ a & c ^ b & c;
|
|
3244
3536
|
}
|
|
3245
3537
|
/**
|
|
3246
3538
|
* Merkle-Damgard hash construction base class.
|
|
3247
3539
|
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
|
3540
|
+
* Accepts only byte-aligned `Uint8Array` input, even when the underlying spec describes bit
|
|
3541
|
+
* strings with partial-byte tails.
|
|
3542
|
+
* @param blockLen - internal block size in bytes
|
|
3543
|
+
* @param outputLen - digest size in bytes
|
|
3544
|
+
* @param padOffset - trailing length field size in bytes
|
|
3545
|
+
* @param isLE - whether length and state words are encoded in little-endian
|
|
3546
|
+
* @example
|
|
3547
|
+
* Use a concrete subclass to get the shared Merkle-Damgard update/digest flow.
|
|
3548
|
+
* ```ts
|
|
3549
|
+
* import { _SHA1 } from '@noble/hashes/legacy.js';
|
|
3550
|
+
* const hash = new _SHA1();
|
|
3551
|
+
* hash.update(new Uint8Array([97, 98, 99]));
|
|
3552
|
+
* hash.digest();
|
|
3553
|
+
* ```
|
|
3248
3554
|
*/
|
|
3249
|
-
var HashMD
|
|
3555
|
+
var HashMD = class {
|
|
3556
|
+
blockLen;
|
|
3557
|
+
outputLen;
|
|
3558
|
+
canXOF = false;
|
|
3559
|
+
padOffset;
|
|
3560
|
+
isLE;
|
|
3561
|
+
buffer;
|
|
3562
|
+
view;
|
|
3563
|
+
finished = false;
|
|
3564
|
+
length = 0;
|
|
3565
|
+
pos = 0;
|
|
3566
|
+
destroyed = false;
|
|
3250
3567
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
3251
|
-
super();
|
|
3252
|
-
this.finished = false;
|
|
3253
|
-
this.length = 0;
|
|
3254
|
-
this.pos = 0;
|
|
3255
|
-
this.destroyed = false;
|
|
3256
3568
|
this.blockLen = blockLen;
|
|
3257
3569
|
this.outputLen = outputLen;
|
|
3258
3570
|
this.padOffset = padOffset;
|
|
3259
3571
|
this.isLE = isLE;
|
|
3260
3572
|
this.buffer = new Uint8Array(blockLen);
|
|
3261
|
-
this.view = createView
|
|
3573
|
+
this.view = createView(this.buffer);
|
|
3262
3574
|
}
|
|
3263
3575
|
update(data) {
|
|
3264
|
-
aexists
|
|
3265
|
-
data = toBytes(data);
|
|
3576
|
+
aexists(this);
|
|
3266
3577
|
abytes$1(data);
|
|
3267
3578
|
const { view, buffer, blockLen } = this;
|
|
3268
3579
|
const len = data.length;
|
|
3269
3580
|
for (let pos = 0; pos < len;) {
|
|
3270
3581
|
const take = Math.min(blockLen - this.pos, len - pos);
|
|
3271
3582
|
if (take === blockLen) {
|
|
3272
|
-
const dataView = createView
|
|
3583
|
+
const dataView = createView(data);
|
|
3273
3584
|
for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);
|
|
3274
3585
|
continue;
|
|
3275
3586
|
}
|
|
@@ -3286,23 +3597,23 @@ var HashMD$1 = class extends Hash {
|
|
|
3286
3597
|
return this;
|
|
3287
3598
|
}
|
|
3288
3599
|
digestInto(out) {
|
|
3289
|
-
aexists
|
|
3290
|
-
aoutput
|
|
3600
|
+
aexists(this);
|
|
3601
|
+
aoutput(out, this);
|
|
3291
3602
|
this.finished = true;
|
|
3292
3603
|
const { buffer, view, blockLen, isLE } = this;
|
|
3293
3604
|
let { pos } = this;
|
|
3294
3605
|
buffer[pos++] = 128;
|
|
3295
|
-
clean
|
|
3606
|
+
clean(this.buffer.subarray(pos));
|
|
3296
3607
|
if (this.padOffset > blockLen - pos) {
|
|
3297
3608
|
this.process(view, 0);
|
|
3298
3609
|
pos = 0;
|
|
3299
3610
|
}
|
|
3300
3611
|
for (let i = pos; i < blockLen; i++) buffer[i] = 0;
|
|
3301
|
-
setBigUint64(
|
|
3612
|
+
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
|
|
3302
3613
|
this.process(view, 0);
|
|
3303
|
-
const oview = createView
|
|
3614
|
+
const oview = createView(out);
|
|
3304
3615
|
const len = this.outputLen;
|
|
3305
|
-
if (len % 4) throw new Error("_sha2: outputLen
|
|
3616
|
+
if (len % 4) throw new Error("_sha2: outputLen must be aligned to 32bit");
|
|
3306
3617
|
const outLen = len / 4;
|
|
3307
3618
|
const state = this.get();
|
|
3308
3619
|
if (outLen > state.length) throw new Error("_sha2: outputLen bigger than state");
|
|
@@ -3316,7 +3627,7 @@ var HashMD$1 = class extends Hash {
|
|
|
3316
3627
|
return res;
|
|
3317
3628
|
}
|
|
3318
3629
|
_cloneInto(to) {
|
|
3319
|
-
to
|
|
3630
|
+
to ||= new this.constructor();
|
|
3320
3631
|
to.set(...this.get());
|
|
3321
3632
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
3322
3633
|
to.destroyed = destroyed;
|
|
@@ -3334,7 +3645,9 @@ var HashMD$1 = class extends Hash {
|
|
|
3334
3645
|
* Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
|
|
3335
3646
|
* Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
|
|
3336
3647
|
*/
|
|
3337
|
-
/** Initial SHA256 state.
|
|
3648
|
+
/** Initial SHA256 state from RFC 6234 §6.1: the first 32 bits of the fractional parts of the
|
|
3649
|
+
* square roots of the first eight prime numbers. Exported as a shared table; callers must treat
|
|
3650
|
+
* it as read-only because constructors copy words from it by index. */
|
|
3338
3651
|
const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
3339
3652
|
1779033703,
|
|
3340
3653
|
3144134277,
|
|
@@ -3345,49 +3658,85 @@ const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
|
3345
3658
|
528734635,
|
|
3346
3659
|
1541459225
|
|
3347
3660
|
]);
|
|
3661
|
+
/** Initial SHA512 state from RFC 6234 §6.3: eight RFC 64-bit `H(0)` words stored as sixteen
|
|
3662
|
+
* big-endian 32-bit halves. Derived from the fractional parts of the square roots of the first
|
|
3663
|
+
* eight prime numbers. Exported as a shared table; callers must treat it as read-only because
|
|
3664
|
+
* constructors copy halves from it by index. */
|
|
3665
|
+
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
3666
|
+
1779033703,
|
|
3667
|
+
4089235720,
|
|
3668
|
+
3144134277,
|
|
3669
|
+
2227873595,
|
|
3670
|
+
1013904242,
|
|
3671
|
+
4271175723,
|
|
3672
|
+
2773480762,
|
|
3673
|
+
1595750129,
|
|
3674
|
+
1359893119,
|
|
3675
|
+
2917565137,
|
|
3676
|
+
2600822924,
|
|
3677
|
+
725511199,
|
|
3678
|
+
528734635,
|
|
3679
|
+
4215389547,
|
|
3680
|
+
1541459225,
|
|
3681
|
+
327033209
|
|
3682
|
+
]);
|
|
3348
3683
|
|
|
3349
3684
|
//#endregion
|
|
3350
|
-
//#region node_modules/@noble/hashes/
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
* @module
|
|
3355
|
-
*/
|
|
3356
|
-
const U32_MASK64$1 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
3357
|
-
const _32n$1 = /* @__PURE__ */ BigInt(32);
|
|
3358
|
-
function fromBig$1(n, le = false) {
|
|
3685
|
+
//#region node_modules/@noble/hashes/_u64.js
|
|
3686
|
+
const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
3687
|
+
const _32n = /* @__PURE__ */ BigInt(32);
|
|
3688
|
+
function fromBig(n, le = false) {
|
|
3359
3689
|
if (le) return {
|
|
3360
|
-
h: Number(n & U32_MASK64
|
|
3361
|
-
l: Number(n >> _32n
|
|
3690
|
+
h: Number(n & U32_MASK64),
|
|
3691
|
+
l: Number(n >> _32n & U32_MASK64)
|
|
3362
3692
|
};
|
|
3363
3693
|
return {
|
|
3364
|
-
h: Number(n >> _32n
|
|
3365
|
-
l: Number(n & U32_MASK64
|
|
3694
|
+
h: Number(n >> _32n & U32_MASK64) | 0,
|
|
3695
|
+
l: Number(n & U32_MASK64) | 0
|
|
3366
3696
|
};
|
|
3367
3697
|
}
|
|
3368
|
-
function split
|
|
3698
|
+
function split(lst, le = false) {
|
|
3369
3699
|
const len = lst.length;
|
|
3370
3700
|
let Ah = new Uint32Array(len);
|
|
3371
3701
|
let Al = new Uint32Array(len);
|
|
3372
3702
|
for (let i = 0; i < len; i++) {
|
|
3373
|
-
const { h, l } = fromBig
|
|
3703
|
+
const { h, l } = fromBig(lst[i], le);
|
|
3374
3704
|
[Ah[i], Al[i]] = [h, l];
|
|
3375
3705
|
}
|
|
3376
3706
|
return [Ah, Al];
|
|
3377
3707
|
}
|
|
3708
|
+
const shrSH = (h, _l, s) => h >>> s;
|
|
3709
|
+
const shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
3710
|
+
const rotrSH = (h, l, s) => h >>> s | l << 32 - s;
|
|
3711
|
+
const rotrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
3712
|
+
const rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
|
|
3713
|
+
const rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
|
|
3714
|
+
function add(Ah, Al, Bh, Bl) {
|
|
3715
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
3716
|
+
return {
|
|
3717
|
+
h: Ah + Bh + (l / 2 ** 32 | 0) | 0,
|
|
3718
|
+
l: l | 0
|
|
3719
|
+
};
|
|
3720
|
+
}
|
|
3721
|
+
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
3722
|
+
const add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
3723
|
+
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
3724
|
+
const add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
3725
|
+
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
3726
|
+
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
3378
3727
|
|
|
3379
3728
|
//#endregion
|
|
3380
|
-
//#region node_modules/@noble/hashes/
|
|
3729
|
+
//#region node_modules/@noble/hashes/sha2.js
|
|
3381
3730
|
/**
|
|
3382
3731
|
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
|
3383
3732
|
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
|
3384
|
-
* Check out
|
|
3385
|
-
*
|
|
3733
|
+
* Check out {@link https://www.rfc-editor.org/rfc/rfc4634 | RFC 4634} and
|
|
3734
|
+
* {@link https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf | FIPS 180-4}.
|
|
3386
3735
|
* @module
|
|
3387
3736
|
*/
|
|
3388
3737
|
/**
|
|
3389
|
-
*
|
|
3390
|
-
*
|
|
3738
|
+
* SHA-224 / SHA-256 round constants from RFC 6234 §5.1: the first 32 bits
|
|
3739
|
+
* of the cube roots of the first 64 primes (2..311).
|
|
3391
3740
|
*/
|
|
3392
3741
|
const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
3393
3742
|
1116352408,
|
|
@@ -3455,19 +3804,12 @@ const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
|
3455
3804
|
3204031479,
|
|
3456
3805
|
3329325298
|
|
3457
3806
|
]);
|
|
3458
|
-
/** Reusable
|
|
3807
|
+
/** Reusable SHA-224 / SHA-256 message schedule buffer `W_t` from RFC 6234 §6.2 step 1. */
|
|
3459
3808
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
3460
|
-
|
|
3461
|
-
|
|
3809
|
+
/** Internal SHA-224 / SHA-256 compression engine from RFC 6234 §6.2. */
|
|
3810
|
+
var SHA2_32B = class extends HashMD {
|
|
3811
|
+
constructor(outputLen) {
|
|
3462
3812
|
super(64, outputLen, 8, false);
|
|
3463
|
-
this.A = SHA256_IV[0] | 0;
|
|
3464
|
-
this.B = SHA256_IV[1] | 0;
|
|
3465
|
-
this.C = SHA256_IV[2] | 0;
|
|
3466
|
-
this.D = SHA256_IV[3] | 0;
|
|
3467
|
-
this.E = SHA256_IV[4] | 0;
|
|
3468
|
-
this.F = SHA256_IV[5] | 0;
|
|
3469
|
-
this.G = SHA256_IV[6] | 0;
|
|
3470
|
-
this.H = SHA256_IV[7] | 0;
|
|
3471
3813
|
}
|
|
3472
3814
|
get() {
|
|
3473
3815
|
const { A, B, C, D, E, F, G, H } = this;
|
|
@@ -3525,15 +3867,30 @@ var SHA256 = class extends HashMD$1 {
|
|
|
3525
3867
|
this.set(A, B, C, D, E, F, G, H);
|
|
3526
3868
|
}
|
|
3527
3869
|
roundClean() {
|
|
3528
|
-
clean
|
|
3870
|
+
clean(SHA256_W);
|
|
3529
3871
|
}
|
|
3530
3872
|
destroy() {
|
|
3873
|
+
this.destroyed = true;
|
|
3531
3874
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
3532
|
-
clean
|
|
3875
|
+
clean(this.buffer);
|
|
3533
3876
|
}
|
|
3534
3877
|
};
|
|
3535
|
-
|
|
3536
|
-
|
|
3878
|
+
/** Internal SHA-256 hash class grounded in RFC 6234 §6.2. */
|
|
3879
|
+
var _SHA256 = class extends SHA2_32B {
|
|
3880
|
+
A = SHA256_IV[0] | 0;
|
|
3881
|
+
B = SHA256_IV[1] | 0;
|
|
3882
|
+
C = SHA256_IV[2] | 0;
|
|
3883
|
+
D = SHA256_IV[3] | 0;
|
|
3884
|
+
E = SHA256_IV[4] | 0;
|
|
3885
|
+
F = SHA256_IV[5] | 0;
|
|
3886
|
+
G = SHA256_IV[6] | 0;
|
|
3887
|
+
H = SHA256_IV[7] | 0;
|
|
3888
|
+
constructor() {
|
|
3889
|
+
super(32);
|
|
3890
|
+
}
|
|
3891
|
+
};
|
|
3892
|
+
const K512 = split([
|
|
3893
|
+
"0x428a2f98d728ae22",
|
|
3537
3894
|
"0x7137449123ef65cd",
|
|
3538
3895
|
"0xb5c0fbcfec4d3b2f",
|
|
3539
3896
|
"0xe9b5dba58189dbbc",
|
|
@@ -3614,31 +3971,170 @@ const K512$1 = split$1([
|
|
|
3614
3971
|
"0x5fcb6fab3ad6faec",
|
|
3615
3972
|
"0x6c44198c4a475817"
|
|
3616
3973
|
].map((n) => BigInt(n)));
|
|
3617
|
-
const SHA512_Kh
|
|
3618
|
-
const SHA512_Kl
|
|
3974
|
+
const SHA512_Kh = K512[0];
|
|
3975
|
+
const SHA512_Kl = K512[1];
|
|
3976
|
+
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
3977
|
+
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
3978
|
+
/** Internal SHA-384 / SHA-512 compression engine from RFC 6234 §6.4. */
|
|
3979
|
+
var SHA2_64B = class extends HashMD {
|
|
3980
|
+
constructor(outputLen) {
|
|
3981
|
+
super(128, outputLen, 16, false);
|
|
3982
|
+
}
|
|
3983
|
+
get() {
|
|
3984
|
+
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
3985
|
+
return [
|
|
3986
|
+
Ah,
|
|
3987
|
+
Al,
|
|
3988
|
+
Bh,
|
|
3989
|
+
Bl,
|
|
3990
|
+
Ch,
|
|
3991
|
+
Cl,
|
|
3992
|
+
Dh,
|
|
3993
|
+
Dl,
|
|
3994
|
+
Eh,
|
|
3995
|
+
El,
|
|
3996
|
+
Fh,
|
|
3997
|
+
Fl,
|
|
3998
|
+
Gh,
|
|
3999
|
+
Gl,
|
|
4000
|
+
Hh,
|
|
4001
|
+
Hl
|
|
4002
|
+
];
|
|
4003
|
+
}
|
|
4004
|
+
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
|
4005
|
+
this.Ah = Ah | 0;
|
|
4006
|
+
this.Al = Al | 0;
|
|
4007
|
+
this.Bh = Bh | 0;
|
|
4008
|
+
this.Bl = Bl | 0;
|
|
4009
|
+
this.Ch = Ch | 0;
|
|
4010
|
+
this.Cl = Cl | 0;
|
|
4011
|
+
this.Dh = Dh | 0;
|
|
4012
|
+
this.Dl = Dl | 0;
|
|
4013
|
+
this.Eh = Eh | 0;
|
|
4014
|
+
this.El = El | 0;
|
|
4015
|
+
this.Fh = Fh | 0;
|
|
4016
|
+
this.Fl = Fl | 0;
|
|
4017
|
+
this.Gh = Gh | 0;
|
|
4018
|
+
this.Gl = Gl | 0;
|
|
4019
|
+
this.Hh = Hh | 0;
|
|
4020
|
+
this.Hl = Hl | 0;
|
|
4021
|
+
}
|
|
4022
|
+
process(view, offset) {
|
|
4023
|
+
for (let i = 0; i < 16; i++, offset += 4) {
|
|
4024
|
+
SHA512_W_H[i] = view.getUint32(offset);
|
|
4025
|
+
SHA512_W_L[i] = view.getUint32(offset += 4);
|
|
4026
|
+
}
|
|
4027
|
+
for (let i = 16; i < 80; i++) {
|
|
4028
|
+
const W15h = SHA512_W_H[i - 15] | 0;
|
|
4029
|
+
const W15l = SHA512_W_L[i - 15] | 0;
|
|
4030
|
+
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
|
4031
|
+
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
|
4032
|
+
const W2h = SHA512_W_H[i - 2] | 0;
|
|
4033
|
+
const W2l = SHA512_W_L[i - 2] | 0;
|
|
4034
|
+
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
4035
|
+
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
4036
|
+
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
4037
|
+
SHA512_W_H[i] = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]) | 0;
|
|
4038
|
+
SHA512_W_L[i] = SUMl | 0;
|
|
4039
|
+
}
|
|
4040
|
+
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
4041
|
+
for (let i = 0; i < 80; i++) {
|
|
4042
|
+
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
|
4043
|
+
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
|
4044
|
+
const CHIh = Eh & Fh ^ ~Eh & Gh;
|
|
4045
|
+
const CHIl = El & Fl ^ ~El & Gl;
|
|
4046
|
+
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
|
4047
|
+
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
|
4048
|
+
const T1l = T1ll | 0;
|
|
4049
|
+
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
|
4050
|
+
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
|
4051
|
+
const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
|
|
4052
|
+
const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
|
|
4053
|
+
Hh = Gh | 0;
|
|
4054
|
+
Hl = Gl | 0;
|
|
4055
|
+
Gh = Fh | 0;
|
|
4056
|
+
Gl = Fl | 0;
|
|
4057
|
+
Fh = Eh | 0;
|
|
4058
|
+
Fl = El | 0;
|
|
4059
|
+
({h: Eh, l: El} = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
|
4060
|
+
Dh = Ch | 0;
|
|
4061
|
+
Dl = Cl | 0;
|
|
4062
|
+
Ch = Bh | 0;
|
|
4063
|
+
Cl = Bl | 0;
|
|
4064
|
+
Bh = Ah | 0;
|
|
4065
|
+
Bl = Al | 0;
|
|
4066
|
+
const All = add3L(T1l, sigma0l, MAJl);
|
|
4067
|
+
Ah = add3H(All, T1h, sigma0h, MAJh);
|
|
4068
|
+
Al = All | 0;
|
|
4069
|
+
}
|
|
4070
|
+
({h: Ah, l: Al} = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
|
4071
|
+
({h: Bh, l: Bl} = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
|
4072
|
+
({h: Ch, l: Cl} = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
|
4073
|
+
({h: Dh, l: Dl} = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
|
4074
|
+
({h: Eh, l: El} = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
|
4075
|
+
({h: Fh, l: Fl} = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
|
4076
|
+
({h: Gh, l: Gl} = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
|
4077
|
+
({h: Hh, l: Hl} = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
|
4078
|
+
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
|
4079
|
+
}
|
|
4080
|
+
roundClean() {
|
|
4081
|
+
clean(SHA512_W_H, SHA512_W_L);
|
|
4082
|
+
}
|
|
4083
|
+
destroy() {
|
|
4084
|
+
this.destroyed = true;
|
|
4085
|
+
clean(this.buffer);
|
|
4086
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
4087
|
+
}
|
|
4088
|
+
};
|
|
4089
|
+
/** Internal SHA-512 hash class grounded in RFC 6234 §6.3 and §6.4. */
|
|
4090
|
+
var _SHA512 = class extends SHA2_64B {
|
|
4091
|
+
Ah = SHA512_IV[0] | 0;
|
|
4092
|
+
Al = SHA512_IV[1] | 0;
|
|
4093
|
+
Bh = SHA512_IV[2] | 0;
|
|
4094
|
+
Bl = SHA512_IV[3] | 0;
|
|
4095
|
+
Ch = SHA512_IV[4] | 0;
|
|
4096
|
+
Cl = SHA512_IV[5] | 0;
|
|
4097
|
+
Dh = SHA512_IV[6] | 0;
|
|
4098
|
+
Dl = SHA512_IV[7] | 0;
|
|
4099
|
+
Eh = SHA512_IV[8] | 0;
|
|
4100
|
+
El = SHA512_IV[9] | 0;
|
|
4101
|
+
Fh = SHA512_IV[10] | 0;
|
|
4102
|
+
Fl = SHA512_IV[11] | 0;
|
|
4103
|
+
Gh = SHA512_IV[12] | 0;
|
|
4104
|
+
Gl = SHA512_IV[13] | 0;
|
|
4105
|
+
Hh = SHA512_IV[14] | 0;
|
|
4106
|
+
Hl = SHA512_IV[15] | 0;
|
|
4107
|
+
constructor() {
|
|
4108
|
+
super(64);
|
|
4109
|
+
}
|
|
4110
|
+
};
|
|
3619
4111
|
/**
|
|
3620
|
-
* SHA2-256 hash function from RFC 4634.
|
|
4112
|
+
* SHA2-256 hash function from RFC 4634. In JS it's the fastest: even faster than Blake3. Some info:
|
|
3621
4113
|
*
|
|
3622
|
-
*
|
|
3623
|
-
*
|
|
3624
|
-
*
|
|
4114
|
+
* - Trying 2^128 hashes would get 50% chance of collision, using birthday attack.
|
|
4115
|
+
* - BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
|
4116
|
+
* - Each sha256 hash is executing 2^18 bit operations.
|
|
4117
|
+
* - Good 2024 ASICs can do 200Th/sec with 3500 watts of power, corresponding to 2^36 hashes/joule.
|
|
4118
|
+
* @param msg - message bytes to hash
|
|
4119
|
+
* @returns Digest bytes.
|
|
4120
|
+
* @example
|
|
4121
|
+
* Hash a message with SHA2-256.
|
|
4122
|
+
* ```ts
|
|
4123
|
+
* sha256(new Uint8Array([97, 98, 99]));
|
|
4124
|
+
* ```
|
|
3625
4125
|
*/
|
|
3626
|
-
const sha256
|
|
3627
|
-
|
|
3628
|
-
//#endregion
|
|
3629
|
-
//#region node_modules/@noble/hashes/esm/sha256.js
|
|
4126
|
+
const sha256 = /* @__PURE__ */ createHasher$1(() => new _SHA256(), /* @__PURE__ */ oidNist(1));
|
|
3630
4127
|
/**
|
|
3631
|
-
* SHA2-
|
|
3632
|
-
*
|
|
3633
|
-
*
|
|
3634
|
-
*
|
|
3635
|
-
*
|
|
3636
|
-
*
|
|
3637
|
-
*
|
|
3638
|
-
*
|
|
4128
|
+
* SHA2-512 hash function from RFC 4634.
|
|
4129
|
+
* @param msg - message bytes to hash
|
|
4130
|
+
* @returns Digest bytes.
|
|
4131
|
+
* @example
|
|
4132
|
+
* Hash a message with SHA2-512.
|
|
4133
|
+
* ```ts
|
|
4134
|
+
* sha512(new Uint8Array([97, 98, 99]));
|
|
4135
|
+
* ```
|
|
3639
4136
|
*/
|
|
3640
|
-
|
|
3641
|
-
const sha256 = sha256$1;
|
|
4137
|
+
const sha512 = /* @__PURE__ */ createHasher$1(() => new _SHA512(), /* @__PURE__ */ oidNist(3));
|
|
3642
4138
|
|
|
3643
4139
|
//#endregion
|
|
3644
4140
|
//#region packages/provider/src/webrtc/SignalingSocket.ts
|
|
@@ -4518,598 +5014,261 @@ function constantTimeEqual(a, b) {
|
|
|
4518
5014
|
}
|
|
4519
5015
|
|
|
4520
5016
|
//#endregion
|
|
4521
|
-
//#region node_modules/@noble/curves/
|
|
5017
|
+
//#region node_modules/@noble/curves/utils.js
|
|
4522
5018
|
/**
|
|
4523
|
-
*
|
|
5019
|
+
* Hex, bytes and number utilities.
|
|
4524
5020
|
* @module
|
|
4525
5021
|
*/
|
|
4526
|
-
/*! noble-
|
|
4527
|
-
/**
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
5022
|
+
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5023
|
+
/**
|
|
5024
|
+
* Validates that a value is a byte array.
|
|
5025
|
+
* @param value - Value to validate.
|
|
5026
|
+
* @param length - Optional exact byte length.
|
|
5027
|
+
* @param title - Optional field name.
|
|
5028
|
+
* @returns Original byte array.
|
|
5029
|
+
* @example
|
|
5030
|
+
* Reject non-byte input before passing data into curve code.
|
|
5031
|
+
*
|
|
5032
|
+
* ```ts
|
|
5033
|
+
* abytes(new Uint8Array(1));
|
|
5034
|
+
* ```
|
|
5035
|
+
*/
|
|
5036
|
+
const abytes = (value, length, title) => abytes$1(value, length, title);
|
|
5037
|
+
/**
|
|
5038
|
+
* Validates that a value is a non-negative safe integer.
|
|
5039
|
+
* @param n - Value to validate.
|
|
5040
|
+
* @param title - Optional field name.
|
|
5041
|
+
* @example
|
|
5042
|
+
* Validate a numeric length before allocating buffers.
|
|
5043
|
+
*
|
|
5044
|
+
* ```ts
|
|
5045
|
+
* anumber(1);
|
|
5046
|
+
* ```
|
|
5047
|
+
*/
|
|
5048
|
+
const anumber = anumber$1;
|
|
5049
|
+
/**
|
|
5050
|
+
* Encodes bytes as lowercase hex.
|
|
5051
|
+
* @param bytes - Bytes to encode.
|
|
5052
|
+
* @returns Lowercase hex string.
|
|
5053
|
+
* @example
|
|
5054
|
+
* Serialize bytes as hex for logging or fixtures.
|
|
5055
|
+
*
|
|
5056
|
+
* ```ts
|
|
5057
|
+
* bytesToHex(Uint8Array.of(1, 2, 3));
|
|
5058
|
+
* ```
|
|
5059
|
+
*/
|
|
5060
|
+
const bytesToHex = bytesToHex$2;
|
|
5061
|
+
/**
|
|
5062
|
+
* Concatenates byte arrays.
|
|
5063
|
+
* @param arrays - Byte arrays to join.
|
|
5064
|
+
* @returns Concatenated bytes.
|
|
5065
|
+
* @example
|
|
5066
|
+
* Join domain-separated chunks into one buffer.
|
|
5067
|
+
*
|
|
5068
|
+
* ```ts
|
|
5069
|
+
* concatBytes(Uint8Array.of(1), Uint8Array.of(2));
|
|
5070
|
+
* ```
|
|
5071
|
+
*/
|
|
5072
|
+
const concatBytes = (...arrays) => concatBytes$1(...arrays);
|
|
5073
|
+
/**
|
|
5074
|
+
* Decodes lowercase or uppercase hex into bytes.
|
|
5075
|
+
* @param hex - Hex string to decode.
|
|
5076
|
+
* @returns Decoded bytes.
|
|
5077
|
+
* @example
|
|
5078
|
+
* Parse fixture hex into bytes before hashing.
|
|
5079
|
+
*
|
|
5080
|
+
* ```ts
|
|
5081
|
+
* hexToBytes('0102');
|
|
5082
|
+
* ```
|
|
5083
|
+
*/
|
|
5084
|
+
const hexToBytes = (hex) => hexToBytes$2(hex);
|
|
5085
|
+
/**
|
|
5086
|
+
* Checks whether a value is a Uint8Array.
|
|
5087
|
+
* @param a - Value to inspect.
|
|
5088
|
+
* @returns `true` when `a` is a Uint8Array.
|
|
5089
|
+
* @example
|
|
5090
|
+
* Branch on byte input before decoding it.
|
|
5091
|
+
*
|
|
5092
|
+
* ```ts
|
|
5093
|
+
* isBytes(new Uint8Array(1));
|
|
5094
|
+
* ```
|
|
5095
|
+
*/
|
|
5096
|
+
const isBytes = isBytes$1;
|
|
5097
|
+
/**
|
|
5098
|
+
* Reads random bytes from the platform CSPRNG.
|
|
5099
|
+
* @param bytesLength - Number of random bytes to read.
|
|
5100
|
+
* @returns Fresh random bytes.
|
|
5101
|
+
* @example
|
|
5102
|
+
* Generate a random seed for a keypair.
|
|
5103
|
+
*
|
|
5104
|
+
* ```ts
|
|
5105
|
+
* randomBytes(2);
|
|
5106
|
+
* ```
|
|
5107
|
+
*/
|
|
5108
|
+
const randomBytes = (bytesLength) => randomBytes$1(bytesLength);
|
|
5109
|
+
const _0n$5 = /* @__PURE__ */ BigInt(0);
|
|
5110
|
+
const _1n$5 = /* @__PURE__ */ BigInt(1);
|
|
5111
|
+
/**
|
|
5112
|
+
* Validates that a flag is boolean.
|
|
5113
|
+
* @param value - Value to validate.
|
|
5114
|
+
* @param title - Optional field name.
|
|
5115
|
+
* @returns Original value.
|
|
5116
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
5117
|
+
* @example
|
|
5118
|
+
* Reject non-boolean option flags early.
|
|
5119
|
+
*
|
|
5120
|
+
* ```ts
|
|
5121
|
+
* abool(true);
|
|
5122
|
+
* ```
|
|
5123
|
+
*/
|
|
5124
|
+
function abool(value, title = "") {
|
|
5125
|
+
if (typeof value !== "boolean") {
|
|
4544
5126
|
const prefix = title && `"${title}" `;
|
|
4545
|
-
|
|
4546
|
-
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
4547
|
-
throw new Error(prefix + "expected Uint8Array" + ofLen + ", got " + got);
|
|
5127
|
+
throw new TypeError(prefix + "expected boolean, got type=" + typeof value);
|
|
4548
5128
|
}
|
|
4549
5129
|
return value;
|
|
4550
5130
|
}
|
|
4551
|
-
/** Asserts a hash instance has not been destroyed / finished */
|
|
4552
|
-
function aexists(instance, checkFinished = true) {
|
|
4553
|
-
if (instance.destroyed) throw new Error("Hash instance has been destroyed");
|
|
4554
|
-
if (checkFinished && instance.finished) throw new Error("Hash#digest() has already been called");
|
|
4555
|
-
}
|
|
4556
|
-
/** Asserts output is properly-sized byte array */
|
|
4557
|
-
function aoutput(out, instance) {
|
|
4558
|
-
abytes(out, void 0, "digestInto() output");
|
|
4559
|
-
const min = instance.outputLen;
|
|
4560
|
-
if (out.length < min) throw new Error("\"digestInto() output\" expected to be of length >=" + min);
|
|
4561
|
-
}
|
|
4562
|
-
/** Zeroize a byte array. Warning: JS provides no guarantees. */
|
|
4563
|
-
function clean(...arrays) {
|
|
4564
|
-
for (let i = 0; i < arrays.length; i++) arrays[i].fill(0);
|
|
4565
|
-
}
|
|
4566
|
-
/** Create DataView of an array for easy byte-level manipulation. */
|
|
4567
|
-
function createView(arr) {
|
|
4568
|
-
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
4569
|
-
}
|
|
4570
|
-
/** Is current platform little-endian? Most are. Big-Endian platform: IBM */
|
|
4571
|
-
const isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
|
|
4572
|
-
const hasHexBuiltin = typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function";
|
|
4573
|
-
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
4574
5131
|
/**
|
|
4575
|
-
*
|
|
4576
|
-
* @
|
|
5132
|
+
* Validates that a value is a non-negative bigint or safe integer.
|
|
5133
|
+
* @param n - Value to validate.
|
|
5134
|
+
* @returns The same validated value.
|
|
5135
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
5136
|
+
* @example
|
|
5137
|
+
* Validate one integer-like value before serializing it.
|
|
5138
|
+
*
|
|
5139
|
+
* ```ts
|
|
5140
|
+
* abignumber(1n);
|
|
5141
|
+
* ```
|
|
4577
5142
|
*/
|
|
4578
|
-
function
|
|
4579
|
-
|
|
4580
|
-
|
|
4581
|
-
|
|
4582
|
-
|
|
4583
|
-
return hex;
|
|
5143
|
+
function abignumber(n) {
|
|
5144
|
+
if (typeof n === "bigint") {
|
|
5145
|
+
if (!isPosBig(n)) throw new RangeError("positive bigint expected, got " + n);
|
|
5146
|
+
} else anumber(n);
|
|
5147
|
+
return n;
|
|
4584
5148
|
}
|
|
4585
|
-
const asciis = {
|
|
4586
|
-
_0: 48,
|
|
4587
|
-
_9: 57,
|
|
4588
|
-
A: 65,
|
|
4589
|
-
F: 70,
|
|
4590
|
-
a: 97,
|
|
4591
|
-
f: 102
|
|
4592
|
-
};
|
|
4593
|
-
function asciiToBase16(ch) {
|
|
4594
|
-
if (ch >= asciis._0 && ch <= asciis._9) return ch - asciis._0;
|
|
4595
|
-
if (ch >= asciis.A && ch <= asciis.F) return ch - (asciis.A - 10);
|
|
4596
|
-
if (ch >= asciis.a && ch <= asciis.f) return ch - (asciis.a - 10);
|
|
4597
|
-
}
|
|
4598
|
-
/**
|
|
4599
|
-
* Convert hex string to byte array. Uses built-in function, when available.
|
|
4600
|
-
* @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
|
|
4601
|
-
*/
|
|
4602
|
-
function hexToBytes(hex) {
|
|
4603
|
-
if (typeof hex !== "string") throw new Error("hex string expected, got " + typeof hex);
|
|
4604
|
-
if (hasHexBuiltin) return Uint8Array.fromHex(hex);
|
|
4605
|
-
const hl = hex.length;
|
|
4606
|
-
const al = hl / 2;
|
|
4607
|
-
if (hl % 2) throw new Error("hex string expected, got unpadded hex of length " + hl);
|
|
4608
|
-
const array = new Uint8Array(al);
|
|
4609
|
-
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
4610
|
-
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
4611
|
-
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
4612
|
-
if (n1 === void 0 || n2 === void 0) {
|
|
4613
|
-
const char = hex[hi] + hex[hi + 1];
|
|
4614
|
-
throw new Error("hex string expected, got non-hex character \"" + char + "\" at index " + hi);
|
|
4615
|
-
}
|
|
4616
|
-
array[ai] = n1 * 16 + n2;
|
|
4617
|
-
}
|
|
4618
|
-
return array;
|
|
4619
|
-
}
|
|
4620
|
-
/** Copies several Uint8Arrays into one. */
|
|
4621
|
-
function concatBytes(...arrays) {
|
|
4622
|
-
let sum = 0;
|
|
4623
|
-
for (let i = 0; i < arrays.length; i++) {
|
|
4624
|
-
const a = arrays[i];
|
|
4625
|
-
abytes(a);
|
|
4626
|
-
sum += a.length;
|
|
4627
|
-
}
|
|
4628
|
-
const res = new Uint8Array(sum);
|
|
4629
|
-
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
4630
|
-
const a = arrays[i];
|
|
4631
|
-
res.set(a, pad);
|
|
4632
|
-
pad += a.length;
|
|
4633
|
-
}
|
|
4634
|
-
return res;
|
|
4635
|
-
}
|
|
4636
|
-
/** Creates function with outputLen, blockLen, create properties from a class constructor. */
|
|
4637
|
-
function createHasher$1(hashCons, info = {}) {
|
|
4638
|
-
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
4639
|
-
const tmp = hashCons(void 0);
|
|
4640
|
-
hashC.outputLen = tmp.outputLen;
|
|
4641
|
-
hashC.blockLen = tmp.blockLen;
|
|
4642
|
-
hashC.create = (opts) => hashCons(opts);
|
|
4643
|
-
Object.assign(hashC, info);
|
|
4644
|
-
return Object.freeze(hashC);
|
|
4645
|
-
}
|
|
4646
|
-
/** Cryptographically secure PRNG. Uses internal OS-level `crypto.getRandomValues`. */
|
|
4647
|
-
function randomBytes(bytesLength = 32) {
|
|
4648
|
-
const cr = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
4649
|
-
if (typeof cr?.getRandomValues !== "function") throw new Error("crypto.getRandomValues must be defined");
|
|
4650
|
-
return cr.getRandomValues(new Uint8Array(bytesLength));
|
|
4651
|
-
}
|
|
4652
|
-
/** Creates OID opts for NIST hashes, with prefix 06 09 60 86 48 01 65 03 04 02. */
|
|
4653
|
-
const oidNist = (suffix) => ({ oid: Uint8Array.from([
|
|
4654
|
-
6,
|
|
4655
|
-
9,
|
|
4656
|
-
96,
|
|
4657
|
-
134,
|
|
4658
|
-
72,
|
|
4659
|
-
1,
|
|
4660
|
-
101,
|
|
4661
|
-
3,
|
|
4662
|
-
4,
|
|
4663
|
-
2,
|
|
4664
|
-
suffix
|
|
4665
|
-
]) });
|
|
4666
|
-
|
|
4667
|
-
//#endregion
|
|
4668
|
-
//#region node_modules/@noble/curves/node_modules/@noble/hashes/_md.js
|
|
4669
|
-
/**
|
|
4670
|
-
* Internal Merkle-Damgard hash utils.
|
|
4671
|
-
* @module
|
|
4672
|
-
*/
|
|
4673
|
-
/**
|
|
4674
|
-
* Merkle-Damgard hash construction base class.
|
|
4675
|
-
* Could be used to create MD5, RIPEMD, SHA1, SHA2.
|
|
4676
|
-
*/
|
|
4677
|
-
var HashMD = class {
|
|
4678
|
-
blockLen;
|
|
4679
|
-
outputLen;
|
|
4680
|
-
padOffset;
|
|
4681
|
-
isLE;
|
|
4682
|
-
buffer;
|
|
4683
|
-
view;
|
|
4684
|
-
finished = false;
|
|
4685
|
-
length = 0;
|
|
4686
|
-
pos = 0;
|
|
4687
|
-
destroyed = false;
|
|
4688
|
-
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
4689
|
-
this.blockLen = blockLen;
|
|
4690
|
-
this.outputLen = outputLen;
|
|
4691
|
-
this.padOffset = padOffset;
|
|
4692
|
-
this.isLE = isLE;
|
|
4693
|
-
this.buffer = new Uint8Array(blockLen);
|
|
4694
|
-
this.view = createView(this.buffer);
|
|
4695
|
-
}
|
|
4696
|
-
update(data) {
|
|
4697
|
-
aexists(this);
|
|
4698
|
-
abytes(data);
|
|
4699
|
-
const { view, buffer, blockLen } = this;
|
|
4700
|
-
const len = data.length;
|
|
4701
|
-
for (let pos = 0; pos < len;) {
|
|
4702
|
-
const take = Math.min(blockLen - this.pos, len - pos);
|
|
4703
|
-
if (take === blockLen) {
|
|
4704
|
-
const dataView = createView(data);
|
|
4705
|
-
for (; blockLen <= len - pos; pos += blockLen) this.process(dataView, pos);
|
|
4706
|
-
continue;
|
|
4707
|
-
}
|
|
4708
|
-
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
4709
|
-
this.pos += take;
|
|
4710
|
-
pos += take;
|
|
4711
|
-
if (this.pos === blockLen) {
|
|
4712
|
-
this.process(view, 0);
|
|
4713
|
-
this.pos = 0;
|
|
4714
|
-
}
|
|
4715
|
-
}
|
|
4716
|
-
this.length += data.length;
|
|
4717
|
-
this.roundClean();
|
|
4718
|
-
return this;
|
|
4719
|
-
}
|
|
4720
|
-
digestInto(out) {
|
|
4721
|
-
aexists(this);
|
|
4722
|
-
aoutput(out, this);
|
|
4723
|
-
this.finished = true;
|
|
4724
|
-
const { buffer, view, blockLen, isLE } = this;
|
|
4725
|
-
let { pos } = this;
|
|
4726
|
-
buffer[pos++] = 128;
|
|
4727
|
-
clean(this.buffer.subarray(pos));
|
|
4728
|
-
if (this.padOffset > blockLen - pos) {
|
|
4729
|
-
this.process(view, 0);
|
|
4730
|
-
pos = 0;
|
|
4731
|
-
}
|
|
4732
|
-
for (let i = pos; i < blockLen; i++) buffer[i] = 0;
|
|
4733
|
-
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
|
|
4734
|
-
this.process(view, 0);
|
|
4735
|
-
const oview = createView(out);
|
|
4736
|
-
const len = this.outputLen;
|
|
4737
|
-
if (len % 4) throw new Error("_sha2: outputLen must be aligned to 32bit");
|
|
4738
|
-
const outLen = len / 4;
|
|
4739
|
-
const state = this.get();
|
|
4740
|
-
if (outLen > state.length) throw new Error("_sha2: outputLen bigger than state");
|
|
4741
|
-
for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE);
|
|
4742
|
-
}
|
|
4743
|
-
digest() {
|
|
4744
|
-
const { buffer, outputLen } = this;
|
|
4745
|
-
this.digestInto(buffer);
|
|
4746
|
-
const res = buffer.slice(0, outputLen);
|
|
4747
|
-
this.destroy();
|
|
4748
|
-
return res;
|
|
4749
|
-
}
|
|
4750
|
-
_cloneInto(to) {
|
|
4751
|
-
to ||= new this.constructor();
|
|
4752
|
-
to.set(...this.get());
|
|
4753
|
-
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
4754
|
-
to.destroyed = destroyed;
|
|
4755
|
-
to.finished = finished;
|
|
4756
|
-
to.length = length;
|
|
4757
|
-
to.pos = pos;
|
|
4758
|
-
if (length % blockLen) to.buffer.set(buffer);
|
|
4759
|
-
return to;
|
|
4760
|
-
}
|
|
4761
|
-
clone() {
|
|
4762
|
-
return this._cloneInto();
|
|
4763
|
-
}
|
|
4764
|
-
};
|
|
4765
|
-
/** Initial SHA512 state. Bits 0..64 of frac part of sqrt of primes 2..19 */
|
|
4766
|
-
const SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
4767
|
-
1779033703,
|
|
4768
|
-
4089235720,
|
|
4769
|
-
3144134277,
|
|
4770
|
-
2227873595,
|
|
4771
|
-
1013904242,
|
|
4772
|
-
4271175723,
|
|
4773
|
-
2773480762,
|
|
4774
|
-
1595750129,
|
|
4775
|
-
1359893119,
|
|
4776
|
-
2917565137,
|
|
4777
|
-
2600822924,
|
|
4778
|
-
725511199,
|
|
4779
|
-
528734635,
|
|
4780
|
-
4215389547,
|
|
4781
|
-
1541459225,
|
|
4782
|
-
327033209
|
|
4783
|
-
]);
|
|
4784
|
-
|
|
4785
|
-
//#endregion
|
|
4786
|
-
//#region node_modules/@noble/curves/node_modules/@noble/hashes/_u64.js
|
|
4787
5149
|
/**
|
|
4788
|
-
*
|
|
4789
|
-
* @
|
|
4790
|
-
* @
|
|
4791
|
-
|
|
4792
|
-
|
|
4793
|
-
|
|
4794
|
-
|
|
4795
|
-
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4799
|
-
return {
|
|
4800
|
-
h: Number(n >> _32n & U32_MASK64) | 0,
|
|
4801
|
-
l: Number(n & U32_MASK64) | 0
|
|
4802
|
-
};
|
|
4803
|
-
}
|
|
4804
|
-
function split(lst, le = false) {
|
|
4805
|
-
const len = lst.length;
|
|
4806
|
-
let Ah = new Uint32Array(len);
|
|
4807
|
-
let Al = new Uint32Array(len);
|
|
4808
|
-
for (let i = 0; i < len; i++) {
|
|
4809
|
-
const { h, l } = fromBig(lst[i], le);
|
|
4810
|
-
[Ah[i], Al[i]] = [h, l];
|
|
4811
|
-
}
|
|
4812
|
-
return [Ah, Al];
|
|
4813
|
-
}
|
|
4814
|
-
const shrSH = (h, _l, s) => h >>> s;
|
|
4815
|
-
const shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
4816
|
-
const rotrSH = (h, l, s) => h >>> s | l << 32 - s;
|
|
4817
|
-
const rotrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
4818
|
-
const rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
|
|
4819
|
-
const rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
|
|
4820
|
-
function add(Ah, Al, Bh, Bl) {
|
|
4821
|
-
const l = (Al >>> 0) + (Bl >>> 0);
|
|
4822
|
-
return {
|
|
4823
|
-
h: Ah + Bh + (l / 2 ** 32 | 0) | 0,
|
|
4824
|
-
l: l | 0
|
|
4825
|
-
};
|
|
4826
|
-
}
|
|
4827
|
-
const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
4828
|
-
const add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
4829
|
-
const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
4830
|
-
const add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
4831
|
-
const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
4832
|
-
const add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
4833
|
-
|
|
4834
|
-
//#endregion
|
|
4835
|
-
//#region node_modules/@noble/curves/node_modules/@noble/hashes/sha2.js
|
|
4836
|
-
/**
|
|
4837
|
-
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
|
4838
|
-
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
|
4839
|
-
* Check out [RFC 4634](https://www.rfc-editor.org/rfc/rfc4634) and
|
|
4840
|
-
* [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
|
4841
|
-
* @module
|
|
4842
|
-
*/
|
|
4843
|
-
const K512 = split([
|
|
4844
|
-
"0x428a2f98d728ae22",
|
|
4845
|
-
"0x7137449123ef65cd",
|
|
4846
|
-
"0xb5c0fbcfec4d3b2f",
|
|
4847
|
-
"0xe9b5dba58189dbbc",
|
|
4848
|
-
"0x3956c25bf348b538",
|
|
4849
|
-
"0x59f111f1b605d019",
|
|
4850
|
-
"0x923f82a4af194f9b",
|
|
4851
|
-
"0xab1c5ed5da6d8118",
|
|
4852
|
-
"0xd807aa98a3030242",
|
|
4853
|
-
"0x12835b0145706fbe",
|
|
4854
|
-
"0x243185be4ee4b28c",
|
|
4855
|
-
"0x550c7dc3d5ffb4e2",
|
|
4856
|
-
"0x72be5d74f27b896f",
|
|
4857
|
-
"0x80deb1fe3b1696b1",
|
|
4858
|
-
"0x9bdc06a725c71235",
|
|
4859
|
-
"0xc19bf174cf692694",
|
|
4860
|
-
"0xe49b69c19ef14ad2",
|
|
4861
|
-
"0xefbe4786384f25e3",
|
|
4862
|
-
"0x0fc19dc68b8cd5b5",
|
|
4863
|
-
"0x240ca1cc77ac9c65",
|
|
4864
|
-
"0x2de92c6f592b0275",
|
|
4865
|
-
"0x4a7484aa6ea6e483",
|
|
4866
|
-
"0x5cb0a9dcbd41fbd4",
|
|
4867
|
-
"0x76f988da831153b5",
|
|
4868
|
-
"0x983e5152ee66dfab",
|
|
4869
|
-
"0xa831c66d2db43210",
|
|
4870
|
-
"0xb00327c898fb213f",
|
|
4871
|
-
"0xbf597fc7beef0ee4",
|
|
4872
|
-
"0xc6e00bf33da88fc2",
|
|
4873
|
-
"0xd5a79147930aa725",
|
|
4874
|
-
"0x06ca6351e003826f",
|
|
4875
|
-
"0x142929670a0e6e70",
|
|
4876
|
-
"0x27b70a8546d22ffc",
|
|
4877
|
-
"0x2e1b21385c26c926",
|
|
4878
|
-
"0x4d2c6dfc5ac42aed",
|
|
4879
|
-
"0x53380d139d95b3df",
|
|
4880
|
-
"0x650a73548baf63de",
|
|
4881
|
-
"0x766a0abb3c77b2a8",
|
|
4882
|
-
"0x81c2c92e47edaee6",
|
|
4883
|
-
"0x92722c851482353b",
|
|
4884
|
-
"0xa2bfe8a14cf10364",
|
|
4885
|
-
"0xa81a664bbc423001",
|
|
4886
|
-
"0xc24b8b70d0f89791",
|
|
4887
|
-
"0xc76c51a30654be30",
|
|
4888
|
-
"0xd192e819d6ef5218",
|
|
4889
|
-
"0xd69906245565a910",
|
|
4890
|
-
"0xf40e35855771202a",
|
|
4891
|
-
"0x106aa07032bbd1b8",
|
|
4892
|
-
"0x19a4c116b8d2d0c8",
|
|
4893
|
-
"0x1e376c085141ab53",
|
|
4894
|
-
"0x2748774cdf8eeb99",
|
|
4895
|
-
"0x34b0bcb5e19b48a8",
|
|
4896
|
-
"0x391c0cb3c5c95a63",
|
|
4897
|
-
"0x4ed8aa4ae3418acb",
|
|
4898
|
-
"0x5b9cca4f7763e373",
|
|
4899
|
-
"0x682e6ff3d6b2b8a3",
|
|
4900
|
-
"0x748f82ee5defb2fc",
|
|
4901
|
-
"0x78a5636f43172f60",
|
|
4902
|
-
"0x84c87814a1f0ab72",
|
|
4903
|
-
"0x8cc702081a6439ec",
|
|
4904
|
-
"0x90befffa23631e28",
|
|
4905
|
-
"0xa4506cebde82bde9",
|
|
4906
|
-
"0xbef9a3f7b2c67915",
|
|
4907
|
-
"0xc67178f2e372532b",
|
|
4908
|
-
"0xca273eceea26619c",
|
|
4909
|
-
"0xd186b8c721c0c207",
|
|
4910
|
-
"0xeada7dd6cde0eb1e",
|
|
4911
|
-
"0xf57d4f7fee6ed178",
|
|
4912
|
-
"0x06f067aa72176fba",
|
|
4913
|
-
"0x0a637dc5a2c898a6",
|
|
4914
|
-
"0x113f9804bef90dae",
|
|
4915
|
-
"0x1b710b35131c471b",
|
|
4916
|
-
"0x28db77f523047d84",
|
|
4917
|
-
"0x32caab7b40c72493",
|
|
4918
|
-
"0x3c9ebe0a15c9bebc",
|
|
4919
|
-
"0x431d67c49c100d4c",
|
|
4920
|
-
"0x4cc5d4becb3e42b6",
|
|
4921
|
-
"0x597f299cfc657e2a",
|
|
4922
|
-
"0x5fcb6fab3ad6faec",
|
|
4923
|
-
"0x6c44198c4a475817"
|
|
4924
|
-
].map((n) => BigInt(n)));
|
|
4925
|
-
const SHA512_Kh = K512[0];
|
|
4926
|
-
const SHA512_Kl = K512[1];
|
|
4927
|
-
const SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
4928
|
-
const SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
4929
|
-
/** Internal 64-byte base SHA2 hash class. */
|
|
4930
|
-
var SHA2_64B = class extends HashMD {
|
|
4931
|
-
constructor(outputLen) {
|
|
4932
|
-
super(128, outputLen, 16, false);
|
|
4933
|
-
}
|
|
4934
|
-
get() {
|
|
4935
|
-
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
4936
|
-
return [
|
|
4937
|
-
Ah,
|
|
4938
|
-
Al,
|
|
4939
|
-
Bh,
|
|
4940
|
-
Bl,
|
|
4941
|
-
Ch,
|
|
4942
|
-
Cl,
|
|
4943
|
-
Dh,
|
|
4944
|
-
Dl,
|
|
4945
|
-
Eh,
|
|
4946
|
-
El,
|
|
4947
|
-
Fh,
|
|
4948
|
-
Fl,
|
|
4949
|
-
Gh,
|
|
4950
|
-
Gl,
|
|
4951
|
-
Hh,
|
|
4952
|
-
Hl
|
|
4953
|
-
];
|
|
4954
|
-
}
|
|
4955
|
-
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
|
|
4956
|
-
this.Ah = Ah | 0;
|
|
4957
|
-
this.Al = Al | 0;
|
|
4958
|
-
this.Bh = Bh | 0;
|
|
4959
|
-
this.Bl = Bl | 0;
|
|
4960
|
-
this.Ch = Ch | 0;
|
|
4961
|
-
this.Cl = Cl | 0;
|
|
4962
|
-
this.Dh = Dh | 0;
|
|
4963
|
-
this.Dl = Dl | 0;
|
|
4964
|
-
this.Eh = Eh | 0;
|
|
4965
|
-
this.El = El | 0;
|
|
4966
|
-
this.Fh = Fh | 0;
|
|
4967
|
-
this.Fl = Fl | 0;
|
|
4968
|
-
this.Gh = Gh | 0;
|
|
4969
|
-
this.Gl = Gl | 0;
|
|
4970
|
-
this.Hh = Hh | 0;
|
|
4971
|
-
this.Hl = Hl | 0;
|
|
4972
|
-
}
|
|
4973
|
-
process(view, offset) {
|
|
4974
|
-
for (let i = 0; i < 16; i++, offset += 4) {
|
|
4975
|
-
SHA512_W_H[i] = view.getUint32(offset);
|
|
4976
|
-
SHA512_W_L[i] = view.getUint32(offset += 4);
|
|
4977
|
-
}
|
|
4978
|
-
for (let i = 16; i < 80; i++) {
|
|
4979
|
-
const W15h = SHA512_W_H[i - 15] | 0;
|
|
4980
|
-
const W15l = SHA512_W_L[i - 15] | 0;
|
|
4981
|
-
const s0h = rotrSH(W15h, W15l, 1) ^ rotrSH(W15h, W15l, 8) ^ shrSH(W15h, W15l, 7);
|
|
4982
|
-
const s0l = rotrSL(W15h, W15l, 1) ^ rotrSL(W15h, W15l, 8) ^ shrSL(W15h, W15l, 7);
|
|
4983
|
-
const W2h = SHA512_W_H[i - 2] | 0;
|
|
4984
|
-
const W2l = SHA512_W_L[i - 2] | 0;
|
|
4985
|
-
const s1h = rotrSH(W2h, W2l, 19) ^ rotrBH(W2h, W2l, 61) ^ shrSH(W2h, W2l, 6);
|
|
4986
|
-
const s1l = rotrSL(W2h, W2l, 19) ^ rotrBL(W2h, W2l, 61) ^ shrSL(W2h, W2l, 6);
|
|
4987
|
-
const SUMl = add4L(s0l, s1l, SHA512_W_L[i - 7], SHA512_W_L[i - 16]);
|
|
4988
|
-
SHA512_W_H[i] = add4H(SUMl, s0h, s1h, SHA512_W_H[i - 7], SHA512_W_H[i - 16]) | 0;
|
|
4989
|
-
SHA512_W_L[i] = SUMl | 0;
|
|
4990
|
-
}
|
|
4991
|
-
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
|
|
4992
|
-
for (let i = 0; i < 80; i++) {
|
|
4993
|
-
const sigma1h = rotrSH(Eh, El, 14) ^ rotrSH(Eh, El, 18) ^ rotrBH(Eh, El, 41);
|
|
4994
|
-
const sigma1l = rotrSL(Eh, El, 14) ^ rotrSL(Eh, El, 18) ^ rotrBL(Eh, El, 41);
|
|
4995
|
-
const CHIh = Eh & Fh ^ ~Eh & Gh;
|
|
4996
|
-
const CHIl = El & Fl ^ ~El & Gl;
|
|
4997
|
-
const T1ll = add5L(Hl, sigma1l, CHIl, SHA512_Kl[i], SHA512_W_L[i]);
|
|
4998
|
-
const T1h = add5H(T1ll, Hh, sigma1h, CHIh, SHA512_Kh[i], SHA512_W_H[i]);
|
|
4999
|
-
const T1l = T1ll | 0;
|
|
5000
|
-
const sigma0h = rotrSH(Ah, Al, 28) ^ rotrBH(Ah, Al, 34) ^ rotrBH(Ah, Al, 39);
|
|
5001
|
-
const sigma0l = rotrSL(Ah, Al, 28) ^ rotrBL(Ah, Al, 34) ^ rotrBL(Ah, Al, 39);
|
|
5002
|
-
const MAJh = Ah & Bh ^ Ah & Ch ^ Bh & Ch;
|
|
5003
|
-
const MAJl = Al & Bl ^ Al & Cl ^ Bl & Cl;
|
|
5004
|
-
Hh = Gh | 0;
|
|
5005
|
-
Hl = Gl | 0;
|
|
5006
|
-
Gh = Fh | 0;
|
|
5007
|
-
Gl = Fl | 0;
|
|
5008
|
-
Fh = Eh | 0;
|
|
5009
|
-
Fl = El | 0;
|
|
5010
|
-
({h: Eh, l: El} = add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
|
|
5011
|
-
Dh = Ch | 0;
|
|
5012
|
-
Dl = Cl | 0;
|
|
5013
|
-
Ch = Bh | 0;
|
|
5014
|
-
Cl = Bl | 0;
|
|
5015
|
-
Bh = Ah | 0;
|
|
5016
|
-
Bl = Al | 0;
|
|
5017
|
-
const All = add3L(T1l, sigma0l, MAJl);
|
|
5018
|
-
Ah = add3H(All, T1h, sigma0h, MAJh);
|
|
5019
|
-
Al = All | 0;
|
|
5020
|
-
}
|
|
5021
|
-
({h: Ah, l: Al} = add(this.Ah | 0, this.Al | 0, Ah | 0, Al | 0));
|
|
5022
|
-
({h: Bh, l: Bl} = add(this.Bh | 0, this.Bl | 0, Bh | 0, Bl | 0));
|
|
5023
|
-
({h: Ch, l: Cl} = add(this.Ch | 0, this.Cl | 0, Ch | 0, Cl | 0));
|
|
5024
|
-
({h: Dh, l: Dl} = add(this.Dh | 0, this.Dl | 0, Dh | 0, Dl | 0));
|
|
5025
|
-
({h: Eh, l: El} = add(this.Eh | 0, this.El | 0, Eh | 0, El | 0));
|
|
5026
|
-
({h: Fh, l: Fl} = add(this.Fh | 0, this.Fl | 0, Fh | 0, Fl | 0));
|
|
5027
|
-
({h: Gh, l: Gl} = add(this.Gh | 0, this.Gl | 0, Gh | 0, Gl | 0));
|
|
5028
|
-
({h: Hh, l: Hl} = add(this.Hh | 0, this.Hl | 0, Hh | 0, Hl | 0));
|
|
5029
|
-
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
|
|
5030
|
-
}
|
|
5031
|
-
roundClean() {
|
|
5032
|
-
clean(SHA512_W_H, SHA512_W_L);
|
|
5033
|
-
}
|
|
5034
|
-
destroy() {
|
|
5035
|
-
clean(this.buffer);
|
|
5036
|
-
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
|
|
5037
|
-
}
|
|
5038
|
-
};
|
|
5039
|
-
/** Internal SHA2-512 hash class. */
|
|
5040
|
-
var _SHA512 = class extends SHA2_64B {
|
|
5041
|
-
Ah = SHA512_IV[0] | 0;
|
|
5042
|
-
Al = SHA512_IV[1] | 0;
|
|
5043
|
-
Bh = SHA512_IV[2] | 0;
|
|
5044
|
-
Bl = SHA512_IV[3] | 0;
|
|
5045
|
-
Ch = SHA512_IV[4] | 0;
|
|
5046
|
-
Cl = SHA512_IV[5] | 0;
|
|
5047
|
-
Dh = SHA512_IV[6] | 0;
|
|
5048
|
-
Dl = SHA512_IV[7] | 0;
|
|
5049
|
-
Eh = SHA512_IV[8] | 0;
|
|
5050
|
-
El = SHA512_IV[9] | 0;
|
|
5051
|
-
Fh = SHA512_IV[10] | 0;
|
|
5052
|
-
Fl = SHA512_IV[11] | 0;
|
|
5053
|
-
Gh = SHA512_IV[12] | 0;
|
|
5054
|
-
Gl = SHA512_IV[13] | 0;
|
|
5055
|
-
Hh = SHA512_IV[14] | 0;
|
|
5056
|
-
Hl = SHA512_IV[15] | 0;
|
|
5057
|
-
constructor() {
|
|
5058
|
-
super(64);
|
|
5059
|
-
}
|
|
5060
|
-
};
|
|
5061
|
-
/** SHA2-512 hash function from RFC 4634. */
|
|
5062
|
-
const sha512 = /* @__PURE__ */ createHasher$1(() => new _SHA512(), /* @__PURE__ */ oidNist(3));
|
|
5063
|
-
|
|
5064
|
-
//#endregion
|
|
5065
|
-
//#region node_modules/@noble/curves/utils.js
|
|
5066
|
-
/**
|
|
5067
|
-
* Hex, bytes and number utilities.
|
|
5068
|
-
* @module
|
|
5150
|
+
* Validates that a value is a safe integer.
|
|
5151
|
+
* @param value - Integer to validate.
|
|
5152
|
+
* @param title - Optional field name.
|
|
5153
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
5154
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
5155
|
+
* @example
|
|
5156
|
+
* Validate a window size before scalar arithmetic uses it.
|
|
5157
|
+
*
|
|
5158
|
+
* ```ts
|
|
5159
|
+
* asafenumber(1);
|
|
5160
|
+
* ```
|
|
5069
5161
|
*/
|
|
5070
|
-
|
|
5071
|
-
|
|
5072
|
-
const _1n$5 = /* @__PURE__ */ BigInt(1);
|
|
5073
|
-
function abool(value, title = "") {
|
|
5074
|
-
if (typeof value !== "boolean") {
|
|
5162
|
+
function asafenumber(value, title = "") {
|
|
5163
|
+
if (typeof value !== "number") {
|
|
5075
5164
|
const prefix = title && `"${title}" `;
|
|
5076
|
-
throw new
|
|
5165
|
+
throw new TypeError(prefix + "expected number, got type=" + typeof value);
|
|
5077
5166
|
}
|
|
5078
|
-
return value;
|
|
5079
|
-
}
|
|
5080
|
-
function abignumber(n) {
|
|
5081
|
-
if (typeof n === "bigint") {
|
|
5082
|
-
if (!isPosBig(n)) throw new Error("positive bigint expected, got " + n);
|
|
5083
|
-
} else anumber(n);
|
|
5084
|
-
return n;
|
|
5085
|
-
}
|
|
5086
|
-
function asafenumber(value, title = "") {
|
|
5087
5167
|
if (!Number.isSafeInteger(value)) {
|
|
5088
5168
|
const prefix = title && `"${title}" `;
|
|
5089
|
-
throw new
|
|
5169
|
+
throw new RangeError(prefix + "expected safe integer, got " + value);
|
|
5090
5170
|
}
|
|
5091
5171
|
}
|
|
5172
|
+
/**
|
|
5173
|
+
* Parses a big-endian hex string into bigint.
|
|
5174
|
+
* Accepts odd-length hex through the native `BigInt('0x' + hex)` parser and currently surfaces the
|
|
5175
|
+
* same native `SyntaxError` for malformed hex instead of wrapping it in a library-specific error.
|
|
5176
|
+
* @param hex - Hex string without `0x`.
|
|
5177
|
+
* @returns Parsed bigint value.
|
|
5178
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
5179
|
+
* @example
|
|
5180
|
+
* Parse a scalar from fixture hex.
|
|
5181
|
+
*
|
|
5182
|
+
* ```ts
|
|
5183
|
+
* hexToNumber('ff');
|
|
5184
|
+
* ```
|
|
5185
|
+
*/
|
|
5092
5186
|
function hexToNumber(hex) {
|
|
5093
|
-
if (typeof hex !== "string") throw new
|
|
5187
|
+
if (typeof hex !== "string") throw new TypeError("hex string expected, got " + typeof hex);
|
|
5094
5188
|
return hex === "" ? _0n$5 : BigInt("0x" + hex);
|
|
5095
5189
|
}
|
|
5190
|
+
/**
|
|
5191
|
+
* Parses big-endian bytes into bigint.
|
|
5192
|
+
* @param bytes - Bytes in big-endian order.
|
|
5193
|
+
* @returns Parsed bigint value.
|
|
5194
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
5195
|
+
* @example
|
|
5196
|
+
* Read a scalar encoded in network byte order.
|
|
5197
|
+
*
|
|
5198
|
+
* ```ts
|
|
5199
|
+
* bytesToNumberBE(Uint8Array.of(1, 0));
|
|
5200
|
+
* ```
|
|
5201
|
+
*/
|
|
5096
5202
|
function bytesToNumberBE(bytes) {
|
|
5097
|
-
return hexToNumber(bytesToHex(bytes));
|
|
5203
|
+
return hexToNumber(bytesToHex$2(bytes));
|
|
5098
5204
|
}
|
|
5205
|
+
/**
|
|
5206
|
+
* Parses little-endian bytes into bigint.
|
|
5207
|
+
* @param bytes - Bytes in little-endian order.
|
|
5208
|
+
* @returns Parsed bigint value.
|
|
5209
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
5210
|
+
* @example
|
|
5211
|
+
* Read a scalar encoded in little-endian form.
|
|
5212
|
+
*
|
|
5213
|
+
* ```ts
|
|
5214
|
+
* bytesToNumberLE(Uint8Array.of(1, 0));
|
|
5215
|
+
* ```
|
|
5216
|
+
*/
|
|
5099
5217
|
function bytesToNumberLE(bytes) {
|
|
5100
|
-
return hexToNumber(bytesToHex(copyBytes(abytes(bytes)).reverse()));
|
|
5218
|
+
return hexToNumber(bytesToHex$2(copyBytes(abytes$1(bytes)).reverse()));
|
|
5101
5219
|
}
|
|
5220
|
+
/**
|
|
5221
|
+
* Encodes a bigint into fixed-length big-endian bytes.
|
|
5222
|
+
* @param n - Number to encode.
|
|
5223
|
+
* @param len - Output length in bytes. Must be greater than zero.
|
|
5224
|
+
* @returns Big-endian byte array.
|
|
5225
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
5226
|
+
* @example
|
|
5227
|
+
* Serialize a scalar into a 32-byte field element.
|
|
5228
|
+
*
|
|
5229
|
+
* ```ts
|
|
5230
|
+
* numberToBytesBE(255n, 2);
|
|
5231
|
+
* ```
|
|
5232
|
+
*/
|
|
5102
5233
|
function numberToBytesBE(n, len) {
|
|
5103
|
-
anumber(len);
|
|
5234
|
+
anumber$1(len);
|
|
5235
|
+
if (len === 0) throw new RangeError("zero length");
|
|
5104
5236
|
n = abignumber(n);
|
|
5105
|
-
const
|
|
5106
|
-
if (
|
|
5107
|
-
return
|
|
5237
|
+
const hex = n.toString(16);
|
|
5238
|
+
if (hex.length > len * 2) throw new RangeError("number too large");
|
|
5239
|
+
return hexToBytes$2(hex.padStart(len * 2, "0"));
|
|
5108
5240
|
}
|
|
5241
|
+
/**
|
|
5242
|
+
* Encodes a bigint into fixed-length little-endian bytes.
|
|
5243
|
+
* @param n - Number to encode.
|
|
5244
|
+
* @param len - Output length in bytes.
|
|
5245
|
+
* @returns Little-endian byte array.
|
|
5246
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
5247
|
+
* @example
|
|
5248
|
+
* Serialize a scalar for little-endian protocols.
|
|
5249
|
+
*
|
|
5250
|
+
* ```ts
|
|
5251
|
+
* numberToBytesLE(255n, 2);
|
|
5252
|
+
* ```
|
|
5253
|
+
*/
|
|
5109
5254
|
function numberToBytesLE(n, len) {
|
|
5110
5255
|
return numberToBytesBE(n, len).reverse();
|
|
5111
5256
|
}
|
|
5257
|
+
/**
|
|
5258
|
+
* Compares two byte arrays in constant-ish time.
|
|
5259
|
+
* @param a - Left byte array.
|
|
5260
|
+
* @param b - Right byte array.
|
|
5261
|
+
* @returns `true` when bytes match.
|
|
5262
|
+
* @example
|
|
5263
|
+
* Compare two encoded points without early exit.
|
|
5264
|
+
*
|
|
5265
|
+
* ```ts
|
|
5266
|
+
* equalBytes(Uint8Array.of(1), Uint8Array.of(1));
|
|
5267
|
+
* ```
|
|
5268
|
+
*/
|
|
5112
5269
|
function equalBytes(a, b) {
|
|
5270
|
+
a = abytes(a);
|
|
5271
|
+
b = abytes(b);
|
|
5113
5272
|
if (a.length !== b.length) return false;
|
|
5114
5273
|
let diff = 0;
|
|
5115
5274
|
for (let i = 0; i < a.length; i++) diff |= a[i] ^ b[i];
|
|
@@ -5118,40 +5277,92 @@ function equalBytes(a, b) {
|
|
|
5118
5277
|
/**
|
|
5119
5278
|
* Copies Uint8Array. We can't use u8a.slice(), because u8a can be Buffer,
|
|
5120
5279
|
* and Buffer#slice creates mutable copy. Never use Buffers!
|
|
5280
|
+
* @param bytes - Bytes to copy.
|
|
5281
|
+
* @returns Detached copy.
|
|
5282
|
+
* @example
|
|
5283
|
+
* Make an isolated copy before mutating serialized bytes.
|
|
5284
|
+
*
|
|
5285
|
+
* ```ts
|
|
5286
|
+
* copyBytes(Uint8Array.of(1, 2, 3));
|
|
5287
|
+
* ```
|
|
5121
5288
|
*/
|
|
5122
5289
|
function copyBytes(bytes) {
|
|
5123
|
-
return Uint8Array.from(bytes);
|
|
5290
|
+
return Uint8Array.from(abytes(bytes));
|
|
5124
5291
|
}
|
|
5125
5292
|
/**
|
|
5126
5293
|
* Decodes 7-bit ASCII string to Uint8Array, throws on non-ascii symbols
|
|
5127
5294
|
* Should be safe to use for things expected to be ASCII.
|
|
5128
5295
|
* Returns exact same result as `TextEncoder` for ASCII or throws.
|
|
5296
|
+
* @param ascii - ASCII input text.
|
|
5297
|
+
* @returns Encoded bytes.
|
|
5298
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
5299
|
+
* @example
|
|
5300
|
+
* Encode an ASCII domain-separation tag.
|
|
5301
|
+
*
|
|
5302
|
+
* ```ts
|
|
5303
|
+
* asciiToBytes('ABC');
|
|
5304
|
+
* ```
|
|
5129
5305
|
*/
|
|
5130
5306
|
function asciiToBytes(ascii) {
|
|
5307
|
+
if (typeof ascii !== "string") throw new TypeError("ascii string expected, got " + typeof ascii);
|
|
5131
5308
|
return Uint8Array.from(ascii, (c, i) => {
|
|
5132
5309
|
const charCode = c.charCodeAt(0);
|
|
5133
|
-
if (c.length !== 1 || charCode > 127) throw new
|
|
5310
|
+
if (c.length !== 1 || charCode > 127) throw new RangeError(`string contains non-ASCII character "${ascii[i]}" with code ${charCode} at position ${i}`);
|
|
5134
5311
|
return charCode;
|
|
5135
5312
|
});
|
|
5136
5313
|
}
|
|
5137
5314
|
const isPosBig = (n) => typeof n === "bigint" && _0n$5 <= n;
|
|
5315
|
+
/**
|
|
5316
|
+
* Checks whether a bigint lies inside a half-open range.
|
|
5317
|
+
* @param n - Candidate value.
|
|
5318
|
+
* @param min - Inclusive lower bound.
|
|
5319
|
+
* @param max - Exclusive upper bound.
|
|
5320
|
+
* @returns `true` when the value is inside the range.
|
|
5321
|
+
* @example
|
|
5322
|
+
* Check whether a candidate scalar fits the field order.
|
|
5323
|
+
*
|
|
5324
|
+
* ```ts
|
|
5325
|
+
* inRange(2n, 1n, 3n);
|
|
5326
|
+
* ```
|
|
5327
|
+
*/
|
|
5138
5328
|
function inRange(n, min, max) {
|
|
5139
5329
|
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
5140
5330
|
}
|
|
5141
5331
|
/**
|
|
5142
|
-
* Asserts min <= n < max
|
|
5332
|
+
* Asserts `min <= n < max`. NOTE: upper bound is exclusive.
|
|
5333
|
+
* @param title - Value label for error messages.
|
|
5334
|
+
* @param n - Candidate value.
|
|
5335
|
+
* @param min - Inclusive lower bound.
|
|
5336
|
+
* @param max - Exclusive upper bound.
|
|
5337
|
+
* Wrong-type inputs are not separated from out-of-range values here: they still flow through the
|
|
5338
|
+
* shared `RangeError` path because this is only a throwing wrapper around `inRange(...)`.
|
|
5339
|
+
* @throws On wrong argument ranges or values. {@link RangeError}
|
|
5143
5340
|
* @example
|
|
5144
|
-
*
|
|
5341
|
+
* Assert that a bigint stays within one half-open range.
|
|
5342
|
+
*
|
|
5343
|
+
* ```ts
|
|
5344
|
+
* aInRange('x', 2n, 1n, 256n);
|
|
5345
|
+
* ```
|
|
5145
5346
|
*/
|
|
5146
5347
|
function aInRange(title, n, min, max) {
|
|
5147
|
-
if (!inRange(n, min, max)) throw new
|
|
5348
|
+
if (!inRange(n, min, max)) throw new RangeError("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
5148
5349
|
}
|
|
5149
5350
|
/**
|
|
5150
5351
|
* Calculates amount of bits in a bigint.
|
|
5151
5352
|
* Same as `n.toString(2).length`
|
|
5152
5353
|
* TODO: merge with nLength in modular
|
|
5354
|
+
* @param n - Value to inspect.
|
|
5355
|
+
* @returns Bit length.
|
|
5356
|
+
* @throws If the value is negative. {@link Error}
|
|
5357
|
+
* @example
|
|
5358
|
+
* Measure the bit length of a scalar before serialization.
|
|
5359
|
+
*
|
|
5360
|
+
* ```ts
|
|
5361
|
+
* bitLen(8n);
|
|
5362
|
+
* ```
|
|
5153
5363
|
*/
|
|
5154
5364
|
function bitLen(n) {
|
|
5365
|
+
if (n < _0n$5) throw new Error("expected non-negative bigint, got " + n);
|
|
5155
5366
|
let len;
|
|
5156
5367
|
for (len = 0; n > _0n$5; n >>= _1n$5, len += 1);
|
|
5157
5368
|
return len;
|
|
@@ -5159,40 +5370,61 @@ function bitLen(n) {
|
|
|
5159
5370
|
/**
|
|
5160
5371
|
* Calculate mask for N bits. Not using ** operator with bigints because of old engines.
|
|
5161
5372
|
* Same as BigInt(`0b${Array(i).fill('1').join('')}`)
|
|
5373
|
+
* @param n - Number of bits. Negative widths are currently passed through to raw bigint shift
|
|
5374
|
+
* semantics and therefore produce `-1n`.
|
|
5375
|
+
* @returns Bitmask value.
|
|
5376
|
+
* @example
|
|
5377
|
+
* Calculate mask for N bits.
|
|
5378
|
+
*
|
|
5379
|
+
* ```ts
|
|
5380
|
+
* bitMask(4);
|
|
5381
|
+
* ```
|
|
5162
5382
|
*/
|
|
5163
5383
|
const bitMask = (n) => (_1n$5 << BigInt(n)) - _1n$5;
|
|
5384
|
+
/**
|
|
5385
|
+
* Validates declared required and optional field types on a plain object.
|
|
5386
|
+
* Extra keys are intentionally ignored because many callers validate only the subset they use from
|
|
5387
|
+
* richer option bags or runtime objects.
|
|
5388
|
+
* @param object - Object to validate.
|
|
5389
|
+
* @param fields - Required field types.
|
|
5390
|
+
* @param optFields - Optional field types.
|
|
5391
|
+
* @throws On wrong argument types. {@link TypeError}
|
|
5392
|
+
* @example
|
|
5393
|
+
* Check user options before building a curve helper.
|
|
5394
|
+
*
|
|
5395
|
+
* ```ts
|
|
5396
|
+
* validateObject({ flag: true }, { flag: 'boolean' });
|
|
5397
|
+
* ```
|
|
5398
|
+
*/
|
|
5164
5399
|
function validateObject(object, fields = {}, optFields = {}) {
|
|
5165
|
-
if (
|
|
5400
|
+
if (Object.prototype.toString.call(object) !== "[object Object]") throw new TypeError("expected valid options object");
|
|
5166
5401
|
function checkField(fieldName, expectedType, isOpt) {
|
|
5402
|
+
if (!isOpt && expectedType !== "function" && !Object.hasOwn(object, fieldName)) throw new TypeError(`param "${fieldName}" is invalid: expected own property`);
|
|
5167
5403
|
const val = object[fieldName];
|
|
5168
5404
|
if (isOpt && val === void 0) return;
|
|
5169
5405
|
const current = typeof val;
|
|
5170
|
-
if (current !== expectedType || val === null) throw new
|
|
5406
|
+
if (current !== expectedType || val === null) throw new TypeError(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
5171
5407
|
}
|
|
5172
5408
|
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
|
|
5173
5409
|
iter(fields, false);
|
|
5174
5410
|
iter(optFields, true);
|
|
5175
5411
|
}
|
|
5176
5412
|
/**
|
|
5177
|
-
*
|
|
5413
|
+
* Throws not implemented error.
|
|
5414
|
+
* @returns Never returns.
|
|
5415
|
+
* @throws If the unfinished code path is reached. {@link Error}
|
|
5416
|
+
* @example
|
|
5417
|
+
* Surface the placeholder error from an unfinished code path.
|
|
5418
|
+
*
|
|
5419
|
+
* ```ts
|
|
5420
|
+
* try {
|
|
5421
|
+
* notImplemented();
|
|
5422
|
+
* } catch {}
|
|
5423
|
+
* ```
|
|
5178
5424
|
*/
|
|
5179
5425
|
const notImplemented = () => {
|
|
5180
5426
|
throw new Error("not implemented");
|
|
5181
5427
|
};
|
|
5182
|
-
/**
|
|
5183
|
-
* Memoizes (caches) computation result.
|
|
5184
|
-
* Uses WeakMap: the value is going auto-cleaned by GC after last reference is removed.
|
|
5185
|
-
*/
|
|
5186
|
-
function memoized(fn) {
|
|
5187
|
-
const map = /* @__PURE__ */ new WeakMap();
|
|
5188
|
-
return (arg, ...args) => {
|
|
5189
|
-
const val = map.get(arg);
|
|
5190
|
-
if (val !== void 0) return val;
|
|
5191
|
-
const computed = fn(arg, ...args);
|
|
5192
|
-
map.set(arg, computed);
|
|
5193
|
-
return computed;
|
|
5194
|
-
};
|
|
5195
|
-
}
|
|
5196
5428
|
|
|
5197
5429
|
//#endregion
|
|
5198
5430
|
//#region node_modules/@noble/curves/abstract/modular.js
|
|
@@ -5207,12 +5439,41 @@ const _0n$4 = /* @__PURE__ */ BigInt(0), _1n$4 = /* @__PURE__ */ BigInt(1), _2n$
|
|
|
5207
5439
|
const _3n$1 = /* @__PURE__ */ BigInt(3), _4n = /* @__PURE__ */ BigInt(4), _5n$1 = /* @__PURE__ */ BigInt(5);
|
|
5208
5440
|
const _7n = /* @__PURE__ */ BigInt(7), _8n$2 = /* @__PURE__ */ BigInt(8), _9n = /* @__PURE__ */ BigInt(9);
|
|
5209
5441
|
const _16n = /* @__PURE__ */ BigInt(16);
|
|
5442
|
+
/**
|
|
5443
|
+
* @param a - Dividend value.
|
|
5444
|
+
* @param b - Positive modulus.
|
|
5445
|
+
* @returns Reduced value in `[0, b)` only when `b` is positive.
|
|
5446
|
+
* @throws If the modulus is not positive. {@link Error}
|
|
5447
|
+
* @example
|
|
5448
|
+
* Normalize a bigint into one field residue.
|
|
5449
|
+
*
|
|
5450
|
+
* ```ts
|
|
5451
|
+
* mod(-1n, 5n);
|
|
5452
|
+
* ```
|
|
5453
|
+
*/
|
|
5210
5454
|
function mod(a, b) {
|
|
5455
|
+
if (b <= _0n$4) throw new Error("mod: expected positive modulus, got " + b);
|
|
5211
5456
|
const result = a % b;
|
|
5212
5457
|
return result >= _0n$4 ? result : b + result;
|
|
5213
5458
|
}
|
|
5214
|
-
/**
|
|
5459
|
+
/**
|
|
5460
|
+
* Does `x^(2^power)` mod p. `pow2(30, 4)` == `30^(2^4)`.
|
|
5461
|
+
* Low-level helper: callers that need canonical residues must pass a valid `x` for the chosen
|
|
5462
|
+
* modulus; the `power===0` fast path intentionally returns the input unchanged.
|
|
5463
|
+
* @param x - Base value.
|
|
5464
|
+
* @param power - Number of squarings.
|
|
5465
|
+
* @param modulo - Reduction modulus.
|
|
5466
|
+
* @returns Repeated-squaring result.
|
|
5467
|
+
* @throws If the exponent is negative. {@link Error}
|
|
5468
|
+
* @example
|
|
5469
|
+
* Apply repeated squaring inside one field.
|
|
5470
|
+
*
|
|
5471
|
+
* ```ts
|
|
5472
|
+
* pow2(3n, 2n, 11n);
|
|
5473
|
+
* ```
|
|
5474
|
+
*/
|
|
5215
5475
|
function pow2(x, power, modulo) {
|
|
5476
|
+
if (power < _0n$4) throw new Error("pow2: expected non-negative exponent, got " + power);
|
|
5216
5477
|
let res = x;
|
|
5217
5478
|
while (power-- > _0n$4) {
|
|
5218
5479
|
res *= res;
|
|
@@ -5222,7 +5483,17 @@ function pow2(x, power, modulo) {
|
|
|
5222
5483
|
}
|
|
5223
5484
|
/**
|
|
5224
5485
|
* Inverses number over modulo.
|
|
5225
|
-
* Implemented using
|
|
5486
|
+
* Implemented using the {@link https://brilliant.org/wiki/extended-euclidean-algorithm/ | extended Euclidean algorithm}.
|
|
5487
|
+
* @param number - Value to invert.
|
|
5488
|
+
* @param modulo - Positive modulus.
|
|
5489
|
+
* @returns Multiplicative inverse.
|
|
5490
|
+
* @throws If the modulus is invalid or the inverse does not exist. {@link Error}
|
|
5491
|
+
* @example
|
|
5492
|
+
* Compute one modular inverse with the extended Euclidean algorithm.
|
|
5493
|
+
*
|
|
5494
|
+
* ```ts
|
|
5495
|
+
* invert(3n, 11n);
|
|
5496
|
+
* ```
|
|
5226
5497
|
*/
|
|
5227
5498
|
function invert(number, modulo) {
|
|
5228
5499
|
if (number === _0n$4) throw new Error("invert: expected non-zero number");
|
|
@@ -5232,7 +5503,7 @@ function invert(number, modulo) {
|
|
|
5232
5503
|
let x = _0n$4, y = _1n$4, u = _1n$4, v = _0n$4;
|
|
5233
5504
|
while (a !== _0n$4) {
|
|
5234
5505
|
const q = b / a;
|
|
5235
|
-
const r = b
|
|
5506
|
+
const r = b - a * q;
|
|
5236
5507
|
const m = x - u * q;
|
|
5237
5508
|
const n = y - v * q;
|
|
5238
5509
|
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
@@ -5241,22 +5512,25 @@ function invert(number, modulo) {
|
|
|
5241
5512
|
return mod(x, modulo);
|
|
5242
5513
|
}
|
|
5243
5514
|
function assertIsSquare(Fp, root, n) {
|
|
5244
|
-
|
|
5515
|
+
const F = Fp;
|
|
5516
|
+
if (!F.eql(F.sqr(root), n)) throw new Error("Cannot find square root");
|
|
5245
5517
|
}
|
|
5246
5518
|
function sqrt3mod4(Fp, n) {
|
|
5247
|
-
const
|
|
5248
|
-
const
|
|
5249
|
-
|
|
5519
|
+
const F = Fp;
|
|
5520
|
+
const p1div4 = (F.ORDER + _1n$4) / _4n;
|
|
5521
|
+
const root = F.pow(n, p1div4);
|
|
5522
|
+
assertIsSquare(F, root, n);
|
|
5250
5523
|
return root;
|
|
5251
5524
|
}
|
|
5252
5525
|
function sqrt5mod8(Fp, n) {
|
|
5253
|
-
const
|
|
5254
|
-
const
|
|
5255
|
-
const
|
|
5256
|
-
const
|
|
5257
|
-
const
|
|
5258
|
-
const
|
|
5259
|
-
|
|
5526
|
+
const F = Fp;
|
|
5527
|
+
const p5div8 = (F.ORDER - _5n$1) / _8n$2;
|
|
5528
|
+
const n2 = F.mul(n, _2n$3);
|
|
5529
|
+
const v = F.pow(n2, p5div8);
|
|
5530
|
+
const nv = F.mul(n, v);
|
|
5531
|
+
const i = F.mul(F.mul(nv, _2n$3), v);
|
|
5532
|
+
const root = F.mul(nv, F.sub(i, F.ONE));
|
|
5533
|
+
assertIsSquare(F, root, n);
|
|
5260
5534
|
return root;
|
|
5261
5535
|
}
|
|
5262
5536
|
function sqrt9mod16(P) {
|
|
@@ -5266,27 +5540,39 @@ function sqrt9mod16(P) {
|
|
|
5266
5540
|
const c2 = tn(Fp_, c1);
|
|
5267
5541
|
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
5268
5542
|
const c4 = (P + _7n) / _16n;
|
|
5269
|
-
return (Fp, n) => {
|
|
5270
|
-
|
|
5271
|
-
let
|
|
5272
|
-
|
|
5273
|
-
const
|
|
5274
|
-
const
|
|
5275
|
-
const
|
|
5276
|
-
|
|
5277
|
-
|
|
5278
|
-
|
|
5279
|
-
const
|
|
5280
|
-
|
|
5543
|
+
return ((Fp, n) => {
|
|
5544
|
+
const F = Fp;
|
|
5545
|
+
let tv1 = F.pow(n, c4);
|
|
5546
|
+
let tv2 = F.mul(tv1, c1);
|
|
5547
|
+
const tv3 = F.mul(tv1, c2);
|
|
5548
|
+
const tv4 = F.mul(tv1, c3);
|
|
5549
|
+
const e1 = F.eql(F.sqr(tv2), n);
|
|
5550
|
+
const e2 = F.eql(F.sqr(tv3), n);
|
|
5551
|
+
tv1 = F.cmov(tv1, tv2, e1);
|
|
5552
|
+
tv2 = F.cmov(tv4, tv3, e2);
|
|
5553
|
+
const e3 = F.eql(F.sqr(tv2), n);
|
|
5554
|
+
const root = F.cmov(tv1, tv2, e3);
|
|
5555
|
+
assertIsSquare(F, root, n);
|
|
5281
5556
|
return root;
|
|
5282
|
-
};
|
|
5557
|
+
});
|
|
5283
5558
|
}
|
|
5284
5559
|
/**
|
|
5285
5560
|
* Tonelli-Shanks square root search algorithm.
|
|
5286
|
-
*
|
|
5561
|
+
* This implementation is variable-time: it searches data-dependently for the first non-residue `Z`
|
|
5562
|
+
* and for the smallest `i` in the main loop, unlike RFC 9380 Appendix I.4's constant-time shape.
|
|
5563
|
+
* 1. {@link https://eprint.iacr.org/2012/685.pdf | eprint 2012/685}, page 12
|
|
5287
5564
|
* 2. Square Roots from 1; 24, 51, 10 to Dan Shanks
|
|
5288
|
-
* @param P field order
|
|
5565
|
+
* @param P - field order
|
|
5289
5566
|
* @returns function that takes field Fp (created from P) and number n
|
|
5567
|
+
* @throws If the field is too small, non-prime, or the square root does not exist. {@link Error}
|
|
5568
|
+
* @example
|
|
5569
|
+
* Construct a square-root helper for primes that need Tonelli-Shanks.
|
|
5570
|
+
*
|
|
5571
|
+
* ```ts
|
|
5572
|
+
* import { Field, tonelliShanks } from '@noble/curves/abstract/modular.js';
|
|
5573
|
+
* const Fp = Field(17n);
|
|
5574
|
+
* const sqrt = tonelliShanks(17n)(Fp, 4n);
|
|
5575
|
+
* ```
|
|
5290
5576
|
*/
|
|
5291
5577
|
function tonelliShanks(P) {
|
|
5292
5578
|
if (P < _3n$1) throw new Error("sqrt is not defined for small field");
|
|
@@ -5303,27 +5589,28 @@ function tonelliShanks(P) {
|
|
|
5303
5589
|
let cc = _Fp.pow(Z, Q);
|
|
5304
5590
|
const Q1div2 = (Q + _1n$4) / _2n$3;
|
|
5305
5591
|
return function tonelliSlow(Fp, n) {
|
|
5306
|
-
|
|
5307
|
-
if (
|
|
5592
|
+
const F = Fp;
|
|
5593
|
+
if (F.is0(n)) return n;
|
|
5594
|
+
if (FpLegendre(F, n) !== 1) throw new Error("Cannot find square root");
|
|
5308
5595
|
let M = S;
|
|
5309
|
-
let c =
|
|
5310
|
-
let t =
|
|
5311
|
-
let R =
|
|
5312
|
-
while (!
|
|
5313
|
-
if (
|
|
5596
|
+
let c = F.mul(F.ONE, cc);
|
|
5597
|
+
let t = F.pow(n, Q);
|
|
5598
|
+
let R = F.pow(n, Q1div2);
|
|
5599
|
+
while (!F.eql(t, F.ONE)) {
|
|
5600
|
+
if (F.is0(t)) return F.ZERO;
|
|
5314
5601
|
let i = 1;
|
|
5315
|
-
let t_tmp =
|
|
5316
|
-
while (!
|
|
5602
|
+
let t_tmp = F.sqr(t);
|
|
5603
|
+
while (!F.eql(t_tmp, F.ONE)) {
|
|
5317
5604
|
i++;
|
|
5318
|
-
t_tmp =
|
|
5605
|
+
t_tmp = F.sqr(t_tmp);
|
|
5319
5606
|
if (i === M) throw new Error("Cannot find square root");
|
|
5320
5607
|
}
|
|
5321
5608
|
const exponent = _1n$4 << BigInt(M - i - 1);
|
|
5322
|
-
const b =
|
|
5609
|
+
const b = F.pow(c, exponent);
|
|
5323
5610
|
M = i;
|
|
5324
|
-
c =
|
|
5325
|
-
t =
|
|
5326
|
-
R =
|
|
5611
|
+
c = F.sqr(b);
|
|
5612
|
+
t = F.mul(t, c);
|
|
5613
|
+
R = F.mul(R, b);
|
|
5327
5614
|
}
|
|
5328
5615
|
return R;
|
|
5329
5616
|
};
|
|
@@ -5337,7 +5624,20 @@ function tonelliShanks(P) {
|
|
|
5337
5624
|
* 4. Tonelli-Shanks algorithm
|
|
5338
5625
|
*
|
|
5339
5626
|
* Different algorithms can give different roots, it is up to user to decide which one they want.
|
|
5340
|
-
* For example there is FpSqrtOdd/FpSqrtEven to
|
|
5627
|
+
* For example there is FpSqrtOdd/FpSqrtEven to choose a root by oddness
|
|
5628
|
+
* (used for hash-to-curve).
|
|
5629
|
+
* @param P - Field order.
|
|
5630
|
+
* @returns Square-root helper. The generic fallback inherits Tonelli-Shanks' variable-time
|
|
5631
|
+
* behavior and this selector assumes prime-field-style integer moduli.
|
|
5632
|
+
* @throws If the field is unsupported or the square root does not exist. {@link Error}
|
|
5633
|
+
* @example
|
|
5634
|
+
* Choose the square-root helper appropriate for one field modulus.
|
|
5635
|
+
*
|
|
5636
|
+
* ```ts
|
|
5637
|
+
* import { Field, FpSqrt } from '@noble/curves/abstract/modular.js';
|
|
5638
|
+
* const Fp = Field(17n);
|
|
5639
|
+
* const sqrt = FpSqrt(17n)(Fp, 4n);
|
|
5640
|
+
* ```
|
|
5341
5641
|
*/
|
|
5342
5642
|
function FpSqrt(P) {
|
|
5343
5643
|
if (P % _4n === _3n$1) return sqrt3mod4;
|
|
@@ -5345,6 +5645,18 @@ function FpSqrt(P) {
|
|
|
5345
5645
|
if (P % _16n === _9n) return sqrt9mod16(P);
|
|
5346
5646
|
return tonelliShanks(P);
|
|
5347
5647
|
}
|
|
5648
|
+
/**
|
|
5649
|
+
* @param num - Value to inspect.
|
|
5650
|
+
* @param modulo - Field modulus.
|
|
5651
|
+
* @returns `true` when the least-significant little-endian bit is set.
|
|
5652
|
+
* @throws If the modulus is invalid for `mod(...)`. {@link Error}
|
|
5653
|
+
* @example
|
|
5654
|
+
* Inspect the low bit used by little-endian sign conventions.
|
|
5655
|
+
*
|
|
5656
|
+
* ```ts
|
|
5657
|
+
* isNegativeLE(3n, 11n);
|
|
5658
|
+
* ```
|
|
5659
|
+
*/
|
|
5348
5660
|
const isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n$4) === _1n$4;
|
|
5349
5661
|
const FIELD_FIELDS = [
|
|
5350
5662
|
"create",
|
|
@@ -5365,6 +5677,20 @@ const FIELD_FIELDS = [
|
|
|
5365
5677
|
"mulN",
|
|
5366
5678
|
"sqrN"
|
|
5367
5679
|
];
|
|
5680
|
+
/**
|
|
5681
|
+
* @param field - Field implementation.
|
|
5682
|
+
* @returns Validated field. This only checks the arithmetic subset needed by generic helpers; it
|
|
5683
|
+
* does not guarantee full runtime-method coverage for serialization, batching, `cmov`, or
|
|
5684
|
+
* field-specific extras beyond positive `BYTES` / `BITS`.
|
|
5685
|
+
* @throws If the field shape or numeric metadata are invalid. {@link Error}
|
|
5686
|
+
* @example
|
|
5687
|
+
* Check that a field implementation exposes the operations curve code expects.
|
|
5688
|
+
*
|
|
5689
|
+
* ```ts
|
|
5690
|
+
* import { Field, validateField } from '@noble/curves/abstract/modular.js';
|
|
5691
|
+
* const Fp = validateField(Field(17n));
|
|
5692
|
+
* ```
|
|
5693
|
+
*/
|
|
5368
5694
|
function validateField(field) {
|
|
5369
5695
|
validateObject(field, FIELD_FIELDS.reduce((map, val) => {
|
|
5370
5696
|
map[val] = "function";
|
|
@@ -5374,42 +5700,72 @@ function validateField(field) {
|
|
|
5374
5700
|
BYTES: "number",
|
|
5375
5701
|
BITS: "number"
|
|
5376
5702
|
}));
|
|
5703
|
+
asafenumber(field.BYTES, "BYTES");
|
|
5704
|
+
asafenumber(field.BITS, "BITS");
|
|
5705
|
+
if (field.BYTES < 1 || field.BITS < 1) throw new Error("invalid field: expected BYTES/BITS > 0");
|
|
5706
|
+
if (field.ORDER <= _1n$4) throw new Error("invalid field: expected ORDER > 1, got " + field.ORDER);
|
|
5377
5707
|
return field;
|
|
5378
5708
|
}
|
|
5379
5709
|
/**
|
|
5380
5710
|
* Same as `pow` but for Fp: non-constant-time.
|
|
5381
5711
|
* Unsafe in some contexts: uses ladder, so can expose bigint bits.
|
|
5712
|
+
* @param Fp - Field implementation.
|
|
5713
|
+
* @param num - Base value.
|
|
5714
|
+
* @param power - Exponent value.
|
|
5715
|
+
* @returns Powered field element.
|
|
5716
|
+
* @throws If the exponent is negative. {@link Error}
|
|
5717
|
+
* @example
|
|
5718
|
+
* Raise one field element to a public exponent.
|
|
5719
|
+
*
|
|
5720
|
+
* ```ts
|
|
5721
|
+
* import { Field, FpPow } from '@noble/curves/abstract/modular.js';
|
|
5722
|
+
* const Fp = Field(17n);
|
|
5723
|
+
* const x = FpPow(Fp, 3n, 5n);
|
|
5724
|
+
* ```
|
|
5382
5725
|
*/
|
|
5383
5726
|
function FpPow(Fp, num, power) {
|
|
5727
|
+
const F = Fp;
|
|
5384
5728
|
if (power < _0n$4) throw new Error("invalid exponent, negatives unsupported");
|
|
5385
|
-
if (power === _0n$4) return
|
|
5729
|
+
if (power === _0n$4) return F.ONE;
|
|
5386
5730
|
if (power === _1n$4) return num;
|
|
5387
|
-
let p =
|
|
5731
|
+
let p = F.ONE;
|
|
5388
5732
|
let d = num;
|
|
5389
5733
|
while (power > _0n$4) {
|
|
5390
|
-
if (power & _1n$4) p =
|
|
5391
|
-
d =
|
|
5734
|
+
if (power & _1n$4) p = F.mul(p, d);
|
|
5735
|
+
d = F.sqr(d);
|
|
5392
5736
|
power >>= _1n$4;
|
|
5393
5737
|
}
|
|
5394
5738
|
return p;
|
|
5395
5739
|
}
|
|
5396
5740
|
/**
|
|
5397
5741
|
* Efficiently invert an array of Field elements.
|
|
5398
|
-
* Exception-free.
|
|
5399
|
-
* @param
|
|
5742
|
+
* Exception-free. Zero-valued field elements stay `undefined` unless `passZero` is enabled.
|
|
5743
|
+
* @param Fp - Field implementation.
|
|
5744
|
+
* @param nums - Values to invert.
|
|
5745
|
+
* @param passZero - map 0 to 0 (instead of undefined)
|
|
5746
|
+
* @returns Inverted values.
|
|
5747
|
+
* @example
|
|
5748
|
+
* Invert several field elements with one shared inversion.
|
|
5749
|
+
*
|
|
5750
|
+
* ```ts
|
|
5751
|
+
* import { Field, FpInvertBatch } from '@noble/curves/abstract/modular.js';
|
|
5752
|
+
* const Fp = Field(17n);
|
|
5753
|
+
* const inv = FpInvertBatch(Fp, [1n, 2n, 4n]);
|
|
5754
|
+
* ```
|
|
5400
5755
|
*/
|
|
5401
5756
|
function FpInvertBatch(Fp, nums, passZero = false) {
|
|
5402
|
-
const
|
|
5757
|
+
const F = Fp;
|
|
5758
|
+
const inverted = new Array(nums.length).fill(passZero ? F.ZERO : void 0);
|
|
5403
5759
|
const multipliedAcc = nums.reduce((acc, num, i) => {
|
|
5404
|
-
if (
|
|
5760
|
+
if (F.is0(num)) return acc;
|
|
5405
5761
|
inverted[i] = acc;
|
|
5406
|
-
return
|
|
5407
|
-
},
|
|
5408
|
-
const invertedAcc =
|
|
5762
|
+
return F.mul(acc, num);
|
|
5763
|
+
}, F.ONE);
|
|
5764
|
+
const invertedAcc = F.inv(multipliedAcc);
|
|
5409
5765
|
nums.reduceRight((acc, num, i) => {
|
|
5410
|
-
if (
|
|
5411
|
-
inverted[i] =
|
|
5412
|
-
return
|
|
5766
|
+
if (F.is0(num)) return acc;
|
|
5767
|
+
inverted[i] = F.mul(acc, inverted[i]);
|
|
5768
|
+
return F.mul(acc, num);
|
|
5413
5769
|
}, invertedAcc);
|
|
5414
5770
|
return inverted;
|
|
5415
5771
|
}
|
|
@@ -5421,24 +5777,55 @@ function FpInvertBatch(Fp, nums, passZero = false) {
|
|
|
5421
5777
|
* * (a | p) ≡ 1 if a is a square (mod p), quadratic residue
|
|
5422
5778
|
* * (a | p) ≡ -1 if a is not a square (mod p), quadratic non residue
|
|
5423
5779
|
* * (a | p) ≡ 0 if a ≡ 0 (mod p)
|
|
5780
|
+
* @param Fp - Field implementation.
|
|
5781
|
+
* @param n - Value to inspect.
|
|
5782
|
+
* @returns Legendre symbol.
|
|
5783
|
+
* @throws If the field returns an invalid Legendre symbol value. {@link Error}
|
|
5784
|
+
* @example
|
|
5785
|
+
* Compute the Legendre symbol of one field element.
|
|
5786
|
+
*
|
|
5787
|
+
* ```ts
|
|
5788
|
+
* import { Field, FpLegendre } from '@noble/curves/abstract/modular.js';
|
|
5789
|
+
* const Fp = Field(17n);
|
|
5790
|
+
* const symbol = FpLegendre(Fp, 4n);
|
|
5791
|
+
* ```
|
|
5424
5792
|
*/
|
|
5425
5793
|
function FpLegendre(Fp, n) {
|
|
5426
|
-
const
|
|
5427
|
-
const
|
|
5428
|
-
const
|
|
5429
|
-
const
|
|
5430
|
-
const
|
|
5794
|
+
const F = Fp;
|
|
5795
|
+
const p1mod2 = (F.ORDER - _1n$4) / _2n$3;
|
|
5796
|
+
const powered = F.pow(n, p1mod2);
|
|
5797
|
+
const yes = F.eql(powered, F.ONE);
|
|
5798
|
+
const zero = F.eql(powered, F.ZERO);
|
|
5799
|
+
const no = F.eql(powered, F.neg(F.ONE));
|
|
5431
5800
|
if (!yes && !zero && !no) throw new Error("invalid Legendre symbol result");
|
|
5432
5801
|
return yes ? 1 : zero ? 0 : -1;
|
|
5433
5802
|
}
|
|
5803
|
+
/**
|
|
5804
|
+
* @param n - Curve order. Callers are expected to pass a positive order.
|
|
5805
|
+
* @param nBitLength - Optional cached bit length. Callers are expected to pass a positive cached
|
|
5806
|
+
* value when overriding the derived bit length.
|
|
5807
|
+
* @returns Byte and bit lengths.
|
|
5808
|
+
* @throws If the order or cached bit length is invalid. {@link Error}
|
|
5809
|
+
* @example
|
|
5810
|
+
* Measure the encoding sizes needed for one modulus.
|
|
5811
|
+
*
|
|
5812
|
+
* ```ts
|
|
5813
|
+
* nLength(255n);
|
|
5814
|
+
* ```
|
|
5815
|
+
*/
|
|
5434
5816
|
function nLength(n, nBitLength) {
|
|
5435
5817
|
if (nBitLength !== void 0) anumber(nBitLength);
|
|
5436
|
-
|
|
5818
|
+
if (n <= _0n$4) throw new Error("invalid n length: expected positive n, got " + n);
|
|
5819
|
+
if (nBitLength !== void 0 && nBitLength < 1) throw new Error("invalid n length: expected positive bit length, got " + nBitLength);
|
|
5820
|
+
const bits = bitLen(n);
|
|
5821
|
+
if (nBitLength !== void 0 && nBitLength < bits) throw new Error(`invalid n length: expected bit length (${bits}) >= n.length (${nBitLength})`);
|
|
5822
|
+
const _nBitLength = nBitLength !== void 0 ? nBitLength : bits;
|
|
5437
5823
|
return {
|
|
5438
5824
|
nBitLength: _nBitLength,
|
|
5439
5825
|
nByteLength: Math.ceil(_nBitLength / 8)
|
|
5440
5826
|
};
|
|
5441
5827
|
}
|
|
5828
|
+
const FIELD_SQRT = /* @__PURE__ */ new WeakMap();
|
|
5442
5829
|
var _Field = class {
|
|
5443
5830
|
ORDER;
|
|
5444
5831
|
BITS;
|
|
@@ -5447,17 +5834,19 @@ var _Field = class {
|
|
|
5447
5834
|
ZERO = _0n$4;
|
|
5448
5835
|
ONE = _1n$4;
|
|
5449
5836
|
_lengths;
|
|
5450
|
-
_sqrt;
|
|
5451
5837
|
_mod;
|
|
5452
5838
|
constructor(ORDER, opts = {}) {
|
|
5453
|
-
if (ORDER <=
|
|
5839
|
+
if (ORDER <= _1n$4) throw new Error("invalid field: expected ORDER > 1, got " + ORDER);
|
|
5454
5840
|
let _nbitLength = void 0;
|
|
5455
5841
|
this.isLE = false;
|
|
5456
5842
|
if (opts != null && typeof opts === "object") {
|
|
5457
5843
|
if (typeof opts.BITS === "number") _nbitLength = opts.BITS;
|
|
5458
|
-
if (typeof opts.sqrt === "function") this
|
|
5844
|
+
if (typeof opts.sqrt === "function") Object.defineProperty(this, "sqrt", {
|
|
5845
|
+
value: opts.sqrt,
|
|
5846
|
+
enumerable: true
|
|
5847
|
+
});
|
|
5459
5848
|
if (typeof opts.isLE === "boolean") this.isLE = opts.isLE;
|
|
5460
|
-
if (opts.allowedLengths) this._lengths = opts.allowedLengths
|
|
5849
|
+
if (opts.allowedLengths) this._lengths = Object.freeze(opts.allowedLengths.slice());
|
|
5461
5850
|
if (typeof opts.modFromBytes === "boolean") this._mod = opts.modFromBytes;
|
|
5462
5851
|
}
|
|
5463
5852
|
const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);
|
|
@@ -5465,14 +5854,13 @@ var _Field = class {
|
|
|
5465
5854
|
this.ORDER = ORDER;
|
|
5466
5855
|
this.BITS = nBitLength;
|
|
5467
5856
|
this.BYTES = nByteLength;
|
|
5468
|
-
this
|
|
5469
|
-
Object.preventExtensions(this);
|
|
5857
|
+
Object.freeze(this);
|
|
5470
5858
|
}
|
|
5471
5859
|
create(num) {
|
|
5472
5860
|
return mod(num, this.ORDER);
|
|
5473
5861
|
}
|
|
5474
5862
|
isValid(num) {
|
|
5475
|
-
if (typeof num !== "bigint") throw new
|
|
5863
|
+
if (typeof num !== "bigint") throw new TypeError("invalid field element: expected bigint, got " + typeof num);
|
|
5476
5864
|
return _0n$4 <= num && num < this.ORDER;
|
|
5477
5865
|
}
|
|
5478
5866
|
is0(num) {
|
|
@@ -5524,8 +5912,9 @@ var _Field = class {
|
|
|
5524
5912
|
return invert(num, this.ORDER);
|
|
5525
5913
|
}
|
|
5526
5914
|
sqrt(num) {
|
|
5527
|
-
|
|
5528
|
-
|
|
5915
|
+
let sqrt = FIELD_SQRT.get(this);
|
|
5916
|
+
if (!sqrt) FIELD_SQRT.set(this, sqrt = FpSqrt(this.ORDER));
|
|
5917
|
+
return sqrt(this, num);
|
|
5529
5918
|
}
|
|
5530
5919
|
toBytes(num) {
|
|
5531
5920
|
return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);
|
|
@@ -5534,7 +5923,7 @@ var _Field = class {
|
|
|
5534
5923
|
abytes(bytes);
|
|
5535
5924
|
const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;
|
|
5536
5925
|
if (allowedLengths) {
|
|
5537
|
-
if (!allowedLengths.includes(bytes.length) || bytes.length > BYTES) throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
5926
|
+
if (bytes.length < 1 || !allowedLengths.includes(bytes.length) || bytes.length > BYTES) throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
5538
5927
|
const padded = new Uint8Array(BYTES);
|
|
5539
5928
|
padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
|
|
5540
5929
|
bytes = padded;
|
|
@@ -5551,53 +5940,95 @@ var _Field = class {
|
|
|
5551
5940
|
return FpInvertBatch(this, lst);
|
|
5552
5941
|
}
|
|
5553
5942
|
cmov(a, b, condition) {
|
|
5943
|
+
abool(condition, "condition");
|
|
5554
5944
|
return condition ? b : a;
|
|
5555
5945
|
}
|
|
5556
5946
|
};
|
|
5947
|
+
Object.freeze(_Field.prototype);
|
|
5557
5948
|
/**
|
|
5558
5949
|
* Creates a finite field. Major performance optimizations:
|
|
5559
5950
|
* * 1. Denormalized operations like mulN instead of mul.
|
|
5560
5951
|
* * 2. Identical object shape: never add or remove keys.
|
|
5561
|
-
* * 3. `
|
|
5952
|
+
* * 3. Frozen stable object shape; the lazy sqrt cache lives in a module-level `WeakMap`.
|
|
5562
5953
|
* Fragile: always run a benchmark on a change.
|
|
5563
|
-
* Security note: operations don't check
|
|
5564
|
-
*
|
|
5954
|
+
* Security note: operations and low-level serializers like `toBytes` don't check `isValid` for
|
|
5955
|
+
* all elements for performance and protocol-flexibility reasons; callers are responsible for
|
|
5956
|
+
* supplying valid elements when they need canonical field behavior.
|
|
5565
5957
|
* This is low-level code, please make sure you know what you're doing.
|
|
5566
5958
|
*
|
|
5567
5959
|
* Note about field properties:
|
|
5568
5960
|
* * CHARACTERISTIC p = prime number, number of elements in main subgroup.
|
|
5569
5961
|
* * ORDER q = similar to cofactor in curves, may be composite `q = p^m`.
|
|
5570
5962
|
*
|
|
5571
|
-
* @param ORDER field order, probably prime, or could be composite
|
|
5572
|
-
* @param
|
|
5573
|
-
* @
|
|
5574
|
-
*
|
|
5963
|
+
* @param ORDER - field order, probably prime, or could be composite
|
|
5964
|
+
* @param opts - Field options such as bit length or endianness. See {@link FieldOpts}.
|
|
5965
|
+
* @returns Frozen field instance with a stable object shape. This wrapper forwards `opts` straight
|
|
5966
|
+
* into `_Field`, so it inherits `_Field`'s assumptions about cached sizes and `allowedLengths`.
|
|
5967
|
+
* @example
|
|
5968
|
+
* Construct one prime field with optional overrides.
|
|
5969
|
+
*
|
|
5970
|
+
* ```ts
|
|
5971
|
+
* Field(11n);
|
|
5972
|
+
* ```
|
|
5575
5973
|
*/
|
|
5576
5974
|
function Field(ORDER, opts = {}) {
|
|
5577
5975
|
return new _Field(ORDER, opts);
|
|
5578
5976
|
}
|
|
5977
|
+
/**
|
|
5978
|
+
* @param Fp - Field implementation.
|
|
5979
|
+
* @param elm - Value to square-root.
|
|
5980
|
+
* @returns Even square root.
|
|
5981
|
+
* @throws If the field lacks oddness checks or the square root does not exist. {@link Error}
|
|
5982
|
+
* @example
|
|
5983
|
+
* Select the even square root when two roots exist.
|
|
5984
|
+
*
|
|
5985
|
+
* ```ts
|
|
5986
|
+
* import { Field, FpSqrtEven } from '@noble/curves/abstract/modular.js';
|
|
5987
|
+
* const Fp = Field(17n);
|
|
5988
|
+
* const root = FpSqrtEven(Fp, 4n);
|
|
5989
|
+
* ```
|
|
5990
|
+
*/
|
|
5579
5991
|
function FpSqrtEven(Fp, elm) {
|
|
5580
|
-
|
|
5581
|
-
|
|
5582
|
-
|
|
5992
|
+
const F = Fp;
|
|
5993
|
+
if (!F.isOdd) throw new Error("Field doesn't have isOdd");
|
|
5994
|
+
const root = F.sqrt(elm);
|
|
5995
|
+
return F.isOdd(root) ? F.neg(root) : root;
|
|
5583
5996
|
}
|
|
5584
5997
|
/**
|
|
5585
5998
|
* Returns total number of bytes consumed by the field element.
|
|
5586
5999
|
* For example, 32 bytes for usual 256-bit weierstrass curve.
|
|
5587
|
-
* @param fieldOrder number of field elements, usually CURVE.n
|
|
6000
|
+
* @param fieldOrder - number of field elements, usually CURVE.n. Callers are expected to pass an
|
|
6001
|
+
* order greater than 1.
|
|
5588
6002
|
* @returns byte length of field
|
|
6003
|
+
* @throws If the field order is not a bigint. {@link Error}
|
|
6004
|
+
* @example
|
|
6005
|
+
* Read the fixed-width byte length of one field.
|
|
6006
|
+
*
|
|
6007
|
+
* ```ts
|
|
6008
|
+
* getFieldBytesLength(255n);
|
|
6009
|
+
* ```
|
|
5589
6010
|
*/
|
|
5590
6011
|
function getFieldBytesLength(fieldOrder) {
|
|
5591
6012
|
if (typeof fieldOrder !== "bigint") throw new Error("field order must be bigint");
|
|
5592
|
-
|
|
6013
|
+
if (fieldOrder <= _1n$4) throw new Error("field order must be greater than 1");
|
|
6014
|
+
const bitLength = bitLen(fieldOrder - _1n$4);
|
|
5593
6015
|
return Math.ceil(bitLength / 8);
|
|
5594
6016
|
}
|
|
5595
6017
|
/**
|
|
5596
6018
|
* Returns minimal amount of bytes that can be safely reduced
|
|
5597
6019
|
* by field order.
|
|
5598
6020
|
* Should be 2^-128 for 128-bit curve such as P256.
|
|
5599
|
-
*
|
|
6021
|
+
* This is the reduction / modulo-bias lower bound; higher-level helpers may still impose a larger
|
|
6022
|
+
* absolute floor for policy reasons.
|
|
6023
|
+
* @param fieldOrder - number of field elements greater than 1, usually CURVE.n.
|
|
5600
6024
|
* @returns byte length of target hash
|
|
6025
|
+
* @throws If the field order is invalid. {@link Error}
|
|
6026
|
+
* @example
|
|
6027
|
+
* Compute the minimum hash length needed for field reduction.
|
|
6028
|
+
*
|
|
6029
|
+
* ```ts
|
|
6030
|
+
* getMinHashLength(255n);
|
|
6031
|
+
* ```
|
|
5601
6032
|
*/
|
|
5602
6033
|
function getMinHashLength(fieldOrder) {
|
|
5603
6034
|
const length = getFieldBytesLength(fieldOrder);
|
|
@@ -5607,21 +6038,31 @@ function getMinHashLength(fieldOrder) {
|
|
|
5607
6038
|
* "Constant-time" private key generation utility.
|
|
5608
6039
|
* Can take (n + n/2) or more bytes of uniform input e.g. from CSPRNG or KDF
|
|
5609
6040
|
* and convert them into private scalar, with the modulo bias being negligible.
|
|
5610
|
-
* Needs at least 48 bytes of input for 32-byte private key.
|
|
5611
|
-
*
|
|
5612
|
-
*
|
|
5613
|
-
*
|
|
5614
|
-
* @
|
|
5615
|
-
* @
|
|
5616
|
-
*
|
|
6041
|
+
* Needs at least 48 bytes of input for 32-byte private key. The implementation also keeps a hard
|
|
6042
|
+
* 16-byte minimum even when `getMinHashLength(...)` is smaller, so toy-small inputs do not look
|
|
6043
|
+
* accidentally acceptable for real scalar derivation.
|
|
6044
|
+
* See {@link https://research.kudelskisecurity.com/2020/07/28/the-definitive-guide-to-modulo-bias-and-how-to-avoid-it/ | Kudelski's modulo-bias guide},
|
|
6045
|
+
* {@link https://csrc.nist.gov/publications/detail/fips/186/5/final | FIPS 186-5 appendix A.2}, and
|
|
6046
|
+
* {@link https://www.rfc-editor.org/rfc/rfc9380#section-5 | RFC 9380 section 5}. Unlike RFC 9380
|
|
6047
|
+
* `hash_to_field`, this helper intentionally maps into the non-zero private-scalar range `1..n-1`.
|
|
6048
|
+
* @param key - Uniform input bytes.
|
|
6049
|
+
* @param fieldOrder - Size of subgroup.
|
|
6050
|
+
* @param isLE - interpret hash bytes as LE num
|
|
5617
6051
|
* @returns valid private scalar
|
|
6052
|
+
* @throws If the hash length or field order is invalid for scalar reduction. {@link Error}
|
|
6053
|
+
* @example
|
|
6054
|
+
* Map hash output into a private scalar range.
|
|
6055
|
+
*
|
|
6056
|
+
* ```ts
|
|
6057
|
+
* mapHashToField(new Uint8Array(48).fill(1), 255n);
|
|
6058
|
+
* ```
|
|
5618
6059
|
*/
|
|
5619
6060
|
function mapHashToField(key, fieldOrder, isLE = false) {
|
|
5620
6061
|
abytes(key);
|
|
5621
6062
|
const len = key.length;
|
|
5622
6063
|
const fieldLen = getFieldBytesLength(fieldOrder);
|
|
5623
|
-
const minLen = getMinHashLength(fieldOrder);
|
|
5624
|
-
if (len <
|
|
6064
|
+
const minLen = Math.max(getMinHashLength(fieldOrder), 16);
|
|
6065
|
+
if (len < minLen || len > 1024) throw new Error("expected " + minLen + "-1024 bytes of input, got " + len);
|
|
5625
6066
|
const reduced = mod(isLE ? bytesToNumberLE(key) : bytesToNumberBE(key), fieldOrder - _1n$4) + _1n$4;
|
|
5626
6067
|
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
|
5627
6068
|
}
|
|
@@ -5636,6 +6077,55 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
|
5636
6077
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5637
6078
|
const _0n$3 = /* @__PURE__ */ BigInt(0);
|
|
5638
6079
|
const _1n$3 = /* @__PURE__ */ BigInt(1);
|
|
6080
|
+
/**
|
|
6081
|
+
* Validates the static surface of a point constructor.
|
|
6082
|
+
* This is only a cheap sanity check for the constructor hooks and fields consumed by generic
|
|
6083
|
+
* factories; it does not certify `BASE`/`ZERO` semantics or prove the curve implementation itself.
|
|
6084
|
+
* @param Point - Runtime point constructor.
|
|
6085
|
+
* @throws On missing constructor hooks or malformed field metadata. {@link TypeError}
|
|
6086
|
+
* @example
|
|
6087
|
+
* Check that one point constructor exposes the static hooks generic helpers need.
|
|
6088
|
+
*
|
|
6089
|
+
* ```ts
|
|
6090
|
+
* import { ed25519 } from '@noble/curves/ed25519.js';
|
|
6091
|
+
* import { validatePointCons } from '@noble/curves/abstract/curve.js';
|
|
6092
|
+
* validatePointCons(ed25519.Point);
|
|
6093
|
+
* ```
|
|
6094
|
+
*/
|
|
6095
|
+
function validatePointCons(Point) {
|
|
6096
|
+
const pc = Point;
|
|
6097
|
+
if (typeof pc !== "function") throw new TypeError("Point must be a constructor");
|
|
6098
|
+
validateObject({
|
|
6099
|
+
Fp: pc.Fp,
|
|
6100
|
+
Fn: pc.Fn,
|
|
6101
|
+
fromAffine: pc.fromAffine,
|
|
6102
|
+
fromBytes: pc.fromBytes,
|
|
6103
|
+
fromHex: pc.fromHex
|
|
6104
|
+
}, {
|
|
6105
|
+
Fp: "object",
|
|
6106
|
+
Fn: "object",
|
|
6107
|
+
fromAffine: "function",
|
|
6108
|
+
fromBytes: "function",
|
|
6109
|
+
fromHex: "function"
|
|
6110
|
+
});
|
|
6111
|
+
validateField(pc.Fp);
|
|
6112
|
+
validateField(pc.Fn);
|
|
6113
|
+
}
|
|
6114
|
+
/**
|
|
6115
|
+
* Computes both candidates first, but the final selection still branches on `condition`, so this
|
|
6116
|
+
* is not a strict constant-time CMOV primitive.
|
|
6117
|
+
* @param condition - Whether to negate the point.
|
|
6118
|
+
* @param item - Point-like value.
|
|
6119
|
+
* @returns Original or negated value.
|
|
6120
|
+
* @example
|
|
6121
|
+
* Keep the point or return its negation based on one boolean branch.
|
|
6122
|
+
*
|
|
6123
|
+
* ```ts
|
|
6124
|
+
* import { negateCt } from '@noble/curves/abstract/curve.js';
|
|
6125
|
+
* import { p256 } from '@noble/curves/nist.js';
|
|
6126
|
+
* const maybeNegated = negateCt(true, p256.Point.BASE);
|
|
6127
|
+
* ```
|
|
6128
|
+
*/
|
|
5639
6129
|
function negateCt(condition, item) {
|
|
5640
6130
|
const neg = item.negate();
|
|
5641
6131
|
return condition ? neg : item;
|
|
@@ -5645,6 +6135,18 @@ function negateCt(condition, item) {
|
|
|
5645
6135
|
* inversion on all of them. Inversion is very slow operation,
|
|
5646
6136
|
* so this improves performance massively.
|
|
5647
6137
|
* Optimization: converts a list of projective points to a list of identical points with Z=1.
|
|
6138
|
+
* Input points are left unchanged; the normalized points are returned as fresh instances.
|
|
6139
|
+
* @param c - Point constructor.
|
|
6140
|
+
* @param points - Projective points.
|
|
6141
|
+
* @returns Fresh projective points reconstructed from normalized affine coordinates.
|
|
6142
|
+
* @example
|
|
6143
|
+
* Batch-normalize projective points with a single shared inversion.
|
|
6144
|
+
*
|
|
6145
|
+
* ```ts
|
|
6146
|
+
* import { normalizeZ } from '@noble/curves/abstract/curve.js';
|
|
6147
|
+
* import { p256 } from '@noble/curves/nist.js';
|
|
6148
|
+
* const points = normalizeZ(p256.Point, [p256.Point.BASE, p256.Point.BASE.double()]);
|
|
6149
|
+
* ```
|
|
5648
6150
|
*/
|
|
5649
6151
|
function normalizeZ(c, points) {
|
|
5650
6152
|
const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
|
|
@@ -5723,8 +6225,18 @@ function assert0(n) {
|
|
|
5723
6225
|
* - +1 window is neccessary for wNAF
|
|
5724
6226
|
* - wNAF reduces table size: 2x less memory + 2x faster generation, but 10% slower multiplication
|
|
5725
6227
|
*
|
|
5726
|
-
*
|
|
5727
|
-
* This would allow windows to be in different memory locations
|
|
6228
|
+
* TODO: research returning a 2d JS array of windows instead of a single window.
|
|
6229
|
+
* This would allow windows to be in different memory locations.
|
|
6230
|
+
* @param Point - Point constructor.
|
|
6231
|
+
* @param bits - Scalar bit length.
|
|
6232
|
+
* @example
|
|
6233
|
+
* Elliptic curve multiplication of Point by scalar.
|
|
6234
|
+
*
|
|
6235
|
+
* ```ts
|
|
6236
|
+
* import { wNAF } from '@noble/curves/abstract/curve.js';
|
|
6237
|
+
* import { p256 } from '@noble/curves/nist.js';
|
|
6238
|
+
* const ladder = new wNAF(p256.Point, p256.Point.Fn.BITS);
|
|
6239
|
+
* ```
|
|
5728
6240
|
*/
|
|
5729
6241
|
var wNAF = class {
|
|
5730
6242
|
BASE;
|
|
@@ -5754,8 +6266,8 @@ var wNAF = class {
|
|
|
5754
6266
|
* - 𝑊 is the window size
|
|
5755
6267
|
* - 𝑛 is the bitlength of the curve order.
|
|
5756
6268
|
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
5757
|
-
* @param point Point instance
|
|
5758
|
-
* @param W window size
|
|
6269
|
+
* @param point - Point instance
|
|
6270
|
+
* @param W - window size
|
|
5759
6271
|
* @returns precomputed point tables flattened to a single array
|
|
5760
6272
|
*/
|
|
5761
6273
|
precomputeWindow(point, W) {
|
|
@@ -5798,8 +6310,9 @@ var wNAF = class {
|
|
|
5798
6310
|
};
|
|
5799
6311
|
}
|
|
5800
6312
|
/**
|
|
5801
|
-
* Implements
|
|
5802
|
-
*
|
|
6313
|
+
* Implements unsafe EC multiplication using precomputed tables
|
|
6314
|
+
* and w-ary non-adjacent form.
|
|
6315
|
+
* @param acc - accumulator point to add result of multiplication
|
|
5803
6316
|
* @returns point
|
|
5804
6317
|
*/
|
|
5805
6318
|
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
@@ -5851,10 +6364,19 @@ var wNAF = class {
|
|
|
5851
6364
|
* 30x faster vs naive addition on L=4096, 10x faster than precomputes.
|
|
5852
6365
|
* For N=254bit, L=1, it does: 1024 ADD + 254 DBL. For L=5: 1536 ADD + 254 DBL.
|
|
5853
6366
|
* Algorithmically constant-time (for same L), even when 1 point + scalar, or when scalar = 0.
|
|
5854
|
-
* @param c Curve Point constructor
|
|
5855
|
-
* @param
|
|
5856
|
-
* @param
|
|
5857
|
-
* @
|
|
6367
|
+
* @param c - Curve Point constructor
|
|
6368
|
+
* @param points - array of L curve points
|
|
6369
|
+
* @param scalars - array of L scalars (aka secret keys / bigints)
|
|
6370
|
+
* @returns MSM result point. Empty input is accepted and returns the identity.
|
|
6371
|
+
* @throws If the point set, scalar set, or MSM sizing is invalid. {@link Error}
|
|
6372
|
+
* @example
|
|
6373
|
+
* Pippenger algorithm for multi-scalar multiplication (MSM, Pa + Qb + Rc + ...).
|
|
6374
|
+
*
|
|
6375
|
+
* ```ts
|
|
6376
|
+
* import { pippenger } from '@noble/curves/abstract/curve.js';
|
|
6377
|
+
* import { p256 } from '@noble/curves/nist.js';
|
|
6378
|
+
* const point = pippenger(p256.Point, [p256.Point.BASE, p256.Point.BASE.double()], [2n, 3n]);
|
|
6379
|
+
* ```
|
|
5858
6380
|
*/
|
|
5859
6381
|
function pippenger(c, points, scalars) {
|
|
5860
6382
|
const fieldN = c.Fn;
|
|
@@ -5897,7 +6419,33 @@ function createField(order, field, isLE) {
|
|
|
5897
6419
|
return field;
|
|
5898
6420
|
} else return Field(order, { isLE });
|
|
5899
6421
|
}
|
|
5900
|
-
/**
|
|
6422
|
+
/**
|
|
6423
|
+
* Validates basic CURVE shape and field membership, then creates fields.
|
|
6424
|
+
* This does not prove that the generator is on-curve, that subgroup/order data are consistent, or
|
|
6425
|
+
* that the curve equation itself is otherwise sane.
|
|
6426
|
+
* @param type - Curve family.
|
|
6427
|
+
* @param CURVE - Curve parameters.
|
|
6428
|
+
* @param curveOpts - Optional field overrides:
|
|
6429
|
+
* - `Fp` (optional): Optional base-field override.
|
|
6430
|
+
* - `Fn` (optional): Optional scalar-field override.
|
|
6431
|
+
* @param FpFnLE - Whether field encoding is little-endian.
|
|
6432
|
+
* @returns Frozen curve parameters and fields.
|
|
6433
|
+
* @throws If the curve parameters or field overrides are invalid. {@link Error}
|
|
6434
|
+
* @example
|
|
6435
|
+
* Build curve fields from raw constants before constructing a curve instance.
|
|
6436
|
+
*
|
|
6437
|
+
* ```ts
|
|
6438
|
+
* const curve = createCurveFields('weierstrass', {
|
|
6439
|
+
* p: 17n,
|
|
6440
|
+
* n: 19n,
|
|
6441
|
+
* h: 1n,
|
|
6442
|
+
* a: 2n,
|
|
6443
|
+
* b: 2n,
|
|
6444
|
+
* Gx: 5n,
|
|
6445
|
+
* Gy: 1n,
|
|
6446
|
+
* });
|
|
6447
|
+
* ```
|
|
6448
|
+
*/
|
|
5901
6449
|
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
5902
6450
|
if (FpFnLE === void 0) FpFnLE = type === "edwards";
|
|
5903
6451
|
if (!CURVE || typeof CURVE !== "object") throw new Error(`expected valid ${type} CURVE object`);
|
|
@@ -5925,6 +6473,20 @@ function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
|
5925
6473
|
Fn
|
|
5926
6474
|
};
|
|
5927
6475
|
}
|
|
6476
|
+
/**
|
|
6477
|
+
* @param randomSecretKey - Secret-key generator.
|
|
6478
|
+
* @param getPublicKey - Public-key derivation helper.
|
|
6479
|
+
* @returns Keypair generator.
|
|
6480
|
+
* @example
|
|
6481
|
+
* Build a `keygen()` helper from existing secret-key and public-key primitives.
|
|
6482
|
+
*
|
|
6483
|
+
* ```ts
|
|
6484
|
+
* import { createKeygen } from '@noble/curves/abstract/curve.js';
|
|
6485
|
+
* import { p256 } from '@noble/curves/nist.js';
|
|
6486
|
+
* const keygen = createKeygen(p256.utils.randomSecretKey, p256.getPublicKey);
|
|
6487
|
+
* const pair = keygen();
|
|
6488
|
+
* ```
|
|
6489
|
+
*/
|
|
5928
6490
|
function createKeygen(randomSecretKey, getPublicKey) {
|
|
5929
6491
|
return function keygen(seed) {
|
|
5930
6492
|
const secretKey = randomSecretKey(seed);
|
|
@@ -5944,7 +6506,7 @@ function createKeygen(randomSecretKey, getPublicKey) {
|
|
|
5944
6506
|
* @module
|
|
5945
6507
|
*/
|
|
5946
6508
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
5947
|
-
const _0n$2 = BigInt(0), _1n$2 = BigInt(1), _2n$2 = BigInt(2), _8n$1 = BigInt(8);
|
|
6509
|
+
const _0n$2 = /* @__PURE__ */ BigInt(0), _1n$2 = /* @__PURE__ */ BigInt(1), _2n$2 = /* @__PURE__ */ BigInt(2), _8n$1 = /* @__PURE__ */ BigInt(8);
|
|
5948
6510
|
function isEdValidXY(Fp, CURVE, x, y) {
|
|
5949
6511
|
const x2 = Fp.sqr(x);
|
|
5950
6512
|
const y2 = Fp.sqr(y);
|
|
@@ -5952,15 +6514,37 @@ function isEdValidXY(Fp, CURVE, x, y) {
|
|
|
5952
6514
|
const right = Fp.add(Fp.ONE, Fp.mul(CURVE.d, Fp.mul(x2, y2)));
|
|
5953
6515
|
return Fp.eql(left, right);
|
|
5954
6516
|
}
|
|
6517
|
+
/**
|
|
6518
|
+
* @param params - Curve parameters. See {@link EdwardsOpts}.
|
|
6519
|
+
* @param extraOpts - Optional helpers and overrides. See {@link EdwardsExtraOpts}.
|
|
6520
|
+
* @returns Edwards point constructor. Generator validation here only checks
|
|
6521
|
+
* that `(Gx, Gy)` satisfies the affine Edwards equation.
|
|
6522
|
+
* RFC 8032 base-point constraints like `B != (0,1)` and `[L]B = 0`
|
|
6523
|
+
* are left to the caller's chosen parameters, since eager subgroup
|
|
6524
|
+
* validation here adds about 10-15ms to heavyweight imports like ed448.
|
|
6525
|
+
* The returned constructor also eagerly marks `Point.BASE` for W=8
|
|
6526
|
+
* precompute caching. Some code paths still assume
|
|
6527
|
+
* `Fp.BYTES === Fn.BYTES`, so mismatched byte lengths are not fully audited here.
|
|
6528
|
+
* @throws If the curve parameters or Edwards overrides are invalid. {@link Error}
|
|
6529
|
+
* @example
|
|
6530
|
+
* ```ts
|
|
6531
|
+
* import { edwards } from '@noble/curves/abstract/edwards.js';
|
|
6532
|
+
* import { jubjub } from '@noble/curves/misc.js';
|
|
6533
|
+
* // Build a point constructor from explicit curve parameters, then use its base point.
|
|
6534
|
+
* const Point = edwards(jubjub.Point.CURVE());
|
|
6535
|
+
* Point.BASE.toHex();
|
|
6536
|
+
* ```
|
|
6537
|
+
*/
|
|
5955
6538
|
function edwards(params, extraOpts = {}) {
|
|
5956
|
-
const
|
|
6539
|
+
const opts = extraOpts;
|
|
6540
|
+
const validated = createCurveFields("edwards", params, opts, opts.FpFnLE);
|
|
5957
6541
|
const { Fp, Fn } = validated;
|
|
5958
6542
|
let CURVE = validated.CURVE;
|
|
5959
6543
|
const { h: cofactor } = CURVE;
|
|
5960
|
-
validateObject(
|
|
6544
|
+
validateObject(opts, {}, { uvRatio: "function" });
|
|
5961
6545
|
const MASK = _2n$2 << BigInt(Fn.BYTES * 8) - _1n$2;
|
|
5962
6546
|
const modP = (n) => Fp.create(n);
|
|
5963
|
-
const uvRatio =
|
|
6547
|
+
const uvRatio = opts.uvRatio === void 0 ? (u, v) => {
|
|
5964
6548
|
try {
|
|
5965
6549
|
return {
|
|
5966
6550
|
isValid: true,
|
|
@@ -5972,7 +6556,7 @@ function edwards(params, extraOpts = {}) {
|
|
|
5972
6556
|
value: _0n$2
|
|
5973
6557
|
};
|
|
5974
6558
|
}
|
|
5975
|
-
}
|
|
6559
|
+
} : opts.uvRatio;
|
|
5976
6560
|
if (!isEdValidXY(Fp, CURVE, CURVE.Gx, CURVE.Gy)) throw new Error("bad curve params: generator point");
|
|
5977
6561
|
/**
|
|
5978
6562
|
* Asserts coordinate is valid: 0 <= n < MASK.
|
|
@@ -5986,35 +6570,6 @@ function edwards(params, extraOpts = {}) {
|
|
|
5986
6570
|
function aedpoint(other) {
|
|
5987
6571
|
if (!(other instanceof Point)) throw new Error("EdwardsPoint expected");
|
|
5988
6572
|
}
|
|
5989
|
-
const toAffineMemo = memoized((p, iz) => {
|
|
5990
|
-
const { X, Y, Z } = p;
|
|
5991
|
-
const is0 = p.is0();
|
|
5992
|
-
if (iz == null) iz = is0 ? _8n$1 : Fp.inv(Z);
|
|
5993
|
-
const x = modP(X * iz);
|
|
5994
|
-
const y = modP(Y * iz);
|
|
5995
|
-
const zz = Fp.mul(Z, iz);
|
|
5996
|
-
if (is0) return {
|
|
5997
|
-
x: _0n$2,
|
|
5998
|
-
y: _1n$2
|
|
5999
|
-
};
|
|
6000
|
-
if (zz !== _1n$2) throw new Error("invZ was invalid");
|
|
6001
|
-
return {
|
|
6002
|
-
x,
|
|
6003
|
-
y
|
|
6004
|
-
};
|
|
6005
|
-
});
|
|
6006
|
-
const assertValidMemo = memoized((p) => {
|
|
6007
|
-
const { a, d } = CURVE;
|
|
6008
|
-
if (p.is0()) throw new Error("bad point: ZERO");
|
|
6009
|
-
const { X, Y, Z, T } = p;
|
|
6010
|
-
const X2 = modP(X * X);
|
|
6011
|
-
const Y2 = modP(Y * Y);
|
|
6012
|
-
const Z2 = modP(Z * Z);
|
|
6013
|
-
const Z4 = modP(Z2 * Z2);
|
|
6014
|
-
if (modP(Z2 * modP(modP(X2 * a) + Y2)) !== modP(Z4 + modP(d * modP(X2 * Y2)))) throw new Error("bad point: equation left != right (1)");
|
|
6015
|
-
if (modP(X * Y) !== modP(Z * T)) throw new Error("bad point: equation left != right (2)");
|
|
6016
|
-
return true;
|
|
6017
|
-
});
|
|
6018
6573
|
class Point {
|
|
6019
6574
|
static BASE = new Point(CURVE.Gx, CURVE.Gy, _1n$2, modP(CURVE.Gx * CURVE.Gy));
|
|
6020
6575
|
static ZERO = new Point(_0n$2, _1n$2, _1n$2, _0n$2);
|
|
@@ -6034,6 +6589,11 @@ function edwards(params, extraOpts = {}) {
|
|
|
6034
6589
|
static CURVE() {
|
|
6035
6590
|
return CURVE;
|
|
6036
6591
|
}
|
|
6592
|
+
/**
|
|
6593
|
+
* Create one extended Edwards point from affine coordinates.
|
|
6594
|
+
* Does NOT validate that the point is on-curve or torsion-free.
|
|
6595
|
+
* Use `.assertValidity()` on adversarial inputs.
|
|
6596
|
+
*/
|
|
6037
6597
|
static fromAffine(p) {
|
|
6038
6598
|
if (p instanceof Point) throw new Error("extended point not allowed");
|
|
6039
6599
|
const { x, y } = p || {};
|
|
@@ -6078,7 +6638,16 @@ function edwards(params, extraOpts = {}) {
|
|
|
6078
6638
|
return this;
|
|
6079
6639
|
}
|
|
6080
6640
|
assertValidity() {
|
|
6081
|
-
|
|
6641
|
+
const p = this;
|
|
6642
|
+
const { a, d } = CURVE;
|
|
6643
|
+
if (p.is0()) throw new Error("bad point: ZERO");
|
|
6644
|
+
const { X, Y, Z, T } = p;
|
|
6645
|
+
const X2 = modP(X * X);
|
|
6646
|
+
const Y2 = modP(Y * Y);
|
|
6647
|
+
const Z2 = modP(Z * Z);
|
|
6648
|
+
const Z4 = modP(Z2 * Z2);
|
|
6649
|
+
if (modP(Z2 * modP(modP(X2 * a) + Y2)) !== modP(Z4 + modP(d * modP(X2 * Y2)))) throw new Error("bad point: equation left != right (1)");
|
|
6650
|
+
if (modP(X * Y) !== modP(Z * T)) throw new Error("bad point: equation left != right (2)");
|
|
6082
6651
|
}
|
|
6083
6652
|
equals(other) {
|
|
6084
6653
|
aedpoint(other);
|
|
@@ -6132,27 +6701,44 @@ function edwards(params, extraOpts = {}) {
|
|
|
6132
6701
|
return new Point(X3, Y3, modP(F * G), T3);
|
|
6133
6702
|
}
|
|
6134
6703
|
subtract(other) {
|
|
6704
|
+
aedpoint(other);
|
|
6135
6705
|
return this.add(other.negate());
|
|
6136
6706
|
}
|
|
6137
6707
|
multiply(scalar) {
|
|
6138
|
-
if (!Fn.isValidNot0(scalar)) throw new
|
|
6708
|
+
if (!Fn.isValidNot0(scalar)) throw new RangeError("invalid scalar: expected 1 <= sc < curve.n");
|
|
6139
6709
|
const { p, f } = wnaf.cached(this, scalar, (p) => normalizeZ(Point, p));
|
|
6140
6710
|
return normalizeZ(Point, [p, f])[0];
|
|
6141
6711
|
}
|
|
6142
|
-
multiplyUnsafe(scalar
|
|
6143
|
-
if (!Fn.isValid(scalar)) throw new
|
|
6712
|
+
multiplyUnsafe(scalar) {
|
|
6713
|
+
if (!Fn.isValid(scalar)) throw new RangeError("invalid scalar: expected 0 <= sc < curve.n");
|
|
6144
6714
|
if (scalar === _0n$2) return Point.ZERO;
|
|
6145
6715
|
if (this.is0() || scalar === _1n$2) return this;
|
|
6146
|
-
return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p)
|
|
6716
|
+
return wnaf.unsafe(this, scalar, (p) => normalizeZ(Point, p));
|
|
6147
6717
|
}
|
|
6148
6718
|
isSmallOrder() {
|
|
6149
|
-
return this.
|
|
6719
|
+
return this.clearCofactor().is0();
|
|
6150
6720
|
}
|
|
6151
6721
|
isTorsionFree() {
|
|
6152
6722
|
return wnaf.unsafe(this, CURVE.n).is0();
|
|
6153
6723
|
}
|
|
6154
6724
|
toAffine(invertedZ) {
|
|
6155
|
-
|
|
6725
|
+
const p = this;
|
|
6726
|
+
let iz = invertedZ;
|
|
6727
|
+
const { X, Y, Z } = p;
|
|
6728
|
+
const is0 = p.is0();
|
|
6729
|
+
if (iz == null) iz = is0 ? _8n$1 : Fp.inv(Z);
|
|
6730
|
+
const x = modP(X * iz);
|
|
6731
|
+
const y = modP(Y * iz);
|
|
6732
|
+
const zz = Fp.mul(Z, iz);
|
|
6733
|
+
if (is0) return {
|
|
6734
|
+
x: _0n$2,
|
|
6735
|
+
y: _1n$2
|
|
6736
|
+
};
|
|
6737
|
+
if (zz !== _1n$2) throw new Error("invZ was invalid");
|
|
6738
|
+
return {
|
|
6739
|
+
x,
|
|
6740
|
+
y
|
|
6741
|
+
};
|
|
6156
6742
|
}
|
|
6157
6743
|
clearCofactor() {
|
|
6158
6744
|
if (cofactor === _1n$2) return this;
|
|
@@ -6172,13 +6758,25 @@ function edwards(params, extraOpts = {}) {
|
|
|
6172
6758
|
}
|
|
6173
6759
|
}
|
|
6174
6760
|
const wnaf = new wNAF(Point, Fn.BITS);
|
|
6175
|
-
Point.BASE.precompute(8);
|
|
6761
|
+
if (Fn.BITS >= 8) Point.BASE.precompute(8);
|
|
6762
|
+
Object.freeze(Point.prototype);
|
|
6763
|
+
Object.freeze(Point);
|
|
6176
6764
|
return Point;
|
|
6177
6765
|
}
|
|
6178
6766
|
/**
|
|
6179
6767
|
* Base class for prime-order points like Ristretto255 and Decaf448.
|
|
6180
6768
|
* These points eliminate cofactor issues by representing equivalence classes
|
|
6181
|
-
* of Edwards curve points.
|
|
6769
|
+
* of Edwards curve points. Multiple Edwards representatives can describe the
|
|
6770
|
+
* same abstract wrapper element, so wrapper validity is not the same thing as
|
|
6771
|
+
* the hidden representative being torsion-free.
|
|
6772
|
+
* @param ep - Backing Edwards point.
|
|
6773
|
+
* @example
|
|
6774
|
+
* Base class for prime-order points like Ristretto255 and Decaf448.
|
|
6775
|
+
*
|
|
6776
|
+
* ```ts
|
|
6777
|
+
* import { ristretto255 } from '@noble/curves/ed25519.js';
|
|
6778
|
+
* const point = ristretto255.Point.BASE.multiply(2n);
|
|
6779
|
+
* ```
|
|
6182
6780
|
*/
|
|
6183
6781
|
var PrimeEdwardsPoint = class {
|
|
6184
6782
|
static BASE;
|
|
@@ -6186,6 +6784,11 @@ var PrimeEdwardsPoint = class {
|
|
|
6186
6784
|
static Fp;
|
|
6187
6785
|
static Fn;
|
|
6188
6786
|
ep;
|
|
6787
|
+
/**
|
|
6788
|
+
* Wrap one internal Edwards representative directly.
|
|
6789
|
+
* This is not a canonical encoding boundary: alternate Edwards
|
|
6790
|
+
* representatives may still describe the same abstract wrapper element.
|
|
6791
|
+
*/
|
|
6189
6792
|
constructor(ep) {
|
|
6190
6793
|
this.ep = ep;
|
|
6191
6794
|
}
|
|
@@ -6207,6 +6810,12 @@ var PrimeEdwardsPoint = class {
|
|
|
6207
6810
|
assertValidity() {
|
|
6208
6811
|
this.ep.assertValidity();
|
|
6209
6812
|
}
|
|
6813
|
+
/**
|
|
6814
|
+
* Return affine coordinates of the current internal Edwards representative.
|
|
6815
|
+
* This is a convenience helper, not a canonical Ristretto/Decaf encoding.
|
|
6816
|
+
* Equal abstract elements may expose different `x` / `y`; use
|
|
6817
|
+
* `toBytes()` / `fromBytes()` for canonical roundtrips.
|
|
6818
|
+
*/
|
|
6210
6819
|
toAffine(invertedZ) {
|
|
6211
6820
|
return this.ep.toAffine(invertedZ);
|
|
6212
6821
|
}
|
|
@@ -6243,37 +6852,65 @@ var PrimeEdwardsPoint = class {
|
|
|
6243
6852
|
return this.init(this.ep.negate());
|
|
6244
6853
|
}
|
|
6245
6854
|
precompute(windowSize, isLazy) {
|
|
6246
|
-
|
|
6855
|
+
this.ep.precompute(windowSize, isLazy);
|
|
6856
|
+
return this;
|
|
6247
6857
|
}
|
|
6248
6858
|
};
|
|
6249
6859
|
/**
|
|
6250
6860
|
* Initializes EdDSA signatures over given Edwards curve.
|
|
6861
|
+
* @param Point - Edwards point constructor.
|
|
6862
|
+
* @param cHash - Hash function.
|
|
6863
|
+
* @param eddsaOpts - Optional signature helpers. See {@link EdDSAOpts}.
|
|
6864
|
+
* @returns EdDSA helper namespace.
|
|
6865
|
+
* @throws If the hash function, options, or derived point operations are invalid. {@link Error}
|
|
6866
|
+
* @example
|
|
6867
|
+
* Initializes EdDSA signatures over given Edwards curve.
|
|
6868
|
+
*
|
|
6869
|
+
* ```ts
|
|
6870
|
+
* import { eddsa } from '@noble/curves/abstract/edwards.js';
|
|
6871
|
+
* import { jubjub } from '@noble/curves/misc.js';
|
|
6872
|
+
* import { sha512 } from '@noble/hashes/sha2.js';
|
|
6873
|
+
* const sigs = eddsa(jubjub.Point, sha512);
|
|
6874
|
+
* const { secretKey, publicKey } = sigs.keygen();
|
|
6875
|
+
* const msg = new TextEncoder().encode('hello noble');
|
|
6876
|
+
* const sig = sigs.sign(msg, secretKey);
|
|
6877
|
+
* const isValid = sigs.verify(sig, msg, publicKey);
|
|
6878
|
+
* ```
|
|
6251
6879
|
*/
|
|
6252
6880
|
function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
6253
6881
|
if (typeof cHash !== "function") throw new Error("\"hash\" function param is required");
|
|
6254
|
-
|
|
6882
|
+
const hash = cHash;
|
|
6883
|
+
const opts = eddsaOpts;
|
|
6884
|
+
validateObject(opts, {}, {
|
|
6255
6885
|
adjustScalarBytes: "function",
|
|
6256
6886
|
randomBytes: "function",
|
|
6257
6887
|
domain: "function",
|
|
6258
6888
|
prehash: "function",
|
|
6889
|
+
zip215: "boolean",
|
|
6259
6890
|
mapToCurve: "function"
|
|
6260
6891
|
});
|
|
6261
|
-
const { prehash } =
|
|
6892
|
+
const { prehash } = opts;
|
|
6262
6893
|
const { BASE, Fp, Fn } = Point;
|
|
6263
|
-
const
|
|
6264
|
-
const
|
|
6265
|
-
|
|
6894
|
+
const outputLen = hash.outputLen;
|
|
6895
|
+
const expectedLen = 2 * Fp.BYTES;
|
|
6896
|
+
if (outputLen !== void 0) {
|
|
6897
|
+
asafenumber(outputLen, "hash.outputLen");
|
|
6898
|
+
if (outputLen !== expectedLen) throw new Error(`hash.outputLen must be ${expectedLen}, got ${outputLen}`);
|
|
6899
|
+
}
|
|
6900
|
+
const randomBytes$2 = opts.randomBytes === void 0 ? randomBytes : opts.randomBytes;
|
|
6901
|
+
const adjustScalarBytes = opts.adjustScalarBytes === void 0 ? (bytes) => bytes : opts.adjustScalarBytes;
|
|
6902
|
+
const domain = opts.domain === void 0 ? (data, ctx, phflag) => {
|
|
6266
6903
|
abool(phflag, "phflag");
|
|
6267
6904
|
if (ctx.length || phflag) throw new Error("Contexts/pre-hash are not supported");
|
|
6268
6905
|
return data;
|
|
6269
|
-
}
|
|
6906
|
+
} : opts.domain;
|
|
6270
6907
|
function modN_LE(hash) {
|
|
6271
6908
|
return Fn.create(bytesToNumberLE(hash));
|
|
6272
6909
|
}
|
|
6273
6910
|
function getPrivateScalar(key) {
|
|
6274
6911
|
const len = lengths.secretKey;
|
|
6275
6912
|
abytes(key, lengths.secretKey, "secretKey");
|
|
6276
|
-
const hashed = abytes(
|
|
6913
|
+
const hashed = abytes(hash(key), 2 * len, "hashedSecretKey");
|
|
6277
6914
|
const head = adjustScalarBytes(hashed.slice(0, len));
|
|
6278
6915
|
return {
|
|
6279
6916
|
head,
|
|
@@ -6281,7 +6918,9 @@ function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
|
6281
6918
|
scalar: modN_LE(head)
|
|
6282
6919
|
};
|
|
6283
6920
|
}
|
|
6284
|
-
/** Convenience method that creates public key from scalar. RFC8032 5.1.5
|
|
6921
|
+
/** Convenience method that creates public key from scalar. RFC8032 5.1.5
|
|
6922
|
+
* Also exposes the derived scalar/prefix tuple and point form reused by sign().
|
|
6923
|
+
*/
|
|
6285
6924
|
function getExtendedPublicKey(secretKey) {
|
|
6286
6925
|
const { head, prefix, scalar } = getPrivateScalar(secretKey);
|
|
6287
6926
|
const point = BASE.multiply(scalar);
|
|
@@ -6298,7 +6937,7 @@ function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
|
6298
6937
|
return getExtendedPublicKey(secretKey).pointBytes;
|
|
6299
6938
|
}
|
|
6300
6939
|
function hashDomainToScalar(context = Uint8Array.of(), ...msgs) {
|
|
6301
|
-
return modN_LE(
|
|
6940
|
+
return modN_LE(hash(domain(concatBytes(...msgs), abytes(context, void 0, "context"), !!prehash)));
|
|
6302
6941
|
}
|
|
6303
6942
|
/** Signs message with secret key. RFC8032 5.1.6 */
|
|
6304
6943
|
function sign(msg, secretKey, options = {}) {
|
|
@@ -6312,13 +6951,14 @@ function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
|
6312
6951
|
if (!Fn.isValid(s)) throw new Error("sign failed: invalid s");
|
|
6313
6952
|
return abytes(concatBytes(R, Fn.toBytes(s)), lengths.signature, "result");
|
|
6314
6953
|
}
|
|
6315
|
-
const verifyOpts = { zip215:
|
|
6954
|
+
const verifyOpts = { zip215: opts.zip215 };
|
|
6316
6955
|
/**
|
|
6317
|
-
* Verifies EdDSA signature against message and public key.
|
|
6318
|
-
*
|
|
6956
|
+
* Verifies EdDSA signature against message and public key. RFC 8032 §§5.1.7 and 5.2.7.
|
|
6957
|
+
* A cofactored verification equation is checked.
|
|
6319
6958
|
*/
|
|
6320
6959
|
function verify(sig, msg, publicKey, options = verifyOpts) {
|
|
6321
|
-
const { context
|
|
6960
|
+
const { context } = options;
|
|
6961
|
+
const zip215 = options.zip215 === void 0 ? !!verifyOpts.zip215 : options.zip215;
|
|
6322
6962
|
const len = lengths.signature;
|
|
6323
6963
|
sig = abytes(sig, len, "signature");
|
|
6324
6964
|
msg = abytes(msg, void 0, "message");
|
|
@@ -6337,7 +6977,7 @@ function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
|
6337
6977
|
return false;
|
|
6338
6978
|
}
|
|
6339
6979
|
if (!zip215 && A.isSmallOrder()) return false;
|
|
6340
|
-
const k = hashDomainToScalar(context,
|
|
6980
|
+
const k = hashDomainToScalar(context, r, publicKey, msg);
|
|
6341
6981
|
return R.add(A.multiplyUnsafe(k)).subtract(SB).clearCofactor().is0();
|
|
6342
6982
|
}
|
|
6343
6983
|
const _size = Fp.BYTES;
|
|
@@ -6347,15 +6987,16 @@ function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
|
6347
6987
|
signature: 2 * _size,
|
|
6348
6988
|
seed: _size
|
|
6349
6989
|
};
|
|
6350
|
-
function randomSecretKey(seed
|
|
6990
|
+
function randomSecretKey(seed) {
|
|
6991
|
+
seed = seed === void 0 ? randomBytes$2(lengths.seed) : seed;
|
|
6351
6992
|
return abytes(seed, lengths.seed, "seed");
|
|
6352
6993
|
}
|
|
6353
6994
|
function isValidSecretKey(key) {
|
|
6354
|
-
return isBytes(key) && key.length ===
|
|
6995
|
+
return isBytes(key) && key.length === lengths.secretKey;
|
|
6355
6996
|
}
|
|
6356
6997
|
function isValidPublicKey(key, zip215) {
|
|
6357
6998
|
try {
|
|
6358
|
-
return !!Point.fromBytes(key, zip215);
|
|
6999
|
+
return !!Point.fromBytes(key, zip215 === void 0 ? verifyOpts.zip215 : zip215);
|
|
6359
7000
|
} catch (error) {
|
|
6360
7001
|
return false;
|
|
6361
7002
|
}
|
|
@@ -6373,21 +7014,224 @@ function eddsa(Point, cHash, eddsaOpts = {}) {
|
|
|
6373
7014
|
const u = is25519 ? Fp.div(_1n$2 + y, _1n$2 - y) : Fp.div(y - _1n$2, y + _1n$2);
|
|
6374
7015
|
return Fp.toBytes(u);
|
|
6375
7016
|
},
|
|
6376
|
-
toMontgomerySecret(secretKey) {
|
|
6377
|
-
const size = lengths.secretKey;
|
|
6378
|
-
abytes(secretKey, size);
|
|
6379
|
-
return adjustScalarBytes(
|
|
7017
|
+
toMontgomerySecret(secretKey) {
|
|
7018
|
+
const size = lengths.secretKey;
|
|
7019
|
+
abytes(secretKey, size);
|
|
7020
|
+
return adjustScalarBytes(hash(secretKey.subarray(0, size))).subarray(0, size);
|
|
7021
|
+
}
|
|
7022
|
+
};
|
|
7023
|
+
Object.freeze(lengths);
|
|
7024
|
+
Object.freeze(utils);
|
|
7025
|
+
return Object.freeze({
|
|
7026
|
+
keygen: createKeygen(randomSecretKey, getPublicKey),
|
|
7027
|
+
getPublicKey,
|
|
7028
|
+
sign,
|
|
7029
|
+
verify,
|
|
7030
|
+
utils,
|
|
7031
|
+
Point,
|
|
7032
|
+
lengths
|
|
7033
|
+
});
|
|
7034
|
+
}
|
|
7035
|
+
|
|
7036
|
+
//#endregion
|
|
7037
|
+
//#region node_modules/@noble/curves/abstract/fft.js
|
|
7038
|
+
function checkU32(n) {
|
|
7039
|
+
if (!Number.isSafeInteger(n) || n < 0 || n > 4294967295) throw new Error("wrong u32 integer:" + n);
|
|
7040
|
+
return n;
|
|
7041
|
+
}
|
|
7042
|
+
/**
|
|
7043
|
+
* @param n - Input value.
|
|
7044
|
+
* @returns Next power of two within the u32/array-length domain.
|
|
7045
|
+
* @throws If `n` is not a valid unsigned 32-bit integer. {@link Error}
|
|
7046
|
+
* @example
|
|
7047
|
+
* Round an integer up to the FFT size it needs.
|
|
7048
|
+
*
|
|
7049
|
+
* ```ts
|
|
7050
|
+
* nextPowerOfTwo(9);
|
|
7051
|
+
* ```
|
|
7052
|
+
*/
|
|
7053
|
+
function nextPowerOfTwo(n) {
|
|
7054
|
+
checkU32(n);
|
|
7055
|
+
if (n <= 1) return 1;
|
|
7056
|
+
if (n > 2147483648) throw new Error("nextPowerOfTwo overflow: result does not fit u32");
|
|
7057
|
+
return 1 << log2(n - 1) + 1 >>> 0;
|
|
7058
|
+
}
|
|
7059
|
+
/**
|
|
7060
|
+
* Similar to `bitLen(x)-1` but much faster for small integers, like indices.
|
|
7061
|
+
* @param n - Input value.
|
|
7062
|
+
* @returns Base-2 logarithm. For `n = 0`, the current implementation returns `-1`.
|
|
7063
|
+
* @throws If `n` is not a valid unsigned 32-bit integer. {@link Error}
|
|
7064
|
+
* @example
|
|
7065
|
+
* Compute the radix-2 stage count for one transform size.
|
|
7066
|
+
*
|
|
7067
|
+
* ```ts
|
|
7068
|
+
* log2(8);
|
|
7069
|
+
* ```
|
|
7070
|
+
*/
|
|
7071
|
+
function log2(n) {
|
|
7072
|
+
checkU32(n);
|
|
7073
|
+
return 31 - Math.clz32(n);
|
|
7074
|
+
}
|
|
7075
|
+
function poly(field, roots, create, fft, length) {
|
|
7076
|
+
const F = field;
|
|
7077
|
+
const _create = create || ((len, elm) => new Array(len).fill(elm ?? F.ZERO));
|
|
7078
|
+
const isPoly = (x) => {
|
|
7079
|
+
if (Array.isArray(x)) return true;
|
|
7080
|
+
if (!ArrayBuffer.isView(x)) return false;
|
|
7081
|
+
const v = x;
|
|
7082
|
+
return typeof v.length === "number" && typeof v.slice === "function" && typeof v[Symbol.iterator] === "function";
|
|
7083
|
+
};
|
|
7084
|
+
const checkLength = (...lst) => {
|
|
7085
|
+
if (!lst.length) return 0;
|
|
7086
|
+
for (const i of lst) if (!isPoly(i)) throw new Error("poly: not polynomial: " + i);
|
|
7087
|
+
const L = lst[0].length;
|
|
7088
|
+
for (let i = 1; i < lst.length; i++) if (lst[i].length !== L) throw new Error(`poly: mismatched lengths ${L} vs ${lst[i].length}`);
|
|
7089
|
+
if (length !== void 0 && L !== length) throw new Error(`poly: expected fixed length ${length}, got ${L}`);
|
|
7090
|
+
return L;
|
|
7091
|
+
};
|
|
7092
|
+
function findOmegaIndex(x, n, brp = false) {
|
|
7093
|
+
const bits = log2(n);
|
|
7094
|
+
const omega = brp ? roots.brp(bits) : roots.roots(bits);
|
|
7095
|
+
for (let i = 0; i < n; i++) if (F.eql(x, omega[i])) return i;
|
|
7096
|
+
return -1;
|
|
7097
|
+
}
|
|
7098
|
+
return {
|
|
7099
|
+
roots,
|
|
7100
|
+
create: _create,
|
|
7101
|
+
length,
|
|
7102
|
+
extend: (a, len) => {
|
|
7103
|
+
checkLength(a);
|
|
7104
|
+
const out = _create(len, F.ZERO);
|
|
7105
|
+
for (let i = 0; i < Math.min(a.length, len); i++) out[i] = a[i];
|
|
7106
|
+
return out;
|
|
7107
|
+
},
|
|
7108
|
+
degree: (a) => {
|
|
7109
|
+
checkLength(a);
|
|
7110
|
+
for (let i = a.length - 1; i >= 0; i--) if (!F.is0(a[i])) return i;
|
|
7111
|
+
return -1;
|
|
7112
|
+
},
|
|
7113
|
+
add: (a, b) => {
|
|
7114
|
+
const len = checkLength(a, b);
|
|
7115
|
+
const out = _create(len);
|
|
7116
|
+
for (let i = 0; i < len; i++) out[i] = F.add(a[i], b[i]);
|
|
7117
|
+
return out;
|
|
7118
|
+
},
|
|
7119
|
+
sub: (a, b) => {
|
|
7120
|
+
const len = checkLength(a, b);
|
|
7121
|
+
const out = _create(len);
|
|
7122
|
+
for (let i = 0; i < len; i++) out[i] = F.sub(a[i], b[i]);
|
|
7123
|
+
return out;
|
|
7124
|
+
},
|
|
7125
|
+
dot: (a, b) => {
|
|
7126
|
+
const len = checkLength(a, b);
|
|
7127
|
+
const out = _create(len);
|
|
7128
|
+
for (let i = 0; i < len; i++) out[i] = F.mul(a[i], b[i]);
|
|
7129
|
+
return out;
|
|
7130
|
+
},
|
|
7131
|
+
mul: (a, b) => {
|
|
7132
|
+
if (isPoly(b)) {
|
|
7133
|
+
const len = checkLength(a, b);
|
|
7134
|
+
if (fft) {
|
|
7135
|
+
const A = fft.direct(a, false, true);
|
|
7136
|
+
const B = fft.direct(b, false, true);
|
|
7137
|
+
for (let i = 0; i < A.length; i++) A[i] = F.mul(A[i], B[i]);
|
|
7138
|
+
return fft.inverse(A, true, false);
|
|
7139
|
+
} else {
|
|
7140
|
+
const res = _create(len);
|
|
7141
|
+
for (let i = 0; i < len; i++) for (let j = 0; j < len; j++) {
|
|
7142
|
+
const k = (i + j) % len;
|
|
7143
|
+
res[k] = F.add(res[k], F.mul(a[i], b[j]));
|
|
7144
|
+
}
|
|
7145
|
+
return res;
|
|
7146
|
+
}
|
|
7147
|
+
} else {
|
|
7148
|
+
const out = _create(checkLength(a));
|
|
7149
|
+
for (let i = 0; i < out.length; i++) out[i] = F.mul(a[i], b);
|
|
7150
|
+
return out;
|
|
7151
|
+
}
|
|
7152
|
+
},
|
|
7153
|
+
convolve(a, b) {
|
|
7154
|
+
const len = nextPowerOfTwo(a.length + b.length - 1);
|
|
7155
|
+
return this.mul(this.extend(a, len), this.extend(b, len));
|
|
7156
|
+
},
|
|
7157
|
+
shift(p, factor) {
|
|
7158
|
+
const out = _create(checkLength(p));
|
|
7159
|
+
out[0] = p[0];
|
|
7160
|
+
for (let i = 1, power = F.ONE; i < p.length; i++) {
|
|
7161
|
+
power = F.mul(power, factor);
|
|
7162
|
+
out[i] = F.mul(p[i], power);
|
|
7163
|
+
}
|
|
7164
|
+
return out;
|
|
7165
|
+
},
|
|
7166
|
+
clone: (a) => {
|
|
7167
|
+
checkLength(a);
|
|
7168
|
+
const out = _create(a.length);
|
|
7169
|
+
for (let i = 0; i < a.length; i++) out[i] = a[i];
|
|
7170
|
+
return out;
|
|
7171
|
+
},
|
|
7172
|
+
eval: (a, basis) => {
|
|
7173
|
+
checkLength(a, basis);
|
|
7174
|
+
let acc = F.ZERO;
|
|
7175
|
+
for (let i = 0; i < a.length; i++) acc = F.add(acc, F.mul(a[i], basis[i]));
|
|
7176
|
+
return acc;
|
|
7177
|
+
},
|
|
7178
|
+
monomial: {
|
|
7179
|
+
basis: (x, n) => {
|
|
7180
|
+
const out = _create(n);
|
|
7181
|
+
let pow = F.ONE;
|
|
7182
|
+
for (let i = 0; i < n; i++) {
|
|
7183
|
+
out[i] = pow;
|
|
7184
|
+
pow = F.mul(pow, x);
|
|
7185
|
+
}
|
|
7186
|
+
return out;
|
|
7187
|
+
},
|
|
7188
|
+
eval: (a, x) => {
|
|
7189
|
+
checkLength(a);
|
|
7190
|
+
let acc = F.ZERO;
|
|
7191
|
+
for (let i = a.length - 1; i >= 0; i--) acc = F.add(F.mul(acc, x), a[i]);
|
|
7192
|
+
return acc;
|
|
7193
|
+
}
|
|
7194
|
+
},
|
|
7195
|
+
lagrange: {
|
|
7196
|
+
basis: (x, n, brp = false, weights) => {
|
|
7197
|
+
const bits = log2(n);
|
|
7198
|
+
const cache = weights || (brp ? roots.brp(bits) : roots.roots(bits));
|
|
7199
|
+
const out = _create(n);
|
|
7200
|
+
const idx = findOmegaIndex(x, n, brp);
|
|
7201
|
+
if (idx !== -1) {
|
|
7202
|
+
out[idx] = F.ONE;
|
|
7203
|
+
return out;
|
|
7204
|
+
}
|
|
7205
|
+
const tm = F.pow(x, BigInt(n));
|
|
7206
|
+
const c = F.mul(F.sub(tm, F.ONE), F.inv(BigInt(n)));
|
|
7207
|
+
const denom = _create(n);
|
|
7208
|
+
for (let i = 0; i < n; i++) denom[i] = F.sub(x, cache[i]);
|
|
7209
|
+
const inv = F.invertBatch(denom);
|
|
7210
|
+
for (let i = 0; i < n; i++) out[i] = F.mul(c, F.mul(cache[i], inv[i]));
|
|
7211
|
+
return out;
|
|
7212
|
+
},
|
|
7213
|
+
eval(a, x, brp = false) {
|
|
7214
|
+
checkLength(a);
|
|
7215
|
+
const idx = findOmegaIndex(x, a.length, brp);
|
|
7216
|
+
if (idx !== -1) return a[idx];
|
|
7217
|
+
const L = this.basis(x, a.length, brp);
|
|
7218
|
+
let acc = F.ZERO;
|
|
7219
|
+
for (let i = 0; i < a.length; i++) if (!F.is0(a[i])) acc = F.add(acc, F.mul(a[i], L[i]));
|
|
7220
|
+
return acc;
|
|
7221
|
+
}
|
|
7222
|
+
},
|
|
7223
|
+
vanishing(roots) {
|
|
7224
|
+
checkLength(roots);
|
|
7225
|
+
const out = _create(roots.length + 1, F.ZERO);
|
|
7226
|
+
out[0] = F.ONE;
|
|
7227
|
+
for (const r of roots) {
|
|
7228
|
+
const neg = F.neg(r);
|
|
7229
|
+
for (let j = out.length - 1; j > 0; j--) out[j] = F.add(F.mul(out[j], neg), out[j - 1]);
|
|
7230
|
+
out[0] = F.mul(out[0], neg);
|
|
7231
|
+
}
|
|
7232
|
+
return out;
|
|
6380
7233
|
}
|
|
6381
7234
|
};
|
|
6382
|
-
return Object.freeze({
|
|
6383
|
-
keygen: createKeygen(randomSecretKey, getPublicKey),
|
|
6384
|
-
getPublicKey,
|
|
6385
|
-
sign,
|
|
6386
|
-
verify,
|
|
6387
|
-
utils,
|
|
6388
|
-
Point,
|
|
6389
|
-
lengths
|
|
6390
|
-
});
|
|
6391
7235
|
}
|
|
6392
7236
|
|
|
6393
7237
|
//#endregion
|
|
@@ -6396,7 +7240,8 @@ const os2ip = bytesToNumberBE;
|
|
|
6396
7240
|
function i2osp(value, length) {
|
|
6397
7241
|
asafenumber(value);
|
|
6398
7242
|
asafenumber(length);
|
|
6399
|
-
if (
|
|
7243
|
+
if (length < 0 || length > 4) throw new Error("invalid I2OSP length: " + length);
|
|
7244
|
+
if (value < 0 || value > 2 ** (8 * length) - 1) throw new Error("invalid I2OSP input: " + value);
|
|
6400
7245
|
const res = Array.from({ length }).fill(0);
|
|
6401
7246
|
for (let i = length - 1; i >= 0; i--) {
|
|
6402
7247
|
res[i] = value & 255;
|
|
@@ -6411,11 +7256,29 @@ function strxor(a, b) {
|
|
|
6411
7256
|
}
|
|
6412
7257
|
function normDST(DST) {
|
|
6413
7258
|
if (!isBytes(DST) && typeof DST !== "string") throw new Error("DST must be Uint8Array or ascii string");
|
|
6414
|
-
|
|
7259
|
+
const dst = typeof DST === "string" ? asciiToBytes(DST) : DST;
|
|
7260
|
+
if (dst.length === 0) throw new Error("DST must be non-empty");
|
|
7261
|
+
return dst;
|
|
6415
7262
|
}
|
|
6416
7263
|
/**
|
|
6417
|
-
* Produces a uniformly random byte string using a cryptographic hash
|
|
6418
|
-
*
|
|
7264
|
+
* Produces a uniformly random byte string using a cryptographic hash
|
|
7265
|
+
* function H that outputs b bits.
|
|
7266
|
+
* See {@link https://www.rfc-editor.org/rfc/rfc9380#section-5.3.1 | RFC 9380 section 5.3.1}.
|
|
7267
|
+
* @param msg - Input message.
|
|
7268
|
+
* @param DST - Domain separation tag. This helper normalizes DST, rejects empty DSTs, and
|
|
7269
|
+
* oversize-hashes DST when needed.
|
|
7270
|
+
* @param lenInBytes - Output length.
|
|
7271
|
+
* @param H - Hash function.
|
|
7272
|
+
* @returns Uniform byte string.
|
|
7273
|
+
* @throws If the message, DST, hash, or output length is invalid. {@link Error}
|
|
7274
|
+
* @example
|
|
7275
|
+
* Expand one message into uniform bytes with the XMD construction.
|
|
7276
|
+
*
|
|
7277
|
+
* ```ts
|
|
7278
|
+
* import { expand_message_xmd } from '@noble/curves/abstract/hash-to-curve.js';
|
|
7279
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
7280
|
+
* const uniform = expand_message_xmd(new TextEncoder().encode('hello noble'), 'DST', 32, sha256);
|
|
7281
|
+
* ```
|
|
6419
7282
|
*/
|
|
6420
7283
|
function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
6421
7284
|
abytes(msg);
|
|
@@ -6426,12 +7289,12 @@ function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
|
6426
7289
|
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
|
6427
7290
|
if (lenInBytes > 65535 || ell > 255) throw new Error("expand_message_xmd: invalid lenInBytes");
|
|
6428
7291
|
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
|
|
6429
|
-
const Z_pad =
|
|
7292
|
+
const Z_pad = new Uint8Array(r_in_bytes);
|
|
6430
7293
|
const l_i_b_str = i2osp(lenInBytes, 2);
|
|
6431
7294
|
const b = new Array(ell);
|
|
6432
7295
|
const b_0 = H(concatBytes(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
|
6433
7296
|
b[0] = H(concatBytes(b_0, i2osp(1, 1), DST_prime));
|
|
6434
|
-
for (let i = 1; i
|
|
7297
|
+
for (let i = 1; i < ell; i++) b[i] = H(concatBytes(...[
|
|
6435
7298
|
strxor(b_0, b[i - 1]),
|
|
6436
7299
|
i2osp(i + 1, 1),
|
|
6437
7300
|
DST_prime
|
|
@@ -6443,7 +7306,29 @@ function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
|
6443
7306
|
* 1. The collision resistance of H MUST be at least k bits.
|
|
6444
7307
|
* 2. H MUST be an XOF that has been proved indifferentiable from
|
|
6445
7308
|
* a random oracle under a reasonable cryptographic assumption.
|
|
6446
|
-
*
|
|
7309
|
+
* See {@link https://www.rfc-editor.org/rfc/rfc9380#section-5.3.2 | RFC 9380 section 5.3.2}.
|
|
7310
|
+
* @param msg - Input message.
|
|
7311
|
+
* @param DST - Domain separation tag. This helper normalizes DST, rejects empty DSTs, and
|
|
7312
|
+
* oversize-hashes DST when needed.
|
|
7313
|
+
* @param lenInBytes - Output length.
|
|
7314
|
+
* @param k - Target security level.
|
|
7315
|
+
* @param H - XOF hash function.
|
|
7316
|
+
* @returns Uniform byte string.
|
|
7317
|
+
* @throws If the message, DST, XOF, or output length is invalid. {@link Error}
|
|
7318
|
+
* @example
|
|
7319
|
+
* Expand one message into uniform bytes with the XOF construction.
|
|
7320
|
+
*
|
|
7321
|
+
* ```ts
|
|
7322
|
+
* import { expand_message_xof } from '@noble/curves/abstract/hash-to-curve.js';
|
|
7323
|
+
* import { shake256 } from '@noble/hashes/sha3.js';
|
|
7324
|
+
* const uniform = expand_message_xof(
|
|
7325
|
+
* new TextEncoder().encode('hello noble'),
|
|
7326
|
+
* 'DST',
|
|
7327
|
+
* 32,
|
|
7328
|
+
* 128,
|
|
7329
|
+
* shake256
|
|
7330
|
+
* );
|
|
7331
|
+
* ```
|
|
6447
7332
|
*/
|
|
6448
7333
|
function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
|
6449
7334
|
abytes(msg);
|
|
@@ -6458,11 +7343,27 @@ function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
|
|
6458
7343
|
}
|
|
6459
7344
|
/**
|
|
6460
7345
|
* Hashes arbitrary-length byte strings to a list of one or more elements of a finite field F.
|
|
6461
|
-
*
|
|
6462
|
-
* @param msg
|
|
6463
|
-
* @param count
|
|
6464
|
-
* @param options
|
|
6465
|
-
* @returns [u_0, ..., u_(count - 1)]
|
|
7346
|
+
* See {@link https://www.rfc-editor.org/rfc/rfc9380#section-5.2 | RFC 9380 section 5.2}.
|
|
7347
|
+
* @param msg - Input message bytes.
|
|
7348
|
+
* @param count - Number of field elements to derive. Must be `>= 1`.
|
|
7349
|
+
* @param options - RFC 9380 options. See {@link H2COpts}. `m` must be `>= 1`.
|
|
7350
|
+
* @returns `[u_0, ..., u_(count - 1)]`, a list of field elements.
|
|
7351
|
+
* @throws If the expander choice or RFC 9380 options are invalid. {@link Error}
|
|
7352
|
+
* @example
|
|
7353
|
+
* Hash one message into field elements before mapping it onto a curve.
|
|
7354
|
+
*
|
|
7355
|
+
* ```ts
|
|
7356
|
+
* import { hash_to_field } from '@noble/curves/abstract/hash-to-curve.js';
|
|
7357
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
7358
|
+
* const scalars = hash_to_field(new TextEncoder().encode('hello noble'), 2, {
|
|
7359
|
+
* DST: 'DST',
|
|
7360
|
+
* p: 17n,
|
|
7361
|
+
* m: 1,
|
|
7362
|
+
* k: 128,
|
|
7363
|
+
* expand: 'xmd',
|
|
7364
|
+
* hash: sha256,
|
|
7365
|
+
* });
|
|
7366
|
+
* ```
|
|
6466
7367
|
*/
|
|
6467
7368
|
function hash_to_field(msg, count, options) {
|
|
6468
7369
|
validateObject(options, {
|
|
@@ -6475,6 +7376,8 @@ function hash_to_field(msg, count, options) {
|
|
|
6475
7376
|
asafenumber(hash.outputLen, "valid hash");
|
|
6476
7377
|
abytes(msg);
|
|
6477
7378
|
asafenumber(count);
|
|
7379
|
+
if (count < 1) throw new Error("hash_to_field: expected count >= 1");
|
|
7380
|
+
if (m < 1) throw new Error("hash_to_field: expected m >= 1");
|
|
6478
7381
|
const log2p = p.toString(2).length;
|
|
6479
7382
|
const L = Math.ceil((log2p + k) / 8);
|
|
6480
7383
|
const len_in_bytes = count * m * L;
|
|
@@ -6494,10 +7397,42 @@ function hash_to_field(msg, count, options) {
|
|
|
6494
7397
|
}
|
|
6495
7398
|
return u;
|
|
6496
7399
|
}
|
|
6497
|
-
const _DST_scalar =
|
|
6498
|
-
/**
|
|
7400
|
+
const _DST_scalar = "HashToScalar-";
|
|
7401
|
+
/**
|
|
7402
|
+
* Creates hash-to-curve methods from EC Point and mapToCurve function. See {@link H2CHasher}.
|
|
7403
|
+
* @param Point - Point constructor.
|
|
7404
|
+
* @param mapToCurve - Map-to-curve function.
|
|
7405
|
+
* @param defaults - Default hash-to-curve options. This object is frozen in place and reused as
|
|
7406
|
+
* the shared defaults bundle for the returned helpers.
|
|
7407
|
+
* @returns Hash-to-curve helper namespace.
|
|
7408
|
+
* @throws If the map-to-curve callback or default hash-to-curve options are invalid. {@link Error}
|
|
7409
|
+
* @example
|
|
7410
|
+
* Bundle hash-to-curve, hash-to-scalar, and encode-to-curve helpers for one curve.
|
|
7411
|
+
*
|
|
7412
|
+
* ```ts
|
|
7413
|
+
* import { createHasher } from '@noble/curves/abstract/hash-to-curve.js';
|
|
7414
|
+
* import { p256 } from '@noble/curves/nist.js';
|
|
7415
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
7416
|
+
* const hasher = createHasher(p256.Point, () => p256.Point.BASE.toAffine(), {
|
|
7417
|
+
* DST: 'P256_XMD:SHA-256_SSWU_RO_',
|
|
7418
|
+
* encodeDST: 'P256_XMD:SHA-256_SSWU_NU_',
|
|
7419
|
+
* p: p256.Point.Fp.ORDER,
|
|
7420
|
+
* m: 1,
|
|
7421
|
+
* k: 128,
|
|
7422
|
+
* expand: 'xmd',
|
|
7423
|
+
* hash: sha256,
|
|
7424
|
+
* });
|
|
7425
|
+
* const point = hasher.encodeToCurve(new TextEncoder().encode('hello noble'));
|
|
7426
|
+
* ```
|
|
7427
|
+
*/
|
|
6499
7428
|
function createHasher(Point, mapToCurve, defaults) {
|
|
6500
7429
|
if (typeof mapToCurve !== "function") throw new Error("mapToCurve() must be defined");
|
|
7430
|
+
const snapshot = (src) => Object.freeze({
|
|
7431
|
+
...src,
|
|
7432
|
+
DST: isBytes(src.DST) ? copyBytes(src.DST) : src.DST,
|
|
7433
|
+
...src.encodeDST === void 0 ? {} : { encodeDST: isBytes(src.encodeDST) ? copyBytes(src.encodeDST) : src.encodeDST }
|
|
7434
|
+
});
|
|
7435
|
+
const safeDefaults = snapshot(defaults);
|
|
6501
7436
|
function map(num) {
|
|
6502
7437
|
return Point.fromAffine(mapToCurve(num));
|
|
6503
7438
|
}
|
|
@@ -6507,21 +7442,23 @@ function createHasher(Point, mapToCurve, defaults) {
|
|
|
6507
7442
|
P.assertValidity();
|
|
6508
7443
|
return P;
|
|
6509
7444
|
}
|
|
6510
|
-
return {
|
|
6511
|
-
defaults
|
|
7445
|
+
return Object.freeze({
|
|
7446
|
+
get defaults() {
|
|
7447
|
+
return snapshot(safeDefaults);
|
|
7448
|
+
},
|
|
6512
7449
|
Point,
|
|
6513
7450
|
hashToCurve(msg, options) {
|
|
6514
|
-
const u = hash_to_field(msg, 2, Object.assign({},
|
|
7451
|
+
const u = hash_to_field(msg, 2, Object.assign({}, safeDefaults, options));
|
|
6515
7452
|
const u0 = map(u[0]);
|
|
6516
7453
|
const u1 = map(u[1]);
|
|
6517
7454
|
return clear(u0.add(u1));
|
|
6518
7455
|
},
|
|
6519
7456
|
encodeToCurve(msg, options) {
|
|
6520
|
-
const optsDst =
|
|
6521
|
-
return clear(map(hash_to_field(msg, 1, Object.assign({},
|
|
7457
|
+
const optsDst = safeDefaults.encodeDST ? { DST: safeDefaults.encodeDST } : {};
|
|
7458
|
+
return clear(map(hash_to_field(msg, 1, Object.assign({}, safeDefaults, optsDst, options))[0]));
|
|
6522
7459
|
},
|
|
6523
7460
|
mapToCurve(scalars) {
|
|
6524
|
-
if (
|
|
7461
|
+
if (safeDefaults.m === 1) {
|
|
6525
7462
|
if (typeof scalars !== "bigint") throw new Error("expected bigint (m=1)");
|
|
6526
7463
|
return clear(map([scalars]));
|
|
6527
7464
|
}
|
|
@@ -6531,13 +7468,551 @@ function createHasher(Point, mapToCurve, defaults) {
|
|
|
6531
7468
|
},
|
|
6532
7469
|
hashToScalar(msg, options) {
|
|
6533
7470
|
const N = Point.Fn.ORDER;
|
|
6534
|
-
return hash_to_field(msg, 1, Object.assign({},
|
|
7471
|
+
return hash_to_field(msg, 1, Object.assign({}, safeDefaults, {
|
|
6535
7472
|
p: N,
|
|
6536
7473
|
m: 1,
|
|
6537
7474
|
DST: _DST_scalar
|
|
6538
7475
|
}, options))[0][0];
|
|
6539
7476
|
}
|
|
7477
|
+
});
|
|
7478
|
+
}
|
|
7479
|
+
|
|
7480
|
+
//#endregion
|
|
7481
|
+
//#region node_modules/@noble/curves/abstract/frost.js
|
|
7482
|
+
/**
|
|
7483
|
+
* FROST: Flexible Round-Optimized Schnorr Threshold Protocol for Two-Round Schnorr Signatures.
|
|
7484
|
+
*
|
|
7485
|
+
* See [RFC 9591](https://datatracker.ietf.org/doc/rfc9591/) and [frost.zfnd.org](https://frost.zfnd.org).
|
|
7486
|
+
* @module
|
|
7487
|
+
*/
|
|
7488
|
+
const validateSigners = (signers) => {
|
|
7489
|
+
if (!Number.isSafeInteger(signers.min) || !Number.isSafeInteger(signers.max)) throw new Error("Wrong signers info: min=" + signers.min + " max=" + signers.max);
|
|
7490
|
+
if (signers.min < 2 || signers.max < 2 || signers.min > signers.max) throw new Error("Wrong signers info: min=" + signers.min + " max=" + signers.max);
|
|
7491
|
+
};
|
|
7492
|
+
const validateCommitmentsNum = (signers, len) => {
|
|
7493
|
+
if (len < signers.min || len > signers.max) throw new Error("Wrong number of commitments=" + len);
|
|
7494
|
+
};
|
|
7495
|
+
var AggErr = class extends Error {
|
|
7496
|
+
cheaters;
|
|
7497
|
+
constructor(msg, cheaters) {
|
|
7498
|
+
super(msg);
|
|
7499
|
+
this.cheaters = cheaters;
|
|
7500
|
+
}
|
|
7501
|
+
};
|
|
7502
|
+
function createFROST(opts) {
|
|
7503
|
+
validateObject(opts, {
|
|
7504
|
+
name: "string",
|
|
7505
|
+
hash: "function"
|
|
7506
|
+
}, {
|
|
7507
|
+
hashToScalar: "function",
|
|
7508
|
+
validatePoint: "function",
|
|
7509
|
+
parsePublicKey: "function",
|
|
7510
|
+
adjustScalar: "function",
|
|
7511
|
+
adjustPoint: "function",
|
|
7512
|
+
challenge: "function",
|
|
7513
|
+
adjustNonces: "function",
|
|
7514
|
+
adjustSecret: "function",
|
|
7515
|
+
adjustPublic: "function",
|
|
7516
|
+
adjustGroupCommitmentShare: "function",
|
|
7517
|
+
adjustDKG: "function"
|
|
7518
|
+
});
|
|
7519
|
+
validatePointCons(opts.Point);
|
|
7520
|
+
const { Point } = opts;
|
|
7521
|
+
const Fn = opts.Fn === void 0 ? Point.Fn : opts.Fn;
|
|
7522
|
+
const hashBytes = opts.hash;
|
|
7523
|
+
const hashToScalar = opts.hashToScalar === void 0 ? (msg, opts = { DST: new Uint8Array() }) => {
|
|
7524
|
+
const t = hashBytes(concatBytes(opts.DST, msg));
|
|
7525
|
+
return Fn.create(Fn.isLE ? bytesToNumberLE(t) : bytesToNumberBE(t));
|
|
7526
|
+
} : opts.hashToScalar;
|
|
7527
|
+
const H1Prefix = utf8ToBytes(opts.H1 !== void 0 ? opts.H1 : opts.name + "rho");
|
|
7528
|
+
const H2Prefix = utf8ToBytes(opts.H2 !== void 0 ? opts.H2 : opts.name + "chal");
|
|
7529
|
+
const H3Prefix = utf8ToBytes(opts.H3 !== void 0 ? opts.H3 : opts.name + "nonce");
|
|
7530
|
+
const H4Prefix = utf8ToBytes(opts.H4 !== void 0 ? opts.H4 : opts.name + "msg");
|
|
7531
|
+
const H5Prefix = utf8ToBytes(opts.H5 !== void 0 ? opts.H5 : opts.name + "com");
|
|
7532
|
+
const HDKGPrefix = utf8ToBytes(opts.HDKG !== void 0 ? opts.HDKG : opts.name + "dkg");
|
|
7533
|
+
const HIDPrefix = utf8ToBytes(opts.HID !== void 0 ? opts.HID : opts.name + "id");
|
|
7534
|
+
const H1 = (msg) => hashToScalar(msg, { DST: H1Prefix });
|
|
7535
|
+
const H2 = (msg) => hashToScalar(msg, { DST: H2Prefix });
|
|
7536
|
+
const H3 = (msg) => hashToScalar(msg, { DST: H3Prefix });
|
|
7537
|
+
const H4 = (msg) => hashBytes(concatBytes(H4Prefix, msg));
|
|
7538
|
+
const H5 = (msg) => hashBytes(concatBytes(H5Prefix, msg));
|
|
7539
|
+
const HDKG = (msg) => hashToScalar(msg, { DST: HDKGPrefix });
|
|
7540
|
+
const HID = (msg) => hashToScalar(msg, { DST: HIDPrefix });
|
|
7541
|
+
const randomScalar = (rng = randomBytes) => {
|
|
7542
|
+
const t = mapHashToField(rng(getMinHashLength(Fn.ORDER)), Fn.ORDER, Fn.isLE);
|
|
7543
|
+
return Fn.isLE ? bytesToNumberLE(t) : bytesToNumberBE(t);
|
|
7544
|
+
};
|
|
7545
|
+
const serializePoint = (p) => p.toBytes();
|
|
7546
|
+
const parsePoint = (bytes) => {
|
|
7547
|
+
const p = Point.fromBytes(bytes);
|
|
7548
|
+
if (opts.validatePoint) opts.validatePoint(p);
|
|
7549
|
+
return p;
|
|
7550
|
+
};
|
|
7551
|
+
const nonceCommitments = (identifier, nonces) => ({
|
|
7552
|
+
identifier,
|
|
7553
|
+
hiding: serializePoint(Point.BASE.multiply(Fn.fromBytes(nonces.hiding))),
|
|
7554
|
+
binding: serializePoint(Point.BASE.multiply(Fn.fromBytes(nonces.binding)))
|
|
7555
|
+
});
|
|
7556
|
+
const adjustPoint = opts.adjustPoint === void 0 ? (n) => n : opts.adjustPoint;
|
|
7557
|
+
const validateIdentifier = (n) => {
|
|
7558
|
+
if (!Fn.isValid(n) || Fn.is0(n)) throw new Error("Invalid identifier " + n);
|
|
7559
|
+
return n;
|
|
7560
|
+
};
|
|
7561
|
+
const serializeIdentifier = (id) => bytesToHex(Fn.toBytes(validateIdentifier(id)));
|
|
7562
|
+
const parseIdentifier = (id) => {
|
|
7563
|
+
const n = validateIdentifier(Fn.fromBytes(hexToBytes(id)));
|
|
7564
|
+
if (serializeIdentifier(n) !== id) throw new Error("expected canonical identifier hex");
|
|
7565
|
+
return n;
|
|
7566
|
+
};
|
|
7567
|
+
const Signature = {
|
|
7568
|
+
encode: (R, z) => {
|
|
7569
|
+
let res = concatBytes(serializePoint(R), Fn.toBytes(z));
|
|
7570
|
+
if (opts.adjustTx) res = opts.adjustTx.encode(res);
|
|
7571
|
+
return res;
|
|
7572
|
+
},
|
|
7573
|
+
decode: (sig) => {
|
|
7574
|
+
if (opts.adjustTx) sig = opts.adjustTx.decode(sig);
|
|
7575
|
+
return {
|
|
7576
|
+
R: parsePoint(sig.subarray(0, -Fn.BYTES)),
|
|
7577
|
+
z: Fn.fromBytes(sig.subarray(-Fn.BYTES))
|
|
7578
|
+
};
|
|
7579
|
+
}
|
|
7580
|
+
};
|
|
7581
|
+
const genPointScalarPair = (rng = randomBytes) => {
|
|
7582
|
+
let n = randomScalar(rng);
|
|
7583
|
+
if (opts.adjustScalar) n = opts.adjustScalar(n);
|
|
7584
|
+
let p = Point.BASE.multiply(n);
|
|
7585
|
+
return {
|
|
7586
|
+
scalar: n,
|
|
7587
|
+
point: p
|
|
7588
|
+
};
|
|
7589
|
+
};
|
|
7590
|
+
const nrErr = "roots are unavailable in FROST polynomial mode";
|
|
7591
|
+
const Poly = poly(Fn, {
|
|
7592
|
+
info: {
|
|
7593
|
+
G: Fn.ZERO,
|
|
7594
|
+
oddFactor: Fn.ZERO,
|
|
7595
|
+
powerOfTwo: 0
|
|
7596
|
+
},
|
|
7597
|
+
roots() {
|
|
7598
|
+
throw new Error(nrErr);
|
|
7599
|
+
},
|
|
7600
|
+
brp() {
|
|
7601
|
+
throw new Error(nrErr);
|
|
7602
|
+
},
|
|
7603
|
+
inverse() {
|
|
7604
|
+
throw new Error(nrErr);
|
|
7605
|
+
},
|
|
7606
|
+
omega() {
|
|
7607
|
+
throw new Error(nrErr);
|
|
7608
|
+
},
|
|
7609
|
+
clear() {}
|
|
7610
|
+
});
|
|
7611
|
+
const msm = (points, scalars) => pippenger(Point, points, scalars);
|
|
7612
|
+
const polynomialEvaluate = (x, coeffs) => {
|
|
7613
|
+
if (!coeffs.length) throw new Error("empty coefficients");
|
|
7614
|
+
return Poly.monomial.eval(coeffs, x);
|
|
7615
|
+
};
|
|
7616
|
+
const deriveInterpolatingValue = (L, xi) => {
|
|
7617
|
+
const err = "invalid parameters";
|
|
7618
|
+
if (!L.some((x) => Fn.eql(x, xi))) throw new Error(err);
|
|
7619
|
+
const Lset = new Set(L);
|
|
7620
|
+
if (Lset.size !== L.length) throw new Error(err);
|
|
7621
|
+
if (!Lset.has(xi)) throw new Error(err);
|
|
7622
|
+
let num = Fn.ONE;
|
|
7623
|
+
let den = Fn.ONE;
|
|
7624
|
+
for (const x of L) {
|
|
7625
|
+
if (Fn.eql(x, xi)) continue;
|
|
7626
|
+
num = Fn.mul(num, x);
|
|
7627
|
+
den = Fn.mul(den, Fn.sub(x, xi));
|
|
7628
|
+
}
|
|
7629
|
+
return Fn.div(num, den);
|
|
7630
|
+
};
|
|
7631
|
+
const evalutateVSS = (identifier, commitment) => {
|
|
7632
|
+
return msm(commitment, Poly.monomial.basis(identifier, commitment.length));
|
|
7633
|
+
};
|
|
7634
|
+
const generateSecretPolynomial = (signers, secret, coeffs, rng = randomBytes) => {
|
|
7635
|
+
validateSigners(signers);
|
|
7636
|
+
const secretScalar = secret === void 0 ? randomScalar(rng) : Fn.fromBytes(secret);
|
|
7637
|
+
if (!coeffs) {
|
|
7638
|
+
coeffs = [];
|
|
7639
|
+
for (let i = 0; i < signers.min - 1; i++) coeffs.push(randomScalar(rng));
|
|
7640
|
+
}
|
|
7641
|
+
if (coeffs.length !== signers.min - 1) throw new Error("wrong coefficients length");
|
|
7642
|
+
const coefficients = [secretScalar, ...coeffs];
|
|
7643
|
+
return {
|
|
7644
|
+
coefficients,
|
|
7645
|
+
commitment: coefficients.map((i) => Point.BASE.multiply(i)),
|
|
7646
|
+
secret: secretScalar
|
|
7647
|
+
};
|
|
7648
|
+
};
|
|
7649
|
+
const ProofOfKnowledge = {
|
|
7650
|
+
challenge: (id, verKey, R) => HDKG(concatBytes(Fn.toBytes(id), serializePoint(verKey), serializePoint(R))),
|
|
7651
|
+
compute(id, coefficents, commitments, rng = randomBytes) {
|
|
7652
|
+
if (coefficents.length < 1) throw new Error("coefficients should have at least one element");
|
|
7653
|
+
const { point: R, scalar: k } = genPointScalarPair(rng);
|
|
7654
|
+
const verKey = commitments[0];
|
|
7655
|
+
const c = this.challenge(id, verKey, R);
|
|
7656
|
+
const mu = Fn.add(k, Fn.mul(coefficents[0], c));
|
|
7657
|
+
return Signature.encode(R, mu);
|
|
7658
|
+
},
|
|
7659
|
+
validate(id, commitment, proof) {
|
|
7660
|
+
if (commitment.length < 1) throw new Error("commitment should have at least one element");
|
|
7661
|
+
const { R, z } = Signature.decode(proof);
|
|
7662
|
+
const phi = parsePoint(commitment[0]);
|
|
7663
|
+
const c = this.challenge(id, phi, R);
|
|
7664
|
+
if (!R.equals(Point.BASE.multiply(z).subtract(phi.multiply(c)))) throw new Error("invalid proof of knowledge");
|
|
7665
|
+
}
|
|
7666
|
+
};
|
|
7667
|
+
const Basic = {
|
|
7668
|
+
challenge: (R, PK, msg) => {
|
|
7669
|
+
if (opts.challenge) return opts.challenge(R, PK, msg);
|
|
7670
|
+
return H2(concatBytes(serializePoint(R), serializePoint(PK), msg));
|
|
7671
|
+
},
|
|
7672
|
+
sign(msg, sk, rng = randomBytes) {
|
|
7673
|
+
const { point: R, scalar: r } = genPointScalarPair(rng);
|
|
7674
|
+
const PK = Point.BASE.multiply(sk);
|
|
7675
|
+
const c = this.challenge(R, PK, msg);
|
|
7676
|
+
return [R, Fn.add(r, Fn.mul(c, sk))];
|
|
7677
|
+
},
|
|
7678
|
+
verify(msg, R, z, PK) {
|
|
7679
|
+
if (opts.adjustPoint) PK = opts.adjustPoint(PK);
|
|
7680
|
+
if (opts.adjustPoint) R = opts.adjustPoint(R);
|
|
7681
|
+
const c = this.challenge(R, PK, msg);
|
|
7682
|
+
const zB = Point.BASE.multiply(z);
|
|
7683
|
+
const cA = PK.multiply(c);
|
|
7684
|
+
let check = zB.subtract(cA).subtract(R);
|
|
7685
|
+
if (check.clearCofactor) check = check.clearCofactor();
|
|
7686
|
+
return Point.ZERO.equals(check);
|
|
7687
|
+
}
|
|
7688
|
+
};
|
|
7689
|
+
const validateSecretShare = (identifier, commitment, signingShare) => {
|
|
7690
|
+
if (!Point.BASE.multiply(signingShare).equals(evalutateVSS(identifier, commitment))) throw new Error("invalid secret share");
|
|
7691
|
+
};
|
|
7692
|
+
const Identifier = {
|
|
7693
|
+
fromNumber(n) {
|
|
7694
|
+
if (!Number.isSafeInteger(n)) throw new Error("expected safe interger");
|
|
7695
|
+
return serializeIdentifier(BigInt(n));
|
|
7696
|
+
},
|
|
7697
|
+
derive(s) {
|
|
7698
|
+
if (typeof s !== "string") throw new Error("wrong identifier string: " + s);
|
|
7699
|
+
return serializeIdentifier(HID(utf8ToBytes(s)));
|
|
7700
|
+
}
|
|
7701
|
+
};
|
|
7702
|
+
const generateNonce = (secret, rng = randomBytes) => H3(concatBytes(rng(32), Fn.toBytes(secret)));
|
|
7703
|
+
const getGroupCommitment = (GPK, commitmentList, msg) => {
|
|
7704
|
+
const CL = commitmentList.map((i) => [
|
|
7705
|
+
i.identifier,
|
|
7706
|
+
parseIdentifier(i.identifier),
|
|
7707
|
+
parsePoint(i.hiding),
|
|
7708
|
+
parsePoint(i.binding)
|
|
7709
|
+
]);
|
|
7710
|
+
CL.sort((a, b) => a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : 0);
|
|
7711
|
+
const Cbytes = [];
|
|
7712
|
+
for (const [_, id, hC, bC] of CL) Cbytes.push(Fn.toBytes(id), serializePoint(hC), serializePoint(bC));
|
|
7713
|
+
const encodedCommitmentHash = H5(concatBytes(...Cbytes));
|
|
7714
|
+
const rhoPrefix = concatBytes(serializePoint(GPK), H4(msg), encodedCommitmentHash);
|
|
7715
|
+
const bindingFactors = {};
|
|
7716
|
+
for (const [i, id] of CL) bindingFactors[i] = H1(concatBytes(rhoPrefix, Fn.toBytes(id)));
|
|
7717
|
+
const points = [];
|
|
7718
|
+
const scalars = [];
|
|
7719
|
+
for (const [i, _, hC, bC] of CL) {
|
|
7720
|
+
if (Point.ZERO.equals(hC) || Point.ZERO.equals(bC)) throw new Error("infinity commitment");
|
|
7721
|
+
points.push(hC, bC);
|
|
7722
|
+
scalars.push(Fn.ONE, bindingFactors[i]);
|
|
7723
|
+
}
|
|
7724
|
+
const groupCommitment = msm(points, scalars);
|
|
7725
|
+
return {
|
|
7726
|
+
identifiers: CL.map((i) => i[1]),
|
|
7727
|
+
groupCommitment,
|
|
7728
|
+
bindingFactors
|
|
7729
|
+
};
|
|
7730
|
+
};
|
|
7731
|
+
const prepareShare = (PK, commitmentList, msg, identifier) => {
|
|
7732
|
+
const GPK = adjustPoint(parsePoint(PK));
|
|
7733
|
+
const id = parseIdentifier(identifier);
|
|
7734
|
+
const { identifiers, groupCommitment, bindingFactors } = getGroupCommitment(GPK, commitmentList, msg);
|
|
7735
|
+
const bindingFactor = bindingFactors[identifier];
|
|
7736
|
+
return {
|
|
7737
|
+
lambda: deriveInterpolatingValue(identifiers, id),
|
|
7738
|
+
challenge: Basic.challenge(groupCommitment, GPK, msg),
|
|
7739
|
+
bindingFactor,
|
|
7740
|
+
groupCommitment
|
|
7741
|
+
};
|
|
7742
|
+
};
|
|
7743
|
+
Object.freeze(Identifier);
|
|
7744
|
+
const frost = {
|
|
7745
|
+
Identifier,
|
|
7746
|
+
DKG: Object.freeze({
|
|
7747
|
+
round1: (id, signers, secret, rng = randomBytes) => {
|
|
7748
|
+
validateSigners(signers);
|
|
7749
|
+
const idNum = parseIdentifier(id);
|
|
7750
|
+
const { coefficients, commitment } = generateSecretPolynomial(signers, secret, void 0, rng);
|
|
7751
|
+
const proofOfKnowledge = ProofOfKnowledge.compute(idNum, coefficients, commitment, rng);
|
|
7752
|
+
const commitmentBytes = commitment.map(serializePoint);
|
|
7753
|
+
return {
|
|
7754
|
+
public: {
|
|
7755
|
+
identifier: serializeIdentifier(idNum),
|
|
7756
|
+
commitment: commitmentBytes,
|
|
7757
|
+
proofOfKnowledge
|
|
7758
|
+
},
|
|
7759
|
+
secret: {
|
|
7760
|
+
identifier: idNum,
|
|
7761
|
+
coefficients,
|
|
7762
|
+
commitment: commitment.map(serializePoint),
|
|
7763
|
+
signers: {
|
|
7764
|
+
min: signers.min,
|
|
7765
|
+
max: signers.max
|
|
7766
|
+
},
|
|
7767
|
+
step: 1
|
|
7768
|
+
}
|
|
7769
|
+
};
|
|
7770
|
+
},
|
|
7771
|
+
round2: (secret, others) => {
|
|
7772
|
+
if (others.length !== secret.signers.max - 1) throw new Error("wrong number of round1 packages");
|
|
7773
|
+
if (!secret.coefficients || secret.step === 3) throw new Error("round3 package used in round2");
|
|
7774
|
+
const res = {};
|
|
7775
|
+
for (const p of others) {
|
|
7776
|
+
if (p.commitment.length !== secret.signers.min) throw new Error("wrong number of commitments");
|
|
7777
|
+
const id = parseIdentifier(p.identifier);
|
|
7778
|
+
if (id === secret.identifier) throw new Error("duplicate id=" + serializeIdentifier(id));
|
|
7779
|
+
ProofOfKnowledge.validate(id, p.commitment, p.proofOfKnowledge);
|
|
7780
|
+
for (const c of p.commitment) parsePoint(c);
|
|
7781
|
+
if (res[p.identifier]) throw new Error("Duplicate id=" + id);
|
|
7782
|
+
const signingShare = Fn.toBytes(polynomialEvaluate(id, secret.coefficients));
|
|
7783
|
+
res[p.identifier] = {
|
|
7784
|
+
identifier: serializeIdentifier(secret.identifier),
|
|
7785
|
+
signingShare
|
|
7786
|
+
};
|
|
7787
|
+
}
|
|
7788
|
+
secret.step = 2;
|
|
7789
|
+
return res;
|
|
7790
|
+
},
|
|
7791
|
+
round3: (secret, round1, round2) => {
|
|
7792
|
+
if (round1.length !== secret.signers.max - 1) throw new Error("wrong length of round1 packages");
|
|
7793
|
+
if (!secret.coefficients || secret.step !== 2) throw new Error("round2 package used in round3");
|
|
7794
|
+
if (round2.length !== round1.length) throw new Error("wrong length of round2 packages");
|
|
7795
|
+
const merged = {};
|
|
7796
|
+
for (const r1 of round1) {
|
|
7797
|
+
if (!r1.identifier || !r1.commitment) throw new Error("wrong round1 share");
|
|
7798
|
+
merged[r1.identifier] = { ...r1 };
|
|
7799
|
+
}
|
|
7800
|
+
for (const r2 of round2) {
|
|
7801
|
+
if (!r2.identifier || !r2.signingShare) throw new Error("wrong round2 share");
|
|
7802
|
+
if (!merged[r2.identifier]) throw new Error("round1 share for " + r2.identifier + " is missing");
|
|
7803
|
+
merged[r2.identifier].signingShare = r2.signingShare;
|
|
7804
|
+
}
|
|
7805
|
+
if (Object.keys(merged).length !== round1.length) throw new Error("mismatch identifiers between rounds");
|
|
7806
|
+
let signingShare = Fn.ZERO;
|
|
7807
|
+
if (secret.commitment.length !== secret.signers.min) throw new Error("wrong commitments length");
|
|
7808
|
+
const localCommitment = secret.commitment.map(parsePoint);
|
|
7809
|
+
const localShare = polynomialEvaluate(secret.identifier, secret.coefficients);
|
|
7810
|
+
validateSecretShare(secret.identifier, localCommitment, localShare);
|
|
7811
|
+
const localCommitmentBytes = localCommitment.map(serializePoint);
|
|
7812
|
+
const commitments = { [serializeIdentifier(secret.identifier)]: localCommitmentBytes };
|
|
7813
|
+
for (const k in merged) {
|
|
7814
|
+
const v = merged[k];
|
|
7815
|
+
if (!v.signingShare || !v.commitment) throw new Error("mismatch identifiers");
|
|
7816
|
+
const id = parseIdentifier(k);
|
|
7817
|
+
const signingSharePart = Fn.fromBytes(v.signingShare);
|
|
7818
|
+
const commitment = v.commitment.map(parsePoint);
|
|
7819
|
+
validateSecretShare(secret.identifier, commitment, signingSharePart);
|
|
7820
|
+
signingShare = Fn.add(signingShare, signingSharePart);
|
|
7821
|
+
const idSer = serializeIdentifier(id);
|
|
7822
|
+
if (commitments[idSer]) throw new Error("duplicated id=" + idSer);
|
|
7823
|
+
commitments[idSer] = v.commitment;
|
|
7824
|
+
}
|
|
7825
|
+
signingShare = Fn.add(signingShare, localShare);
|
|
7826
|
+
const mergedCommitment = new Array(secret.signers.min).fill(Point.ZERO);
|
|
7827
|
+
for (const k in commitments) {
|
|
7828
|
+
const v = commitments[k];
|
|
7829
|
+
if (v.length !== secret.signers.min) throw new Error("wrong commitments length");
|
|
7830
|
+
for (let i = 0; i < v.length; i++) mergedCommitment[i] = mergedCommitment[i].add(parsePoint(v[i]));
|
|
7831
|
+
}
|
|
7832
|
+
const mergedCommitmentBytes = mergedCommitment.map(serializePoint);
|
|
7833
|
+
const verifyingShares = {};
|
|
7834
|
+
for (const k in commitments) verifyingShares[k] = serializePoint(evalutateVSS(parseIdentifier(k), mergedCommitment));
|
|
7835
|
+
let res = {
|
|
7836
|
+
public: {
|
|
7837
|
+
signers: {
|
|
7838
|
+
min: secret.signers.min,
|
|
7839
|
+
max: secret.signers.max
|
|
7840
|
+
},
|
|
7841
|
+
commitments: mergedCommitmentBytes,
|
|
7842
|
+
verifyingShares: Object.fromEntries(Object.entries(verifyingShares).map(([k, v]) => [k, v.slice()]))
|
|
7843
|
+
},
|
|
7844
|
+
secret: {
|
|
7845
|
+
identifier: serializeIdentifier(secret.identifier),
|
|
7846
|
+
signingShare: Fn.toBytes(signingShare)
|
|
7847
|
+
}
|
|
7848
|
+
};
|
|
7849
|
+
if (opts.adjustDKG) res = opts.adjustDKG(res);
|
|
7850
|
+
for (let i = 0; i < secret.coefficients.length; i++) secret.coefficients[i] -= secret.coefficients[i];
|
|
7851
|
+
delete secret.coefficients;
|
|
7852
|
+
secret.step = 3;
|
|
7853
|
+
return res;
|
|
7854
|
+
},
|
|
7855
|
+
clean(secret) {
|
|
7856
|
+
secret.identifier -= secret.identifier;
|
|
7857
|
+
if (secret.coefficients) for (let i = 0; i < secret.coefficients.length; i++) secret.coefficients[i] -= secret.coefficients[i];
|
|
7858
|
+
secret.step = 3;
|
|
7859
|
+
}
|
|
7860
|
+
}),
|
|
7861
|
+
trustedDealer(signers, identifiers, secret, rng = randomBytes) {
|
|
7862
|
+
validateSigners(signers);
|
|
7863
|
+
if (identifiers === void 0) {
|
|
7864
|
+
identifiers = [];
|
|
7865
|
+
for (let i = 1; i <= signers.max; i++) identifiers.push(Identifier.fromNumber(i));
|
|
7866
|
+
} else if (!Array.isArray(identifiers) || identifiers.length !== signers.max) throw new Error("identifiers should be array of " + signers.max);
|
|
7867
|
+
const identifierNums = {};
|
|
7868
|
+
for (const id of identifiers) {
|
|
7869
|
+
const idNum = parseIdentifier(id);
|
|
7870
|
+
if (id in identifierNums) throw new Error("duplicated id=" + id);
|
|
7871
|
+
identifierNums[id] = idNum;
|
|
7872
|
+
}
|
|
7873
|
+
const sp = generateSecretPolynomial(signers, secret, void 0, rng);
|
|
7874
|
+
const commitmentBytes = sp.commitment.map(serializePoint);
|
|
7875
|
+
const secretShares = {};
|
|
7876
|
+
const verifyingShares = {};
|
|
7877
|
+
for (const id of identifiers) {
|
|
7878
|
+
const signingShare = polynomialEvaluate(identifierNums[id], sp.coefficients);
|
|
7879
|
+
verifyingShares[id] = serializePoint(Point.BASE.multiply(signingShare));
|
|
7880
|
+
secretShares[id] = {
|
|
7881
|
+
identifier: id,
|
|
7882
|
+
signingShare: Fn.toBytes(signingShare)
|
|
7883
|
+
};
|
|
7884
|
+
}
|
|
7885
|
+
return {
|
|
7886
|
+
public: {
|
|
7887
|
+
signers: {
|
|
7888
|
+
min: signers.min,
|
|
7889
|
+
max: signers.max
|
|
7890
|
+
},
|
|
7891
|
+
commitments: commitmentBytes,
|
|
7892
|
+
verifyingShares
|
|
7893
|
+
},
|
|
7894
|
+
secretShares
|
|
7895
|
+
};
|
|
7896
|
+
},
|
|
7897
|
+
validateSecret(secret, pub) {
|
|
7898
|
+
validateSecretShare(parseIdentifier(secret.identifier), pub.commitments.map(parsePoint), Fn.fromBytes(secret.signingShare));
|
|
7899
|
+
},
|
|
7900
|
+
commit(secret, rng = randomBytes) {
|
|
7901
|
+
const secretScalar = Fn.fromBytes(secret.signingShare);
|
|
7902
|
+
const hiding = generateNonce(secretScalar, rng);
|
|
7903
|
+
const binding = generateNonce(secretScalar, rng);
|
|
7904
|
+
const nonces = {
|
|
7905
|
+
hiding: Fn.toBytes(hiding),
|
|
7906
|
+
binding: Fn.toBytes(binding)
|
|
7907
|
+
};
|
|
7908
|
+
return {
|
|
7909
|
+
nonces,
|
|
7910
|
+
commitments: nonceCommitments(secret.identifier, nonces)
|
|
7911
|
+
};
|
|
7912
|
+
},
|
|
7913
|
+
signShare(secret, pub, nonces, commitmentList, msg) {
|
|
7914
|
+
validateCommitmentsNum(pub.signers, commitmentList.length);
|
|
7915
|
+
const hidingNonce0 = Fn.fromBytes(nonces.hiding);
|
|
7916
|
+
const bindingNonce0 = Fn.fromBytes(nonces.binding);
|
|
7917
|
+
if (Fn.is0(hidingNonce0) || Fn.is0(bindingNonce0)) throw new Error("signing nonces already used");
|
|
7918
|
+
const expectedCommitment = {
|
|
7919
|
+
identifier: secret.identifier,
|
|
7920
|
+
hiding: serializePoint(Point.BASE.multiply(hidingNonce0)),
|
|
7921
|
+
binding: serializePoint(Point.BASE.multiply(bindingNonce0))
|
|
7922
|
+
};
|
|
7923
|
+
const commitment = commitmentList.find((i) => i.identifier === secret.identifier);
|
|
7924
|
+
if (!commitment) throw new Error("missing signer commitment");
|
|
7925
|
+
if (bytesToHex(commitment.hiding) !== bytesToHex(expectedCommitment.hiding) || bytesToHex(commitment.binding) !== bytesToHex(expectedCommitment.binding)) throw new Error("incorrect signer commitment");
|
|
7926
|
+
if (opts.adjustSecret) secret = opts.adjustSecret(secret, pub);
|
|
7927
|
+
if (opts.adjustPublic) pub = opts.adjustPublic(pub);
|
|
7928
|
+
const SK = Fn.fromBytes(secret.signingShare);
|
|
7929
|
+
const { lambda, challenge, bindingFactor, groupCommitment } = prepareShare(pub.commitments[0], commitmentList, msg, secret.identifier);
|
|
7930
|
+
const N = opts.adjustNonces ? opts.adjustNonces(groupCommitment, nonces) : nonces;
|
|
7931
|
+
const hidingNonce = opts.adjustNonces ? Fn.fromBytes(N.hiding) : hidingNonce0;
|
|
7932
|
+
const bindingNonce = opts.adjustNonces ? Fn.fromBytes(N.binding) : bindingNonce0;
|
|
7933
|
+
const t = Fn.mul(Fn.mul(lambda, SK), challenge);
|
|
7934
|
+
const t2 = Fn.mul(bindingNonce, bindingFactor);
|
|
7935
|
+
const r = Fn.toBytes(Fn.add(Fn.add(hidingNonce, t2), t));
|
|
7936
|
+
nonces.hiding.fill(0);
|
|
7937
|
+
nonces.binding.fill(0);
|
|
7938
|
+
return r;
|
|
7939
|
+
},
|
|
7940
|
+
verifyShare(pub, commitmentList, msg, identifier, sigShare) {
|
|
7941
|
+
if (opts.adjustPublic) pub = opts.adjustPublic(pub);
|
|
7942
|
+
const comm = commitmentList.find((i) => i.identifier === identifier);
|
|
7943
|
+
if (!comm) throw new Error("cannot find identifier commitment");
|
|
7944
|
+
const PK = parsePoint(pub.verifyingShares[identifier]);
|
|
7945
|
+
const hidingNonceCommitment = parsePoint(comm.hiding);
|
|
7946
|
+
const bindingNonceCommitment = parsePoint(comm.binding);
|
|
7947
|
+
const { lambda, challenge, bindingFactor, groupCommitment } = prepareShare(pub.commitments[0], commitmentList, msg, identifier);
|
|
7948
|
+
let commShare = hidingNonceCommitment.add(bindingNonceCommitment.multiply(bindingFactor));
|
|
7949
|
+
if (opts.adjustGroupCommitmentShare) commShare = opts.adjustGroupCommitmentShare(groupCommitment, commShare);
|
|
7950
|
+
const l = Point.BASE.multiply(Fn.fromBytes(sigShare));
|
|
7951
|
+
const r = commShare.add(PK.multiply(Fn.mul(challenge, lambda)));
|
|
7952
|
+
return l.equals(r);
|
|
7953
|
+
},
|
|
7954
|
+
aggregate(pub, commitmentList, msg, sigShares) {
|
|
7955
|
+
if (opts.adjustPublic) pub = opts.adjustPublic(pub);
|
|
7956
|
+
try {
|
|
7957
|
+
validateCommitmentsNum(pub.signers, commitmentList.length);
|
|
7958
|
+
} catch {
|
|
7959
|
+
throw new AggErr("aggregation failed", []);
|
|
7960
|
+
}
|
|
7961
|
+
const ids = commitmentList.map((i) => i.identifier);
|
|
7962
|
+
if (ids.length !== Object.keys(sigShares).length) throw new AggErr("aggregation failed", []);
|
|
7963
|
+
for (const id of ids) if (!(id in sigShares) || !(id in pub.verifyingShares)) throw new AggErr("aggregation failed", []);
|
|
7964
|
+
const GPK = parsePoint(pub.commitments[0]);
|
|
7965
|
+
const { groupCommitment } = getGroupCommitment(GPK, commitmentList, msg);
|
|
7966
|
+
let z = Fn.ZERO;
|
|
7967
|
+
for (const id of ids) z = Fn.add(z, Fn.fromBytes(sigShares[id]));
|
|
7968
|
+
if (!Basic.verify(msg, groupCommitment, z, GPK)) {
|
|
7969
|
+
const cheaters = [];
|
|
7970
|
+
for (const id of ids) if (!this.verifyShare(pub, commitmentList, msg, id, sigShares[id])) cheaters.push(id);
|
|
7971
|
+
throw new AggErr("aggregation failed", cheaters);
|
|
7972
|
+
}
|
|
7973
|
+
return Signature.encode(groupCommitment, z);
|
|
7974
|
+
},
|
|
7975
|
+
sign(msg, secretKey) {
|
|
7976
|
+
let sk = Fn.fromBytes(secretKey);
|
|
7977
|
+
if (opts.adjustScalar) sk = opts.adjustScalar(sk);
|
|
7978
|
+
const [R, z] = Basic.sign(msg, sk);
|
|
7979
|
+
return Signature.encode(R, z);
|
|
7980
|
+
},
|
|
7981
|
+
verify(sig, msg, publicKey) {
|
|
7982
|
+
const PK = opts.parsePublicKey ? opts.parsePublicKey(publicKey) : parsePoint(publicKey);
|
|
7983
|
+
const { R, z } = Signature.decode(sig);
|
|
7984
|
+
return Basic.verify(msg, R, z, PK);
|
|
7985
|
+
},
|
|
7986
|
+
combineSecret(shares, signers) {
|
|
7987
|
+
validateSigners(signers);
|
|
7988
|
+
if (!Array.isArray(shares) || shares.length < signers.min) throw new Error("wrong secret shares array");
|
|
7989
|
+
const points = [];
|
|
7990
|
+
const seen = {};
|
|
7991
|
+
for (const s of shares) {
|
|
7992
|
+
const idNum = parseIdentifier(s.identifier);
|
|
7993
|
+
const id = serializeIdentifier(idNum);
|
|
7994
|
+
if (seen[id]) throw new Error("duplicated id=" + id);
|
|
7995
|
+
seen[id] = true;
|
|
7996
|
+
points.push([idNum, Fn.fromBytes(s.signingShare)]);
|
|
7997
|
+
}
|
|
7998
|
+
const xCoords = points.map(([x]) => x);
|
|
7999
|
+
let res = Fn.ZERO;
|
|
8000
|
+
for (const [x, y] of points) res = Fn.add(res, Fn.mul(y, deriveInterpolatingValue(xCoords, x)));
|
|
8001
|
+
return Fn.toBytes(res);
|
|
8002
|
+
},
|
|
8003
|
+
utils: Object.freeze({
|
|
8004
|
+
Fn,
|
|
8005
|
+
randomScalar: (rng = randomBytes) => Fn.toBytes(genPointScalarPair(rng).scalar),
|
|
8006
|
+
generateSecretPolynomial: (signers, secret, coeffs, rng) => {
|
|
8007
|
+
const res = generateSecretPolynomial(signers, secret, coeffs, rng);
|
|
8008
|
+
return {
|
|
8009
|
+
...res,
|
|
8010
|
+
commitment: res.commitment.map(serializePoint)
|
|
8011
|
+
};
|
|
8012
|
+
}
|
|
8013
|
+
})
|
|
6540
8014
|
};
|
|
8015
|
+
return Object.freeze(frost);
|
|
6541
8016
|
}
|
|
6542
8017
|
|
|
6543
8018
|
//#endregion
|
|
@@ -6554,16 +8029,31 @@ const _1n$1 = BigInt(1);
|
|
|
6554
8029
|
const _2n$1 = BigInt(2);
|
|
6555
8030
|
function validateOpts(curve) {
|
|
6556
8031
|
validateObject(curve, {
|
|
8032
|
+
P: "bigint",
|
|
8033
|
+
type: "string",
|
|
6557
8034
|
adjustScalarBytes: "function",
|
|
6558
8035
|
powPminus2: "function"
|
|
6559
|
-
});
|
|
8036
|
+
}, { randomBytes: "function" });
|
|
6560
8037
|
return Object.freeze({ ...curve });
|
|
6561
8038
|
}
|
|
8039
|
+
/**
|
|
8040
|
+
* @param curveDef - Montgomery curve definition.
|
|
8041
|
+
* @returns ECDH helper namespace.
|
|
8042
|
+
* @throws If the curve definition or derived shared point is invalid. {@link Error}
|
|
8043
|
+
* @example
|
|
8044
|
+
* Perform one X25519 key exchange through the generic Montgomery helper.
|
|
8045
|
+
*
|
|
8046
|
+
* ```ts
|
|
8047
|
+
* import { x25519 } from '@noble/curves/ed25519.js';
|
|
8048
|
+
* const alice = x25519.keygen();
|
|
8049
|
+
* const shared = x25519.getSharedSecret(alice.secretKey, alice.publicKey);
|
|
8050
|
+
* ```
|
|
8051
|
+
*/
|
|
6562
8052
|
function montgomery(curveDef) {
|
|
6563
8053
|
const { P, type, adjustScalarBytes, powPminus2, randomBytes: rand } = validateOpts(curveDef);
|
|
6564
8054
|
const is25519 = type === "x25519";
|
|
6565
8055
|
if (!is25519 && type !== "x448") throw new Error("invalid type");
|
|
6566
|
-
const randomBytes_ = rand
|
|
8056
|
+
const randomBytes_ = rand === void 0 ? randomBytes : rand;
|
|
6567
8057
|
const montgomeryBits = is25519 ? 255 : 448;
|
|
6568
8058
|
const fieldLen = is25519 ? 32 : 56;
|
|
6569
8059
|
const Gu = is25519 ? BigInt(9) : BigInt(5);
|
|
@@ -6603,10 +8093,10 @@ function montgomery(curveDef) {
|
|
|
6603
8093
|
};
|
|
6604
8094
|
}
|
|
6605
8095
|
/**
|
|
6606
|
-
* Montgomery x-only multiplication ladder.
|
|
6607
|
-
* @param pointU u coordinate
|
|
6608
|
-
* @param scalar by which the point
|
|
6609
|
-
* @returns
|
|
8096
|
+
* Montgomery x-only multiplication ladder for the selected X25519/X448 curve.
|
|
8097
|
+
* @param pointU - decoded Montgomery u coordinate for the selected curve
|
|
8098
|
+
* @param scalar - decoded clamped scalar by which the point is multiplied
|
|
8099
|
+
* @returns resulting Montgomery u coordinate for the selected curve
|
|
6610
8100
|
*/
|
|
6611
8101
|
function montgomeryLadder(u, scalar) {
|
|
6612
8102
|
aInRange("u", u, _0n$1, P);
|
|
@@ -6649,11 +8139,14 @@ function montgomery(curveDef) {
|
|
|
6649
8139
|
publicKey: fieldLen,
|
|
6650
8140
|
seed: fieldLen
|
|
6651
8141
|
};
|
|
6652
|
-
const randomSecretKey = (seed
|
|
8142
|
+
const randomSecretKey = (seed) => {
|
|
8143
|
+
seed = seed === void 0 ? randomBytes_(fieldLen) : seed;
|
|
6653
8144
|
abytes(seed, lengths.seed, "seed");
|
|
6654
8145
|
return seed;
|
|
6655
8146
|
};
|
|
6656
8147
|
const utils = { randomSecretKey };
|
|
8148
|
+
Object.freeze(lengths);
|
|
8149
|
+
Object.freeze(utils);
|
|
6657
8150
|
return Object.freeze({
|
|
6658
8151
|
keygen: createKeygen(randomSecretKey, getPublicKey),
|
|
6659
8152
|
getSharedSecret,
|
|
@@ -6704,10 +8197,12 @@ queries private.
|
|
|
6704
8197
|
## Modes
|
|
6705
8198
|
|
|
6706
8199
|
- OPRF: simple mode, client doesn't need to know server public key
|
|
6707
|
-
- VOPRF:
|
|
8200
|
+
- VOPRF: verifiable mode. It lets the client verify that the server used the
|
|
8201
|
+
secret key corresponding to a known public key
|
|
6708
8202
|
- POPRF: partially oblivious mode, VOPRF + domain separation
|
|
6709
8203
|
|
|
6710
|
-
There is also non-interactive mode (Evaluate)
|
|
8204
|
+
There is also non-interactive mode (Evaluate), which creates Output
|
|
8205
|
+
non-interactively with knowledge of the secret key.
|
|
6711
8206
|
|
|
6712
8207
|
Flow:
|
|
6713
8208
|
- (once) Server generates secret and public keys, distributes public keys to clients
|
|
@@ -6719,17 +8214,39 @@ Flow:
|
|
|
6719
8214
|
* @module
|
|
6720
8215
|
*/
|
|
6721
8216
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
6722
|
-
|
|
8217
|
+
const _DST_scalarBytes = /* @__PURE__ */ asciiToBytes(_DST_scalar);
|
|
8218
|
+
/**
|
|
8219
|
+
* @param opts - OPRF ciphersuite options. See {@link OPRFOpts}.
|
|
8220
|
+
* @returns OPRF helper namespace.
|
|
8221
|
+
* @example
|
|
8222
|
+
* Instantiate an OPRF suite from curve-specific hashing hooks.
|
|
8223
|
+
*
|
|
8224
|
+
* ```ts
|
|
8225
|
+
* import { createOPRF } from '@noble/curves/abstract/oprf.js';
|
|
8226
|
+
* import { p256, p256_hasher } from '@noble/curves/nist.js';
|
|
8227
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
8228
|
+
* const oprf = createOPRF({
|
|
8229
|
+
* name: 'P256-SHA256',
|
|
8230
|
+
* Point: p256.Point,
|
|
8231
|
+
* hash: sha256,
|
|
8232
|
+
* hashToGroup: p256_hasher.hashToCurve,
|
|
8233
|
+
* hashToScalar: p256_hasher.hashToScalar,
|
|
8234
|
+
* });
|
|
8235
|
+
* const keys = oprf.oprf.generateKeyPair();
|
|
8236
|
+
* ```
|
|
8237
|
+
*/
|
|
8238
|
+
function createOPRF(opts) {
|
|
6723
8239
|
validateObject(opts, {
|
|
6724
8240
|
name: "string",
|
|
6725
8241
|
hash: "function",
|
|
6726
8242
|
hashToScalar: "function",
|
|
6727
8243
|
hashToGroup: "function"
|
|
6728
8244
|
});
|
|
8245
|
+
validatePointCons(opts.Point);
|
|
6729
8246
|
const { name, Point, hash } = opts;
|
|
6730
8247
|
const { Fn } = Point;
|
|
6731
8248
|
const hashToGroup = (msg, ctx) => opts.hashToGroup(msg, { DST: concatBytes(asciiToBytes("HashToGroup-"), ctx) });
|
|
6732
|
-
const hashToScalarPrefixed = (msg, ctx) => opts.hashToScalar(msg, { DST: concatBytes(
|
|
8249
|
+
const hashToScalarPrefixed = (msg, ctx) => opts.hashToScalar(msg, { DST: concatBytes(_DST_scalarBytes, ctx) });
|
|
6733
8250
|
const randomScalar = (rng = randomBytes) => {
|
|
6734
8251
|
const t = mapHashToField(rng(getMinHashLength(Fn.ORDER)), Fn.ORDER, Fn.isLE);
|
|
6735
8252
|
return Fn.isLE ? bytesToNumberLE(t) : bytesToNumberBE(t);
|
|
@@ -6749,6 +8266,11 @@ function createORPF(opts) {
|
|
|
6749
8266
|
}
|
|
6750
8267
|
return concatBytes(...res);
|
|
6751
8268
|
}
|
|
8269
|
+
const inputBytes = (title, bytes) => {
|
|
8270
|
+
abytes(bytes, void 0, title);
|
|
8271
|
+
if (bytes.length > 65535) throw new Error(`"${title}" expected Uint8Array of length <= 65535, got length=${bytes.length}`);
|
|
8272
|
+
return bytes;
|
|
8273
|
+
};
|
|
6752
8274
|
const hashInput = (...bytes) => hash(encode(...bytes, "Finalize"));
|
|
6753
8275
|
function getTranscripts(B, C, D, ctx) {
|
|
6754
8276
|
const seed = hash(encode(B.toBytes(), concatBytes(asciiToBytes("Seed-"), ctx)));
|
|
@@ -6807,6 +8329,8 @@ function createORPF(opts) {
|
|
|
6807
8329
|
};
|
|
6808
8330
|
}
|
|
6809
8331
|
function deriveKeyPair(ctx, seed, info) {
|
|
8332
|
+
abytes(seed, 32, "seed");
|
|
8333
|
+
info = inputBytes("keyInfo", info);
|
|
6810
8334
|
const dst = concatBytes(asciiToBytes("DeriveKeyPair"), ctx);
|
|
6811
8335
|
const msg = concatBytes(seed, encode(info), Uint8Array.of(0));
|
|
6812
8336
|
for (let counter = 0; counter <= 255; counter++) {
|
|
@@ -6820,7 +8344,13 @@ function createORPF(opts) {
|
|
|
6820
8344
|
}
|
|
6821
8345
|
throw new Error("Cannot derive key");
|
|
6822
8346
|
}
|
|
8347
|
+
const wirePoint = (label, bytes) => {
|
|
8348
|
+
const point = Point.fromBytes(bytes);
|
|
8349
|
+
if (point.equals(Point.ZERO)) throw new Error(label + " point at infinity");
|
|
8350
|
+
return point;
|
|
8351
|
+
};
|
|
6823
8352
|
function blind(ctx, input, rng = randomBytes) {
|
|
8353
|
+
input = inputBytes("input", input);
|
|
6824
8354
|
const blind = randomScalar(rng);
|
|
6825
8355
|
const inputPoint = hashToGroup(input, ctx);
|
|
6826
8356
|
if (inputPoint.equals(Point.ZERO)) throw new Error("Input point at infinity");
|
|
@@ -6831,34 +8361,38 @@ function createORPF(opts) {
|
|
|
6831
8361
|
};
|
|
6832
8362
|
}
|
|
6833
8363
|
function evaluate(ctx, secretKey, input) {
|
|
8364
|
+
input = inputBytes("input", input);
|
|
6834
8365
|
const skS = Fn.fromBytes(secretKey);
|
|
6835
8366
|
const inputPoint = hashToGroup(input, ctx);
|
|
6836
8367
|
if (inputPoint.equals(Point.ZERO)) throw new Error("Input point at infinity");
|
|
6837
|
-
|
|
8368
|
+
const unblinded = inputPoint.multiply(skS).toBytes();
|
|
8369
|
+
return hashInput(input, unblinded);
|
|
6838
8370
|
}
|
|
6839
|
-
const oprf = {
|
|
8371
|
+
const oprf = Object.freeze({
|
|
6840
8372
|
generateKeyPair,
|
|
6841
8373
|
deriveKeyPair: (seed, keyInfo) => deriveKeyPair(ctxOPRF, seed, keyInfo),
|
|
6842
8374
|
blind: (input, rng = randomBytes) => blind(ctxOPRF, input, rng),
|
|
6843
8375
|
blindEvaluate(secretKey, blindedPoint) {
|
|
6844
8376
|
const skS = Fn.fromBytes(secretKey);
|
|
6845
|
-
return
|
|
8377
|
+
return wirePoint("blinded", blindedPoint).multiply(skS).toBytes();
|
|
6846
8378
|
},
|
|
6847
8379
|
finalize(input, blindBytes, evaluatedBytes) {
|
|
8380
|
+
input = inputBytes("input", input);
|
|
6848
8381
|
const blind = Fn.fromBytes(blindBytes);
|
|
6849
|
-
|
|
8382
|
+
const unblinded = wirePoint("evaluated", evaluatedBytes).multiply(Fn.inv(blind)).toBytes();
|
|
8383
|
+
return hashInput(input, unblinded);
|
|
6850
8384
|
},
|
|
6851
8385
|
evaluate: (secretKey, input) => evaluate(ctxOPRF, secretKey, input)
|
|
6852
|
-
};
|
|
6853
|
-
const voprf = {
|
|
8386
|
+
});
|
|
8387
|
+
const voprf = Object.freeze({
|
|
6854
8388
|
generateKeyPair,
|
|
6855
8389
|
deriveKeyPair: (seed, keyInfo) => deriveKeyPair(ctxVOPRF, seed, keyInfo),
|
|
6856
8390
|
blind: (input, rng = randomBytes) => blind(ctxVOPRF, input, rng),
|
|
6857
8391
|
blindEvaluateBatch(secretKey, publicKey, blinded, rng = randomBytes) {
|
|
6858
8392
|
if (!Array.isArray(blinded)) throw new Error("expected array");
|
|
6859
8393
|
const skS = Fn.fromBytes(secretKey);
|
|
6860
|
-
const pkS =
|
|
6861
|
-
const blindedPoints = blinded.map(
|
|
8394
|
+
const pkS = wirePoint("public key", publicKey);
|
|
8395
|
+
const blindedPoints = blinded.map((i) => wirePoint("blinded", i));
|
|
6862
8396
|
const evaluated = blindedPoints.map((i) => i.multiply(skS));
|
|
6863
8397
|
const proof = generateProof(ctxVOPRF, skS, pkS, blindedPoints, evaluated, rng);
|
|
6864
8398
|
return {
|
|
@@ -6875,7 +8409,7 @@ function createORPF(opts) {
|
|
|
6875
8409
|
},
|
|
6876
8410
|
finalizeBatch(items, publicKey, proof) {
|
|
6877
8411
|
if (!Array.isArray(items)) throw new Error("expected array");
|
|
6878
|
-
verifyProof(ctxVOPRF,
|
|
8412
|
+
verifyProof(ctxVOPRF, wirePoint("public key", publicKey), items.map((i) => wirePoint("blinded", i.blinded)), items.map((i) => wirePoint("evaluated", i.evaluated)), proof);
|
|
6879
8413
|
return items.map((i) => oprf.finalize(i.input, i.blind, i.evaluated));
|
|
6880
8414
|
},
|
|
6881
8415
|
finalize(input, blind, evaluated, blinded, publicKey, proof) {
|
|
@@ -6887,15 +8421,17 @@ function createORPF(opts) {
|
|
|
6887
8421
|
}], publicKey, proof)[0];
|
|
6888
8422
|
},
|
|
6889
8423
|
evaluate: (secretKey, input) => evaluate(ctxVOPRF, secretKey, input)
|
|
6890
|
-
};
|
|
8424
|
+
});
|
|
6891
8425
|
const poprf = (info) => {
|
|
8426
|
+
info = inputBytes("info", info);
|
|
6892
8427
|
const m = hashToScalarPrefixed(encode("Info", info), ctxPOPRF);
|
|
6893
8428
|
const T = Point.BASE.multiply(m);
|
|
6894
|
-
return {
|
|
8429
|
+
return Object.freeze({
|
|
6895
8430
|
generateKeyPair,
|
|
6896
8431
|
deriveKeyPair: (seed, keyInfo) => deriveKeyPair(ctxPOPRF, seed, keyInfo),
|
|
6897
8432
|
blind(input, publicKey, rng = randomBytes) {
|
|
6898
|
-
|
|
8433
|
+
input = inputBytes("input", input);
|
|
8434
|
+
const pkS = wirePoint("public key", publicKey);
|
|
6899
8435
|
const tweakedKey = T.add(pkS);
|
|
6900
8436
|
if (tweakedKey.equals(Point.ZERO)) throw new Error("tweakedKey point at infinity");
|
|
6901
8437
|
const blind = randomScalar(rng);
|
|
@@ -6913,7 +8449,7 @@ function createORPF(opts) {
|
|
|
6913
8449
|
const skS = Fn.fromBytes(secretKey);
|
|
6914
8450
|
const t = Fn.add(skS, m);
|
|
6915
8451
|
const invT = Fn.inv(t);
|
|
6916
|
-
const blindedPoints = blinded.map(
|
|
8452
|
+
const blindedPoints = blinded.map((i) => wirePoint("blinded", i));
|
|
6917
8453
|
const evalPoints = blindedPoints.map((i) => i.multiply(invT));
|
|
6918
8454
|
const proof = generateProof(ctxPOPRF, t, Point.BASE.multiply(t), evalPoints, blindedPoints, rng);
|
|
6919
8455
|
return {
|
|
@@ -6930,12 +8466,13 @@ function createORPF(opts) {
|
|
|
6930
8466
|
},
|
|
6931
8467
|
finalizeBatch(items, proof, tweakedKey) {
|
|
6932
8468
|
if (!Array.isArray(items)) throw new Error("expected array");
|
|
6933
|
-
const
|
|
6934
|
-
|
|
8469
|
+
const inputs = items.map((i) => inputBytes("input", i.input));
|
|
8470
|
+
const evalPoints = items.map((i) => wirePoint("evaluated", i.evaluated));
|
|
8471
|
+
verifyProof(ctxPOPRF, wirePoint("tweakedKey", tweakedKey), evalPoints, items.map((i) => wirePoint("blinded", i.blinded)), proof);
|
|
6935
8472
|
return items.map((i, j) => {
|
|
6936
8473
|
const blind = Fn.fromBytes(i.blind);
|
|
6937
8474
|
const point = evalPoints[j].multiply(Fn.inv(blind)).toBytes();
|
|
6938
|
-
return hashInput(
|
|
8475
|
+
return hashInput(inputs[j], info, point);
|
|
6939
8476
|
});
|
|
6940
8477
|
},
|
|
6941
8478
|
finalize(input, blind, evaluated, blinded, proof, tweakedKey) {
|
|
@@ -6947,22 +8484,25 @@ function createORPF(opts) {
|
|
|
6947
8484
|
}], proof, tweakedKey)[0];
|
|
6948
8485
|
},
|
|
6949
8486
|
evaluate(secretKey, input) {
|
|
8487
|
+
input = inputBytes("input", input);
|
|
6950
8488
|
const skS = Fn.fromBytes(secretKey);
|
|
6951
8489
|
const inputPoint = hashToGroup(input, ctxPOPRF);
|
|
6952
8490
|
if (inputPoint.equals(Point.ZERO)) throw new Error("Input point at infinity");
|
|
6953
8491
|
const t = Fn.add(skS, m);
|
|
6954
8492
|
const invT = Fn.inv(t);
|
|
6955
|
-
|
|
8493
|
+
const unblinded = inputPoint.multiply(invT).toBytes();
|
|
8494
|
+
return hashInput(input, info, unblinded);
|
|
6956
8495
|
}
|
|
6957
|
-
};
|
|
8496
|
+
});
|
|
6958
8497
|
};
|
|
6959
|
-
|
|
8498
|
+
const res = {
|
|
6960
8499
|
name,
|
|
6961
8500
|
oprf,
|
|
6962
8501
|
voprf,
|
|
6963
8502
|
poprf,
|
|
6964
|
-
__tests: { Fn }
|
|
6965
|
-
}
|
|
8503
|
+
__tests: Object.freeze({ Fn })
|
|
8504
|
+
};
|
|
8505
|
+
return Object.freeze(res);
|
|
6966
8506
|
}
|
|
6967
8507
|
|
|
6968
8508
|
//#endregion
|
|
@@ -6975,9 +8515,9 @@ function createORPF(opts) {
|
|
|
6975
8515
|
* @module
|
|
6976
8516
|
*/
|
|
6977
8517
|
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
|
6978
|
-
const _0n = /* @__PURE__ */ BigInt(0), _1n = BigInt(1), _2n = BigInt(2), _3n = /* @__PURE__ */ BigInt(3);
|
|
6979
|
-
const _5n = BigInt(5), _8n = BigInt(8);
|
|
6980
|
-
const ed25519_CURVE_p = BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
8518
|
+
const _0n = /* @__PURE__ */ BigInt(0), _1n = /* @__PURE__ */ BigInt(1), _2n = /* @__PURE__ */ BigInt(2), _3n = /* @__PURE__ */ BigInt(3);
|
|
8519
|
+
const _5n = /* @__PURE__ */ BigInt(5), _8n = /* @__PURE__ */ BigInt(8);
|
|
8520
|
+
const ed25519_CURVE_p = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
6981
8521
|
const ed25519_CURVE = {
|
|
6982
8522
|
p: ed25519_CURVE_p,
|
|
6983
8523
|
n: BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),
|
|
@@ -7031,26 +8571,59 @@ const ed25519_Point = /* @__PURE__ */ edwards(ed25519_CURVE, { uvRatio });
|
|
|
7031
8571
|
const Fp = ed25519_Point.Fp;
|
|
7032
8572
|
const Fn = ed25519_Point.Fn;
|
|
7033
8573
|
function ed$1(opts) {
|
|
7034
|
-
return eddsa(ed25519_Point, sha512, Object.assign({
|
|
8574
|
+
return eddsa(ed25519_Point, sha512, Object.assign({
|
|
8575
|
+
adjustScalarBytes,
|
|
8576
|
+
zip215: true
|
|
8577
|
+
}, opts));
|
|
7035
8578
|
}
|
|
7036
8579
|
/**
|
|
7037
8580
|
* ed25519 curve with EdDSA signatures.
|
|
8581
|
+
* Seeded `keygen(seed)` / `utils.randomSecretKey(seed)` reuse the provided
|
|
8582
|
+
* 32-byte seed buffer instead of copying it.
|
|
7038
8583
|
* @example
|
|
8584
|
+
* Generate one Ed25519 keypair, sign a message, and verify it.
|
|
8585
|
+
*
|
|
7039
8586
|
* ```js
|
|
7040
8587
|
* import { ed25519 } from '@noble/curves/ed25519.js';
|
|
7041
8588
|
* const { secretKey, publicKey } = ed25519.keygen();
|
|
7042
8589
|
* // const publicKey = ed25519.getPublicKey(secretKey);
|
|
7043
8590
|
* const msg = new TextEncoder().encode('hello noble');
|
|
7044
8591
|
* const sig = ed25519.sign(msg, secretKey);
|
|
7045
|
-
* const isValid = ed25519.verify(sig, msg,
|
|
8592
|
+
* const isValid = ed25519.verify(sig, msg, publicKey); // ZIP215
|
|
7046
8593
|
* // RFC8032 / FIPS 186-5
|
|
7047
|
-
* const isValid2 = ed25519.verify(sig, msg,
|
|
8594
|
+
* const isValid2 = ed25519.verify(sig, msg, publicKey, { zip215: false });
|
|
7048
8595
|
* ```
|
|
7049
8596
|
*/
|
|
7050
8597
|
const ed25519 = /* @__PURE__ */ ed$1({});
|
|
7051
8598
|
/**
|
|
8599
|
+
* FROST threshold signatures over ed25519. RFC 9591.
|
|
8600
|
+
* @example
|
|
8601
|
+
* Create one trusted-dealer package for 2-of-3 ed25519 signing.
|
|
8602
|
+
*
|
|
8603
|
+
* ```ts
|
|
8604
|
+
* const alice = ed25519_FROST.Identifier.derive('alice@example.com');
|
|
8605
|
+
* const bob = ed25519_FROST.Identifier.derive('bob@example.com');
|
|
8606
|
+
* const carol = ed25519_FROST.Identifier.derive('carol@example.com');
|
|
8607
|
+
* const deal = ed25519_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);
|
|
8608
|
+
* ```
|
|
8609
|
+
*/
|
|
8610
|
+
const ed25519_FROST = createFROST({
|
|
8611
|
+
name: "FROST-ED25519-SHA512-v1",
|
|
8612
|
+
Point: ed25519_Point,
|
|
8613
|
+
validatePoint: (p) => {
|
|
8614
|
+
p.assertValidity();
|
|
8615
|
+
if (!p.isTorsionFree()) throw new Error("bad point: not torsion-free");
|
|
8616
|
+
},
|
|
8617
|
+
hash: sha512,
|
|
8618
|
+
H2: ""
|
|
8619
|
+
});
|
|
8620
|
+
/**
|
|
7052
8621
|
* ECDH using curve25519 aka x25519.
|
|
8622
|
+
* `getSharedSecret()` rejects low-order peer inputs by default, and seeded
|
|
8623
|
+
* `keygen(seed)` reuses the provided 32-byte seed buffer instead of copying it.
|
|
7053
8624
|
* @example
|
|
8625
|
+
* Derive one shared secret between two X25519 peers.
|
|
8626
|
+
*
|
|
7054
8627
|
* ```js
|
|
7055
8628
|
* import { x25519 } from '@noble/curves/ed25519.js';
|
|
7056
8629
|
* const alice = x25519.keygen();
|
|
@@ -7145,7 +8718,17 @@ function map_to_curve_elligator2_edwards25519(u) {
|
|
|
7145
8718
|
y: Fp.mul(yn, yd_inv)
|
|
7146
8719
|
};
|
|
7147
8720
|
}
|
|
7148
|
-
/**
|
|
8721
|
+
/**
|
|
8722
|
+
* Hashing to ed25519 points / field. RFC 9380 methods.
|
|
8723
|
+
* Public `mapToCurve()` returns the cofactor-cleared subgroup point; the
|
|
8724
|
+
* internal map callback below consumes one field element bigint, not `[bigint]`.
|
|
8725
|
+
* @example
|
|
8726
|
+
* Hash one message onto the ed25519 curve.
|
|
8727
|
+
*
|
|
8728
|
+
* ```ts
|
|
8729
|
+
* const point = ed25519_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
8730
|
+
* ```
|
|
8731
|
+
*/
|
|
7149
8732
|
const ed25519_hasher = createHasher(ed25519_Point, (scalars) => map_to_curve_elligator2_edwards25519(scalars[0]), {
|
|
7150
8733
|
DST: "edwards25519_XMD:SHA-512_ELL2_RO_",
|
|
7151
8734
|
encodeDST: "edwards25519_XMD:SHA-512_ELL2_NU_",
|
|
@@ -7165,8 +8748,9 @@ const MAX_255B = /* @__PURE__ */ BigInt("0x7ffffffffffffffffffffffffffffffffffff
|
|
|
7165
8748
|
const bytes255ToNumberLE = (bytes) => Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
|
7166
8749
|
/**
|
|
7167
8750
|
* Computes Elligator map for Ristretto255.
|
|
7168
|
-
*
|
|
7169
|
-
*
|
|
8751
|
+
* Primary formula source is RFC 9496 §4.3.4 MAP; RFC 9380 Appendix B builds
|
|
8752
|
+
* `hash_to_ristretto255` on top of this helper.
|
|
8753
|
+
* Returns an internal Edwards representative, not a public `_RistrettoPoint`.
|
|
7170
8754
|
*/
|
|
7171
8755
|
function calcElligatorRistrettoMap(r0) {
|
|
7172
8756
|
const { d } = ed25519_CURVE;
|
|
@@ -7206,6 +8790,12 @@ var _RistrettoPoint = class _RistrettoPoint extends PrimeEdwardsPoint {
|
|
|
7206
8790
|
constructor(ep) {
|
|
7207
8791
|
super(ep);
|
|
7208
8792
|
}
|
|
8793
|
+
/**
|
|
8794
|
+
* Create one Ristretto255 point from affine Edwards coordinates.
|
|
8795
|
+
* This wraps the internal Edwards representative directly and is not a
|
|
8796
|
+
* canonical ristretto255 decoding path.
|
|
8797
|
+
* Use `toBytes()` / `fromBytes()` if canonical ristretto255 bytes matter.
|
|
8798
|
+
*/
|
|
7209
8799
|
static fromAffine(ap) {
|
|
7210
8800
|
return new _RistrettoPoint(ed25519_Point.fromAffine(ap));
|
|
7211
8801
|
}
|
|
@@ -7216,7 +8806,7 @@ var _RistrettoPoint = class _RistrettoPoint extends PrimeEdwardsPoint {
|
|
|
7216
8806
|
return new _RistrettoPoint(ep);
|
|
7217
8807
|
}
|
|
7218
8808
|
static fromBytes(bytes) {
|
|
7219
|
-
abytes(bytes, 32);
|
|
8809
|
+
abytes$1(bytes, 32);
|
|
7220
8810
|
const { a, d } = ed25519_CURVE;
|
|
7221
8811
|
const P = ed25519_CURVE_p;
|
|
7222
8812
|
const mod = (n) => Fp.create(n);
|
|
@@ -7241,10 +8831,10 @@ var _RistrettoPoint = class _RistrettoPoint extends PrimeEdwardsPoint {
|
|
|
7241
8831
|
/**
|
|
7242
8832
|
* Converts ristretto-encoded string to ristretto point.
|
|
7243
8833
|
* Described in [RFC9496](https://www.rfc-editor.org/rfc/rfc9496#name-decode).
|
|
7244
|
-
* @param hex Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
|
8834
|
+
* @param hex - Ristretto-encoded 32 bytes. Not every 32-byte string is valid ristretto encoding
|
|
7245
8835
|
*/
|
|
7246
8836
|
static fromHex(hex) {
|
|
7247
|
-
return _RistrettoPoint.fromBytes(hexToBytes(hex));
|
|
8837
|
+
return _RistrettoPoint.fromBytes(hexToBytes$2(hex));
|
|
7248
8838
|
}
|
|
7249
8839
|
/**
|
|
7250
8840
|
* Encodes ristretto point to Uint8Array.
|
|
@@ -7290,11 +8880,26 @@ var _RistrettoPoint = class _RistrettoPoint extends PrimeEdwardsPoint {
|
|
|
7290
8880
|
return this.equals(_RistrettoPoint.ZERO);
|
|
7291
8881
|
}
|
|
7292
8882
|
};
|
|
7293
|
-
|
|
7294
|
-
|
|
8883
|
+
Object.freeze(_RistrettoPoint.BASE);
|
|
8884
|
+
Object.freeze(_RistrettoPoint.ZERO);
|
|
8885
|
+
Object.freeze(_RistrettoPoint.prototype);
|
|
8886
|
+
Object.freeze(_RistrettoPoint);
|
|
8887
|
+
/**
|
|
8888
|
+
* Hashing to ristretto255 points / field. RFC 9380 methods.
|
|
8889
|
+
* `hashToCurve()` is RFC 9380 Appendix B, `deriveToCurve()` is the RFC 9496
|
|
8890
|
+
* §4.3.4 element-derivation building block, and `hashToScalar()` is a
|
|
8891
|
+
* library-specific helper for OPRF-style use.
|
|
8892
|
+
* @example
|
|
8893
|
+
* Hash one message onto ristretto255.
|
|
8894
|
+
*
|
|
8895
|
+
* ```ts
|
|
8896
|
+
* const point = ristretto255_hasher.hashToCurve(new TextEncoder().encode('hello noble'));
|
|
8897
|
+
* ```
|
|
8898
|
+
*/
|
|
8899
|
+
const ristretto255_hasher = Object.freeze({
|
|
7295
8900
|
Point: _RistrettoPoint,
|
|
7296
8901
|
hashToCurve(msg, options) {
|
|
7297
|
-
const xmd = expand_message_xmd(msg, options?.DST
|
|
8902
|
+
const xmd = expand_message_xmd(msg, options?.DST === void 0 ? "ristretto255_XMD:SHA-512_R255MAP_RO_" : options.DST, 64, sha512);
|
|
7298
8903
|
return ristretto255_hasher.deriveToCurve(xmd);
|
|
7299
8904
|
},
|
|
7300
8905
|
hashToScalar(msg, options = { DST: _DST_scalar }) {
|
|
@@ -7302,34 +8907,75 @@ const ristretto255_hasher = {
|
|
|
7302
8907
|
return Fn.create(bytesToNumberLE(xmd));
|
|
7303
8908
|
},
|
|
7304
8909
|
deriveToCurve(bytes) {
|
|
7305
|
-
abytes(bytes, 64);
|
|
8910
|
+
abytes$1(bytes, 64);
|
|
7306
8911
|
const R1 = calcElligatorRistrettoMap(bytes255ToNumberLE(bytes.subarray(0, 32)));
|
|
7307
8912
|
const R2 = calcElligatorRistrettoMap(bytes255ToNumberLE(bytes.subarray(32, 64)));
|
|
7308
8913
|
return new _RistrettoPoint(R1.add(R2));
|
|
7309
8914
|
}
|
|
7310
|
-
};
|
|
7311
|
-
/**
|
|
7312
|
-
|
|
8915
|
+
});
|
|
8916
|
+
/**
|
|
8917
|
+
* ristretto255 OPRF/VOPRF/POPRF bundle, defined in RFC 9497.
|
|
8918
|
+
* @example
|
|
8919
|
+
* Run one blind/evaluate/finalize OPRF round over ristretto255.
|
|
8920
|
+
*
|
|
8921
|
+
* ```ts
|
|
8922
|
+
* const input = new TextEncoder().encode('hello noble');
|
|
8923
|
+
* const keys = ristretto255_oprf.oprf.generateKeyPair();
|
|
8924
|
+
* const blind = ristretto255_oprf.oprf.blind(input);
|
|
8925
|
+
* const evaluated = ristretto255_oprf.oprf.blindEvaluate(keys.secretKey, blind.blinded);
|
|
8926
|
+
* const output = ristretto255_oprf.oprf.finalize(input, blind.blind, evaluated);
|
|
8927
|
+
* ```
|
|
8928
|
+
*/
|
|
8929
|
+
const ristretto255_oprf = createOPRF({
|
|
7313
8930
|
name: "ristretto255-SHA512",
|
|
7314
8931
|
Point: _RistrettoPoint,
|
|
7315
8932
|
hash: sha512,
|
|
7316
8933
|
hashToGroup: ristretto255_hasher.hashToCurve,
|
|
7317
8934
|
hashToScalar: ristretto255_hasher.hashToScalar
|
|
7318
8935
|
});
|
|
8936
|
+
/**
|
|
8937
|
+
* FROST threshold signatures over ristretto255. RFC 9591.
|
|
8938
|
+
* @example
|
|
8939
|
+
* Create one trusted-dealer package for 2-of-3 ristretto255 signing.
|
|
8940
|
+
*
|
|
8941
|
+
* ```ts
|
|
8942
|
+
* const alice = ristretto255_FROST.Identifier.derive('alice@example.com');
|
|
8943
|
+
* const bob = ristretto255_FROST.Identifier.derive('bob@example.com');
|
|
8944
|
+
* const carol = ristretto255_FROST.Identifier.derive('carol@example.com');
|
|
8945
|
+
* const deal = ristretto255_FROST.trustedDealer({ min: 2, max: 3 }, [alice, bob, carol]);
|
|
8946
|
+
* ```
|
|
8947
|
+
*/
|
|
8948
|
+
const ristretto255_FROST = createFROST({
|
|
8949
|
+
name: "FROST-RISTRETTO255-SHA512-v1",
|
|
8950
|
+
Point: _RistrettoPoint,
|
|
8951
|
+
validatePoint: (p) => {
|
|
8952
|
+
p.assertValidity();
|
|
8953
|
+
},
|
|
8954
|
+
hash: sha512
|
|
8955
|
+
});
|
|
7319
8956
|
|
|
7320
8957
|
//#endregion
|
|
7321
|
-
//#region node_modules/@noble/hashes/
|
|
8958
|
+
//#region node_modules/@noble/hashes/hmac.js
|
|
7322
8959
|
/**
|
|
7323
8960
|
* HMAC: RFC2104 message authentication code.
|
|
7324
8961
|
* @module
|
|
7325
8962
|
*/
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
8963
|
+
/**
|
|
8964
|
+
* Internal class for HMAC.
|
|
8965
|
+
* Accepts any byte key, although RFC 2104 §3 recommends keys at least
|
|
8966
|
+
* `HashLen` bytes long.
|
|
8967
|
+
*/
|
|
8968
|
+
var _HMAC = class {
|
|
8969
|
+
oHash;
|
|
8970
|
+
iHash;
|
|
8971
|
+
blockLen;
|
|
8972
|
+
outputLen;
|
|
8973
|
+
canXOF = false;
|
|
8974
|
+
finished = false;
|
|
8975
|
+
destroyed = false;
|
|
8976
|
+
constructor(hash, key) {
|
|
7331
8977
|
ahash(hash);
|
|
7332
|
-
|
|
8978
|
+
abytes$1(key, void 0, "key");
|
|
7333
8979
|
this.iHash = hash.create();
|
|
7334
8980
|
if (typeof this.iHash.update !== "function") throw new Error("Expected instance of class which extends utils.Hash");
|
|
7335
8981
|
this.blockLen = this.iHash.blockLen;
|
|
@@ -7342,20 +8988,21 @@ var HMAC = class extends Hash {
|
|
|
7342
8988
|
this.oHash = hash.create();
|
|
7343
8989
|
for (let i = 0; i < pad.length; i++) pad[i] ^= 106;
|
|
7344
8990
|
this.oHash.update(pad);
|
|
7345
|
-
clean
|
|
8991
|
+
clean(pad);
|
|
7346
8992
|
}
|
|
7347
8993
|
update(buf) {
|
|
7348
|
-
aexists
|
|
8994
|
+
aexists(this);
|
|
7349
8995
|
this.iHash.update(buf);
|
|
7350
8996
|
return this;
|
|
7351
8997
|
}
|
|
7352
8998
|
digestInto(out) {
|
|
7353
|
-
aexists
|
|
7354
|
-
|
|
8999
|
+
aexists(this);
|
|
9000
|
+
aoutput(out, this);
|
|
7355
9001
|
this.finished = true;
|
|
7356
|
-
this.
|
|
7357
|
-
this.
|
|
7358
|
-
this.oHash.
|
|
9002
|
+
const buf = out.subarray(0, this.outputLen);
|
|
9003
|
+
this.iHash.digestInto(buf);
|
|
9004
|
+
this.oHash.update(buf);
|
|
9005
|
+
this.oHash.digestInto(buf);
|
|
7359
9006
|
this.destroy();
|
|
7360
9007
|
}
|
|
7361
9008
|
digest() {
|
|
@@ -7364,7 +9011,7 @@ var HMAC = class extends Hash {
|
|
|
7364
9011
|
return out;
|
|
7365
9012
|
}
|
|
7366
9013
|
_cloneInto(to) {
|
|
7367
|
-
to
|
|
9014
|
+
to ||= Object.create(Object.getPrototypeOf(this), {});
|
|
7368
9015
|
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
|
|
7369
9016
|
to = to;
|
|
7370
9017
|
to.finished = finished;
|
|
@@ -7384,54 +9031,71 @@ var HMAC = class extends Hash {
|
|
|
7384
9031
|
this.iHash.destroy();
|
|
7385
9032
|
}
|
|
7386
9033
|
};
|
|
7387
|
-
|
|
7388
|
-
|
|
7389
|
-
|
|
7390
|
-
|
|
7391
|
-
|
|
7392
|
-
* @example
|
|
7393
|
-
* import { hmac } from '@noble/hashes/hmac';
|
|
7394
|
-
* import { sha256 } from '@noble/hashes/sha2';
|
|
7395
|
-
* const mac1 = hmac(sha256, 'key', 'message');
|
|
7396
|
-
*/
|
|
7397
|
-
const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
|
|
7398
|
-
hmac.create = (hash, key) => new HMAC(hash, key);
|
|
9034
|
+
const hmac = /* @__PURE__ */ (() => {
|
|
9035
|
+
const hmac_ = ((hash, key, message) => new _HMAC(hash, key).update(message).digest());
|
|
9036
|
+
hmac_.create = (hash, key) => new _HMAC(hash, key);
|
|
9037
|
+
return hmac_;
|
|
9038
|
+
})();
|
|
7399
9039
|
|
|
7400
9040
|
//#endregion
|
|
7401
|
-
//#region node_modules/@noble/hashes/
|
|
9041
|
+
//#region node_modules/@noble/hashes/hkdf.js
|
|
7402
9042
|
/**
|
|
7403
9043
|
* HKDF (RFC 5869): extract + expand in one step.
|
|
7404
|
-
* See https://soatok.blog/2021/11/17/understanding-hkdf
|
|
9044
|
+
* See {@link https://soatok.blog/2021/11/17/understanding-hkdf/}.
|
|
7405
9045
|
* @module
|
|
7406
9046
|
*/
|
|
7407
9047
|
/**
|
|
7408
9048
|
* HKDF-extract from spec. Less important part. `HKDF-Extract(IKM, salt) -> PRK`
|
|
7409
9049
|
* Arguments position differs from spec (IKM is first one, since it is not optional)
|
|
9050
|
+
* Local validation only checks `hash`; `ikm` / `salt` byte validation is delegated to `hmac()`.
|
|
7410
9051
|
* @param hash - hash function that would be used (e.g. sha256)
|
|
7411
9052
|
* @param ikm - input keying material, the initial key
|
|
7412
9053
|
* @param salt - optional salt value (a non-secret random value)
|
|
9054
|
+
* @returns Pseudorandom key derived from input keying material.
|
|
9055
|
+
* @example
|
|
9056
|
+
* Run the HKDF extract step.
|
|
9057
|
+
* ```ts
|
|
9058
|
+
* import { extract } from '@noble/hashes/hkdf.js';
|
|
9059
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
9060
|
+
* extract(sha256, new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6]));
|
|
9061
|
+
* ```
|
|
7413
9062
|
*/
|
|
7414
9063
|
function extract(hash, ikm, salt) {
|
|
7415
9064
|
ahash(hash);
|
|
7416
9065
|
if (salt === void 0) salt = new Uint8Array(hash.outputLen);
|
|
7417
|
-
return hmac(hash,
|
|
9066
|
+
return hmac(hash, salt, ikm);
|
|
7418
9067
|
}
|
|
7419
|
-
const HKDF_COUNTER = /* @__PURE__ */ Uint8Array.
|
|
9068
|
+
const HKDF_COUNTER = /* @__PURE__ */ Uint8Array.of(0);
|
|
7420
9069
|
const EMPTY_BUFFER = /* @__PURE__ */ Uint8Array.of();
|
|
7421
9070
|
/**
|
|
7422
9071
|
* HKDF-expand from the spec. The most important part. `HKDF-Expand(PRK, info, L) -> OKM`
|
|
7423
9072
|
* @param hash - hash function that would be used (e.g. sha256)
|
|
7424
|
-
* @param prk - a pseudorandom key of at least HashLen octets
|
|
9073
|
+
* @param prk - a pseudorandom key of at least HashLen octets
|
|
9074
|
+
* (usually, the output from the extract step)
|
|
7425
9075
|
* @param info - optional context and application specific information (can be a zero-length string)
|
|
7426
|
-
* @param length - length of output keying material in bytes
|
|
9076
|
+
* @param length - length of output keying material in bytes.
|
|
9077
|
+
* RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.
|
|
9078
|
+
* @returns Output keying material with the requested length.
|
|
9079
|
+
* @throws If the requested output length exceeds the HKDF limit
|
|
9080
|
+
* for the selected hash. {@link Error}
|
|
9081
|
+
* @example
|
|
9082
|
+
* Run the HKDF expand step.
|
|
9083
|
+
* ```ts
|
|
9084
|
+
* import { expand } from '@noble/hashes/hkdf.js';
|
|
9085
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
9086
|
+
* expand(sha256, new Uint8Array(32), new Uint8Array([1, 2, 3]), 16);
|
|
9087
|
+
* ```
|
|
7427
9088
|
*/
|
|
7428
9089
|
function expand(hash, prk, info, length = 32) {
|
|
7429
9090
|
ahash(hash);
|
|
7430
|
-
anumber$1(length);
|
|
9091
|
+
anumber$1(length, "length");
|
|
9092
|
+
abytes$1(prk, void 0, "prk");
|
|
7431
9093
|
const olen = hash.outputLen;
|
|
7432
|
-
if (length
|
|
9094
|
+
if (prk.length < olen) throw new Error("\"prk\" must be at least HashLen octets");
|
|
9095
|
+
if (length > 255 * olen) throw new Error("Length must be <= 255*HashLen");
|
|
7433
9096
|
const blocks = Math.ceil(length / olen);
|
|
7434
9097
|
if (info === void 0) info = EMPTY_BUFFER;
|
|
9098
|
+
else abytes$1(info, void 0, "info");
|
|
7435
9099
|
const okm = new Uint8Array(blocks * olen);
|
|
7436
9100
|
const HMAC = hmac.create(hash, prk);
|
|
7437
9101
|
const HMACTmp = HMAC._cloneInto();
|
|
@@ -7444,7 +9108,7 @@ function expand(hash, prk, info, length = 32) {
|
|
|
7444
9108
|
}
|
|
7445
9109
|
HMAC.destroy();
|
|
7446
9110
|
HMACTmp.destroy();
|
|
7447
|
-
clean
|
|
9111
|
+
clean(T, HKDF_COUNTER);
|
|
7448
9112
|
return okm.slice(0, length);
|
|
7449
9113
|
}
|
|
7450
9114
|
/**
|
|
@@ -7453,16 +9117,23 @@ function expand(hash, prk, info, length = 32) {
|
|
|
7453
9117
|
* @param hash - hash function that would be used (e.g. sha256)
|
|
7454
9118
|
* @param ikm - input keying material, the initial key
|
|
7455
9119
|
* @param salt - optional salt value (a non-secret random value)
|
|
7456
|
-
* @param info - optional context and application specific information
|
|
7457
|
-
* @param length - length of output keying material in bytes
|
|
9120
|
+
* @param info - optional context and application specific information bytes
|
|
9121
|
+
* @param length - length of output keying material in bytes.
|
|
9122
|
+
* RFC 5869 §2.3 allows `0..255*HashLen`, so `0` returns an empty OKM.
|
|
9123
|
+
* @returns Output keying material derived from the input key.
|
|
9124
|
+
* @throws If the requested output length exceeds the HKDF limit
|
|
9125
|
+
* for the selected hash. {@link Error}
|
|
7458
9126
|
* @example
|
|
7459
|
-
*
|
|
7460
|
-
*
|
|
7461
|
-
* import {
|
|
9127
|
+
* HKDF (RFC 5869): derive keys from an initial input.
|
|
9128
|
+
* ```ts
|
|
9129
|
+
* import { hkdf } from '@noble/hashes/hkdf.js';
|
|
9130
|
+
* import { sha256 } from '@noble/hashes/sha2.js';
|
|
9131
|
+
* import { randomBytes, utf8ToBytes } from '@noble/hashes/utils.js';
|
|
7462
9132
|
* const inputKey = randomBytes(32);
|
|
7463
9133
|
* const salt = randomBytes(32);
|
|
7464
|
-
* const info = 'application-key';
|
|
7465
|
-
* const
|
|
9134
|
+
* const info = utf8ToBytes('application-key');
|
|
9135
|
+
* const okm = hkdf(sha256, inputKey, salt, info, 32);
|
|
9136
|
+
* ```
|
|
7466
9137
|
*/
|
|
7467
9138
|
const hkdf = (hash, ikm, salt, info, length) => expand(hash, extract(hash, ikm, salt), info, length);
|
|
7468
9139
|
|
|
@@ -9016,7 +10687,11 @@ var AbracadabraClient = class {
|
|
|
9016
10687
|
async getDocumentAccess(docId) {
|
|
9017
10688
|
return this.request("GET", `/docs/${encodeURIComponent(docId)}/access`);
|
|
9018
10689
|
}
|
|
9019
|
-
/**
|
|
10690
|
+
/**
|
|
10691
|
+
* Update document metadata (label, description, kind, parent_id). Requires
|
|
10692
|
+
* manage permission on the doc; reparenting additionally requires manage on
|
|
10693
|
+
* the new parent (or admin if moving under the server root).
|
|
10694
|
+
*/
|
|
9020
10695
|
async updateDocumentMeta(docId, opts) {
|
|
9021
10696
|
await this.request("PATCH", `/docs/${encodeURIComponent(docId)}`, { body: opts });
|
|
9022
10697
|
}
|
|
@@ -9464,8 +11139,9 @@ const ConnectionTimeout = {
|
|
|
9464
11139
|
};
|
|
9465
11140
|
|
|
9466
11141
|
//#endregion
|
|
9467
|
-
//#region node_modules/@scure/bip39/
|
|
9468
|
-
|
|
11142
|
+
//#region node_modules/@scure/bip39/wordlists/english.js
|
|
11143
|
+
/** English BIP39 wordlist. */
|
|
11144
|
+
const wordlist = /* @__PURE__ */ Object.freeze(`abandon
|
|
9469
11145
|
ability
|
|
9470
11146
|
able
|
|
9471
11147
|
about
|
|
@@ -11512,7 +13188,7 @@ youth
|
|
|
11512
13188
|
zebra
|
|
11513
13189
|
zero
|
|
11514
13190
|
zone
|
|
11515
|
-
zoo`.split("\n");
|
|
13191
|
+
zoo`.split("\n"));
|
|
11516
13192
|
|
|
11517
13193
|
//#endregion
|
|
11518
13194
|
//#region packages/provider/src/MnemonicKeyDerivation.ts
|
|
@@ -11537,6 +13213,8 @@ zoo`.split("\n");
|
|
|
11537
13213
|
*
|
|
11538
13214
|
* Dependencies: @scure/bip39, @noble/ed25519, @noble/hashes, @noble/curves
|
|
11539
13215
|
*/
|
|
13216
|
+
ed.hashes.sha512 = sha512;
|
|
13217
|
+
ed.hashes.sha512Async = (m) => Promise.resolve(sha512(m));
|
|
11540
13218
|
/** HKDF salt for mnemonic → Ed25519 seed derivation. */
|
|
11541
13219
|
const MNEMONIC_HKDF_SALT = /* @__PURE__ */ new TextEncoder().encode("abracadabra-mnemonic-v1");
|
|
11542
13220
|
/** HKDF info string — intentionally matches the passkey path's HKDF_INFO. */
|
|
@@ -11660,6 +13338,8 @@ async function unwrapSeed(ciphertext, iv, wrappingKeyBytes) {
|
|
|
11660
13338
|
*
|
|
11661
13339
|
* Dependencies: @noble/ed25519, @noble/hashes, @noble/curves, @scure/bip39
|
|
11662
13340
|
*/
|
|
13341
|
+
ed.hashes.sha512 = sha512;
|
|
13342
|
+
ed.hashes.sha512Async = (m) => Promise.resolve(sha512(m));
|
|
11663
13343
|
/**
|
|
11664
13344
|
* Fixed PRF eval salt. Must be constant across all devices so the same synced
|
|
11665
13345
|
* passkey produces the same PRF output everywhere.
|