@blamejs/core 0.18.13 → 0.18.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2 -0
- package/NOTICE +2 -2
- package/lib/middleware/body-parser.js +0 -15
- package/lib/vendor/MANIFEST.json +16 -16
- package/lib/vendor/blamejs-pki.cjs +171 -3
- package/lib/vendor/noble-curves.cjs +954 -858
- package/package.json +1 -1
- package/sbom.cdx.json +6 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// @noble/curves v2.
|
|
1
|
+
// @noble/curves v2.3.0 — vendored from Paul Miller
|
|
2
2
|
// License: MIT — https://github.com/paulmillr/noble-curves
|
|
3
3
|
// Bundled with esbuild. Exports the RFC 9497 OPRF suites:
|
|
4
4
|
// ristretto255_oprf (ristretto255-SHA512), p256_oprf (P-256-SHA256),
|
|
@@ -32,46 +32,89 @@ __export(entry_exports, {
|
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(entry_exports);
|
|
34
34
|
|
|
35
|
+
// node_modules/@noble/hashes/_u64.js
|
|
36
|
+
var U32_MASK64 = /* @__PURE__ */ (() => BigInt(2 ** 32 - 1))();
|
|
37
|
+
var _32n = /* @__PURE__ */ BigInt(32);
|
|
38
|
+
function fromBig(n, le = false) {
|
|
39
|
+
if (le)
|
|
40
|
+
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
41
|
+
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
42
|
+
}
|
|
43
|
+
function split(lst, le = false) {
|
|
44
|
+
const len = lst.length;
|
|
45
|
+
let Ah = new Uint32Array(len);
|
|
46
|
+
let Al = new Uint32Array(len);
|
|
47
|
+
for (let i = 0; i < len; i++) {
|
|
48
|
+
const { h, l } = fromBig(lst[i], le);
|
|
49
|
+
[Ah[i], Al[i]] = [h, l];
|
|
50
|
+
}
|
|
51
|
+
return [Ah, Al];
|
|
52
|
+
}
|
|
53
|
+
var fromNumH = (n) => n / 2 ** 32 | 0;
|
|
54
|
+
var fromNumL = (n) => n >>> 0;
|
|
55
|
+
function setU64FromNum(view, byteOffset, n, isLE) {
|
|
56
|
+
const h = fromNumH(n);
|
|
57
|
+
const l = fromNumL(n);
|
|
58
|
+
view.setUint32(byteOffset, isLE ? l : h, isLE);
|
|
59
|
+
view.setUint32(byteOffset + 4, isLE ? h : l, isLE);
|
|
60
|
+
}
|
|
61
|
+
var shrSH = (h, _l, s) => h >>> s;
|
|
62
|
+
var shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
63
|
+
var rotrSH = (h, l, s) => h >>> s | l << 32 - s;
|
|
64
|
+
var rotrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
65
|
+
var rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
|
|
66
|
+
var rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
|
|
67
|
+
function add(Ah, Al, Bh, Bl) {
|
|
68
|
+
const l = (Al >>> 0) + (Bl >>> 0);
|
|
69
|
+
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
70
|
+
}
|
|
71
|
+
var add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
72
|
+
var add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
73
|
+
var add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
74
|
+
var add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
75
|
+
var add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
76
|
+
var add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
77
|
+
|
|
35
78
|
// node_modules/@noble/hashes/utils.js
|
|
36
79
|
function isBytes(a) {
|
|
37
80
|
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
38
81
|
}
|
|
82
|
+
var atitle = (title) => title ? `"${title}" ` : "";
|
|
39
83
|
function anumber(n, title = "") {
|
|
40
|
-
if (typeof n !== "number")
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
const prefix = title && `"${title}" `;
|
|
46
|
-
throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);
|
|
47
|
-
}
|
|
84
|
+
if (typeof n !== "number")
|
|
85
|
+
throw new TypeError(atitle(title) + "expected number, got " + typeof n);
|
|
86
|
+
if (!Number.isSafeInteger(n) || n < 0)
|
|
87
|
+
throw new RangeError(atitle(title) + "expected integer >= 0, got " + n);
|
|
88
|
+
return n;
|
|
48
89
|
}
|
|
49
90
|
function abytes(value, length, title = "") {
|
|
91
|
+
if (isBytes(value) && (length === void 0 || value.length === length))
|
|
92
|
+
return value;
|
|
93
|
+
if (length !== void 0)
|
|
94
|
+
anumber(length, "length");
|
|
50
95
|
const bytes = isBytes(value);
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
throw new
|
|
61
|
-
|
|
62
|
-
return value;
|
|
63
|
-
}
|
|
96
|
+
const ofLen = length !== void 0 ? ` of length ${length}` : "";
|
|
97
|
+
const got = bytes ? `length=${value.length}` : `type=${typeof value}`;
|
|
98
|
+
const message = atitle(title) + "expected Uint8Array" + ofLen + ", got " + got;
|
|
99
|
+
if (!bytes)
|
|
100
|
+
throw new TypeError(message);
|
|
101
|
+
throw new RangeError(message);
|
|
102
|
+
}
|
|
103
|
+
var aobject = (value, label) => {
|
|
104
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
105
|
+
throw new TypeError((label === "object" ? "" : `"${label}" `) + "expected object, got type=" + typeof value);
|
|
106
|
+
};
|
|
64
107
|
function aexists(instance, checkFinished = true) {
|
|
65
108
|
if (instance.destroyed)
|
|
66
|
-
throw new Error("
|
|
109
|
+
throw new Error("hash was destroyed");
|
|
67
110
|
if (checkFinished && instance.finished)
|
|
68
|
-
throw new Error("
|
|
111
|
+
throw new Error("digest() was already called");
|
|
69
112
|
}
|
|
70
113
|
function aoutput(out, instance) {
|
|
71
|
-
abytes(out, void 0, "
|
|
114
|
+
abytes(out, void 0, "output");
|
|
72
115
|
const min = instance.outputLen;
|
|
73
|
-
if (out.length
|
|
74
|
-
throw new RangeError('"
|
|
116
|
+
if (!(out.length >= min)) {
|
|
117
|
+
throw new RangeError('"output" expected length >= ' + min);
|
|
75
118
|
}
|
|
76
119
|
}
|
|
77
120
|
function clean(...arrays) {
|
|
@@ -100,15 +143,8 @@ function bytesToHex(bytes) {
|
|
|
100
143
|
}
|
|
101
144
|
return hex;
|
|
102
145
|
}
|
|
103
|
-
var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
104
146
|
function asciiToBase16(ch) {
|
|
105
|
-
|
|
106
|
-
return ch - asciis._0;
|
|
107
|
-
if (ch >= asciis.A && ch <= asciis.F)
|
|
108
|
-
return ch - (asciis.A - 10);
|
|
109
|
-
if (ch >= asciis.a && ch <= asciis.f)
|
|
110
|
-
return ch - (asciis.a - 10);
|
|
111
|
-
return;
|
|
147
|
+
return ch >= 48 && ch <= 57 ? ch - 48 : ch >= 65 && ch <= 70 ? ch - (65 - 10) : ch >= 97 && ch <= 102 ? ch - (97 - 10) : void 0;
|
|
112
148
|
}
|
|
113
149
|
function hexToBytes(hex) {
|
|
114
150
|
if (typeof hex !== "string")
|
|
@@ -153,7 +189,17 @@ function concatBytes(...arrays) {
|
|
|
153
189
|
}
|
|
154
190
|
return res;
|
|
155
191
|
}
|
|
192
|
+
function checkOpts(defaults, opts, title = "opts") {
|
|
193
|
+
aobject(defaults, "defaults");
|
|
194
|
+
if (opts !== void 0)
|
|
195
|
+
aobject(opts, title);
|
|
196
|
+
const merged = Object.assign(defaults, opts);
|
|
197
|
+
return merged;
|
|
198
|
+
}
|
|
156
199
|
function createHasher(hashCons, info = {}) {
|
|
200
|
+
if (typeof hashCons !== "function")
|
|
201
|
+
throw new TypeError('"hashCons" expected function, got type=' + typeof hashCons);
|
|
202
|
+
info = checkOpts({}, info, "info");
|
|
157
203
|
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
158
204
|
const tmp = hashCons(void 0);
|
|
159
205
|
hashC.outputLen = tmp.outputLen;
|
|
@@ -211,24 +257,28 @@ var HashMD = class {
|
|
|
211
257
|
abytes(data);
|
|
212
258
|
const { view, buffer, blockLen } = this;
|
|
213
259
|
const len = data.length;
|
|
260
|
+
let processed = false;
|
|
214
261
|
for (let pos = 0; pos < len; ) {
|
|
215
262
|
const take = Math.min(blockLen - this.pos, len - pos);
|
|
216
263
|
if (take === blockLen) {
|
|
217
264
|
const dataView = createView(data);
|
|
218
265
|
for (; blockLen <= len - pos; pos += blockLen)
|
|
219
266
|
this.process(dataView, pos);
|
|
267
|
+
processed = true;
|
|
220
268
|
continue;
|
|
221
269
|
}
|
|
222
|
-
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
270
|
+
buffer.set(pos === 0 && take === len ? data : data.subarray(pos, pos + take), this.pos);
|
|
223
271
|
this.pos += take;
|
|
224
272
|
pos += take;
|
|
225
273
|
if (this.pos === blockLen) {
|
|
226
274
|
this.process(view, 0);
|
|
227
275
|
this.pos = 0;
|
|
276
|
+
processed = true;
|
|
228
277
|
}
|
|
229
278
|
}
|
|
230
279
|
this.length += data.length;
|
|
231
|
-
|
|
280
|
+
if (processed)
|
|
281
|
+
this.roundClean();
|
|
232
282
|
return this;
|
|
233
283
|
}
|
|
234
284
|
digestInto(out) {
|
|
@@ -238,23 +288,20 @@ var HashMD = class {
|
|
|
238
288
|
const { buffer, view, blockLen, isLE } = this;
|
|
239
289
|
let { pos } = this;
|
|
240
290
|
buffer[pos++] = 128;
|
|
241
|
-
|
|
291
|
+
buffer.fill(0, pos);
|
|
242
292
|
if (this.padOffset > blockLen - pos) {
|
|
243
293
|
this.process(view, 0);
|
|
244
|
-
|
|
294
|
+
buffer.fill(0);
|
|
245
295
|
}
|
|
246
|
-
|
|
247
|
-
buffer[i] = 0;
|
|
248
|
-
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
|
|
296
|
+
setU64FromNum(view, blockLen - 8, this.length * 8, isLE);
|
|
249
297
|
this.process(view, 0);
|
|
250
|
-
|
|
298
|
+
this.roundClean();
|
|
299
|
+
const oview = out === buffer ? view : createView(out);
|
|
251
300
|
const len = this.outputLen;
|
|
252
|
-
if (len % 4)
|
|
253
|
-
throw new Error("_sha2: outputLen must be aligned to 32bit");
|
|
254
301
|
const outLen = len / 4;
|
|
255
302
|
const state = this.get();
|
|
256
|
-
if (outLen > state.length)
|
|
257
|
-
throw new Error("
|
|
303
|
+
if (len % 4 || outLen > state.length)
|
|
304
|
+
throw new Error("invalid outputLen");
|
|
258
305
|
for (let i = 0; i < outLen; i++)
|
|
259
306
|
oview.setUint32(4 * i, state[i], isLE);
|
|
260
307
|
}
|
|
@@ -265,15 +312,13 @@ var HashMD = class {
|
|
|
265
312
|
this.destroy();
|
|
266
313
|
return res;
|
|
267
314
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
to.set(...this.get());
|
|
271
|
-
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
315
|
+
_cloneIntoMeta(to) {
|
|
316
|
+
const { buffer, length, finished, destroyed, pos } = this;
|
|
272
317
|
to.destroyed = destroyed;
|
|
273
318
|
to.finished = finished;
|
|
274
319
|
to.length = length;
|
|
275
320
|
to.pos = pos;
|
|
276
|
-
if (
|
|
321
|
+
if (pos)
|
|
277
322
|
to.buffer.set(buffer);
|
|
278
323
|
return to;
|
|
279
324
|
}
|
|
@@ -328,41 +373,6 @@ var SHA512_IV = /* @__PURE__ */ Uint32Array.from([
|
|
|
328
373
|
327033209
|
|
329
374
|
]);
|
|
330
375
|
|
|
331
|
-
// node_modules/@noble/hashes/_u64.js
|
|
332
|
-
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
|
|
333
|
-
var _32n = /* @__PURE__ */ BigInt(32);
|
|
334
|
-
function fromBig(n, le = false) {
|
|
335
|
-
if (le)
|
|
336
|
-
return { h: Number(n & U32_MASK64), l: Number(n >> _32n & U32_MASK64) };
|
|
337
|
-
return { h: Number(n >> _32n & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
|
|
338
|
-
}
|
|
339
|
-
function split(lst, le = false) {
|
|
340
|
-
const len = lst.length;
|
|
341
|
-
let Ah = new Uint32Array(len);
|
|
342
|
-
let Al = new Uint32Array(len);
|
|
343
|
-
for (let i = 0; i < len; i++) {
|
|
344
|
-
const { h, l } = fromBig(lst[i], le);
|
|
345
|
-
[Ah[i], Al[i]] = [h, l];
|
|
346
|
-
}
|
|
347
|
-
return [Ah, Al];
|
|
348
|
-
}
|
|
349
|
-
var shrSH = (h, _l, s) => h >>> s;
|
|
350
|
-
var shrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
351
|
-
var rotrSH = (h, l, s) => h >>> s | l << 32 - s;
|
|
352
|
-
var rotrSL = (h, l, s) => h << 32 - s | l >>> s;
|
|
353
|
-
var rotrBH = (h, l, s) => h << 64 - s | l >>> s - 32;
|
|
354
|
-
var rotrBL = (h, l, s) => h >>> s - 32 | l << 64 - s;
|
|
355
|
-
function add(Ah, Al, Bh, Bl) {
|
|
356
|
-
const l = (Al >>> 0) + (Bl >>> 0);
|
|
357
|
-
return { h: Ah + Bh + (l / 2 ** 32 | 0) | 0, l: l | 0 };
|
|
358
|
-
}
|
|
359
|
-
var add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
|
|
360
|
-
var add3H = (low, Ah, Bh, Ch) => Ah + Bh + Ch + (low / 2 ** 32 | 0) | 0;
|
|
361
|
-
var add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
|
|
362
|
-
var add4H = (low, Ah, Bh, Ch, Dh) => Ah + Bh + Ch + Dh + (low / 2 ** 32 | 0) | 0;
|
|
363
|
-
var add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
|
|
364
|
-
var add5H = (low, Ah, Bh, Ch, Dh, Eh) => Ah + Bh + Ch + Dh + Eh + (low / 2 ** 32 | 0) | 0;
|
|
365
|
-
|
|
366
376
|
// node_modules/@noble/hashes/sha2.js
|
|
367
377
|
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
368
378
|
1116352408,
|
|
@@ -432,8 +442,28 @@ var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
|
432
442
|
]);
|
|
433
443
|
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
434
444
|
var SHA2_32B = class extends HashMD {
|
|
435
|
-
|
|
445
|
+
// We cannot use array here since array allows indexing by variable
|
|
446
|
+
// which means optimizer/compiler cannot use registers.
|
|
447
|
+
// Numeric initializers matter: starting the fields as `undefined` changes
|
|
448
|
+
// V8's field representation and makes sha256 3x slower (measured).
|
|
449
|
+
A = 0;
|
|
450
|
+
B = 0;
|
|
451
|
+
C = 0;
|
|
452
|
+
D = 0;
|
|
453
|
+
E = 0;
|
|
454
|
+
F = 0;
|
|
455
|
+
G = 0;
|
|
456
|
+
H = 0;
|
|
457
|
+
constructor(outputLen, IV) {
|
|
436
458
|
super(64, outputLen, 8, false);
|
|
459
|
+
this.A = IV[0] | 0;
|
|
460
|
+
this.B = IV[1] | 0;
|
|
461
|
+
this.C = IV[2] | 0;
|
|
462
|
+
this.D = IV[3] | 0;
|
|
463
|
+
this.E = IV[4] | 0;
|
|
464
|
+
this.F = IV[5] | 0;
|
|
465
|
+
this.G = IV[6] | 0;
|
|
466
|
+
this.H = IV[7] | 0;
|
|
437
467
|
}
|
|
438
468
|
get() {
|
|
439
469
|
const { A, B, C, D, E, F, G, H } = this;
|
|
@@ -450,6 +480,10 @@ var SHA2_32B = class extends HashMD {
|
|
|
450
480
|
this.G = G | 0;
|
|
451
481
|
this.H = H | 0;
|
|
452
482
|
}
|
|
483
|
+
_cloneInto(to) {
|
|
484
|
+
(to ||= new this.constructor()).set(...this.get());
|
|
485
|
+
return this._cloneIntoMeta(to);
|
|
486
|
+
}
|
|
453
487
|
process(view, offset) {
|
|
454
488
|
for (let i = 0; i < 16; i++, offset += 4)
|
|
455
489
|
SHA256_W[i] = view.getUint32(offset, false);
|
|
@@ -495,18 +529,8 @@ var SHA2_32B = class extends HashMD {
|
|
|
495
529
|
}
|
|
496
530
|
};
|
|
497
531
|
var _SHA256 = class extends SHA2_32B {
|
|
498
|
-
// We cannot use array here since array allows indexing by variable
|
|
499
|
-
// which means optimizer/compiler cannot use registers.
|
|
500
|
-
A = SHA256_IV[0] | 0;
|
|
501
|
-
B = SHA256_IV[1] | 0;
|
|
502
|
-
C = SHA256_IV[2] | 0;
|
|
503
|
-
D = SHA256_IV[3] | 0;
|
|
504
|
-
E = SHA256_IV[4] | 0;
|
|
505
|
-
F = SHA256_IV[5] | 0;
|
|
506
|
-
G = SHA256_IV[6] | 0;
|
|
507
|
-
H = SHA256_IV[7] | 0;
|
|
508
532
|
constructor() {
|
|
509
|
-
super(32);
|
|
533
|
+
super(32, SHA256_IV);
|
|
510
534
|
}
|
|
511
535
|
};
|
|
512
536
|
var K512 = /* @__PURE__ */ (() => split([
|
|
@@ -596,8 +620,45 @@ var SHA512_Kl = /* @__PURE__ */ (() => K512[1])();
|
|
|
596
620
|
var SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
|
|
597
621
|
var SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
|
|
598
622
|
var SHA2_64B = class extends HashMD {
|
|
599
|
-
|
|
623
|
+
// We cannot use array here since array allows indexing by variable
|
|
624
|
+
// which means optimizer/compiler cannot use registers.
|
|
625
|
+
// h -- high 32 bits, l -- low 32 bits
|
|
626
|
+
// Numeric initializers matter: starting the fields as `undefined` changes
|
|
627
|
+
// V8's field representation and slows hashing down (measured on sha256).
|
|
628
|
+
Ah = 0;
|
|
629
|
+
Al = 0;
|
|
630
|
+
Bh = 0;
|
|
631
|
+
Bl = 0;
|
|
632
|
+
Ch = 0;
|
|
633
|
+
Cl = 0;
|
|
634
|
+
Dh = 0;
|
|
635
|
+
Dl = 0;
|
|
636
|
+
Eh = 0;
|
|
637
|
+
El = 0;
|
|
638
|
+
Fh = 0;
|
|
639
|
+
Fl = 0;
|
|
640
|
+
Gh = 0;
|
|
641
|
+
Gl = 0;
|
|
642
|
+
Hh = 0;
|
|
643
|
+
Hl = 0;
|
|
644
|
+
constructor(outputLen, IV) {
|
|
600
645
|
super(128, outputLen, 16, false);
|
|
646
|
+
this.Ah = IV[0] | 0;
|
|
647
|
+
this.Al = IV[1] | 0;
|
|
648
|
+
this.Bh = IV[2] | 0;
|
|
649
|
+
this.Bl = IV[3] | 0;
|
|
650
|
+
this.Ch = IV[4] | 0;
|
|
651
|
+
this.Cl = IV[5] | 0;
|
|
652
|
+
this.Dh = IV[6] | 0;
|
|
653
|
+
this.Dl = IV[7] | 0;
|
|
654
|
+
this.Eh = IV[8] | 0;
|
|
655
|
+
this.El = IV[9] | 0;
|
|
656
|
+
this.Fh = IV[10] | 0;
|
|
657
|
+
this.Fl = IV[11] | 0;
|
|
658
|
+
this.Gh = IV[12] | 0;
|
|
659
|
+
this.Gl = IV[13] | 0;
|
|
660
|
+
this.Hh = IV[14] | 0;
|
|
661
|
+
this.Hl = IV[15] | 0;
|
|
601
662
|
}
|
|
602
663
|
// prettier-ignore
|
|
603
664
|
get() {
|
|
@@ -623,6 +684,10 @@ var SHA2_64B = class extends HashMD {
|
|
|
623
684
|
this.Hh = Hh | 0;
|
|
624
685
|
this.Hl = Hl | 0;
|
|
625
686
|
}
|
|
687
|
+
_cloneInto(to) {
|
|
688
|
+
(to ||= new this.constructor()).set(...this.get());
|
|
689
|
+
return this._cloneIntoMeta(to);
|
|
690
|
+
}
|
|
626
691
|
process(view, offset) {
|
|
627
692
|
for (let i = 0; i < 16; i++, offset += 4) {
|
|
628
693
|
SHA512_W_H[i] = view.getUint32(offset);
|
|
@@ -692,45 +757,13 @@ var SHA2_64B = class extends HashMD {
|
|
|
692
757
|
}
|
|
693
758
|
};
|
|
694
759
|
var _SHA512 = class extends SHA2_64B {
|
|
695
|
-
Ah = SHA512_IV[0] | 0;
|
|
696
|
-
Al = SHA512_IV[1] | 0;
|
|
697
|
-
Bh = SHA512_IV[2] | 0;
|
|
698
|
-
Bl = SHA512_IV[3] | 0;
|
|
699
|
-
Ch = SHA512_IV[4] | 0;
|
|
700
|
-
Cl = SHA512_IV[5] | 0;
|
|
701
|
-
Dh = SHA512_IV[6] | 0;
|
|
702
|
-
Dl = SHA512_IV[7] | 0;
|
|
703
|
-
Eh = SHA512_IV[8] | 0;
|
|
704
|
-
El = SHA512_IV[9] | 0;
|
|
705
|
-
Fh = SHA512_IV[10] | 0;
|
|
706
|
-
Fl = SHA512_IV[11] | 0;
|
|
707
|
-
Gh = SHA512_IV[12] | 0;
|
|
708
|
-
Gl = SHA512_IV[13] | 0;
|
|
709
|
-
Hh = SHA512_IV[14] | 0;
|
|
710
|
-
Hl = SHA512_IV[15] | 0;
|
|
711
760
|
constructor() {
|
|
712
|
-
super(64);
|
|
761
|
+
super(64, SHA512_IV);
|
|
713
762
|
}
|
|
714
763
|
};
|
|
715
764
|
var _SHA384 = class extends SHA2_64B {
|
|
716
|
-
Ah = SHA384_IV[0] | 0;
|
|
717
|
-
Al = SHA384_IV[1] | 0;
|
|
718
|
-
Bh = SHA384_IV[2] | 0;
|
|
719
|
-
Bl = SHA384_IV[3] | 0;
|
|
720
|
-
Ch = SHA384_IV[4] | 0;
|
|
721
|
-
Cl = SHA384_IV[5] | 0;
|
|
722
|
-
Dh = SHA384_IV[6] | 0;
|
|
723
|
-
Dl = SHA384_IV[7] | 0;
|
|
724
|
-
Eh = SHA384_IV[8] | 0;
|
|
725
|
-
El = SHA384_IV[9] | 0;
|
|
726
|
-
Fh = SHA384_IV[10] | 0;
|
|
727
|
-
Fl = SHA384_IV[11] | 0;
|
|
728
|
-
Gh = SHA384_IV[12] | 0;
|
|
729
|
-
Gl = SHA384_IV[13] | 0;
|
|
730
|
-
Hh = SHA384_IV[14] | 0;
|
|
731
|
-
Hl = SHA384_IV[15] | 0;
|
|
732
765
|
constructor() {
|
|
733
|
-
super(48);
|
|
766
|
+
super(48, SHA384_IV);
|
|
734
767
|
}
|
|
735
768
|
};
|
|
736
769
|
var sha256 = /* @__PURE__ */ createHasher(
|
|
@@ -747,8 +780,26 @@ var sha384 = /* @__PURE__ */ createHasher(
|
|
|
747
780
|
);
|
|
748
781
|
|
|
749
782
|
// node_modules/@noble/curves/utils.js
|
|
783
|
+
function aarray(item, title, inner = () => {
|
|
784
|
+
}) {
|
|
785
|
+
if (!Array.isArray(item))
|
|
786
|
+
throw new TypeError(`"${title}" expected array, got type=${typeof item}`);
|
|
787
|
+
for (let i = 0; i < item.length; i++)
|
|
788
|
+
inner(item[i], `${title}[${i}]`);
|
|
789
|
+
return item;
|
|
790
|
+
}
|
|
750
791
|
var abytes2 = (value, length, title) => abytes(value, length, title);
|
|
751
792
|
var anumber2 = anumber;
|
|
793
|
+
function aobject2(value, title = "object") {
|
|
794
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
795
|
+
throw new TypeError(title === "object" ? "expected valid options object" : `"${title}" expected object, got type=${typeof value}`);
|
|
796
|
+
return value;
|
|
797
|
+
}
|
|
798
|
+
function afunction(value, title) {
|
|
799
|
+
if (typeof value !== "function")
|
|
800
|
+
throw new TypeError(`"${title}" is invalid: expected function, got ${typeof value}`);
|
|
801
|
+
return value;
|
|
802
|
+
}
|
|
752
803
|
var bytesToHex2 = bytesToHex;
|
|
753
804
|
var concatBytes2 = (...arrays) => concatBytes(...arrays);
|
|
754
805
|
var hexToBytes2 = (hex) => hexToBytes(hex);
|
|
@@ -756,11 +807,10 @@ var isBytes2 = isBytes;
|
|
|
756
807
|
var randomBytes2 = (bytesLength) => randomBytes(bytesLength);
|
|
757
808
|
var _0n = /* @__PURE__ */ BigInt(0);
|
|
758
809
|
var _1n = /* @__PURE__ */ BigInt(1);
|
|
810
|
+
var atitle2 = (title) => title ? `"${title}" ` : "";
|
|
759
811
|
function abool(value, title = "") {
|
|
760
|
-
if (typeof value !== "boolean")
|
|
761
|
-
|
|
762
|
-
throw new TypeError(prefix + "expected boolean, got type=" + typeof value);
|
|
763
|
-
}
|
|
812
|
+
if (typeof value !== "boolean")
|
|
813
|
+
throw new TypeError(atitle2(title) + "expected boolean, got type=" + typeof value);
|
|
764
814
|
return value;
|
|
765
815
|
}
|
|
766
816
|
function abignumber(n) {
|
|
@@ -781,10 +831,6 @@ function asafenumber(value, title = "") {
|
|
|
781
831
|
throw new RangeError(prefix + "expected safe integer, got " + value);
|
|
782
832
|
}
|
|
783
833
|
}
|
|
784
|
-
function numberToHexUnpadded(num) {
|
|
785
|
-
const hex = abignumber(num).toString(16);
|
|
786
|
-
return hex.length & 1 ? "0" + hex : hex;
|
|
787
|
-
}
|
|
788
834
|
function hexToNumber(hex) {
|
|
789
835
|
if (typeof hex !== "string")
|
|
790
836
|
throw new TypeError("hex string expected, got " + typeof hex);
|
|
@@ -799,12 +845,13 @@ function bytesToNumberLE(bytes) {
|
|
|
799
845
|
function numberToBytesBE(n, len) {
|
|
800
846
|
anumber(len);
|
|
801
847
|
if (len === 0)
|
|
802
|
-
throw new
|
|
848
|
+
throw new Error("zero output length is invalid");
|
|
803
849
|
n = abignumber(n);
|
|
850
|
+
const expectedLen = len * 2;
|
|
804
851
|
const hex = n.toString(16);
|
|
805
|
-
if (hex.length >
|
|
806
|
-
throw new RangeError("number too large");
|
|
807
|
-
return hexToBytes(hex.padStart(
|
|
852
|
+
if (hex.length > expectedLen)
|
|
853
|
+
throw new RangeError("number is too large");
|
|
854
|
+
return hexToBytes(hex.padStart(expectedLen, "0"));
|
|
808
855
|
}
|
|
809
856
|
function numberToBytesLE(n, len) {
|
|
810
857
|
return numberToBytesBE(n, len).reverse();
|
|
@@ -833,7 +880,9 @@ function asciiToBytes(ascii) {
|
|
|
833
880
|
return charCode;
|
|
834
881
|
});
|
|
835
882
|
}
|
|
836
|
-
|
|
883
|
+
function isPosBig(n) {
|
|
884
|
+
return typeof n === "bigint" && _0n <= n;
|
|
885
|
+
}
|
|
837
886
|
function inRange(n, min, max) {
|
|
838
887
|
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
839
888
|
}
|
|
@@ -844,24 +893,27 @@ function aInRange(title, n, min, max) {
|
|
|
844
893
|
function bitLen(n) {
|
|
845
894
|
if (n < _0n)
|
|
846
895
|
throw new Error("expected non-negative bigint, got " + n);
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
function validateObject(object, fields = {}, optFields = {}) {
|
|
854
|
-
|
|
855
|
-
|
|
896
|
+
return n === _0n ? 0 : n.toString(2).length;
|
|
897
|
+
}
|
|
898
|
+
var bitMask = (n) => {
|
|
899
|
+
asafenumber(n, "n");
|
|
900
|
+
return (_1n << BigInt(n)) - _1n;
|
|
901
|
+
};
|
|
902
|
+
function validateObject(object, fields = {}, optFields = {}, title = "object") {
|
|
903
|
+
aobject2(object, title);
|
|
904
|
+
aobject2(fields, "fields");
|
|
905
|
+
aobject2(optFields, "optFields");
|
|
856
906
|
function checkField(fieldName, expectedType, isOpt) {
|
|
857
|
-
|
|
858
|
-
throw new TypeError(`param "${fieldName}" is invalid: expected own property`);
|
|
907
|
+
const label = title === "object" ? `param "${String(fieldName)}"` : `"${title}.${String(fieldName)}"`;
|
|
859
908
|
const val = object[fieldName];
|
|
909
|
+
if (!Object.hasOwn(object, fieldName) && (isOpt ? val !== void 0 : expectedType !== "function")) {
|
|
910
|
+
throw new TypeError(`${label} is invalid: expected own property`);
|
|
911
|
+
}
|
|
860
912
|
if (isOpt && val === void 0)
|
|
861
913
|
return;
|
|
862
914
|
const current = typeof val;
|
|
863
915
|
if (current !== expectedType || val === null)
|
|
864
|
-
throw new TypeError(
|
|
916
|
+
throw new TypeError(`${label} is invalid: expected ${expectedType}, got ${current}`);
|
|
865
917
|
}
|
|
866
918
|
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
|
|
867
919
|
iter(fields, false);
|
|
@@ -881,14 +933,64 @@ var _5n = /* @__PURE__ */ BigInt(5);
|
|
|
881
933
|
var _7n = /* @__PURE__ */ BigInt(7);
|
|
882
934
|
var _8n = /* @__PURE__ */ BigInt(8);
|
|
883
935
|
var _9n = /* @__PURE__ */ BigInt(9);
|
|
936
|
+
var _15n = /* @__PURE__ */ BigInt(15);
|
|
884
937
|
var _16n = /* @__PURE__ */ BigInt(16);
|
|
938
|
+
var POW_WINDOWED_MIN = /* @__PURE__ */ BigInt("0x10000000000000000");
|
|
885
939
|
function mod(a, b) {
|
|
886
940
|
if (b <= _0n2)
|
|
887
941
|
throw new Error("mod: expected positive modulus, got " + b);
|
|
888
942
|
const result = a % b;
|
|
889
943
|
return result >= _0n2 ? result : b + result;
|
|
890
944
|
}
|
|
945
|
+
function pow(num, power, modulo) {
|
|
946
|
+
if (modulo <= _1n2)
|
|
947
|
+
throw new Error("pow: expected modulus > 1, got " + modulo);
|
|
948
|
+
if (typeof power !== "bigint")
|
|
949
|
+
throw new TypeError("invalid exponent: expected bigint, got " + typeof power);
|
|
950
|
+
if (power < _0n2)
|
|
951
|
+
throw new Error("invalid exponent, negatives unsupported");
|
|
952
|
+
if (power === _0n2)
|
|
953
|
+
return _1n2;
|
|
954
|
+
if (power === _1n2)
|
|
955
|
+
return num;
|
|
956
|
+
let d = num % modulo;
|
|
957
|
+
if (d < _0n2)
|
|
958
|
+
d += modulo;
|
|
959
|
+
if (power < POW_WINDOWED_MIN) {
|
|
960
|
+
let p2 = _1n2;
|
|
961
|
+
while (power > _0n2) {
|
|
962
|
+
if (power & _1n2)
|
|
963
|
+
p2 = p2 * d % modulo;
|
|
964
|
+
d = d * d % modulo;
|
|
965
|
+
power >>= _1n2;
|
|
966
|
+
}
|
|
967
|
+
return p2;
|
|
968
|
+
}
|
|
969
|
+
const digits = [];
|
|
970
|
+
while (power > _0n2) {
|
|
971
|
+
digits.push(Number(power & _15n));
|
|
972
|
+
power >>= _4n;
|
|
973
|
+
}
|
|
974
|
+
const table = new Array(16);
|
|
975
|
+
table[0] = _1n2;
|
|
976
|
+
table[1] = d;
|
|
977
|
+
for (let i = 2; i < 16; i++)
|
|
978
|
+
table[i] = table[i - 1] * d % modulo;
|
|
979
|
+
let p = table[digits[digits.length - 1]];
|
|
980
|
+
for (let w = digits.length - 2; w >= 0; w--) {
|
|
981
|
+
p = p * p % modulo;
|
|
982
|
+
p = p * p % modulo;
|
|
983
|
+
p = p * p % modulo;
|
|
984
|
+
p = p * p % modulo;
|
|
985
|
+
const digit = digits[w];
|
|
986
|
+
if (digit !== 0)
|
|
987
|
+
p = p * table[digit] % modulo;
|
|
988
|
+
}
|
|
989
|
+
return p;
|
|
990
|
+
}
|
|
891
991
|
function pow2(x, power, modulo) {
|
|
992
|
+
if (modulo <= _1n2)
|
|
993
|
+
throw new Error("pow2: expected modulus > 1, got " + modulo);
|
|
892
994
|
if (power < _0n2)
|
|
893
995
|
throw new Error("pow2: expected non-negative exponent, got " + power);
|
|
894
996
|
let res = x;
|
|
@@ -901,17 +1003,16 @@ function pow2(x, power, modulo) {
|
|
|
901
1003
|
function invert(number, modulo) {
|
|
902
1004
|
if (number === _0n2)
|
|
903
1005
|
throw new Error("invert: expected non-zero number");
|
|
904
|
-
if (modulo <=
|
|
905
|
-
throw new Error("invert: expected
|
|
1006
|
+
if (modulo <= _1n2)
|
|
1007
|
+
throw new Error("invert: expected modulus > 1, got " + modulo);
|
|
906
1008
|
let a = mod(number, modulo);
|
|
907
1009
|
let b = modulo;
|
|
908
|
-
let x = _0n2,
|
|
1010
|
+
let x = _0n2, u = _1n2;
|
|
909
1011
|
while (a !== _0n2) {
|
|
910
1012
|
const q = b / a;
|
|
911
1013
|
const r = b - a * q;
|
|
912
1014
|
const m = x - u * q;
|
|
913
|
-
|
|
914
|
-
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
1015
|
+
b = a, a = r, x = u, u = m;
|
|
915
1016
|
}
|
|
916
1017
|
const gcd = b;
|
|
917
1018
|
if (gcd !== _1n2)
|
|
@@ -923,6 +1024,10 @@ function assertIsSquare(Fp2, root, n) {
|
|
|
923
1024
|
if (!F.eql(F.sqr(root), n))
|
|
924
1025
|
throw new Error("Cannot find square root");
|
|
925
1026
|
}
|
|
1027
|
+
function aoddModulus(order, fnName) {
|
|
1028
|
+
if ((order & _1n2) === _0n2)
|
|
1029
|
+
throw new Error(fnName + ": expected odd modulus, got " + order);
|
|
1030
|
+
}
|
|
926
1031
|
function sqrt3mod4(Fp2, n) {
|
|
927
1032
|
const F = Fp2;
|
|
928
1033
|
const p1div4 = (F.ORDER + _1n2) / _4n;
|
|
@@ -967,6 +1072,7 @@ function sqrt9mod16(P) {
|
|
|
967
1072
|
function tonelliShanks(P) {
|
|
968
1073
|
if (P < _3n)
|
|
969
1074
|
throw new Error("sqrt is not defined for small field");
|
|
1075
|
+
aoddModulus(P, "tonelliShanks");
|
|
970
1076
|
let Q = P - _1n2;
|
|
971
1077
|
let S = 0;
|
|
972
1078
|
while (Q % _2n === _0n2) {
|
|
@@ -995,7 +1101,7 @@ function tonelliShanks(P) {
|
|
|
995
1101
|
let R = F.pow(n, Q1div2);
|
|
996
1102
|
while (!F.eql(t, F.ONE)) {
|
|
997
1103
|
if (F.is0(t))
|
|
998
|
-
|
|
1104
|
+
throw new Error("Cannot find square root: probably non-prime P");
|
|
999
1105
|
let i = 1;
|
|
1000
1106
|
let t_tmp = F.sqr(t);
|
|
1001
1107
|
while (!F.eql(t_tmp, F.ONE)) {
|
|
@@ -1015,6 +1121,7 @@ function tonelliShanks(P) {
|
|
|
1015
1121
|
};
|
|
1016
1122
|
}
|
|
1017
1123
|
function FpSqrt(P) {
|
|
1124
|
+
aoddModulus(P, "Fp.sqrt");
|
|
1018
1125
|
if (P % _4n === _3n)
|
|
1019
1126
|
return sqrt3mod4;
|
|
1020
1127
|
if (P % _8n === _5n)
|
|
@@ -1044,43 +1151,23 @@ var FIELD_FIELDS = [
|
|
|
1044
1151
|
"sqrN"
|
|
1045
1152
|
];
|
|
1046
1153
|
function validateField(field) {
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
BITS: "number"
|
|
1051
|
-
};
|
|
1052
|
-
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
1053
|
-
map[val] = "function";
|
|
1054
|
-
return map;
|
|
1055
|
-
}, initial);
|
|
1056
|
-
validateObject(field, opts);
|
|
1154
|
+
aobject2(field, "field");
|
|
1155
|
+
if (typeof field.ORDER !== "bigint")
|
|
1156
|
+
throw new TypeError('param "ORDER" is invalid: expected bigint, got ' + typeof field.ORDER);
|
|
1057
1157
|
asafenumber(field.BYTES, "BYTES");
|
|
1058
1158
|
asafenumber(field.BITS, "BITS");
|
|
1159
|
+
for (const name of FIELD_FIELDS)
|
|
1160
|
+
afunction(field[name], "field." + name);
|
|
1059
1161
|
if (field.BYTES < 1 || field.BITS < 1)
|
|
1060
1162
|
throw new Error("invalid field: expected BYTES/BITS > 0");
|
|
1061
1163
|
if (field.ORDER <= _1n2)
|
|
1062
1164
|
throw new Error("invalid field: expected ORDER > 1, got " + field.ORDER);
|
|
1063
1165
|
return field;
|
|
1064
1166
|
}
|
|
1065
|
-
function FpPow(Fp2, num, power) {
|
|
1066
|
-
const F = Fp2;
|
|
1067
|
-
if (power < _0n2)
|
|
1068
|
-
throw new Error("invalid exponent, negatives unsupported");
|
|
1069
|
-
if (power === _0n2)
|
|
1070
|
-
return F.ONE;
|
|
1071
|
-
if (power === _1n2)
|
|
1072
|
-
return num;
|
|
1073
|
-
let p = F.ONE;
|
|
1074
|
-
let d = num;
|
|
1075
|
-
while (power > _0n2) {
|
|
1076
|
-
if (power & _1n2)
|
|
1077
|
-
p = F.mul(p, d);
|
|
1078
|
-
d = F.sqr(d);
|
|
1079
|
-
power >>= _1n2;
|
|
1080
|
-
}
|
|
1081
|
-
return p;
|
|
1082
|
-
}
|
|
1083
1167
|
function FpInvertBatch(Fp2, nums, passZero = false) {
|
|
1168
|
+
validateField(Fp2);
|
|
1169
|
+
aarray(nums, "nums");
|
|
1170
|
+
abool(passZero, "passZero");
|
|
1084
1171
|
const F = Fp2;
|
|
1085
1172
|
const inverted = new Array(nums.length).fill(passZero ? F.ZERO : void 0);
|
|
1086
1173
|
const multipliedAcc = nums.reduce((acc, num, i) => {
|
|
@@ -1099,7 +1186,9 @@ function FpInvertBatch(Fp2, nums, passZero = false) {
|
|
|
1099
1186
|
return inverted;
|
|
1100
1187
|
}
|
|
1101
1188
|
function FpLegendre(Fp2, n) {
|
|
1189
|
+
validateField(Fp2);
|
|
1102
1190
|
const F = Fp2;
|
|
1191
|
+
aoddModulus(F.ORDER, "FpLegendre");
|
|
1103
1192
|
const p1mod2 = (F.ORDER - _1n2) / _2n;
|
|
1104
1193
|
const powered = F.pow(n, p1mod2);
|
|
1105
1194
|
const yes = F.eql(powered, F.ONE);
|
|
@@ -1122,7 +1211,7 @@ function nLength(n, nBitLength) {
|
|
|
1122
1211
|
throw new Error("invalid n length: expected positive bit length, got " + nBitLength);
|
|
1123
1212
|
const bits = bitLen(n);
|
|
1124
1213
|
if (nBitLength !== void 0 && nBitLength < bits)
|
|
1125
|
-
throw new Error(`invalid n length: expected
|
|
1214
|
+
throw new Error(`invalid n length: expected nBitLength (${nBitLength}) >= bitLen(n) (${bits})`);
|
|
1126
1215
|
const _nBitLength = nBitLength !== void 0 ? nBitLength : bits;
|
|
1127
1216
|
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
1128
1217
|
return { nBitLength: _nBitLength, nByteLength };
|
|
@@ -1199,7 +1288,7 @@ var _Field = class {
|
|
|
1199
1288
|
return mod(lhs * rhs, this.ORDER);
|
|
1200
1289
|
}
|
|
1201
1290
|
pow(num, power) {
|
|
1202
|
-
return
|
|
1291
|
+
return pow(num, power, this.ORDER);
|
|
1203
1292
|
}
|
|
1204
1293
|
div(lhs, rhs) {
|
|
1205
1294
|
return mod(lhs * invert(rhs, this.ORDER), this.ORDER);
|
|
@@ -1253,7 +1342,7 @@ var _Field = class {
|
|
|
1253
1342
|
}
|
|
1254
1343
|
// TODO: we don't need it here, move out to separate fn
|
|
1255
1344
|
invertBatch(lst) {
|
|
1256
|
-
return FpInvertBatch(this, lst);
|
|
1345
|
+
return FpInvertBatch(this, lst, true);
|
|
1257
1346
|
}
|
|
1258
1347
|
// We can't move this out because Fp6, Fp12 implement it
|
|
1259
1348
|
// and it's unclear what to return in there.
|
|
@@ -1262,8 +1351,8 @@ var _Field = class {
|
|
|
1262
1351
|
return condition ? b : a;
|
|
1263
1352
|
}
|
|
1264
1353
|
};
|
|
1265
|
-
Object.freeze(_Field.prototype);
|
|
1266
1354
|
function Field(ORDER, opts = {}) {
|
|
1355
|
+
Object.freeze(_Field.prototype);
|
|
1267
1356
|
return new _Field(ORDER, opts);
|
|
1268
1357
|
}
|
|
1269
1358
|
function getFieldBytesLength(fieldOrder) {
|
|
@@ -1293,274 +1382,348 @@ function mapHashToField(key, fieldOrder, isLE = false) {
|
|
|
1293
1382
|
// node_modules/@noble/curves/abstract/curve.js
|
|
1294
1383
|
var _0n3 = /* @__PURE__ */ BigInt(0);
|
|
1295
1384
|
var _1n3 = /* @__PURE__ */ BigInt(1);
|
|
1385
|
+
var _4n2 = /* @__PURE__ */ BigInt(4);
|
|
1386
|
+
var BLIND_BYTES = 16;
|
|
1387
|
+
var BLIND_BITS = 128;
|
|
1388
|
+
var FW_WINDOW = 5;
|
|
1389
|
+
var TABLE_BYTES_MAX = /* @__PURE__ */ (() => 2 ** 31)();
|
|
1296
1390
|
function validatePointCons(Point) {
|
|
1297
1391
|
const pc = Point;
|
|
1298
1392
|
if (typeof pc !== "function")
|
|
1299
|
-
throw new TypeError("Point
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
fromHex: pc.fromHex
|
|
1306
|
-
}, {
|
|
1307
|
-
Fp: "object",
|
|
1308
|
-
Fn: "object",
|
|
1309
|
-
fromAffine: "function",
|
|
1310
|
-
fromBytes: "function",
|
|
1311
|
-
fromHex: "function"
|
|
1312
|
-
});
|
|
1393
|
+
throw new TypeError('"Point" expected constructor, got type=' + typeof Point);
|
|
1394
|
+
afunction(pc.fromAffine, "Point.fromAffine");
|
|
1395
|
+
afunction(pc.fromBytes, "Point.fromBytes");
|
|
1396
|
+
afunction(pc.fromHex, "Point.fromHex");
|
|
1397
|
+
aobject2(pc.BASE, "Point.BASE");
|
|
1398
|
+
aobject2(pc.ZERO, "Point.ZERO");
|
|
1313
1399
|
validateField(pc.Fp);
|
|
1314
1400
|
validateField(pc.Fn);
|
|
1315
1401
|
}
|
|
1316
|
-
function negateCt(condition, item) {
|
|
1317
|
-
const neg = item.negate();
|
|
1318
|
-
return condition ? neg : item;
|
|
1319
|
-
}
|
|
1320
1402
|
function normalizeZ(c, points) {
|
|
1403
|
+
validatePointCons(c);
|
|
1404
|
+
validateMSMPoints(points, c);
|
|
1321
1405
|
const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
|
|
1322
1406
|
return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
|
|
1323
1407
|
}
|
|
1324
|
-
function validateW(W, bits) {
|
|
1325
|
-
if (!Number.isSafeInteger(W) || W
|
|
1326
|
-
throw new Error("invalid window size, expected [
|
|
1408
|
+
function validateW(W, bits, min = 1) {
|
|
1409
|
+
if (!Number.isSafeInteger(W) || W < min || W > bits)
|
|
1410
|
+
throw new Error("invalid window size, expected [" + min + ".." + bits + "], got W=" + W);
|
|
1327
1411
|
}
|
|
1328
|
-
function
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
const offsetStart = window * windowSize;
|
|
1346
|
-
const offset = offsetStart + Math.abs(wbits) - 1;
|
|
1347
|
-
const isZero = wbits === 0;
|
|
1348
|
-
const isNeg = wbits < 0;
|
|
1349
|
-
const isNegF = window % 2 !== 0;
|
|
1350
|
-
const offsetF = offsetStart;
|
|
1351
|
-
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
|
1412
|
+
function validateTableBytes(numPoints, fpBytes) {
|
|
1413
|
+
const bytes = numPoints * (4 * fpBytes + 128);
|
|
1414
|
+
if (bytes > TABLE_BYTES_MAX)
|
|
1415
|
+
throw new Error("invalid window size: table would need ~" + Math.ceil(bytes / 2 ** 20) + " MiB, max " + TABLE_BYTES_MAX / 2 ** 20 + " MiB");
|
|
1416
|
+
}
|
|
1417
|
+
function probeRandomBytes(randomBytes3, length) {
|
|
1418
|
+
if (randomBytes3 === void 0)
|
|
1419
|
+
return void 0;
|
|
1420
|
+
afunction(randomBytes3, "randomBytes");
|
|
1421
|
+
try {
|
|
1422
|
+
const probe = randomBytes3(length);
|
|
1423
|
+
if (!isBytes2(probe) || probe.length !== length)
|
|
1424
|
+
return void 0;
|
|
1425
|
+
} catch {
|
|
1426
|
+
return void 0;
|
|
1427
|
+
}
|
|
1428
|
+
return randomBytes3;
|
|
1352
1429
|
}
|
|
1353
1430
|
function validateMSMPoints(points, c) {
|
|
1354
|
-
|
|
1355
|
-
throw new Error("array expected");
|
|
1431
|
+
aarray(points, "points");
|
|
1356
1432
|
points.forEach((p, i) => {
|
|
1357
1433
|
if (!(p instanceof c))
|
|
1358
1434
|
throw new Error("invalid point at index " + i);
|
|
1359
1435
|
});
|
|
1360
1436
|
}
|
|
1361
|
-
function validateMSMScalars(scalars, field) {
|
|
1437
|
+
function validateMSMScalars(scalars, field, maxScalar) {
|
|
1362
1438
|
if (!Array.isArray(scalars))
|
|
1363
1439
|
throw new Error("array of scalars expected");
|
|
1364
1440
|
scalars.forEach((s, i) => {
|
|
1365
|
-
|
|
1441
|
+
const ok = maxScalar === void 0 ? field.isValid(s) : isPosBig(s) && s < maxScalar;
|
|
1442
|
+
if (!ok)
|
|
1366
1443
|
throw new Error("invalid scalar at index " + i);
|
|
1367
1444
|
});
|
|
1368
1445
|
}
|
|
1369
|
-
var pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
1370
1446
|
var pointWindowSizes = /* @__PURE__ */ new WeakMap();
|
|
1371
|
-
function
|
|
1447
|
+
function getWindowSize(P) {
|
|
1372
1448
|
return pointWindowSizes.get(P) || 1;
|
|
1373
1449
|
}
|
|
1374
|
-
function
|
|
1450
|
+
function oddMultiples(p, size) {
|
|
1451
|
+
const dbl = p.double();
|
|
1452
|
+
const t = [p];
|
|
1453
|
+
for (let j = 1; j < size; j++)
|
|
1454
|
+
t.push(t[j - 1].add(dbl));
|
|
1455
|
+
return t;
|
|
1456
|
+
}
|
|
1457
|
+
function wnafDigits(n, W) {
|
|
1458
|
+
const size = 2 ** W;
|
|
1459
|
+
const half = size / 2;
|
|
1460
|
+
const mask = BigInt(size - 1);
|
|
1461
|
+
const d = [];
|
|
1462
|
+
while (n > _0n3) {
|
|
1463
|
+
let w = 0;
|
|
1464
|
+
if (n & _1n3) {
|
|
1465
|
+
w = Number(n & mask);
|
|
1466
|
+
if (w >= half)
|
|
1467
|
+
w -= size;
|
|
1468
|
+
n -= BigInt(w);
|
|
1469
|
+
}
|
|
1470
|
+
d.push(w);
|
|
1471
|
+
n >>= _1n3;
|
|
1472
|
+
}
|
|
1473
|
+
return d;
|
|
1474
|
+
}
|
|
1475
|
+
function signedWindowDigits(n, W, windows) {
|
|
1476
|
+
const size = 2 ** W;
|
|
1477
|
+
const half = size / 2;
|
|
1478
|
+
const mask = BigInt(size - 1);
|
|
1479
|
+
const shiftBy = BigInt(W);
|
|
1480
|
+
const d = [];
|
|
1481
|
+
for (let w = 0; w < windows; w++) {
|
|
1482
|
+
let v = Number(n & mask);
|
|
1483
|
+
n >>= shiftBy;
|
|
1484
|
+
if (v > half) {
|
|
1485
|
+
v -= size;
|
|
1486
|
+
n += _1n3;
|
|
1487
|
+
}
|
|
1488
|
+
d.push(v);
|
|
1489
|
+
}
|
|
1375
1490
|
if (n !== _0n3)
|
|
1376
|
-
throw new Error("invalid
|
|
1491
|
+
throw new Error("invalid wnaf");
|
|
1492
|
+
return d;
|
|
1493
|
+
}
|
|
1494
|
+
function wnafWalk(zero, tables, digits) {
|
|
1495
|
+
let max = 0;
|
|
1496
|
+
for (const d of digits)
|
|
1497
|
+
max = Math.max(max, d.length);
|
|
1498
|
+
let acc = zero;
|
|
1499
|
+
for (let bit = max - 1; bit >= 0; bit--) {
|
|
1500
|
+
if (bit !== max - 1)
|
|
1501
|
+
acc = acc.double();
|
|
1502
|
+
for (let i = 0; i < digits.length; i++) {
|
|
1503
|
+
const w = digits[i][bit];
|
|
1504
|
+
if (w) {
|
|
1505
|
+
const item = tables[i][Math.abs(w) - 1 >> 1];
|
|
1506
|
+
acc = acc.add(w < 0 ? item.negate() : item);
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
}
|
|
1510
|
+
return acc;
|
|
1377
1511
|
}
|
|
1378
|
-
var
|
|
1512
|
+
var ScalarMultiplier = class {
|
|
1513
|
+
Point;
|
|
1379
1514
|
BASE;
|
|
1380
1515
|
ZERO;
|
|
1381
|
-
|
|
1516
|
+
randomBytes;
|
|
1517
|
+
wnafPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
1518
|
+
baseCanBeBlinded;
|
|
1382
1519
|
bits;
|
|
1383
1520
|
// Parametrized with a given Point class (not individual point)
|
|
1384
|
-
constructor(Point,
|
|
1521
|
+
constructor(Point, randomBytes3) {
|
|
1522
|
+
validatePointCons(Point);
|
|
1523
|
+
this.randomBytes = probeRandomBytes(randomBytes3, BLIND_BYTES);
|
|
1524
|
+
this.Point = Point;
|
|
1385
1525
|
this.BASE = Point.BASE;
|
|
1386
1526
|
this.ZERO = Point.ZERO;
|
|
1387
|
-
this.
|
|
1388
|
-
this.bits = bits;
|
|
1389
|
-
}
|
|
1390
|
-
// non-const time multiplication ladder
|
|
1391
|
-
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
1392
|
-
let d = elm;
|
|
1393
|
-
while (n > _0n3) {
|
|
1394
|
-
if (n & _1n3)
|
|
1395
|
-
p = p.add(d);
|
|
1396
|
-
d = d.double();
|
|
1397
|
-
n >>= _1n3;
|
|
1398
|
-
}
|
|
1399
|
-
return p;
|
|
1527
|
+
this.bits = Point.Fn.BITS;
|
|
1400
1528
|
}
|
|
1401
1529
|
/**
|
|
1402
|
-
* Creates a wNAF precomputation window
|
|
1403
|
-
*
|
|
1404
|
-
*
|
|
1405
|
-
*
|
|
1406
|
-
* -
|
|
1407
|
-
* - 𝑛 is the bitlength of the curve order.
|
|
1408
|
-
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
1530
|
+
* Creates a signed fixed-window wNAF precomputation table: for every window w, the
|
|
1531
|
+
* multiples `[1..2^(W−1)]⋅2^(w⋅W)⋅P`, flattened. All doublings are baked into the table,
|
|
1532
|
+
* so cached multiplication is additions-only. `windows = ceil(bits/W) + 1`: the extra
|
|
1533
|
+
* window absorbs the final carry of signed-digit recoding.
|
|
1534
|
+
* For a 256-bit curve and W=6, the table is 44⋅32 = 1408 points.
|
|
1409
1535
|
* @param point - Point instance
|
|
1410
1536
|
* @param W - window size
|
|
1411
|
-
* @
|
|
1537
|
+
* @param bits - scalar bitlength the table must cover
|
|
1412
1538
|
*/
|
|
1413
|
-
|
|
1414
|
-
const
|
|
1415
|
-
const
|
|
1416
|
-
|
|
1417
|
-
let base =
|
|
1418
|
-
for (let
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
points.push(base);
|
|
1539
|
+
buildWnafTable(point, W, bits) {
|
|
1540
|
+
const windows = Math.ceil(bits / W) + 1;
|
|
1541
|
+
const half = 2 ** (W - 1);
|
|
1542
|
+
const comp = [];
|
|
1543
|
+
let base = point;
|
|
1544
|
+
for (let w = 0; w < windows; w++) {
|
|
1545
|
+
let acc = base;
|
|
1546
|
+
for (let i = 0; i < half; i++) {
|
|
1547
|
+
comp.push(acc);
|
|
1548
|
+
acc = acc.add(base);
|
|
1424
1549
|
}
|
|
1425
|
-
|
|
1550
|
+
base = comp[comp.length - 1].double();
|
|
1426
1551
|
}
|
|
1427
|
-
return
|
|
1552
|
+
return { W, bits, windows, comp };
|
|
1428
1553
|
}
|
|
1429
1554
|
/**
|
|
1430
|
-
* Implements ec multiplication using precomputed
|
|
1431
|
-
*
|
|
1432
|
-
*
|
|
1555
|
+
* Implements ec multiplication using precomputed signed fixed-window wNAF tables.
|
|
1556
|
+
* Constant-time: fixed window count with one table addition per window — zero digits feed
|
|
1557
|
+
* the fake accumulator — and no doublings; the lookup scans the whole window slice.
|
|
1558
|
+
* Scalar bounds are validated by the public entry points ({@link ScalarMultiplier.mulCT},
|
|
1559
|
+
* {@link ScalarMultiplier.mulCTBlinded}, {@link ScalarMultiplier.mulUnsafe});
|
|
1560
|
+
* signedWindowDigits throws if `n` exceeds the table.
|
|
1433
1561
|
* @returns real and fake (for const-time) points
|
|
1434
1562
|
*/
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1563
|
+
wnafCachedCT(precomputes, n) {
|
|
1564
|
+
const { W, windows, comp } = precomputes;
|
|
1565
|
+
const half = 2 ** (W - 1);
|
|
1566
|
+
const digits = signedWindowDigits(n, W, windows);
|
|
1438
1567
|
let p = this.ZERO;
|
|
1439
1568
|
let f = this.BASE;
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
const
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1569
|
+
for (let w = 0; w < windows; w++) {
|
|
1570
|
+
const digit = digits[w];
|
|
1571
|
+
const start = w * half;
|
|
1572
|
+
const idx = Math.abs(digit) - 1;
|
|
1573
|
+
let sel = comp[start];
|
|
1574
|
+
for (let i = 1; i < half; i++)
|
|
1575
|
+
sel = i === idx ? comp[start + i] : sel;
|
|
1576
|
+
const neg = sel.negate();
|
|
1577
|
+
if (digit === 0)
|
|
1578
|
+
f = f.add(comp[start]);
|
|
1579
|
+
else
|
|
1580
|
+
p = p.add(digit < 0 ? neg : sel);
|
|
1449
1581
|
}
|
|
1450
|
-
assert0(n);
|
|
1451
1582
|
return { p, f };
|
|
1452
1583
|
}
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
1460
|
-
const wo = calcWOpts(W, this.bits);
|
|
1461
|
-
for (let window = 0; window < wo.windows; window++) {
|
|
1462
|
-
if (n === _0n3)
|
|
1463
|
-
break;
|
|
1464
|
-
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
|
1465
|
-
n = nextN;
|
|
1466
|
-
if (isZero) {
|
|
1467
|
-
continue;
|
|
1468
|
-
} else {
|
|
1469
|
-
const item = precomputes[offset];
|
|
1470
|
-
acc = acc.add(isNeg ? item.negate() : item);
|
|
1471
|
-
}
|
|
1472
|
-
}
|
|
1473
|
-
assert0(n);
|
|
1474
|
-
return acc;
|
|
1475
|
-
}
|
|
1476
|
-
getPrecomputes(W, point, transform) {
|
|
1477
|
-
let comp = pointPrecomputes.get(point);
|
|
1584
|
+
// Cache key is point identity plus (W, bits); at most two entries exist per point (public-width
|
|
1585
|
+
// `Fn.BITS` and blinded `Fn.BITS + BLIND_BITS`). Callers must not reuse the same point with
|
|
1586
|
+
// incompatible `transform(...)` layouts and expect a separate cache entry.
|
|
1587
|
+
getWnafPrecomputes(W, point, bits, transform) {
|
|
1588
|
+
let entries = this.wnafPrecomputes.get(point);
|
|
1589
|
+
let comp = entries?.find((entry) => entry.W === W && entry.bits === bits);
|
|
1478
1590
|
if (!comp) {
|
|
1479
|
-
comp = this.
|
|
1480
|
-
if (
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1591
|
+
comp = this.buildWnafTable(point, W, bits);
|
|
1592
|
+
if (typeof transform === "function")
|
|
1593
|
+
comp = { ...comp, comp: transform(comp.comp) };
|
|
1594
|
+
if (!entries) {
|
|
1595
|
+
entries = [];
|
|
1596
|
+
this.wnafPrecomputes.set(point, entries);
|
|
1484
1597
|
}
|
|
1598
|
+
entries.push(comp);
|
|
1485
1599
|
}
|
|
1486
1600
|
return comp;
|
|
1487
1601
|
}
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1602
|
+
assertPoint(point) {
|
|
1603
|
+
if (!(point instanceof this.Point))
|
|
1604
|
+
throw new TypeError('"point" expected Point instance, got type=' + typeof point);
|
|
1491
1605
|
}
|
|
1492
|
-
|
|
1493
|
-
|
|
1606
|
+
// Shared prologue of the constant-time entry points. Rejects scalar 0: in key/signature-style
|
|
1607
|
+
// callers a zero scalar means broken upstream plumbing, and concrete Points already reject it.
|
|
1608
|
+
// Uses inRange instead of Fn.isValidNot0: validateField() only certifies the arithmetic subset.
|
|
1609
|
+
validateMulInput(point, scalar) {
|
|
1610
|
+
this.assertPoint(point);
|
|
1611
|
+
if (!inRange(scalar, _1n3, this.Point.Fn.ORDER))
|
|
1612
|
+
throw new Error("invalid scalar");
|
|
1613
|
+
}
|
|
1614
|
+
// Constant-time dispatch shared by mulCT / mulCTBlinded. Un-precomputed points (W===1, e.g.
|
|
1615
|
+
// ECDH peer keys) skip building a throwaway cached table in favor of a small fixed-window
|
|
1616
|
+
// multiply. `n` must be < 2^bits.
|
|
1617
|
+
runCT(point, n, bits, transform) {
|
|
1618
|
+
const W = getWindowSize(point);
|
|
1494
1619
|
if (W === 1)
|
|
1495
|
-
return this.
|
|
1496
|
-
return this.
|
|
1620
|
+
return this.fixedWindowCT(point, n, bits);
|
|
1621
|
+
return this.wnafCachedCT(this.getWnafPrecomputes(W, point, bits, transform), n);
|
|
1622
|
+
}
|
|
1623
|
+
mulCT(point, scalar, transform) {
|
|
1624
|
+
this.validateMulInput(point, scalar);
|
|
1625
|
+
return this.runCT(point, scalar, this.bits, transform);
|
|
1626
|
+
}
|
|
1627
|
+
mulCTBlinded(point, scalar, transform) {
|
|
1628
|
+
this.validateMulInput(point, scalar);
|
|
1629
|
+
if (this.randomBytes === void 0)
|
|
1630
|
+
throw new Error("randomBytes is required for scalar blinding");
|
|
1631
|
+
const bits = this.Point.Fn.BITS + BLIND_BITS;
|
|
1632
|
+
const blind = this.randomBytes(BLIND_BYTES);
|
|
1633
|
+
if (!isBytes2(blind) || blind.length !== BLIND_BYTES)
|
|
1634
|
+
throw new Error("randomBytes returned invalid byte array");
|
|
1635
|
+
blind[0] = blind[0] & 63 | 128;
|
|
1636
|
+
const n = scalar + bytesToNumberBE(blind) * this.Point.Fn.ORDER;
|
|
1637
|
+
return this.runCT(point, n, bits, transform);
|
|
1497
1638
|
}
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1639
|
+
/**
|
|
1640
|
+
* Constant-time multiplication `n*point` for an un-precomputed point, via a small fixed window.
|
|
1641
|
+
* A cached wNAF table only pays off when reused; a flat 2^FW_WINDOW table (`size-1` adds) is
|
|
1642
|
+
* far cheaper to build for a single use. The point-operation sequence is independent of `n`:
|
|
1643
|
+
* build the table, then per window exactly FW_WINDOW doublings, a data-oblivious scan over
|
|
1644
|
+
* every table entry, and one addition (adds the identity when the window digit is 0 — never
|
|
1645
|
+
* skipped).
|
|
1646
|
+
*
|
|
1647
|
+
* `n` must be `< 2^bits`. Assumes complete addition (adding the identity costs the same as any
|
|
1648
|
+
* add), which holds for the Weierstrass/Edwards point types used here. The table is left in
|
|
1649
|
+
* projective form (no normalizeZ): normalizing this small a table costs more than the
|
|
1650
|
+
* mixed-add savings it would buy for a single multiply.
|
|
1651
|
+
* @returns real point `p`; `f` duplicates it only to match {@link wnafCachedCT}'s return shape
|
|
1652
|
+
* (this path needs no fake accumulator — its op-count is already scalar-independent).
|
|
1653
|
+
*/
|
|
1654
|
+
fixedWindowCT(point, n, bits) {
|
|
1655
|
+
const W = FW_WINDOW;
|
|
1656
|
+
const size = 1 << W;
|
|
1657
|
+
const mask = bitMask(W);
|
|
1658
|
+
const table = new Array(size);
|
|
1659
|
+
table[0] = this.ZERO;
|
|
1660
|
+
for (let i = 1; i < size; i++)
|
|
1661
|
+
table[i] = table[i - 1].add(point);
|
|
1662
|
+
const windows = Math.ceil(bits / W);
|
|
1663
|
+
let acc = this.ZERO;
|
|
1664
|
+
for (let window = windows - 1; window >= 0; window--) {
|
|
1665
|
+
if (window !== windows - 1)
|
|
1666
|
+
for (let d = 0; d < W; d++)
|
|
1667
|
+
acc = acc.double();
|
|
1668
|
+
const digit = Number(n >> BigInt(window * W) & mask);
|
|
1669
|
+
let sel = table[0];
|
|
1670
|
+
for (let i = 1; i < size; i++)
|
|
1671
|
+
sel = i === digit ? table[i] : sel;
|
|
1672
|
+
acc = acc.add(sel);
|
|
1673
|
+
}
|
|
1674
|
+
return { p: acc, f: acc };
|
|
1675
|
+
}
|
|
1676
|
+
shouldBlind(point, cofactor) {
|
|
1677
|
+
if (this.randomBytes === void 0)
|
|
1678
|
+
return false;
|
|
1679
|
+
if (cofactor === _1n3)
|
|
1680
|
+
return true;
|
|
1681
|
+
if (point !== this.BASE)
|
|
1682
|
+
return false;
|
|
1683
|
+
if (this.baseCanBeBlinded === void 0)
|
|
1684
|
+
this.baseCanBeBlinded = this.mulUnsafe(this.BASE, this.Point.Fn.ORDER).is0();
|
|
1685
|
+
return this.baseCanBeBlinded;
|
|
1686
|
+
}
|
|
1687
|
+
mulSecret(point, scalar, cofactor, transform) {
|
|
1688
|
+
return this.shouldBlind(point, cofactor) ? this.mulCTBlinded(point, scalar, transform) : this.mulCT(point, scalar, transform);
|
|
1689
|
+
}
|
|
1690
|
+
mulUnsafe(point, scalar, transform) {
|
|
1691
|
+
this.assertPoint(point);
|
|
1692
|
+
if (!isPosBig(scalar))
|
|
1693
|
+
throw new Error("invalid scalar");
|
|
1694
|
+
const W = getWindowSize(point);
|
|
1695
|
+
if (W === 1 || scalar >= this.Point.Fn.ORDER)
|
|
1696
|
+
return mulAddUnsafe(this.Point, [point], [scalar], true);
|
|
1697
|
+
const precomputes = this.getWnafPrecomputes(W, point, this.bits, transform);
|
|
1698
|
+
return this.wnafCachedCT(precomputes, scalar).p;
|
|
1699
|
+
}
|
|
1700
|
+
// Remembers the window size used for precomputed wNAF multiplication of the given point
|
|
1701
|
+
// and drops any previously built tables. Usually only the base point is precomputed.
|
|
1702
|
+
// W=1 resets the point to the un-precomputed (table-less) paths.
|
|
1703
|
+
// W is additionally capped so tables stay under ~2 GiB ({@link TABLE_BYTES_MAX}).
|
|
1704
|
+
setWindowSize(point, W) {
|
|
1705
|
+
this.assertPoint(point);
|
|
1502
1706
|
validateW(W, this.bits);
|
|
1503
|
-
|
|
1504
|
-
|
|
1707
|
+
const windows = Math.ceil((this.bits + BLIND_BITS) / W) + 1;
|
|
1708
|
+
validateTableBytes(windows * 2 ** (W - 1), this.Point.Fp.BYTES);
|
|
1709
|
+
pointWindowSizes.set(point, W);
|
|
1710
|
+
this.wnafPrecomputes.delete(point);
|
|
1505
1711
|
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1712
|
+
// True when a window size is set: tables themselves are built lazily on first multiply.
|
|
1713
|
+
hasWindowSize(point) {
|
|
1714
|
+
return getWindowSize(point) !== 1;
|
|
1508
1715
|
}
|
|
1509
1716
|
};
|
|
1510
|
-
function
|
|
1511
|
-
|
|
1512
|
-
let p1 = Point.ZERO;
|
|
1513
|
-
let p2 = Point.ZERO;
|
|
1514
|
-
while (k1 > _0n3 || k2 > _0n3) {
|
|
1515
|
-
if (k1 & _1n3)
|
|
1516
|
-
p1 = p1.add(acc);
|
|
1517
|
-
if (k2 & _1n3)
|
|
1518
|
-
p2 = p2.add(acc);
|
|
1519
|
-
acc = acc.double();
|
|
1520
|
-
k1 >>= _1n3;
|
|
1521
|
-
k2 >>= _1n3;
|
|
1522
|
-
}
|
|
1523
|
-
return { p1, p2 };
|
|
1524
|
-
}
|
|
1525
|
-
function pippenger(c, points, scalars) {
|
|
1526
|
-
const fieldN = c.Fn;
|
|
1717
|
+
function mulAddUnsafe(c, points, scalars, allowOversized = false) {
|
|
1718
|
+
validatePointCons(c);
|
|
1527
1719
|
validateMSMPoints(points, c);
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
if (plength !== slength)
|
|
1720
|
+
abool(allowOversized, "allowOversized");
|
|
1721
|
+
validateMSMScalars(scalars, c.Fn, allowOversized ? c.Fn.ORDER ** _4n2 : void 0);
|
|
1722
|
+
if (points.length !== scalars.length)
|
|
1532
1723
|
throw new Error("arrays of points and scalars must have equal length");
|
|
1533
|
-
const
|
|
1534
|
-
const
|
|
1535
|
-
|
|
1536
|
-
if (wbits > 12)
|
|
1537
|
-
windowSize = wbits - 3;
|
|
1538
|
-
else if (wbits > 4)
|
|
1539
|
-
windowSize = wbits - 2;
|
|
1540
|
-
else if (wbits > 0)
|
|
1541
|
-
windowSize = 2;
|
|
1542
|
-
const MASK = bitMask(windowSize);
|
|
1543
|
-
const buckets = new Array(Number(MASK) + 1).fill(zero);
|
|
1544
|
-
const lastBits = Math.floor((fieldN.BITS - 1) / windowSize) * windowSize;
|
|
1545
|
-
let sum = zero;
|
|
1546
|
-
for (let i = lastBits; i >= 0; i -= windowSize) {
|
|
1547
|
-
buckets.fill(zero);
|
|
1548
|
-
for (let j = 0; j < slength; j++) {
|
|
1549
|
-
const scalar = scalars[j];
|
|
1550
|
-
const wbits2 = Number(scalar >> BigInt(i) & MASK);
|
|
1551
|
-
buckets[wbits2] = buckets[wbits2].add(points[j]);
|
|
1552
|
-
}
|
|
1553
|
-
let resI = zero;
|
|
1554
|
-
for (let j = buckets.length - 1, sumI = zero; j > 0; j--) {
|
|
1555
|
-
sumI = sumI.add(buckets[j]);
|
|
1556
|
-
resI = resI.add(sumI);
|
|
1557
|
-
}
|
|
1558
|
-
sum = sum.add(resI);
|
|
1559
|
-
if (i !== 0)
|
|
1560
|
-
for (let j = 0; j < windowSize; j++)
|
|
1561
|
-
sum = sum.double();
|
|
1562
|
-
}
|
|
1563
|
-
return sum;
|
|
1724
|
+
const tables = points.map((p) => oddMultiples(p, 4));
|
|
1725
|
+
const digits = scalars.map((n) => wnafDigits(n, 4));
|
|
1726
|
+
return wnafWalk(c.ZERO, tables, digits);
|
|
1564
1727
|
}
|
|
1565
1728
|
function createField(order, field, isLE) {
|
|
1566
1729
|
if (field) {
|
|
@@ -1573,13 +1736,16 @@ function createField(order, field, isLE) {
|
|
|
1573
1736
|
}
|
|
1574
1737
|
}
|
|
1575
1738
|
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
1739
|
+
if (type !== "weierstrass" && type !== "edwards")
|
|
1740
|
+
throw new Error('expected curve type "weierstrass" or "edwards"');
|
|
1576
1741
|
if (FpFnLE === void 0)
|
|
1577
1742
|
FpFnLE = type === "edwards";
|
|
1578
1743
|
if (!CURVE || typeof CURVE !== "object")
|
|
1579
1744
|
throw new Error(`expected valid ${type} CURVE object`);
|
|
1745
|
+
validateObject(curveOpts);
|
|
1580
1746
|
for (const p of ["p", "n", "h"]) {
|
|
1581
1747
|
const val = CURVE[p];
|
|
1582
|
-
if (!(
|
|
1748
|
+
if (!(isPosBig(val) && val !== _0n3))
|
|
1583
1749
|
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
1584
1750
|
}
|
|
1585
1751
|
const Fp2 = createField(CURVE.p, curveOpts.Fp, FpFnLE);
|
|
@@ -1598,6 +1764,7 @@ function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
|
1598
1764
|
var _0n4 = /* @__PURE__ */ BigInt(0);
|
|
1599
1765
|
var _1n4 = /* @__PURE__ */ BigInt(1);
|
|
1600
1766
|
var _2n2 = /* @__PURE__ */ BigInt(2);
|
|
1767
|
+
var _4n3 = /* @__PURE__ */ BigInt(4);
|
|
1601
1768
|
var _8n2 = /* @__PURE__ */ BigInt(8);
|
|
1602
1769
|
function isEdValidXY(Fp2, CURVE, x, y) {
|
|
1603
1770
|
const x2 = Fp2.sqr(x);
|
|
@@ -1607,14 +1774,24 @@ function isEdValidXY(Fp2, CURVE, x, y) {
|
|
|
1607
1774
|
return Fp2.eql(left, right);
|
|
1608
1775
|
}
|
|
1609
1776
|
function edwards(params, extraOpts = {}) {
|
|
1777
|
+
validateObject(extraOpts, {}, {}, "extraOpts");
|
|
1610
1778
|
const opts = extraOpts;
|
|
1611
1779
|
const validated = createCurveFields("edwards", params, opts, opts.FpFnLE);
|
|
1612
1780
|
const { Fp: Fp2, Fn: Fn2 } = validated;
|
|
1613
1781
|
let CURVE = validated.CURVE;
|
|
1614
1782
|
const { h: cofactor } = CURVE;
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1783
|
+
if (FpLegendre(Fp2, CURVE.a) !== 1)
|
|
1784
|
+
throw new Error("edwards: CURVE.a must be a square in Fp for complete addition formulas");
|
|
1785
|
+
if (FpLegendre(Fp2, CURVE.d) !== -1)
|
|
1786
|
+
throw new Error("edwards: CURVE.d must be a non-square in Fp for complete addition formulas");
|
|
1787
|
+
validateObject(opts, {}, { uvRatio: "function", randomBytes: "function" });
|
|
1788
|
+
const randomBytes3 = opts.randomBytes === void 0 ? randomBytes2 : opts.randomBytes;
|
|
1789
|
+
const MASK = _2n2 << BigInt(Fp2.BYTES * 8) - _1n4;
|
|
1790
|
+
function isOdd(n) {
|
|
1791
|
+
if (!Fp2.isOdd)
|
|
1792
|
+
throw new Error("Field does not have .isOdd()");
|
|
1793
|
+
return Fp2.isOdd(n);
|
|
1794
|
+
}
|
|
1618
1795
|
const uvRatio2 = opts.uvRatio === void 0 ? (u, v) => {
|
|
1619
1796
|
try {
|
|
1620
1797
|
return { isValid: true, value: Fp2.sqrt(Fp2.div(u, v)) };
|
|
@@ -1624,6 +1801,7 @@ function edwards(params, extraOpts = {}) {
|
|
|
1624
1801
|
} : opts.uvRatio;
|
|
1625
1802
|
if (!isEdValidXY(Fp2, CURVE, CURVE.Gx, CURVE.Gy))
|
|
1626
1803
|
throw new Error("bad curve params: generator point");
|
|
1804
|
+
const mulA = Fp2.eql(CURVE.a, Fp2.neg(Fp2.ONE)) ? (x) => Fp2.neg(x) : Fp2.eql(CURVE.a, Fp2.ONE) ? (x) => x : (x) => Fp2.mul(CURVE.a, x);
|
|
1627
1805
|
function acoord(title, n, banZero = false) {
|
|
1628
1806
|
const min = banZero ? _1n4 : _0n4;
|
|
1629
1807
|
aInRange("coordinate " + title, n, min, MASK);
|
|
@@ -1634,14 +1812,9 @@ function edwards(params, extraOpts = {}) {
|
|
|
1634
1812
|
throw new Error("EdwardsPoint expected");
|
|
1635
1813
|
}
|
|
1636
1814
|
class Point {
|
|
1637
|
-
|
|
1638
|
-
static
|
|
1639
|
-
// zero / infinity / identity point
|
|
1640
|
-
static ZERO = new Point(_0n4, _1n4, _1n4, _0n4);
|
|
1641
|
-
// 0, 1, 1, 0
|
|
1642
|
-
// math field
|
|
1815
|
+
static BASE = new Point(CURVE.Gx, CURVE.Gy, Fp2.ONE, Fp2.mul(CURVE.Gx, CURVE.Gy));
|
|
1816
|
+
static ZERO = new Point(Fp2.ZERO, Fp2.ONE, Fp2.ONE, Fp2.ZERO);
|
|
1643
1817
|
static Fp = Fp2;
|
|
1644
|
-
// scalar field
|
|
1645
1818
|
static Fn = Fn2;
|
|
1646
1819
|
X;
|
|
1647
1820
|
Y;
|
|
@@ -1668,7 +1841,7 @@ function edwards(params, extraOpts = {}) {
|
|
|
1668
1841
|
const { x, y } = p || {};
|
|
1669
1842
|
acoord("x", x);
|
|
1670
1843
|
acoord("y", y);
|
|
1671
|
-
return new Point(x, y,
|
|
1844
|
+
return new Point(x, y, Fp2.ONE, Fp2.mul(x, y));
|
|
1672
1845
|
}
|
|
1673
1846
|
// Uses algo from RFC8032 5.1.3.
|
|
1674
1847
|
static fromBytes(bytes, zip215 = false) {
|
|
@@ -1682,18 +1855,18 @@ function edwards(params, extraOpts = {}) {
|
|
|
1682
1855
|
const y = bytesToNumberLE(normed);
|
|
1683
1856
|
const max = zip215 ? MASK : Fp2.ORDER;
|
|
1684
1857
|
aInRange("point.y", y, _0n4, max);
|
|
1685
|
-
const y2 =
|
|
1686
|
-
const u =
|
|
1687
|
-
const v =
|
|
1858
|
+
const y2 = Fp2.sqr(y);
|
|
1859
|
+
const u = Fp2.sub(y2, Fp2.ONE);
|
|
1860
|
+
const v = Fp2.sub(Fp2.mulN(d, y2), a);
|
|
1688
1861
|
let { isValid, value: x } = uvRatio2(u, v);
|
|
1689
1862
|
if (!isValid)
|
|
1690
1863
|
throw new Error("bad point: invalid y coordinate");
|
|
1691
|
-
const isXOdd = (x
|
|
1864
|
+
const isXOdd = isOdd(x);
|
|
1692
1865
|
const isLastByteOdd = (lastByte & 128) !== 0;
|
|
1693
|
-
if (!zip215 && x
|
|
1866
|
+
if (!zip215 && Fp2.is0(x) && isLastByteOdd)
|
|
1694
1867
|
throw new Error("bad point: x=0 and x_0=1");
|
|
1695
1868
|
if (isLastByteOdd !== isXOdd)
|
|
1696
|
-
x =
|
|
1869
|
+
x = Fp2.neg(x);
|
|
1697
1870
|
return Point.fromAffine({ x, y });
|
|
1698
1871
|
}
|
|
1699
1872
|
static fromHex(hex, zip215 = false) {
|
|
@@ -1705,8 +1878,8 @@ function edwards(params, extraOpts = {}) {
|
|
|
1705
1878
|
get y() {
|
|
1706
1879
|
return this.toAffine().y;
|
|
1707
1880
|
}
|
|
1708
|
-
precompute(windowSize =
|
|
1709
|
-
wnaf.
|
|
1881
|
+
precompute(windowSize = 6, isLazy = true) {
|
|
1882
|
+
wnaf.setWindowSize(this, windowSize);
|
|
1710
1883
|
if (!isLazy)
|
|
1711
1884
|
this.multiply(_2n2);
|
|
1712
1885
|
return this;
|
|
@@ -1718,18 +1891,18 @@ function edwards(params, extraOpts = {}) {
|
|
|
1718
1891
|
if (p.is0())
|
|
1719
1892
|
throw new Error("bad point: ZERO");
|
|
1720
1893
|
const { X, Y, Z, T } = p;
|
|
1721
|
-
const X2 =
|
|
1722
|
-
const Y2 =
|
|
1723
|
-
const Z2 =
|
|
1724
|
-
const Z4 =
|
|
1725
|
-
const aX2 =
|
|
1726
|
-
const left =
|
|
1727
|
-
const right =
|
|
1728
|
-
if (left
|
|
1894
|
+
const X2 = Fp2.sqr(X);
|
|
1895
|
+
const Y2 = Fp2.sqr(Y);
|
|
1896
|
+
const Z2 = Fp2.sqr(Z);
|
|
1897
|
+
const Z4 = Fp2.sqr(Z2);
|
|
1898
|
+
const aX2 = Fp2.mul(X2, a);
|
|
1899
|
+
const left = Fp2.mul(Fp2.add(aX2, Y2), Z2);
|
|
1900
|
+
const right = Fp2.add(Z4, Fp2.mul(d, Fp2.mul(X2, Y2)));
|
|
1901
|
+
if (!Fp2.eql(left, right))
|
|
1729
1902
|
throw new Error("bad point: equation left != right (1)");
|
|
1730
|
-
const XY =
|
|
1731
|
-
const ZT =
|
|
1732
|
-
if (XY
|
|
1903
|
+
const XY = Fp2.mul(X, Y);
|
|
1904
|
+
const ZT = Fp2.mul(Z, T);
|
|
1905
|
+
if (!Fp2.eql(XY, ZT))
|
|
1733
1906
|
throw new Error("bad point: equation left != right (2)");
|
|
1734
1907
|
}
|
|
1735
1908
|
// Compare one point to another.
|
|
@@ -1737,37 +1910,36 @@ function edwards(params, extraOpts = {}) {
|
|
|
1737
1910
|
aedpoint(other);
|
|
1738
1911
|
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
1739
1912
|
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
1740
|
-
const X1Z2 =
|
|
1741
|
-
const X2Z1 =
|
|
1742
|
-
const Y1Z2 =
|
|
1743
|
-
const Y2Z1 =
|
|
1744
|
-
return X1Z2
|
|
1913
|
+
const X1Z2 = Fp2.mul(X1, Z2);
|
|
1914
|
+
const X2Z1 = Fp2.mul(X2, Z1);
|
|
1915
|
+
const Y1Z2 = Fp2.mul(Y1, Z2);
|
|
1916
|
+
const Y2Z1 = Fp2.mul(Y2, Z1);
|
|
1917
|
+
return Fp2.eql(X1Z2, X2Z1) && Fp2.eql(Y1Z2, Y2Z1);
|
|
1745
1918
|
}
|
|
1746
1919
|
is0() {
|
|
1747
1920
|
return this.equals(Point.ZERO);
|
|
1748
1921
|
}
|
|
1749
1922
|
negate() {
|
|
1750
|
-
return new Point(
|
|
1923
|
+
return new Point(Fp2.neg(this.X), this.Y, this.Z, Fp2.neg(this.T));
|
|
1751
1924
|
}
|
|
1752
1925
|
// Fast algo for doubling Extended Point.
|
|
1753
1926
|
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
|
|
1754
1927
|
// Cost: 4M + 4S + 1*a + 6add + 1*2.
|
|
1755
1928
|
double() {
|
|
1756
|
-
const { a } = CURVE;
|
|
1757
1929
|
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
1758
|
-
const A =
|
|
1759
|
-
const B =
|
|
1760
|
-
const C =
|
|
1761
|
-
const D =
|
|
1762
|
-
const x1y1 = X1
|
|
1763
|
-
const E =
|
|
1764
|
-
const G = D
|
|
1765
|
-
const F = G
|
|
1766
|
-
const H = D
|
|
1767
|
-
const X3 =
|
|
1768
|
-
const Y3 =
|
|
1769
|
-
const T3 =
|
|
1770
|
-
const Z3 =
|
|
1930
|
+
const A = Fp2.sqr(X1);
|
|
1931
|
+
const B = Fp2.sqr(Y1);
|
|
1932
|
+
const C = Fp2.mul(Fp2.sqr(Z1), _2n2);
|
|
1933
|
+
const D = mulA(A);
|
|
1934
|
+
const x1y1 = Fp2.addN(X1, Y1);
|
|
1935
|
+
const E = Fp2.sub(Fp2.subN(Fp2.sqr(x1y1), A), B);
|
|
1936
|
+
const G = Fp2.addN(D, B);
|
|
1937
|
+
const F = Fp2.subN(G, C);
|
|
1938
|
+
const H = Fp2.subN(D, B);
|
|
1939
|
+
const X3 = Fp2.mul(E, F);
|
|
1940
|
+
const Y3 = Fp2.mul(G, H);
|
|
1941
|
+
const T3 = Fp2.mul(E, H);
|
|
1942
|
+
const Z3 = Fp2.mul(F, G);
|
|
1771
1943
|
return new Point(X3, Y3, Z3, T3);
|
|
1772
1944
|
}
|
|
1773
1945
|
// Fast algo for adding 2 Extended Points.
|
|
@@ -1775,21 +1947,21 @@ function edwards(params, extraOpts = {}) {
|
|
|
1775
1947
|
// Cost: 9M + 1*a + 1*d + 7add.
|
|
1776
1948
|
add(other) {
|
|
1777
1949
|
aedpoint(other);
|
|
1778
|
-
const {
|
|
1950
|
+
const { d } = CURVE;
|
|
1779
1951
|
const { X: X1, Y: Y1, Z: Z1, T: T1 } = this;
|
|
1780
1952
|
const { X: X2, Y: Y2, Z: Z2, T: T2 } = other;
|
|
1781
|
-
const A =
|
|
1782
|
-
const B =
|
|
1783
|
-
const C =
|
|
1784
|
-
const D =
|
|
1785
|
-
const E =
|
|
1786
|
-
const F = D
|
|
1787
|
-
const G = D
|
|
1788
|
-
const H =
|
|
1789
|
-
const X3 =
|
|
1790
|
-
const Y3 =
|
|
1791
|
-
const T3 =
|
|
1792
|
-
const Z3 =
|
|
1953
|
+
const A = Fp2.mul(X1, X2);
|
|
1954
|
+
const B = Fp2.mul(Y1, Y2);
|
|
1955
|
+
const C = Fp2.mul(Fp2.mulN(T1, d), T2);
|
|
1956
|
+
const D = Fp2.mul(Z1, Z2);
|
|
1957
|
+
const E = Fp2.sub(Fp2.subN(Fp2.mulN(Fp2.addN(X1, Y1), Fp2.addN(X2, Y2)), A), B);
|
|
1958
|
+
const F = Fp2.subN(D, C);
|
|
1959
|
+
const G = Fp2.addN(D, C);
|
|
1960
|
+
const H = Fp2.sub(B, mulA(A));
|
|
1961
|
+
const X3 = Fp2.mul(E, F);
|
|
1962
|
+
const Y3 = Fp2.mul(G, H);
|
|
1963
|
+
const T3 = Fp2.mul(E, H);
|
|
1964
|
+
const Z3 = Fp2.mul(F, G);
|
|
1793
1965
|
return new Point(X3, Y3, Z3, T3);
|
|
1794
1966
|
}
|
|
1795
1967
|
subtract(other) {
|
|
@@ -1800,8 +1972,8 @@ function edwards(params, extraOpts = {}) {
|
|
|
1800
1972
|
multiply(scalar) {
|
|
1801
1973
|
if (!Fn2.isValidNot0(scalar))
|
|
1802
1974
|
throw new RangeError("invalid scalar: expected 1 <= sc < curve.n");
|
|
1803
|
-
const { p, f } = wnaf.
|
|
1804
|
-
return
|
|
1975
|
+
const { p, f } = wnaf.mulSecret(this, scalar, cofactor, normalize);
|
|
1976
|
+
return normalize([p, f])[0];
|
|
1805
1977
|
}
|
|
1806
1978
|
// Non-constant-time multiplication. Uses double-and-add algorithm.
|
|
1807
1979
|
// It's faster, but should only be used when you don't care about
|
|
@@ -1815,7 +1987,7 @@ function edwards(params, extraOpts = {}) {
|
|
|
1815
1987
|
return Point.ZERO;
|
|
1816
1988
|
if (this.is0() || scalar === _1n4)
|
|
1817
1989
|
return this;
|
|
1818
|
-
return wnaf.
|
|
1990
|
+
return wnaf.mulUnsafe(this, scalar, normalize);
|
|
1819
1991
|
}
|
|
1820
1992
|
// Checks if point is of small order.
|
|
1821
1993
|
// If you add something to small order point, you will have "dirty"
|
|
@@ -1827,35 +1999,43 @@ function edwards(params, extraOpts = {}) {
|
|
|
1827
1999
|
// Multiplies point by curve order and checks if the result is 0.
|
|
1828
2000
|
// Returns `false` is the point is dirty.
|
|
1829
2001
|
isTorsionFree() {
|
|
1830
|
-
return wnaf.
|
|
2002
|
+
return wnaf.mulUnsafe(this, CURVE.n).is0();
|
|
1831
2003
|
}
|
|
1832
2004
|
// Converts Extended point to default (x, y) coordinates.
|
|
1833
2005
|
// Can accept precomputed Z^-1 - for example, from invertBatch.
|
|
1834
2006
|
toAffine(invertedZ) {
|
|
1835
2007
|
const p = this;
|
|
1836
2008
|
let iz = invertedZ;
|
|
2009
|
+
if (iz != null && typeof iz !== "bigint")
|
|
2010
|
+
throw new TypeError('"invertedZ" expected bigint, got type=' + typeof iz);
|
|
1837
2011
|
const { X, Y, Z } = p;
|
|
1838
2012
|
const is0 = p.is0();
|
|
1839
2013
|
if (iz == null)
|
|
1840
|
-
iz = is0 ? _8n2 : Fp2.inv(Z);
|
|
1841
|
-
const x =
|
|
1842
|
-
const y =
|
|
2014
|
+
iz = is0 ? Fp2.create(_8n2) : Fp2.inv(Z);
|
|
2015
|
+
const x = Fp2.mul(X, iz);
|
|
2016
|
+
const y = Fp2.mul(Y, iz);
|
|
1843
2017
|
const zz = Fp2.mul(Z, iz);
|
|
1844
2018
|
if (is0)
|
|
1845
|
-
return { x:
|
|
1846
|
-
if (zz
|
|
2019
|
+
return { x: Fp2.ZERO, y: Fp2.ONE };
|
|
2020
|
+
if (!Fp2.eql(zz, Fp2.ONE))
|
|
1847
2021
|
throw new Error("invZ was invalid");
|
|
1848
2022
|
return { x, y };
|
|
1849
2023
|
}
|
|
1850
2024
|
clearCofactor() {
|
|
1851
2025
|
if (cofactor === _1n4)
|
|
1852
2026
|
return this;
|
|
2027
|
+
if (cofactor === _2n2)
|
|
2028
|
+
return this.double();
|
|
2029
|
+
if (cofactor === _4n3)
|
|
2030
|
+
return this.double().double();
|
|
2031
|
+
if (cofactor === _8n2)
|
|
2032
|
+
return this.double().double().double();
|
|
1853
2033
|
return this.multiplyUnsafe(cofactor);
|
|
1854
2034
|
}
|
|
1855
2035
|
toBytes() {
|
|
1856
2036
|
const { x, y } = this.toAffine();
|
|
1857
2037
|
const bytes = Fp2.toBytes(y);
|
|
1858
|
-
bytes[bytes.length - 1] |= x
|
|
2038
|
+
bytes[bytes.length - 1] |= isOdd(x) ? 128 : 0;
|
|
1859
2039
|
return bytes;
|
|
1860
2040
|
}
|
|
1861
2041
|
toHex() {
|
|
@@ -1865,9 +2045,10 @@ function edwards(params, extraOpts = {}) {
|
|
|
1865
2045
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
1866
2046
|
}
|
|
1867
2047
|
}
|
|
1868
|
-
const
|
|
1869
|
-
|
|
1870
|
-
|
|
2048
|
+
const normalize = (points) => normalizeZ(Point, points);
|
|
2049
|
+
const wnaf = new ScalarMultiplier(Point, randomBytes3);
|
|
2050
|
+
if (wnaf.bits >= 6)
|
|
2051
|
+
Point.BASE.precompute(6);
|
|
1871
2052
|
Object.freeze(Point.prototype);
|
|
1872
2053
|
Object.freeze(Point);
|
|
1873
2054
|
return Point;
|
|
@@ -1954,6 +2135,11 @@ var PrimeEdwardsPoint = class {
|
|
|
1954
2135
|
};
|
|
1955
2136
|
|
|
1956
2137
|
// node_modules/@noble/curves/abstract/hash-to-curve.js
|
|
2138
|
+
var _0n5 = /* @__PURE__ */ BigInt(0);
|
|
2139
|
+
var _1n5 = /* @__PURE__ */ BigInt(1);
|
|
2140
|
+
var _2n3 = /* @__PURE__ */ BigInt(2);
|
|
2141
|
+
var _3n2 = /* @__PURE__ */ BigInt(3);
|
|
2142
|
+
var _4n4 = /* @__PURE__ */ BigInt(4);
|
|
1957
2143
|
var os2ip = bytesToNumberBE;
|
|
1958
2144
|
function i2osp(value, length) {
|
|
1959
2145
|
asafenumber(value);
|
|
@@ -1987,6 +2173,10 @@ function normDST(DST) {
|
|
|
1987
2173
|
function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
1988
2174
|
abytes2(msg);
|
|
1989
2175
|
asafenumber(lenInBytes);
|
|
2176
|
+
if (typeof H !== "function")
|
|
2177
|
+
throw new Error("expand_message_xmd: expected hash function");
|
|
2178
|
+
asafenumber(H.outputLen, "hash.outputLen");
|
|
2179
|
+
asafenumber(H.blockLen, "hash.blockLen");
|
|
1990
2180
|
DST = normDST(DST);
|
|
1991
2181
|
if (DST.length > 255)
|
|
1992
2182
|
DST = H(concatBytes2(asciiToBytes("H2C-OVERSIZE-DST-"), DST));
|
|
@@ -2010,13 +2200,22 @@ function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
|
2010
2200
|
function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
|
2011
2201
|
abytes2(msg);
|
|
2012
2202
|
asafenumber(lenInBytes);
|
|
2203
|
+
asafenumber(k, "k");
|
|
2204
|
+
if (k < 0)
|
|
2205
|
+
throw new Error("expand_message_xof: invalid k");
|
|
2206
|
+
if (typeof H !== "function")
|
|
2207
|
+
throw new Error("expand_message_xof: expected XOF function");
|
|
2208
|
+
if (typeof H.create !== "function")
|
|
2209
|
+
throw new Error("expand_message_xof: expected XOF create");
|
|
2013
2210
|
DST = normDST(DST);
|
|
2211
|
+
if (lenInBytes < 0 || lenInBytes > 65535)
|
|
2212
|
+
throw new Error("expand_message_xof: invalid lenInBytes");
|
|
2014
2213
|
if (DST.length > 255) {
|
|
2015
2214
|
const dkLen = Math.ceil(2 * k / 8);
|
|
2016
2215
|
DST = H.create({ dkLen }).update(asciiToBytes("H2C-OVERSIZE-DST-")).update(DST).digest();
|
|
2017
2216
|
}
|
|
2018
|
-
if (
|
|
2019
|
-
throw new Error("expand_message_xof: invalid
|
|
2217
|
+
if (DST.length > 255)
|
|
2218
|
+
throw new Error("expand_message_xof: invalid DST");
|
|
2020
2219
|
return H.create({ dkLen: lenInBytes }).update(msg).update(i2osp(lenInBytes, 2)).update(DST).update(i2osp(DST.length, 1)).digest();
|
|
2021
2220
|
}
|
|
2022
2221
|
function hash_to_field(msg, count, options) {
|
|
@@ -2030,10 +2229,16 @@ function hash_to_field(msg, count, options) {
|
|
|
2030
2229
|
asafenumber(hash.outputLen, "valid hash");
|
|
2031
2230
|
abytes2(msg);
|
|
2032
2231
|
asafenumber(count);
|
|
2232
|
+
asafenumber(m, "m");
|
|
2233
|
+
asafenumber(k, "k");
|
|
2234
|
+
if (p <= BigInt(1))
|
|
2235
|
+
throw new Error("hash_to_field: expected valid field characteristic");
|
|
2033
2236
|
if (count < 1)
|
|
2034
2237
|
throw new Error("hash_to_field: expected count >= 1");
|
|
2035
2238
|
if (m < 1)
|
|
2036
2239
|
throw new Error("hash_to_field: expected m >= 1");
|
|
2240
|
+
if (k < 0)
|
|
2241
|
+
throw new Error("hash_to_field: invalid k");
|
|
2037
2242
|
const log2p = p.toString(2).length;
|
|
2038
2243
|
const L = Math.ceil((log2p + k) / 8);
|
|
2039
2244
|
const len_in_bytes = count * m * L;
|
|
@@ -2063,12 +2268,14 @@ var _DST_scalar = "HashToScalar-";
|
|
|
2063
2268
|
function createHasher2(Point, mapToCurve, defaults) {
|
|
2064
2269
|
if (typeof mapToCurve !== "function")
|
|
2065
2270
|
throw new Error("mapToCurve() must be defined");
|
|
2271
|
+
validateObject(defaults);
|
|
2066
2272
|
const snapshot = (src) => Object.freeze({
|
|
2067
2273
|
...src,
|
|
2068
2274
|
DST: isBytes2(src.DST) ? copyBytes(src.DST) : src.DST,
|
|
2069
2275
|
...src.encodeDST === void 0 ? {} : { encodeDST: isBytes2(src.encodeDST) ? copyBytes(src.encodeDST) : src.encodeDST }
|
|
2070
2276
|
});
|
|
2071
2277
|
const safeDefaults = snapshot(defaults);
|
|
2278
|
+
const dstOverride = (options) => options && options.DST !== void 0 ? { DST: options.DST } : void 0;
|
|
2072
2279
|
function map(num) {
|
|
2073
2280
|
return Point.fromAffine(mapToCurve(num));
|
|
2074
2281
|
}
|
|
@@ -2085,15 +2292,15 @@ function createHasher2(Point, mapToCurve, defaults) {
|
|
|
2085
2292
|
},
|
|
2086
2293
|
Point,
|
|
2087
2294
|
hashToCurve(msg, options) {
|
|
2088
|
-
const opts = Object.assign({}, safeDefaults, options);
|
|
2295
|
+
const opts = Object.assign({}, safeDefaults, dstOverride(options));
|
|
2089
2296
|
const u = hash_to_field(msg, 2, opts);
|
|
2090
2297
|
const u0 = map(u[0]);
|
|
2091
2298
|
const u1 = map(u[1]);
|
|
2092
2299
|
return clear(u0.add(u1));
|
|
2093
2300
|
},
|
|
2094
2301
|
encodeToCurve(msg, options) {
|
|
2095
|
-
const optsDst = safeDefaults.encodeDST ? { DST: safeDefaults.encodeDST }
|
|
2096
|
-
const opts = Object.assign({}, safeDefaults, optsDst, options);
|
|
2302
|
+
const optsDst = safeDefaults.encodeDST === void 0 ? {} : { DST: safeDefaults.encodeDST };
|
|
2303
|
+
const opts = Object.assign({}, safeDefaults, optsDst, dstOverride(options));
|
|
2097
2304
|
const u = hash_to_field(msg, 1, opts);
|
|
2098
2305
|
const u0 = map(u[0]);
|
|
2099
2306
|
return clear(u0);
|
|
@@ -2107,6 +2314,8 @@ function createHasher2(Point, mapToCurve, defaults) {
|
|
|
2107
2314
|
}
|
|
2108
2315
|
if (!Array.isArray(scalars))
|
|
2109
2316
|
throw new Error("expected array of bigints");
|
|
2317
|
+
if (scalars.length !== safeDefaults.m)
|
|
2318
|
+
throw new Error(`expected array of ${safeDefaults.m} bigints`);
|
|
2110
2319
|
for (const i of scalars)
|
|
2111
2320
|
if (typeof i !== "bigint")
|
|
2112
2321
|
throw new Error("expected array of bigints");
|
|
@@ -2117,11 +2326,123 @@ function createHasher2(Point, mapToCurve, defaults) {
|
|
|
2117
2326
|
// `HashToScalar-` prefix above unless the caller overrides it per invocation.
|
|
2118
2327
|
hashToScalar(msg, options) {
|
|
2119
2328
|
const N = Point.Fn.ORDER;
|
|
2120
|
-
const opts = Object.assign({}, safeDefaults, {
|
|
2329
|
+
const opts = Object.assign({}, safeDefaults, { DST: _DST_scalar }, dstOverride(options), {
|
|
2330
|
+
p: N,
|
|
2331
|
+
m: 1
|
|
2332
|
+
});
|
|
2121
2333
|
return hash_to_field(msg, 1, opts)[0][0];
|
|
2122
2334
|
}
|
|
2123
2335
|
});
|
|
2124
2336
|
}
|
|
2337
|
+
function SWUFpSqrtRatio(Fp2, Z) {
|
|
2338
|
+
const F = validateField(Fp2);
|
|
2339
|
+
const q = F.ORDER;
|
|
2340
|
+
let l = _0n5;
|
|
2341
|
+
for (let o = q - _1n5; o % _2n3 === _0n5; o /= _2n3)
|
|
2342
|
+
l += _1n5;
|
|
2343
|
+
const c1 = l;
|
|
2344
|
+
const _2n_pow_c1_1 = _2n3 << c1 - _1n5 - _1n5;
|
|
2345
|
+
const _2n_pow_c1 = _2n_pow_c1_1 * _2n3;
|
|
2346
|
+
const c2 = (q - _1n5) / _2n_pow_c1;
|
|
2347
|
+
const c3 = (c2 - _1n5) / _2n3;
|
|
2348
|
+
const c4 = _2n_pow_c1 - _1n5;
|
|
2349
|
+
const c5 = _2n_pow_c1_1;
|
|
2350
|
+
const c6 = F.pow(Z, c2);
|
|
2351
|
+
const c7 = F.pow(Z, (c2 + _1n5) / _2n3);
|
|
2352
|
+
let sqrtRatio = (u, v) => {
|
|
2353
|
+
let tv1 = c6;
|
|
2354
|
+
let tv2 = F.pow(v, c4);
|
|
2355
|
+
let tv3 = F.sqr(tv2);
|
|
2356
|
+
tv3 = F.mul(tv3, v);
|
|
2357
|
+
let tv5 = F.mul(u, tv3);
|
|
2358
|
+
tv5 = F.pow(tv5, c3);
|
|
2359
|
+
tv5 = F.mul(tv5, tv2);
|
|
2360
|
+
tv2 = F.mul(tv5, v);
|
|
2361
|
+
tv3 = F.mul(tv5, u);
|
|
2362
|
+
let tv4 = F.mul(tv3, tv2);
|
|
2363
|
+
tv5 = F.pow(tv4, c5);
|
|
2364
|
+
let isQR = F.eql(tv5, F.ONE);
|
|
2365
|
+
tv2 = F.mul(tv3, c7);
|
|
2366
|
+
tv5 = F.mul(tv4, tv1);
|
|
2367
|
+
tv3 = F.cmov(tv2, tv3, isQR);
|
|
2368
|
+
tv4 = F.cmov(tv5, tv4, isQR);
|
|
2369
|
+
for (let i = c1; i > _1n5; i--) {
|
|
2370
|
+
let tv52 = i - _2n3;
|
|
2371
|
+
tv52 = _2n3 << tv52 - _1n5;
|
|
2372
|
+
let tvv5 = F.pow(tv4, tv52);
|
|
2373
|
+
const e1 = F.eql(tvv5, F.ONE);
|
|
2374
|
+
tv2 = F.mul(tv3, tv1);
|
|
2375
|
+
tv1 = F.mul(tv1, tv1);
|
|
2376
|
+
tvv5 = F.mul(tv4, tv1);
|
|
2377
|
+
tv3 = F.cmov(tv2, tv3, e1);
|
|
2378
|
+
tv4 = F.cmov(tvv5, tv4, e1);
|
|
2379
|
+
}
|
|
2380
|
+
return { isValid: !F.is0(v) && (isQR || F.is0(u)), value: tv3 };
|
|
2381
|
+
};
|
|
2382
|
+
if (F.ORDER % _4n4 === _3n2) {
|
|
2383
|
+
const c12 = (F.ORDER - _3n2) / _4n4;
|
|
2384
|
+
const c22 = F.sqrt(F.neg(Z));
|
|
2385
|
+
sqrtRatio = (u, v) => {
|
|
2386
|
+
let tv1 = F.sqr(v);
|
|
2387
|
+
const tv2 = F.mul(u, v);
|
|
2388
|
+
tv1 = F.mul(tv1, tv2);
|
|
2389
|
+
let y1 = F.pow(tv1, c12);
|
|
2390
|
+
y1 = F.mul(y1, tv2);
|
|
2391
|
+
const y2 = F.mul(y1, c22);
|
|
2392
|
+
const tv3 = F.mul(F.sqr(y1), v);
|
|
2393
|
+
const isQR = F.eql(tv3, u);
|
|
2394
|
+
let y = F.cmov(y2, y1, isQR);
|
|
2395
|
+
return { isValid: !F.is0(v) && isQR, value: y };
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
return sqrtRatio;
|
|
2399
|
+
}
|
|
2400
|
+
function mapToCurveSimpleSWU(Fp2, opts) {
|
|
2401
|
+
const F = validateField(Fp2);
|
|
2402
|
+
validateObject(opts, {}, {}, "opts");
|
|
2403
|
+
const { A, B, Z } = opts;
|
|
2404
|
+
if (!F.isValidNot0(A) || !F.isValidNot0(B) || !F.isValid(Z))
|
|
2405
|
+
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
2406
|
+
if (F.eql(Z, F.neg(F.ONE)) || FpIsSquare(F, Z))
|
|
2407
|
+
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
2408
|
+
const x = F.mul(B, F.inv(F.mul(Z, A)));
|
|
2409
|
+
const gx = F.add(F.add(F.mul(F.sqr(x), x), F.mul(A, x)), B);
|
|
2410
|
+
if (!FpIsSquare(F, gx))
|
|
2411
|
+
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
2412
|
+
const sqrtRatio = SWUFpSqrtRatio(F, Z);
|
|
2413
|
+
if (!F.isOdd)
|
|
2414
|
+
throw new Error("Field does not have .isOdd()");
|
|
2415
|
+
return (u) => {
|
|
2416
|
+
let tv1, tv2, tv3, tv4, tv5, tv6, x2, y;
|
|
2417
|
+
tv1 = F.sqr(u);
|
|
2418
|
+
tv1 = F.mul(tv1, Z);
|
|
2419
|
+
tv2 = F.sqr(tv1);
|
|
2420
|
+
tv2 = F.add(tv2, tv1);
|
|
2421
|
+
tv3 = F.add(tv2, F.ONE);
|
|
2422
|
+
tv3 = F.mul(tv3, B);
|
|
2423
|
+
tv4 = F.cmov(Z, F.neg(tv2), !F.eql(tv2, F.ZERO));
|
|
2424
|
+
tv4 = F.mul(tv4, A);
|
|
2425
|
+
tv2 = F.sqr(tv3);
|
|
2426
|
+
tv6 = F.sqr(tv4);
|
|
2427
|
+
tv5 = F.mul(tv6, A);
|
|
2428
|
+
tv2 = F.add(tv2, tv5);
|
|
2429
|
+
tv2 = F.mul(tv2, tv3);
|
|
2430
|
+
tv6 = F.mul(tv6, tv4);
|
|
2431
|
+
tv5 = F.mul(tv6, B);
|
|
2432
|
+
tv2 = F.add(tv2, tv5);
|
|
2433
|
+
x2 = F.mul(tv1, tv3);
|
|
2434
|
+
const { isValid, value } = sqrtRatio(tv2, tv6);
|
|
2435
|
+
y = F.mul(tv1, u);
|
|
2436
|
+
y = F.mul(y, value);
|
|
2437
|
+
x2 = F.cmov(x2, tv3, isValid);
|
|
2438
|
+
y = F.cmov(y, value, isValid);
|
|
2439
|
+
const e1 = F.isOdd(u) === F.isOdd(y);
|
|
2440
|
+
y = F.cmov(F.neg(y), y, e1);
|
|
2441
|
+
const tv4_inv = FpInvertBatch(F, [tv4], true)[0];
|
|
2442
|
+
x2 = F.mul(x2, tv4_inv);
|
|
2443
|
+
return { x: x2, y };
|
|
2444
|
+
};
|
|
2445
|
+
}
|
|
2125
2446
|
|
|
2126
2447
|
// node_modules/@noble/curves/abstract/oprf.js
|
|
2127
2448
|
var _DST_scalarBytes = /* @__PURE__ */ asciiToBytes(_DST_scalar);
|
|
@@ -2140,10 +2461,12 @@ function createOPRF(opts) {
|
|
|
2140
2461
|
});
|
|
2141
2462
|
const hashToScalarPrefixed = (msg, ctx) => opts.hashToScalar(msg, { DST: concatBytes2(_DST_scalarBytes, ctx) });
|
|
2142
2463
|
const randomScalar = (rng = randomBytes2) => {
|
|
2464
|
+
if (typeof rng !== "function")
|
|
2465
|
+
throw new TypeError('"rng" expected function, got type=' + typeof rng);
|
|
2143
2466
|
const t = mapHashToField(rng(getMinHashLength(Fn2.ORDER)), Fn2.ORDER, Fn2.isLE);
|
|
2144
2467
|
return Fn2.isLE ? bytesToNumberLE(t) : bytesToNumberBE(t);
|
|
2145
2468
|
};
|
|
2146
|
-
const msm = (points, scalars) =>
|
|
2469
|
+
const msm = (points, scalars) => mulAddUnsafe(Point, points, scalars);
|
|
2147
2470
|
const getCtx = (mode) => concatBytes2(asciiToBytes("OPRFV1-"), new Uint8Array([mode]), asciiToBytes("-" + name));
|
|
2148
2471
|
const ctxOPRF = getCtx(0);
|
|
2149
2472
|
const ctxVOPRF = getCtx(1);
|
|
@@ -2210,8 +2533,8 @@ function createOPRF(opts) {
|
|
|
2210
2533
|
abytes2(proof, 2 * Fn2.BYTES);
|
|
2211
2534
|
const { M, Z } = computeComposites(B, C, D, ctx);
|
|
2212
2535
|
const [c, s] = [proof.subarray(0, Fn2.BYTES), proof.subarray(Fn2.BYTES)].map((f) => Fn2.fromBytes(f));
|
|
2213
|
-
const t2 = Point.BASE
|
|
2214
|
-
const t3 = M
|
|
2536
|
+
const t2 = msm([Point.BASE, B], [s, c]);
|
|
2537
|
+
const t3 = msm([M, Z], [s, c]);
|
|
2215
2538
|
const expectedC = challengeTranscript(B, M, Z, t2, t3, ctx);
|
|
2216
2539
|
if (!Fn2.eql(c, expectedC))
|
|
2217
2540
|
throw new Error("proof verification failed");
|
|
@@ -2305,7 +2628,12 @@ function createOPRF(opts) {
|
|
|
2305
2628
|
const blindedPoints = items.map((i) => wirePoint("blinded", i.blinded));
|
|
2306
2629
|
const evalPoints = items.map((i) => wirePoint("evaluated", i.evaluated));
|
|
2307
2630
|
verifyProof(ctxVOPRF, pkS, blindedPoints, evalPoints, proof);
|
|
2308
|
-
return items.map((i) =>
|
|
2631
|
+
return items.map((i, j) => {
|
|
2632
|
+
const input = inputBytes("input", i.input);
|
|
2633
|
+
const blind2 = Fn2.fromBytes(i.blind);
|
|
2634
|
+
const unblinded = evalPoints[j].multiply(Fn2.inv(blind2)).toBytes();
|
|
2635
|
+
return hashInput(input, unblinded);
|
|
2636
|
+
});
|
|
2309
2637
|
},
|
|
2310
2638
|
finalize(input, blind2, evaluated, blinded, publicKey, proof) {
|
|
2311
2639
|
return this.finalizeBatch([{ input, blind: blind2, evaluated, blinded }], publicKey, proof)[0];
|
|
@@ -2313,7 +2641,7 @@ function createOPRF(opts) {
|
|
|
2313
2641
|
evaluate: (secretKey, input) => evaluate(ctxVOPRF, secretKey, input)
|
|
2314
2642
|
});
|
|
2315
2643
|
const poprf = (info) => {
|
|
2316
|
-
info = inputBytes("info", info);
|
|
2644
|
+
info = copyBytes(inputBytes("info", info));
|
|
2317
2645
|
const m = hashToScalarPrefixed(encode("Info", info), ctxPOPRF);
|
|
2318
2646
|
const T = Point.BASE.multiply(m);
|
|
2319
2647
|
return Object.freeze({
|
|
@@ -2385,9 +2713,8 @@ function createOPRF(opts) {
|
|
|
2385
2713
|
}
|
|
2386
2714
|
|
|
2387
2715
|
// node_modules/@noble/curves/ed25519.js
|
|
2388
|
-
var
|
|
2389
|
-
var
|
|
2390
|
-
var _2n3 = /* @__PURE__ */ BigInt(2);
|
|
2716
|
+
var _1n6 = /* @__PURE__ */ BigInt(1);
|
|
2717
|
+
var _2n4 = /* @__PURE__ */ BigInt(2);
|
|
2391
2718
|
var _5n2 = /* @__PURE__ */ BigInt(5);
|
|
2392
2719
|
var _8n3 = /* @__PURE__ */ BigInt(8);
|
|
2393
2720
|
var ed25519_CURVE_p = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed");
|
|
@@ -2405,8 +2732,8 @@ function ed25519_pow_2_252_3(x) {
|
|
|
2405
2732
|
const P = ed25519_CURVE_p;
|
|
2406
2733
|
const x2 = x * x % P;
|
|
2407
2734
|
const b2 = x2 * x % P;
|
|
2408
|
-
const b4 = pow2(b2,
|
|
2409
|
-
const b5 = pow2(b4,
|
|
2735
|
+
const b4 = pow2(b2, _2n4, P) * b2 % P;
|
|
2736
|
+
const b5 = pow2(b4, _1n6, P) * x % P;
|
|
2410
2737
|
const b10 = pow2(b5, _5n2, P) * b5 % P;
|
|
2411
2738
|
const b20 = pow2(b10, _10n, P) * b10 % P;
|
|
2412
2739
|
const b40 = pow2(b20, _20n, P) * b20 % P;
|
|
@@ -2414,7 +2741,7 @@ function ed25519_pow_2_252_3(x) {
|
|
|
2414
2741
|
const b160 = pow2(b80, _80n, P) * b80 % P;
|
|
2415
2742
|
const b240 = pow2(b160, _80n, P) * b80 % P;
|
|
2416
2743
|
const b250 = pow2(b240, _10n, P) * b10 % P;
|
|
2417
|
-
const pow_p_5_8 = pow2(b250,
|
|
2744
|
+
const pow_p_5_8 = pow2(b250, _2n4, P) * x % P;
|
|
2418
2745
|
return { pow_p_5_8, b2 };
|
|
2419
2746
|
}
|
|
2420
2747
|
var ED25519_SQRT_M1 = /* @__PURE__ */ BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");
|
|
@@ -2422,8 +2749,8 @@ function uvRatio(u, v) {
|
|
|
2422
2749
|
const P = ed25519_CURVE_p;
|
|
2423
2750
|
const v3 = mod(v * v * v, P);
|
|
2424
2751
|
const v7 = mod(v3 * v3 * v, P);
|
|
2425
|
-
const
|
|
2426
|
-
let x = mod(u * v3 *
|
|
2752
|
+
const pow3 = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
|
|
2753
|
+
let x = mod(u * v3 * pow3, P);
|
|
2427
2754
|
const vx2 = mod(v * x * x, P);
|
|
2428
2755
|
const root1 = x;
|
|
2429
2756
|
const root2 = mod(x * ED25519_SQRT_M1, P);
|
|
@@ -2446,32 +2773,30 @@ var SQRT_AD_MINUS_ONE = /* @__PURE__ */ BigInt("25063068953384623474111414158702
|
|
|
2446
2773
|
var INVSQRT_A_MINUS_D = /* @__PURE__ */ BigInt("54469307008909316920995813868745141605393597292927456921205312896311721017578");
|
|
2447
2774
|
var ONE_MINUS_D_SQ = /* @__PURE__ */ BigInt("1159843021668779879193775521855586647937357759715417654439879720876111806838");
|
|
2448
2775
|
var D_MINUS_ONE_SQ = /* @__PURE__ */ BigInt("40440834346308536858101042469323190826248399146238708352240133220865137265952");
|
|
2449
|
-
var invertSqrt = (number) => uvRatio(
|
|
2776
|
+
var invertSqrt = (number) => uvRatio(_1n6, number);
|
|
2450
2777
|
var MAX_255B = /* @__PURE__ */ BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
|
2451
2778
|
var bytes255ToNumberLE = (bytes) => Fp.create(bytesToNumberLE(bytes) & MAX_255B);
|
|
2452
2779
|
function calcElligatorRistrettoMap(r0) {
|
|
2453
2780
|
const { d } = ed25519_CURVE;
|
|
2454
|
-
const
|
|
2455
|
-
const
|
|
2456
|
-
const r = mod2(SQRT_M1 * r0 * r0);
|
|
2457
|
-
const Ns = mod2((r + _1n5) * ONE_MINUS_D_SQ);
|
|
2781
|
+
const r = Fp.mul(Fp.mulN(SQRT_M1, r0), r0);
|
|
2782
|
+
const Ns = Fp.mul(Fp.addN(r, _1n6), ONE_MINUS_D_SQ);
|
|
2458
2783
|
let c = BigInt(-1);
|
|
2459
|
-
const D =
|
|
2784
|
+
const D = Fp.mul(Fp.subN(c, Fp.mulN(d, r)), Fp.add(r, d));
|
|
2460
2785
|
let { isValid: Ns_D_is_sq, value: s } = uvRatio(Ns, D);
|
|
2461
|
-
let s_ =
|
|
2462
|
-
if (!
|
|
2463
|
-
s_ =
|
|
2786
|
+
let s_ = Fp.mul(s, r0);
|
|
2787
|
+
if (!Fp.isOdd(s_))
|
|
2788
|
+
s_ = Fp.neg(s_);
|
|
2464
2789
|
if (!Ns_D_is_sq)
|
|
2465
2790
|
s = s_;
|
|
2466
2791
|
if (!Ns_D_is_sq)
|
|
2467
2792
|
c = r;
|
|
2468
|
-
const Nt =
|
|
2469
|
-
const s2 = s
|
|
2470
|
-
const W0 =
|
|
2471
|
-
const W1 =
|
|
2472
|
-
const W2 =
|
|
2473
|
-
const W3 =
|
|
2474
|
-
return new ed25519_Point(
|
|
2793
|
+
const Nt = Fp.sub(Fp.mulN(Fp.mulN(c, Fp.subN(r, _1n6)), D_MINUS_ONE_SQ), D);
|
|
2794
|
+
const s2 = Fp.sqrN(s);
|
|
2795
|
+
const W0 = Fp.mul(Fp.addN(s, s), D);
|
|
2796
|
+
const W1 = Fp.mul(Nt, SQRT_AD_MINUS_ONE);
|
|
2797
|
+
const W2 = Fp.sub(_1n6, s2);
|
|
2798
|
+
const W3 = Fp.add(_1n6, s2);
|
|
2799
|
+
return new ed25519_Point(Fp.mul(W0, W3), Fp.mul(W2, W1), Fp.mul(W1, W3), Fp.mul(W0, W2));
|
|
2475
2800
|
}
|
|
2476
2801
|
var _RistrettoPoint = class __RistrettoPoint extends PrimeEdwardsPoint {
|
|
2477
2802
|
// Do NOT change syntax: the following gymnastics is done,
|
|
@@ -2506,28 +2831,26 @@ var _RistrettoPoint = class __RistrettoPoint extends PrimeEdwardsPoint {
|
|
|
2506
2831
|
static fromBytes(bytes) {
|
|
2507
2832
|
abytes(bytes, 32);
|
|
2508
2833
|
const { a, d } = ed25519_CURVE;
|
|
2509
|
-
const P = ed25519_CURVE_p;
|
|
2510
|
-
const mod2 = (n) => Fp.create(n);
|
|
2511
2834
|
const s = bytes255ToNumberLE(bytes);
|
|
2512
|
-
if (!equalBytes(Fp.toBytes(s), bytes) ||
|
|
2835
|
+
if (!equalBytes(Fp.toBytes(s), bytes) || Fp.isOdd(s))
|
|
2513
2836
|
throw new Error("invalid ristretto255 encoding 1");
|
|
2514
|
-
const s2 =
|
|
2515
|
-
const u1 =
|
|
2516
|
-
const u2 =
|
|
2517
|
-
const u1_2 =
|
|
2518
|
-
const u2_2 =
|
|
2519
|
-
const v =
|
|
2520
|
-
const { isValid, value: I } = invertSqrt(
|
|
2521
|
-
const Dx =
|
|
2522
|
-
const Dy =
|
|
2523
|
-
let x =
|
|
2524
|
-
if (
|
|
2525
|
-
x =
|
|
2526
|
-
const y =
|
|
2527
|
-
const t =
|
|
2528
|
-
if (!isValid ||
|
|
2837
|
+
const s2 = Fp.sqr(s);
|
|
2838
|
+
const u1 = Fp.add(_1n6, Fp.mulN(a, s2));
|
|
2839
|
+
const u2 = Fp.sub(_1n6, Fp.mulN(a, s2));
|
|
2840
|
+
const u1_2 = Fp.sqr(u1);
|
|
2841
|
+
const u2_2 = Fp.sqr(u2);
|
|
2842
|
+
const v = Fp.sub(Fp.mulN(Fp.mulN(a, d), u1_2), u2_2);
|
|
2843
|
+
const { isValid, value: I } = invertSqrt(Fp.mul(v, u2_2));
|
|
2844
|
+
const Dx = Fp.mul(I, u2);
|
|
2845
|
+
const Dy = Fp.mul(Fp.mulN(I, Dx), v);
|
|
2846
|
+
let x = Fp.mul(Fp.addN(s, s), Dx);
|
|
2847
|
+
if (Fp.isOdd(x))
|
|
2848
|
+
x = Fp.neg(x);
|
|
2849
|
+
const y = Fp.mul(u1, Dy);
|
|
2850
|
+
const t = Fp.mul(x, y);
|
|
2851
|
+
if (!isValid || Fp.isOdd(t) || Fp.is0(y))
|
|
2529
2852
|
throw new Error("invalid ristretto255 encoding 2");
|
|
2530
|
-
return new __RistrettoPoint(new ed25519_Point(x, y,
|
|
2853
|
+
return new __RistrettoPoint(new ed25519_Point(x, y, Fp.ONE, t));
|
|
2531
2854
|
}
|
|
2532
2855
|
/**
|
|
2533
2856
|
* Converts ristretto-encoded string to ristretto point.
|
|
@@ -2543,30 +2866,28 @@ var _RistrettoPoint = class __RistrettoPoint extends PrimeEdwardsPoint {
|
|
|
2543
2866
|
*/
|
|
2544
2867
|
toBytes() {
|
|
2545
2868
|
let { X, Y, Z, T } = this.ep;
|
|
2546
|
-
const
|
|
2547
|
-
const
|
|
2548
|
-
const
|
|
2549
|
-
const
|
|
2550
|
-
const
|
|
2551
|
-
const
|
|
2552
|
-
const
|
|
2553
|
-
const D2 = mod2(invsqrt * u2);
|
|
2554
|
-
const zInv = mod2(D1 * D2 * T);
|
|
2869
|
+
const u1 = Fp.mul(Fp.add(Z, Y), Fp.sub(Z, Y));
|
|
2870
|
+
const u2 = Fp.mul(X, Y);
|
|
2871
|
+
const u2sq = Fp.sqr(u2);
|
|
2872
|
+
const { value: invsqrt } = invertSqrt(Fp.mul(u1, u2sq));
|
|
2873
|
+
const D1 = Fp.mul(invsqrt, u1);
|
|
2874
|
+
const D2 = Fp.mul(invsqrt, u2);
|
|
2875
|
+
const zInv = Fp.mul(Fp.mulN(D1, D2), T);
|
|
2555
2876
|
let D;
|
|
2556
|
-
if (
|
|
2557
|
-
let _x =
|
|
2558
|
-
let _y =
|
|
2877
|
+
if (Fp.isOdd(Fp.mul(T, zInv))) {
|
|
2878
|
+
let _x = Fp.mul(Y, SQRT_M1);
|
|
2879
|
+
let _y = Fp.mul(X, SQRT_M1);
|
|
2559
2880
|
X = _x;
|
|
2560
2881
|
Y = _y;
|
|
2561
|
-
D =
|
|
2882
|
+
D = Fp.mul(D1, INVSQRT_A_MINUS_D);
|
|
2562
2883
|
} else {
|
|
2563
2884
|
D = D2;
|
|
2564
2885
|
}
|
|
2565
|
-
if (
|
|
2566
|
-
Y =
|
|
2567
|
-
let s =
|
|
2568
|
-
if (
|
|
2569
|
-
s =
|
|
2886
|
+
if (Fp.isOdd(Fp.mul(X, zInv)))
|
|
2887
|
+
Y = Fp.neg(Y);
|
|
2888
|
+
let s = Fp.mul(Fp.subN(Z, Y), D);
|
|
2889
|
+
if (Fp.isOdd(s))
|
|
2890
|
+
s = Fp.neg(s);
|
|
2570
2891
|
return Fp.toBytes(s);
|
|
2571
2892
|
}
|
|
2572
2893
|
/**
|
|
@@ -2577,20 +2898,15 @@ var _RistrettoPoint = class __RistrettoPoint extends PrimeEdwardsPoint {
|
|
|
2577
2898
|
this.assertSame(other);
|
|
2578
2899
|
const { X: X1, Y: Y1 } = this.ep;
|
|
2579
2900
|
const { X: X2, Y: Y2 } = other.ep;
|
|
2580
|
-
const
|
|
2581
|
-
const
|
|
2582
|
-
const two = mod2(Y1 * Y2) === mod2(X1 * X2);
|
|
2901
|
+
const one = Fp.eql(Fp.mul(X1, Y2), Fp.mul(Y1, X2));
|
|
2902
|
+
const two = Fp.eql(Fp.mul(Y1, Y2), Fp.mul(X1, X2));
|
|
2583
2903
|
return one || two;
|
|
2584
2904
|
}
|
|
2585
2905
|
is0() {
|
|
2586
2906
|
return this.equals(__RistrettoPoint.ZERO);
|
|
2587
2907
|
}
|
|
2588
2908
|
};
|
|
2589
|
-
Object.freeze(
|
|
2590
|
-
Object.freeze(_RistrettoPoint.ZERO);
|
|
2591
|
-
Object.freeze(_RistrettoPoint.prototype);
|
|
2592
|
-
Object.freeze(_RistrettoPoint);
|
|
2593
|
-
var ristretto255_hasher = Object.freeze({
|
|
2909
|
+
var ristretto255_hasher = /* @__PURE__ */ Object.freeze({
|
|
2594
2910
|
Point: _RistrettoPoint,
|
|
2595
2911
|
/**
|
|
2596
2912
|
* Spec: https://www.rfc-editor.org/rfc/rfc9380.html#name-hashing-to-ristretto255. Caveats:
|
|
@@ -2611,8 +2927,9 @@ var ristretto255_hasher = Object.freeze({
|
|
|
2611
2927
|
const xmd = expand_message_xmd(msg, DST, 64, sha512);
|
|
2612
2928
|
return ristretto255_hasher.deriveToCurve(xmd);
|
|
2613
2929
|
},
|
|
2614
|
-
hashToScalar(msg, options
|
|
2615
|
-
const
|
|
2930
|
+
hashToScalar(msg, options) {
|
|
2931
|
+
const DST = options?.DST === void 0 ? _DST_scalar : options.DST;
|
|
2932
|
+
const xmd = expand_message_xmd(msg, DST, 64, sha512);
|
|
2616
2933
|
return Fn.create(bytesToNumberLE(xmd));
|
|
2617
2934
|
},
|
|
2618
2935
|
/**
|
|
@@ -2642,7 +2959,7 @@ var ristretto255_oprf = /* @__PURE__ */ (() => createOPRF({
|
|
|
2642
2959
|
}))();
|
|
2643
2960
|
|
|
2644
2961
|
// node_modules/@noble/curves/abstract/weierstrass.js
|
|
2645
|
-
var divNearest = (num, den) => (num + (num >= 0 ? den : -den) /
|
|
2962
|
+
var divNearest = (num, den) => (num + (num >= 0 ? den : -den) / _2n5) / den;
|
|
2646
2963
|
function _splitEndoScalar(k, basis, n) {
|
|
2647
2964
|
aInRange("scalar", k, _0n6, n);
|
|
2648
2965
|
const [[a1, b1], [a2, b2]] = basis;
|
|
@@ -2656,132 +2973,17 @@ function _splitEndoScalar(k, basis, n) {
|
|
|
2656
2973
|
k1 = -k1;
|
|
2657
2974
|
if (k2neg)
|
|
2658
2975
|
k2 = -k2;
|
|
2659
|
-
const MAX_NUM = bitMask(Math.ceil(bitLen(n) / 2)) +
|
|
2976
|
+
const MAX_NUM = bitMask(Math.ceil(bitLen(n) / 2)) + _1n7;
|
|
2660
2977
|
if (k1 < _0n6 || k1 >= MAX_NUM || k2 < _0n6 || k2 >= MAX_NUM) {
|
|
2661
2978
|
throw new Error("splitScalar (endomorphism): failed for k");
|
|
2662
2979
|
}
|
|
2663
2980
|
return { k1neg, k1, k2neg, k2 };
|
|
2664
2981
|
}
|
|
2665
|
-
var DERErr = class extends Error {
|
|
2666
|
-
constructor(m = "") {
|
|
2667
|
-
super(m);
|
|
2668
|
-
}
|
|
2669
|
-
};
|
|
2670
|
-
var DER = {
|
|
2671
|
-
// asn.1 DER encoding utils
|
|
2672
|
-
Err: DERErr,
|
|
2673
|
-
// Basic building block is TLV (Tag-Length-Value)
|
|
2674
|
-
_tlv: {
|
|
2675
|
-
encode: (tag, data) => {
|
|
2676
|
-
const { Err: E } = DER;
|
|
2677
|
-
asafenumber(tag, "tag");
|
|
2678
|
-
if (tag < 0 || tag > 255)
|
|
2679
|
-
throw new E("tlv.encode: wrong tag");
|
|
2680
|
-
if (typeof data !== "string")
|
|
2681
|
-
throw new TypeError('"data" expected string, got type=' + typeof data);
|
|
2682
|
-
if (data.length & 1)
|
|
2683
|
-
throw new E("tlv.encode: unpadded data");
|
|
2684
|
-
const dataLen = data.length / 2;
|
|
2685
|
-
const len = numberToHexUnpadded(dataLen);
|
|
2686
|
-
if (len.length / 2 & 128)
|
|
2687
|
-
throw new E("tlv.encode: long form length too big");
|
|
2688
|
-
const lenLen = dataLen > 127 ? numberToHexUnpadded(len.length / 2 | 128) : "";
|
|
2689
|
-
const t = numberToHexUnpadded(tag);
|
|
2690
|
-
return t + lenLen + len + data;
|
|
2691
|
-
},
|
|
2692
|
-
// v - value, l - left bytes (unparsed)
|
|
2693
|
-
decode(tag, data) {
|
|
2694
|
-
const { Err: E } = DER;
|
|
2695
|
-
data = abytes2(data, void 0, "DER data");
|
|
2696
|
-
let pos = 0;
|
|
2697
|
-
if (tag < 0 || tag > 255)
|
|
2698
|
-
throw new E("tlv.encode: wrong tag");
|
|
2699
|
-
if (data.length < 2 || data[pos++] !== tag)
|
|
2700
|
-
throw new E("tlv.decode: wrong tlv");
|
|
2701
|
-
const first = data[pos++];
|
|
2702
|
-
const isLong = !!(first & 128);
|
|
2703
|
-
let length = 0;
|
|
2704
|
-
if (!isLong)
|
|
2705
|
-
length = first;
|
|
2706
|
-
else {
|
|
2707
|
-
const lenLen = first & 127;
|
|
2708
|
-
if (!lenLen)
|
|
2709
|
-
throw new E("tlv.decode(long): indefinite length not supported");
|
|
2710
|
-
if (lenLen > 4)
|
|
2711
|
-
throw new E("tlv.decode(long): byte length is too big");
|
|
2712
|
-
const lengthBytes = data.subarray(pos, pos + lenLen);
|
|
2713
|
-
if (lengthBytes.length !== lenLen)
|
|
2714
|
-
throw new E("tlv.decode: length bytes not complete");
|
|
2715
|
-
if (lengthBytes[0] === 0)
|
|
2716
|
-
throw new E("tlv.decode(long): zero leftmost byte");
|
|
2717
|
-
for (const b of lengthBytes)
|
|
2718
|
-
length = length << 8 | b;
|
|
2719
|
-
pos += lenLen;
|
|
2720
|
-
if (length < 128)
|
|
2721
|
-
throw new E("tlv.decode(long): not minimal encoding");
|
|
2722
|
-
}
|
|
2723
|
-
const v = data.subarray(pos, pos + length);
|
|
2724
|
-
if (v.length !== length)
|
|
2725
|
-
throw new E("tlv.decode: wrong value length");
|
|
2726
|
-
return { v, l: data.subarray(pos + length) };
|
|
2727
|
-
}
|
|
2728
|
-
},
|
|
2729
|
-
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
|
2730
|
-
// since we always use positive integers here. It must always be empty:
|
|
2731
|
-
// - add zero byte if exists
|
|
2732
|
-
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
|
2733
|
-
_int: {
|
|
2734
|
-
encode(num) {
|
|
2735
|
-
const { Err: E } = DER;
|
|
2736
|
-
abignumber(num);
|
|
2737
|
-
if (num < _0n6)
|
|
2738
|
-
throw new E("integer: negative integers are not allowed");
|
|
2739
|
-
let hex = numberToHexUnpadded(num);
|
|
2740
|
-
if (Number.parseInt(hex[0], 16) & 8)
|
|
2741
|
-
hex = "00" + hex;
|
|
2742
|
-
if (hex.length & 1)
|
|
2743
|
-
throw new E("unexpected DER parsing assertion: unpadded hex");
|
|
2744
|
-
return hex;
|
|
2745
|
-
},
|
|
2746
|
-
decode(data) {
|
|
2747
|
-
const { Err: E } = DER;
|
|
2748
|
-
if (data.length < 1)
|
|
2749
|
-
throw new E("invalid signature integer: empty");
|
|
2750
|
-
if (data[0] & 128)
|
|
2751
|
-
throw new E("invalid signature integer: negative");
|
|
2752
|
-
if (data.length > 1 && data[0] === 0 && !(data[1] & 128))
|
|
2753
|
-
throw new E("invalid signature integer: unnecessary leading zero");
|
|
2754
|
-
return bytesToNumberBE(data);
|
|
2755
|
-
}
|
|
2756
|
-
},
|
|
2757
|
-
toSig(bytes) {
|
|
2758
|
-
const { Err: E, _int: int, _tlv: tlv } = DER;
|
|
2759
|
-
const data = abytes2(bytes, void 0, "signature");
|
|
2760
|
-
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(48, data);
|
|
2761
|
-
if (seqLeftBytes.length)
|
|
2762
|
-
throw new E("invalid signature: left bytes after parsing");
|
|
2763
|
-
const { v: rBytes, l: rLeftBytes } = tlv.decode(2, seqBytes);
|
|
2764
|
-
const { v: sBytes, l: sLeftBytes } = tlv.decode(2, rLeftBytes);
|
|
2765
|
-
if (sLeftBytes.length)
|
|
2766
|
-
throw new E("invalid signature: left bytes after parsing");
|
|
2767
|
-
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
|
2768
|
-
},
|
|
2769
|
-
hexFromSig(sig) {
|
|
2770
|
-
const { _tlv: tlv, _int: int } = DER;
|
|
2771
|
-
const rs = tlv.encode(2, int.encode(sig.r));
|
|
2772
|
-
const ss = tlv.encode(2, int.encode(sig.s));
|
|
2773
|
-
const seq = rs + ss;
|
|
2774
|
-
return tlv.encode(48, seq);
|
|
2775
|
-
}
|
|
2776
|
-
};
|
|
2777
|
-
Object.freeze(DER._tlv);
|
|
2778
|
-
Object.freeze(DER._int);
|
|
2779
|
-
Object.freeze(DER);
|
|
2780
2982
|
var _0n6 = /* @__PURE__ */ BigInt(0);
|
|
2781
|
-
var
|
|
2782
|
-
var
|
|
2783
|
-
var
|
|
2784
|
-
var
|
|
2983
|
+
var _1n7 = /* @__PURE__ */ BigInt(1);
|
|
2984
|
+
var _2n5 = /* @__PURE__ */ BigInt(2);
|
|
2985
|
+
var _3n3 = /* @__PURE__ */ BigInt(3);
|
|
2986
|
+
var _4n5 = /* @__PURE__ */ BigInt(4);
|
|
2785
2987
|
function weierstrass(params, extraOpts = {}) {
|
|
2786
2988
|
const validated = createCurveFields("weierstrass", params, extraOpts);
|
|
2787
2989
|
const Fp2 = validated.Fp;
|
|
@@ -2794,9 +2996,11 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2794
2996
|
isTorsionFree: "function",
|
|
2795
2997
|
fromBytes: "function",
|
|
2796
2998
|
toBytes: "function",
|
|
2797
|
-
endo: "object"
|
|
2999
|
+
endo: "object",
|
|
3000
|
+
randomBytes: "function"
|
|
2798
3001
|
});
|
|
2799
3002
|
const { endo, allowInfinityPoint } = extraOpts;
|
|
3003
|
+
const randomBytes3 = extraOpts.randomBytes === void 0 ? randomBytes2 : extraOpts.randomBytes;
|
|
2800
3004
|
if (endo) {
|
|
2801
3005
|
if (!Fp2.is0(CURVE.a) || typeof endo.beta !== "bigint" || !Array.isArray(endo.basises)) {
|
|
2802
3006
|
throw new Error('invalid endo: expected "beta": bigint and "basises": array');
|
|
@@ -2860,6 +3064,8 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2860
3064
|
}
|
|
2861
3065
|
const encodePoint = extraOpts.toBytes === void 0 ? pointToBytes : extraOpts.toBytes;
|
|
2862
3066
|
const decodePoint = extraOpts.fromBytes === void 0 ? pointFromBytes : extraOpts.fromBytes;
|
|
3067
|
+
const b3 = Fp2.mul(CURVE.b, _3n3);
|
|
3068
|
+
const mulA = Fp2.is0(CURVE.a) ? (_) => Fp2.ZERO : (x) => Fp2.mul(CURVE.a, x);
|
|
2863
3069
|
function weierstrassEquation(x) {
|
|
2864
3070
|
const x2 = Fp2.sqr(x);
|
|
2865
3071
|
const x3 = Fp2.mul(x2, x);
|
|
@@ -2872,7 +3078,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2872
3078
|
}
|
|
2873
3079
|
if (!isValidXY(CURVE.Gx, CURVE.Gy))
|
|
2874
3080
|
throw new Error("bad curve params: generator point");
|
|
2875
|
-
const _4a3 = Fp2.mul(Fp2.pow(CURVE.a,
|
|
3081
|
+
const _4a3 = Fp2.mul(Fp2.pow(CURVE.a, _3n3), _4n5);
|
|
2876
3082
|
const _27b2 = Fp2.mul(Fp2.sqr(CURVE.b), BigInt(27));
|
|
2877
3083
|
if (Fp2.is0(Fp2.add(_4a3, _27b2)))
|
|
2878
3084
|
throw new Error("bad curve params: a or b");
|
|
@@ -2890,21 +3096,24 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2890
3096
|
throw new Error("no endo");
|
|
2891
3097
|
return _splitEndoScalar(k, endo.basises, Fn2.ORDER);
|
|
2892
3098
|
}
|
|
2893
|
-
function
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
3099
|
+
function pushWnafPair(points, scalars, p, k) {
|
|
3100
|
+
if (!Fn2.isValid(k))
|
|
3101
|
+
throw new RangeError("invalid scalar: out of range");
|
|
3102
|
+
if (endo) {
|
|
3103
|
+
const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(k);
|
|
3104
|
+
const psi = new Point(Fp2.mul(p.X, endo.beta), p.Y, p.Z);
|
|
3105
|
+
points.push(k1neg ? p.negate() : p, k2neg ? psi.negate() : psi);
|
|
3106
|
+
scalars.push(k1, k2);
|
|
3107
|
+
} else {
|
|
3108
|
+
points.push(p);
|
|
3109
|
+
scalars.push(k);
|
|
3110
|
+
}
|
|
2898
3111
|
}
|
|
3112
|
+
const validityCache = /* @__PURE__ */ new WeakSet();
|
|
2899
3113
|
class Point {
|
|
2900
|
-
// base / generator point
|
|
2901
3114
|
static BASE = new Point(CURVE.Gx, CURVE.Gy, Fp2.ONE);
|
|
2902
|
-
// zero / infinity / identity point
|
|
2903
3115
|
static ZERO = new Point(Fp2.ZERO, Fp2.ONE, Fp2.ZERO);
|
|
2904
|
-
// 0, 1, 0
|
|
2905
|
-
// math field
|
|
2906
3116
|
static Fp = Fp2;
|
|
2907
|
-
// scalar field
|
|
2908
3117
|
static Fn = Fn2;
|
|
2909
3118
|
X;
|
|
2910
3119
|
Y;
|
|
@@ -2945,15 +3154,12 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2945
3154
|
return this.toAffine().y;
|
|
2946
3155
|
}
|
|
2947
3156
|
/**
|
|
2948
|
-
*
|
|
2949
|
-
* @param windowSize
|
|
2950
3157
|
* @param isLazy - true will defer table computation until the first multiplication
|
|
2951
|
-
* @returns
|
|
2952
3158
|
*/
|
|
2953
|
-
precompute(windowSize =
|
|
2954
|
-
wnaf.
|
|
3159
|
+
precompute(windowSize = 6, isLazy = true) {
|
|
3160
|
+
wnaf.setWindowSize(this, windowSize);
|
|
2955
3161
|
if (!isLazy)
|
|
2956
|
-
this.multiply(
|
|
3162
|
+
this.multiply(_3n3);
|
|
2957
3163
|
return this;
|
|
2958
3164
|
}
|
|
2959
3165
|
// TODO: return `this`
|
|
@@ -2965,6 +3171,8 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2965
3171
|
return;
|
|
2966
3172
|
throw new Error("bad point: ZERO");
|
|
2967
3173
|
}
|
|
3174
|
+
if (validityCache.has(p))
|
|
3175
|
+
return;
|
|
2968
3176
|
const { x, y } = p.toAffine();
|
|
2969
3177
|
if (!Fp2.isValid(x) || !Fp2.isValid(y))
|
|
2970
3178
|
throw new Error("bad point: x or y not field elements");
|
|
@@ -2972,6 +3180,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2972
3180
|
throw new Error("bad point: equation left != right");
|
|
2973
3181
|
if (!p.isTorsionFree())
|
|
2974
3182
|
throw new Error("bad point: not in prime-order subgroup");
|
|
3183
|
+
validityCache.add(p);
|
|
2975
3184
|
}
|
|
2976
3185
|
hasEvenY() {
|
|
2977
3186
|
const { y } = this.toAffine();
|
|
@@ -2997,8 +3206,6 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
2997
3206
|
// https://eprint.iacr.org/2015/1060, algorithm 3
|
|
2998
3207
|
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
|
2999
3208
|
double() {
|
|
3000
|
-
const { a, b } = CURVE;
|
|
3001
|
-
const b3 = Fp2.mul(b, _3n2);
|
|
3002
3209
|
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
3003
3210
|
let X3 = Fp2.ZERO, Y3 = Fp2.ZERO, Z3 = Fp2.ZERO;
|
|
3004
3211
|
let t0 = Fp2.mul(X1, X1);
|
|
@@ -3008,7 +3215,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3008
3215
|
t3 = Fp2.add(t3, t3);
|
|
3009
3216
|
Z3 = Fp2.mul(X1, Z1);
|
|
3010
3217
|
Z3 = Fp2.add(Z3, Z3);
|
|
3011
|
-
X3 =
|
|
3218
|
+
X3 = mulA(Z3);
|
|
3012
3219
|
Y3 = Fp2.mul(b3, t2);
|
|
3013
3220
|
Y3 = Fp2.add(X3, Y3);
|
|
3014
3221
|
X3 = Fp2.sub(t1, Y3);
|
|
@@ -3016,9 +3223,9 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3016
3223
|
Y3 = Fp2.mul(X3, Y3);
|
|
3017
3224
|
X3 = Fp2.mul(t3, X3);
|
|
3018
3225
|
Z3 = Fp2.mul(b3, Z3);
|
|
3019
|
-
t2 =
|
|
3226
|
+
t2 = mulA(t2);
|
|
3020
3227
|
t3 = Fp2.sub(t0, t2);
|
|
3021
|
-
t3 =
|
|
3228
|
+
t3 = mulA(t3);
|
|
3022
3229
|
t3 = Fp2.add(t3, Z3);
|
|
3023
3230
|
Z3 = Fp2.add(t0, t0);
|
|
3024
3231
|
t0 = Fp2.add(Z3, t0);
|
|
@@ -3043,8 +3250,6 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3043
3250
|
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
3044
3251
|
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
3045
3252
|
let X3 = Fp2.ZERO, Y3 = Fp2.ZERO, Z3 = Fp2.ZERO;
|
|
3046
|
-
const a = CURVE.a;
|
|
3047
|
-
const b3 = Fp2.mul(CURVE.b, _3n2);
|
|
3048
3253
|
let t0 = Fp2.mul(X1, X2);
|
|
3049
3254
|
let t1 = Fp2.mul(Y1, Y2);
|
|
3050
3255
|
let t2 = Fp2.mul(Z1, Z2);
|
|
@@ -3063,7 +3268,7 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3063
3268
|
t5 = Fp2.mul(t5, X3);
|
|
3064
3269
|
X3 = Fp2.add(t1, t2);
|
|
3065
3270
|
t5 = Fp2.sub(t5, X3);
|
|
3066
|
-
Z3 =
|
|
3271
|
+
Z3 = mulA(t4);
|
|
3067
3272
|
X3 = Fp2.mul(b3, t2);
|
|
3068
3273
|
Z3 = Fp2.add(X3, Z3);
|
|
3069
3274
|
X3 = Fp2.sub(t1, Z3);
|
|
@@ -3071,11 +3276,11 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3071
3276
|
Y3 = Fp2.mul(X3, Z3);
|
|
3072
3277
|
t1 = Fp2.add(t0, t0);
|
|
3073
3278
|
t1 = Fp2.add(t1, t0);
|
|
3074
|
-
t2 =
|
|
3279
|
+
t2 = mulA(t2);
|
|
3075
3280
|
t4 = Fp2.mul(b3, t4);
|
|
3076
3281
|
t1 = Fp2.add(t1, t2);
|
|
3077
3282
|
t2 = Fp2.sub(t0, t2);
|
|
3078
|
-
t2 =
|
|
3283
|
+
t2 = mulA(t2);
|
|
3079
3284
|
t4 = Fp2.add(t4, t2);
|
|
3080
3285
|
t0 = Fp2.mul(t1, t4);
|
|
3081
3286
|
Y3 = Fp2.add(Y3, t0);
|
|
@@ -3096,56 +3301,53 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3096
3301
|
}
|
|
3097
3302
|
/**
|
|
3098
3303
|
* Constant time multiplication.
|
|
3099
|
-
* Uses
|
|
3100
|
-
*
|
|
3101
|
-
* Uses precomputes when available.
|
|
3102
|
-
* Uses endomorphism for Koblitz curves.
|
|
3304
|
+
* Uses precomputed tables (signed fixed-window wNAF) when available.
|
|
3305
|
+
* Uses scalar blinding and avoids endomorphism splitting in the secret-scalar path.
|
|
3103
3306
|
* @param scalar - by which the point would be multiplied
|
|
3104
3307
|
* @returns New point
|
|
3105
3308
|
*/
|
|
3106
3309
|
multiply(scalar) {
|
|
3107
|
-
const { endo: endo2 } = extraOpts;
|
|
3108
3310
|
if (!Fn2.isValidNot0(scalar))
|
|
3109
3311
|
throw new RangeError("invalid scalar: out of range");
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
if (endo2) {
|
|
3113
|
-
const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar);
|
|
3114
|
-
const { p: k1p, f: k1f } = mul(k1);
|
|
3115
|
-
const { p: k2p, f: k2f } = mul(k2);
|
|
3116
|
-
fake = k1f.add(k2f);
|
|
3117
|
-
point = finishEndo(endo2.beta, k1p, k2p, k1neg, k2neg);
|
|
3118
|
-
} else {
|
|
3119
|
-
const { p, f } = mul(scalar);
|
|
3120
|
-
point = p;
|
|
3121
|
-
fake = f;
|
|
3122
|
-
}
|
|
3123
|
-
return normalizeZ(Point, [point, fake])[0];
|
|
3312
|
+
const { p, f } = wnaf.mulSecret(this, scalar, cofactor, normalize);
|
|
3313
|
+
return normalize([p, f])[0];
|
|
3124
3314
|
}
|
|
3125
3315
|
/**
|
|
3126
|
-
* Non-constant-time multiplication. Uses
|
|
3316
|
+
* Non-constant-time multiplication. Uses width-4 wNAF with GLV endomorphism splitting
|
|
3317
|
+
* when available (two half-width scalars sharing one halved doubling chain).
|
|
3127
3318
|
* It's faster, but should only be used when you don't care about
|
|
3128
3319
|
* an exposed secret key e.g. sig verification, which works over *public* keys.
|
|
3129
3320
|
*/
|
|
3130
3321
|
multiplyUnsafe(scalar) {
|
|
3131
|
-
const { endo: endo2 } = extraOpts;
|
|
3132
3322
|
const p = this;
|
|
3133
3323
|
const sc = scalar;
|
|
3134
3324
|
if (!Fn2.isValid(sc))
|
|
3135
3325
|
throw new RangeError("invalid scalar: out of range");
|
|
3136
3326
|
if (sc === _0n6 || p.is0())
|
|
3137
3327
|
return Point.ZERO;
|
|
3138
|
-
if (sc ===
|
|
3328
|
+
if (sc === _1n7)
|
|
3139
3329
|
return p;
|
|
3140
|
-
if (wnaf.
|
|
3141
|
-
return
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3330
|
+
if (wnaf.hasWindowSize(this))
|
|
3331
|
+
return wnaf.mulUnsafe(p, sc, normalize);
|
|
3332
|
+
const points = [];
|
|
3333
|
+
const scalars = [];
|
|
3334
|
+
pushWnafPair(points, scalars, p, sc);
|
|
3335
|
+
return mulAddUnsafe(Point, points, scalars);
|
|
3336
|
+
}
|
|
3337
|
+
/**
|
|
3338
|
+
* Non-constant-time double-scalar multiplication `a⋅this + b⋅other` (Strauss–Shamir).
|
|
3339
|
+
* Both walks share one doubling chain via {@link mulAddUnsafe}, and GLV endomorphism
|
|
3340
|
+
* (when available) halves the chain again by splitting each scalar into two half-width
|
|
3341
|
+
* parts. Used by ECDSA verification and public-key recovery for `R = u1⋅G + u2⋅P`.
|
|
3342
|
+
* Only for public scalars.
|
|
3343
|
+
*/
|
|
3344
|
+
mulAddUnsafe(a, other, b) {
|
|
3345
|
+
aprjpoint(other);
|
|
3346
|
+
const points = [];
|
|
3347
|
+
const scalars = [];
|
|
3348
|
+
pushWnafPair(points, scalars, this, a);
|
|
3349
|
+
pushWnafPair(points, scalars, other, b);
|
|
3350
|
+
return mulAddUnsafe(Point, points, scalars);
|
|
3149
3351
|
}
|
|
3150
3352
|
/**
|
|
3151
3353
|
* Converts Projective point to affine (x, y) coordinates.
|
|
@@ -3155,6 +3357,8 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3155
3357
|
toAffine(invertedZ) {
|
|
3156
3358
|
const p = this;
|
|
3157
3359
|
let iz = invertedZ;
|
|
3360
|
+
if (iz != null && !Fp2.isValid(iz))
|
|
3361
|
+
throw new RangeError('"invertedZ" expected valid field element');
|
|
3158
3362
|
const { X, Y, Z } = p;
|
|
3159
3363
|
if (Fp2.eql(Z, Fp2.ONE))
|
|
3160
3364
|
return { x: X, y: Y };
|
|
@@ -3176,22 +3380,22 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3176
3380
|
*/
|
|
3177
3381
|
isTorsionFree() {
|
|
3178
3382
|
const { isTorsionFree } = extraOpts;
|
|
3179
|
-
if (cofactor ===
|
|
3383
|
+
if (cofactor === _1n7)
|
|
3180
3384
|
return true;
|
|
3181
3385
|
if (isTorsionFree)
|
|
3182
3386
|
return isTorsionFree(Point, this);
|
|
3183
|
-
return wnaf.
|
|
3387
|
+
return wnaf.mulUnsafe(this, CURVE_ORDER).is0();
|
|
3184
3388
|
}
|
|
3185
3389
|
clearCofactor() {
|
|
3186
3390
|
const { clearCofactor } = extraOpts;
|
|
3187
|
-
if (cofactor ===
|
|
3391
|
+
if (cofactor === _1n7)
|
|
3188
3392
|
return this;
|
|
3189
3393
|
if (clearCofactor)
|
|
3190
3394
|
return clearCofactor(Point, this);
|
|
3191
3395
|
return this.multiplyUnsafe(cofactor);
|
|
3192
3396
|
}
|
|
3193
3397
|
isSmallOrder() {
|
|
3194
|
-
if (cofactor ===
|
|
3398
|
+
if (cofactor === _1n7)
|
|
3195
3399
|
return this.is0();
|
|
3196
3400
|
return this.clearCofactor().is0();
|
|
3197
3401
|
}
|
|
@@ -3207,10 +3411,10 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3207
3411
|
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
3208
3412
|
}
|
|
3209
3413
|
}
|
|
3210
|
-
const
|
|
3211
|
-
const wnaf = new
|
|
3212
|
-
if (bits >=
|
|
3213
|
-
Point.BASE.precompute(
|
|
3414
|
+
const normalize = (points) => normalizeZ(Point, points);
|
|
3415
|
+
const wnaf = new ScalarMultiplier(Point, randomBytes3);
|
|
3416
|
+
if (wnaf.bits >= 6)
|
|
3417
|
+
Point.BASE.precompute(6);
|
|
3214
3418
|
Object.freeze(Point.prototype);
|
|
3215
3419
|
Object.freeze(Point);
|
|
3216
3420
|
return Point;
|
|
@@ -3218,114 +3422,6 @@ function weierstrass(params, extraOpts = {}) {
|
|
|
3218
3422
|
function pprefix(hasEvenY) {
|
|
3219
3423
|
return Uint8Array.of(hasEvenY ? 2 : 3);
|
|
3220
3424
|
}
|
|
3221
|
-
function SWUFpSqrtRatio(Fp2, Z) {
|
|
3222
|
-
const F = validateField(Fp2);
|
|
3223
|
-
const q = F.ORDER;
|
|
3224
|
-
let l = _0n6;
|
|
3225
|
-
for (let o = q - _1n6; o % _2n4 === _0n6; o /= _2n4)
|
|
3226
|
-
l += _1n6;
|
|
3227
|
-
const c1 = l;
|
|
3228
|
-
const _2n_pow_c1_1 = _2n4 << c1 - _1n6 - _1n6;
|
|
3229
|
-
const _2n_pow_c1 = _2n_pow_c1_1 * _2n4;
|
|
3230
|
-
const c2 = (q - _1n6) / _2n_pow_c1;
|
|
3231
|
-
const c3 = (c2 - _1n6) / _2n4;
|
|
3232
|
-
const c4 = _2n_pow_c1 - _1n6;
|
|
3233
|
-
const c5 = _2n_pow_c1_1;
|
|
3234
|
-
const c6 = F.pow(Z, c2);
|
|
3235
|
-
const c7 = F.pow(Z, (c2 + _1n6) / _2n4);
|
|
3236
|
-
let sqrtRatio = (u, v) => {
|
|
3237
|
-
let tv1 = c6;
|
|
3238
|
-
let tv2 = F.pow(v, c4);
|
|
3239
|
-
let tv3 = F.sqr(tv2);
|
|
3240
|
-
tv3 = F.mul(tv3, v);
|
|
3241
|
-
let tv5 = F.mul(u, tv3);
|
|
3242
|
-
tv5 = F.pow(tv5, c3);
|
|
3243
|
-
tv5 = F.mul(tv5, tv2);
|
|
3244
|
-
tv2 = F.mul(tv5, v);
|
|
3245
|
-
tv3 = F.mul(tv5, u);
|
|
3246
|
-
let tv4 = F.mul(tv3, tv2);
|
|
3247
|
-
tv5 = F.pow(tv4, c5);
|
|
3248
|
-
let isQR = F.eql(tv5, F.ONE);
|
|
3249
|
-
tv2 = F.mul(tv3, c7);
|
|
3250
|
-
tv5 = F.mul(tv4, tv1);
|
|
3251
|
-
tv3 = F.cmov(tv2, tv3, isQR);
|
|
3252
|
-
tv4 = F.cmov(tv5, tv4, isQR);
|
|
3253
|
-
for (let i = c1; i > _1n6; i--) {
|
|
3254
|
-
let tv52 = i - _2n4;
|
|
3255
|
-
tv52 = _2n4 << tv52 - _1n6;
|
|
3256
|
-
let tvv5 = F.pow(tv4, tv52);
|
|
3257
|
-
const e1 = F.eql(tvv5, F.ONE);
|
|
3258
|
-
tv2 = F.mul(tv3, tv1);
|
|
3259
|
-
tv1 = F.mul(tv1, tv1);
|
|
3260
|
-
tvv5 = F.mul(tv4, tv1);
|
|
3261
|
-
tv3 = F.cmov(tv2, tv3, e1);
|
|
3262
|
-
tv4 = F.cmov(tvv5, tv4, e1);
|
|
3263
|
-
}
|
|
3264
|
-
return { isValid: !F.is0(v) && (isQR || F.is0(u)), value: tv3 };
|
|
3265
|
-
};
|
|
3266
|
-
if (F.ORDER % _4n2 === _3n2) {
|
|
3267
|
-
const c12 = (F.ORDER - _3n2) / _4n2;
|
|
3268
|
-
const c22 = F.sqrt(F.neg(Z));
|
|
3269
|
-
sqrtRatio = (u, v) => {
|
|
3270
|
-
let tv1 = F.sqr(v);
|
|
3271
|
-
const tv2 = F.mul(u, v);
|
|
3272
|
-
tv1 = F.mul(tv1, tv2);
|
|
3273
|
-
let y1 = F.pow(tv1, c12);
|
|
3274
|
-
y1 = F.mul(y1, tv2);
|
|
3275
|
-
const y2 = F.mul(y1, c22);
|
|
3276
|
-
const tv3 = F.mul(F.sqr(y1), v);
|
|
3277
|
-
const isQR = F.eql(tv3, u);
|
|
3278
|
-
let y = F.cmov(y2, y1, isQR);
|
|
3279
|
-
return { isValid: !F.is0(v) && isQR, value: y };
|
|
3280
|
-
};
|
|
3281
|
-
}
|
|
3282
|
-
return sqrtRatio;
|
|
3283
|
-
}
|
|
3284
|
-
function mapToCurveSimpleSWU(Fp2, opts) {
|
|
3285
|
-
const F = validateField(Fp2);
|
|
3286
|
-
const { A, B, Z } = opts;
|
|
3287
|
-
if (!F.isValidNot0(A) || !F.isValidNot0(B) || !F.isValid(Z))
|
|
3288
|
-
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
3289
|
-
if (F.eql(Z, F.neg(F.ONE)) || FpIsSquare(F, Z))
|
|
3290
|
-
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
3291
|
-
const x = F.mul(B, F.inv(F.mul(Z, A)));
|
|
3292
|
-
const gx = F.add(F.add(F.mul(F.sqr(x), x), F.mul(A, x)), B);
|
|
3293
|
-
if (!FpIsSquare(F, gx))
|
|
3294
|
-
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
3295
|
-
const sqrtRatio = SWUFpSqrtRatio(F, Z);
|
|
3296
|
-
if (!F.isOdd)
|
|
3297
|
-
throw new Error("Field does not have .isOdd()");
|
|
3298
|
-
return (u) => {
|
|
3299
|
-
let tv1, tv2, tv3, tv4, tv5, tv6, x2, y;
|
|
3300
|
-
tv1 = F.sqr(u);
|
|
3301
|
-
tv1 = F.mul(tv1, Z);
|
|
3302
|
-
tv2 = F.sqr(tv1);
|
|
3303
|
-
tv2 = F.add(tv2, tv1);
|
|
3304
|
-
tv3 = F.add(tv2, F.ONE);
|
|
3305
|
-
tv3 = F.mul(tv3, B);
|
|
3306
|
-
tv4 = F.cmov(Z, F.neg(tv2), !F.eql(tv2, F.ZERO));
|
|
3307
|
-
tv4 = F.mul(tv4, A);
|
|
3308
|
-
tv2 = F.sqr(tv3);
|
|
3309
|
-
tv6 = F.sqr(tv4);
|
|
3310
|
-
tv5 = F.mul(tv6, A);
|
|
3311
|
-
tv2 = F.add(tv2, tv5);
|
|
3312
|
-
tv2 = F.mul(tv2, tv3);
|
|
3313
|
-
tv6 = F.mul(tv6, tv4);
|
|
3314
|
-
tv5 = F.mul(tv6, B);
|
|
3315
|
-
tv2 = F.add(tv2, tv5);
|
|
3316
|
-
x2 = F.mul(tv1, tv3);
|
|
3317
|
-
const { isValid, value } = sqrtRatio(tv2, tv6);
|
|
3318
|
-
y = F.mul(tv1, u);
|
|
3319
|
-
y = F.mul(y, value);
|
|
3320
|
-
x2 = F.cmov(x2, tv3, isValid);
|
|
3321
|
-
y = F.cmov(y, value, isValid);
|
|
3322
|
-
const e1 = F.isOdd(u) === F.isOdd(y);
|
|
3323
|
-
y = F.cmov(F.neg(y), y, e1);
|
|
3324
|
-
const tv4_inv = FpInvertBatch(F, [tv4], true)[0];
|
|
3325
|
-
x2 = F.mul(x2, tv4_inv);
|
|
3326
|
-
return { x: x2, y };
|
|
3327
|
-
};
|
|
3328
|
-
}
|
|
3329
3425
|
function getWLengths(Fp2, Fn2) {
|
|
3330
3426
|
return {
|
|
3331
3427
|
secretKey: Fn2.BYTES,
|
|
@@ -3375,7 +3471,7 @@ var p256_hasher = /* @__PURE__ */ (() => {
|
|
|
3375
3471
|
return createHasher2(p256_Point, createSWU(p256_Point, {
|
|
3376
3472
|
A: p256_CURVE.a,
|
|
3377
3473
|
B: p256_CURVE.b,
|
|
3378
|
-
Z: p256_Point.Fp.
|
|
3474
|
+
Z: p256_Point.Fp.neg(BigInt(10))
|
|
3379
3475
|
}), {
|
|
3380
3476
|
DST: "P256_XMD:SHA-256_SSWU_RO_",
|
|
3381
3477
|
encodeDST: "P256_XMD:SHA-256_SSWU_NU_",
|
|
@@ -3398,7 +3494,7 @@ var p384_hasher = /* @__PURE__ */ (() => {
|
|
|
3398
3494
|
return createHasher2(p384_Point, createSWU(p384_Point, {
|
|
3399
3495
|
A: p384_CURVE.a,
|
|
3400
3496
|
B: p384_CURVE.b,
|
|
3401
|
-
Z: p384_Point.Fp.
|
|
3497
|
+
Z: p384_Point.Fp.neg(BigInt(12))
|
|
3402
3498
|
}), {
|
|
3403
3499
|
DST: "P384_XMD:SHA-384_SSWU_RO_",
|
|
3404
3500
|
encodeDST: "P384_XMD:SHA-384_SSWU_NU_",
|
|
@@ -3421,7 +3517,7 @@ var p521_hasher = /* @__PURE__ */ (() => {
|
|
|
3421
3517
|
return createHasher2(p521_Point, createSWU(p521_Point, {
|
|
3422
3518
|
A: p521_CURVE.a,
|
|
3423
3519
|
B: p521_CURVE.b,
|
|
3424
|
-
Z: p521_Point.Fp.
|
|
3520
|
+
Z: p521_Point.Fp.neg(BigInt(4))
|
|
3425
3521
|
}), {
|
|
3426
3522
|
DST: "P521_XMD:SHA-512_SSWU_RO_",
|
|
3427
3523
|
encodeDST: "P521_XMD:SHA-512_SSWU_NU_",
|