@obolnetwork/obol-sdk 2.11.13 → 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser/src/index.js +445 -134
- package/dist/browser/src/index.js.map +1 -1
- package/dist/cjs/src/blsUtils.js +3826 -0
- package/dist/cjs/src/blsUtils.js.map +1 -0
- package/dist/cjs/src/index.js +528 -222
- package/dist/cjs/src/index.js.map +1 -1
- package/dist/cjs/src/verification/lockWorker.js +3828 -0
- package/dist/cjs/src/verification/lockWorker.js.map +1 -0
- package/dist/cjs/src/verification/parallelPool.js +3992 -0
- package/dist/cjs/src/verification/parallelPool.js.map +1 -0
- package/dist/esm/src/blsUtils.js +17 -0
- package/dist/esm/src/blsUtils.js.map +1 -0
- package/dist/esm/src/chunk-267HIPEB.js +4355 -0
- package/dist/esm/src/chunk-267HIPEB.js.map +1 -0
- package/dist/esm/src/chunk-OYZHSNKR.js +186 -0
- package/dist/esm/src/chunk-OYZHSNKR.js.map +1 -0
- package/dist/esm/src/index.js +834 -5000
- package/dist/esm/src/index.js.map +1 -1
- package/dist/esm/src/verification/lockWorker.js +50 -0
- package/dist/esm/src/verification/lockWorker.js.map +1 -0
- package/dist/esm/src/verification/parallelPool.js +10 -0
- package/dist/esm/src/verification/parallelPool.js.map +1 -0
- package/dist/types/src/blsUtils.d.ts +2 -0
- package/dist/types/src/verification/common.d.ts +9 -0
- package/dist/types/src/verification/lockWorker.d.ts +13 -0
- package/dist/types/src/verification/parallelPool.d.ts +2 -0
- package/dist/types/test/verification/parallelPool.spec.d.ts +1 -0
- package/dist/types/tsconfig.types.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,3992 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
11
|
+
var __spreadValues = (a, b) => {
|
|
12
|
+
for (var prop in b || (b = {}))
|
|
13
|
+
if (__hasOwnProp.call(b, prop))
|
|
14
|
+
__defNormalProp(a, prop, b[prop]);
|
|
15
|
+
if (__getOwnPropSymbols)
|
|
16
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
17
|
+
if (__propIsEnum.call(b, prop))
|
|
18
|
+
__defNormalProp(a, prop, b[prop]);
|
|
19
|
+
}
|
|
20
|
+
return a;
|
|
21
|
+
};
|
|
22
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
|
+
var __export = (target, all) => {
|
|
24
|
+
for (var name in all)
|
|
25
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
26
|
+
};
|
|
27
|
+
var __copyProps = (to, from, except, desc) => {
|
|
28
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
29
|
+
for (let key of __getOwnPropNames(from))
|
|
30
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
31
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
32
|
+
}
|
|
33
|
+
return to;
|
|
34
|
+
};
|
|
35
|
+
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
|
|
36
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
37
|
+
var __async = (__this, __arguments, generator) => {
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
var fulfilled = (value) => {
|
|
40
|
+
try {
|
|
41
|
+
step(generator.next(value));
|
|
42
|
+
} catch (e) {
|
|
43
|
+
reject(e);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var rejected = (value) => {
|
|
47
|
+
try {
|
|
48
|
+
step(generator.throw(value));
|
|
49
|
+
} catch (e) {
|
|
50
|
+
reject(e);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
54
|
+
step((generator = generator.apply(__this, __arguments)).next());
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// src/verification/parallelPool.ts
|
|
59
|
+
var parallelPool_exports = {};
|
|
60
|
+
__export(parallelPool_exports, {
|
|
61
|
+
verifyBatchParallel: () => verifyBatchParallel,
|
|
62
|
+
verifySharesBinding: () => verifySharesBinding
|
|
63
|
+
});
|
|
64
|
+
module.exports = __toCommonJS(parallelPool_exports);
|
|
65
|
+
var import_ssz = require("@chainsafe/ssz");
|
|
66
|
+
|
|
67
|
+
// node_modules/@noble/curves/node_modules/@noble/hashes/utils.js
|
|
68
|
+
function isBytes(a) {
|
|
69
|
+
return a instanceof Uint8Array || ArrayBuffer.isView(a) && a.constructor.name === "Uint8Array" && "BYTES_PER_ELEMENT" in a && a.BYTES_PER_ELEMENT === 1;
|
|
70
|
+
}
|
|
71
|
+
function anumber(n, title = "") {
|
|
72
|
+
if (typeof n !== "number") {
|
|
73
|
+
const prefix = title && `"${title}" `;
|
|
74
|
+
throw new TypeError(`${prefix}expected number, got ${typeof n}`);
|
|
75
|
+
}
|
|
76
|
+
if (!Number.isSafeInteger(n) || n < 0) {
|
|
77
|
+
const prefix = title && `"${title}" `;
|
|
78
|
+
throw new RangeError(`${prefix}expected integer >= 0, got ${n}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function abytes(value, length, title = "") {
|
|
82
|
+
const bytes = isBytes(value);
|
|
83
|
+
const len = value == null ? void 0 : value.length;
|
|
84
|
+
const needsLen = length !== void 0;
|
|
85
|
+
if (!bytes || needsLen && len !== length) {
|
|
86
|
+
const prefix = title && `"${title}" `;
|
|
87
|
+
const ofLen = needsLen ? ` of length ${length}` : "";
|
|
88
|
+
const got = bytes ? `length=${len}` : `type=${typeof value}`;
|
|
89
|
+
const message = prefix + "expected Uint8Array" + ofLen + ", got " + got;
|
|
90
|
+
if (!bytes)
|
|
91
|
+
throw new TypeError(message);
|
|
92
|
+
throw new RangeError(message);
|
|
93
|
+
}
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
function aexists(instance, checkFinished = true) {
|
|
97
|
+
if (instance.destroyed)
|
|
98
|
+
throw new Error("Hash instance has been destroyed");
|
|
99
|
+
if (checkFinished && instance.finished)
|
|
100
|
+
throw new Error("Hash#digest() has already been called");
|
|
101
|
+
}
|
|
102
|
+
function aoutput(out, instance) {
|
|
103
|
+
abytes(out, void 0, "digestInto() output");
|
|
104
|
+
const min = instance.outputLen;
|
|
105
|
+
if (out.length < min) {
|
|
106
|
+
throw new RangeError('"digestInto() output" expected to be of length >=' + min);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function clean(...arrays) {
|
|
110
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
111
|
+
arrays[i].fill(0);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function createView(arr) {
|
|
115
|
+
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
|
116
|
+
}
|
|
117
|
+
function rotr(word, shift) {
|
|
118
|
+
return word << 32 - shift | word >>> shift;
|
|
119
|
+
}
|
|
120
|
+
var hasHexBuiltin = /* @__PURE__ */ (() => (
|
|
121
|
+
// @ts-ignore
|
|
122
|
+
typeof Uint8Array.from([]).toHex === "function" && typeof Uint8Array.fromHex === "function"
|
|
123
|
+
))();
|
|
124
|
+
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
|
|
125
|
+
function bytesToHex(bytes) {
|
|
126
|
+
abytes(bytes);
|
|
127
|
+
if (hasHexBuiltin)
|
|
128
|
+
return bytes.toHex();
|
|
129
|
+
let hex = "";
|
|
130
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
131
|
+
hex += hexes[bytes[i]];
|
|
132
|
+
}
|
|
133
|
+
return hex;
|
|
134
|
+
}
|
|
135
|
+
var asciis = { _0: 48, _9: 57, A: 65, F: 70, a: 97, f: 102 };
|
|
136
|
+
function asciiToBase16(ch) {
|
|
137
|
+
if (ch >= asciis._0 && ch <= asciis._9)
|
|
138
|
+
return ch - asciis._0;
|
|
139
|
+
if (ch >= asciis.A && ch <= asciis.F)
|
|
140
|
+
return ch - (asciis.A - 10);
|
|
141
|
+
if (ch >= asciis.a && ch <= asciis.f)
|
|
142
|
+
return ch - (asciis.a - 10);
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
function hexToBytes(hex) {
|
|
146
|
+
if (typeof hex !== "string")
|
|
147
|
+
throw new TypeError("hex string expected, got " + typeof hex);
|
|
148
|
+
if (hasHexBuiltin) {
|
|
149
|
+
try {
|
|
150
|
+
return Uint8Array.fromHex(hex);
|
|
151
|
+
} catch (error) {
|
|
152
|
+
if (error instanceof SyntaxError)
|
|
153
|
+
throw new RangeError(error.message);
|
|
154
|
+
throw error;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const hl = hex.length;
|
|
158
|
+
const al = hl / 2;
|
|
159
|
+
if (hl % 2)
|
|
160
|
+
throw new RangeError("hex string expected, got unpadded hex of length " + hl);
|
|
161
|
+
const array = new Uint8Array(al);
|
|
162
|
+
for (let ai = 0, hi = 0; ai < al; ai++, hi += 2) {
|
|
163
|
+
const n1 = asciiToBase16(hex.charCodeAt(hi));
|
|
164
|
+
const n2 = asciiToBase16(hex.charCodeAt(hi + 1));
|
|
165
|
+
if (n1 === void 0 || n2 === void 0) {
|
|
166
|
+
const char = hex[hi] + hex[hi + 1];
|
|
167
|
+
throw new RangeError('hex string expected, got non-hex character "' + char + '" at index ' + hi);
|
|
168
|
+
}
|
|
169
|
+
array[ai] = n1 * 16 + n2;
|
|
170
|
+
}
|
|
171
|
+
return array;
|
|
172
|
+
}
|
|
173
|
+
function concatBytes(...arrays) {
|
|
174
|
+
let sum = 0;
|
|
175
|
+
for (let i = 0; i < arrays.length; i++) {
|
|
176
|
+
const a = arrays[i];
|
|
177
|
+
abytes(a);
|
|
178
|
+
sum += a.length;
|
|
179
|
+
}
|
|
180
|
+
const res = new Uint8Array(sum);
|
|
181
|
+
for (let i = 0, pad = 0; i < arrays.length; i++) {
|
|
182
|
+
const a = arrays[i];
|
|
183
|
+
res.set(a, pad);
|
|
184
|
+
pad += a.length;
|
|
185
|
+
}
|
|
186
|
+
return res;
|
|
187
|
+
}
|
|
188
|
+
function createHasher(hashCons, info = {}) {
|
|
189
|
+
const hashC = (msg, opts) => hashCons(opts).update(msg).digest();
|
|
190
|
+
const tmp = hashCons(void 0);
|
|
191
|
+
hashC.outputLen = tmp.outputLen;
|
|
192
|
+
hashC.blockLen = tmp.blockLen;
|
|
193
|
+
hashC.canXOF = tmp.canXOF;
|
|
194
|
+
hashC.create = (opts) => hashCons(opts);
|
|
195
|
+
Object.assign(hashC, info);
|
|
196
|
+
return Object.freeze(hashC);
|
|
197
|
+
}
|
|
198
|
+
function randomBytes(bytesLength = 32) {
|
|
199
|
+
anumber(bytesLength, "bytesLength");
|
|
200
|
+
const cr = typeof globalThis === "object" ? globalThis.crypto : null;
|
|
201
|
+
if (typeof (cr == null ? void 0 : cr.getRandomValues) !== "function")
|
|
202
|
+
throw new Error("crypto.getRandomValues must be defined");
|
|
203
|
+
if (bytesLength > 65536)
|
|
204
|
+
throw new RangeError(`"bytesLength" expected <= 65536, got ${bytesLength}`);
|
|
205
|
+
return cr.getRandomValues(new Uint8Array(bytesLength));
|
|
206
|
+
}
|
|
207
|
+
var oidNist = (suffix) => ({
|
|
208
|
+
// Current NIST hashAlgs suffixes used here fit in one DER subidentifier octet.
|
|
209
|
+
// Larger suffix values would need base-128 OID encoding and a different length byte.
|
|
210
|
+
oid: Uint8Array.from([6, 9, 96, 134, 72, 1, 101, 3, 4, 2, suffix])
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
// node_modules/@noble/curves/node_modules/@noble/hashes/_md.js
|
|
214
|
+
function Chi(a, b, c) {
|
|
215
|
+
return a & b ^ ~a & c;
|
|
216
|
+
}
|
|
217
|
+
function Maj(a, b, c) {
|
|
218
|
+
return a & b ^ a & c ^ b & c;
|
|
219
|
+
}
|
|
220
|
+
var HashMD = class {
|
|
221
|
+
constructor(blockLen, outputLen, padOffset, isLE) {
|
|
222
|
+
__publicField(this, "blockLen");
|
|
223
|
+
__publicField(this, "outputLen");
|
|
224
|
+
__publicField(this, "canXOF", false);
|
|
225
|
+
__publicField(this, "padOffset");
|
|
226
|
+
__publicField(this, "isLE");
|
|
227
|
+
// For partial updates less than block size
|
|
228
|
+
__publicField(this, "buffer");
|
|
229
|
+
__publicField(this, "view");
|
|
230
|
+
__publicField(this, "finished", false);
|
|
231
|
+
__publicField(this, "length", 0);
|
|
232
|
+
__publicField(this, "pos", 0);
|
|
233
|
+
__publicField(this, "destroyed", false);
|
|
234
|
+
this.blockLen = blockLen;
|
|
235
|
+
this.outputLen = outputLen;
|
|
236
|
+
this.padOffset = padOffset;
|
|
237
|
+
this.isLE = isLE;
|
|
238
|
+
this.buffer = new Uint8Array(blockLen);
|
|
239
|
+
this.view = createView(this.buffer);
|
|
240
|
+
}
|
|
241
|
+
update(data) {
|
|
242
|
+
aexists(this);
|
|
243
|
+
abytes(data);
|
|
244
|
+
const { view, buffer, blockLen } = this;
|
|
245
|
+
const len = data.length;
|
|
246
|
+
for (let pos = 0; pos < len; ) {
|
|
247
|
+
const take = Math.min(blockLen - this.pos, len - pos);
|
|
248
|
+
if (take === blockLen) {
|
|
249
|
+
const dataView = createView(data);
|
|
250
|
+
for (; blockLen <= len - pos; pos += blockLen)
|
|
251
|
+
this.process(dataView, pos);
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
buffer.set(data.subarray(pos, pos + take), this.pos);
|
|
255
|
+
this.pos += take;
|
|
256
|
+
pos += take;
|
|
257
|
+
if (this.pos === blockLen) {
|
|
258
|
+
this.process(view, 0);
|
|
259
|
+
this.pos = 0;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
this.length += data.length;
|
|
263
|
+
this.roundClean();
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
digestInto(out) {
|
|
267
|
+
aexists(this);
|
|
268
|
+
aoutput(out, this);
|
|
269
|
+
this.finished = true;
|
|
270
|
+
const { buffer, view, blockLen, isLE } = this;
|
|
271
|
+
let { pos } = this;
|
|
272
|
+
buffer[pos++] = 128;
|
|
273
|
+
clean(this.buffer.subarray(pos));
|
|
274
|
+
if (this.padOffset > blockLen - pos) {
|
|
275
|
+
this.process(view, 0);
|
|
276
|
+
pos = 0;
|
|
277
|
+
}
|
|
278
|
+
for (let i = pos; i < blockLen; i++)
|
|
279
|
+
buffer[i] = 0;
|
|
280
|
+
view.setBigUint64(blockLen - 8, BigInt(this.length * 8), isLE);
|
|
281
|
+
this.process(view, 0);
|
|
282
|
+
const oview = createView(out);
|
|
283
|
+
const len = this.outputLen;
|
|
284
|
+
if (len % 4)
|
|
285
|
+
throw new Error("_sha2: outputLen must be aligned to 32bit");
|
|
286
|
+
const outLen = len / 4;
|
|
287
|
+
const state = this.get();
|
|
288
|
+
if (outLen > state.length)
|
|
289
|
+
throw new Error("_sha2: outputLen bigger than state");
|
|
290
|
+
for (let i = 0; i < outLen; i++)
|
|
291
|
+
oview.setUint32(4 * i, state[i], isLE);
|
|
292
|
+
}
|
|
293
|
+
digest() {
|
|
294
|
+
const { buffer, outputLen } = this;
|
|
295
|
+
this.digestInto(buffer);
|
|
296
|
+
const res = buffer.slice(0, outputLen);
|
|
297
|
+
this.destroy();
|
|
298
|
+
return res;
|
|
299
|
+
}
|
|
300
|
+
_cloneInto(to) {
|
|
301
|
+
to || (to = new this.constructor());
|
|
302
|
+
to.set(...this.get());
|
|
303
|
+
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
|
304
|
+
to.destroyed = destroyed;
|
|
305
|
+
to.finished = finished;
|
|
306
|
+
to.length = length;
|
|
307
|
+
to.pos = pos;
|
|
308
|
+
if (length % blockLen)
|
|
309
|
+
to.buffer.set(buffer);
|
|
310
|
+
return to;
|
|
311
|
+
}
|
|
312
|
+
clone() {
|
|
313
|
+
return this._cloneInto();
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
var SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
|
317
|
+
1779033703,
|
|
318
|
+
3144134277,
|
|
319
|
+
1013904242,
|
|
320
|
+
2773480762,
|
|
321
|
+
1359893119,
|
|
322
|
+
2600822924,
|
|
323
|
+
528734635,
|
|
324
|
+
1541459225
|
|
325
|
+
]);
|
|
326
|
+
|
|
327
|
+
// node_modules/@noble/curves/node_modules/@noble/hashes/sha2.js
|
|
328
|
+
var SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
|
329
|
+
1116352408,
|
|
330
|
+
1899447441,
|
|
331
|
+
3049323471,
|
|
332
|
+
3921009573,
|
|
333
|
+
961987163,
|
|
334
|
+
1508970993,
|
|
335
|
+
2453635748,
|
|
336
|
+
2870763221,
|
|
337
|
+
3624381080,
|
|
338
|
+
310598401,
|
|
339
|
+
607225278,
|
|
340
|
+
1426881987,
|
|
341
|
+
1925078388,
|
|
342
|
+
2162078206,
|
|
343
|
+
2614888103,
|
|
344
|
+
3248222580,
|
|
345
|
+
3835390401,
|
|
346
|
+
4022224774,
|
|
347
|
+
264347078,
|
|
348
|
+
604807628,
|
|
349
|
+
770255983,
|
|
350
|
+
1249150122,
|
|
351
|
+
1555081692,
|
|
352
|
+
1996064986,
|
|
353
|
+
2554220882,
|
|
354
|
+
2821834349,
|
|
355
|
+
2952996808,
|
|
356
|
+
3210313671,
|
|
357
|
+
3336571891,
|
|
358
|
+
3584528711,
|
|
359
|
+
113926993,
|
|
360
|
+
338241895,
|
|
361
|
+
666307205,
|
|
362
|
+
773529912,
|
|
363
|
+
1294757372,
|
|
364
|
+
1396182291,
|
|
365
|
+
1695183700,
|
|
366
|
+
1986661051,
|
|
367
|
+
2177026350,
|
|
368
|
+
2456956037,
|
|
369
|
+
2730485921,
|
|
370
|
+
2820302411,
|
|
371
|
+
3259730800,
|
|
372
|
+
3345764771,
|
|
373
|
+
3516065817,
|
|
374
|
+
3600352804,
|
|
375
|
+
4094571909,
|
|
376
|
+
275423344,
|
|
377
|
+
430227734,
|
|
378
|
+
506948616,
|
|
379
|
+
659060556,
|
|
380
|
+
883997877,
|
|
381
|
+
958139571,
|
|
382
|
+
1322822218,
|
|
383
|
+
1537002063,
|
|
384
|
+
1747873779,
|
|
385
|
+
1955562222,
|
|
386
|
+
2024104815,
|
|
387
|
+
2227730452,
|
|
388
|
+
2361852424,
|
|
389
|
+
2428436474,
|
|
390
|
+
2756734187,
|
|
391
|
+
3204031479,
|
|
392
|
+
3329325298
|
|
393
|
+
]);
|
|
394
|
+
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
|
395
|
+
var SHA2_32B = class extends HashMD {
|
|
396
|
+
constructor(outputLen) {
|
|
397
|
+
super(64, outputLen, 8, false);
|
|
398
|
+
}
|
|
399
|
+
get() {
|
|
400
|
+
const { A, B, C, D, E, F, G, H } = this;
|
|
401
|
+
return [A, B, C, D, E, F, G, H];
|
|
402
|
+
}
|
|
403
|
+
// prettier-ignore
|
|
404
|
+
set(A, B, C, D, E, F, G, H) {
|
|
405
|
+
this.A = A | 0;
|
|
406
|
+
this.B = B | 0;
|
|
407
|
+
this.C = C | 0;
|
|
408
|
+
this.D = D | 0;
|
|
409
|
+
this.E = E | 0;
|
|
410
|
+
this.F = F | 0;
|
|
411
|
+
this.G = G | 0;
|
|
412
|
+
this.H = H | 0;
|
|
413
|
+
}
|
|
414
|
+
process(view, offset) {
|
|
415
|
+
for (let i = 0; i < 16; i++, offset += 4)
|
|
416
|
+
SHA256_W[i] = view.getUint32(offset, false);
|
|
417
|
+
for (let i = 16; i < 64; i++) {
|
|
418
|
+
const W15 = SHA256_W[i - 15];
|
|
419
|
+
const W2 = SHA256_W[i - 2];
|
|
420
|
+
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
|
|
421
|
+
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
|
|
422
|
+
SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
|
|
423
|
+
}
|
|
424
|
+
let { A, B, C, D, E, F, G, H } = this;
|
|
425
|
+
for (let i = 0; i < 64; i++) {
|
|
426
|
+
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
|
|
427
|
+
const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
|
|
428
|
+
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
|
|
429
|
+
const T2 = sigma0 + Maj(A, B, C) | 0;
|
|
430
|
+
H = G;
|
|
431
|
+
G = F;
|
|
432
|
+
F = E;
|
|
433
|
+
E = D + T1 | 0;
|
|
434
|
+
D = C;
|
|
435
|
+
C = B;
|
|
436
|
+
B = A;
|
|
437
|
+
A = T1 + T2 | 0;
|
|
438
|
+
}
|
|
439
|
+
A = A + this.A | 0;
|
|
440
|
+
B = B + this.B | 0;
|
|
441
|
+
C = C + this.C | 0;
|
|
442
|
+
D = D + this.D | 0;
|
|
443
|
+
E = E + this.E | 0;
|
|
444
|
+
F = F + this.F | 0;
|
|
445
|
+
G = G + this.G | 0;
|
|
446
|
+
H = H + this.H | 0;
|
|
447
|
+
this.set(A, B, C, D, E, F, G, H);
|
|
448
|
+
}
|
|
449
|
+
roundClean() {
|
|
450
|
+
clean(SHA256_W);
|
|
451
|
+
}
|
|
452
|
+
destroy() {
|
|
453
|
+
this.destroyed = true;
|
|
454
|
+
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
|
455
|
+
clean(this.buffer);
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
var _SHA256 = class extends SHA2_32B {
|
|
459
|
+
constructor() {
|
|
460
|
+
super(32);
|
|
461
|
+
// We cannot use array here since array allows indexing by variable
|
|
462
|
+
// which means optimizer/compiler cannot use registers.
|
|
463
|
+
__publicField(this, "A", SHA256_IV[0] | 0);
|
|
464
|
+
__publicField(this, "B", SHA256_IV[1] | 0);
|
|
465
|
+
__publicField(this, "C", SHA256_IV[2] | 0);
|
|
466
|
+
__publicField(this, "D", SHA256_IV[3] | 0);
|
|
467
|
+
__publicField(this, "E", SHA256_IV[4] | 0);
|
|
468
|
+
__publicField(this, "F", SHA256_IV[5] | 0);
|
|
469
|
+
__publicField(this, "G", SHA256_IV[6] | 0);
|
|
470
|
+
__publicField(this, "H", SHA256_IV[7] | 0);
|
|
471
|
+
}
|
|
472
|
+
};
|
|
473
|
+
var sha256 = /* @__PURE__ */ createHasher(
|
|
474
|
+
() => new _SHA256(),
|
|
475
|
+
/* @__PURE__ */ oidNist(1)
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
// node_modules/@noble/curves/utils.js
|
|
479
|
+
var abytes2 = (value, length, title) => abytes(value, length, title);
|
|
480
|
+
var anumber2 = anumber;
|
|
481
|
+
var bytesToHex2 = bytesToHex;
|
|
482
|
+
var concatBytes2 = (...arrays) => concatBytes(...arrays);
|
|
483
|
+
var hexToBytes2 = (hex) => hexToBytes(hex);
|
|
484
|
+
var isBytes2 = isBytes;
|
|
485
|
+
var randomBytes2 = (bytesLength) => randomBytes(bytesLength);
|
|
486
|
+
var _0n = /* @__PURE__ */ BigInt(0);
|
|
487
|
+
var _1n = /* @__PURE__ */ BigInt(1);
|
|
488
|
+
function abool(value, title = "") {
|
|
489
|
+
if (typeof value !== "boolean") {
|
|
490
|
+
const prefix = title && `"${title}" `;
|
|
491
|
+
throw new TypeError(prefix + "expected boolean, got type=" + typeof value);
|
|
492
|
+
}
|
|
493
|
+
return value;
|
|
494
|
+
}
|
|
495
|
+
function abignumber(n) {
|
|
496
|
+
if (typeof n === "bigint") {
|
|
497
|
+
if (!isPosBig(n))
|
|
498
|
+
throw new RangeError("positive bigint expected, got " + n);
|
|
499
|
+
} else
|
|
500
|
+
anumber2(n);
|
|
501
|
+
return n;
|
|
502
|
+
}
|
|
503
|
+
function asafenumber(value, title = "") {
|
|
504
|
+
if (typeof value !== "number") {
|
|
505
|
+
const prefix = title && `"${title}" `;
|
|
506
|
+
throw new TypeError(prefix + "expected number, got type=" + typeof value);
|
|
507
|
+
}
|
|
508
|
+
if (!Number.isSafeInteger(value)) {
|
|
509
|
+
const prefix = title && `"${title}" `;
|
|
510
|
+
throw new RangeError(prefix + "expected safe integer, got " + value);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function numberToHexUnpadded(num) {
|
|
514
|
+
const hex = abignumber(num).toString(16);
|
|
515
|
+
return hex.length & 1 ? "0" + hex : hex;
|
|
516
|
+
}
|
|
517
|
+
function hexToNumber(hex) {
|
|
518
|
+
if (typeof hex !== "string")
|
|
519
|
+
throw new TypeError("hex string expected, got " + typeof hex);
|
|
520
|
+
return hex === "" ? _0n : BigInt("0x" + hex);
|
|
521
|
+
}
|
|
522
|
+
function bytesToNumberBE(bytes) {
|
|
523
|
+
return hexToNumber(bytesToHex(bytes));
|
|
524
|
+
}
|
|
525
|
+
function bytesToNumberLE(bytes) {
|
|
526
|
+
return hexToNumber(bytesToHex(copyBytes(abytes(bytes)).reverse()));
|
|
527
|
+
}
|
|
528
|
+
function numberToBytesBE(n, len) {
|
|
529
|
+
anumber(len);
|
|
530
|
+
if (len === 0)
|
|
531
|
+
throw new RangeError("zero length");
|
|
532
|
+
n = abignumber(n);
|
|
533
|
+
const hex = n.toString(16);
|
|
534
|
+
if (hex.length > len * 2)
|
|
535
|
+
throw new RangeError("number too large");
|
|
536
|
+
return hexToBytes(hex.padStart(len * 2, "0"));
|
|
537
|
+
}
|
|
538
|
+
function numberToBytesLE(n, len) {
|
|
539
|
+
return numberToBytesBE(n, len).reverse();
|
|
540
|
+
}
|
|
541
|
+
function copyBytes(bytes) {
|
|
542
|
+
return Uint8Array.from(abytes2(bytes));
|
|
543
|
+
}
|
|
544
|
+
function asciiToBytes(ascii) {
|
|
545
|
+
if (typeof ascii !== "string")
|
|
546
|
+
throw new TypeError("ascii string expected, got " + typeof ascii);
|
|
547
|
+
return Uint8Array.from(ascii, (c, i) => {
|
|
548
|
+
const charCode = c.charCodeAt(0);
|
|
549
|
+
if (c.length !== 1 || charCode > 127) {
|
|
550
|
+
throw new RangeError(`string contains non-ASCII character "${ascii[i]}" with code ${charCode} at position ${i}`);
|
|
551
|
+
}
|
|
552
|
+
return charCode;
|
|
553
|
+
});
|
|
554
|
+
}
|
|
555
|
+
var isPosBig = (n) => typeof n === "bigint" && _0n <= n;
|
|
556
|
+
function inRange(n, min, max) {
|
|
557
|
+
return isPosBig(n) && isPosBig(min) && isPosBig(max) && min <= n && n < max;
|
|
558
|
+
}
|
|
559
|
+
function aInRange(title, n, min, max) {
|
|
560
|
+
if (!inRange(n, min, max))
|
|
561
|
+
throw new RangeError("expected valid " + title + ": " + min + " <= n < " + max + ", got " + n);
|
|
562
|
+
}
|
|
563
|
+
function bitLen(n) {
|
|
564
|
+
if (n < _0n)
|
|
565
|
+
throw new Error("expected non-negative bigint, got " + n);
|
|
566
|
+
let len;
|
|
567
|
+
for (len = 0; n > _0n; n >>= _1n, len += 1)
|
|
568
|
+
;
|
|
569
|
+
return len;
|
|
570
|
+
}
|
|
571
|
+
function bitGet(n, pos) {
|
|
572
|
+
return n >> BigInt(pos) & _1n;
|
|
573
|
+
}
|
|
574
|
+
var bitMask = (n) => (_1n << BigInt(n)) - _1n;
|
|
575
|
+
function validateObject(object, fields2 = {}, optFields = {}) {
|
|
576
|
+
if (Object.prototype.toString.call(object) !== "[object Object]")
|
|
577
|
+
throw new TypeError("expected valid options object");
|
|
578
|
+
function checkField(fieldName, expectedType, isOpt) {
|
|
579
|
+
if (!isOpt && expectedType !== "function" && !Object.hasOwn(object, fieldName))
|
|
580
|
+
throw new TypeError(`param "${fieldName}" is invalid: expected own property`);
|
|
581
|
+
const val = object[fieldName];
|
|
582
|
+
if (isOpt && val === void 0)
|
|
583
|
+
return;
|
|
584
|
+
const current = typeof val;
|
|
585
|
+
if (current !== expectedType || val === null)
|
|
586
|
+
throw new TypeError(`param "${fieldName}" is invalid: expected ${expectedType}, got ${current}`);
|
|
587
|
+
}
|
|
588
|
+
const iter = (f, isOpt) => Object.entries(f).forEach(([k, v]) => checkField(k, v, isOpt));
|
|
589
|
+
iter(fields2, false);
|
|
590
|
+
iter(optFields, true);
|
|
591
|
+
}
|
|
592
|
+
var notImplemented = () => {
|
|
593
|
+
throw new Error("not implemented");
|
|
594
|
+
};
|
|
595
|
+
|
|
596
|
+
// node_modules/@noble/curves/abstract/modular.js
|
|
597
|
+
var _0n2 = /* @__PURE__ */ BigInt(0);
|
|
598
|
+
var _1n2 = /* @__PURE__ */ BigInt(1);
|
|
599
|
+
var _2n = /* @__PURE__ */ BigInt(2);
|
|
600
|
+
var _3n = /* @__PURE__ */ BigInt(3);
|
|
601
|
+
var _4n = /* @__PURE__ */ BigInt(4);
|
|
602
|
+
var _5n = /* @__PURE__ */ BigInt(5);
|
|
603
|
+
var _7n = /* @__PURE__ */ BigInt(7);
|
|
604
|
+
var _8n = /* @__PURE__ */ BigInt(8);
|
|
605
|
+
var _9n = /* @__PURE__ */ BigInt(9);
|
|
606
|
+
var _16n = /* @__PURE__ */ BigInt(16);
|
|
607
|
+
function mod(a, b) {
|
|
608
|
+
if (b <= _0n2)
|
|
609
|
+
throw new Error("mod: expected positive modulus, got " + b);
|
|
610
|
+
const result = a % b;
|
|
611
|
+
return result >= _0n2 ? result : b + result;
|
|
612
|
+
}
|
|
613
|
+
function invert(number, modulo) {
|
|
614
|
+
if (number === _0n2)
|
|
615
|
+
throw new Error("invert: expected non-zero number");
|
|
616
|
+
if (modulo <= _0n2)
|
|
617
|
+
throw new Error("invert: expected positive modulus, got " + modulo);
|
|
618
|
+
let a = mod(number, modulo);
|
|
619
|
+
let b = modulo;
|
|
620
|
+
let x = _0n2, y = _1n2, u = _1n2, v = _0n2;
|
|
621
|
+
while (a !== _0n2) {
|
|
622
|
+
const q = b / a;
|
|
623
|
+
const r = b - a * q;
|
|
624
|
+
const m = x - u * q;
|
|
625
|
+
const n = y - v * q;
|
|
626
|
+
b = a, a = r, x = u, y = v, u = m, v = n;
|
|
627
|
+
}
|
|
628
|
+
const gcd = b;
|
|
629
|
+
if (gcd !== _1n2)
|
|
630
|
+
throw new Error("invert: does not exist");
|
|
631
|
+
return mod(x, modulo);
|
|
632
|
+
}
|
|
633
|
+
function assertIsSquare(Fp3, root, n) {
|
|
634
|
+
const F = Fp3;
|
|
635
|
+
if (!F.eql(F.sqr(root), n))
|
|
636
|
+
throw new Error("Cannot find square root");
|
|
637
|
+
}
|
|
638
|
+
function sqrt3mod4(Fp3, n) {
|
|
639
|
+
const F = Fp3;
|
|
640
|
+
const p1div4 = (F.ORDER + _1n2) / _4n;
|
|
641
|
+
const root = F.pow(n, p1div4);
|
|
642
|
+
assertIsSquare(F, root, n);
|
|
643
|
+
return root;
|
|
644
|
+
}
|
|
645
|
+
function sqrt5mod8(Fp3, n) {
|
|
646
|
+
const F = Fp3;
|
|
647
|
+
const p5div8 = (F.ORDER - _5n) / _8n;
|
|
648
|
+
const n2 = F.mul(n, _2n);
|
|
649
|
+
const v = F.pow(n2, p5div8);
|
|
650
|
+
const nv = F.mul(n, v);
|
|
651
|
+
const i = F.mul(F.mul(nv, _2n), v);
|
|
652
|
+
const root = F.mul(nv, F.sub(i, F.ONE));
|
|
653
|
+
assertIsSquare(F, root, n);
|
|
654
|
+
return root;
|
|
655
|
+
}
|
|
656
|
+
function sqrt9mod16(P) {
|
|
657
|
+
const Fp_ = Field(P);
|
|
658
|
+
const tn = tonelliShanks(P);
|
|
659
|
+
const c1 = tn(Fp_, Fp_.neg(Fp_.ONE));
|
|
660
|
+
const c2 = tn(Fp_, c1);
|
|
661
|
+
const c3 = tn(Fp_, Fp_.neg(c1));
|
|
662
|
+
const c4 = (P + _7n) / _16n;
|
|
663
|
+
return ((Fp3, n) => {
|
|
664
|
+
const F = Fp3;
|
|
665
|
+
let tv1 = F.pow(n, c4);
|
|
666
|
+
let tv2 = F.mul(tv1, c1);
|
|
667
|
+
const tv3 = F.mul(tv1, c2);
|
|
668
|
+
const tv4 = F.mul(tv1, c3);
|
|
669
|
+
const e1 = F.eql(F.sqr(tv2), n);
|
|
670
|
+
const e2 = F.eql(F.sqr(tv3), n);
|
|
671
|
+
tv1 = F.cmov(tv1, tv2, e1);
|
|
672
|
+
tv2 = F.cmov(tv4, tv3, e2);
|
|
673
|
+
const e3 = F.eql(F.sqr(tv2), n);
|
|
674
|
+
const root = F.cmov(tv1, tv2, e3);
|
|
675
|
+
assertIsSquare(F, root, n);
|
|
676
|
+
return root;
|
|
677
|
+
});
|
|
678
|
+
}
|
|
679
|
+
function tonelliShanks(P) {
|
|
680
|
+
if (P < _3n)
|
|
681
|
+
throw new Error("sqrt is not defined for small field");
|
|
682
|
+
let Q = P - _1n2;
|
|
683
|
+
let S = 0;
|
|
684
|
+
while (Q % _2n === _0n2) {
|
|
685
|
+
Q /= _2n;
|
|
686
|
+
S++;
|
|
687
|
+
}
|
|
688
|
+
let Z = _2n;
|
|
689
|
+
const _Fp = Field(P);
|
|
690
|
+
while (FpLegendre(_Fp, Z) === 1) {
|
|
691
|
+
if (Z++ > 1e3)
|
|
692
|
+
throw new Error("Cannot find square root: probably non-prime P");
|
|
693
|
+
}
|
|
694
|
+
if (S === 1)
|
|
695
|
+
return sqrt3mod4;
|
|
696
|
+
let cc = _Fp.pow(Z, Q);
|
|
697
|
+
const Q1div2 = (Q + _1n2) / _2n;
|
|
698
|
+
return function tonelliSlow(Fp3, n) {
|
|
699
|
+
const F = Fp3;
|
|
700
|
+
if (F.is0(n))
|
|
701
|
+
return n;
|
|
702
|
+
if (FpLegendre(F, n) !== 1)
|
|
703
|
+
throw new Error("Cannot find square root");
|
|
704
|
+
let M = S;
|
|
705
|
+
let c = F.mul(F.ONE, cc);
|
|
706
|
+
let t = F.pow(n, Q);
|
|
707
|
+
let R = F.pow(n, Q1div2);
|
|
708
|
+
while (!F.eql(t, F.ONE)) {
|
|
709
|
+
if (F.is0(t))
|
|
710
|
+
return F.ZERO;
|
|
711
|
+
let i = 1;
|
|
712
|
+
let t_tmp = F.sqr(t);
|
|
713
|
+
while (!F.eql(t_tmp, F.ONE)) {
|
|
714
|
+
i++;
|
|
715
|
+
t_tmp = F.sqr(t_tmp);
|
|
716
|
+
if (i === M)
|
|
717
|
+
throw new Error("Cannot find square root");
|
|
718
|
+
}
|
|
719
|
+
const exponent = _1n2 << BigInt(M - i - 1);
|
|
720
|
+
const b = F.pow(c, exponent);
|
|
721
|
+
M = i;
|
|
722
|
+
c = F.sqr(b);
|
|
723
|
+
t = F.mul(t, c);
|
|
724
|
+
R = F.mul(R, b);
|
|
725
|
+
}
|
|
726
|
+
return R;
|
|
727
|
+
};
|
|
728
|
+
}
|
|
729
|
+
function FpSqrt(P) {
|
|
730
|
+
if (P % _4n === _3n)
|
|
731
|
+
return sqrt3mod4;
|
|
732
|
+
if (P % _8n === _5n)
|
|
733
|
+
return sqrt5mod8;
|
|
734
|
+
if (P % _16n === _9n)
|
|
735
|
+
return sqrt9mod16(P);
|
|
736
|
+
return tonelliShanks(P);
|
|
737
|
+
}
|
|
738
|
+
var FIELD_FIELDS = [
|
|
739
|
+
"create",
|
|
740
|
+
"isValid",
|
|
741
|
+
"is0",
|
|
742
|
+
"neg",
|
|
743
|
+
"inv",
|
|
744
|
+
"sqrt",
|
|
745
|
+
"sqr",
|
|
746
|
+
"eql",
|
|
747
|
+
"add",
|
|
748
|
+
"sub",
|
|
749
|
+
"mul",
|
|
750
|
+
"pow",
|
|
751
|
+
"div",
|
|
752
|
+
"addN",
|
|
753
|
+
"subN",
|
|
754
|
+
"mulN",
|
|
755
|
+
"sqrN"
|
|
756
|
+
];
|
|
757
|
+
function validateField(field) {
|
|
758
|
+
const initial = {
|
|
759
|
+
ORDER: "bigint",
|
|
760
|
+
BYTES: "number",
|
|
761
|
+
BITS: "number"
|
|
762
|
+
};
|
|
763
|
+
const opts = FIELD_FIELDS.reduce((map, val) => {
|
|
764
|
+
map[val] = "function";
|
|
765
|
+
return map;
|
|
766
|
+
}, initial);
|
|
767
|
+
validateObject(field, opts);
|
|
768
|
+
asafenumber(field.BYTES, "BYTES");
|
|
769
|
+
asafenumber(field.BITS, "BITS");
|
|
770
|
+
if (field.BYTES < 1 || field.BITS < 1)
|
|
771
|
+
throw new Error("invalid field: expected BYTES/BITS > 0");
|
|
772
|
+
if (field.ORDER <= _1n2)
|
|
773
|
+
throw new Error("invalid field: expected ORDER > 1, got " + field.ORDER);
|
|
774
|
+
return field;
|
|
775
|
+
}
|
|
776
|
+
function FpPow(Fp3, num, power) {
|
|
777
|
+
const F = Fp3;
|
|
778
|
+
if (power < _0n2)
|
|
779
|
+
throw new Error("invalid exponent, negatives unsupported");
|
|
780
|
+
if (power === _0n2)
|
|
781
|
+
return F.ONE;
|
|
782
|
+
if (power === _1n2)
|
|
783
|
+
return num;
|
|
784
|
+
let p = F.ONE;
|
|
785
|
+
let d = num;
|
|
786
|
+
while (power > _0n2) {
|
|
787
|
+
if (power & _1n2)
|
|
788
|
+
p = F.mul(p, d);
|
|
789
|
+
d = F.sqr(d);
|
|
790
|
+
power >>= _1n2;
|
|
791
|
+
}
|
|
792
|
+
return p;
|
|
793
|
+
}
|
|
794
|
+
function FpInvertBatch(Fp3, nums, passZero = false) {
|
|
795
|
+
const F = Fp3;
|
|
796
|
+
const inverted = new Array(nums.length).fill(passZero ? F.ZERO : void 0);
|
|
797
|
+
const multipliedAcc = nums.reduce((acc, num, i) => {
|
|
798
|
+
if (F.is0(num))
|
|
799
|
+
return acc;
|
|
800
|
+
inverted[i] = acc;
|
|
801
|
+
return F.mul(acc, num);
|
|
802
|
+
}, F.ONE);
|
|
803
|
+
const invertedAcc = F.inv(multipliedAcc);
|
|
804
|
+
nums.reduceRight((acc, num, i) => {
|
|
805
|
+
if (F.is0(num))
|
|
806
|
+
return acc;
|
|
807
|
+
inverted[i] = F.mul(acc, inverted[i]);
|
|
808
|
+
return F.mul(acc, num);
|
|
809
|
+
}, invertedAcc);
|
|
810
|
+
return inverted;
|
|
811
|
+
}
|
|
812
|
+
function FpLegendre(Fp3, n) {
|
|
813
|
+
const F = Fp3;
|
|
814
|
+
const p1mod2 = (F.ORDER - _1n2) / _2n;
|
|
815
|
+
const powered = F.pow(n, p1mod2);
|
|
816
|
+
const yes = F.eql(powered, F.ONE);
|
|
817
|
+
const zero = F.eql(powered, F.ZERO);
|
|
818
|
+
const no = F.eql(powered, F.neg(F.ONE));
|
|
819
|
+
if (!yes && !zero && !no)
|
|
820
|
+
throw new Error("invalid Legendre symbol result");
|
|
821
|
+
return yes ? 1 : zero ? 0 : -1;
|
|
822
|
+
}
|
|
823
|
+
function FpIsSquare(Fp3, n) {
|
|
824
|
+
const l = FpLegendre(Fp3, n);
|
|
825
|
+
return l !== -1;
|
|
826
|
+
}
|
|
827
|
+
function nLength(n, nBitLength) {
|
|
828
|
+
if (nBitLength !== void 0)
|
|
829
|
+
anumber2(nBitLength);
|
|
830
|
+
if (n <= _0n2)
|
|
831
|
+
throw new Error("invalid n length: expected positive n, got " + n);
|
|
832
|
+
if (nBitLength !== void 0 && nBitLength < 1)
|
|
833
|
+
throw new Error("invalid n length: expected positive bit length, got " + nBitLength);
|
|
834
|
+
const bits = bitLen(n);
|
|
835
|
+
if (nBitLength !== void 0 && nBitLength < bits)
|
|
836
|
+
throw new Error(`invalid n length: expected bit length (${bits}) >= n.length (${nBitLength})`);
|
|
837
|
+
const _nBitLength = nBitLength !== void 0 ? nBitLength : bits;
|
|
838
|
+
const nByteLength = Math.ceil(_nBitLength / 8);
|
|
839
|
+
return { nBitLength: _nBitLength, nByteLength };
|
|
840
|
+
}
|
|
841
|
+
var FIELD_SQRT = /* @__PURE__ */ new WeakMap();
|
|
842
|
+
var _Field = class {
|
|
843
|
+
constructor(ORDER, opts = {}) {
|
|
844
|
+
__publicField(this, "ORDER");
|
|
845
|
+
__publicField(this, "BITS");
|
|
846
|
+
__publicField(this, "BYTES");
|
|
847
|
+
__publicField(this, "isLE");
|
|
848
|
+
__publicField(this, "ZERO", _0n2);
|
|
849
|
+
__publicField(this, "ONE", _1n2);
|
|
850
|
+
__publicField(this, "_lengths");
|
|
851
|
+
__publicField(this, "_mod");
|
|
852
|
+
if (ORDER <= _1n2)
|
|
853
|
+
throw new Error("invalid field: expected ORDER > 1, got " + ORDER);
|
|
854
|
+
let _nbitLength = void 0;
|
|
855
|
+
this.isLE = false;
|
|
856
|
+
if (opts != null && typeof opts === "object") {
|
|
857
|
+
if (typeof opts.BITS === "number")
|
|
858
|
+
_nbitLength = opts.BITS;
|
|
859
|
+
if (typeof opts.sqrt === "function")
|
|
860
|
+
Object.defineProperty(this, "sqrt", { value: opts.sqrt, enumerable: true });
|
|
861
|
+
if (typeof opts.isLE === "boolean")
|
|
862
|
+
this.isLE = opts.isLE;
|
|
863
|
+
if (opts.allowedLengths)
|
|
864
|
+
this._lengths = Object.freeze(opts.allowedLengths.slice());
|
|
865
|
+
if (typeof opts.modFromBytes === "boolean")
|
|
866
|
+
this._mod = opts.modFromBytes;
|
|
867
|
+
}
|
|
868
|
+
const { nBitLength, nByteLength } = nLength(ORDER, _nbitLength);
|
|
869
|
+
if (nByteLength > 2048)
|
|
870
|
+
throw new Error("invalid field: expected ORDER of <= 2048 bytes");
|
|
871
|
+
this.ORDER = ORDER;
|
|
872
|
+
this.BITS = nBitLength;
|
|
873
|
+
this.BYTES = nByteLength;
|
|
874
|
+
Object.freeze(this);
|
|
875
|
+
}
|
|
876
|
+
create(num) {
|
|
877
|
+
return mod(num, this.ORDER);
|
|
878
|
+
}
|
|
879
|
+
isValid(num) {
|
|
880
|
+
if (typeof num !== "bigint")
|
|
881
|
+
throw new TypeError("invalid field element: expected bigint, got " + typeof num);
|
|
882
|
+
return _0n2 <= num && num < this.ORDER;
|
|
883
|
+
}
|
|
884
|
+
is0(num) {
|
|
885
|
+
return num === _0n2;
|
|
886
|
+
}
|
|
887
|
+
// is valid and invertible
|
|
888
|
+
isValidNot0(num) {
|
|
889
|
+
return !this.is0(num) && this.isValid(num);
|
|
890
|
+
}
|
|
891
|
+
isOdd(num) {
|
|
892
|
+
return (num & _1n2) === _1n2;
|
|
893
|
+
}
|
|
894
|
+
neg(num) {
|
|
895
|
+
return mod(-num, this.ORDER);
|
|
896
|
+
}
|
|
897
|
+
eql(lhs, rhs) {
|
|
898
|
+
return lhs === rhs;
|
|
899
|
+
}
|
|
900
|
+
sqr(num) {
|
|
901
|
+
return mod(num * num, this.ORDER);
|
|
902
|
+
}
|
|
903
|
+
add(lhs, rhs) {
|
|
904
|
+
return mod(lhs + rhs, this.ORDER);
|
|
905
|
+
}
|
|
906
|
+
sub(lhs, rhs) {
|
|
907
|
+
return mod(lhs - rhs, this.ORDER);
|
|
908
|
+
}
|
|
909
|
+
mul(lhs, rhs) {
|
|
910
|
+
return mod(lhs * rhs, this.ORDER);
|
|
911
|
+
}
|
|
912
|
+
pow(num, power) {
|
|
913
|
+
return FpPow(this, num, power);
|
|
914
|
+
}
|
|
915
|
+
div(lhs, rhs) {
|
|
916
|
+
return mod(lhs * invert(rhs, this.ORDER), this.ORDER);
|
|
917
|
+
}
|
|
918
|
+
// Same as above, but doesn't normalize
|
|
919
|
+
sqrN(num) {
|
|
920
|
+
return num * num;
|
|
921
|
+
}
|
|
922
|
+
addN(lhs, rhs) {
|
|
923
|
+
return lhs + rhs;
|
|
924
|
+
}
|
|
925
|
+
subN(lhs, rhs) {
|
|
926
|
+
return lhs - rhs;
|
|
927
|
+
}
|
|
928
|
+
mulN(lhs, rhs) {
|
|
929
|
+
return lhs * rhs;
|
|
930
|
+
}
|
|
931
|
+
inv(num) {
|
|
932
|
+
return invert(num, this.ORDER);
|
|
933
|
+
}
|
|
934
|
+
sqrt(num) {
|
|
935
|
+
let sqrt = FIELD_SQRT.get(this);
|
|
936
|
+
if (!sqrt)
|
|
937
|
+
FIELD_SQRT.set(this, sqrt = FpSqrt(this.ORDER));
|
|
938
|
+
return sqrt(this, num);
|
|
939
|
+
}
|
|
940
|
+
toBytes(num) {
|
|
941
|
+
return this.isLE ? numberToBytesLE(num, this.BYTES) : numberToBytesBE(num, this.BYTES);
|
|
942
|
+
}
|
|
943
|
+
fromBytes(bytes, skipValidation = false) {
|
|
944
|
+
abytes2(bytes);
|
|
945
|
+
const { _lengths: allowedLengths, BYTES, isLE, ORDER, _mod: modFromBytes } = this;
|
|
946
|
+
if (allowedLengths) {
|
|
947
|
+
if (bytes.length < 1 || !allowedLengths.includes(bytes.length) || bytes.length > BYTES) {
|
|
948
|
+
throw new Error("Field.fromBytes: expected " + allowedLengths + " bytes, got " + bytes.length);
|
|
949
|
+
}
|
|
950
|
+
const padded = new Uint8Array(BYTES);
|
|
951
|
+
padded.set(bytes, isLE ? 0 : padded.length - bytes.length);
|
|
952
|
+
bytes = padded;
|
|
953
|
+
}
|
|
954
|
+
if (bytes.length !== BYTES)
|
|
955
|
+
throw new Error("Field.fromBytes: expected " + BYTES + " bytes, got " + bytes.length);
|
|
956
|
+
let scalar = isLE ? bytesToNumberLE(bytes) : bytesToNumberBE(bytes);
|
|
957
|
+
if (modFromBytes)
|
|
958
|
+
scalar = mod(scalar, ORDER);
|
|
959
|
+
if (!skipValidation) {
|
|
960
|
+
if (!this.isValid(scalar))
|
|
961
|
+
throw new Error("invalid field element: outside of range 0..ORDER");
|
|
962
|
+
}
|
|
963
|
+
return scalar;
|
|
964
|
+
}
|
|
965
|
+
// TODO: we don't need it here, move out to separate fn
|
|
966
|
+
invertBatch(lst) {
|
|
967
|
+
return FpInvertBatch(this, lst);
|
|
968
|
+
}
|
|
969
|
+
// We can't move this out because Fp6, Fp12 implement it
|
|
970
|
+
// and it's unclear what to return in there.
|
|
971
|
+
cmov(a, b, condition) {
|
|
972
|
+
abool(condition, "condition");
|
|
973
|
+
return condition ? b : a;
|
|
974
|
+
}
|
|
975
|
+
};
|
|
976
|
+
Object.freeze(_Field.prototype);
|
|
977
|
+
function Field(ORDER, opts = {}) {
|
|
978
|
+
return new _Field(ORDER, opts);
|
|
979
|
+
}
|
|
980
|
+
function getFieldBytesLength(fieldOrder) {
|
|
981
|
+
if (typeof fieldOrder !== "bigint")
|
|
982
|
+
throw new Error("field order must be bigint");
|
|
983
|
+
if (fieldOrder <= _1n2)
|
|
984
|
+
throw new Error("field order must be greater than 1");
|
|
985
|
+
const bitLength = bitLen(fieldOrder - _1n2);
|
|
986
|
+
return Math.ceil(bitLength / 8);
|
|
987
|
+
}
|
|
988
|
+
function getMinHashLength(fieldOrder) {
|
|
989
|
+
const length = getFieldBytesLength(fieldOrder);
|
|
990
|
+
return length + Math.ceil(length / 2);
|
|
991
|
+
}
|
|
992
|
+
function mapHashToField(key, fieldOrder, isLE = false) {
|
|
993
|
+
abytes2(key);
|
|
994
|
+
const len = key.length;
|
|
995
|
+
const fieldLen = getFieldBytesLength(fieldOrder);
|
|
996
|
+
const minLen = Math.max(getMinHashLength(fieldOrder), 16);
|
|
997
|
+
if (len < minLen || len > 1024)
|
|
998
|
+
throw new Error("expected " + minLen + "-1024 bytes of input, got " + len);
|
|
999
|
+
const num = isLE ? bytesToNumberLE(key) : bytesToNumberBE(key);
|
|
1000
|
+
const reduced = mod(num, fieldOrder - _1n2) + _1n2;
|
|
1001
|
+
return isLE ? numberToBytesLE(reduced, fieldLen) : numberToBytesBE(reduced, fieldLen);
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// node_modules/@noble/curves/abstract/curve.js
|
|
1005
|
+
var _0n3 = /* @__PURE__ */ BigInt(0);
|
|
1006
|
+
var _1n3 = /* @__PURE__ */ BigInt(1);
|
|
1007
|
+
function negateCt(condition, item) {
|
|
1008
|
+
const neg = item.negate();
|
|
1009
|
+
return condition ? neg : item;
|
|
1010
|
+
}
|
|
1011
|
+
function normalizeZ(c, points) {
|
|
1012
|
+
const invertedZs = FpInvertBatch(c.Fp, points.map((p) => p.Z));
|
|
1013
|
+
return points.map((p, i) => c.fromAffine(p.toAffine(invertedZs[i])));
|
|
1014
|
+
}
|
|
1015
|
+
function validateW(W, bits) {
|
|
1016
|
+
if (!Number.isSafeInteger(W) || W <= 0 || W > bits)
|
|
1017
|
+
throw new Error("invalid window size, expected [1.." + bits + "], got W=" + W);
|
|
1018
|
+
}
|
|
1019
|
+
function calcWOpts(W, scalarBits) {
|
|
1020
|
+
validateW(W, scalarBits);
|
|
1021
|
+
const windows = Math.ceil(scalarBits / W) + 1;
|
|
1022
|
+
const windowSize = 2 ** (W - 1);
|
|
1023
|
+
const maxNumber = 2 ** W;
|
|
1024
|
+
const mask = bitMask(W);
|
|
1025
|
+
const shiftBy = BigInt(W);
|
|
1026
|
+
return { windows, windowSize, mask, maxNumber, shiftBy };
|
|
1027
|
+
}
|
|
1028
|
+
function calcOffsets(n, window, wOpts) {
|
|
1029
|
+
const { windowSize, mask, maxNumber, shiftBy } = wOpts;
|
|
1030
|
+
let wbits = Number(n & mask);
|
|
1031
|
+
let nextN = n >> shiftBy;
|
|
1032
|
+
if (wbits > windowSize) {
|
|
1033
|
+
wbits -= maxNumber;
|
|
1034
|
+
nextN += _1n3;
|
|
1035
|
+
}
|
|
1036
|
+
const offsetStart = window * windowSize;
|
|
1037
|
+
const offset = offsetStart + Math.abs(wbits) - 1;
|
|
1038
|
+
const isZero = wbits === 0;
|
|
1039
|
+
const isNeg = wbits < 0;
|
|
1040
|
+
const isNegF = window % 2 !== 0;
|
|
1041
|
+
const offsetF = offsetStart;
|
|
1042
|
+
return { nextN, offset, isZero, isNeg, isNegF, offsetF };
|
|
1043
|
+
}
|
|
1044
|
+
var pointPrecomputes = /* @__PURE__ */ new WeakMap();
|
|
1045
|
+
var pointWindowSizes = /* @__PURE__ */ new WeakMap();
|
|
1046
|
+
function getW(P) {
|
|
1047
|
+
return pointWindowSizes.get(P) || 1;
|
|
1048
|
+
}
|
|
1049
|
+
function assert0(n) {
|
|
1050
|
+
if (n !== _0n3)
|
|
1051
|
+
throw new Error("invalid wNAF");
|
|
1052
|
+
}
|
|
1053
|
+
var wNAF = class {
|
|
1054
|
+
// Parametrized with a given Point class (not individual point)
|
|
1055
|
+
constructor(Point, bits) {
|
|
1056
|
+
__publicField(this, "BASE");
|
|
1057
|
+
__publicField(this, "ZERO");
|
|
1058
|
+
__publicField(this, "Fn");
|
|
1059
|
+
__publicField(this, "bits");
|
|
1060
|
+
this.BASE = Point.BASE;
|
|
1061
|
+
this.ZERO = Point.ZERO;
|
|
1062
|
+
this.Fn = Point.Fn;
|
|
1063
|
+
this.bits = bits;
|
|
1064
|
+
}
|
|
1065
|
+
// non-const time multiplication ladder
|
|
1066
|
+
_unsafeLadder(elm, n, p = this.ZERO) {
|
|
1067
|
+
let d = elm;
|
|
1068
|
+
while (n > _0n3) {
|
|
1069
|
+
if (n & _1n3)
|
|
1070
|
+
p = p.add(d);
|
|
1071
|
+
d = d.double();
|
|
1072
|
+
n >>= _1n3;
|
|
1073
|
+
}
|
|
1074
|
+
return p;
|
|
1075
|
+
}
|
|
1076
|
+
/**
|
|
1077
|
+
* Creates a wNAF precomputation window. Used for caching.
|
|
1078
|
+
* Default window size is set by `utils.precompute()` and is equal to 8.
|
|
1079
|
+
* Number of precomputed points depends on the curve size:
|
|
1080
|
+
* 2^(𝑊−1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
|
|
1081
|
+
* - 𝑊 is the window size
|
|
1082
|
+
* - 𝑛 is the bitlength of the curve order.
|
|
1083
|
+
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
|
|
1084
|
+
* @param point - Point instance
|
|
1085
|
+
* @param W - window size
|
|
1086
|
+
* @returns precomputed point tables flattened to a single array
|
|
1087
|
+
*/
|
|
1088
|
+
precomputeWindow(point, W) {
|
|
1089
|
+
const { windows, windowSize } = calcWOpts(W, this.bits);
|
|
1090
|
+
const points = [];
|
|
1091
|
+
let p = point;
|
|
1092
|
+
let base = p;
|
|
1093
|
+
for (let window = 0; window < windows; window++) {
|
|
1094
|
+
base = p;
|
|
1095
|
+
points.push(base);
|
|
1096
|
+
for (let i = 1; i < windowSize; i++) {
|
|
1097
|
+
base = base.add(p);
|
|
1098
|
+
points.push(base);
|
|
1099
|
+
}
|
|
1100
|
+
p = base.double();
|
|
1101
|
+
}
|
|
1102
|
+
return points;
|
|
1103
|
+
}
|
|
1104
|
+
/**
|
|
1105
|
+
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
|
|
1106
|
+
* More compact implementation:
|
|
1107
|
+
* https://github.com/paulmillr/noble-secp256k1/blob/47cb1669b6e506ad66b35fe7d76132ae97465da2/index.ts#L502-L541
|
|
1108
|
+
* @returns real and fake (for const-time) points
|
|
1109
|
+
*/
|
|
1110
|
+
wNAF(W, precomputes, n) {
|
|
1111
|
+
if (!this.Fn.isValid(n))
|
|
1112
|
+
throw new Error("invalid scalar");
|
|
1113
|
+
let p = this.ZERO;
|
|
1114
|
+
let f = this.BASE;
|
|
1115
|
+
const wo = calcWOpts(W, this.bits);
|
|
1116
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
1117
|
+
const { nextN, offset, isZero, isNeg, isNegF, offsetF } = calcOffsets(n, window, wo);
|
|
1118
|
+
n = nextN;
|
|
1119
|
+
if (isZero) {
|
|
1120
|
+
f = f.add(negateCt(isNegF, precomputes[offsetF]));
|
|
1121
|
+
} else {
|
|
1122
|
+
p = p.add(negateCt(isNeg, precomputes[offset]));
|
|
1123
|
+
}
|
|
1124
|
+
}
|
|
1125
|
+
assert0(n);
|
|
1126
|
+
return { p, f };
|
|
1127
|
+
}
|
|
1128
|
+
/**
|
|
1129
|
+
* Implements unsafe EC multiplication using precomputed tables
|
|
1130
|
+
* and w-ary non-adjacent form.
|
|
1131
|
+
* @param acc - accumulator point to add result of multiplication
|
|
1132
|
+
* @returns point
|
|
1133
|
+
*/
|
|
1134
|
+
wNAFUnsafe(W, precomputes, n, acc = this.ZERO) {
|
|
1135
|
+
const wo = calcWOpts(W, this.bits);
|
|
1136
|
+
for (let window = 0; window < wo.windows; window++) {
|
|
1137
|
+
if (n === _0n3)
|
|
1138
|
+
break;
|
|
1139
|
+
const { nextN, offset, isZero, isNeg } = calcOffsets(n, window, wo);
|
|
1140
|
+
n = nextN;
|
|
1141
|
+
if (isZero) {
|
|
1142
|
+
continue;
|
|
1143
|
+
} else {
|
|
1144
|
+
const item = precomputes[offset];
|
|
1145
|
+
acc = acc.add(isNeg ? item.negate() : item);
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
assert0(n);
|
|
1149
|
+
return acc;
|
|
1150
|
+
}
|
|
1151
|
+
getPrecomputes(W, point, transform) {
|
|
1152
|
+
let comp = pointPrecomputes.get(point);
|
|
1153
|
+
if (!comp) {
|
|
1154
|
+
comp = this.precomputeWindow(point, W);
|
|
1155
|
+
if (W !== 1) {
|
|
1156
|
+
if (typeof transform === "function")
|
|
1157
|
+
comp = transform(comp);
|
|
1158
|
+
pointPrecomputes.set(point, comp);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
return comp;
|
|
1162
|
+
}
|
|
1163
|
+
cached(point, scalar, transform) {
|
|
1164
|
+
const W = getW(point);
|
|
1165
|
+
return this.wNAF(W, this.getPrecomputes(W, point, transform), scalar);
|
|
1166
|
+
}
|
|
1167
|
+
unsafe(point, scalar, transform, prev) {
|
|
1168
|
+
const W = getW(point);
|
|
1169
|
+
if (W === 1)
|
|
1170
|
+
return this._unsafeLadder(point, scalar, prev);
|
|
1171
|
+
return this.wNAFUnsafe(W, this.getPrecomputes(W, point, transform), scalar, prev);
|
|
1172
|
+
}
|
|
1173
|
+
// We calculate precomputes for elliptic curve point multiplication
|
|
1174
|
+
// using windowed method. This specifies window size and
|
|
1175
|
+
// stores precomputed values. Usually only base point would be precomputed.
|
|
1176
|
+
createCache(P, W) {
|
|
1177
|
+
validateW(W, this.bits);
|
|
1178
|
+
pointWindowSizes.set(P, W);
|
|
1179
|
+
pointPrecomputes.delete(P);
|
|
1180
|
+
}
|
|
1181
|
+
hasCache(elm) {
|
|
1182
|
+
return getW(elm) !== 1;
|
|
1183
|
+
}
|
|
1184
|
+
};
|
|
1185
|
+
function mulEndoUnsafe(Point, point, k1, k2) {
|
|
1186
|
+
let acc = point;
|
|
1187
|
+
let p1 = Point.ZERO;
|
|
1188
|
+
let p2 = Point.ZERO;
|
|
1189
|
+
while (k1 > _0n3 || k2 > _0n3) {
|
|
1190
|
+
if (k1 & _1n3)
|
|
1191
|
+
p1 = p1.add(acc);
|
|
1192
|
+
if (k2 & _1n3)
|
|
1193
|
+
p2 = p2.add(acc);
|
|
1194
|
+
acc = acc.double();
|
|
1195
|
+
k1 >>= _1n3;
|
|
1196
|
+
k2 >>= _1n3;
|
|
1197
|
+
}
|
|
1198
|
+
return { p1, p2 };
|
|
1199
|
+
}
|
|
1200
|
+
function createField(order, field, isLE) {
|
|
1201
|
+
if (field) {
|
|
1202
|
+
if (field.ORDER !== order)
|
|
1203
|
+
throw new Error("Field.ORDER must match order: Fp == p, Fn == n");
|
|
1204
|
+
validateField(field);
|
|
1205
|
+
return field;
|
|
1206
|
+
} else {
|
|
1207
|
+
return Field(order, { isLE });
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
function createCurveFields(type, CURVE, curveOpts = {}, FpFnLE) {
|
|
1211
|
+
if (FpFnLE === void 0)
|
|
1212
|
+
FpFnLE = type === "edwards";
|
|
1213
|
+
if (!CURVE || typeof CURVE !== "object")
|
|
1214
|
+
throw new Error(`expected valid ${type} CURVE object`);
|
|
1215
|
+
for (const p of ["p", "n", "h"]) {
|
|
1216
|
+
const val = CURVE[p];
|
|
1217
|
+
if (!(typeof val === "bigint" && val > _0n3))
|
|
1218
|
+
throw new Error(`CURVE.${p} must be positive bigint`);
|
|
1219
|
+
}
|
|
1220
|
+
const Fp3 = createField(CURVE.p, curveOpts.Fp, FpFnLE);
|
|
1221
|
+
const Fn = createField(CURVE.n, curveOpts.Fn, FpFnLE);
|
|
1222
|
+
const _b = type === "weierstrass" ? "b" : "d";
|
|
1223
|
+
const params = ["Gx", "Gy", "a", _b];
|
|
1224
|
+
for (const p of params) {
|
|
1225
|
+
if (!Fp3.isValid(CURVE[p]))
|
|
1226
|
+
throw new Error(`CURVE.${p} must be valid field element of CURVE.Fp`);
|
|
1227
|
+
}
|
|
1228
|
+
CURVE = Object.freeze(Object.assign({}, CURVE));
|
|
1229
|
+
return { CURVE, Fp: Fp3, Fn };
|
|
1230
|
+
}
|
|
1231
|
+
|
|
1232
|
+
// node_modules/@noble/curves/abstract/hash-to-curve.js
|
|
1233
|
+
var os2ip = bytesToNumberBE;
|
|
1234
|
+
function i2osp(value, length) {
|
|
1235
|
+
asafenumber(value);
|
|
1236
|
+
asafenumber(length);
|
|
1237
|
+
if (length < 0 || length > 4)
|
|
1238
|
+
throw new Error("invalid I2OSP length: " + length);
|
|
1239
|
+
if (value < 0 || value > 2 ** (8 * length) - 1)
|
|
1240
|
+
throw new Error("invalid I2OSP input: " + value);
|
|
1241
|
+
const res = Array.from({ length }).fill(0);
|
|
1242
|
+
for (let i = length - 1; i >= 0; i--) {
|
|
1243
|
+
res[i] = value & 255;
|
|
1244
|
+
value >>>= 8;
|
|
1245
|
+
}
|
|
1246
|
+
return new Uint8Array(res);
|
|
1247
|
+
}
|
|
1248
|
+
function strxor(a, b) {
|
|
1249
|
+
const arr = new Uint8Array(a.length);
|
|
1250
|
+
for (let i = 0; i < a.length; i++) {
|
|
1251
|
+
arr[i] = a[i] ^ b[i];
|
|
1252
|
+
}
|
|
1253
|
+
return arr;
|
|
1254
|
+
}
|
|
1255
|
+
function normDST(DST) {
|
|
1256
|
+
if (!isBytes2(DST) && typeof DST !== "string")
|
|
1257
|
+
throw new Error("DST must be Uint8Array or ascii string");
|
|
1258
|
+
const dst = typeof DST === "string" ? asciiToBytes(DST) : DST;
|
|
1259
|
+
if (dst.length === 0)
|
|
1260
|
+
throw new Error("DST must be non-empty");
|
|
1261
|
+
return dst;
|
|
1262
|
+
}
|
|
1263
|
+
function expand_message_xmd(msg, DST, lenInBytes, H) {
|
|
1264
|
+
abytes2(msg);
|
|
1265
|
+
asafenumber(lenInBytes);
|
|
1266
|
+
DST = normDST(DST);
|
|
1267
|
+
if (DST.length > 255)
|
|
1268
|
+
DST = H(concatBytes2(asciiToBytes("H2C-OVERSIZE-DST-"), DST));
|
|
1269
|
+
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
|
|
1270
|
+
const ell = Math.ceil(lenInBytes / b_in_bytes);
|
|
1271
|
+
if (lenInBytes > 65535 || ell > 255)
|
|
1272
|
+
throw new Error("expand_message_xmd: invalid lenInBytes");
|
|
1273
|
+
const DST_prime = concatBytes2(DST, i2osp(DST.length, 1));
|
|
1274
|
+
const Z_pad = new Uint8Array(r_in_bytes);
|
|
1275
|
+
const l_i_b_str = i2osp(lenInBytes, 2);
|
|
1276
|
+
const b = new Array(ell);
|
|
1277
|
+
const b_0 = H(concatBytes2(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
|
|
1278
|
+
b[0] = H(concatBytes2(b_0, i2osp(1, 1), DST_prime));
|
|
1279
|
+
for (let i = 1; i < ell; i++) {
|
|
1280
|
+
const args = [strxor(b_0, b[i - 1]), i2osp(i + 1, 1), DST_prime];
|
|
1281
|
+
b[i] = H(concatBytes2(...args));
|
|
1282
|
+
}
|
|
1283
|
+
const pseudo_random_bytes = concatBytes2(...b);
|
|
1284
|
+
return pseudo_random_bytes.slice(0, lenInBytes);
|
|
1285
|
+
}
|
|
1286
|
+
function expand_message_xof(msg, DST, lenInBytes, k, H) {
|
|
1287
|
+
abytes2(msg);
|
|
1288
|
+
asafenumber(lenInBytes);
|
|
1289
|
+
DST = normDST(DST);
|
|
1290
|
+
if (DST.length > 255) {
|
|
1291
|
+
const dkLen = Math.ceil(2 * k / 8);
|
|
1292
|
+
DST = H.create({ dkLen }).update(asciiToBytes("H2C-OVERSIZE-DST-")).update(DST).digest();
|
|
1293
|
+
}
|
|
1294
|
+
if (lenInBytes > 65535 || DST.length > 255)
|
|
1295
|
+
throw new Error("expand_message_xof: invalid lenInBytes");
|
|
1296
|
+
return H.create({ dkLen: lenInBytes }).update(msg).update(i2osp(lenInBytes, 2)).update(DST).update(i2osp(DST.length, 1)).digest();
|
|
1297
|
+
}
|
|
1298
|
+
function hash_to_field(msg, count, options) {
|
|
1299
|
+
validateObject(options, {
|
|
1300
|
+
p: "bigint",
|
|
1301
|
+
m: "number",
|
|
1302
|
+
k: "number",
|
|
1303
|
+
hash: "function"
|
|
1304
|
+
});
|
|
1305
|
+
const { p, k, m, hash, expand, DST } = options;
|
|
1306
|
+
asafenumber(hash.outputLen, "valid hash");
|
|
1307
|
+
abytes2(msg);
|
|
1308
|
+
asafenumber(count);
|
|
1309
|
+
if (count < 1)
|
|
1310
|
+
throw new Error("hash_to_field: expected count >= 1");
|
|
1311
|
+
if (m < 1)
|
|
1312
|
+
throw new Error("hash_to_field: expected m >= 1");
|
|
1313
|
+
const log2p = p.toString(2).length;
|
|
1314
|
+
const L = Math.ceil((log2p + k) / 8);
|
|
1315
|
+
const len_in_bytes = count * m * L;
|
|
1316
|
+
let prb;
|
|
1317
|
+
if (expand === "xmd") {
|
|
1318
|
+
prb = expand_message_xmd(msg, DST, len_in_bytes, hash);
|
|
1319
|
+
} else if (expand === "xof") {
|
|
1320
|
+
prb = expand_message_xof(msg, DST, len_in_bytes, k, hash);
|
|
1321
|
+
} else if (expand === "_internal_pass") {
|
|
1322
|
+
prb = msg;
|
|
1323
|
+
} else {
|
|
1324
|
+
throw new Error('expand must be "xmd" or "xof"');
|
|
1325
|
+
}
|
|
1326
|
+
const u = new Array(count);
|
|
1327
|
+
for (let i = 0; i < count; i++) {
|
|
1328
|
+
const e = new Array(m);
|
|
1329
|
+
for (let j = 0; j < m; j++) {
|
|
1330
|
+
const elm_offset = L * (j + i * m);
|
|
1331
|
+
const tv = prb.subarray(elm_offset, elm_offset + L);
|
|
1332
|
+
e[j] = mod(os2ip(tv), p);
|
|
1333
|
+
}
|
|
1334
|
+
u[i] = e;
|
|
1335
|
+
}
|
|
1336
|
+
return u;
|
|
1337
|
+
}
|
|
1338
|
+
function isogenyMap(field, map) {
|
|
1339
|
+
const coeff = map.map((i) => Array.from(i).reverse());
|
|
1340
|
+
return (x, y) => {
|
|
1341
|
+
const [xn, xd, yn, yd] = coeff.map((val) => val.reduce((acc, i) => field.add(field.mul(acc, x), i)));
|
|
1342
|
+
const [xd_inv, yd_inv] = FpInvertBatch(field, [xd, yd], true);
|
|
1343
|
+
x = field.mul(xn, xd_inv);
|
|
1344
|
+
y = field.mul(y, field.mul(yn, yd_inv));
|
|
1345
|
+
return { x, y };
|
|
1346
|
+
};
|
|
1347
|
+
}
|
|
1348
|
+
var _DST_scalar = "HashToScalar-";
|
|
1349
|
+
function createHasher2(Point, mapToCurve, defaults) {
|
|
1350
|
+
if (typeof mapToCurve !== "function")
|
|
1351
|
+
throw new Error("mapToCurve() must be defined");
|
|
1352
|
+
const snapshot = (src) => Object.freeze(__spreadValues(__spreadProps(__spreadValues({}, src), {
|
|
1353
|
+
DST: isBytes2(src.DST) ? copyBytes(src.DST) : src.DST
|
|
1354
|
+
}), src.encodeDST === void 0 ? {} : { encodeDST: isBytes2(src.encodeDST) ? copyBytes(src.encodeDST) : src.encodeDST }));
|
|
1355
|
+
const safeDefaults = snapshot(defaults);
|
|
1356
|
+
function map(num) {
|
|
1357
|
+
return Point.fromAffine(mapToCurve(num));
|
|
1358
|
+
}
|
|
1359
|
+
function clear(initial) {
|
|
1360
|
+
const P = initial.clearCofactor();
|
|
1361
|
+
if (P.equals(Point.ZERO))
|
|
1362
|
+
return Point.ZERO;
|
|
1363
|
+
P.assertValidity();
|
|
1364
|
+
return P;
|
|
1365
|
+
}
|
|
1366
|
+
return Object.freeze({
|
|
1367
|
+
get defaults() {
|
|
1368
|
+
return snapshot(safeDefaults);
|
|
1369
|
+
},
|
|
1370
|
+
Point,
|
|
1371
|
+
hashToCurve(msg, options) {
|
|
1372
|
+
const opts = Object.assign({}, safeDefaults, options);
|
|
1373
|
+
const u = hash_to_field(msg, 2, opts);
|
|
1374
|
+
const u0 = map(u[0]);
|
|
1375
|
+
const u1 = map(u[1]);
|
|
1376
|
+
return clear(u0.add(u1));
|
|
1377
|
+
},
|
|
1378
|
+
encodeToCurve(msg, options) {
|
|
1379
|
+
const optsDst = safeDefaults.encodeDST ? { DST: safeDefaults.encodeDST } : {};
|
|
1380
|
+
const opts = Object.assign({}, safeDefaults, optsDst, options);
|
|
1381
|
+
const u = hash_to_field(msg, 1, opts);
|
|
1382
|
+
const u0 = map(u[0]);
|
|
1383
|
+
return clear(u0);
|
|
1384
|
+
},
|
|
1385
|
+
/** See {@link H2CHasher} */
|
|
1386
|
+
mapToCurve(scalars) {
|
|
1387
|
+
if (safeDefaults.m === 1) {
|
|
1388
|
+
if (typeof scalars !== "bigint")
|
|
1389
|
+
throw new Error("expected bigint (m=1)");
|
|
1390
|
+
return clear(map([scalars]));
|
|
1391
|
+
}
|
|
1392
|
+
if (!Array.isArray(scalars))
|
|
1393
|
+
throw new Error("expected array of bigints");
|
|
1394
|
+
for (const i of scalars)
|
|
1395
|
+
if (typeof i !== "bigint")
|
|
1396
|
+
throw new Error("expected array of bigints");
|
|
1397
|
+
return clear(map(scalars));
|
|
1398
|
+
},
|
|
1399
|
+
// hash_to_scalar can produce 0: https://www.rfc-editor.org/errata/eid8393
|
|
1400
|
+
// RFC 9380, draft-irtf-cfrg-bbs-signatures-08. Default scalar DST is the shared generic
|
|
1401
|
+
// `HashToScalar-` prefix above unless the caller overrides it per invocation.
|
|
1402
|
+
hashToScalar(msg, options) {
|
|
1403
|
+
const N = Point.Fn.ORDER;
|
|
1404
|
+
const opts = Object.assign({}, safeDefaults, { p: N, m: 1, DST: _DST_scalar }, options);
|
|
1405
|
+
return hash_to_field(msg, 1, opts)[0][0];
|
|
1406
|
+
}
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
// node_modules/@noble/curves/abstract/weierstrass.js
|
|
1411
|
+
var divNearest = (num, den) => (num + (num >= 0 ? den : -den) / _2n2) / den;
|
|
1412
|
+
function _splitEndoScalar(k, basis, n) {
|
|
1413
|
+
aInRange("scalar", k, _0n4, n);
|
|
1414
|
+
const [[a1, b1], [a2, b2]] = basis;
|
|
1415
|
+
const c1 = divNearest(b2 * k, n);
|
|
1416
|
+
const c2 = divNearest(-b1 * k, n);
|
|
1417
|
+
let k1 = k - c1 * a1 - c2 * a2;
|
|
1418
|
+
let k2 = -c1 * b1 - c2 * b2;
|
|
1419
|
+
const k1neg = k1 < _0n4;
|
|
1420
|
+
const k2neg = k2 < _0n4;
|
|
1421
|
+
if (k1neg)
|
|
1422
|
+
k1 = -k1;
|
|
1423
|
+
if (k2neg)
|
|
1424
|
+
k2 = -k2;
|
|
1425
|
+
const MAX_NUM = bitMask(Math.ceil(bitLen(n) / 2)) + _1n4;
|
|
1426
|
+
if (k1 < _0n4 || k1 >= MAX_NUM || k2 < _0n4 || k2 >= MAX_NUM) {
|
|
1427
|
+
throw new Error("splitScalar (endomorphism): failed for k");
|
|
1428
|
+
}
|
|
1429
|
+
return { k1neg, k1, k2neg, k2 };
|
|
1430
|
+
}
|
|
1431
|
+
var DERErr = class extends Error {
|
|
1432
|
+
constructor(m = "") {
|
|
1433
|
+
super(m);
|
|
1434
|
+
}
|
|
1435
|
+
};
|
|
1436
|
+
var DER = {
|
|
1437
|
+
// asn.1 DER encoding utils
|
|
1438
|
+
Err: DERErr,
|
|
1439
|
+
// Basic building block is TLV (Tag-Length-Value)
|
|
1440
|
+
_tlv: {
|
|
1441
|
+
encode: (tag, data) => {
|
|
1442
|
+
const { Err: E } = DER;
|
|
1443
|
+
asafenumber(tag, "tag");
|
|
1444
|
+
if (tag < 0 || tag > 255)
|
|
1445
|
+
throw new E("tlv.encode: wrong tag");
|
|
1446
|
+
if (typeof data !== "string")
|
|
1447
|
+
throw new TypeError('"data" expected string, got type=' + typeof data);
|
|
1448
|
+
if (data.length & 1)
|
|
1449
|
+
throw new E("tlv.encode: unpadded data");
|
|
1450
|
+
const dataLen = data.length / 2;
|
|
1451
|
+
const len = numberToHexUnpadded(dataLen);
|
|
1452
|
+
if (len.length / 2 & 128)
|
|
1453
|
+
throw new E("tlv.encode: long form length too big");
|
|
1454
|
+
const lenLen = dataLen > 127 ? numberToHexUnpadded(len.length / 2 | 128) : "";
|
|
1455
|
+
const t = numberToHexUnpadded(tag);
|
|
1456
|
+
return t + lenLen + len + data;
|
|
1457
|
+
},
|
|
1458
|
+
// v - value, l - left bytes (unparsed)
|
|
1459
|
+
decode(tag, data) {
|
|
1460
|
+
const { Err: E } = DER;
|
|
1461
|
+
data = abytes2(data, void 0, "DER data");
|
|
1462
|
+
let pos = 0;
|
|
1463
|
+
if (tag < 0 || tag > 255)
|
|
1464
|
+
throw new E("tlv.encode: wrong tag");
|
|
1465
|
+
if (data.length < 2 || data[pos++] !== tag)
|
|
1466
|
+
throw new E("tlv.decode: wrong tlv");
|
|
1467
|
+
const first = data[pos++];
|
|
1468
|
+
const isLong = !!(first & 128);
|
|
1469
|
+
let length = 0;
|
|
1470
|
+
if (!isLong)
|
|
1471
|
+
length = first;
|
|
1472
|
+
else {
|
|
1473
|
+
const lenLen = first & 127;
|
|
1474
|
+
if (!lenLen)
|
|
1475
|
+
throw new E("tlv.decode(long): indefinite length not supported");
|
|
1476
|
+
if (lenLen > 4)
|
|
1477
|
+
throw new E("tlv.decode(long): byte length is too big");
|
|
1478
|
+
const lengthBytes = data.subarray(pos, pos + lenLen);
|
|
1479
|
+
if (lengthBytes.length !== lenLen)
|
|
1480
|
+
throw new E("tlv.decode: length bytes not complete");
|
|
1481
|
+
if (lengthBytes[0] === 0)
|
|
1482
|
+
throw new E("tlv.decode(long): zero leftmost byte");
|
|
1483
|
+
for (const b of lengthBytes)
|
|
1484
|
+
length = length << 8 | b;
|
|
1485
|
+
pos += lenLen;
|
|
1486
|
+
if (length < 128)
|
|
1487
|
+
throw new E("tlv.decode(long): not minimal encoding");
|
|
1488
|
+
}
|
|
1489
|
+
const v = data.subarray(pos, pos + length);
|
|
1490
|
+
if (v.length !== length)
|
|
1491
|
+
throw new E("tlv.decode: wrong value length");
|
|
1492
|
+
return { v, l: data.subarray(pos + length) };
|
|
1493
|
+
}
|
|
1494
|
+
},
|
|
1495
|
+
// https://crypto.stackexchange.com/a/57734 Leftmost bit of first byte is 'negative' flag,
|
|
1496
|
+
// since we always use positive integers here. It must always be empty:
|
|
1497
|
+
// - add zero byte if exists
|
|
1498
|
+
// - if next byte doesn't have a flag, leading zero is not allowed (minimal encoding)
|
|
1499
|
+
_int: {
|
|
1500
|
+
encode(num) {
|
|
1501
|
+
const { Err: E } = DER;
|
|
1502
|
+
abignumber(num);
|
|
1503
|
+
if (num < _0n4)
|
|
1504
|
+
throw new E("integer: negative integers are not allowed");
|
|
1505
|
+
let hex = numberToHexUnpadded(num);
|
|
1506
|
+
if (Number.parseInt(hex[0], 16) & 8)
|
|
1507
|
+
hex = "00" + hex;
|
|
1508
|
+
if (hex.length & 1)
|
|
1509
|
+
throw new E("unexpected DER parsing assertion: unpadded hex");
|
|
1510
|
+
return hex;
|
|
1511
|
+
},
|
|
1512
|
+
decode(data) {
|
|
1513
|
+
const { Err: E } = DER;
|
|
1514
|
+
if (data.length < 1)
|
|
1515
|
+
throw new E("invalid signature integer: empty");
|
|
1516
|
+
if (data[0] & 128)
|
|
1517
|
+
throw new E("invalid signature integer: negative");
|
|
1518
|
+
if (data.length > 1 && data[0] === 0 && !(data[1] & 128))
|
|
1519
|
+
throw new E("invalid signature integer: unnecessary leading zero");
|
|
1520
|
+
return bytesToNumberBE(data);
|
|
1521
|
+
}
|
|
1522
|
+
},
|
|
1523
|
+
toSig(bytes) {
|
|
1524
|
+
const { Err: E, _int: int, _tlv: tlv } = DER;
|
|
1525
|
+
const data = abytes2(bytes, void 0, "signature");
|
|
1526
|
+
const { v: seqBytes, l: seqLeftBytes } = tlv.decode(48, data);
|
|
1527
|
+
if (seqLeftBytes.length)
|
|
1528
|
+
throw new E("invalid signature: left bytes after parsing");
|
|
1529
|
+
const { v: rBytes, l: rLeftBytes } = tlv.decode(2, seqBytes);
|
|
1530
|
+
const { v: sBytes, l: sLeftBytes } = tlv.decode(2, rLeftBytes);
|
|
1531
|
+
if (sLeftBytes.length)
|
|
1532
|
+
throw new E("invalid signature: left bytes after parsing");
|
|
1533
|
+
return { r: int.decode(rBytes), s: int.decode(sBytes) };
|
|
1534
|
+
},
|
|
1535
|
+
hexFromSig(sig) {
|
|
1536
|
+
const { _tlv: tlv, _int: int } = DER;
|
|
1537
|
+
const rs = tlv.encode(2, int.encode(sig.r));
|
|
1538
|
+
const ss = tlv.encode(2, int.encode(sig.s));
|
|
1539
|
+
const seq = rs + ss;
|
|
1540
|
+
return tlv.encode(48, seq);
|
|
1541
|
+
}
|
|
1542
|
+
};
|
|
1543
|
+
Object.freeze(DER._tlv);
|
|
1544
|
+
Object.freeze(DER._int);
|
|
1545
|
+
Object.freeze(DER);
|
|
1546
|
+
var _0n4 = /* @__PURE__ */ BigInt(0);
|
|
1547
|
+
var _1n4 = /* @__PURE__ */ BigInt(1);
|
|
1548
|
+
var _2n2 = /* @__PURE__ */ BigInt(2);
|
|
1549
|
+
var _3n2 = /* @__PURE__ */ BigInt(3);
|
|
1550
|
+
var _4n2 = /* @__PURE__ */ BigInt(4);
|
|
1551
|
+
function weierstrass(params, extraOpts = {}) {
|
|
1552
|
+
const validated = createCurveFields("weierstrass", params, extraOpts);
|
|
1553
|
+
const Fp3 = validated.Fp;
|
|
1554
|
+
const Fn = validated.Fn;
|
|
1555
|
+
let CURVE = validated.CURVE;
|
|
1556
|
+
const { h: cofactor, n: CURVE_ORDER } = CURVE;
|
|
1557
|
+
validateObject(extraOpts, {}, {
|
|
1558
|
+
allowInfinityPoint: "boolean",
|
|
1559
|
+
clearCofactor: "function",
|
|
1560
|
+
isTorsionFree: "function",
|
|
1561
|
+
fromBytes: "function",
|
|
1562
|
+
toBytes: "function",
|
|
1563
|
+
endo: "object"
|
|
1564
|
+
});
|
|
1565
|
+
const { endo, allowInfinityPoint } = extraOpts;
|
|
1566
|
+
if (endo) {
|
|
1567
|
+
if (!Fp3.is0(CURVE.a) || typeof endo.beta !== "bigint" || !Array.isArray(endo.basises)) {
|
|
1568
|
+
throw new Error('invalid endo: expected "beta": bigint and "basises": array');
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1571
|
+
const lengths = getWLengths(Fp3, Fn);
|
|
1572
|
+
function assertCompressionIsSupported() {
|
|
1573
|
+
if (!Fp3.isOdd)
|
|
1574
|
+
throw new Error("compression is not supported: Field does not have .isOdd()");
|
|
1575
|
+
}
|
|
1576
|
+
function pointToBytes(_c, point, isCompressed) {
|
|
1577
|
+
if (allowInfinityPoint && point.is0())
|
|
1578
|
+
return Uint8Array.of(0);
|
|
1579
|
+
const { x, y } = point.toAffine();
|
|
1580
|
+
const bx = Fp3.toBytes(x);
|
|
1581
|
+
abool(isCompressed, "isCompressed");
|
|
1582
|
+
if (isCompressed) {
|
|
1583
|
+
assertCompressionIsSupported();
|
|
1584
|
+
const hasEvenY = !Fp3.isOdd(y);
|
|
1585
|
+
return concatBytes2(pprefix(hasEvenY), bx);
|
|
1586
|
+
} else {
|
|
1587
|
+
return concatBytes2(Uint8Array.of(4), bx, Fp3.toBytes(y));
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
function pointFromBytes(bytes) {
|
|
1591
|
+
abytes2(bytes, void 0, "Point");
|
|
1592
|
+
const { publicKey: comp, publicKeyUncompressed: uncomp } = lengths;
|
|
1593
|
+
const length = bytes.length;
|
|
1594
|
+
const head = bytes[0];
|
|
1595
|
+
const tail = bytes.subarray(1);
|
|
1596
|
+
if (allowInfinityPoint && length === 1 && head === 0)
|
|
1597
|
+
return { x: Fp3.ZERO, y: Fp3.ZERO };
|
|
1598
|
+
if (length === comp && (head === 2 || head === 3)) {
|
|
1599
|
+
const x = Fp3.fromBytes(tail);
|
|
1600
|
+
if (!Fp3.isValid(x))
|
|
1601
|
+
throw new Error("bad point: is not on curve, wrong x");
|
|
1602
|
+
const y2 = weierstrassEquation(x);
|
|
1603
|
+
let y;
|
|
1604
|
+
try {
|
|
1605
|
+
y = Fp3.sqrt(y2);
|
|
1606
|
+
} catch (sqrtError) {
|
|
1607
|
+
const err = sqrtError instanceof Error ? ": " + sqrtError.message : "";
|
|
1608
|
+
throw new Error("bad point: is not on curve, sqrt error" + err);
|
|
1609
|
+
}
|
|
1610
|
+
assertCompressionIsSupported();
|
|
1611
|
+
const evenY = Fp3.isOdd(y);
|
|
1612
|
+
const evenH = (head & 1) === 1;
|
|
1613
|
+
if (evenH !== evenY)
|
|
1614
|
+
y = Fp3.neg(y);
|
|
1615
|
+
return { x, y };
|
|
1616
|
+
} else if (length === uncomp && head === 4) {
|
|
1617
|
+
const L = Fp3.BYTES;
|
|
1618
|
+
const x = Fp3.fromBytes(tail.subarray(0, L));
|
|
1619
|
+
const y = Fp3.fromBytes(tail.subarray(L, L * 2));
|
|
1620
|
+
if (!isValidXY(x, y))
|
|
1621
|
+
throw new Error("bad point: is not on curve");
|
|
1622
|
+
return { x, y };
|
|
1623
|
+
} else {
|
|
1624
|
+
throw new Error(`bad point: got length ${length}, expected compressed=${comp} or uncompressed=${uncomp}`);
|
|
1625
|
+
}
|
|
1626
|
+
}
|
|
1627
|
+
const encodePoint = extraOpts.toBytes === void 0 ? pointToBytes : extraOpts.toBytes;
|
|
1628
|
+
const decodePoint = extraOpts.fromBytes === void 0 ? pointFromBytes : extraOpts.fromBytes;
|
|
1629
|
+
function weierstrassEquation(x) {
|
|
1630
|
+
const x2 = Fp3.sqr(x);
|
|
1631
|
+
const x3 = Fp3.mul(x2, x);
|
|
1632
|
+
return Fp3.add(Fp3.add(x3, Fp3.mul(x, CURVE.a)), CURVE.b);
|
|
1633
|
+
}
|
|
1634
|
+
function isValidXY(x, y) {
|
|
1635
|
+
const left = Fp3.sqr(y);
|
|
1636
|
+
const right = weierstrassEquation(x);
|
|
1637
|
+
return Fp3.eql(left, right);
|
|
1638
|
+
}
|
|
1639
|
+
if (!isValidXY(CURVE.Gx, CURVE.Gy))
|
|
1640
|
+
throw new Error("bad curve params: generator point");
|
|
1641
|
+
const _4a3 = Fp3.mul(Fp3.pow(CURVE.a, _3n2), _4n2);
|
|
1642
|
+
const _27b2 = Fp3.mul(Fp3.sqr(CURVE.b), BigInt(27));
|
|
1643
|
+
if (Fp3.is0(Fp3.add(_4a3, _27b2)))
|
|
1644
|
+
throw new Error("bad curve params: a or b");
|
|
1645
|
+
function acoord(title, n, banZero = false) {
|
|
1646
|
+
if (!Fp3.isValid(n) || banZero && Fp3.is0(n))
|
|
1647
|
+
throw new Error(`bad point coordinate ${title}`);
|
|
1648
|
+
return n;
|
|
1649
|
+
}
|
|
1650
|
+
function aprjpoint(other) {
|
|
1651
|
+
if (!(other instanceof Point))
|
|
1652
|
+
throw new Error("Weierstrass Point expected");
|
|
1653
|
+
}
|
|
1654
|
+
function splitEndoScalarN(k) {
|
|
1655
|
+
if (!endo || !endo.basises)
|
|
1656
|
+
throw new Error("no endo");
|
|
1657
|
+
return _splitEndoScalar(k, endo.basises, Fn.ORDER);
|
|
1658
|
+
}
|
|
1659
|
+
function finishEndo(endoBeta, k1p, k2p, k1neg, k2neg) {
|
|
1660
|
+
k2p = new Point(Fp3.mul(k2p.X, endoBeta), k2p.Y, k2p.Z);
|
|
1661
|
+
k1p = negateCt(k1neg, k1p);
|
|
1662
|
+
k2p = negateCt(k2neg, k2p);
|
|
1663
|
+
return k1p.add(k2p);
|
|
1664
|
+
}
|
|
1665
|
+
const _Point = class _Point {
|
|
1666
|
+
/** Does NOT validate if the point is valid. Use `.assertValidity()`. */
|
|
1667
|
+
constructor(X, Y, Z) {
|
|
1668
|
+
__publicField(this, "X");
|
|
1669
|
+
__publicField(this, "Y");
|
|
1670
|
+
__publicField(this, "Z");
|
|
1671
|
+
this.X = acoord("x", X);
|
|
1672
|
+
this.Y = acoord("y", Y, true);
|
|
1673
|
+
this.Z = acoord("z", Z);
|
|
1674
|
+
Object.freeze(this);
|
|
1675
|
+
}
|
|
1676
|
+
static CURVE() {
|
|
1677
|
+
return CURVE;
|
|
1678
|
+
}
|
|
1679
|
+
/** Does NOT validate if the point is valid. Use `.assertValidity()`. */
|
|
1680
|
+
static fromAffine(p) {
|
|
1681
|
+
const { x, y } = p || {};
|
|
1682
|
+
if (!p || !Fp3.isValid(x) || !Fp3.isValid(y))
|
|
1683
|
+
throw new Error("invalid affine point");
|
|
1684
|
+
if (p instanceof _Point)
|
|
1685
|
+
throw new Error("projective point not allowed");
|
|
1686
|
+
if (Fp3.is0(x) && Fp3.is0(y))
|
|
1687
|
+
return _Point.ZERO;
|
|
1688
|
+
return new _Point(x, y, Fp3.ONE);
|
|
1689
|
+
}
|
|
1690
|
+
static fromBytes(bytes) {
|
|
1691
|
+
const P = _Point.fromAffine(decodePoint(abytes2(bytes, void 0, "point")));
|
|
1692
|
+
P.assertValidity();
|
|
1693
|
+
return P;
|
|
1694
|
+
}
|
|
1695
|
+
static fromHex(hex) {
|
|
1696
|
+
return _Point.fromBytes(hexToBytes2(hex));
|
|
1697
|
+
}
|
|
1698
|
+
get x() {
|
|
1699
|
+
return this.toAffine().x;
|
|
1700
|
+
}
|
|
1701
|
+
get y() {
|
|
1702
|
+
return this.toAffine().y;
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
*
|
|
1706
|
+
* @param windowSize
|
|
1707
|
+
* @param isLazy - true will defer table computation until the first multiplication
|
|
1708
|
+
* @returns
|
|
1709
|
+
*/
|
|
1710
|
+
precompute(windowSize = 8, isLazy = true) {
|
|
1711
|
+
wnaf.createCache(this, windowSize);
|
|
1712
|
+
if (!isLazy)
|
|
1713
|
+
this.multiply(_3n2);
|
|
1714
|
+
return this;
|
|
1715
|
+
}
|
|
1716
|
+
// TODO: return `this`
|
|
1717
|
+
/** A point on curve is valid if it conforms to equation. */
|
|
1718
|
+
assertValidity() {
|
|
1719
|
+
const p = this;
|
|
1720
|
+
if (p.is0()) {
|
|
1721
|
+
if (extraOpts.allowInfinityPoint && Fp3.is0(p.X) && Fp3.eql(p.Y, Fp3.ONE) && Fp3.is0(p.Z))
|
|
1722
|
+
return;
|
|
1723
|
+
throw new Error("bad point: ZERO");
|
|
1724
|
+
}
|
|
1725
|
+
const { x, y } = p.toAffine();
|
|
1726
|
+
if (!Fp3.isValid(x) || !Fp3.isValid(y))
|
|
1727
|
+
throw new Error("bad point: x or y not field elements");
|
|
1728
|
+
if (!isValidXY(x, y))
|
|
1729
|
+
throw new Error("bad point: equation left != right");
|
|
1730
|
+
if (!p.isTorsionFree())
|
|
1731
|
+
throw new Error("bad point: not in prime-order subgroup");
|
|
1732
|
+
}
|
|
1733
|
+
hasEvenY() {
|
|
1734
|
+
const { y } = this.toAffine();
|
|
1735
|
+
if (!Fp3.isOdd)
|
|
1736
|
+
throw new Error("Field doesn't support isOdd");
|
|
1737
|
+
return !Fp3.isOdd(y);
|
|
1738
|
+
}
|
|
1739
|
+
/** Compare one point to another. */
|
|
1740
|
+
equals(other) {
|
|
1741
|
+
aprjpoint(other);
|
|
1742
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
1743
|
+
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
1744
|
+
const U1 = Fp3.eql(Fp3.mul(X1, Z2), Fp3.mul(X2, Z1));
|
|
1745
|
+
const U2 = Fp3.eql(Fp3.mul(Y1, Z2), Fp3.mul(Y2, Z1));
|
|
1746
|
+
return U1 && U2;
|
|
1747
|
+
}
|
|
1748
|
+
/** Flips point to one corresponding to (x, -y) in Affine coordinates. */
|
|
1749
|
+
negate() {
|
|
1750
|
+
return new _Point(this.X, Fp3.neg(this.Y), this.Z);
|
|
1751
|
+
}
|
|
1752
|
+
// Renes-Costello-Batina exception-free doubling formula.
|
|
1753
|
+
// There is 30% faster Jacobian formula, but it is not complete.
|
|
1754
|
+
// https://eprint.iacr.org/2015/1060, algorithm 3
|
|
1755
|
+
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
|
|
1756
|
+
double() {
|
|
1757
|
+
const { a, b } = CURVE;
|
|
1758
|
+
const b3 = Fp3.mul(b, _3n2);
|
|
1759
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
1760
|
+
let X3 = Fp3.ZERO, Y3 = Fp3.ZERO, Z3 = Fp3.ZERO;
|
|
1761
|
+
let t0 = Fp3.mul(X1, X1);
|
|
1762
|
+
let t1 = Fp3.mul(Y1, Y1);
|
|
1763
|
+
let t2 = Fp3.mul(Z1, Z1);
|
|
1764
|
+
let t3 = Fp3.mul(X1, Y1);
|
|
1765
|
+
t3 = Fp3.add(t3, t3);
|
|
1766
|
+
Z3 = Fp3.mul(X1, Z1);
|
|
1767
|
+
Z3 = Fp3.add(Z3, Z3);
|
|
1768
|
+
X3 = Fp3.mul(a, Z3);
|
|
1769
|
+
Y3 = Fp3.mul(b3, t2);
|
|
1770
|
+
Y3 = Fp3.add(X3, Y3);
|
|
1771
|
+
X3 = Fp3.sub(t1, Y3);
|
|
1772
|
+
Y3 = Fp3.add(t1, Y3);
|
|
1773
|
+
Y3 = Fp3.mul(X3, Y3);
|
|
1774
|
+
X3 = Fp3.mul(t3, X3);
|
|
1775
|
+
Z3 = Fp3.mul(b3, Z3);
|
|
1776
|
+
t2 = Fp3.mul(a, t2);
|
|
1777
|
+
t3 = Fp3.sub(t0, t2);
|
|
1778
|
+
t3 = Fp3.mul(a, t3);
|
|
1779
|
+
t3 = Fp3.add(t3, Z3);
|
|
1780
|
+
Z3 = Fp3.add(t0, t0);
|
|
1781
|
+
t0 = Fp3.add(Z3, t0);
|
|
1782
|
+
t0 = Fp3.add(t0, t2);
|
|
1783
|
+
t0 = Fp3.mul(t0, t3);
|
|
1784
|
+
Y3 = Fp3.add(Y3, t0);
|
|
1785
|
+
t2 = Fp3.mul(Y1, Z1);
|
|
1786
|
+
t2 = Fp3.add(t2, t2);
|
|
1787
|
+
t0 = Fp3.mul(t2, t3);
|
|
1788
|
+
X3 = Fp3.sub(X3, t0);
|
|
1789
|
+
Z3 = Fp3.mul(t2, t1);
|
|
1790
|
+
Z3 = Fp3.add(Z3, Z3);
|
|
1791
|
+
Z3 = Fp3.add(Z3, Z3);
|
|
1792
|
+
return new _Point(X3, Y3, Z3);
|
|
1793
|
+
}
|
|
1794
|
+
// Renes-Costello-Batina exception-free addition formula.
|
|
1795
|
+
// There is 30% faster Jacobian formula, but it is not complete.
|
|
1796
|
+
// https://eprint.iacr.org/2015/1060, algorithm 1
|
|
1797
|
+
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
|
|
1798
|
+
add(other) {
|
|
1799
|
+
aprjpoint(other);
|
|
1800
|
+
const { X: X1, Y: Y1, Z: Z1 } = this;
|
|
1801
|
+
const { X: X2, Y: Y2, Z: Z2 } = other;
|
|
1802
|
+
let X3 = Fp3.ZERO, Y3 = Fp3.ZERO, Z3 = Fp3.ZERO;
|
|
1803
|
+
const a = CURVE.a;
|
|
1804
|
+
const b3 = Fp3.mul(CURVE.b, _3n2);
|
|
1805
|
+
let t0 = Fp3.mul(X1, X2);
|
|
1806
|
+
let t1 = Fp3.mul(Y1, Y2);
|
|
1807
|
+
let t2 = Fp3.mul(Z1, Z2);
|
|
1808
|
+
let t3 = Fp3.add(X1, Y1);
|
|
1809
|
+
let t4 = Fp3.add(X2, Y2);
|
|
1810
|
+
t3 = Fp3.mul(t3, t4);
|
|
1811
|
+
t4 = Fp3.add(t0, t1);
|
|
1812
|
+
t3 = Fp3.sub(t3, t4);
|
|
1813
|
+
t4 = Fp3.add(X1, Z1);
|
|
1814
|
+
let t5 = Fp3.add(X2, Z2);
|
|
1815
|
+
t4 = Fp3.mul(t4, t5);
|
|
1816
|
+
t5 = Fp3.add(t0, t2);
|
|
1817
|
+
t4 = Fp3.sub(t4, t5);
|
|
1818
|
+
t5 = Fp3.add(Y1, Z1);
|
|
1819
|
+
X3 = Fp3.add(Y2, Z2);
|
|
1820
|
+
t5 = Fp3.mul(t5, X3);
|
|
1821
|
+
X3 = Fp3.add(t1, t2);
|
|
1822
|
+
t5 = Fp3.sub(t5, X3);
|
|
1823
|
+
Z3 = Fp3.mul(a, t4);
|
|
1824
|
+
X3 = Fp3.mul(b3, t2);
|
|
1825
|
+
Z3 = Fp3.add(X3, Z3);
|
|
1826
|
+
X3 = Fp3.sub(t1, Z3);
|
|
1827
|
+
Z3 = Fp3.add(t1, Z3);
|
|
1828
|
+
Y3 = Fp3.mul(X3, Z3);
|
|
1829
|
+
t1 = Fp3.add(t0, t0);
|
|
1830
|
+
t1 = Fp3.add(t1, t0);
|
|
1831
|
+
t2 = Fp3.mul(a, t2);
|
|
1832
|
+
t4 = Fp3.mul(b3, t4);
|
|
1833
|
+
t1 = Fp3.add(t1, t2);
|
|
1834
|
+
t2 = Fp3.sub(t0, t2);
|
|
1835
|
+
t2 = Fp3.mul(a, t2);
|
|
1836
|
+
t4 = Fp3.add(t4, t2);
|
|
1837
|
+
t0 = Fp3.mul(t1, t4);
|
|
1838
|
+
Y3 = Fp3.add(Y3, t0);
|
|
1839
|
+
t0 = Fp3.mul(t5, t4);
|
|
1840
|
+
X3 = Fp3.mul(t3, X3);
|
|
1841
|
+
X3 = Fp3.sub(X3, t0);
|
|
1842
|
+
t0 = Fp3.mul(t3, t1);
|
|
1843
|
+
Z3 = Fp3.mul(t5, Z3);
|
|
1844
|
+
Z3 = Fp3.add(Z3, t0);
|
|
1845
|
+
return new _Point(X3, Y3, Z3);
|
|
1846
|
+
}
|
|
1847
|
+
subtract(other) {
|
|
1848
|
+
aprjpoint(other);
|
|
1849
|
+
return this.add(other.negate());
|
|
1850
|
+
}
|
|
1851
|
+
is0() {
|
|
1852
|
+
return this.equals(_Point.ZERO);
|
|
1853
|
+
}
|
|
1854
|
+
/**
|
|
1855
|
+
* Constant time multiplication.
|
|
1856
|
+
* Uses wNAF method. Windowed method may be 10% faster,
|
|
1857
|
+
* but takes 2x longer to generate and consumes 2x memory.
|
|
1858
|
+
* Uses precomputes when available.
|
|
1859
|
+
* Uses endomorphism for Koblitz curves.
|
|
1860
|
+
* @param scalar - by which the point would be multiplied
|
|
1861
|
+
* @returns New point
|
|
1862
|
+
*/
|
|
1863
|
+
multiply(scalar) {
|
|
1864
|
+
const { endo: endo2 } = extraOpts;
|
|
1865
|
+
if (!Fn.isValidNot0(scalar))
|
|
1866
|
+
throw new RangeError("invalid scalar: out of range");
|
|
1867
|
+
let point, fake;
|
|
1868
|
+
const mul = (n) => wnaf.cached(this, n, (p) => normalizeZ(_Point, p));
|
|
1869
|
+
if (endo2) {
|
|
1870
|
+
const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(scalar);
|
|
1871
|
+
const { p: k1p, f: k1f } = mul(k1);
|
|
1872
|
+
const { p: k2p, f: k2f } = mul(k2);
|
|
1873
|
+
fake = k1f.add(k2f);
|
|
1874
|
+
point = finishEndo(endo2.beta, k1p, k2p, k1neg, k2neg);
|
|
1875
|
+
} else {
|
|
1876
|
+
const { p, f } = mul(scalar);
|
|
1877
|
+
point = p;
|
|
1878
|
+
fake = f;
|
|
1879
|
+
}
|
|
1880
|
+
return normalizeZ(_Point, [point, fake])[0];
|
|
1881
|
+
}
|
|
1882
|
+
/**
|
|
1883
|
+
* Non-constant-time multiplication. Uses double-and-add algorithm.
|
|
1884
|
+
* It's faster, but should only be used when you don't care about
|
|
1885
|
+
* an exposed secret key e.g. sig verification, which works over *public* keys.
|
|
1886
|
+
*/
|
|
1887
|
+
multiplyUnsafe(scalar) {
|
|
1888
|
+
const { endo: endo2 } = extraOpts;
|
|
1889
|
+
const p = this;
|
|
1890
|
+
const sc = scalar;
|
|
1891
|
+
if (!Fn.isValid(sc))
|
|
1892
|
+
throw new RangeError("invalid scalar: out of range");
|
|
1893
|
+
if (sc === _0n4 || p.is0())
|
|
1894
|
+
return _Point.ZERO;
|
|
1895
|
+
if (sc === _1n4)
|
|
1896
|
+
return p;
|
|
1897
|
+
if (wnaf.hasCache(this))
|
|
1898
|
+
return this.multiply(sc);
|
|
1899
|
+
if (endo2) {
|
|
1900
|
+
const { k1neg, k1, k2neg, k2 } = splitEndoScalarN(sc);
|
|
1901
|
+
const { p1, p2 } = mulEndoUnsafe(_Point, p, k1, k2);
|
|
1902
|
+
return finishEndo(endo2.beta, p1, p2, k1neg, k2neg);
|
|
1903
|
+
} else {
|
|
1904
|
+
return wnaf.unsafe(p, sc);
|
|
1905
|
+
}
|
|
1906
|
+
}
|
|
1907
|
+
/**
|
|
1908
|
+
* Converts Projective point to affine (x, y) coordinates.
|
|
1909
|
+
* (X, Y, Z) ∋ (x=X/Z, y=Y/Z).
|
|
1910
|
+
* @param invertedZ - Z^-1 (inverted zero) - optional, precomputation is useful for invertBatch
|
|
1911
|
+
*/
|
|
1912
|
+
toAffine(invertedZ) {
|
|
1913
|
+
const p = this;
|
|
1914
|
+
let iz = invertedZ;
|
|
1915
|
+
const { X, Y, Z } = p;
|
|
1916
|
+
if (Fp3.eql(Z, Fp3.ONE))
|
|
1917
|
+
return { x: X, y: Y };
|
|
1918
|
+
const is0 = p.is0();
|
|
1919
|
+
if (iz == null)
|
|
1920
|
+
iz = is0 ? Fp3.ONE : Fp3.inv(Z);
|
|
1921
|
+
const x = Fp3.mul(X, iz);
|
|
1922
|
+
const y = Fp3.mul(Y, iz);
|
|
1923
|
+
const zz = Fp3.mul(Z, iz);
|
|
1924
|
+
if (is0)
|
|
1925
|
+
return { x: Fp3.ZERO, y: Fp3.ZERO };
|
|
1926
|
+
if (!Fp3.eql(zz, Fp3.ONE))
|
|
1927
|
+
throw new Error("invZ was invalid");
|
|
1928
|
+
return { x, y };
|
|
1929
|
+
}
|
|
1930
|
+
/**
|
|
1931
|
+
* Checks whether Point is free of torsion elements (is in prime subgroup).
|
|
1932
|
+
* Always torsion-free for cofactor=1 curves.
|
|
1933
|
+
*/
|
|
1934
|
+
isTorsionFree() {
|
|
1935
|
+
const { isTorsionFree } = extraOpts;
|
|
1936
|
+
if (cofactor === _1n4)
|
|
1937
|
+
return true;
|
|
1938
|
+
if (isTorsionFree)
|
|
1939
|
+
return isTorsionFree(_Point, this);
|
|
1940
|
+
return wnaf.unsafe(this, CURVE_ORDER).is0();
|
|
1941
|
+
}
|
|
1942
|
+
clearCofactor() {
|
|
1943
|
+
const { clearCofactor } = extraOpts;
|
|
1944
|
+
if (cofactor === _1n4)
|
|
1945
|
+
return this;
|
|
1946
|
+
if (clearCofactor)
|
|
1947
|
+
return clearCofactor(_Point, this);
|
|
1948
|
+
return this.multiplyUnsafe(cofactor);
|
|
1949
|
+
}
|
|
1950
|
+
isSmallOrder() {
|
|
1951
|
+
if (cofactor === _1n4)
|
|
1952
|
+
return this.is0();
|
|
1953
|
+
return this.clearCofactor().is0();
|
|
1954
|
+
}
|
|
1955
|
+
toBytes(isCompressed = true) {
|
|
1956
|
+
abool(isCompressed, "isCompressed");
|
|
1957
|
+
this.assertValidity();
|
|
1958
|
+
return encodePoint(_Point, this, isCompressed);
|
|
1959
|
+
}
|
|
1960
|
+
toHex(isCompressed = true) {
|
|
1961
|
+
return bytesToHex2(this.toBytes(isCompressed));
|
|
1962
|
+
}
|
|
1963
|
+
toString() {
|
|
1964
|
+
return `<Point ${this.is0() ? "ZERO" : this.toHex()}>`;
|
|
1965
|
+
}
|
|
1966
|
+
};
|
|
1967
|
+
// base / generator point
|
|
1968
|
+
__publicField(_Point, "BASE", new _Point(CURVE.Gx, CURVE.Gy, Fp3.ONE));
|
|
1969
|
+
// zero / infinity / identity point
|
|
1970
|
+
__publicField(_Point, "ZERO", new _Point(Fp3.ZERO, Fp3.ONE, Fp3.ZERO));
|
|
1971
|
+
// 0, 1, 0
|
|
1972
|
+
// math field
|
|
1973
|
+
__publicField(_Point, "Fp", Fp3);
|
|
1974
|
+
// scalar field
|
|
1975
|
+
__publicField(_Point, "Fn", Fn);
|
|
1976
|
+
let Point = _Point;
|
|
1977
|
+
const bits = Fn.BITS;
|
|
1978
|
+
const wnaf = new wNAF(Point, extraOpts.endo ? Math.ceil(bits / 2) : bits);
|
|
1979
|
+
if (bits >= 8)
|
|
1980
|
+
Point.BASE.precompute(8);
|
|
1981
|
+
Object.freeze(Point.prototype);
|
|
1982
|
+
Object.freeze(Point);
|
|
1983
|
+
return Point;
|
|
1984
|
+
}
|
|
1985
|
+
function pprefix(hasEvenY) {
|
|
1986
|
+
return Uint8Array.of(hasEvenY ? 2 : 3);
|
|
1987
|
+
}
|
|
1988
|
+
function SWUFpSqrtRatio(Fp3, Z) {
|
|
1989
|
+
const F = validateField(Fp3);
|
|
1990
|
+
const q = F.ORDER;
|
|
1991
|
+
let l = _0n4;
|
|
1992
|
+
for (let o = q - _1n4; o % _2n2 === _0n4; o /= _2n2)
|
|
1993
|
+
l += _1n4;
|
|
1994
|
+
const c1 = l;
|
|
1995
|
+
const _2n_pow_c1_1 = _2n2 << c1 - _1n4 - _1n4;
|
|
1996
|
+
const _2n_pow_c1 = _2n_pow_c1_1 * _2n2;
|
|
1997
|
+
const c2 = (q - _1n4) / _2n_pow_c1;
|
|
1998
|
+
const c3 = (c2 - _1n4) / _2n2;
|
|
1999
|
+
const c4 = _2n_pow_c1 - _1n4;
|
|
2000
|
+
const c5 = _2n_pow_c1_1;
|
|
2001
|
+
const c6 = F.pow(Z, c2);
|
|
2002
|
+
const c7 = F.pow(Z, (c2 + _1n4) / _2n2);
|
|
2003
|
+
let sqrtRatio = (u, v) => {
|
|
2004
|
+
let tv1 = c6;
|
|
2005
|
+
let tv2 = F.pow(v, c4);
|
|
2006
|
+
let tv3 = F.sqr(tv2);
|
|
2007
|
+
tv3 = F.mul(tv3, v);
|
|
2008
|
+
let tv5 = F.mul(u, tv3);
|
|
2009
|
+
tv5 = F.pow(tv5, c3);
|
|
2010
|
+
tv5 = F.mul(tv5, tv2);
|
|
2011
|
+
tv2 = F.mul(tv5, v);
|
|
2012
|
+
tv3 = F.mul(tv5, u);
|
|
2013
|
+
let tv4 = F.mul(tv3, tv2);
|
|
2014
|
+
tv5 = F.pow(tv4, c5);
|
|
2015
|
+
let isQR = F.eql(tv5, F.ONE);
|
|
2016
|
+
tv2 = F.mul(tv3, c7);
|
|
2017
|
+
tv5 = F.mul(tv4, tv1);
|
|
2018
|
+
tv3 = F.cmov(tv2, tv3, isQR);
|
|
2019
|
+
tv4 = F.cmov(tv5, tv4, isQR);
|
|
2020
|
+
for (let i = c1; i > _1n4; i--) {
|
|
2021
|
+
let tv52 = i - _2n2;
|
|
2022
|
+
tv52 = _2n2 << tv52 - _1n4;
|
|
2023
|
+
let tvv5 = F.pow(tv4, tv52);
|
|
2024
|
+
const e1 = F.eql(tvv5, F.ONE);
|
|
2025
|
+
tv2 = F.mul(tv3, tv1);
|
|
2026
|
+
tv1 = F.mul(tv1, tv1);
|
|
2027
|
+
tvv5 = F.mul(tv4, tv1);
|
|
2028
|
+
tv3 = F.cmov(tv2, tv3, e1);
|
|
2029
|
+
tv4 = F.cmov(tvv5, tv4, e1);
|
|
2030
|
+
}
|
|
2031
|
+
return { isValid: !F.is0(v) && (isQR || F.is0(u)), value: tv3 };
|
|
2032
|
+
};
|
|
2033
|
+
if (F.ORDER % _4n2 === _3n2) {
|
|
2034
|
+
const c12 = (F.ORDER - _3n2) / _4n2;
|
|
2035
|
+
const c22 = F.sqrt(F.neg(Z));
|
|
2036
|
+
sqrtRatio = (u, v) => {
|
|
2037
|
+
let tv1 = F.sqr(v);
|
|
2038
|
+
const tv2 = F.mul(u, v);
|
|
2039
|
+
tv1 = F.mul(tv1, tv2);
|
|
2040
|
+
let y1 = F.pow(tv1, c12);
|
|
2041
|
+
y1 = F.mul(y1, tv2);
|
|
2042
|
+
const y2 = F.mul(y1, c22);
|
|
2043
|
+
const tv3 = F.mul(F.sqr(y1), v);
|
|
2044
|
+
const isQR = F.eql(tv3, u);
|
|
2045
|
+
let y = F.cmov(y2, y1, isQR);
|
|
2046
|
+
return { isValid: !F.is0(v) && isQR, value: y };
|
|
2047
|
+
};
|
|
2048
|
+
}
|
|
2049
|
+
return sqrtRatio;
|
|
2050
|
+
}
|
|
2051
|
+
function mapToCurveSimpleSWU(Fp3, opts) {
|
|
2052
|
+
const F = validateField(Fp3);
|
|
2053
|
+
const { A, B, Z } = opts;
|
|
2054
|
+
if (!F.isValidNot0(A) || !F.isValidNot0(B) || !F.isValid(Z))
|
|
2055
|
+
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
2056
|
+
if (F.eql(Z, F.neg(F.ONE)) || FpIsSquare(F, Z))
|
|
2057
|
+
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
2058
|
+
const x = F.mul(B, F.inv(F.mul(Z, A)));
|
|
2059
|
+
const gx = F.add(F.add(F.mul(F.sqr(x), x), F.mul(A, x)), B);
|
|
2060
|
+
if (!FpIsSquare(F, gx))
|
|
2061
|
+
throw new Error("mapToCurveSimpleSWU: invalid opts");
|
|
2062
|
+
const sqrtRatio = SWUFpSqrtRatio(F, Z);
|
|
2063
|
+
if (!F.isOdd)
|
|
2064
|
+
throw new Error("Field does not have .isOdd()");
|
|
2065
|
+
return (u) => {
|
|
2066
|
+
let tv1, tv2, tv3, tv4, tv5, tv6, x2, y;
|
|
2067
|
+
tv1 = F.sqr(u);
|
|
2068
|
+
tv1 = F.mul(tv1, Z);
|
|
2069
|
+
tv2 = F.sqr(tv1);
|
|
2070
|
+
tv2 = F.add(tv2, tv1);
|
|
2071
|
+
tv3 = F.add(tv2, F.ONE);
|
|
2072
|
+
tv3 = F.mul(tv3, B);
|
|
2073
|
+
tv4 = F.cmov(Z, F.neg(tv2), !F.eql(tv2, F.ZERO));
|
|
2074
|
+
tv4 = F.mul(tv4, A);
|
|
2075
|
+
tv2 = F.sqr(tv3);
|
|
2076
|
+
tv6 = F.sqr(tv4);
|
|
2077
|
+
tv5 = F.mul(tv6, A);
|
|
2078
|
+
tv2 = F.add(tv2, tv5);
|
|
2079
|
+
tv2 = F.mul(tv2, tv3);
|
|
2080
|
+
tv6 = F.mul(tv6, tv4);
|
|
2081
|
+
tv5 = F.mul(tv6, B);
|
|
2082
|
+
tv2 = F.add(tv2, tv5);
|
|
2083
|
+
x2 = F.mul(tv1, tv3);
|
|
2084
|
+
const { isValid, value } = sqrtRatio(tv2, tv6);
|
|
2085
|
+
y = F.mul(tv1, u);
|
|
2086
|
+
y = F.mul(y, value);
|
|
2087
|
+
x2 = F.cmov(x2, tv3, isValid);
|
|
2088
|
+
y = F.cmov(y, value, isValid);
|
|
2089
|
+
const e1 = F.isOdd(u) === F.isOdd(y);
|
|
2090
|
+
y = F.cmov(F.neg(y), y, e1);
|
|
2091
|
+
const tv4_inv = FpInvertBatch(F, [tv4], true)[0];
|
|
2092
|
+
x2 = F.mul(x2, tv4_inv);
|
|
2093
|
+
return { x: x2, y };
|
|
2094
|
+
};
|
|
2095
|
+
}
|
|
2096
|
+
function getWLengths(Fp3, Fn) {
|
|
2097
|
+
return {
|
|
2098
|
+
secretKey: Fn.BYTES,
|
|
2099
|
+
publicKey: 1 + Fp3.BYTES,
|
|
2100
|
+
publicKeyUncompressed: 1 + 2 * Fp3.BYTES,
|
|
2101
|
+
publicKeyHasPrefix: true,
|
|
2102
|
+
// Raw compact `(r || s)` signature width; DER and recovered signatures use
|
|
2103
|
+
// different lengths outside this helper.
|
|
2104
|
+
signature: 2 * Fn.BYTES
|
|
2105
|
+
};
|
|
2106
|
+
}
|
|
2107
|
+
|
|
2108
|
+
// node_modules/@noble/curves/abstract/bls.js
|
|
2109
|
+
var _0n5 = BigInt(0);
|
|
2110
|
+
var _1n5 = BigInt(1);
|
|
2111
|
+
var _2n3 = BigInt(2);
|
|
2112
|
+
var _3n3 = BigInt(3);
|
|
2113
|
+
function NAfDecomposition(a) {
|
|
2114
|
+
const res = [];
|
|
2115
|
+
for (; a > _1n5; a >>= _1n5) {
|
|
2116
|
+
if ((a & _1n5) === _0n5)
|
|
2117
|
+
res.unshift(0);
|
|
2118
|
+
else if ((a & _3n3) === _3n3) {
|
|
2119
|
+
res.unshift(-1);
|
|
2120
|
+
a += _1n5;
|
|
2121
|
+
} else
|
|
2122
|
+
res.unshift(1);
|
|
2123
|
+
}
|
|
2124
|
+
return res;
|
|
2125
|
+
}
|
|
2126
|
+
function aNonEmpty(arr) {
|
|
2127
|
+
if (!Array.isArray(arr) || arr.length === 0)
|
|
2128
|
+
throw new Error("expected non-empty array");
|
|
2129
|
+
}
|
|
2130
|
+
function createBlsPairing(fields2, G1, G2, params) {
|
|
2131
|
+
const { Fr, Fp2: Fp22, Fp12: Fp122 } = fields2;
|
|
2132
|
+
const { twistType, ateLoopSize, xNegative, postPrecompute } = params;
|
|
2133
|
+
let lineFunction;
|
|
2134
|
+
if (twistType === "multiplicative") {
|
|
2135
|
+
lineFunction = (c0, c1, c2, f, Px, Py) => Fp122.mul014(f, c0, Fp22.mul(c1, Px), Fp22.mul(c2, Py));
|
|
2136
|
+
} else if (twistType === "divisive") {
|
|
2137
|
+
lineFunction = (c0, c1, c2, f, Px, Py) => Fp122.mul034(f, Fp22.mul(c2, Py), Fp22.mul(c1, Px), c0);
|
|
2138
|
+
} else
|
|
2139
|
+
throw new Error("bls: unknown twist type");
|
|
2140
|
+
const Fp2div2 = Fp22.div(Fp22.ONE, Fp22.mul(Fp22.ONE, _2n3));
|
|
2141
|
+
function pointDouble(ell, Rx, Ry, Rz) {
|
|
2142
|
+
const t0 = Fp22.sqr(Ry);
|
|
2143
|
+
const t1 = Fp22.sqr(Rz);
|
|
2144
|
+
const t2 = Fp22.mulByB(Fp22.mul(t1, _3n3));
|
|
2145
|
+
const t3 = Fp22.mul(t2, _3n3);
|
|
2146
|
+
const t4 = Fp22.sub(Fp22.sub(Fp22.sqr(Fp22.add(Ry, Rz)), t1), t0);
|
|
2147
|
+
const c0 = Fp22.sub(t2, t0);
|
|
2148
|
+
const c1 = Fp22.mul(Fp22.sqr(Rx), _3n3);
|
|
2149
|
+
const c2 = Fp22.neg(t4);
|
|
2150
|
+
ell.push([c0, c1, c2]);
|
|
2151
|
+
Rx = Fp22.mul(Fp22.mul(Fp22.mul(Fp22.sub(t0, t3), Rx), Ry), Fp2div2);
|
|
2152
|
+
Ry = Fp22.sub(Fp22.sqr(Fp22.mul(Fp22.add(t0, t3), Fp2div2)), Fp22.mul(Fp22.sqr(t2), _3n3));
|
|
2153
|
+
Rz = Fp22.mul(t0, t4);
|
|
2154
|
+
return { Rx, Ry, Rz };
|
|
2155
|
+
}
|
|
2156
|
+
function pointAdd(ell, Rx, Ry, Rz, Qx, Qy) {
|
|
2157
|
+
const t0 = Fp22.sub(Ry, Fp22.mul(Qy, Rz));
|
|
2158
|
+
const t1 = Fp22.sub(Rx, Fp22.mul(Qx, Rz));
|
|
2159
|
+
const c0 = Fp22.sub(Fp22.mul(t0, Qx), Fp22.mul(t1, Qy));
|
|
2160
|
+
const c1 = Fp22.neg(t0);
|
|
2161
|
+
const c2 = t1;
|
|
2162
|
+
ell.push([c0, c1, c2]);
|
|
2163
|
+
const t2 = Fp22.sqr(t1);
|
|
2164
|
+
const t3 = Fp22.mul(t2, t1);
|
|
2165
|
+
const t4 = Fp22.mul(t2, Rx);
|
|
2166
|
+
const t5 = Fp22.add(Fp22.sub(t3, Fp22.mul(t4, _2n3)), Fp22.mul(Fp22.sqr(t0), Rz));
|
|
2167
|
+
Rx = Fp22.mul(t1, t5);
|
|
2168
|
+
Ry = Fp22.sub(Fp22.mul(Fp22.sub(t4, t5), t0), Fp22.mul(t3, Ry));
|
|
2169
|
+
Rz = Fp22.mul(Rz, t3);
|
|
2170
|
+
return { Rx, Ry, Rz };
|
|
2171
|
+
}
|
|
2172
|
+
const ATE_NAF = NAfDecomposition(ateLoopSize);
|
|
2173
|
+
const calcPairingPrecomputes = (point) => {
|
|
2174
|
+
const p = point;
|
|
2175
|
+
const { x, y } = p.toAffine();
|
|
2176
|
+
const Qx = x, Qy = y, negQy = Fp22.neg(y);
|
|
2177
|
+
let Rx = Qx, Ry = Qy, Rz = Fp22.ONE;
|
|
2178
|
+
const ell = [];
|
|
2179
|
+
for (const bit of ATE_NAF) {
|
|
2180
|
+
const cur = [];
|
|
2181
|
+
({ Rx, Ry, Rz } = pointDouble(cur, Rx, Ry, Rz));
|
|
2182
|
+
if (bit)
|
|
2183
|
+
({ Rx, Ry, Rz } = pointAdd(cur, Rx, Ry, Rz, Qx, bit === -1 ? negQy : Qy));
|
|
2184
|
+
ell.push(cur);
|
|
2185
|
+
}
|
|
2186
|
+
if (postPrecompute) {
|
|
2187
|
+
const last = ell[ell.length - 1];
|
|
2188
|
+
postPrecompute(Rx, Ry, Rz, Qx, Qy, pointAdd.bind(null, last));
|
|
2189
|
+
}
|
|
2190
|
+
return ell;
|
|
2191
|
+
};
|
|
2192
|
+
function millerLoopBatch(pairs, withFinalExponent = false) {
|
|
2193
|
+
let f12 = Fp122.ONE;
|
|
2194
|
+
if (pairs.length) {
|
|
2195
|
+
const ellLen = pairs[0][0].length;
|
|
2196
|
+
for (let i = 0; i < ellLen; i++) {
|
|
2197
|
+
f12 = Fp122.sqr(f12);
|
|
2198
|
+
for (const [ell, Px, Py] of pairs) {
|
|
2199
|
+
for (const [c0, c1, c2] of ell[i])
|
|
2200
|
+
f12 = lineFunction(c0, c1, c2, f12, Px, Py);
|
|
2201
|
+
}
|
|
2202
|
+
}
|
|
2203
|
+
}
|
|
2204
|
+
if (xNegative)
|
|
2205
|
+
f12 = Fp122.conjugate(f12);
|
|
2206
|
+
return withFinalExponent ? Fp122.finalExponentiate(f12) : f12;
|
|
2207
|
+
}
|
|
2208
|
+
function pairingBatch(pairs, withFinalExponent = true) {
|
|
2209
|
+
const res = [];
|
|
2210
|
+
for (const { g1: g12, g2: g22 } of pairs) {
|
|
2211
|
+
if (g12.is0() || g22.is0())
|
|
2212
|
+
throw new Error("pairing is not available for ZERO point");
|
|
2213
|
+
g12.assertValidity();
|
|
2214
|
+
g22.assertValidity();
|
|
2215
|
+
const Qa = g12.toAffine();
|
|
2216
|
+
res.push([calcPairingPrecomputes(g22), Qa.x, Qa.y]);
|
|
2217
|
+
}
|
|
2218
|
+
return millerLoopBatch(res, withFinalExponent);
|
|
2219
|
+
}
|
|
2220
|
+
function pairing(Q, P, withFinalExponent = true) {
|
|
2221
|
+
return pairingBatch([{ g1: Q, g2: P }], withFinalExponent);
|
|
2222
|
+
}
|
|
2223
|
+
const lengths = {
|
|
2224
|
+
seed: getMinHashLength(Fr.ORDER)
|
|
2225
|
+
};
|
|
2226
|
+
const rand = params.randomBytes === void 0 ? randomBytes2 : params.randomBytes;
|
|
2227
|
+
const randomSecretKey = (seed) => {
|
|
2228
|
+
seed = seed === void 0 ? rand(lengths.seed) : seed;
|
|
2229
|
+
abytes2(seed, lengths.seed, "seed");
|
|
2230
|
+
return mapHashToField(seed, Fr.ORDER);
|
|
2231
|
+
};
|
|
2232
|
+
Object.freeze(lengths);
|
|
2233
|
+
return {
|
|
2234
|
+
lengths,
|
|
2235
|
+
Fr,
|
|
2236
|
+
Fp12: Fp122,
|
|
2237
|
+
// NOTE: we re-export Fp12 here because pairing results are Fp12!
|
|
2238
|
+
millerLoopBatch,
|
|
2239
|
+
pairing,
|
|
2240
|
+
pairingBatch,
|
|
2241
|
+
calcPairingPrecomputes,
|
|
2242
|
+
randomSecretKey
|
|
2243
|
+
};
|
|
2244
|
+
}
|
|
2245
|
+
function createBlsSig(blsPairing, PubPoint, SigPoint, isSigG1, hashToSigCurve, SignatureCoder) {
|
|
2246
|
+
const { Fr, Fp12: Fp122, pairingBatch, randomSecretKey, lengths } = blsPairing;
|
|
2247
|
+
if (!SignatureCoder) {
|
|
2248
|
+
SignatureCoder = {
|
|
2249
|
+
fromBytes: notImplemented,
|
|
2250
|
+
fromHex: notImplemented,
|
|
2251
|
+
toBytes: notImplemented,
|
|
2252
|
+
toHex: notImplemented
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
function normPub(point) {
|
|
2256
|
+
return point instanceof PubPoint ? point : PubPoint.fromBytes(point);
|
|
2257
|
+
}
|
|
2258
|
+
function normSig(point) {
|
|
2259
|
+
return point instanceof SigPoint ? point : SigPoint.fromBytes(point);
|
|
2260
|
+
}
|
|
2261
|
+
function amsg(m) {
|
|
2262
|
+
if (!(m instanceof SigPoint))
|
|
2263
|
+
throw new Error(`expected valid message hashed to ${!isSigG1 ? "G2" : "G1"} curve`);
|
|
2264
|
+
return m;
|
|
2265
|
+
}
|
|
2266
|
+
const pair = !isSigG1 ? (a, b) => ({ g1: a, g2: b }) : (a, b) => ({ g1: b, g2: a });
|
|
2267
|
+
return Object.freeze({
|
|
2268
|
+
lengths: Object.freeze(__spreadProps(__spreadValues({}, lengths), { secretKey: Fr.BYTES })),
|
|
2269
|
+
keygen(seed) {
|
|
2270
|
+
const secretKey = randomSecretKey(seed);
|
|
2271
|
+
const publicKey = this.getPublicKey(secretKey);
|
|
2272
|
+
return { secretKey, publicKey };
|
|
2273
|
+
},
|
|
2274
|
+
// P = pk x G
|
|
2275
|
+
getPublicKey(secretKey) {
|
|
2276
|
+
let sec;
|
|
2277
|
+
try {
|
|
2278
|
+
sec = PubPoint.Fn.fromBytes(secretKey);
|
|
2279
|
+
} catch (error) {
|
|
2280
|
+
throw new Error("invalid private key: " + typeof secretKey, { cause: error });
|
|
2281
|
+
}
|
|
2282
|
+
return PubPoint.BASE.multiply(sec);
|
|
2283
|
+
},
|
|
2284
|
+
// S = pk x H(m)
|
|
2285
|
+
sign(message, secretKey, unusedArg) {
|
|
2286
|
+
if (unusedArg != null)
|
|
2287
|
+
throw new Error("sign() expects 2 arguments");
|
|
2288
|
+
const sec = PubPoint.Fn.fromBytes(secretKey);
|
|
2289
|
+
amsg(message).assertValidity();
|
|
2290
|
+
return message.multiply(sec);
|
|
2291
|
+
},
|
|
2292
|
+
// Checks if pairing of public key & hash is equal to pairing of generator & signature.
|
|
2293
|
+
// e(P, H(m)) == e(G, S)
|
|
2294
|
+
// e(S, G) == e(H(m), P)
|
|
2295
|
+
verify(signature, message, publicKey, unusedArg) {
|
|
2296
|
+
if (unusedArg != null)
|
|
2297
|
+
throw new Error("verify() expects 3 arguments");
|
|
2298
|
+
signature = normSig(signature);
|
|
2299
|
+
publicKey = normPub(publicKey);
|
|
2300
|
+
const P = publicKey.negate();
|
|
2301
|
+
const G = PubPoint.BASE;
|
|
2302
|
+
const Hm = amsg(message);
|
|
2303
|
+
const S = signature;
|
|
2304
|
+
try {
|
|
2305
|
+
const exp = pairingBatch([pair(P, Hm), pair(G, S)]);
|
|
2306
|
+
return Fp122.eql(exp, Fp122.ONE);
|
|
2307
|
+
} catch (e) {
|
|
2308
|
+
return false;
|
|
2309
|
+
}
|
|
2310
|
+
},
|
|
2311
|
+
// https://ethresear.ch/t/fast-verification-of-multiple-bls-signatures/5407
|
|
2312
|
+
// e(G, S) = e(G, SUM(n)(Si)) = MUL(n)(e(G, Si))
|
|
2313
|
+
// TODO: maybe `{message: G2Hex, publicKey: G1Hex}[]` instead?
|
|
2314
|
+
verifyBatch(signature, items) {
|
|
2315
|
+
aNonEmpty(items);
|
|
2316
|
+
const sig = normSig(signature);
|
|
2317
|
+
const nMessages = items.map((i) => i.message);
|
|
2318
|
+
const nPublicKeys = items.map((i) => normPub(i.publicKey));
|
|
2319
|
+
const messagePubKeyMap = /* @__PURE__ */ new Map();
|
|
2320
|
+
for (let i = 0; i < nPublicKeys.length; i++) {
|
|
2321
|
+
const pub = nPublicKeys[i];
|
|
2322
|
+
const msg = nMessages[i];
|
|
2323
|
+
let keys = messagePubKeyMap.get(msg);
|
|
2324
|
+
if (keys === void 0) {
|
|
2325
|
+
keys = [];
|
|
2326
|
+
messagePubKeyMap.set(msg, keys);
|
|
2327
|
+
}
|
|
2328
|
+
keys.push(pub);
|
|
2329
|
+
}
|
|
2330
|
+
const paired = [];
|
|
2331
|
+
const G = PubPoint.BASE;
|
|
2332
|
+
try {
|
|
2333
|
+
for (const [msg, keys] of messagePubKeyMap) {
|
|
2334
|
+
const groupPublicKey = keys.reduce((acc, msg2) => acc.add(msg2));
|
|
2335
|
+
paired.push(pair(groupPublicKey, msg));
|
|
2336
|
+
}
|
|
2337
|
+
paired.push(pair(G.negate(), sig));
|
|
2338
|
+
return Fp122.eql(pairingBatch(paired), Fp122.ONE);
|
|
2339
|
+
} catch (e) {
|
|
2340
|
+
return false;
|
|
2341
|
+
}
|
|
2342
|
+
},
|
|
2343
|
+
// Adds a bunch of public key points together.
|
|
2344
|
+
// pk1 + pk2 + pk3 = pkA
|
|
2345
|
+
aggregatePublicKeys(publicKeys) {
|
|
2346
|
+
aNonEmpty(publicKeys);
|
|
2347
|
+
publicKeys = publicKeys.map((pub) => normPub(pub));
|
|
2348
|
+
const agg = publicKeys.reduce((sum, p) => sum.add(p), PubPoint.ZERO);
|
|
2349
|
+
agg.assertValidity();
|
|
2350
|
+
return agg;
|
|
2351
|
+
},
|
|
2352
|
+
// Adds a bunch of signature points together.
|
|
2353
|
+
// pk1 + pk2 + pk3 = pkA
|
|
2354
|
+
aggregateSignatures(signatures) {
|
|
2355
|
+
aNonEmpty(signatures);
|
|
2356
|
+
signatures = signatures.map((sig) => normSig(sig));
|
|
2357
|
+
const agg = signatures.reduce((sum, s) => sum.add(s), SigPoint.ZERO);
|
|
2358
|
+
agg.assertValidity();
|
|
2359
|
+
return agg;
|
|
2360
|
+
},
|
|
2361
|
+
hash(messageBytes, DST) {
|
|
2362
|
+
abytes2(messageBytes);
|
|
2363
|
+
const opts = DST ? { DST } : void 0;
|
|
2364
|
+
return hashToSigCurve(messageBytes, opts);
|
|
2365
|
+
},
|
|
2366
|
+
Signature: Object.freeze(__spreadValues({}, SignatureCoder))
|
|
2367
|
+
});
|
|
2368
|
+
}
|
|
2369
|
+
function blsBasic(fields2, G1_Point2, G2_Point2, params) {
|
|
2370
|
+
const { Fp: Fp3, Fr, Fp2: Fp22, Fp6: Fp62, Fp12: Fp122 } = fields2;
|
|
2371
|
+
const G1 = { Point: G1_Point2 };
|
|
2372
|
+
const G2 = { Point: G2_Point2 };
|
|
2373
|
+
const pairingRes = createBlsPairing(fields2, G1_Point2, G2_Point2, params);
|
|
2374
|
+
const { millerLoopBatch, pairing, pairingBatch, calcPairingPrecomputes, randomSecretKey, lengths } = pairingRes;
|
|
2375
|
+
G1.Point.BASE.precompute(4);
|
|
2376
|
+
Object.freeze(G1);
|
|
2377
|
+
Object.freeze(G2);
|
|
2378
|
+
return Object.freeze({
|
|
2379
|
+
lengths: Object.freeze(lengths),
|
|
2380
|
+
millerLoopBatch,
|
|
2381
|
+
pairing,
|
|
2382
|
+
pairingBatch,
|
|
2383
|
+
G1,
|
|
2384
|
+
G2,
|
|
2385
|
+
fields: Object.freeze({ Fr, Fp: Fp3, Fp2: Fp22, Fp6: Fp62, Fp12: Fp122 }),
|
|
2386
|
+
params: Object.freeze({
|
|
2387
|
+
ateLoopSize: params.ateLoopSize,
|
|
2388
|
+
twistType: params.twistType
|
|
2389
|
+
}),
|
|
2390
|
+
utils: Object.freeze({
|
|
2391
|
+
randomSecretKey,
|
|
2392
|
+
calcPairingPrecomputes
|
|
2393
|
+
})
|
|
2394
|
+
});
|
|
2395
|
+
}
|
|
2396
|
+
function blsHashers(fields2, G1_Point2, G2_Point2, params, hasherParams) {
|
|
2397
|
+
const base = blsBasic(fields2, G1_Point2, G2_Point2, params);
|
|
2398
|
+
const G1Hasher = createHasher2(G1_Point2, hasherParams.mapToG1 === void 0 ? notImplemented : hasherParams.mapToG1, __spreadValues(__spreadValues({}, hasherParams.hasherOpts), hasherParams.hasherOptsG1));
|
|
2399
|
+
const G2Hasher = createHasher2(G2_Point2, hasherParams.mapToG2 === void 0 ? notImplemented : hasherParams.mapToG2, __spreadValues(__spreadValues({}, hasherParams.hasherOpts), hasherParams.hasherOptsG2));
|
|
2400
|
+
return Object.freeze(__spreadProps(__spreadValues({}, base), { G1: G1Hasher, G2: G2Hasher }));
|
|
2401
|
+
}
|
|
2402
|
+
function bls(fields2, G1_Point2, G2_Point2, params, hasherParams, signatureCoders2) {
|
|
2403
|
+
const base = blsHashers(fields2, G1_Point2, G2_Point2, params, hasherParams);
|
|
2404
|
+
const pairingRes = __spreadProps(__spreadValues({}, base), {
|
|
2405
|
+
Fr: base.fields.Fr,
|
|
2406
|
+
Fp12: base.fields.Fp12,
|
|
2407
|
+
calcPairingPrecomputes: base.utils.calcPairingPrecomputes,
|
|
2408
|
+
randomSecretKey: base.utils.randomSecretKey
|
|
2409
|
+
});
|
|
2410
|
+
const longSignatures = createBlsSig(pairingRes, G1_Point2, G2_Point2, false, base.G2.hashToCurve, signatureCoders2 == null ? void 0 : signatureCoders2.LongSignature);
|
|
2411
|
+
const shortSignatures = createBlsSig(pairingRes, G2_Point2, G1_Point2, true, base.G1.hashToCurve, signatureCoders2 == null ? void 0 : signatureCoders2.ShortSignature);
|
|
2412
|
+
return Object.freeze(__spreadProps(__spreadValues({}, base), { longSignatures, shortSignatures }));
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// node_modules/@noble/curves/abstract/tower.js
|
|
2416
|
+
var _0n6 = /* @__PURE__ */ BigInt(0);
|
|
2417
|
+
var _1n6 = /* @__PURE__ */ BigInt(1);
|
|
2418
|
+
var _2n4 = /* @__PURE__ */ BigInt(2);
|
|
2419
|
+
var _3n4 = /* @__PURE__ */ BigInt(3);
|
|
2420
|
+
var _6n = /* @__PURE__ */ BigInt(6);
|
|
2421
|
+
var _12n = /* @__PURE__ */ BigInt(12);
|
|
2422
|
+
var isObj = (value) => !!value && typeof value === "object";
|
|
2423
|
+
function calcFrobeniusCoefficients(Fp3, nonResidue, modulus, degree, num = 1, divisor) {
|
|
2424
|
+
asafenumber(num, "num");
|
|
2425
|
+
const F = Fp3;
|
|
2426
|
+
if (num <= 0)
|
|
2427
|
+
throw new Error("calcFrobeniusCoefficients: expected positive row count, got " + num);
|
|
2428
|
+
const _divisor = BigInt(divisor === void 0 ? degree : divisor);
|
|
2429
|
+
const towerModulus = modulus ** BigInt(degree);
|
|
2430
|
+
const res = [];
|
|
2431
|
+
for (let i = 0; i < num; i++) {
|
|
2432
|
+
const a = BigInt(i + 1);
|
|
2433
|
+
const powers = [];
|
|
2434
|
+
for (let j = 0, qPower = _1n6; j < degree; j++) {
|
|
2435
|
+
const numer = a * qPower - a;
|
|
2436
|
+
if (numer % _divisor)
|
|
2437
|
+
throw new Error("calcFrobeniusCoefficients: inexact tower exponent");
|
|
2438
|
+
const power = numer / _divisor % towerModulus;
|
|
2439
|
+
powers.push(F.pow(nonResidue, power));
|
|
2440
|
+
qPower *= modulus;
|
|
2441
|
+
}
|
|
2442
|
+
res.push(powers);
|
|
2443
|
+
}
|
|
2444
|
+
return res;
|
|
2445
|
+
}
|
|
2446
|
+
function psiFrobenius(Fp3, Fp22, base) {
|
|
2447
|
+
const PSI_X = Fp22.pow(base, (Fp3.ORDER - _1n6) / _3n4);
|
|
2448
|
+
const PSI_Y = Fp22.pow(base, (Fp3.ORDER - _1n6) / _2n4);
|
|
2449
|
+
function psi(x, y) {
|
|
2450
|
+
const x2 = Fp22.mul(Fp22.frobeniusMap(x, 1), PSI_X);
|
|
2451
|
+
const y2 = Fp22.mul(Fp22.frobeniusMap(y, 1), PSI_Y);
|
|
2452
|
+
return [x2, y2];
|
|
2453
|
+
}
|
|
2454
|
+
const PSI2_X = Fp22.pow(base, (Fp3.ORDER ** _2n4 - _1n6) / _3n4);
|
|
2455
|
+
const PSI2_Y = Fp22.pow(base, (Fp3.ORDER ** _2n4 - _1n6) / _2n4);
|
|
2456
|
+
if (!Fp22.eql(PSI2_Y, Fp22.neg(Fp22.ONE)))
|
|
2457
|
+
throw new Error("psiFrobenius: PSI2_Y!==-1");
|
|
2458
|
+
function psi2(x, y) {
|
|
2459
|
+
return [Fp22.mul(x, PSI2_X), Fp22.neg(y)];
|
|
2460
|
+
}
|
|
2461
|
+
const mapAffine = (fn) => (c, P) => {
|
|
2462
|
+
const affine = P.toAffine();
|
|
2463
|
+
const p = fn(affine.x, affine.y);
|
|
2464
|
+
return c.fromAffine({ x: p[0], y: p[1] });
|
|
2465
|
+
};
|
|
2466
|
+
const G2psi3 = mapAffine(psi);
|
|
2467
|
+
const G2psi22 = mapAffine(psi2);
|
|
2468
|
+
return { psi, psi2, G2psi: G2psi3, G2psi2: G2psi22, PSI_X, PSI_Y, PSI2_X, PSI2_Y };
|
|
2469
|
+
}
|
|
2470
|
+
var _Field2 = class {
|
|
2471
|
+
constructor(Fp3, opts = {}) {
|
|
2472
|
+
__publicField(this, "ORDER");
|
|
2473
|
+
__publicField(this, "BITS");
|
|
2474
|
+
__publicField(this, "BYTES");
|
|
2475
|
+
__publicField(this, "isLE");
|
|
2476
|
+
__publicField(this, "ZERO");
|
|
2477
|
+
__publicField(this, "ONE");
|
|
2478
|
+
__publicField(this, "Fp");
|
|
2479
|
+
__publicField(this, "NONRESIDUE");
|
|
2480
|
+
__publicField(this, "mulByB");
|
|
2481
|
+
__publicField(this, "Fp_NONRESIDUE");
|
|
2482
|
+
__publicField(this, "Fp_div2");
|
|
2483
|
+
__publicField(this, "FROBENIUS_COEFFICIENTS");
|
|
2484
|
+
const { NONRESIDUE = BigInt(-1), FP2_NONRESIDUE, Fp2mulByB } = opts;
|
|
2485
|
+
const ORDER = Fp3.ORDER;
|
|
2486
|
+
const FP2_ORDER = ORDER * ORDER;
|
|
2487
|
+
this.Fp = Fp3;
|
|
2488
|
+
this.ORDER = FP2_ORDER;
|
|
2489
|
+
this.BITS = bitLen(FP2_ORDER);
|
|
2490
|
+
this.BYTES = Math.ceil(bitLen(FP2_ORDER) / 8);
|
|
2491
|
+
this.isLE = Fp3.isLE;
|
|
2492
|
+
this.ZERO = this.create({ c0: Fp3.ZERO, c1: Fp3.ZERO });
|
|
2493
|
+
this.ONE = this.create({ c0: Fp3.ONE, c1: Fp3.ZERO });
|
|
2494
|
+
this.Fp_NONRESIDUE = Fp3.create(NONRESIDUE);
|
|
2495
|
+
this.Fp_div2 = Fp3.div(Fp3.ONE, _2n4);
|
|
2496
|
+
this.NONRESIDUE = this.create({ c0: FP2_NONRESIDUE[0], c1: FP2_NONRESIDUE[1] });
|
|
2497
|
+
this.FROBENIUS_COEFFICIENTS = Object.freeze(calcFrobeniusCoefficients(Fp3, this.Fp_NONRESIDUE, Fp3.ORDER, 2)[0]);
|
|
2498
|
+
this.mulByB = (num) => {
|
|
2499
|
+
const { c0, c1 } = Fp2mulByB(num);
|
|
2500
|
+
return Object.freeze({ c0, c1 });
|
|
2501
|
+
};
|
|
2502
|
+
Object.freeze(this);
|
|
2503
|
+
}
|
|
2504
|
+
fromBigTuple(tuple) {
|
|
2505
|
+
if (!Array.isArray(tuple) || tuple.length !== 2)
|
|
2506
|
+
throw new Error("invalid Fp2.fromBigTuple");
|
|
2507
|
+
const [c0, c1] = tuple;
|
|
2508
|
+
if (typeof c0 !== "bigint" || typeof c1 !== "bigint")
|
|
2509
|
+
throw new Error("invalid Fp2.fromBigTuple");
|
|
2510
|
+
return this.create({ c0, c1 });
|
|
2511
|
+
}
|
|
2512
|
+
create(num) {
|
|
2513
|
+
const { Fp: Fp3 } = this;
|
|
2514
|
+
const c0 = Fp3.create(num.c0);
|
|
2515
|
+
const c1 = Fp3.create(num.c1);
|
|
2516
|
+
return Object.freeze({ c0, c1 });
|
|
2517
|
+
}
|
|
2518
|
+
isValid(num) {
|
|
2519
|
+
if (!isObj(num))
|
|
2520
|
+
throw new TypeError("invalid field element: expected object, got " + typeof num);
|
|
2521
|
+
const { c0, c1 } = num;
|
|
2522
|
+
const { Fp: Fp3 } = this;
|
|
2523
|
+
return Fp3.isValid(c0) && Fp3.isValid(c1);
|
|
2524
|
+
}
|
|
2525
|
+
is0(num) {
|
|
2526
|
+
if (!isObj(num))
|
|
2527
|
+
return false;
|
|
2528
|
+
const { c0, c1 } = num;
|
|
2529
|
+
const { Fp: Fp3 } = this;
|
|
2530
|
+
return Fp3.is0(c0) && Fp3.is0(c1);
|
|
2531
|
+
}
|
|
2532
|
+
isValidNot0(num) {
|
|
2533
|
+
return !this.is0(num) && this.isValid(num);
|
|
2534
|
+
}
|
|
2535
|
+
eql({ c0, c1 }, { c0: r0, c1: r1 }) {
|
|
2536
|
+
const { Fp: Fp3 } = this;
|
|
2537
|
+
return Fp3.eql(c0, r0) && Fp3.eql(c1, r1);
|
|
2538
|
+
}
|
|
2539
|
+
neg({ c0, c1 }) {
|
|
2540
|
+
const { Fp: Fp3 } = this;
|
|
2541
|
+
return Object.freeze({ c0: Fp3.neg(c0), c1: Fp3.neg(c1) });
|
|
2542
|
+
}
|
|
2543
|
+
pow(num, power) {
|
|
2544
|
+
return FpPow(this, num, power);
|
|
2545
|
+
}
|
|
2546
|
+
invertBatch(nums) {
|
|
2547
|
+
return FpInvertBatch(this, nums);
|
|
2548
|
+
}
|
|
2549
|
+
// Normalized
|
|
2550
|
+
add(f1, f2) {
|
|
2551
|
+
const { Fp: Fp3 } = this;
|
|
2552
|
+
const { c0, c1 } = f1;
|
|
2553
|
+
const { c0: r0, c1: r1 } = f2;
|
|
2554
|
+
return Object.freeze({
|
|
2555
|
+
c0: Fp3.add(c0, r0),
|
|
2556
|
+
c1: Fp3.add(c1, r1)
|
|
2557
|
+
});
|
|
2558
|
+
}
|
|
2559
|
+
sub({ c0, c1 }, { c0: r0, c1: r1 }) {
|
|
2560
|
+
const { Fp: Fp3 } = this;
|
|
2561
|
+
return Object.freeze({
|
|
2562
|
+
c0: Fp3.sub(c0, r0),
|
|
2563
|
+
c1: Fp3.sub(c1, r1)
|
|
2564
|
+
});
|
|
2565
|
+
}
|
|
2566
|
+
mul({ c0, c1 }, rhs) {
|
|
2567
|
+
const { Fp: Fp3 } = this;
|
|
2568
|
+
if (typeof rhs === "bigint")
|
|
2569
|
+
return Object.freeze({ c0: Fp3.mul(c0, rhs), c1: Fp3.mul(c1, rhs) });
|
|
2570
|
+
const { c0: r0, c1: r1 } = rhs;
|
|
2571
|
+
let t1 = Fp3.mul(c0, r0);
|
|
2572
|
+
let t2 = Fp3.mul(c1, r1);
|
|
2573
|
+
const o0 = Fp3.sub(t1, t2);
|
|
2574
|
+
const o1 = Fp3.sub(Fp3.mul(Fp3.add(c0, c1), Fp3.add(r0, r1)), Fp3.add(t1, t2));
|
|
2575
|
+
return Object.freeze({ c0: o0, c1: o1 });
|
|
2576
|
+
}
|
|
2577
|
+
sqr({ c0, c1 }) {
|
|
2578
|
+
const { Fp: Fp3 } = this;
|
|
2579
|
+
const a = Fp3.add(c0, c1);
|
|
2580
|
+
const b = Fp3.sub(c0, c1);
|
|
2581
|
+
const c = Fp3.add(c0, c0);
|
|
2582
|
+
return Object.freeze({ c0: Fp3.mul(a, b), c1: Fp3.mul(c, c1) });
|
|
2583
|
+
}
|
|
2584
|
+
// NonNormalized stuff
|
|
2585
|
+
addN(a, b) {
|
|
2586
|
+
return this.add(a, b);
|
|
2587
|
+
}
|
|
2588
|
+
subN(a, b) {
|
|
2589
|
+
return this.sub(a, b);
|
|
2590
|
+
}
|
|
2591
|
+
mulN(a, b) {
|
|
2592
|
+
return this.mul(a, b);
|
|
2593
|
+
}
|
|
2594
|
+
sqrN(a) {
|
|
2595
|
+
return this.sqr(a);
|
|
2596
|
+
}
|
|
2597
|
+
// Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
|
|
2598
|
+
div(lhs, rhs) {
|
|
2599
|
+
const { Fp: Fp3 } = this;
|
|
2600
|
+
return this.mul(lhs, typeof rhs === "bigint" ? Fp3.inv(Fp3.create(rhs)) : this.inv(rhs));
|
|
2601
|
+
}
|
|
2602
|
+
inv({ c0: a, c1: b }) {
|
|
2603
|
+
const { Fp: Fp3 } = this;
|
|
2604
|
+
const factor = Fp3.inv(Fp3.create(a * a + b * b));
|
|
2605
|
+
return Object.freeze({ c0: Fp3.mul(factor, Fp3.create(a)), c1: Fp3.mul(factor, Fp3.create(-b)) });
|
|
2606
|
+
}
|
|
2607
|
+
sqrt(num) {
|
|
2608
|
+
const { Fp: Fp3 } = this;
|
|
2609
|
+
const Fp22 = this;
|
|
2610
|
+
const { c0, c1 } = num;
|
|
2611
|
+
if (Fp3.is0(c1)) {
|
|
2612
|
+
if (FpLegendre(Fp3, c0) === 1)
|
|
2613
|
+
return Fp22.create({ c0: Fp3.sqrt(c0), c1: Fp3.ZERO });
|
|
2614
|
+
else
|
|
2615
|
+
return Fp22.create({ c0: Fp3.ZERO, c1: Fp3.sqrt(Fp3.div(c0, this.Fp_NONRESIDUE)) });
|
|
2616
|
+
}
|
|
2617
|
+
const a = Fp3.sqrt(Fp3.sub(Fp3.sqr(c0), Fp3.mul(Fp3.sqr(c1), this.Fp_NONRESIDUE)));
|
|
2618
|
+
let d = Fp3.mul(Fp3.add(a, c0), this.Fp_div2);
|
|
2619
|
+
const legendre = FpLegendre(Fp3, d);
|
|
2620
|
+
if (legendre === -1)
|
|
2621
|
+
d = Fp3.sub(d, a);
|
|
2622
|
+
const a0 = Fp3.sqrt(d);
|
|
2623
|
+
const candidateSqrt = Fp22.create({ c0: a0, c1: Fp3.div(Fp3.mul(c1, this.Fp_div2), a0) });
|
|
2624
|
+
if (!Fp22.eql(Fp22.sqr(candidateSqrt), num))
|
|
2625
|
+
throw new Error("Cannot find square root");
|
|
2626
|
+
const x1 = candidateSqrt;
|
|
2627
|
+
const x2 = Fp22.neg(x1);
|
|
2628
|
+
const { re: re1, im: im1 } = Fp22.reim(x1);
|
|
2629
|
+
const { re: re2, im: im2 } = Fp22.reim(x2);
|
|
2630
|
+
if (im1 > im2 || im1 === im2 && re1 > re2)
|
|
2631
|
+
return x1;
|
|
2632
|
+
return x2;
|
|
2633
|
+
}
|
|
2634
|
+
// Same as sgn0_m_eq_2 in RFC 9380
|
|
2635
|
+
isOdd(x) {
|
|
2636
|
+
const { re: x0, im: x1 } = this.reim(x);
|
|
2637
|
+
const sign_0 = x0 % _2n4;
|
|
2638
|
+
const zero_0 = x0 === _0n6;
|
|
2639
|
+
const sign_1 = x1 % _2n4;
|
|
2640
|
+
return BigInt(sign_0 || zero_0 && sign_1) == _1n6;
|
|
2641
|
+
}
|
|
2642
|
+
// Bytes util
|
|
2643
|
+
fromBytes(b) {
|
|
2644
|
+
const { Fp: Fp3 } = this;
|
|
2645
|
+
abytes2(b);
|
|
2646
|
+
if (b.length !== this.BYTES)
|
|
2647
|
+
throw new Error("fromBytes invalid length=" + b.length);
|
|
2648
|
+
return this.create({
|
|
2649
|
+
c0: Fp3.fromBytes(b.subarray(0, Fp3.BYTES)),
|
|
2650
|
+
c1: Fp3.fromBytes(b.subarray(Fp3.BYTES))
|
|
2651
|
+
});
|
|
2652
|
+
}
|
|
2653
|
+
toBytes({ c0, c1 }) {
|
|
2654
|
+
return concatBytes2(this.Fp.toBytes(c0), this.Fp.toBytes(c1));
|
|
2655
|
+
}
|
|
2656
|
+
cmov({ c0, c1 }, { c0: r0, c1: r1 }, c) {
|
|
2657
|
+
const { Fp: Fp3 } = this;
|
|
2658
|
+
return this.create({
|
|
2659
|
+
c0: Fp3.cmov(c0, r0, c),
|
|
2660
|
+
c1: Fp3.cmov(c1, r1, c)
|
|
2661
|
+
});
|
|
2662
|
+
}
|
|
2663
|
+
reim({ c0, c1 }) {
|
|
2664
|
+
return { re: c0, im: c1 };
|
|
2665
|
+
}
|
|
2666
|
+
Fp4Square(a, b) {
|
|
2667
|
+
const Fp22 = this;
|
|
2668
|
+
const a2 = Fp22.sqr(a);
|
|
2669
|
+
const b2 = Fp22.sqr(b);
|
|
2670
|
+
return {
|
|
2671
|
+
first: Fp22.add(Fp22.mulByNonresidue(b2), a2),
|
|
2672
|
+
// b² * Nonresidue + a²
|
|
2673
|
+
second: Fp22.sub(Fp22.sub(Fp22.sqr(Fp22.add(a, b)), a2), b2)
|
|
2674
|
+
// (a + b)² - a² - b²
|
|
2675
|
+
};
|
|
2676
|
+
}
|
|
2677
|
+
// multiply by u + 1
|
|
2678
|
+
mulByNonresidue({ c0, c1 }) {
|
|
2679
|
+
return this.mul({ c0, c1 }, this.NONRESIDUE);
|
|
2680
|
+
}
|
|
2681
|
+
frobeniusMap({ c0, c1 }, power) {
|
|
2682
|
+
return Object.freeze({
|
|
2683
|
+
c0,
|
|
2684
|
+
c1: this.Fp.mul(c1, this.FROBENIUS_COEFFICIENTS[power % 2])
|
|
2685
|
+
});
|
|
2686
|
+
}
|
|
2687
|
+
};
|
|
2688
|
+
var _Field6 = class {
|
|
2689
|
+
constructor(Fp22) {
|
|
2690
|
+
__publicField(this, "ORDER");
|
|
2691
|
+
__publicField(this, "BITS");
|
|
2692
|
+
__publicField(this, "BYTES");
|
|
2693
|
+
__publicField(this, "isLE");
|
|
2694
|
+
__publicField(this, "ZERO");
|
|
2695
|
+
__publicField(this, "ONE");
|
|
2696
|
+
__publicField(this, "Fp2");
|
|
2697
|
+
this.Fp2 = Fp22;
|
|
2698
|
+
this.ORDER = Fp22.Fp.ORDER ** _6n;
|
|
2699
|
+
this.BITS = 3 * Fp22.BITS;
|
|
2700
|
+
this.BYTES = 3 * Fp22.BYTES;
|
|
2701
|
+
this.isLE = Fp22.isLE;
|
|
2702
|
+
this.ZERO = this.create({ c0: Fp22.ZERO, c1: Fp22.ZERO, c2: Fp22.ZERO });
|
|
2703
|
+
this.ONE = this.create({ c0: Fp22.ONE, c1: Fp22.ZERO, c2: Fp22.ZERO });
|
|
2704
|
+
Object.freeze(this);
|
|
2705
|
+
}
|
|
2706
|
+
// Most callers never touch Frobenius maps, so keep the sextic tables lazy:
|
|
2707
|
+
// eagerly deriving them dominates `bls12-381.js` / `bn254.js` import time.
|
|
2708
|
+
get FROBENIUS_COEFFICIENTS_1() {
|
|
2709
|
+
const frob2 = _FROBENIUS_COEFFICIENTS_6.get(this);
|
|
2710
|
+
if (frob2)
|
|
2711
|
+
return frob2[0];
|
|
2712
|
+
const { Fp2: Fp22 } = this;
|
|
2713
|
+
const { Fp: Fp3 } = Fp22;
|
|
2714
|
+
const rows = calcFrobeniusCoefficients(Fp22, Fp22.NONRESIDUE, Fp3.ORDER, 6, 2, 3);
|
|
2715
|
+
const cache = [Object.freeze(rows[0]), Object.freeze(rows[1])];
|
|
2716
|
+
_FROBENIUS_COEFFICIENTS_6.set(this, cache);
|
|
2717
|
+
return cache[0];
|
|
2718
|
+
}
|
|
2719
|
+
get FROBENIUS_COEFFICIENTS_2() {
|
|
2720
|
+
const frob2 = _FROBENIUS_COEFFICIENTS_6.get(this);
|
|
2721
|
+
if (frob2)
|
|
2722
|
+
return frob2[1];
|
|
2723
|
+
void this.FROBENIUS_COEFFICIENTS_1;
|
|
2724
|
+
return _FROBENIUS_COEFFICIENTS_6.get(this)[1];
|
|
2725
|
+
}
|
|
2726
|
+
add({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) {
|
|
2727
|
+
const { Fp2: Fp22 } = this;
|
|
2728
|
+
return Object.freeze({
|
|
2729
|
+
c0: Fp22.add(c0, r0),
|
|
2730
|
+
c1: Fp22.add(c1, r1),
|
|
2731
|
+
c2: Fp22.add(c2, r2)
|
|
2732
|
+
});
|
|
2733
|
+
}
|
|
2734
|
+
sub({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) {
|
|
2735
|
+
const { Fp2: Fp22 } = this;
|
|
2736
|
+
return Object.freeze({
|
|
2737
|
+
c0: Fp22.sub(c0, r0),
|
|
2738
|
+
c1: Fp22.sub(c1, r1),
|
|
2739
|
+
c2: Fp22.sub(c2, r2)
|
|
2740
|
+
});
|
|
2741
|
+
}
|
|
2742
|
+
mul({ c0, c1, c2 }, rhs) {
|
|
2743
|
+
const { Fp2: Fp22 } = this;
|
|
2744
|
+
if (typeof rhs === "bigint") {
|
|
2745
|
+
return Object.freeze({
|
|
2746
|
+
c0: Fp22.mul(c0, rhs),
|
|
2747
|
+
c1: Fp22.mul(c1, rhs),
|
|
2748
|
+
c2: Fp22.mul(c2, rhs)
|
|
2749
|
+
});
|
|
2750
|
+
}
|
|
2751
|
+
const { c0: r0, c1: r1, c2: r2 } = rhs;
|
|
2752
|
+
const t0 = Fp22.mul(c0, r0);
|
|
2753
|
+
const t1 = Fp22.mul(c1, r1);
|
|
2754
|
+
const t2 = Fp22.mul(c2, r2);
|
|
2755
|
+
return Object.freeze({
|
|
2756
|
+
// t0 + (c1 + c2) * (r1 * r2) - (T1 + T2) * (u + 1)
|
|
2757
|
+
c0: Fp22.add(t0, Fp22.mulByNonresidue(Fp22.sub(Fp22.mul(Fp22.add(c1, c2), Fp22.add(r1, r2)), Fp22.add(t1, t2)))),
|
|
2758
|
+
// (c0 + c1) * (r0 + r1) - (T0 + T1) + T2 * (u + 1)
|
|
2759
|
+
c1: Fp22.add(Fp22.sub(Fp22.mul(Fp22.add(c0, c1), Fp22.add(r0, r1)), Fp22.add(t0, t1)), Fp22.mulByNonresidue(t2)),
|
|
2760
|
+
// T1 + (c0 + c2) * (r0 + r2) - T0 + T2
|
|
2761
|
+
c2: Fp22.sub(Fp22.add(t1, Fp22.mul(Fp22.add(c0, c2), Fp22.add(r0, r2))), Fp22.add(t0, t2))
|
|
2762
|
+
});
|
|
2763
|
+
}
|
|
2764
|
+
sqr({ c0, c1, c2 }) {
|
|
2765
|
+
const { Fp2: Fp22 } = this;
|
|
2766
|
+
let t0 = Fp22.sqr(c0);
|
|
2767
|
+
let t1 = Fp22.mul(Fp22.mul(c0, c1), _2n4);
|
|
2768
|
+
let t3 = Fp22.mul(Fp22.mul(c1, c2), _2n4);
|
|
2769
|
+
let t4 = Fp22.sqr(c2);
|
|
2770
|
+
return Object.freeze({
|
|
2771
|
+
c0: Fp22.add(Fp22.mulByNonresidue(t3), t0),
|
|
2772
|
+
// T3 * (u + 1) + T0
|
|
2773
|
+
c1: Fp22.add(Fp22.mulByNonresidue(t4), t1),
|
|
2774
|
+
// T4 * (u + 1) + T1
|
|
2775
|
+
// T1 + (c0 - c1 + c2)² + T3 - T0 - T4
|
|
2776
|
+
c2: Fp22.sub(Fp22.sub(Fp22.add(Fp22.add(t1, Fp22.sqr(Fp22.add(Fp22.sub(c0, c1), c2))), t3), t0), t4)
|
|
2777
|
+
});
|
|
2778
|
+
}
|
|
2779
|
+
addN(a, b) {
|
|
2780
|
+
return this.add(a, b);
|
|
2781
|
+
}
|
|
2782
|
+
subN(a, b) {
|
|
2783
|
+
return this.sub(a, b);
|
|
2784
|
+
}
|
|
2785
|
+
mulN(a, b) {
|
|
2786
|
+
return this.mul(a, b);
|
|
2787
|
+
}
|
|
2788
|
+
sqrN(a) {
|
|
2789
|
+
return this.sqr(a);
|
|
2790
|
+
}
|
|
2791
|
+
create(num) {
|
|
2792
|
+
const { Fp2: Fp22 } = this;
|
|
2793
|
+
const c0 = Fp22.create(num.c0);
|
|
2794
|
+
const c1 = Fp22.create(num.c1);
|
|
2795
|
+
const c2 = Fp22.create(num.c2);
|
|
2796
|
+
return Object.freeze({ c0, c1, c2 });
|
|
2797
|
+
}
|
|
2798
|
+
isValid(num) {
|
|
2799
|
+
if (!isObj(num))
|
|
2800
|
+
throw new TypeError("invalid field element: expected object, got " + typeof num);
|
|
2801
|
+
const { c0, c1, c2 } = num;
|
|
2802
|
+
const { Fp2: Fp22 } = this;
|
|
2803
|
+
return Fp22.isValid(c0) && Fp22.isValid(c1) && Fp22.isValid(c2);
|
|
2804
|
+
}
|
|
2805
|
+
is0(num) {
|
|
2806
|
+
if (!isObj(num))
|
|
2807
|
+
return false;
|
|
2808
|
+
const { c0, c1, c2 } = num;
|
|
2809
|
+
const { Fp2: Fp22 } = this;
|
|
2810
|
+
return Fp22.is0(c0) && Fp22.is0(c1) && Fp22.is0(c2);
|
|
2811
|
+
}
|
|
2812
|
+
isValidNot0(num) {
|
|
2813
|
+
return !this.is0(num) && this.isValid(num);
|
|
2814
|
+
}
|
|
2815
|
+
neg({ c0, c1, c2 }) {
|
|
2816
|
+
const { Fp2: Fp22 } = this;
|
|
2817
|
+
return Object.freeze({ c0: Fp22.neg(c0), c1: Fp22.neg(c1), c2: Fp22.neg(c2) });
|
|
2818
|
+
}
|
|
2819
|
+
eql({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) {
|
|
2820
|
+
const { Fp2: Fp22 } = this;
|
|
2821
|
+
return Fp22.eql(c0, r0) && Fp22.eql(c1, r1) && Fp22.eql(c2, r2);
|
|
2822
|
+
}
|
|
2823
|
+
sqrt(_) {
|
|
2824
|
+
return notImplemented();
|
|
2825
|
+
}
|
|
2826
|
+
// Do we need division by bigint at all? Should be done via order:
|
|
2827
|
+
div(lhs, rhs) {
|
|
2828
|
+
const { Fp2: Fp22 } = this;
|
|
2829
|
+
const { Fp: Fp3 } = Fp22;
|
|
2830
|
+
return this.mul(lhs, typeof rhs === "bigint" ? Fp3.inv(Fp3.create(rhs)) : this.inv(rhs));
|
|
2831
|
+
}
|
|
2832
|
+
pow(num, power) {
|
|
2833
|
+
return FpPow(this, num, power);
|
|
2834
|
+
}
|
|
2835
|
+
invertBatch(nums) {
|
|
2836
|
+
return FpInvertBatch(this, nums);
|
|
2837
|
+
}
|
|
2838
|
+
inv({ c0, c1, c2 }) {
|
|
2839
|
+
const { Fp2: Fp22 } = this;
|
|
2840
|
+
let t0 = Fp22.sub(Fp22.sqr(c0), Fp22.mulByNonresidue(Fp22.mul(c2, c1)));
|
|
2841
|
+
let t1 = Fp22.sub(Fp22.mulByNonresidue(Fp22.sqr(c2)), Fp22.mul(c0, c1));
|
|
2842
|
+
let t2 = Fp22.sub(Fp22.sqr(c1), Fp22.mul(c0, c2));
|
|
2843
|
+
let t4 = Fp22.inv(Fp22.add(Fp22.mulByNonresidue(Fp22.add(Fp22.mul(c2, t1), Fp22.mul(c1, t2))), Fp22.mul(c0, t0)));
|
|
2844
|
+
return Object.freeze({ c0: Fp22.mul(t4, t0), c1: Fp22.mul(t4, t1), c2: Fp22.mul(t4, t2) });
|
|
2845
|
+
}
|
|
2846
|
+
// Bytes utils
|
|
2847
|
+
fromBytes(b) {
|
|
2848
|
+
const { Fp2: Fp22 } = this;
|
|
2849
|
+
abytes2(b);
|
|
2850
|
+
if (b.length !== this.BYTES)
|
|
2851
|
+
throw new Error("fromBytes invalid length=" + b.length);
|
|
2852
|
+
const B2 = Fp22.BYTES;
|
|
2853
|
+
return this.create({
|
|
2854
|
+
c0: Fp22.fromBytes(b.subarray(0, B2)),
|
|
2855
|
+
c1: Fp22.fromBytes(b.subarray(B2, B2 * 2)),
|
|
2856
|
+
c2: Fp22.fromBytes(b.subarray(2 * B2))
|
|
2857
|
+
});
|
|
2858
|
+
}
|
|
2859
|
+
toBytes({ c0, c1, c2 }) {
|
|
2860
|
+
const { Fp2: Fp22 } = this;
|
|
2861
|
+
return concatBytes2(Fp22.toBytes(c0), Fp22.toBytes(c1), Fp22.toBytes(c2));
|
|
2862
|
+
}
|
|
2863
|
+
cmov({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }, c) {
|
|
2864
|
+
const { Fp2: Fp22 } = this;
|
|
2865
|
+
return this.create({
|
|
2866
|
+
c0: Fp22.cmov(c0, r0, c),
|
|
2867
|
+
c1: Fp22.cmov(c1, r1, c),
|
|
2868
|
+
c2: Fp22.cmov(c2, r2, c)
|
|
2869
|
+
});
|
|
2870
|
+
}
|
|
2871
|
+
fromBigSix(tuple) {
|
|
2872
|
+
const { Fp2: Fp22 } = this;
|
|
2873
|
+
if (!Array.isArray(tuple) || tuple.length !== 6)
|
|
2874
|
+
throw new Error("invalid Fp6.fromBigSix");
|
|
2875
|
+
for (let i = 0; i < 6; i++)
|
|
2876
|
+
if (typeof tuple[i] !== "bigint")
|
|
2877
|
+
throw new Error("invalid Fp6.fromBigSix");
|
|
2878
|
+
const t = tuple;
|
|
2879
|
+
return this.create({
|
|
2880
|
+
c0: Fp22.fromBigTuple(t.slice(0, 2)),
|
|
2881
|
+
c1: Fp22.fromBigTuple(t.slice(2, 4)),
|
|
2882
|
+
c2: Fp22.fromBigTuple(t.slice(4, 6))
|
|
2883
|
+
});
|
|
2884
|
+
}
|
|
2885
|
+
frobeniusMap({ c0, c1, c2 }, power) {
|
|
2886
|
+
const { Fp2: Fp22 } = this;
|
|
2887
|
+
return Object.freeze({
|
|
2888
|
+
c0: Fp22.frobeniusMap(c0, power),
|
|
2889
|
+
c1: Fp22.mul(Fp22.frobeniusMap(c1, power), this.FROBENIUS_COEFFICIENTS_1[power % 6]),
|
|
2890
|
+
c2: Fp22.mul(Fp22.frobeniusMap(c2, power), this.FROBENIUS_COEFFICIENTS_2[power % 6])
|
|
2891
|
+
});
|
|
2892
|
+
}
|
|
2893
|
+
mulByFp2({ c0, c1, c2 }, rhs) {
|
|
2894
|
+
const { Fp2: Fp22 } = this;
|
|
2895
|
+
return Object.freeze({
|
|
2896
|
+
c0: Fp22.mul(c0, rhs),
|
|
2897
|
+
c1: Fp22.mul(c1, rhs),
|
|
2898
|
+
c2: Fp22.mul(c2, rhs)
|
|
2899
|
+
});
|
|
2900
|
+
}
|
|
2901
|
+
mulByNonresidue({ c0, c1, c2 }) {
|
|
2902
|
+
const { Fp2: Fp22 } = this;
|
|
2903
|
+
return Object.freeze({ c0: Fp22.mulByNonresidue(c2), c1: c0, c2: c1 });
|
|
2904
|
+
}
|
|
2905
|
+
// Sparse multiplication
|
|
2906
|
+
mul1({ c0, c1, c2 }, b1) {
|
|
2907
|
+
const { Fp2: Fp22 } = this;
|
|
2908
|
+
return Object.freeze({
|
|
2909
|
+
c0: Fp22.mulByNonresidue(Fp22.mul(c2, b1)),
|
|
2910
|
+
c1: Fp22.mul(c0, b1),
|
|
2911
|
+
c2: Fp22.mul(c1, b1)
|
|
2912
|
+
});
|
|
2913
|
+
}
|
|
2914
|
+
// Sparse multiplication
|
|
2915
|
+
mul01({ c0, c1, c2 }, b0, b1) {
|
|
2916
|
+
const { Fp2: Fp22 } = this;
|
|
2917
|
+
let t0 = Fp22.mul(c0, b0);
|
|
2918
|
+
let t1 = Fp22.mul(c1, b1);
|
|
2919
|
+
return Object.freeze({
|
|
2920
|
+
// ((c1 + c2) * b1 - T1) * (u + 1) + T0
|
|
2921
|
+
c0: Fp22.add(Fp22.mulByNonresidue(Fp22.sub(Fp22.mul(Fp22.add(c1, c2), b1), t1)), t0),
|
|
2922
|
+
// (b0 + b1) * (c0 + c1) - T0 - T1
|
|
2923
|
+
c1: Fp22.sub(Fp22.sub(Fp22.mul(Fp22.add(b0, b1), Fp22.add(c0, c1)), t0), t1),
|
|
2924
|
+
// (c0 + c2) * b0 - T0 + T1
|
|
2925
|
+
c2: Fp22.add(Fp22.sub(Fp22.mul(Fp22.add(c0, c2), b0), t0), t1)
|
|
2926
|
+
});
|
|
2927
|
+
}
|
|
2928
|
+
};
|
|
2929
|
+
var _FROBENIUS_COEFFICIENTS_6 = /* @__PURE__ */ new WeakMap();
|
|
2930
|
+
var _Field12 = class {
|
|
2931
|
+
constructor(Fp62, opts) {
|
|
2932
|
+
__publicField(this, "ORDER");
|
|
2933
|
+
__publicField(this, "BITS");
|
|
2934
|
+
__publicField(this, "BYTES");
|
|
2935
|
+
__publicField(this, "isLE");
|
|
2936
|
+
__publicField(this, "ZERO");
|
|
2937
|
+
__publicField(this, "ONE");
|
|
2938
|
+
__publicField(this, "Fp6");
|
|
2939
|
+
__publicField(this, "X_LEN");
|
|
2940
|
+
__publicField(this, "finalExponentiate");
|
|
2941
|
+
const { X_LEN, Fp12finalExponentiate } = opts;
|
|
2942
|
+
const { Fp2: Fp22 } = Fp62;
|
|
2943
|
+
const { Fp: Fp3 } = Fp22;
|
|
2944
|
+
this.Fp6 = Fp62;
|
|
2945
|
+
this.ORDER = Fp3.ORDER ** _12n;
|
|
2946
|
+
this.BITS = 2 * Fp62.BITS;
|
|
2947
|
+
this.BYTES = 2 * Fp62.BYTES;
|
|
2948
|
+
this.isLE = Fp62.isLE;
|
|
2949
|
+
this.ZERO = this.create({ c0: Fp62.ZERO, c1: Fp62.ZERO });
|
|
2950
|
+
this.ONE = this.create({ c0: Fp62.ONE, c1: Fp62.ZERO });
|
|
2951
|
+
this.X_LEN = X_LEN;
|
|
2952
|
+
this.finalExponentiate = (num) => {
|
|
2953
|
+
const copy2 = ({ c0, c1 }) => Object.freeze({ c0, c1 });
|
|
2954
|
+
const copy6 = ({ c0, c1, c2 }) => Object.freeze({ c0: copy2(c0), c1: copy2(c1), c2: copy2(c2) });
|
|
2955
|
+
const res = Fp12finalExponentiate(num);
|
|
2956
|
+
return Object.freeze({ c0: copy6(res.c0), c1: copy6(res.c1) });
|
|
2957
|
+
};
|
|
2958
|
+
Object.freeze(this);
|
|
2959
|
+
}
|
|
2960
|
+
// Keep the degree-12 Frobenius row lazy too; after the first lookup the cached
|
|
2961
|
+
// array is reused exactly like the old eager table.
|
|
2962
|
+
get FROBENIUS_COEFFICIENTS() {
|
|
2963
|
+
const frob2 = _FROBENIUS_COEFFICIENTS_12.get(this);
|
|
2964
|
+
if (frob2)
|
|
2965
|
+
return frob2;
|
|
2966
|
+
const { Fp2: Fp22 } = this.Fp6;
|
|
2967
|
+
const { Fp: Fp3 } = Fp22;
|
|
2968
|
+
const cache = Object.freeze(calcFrobeniusCoefficients(Fp22, Fp22.NONRESIDUE, Fp3.ORDER, 12, 1, 6)[0]);
|
|
2969
|
+
_FROBENIUS_COEFFICIENTS_12.set(this, cache);
|
|
2970
|
+
return cache;
|
|
2971
|
+
}
|
|
2972
|
+
create(num) {
|
|
2973
|
+
const { Fp6: Fp62 } = this;
|
|
2974
|
+
const c0 = Fp62.create(num.c0);
|
|
2975
|
+
const c1 = Fp62.create(num.c1);
|
|
2976
|
+
return Object.freeze({ c0, c1 });
|
|
2977
|
+
}
|
|
2978
|
+
isValid(num) {
|
|
2979
|
+
if (!isObj(num))
|
|
2980
|
+
throw new TypeError("invalid field element: expected object, got " + typeof num);
|
|
2981
|
+
const { c0, c1 } = num;
|
|
2982
|
+
const { Fp6: Fp62 } = this;
|
|
2983
|
+
return Fp62.isValid(c0) && Fp62.isValid(c1);
|
|
2984
|
+
}
|
|
2985
|
+
is0(num) {
|
|
2986
|
+
if (!isObj(num))
|
|
2987
|
+
return false;
|
|
2988
|
+
const { c0, c1 } = num;
|
|
2989
|
+
const { Fp6: Fp62 } = this;
|
|
2990
|
+
return Fp62.is0(c0) && Fp62.is0(c1);
|
|
2991
|
+
}
|
|
2992
|
+
isValidNot0(num) {
|
|
2993
|
+
return !this.is0(num) && this.isValid(num);
|
|
2994
|
+
}
|
|
2995
|
+
neg({ c0, c1 }) {
|
|
2996
|
+
const { Fp6: Fp62 } = this;
|
|
2997
|
+
return Object.freeze({ c0: Fp62.neg(c0), c1: Fp62.neg(c1) });
|
|
2998
|
+
}
|
|
2999
|
+
eql({ c0, c1 }, { c0: r0, c1: r1 }) {
|
|
3000
|
+
const { Fp6: Fp62 } = this;
|
|
3001
|
+
return Fp62.eql(c0, r0) && Fp62.eql(c1, r1);
|
|
3002
|
+
}
|
|
3003
|
+
sqrt(_) {
|
|
3004
|
+
return notImplemented();
|
|
3005
|
+
}
|
|
3006
|
+
inv({ c0, c1 }) {
|
|
3007
|
+
const { Fp6: Fp62 } = this;
|
|
3008
|
+
let t = Fp62.inv(Fp62.sub(Fp62.sqr(c0), Fp62.mulByNonresidue(Fp62.sqr(c1))));
|
|
3009
|
+
return Object.freeze({ c0: Fp62.mul(c0, t), c1: Fp62.neg(Fp62.mul(c1, t)) });
|
|
3010
|
+
}
|
|
3011
|
+
div(lhs, rhs) {
|
|
3012
|
+
const { Fp6: Fp62 } = this;
|
|
3013
|
+
const { Fp2: Fp22 } = Fp62;
|
|
3014
|
+
const { Fp: Fp3 } = Fp22;
|
|
3015
|
+
return this.mul(lhs, typeof rhs === "bigint" ? Fp3.inv(Fp3.create(rhs)) : this.inv(rhs));
|
|
3016
|
+
}
|
|
3017
|
+
pow(num, power) {
|
|
3018
|
+
return FpPow(this, num, power);
|
|
3019
|
+
}
|
|
3020
|
+
invertBatch(nums) {
|
|
3021
|
+
return FpInvertBatch(this, nums);
|
|
3022
|
+
}
|
|
3023
|
+
// Normalized
|
|
3024
|
+
add({ c0, c1 }, { c0: r0, c1: r1 }) {
|
|
3025
|
+
const { Fp6: Fp62 } = this;
|
|
3026
|
+
return Object.freeze({
|
|
3027
|
+
c0: Fp62.add(c0, r0),
|
|
3028
|
+
c1: Fp62.add(c1, r1)
|
|
3029
|
+
});
|
|
3030
|
+
}
|
|
3031
|
+
sub({ c0, c1 }, { c0: r0, c1: r1 }) {
|
|
3032
|
+
const { Fp6: Fp62 } = this;
|
|
3033
|
+
return Object.freeze({
|
|
3034
|
+
c0: Fp62.sub(c0, r0),
|
|
3035
|
+
c1: Fp62.sub(c1, r1)
|
|
3036
|
+
});
|
|
3037
|
+
}
|
|
3038
|
+
mul({ c0, c1 }, rhs) {
|
|
3039
|
+
const { Fp6: Fp62 } = this;
|
|
3040
|
+
if (typeof rhs === "bigint")
|
|
3041
|
+
return Object.freeze({ c0: Fp62.mul(c0, rhs), c1: Fp62.mul(c1, rhs) });
|
|
3042
|
+
let { c0: r0, c1: r1 } = rhs;
|
|
3043
|
+
let t1 = Fp62.mul(c0, r0);
|
|
3044
|
+
let t2 = Fp62.mul(c1, r1);
|
|
3045
|
+
return Object.freeze({
|
|
3046
|
+
c0: Fp62.add(t1, Fp62.mulByNonresidue(t2)),
|
|
3047
|
+
// T1 + T2 * v
|
|
3048
|
+
// (c0 + c1) * (r0 + r1) - (T1 + T2)
|
|
3049
|
+
c1: Fp62.sub(Fp62.mul(Fp62.add(c0, c1), Fp62.add(r0, r1)), Fp62.add(t1, t2))
|
|
3050
|
+
});
|
|
3051
|
+
}
|
|
3052
|
+
sqr({ c0, c1 }) {
|
|
3053
|
+
const { Fp6: Fp62 } = this;
|
|
3054
|
+
let ab = Fp62.mul(c0, c1);
|
|
3055
|
+
return Object.freeze({
|
|
3056
|
+
// (c1 * v + c0) * (c0 + c1) - AB - AB * v
|
|
3057
|
+
c0: Fp62.sub(Fp62.sub(Fp62.mul(Fp62.add(Fp62.mulByNonresidue(c1), c0), Fp62.add(c0, c1)), ab), Fp62.mulByNonresidue(ab)),
|
|
3058
|
+
c1: Fp62.add(ab, ab)
|
|
3059
|
+
});
|
|
3060
|
+
}
|
|
3061
|
+
// NonNormalized stuff
|
|
3062
|
+
addN(a, b) {
|
|
3063
|
+
return this.add(a, b);
|
|
3064
|
+
}
|
|
3065
|
+
subN(a, b) {
|
|
3066
|
+
return this.sub(a, b);
|
|
3067
|
+
}
|
|
3068
|
+
mulN(a, b) {
|
|
3069
|
+
return this.mul(a, b);
|
|
3070
|
+
}
|
|
3071
|
+
sqrN(a) {
|
|
3072
|
+
return this.sqr(a);
|
|
3073
|
+
}
|
|
3074
|
+
// Bytes utils
|
|
3075
|
+
fromBytes(b) {
|
|
3076
|
+
const { Fp6: Fp62 } = this;
|
|
3077
|
+
abytes2(b);
|
|
3078
|
+
if (b.length !== this.BYTES)
|
|
3079
|
+
throw new Error("fromBytes invalid length=" + b.length);
|
|
3080
|
+
return this.create({
|
|
3081
|
+
c0: Fp62.fromBytes(b.subarray(0, Fp62.BYTES)),
|
|
3082
|
+
c1: Fp62.fromBytes(b.subarray(Fp62.BYTES))
|
|
3083
|
+
});
|
|
3084
|
+
}
|
|
3085
|
+
toBytes({ c0, c1 }) {
|
|
3086
|
+
const { Fp6: Fp62 } = this;
|
|
3087
|
+
return concatBytes2(Fp62.toBytes(c0), Fp62.toBytes(c1));
|
|
3088
|
+
}
|
|
3089
|
+
cmov({ c0, c1 }, { c0: r0, c1: r1 }, c) {
|
|
3090
|
+
const { Fp6: Fp62 } = this;
|
|
3091
|
+
return this.create({
|
|
3092
|
+
c0: Fp62.cmov(c0, r0, c),
|
|
3093
|
+
c1: Fp62.cmov(c1, r1, c)
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
3096
|
+
// Utils
|
|
3097
|
+
// toString() {
|
|
3098
|
+
// return '' + 'Fp12(' + this.c0 + this.c1 + '* w');
|
|
3099
|
+
// },
|
|
3100
|
+
// fromTuple(c: [Fp6, Fp6]) {
|
|
3101
|
+
// return new Fp12(...c);
|
|
3102
|
+
// }
|
|
3103
|
+
fromBigTwelve(tuple) {
|
|
3104
|
+
const { Fp6: Fp62 } = this;
|
|
3105
|
+
if (!Array.isArray(tuple) || tuple.length !== 12)
|
|
3106
|
+
throw new Error("invalid Fp12.fromBigTwelve");
|
|
3107
|
+
for (let i = 0; i < 12; i++)
|
|
3108
|
+
if (typeof tuple[i] !== "bigint")
|
|
3109
|
+
throw new Error("invalid Fp12.fromBigTwelve");
|
|
3110
|
+
const t = tuple;
|
|
3111
|
+
return this.create({
|
|
3112
|
+
c0: Fp62.fromBigSix(t.slice(0, 6)),
|
|
3113
|
+
c1: Fp62.fromBigSix(t.slice(6, 12))
|
|
3114
|
+
});
|
|
3115
|
+
}
|
|
3116
|
+
// Raises to q**i -th power
|
|
3117
|
+
frobeniusMap(lhs, power) {
|
|
3118
|
+
const { Fp6: Fp62 } = this;
|
|
3119
|
+
const { Fp2: Fp22 } = Fp62;
|
|
3120
|
+
const { c0, c1, c2 } = Fp62.frobeniusMap(lhs.c1, power);
|
|
3121
|
+
const coeff = this.FROBENIUS_COEFFICIENTS[power % 12];
|
|
3122
|
+
return Object.freeze({
|
|
3123
|
+
c0: Fp62.frobeniusMap(lhs.c0, power),
|
|
3124
|
+
c1: Object.freeze({
|
|
3125
|
+
c0: Fp22.mul(c0, coeff),
|
|
3126
|
+
c1: Fp22.mul(c1, coeff),
|
|
3127
|
+
c2: Fp22.mul(c2, coeff)
|
|
3128
|
+
})
|
|
3129
|
+
});
|
|
3130
|
+
}
|
|
3131
|
+
mulByFp2({ c0, c1 }, rhs) {
|
|
3132
|
+
const { Fp6: Fp62 } = this;
|
|
3133
|
+
return Object.freeze({
|
|
3134
|
+
c0: Fp62.mulByFp2(c0, rhs),
|
|
3135
|
+
c1: Fp62.mulByFp2(c1, rhs)
|
|
3136
|
+
});
|
|
3137
|
+
}
|
|
3138
|
+
conjugate({ c0, c1 }) {
|
|
3139
|
+
return Object.freeze({ c0, c1: this.Fp6.neg(c1) });
|
|
3140
|
+
}
|
|
3141
|
+
// Sparse multiplication
|
|
3142
|
+
mul014({ c0, c1 }, o0, o1, o4) {
|
|
3143
|
+
const { Fp6: Fp62 } = this;
|
|
3144
|
+
const { Fp2: Fp22 } = Fp62;
|
|
3145
|
+
let t0 = Fp62.mul01(c0, o0, o1);
|
|
3146
|
+
let t1 = Fp62.mul1(c1, o4);
|
|
3147
|
+
return Object.freeze({
|
|
3148
|
+
c0: Fp62.add(Fp62.mulByNonresidue(t1), t0),
|
|
3149
|
+
// T1 * v + T0
|
|
3150
|
+
// (c1 + c0) * [o0, o1+o4] - T0 - T1
|
|
3151
|
+
c1: Fp62.sub(Fp62.sub(Fp62.mul01(Fp62.add(c1, c0), o0, Fp22.add(o1, o4)), t0), t1)
|
|
3152
|
+
});
|
|
3153
|
+
}
|
|
3154
|
+
mul034({ c0, c1 }, o0, o3, o4) {
|
|
3155
|
+
const { Fp6: Fp62 } = this;
|
|
3156
|
+
const { Fp2: Fp22 } = Fp62;
|
|
3157
|
+
const a = Object.freeze({
|
|
3158
|
+
c0: Fp22.mul(c0.c0, o0),
|
|
3159
|
+
c1: Fp22.mul(c0.c1, o0),
|
|
3160
|
+
c2: Fp22.mul(c0.c2, o0)
|
|
3161
|
+
});
|
|
3162
|
+
const b = Fp62.mul01(c1, o3, o4);
|
|
3163
|
+
const e = Fp62.mul01(Fp62.add(c0, c1), Fp22.add(o0, o3), o4);
|
|
3164
|
+
return Object.freeze({
|
|
3165
|
+
c0: Fp62.add(Fp62.mulByNonresidue(b), a),
|
|
3166
|
+
c1: Fp62.sub(e, Fp62.add(a, b))
|
|
3167
|
+
});
|
|
3168
|
+
}
|
|
3169
|
+
// A cyclotomic group is a subgroup of Fp^n defined by
|
|
3170
|
+
// GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
|
|
3171
|
+
// The result of any pairing is in a cyclotomic subgroup
|
|
3172
|
+
// https://eprint.iacr.org/2009/565.pdf
|
|
3173
|
+
// https://eprint.iacr.org/2010/354.pdf
|
|
3174
|
+
_cyclotomicSquare({ c0, c1 }) {
|
|
3175
|
+
const { Fp6: Fp62 } = this;
|
|
3176
|
+
const { Fp2: Fp22 } = Fp62;
|
|
3177
|
+
const { c0: c0c0, c1: c0c1, c2: c0c2 } = c0;
|
|
3178
|
+
const { c0: c1c0, c1: c1c1, c2: c1c2 } = c1;
|
|
3179
|
+
const { first: t3, second: t4 } = Fp22.Fp4Square(c0c0, c1c1);
|
|
3180
|
+
const { first: t5, second: t6 } = Fp22.Fp4Square(c1c0, c0c2);
|
|
3181
|
+
const { first: t7, second: t8 } = Fp22.Fp4Square(c0c1, c1c2);
|
|
3182
|
+
const t9 = Fp22.mulByNonresidue(t8);
|
|
3183
|
+
return Object.freeze({
|
|
3184
|
+
c0: Object.freeze({
|
|
3185
|
+
c0: Fp22.add(Fp22.mul(Fp22.sub(t3, c0c0), _2n4), t3),
|
|
3186
|
+
// 2 * (T3 - c0c0) + T3
|
|
3187
|
+
c1: Fp22.add(Fp22.mul(Fp22.sub(t5, c0c1), _2n4), t5),
|
|
3188
|
+
// 2 * (T5 - c0c1) + T5
|
|
3189
|
+
c2: Fp22.add(Fp22.mul(Fp22.sub(t7, c0c2), _2n4), t7)
|
|
3190
|
+
}),
|
|
3191
|
+
// 2 * (T7 - c0c2) + T7
|
|
3192
|
+
c1: Object.freeze({
|
|
3193
|
+
c0: Fp22.add(Fp22.mul(Fp22.add(t9, c1c0), _2n4), t9),
|
|
3194
|
+
// 2 * (T9 + c1c0) + T9
|
|
3195
|
+
c1: Fp22.add(Fp22.mul(Fp22.add(t4, c1c1), _2n4), t4),
|
|
3196
|
+
// 2 * (T4 + c1c1) + T4
|
|
3197
|
+
c2: Fp22.add(Fp22.mul(Fp22.add(t6, c1c2), _2n4), t6)
|
|
3198
|
+
})
|
|
3199
|
+
});
|
|
3200
|
+
}
|
|
3201
|
+
// https://eprint.iacr.org/2009/565.pdf
|
|
3202
|
+
_cyclotomicExp(num, n) {
|
|
3203
|
+
aInRange("cyclotomic exponent", n, _0n6, _1n6 << BigInt(this.X_LEN));
|
|
3204
|
+
let z = this.ONE;
|
|
3205
|
+
for (let i = this.X_LEN - 1; i >= 0; i--) {
|
|
3206
|
+
z = this._cyclotomicSquare(z);
|
|
3207
|
+
if (bitGet(n, i))
|
|
3208
|
+
z = this.mul(z, num);
|
|
3209
|
+
}
|
|
3210
|
+
return z;
|
|
3211
|
+
}
|
|
3212
|
+
};
|
|
3213
|
+
var _FROBENIUS_COEFFICIENTS_12 = /* @__PURE__ */ new WeakMap();
|
|
3214
|
+
function tower12(opts) {
|
|
3215
|
+
validateObject(opts, {
|
|
3216
|
+
ORDER: "bigint",
|
|
3217
|
+
X_LEN: "number",
|
|
3218
|
+
FP2_NONRESIDUE: "object",
|
|
3219
|
+
Fp2mulByB: "function",
|
|
3220
|
+
Fp12finalExponentiate: "function"
|
|
3221
|
+
}, { NONRESIDUE: "bigint" });
|
|
3222
|
+
asafenumber(opts.X_LEN, "X_LEN");
|
|
3223
|
+
if (opts.X_LEN < 1)
|
|
3224
|
+
throw new Error("invalid X_LEN");
|
|
3225
|
+
const nonresidue = opts.FP2_NONRESIDUE;
|
|
3226
|
+
if (!Array.isArray(nonresidue) || nonresidue.length !== 2)
|
|
3227
|
+
throw new Error("invalid FP2_NONRESIDUE");
|
|
3228
|
+
if (typeof nonresidue[0] !== "bigint" || typeof nonresidue[1] !== "bigint")
|
|
3229
|
+
throw new Error("invalid FP2_NONRESIDUE");
|
|
3230
|
+
const Fp3 = Field(opts.ORDER);
|
|
3231
|
+
const Fp22 = new _Field2(Fp3, opts);
|
|
3232
|
+
const Fp62 = new _Field6(Fp22);
|
|
3233
|
+
const Fp122 = new _Field12(Fp62, opts);
|
|
3234
|
+
return { Fp: Fp3, Fp2: Fp22, Fp6: Fp62, Fp12: Fp122 };
|
|
3235
|
+
}
|
|
3236
|
+
|
|
3237
|
+
// node_modules/@noble/curves/bls12-381.js
|
|
3238
|
+
var _0n7 = BigInt(0);
|
|
3239
|
+
var _1n7 = BigInt(1);
|
|
3240
|
+
var _2n5 = BigInt(2);
|
|
3241
|
+
var _3n5 = BigInt(3);
|
|
3242
|
+
var _4n3 = BigInt(4);
|
|
3243
|
+
var BLS_X = BigInt("0xd201000000010000");
|
|
3244
|
+
var BLS_X_LEN = bitLen(BLS_X);
|
|
3245
|
+
var bls12_381_CURVE_G1 = {
|
|
3246
|
+
p: BigInt("0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"),
|
|
3247
|
+
n: BigInt("0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001"),
|
|
3248
|
+
h: BigInt("0x396c8c005555e1568c00aaab0000aaab"),
|
|
3249
|
+
a: _0n7,
|
|
3250
|
+
b: _4n3,
|
|
3251
|
+
Gx: BigInt("0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"),
|
|
3252
|
+
Gy: BigInt("0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1")
|
|
3253
|
+
};
|
|
3254
|
+
var bls12_381_Fr = Field(bls12_381_CURVE_G1.n, {
|
|
3255
|
+
modFromBytes: true
|
|
3256
|
+
});
|
|
3257
|
+
var { Fp, Fp2, Fp6, Fp12 } = tower12({
|
|
3258
|
+
ORDER: bls12_381_CURVE_G1.p,
|
|
3259
|
+
X_LEN: BLS_X_LEN,
|
|
3260
|
+
// Finite extension field over irreducible polynominal.
|
|
3261
|
+
// Fp(u) / (u² - β) where β = -1
|
|
3262
|
+
// Public `Fp2.NONRESIDUE` below is the sextic-tower value `(1, 1) = u + 1`;
|
|
3263
|
+
// the quadratic non-residue for the base Fp2 construction is still `-1`.
|
|
3264
|
+
FP2_NONRESIDUE: [_1n7, _1n7],
|
|
3265
|
+
Fp2mulByB: ({ c0, c1 }) => {
|
|
3266
|
+
const t0 = Fp.mul(c0, _4n3);
|
|
3267
|
+
const t1 = Fp.mul(c1, _4n3);
|
|
3268
|
+
return { c0: Fp.sub(t0, t1), c1: Fp.add(t0, t1) };
|
|
3269
|
+
},
|
|
3270
|
+
Fp12finalExponentiate: (num) => {
|
|
3271
|
+
const x = BLS_X;
|
|
3272
|
+
const t0 = Fp12.div(Fp12.frobeniusMap(num, 6), num);
|
|
3273
|
+
const t1 = Fp12.mul(Fp12.frobeniusMap(t0, 2), t0);
|
|
3274
|
+
const t2 = Fp12.conjugate(Fp12._cyclotomicExp(t1, x));
|
|
3275
|
+
const t3 = Fp12.mul(Fp12.conjugate(Fp12._cyclotomicSquare(t1)), t2);
|
|
3276
|
+
const t4 = Fp12.conjugate(Fp12._cyclotomicExp(t3, x));
|
|
3277
|
+
const t5 = Fp12.conjugate(Fp12._cyclotomicExp(t4, x));
|
|
3278
|
+
const t6 = Fp12.mul(Fp12.conjugate(Fp12._cyclotomicExp(t5, x)), Fp12._cyclotomicSquare(t2));
|
|
3279
|
+
const t7 = Fp12.conjugate(Fp12._cyclotomicExp(t6, x));
|
|
3280
|
+
const t2_t5_pow_q2 = Fp12.frobeniusMap(Fp12.mul(t2, t5), 2);
|
|
3281
|
+
const t4_t1_pow_q3 = Fp12.frobeniusMap(Fp12.mul(t4, t1), 3);
|
|
3282
|
+
const t6_t1c_pow_q1 = Fp12.frobeniusMap(Fp12.mul(t6, Fp12.conjugate(t1)), 1);
|
|
3283
|
+
const t7_t3c_t1 = Fp12.mul(Fp12.mul(t7, Fp12.conjugate(t3)), t1);
|
|
3284
|
+
return Fp12.mul(Fp12.mul(Fp12.mul(t2_t5_pow_q2, t4_t1_pow_q3), t6_t1c_pow_q1), t7_t3c_t1);
|
|
3285
|
+
}
|
|
3286
|
+
});
|
|
3287
|
+
var frob;
|
|
3288
|
+
var getFrob = () => frob || (frob = psiFrobenius(Fp, Fp2, Fp2.div(Fp2.ONE, Fp2.NONRESIDUE)));
|
|
3289
|
+
var G2psi = (c, P) => {
|
|
3290
|
+
const fn = getFrob().G2psi;
|
|
3291
|
+
G2psi = fn;
|
|
3292
|
+
return fn(c, P);
|
|
3293
|
+
};
|
|
3294
|
+
var G2psi2 = (c, P) => {
|
|
3295
|
+
const fn = getFrob().G2psi2;
|
|
3296
|
+
G2psi2 = fn;
|
|
3297
|
+
return fn(c, P);
|
|
3298
|
+
};
|
|
3299
|
+
var hasher_opts = Object.freeze({
|
|
3300
|
+
DST: "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_",
|
|
3301
|
+
encodeDST: "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_",
|
|
3302
|
+
p: Fp.ORDER,
|
|
3303
|
+
m: 2,
|
|
3304
|
+
k: 128,
|
|
3305
|
+
expand: "xmd",
|
|
3306
|
+
hash: sha256
|
|
3307
|
+
});
|
|
3308
|
+
var bls12_381_CURVE_G2 = {
|
|
3309
|
+
p: Fp2.ORDER,
|
|
3310
|
+
n: bls12_381_CURVE_G1.n,
|
|
3311
|
+
h: BigInt("0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5"),
|
|
3312
|
+
a: Fp2.ZERO,
|
|
3313
|
+
b: Fp2.fromBigTuple([_4n3, _4n3]),
|
|
3314
|
+
Gx: Fp2.fromBigTuple([
|
|
3315
|
+
BigInt("0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"),
|
|
3316
|
+
BigInt("0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e")
|
|
3317
|
+
]),
|
|
3318
|
+
Gy: Fp2.fromBigTuple([
|
|
3319
|
+
BigInt("0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801"),
|
|
3320
|
+
BigInt("0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be")
|
|
3321
|
+
])
|
|
3322
|
+
};
|
|
3323
|
+
var sortBit = (parts, p) => {
|
|
3324
|
+
for (const part of parts) {
|
|
3325
|
+
if (part !== _0n7)
|
|
3326
|
+
return Boolean(part * _2n5 / p);
|
|
3327
|
+
}
|
|
3328
|
+
return false;
|
|
3329
|
+
};
|
|
3330
|
+
var fp2 = {
|
|
3331
|
+
// Generic tower bytes use `c0 || c1`, but the BLS12-381 G2 point/signature wire encoding uses
|
|
3332
|
+
// `c1 || c0`, so keep this local wrapper instead of changing generic field serialization.
|
|
3333
|
+
encode({ c0, c1 }) {
|
|
3334
|
+
const { BYTES: L } = Fp;
|
|
3335
|
+
return concatBytes2(numberToBytesBE(c1, L), numberToBytesBE(c0, L));
|
|
3336
|
+
},
|
|
3337
|
+
decode(bytes) {
|
|
3338
|
+
const { BYTES: L } = Fp;
|
|
3339
|
+
return Fp2.create({
|
|
3340
|
+
c0: Fp.create(bytesToNumberBE(bytes.subarray(L))),
|
|
3341
|
+
c1: Fp.create(bytesToNumberBE(bytes.subarray(0, L)))
|
|
3342
|
+
});
|
|
3343
|
+
}
|
|
3344
|
+
};
|
|
3345
|
+
var BaseFp = Fp;
|
|
3346
|
+
var coder = (name, Fp3, b, encode, decode, yparts) => {
|
|
3347
|
+
const F = Fp3;
|
|
3348
|
+
const enc = encode;
|
|
3349
|
+
const dec = decode;
|
|
3350
|
+
const W = F.BYTES;
|
|
3351
|
+
return (allowUncompressed) => ({
|
|
3352
|
+
encode(point, compressed = true) {
|
|
3353
|
+
if (!compressed && !allowUncompressed)
|
|
3354
|
+
throw new Error("invalid signature: expected compressed encoding");
|
|
3355
|
+
const infinity = point.is0();
|
|
3356
|
+
const { x, y } = point.toAffine();
|
|
3357
|
+
const bytes = compressed ? enc(x) : concatBytes2(enc(x), enc(y));
|
|
3358
|
+
let sort;
|
|
3359
|
+
if (compressed && !infinity)
|
|
3360
|
+
sort = sortBit(yparts(y), BaseFp.ORDER);
|
|
3361
|
+
return setMask(bytes, { compressed, infinity, sort });
|
|
3362
|
+
},
|
|
3363
|
+
decode(bytes) {
|
|
3364
|
+
const raw = allowUncompressed ? abytes2(bytes, void 0, "point") : abytes2(bytes, W, "signature");
|
|
3365
|
+
const { compressed, infinity, sort, value } = parseMask(raw);
|
|
3366
|
+
if (!allowUncompressed && !compressed)
|
|
3367
|
+
throw new Error("invalid signature: expected compressed encoding");
|
|
3368
|
+
const len = compressed ? W : 2 * W;
|
|
3369
|
+
if (value.length !== len)
|
|
3370
|
+
throw new Error(`invalid ${name} point: expected ${len} bytes`);
|
|
3371
|
+
if (infinity) {
|
|
3372
|
+
for (const b2 of value) {
|
|
3373
|
+
if (b2)
|
|
3374
|
+
throw new Error(`invalid ${name} point: non-canonical zero`);
|
|
3375
|
+
}
|
|
3376
|
+
return { x: F.ZERO, y: F.ZERO };
|
|
3377
|
+
}
|
|
3378
|
+
const x = dec(compressed ? value : value.subarray(0, W));
|
|
3379
|
+
let y;
|
|
3380
|
+
if (compressed) {
|
|
3381
|
+
y = F.sqrt(F.add(F.pow(x, _3n5), b));
|
|
3382
|
+
if (!y)
|
|
3383
|
+
throw new Error(`invalid ${name} point: compressed`);
|
|
3384
|
+
if (sortBit(yparts(y), BaseFp.ORDER) !== sort)
|
|
3385
|
+
y = F.neg(y);
|
|
3386
|
+
} else {
|
|
3387
|
+
y = dec(value.subarray(W));
|
|
3388
|
+
}
|
|
3389
|
+
if (!compressed && F.is0(x) && F.is0(y))
|
|
3390
|
+
throw new Error(`invalid ${name} point: uncompressed`);
|
|
3391
|
+
return { x, y };
|
|
3392
|
+
}
|
|
3393
|
+
});
|
|
3394
|
+
};
|
|
3395
|
+
function validateMask({ compressed, infinity, sort }) {
|
|
3396
|
+
if (!compressed && !infinity && sort || // 0010_0000 = 0x20
|
|
3397
|
+
!compressed && infinity && sort || // 0110_0000 = 0x60
|
|
3398
|
+
compressed && infinity && sort)
|
|
3399
|
+
throw new Error("invalid encoding flag");
|
|
3400
|
+
}
|
|
3401
|
+
function parseMask(bytes) {
|
|
3402
|
+
bytes = copyBytes(bytes);
|
|
3403
|
+
const mask = bytes[0] & 224;
|
|
3404
|
+
const compressed = !!(mask >> 7 & 1);
|
|
3405
|
+
const infinity = !!(mask >> 6 & 1);
|
|
3406
|
+
const sort = !!(mask >> 5 & 1);
|
|
3407
|
+
validateMask({ compressed, infinity, sort });
|
|
3408
|
+
bytes[0] &= 31;
|
|
3409
|
+
return { compressed, infinity, sort, value: bytes };
|
|
3410
|
+
}
|
|
3411
|
+
function setMask(bytes, mask) {
|
|
3412
|
+
if (bytes[0] & 224)
|
|
3413
|
+
throw new Error("setMask: non-empty mask");
|
|
3414
|
+
validateMask({ compressed: !!mask.compressed, infinity: !!mask.infinity, sort: !!mask.sort });
|
|
3415
|
+
if (mask.compressed)
|
|
3416
|
+
bytes[0] |= 128;
|
|
3417
|
+
if (mask.infinity)
|
|
3418
|
+
bytes[0] |= 64;
|
|
3419
|
+
if (mask.sort)
|
|
3420
|
+
bytes[0] |= 32;
|
|
3421
|
+
return bytes;
|
|
3422
|
+
}
|
|
3423
|
+
var g1coder = coder("G1", Fp, Fp.create(bls12_381_CURVE_G1.b), (x) => numberToBytesBE(x, Fp.BYTES), (bytes) => Fp.create(bytesToNumberBE(bytes) & bitMask(Fp.BITS)), (y) => [y]);
|
|
3424
|
+
var g1 = { point: g1coder(true), sig: g1coder(false) };
|
|
3425
|
+
var signatureG1ToBytes = (point) => {
|
|
3426
|
+
point.assertValidity();
|
|
3427
|
+
return g1.sig.encode(point);
|
|
3428
|
+
};
|
|
3429
|
+
function signatureG1FromBytes(bytes) {
|
|
3430
|
+
const Point = bls12_381.G1.Point;
|
|
3431
|
+
const point = Point.fromAffine(g1.sig.decode(bytes));
|
|
3432
|
+
point.assertValidity();
|
|
3433
|
+
return point;
|
|
3434
|
+
}
|
|
3435
|
+
var g2coder = coder("G2", Fp2, bls12_381_CURVE_G2.b, fp2.encode, fp2.decode, (y) => [
|
|
3436
|
+
y.c1,
|
|
3437
|
+
y.c0
|
|
3438
|
+
]);
|
|
3439
|
+
var g2 = { point: g2coder(true), sig: g2coder(false) };
|
|
3440
|
+
var signatureG2ToBytes = (point) => {
|
|
3441
|
+
point.assertValidity();
|
|
3442
|
+
return g2.sig.encode(point);
|
|
3443
|
+
};
|
|
3444
|
+
function signatureG2FromBytes(bytes) {
|
|
3445
|
+
const Point = bls12_381.G2.Point;
|
|
3446
|
+
const point = Point.fromAffine(g2.sig.decode(bytes));
|
|
3447
|
+
point.assertValidity();
|
|
3448
|
+
return point;
|
|
3449
|
+
}
|
|
3450
|
+
var signatureCoders = {
|
|
3451
|
+
ShortSignature: {
|
|
3452
|
+
fromBytes(bytes) {
|
|
3453
|
+
return signatureG1FromBytes(abytes2(bytes));
|
|
3454
|
+
},
|
|
3455
|
+
fromHex(hex) {
|
|
3456
|
+
return signatureG1FromBytes(hexToBytes2(hex));
|
|
3457
|
+
},
|
|
3458
|
+
toBytes(point) {
|
|
3459
|
+
return signatureG1ToBytes(point);
|
|
3460
|
+
},
|
|
3461
|
+
// Historical alias: BLS signatures have a single compressed byte format here.
|
|
3462
|
+
toRawBytes(point) {
|
|
3463
|
+
return signatureG1ToBytes(point);
|
|
3464
|
+
},
|
|
3465
|
+
toHex(point) {
|
|
3466
|
+
return bytesToHex2(signatureG1ToBytes(point));
|
|
3467
|
+
}
|
|
3468
|
+
},
|
|
3469
|
+
LongSignature: {
|
|
3470
|
+
fromBytes(bytes) {
|
|
3471
|
+
return signatureG2FromBytes(abytes2(bytes));
|
|
3472
|
+
},
|
|
3473
|
+
fromHex(hex) {
|
|
3474
|
+
return signatureG2FromBytes(hexToBytes2(hex));
|
|
3475
|
+
},
|
|
3476
|
+
toBytes(point) {
|
|
3477
|
+
return signatureG2ToBytes(point);
|
|
3478
|
+
},
|
|
3479
|
+
// Historical alias: BLS signatures have a single compressed byte format here.
|
|
3480
|
+
toRawBytes(point) {
|
|
3481
|
+
return signatureG2ToBytes(point);
|
|
3482
|
+
},
|
|
3483
|
+
toHex(point) {
|
|
3484
|
+
return bytesToHex2(signatureG2ToBytes(point));
|
|
3485
|
+
}
|
|
3486
|
+
}
|
|
3487
|
+
};
|
|
3488
|
+
var fields = {
|
|
3489
|
+
Fp,
|
|
3490
|
+
Fp2,
|
|
3491
|
+
Fp6,
|
|
3492
|
+
Fp12,
|
|
3493
|
+
Fr: bls12_381_Fr
|
|
3494
|
+
};
|
|
3495
|
+
var G1_Point = weierstrass(bls12_381_CURVE_G1, {
|
|
3496
|
+
// Public point APIs still accept infinity, even though the Zcash proof
|
|
3497
|
+
// encoding rules cited above only define nonzero point encodings.
|
|
3498
|
+
allowInfinityPoint: true,
|
|
3499
|
+
Fn: bls12_381_Fr,
|
|
3500
|
+
fromBytes: g1.point.decode,
|
|
3501
|
+
toBytes: (_c, point, isComp) => g1.point.encode(point, isComp),
|
|
3502
|
+
// Checks is the point resides in prime-order subgroup.
|
|
3503
|
+
// point.isTorsionFree() should return true for valid points
|
|
3504
|
+
// It returns false for shitty points.
|
|
3505
|
+
// https://eprint.iacr.org/2021/1130.pdf
|
|
3506
|
+
isTorsionFree: (c, point) => {
|
|
3507
|
+
const beta = BigInt("0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe");
|
|
3508
|
+
const phi = new c(Fp.mul(point.X, beta), point.Y, point.Z);
|
|
3509
|
+
const xP = point.multiplyUnsafe(BLS_X).negate();
|
|
3510
|
+
const u2P = xP.multiplyUnsafe(BLS_X);
|
|
3511
|
+
return u2P.equals(phi);
|
|
3512
|
+
},
|
|
3513
|
+
// Clear cofactor of G1
|
|
3514
|
+
// https://eprint.iacr.org/2019/403
|
|
3515
|
+
clearCofactor: (_c, point) => {
|
|
3516
|
+
return point.multiplyUnsafe(BLS_X).add(point);
|
|
3517
|
+
}
|
|
3518
|
+
});
|
|
3519
|
+
var G2_Point = weierstrass(bls12_381_CURVE_G2, {
|
|
3520
|
+
Fp: Fp2,
|
|
3521
|
+
// Public point APIs still accept infinity, even though the Zcash proof
|
|
3522
|
+
// encoding rules cited above only define nonzero point encodings.
|
|
3523
|
+
allowInfinityPoint: true,
|
|
3524
|
+
Fn: bls12_381_Fr,
|
|
3525
|
+
fromBytes: g2.point.decode,
|
|
3526
|
+
toBytes: (_c, point, isComp) => g2.point.encode(point, isComp),
|
|
3527
|
+
// https://eprint.iacr.org/2021/1130.pdf
|
|
3528
|
+
// Older version: https://eprint.iacr.org/2019/814.pdf
|
|
3529
|
+
isTorsionFree: (c, P) => {
|
|
3530
|
+
return P.multiplyUnsafe(BLS_X).negate().equals(G2psi(c, P));
|
|
3531
|
+
},
|
|
3532
|
+
// clear_cofactor_bls12381_g2 from RFC 9380.
|
|
3533
|
+
// https://eprint.iacr.org/2017/419.pdf
|
|
3534
|
+
// prettier-ignore
|
|
3535
|
+
clearCofactor: (c, P) => {
|
|
3536
|
+
const x = BLS_X;
|
|
3537
|
+
let t1 = P.multiplyUnsafe(x).negate();
|
|
3538
|
+
let t2 = G2psi(c, P);
|
|
3539
|
+
let t3 = P.double();
|
|
3540
|
+
t3 = G2psi2(c, t3);
|
|
3541
|
+
t3 = t3.subtract(t2);
|
|
3542
|
+
t2 = t1.add(t2);
|
|
3543
|
+
t2 = t2.multiplyUnsafe(x).negate();
|
|
3544
|
+
t3 = t3.add(t2);
|
|
3545
|
+
t3 = t3.subtract(t1);
|
|
3546
|
+
const Q = t3.subtract(P);
|
|
3547
|
+
return Q;
|
|
3548
|
+
}
|
|
3549
|
+
});
|
|
3550
|
+
var bls12_hasher_opts = {
|
|
3551
|
+
mapToG1,
|
|
3552
|
+
mapToG2,
|
|
3553
|
+
hasherOpts: hasher_opts,
|
|
3554
|
+
// RFC 9380 Appendix J defines distinct G1/G2 RO and NU suite IDs, and
|
|
3555
|
+
// draft-irtf-cfrg-bls-signature-06 §4.2.1 gives separate G1/G2 `_NUL_` DSTs.
|
|
3556
|
+
// Keep G1 encode-to-curve on the G1 domain instead of inheriting G2's `encodeDST`.
|
|
3557
|
+
hasherOptsG1: __spreadProps(__spreadValues({}, hasher_opts), {
|
|
3558
|
+
m: 1,
|
|
3559
|
+
DST: "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_",
|
|
3560
|
+
encodeDST: "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_"
|
|
3561
|
+
}),
|
|
3562
|
+
hasherOptsG2: __spreadValues({}, hasher_opts)
|
|
3563
|
+
};
|
|
3564
|
+
var bls12_params = {
|
|
3565
|
+
ateLoopSize: BLS_X,
|
|
3566
|
+
// The BLS parameter x for BLS12-381
|
|
3567
|
+
xNegative: true,
|
|
3568
|
+
twistType: "multiplicative",
|
|
3569
|
+
randomBytes: randomBytes2
|
|
3570
|
+
};
|
|
3571
|
+
var bls12_381 = bls(fields, G1_Point, G2_Point, bls12_params, bls12_hasher_opts, signatureCoders);
|
|
3572
|
+
var isogenyMapG2 = isogenyMap(Fp2, [
|
|
3573
|
+
// xNum
|
|
3574
|
+
[
|
|
3575
|
+
[
|
|
3576
|
+
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6",
|
|
3577
|
+
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6"
|
|
3578
|
+
],
|
|
3579
|
+
[
|
|
3580
|
+
"0x0",
|
|
3581
|
+
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a"
|
|
3582
|
+
],
|
|
3583
|
+
[
|
|
3584
|
+
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e",
|
|
3585
|
+
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d"
|
|
3586
|
+
],
|
|
3587
|
+
[
|
|
3588
|
+
"0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1",
|
|
3589
|
+
"0x0"
|
|
3590
|
+
]
|
|
3591
|
+
],
|
|
3592
|
+
// xDen
|
|
3593
|
+
[
|
|
3594
|
+
[
|
|
3595
|
+
"0x0",
|
|
3596
|
+
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63"
|
|
3597
|
+
],
|
|
3598
|
+
[
|
|
3599
|
+
"0xc",
|
|
3600
|
+
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f"
|
|
3601
|
+
],
|
|
3602
|
+
["0x1", "0x0"]
|
|
3603
|
+
// LAST 1
|
|
3604
|
+
],
|
|
3605
|
+
// yNum
|
|
3606
|
+
[
|
|
3607
|
+
[
|
|
3608
|
+
"0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706",
|
|
3609
|
+
"0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706"
|
|
3610
|
+
],
|
|
3611
|
+
[
|
|
3612
|
+
"0x0",
|
|
3613
|
+
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be"
|
|
3614
|
+
],
|
|
3615
|
+
[
|
|
3616
|
+
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c",
|
|
3617
|
+
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f"
|
|
3618
|
+
],
|
|
3619
|
+
[
|
|
3620
|
+
"0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10",
|
|
3621
|
+
"0x0"
|
|
3622
|
+
]
|
|
3623
|
+
],
|
|
3624
|
+
// yDen
|
|
3625
|
+
[
|
|
3626
|
+
[
|
|
3627
|
+
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb",
|
|
3628
|
+
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb"
|
|
3629
|
+
],
|
|
3630
|
+
[
|
|
3631
|
+
"0x0",
|
|
3632
|
+
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3"
|
|
3633
|
+
],
|
|
3634
|
+
[
|
|
3635
|
+
"0x12",
|
|
3636
|
+
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99"
|
|
3637
|
+
],
|
|
3638
|
+
["0x1", "0x0"]
|
|
3639
|
+
// LAST 1
|
|
3640
|
+
]
|
|
3641
|
+
].map((i) => i.map((pair) => Fp2.fromBigTuple(pair.map(BigInt)))));
|
|
3642
|
+
var isogenyMapG1 = isogenyMap(Fp, [
|
|
3643
|
+
// xNum
|
|
3644
|
+
[
|
|
3645
|
+
"0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7",
|
|
3646
|
+
"0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb",
|
|
3647
|
+
"0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0",
|
|
3648
|
+
"0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861",
|
|
3649
|
+
"0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9",
|
|
3650
|
+
"0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983",
|
|
3651
|
+
"0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84",
|
|
3652
|
+
"0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e",
|
|
3653
|
+
"0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317",
|
|
3654
|
+
"0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e",
|
|
3655
|
+
"0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b",
|
|
3656
|
+
"0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229"
|
|
3657
|
+
],
|
|
3658
|
+
// xDen
|
|
3659
|
+
[
|
|
3660
|
+
"0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c",
|
|
3661
|
+
"0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff",
|
|
3662
|
+
"0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19",
|
|
3663
|
+
"0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8",
|
|
3664
|
+
"0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e",
|
|
3665
|
+
"0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5",
|
|
3666
|
+
"0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a",
|
|
3667
|
+
"0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e",
|
|
3668
|
+
"0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641",
|
|
3669
|
+
"0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a",
|
|
3670
|
+
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
|
|
3671
|
+
// LAST 1
|
|
3672
|
+
],
|
|
3673
|
+
// yNum
|
|
3674
|
+
[
|
|
3675
|
+
"0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33",
|
|
3676
|
+
"0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696",
|
|
3677
|
+
"0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6",
|
|
3678
|
+
"0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb",
|
|
3679
|
+
"0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb",
|
|
3680
|
+
"0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0",
|
|
3681
|
+
"0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2",
|
|
3682
|
+
"0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29",
|
|
3683
|
+
"0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587",
|
|
3684
|
+
"0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30",
|
|
3685
|
+
"0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132",
|
|
3686
|
+
"0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e",
|
|
3687
|
+
"0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8",
|
|
3688
|
+
"0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133",
|
|
3689
|
+
"0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b",
|
|
3690
|
+
"0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604"
|
|
3691
|
+
],
|
|
3692
|
+
// yDen
|
|
3693
|
+
[
|
|
3694
|
+
"0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1",
|
|
3695
|
+
"0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d",
|
|
3696
|
+
"0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2",
|
|
3697
|
+
"0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416",
|
|
3698
|
+
"0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d",
|
|
3699
|
+
"0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac",
|
|
3700
|
+
"0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c",
|
|
3701
|
+
"0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9",
|
|
3702
|
+
"0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a",
|
|
3703
|
+
"0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55",
|
|
3704
|
+
"0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8",
|
|
3705
|
+
"0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092",
|
|
3706
|
+
"0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc",
|
|
3707
|
+
"0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7",
|
|
3708
|
+
"0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f",
|
|
3709
|
+
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001"
|
|
3710
|
+
// LAST 1
|
|
3711
|
+
]
|
|
3712
|
+
].map((i) => i.map((j) => BigInt(j))));
|
|
3713
|
+
var G1_SWU;
|
|
3714
|
+
var G2_SWU;
|
|
3715
|
+
var getG1_SWU = () => G1_SWU || (G1_SWU = mapToCurveSimpleSWU(Fp, {
|
|
3716
|
+
A: Fp.create(BigInt("0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d")),
|
|
3717
|
+
B: Fp.create(BigInt("0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0")),
|
|
3718
|
+
Z: Fp.create(BigInt(11))
|
|
3719
|
+
}));
|
|
3720
|
+
var getG2_SWU = () => G2_SWU || (G2_SWU = mapToCurveSimpleSWU(Fp2, {
|
|
3721
|
+
// SWU map for the RFC 9380 §8.8.2 pre-isogeny G2 curve E':
|
|
3722
|
+
// y² = x³ + 240i * x + 1012 + 1012i
|
|
3723
|
+
A: Fp2.create({ c0: Fp.create(_0n7), c1: Fp.create(BigInt(240)) }),
|
|
3724
|
+
// A' = 240 * I
|
|
3725
|
+
B: Fp2.create({ c0: Fp.create(BigInt(1012)), c1: Fp.create(BigInt(1012)) }),
|
|
3726
|
+
// B' = 1012 * (1 + I)
|
|
3727
|
+
Z: Fp2.create({ c0: Fp.create(BigInt(-2)), c1: Fp.create(BigInt(-1)) })
|
|
3728
|
+
// Z: -(2 + I)
|
|
3729
|
+
}));
|
|
3730
|
+
function mapToG1(scalars) {
|
|
3731
|
+
const { x, y } = getG1_SWU()(Fp.create(scalars[0]));
|
|
3732
|
+
return isogenyMapG1(x, y);
|
|
3733
|
+
}
|
|
3734
|
+
function mapToG2(scalars) {
|
|
3735
|
+
const { x, y } = getG2_SWU()(Fp2.fromBigTuple(scalars));
|
|
3736
|
+
return isogenyMapG2(x, y);
|
|
3737
|
+
}
|
|
3738
|
+
|
|
3739
|
+
// src/blsUtils.ts
|
|
3740
|
+
var { longSignatures: ls } = bls12_381;
|
|
3741
|
+
var ETH2_DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_";
|
|
3742
|
+
function blsVerifyMultiple(pubkeys, messages, signature) {
|
|
3743
|
+
try {
|
|
3744
|
+
if (pubkeys.length !== messages.length) return false;
|
|
3745
|
+
const items = messages.map((msg, i) => ({
|
|
3746
|
+
message: ls.hash(msg, ETH2_DST),
|
|
3747
|
+
publicKey: pubkeys[i]
|
|
3748
|
+
}));
|
|
3749
|
+
return ls.verifyBatch(signature, items);
|
|
3750
|
+
} catch (e) {
|
|
3751
|
+
return false;
|
|
3752
|
+
}
|
|
3753
|
+
}
|
|
3754
|
+
function blsAggregateSignatures(signatures) {
|
|
3755
|
+
return ls.Signature.toBytes(ls.aggregateSignatures(signatures));
|
|
3756
|
+
}
|
|
3757
|
+
function lagrangeCoeffAtZero(shareIndex, indices) {
|
|
3758
|
+
const { Fr } = bls12_381.fields;
|
|
3759
|
+
let num = BigInt(1);
|
|
3760
|
+
let den = BigInt(1);
|
|
3761
|
+
for (const j of indices) {
|
|
3762
|
+
if (j === shareIndex) continue;
|
|
3763
|
+
num = Fr.mul(num, Fr.neg(j));
|
|
3764
|
+
den = Fr.mul(den, Fr.sub(shareIndex, j));
|
|
3765
|
+
}
|
|
3766
|
+
return Fr.mul(num, Fr.inv(den));
|
|
3767
|
+
}
|
|
3768
|
+
function blsRecoverWithIndices(shares, indices) {
|
|
3769
|
+
try {
|
|
3770
|
+
let recovered = bls12_381.G1.Point.ZERO;
|
|
3771
|
+
for (let i = 0; i < shares.length; i++) {
|
|
3772
|
+
const point = bls12_381.G1.Point.fromBytes(shares[i]);
|
|
3773
|
+
const coeff = lagrangeCoeffAtZero(indices[i], indices);
|
|
3774
|
+
recovered = recovered.add(point.multiply(coeff));
|
|
3775
|
+
}
|
|
3776
|
+
return recovered.toBytes();
|
|
3777
|
+
} catch (e) {
|
|
3778
|
+
return null;
|
|
3779
|
+
}
|
|
3780
|
+
}
|
|
3781
|
+
function blsRecoverDistributedPubkeyFromShares(pubshares, threshold) {
|
|
3782
|
+
if (threshold <= 0 || pubshares.length < threshold) return null;
|
|
3783
|
+
const selected = pubshares.slice(0, threshold);
|
|
3784
|
+
const indices = selected.map((_, i) => BigInt(i + 1));
|
|
3785
|
+
return blsRecoverWithIndices(selected, indices);
|
|
3786
|
+
}
|
|
3787
|
+
function blsVerifyExtraShares(pubshares, threshold, distributedPubkey) {
|
|
3788
|
+
if (threshold <= 0 || pubshares.length < threshold) return false;
|
|
3789
|
+
try {
|
|
3790
|
+
const baseShares = pubshares.slice(0, threshold - 1);
|
|
3791
|
+
const baseIndices = baseShares.map((_, i) => BigInt(i + 1));
|
|
3792
|
+
for (let i = threshold; i < pubshares.length; i++) {
|
|
3793
|
+
const shares = [...baseShares, pubshares[i]];
|
|
3794
|
+
const indices = [...baseIndices, BigInt(i + 1)];
|
|
3795
|
+
const recovered = blsRecoverWithIndices(shares, indices);
|
|
3796
|
+
if (!recovered || recovered.length !== distributedPubkey.length || !recovered.every((b, j) => b === distributedPubkey[j])) {
|
|
3797
|
+
return false;
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
return true;
|
|
3801
|
+
} catch (e) {
|
|
3802
|
+
return false;
|
|
3803
|
+
}
|
|
3804
|
+
}
|
|
3805
|
+
|
|
3806
|
+
// src/verification/parallelPool.ts
|
|
3807
|
+
var MIN_PARALLEL_VALIDATORS = 50;
|
|
3808
|
+
var MIN_PARALLEL_BATCH_PAIRS = 100;
|
|
3809
|
+
var MAX_WORKERS = 8;
|
|
3810
|
+
var MIN_VALIDATORS_PER_WORKER = 25;
|
|
3811
|
+
var MIN_PAIRS_PER_WORKER = 50;
|
|
3812
|
+
var WORKER_TIMEOUT_MS = 6e4;
|
|
3813
|
+
var workerThreadsCache;
|
|
3814
|
+
var osCache;
|
|
3815
|
+
var workerPathCache;
|
|
3816
|
+
function loadWorkerThreads() {
|
|
3817
|
+
if (workerThreadsCache !== void 0) return workerThreadsCache;
|
|
3818
|
+
try {
|
|
3819
|
+
workerThreadsCache = require("worker_threads");
|
|
3820
|
+
} catch (e) {
|
|
3821
|
+
workerThreadsCache = null;
|
|
3822
|
+
}
|
|
3823
|
+
return workerThreadsCache;
|
|
3824
|
+
}
|
|
3825
|
+
function loadOs() {
|
|
3826
|
+
if (osCache !== void 0) return osCache;
|
|
3827
|
+
try {
|
|
3828
|
+
osCache = require("os");
|
|
3829
|
+
} catch (e) {
|
|
3830
|
+
osCache = null;
|
|
3831
|
+
}
|
|
3832
|
+
return osCache;
|
|
3833
|
+
}
|
|
3834
|
+
function getWorkerPath() {
|
|
3835
|
+
if (workerPathCache !== void 0) return workerPathCache;
|
|
3836
|
+
if (typeof __dirname === "undefined") return workerPathCache = null;
|
|
3837
|
+
const path = require("path");
|
|
3838
|
+
const candidate = path.join(__dirname, "lockWorker.js");
|
|
3839
|
+
try {
|
|
3840
|
+
const fs = require("fs");
|
|
3841
|
+
if (!fs.existsSync(candidate)) return workerPathCache = null;
|
|
3842
|
+
} catch (e) {
|
|
3843
|
+
return workerPathCache = null;
|
|
3844
|
+
}
|
|
3845
|
+
return workerPathCache = candidate;
|
|
3846
|
+
}
|
|
3847
|
+
function chunkArrays(arr, n) {
|
|
3848
|
+
const size = Math.ceil(arr.length / n);
|
|
3849
|
+
const out = [];
|
|
3850
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
3851
|
+
out.push(arr.slice(i, i + size));
|
|
3852
|
+
}
|
|
3853
|
+
return out;
|
|
3854
|
+
}
|
|
3855
|
+
function verifySharesSync(shares, distributedKeys, threshold) {
|
|
3856
|
+
for (let i = 0; i < shares.length; i++) {
|
|
3857
|
+
const sharesBytes = shares[i].map((s) => (0, import_ssz.fromHexString)(s));
|
|
3858
|
+
const dkBytes = (0, import_ssz.fromHexString)(distributedKeys[i]);
|
|
3859
|
+
const recovered = blsRecoverDistributedPubkeyFromShares(
|
|
3860
|
+
sharesBytes,
|
|
3861
|
+
threshold
|
|
3862
|
+
);
|
|
3863
|
+
if (!recovered) return false;
|
|
3864
|
+
if (recovered.length !== dkBytes.length) return false;
|
|
3865
|
+
for (let j = 0; j < recovered.length; j++) {
|
|
3866
|
+
if (recovered[j] !== dkBytes[j]) return false;
|
|
3867
|
+
}
|
|
3868
|
+
if (!blsVerifyExtraShares(sharesBytes, threshold, dkBytes)) {
|
|
3869
|
+
return false;
|
|
3870
|
+
}
|
|
3871
|
+
}
|
|
3872
|
+
return true;
|
|
3873
|
+
}
|
|
3874
|
+
function runWorker(wt, workerFile, data) {
|
|
3875
|
+
return __async(this, null, function* () {
|
|
3876
|
+
return yield new Promise((resolve) => {
|
|
3877
|
+
let settled = false;
|
|
3878
|
+
const worker = new wt.Worker(workerFile, { workerData: data });
|
|
3879
|
+
const finish = (result) => {
|
|
3880
|
+
if (settled) return;
|
|
3881
|
+
settled = true;
|
|
3882
|
+
clearTimeout(timer);
|
|
3883
|
+
worker.terminate();
|
|
3884
|
+
resolve(result);
|
|
3885
|
+
};
|
|
3886
|
+
const timer = setTimeout(() => {
|
|
3887
|
+
finish(false);
|
|
3888
|
+
}, WORKER_TIMEOUT_MS);
|
|
3889
|
+
worker.once("message", (msg) => {
|
|
3890
|
+
finish(msg === true);
|
|
3891
|
+
});
|
|
3892
|
+
worker.once("error", () => {
|
|
3893
|
+
finish(false);
|
|
3894
|
+
});
|
|
3895
|
+
worker.once("exit", (code) => {
|
|
3896
|
+
if (code !== 0) finish(false);
|
|
3897
|
+
});
|
|
3898
|
+
});
|
|
3899
|
+
});
|
|
3900
|
+
}
|
|
3901
|
+
function poolSize(itemCount, minPerWorker) {
|
|
3902
|
+
const wt = loadWorkerThreads();
|
|
3903
|
+
const os = loadOs();
|
|
3904
|
+
const workerFile = getWorkerPath();
|
|
3905
|
+
const numCpus = os ? os.cpus().length : 1;
|
|
3906
|
+
const numWorkers = Math.min(
|
|
3907
|
+
MAX_WORKERS,
|
|
3908
|
+
Math.max(1, Math.floor(itemCount / minPerWorker)),
|
|
3909
|
+
numCpus
|
|
3910
|
+
);
|
|
3911
|
+
return { numWorkers, wt, workerFile };
|
|
3912
|
+
}
|
|
3913
|
+
function verifySharesBinding(shares, distributedKeys, threshold) {
|
|
3914
|
+
return __async(this, null, function* () {
|
|
3915
|
+
if (shares.length !== distributedKeys.length) return false;
|
|
3916
|
+
if (shares.length === 0) return true;
|
|
3917
|
+
const { numWorkers, wt, workerFile } = poolSize(
|
|
3918
|
+
shares.length,
|
|
3919
|
+
MIN_VALIDATORS_PER_WORKER
|
|
3920
|
+
);
|
|
3921
|
+
if (wt === null || workerFile === null || shares.length < MIN_PARALLEL_VALIDATORS || numWorkers < 2) {
|
|
3922
|
+
return verifySharesSync(shares, distributedKeys, threshold);
|
|
3923
|
+
}
|
|
3924
|
+
const shareChunks = chunkArrays(shares, numWorkers);
|
|
3925
|
+
const keyChunks = chunkArrays(distributedKeys, numWorkers);
|
|
3926
|
+
const results = yield Promise.all(
|
|
3927
|
+
shareChunks.map(
|
|
3928
|
+
(chunk, i) => __async(null, null, function* () {
|
|
3929
|
+
return yield runWorker(wt, workerFile, {
|
|
3930
|
+
mode: "shareBinding",
|
|
3931
|
+
shares: chunk,
|
|
3932
|
+
distributedKeys: keyChunks[i],
|
|
3933
|
+
threshold
|
|
3934
|
+
});
|
|
3935
|
+
})
|
|
3936
|
+
)
|
|
3937
|
+
);
|
|
3938
|
+
return results.every(Boolean);
|
|
3939
|
+
});
|
|
3940
|
+
}
|
|
3941
|
+
function verifyBatchParallel(pubkeys, messages, signatures) {
|
|
3942
|
+
return __async(this, null, function* () {
|
|
3943
|
+
if (pubkeys.length !== messages.length || pubkeys.length !== signatures.length) {
|
|
3944
|
+
return false;
|
|
3945
|
+
}
|
|
3946
|
+
if (pubkeys.length === 0) return true;
|
|
3947
|
+
const { numWorkers, wt, workerFile } = poolSize(
|
|
3948
|
+
pubkeys.length,
|
|
3949
|
+
MIN_PAIRS_PER_WORKER
|
|
3950
|
+
);
|
|
3951
|
+
if (wt === null || workerFile === null || pubkeys.length < MIN_PARALLEL_BATCH_PAIRS || numWorkers < 2) {
|
|
3952
|
+
return blsVerifyMultiple(
|
|
3953
|
+
pubkeys,
|
|
3954
|
+
messages,
|
|
3955
|
+
blsAggregateSignatures(signatures)
|
|
3956
|
+
);
|
|
3957
|
+
}
|
|
3958
|
+
const pkChunks = chunkArrays(pubkeys, numWorkers);
|
|
3959
|
+
const msgChunks = chunkArrays(messages, numWorkers);
|
|
3960
|
+
const sigChunks = chunkArrays(signatures, numWorkers);
|
|
3961
|
+
const results = yield Promise.all(
|
|
3962
|
+
pkChunks.map(
|
|
3963
|
+
(pks, i) => __async(null, null, function* () {
|
|
3964
|
+
return yield runWorker(wt, workerFile, {
|
|
3965
|
+
mode: "verifyBatch",
|
|
3966
|
+
pubkeys: pks,
|
|
3967
|
+
messages: msgChunks[i],
|
|
3968
|
+
aggregateSignature: blsAggregateSignatures(sigChunks[i])
|
|
3969
|
+
});
|
|
3970
|
+
})
|
|
3971
|
+
)
|
|
3972
|
+
);
|
|
3973
|
+
return results.every(Boolean);
|
|
3974
|
+
});
|
|
3975
|
+
}
|
|
3976
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3977
|
+
0 && (module.exports = {
|
|
3978
|
+
verifyBatchParallel,
|
|
3979
|
+
verifySharesBinding
|
|
3980
|
+
});
|
|
3981
|
+
/*! Bundled license information:
|
|
3982
|
+
|
|
3983
|
+
@noble/curves/utils.js:
|
|
3984
|
+
@noble/curves/abstract/modular.js:
|
|
3985
|
+
@noble/curves/abstract/curve.js:
|
|
3986
|
+
@noble/curves/abstract/weierstrass.js:
|
|
3987
|
+
@noble/curves/abstract/bls.js:
|
|
3988
|
+
@noble/curves/abstract/tower.js:
|
|
3989
|
+
@noble/curves/bls12-381.js:
|
|
3990
|
+
(*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
|
|
3991
|
+
*/
|
|
3992
|
+
//# sourceMappingURL=parallelPool.js.map
|