From e9be7570ab83340f56c5b62d6f351a32bdc7590e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 22 Jul 2024 12:04:48 +0200 Subject: [PATCH 1/5] feat: setup drand client MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- deps.ts | 7 + lib/drand-client.js | 34 + test/drand-client.test.js | 8 + vendor/deno-deps.js | 3470 +++++++++++++++++++++++++++++++++++++ 4 files changed, 3519 insertions(+) create mode 100644 lib/drand-client.js create mode 100644 test/drand-client.test.js diff --git a/deps.ts b/deps.ts index e55127b..ad860c3 100644 --- a/deps.ts +++ b/deps.ts @@ -15,3 +15,10 @@ export { HashMismatchError, validateBlock } from 'https://cdn.skypack.dev/@web3-storage/car-block-validator@1.2.0/?dts' +// cdn.skypack.dev cannot resolve import from @noble/hashes +// jsdelivr.net seems to work better, it's also recommended by drand-client +export { + fetchBeaconByTime, + HttpChainClient, + HttpCachingChain +} from 'https://cdn.jsdelivr.net/npm/drand-client@1.2.6/index.js/+esm' diff --git a/lib/drand-client.js b/lib/drand-client.js new file mode 100644 index 0000000..0db3fba --- /dev/null +++ b/lib/drand-client.js @@ -0,0 +1,34 @@ +import { + fetchBeaconByTime, + HttpChainClient, + HttpCachingChain +} from '../vendor/deno-deps.js' + +// See https://docs.filecoin.io/networks/mainnet#genesis +const FIL_MAINNET_GENESIS_TS = new Date('2020-08-24T22:00:00Z').getTime() +const FIL_MAINNET_BLOCK_TIME = 30_000 // 30 seconds + +/** @type {import('https://cdn.skypack.dev/drand-client@1.2.6/?dts').ChainOptions} */ +const DRAND_OPTIONS = { + // FIXME: beacon verification does not work when using drand-client via CDN :( + disableBeaconVerification: true, + noCache: false, + chainVerificationParams: { + // quicknet + chainHash: '52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971', + publicKey: '83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a' + } +} + +const DRAND_URL = `https://api.drand.sh/${DRAND_OPTIONS.chainVerificationParams.chainHash}` +const chain = new HttpCachingChain(DRAND_URL, DRAND_OPTIONS) +const client = new HttpChainClient(chain, DRAND_OPTIONS) + +/** + * @param {number} roundStartEpoch + */ +export async function getRandomnessForSparkRound (roundStartEpoch) { + const roundStartedAt = roundStartEpoch * FIL_MAINNET_BLOCK_TIME + FIL_MAINNET_GENESIS_TS + const beacon = await fetchBeaconByTime(client, roundStartedAt) + return beacon.randomness +} diff --git a/test/drand-client.test.js b/test/drand-client.test.js new file mode 100644 index 0000000..77ee80b --- /dev/null +++ b/test/drand-client.test.js @@ -0,0 +1,8 @@ +import { test } from 'zinnia:test' +import { assertEquals } from 'zinnia:assert' +import { getRandomnessForSparkRound } from '../lib/drand-client.js' + +test('getRandomnessForSparkRound', async () => { + const randomness = await getRandomnessForSparkRound(4111111) + assertEquals(randomness, 'fc90e50dcdf20886b56c038b30fa921a5e57c532ea448dadcc209e44eec0445e') +}) diff --git a/vendor/deno-deps.js b/vendor/deno-deps.js index a5b337d..c1fa2c5 100644 --- a/vendor/deno-deps.js +++ b/vendor/deno-deps.js @@ -8220,8 +8220,3478 @@ function validateBlock(block) { } compareDigests(result); } +const o = "object" == typeof globalThis && "crypto" in globalThis ? globalThis.crypto : void 0; +function t(t1, ...e) { + if (!((s = t1) instanceof Uint8Array || null != s && "object" == typeof s && "Uint8Array" === s.constructor.name)) throw new Error("Uint8Array expected"); + var s; + if (e.length > 0 && !e.includes(t1.length)) throw new Error(`Uint8Array expected of length ${e}, not of length=${t1.length}`); +} +function e(t, e = !0) { + if (t.destroyed) throw new Error("Hash instance has been destroyed"); + if (e && t.finished) throw new Error("Hash#digest() has already been called"); +} +const s = (t)=>new DataView(t.buffer, t.byteOffset, t.byteLength), n = (t, e)=>t << 32 - e | t >>> e; +function i(e) { + return "string" == typeof e && (e = function(t) { + if ("string" != typeof t) throw new Error("utf8ToBytes expected string, got " + typeof t); + return new Uint8Array((new TextEncoder).encode(t)); + }(e)), t(e), e; +} +new Uint8Array(new Uint32Array([ + 287454020 +]).buffer)[0]; +class r { + clone() { + return this._cloneInto(); + } +} +function o1(t) { + const e = (e)=>t().update(i(e)).digest(), s = t(); + return e.outputLen = s.outputLen, e.blockLen = s.blockLen, e.create = ()=>t(), e; +} +const h = (t, e, s)=>t & e ^ t & s ^ e & s; +class f extends r { + constructor(t, e, n, i){ + super(), this.blockLen = t, this.outputLen = e, this.padOffset = n, this.isLE = i, this.finished = !1, this.length = 0, this.pos = 0, this.destroyed = !1, this.buffer = new Uint8Array(t), this.view = s(this.buffer); + } + update(t) { + e(this); + const { view: n, buffer: r, blockLen: o } = this, h = (t = i(t)).length; + for(let e = 0; e < h;){ + const i = Math.min(o - this.pos, h - e); + if (i !== o) r.set(t.subarray(e, e + i), this.pos), this.pos += i, e += i, this.pos === o && (this.process(n, 0), this.pos = 0); + else { + const n = s(t); + for(; o <= h - e; e += o)this.process(n, e); + } + } + return this.length += t.length, this.roundClean(), this; + } + digestInto(n) { + e(this), function(e, s) { + t(e); + const n = s.outputLen; + if (e.length < n) throw new Error(`digestInto() expects output buffer of length at least ${n}`); + }(n, this), this.finished = !0; + const { buffer: i, view: r, blockLen: o, isLE: h } = this; + let { pos: f } = this; + i[f++] = 128, this.buffer.subarray(f).fill(0), this.padOffset > o - f && (this.process(r, 0), f = 0); + for(let t = f; t < o; t++)i[t] = 0; + !function(t, e, s, n) { + if ("function" == typeof t.setBigUint64) return t.setBigUint64(e, s, n); + const i = BigInt(32), r = BigInt(4294967295), o = Number(s >> i & r), h = Number(s & r), f = n ? 4 : 0, u = n ? 0 : 4; + t.setUint32(e + f, o, n), t.setUint32(e + u, h, n); + }(r, o - 8, BigInt(8 * this.length), h), this.process(r, 0); + const u = s(n), c = this.outputLen; + if (c % 4) throw new Error("_sha2: outputLen should be aligned to 32bit"); + const l = c / 4, a = this.get(); + if (l > a.length) throw new Error("_sha2: outputLen bigger than state"); + for(let t = 0; t < l; t++)u.setUint32(4 * t, a[t], h); + } + digest() { + const { buffer: t, outputLen: e } = this; + this.digestInto(t); + const s = t.slice(0, e); + return this.destroy(), s; + } + _cloneInto(t) { + t || (t = new this.constructor), t.set(...this.get()); + const { blockLen: e, buffer: s, length: n, finished: i, destroyed: r, pos: o } = this; + return t.length = n, t.pos = o, t.finished = i, t.destroyed = r, n % e && t.buffer.set(s), t; + } +} +const u = new Uint32Array([ + 1116352408, + 1899447441, + 3049323471, + 3921009573, + 961987163, + 1508970993, + 2453635748, + 2870763221, + 3624381080, + 310598401, + 607225278, + 1426881987, + 1925078388, + 2162078206, + 2614888103, + 3248222580, + 3835390401, + 4022224774, + 264347078, + 604807628, + 770255983, + 1249150122, + 1555081692, + 1996064986, + 2554220882, + 2821834349, + 2952996808, + 3210313671, + 3336571891, + 3584528711, + 113926993, + 338241895, + 666307205, + 773529912, + 1294757372, + 1396182291, + 1695183700, + 1986661051, + 2177026350, + 2456956037, + 2730485921, + 2820302411, + 3259730800, + 3345764771, + 3516065817, + 3600352804, + 4094571909, + 275423344, + 430227734, + 506948616, + 659060556, + 883997877, + 958139571, + 1322822218, + 1537002063, + 1747873779, + 1955562222, + 2024104815, + 2227730452, + 2361852424, + 2428436474, + 2756734187, + 3204031479, + 3329325298 +]), c = new Uint32Array([ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225 +]), l = new Uint32Array(64); +class a extends f { + constructor(){ + super(64, 32, 8, !1), this.A = 0 | c[0], this.B = 0 | c[1], this.C = 0 | c[2], this.D = 0 | c[3], this.E = 0 | c[4], this.F = 0 | c[5], this.G = 0 | c[6], this.H = 0 | c[7]; + } + get() { + const { A: t, B: e, C: s, D: n, E: i, F: r, G: o, H: h } = this; + return [ + t, + e, + s, + n, + i, + r, + o, + h + ]; + } + set(t, e, s, n, i, r, o, h) { + this.A = 0 | t, this.B = 0 | e, this.C = 0 | s, this.D = 0 | n, this.E = 0 | i, this.F = 0 | r, this.G = 0 | o, this.H = 0 | h; + } + process(t, e) { + for(let s = 0; s < 16; s++, e += 4)l[s] = t.getUint32(e, !1); + for(let t = 16; t < 64; t++){ + const e = l[t - 15], s = l[t - 2], i = n(e, 7) ^ n(e, 18) ^ e >>> 3, r = n(s, 17) ^ n(s, 19) ^ s >>> 10; + l[t] = r + l[t - 7] + i + l[t - 16] | 0; + } + let { A: s, B: i, C: r, D: o, E: f, F: c, G: a, H: p } = this; + for(let t = 0; t < 64; t++){ + const e = p + (n(f, 6) ^ n(f, 11) ^ n(f, 25)) + ((d = f) & c ^ ~d & a) + u[t] + l[t] | 0, g = (n(s, 2) ^ n(s, 13) ^ n(s, 22)) + h(s, i, r) | 0; + p = a, a = c, c = f, f = o + e | 0, o = r, r = i, i = s, s = e + g | 0; + } + var d; + s = s + this.A | 0, i = i + this.B | 0, r = r + this.C | 0, o = o + this.D | 0, f = f + this.E | 0, c = c + this.F | 0, a = a + this.G | 0, p = p + this.H | 0, this.set(s, i, r, o, f, c, a, p); + } + roundClean() { + l.fill(0); + } + destroy() { + this.set(0, 0, 0, 0, 0, 0, 0, 0), this.buffer.fill(0); + } +} +class p extends a { + constructor(){ + super(), this.A = -1056596264, this.B = 914150663, this.C = 812702999, this.D = -150054599, this.E = -4191439, this.F = 1750603025, this.G = 1694076839, this.H = -1090891868, this.outputLen = 28; + } +} +const d = o1(()=>new a), g = o1(()=>new p); +68 === new Uint8Array(new Uint32Array([ + 287454020 +]).buffer)[0]; +Array.from({ + length: 256 +}, (t, e)=>e.toString(16).padStart(2, "0")); +function O(e = 32) { + if (o && "function" == typeof o.getRandomValues) return o.getRandomValues(new Uint8Array(e)); + throw new Error("crypto.getRandomValues must be defined"); +} +const c1 = BigInt(0), a1 = BigInt(1), f1 = BigInt(2); +function r1(e) { + return e instanceof Uint8Array || null != e && "object" == typeof e && "Uint8Array" === e.constructor.name; +} +function n1(e) { + if (!r1(e)) throw new Error("Uint8Array expected"); +} +const d1 = Array.from({ + length: 256 +}, (e, t)=>t.toString(16).padStart(2, "0")); +function i1(e) { + n1(e); + let t = ""; + for(let c = 0; c < e.length; c++)t += d1[e[c]]; + return t; +} +function o2(e) { + if ("string" != typeof e) throw new Error("hex string expected, got " + typeof e); + return BigInt("" === e ? "0" : `0x${e}`); +} +const b = { + _0: 48, + _9: 57, + _A: 65, + _F: 70, + _a: 97, + _f: 102 +}; +function s1(e) { + return e >= b._0 && e <= b._9 ? e - b._0 : e >= b._A && e <= b._F ? e - (b._A - 10) : e >= b._a && e <= b._f ? e - (b._a - 10) : void 0; +} +function u1(e) { + if ("string" != typeof e) throw new Error("hex string expected, got " + typeof e); + const t = e.length, c = t / 2; + if (t % 2) throw new Error("padded hex string expected, got unpadded hex of length " + t); + const a = new Uint8Array(c); + for(let t = 0, f = 0; t < c; t++, f += 2){ + const c = s1(e.charCodeAt(f)), r = s1(e.charCodeAt(f + 1)); + if (void 0 === c || void 0 === r) { + const t = e[f] + e[f + 1]; + throw new Error('hex string expected, got non-hex character "' + t + '" at index ' + f); + } + a[t] = 16 * c + r; + } + return a; +} +function l1(e) { + return o2(i1(e)); +} +function m1(e) { + return n1(e), o2(i1(Uint8Array.from(e).reverse())); +} +function p1(e, t) { + return u1(e.toString(16).padStart(2 * t, "0")); +} +function g1(e, t) { + return p1(e, t).reverse(); +} +function y(e, t, c) { + let a; + if ("string" == typeof t) try { + a = u1(t); + } catch (c) { + throw new Error(`${e} must be valid hex string, got "${t}". Cause: ${c}`); + } + else { + if (!r1(t)) throw new Error(`${e} must be hex string or Uint8Array`); + a = Uint8Array.from(t); + } + const f = a.length; + if ("number" == typeof c && f !== c) throw new Error(`${e} expected ${c} bytes, got ${f}`); + return a; +} +function B(...e) { + let t = 0; + for(let c = 0; c < e.length; c++){ + const a = e[c]; + n1(a), t += a.length; + } + const c = new Uint8Array(t); + for(let t = 0, a = 0; t < e.length; t++){ + const f = e[t]; + c.set(f, a), a += f.length; + } + return c; +} +function x(e) { + if ("string" != typeof e) throw new Error("utf8ToBytes expected string, got " + typeof e); + return new Uint8Array((new TextEncoder).encode(e)); +} +function E(e) { + let t; + for(t = 0; e > c1; e >>= a1, t += 1); + return t; +} +function h1(e, t) { + return e >> BigInt(t) & a1; +} +const w = (e)=>(f1 << BigInt(e - 1)) - a1, v1 = { + bigint: (e)=>"bigint" == typeof e, + function: (e)=>"function" == typeof e, + boolean: (e)=>"boolean" == typeof e, + string: (e)=>"string" == typeof e, + stringOrUint8Array: (e)=>"string" == typeof e || r1(e), + isSafeInteger: (e)=>Number.isSafeInteger(e), + array: (e)=>Array.isArray(e), + field: (e, t)=>t.Fp.isValid(e), + hash: (e)=>"function" == typeof e && Number.isSafeInteger(e.outputLen) +}; +function I(e, t, c = {}) { + const a = (t, c, a)=>{ + const f = v1[c]; + if ("function" != typeof f) throw new Error(`Invalid validator "${c}", expected function`); + const r = e[t]; + if (!(a && void 0 === r || f(r, e))) throw new Error(`Invalid param ${String(t)}=${r} (${typeof r}), expected ${c}`); + }; + for (const [e, c] of Object.entries(t))a(e, c, !1); + for (const [e, t] of Object.entries(c))a(e, t, !0); + return e; +} +const O1 = BigInt(0), S = BigInt(1), R = BigInt(2), q = BigInt(3), P = BigInt(4), T = BigInt(5), A = BigInt(8); +function N(e, t) { + const c = e % t; + return c >= O1 ? c : t + c; +} +function Z(e, t, c) { + if (c <= O1 || t < O1) throw new Error("Expected power/modulo > 0"); + if (c === S) return O1; + let a = S; + for(; t > O1;)t & S && (a = a * e % c), e = e * e % c, t >>= S; + return a; +} +function _(e, t) { + if (e === O1 || t <= O1) throw new Error(`invert: expected positive integers, got n=${e} mod=${t}`); + let c = N(e, t), a = t, f = O1, r = S; + for(; c !== O1;){ + const e = a % c, t = f - r * (a / c); + a = c, c = e, f = r, r = t; + } + if (a !== S) throw new Error("invert: does not exist"); + return N(f, t); +} +function j(e) { + if (e % P === q) { + const t = (e + S) / P; + return function(e, c) { + const a = e.pow(c, t); + if (!e.eql(e.sqr(a), c)) throw new Error("Cannot find square root"); + return a; + }; + } + if (e % A === T) { + const t = (e - T) / A; + return function(e, c) { + const a = e.mul(c, R), f = e.pow(a, t), r = e.mul(c, f), n = e.mul(e.mul(r, R), f), d = e.mul(r, e.sub(n, e.ONE)); + if (!e.eql(e.sqr(d), c)) throw new Error("Cannot find square root"); + return d; + }; + } + return function(e) { + const t = (e - S) / R; + let c, a, f; + for(c = e - S, a = 0; c % R === O1; c /= R, a++); + for(f = R; f < e && Z(f, t, e) !== e - S; f++); + if (1 === a) { + const t = (e + S) / P; + return function(e, c) { + const a = e.pow(c, t); + if (!e.eql(e.sqr(a), c)) throw new Error("Cannot find square root"); + return a; + }; + } + const r = (c + S) / R; + return function(e, n) { + if (e.pow(n, t) === e.neg(e.ONE)) throw new Error("Cannot find square root"); + let d = a, i = e.pow(e.mul(e.ONE, f), c), o = e.pow(n, r), b = e.pow(n, c); + for(; !e.eql(b, e.ONE);){ + if (e.eql(b, e.ZERO)) return e.ZERO; + let t = 1; + for(let c = e.sqr(b); t < d && !e.eql(c, e.ONE); t++)c = e.sqr(c); + const c = e.pow(i, S << BigInt(d - t - 1)); + i = e.sqr(c), o = e.mul(o, c), b = e.mul(b, i), d = t; + } + return o; + }; + }(e); +} +BigInt(9), BigInt(16); +const F = [ + "create", + "isValid", + "is0", + "neg", + "inv", + "sqrt", + "sqr", + "eql", + "add", + "sub", + "mul", + "pow", + "div", + "addN", + "subN", + "mulN", + "sqrN" +]; +function G(e) { + return I(e, F.reduce((e, t)=>(e[t] = "function", e), { + ORDER: "bigint", + MASK: "bigint", + BYTES: "isSafeInteger", + BITS: "isSafeInteger" + })); +} +function D(e, t, c) { + if (c < O1) throw new Error("Expected power > 0"); + if (c === O1) return e.ONE; + if (c === S) return t; + let a = e.ONE, f = t; + for(; c > O1;)c & S && (a = e.mul(a, f)), f = e.sqr(f), c >>= S; + return a; +} +function V(e, t) { + const c = new Array(t.length), a = t.reduce((t, a, f)=>e.is0(a) ? t : (c[f] = t, e.mul(t, a)), e.ONE), f = e.inv(a); + return t.reduceRight((t, a, f)=>e.is0(a) ? t : (c[f] = e.mul(t, c[f]), e.mul(t, a)), f), c; +} +function M(e, t) { + const c = void 0 !== t ? t : e.toString(2).length; + return { + nBitLength: c, + nByteLength: Math.ceil(c / 8) + }; +} +function U(e, t, c = !1, a = {}) { + if (e <= O1) throw new Error(`Expected Field ORDER > 0, got ${e}`); + const { nBitLength: f, nByteLength: r } = M(e, t); + if (r > 2048) throw new Error("Field lengths over 2048 bytes are not supported"); + const n = j(e), d = Object.freeze({ + ORDER: e, + BITS: f, + BYTES: r, + MASK: w(f), + ZERO: O1, + ONE: S, + create: (t)=>N(t, e), + isValid: (t)=>{ + if ("bigint" != typeof t) throw new Error("Invalid field element: expected bigint, got " + typeof t); + return O1 <= t && t < e; + }, + is0: (e)=>e === O1, + isOdd: (e)=>(e & S) === S, + neg: (t)=>N(-t, e), + eql: (e, t)=>e === t, + sqr: (t)=>N(t * t, e), + add: (t, c)=>N(t + c, e), + sub: (t, c)=>N(t - c, e), + mul: (t, c)=>N(t * c, e), + pow: (e, t)=>D(d, e, t), + div: (t, c)=>N(t * _(c, e), e), + sqrN: (e)=>e * e, + addN: (e, t)=>e + t, + subN: (e, t)=>e - t, + mulN: (e, t)=>e * t, + inv: (t)=>_(t, e), + sqrt: a.sqrt || ((e)=>n(d, e)), + invertBatch: (e)=>V(d, e), + cmov: (e, t, c)=>c ? t : e, + toBytes: (e)=>c ? g1(e, r) : p1(e, r), + fromBytes: (e)=>{ + if (e.length !== r) throw new Error(`Fp.fromBytes: expected ${r}, got ${e.length}`); + return c ? m1(e) : l1(e); + } + }); + return Object.freeze(d); +} +function C(e) { + if ("bigint" != typeof e) throw new Error("field order must be bigint"); + const t = e.toString(2).length; + return Math.ceil(t / 8); +} +function Y(e) { + const t = C(e); + return t + Math.ceil(t / 2); +} +const L = l1; +function $(e, t) { + if (e < 0 || e >= 1 << 8 * t) throw new Error(`bad I2OSP call: value=${e} length=${t}`); + const c = Array.from({ + length: t + }).fill(0); + for(let a = t - 1; a >= 0; a--)c[a] = 255 & e, e >>>= 8; + return new Uint8Array(c); +} +function z(e, t) { + const c = new Uint8Array(e.length); + for(let a = 0; a < e.length; a++)c[a] = e[a] ^ t[a]; + return c; +} +function K(e) { + if (!Number.isSafeInteger(e)) throw new Error("number expected"); +} +function k(e, t, c) { + I(c, { + DST: "stringOrUint8Array", + p: "bigint", + m: "isSafeInteger", + k: "isSafeInteger", + hash: "hash" + }); + const { p: a, k: f, m: r, hash: d, expand: i, DST: o } = c; + n1(e), K(t); + const b = "string" == typeof o ? x(o) : o, s = a.toString(2).length, u = Math.ceil((s + f) / 8), l = t * r * u; + let m; + if ("xmd" === i) m = function(e, t, c, a) { + n1(e), n1(t), K(c), t.length > 255 && (t = a(B(x("H2C-OVERSIZE-DST-"), t))); + const { outputLen: f, blockLen: r } = a, d = Math.ceil(c / f); + if (d > 255) throw new Error("Invalid xmd length"); + const i = B(t, $(t.length, 1)), o = $(0, r), b = $(c, 2), s = new Array(d), u = a(B(o, e, b, $(0, 1), i)); + s[0] = a(B(u, $(1, 1), i)); + for(let e = 1; e <= d; e++){ + const t = [ + z(u, s[e - 1]), + $(e + 1, 1), + i + ]; + s[e] = a(B(...t)); + } + return B(...s).slice(0, c); + }(e, b, l, d); + else if ("xof" === i) m = function(e, t, c, a, f) { + if (n1(e), n1(t), K(c), t.length > 255) { + const e = Math.ceil(2 * a / 8); + t = f.create({ + dkLen: e + }).update(x("H2C-OVERSIZE-DST-")).update(t).digest(); + } + if (c > 65535 || t.length > 255) throw new Error("expand_message_xof: invalid lenInBytes"); + return f.create({ + dkLen: c + }).update(e).update($(c, 2)).update(t).update($(t.length, 1)).digest(); + }(e, b, l, f, d); + else { + if ("_internal_pass" !== i) throw new Error('expand must be "xmd" or "xof"'); + m = e; + } + const p = new Array(t); + for(let e = 0; e < t; e++){ + const t = new Array(r); + for(let c = 0; c < r; c++){ + const f = u * (c + e * r), n = m.subarray(f, f + u); + t[c] = N(L(n), a); + } + p[e] = t; + } + return p; +} +function H(e, t) { + const c = t.map((e)=>Array.from(e).reverse()); + return (t, a)=>{ + const [f, r, n, d] = c.map((c)=>c.reduce((c, a)=>e.add(e.mul(c, t), a))); + return t = e.div(f, r), a = e.mul(a, e.div(n, d)), { + x: t, + y: a + }; + }; +} +function W(e, t, c) { + if ("function" != typeof t) throw new Error("mapToCurve() must be defined"); + return { + hashToCurve (a, f) { + const r = k(a, 2, { + ...c, + DST: c.DST, + ...f + }), n = e.fromAffine(t(r[0])), d = e.fromAffine(t(r[1])), i = n.add(d).clearCofactor(); + return i.assertValidity(), i; + }, + encodeToCurve (a, f) { + const r = k(a, 1, { + ...c, + DST: c.encodeDST, + ...f + }), n = e.fromAffine(t(r[0])).clearCofactor(); + return n.assertValidity(), n; + }, + mapToCurve (c) { + if (!Array.isArray(c)) throw new Error("mapToCurve: expected array of bigints"); + for (const e of c)if ("bigint" != typeof e) throw new Error(`mapToCurve: expected array of bigints, got ${e} in array`); + const a = e.fromAffine(t(c)).clearCofactor(); + return a.assertValidity(), a; + } + }; +} +const X = BigInt(0), J = BigInt(1); +function Q(e) { + const t = function(e) { + return G(e.Fp), I(e, { + n: "bigint", + h: "bigint", + Gx: "field", + Gy: "field" + }, { + nBitLength: "isSafeInteger", + nByteLength: "isSafeInteger" + }), Object.freeze({ + ...M(e.n, e.nBitLength), + ...e, + p: e.Fp.ORDER + }); + }(e); + I(t, { + a: "field", + b: "field" + }, { + allowedPrivateKeyLengths: "array", + wrapPrivateKey: "boolean", + isTorsionFree: "function", + clearCofactor: "function", + allowInfinityPoint: "boolean", + fromBytes: "function", + toBytes: "function" + }); + const { endo: c, Fp: a, a: f } = t; + if (c) { + if (!a.eql(f, a.ZERO)) throw new Error("Endomorphism can only be defined for Koblitz curves that have a=0"); + if ("object" != typeof c || "bigint" != typeof c.beta || "function" != typeof c.splitScalar) throw new Error("Expected endomorphism with beta: bigint and splitScalar: function"); + } + return Object.freeze({ + ...t + }); +} +const ee = BigInt(0), te = BigInt(1), ce = BigInt(2), ae = BigInt(3), fe = BigInt(4); +function re(e) { + const t = Q(e), { Fp: c } = t, a = t.toBytes || ((e, t, a)=>{ + const f = t.toAffine(); + return B(Uint8Array.from([ + 4 + ]), c.toBytes(f.x), c.toBytes(f.y)); + }), f = t.fromBytes || ((e)=>{ + const t = e.subarray(1); + return { + x: c.fromBytes(t.subarray(0, c.BYTES)), + y: c.fromBytes(t.subarray(c.BYTES, 2 * c.BYTES)) + }; + }); + function n(e) { + const { a: a, b: f } = t, r = c.sqr(e), n = c.mul(r, e); + return c.add(c.add(n, c.mul(e, a)), f); + } + if (!c.eql(c.sqr(t.Gy), n(t.Gx))) throw new Error("bad generator point: equation left != right"); + function d(e) { + return "bigint" == typeof e && ee < e && e < t.n; + } + function o(e) { + if (!d(e)) throw new Error("Expected valid bigint: 0 < bigint < curve.n"); + } + function b(e) { + const { allowedPrivateKeyLengths: c, nByteLength: a, wrapPrivateKey: f, n: n } = t; + if (c && "bigint" != typeof e) { + if (r1(e) && (e = i1(e)), "string" != typeof e || !c.includes(e.length)) throw new Error("Invalid key"); + e = e.padStart(2 * a, "0"); + } + let d; + try { + d = "bigint" == typeof e ? e : l1(y("private key", e, a)); + } catch (t) { + throw new Error(`private key must be ${a} bytes, hex or bigint, not ${typeof e}`); + } + return f && (d = N(d, n)), o(d), d; + } + const s = new Map; + function u(e) { + if (!(e instanceof m)) throw new Error("ProjectivePoint expected"); + } + class m { + constructor(e, t, a){ + if (this.px = e, this.py = t, this.pz = a, null == e || !c.isValid(e)) throw new Error("x required"); + if (null == t || !c.isValid(t)) throw new Error("y required"); + if (null == a || !c.isValid(a)) throw new Error("z required"); + } + static fromAffine(e) { + const { x: t, y: a } = e || {}; + if (!e || !c.isValid(t) || !c.isValid(a)) throw new Error("invalid affine point"); + if (e instanceof m) throw new Error("projective point not allowed"); + const f = (e)=>c.eql(e, c.ZERO); + return f(t) && f(a) ? m.ZERO : new m(t, a, c.ONE); + } + get x() { + return this.toAffine().x; + } + get y() { + return this.toAffine().y; + } + static normalizeZ(e) { + const t = c.invertBatch(e.map((e)=>e.pz)); + return e.map((e, c)=>e.toAffine(t[c])).map(m.fromAffine); + } + static fromHex(e) { + const t = m.fromAffine(f(y("pointHex", e))); + return t.assertValidity(), t; + } + static fromPrivateKey(e) { + return m.BASE.multiply(b(e)); + } + _setWindowSize(e) { + this._WINDOW_SIZE = e, s.delete(this); + } + assertValidity() { + if (this.is0()) { + if (t.allowInfinityPoint && !c.is0(this.py)) return; + throw new Error("bad point: ZERO"); + } + const { x: e, y: a } = this.toAffine(); + if (!c.isValid(e) || !c.isValid(a)) throw new Error("bad point: x or y not FE"); + const f = c.sqr(a), r = n(e); + if (!c.eql(f, r)) throw new Error("bad point: equation left != right"); + if (!this.isTorsionFree()) throw new Error("bad point: not in prime-order subgroup"); + } + hasEvenY() { + const { y: e } = this.toAffine(); + if (c.isOdd) return !c.isOdd(e); + throw new Error("Field doesn't support isOdd"); + } + equals(e) { + u(e); + const { px: t, py: a, pz: f } = this, { px: r, py: n, pz: d } = e, i = c.eql(c.mul(t, d), c.mul(r, f)), o = c.eql(c.mul(a, d), c.mul(n, f)); + return i && o; + } + negate() { + return new m(this.px, c.neg(this.py), this.pz); + } + double() { + const { a: e, b: a } = t, f = c.mul(a, ae), { px: r, py: n, pz: d } = this; + let i = c.ZERO, o = c.ZERO, b = c.ZERO, s = c.mul(r, r), u = c.mul(n, n), l = c.mul(d, d), p = c.mul(r, n); + return p = c.add(p, p), b = c.mul(r, d), b = c.add(b, b), i = c.mul(e, b), o = c.mul(f, l), o = c.add(i, o), i = c.sub(u, o), o = c.add(u, o), o = c.mul(i, o), i = c.mul(p, i), b = c.mul(f, b), l = c.mul(e, l), p = c.sub(s, l), p = c.mul(e, p), p = c.add(p, b), b = c.add(s, s), s = c.add(b, s), s = c.add(s, l), s = c.mul(s, p), o = c.add(o, s), l = c.mul(n, d), l = c.add(l, l), s = c.mul(l, p), i = c.sub(i, s), b = c.mul(l, u), b = c.add(b, b), b = c.add(b, b), new m(i, o, b); + } + add(e) { + u(e); + const { px: a, py: f, pz: r } = this, { px: n, py: d, pz: i } = e; + let o = c.ZERO, b = c.ZERO, s = c.ZERO; + const l = t.a, p = c.mul(t.b, ae); + let g = c.mul(a, n), y = c.mul(f, d), B = c.mul(r, i), x = c.add(a, f), E = c.add(n, d); + x = c.mul(x, E), E = c.add(g, y), x = c.sub(x, E), E = c.add(a, r); + let h = c.add(n, i); + return E = c.mul(E, h), h = c.add(g, B), E = c.sub(E, h), h = c.add(f, r), o = c.add(d, i), h = c.mul(h, o), o = c.add(y, B), h = c.sub(h, o), s = c.mul(l, E), o = c.mul(p, B), s = c.add(o, s), o = c.sub(y, s), s = c.add(y, s), b = c.mul(o, s), y = c.add(g, g), y = c.add(y, g), B = c.mul(l, B), E = c.mul(p, E), y = c.add(y, B), B = c.sub(g, B), B = c.mul(l, B), E = c.add(E, B), g = c.mul(y, E), b = c.add(b, g), g = c.mul(h, E), o = c.mul(x, o), o = c.sub(o, g), g = c.mul(x, y), s = c.mul(h, s), s = c.add(s, g), new m(o, b, s); + } + subtract(e) { + return this.add(e.negate()); + } + is0() { + return this.equals(m.ZERO); + } + wNAF(e) { + return g.wNAFCached(this, s, e, (e)=>{ + const t = c.invertBatch(e.map((e)=>e.pz)); + return e.map((e, c)=>e.toAffine(t[c])).map(m.fromAffine); + }); + } + multiplyUnsafe(e) { + const a = m.ZERO; + if (e === ee) return a; + if (o(e), e === te) return this; + const { endo: f } = t; + if (!f) return g.unsafeLadder(this, e); + let { k1neg: r, k1: n, k2neg: d, k2: i } = f.splitScalar(e), b = a, s = a, u = this; + for(; n > ee || i > ee;)n & te && (b = b.add(u)), i & te && (s = s.add(u)), u = u.double(), n >>= te, i >>= te; + return r && (b = b.negate()), d && (s = s.negate()), s = new m(c.mul(s.px, f.beta), s.py, s.pz), b.add(s); + } + multiply(e) { + o(e); + let a, f, r = e; + const { endo: n } = t; + if (n) { + const { k1neg: e, k1: t, k2neg: d, k2: i } = n.splitScalar(r); + let { p: o, f: b } = this.wNAF(t), { p: s, f: u } = this.wNAF(i); + o = g.constTimeNegate(e, o), s = g.constTimeNegate(d, s), s = new m(c.mul(s.px, n.beta), s.py, s.pz), a = o.add(s), f = b.add(u); + } else { + const { p: e, f: t } = this.wNAF(r); + a = e, f = t; + } + return m.normalizeZ([ + a, + f + ])[0]; + } + multiplyAndAddUnsafe(e, t, c) { + const a = m.BASE, f = (e, t)=>t !== ee && t !== te && e.equals(a) ? e.multiply(t) : e.multiplyUnsafe(t), r = f(this, t).add(f(e, c)); + return r.is0() ? void 0 : r; + } + toAffine(e) { + const { px: t, py: a, pz: f } = this, r = this.is0(); + null == e && (e = r ? c.ONE : c.inv(f)); + const n = c.mul(t, e), d = c.mul(a, e), i = c.mul(f, e); + if (r) return { + x: c.ZERO, + y: c.ZERO + }; + if (!c.eql(i, c.ONE)) throw new Error("invZ was invalid"); + return { + x: n, + y: d + }; + } + isTorsionFree() { + const { h: e, isTorsionFree: c } = t; + if (e === te) return !0; + if (c) return c(m, this); + throw new Error("isTorsionFree() has not been declared for the elliptic curve"); + } + clearCofactor() { + const { h: e, clearCofactor: c } = t; + return e === te ? this : c ? c(m, this) : this.multiplyUnsafe(t.h); + } + toRawBytes(e = !0) { + return this.assertValidity(), a(m, this, e); + } + toHex(e = !0) { + return i1(this.toRawBytes(e)); + } + } + m.BASE = new m(t.Gx, t.Gy, c.ONE), m.ZERO = new m(c.ZERO, c.ONE, c.ZERO); + const p = t.nBitLength, g = function(e, t) { + const c = (e, t)=>{ + const c = t.negate(); + return e ? c : t; + }, a = (e)=>({ + windows: Math.ceil(t / e) + 1, + windowSize: 2 ** (e - 1) + }); + return { + constTimeNegate: c, + unsafeLadder (t, c) { + let a = e.ZERO, f = t; + for(; c > X;)c & J && (a = a.add(f)), f = f.double(), c >>= J; + return a; + }, + precomputeWindow (e, t) { + const { windows: c, windowSize: f } = a(t), r = []; + let n = e, d = n; + for(let e = 0; e < c; e++){ + d = n, r.push(d); + for(let e = 1; e < f; e++)d = d.add(n), r.push(d); + n = d.double(); + } + return r; + }, + wNAF (t, f, r) { + const { windows: n, windowSize: d } = a(t); + let i = e.ZERO, o = e.BASE; + const b = BigInt(2 ** t - 1), s = 2 ** t, u = BigInt(t); + for(let e = 0; e < n; e++){ + const t = e * d; + let a = Number(r & b); + r >>= u, a > d && (a -= s, r += J); + const n = t, l = t + Math.abs(a) - 1, m = e % 2 != 0, p = a < 0; + 0 === a ? o = o.add(c(m, f[n])) : i = i.add(c(p, f[l])); + } + return { + p: i, + f: o + }; + }, + wNAFCached (e, t, c, a) { + const f = e._WINDOW_SIZE || 1; + let r = t.get(e); + return r || (r = this.precomputeWindow(e, f), 1 !== f && t.set(e, a(r))), this.wNAF(f, r, c); + } + }; + }(m, t.endo ? Math.ceil(p / 2) : p); + return { + CURVE: t, + ProjectivePoint: m, + normPrivateKeyToScalar: b, + weierstrassEquation: n, + isWithinCurveOrder: d + }; +} +function ne(e, t) { + if (G(e), !e.isValid(t.A) || !e.isValid(t.B) || !e.isValid(t.Z)) throw new Error("mapToCurveSimpleSWU: invalid opts"); + const c = function(e, t) { + const c = e.ORDER; + let a = ee; + for(let e = c - te; e % ce === ee; e /= ce)a += te; + const f = a, r = ce << f - te - te, n = r * ce, d = (c - te) / n, i = (d - te) / ce, o = n - te, b = r, s = e.pow(t, d), u = e.pow(t, (d + te) / ce); + let l = (t, c)=>{ + let a = s, r = e.pow(c, o), n = e.sqr(r); + n = e.mul(n, c); + let d = e.mul(t, n); + d = e.pow(d, i), d = e.mul(d, r), r = e.mul(d, c), n = e.mul(d, t); + let l = e.mul(n, r); + d = e.pow(l, b); + let m = e.eql(d, e.ONE); + r = e.mul(n, u), d = e.mul(l, a), n = e.cmov(r, n, m), l = e.cmov(d, l, m); + for(let t = f; t > te; t--){ + let c = t - ce; + c = ce << c - te; + let f = e.pow(l, c); + const d = e.eql(f, e.ONE); + r = e.mul(n, a), a = e.mul(a, a), f = e.mul(l, a), n = e.cmov(r, n, d), l = e.cmov(f, l, d); + } + return { + isValid: m, + value: n + }; + }; + if (e.ORDER % fe === ae) { + const c = (e.ORDER - ae) / fe, a = e.sqrt(e.neg(t)); + l = (t, f)=>{ + let r = e.sqr(f); + const n = e.mul(t, f); + r = e.mul(r, n); + let d = e.pow(r, c); + d = e.mul(d, n); + const i = e.mul(d, a), o = e.mul(e.sqr(d), f), b = e.eql(o, t); + return { + isValid: b, + value: e.cmov(i, d, b) + }; + }; + } + return l; + }(e, t.Z); + if (!e.isOdd) throw new Error("Fp.isOdd is not implemented!"); + return (a)=>{ + let f, r, n, d, i, o, b, s; + f = e.sqr(a), f = e.mul(f, t.Z), r = e.sqr(f), r = e.add(r, f), n = e.add(r, e.ONE), n = e.mul(n, t.B), d = e.cmov(t.Z, e.neg(r), !e.eql(r, e.ZERO)), d = e.mul(d, t.A), r = e.sqr(n), o = e.sqr(d), i = e.mul(o, t.A), r = e.add(r, i), r = e.mul(r, n), o = e.mul(o, d), i = e.mul(o, t.B), r = e.add(r, i), b = e.mul(f, n); + const { isValid: u, value: l } = c(r, o); + s = e.mul(f, a), s = e.mul(s, l), b = e.cmov(b, n, u), s = e.cmov(s, l, u); + const m = e.isOdd(a) === e.isOdd(s); + return s = e.cmov(e.neg(s), s, m), b = e.div(b, d), { + x: b, + y: s + }; + }; +} +const de = BigInt(2), ie = BigInt(3); +const oe = BigInt(0), be = BigInt(1), se = BigInt(2), ue = BigInt(3), le = BigInt(4), me = BigInt(8), pe = BigInt(16), ge = BigInt("0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"), ye = U(ge), Be = U(BigInt("0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001")), xe = ({ c0: e, c1: t }, { c0: c, c1: a })=>({ + c0: ye.add(e, c), + c1: ye.add(t, a) + }), Ee = ({ c0: e, c1: t }, { c0: c, c1: a })=>({ + c0: ye.sub(e, c), + c1: ye.sub(t, a) + }), he = ({ c0: e, c1: t }, c)=>{ + if ("bigint" == typeof c) return { + c0: ye.mul(e, c), + c1: ye.mul(t, c) + }; + const { c0: a, c1: f } = c; + let r = ye.mul(e, a), n = ye.mul(t, f); + return { + c0: ye.sub(r, n), + c1: ye.sub(ye.mul(ye.add(e, t), ye.add(a, f)), ye.add(r, n)) + }; +}, we = ({ c0: e, c1: t })=>{ + const c = ye.add(e, t), a = ye.sub(e, t), f = ye.add(e, e); + return { + c0: ye.mul(c, a), + c1: ye.mul(f, t) + }; +}, ve = ge * ge, Ie = { + ORDER: ve, + BITS: E(ve), + BYTES: Math.ceil(E(ve) / 8), + MASK: w(E(ve)), + ZERO: { + c0: ye.ZERO, + c1: ye.ZERO + }, + ONE: { + c0: ye.ONE, + c1: ye.ZERO + }, + create: (e)=>e, + isValid: ({ c0: e, c1: t })=>"bigint" == typeof e && "bigint" == typeof t, + is0: ({ c0: e, c1: t })=>ye.is0(e) && ye.is0(t), + eql: ({ c0: e, c1: t }, { c0: c, c1: a })=>ye.eql(e, c) && ye.eql(t, a), + neg: ({ c0: e, c1: t })=>({ + c0: ye.neg(e), + c1: ye.neg(t) + }), + pow: (e, t)=>D(Ie, e, t), + invertBatch: (e)=>V(Ie, e), + add: xe, + sub: Ee, + mul: he, + sqr: we, + addN: xe, + subN: Ee, + mulN: he, + sqrN: we, + div: (e, t)=>Ie.mul(e, "bigint" == typeof t ? ye.inv(ye.create(t)) : Ie.inv(t)), + inv: ({ c0: e, c1: t })=>{ + const c = ye.inv(ye.create(e * e + t * t)); + return { + c0: ye.mul(c, ye.create(e)), + c1: ye.mul(c, ye.create(-t)) + }; + }, + sqrt: (e)=>{ + if (Ie.eql(e, Ie.ZERO)) return Ie.ZERO; + const t = Ie.pow(e, (Ie.ORDER + me) / pe), c = Ie.div(Ie.sqr(t), e), a = Re, f = [ + a[0], + a[2], + a[4], + a[6] + ].find((e)=>Ie.eql(e, c)); + if (!f) throw new Error("No root"); + const r = a.indexOf(f), n = a[r / 2]; + if (!n) throw new Error("Invalid root"); + const d = Ie.div(t, n), i = Ie.neg(d), { re: o, im: b } = Ie.reim(d), { re: s, im: u } = Ie.reim(i); + return b > u || b === u && o > s ? d : i; + }, + isOdd: (e)=>{ + const { re: t, im: c } = Ie.reim(e); + return BigInt(t % se || t === oe && c % se) == be; + }, + fromBytes (e) { + if (e.length !== Ie.BYTES) throw new Error(`fromBytes wrong length=${e.length}`); + return { + c0: ye.fromBytes(e.subarray(0, ye.BYTES)), + c1: ye.fromBytes(e.subarray(ye.BYTES)) + }; + }, + toBytes: ({ c0: e, c1: t })=>B(ye.toBytes(e), ye.toBytes(t)), + cmov: ({ c0: e, c1: t }, { c0: c, c1: a }, f)=>({ + c0: ye.cmov(e, c, f), + c1: ye.cmov(t, a, f) + }), + reim: ({ c0: e, c1: t })=>({ + re: e, + im: t + }), + mulByNonresidue: ({ c0: e, c1: t })=>({ + c0: ye.sub(e, t), + c1: ye.add(e, t) + }), + multiplyByB: ({ c0: e, c1: t })=>{ + let c = ye.mul(e, le), a = ye.mul(t, le); + return { + c0: ye.sub(c, a), + c1: ye.add(c, a) + }; + }, + fromBigTuple: (e)=>{ + if (2 !== e.length) throw new Error("Invalid tuple"); + const t = e.map((e)=>ye.create(e)); + return { + c0: t[0], + c1: t[1] + }; + }, + frobeniusMap: ({ c0: e, c1: t }, c)=>({ + c0: e, + c1: ye.mul(t, Oe[c % 2]) + }) +}, Oe = [ + BigInt("0x1"), + BigInt("0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa") +].map((e)=>ye.create(e)), Se = BigInt("0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"), Re = [ + [ + be, + oe + ], + [ + Se, + -Se + ], + [ + oe, + be + ], + [ + Se, + Se + ], + [ + -be, + oe + ], + [ + -Se, + Se + ], + [ + oe, + -be + ], + [ + -Se, + -Se + ] +].map((e)=>Ie.fromBigTuple(e)), qe = ({ c0: e, c1: t, c2: c }, { c0: a, c1: f, c2: r })=>({ + c0: Ie.add(e, a), + c1: Ie.add(t, f), + c2: Ie.add(c, r) + }), Pe = ({ c0: e, c1: t, c2: c }, { c0: a, c1: f, c2: r })=>({ + c0: Ie.sub(e, a), + c1: Ie.sub(t, f), + c2: Ie.sub(c, r) + }), Te = ({ c0: e, c1: t, c2: c }, a)=>{ + if ("bigint" == typeof a) return { + c0: Ie.mul(e, a), + c1: Ie.mul(t, a), + c2: Ie.mul(c, a) + }; + const { c0: f, c1: r, c2: n } = a, d = Ie.mul(e, f), i = Ie.mul(t, r), o = Ie.mul(c, n); + return { + c0: Ie.add(d, Ie.mulByNonresidue(Ie.sub(Ie.mul(Ie.add(t, c), Ie.add(r, n)), Ie.add(i, o)))), + c1: Ie.add(Ie.sub(Ie.mul(Ie.add(e, t), Ie.add(f, r)), Ie.add(d, i)), Ie.mulByNonresidue(o)), + c2: Ie.sub(Ie.add(i, Ie.mul(Ie.add(e, c), Ie.add(f, n))), Ie.add(d, o)) + }; +}, Ae = ({ c0: e, c1: t, c2: c })=>{ + let a = Ie.sqr(e), f = Ie.mul(Ie.mul(e, t), se), r = Ie.mul(Ie.mul(t, c), se), n = Ie.sqr(c); + return { + c0: Ie.add(Ie.mulByNonresidue(r), a), + c1: Ie.add(Ie.mulByNonresidue(n), f), + c2: Ie.sub(Ie.sub(Ie.add(Ie.add(f, Ie.sqr(Ie.add(Ie.sub(e, t), c))), r), a), n) + }; +}, Ne = { + ORDER: Ie.ORDER, + BITS: 3 * Ie.BITS, + BYTES: 3 * Ie.BYTES, + MASK: w(3 * Ie.BITS), + ZERO: { + c0: Ie.ZERO, + c1: Ie.ZERO, + c2: Ie.ZERO + }, + ONE: { + c0: Ie.ONE, + c1: Ie.ZERO, + c2: Ie.ZERO + }, + create: (e)=>e, + isValid: ({ c0: e, c1: t, c2: c })=>Ie.isValid(e) && Ie.isValid(t) && Ie.isValid(c), + is0: ({ c0: e, c1: t, c2: c })=>Ie.is0(e) && Ie.is0(t) && Ie.is0(c), + neg: ({ c0: e, c1: t, c2: c })=>({ + c0: Ie.neg(e), + c1: Ie.neg(t), + c2: Ie.neg(c) + }), + eql: ({ c0: e, c1: t, c2: c }, { c0: a, c1: f, c2: r })=>Ie.eql(e, a) && Ie.eql(t, f) && Ie.eql(c, r), + sqrt: ()=>{ + throw new Error("Not implemented"); + }, + div: (e, t)=>Ne.mul(e, "bigint" == typeof t ? ye.inv(ye.create(t)) : Ne.inv(t)), + pow: (e, t)=>D(Ne, e, t), + invertBatch: (e)=>V(Ne, e), + add: qe, + sub: Pe, + mul: Te, + sqr: Ae, + addN: qe, + subN: Pe, + mulN: Te, + sqrN: Ae, + inv: ({ c0: e, c1: t, c2: c })=>{ + let a = Ie.sub(Ie.sqr(e), Ie.mulByNonresidue(Ie.mul(c, t))), f = Ie.sub(Ie.mulByNonresidue(Ie.sqr(c)), Ie.mul(e, t)), r = Ie.sub(Ie.sqr(t), Ie.mul(e, c)), n = Ie.inv(Ie.add(Ie.mulByNonresidue(Ie.add(Ie.mul(c, f), Ie.mul(t, r))), Ie.mul(e, a))); + return { + c0: Ie.mul(n, a), + c1: Ie.mul(n, f), + c2: Ie.mul(n, r) + }; + }, + fromBytes: (e)=>{ + if (e.length !== Ne.BYTES) throw new Error(`fromBytes wrong length=${e.length}`); + return { + c0: Ie.fromBytes(e.subarray(0, Ie.BYTES)), + c1: Ie.fromBytes(e.subarray(Ie.BYTES, 2 * Ie.BYTES)), + c2: Ie.fromBytes(e.subarray(2 * Ie.BYTES)) + }; + }, + toBytes: ({ c0: e, c1: t, c2: c })=>B(Ie.toBytes(e), Ie.toBytes(t), Ie.toBytes(c)), + cmov: ({ c0: e, c1: t, c2: c }, { c0: a, c1: f, c2: r }, n)=>({ + c0: Ie.cmov(e, a, n), + c1: Ie.cmov(t, f, n), + c2: Ie.cmov(c, r, n) + }), + fromBigSix: (e)=>{ + if (!Array.isArray(e) || 6 !== e.length) throw new Error("Invalid Fp6 usage"); + return { + c0: Ie.fromBigTuple(e.slice(0, 2)), + c1: Ie.fromBigTuple(e.slice(2, 4)), + c2: Ie.fromBigTuple(e.slice(4, 6)) + }; + }, + frobeniusMap: ({ c0: e, c1: t, c2: c }, a)=>({ + c0: Ie.frobeniusMap(e, a), + c1: Ie.mul(Ie.frobeniusMap(t, a), Ze[a % 6]), + c2: Ie.mul(Ie.frobeniusMap(c, a), _e[a % 6]) + }), + mulByNonresidue: ({ c0: e, c1: t, c2: c })=>({ + c0: Ie.mulByNonresidue(c), + c1: e, + c2: t + }), + multiplyBy1: ({ c0: e, c1: t, c2: c }, a)=>({ + c0: Ie.mulByNonresidue(Ie.mul(c, a)), + c1: Ie.mul(e, a), + c2: Ie.mul(t, a) + }), + multiplyBy01 ({ c0: e, c1: t, c2: c }, a, f) { + let r = Ie.mul(e, a), n = Ie.mul(t, f); + return { + c0: Ie.add(Ie.mulByNonresidue(Ie.sub(Ie.mul(Ie.add(t, c), f), n)), r), + c1: Ie.sub(Ie.sub(Ie.mul(Ie.add(a, f), Ie.add(e, t)), r), n), + c2: Ie.add(Ie.sub(Ie.mul(Ie.add(e, c), a), r), n) + }; + }, + multiplyByFp2: ({ c0: e, c1: t, c2: c }, a)=>({ + c0: Ie.mul(e, a), + c1: Ie.mul(t, a), + c2: Ie.mul(c, a) + }) +}, Ze = [ + [ + BigInt("0x1"), + BigInt("0x0") + ], + [ + BigInt("0x0"), + BigInt("0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac") + ], + [ + BigInt("0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe"), + BigInt("0x0") + ], + [ + BigInt("0x0"), + BigInt("0x1") + ], + [ + BigInt("0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac"), + BigInt("0x0") + ], + [ + BigInt("0x0"), + BigInt("0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe") + ] +].map((e)=>Ie.fromBigTuple(e)), _e = [ + [ + BigInt("0x1"), + BigInt("0x0") + ], + [ + BigInt("0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad"), + BigInt("0x0") + ], + [ + BigInt("0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac"), + BigInt("0x0") + ], + [ + BigInt("0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa"), + BigInt("0x0") + ], + [ + BigInt("0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe"), + BigInt("0x0") + ], + [ + BigInt("0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff"), + BigInt("0x0") + ] +].map((e)=>Ie.fromBigTuple(e)), je = BigInt("0xd201000000010000"), Fe = E(je), Ge = ({ c0: e, c1: t }, { c0: c, c1: a })=>({ + c0: Ne.add(e, c), + c1: Ne.add(t, a) + }), De = ({ c0: e, c1: t }, { c0: c, c1: a })=>({ + c0: Ne.sub(e, c), + c1: Ne.sub(t, a) + }), Ve = ({ c0: e, c1: t }, c)=>{ + if ("bigint" == typeof c) return { + c0: Ne.mul(e, c), + c1: Ne.mul(t, c) + }; + let { c0: a, c1: f } = c, r = Ne.mul(e, a), n = Ne.mul(t, f); + return { + c0: Ne.add(r, Ne.mulByNonresidue(n)), + c1: Ne.sub(Ne.mul(Ne.add(e, t), Ne.add(a, f)), Ne.add(r, n)) + }; +}, Me = ({ c0: e, c1: t })=>{ + let c = Ne.mul(e, t); + return { + c0: Ne.sub(Ne.sub(Ne.mul(Ne.add(Ne.mulByNonresidue(t), e), Ne.add(e, t)), c), Ne.mulByNonresidue(c)), + c1: Ne.add(c, c) + }; +}; +function Ue(e, t) { + const c = Ie.sqr(e), a = Ie.sqr(t); + return { + first: Ie.add(Ie.mulByNonresidue(a), c), + second: Ie.sub(Ie.sub(Ie.sqr(Ie.add(e, t)), c), a) + }; +} +const Ce = { + ORDER: Ie.ORDER, + BITS: 2 * Ie.BITS, + BYTES: 2 * Ie.BYTES, + MASK: w(2 * Ie.BITS), + ZERO: { + c0: Ne.ZERO, + c1: Ne.ZERO + }, + ONE: { + c0: Ne.ONE, + c1: Ne.ZERO + }, + create: (e)=>e, + isValid: ({ c0: e, c1: t })=>Ne.isValid(e) && Ne.isValid(t), + is0: ({ c0: e, c1: t })=>Ne.is0(e) && Ne.is0(t), + neg: ({ c0: e, c1: t })=>({ + c0: Ne.neg(e), + c1: Ne.neg(t) + }), + eql: ({ c0: e, c1: t }, { c0: c, c1: a })=>Ne.eql(e, c) && Ne.eql(t, a), + sqrt: ()=>{ + throw new Error("Not implemented"); + }, + inv: ({ c0: e, c1: t })=>{ + let c = Ne.inv(Ne.sub(Ne.sqr(e), Ne.mulByNonresidue(Ne.sqr(t)))); + return { + c0: Ne.mul(e, c), + c1: Ne.neg(Ne.mul(t, c)) + }; + }, + div: (e, t)=>Ce.mul(e, "bigint" == typeof t ? ye.inv(ye.create(t)) : Ce.inv(t)), + pow: (e, t)=>D(Ce, e, t), + invertBatch: (e)=>V(Ce, e), + add: Ge, + sub: De, + mul: Ve, + sqr: Me, + addN: Ge, + subN: De, + mulN: Ve, + sqrN: Me, + fromBytes: (e)=>{ + if (e.length !== Ce.BYTES) throw new Error(`fromBytes wrong length=${e.length}`); + return { + c0: Ne.fromBytes(e.subarray(0, Ne.BYTES)), + c1: Ne.fromBytes(e.subarray(Ne.BYTES)) + }; + }, + toBytes: ({ c0: e, c1: t })=>B(Ne.toBytes(e), Ne.toBytes(t)), + cmov: ({ c0: e, c1: t }, { c0: c, c1: a }, f)=>({ + c0: Ne.cmov(e, c, f), + c1: Ne.cmov(t, a, f) + }), + fromBigTwelve: (e)=>({ + c0: Ne.fromBigSix(e.slice(0, 6)), + c1: Ne.fromBigSix(e.slice(6, 12)) + }), + frobeniusMap (e, t) { + const c = Ne.frobeniusMap(e.c0, t), { c0: a, c1: f, c2: r } = Ne.frobeniusMap(e.c1, t), n = Ye[t % 12]; + return { + c0: c, + c1: Ne.create({ + c0: Ie.mul(a, n), + c1: Ie.mul(f, n), + c2: Ie.mul(r, n) + }) + }; + }, + multiplyBy014: ({ c0: e, c1: t }, c, a, f)=>{ + let r = Ne.multiplyBy01(e, c, a), n = Ne.multiplyBy1(t, f); + return { + c0: Ne.add(Ne.mulByNonresidue(n), r), + c1: Ne.sub(Ne.sub(Ne.multiplyBy01(Ne.add(t, e), c, Ie.add(a, f)), r), n) + }; + }, + multiplyByFp2: ({ c0: e, c1: t }, c)=>({ + c0: Ne.multiplyByFp2(e, c), + c1: Ne.multiplyByFp2(t, c) + }), + conjugate: ({ c0: e, c1: t })=>({ + c0: e, + c1: Ne.neg(t) + }), + _cyclotomicSquare: ({ c0: e, c1: t })=>{ + const { c0: c, c1: a, c2: f } = e, { c0: r, c1: n, c2: d } = t, { first: i, second: o } = Ue(c, n), { first: b, second: s } = Ue(r, f), { first: u, second: l } = Ue(a, d); + let m = Ie.mulByNonresidue(l); + return { + c0: Ne.create({ + c0: Ie.add(Ie.mul(Ie.sub(i, c), se), i), + c1: Ie.add(Ie.mul(Ie.sub(b, a), se), b), + c2: Ie.add(Ie.mul(Ie.sub(u, f), se), u) + }), + c1: Ne.create({ + c0: Ie.add(Ie.mul(Ie.add(m, r), se), m), + c1: Ie.add(Ie.mul(Ie.add(o, n), se), o), + c2: Ie.add(Ie.mul(Ie.add(s, d), se), s) + }) + }; + }, + _cyclotomicExp (e, t) { + let c = Ce.ONE; + for(let a = Fe - 1; a >= 0; a--)c = Ce._cyclotomicSquare(c), h1(t, a) && (c = Ce.mul(c, e)); + return c; + }, + finalExponentiate: (e)=>{ + const t = je, c = Ce.div(Ce.frobeniusMap(e, 6), e), a = Ce.mul(Ce.frobeniusMap(c, 2), c), f = Ce.conjugate(Ce._cyclotomicExp(a, t)), r = Ce.mul(Ce.conjugate(Ce._cyclotomicSquare(a)), f), n = Ce.conjugate(Ce._cyclotomicExp(r, t)), d = Ce.conjugate(Ce._cyclotomicExp(n, t)), i = Ce.mul(Ce.conjugate(Ce._cyclotomicExp(d, t)), Ce._cyclotomicSquare(f)), o = Ce.conjugate(Ce._cyclotomicExp(i, t)), b = Ce.frobeniusMap(Ce.mul(f, d), 2), s = Ce.frobeniusMap(Ce.mul(n, a), 3), u = Ce.frobeniusMap(Ce.mul(i, Ce.conjugate(a)), 1), l = Ce.mul(Ce.mul(o, Ce.conjugate(r)), a); + return Ce.mul(Ce.mul(Ce.mul(b, s), u), l); + } +}, Ye = [ + [ + BigInt("0x1"), + BigInt("0x0") + ], + [ + BigInt("0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8"), + BigInt("0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3") + ], + [ + BigInt("0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff"), + BigInt("0x0") + ], + [ + BigInt("0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2"), + BigInt("0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09") + ], + [ + BigInt("0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe"), + BigInt("0x0") + ], + [ + BigInt("0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995"), + BigInt("0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116") + ], + [ + BigInt("0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa"), + BigInt("0x0") + ], + [ + BigInt("0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3"), + BigInt("0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8") + ], + [ + BigInt("0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac"), + BigInt("0x0") + ], + [ + BigInt("0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"), + BigInt("0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2") + ], + [ + BigInt("0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad"), + BigInt("0x0") + ], + [ + BigInt("0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116"), + BigInt("0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995") + ] +].map((e)=>Ie.fromBigTuple(e)), Le = H(Ie, [ + [ + [ + "0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6", + "0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6" + ], + [ + "0x0", + "0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a" + ], + [ + "0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e", + "0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d" + ], + [ + "0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1", + "0x0" + ] + ], + [ + [ + "0x0", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63" + ], + [ + "0xc", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f" + ], + [ + "0x1", + "0x0" + ] + ], + [ + [ + "0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706", + "0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706" + ], + [ + "0x0", + "0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be" + ], + [ + "0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c", + "0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f" + ], + [ + "0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10", + "0x0" + ] + ], + [ + [ + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb" + ], + [ + "0x0", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3" + ], + [ + "0x12", + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99" + ], + [ + "0x1", + "0x0" + ] + ] +].map((e)=>e.map((e)=>Ie.fromBigTuple(e.map(BigInt))))), $e = H(ye, [ + [ + "0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7", + "0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb", + "0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0", + "0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861", + "0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9", + "0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983", + "0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84", + "0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e", + "0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317", + "0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e", + "0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b", + "0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229" + ], + [ + "0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c", + "0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff", + "0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19", + "0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8", + "0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e", + "0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5", + "0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a", + "0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e", + "0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641", + "0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a", + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" + ], + [ + "0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33", + "0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696", + "0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6", + "0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb", + "0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb", + "0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0", + "0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2", + "0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29", + "0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587", + "0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30", + "0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132", + "0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e", + "0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8", + "0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133", + "0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b", + "0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604" + ], + [ + "0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1", + "0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d", + "0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2", + "0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416", + "0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d", + "0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac", + "0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c", + "0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9", + "0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a", + "0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55", + "0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8", + "0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092", + "0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc", + "0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7", + "0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f", + "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" + ] +].map((e)=>e.map((e)=>BigInt(e)))), ze = ne(Ie, { + A: Ie.create({ + c0: ye.create(oe), + c1: ye.create(BigInt(240)) + }), + B: Ie.create({ + c0: ye.create(BigInt(1012)), + c1: ye.create(BigInt(1012)) + }), + Z: Ie.create({ + c0: ye.create(BigInt(-2)), + c1: ye.create(BigInt(-1)) + }) +}), Ke = ne(ye, { + A: ye.create(BigInt("0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d")), + B: ye.create(BigInt("0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0")), + Z: ye.create(BigInt(11)) +}), ke = Ne.create({ + c0: Ie.ZERO, + c1: Ie.ONE, + c2: Ie.ZERO +}), He = Ce.create({ + c0: ke, + c1: Ne.ZERO +}), We = Ce.create({ + c0: Ne.ZERO, + c1: ke +}), [Xe, Je] = Ce.invertBatch([ + He, + We +]); +function Qe(e, t) { + const c = t.toAffine(), a = (f = c.x, r = c.y, [ + Ce.mul(Ce.frobeniusMap(Ce.multiplyByFp2(Xe, f), 1), He).c0.c0, + Ce.mul(Ce.frobeniusMap(Ce.multiplyByFp2(Je, r), 1), We).c0.c0 + ]); + var f, r; + return new e(a[0], a[1], Ie.ONE); +} +const et = BigInt("0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac"); +function tt(e, t) { + const c = t.toAffine(), a = (f = c.x, r = c.y, [ + Ie.mul(f, et), + Ie.neg(r) + ]); + var f, r; + return new e(a[0], a[1], Ie.ONE); +} +const ct = Object.freeze({ + DST: "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_", + encodeDST: "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_", + p: ye.ORDER, + m: 2, + k: 128, + expand: "xmd", + hash: d +}), at = rt(ye.toBytes(oe), { + infinity: !0, + compressed: !0 +}); +function ft(e) { + const t = 224 & (e = e.slice())[0], c = !!(t >> 7 & 1), a = !!(t >> 6 & 1), f = !!(t >> 5 & 1); + return e[0] &= 31, { + compressed: c, + infinity: a, + sort: f, + value: e + }; +} +function rt(e, t) { + if (224 & e[0]) throw new Error("setMask: non-empty mask"); + return t.compressed && (e[0] |= 128), t.infinity && (e[0] |= 64), t.sort && (e[0] |= 32), e; +} +function nt(e) { + e.assertValidity(); + const t = e.equals(it.G1.ProjectivePoint.ZERO), { x: c, y: a } = e.toAffine(); + if (t) return at.slice(); + const f = ye.ORDER, r = Boolean(a * se / f); + return rt(p1(c, ye.BYTES), { + compressed: !0, + sort: r + }); +} +function dt(e) { + e.assertValidity(); + const t = ye.BYTES; + if (e.equals(it.G2.ProjectivePoint.ZERO)) return B(at, p1(oe, t)); + const { x: c, y: a } = e.toAffine(), { re: f, im: r } = Ie.reim(c), { re: n, im: d } = Ie.reim(a), i = Boolean((d > oe ? d * se : n * se) / ye.ORDER & be), o = f; + return B(rt(p1(r, t), { + sort: i, + compressed: !0 + }), p1(o, t)); +} +const it = function(e) { + const { Fp: t, Fr: c, Fp2: a, Fp6: f, Fp12: r } = e.fields, n = E(e.params.x); + function d(t) { + const { x: c, y: f } = t, r = c, d = f; + let i = r, o = d, b = a.ONE, s = []; + for(let t = n - 2; t >= 0; t--){ + let c = a.sqr(o), f = a.sqr(b), n = a.multiplyByB(a.mul(f, ie)), u = a.mul(n, ie), l = a.sub(a.sub(a.sqr(a.add(o, b)), f), c); + if (s.push([ + a.sub(n, c), + a.mul(a.sqr(i), ie), + a.neg(l) + ]), i = a.div(a.mul(a.mul(a.sub(c, u), i), o), de), o = a.sub(a.sqr(a.div(a.add(c, u), de)), a.mul(a.sqr(n), ie)), b = a.mul(c, l), h1(e.params.x, t)) { + let e = a.sub(o, a.mul(d, b)), t = a.sub(i, a.mul(r, b)); + s.push([ + a.sub(a.mul(e, r), a.mul(t, d)), + a.neg(e), + t + ]); + let c = a.sqr(t), f = a.mul(c, t), n = a.mul(c, i), u = a.add(a.sub(f, a.mul(n, de)), a.mul(a.sqr(e), b)); + i = a.mul(t, u), o = a.sub(a.mul(a.sub(n, u), e), a.mul(f, o)), b = a.mul(b, f); + } + } + return s; + } + function i(t, c) { + const { x: f } = e.params, d = c[0], i = c[1]; + let o = r.ONE; + for(let e = 0, c = n - 2; c >= 0; c--, e++){ + const n = t[e]; + if (o = r.multiplyBy014(o, n[0], a.mul(n[1], d), a.mul(n[2], i)), h1(f, c)) { + e += 1; + const c = t[e]; + o = r.multiplyBy014(o, c[0], a.mul(c[1], d), a.mul(c[2], i)); + } + 0 !== c && (o = r.sqr(o)); + } + return r.conjugate(o); + } + const o = { + randomPrivateKey: ()=>{ + const t = Y(c.ORDER); + return function(e, t, c = !1) { + const a = e.length, f = C(t), r = Y(t); + if (a < 16 || a < r || a > 1024) throw new Error(`expected ${r}-1024 bytes of input, got ${a}`); + const n = N(c ? l1(e) : m1(e), t - S) + S; + return c ? g1(n, f) : p1(n, f); + }(e.randomBytes(t), c.ORDER); + }, + calcPairingPrecomputes: d + }, b = re({ + n: c.ORDER, + ...e.G1 + }), s = Object.assign(b, W(b.ProjectivePoint, e.G1.mapToCurve, { + ...e.htfDefaults, + ...e.G1.htfDefaults + })), u = re({ + n: c.ORDER, + ...e.G2 + }), B = Object.assign(u, W(u.ProjectivePoint, e.G2.mapToCurve, { + ...e.htfDefaults, + ...e.G2.htfDefaults + })), { ShortSignature: x } = e.G1, { Signature: w } = e.G2; + function v(e, t, c = !0) { + if (e.equals(s.ProjectivePoint.ZERO) || t.equals(B.ProjectivePoint.ZERO)) throw new Error("pairing is not available for ZERO point"); + e.assertValidity(), t.assertValidity(); + const a = e.toAffine(), f = i(function(e) { + const t = e; + return t._PPRECOMPUTES || (t._PPRECOMPUTES = d(e.toAffine())), t._PPRECOMPUTES; + }(t), [ + a.x, + a.y + ]); + return c ? r.finalExponentiate(f) : f; + } + function I(e) { + return e instanceof s.ProjectivePoint ? e : s.ProjectivePoint.fromHex(e); + } + function O(e, t) { + return e instanceof s.ProjectivePoint ? e : s.hashToCurve(y("point", e), t); + } + function R(e) { + return e instanceof B.ProjectivePoint ? e : w.fromHex(e); + } + function q(e, t) { + return e instanceof B.ProjectivePoint ? e : B.hashToCurve(y("point", e), t); + } + return s.ProjectivePoint.BASE._setWindowSize(4), { + getPublicKey: function(e) { + return s.ProjectivePoint.fromPrivateKey(e).toRawBytes(!0); + }, + getPublicKeyForShortSignatures: function(e) { + return B.ProjectivePoint.fromPrivateKey(e).toRawBytes(!0); + }, + sign: function(e, t, c) { + const a = q(e, c); + a.assertValidity(); + const f = a.multiply(s.normPrivateKeyToScalar(t)); + return e instanceof B.ProjectivePoint ? f : w.toRawBytes(f); + }, + signShortSignature: function(e, t, c) { + const a = O(e, c); + a.assertValidity(); + const f = a.multiply(s.normPrivateKeyToScalar(t)); + return e instanceof s.ProjectivePoint ? f : x.toRawBytes(f); + }, + verify: function(e, t, c, a) { + const f = I(c), n = q(t, a), d = s.ProjectivePoint.BASE, i = R(e), o = v(f.negate(), n, !1), b = v(d, i, !1), u = r.finalExponentiate(r.mul(b, o)); + return r.eql(u, r.ONE); + }, + verifyBatch: function(e, t, c, a) { + if (!t.length) throw new Error("Expected non-empty messages array"); + if (c.length !== t.length) throw new Error("Pubkey count should equal msg count"); + const f = R(e), n = t.map((e)=>q(e, a)), d = c.map(I); + try { + const e = []; + for (const t of new Set(n)){ + const c = n.reduce((e, c, a)=>c === t ? e.add(d[a]) : e, s.ProjectivePoint.ZERO); + e.push(v(c, t, !1)); + } + e.push(v(s.ProjectivePoint.BASE.negate(), f, !1)); + const t = e.reduce((e, t)=>r.mul(e, t), r.ONE), c = r.finalExponentiate(t); + return r.eql(c, r.ONE); + } catch { + return !1; + } + }, + verifyShortSignature: function(e, t, c, a) { + const f = R(c), n = O(t, a), d = B.ProjectivePoint.BASE, i = I(e), o = v(n, f, !1), b = v(i, d.negate(), !1), s = r.finalExponentiate(r.mul(b, o)); + return r.eql(s, r.ONE); + }, + aggregatePublicKeys: function(e) { + if (!e.length) throw new Error("Expected non-empty array"); + const t = e.map(I).reduce((e, t)=>e.add(t), s.ProjectivePoint.ZERO); + return e[0] instanceof s.ProjectivePoint ? (t.assertValidity(), t) : t.toRawBytes(!0); + }, + aggregateSignatures: function(e) { + if (!e.length) throw new Error("Expected non-empty array"); + const t = e.map(R).reduce((e, t)=>e.add(t), B.ProjectivePoint.ZERO); + return e[0] instanceof B.ProjectivePoint ? (t.assertValidity(), t) : w.toRawBytes(t); + }, + aggregateShortSignatures: function(e) { + if (!e.length) throw new Error("Expected non-empty array"); + const t = e.map(I).reduce((e, t)=>e.add(t), s.ProjectivePoint.ZERO); + return e[0] instanceof s.ProjectivePoint ? (t.assertValidity(), t) : x.toRawBytes(t); + }, + millerLoop: i, + pairing: v, + G1: s, + G2: B, + Signature: w, + ShortSignature: x, + fields: { + Fr: c, + Fp: t, + Fp2: a, + Fp6: f, + Fp12: r + }, + params: { + x: e.params.x, + r: e.params.r, + G1b: e.G1.b, + G2b: e.G2.b + }, + utils: o + }; +}({ + fields: { + Fp: ye, + Fp2: Ie, + Fp6: Ne, + Fp12: Ce, + Fr: Be + }, + G1: { + Fp: ye, + h: BigInt("0x396c8c005555e1568c00aaab0000aaab"), + Gx: BigInt("0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb"), + Gy: BigInt("0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1"), + a: ye.ZERO, + b: le, + htfDefaults: { + ...ct, + m: 1, + DST: "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_" + }, + wrapPrivateKey: !0, + allowInfinityPoint: !0, + isTorsionFree: (e, t)=>{ + const c = BigInt("0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe"), a = new e(ye.mul(t.px, c), t.py, t.pz); + return t.multiplyUnsafe(it.params.x).negate().multiplyUnsafe(it.params.x).equals(a); + }, + clearCofactor: (e, t)=>t.multiplyUnsafe(it.params.x).add(t), + mapToCurve: (e)=>{ + const { x: t, y: c } = Ke(ye.create(e[0])); + return $e(t, c); + }, + fromBytes: (e)=>{ + const { compressed: t, infinity: c, sort: a, value: f } = ft(e); + if (48 === f.length && t) { + const e = ye.ORDER, t = l1(f), r = ye.create(t & ye.MASK); + if (c) { + if (r !== oe) throw new Error("G1: non-empty compressed point at infinity"); + return { + x: oe, + y: oe + }; + } + const n = ye.add(ye.pow(r, ue), ye.create(it.params.G1b)); + let d = ye.sqrt(n); + if (!d) throw new Error("Invalid compressed G1 point"); + return d * se / e !== BigInt(a) && (d = ye.neg(d)), { + x: ye.create(r), + y: ye.create(d) + }; + } + if (96 !== f.length || t) throw new Error("Invalid point G1, expected 48/96 bytes"); + { + const e = l1(f.subarray(0, ye.BYTES)), t = l1(f.subarray(ye.BYTES)); + if (c) { + if (e !== oe || t !== oe) throw new Error("G1: non-empty point at infinity"); + return it.G1.ProjectivePoint.ZERO.toAffine(); + } + return { + x: ye.create(e), + y: ye.create(t) + }; + } + }, + toBytes: (e, t, c)=>{ + const a = t.equals(e.ZERO), { x: f, y: r } = t.toAffine(); + if (c) { + if (a) return at.slice(); + const e = ye.ORDER, t = Boolean(r * se / e); + return rt(p1(f, ye.BYTES), { + compressed: !0, + sort: t + }); + } + if (a) { + return B(new Uint8Array([ + 64 + ]), new Uint8Array(2 * ye.BYTES - 1)); + } + return B(p1(f, ye.BYTES), p1(r, ye.BYTES)); + }, + ShortSignature: { + fromHex (e) { + const { infinity: t, sort: c, value: a } = ft(y("signatureHex", e, 48)), f = ye.ORDER, r = l1(a); + if (t) return it.G1.ProjectivePoint.ZERO; + const n = ye.create(r & ye.MASK), d = ye.add(ye.pow(n, ue), ye.create(it.params.G1b)); + let i = ye.sqrt(d); + if (!i) throw new Error("Invalid compressed G1 point"); + const o = BigInt(c); + i * se / f !== o && (i = ye.neg(i)); + const b = it.G1.ProjectivePoint.fromAffine({ + x: n, + y: i + }); + return b.assertValidity(), b; + }, + toRawBytes: (e)=>nt(e), + toHex: (e)=>i1(nt(e)) + } + }, + G2: { + Fp: Ie, + h: BigInt("0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5"), + Gx: Ie.fromBigTuple([ + BigInt("0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8"), + BigInt("0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e") + ]), + Gy: Ie.fromBigTuple([ + BigInt("0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801"), + BigInt("0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be") + ]), + a: Ie.ZERO, + b: Ie.fromBigTuple([ + le, + le + ]), + hEff: BigInt("0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551"), + htfDefaults: { + ...ct + }, + wrapPrivateKey: !0, + allowInfinityPoint: !0, + mapToCurve: (e)=>{ + const { x: t, y: c } = ze(Ie.fromBigTuple(e)); + return Le(t, c); + }, + isTorsionFree: (e, t)=>t.multiplyUnsafe(it.params.x).negate().equals(Qe(e, t)), + clearCofactor: (e, t)=>{ + const c = it.params.x; + let a = t.multiplyUnsafe(c).negate(), f = Qe(e, t), r = t.double(); + r = tt(e, r), r = r.subtract(f), f = a.add(f), f = f.multiplyUnsafe(c).negate(), r = r.add(f), r = r.subtract(a); + return r.subtract(t); + }, + fromBytes: (e)=>{ + const { compressed: t, infinity: c, sort: a, value: f } = ft(e); + if (!t && !c && a || !t && c && a || a && c && t) throw new Error("Invalid encoding flag: " + (224 & e[0])); + const r = ye.BYTES, n = (e, t, c)=>l1(e.slice(t, c)); + if (96 === f.length && t) { + const e = it.params.G2b, t = ye.ORDER; + if (c) { + if (f.reduce((e, t)=>0 !== e ? t + 1 : t, 0) > 0) throw new Error("Invalid compressed G2 point"); + return { + x: Ie.ZERO, + y: Ie.ZERO + }; + } + const d = n(f, 0, r), i = n(f, r, 2 * r), o = Ie.create({ + c0: ye.create(i), + c1: ye.create(d) + }), b = Ie.add(Ie.pow(o, ue), e); + let s = Ie.sqrt(b); + const u = s.c1 === oe ? s.c0 * se / t : s.c1 * se / t ? be : oe; + return s = a && u > 0 ? s : Ie.neg(s), { + x: o, + y: s + }; + } + if (192 !== f.length || t) throw new Error("Invalid point G2, expected 96/192 bytes"); + { + if (c) { + if (f.reduce((e, t)=>0 !== e ? t + 1 : t, 0) > 0) throw new Error("Invalid uncompressed G2 point"); + return { + x: Ie.ZERO, + y: Ie.ZERO + }; + } + const e = n(f, 0, r), t = n(f, r, 2 * r), a = n(f, 2 * r, 3 * r), d = n(f, 3 * r, 4 * r); + return { + x: Ie.fromBigTuple([ + t, + e + ]), + y: Ie.fromBigTuple([ + d, + a + ]) + }; + } + }, + toBytes: (e, t, c)=>{ + const { BYTES: a, ORDER: f } = ye, r = t.equals(e.ZERO), { x: n, y: d } = t.toAffine(); + if (c) { + if (r) return B(at, p1(oe, a)); + const e = Boolean(d.c1 === oe ? d.c0 * se / f : d.c1 * se / f); + return B(rt(p1(n.c1, a), { + compressed: !0, + sort: e + }), p1(n.c0, a)); + } + { + if (r) return B(new Uint8Array([ + 64 + ]), new Uint8Array(4 * a - 1)); + const { re: e, im: t } = Ie.reim(n), { re: c, im: f } = Ie.reim(d); + return B(p1(t, a), p1(e, a), p1(f, a), p1(c, a)); + } + }, + Signature: { + fromHex (e) { + const { infinity: t, sort: c, value: a } = ft(y("signatureHex", e)), f = ye.ORDER, r = a.length / 2; + if (48 !== r && 96 !== r) throw new Error("Invalid compressed signature length, must be 96 or 192"); + const n = l1(a.slice(0, r)), d = l1(a.slice(r)); + if (t) return it.G2.ProjectivePoint.ZERO; + const i = ye.create(n & ye.MASK), o = ye.create(d), b = Ie.create({ + c0: o, + c1: i + }), s = Ie.add(Ie.pow(b, ue), it.params.G2b); + let u = Ie.sqrt(s); + if (!u) throw new Error("Failed to find a square root"); + const { re: m, im: p } = Ie.reim(u), g = BigInt(c); + (p > oe && p * se / f !== g || p === oe && m * se / f !== g) && (u = Ie.neg(u)); + const B = it.G2.ProjectivePoint.fromAffine({ + x: b, + y: u + }); + return B.assertValidity(), B; + }, + toRawBytes: (e)=>dt(e), + toHex: (e)=>i1(dt(e)) + } + }, + params: { + x: je, + r: Be.ORDER + }, + htfDefaults: ct, + hash: d, + randomBytes: O +}); +function t1(t11, ...e) { + if (!((s = t11) instanceof Uint8Array || null != s && "object" == typeof s && "Uint8Array" === s.constructor.name)) throw new Error("Uint8Array expected"); + var s; + if (e.length > 0 && !e.includes(t11.length)) throw new Error(`Uint8Array expected of length ${e}, not of length=${t11.length}`); +} +function e1(t, e = !0) { + if (t.destroyed) throw new Error("Hash instance has been destroyed"); + if (e && t.finished) throw new Error("Hash#digest() has already been called"); +} +const s2 = (t)=>new DataView(t.buffer, t.byteOffset, t.byteLength), n2 = (t, e)=>t << 32 - e | t >>> e; +function i2(e) { + return "string" == typeof e && (e = function(t) { + if ("string" != typeof t) throw new Error("utf8ToBytes expected string, got " + typeof t); + return new Uint8Array((new TextEncoder).encode(t)); + }(e)), t1(e), e; +} +new Uint8Array(new Uint32Array([ + 287454020 +]).buffer)[0]; +class r2 { + clone() { + return this._cloneInto(); + } +} +function o3(t) { + const e = (e)=>t().update(i2(e)).digest(), s = t(); + return e.outputLen = s.outputLen, e.blockLen = s.blockLen, e.create = ()=>t(), e; +} +const h2 = (t, e, s)=>t & e ^ t & s ^ e & s; +class f2 extends r2 { + constructor(t, e, n, i){ + super(), this.blockLen = t, this.outputLen = e, this.padOffset = n, this.isLE = i, this.finished = !1, this.length = 0, this.pos = 0, this.destroyed = !1, this.buffer = new Uint8Array(t), this.view = s2(this.buffer); + } + update(t) { + e1(this); + const { view: n, buffer: r, blockLen: o } = this, h = (t = i2(t)).length; + for(let e = 0; e < h;){ + const i = Math.min(o - this.pos, h - e); + if (i !== o) r.set(t.subarray(e, e + i), this.pos), this.pos += i, e += i, this.pos === o && (this.process(n, 0), this.pos = 0); + else { + const n = s2(t); + for(; o <= h - e; e += o)this.process(n, e); + } + } + return this.length += t.length, this.roundClean(), this; + } + digestInto(n) { + e1(this), function(e, s) { + t1(e); + const n = s.outputLen; + if (e.length < n) throw new Error(`digestInto() expects output buffer of length at least ${n}`); + }(n, this), this.finished = !0; + const { buffer: i, view: r, blockLen: o, isLE: h } = this; + let { pos: f } = this; + i[f++] = 128, this.buffer.subarray(f).fill(0), this.padOffset > o - f && (this.process(r, 0), f = 0); + for(let t = f; t < o; t++)i[t] = 0; + !function(t, e, s, n) { + if ("function" == typeof t.setBigUint64) return t.setBigUint64(e, s, n); + const i = BigInt(32), r = BigInt(4294967295), o = Number(s >> i & r), h = Number(s & r), f = n ? 4 : 0, u = n ? 0 : 4; + t.setUint32(e + f, o, n), t.setUint32(e + u, h, n); + }(r, o - 8, BigInt(8 * this.length), h), this.process(r, 0); + const u = s2(n), c = this.outputLen; + if (c % 4) throw new Error("_sha2: outputLen should be aligned to 32bit"); + const l = c / 4, a = this.get(); + if (l > a.length) throw new Error("_sha2: outputLen bigger than state"); + for(let t = 0; t < l; t++)u.setUint32(4 * t, a[t], h); + } + digest() { + const { buffer: t, outputLen: e } = this; + this.digestInto(t); + const s = t.slice(0, e); + return this.destroy(), s; + } + _cloneInto(t) { + t || (t = new this.constructor), t.set(...this.get()); + const { blockLen: e, buffer: s, length: n, finished: i, destroyed: r, pos: o } = this; + return t.length = n, t.pos = o, t.finished = i, t.destroyed = r, n % e && t.buffer.set(s), t; + } +} +const u2 = new Uint32Array([ + 1116352408, + 1899447441, + 3049323471, + 3921009573, + 961987163, + 1508970993, + 2453635748, + 2870763221, + 3624381080, + 310598401, + 607225278, + 1426881987, + 1925078388, + 2162078206, + 2614888103, + 3248222580, + 3835390401, + 4022224774, + 264347078, + 604807628, + 770255983, + 1249150122, + 1555081692, + 1996064986, + 2554220882, + 2821834349, + 2952996808, + 3210313671, + 3336571891, + 3584528711, + 113926993, + 338241895, + 666307205, + 773529912, + 1294757372, + 1396182291, + 1695183700, + 1986661051, + 2177026350, + 2456956037, + 2730485921, + 2820302411, + 3259730800, + 3345764771, + 3516065817, + 3600352804, + 4094571909, + 275423344, + 430227734, + 506948616, + 659060556, + 883997877, + 958139571, + 1322822218, + 1537002063, + 1747873779, + 1955562222, + 2024104815, + 2227730452, + 2361852424, + 2428436474, + 2756734187, + 3204031479, + 3329325298 +]), c2 = new Uint32Array([ + 1779033703, + 3144134277, + 1013904242, + 2773480762, + 1359893119, + 2600822924, + 528734635, + 1541459225 +]), l2 = new Uint32Array(64); +class a2 extends f2 { + constructor(){ + super(64, 32, 8, !1), this.A = 0 | c2[0], this.B = 0 | c2[1], this.C = 0 | c2[2], this.D = 0 | c2[3], this.E = 0 | c2[4], this.F = 0 | c2[5], this.G = 0 | c2[6], this.H = 0 | c2[7]; + } + get() { + const { A: t, B: e, C: s, D: n, E: i, F: r, G: o, H: h } = this; + return [ + t, + e, + s, + n, + i, + r, + o, + h + ]; + } + set(t, e, s, n, i, r, o, h) { + this.A = 0 | t, this.B = 0 | e, this.C = 0 | s, this.D = 0 | n, this.E = 0 | i, this.F = 0 | r, this.G = 0 | o, this.H = 0 | h; + } + process(t, e) { + for(let s = 0; s < 16; s++, e += 4)l2[s] = t.getUint32(e, !1); + for(let t = 16; t < 64; t++){ + const e = l2[t - 15], s = l2[t - 2], i = n2(e, 7) ^ n2(e, 18) ^ e >>> 3, r = n2(s, 17) ^ n2(s, 19) ^ s >>> 10; + l2[t] = r + l2[t - 7] + i + l2[t - 16] | 0; + } + let { A: s, B: i, C: r, D: o, E: f, F: c, G: a, H: p } = this; + for(let t = 0; t < 64; t++){ + const e = p + (n2(f, 6) ^ n2(f, 11) ^ n2(f, 25)) + ((d = f) & c ^ ~d & a) + u2[t] + l2[t] | 0, g = (n2(s, 2) ^ n2(s, 13) ^ n2(s, 22)) + h2(s, i, r) | 0; + p = a, a = c, c = f, f = o + e | 0, o = r, r = i, i = s, s = e + g | 0; + } + var d; + s = s + this.A | 0, i = i + this.B | 0, r = r + this.C | 0, o = o + this.D | 0, f = f + this.E | 0, c = c + this.F | 0, a = a + this.G | 0, p = p + this.H | 0, this.set(s, i, r, o, f, c, a, p); + } + roundClean() { + l2.fill(0); + } + destroy() { + this.set(0, 0, 0, 0, 0, 0, 0, 0), this.buffer.fill(0); + } +} +class p2 extends a2 { + constructor(){ + super(), this.A = -1056596264, this.B = 914150663, this.C = 812702999, this.D = -150054599, this.E = -4191439, this.F = 1750603025, this.G = 1694076839, this.H = -1090891868, this.outputLen = 28; + } +} +o3(()=>new a2), o3(()=>new p2); +BigInt(0), BigInt(1), BigInt(2); +Array.from({ + length: 256 +}, (t, n)=>n.toString(16).padStart(2, "0")); +var r3 = "undefined" != typeof globalThis ? globalThis : "undefined" != typeof window ? window : "undefined" != typeof global ? global : "undefined" != typeof self ? self : {}; +function i3(t) { + return t && Object.prototype.hasOwnProperty.call(t, "default") ? t.default : t; +} +var o4 = {}, a3 = {}, s3 = {}, u3 = {}; +Object.defineProperty(u3, "__esModule", { + value: !0 +}), u3.LIB_VERSION = void 0, u3.LIB_VERSION = "1.2.6", function(t) { + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.retryOnError = t.jsonOrError = t.defaultHttpOptions = t.roundTime = t.roundAt = t.sleep = void 0; + const e = u3; + t.sleep = function(t) { + return new Promise((e)=>{ + t <= 0 && e(), setTimeout(e, t); + }); + }, t.roundAt = function(t, e) { + if (!Number.isFinite(t)) throw new Error("Cannot use Infinity or NaN as a beacon time"); + if (t < 1e3 * e.genesis_time) throw Error("Cannot request a round before the genesis time"); + return Math.floor((t - 1e3 * e.genesis_time) / (1e3 * e.period)) + 1; + }, t.roundTime = function(t, e) { + if (!Number.isFinite(e)) throw new Error("Cannot use Infinity or NaN as a round number"); + return e = e < 0 ? 0 : e, 1e3 * (t.genesis_time + (e - 1) * t.period); + }, t.defaultHttpOptions = { + userAgent: `drand-client-${e.LIB_VERSION}` + }, t.jsonOrError = async function(e, n = t.defaultHttpOptions) { + const r = { + ...n.headers + }; + n.userAgent && (r["User-Agent"] = n.userAgent); + const i = await fetch(e, { + headers: r + }); + if (!i.ok) throw Error(`Error response fetching ${e} - got ${i.status}`); + return await i.json(); + }, t.retryOnError = async function t(e, n) { + try { + return await e(); + } catch (r) { + if (0 === n) throw r; + return t(e, n - 1); + } + }; +}(s3), Object.defineProperty(a3, "__esModule", { + value: !0 +}), a3.HttpChain = void 0; +const f3 = o4, c3 = s3; +class h3 { + baseUrl; + options; + httpOptions; + constructor(t, e = f3.defaultChainOptions, n = {}){ + this.baseUrl = t, this.options = e, this.httpOptions = n; + } + async info() { + const t = await (0, c3.jsonOrError)(`${this.baseUrl}/info`, this.httpOptions); + if (this.options.chainVerificationParams && !function(t, e) { + return t.hash === e.chainHash && t.public_key === e.publicKey; + }(t, this.options.chainVerificationParams)) throw Error(`The chain info retrieved from ${this.baseUrl} did not match the verification params!`); + return t; + } +} +a3.HttpChain = h3; +a3.default = class { + baseUrl; + options; + chain; + cachedInfo; + constructor(t, e = f3.defaultChainOptions){ + this.baseUrl = t, this.options = e, this.chain = new h3(t, e); + } + async info() { + return this.cachedInfo || (this.cachedInfo = await this.chain.info()), this.cachedInfo; + } +}; +var l3 = {}; +Object.defineProperty(l3, "__esModule", { + value: !0 +}); +const d2 = o4, p3 = s3; +function b1(t, e) { + return e.noCache ? `${t}?${Date.now()}` : t; +} +l3.default = class { + someChain; + options; + httpOptions; + constructor(t, e = d2.defaultChainOptions, n = p3.defaultHttpOptions){ + this.someChain = t, this.options = e, this.httpOptions = n; + } + async get(t) { + const e = b1(`${this.someChain.baseUrl}/public/${t}`, this.options); + return await (0, p3.jsonOrError)(e, this.httpOptions); + } + async latest() { + const t = b1(`${this.someChain.baseUrl}/public/latest`, this.options); + return await (0, p3.jsonOrError)(t, this.httpOptions); + } + chain() { + return this.someChain; + } +}; +var g2 = {}, _1 = {}; +Object.defineProperty(_1, "__esModule", { + value: !0 +}), _1.createSpeedTest = void 0, _1.createSpeedTest = function(t, e, n = 5) { + let r = new y1(n), i = null; + const o = async ()=>{ + const e = Date.now(); + try { + await t(), r.add(Date.now() - e); + } catch (t) { + r.add(Number.MAX_SAFE_INTEGER); + } + }; + return { + start: ()=>{ + null == i ? i = setInterval(o, e) : console.warn("Attempted to start a speed test, but it had already been started!"); + }, + stop: ()=>{ + null !== i && (clearInterval(i), i = null, r = new y1(n)); + }, + average: ()=>{ + const t = r.get(); + if (0 === t.length) return Number.MAX_SAFE_INTEGER; + return t.reduce((t, e)=>t + e, 0) / t.length; + } + }; +}; +class y1 { + capacity; + values = []; + constructor(t){ + this.capacity = t; + } + add(t) { + this.values.push(t), this.values.length > this.capacity && this.values.pop(); + } + get() { + return this.values; + } +} +var w1 = r3 && r3.__createBinding || (Object.create ? function(t, e, n, r) { + void 0 === r && (r = n); + var i = Object.getOwnPropertyDescriptor(e, n); + i && !("get" in i ? !e.__esModule : i.writable || i.configurable) || (i = { + enumerable: !0, + get: function() { + return e[n]; + } + }), Object.defineProperty(t, r, i); +} : function(t, e, n, r) { + void 0 === r && (r = n), t[r] = e[n]; +}), E1 = r3 && r3.__setModuleDefault || (Object.create ? function(t, e) { + Object.defineProperty(t, "default", { + enumerable: !0, + value: e + }); +} : function(t, e) { + t.default = e; +}), v2 = r3 && r3.__importStar || function(t) { + if (t && t.__esModule) return t; + var e = {}; + if (null != t) for(var n in t)"default" !== n && Object.prototype.hasOwnProperty.call(t, n) && w1(e, t, n); + return E1(e, t), e; +}, T1 = r3 && r3.__importDefault || function(t) { + return t && t.__esModule ? t : { + default: t + }; +}; +Object.defineProperty(g2, "__esModule", { + value: !0 +}); +const m2 = o4, A1 = v2(a3), C1 = _1, I1 = T1(l3); +g2.default = class { + baseUrls; + options; + speedTestIntervalMs; + speedTests = []; + speedTestHttpOptions = { + userAgent: "drand-web-client-speedtest" + }; + constructor(t, e = m2.defaultChainOptions, n = 3e5){ + if (this.baseUrls = t, this.options = e, this.speedTestIntervalMs = n, 0 === t.length) throw Error("Can't optimise an empty `baseUrls` array!"); + } + async latest() { + return new I1.default(this.current(), this.options).latest(); + } + async get(t) { + return new I1.default(this.current(), this.options).get(t); + } + chain() { + return this.current(); + } + start() { + 1 !== this.baseUrls.length ? this.speedTests = this.baseUrls.map((t)=>{ + const e = (0, C1.createSpeedTest)(async ()=>{ + await new A1.HttpChain(t, this.options, this.speedTestHttpOptions).info(); + }, this.speedTestIntervalMs); + return e.start(), { + test: e, + url: t + }; + }) : console.warn("There was only a single base URL in the `FastestNodeClient` - not running speed testing"); + } + current() { + 0 === this.speedTests.length && console.warn("You are not currently running speed tests to choose the fastest client. Run `.start()` to speed test"); + const t = this.speedTests.slice().sort((t, e)=>t.test.average() - e.test.average()).shift(); + if (!t) throw Error("Somehow there were no entries to optimise! This should be impossible by now"); + return new A1.default(t.url, this.options); + } + stop() { + this.speedTests.forEach((t)=>t.test.stop()), this.speedTests = []; + } +}; +var N10 = {}, U1 = r3 && r3.__importDefault || function(t) { + return t && t.__esModule ? t : { + default: t + }; +}; +Object.defineProperty(N10, "__esModule", { + value: !0 +}); +const O2 = o4, R1 = U1(a3), P1 = s3; +N10.default = class { + baseUrl; + options; + constructor(t, e = O2.defaultChainOptions){ + this.baseUrl = t, this.options = e; + } + async chains() { + const t = await (0, P1.jsonOrError)(`${this.baseUrl}/chains`); + if (!Array.isArray(t)) throw Error(`Expected an array from the chains endpoint but got: ${t}`); + return t.map((t)=>new R1.default(`${this.baseUrl}/${t}`), this.options); + } + async health() { + const t = await fetch(`${this.baseUrl}/health`); + if (!t.ok) return { + status: t.status, + current: -1, + expected: -1 + }; + const e = await t.json(); + return { + status: t.status, + current: e.current ?? -1, + expected: e.expected ?? -1 + }; + } +}; +var B1 = {}, S1 = "undefined" != typeof global ? global : "undefined" != typeof self ? self : "undefined" != typeof window ? window : {}, D1 = [], H1 = [], L1 = "undefined" != typeof Uint8Array ? Uint8Array : Array, F1 = !1; +function M1() { + F1 = !0; + for(var t = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", e = 0; e < 64; ++e)D1[e] = t[e], H1[t.charCodeAt(e)] = e; + H1["-".charCodeAt(0)] = 62, H1["_".charCodeAt(0)] = 63; +} +function Y1(t, e, n) { + for(var r, i, o = [], a = e; a < n; a += 3)r = (t[a] << 16) + (t[a + 1] << 8) + t[a + 2], o.push(D1[(i = r) >> 18 & 63] + D1[i >> 12 & 63] + D1[i >> 6 & 63] + D1[63 & i]); + return o.join(""); +} +function j1(t) { + var e; + F1 || M1(); + for(var n = t.length, r = n % 3, i = "", o = [], a = 16383, s = 0, u = n - r; s < u; s += a)o.push(Y1(t, s, s + a > u ? u : s + a)); + return 1 === r ? (e = t[n - 1], i += D1[e >> 2], i += D1[e << 4 & 63], i += "==") : 2 === r && (e = (t[n - 2] << 8) + t[n - 1], i += D1[e >> 10], i += D1[e >> 4 & 63], i += D1[e << 2 & 63], i += "="), o.push(i), o.join(""); +} +function k1(t, e, n, r, i) { + var o, a, s = 8 * i - r - 1, u = (1 << s) - 1, f = u >> 1, c = -7, h = n ? i - 1 : 0, l = n ? -1 : 1, d = t[e + h]; + for(h += l, o = d & (1 << -c) - 1, d >>= -c, c += s; c > 0; o = 256 * o + t[e + h], h += l, c -= 8); + for(a = o & (1 << -c) - 1, o >>= -c, c += r; c > 0; a = 256 * a + t[e + h], h += l, c -= 8); + if (0 === o) o = 1 - f; + else { + if (o === u) return a ? NaN : 1 / 0 * (d ? -1 : 1); + a += Math.pow(2, r), o -= f; + } + return (d ? -1 : 1) * a * Math.pow(2, o - r); +} +function x1(t, e, n, r, i, o) { + var a, s, u, f = 8 * o - i - 1, c = (1 << f) - 1, h = c >> 1, l = 23 === i ? Math.pow(2, -24) - Math.pow(2, -77) : 0, d = r ? 0 : o - 1, p = r ? 1 : -1, b = e < 0 || 0 === e && 1 / e < 0 ? 1 : 0; + for(e = Math.abs(e), isNaN(e) || e === 1 / 0 ? (s = isNaN(e) ? 1 : 0, a = c) : (a = Math.floor(Math.log(e) / Math.LN2), e * (u = Math.pow(2, -a)) < 1 && (a--, u *= 2), (e += a + h >= 1 ? l / u : l * Math.pow(2, 1 - h)) * u >= 2 && (a++, u /= 2), a + h >= c ? (s = 0, a = c) : a + h >= 1 ? (s = (e * u - 1) * Math.pow(2, i), a += h) : (s = e * Math.pow(2, h - 1) * Math.pow(2, i), a = 0)); i >= 8; t[n + d] = 255 & s, d += p, s /= 256, i -= 8); + for(a = a << i | s, f += i; f > 0; t[n + d] = 255 & a, d += p, a /= 256, f -= 8); + t[n + d - p] |= 128 * b; +} +var G1 = {}.toString, K1 = Array.isArray || function(t) { + return "[object Array]" == G1.call(t); +}; +q1.TYPED_ARRAY_SUPPORT = void 0 === S1.TYPED_ARRAY_SUPPORT || S1.TYPED_ARRAY_SUPPORT; +var Q1 = $1(); +function $1() { + return q1.TYPED_ARRAY_SUPPORT ? 2147483647 : 1073741823; +} +function V1(t, e) { + if ($1() < e) throw new RangeError("Invalid typed array length"); + return q1.TYPED_ARRAY_SUPPORT ? (t = new Uint8Array(e)).__proto__ = q1.prototype : (null === t && (t = new q1(e)), t.length = e), t; +} +function q1(t, e, n) { + if (!(q1.TYPED_ARRAY_SUPPORT || this instanceof q1)) return new q1(t, e, n); + if ("number" == typeof t) { + if ("string" == typeof e) throw new Error("If encoding is specified then the first argument must be a string"); + return W1(this, t); + } + return z1(this, t, e, n); +} +function z1(t, e, n, r) { + if ("number" == typeof e) throw new TypeError('"value" argument must not be a number'); + return "undefined" != typeof ArrayBuffer && e instanceof ArrayBuffer ? function(t, e, n, r) { + if (e.byteLength, n < 0 || e.byteLength < n) throw new RangeError("'offset' is out of bounds"); + if (e.byteLength < n + (r || 0)) throw new RangeError("'length' is out of bounds"); + e = void 0 === n && void 0 === r ? new Uint8Array(e) : void 0 === r ? new Uint8Array(e, n) : new Uint8Array(e, n, r); + q1.TYPED_ARRAY_SUPPORT ? (t = e).__proto__ = q1.prototype : t = J1(t, e); + return t; + }(t, e, n, r) : "string" == typeof e ? function(t, e, n) { + "string" == typeof n && "" !== n || (n = "utf8"); + if (!q1.isEncoding(n)) throw new TypeError('"encoding" must be a valid string encoding'); + var r = 0 | nt1(e, n); + t = V1(t, r); + var i = t.write(e, n); + i !== r && (t = t.slice(0, i)); + return t; + }(t, e, n) : function(t, e) { + if (et1(e)) { + var n = 0 | Z1(e.length); + return 0 === (t = V1(t, n)).length || e.copy(t, 0, 0, n), t; + } + if (e) { + if ("undefined" != typeof ArrayBuffer && e.buffer instanceof ArrayBuffer || "length" in e) return "number" != typeof e.length || (r = e.length) != r ? V1(t, 0) : J1(t, e); + if ("Buffer" === e.type && K1(e.data)) return J1(t, e.data); + } + var r; + throw new TypeError("First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object."); + }(t, e); +} +function X1(t) { + if ("number" != typeof t) throw new TypeError('"size" argument must be a number'); + if (t < 0) throw new RangeError('"size" argument must not be negative'); +} +function W1(t, e) { + if (X1(e), t = V1(t, e < 0 ? 0 : 0 | Z1(e)), !q1.TYPED_ARRAY_SUPPORT) for(var n = 0; n < e; ++n)t[n] = 0; + return t; +} +function J1(t, e) { + var n = e.length < 0 ? 0 : 0 | Z1(e.length); + t = V1(t, n); + for(var r = 0; r < n; r += 1)t[r] = 255 & e[r]; + return t; +} +function Z1(t) { + if (t >= $1()) throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + $1().toString(16) + " bytes"); + return 0 | t; +} +function tt1(t) { + return +t != t && (t = 0), q1.alloc(+t); +} +function et1(t) { + return !(null == t || !t._isBuffer); +} +function nt1(t, e) { + if (et1(t)) return t.length; + if ("undefined" != typeof ArrayBuffer && "function" == typeof ArrayBuffer.isView && (ArrayBuffer.isView(t) || t instanceof ArrayBuffer)) return t.byteLength; + "string" != typeof t && (t = "" + t); + var n = t.length; + if (0 === n) return 0; + for(var r = !1;;)switch(e){ + case "ascii": + case "latin1": + case "binary": + return n; + case "utf8": + case "utf-8": + case void 0: + return Ot(t).length; + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return 2 * n; + case "hex": + return n >>> 1; + case "base64": + return Rt(t).length; + default: + if (r) return Ot(t).length; + e = ("" + e).toLowerCase(), r = !0; + } +} +function rt1(t, e, n) { + var r = !1; + if ((void 0 === e || e < 0) && (e = 0), e > this.length) return ""; + if ((void 0 === n || n > this.length) && (n = this.length), n <= 0) return ""; + if ((n >>>= 0) <= (e >>>= 0)) return ""; + for(t || (t = "utf8");;)switch(t){ + case "hex": + return yt(this, e, n); + case "utf8": + case "utf-8": + return pt(this, e, n); + case "ascii": + return gt(this, e, n); + case "latin1": + case "binary": + return _t(this, e, n); + case "base64": + return dt1(this, e, n); + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return wt(this, e, n); + default: + if (r) throw new TypeError("Unknown encoding: " + t); + t = (t + "").toLowerCase(), r = !0; + } +} +function it1(t, e, n) { + var r = t[e]; + t[e] = t[n], t[n] = r; +} +function ot(t, e, n, r, i) { + if (0 === t.length) return -1; + if ("string" == typeof n ? (r = n, n = 0) : n > 2147483647 ? n = 2147483647 : n < -2147483648 && (n = -2147483648), n = +n, isNaN(n) && (n = i ? 0 : t.length - 1), n < 0 && (n = t.length + n), n >= t.length) { + if (i) return -1; + n = t.length - 1; + } else if (n < 0) { + if (!i) return -1; + n = 0; + } + if ("string" == typeof e && (e = q1.from(e, r)), et1(e)) return 0 === e.length ? -1 : at1(t, e, n, r, i); + if ("number" == typeof e) return e &= 255, q1.TYPED_ARRAY_SUPPORT && "function" == typeof Uint8Array.prototype.indexOf ? i ? Uint8Array.prototype.indexOf.call(t, e, n) : Uint8Array.prototype.lastIndexOf.call(t, e, n) : at1(t, [ + e + ], n, r, i); + throw new TypeError("val must be string, number or Buffer"); +} +function at1(t, e, n, r, i) { + var o, a = 1, s = t.length, u = e.length; + if (void 0 !== r && ("ucs2" === (r = String(r).toLowerCase()) || "ucs-2" === r || "utf16le" === r || "utf-16le" === r)) { + if (t.length < 2 || e.length < 2) return -1; + a = 2, s /= 2, u /= 2, n /= 2; + } + function f(t, e) { + return 1 === a ? t[e] : t.readUInt16BE(e * a); + } + if (i) { + var c = -1; + for(o = n; o < s; o++)if (f(t, o) === f(e, -1 === c ? 0 : o - c)) { + if (-1 === c && (c = o), o - c + 1 === u) return c * a; + } else -1 !== c && (o -= o - c), c = -1; + } else for(n + u > s && (n = s - u), o = n; o >= 0; o--){ + for(var h = !0, l = 0; l < u; l++)if (f(t, o + l) !== f(e, l)) { + h = !1; + break; + } + if (h) return o; + } + return -1; +} +function st(t, e, n, r) { + n = Number(n) || 0; + var i = t.length - n; + r ? (r = Number(r)) > i && (r = i) : r = i; + var o = e.length; + if (o % 2 != 0) throw new TypeError("Invalid hex string"); + r > o / 2 && (r = o / 2); + for(var a = 0; a < r; ++a){ + var s = parseInt(e.substr(2 * a, 2), 16); + if (isNaN(s)) return a; + t[n + a] = s; + } + return a; +} +function ut(t, e, n, r) { + return Pt(Ot(e, t.length - n), t, n, r); +} +function ft1(t, e, n, r) { + return Pt(function(t) { + for(var e = [], n = 0; n < t.length; ++n)e.push(255 & t.charCodeAt(n)); + return e; + }(e), t, n, r); +} +function ct1(t, e, n, r) { + return ft1(t, e, n, r); +} +function ht(t, e, n, r) { + return Pt(Rt(e), t, n, r); +} +function lt(t, e, n, r) { + return Pt(function(t, e) { + for(var n, r, i, o = [], a = 0; a < t.length && !((e -= 2) < 0); ++a)r = (n = t.charCodeAt(a)) >> 8, i = n % 256, o.push(i), o.push(r); + return o; + }(e, t.length - n), t, n, r); +} +function dt1(t, e, n) { + return 0 === e && n === t.length ? j1(t) : j1(t.slice(e, n)); +} +function pt(t, e, n) { + n = Math.min(t.length, n); + for(var r = [], i = e; i < n;){ + var o, a, s, u, f = t[i], c = null, h = f > 239 ? 4 : f > 223 ? 3 : f > 191 ? 2 : 1; + if (i + h <= n) switch(h){ + case 1: + f < 128 && (c = f); + break; + case 2: + 128 == (192 & (o = t[i + 1])) && (u = (31 & f) << 6 | 63 & o) > 127 && (c = u); + break; + case 3: + o = t[i + 1], a = t[i + 2], 128 == (192 & o) && 128 == (192 & a) && (u = (15 & f) << 12 | (63 & o) << 6 | 63 & a) > 2047 && (u < 55296 || u > 57343) && (c = u); + break; + case 4: + o = t[i + 1], a = t[i + 2], s = t[i + 3], 128 == (192 & o) && 128 == (192 & a) && 128 == (192 & s) && (u = (15 & f) << 18 | (63 & o) << 12 | (63 & a) << 6 | 63 & s) > 65535 && u < 1114112 && (c = u); + } + null === c ? (c = 65533, h = 1) : c > 65535 && (c -= 65536, r.push(c >>> 10 & 1023 | 55296), c = 56320 | 1023 & c), r.push(c), i += h; + } + return function(t) { + var e = t.length; + if (e <= bt) return String.fromCharCode.apply(String, t); + var n = "", r = 0; + for(; r < e;)n += String.fromCharCode.apply(String, t.slice(r, r += bt)); + return n; + }(r); +} +q1.poolSize = 8192, q1._augment = function(t) { + return t.__proto__ = q1.prototype, t; +}, q1.from = function(t, e, n) { + return z1(null, t, e, n); +}, q1.TYPED_ARRAY_SUPPORT && (q1.prototype.__proto__ = Uint8Array.prototype, q1.__proto__ = Uint8Array, "undefined" != typeof Symbol && Symbol.species && q1[Symbol.species]), q1.alloc = function(t, e, n) { + return function(t, e, n, r) { + return X1(e), e <= 0 ? V1(t, e) : void 0 !== n ? "string" == typeof r ? V1(t, e).fill(n, r) : V1(t, e).fill(n) : V1(t, e); + }(null, t, e, n); +}, q1.allocUnsafe = function(t) { + return W1(null, t); +}, q1.allocUnsafeSlow = function(t) { + return W1(null, t); +}, q1.isBuffer = Bt, q1.compare = function(t, e) { + if (!et1(t) || !et1(e)) throw new TypeError("Arguments must be Buffers"); + if (t === e) return 0; + for(var n = t.length, r = e.length, i = 0, o = Math.min(n, r); i < o; ++i)if (t[i] !== e[i]) { + n = t[i], r = e[i]; + break; + } + return n < r ? -1 : r < n ? 1 : 0; +}, q1.isEncoding = function(t) { + switch(String(t).toLowerCase()){ + case "hex": + case "utf8": + case "utf-8": + case "ascii": + case "latin1": + case "binary": + case "base64": + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return !0; + default: + return !1; + } +}, q1.concat = function(t, e) { + if (!K1(t)) throw new TypeError('"list" argument must be an Array of Buffers'); + if (0 === t.length) return q1.alloc(0); + var n; + if (void 0 === e) for(e = 0, n = 0; n < t.length; ++n)e += t[n].length; + var r = q1.allocUnsafe(e), i = 0; + for(n = 0; n < t.length; ++n){ + var o = t[n]; + if (!et1(o)) throw new TypeError('"list" argument must be an Array of Buffers'); + o.copy(r, i), i += o.length; + } + return r; +}, q1.byteLength = nt1, q1.prototype._isBuffer = !0, q1.prototype.swap16 = function() { + var t = this.length; + if (t % 2 != 0) throw new RangeError("Buffer size must be a multiple of 16-bits"); + for(var e = 0; e < t; e += 2)it1(this, e, e + 1); + return this; +}, q1.prototype.swap32 = function() { + var t = this.length; + if (t % 4 != 0) throw new RangeError("Buffer size must be a multiple of 32-bits"); + for(var e = 0; e < t; e += 4)it1(this, e, e + 3), it1(this, e + 1, e + 2); + return this; +}, q1.prototype.swap64 = function() { + var t = this.length; + if (t % 8 != 0) throw new RangeError("Buffer size must be a multiple of 64-bits"); + for(var e = 0; e < t; e += 8)it1(this, e, e + 7), it1(this, e + 1, e + 6), it1(this, e + 2, e + 5), it1(this, e + 3, e + 4); + return this; +}, q1.prototype.toString = function() { + var t = 0 | this.length; + return 0 === t ? "" : 0 === arguments.length ? pt(this, 0, t) : rt1.apply(this, arguments); +}, q1.prototype.equals = function(t) { + if (!et1(t)) throw new TypeError("Argument must be a Buffer"); + return this === t || 0 === q1.compare(this, t); +}, q1.prototype.inspect = function() { + var t = ""; + return this.length > 0 && (t = this.toString("hex", 0, 50).match(/.{2}/g).join(" "), this.length > 50 && (t += " ... ")), ""; +}, q1.prototype.compare = function(t, e, n, r, i) { + if (!et1(t)) throw new TypeError("Argument must be a Buffer"); + if (void 0 === e && (e = 0), void 0 === n && (n = t ? t.length : 0), void 0 === r && (r = 0), void 0 === i && (i = this.length), e < 0 || n > t.length || r < 0 || i > this.length) throw new RangeError("out of range index"); + if (r >= i && e >= n) return 0; + if (r >= i) return -1; + if (e >= n) return 1; + if (this === t) return 0; + for(var o = (i >>>= 0) - (r >>>= 0), a = (n >>>= 0) - (e >>>= 0), s = Math.min(o, a), u = this.slice(r, i), f = t.slice(e, n), c = 0; c < s; ++c)if (u[c] !== f[c]) { + o = u[c], a = f[c]; + break; + } + return o < a ? -1 : a < o ? 1 : 0; +}, q1.prototype.includes = function(t, e, n) { + return -1 !== this.indexOf(t, e, n); +}, q1.prototype.indexOf = function(t, e, n) { + return ot(this, t, e, n, !0); +}, q1.prototype.lastIndexOf = function(t, e, n) { + return ot(this, t, e, n, !1); +}, q1.prototype.write = function(t, e, n, r) { + if (void 0 === e) r = "utf8", n = this.length, e = 0; + else if (void 0 === n && "string" == typeof e) r = e, n = this.length, e = 0; + else { + if (!isFinite(e)) throw new Error("Buffer.write(string, encoding, offset[, length]) is no longer supported"); + e |= 0, isFinite(n) ? (n |= 0, void 0 === r && (r = "utf8")) : (r = n, n = void 0); + } + var i = this.length - e; + if ((void 0 === n || n > i) && (n = i), t.length > 0 && (n < 0 || e < 0) || e > this.length) throw new RangeError("Attempt to write outside buffer bounds"); + r || (r = "utf8"); + for(var o = !1;;)switch(r){ + case "hex": + return st(this, t, e, n); + case "utf8": + case "utf-8": + return ut(this, t, e, n); + case "ascii": + return ft1(this, t, e, n); + case "latin1": + case "binary": + return ct1(this, t, e, n); + case "base64": + return ht(this, t, e, n); + case "ucs2": + case "ucs-2": + case "utf16le": + case "utf-16le": + return lt(this, t, e, n); + default: + if (o) throw new TypeError("Unknown encoding: " + r); + r = ("" + r).toLowerCase(), o = !0; + } +}, q1.prototype.toJSON = function() { + return { + type: "Buffer", + data: Array.prototype.slice.call(this._arr || this, 0) + }; +}; +var bt = 4096; +function gt(t, e, n) { + var r = ""; + n = Math.min(t.length, n); + for(var i = e; i < n; ++i)r += String.fromCharCode(127 & t[i]); + return r; +} +function _t(t, e, n) { + var r = ""; + n = Math.min(t.length, n); + for(var i = e; i < n; ++i)r += String.fromCharCode(t[i]); + return r; +} +function yt(t, e, n) { + var r = t.length; + (!e || e < 0) && (e = 0), (!n || n < 0 || n > r) && (n = r); + for(var i = "", o = e; o < n; ++o)i += Ut(t[o]); + return i; +} +function wt(t, e, n) { + for(var r = t.slice(e, n), i = "", o = 0; o < r.length; o += 2)i += String.fromCharCode(r[o] + 256 * r[o + 1]); + return i; +} +function Et(t, e, n) { + if (t % 1 != 0 || t < 0) throw new RangeError("offset is not uint"); + if (t + e > n) throw new RangeError("Trying to access beyond buffer length"); +} +function vt(t, e, n, r, i, o) { + if (!et1(t)) throw new TypeError('"buffer" argument must be a Buffer instance'); + if (e > i || e < o) throw new RangeError('"value" argument is out of bounds'); + if (n + r > t.length) throw new RangeError("Index out of range"); +} +function Tt(t, e, n, r) { + e < 0 && (e = 65535 + e + 1); + for(var i = 0, o = Math.min(t.length - n, 2); i < o; ++i)t[n + i] = (e & 255 << 8 * (r ? i : 1 - i)) >>> 8 * (r ? i : 1 - i); +} +function mt(t, e, n, r) { + e < 0 && (e = 4294967295 + e + 1); + for(var i = 0, o = Math.min(t.length - n, 4); i < o; ++i)t[n + i] = e >>> 8 * (r ? i : 3 - i) & 255; +} +function At(t, e, n, r, i, o) { + if (n + r > t.length) throw new RangeError("Index out of range"); + if (n < 0) throw new RangeError("Index out of range"); +} +function Ct(t, e, n, r, i) { + return i || At(t, 0, n, 4), x1(t, e, n, r, 23, 4), n + 4; +} +function It(t, e, n, r, i) { + return i || At(t, 0, n, 8), x1(t, e, n, r, 52, 8), n + 8; +} +q1.prototype.slice = function(t, e) { + var n, r = this.length; + if ((t = ~~t) < 0 ? (t += r) < 0 && (t = 0) : t > r && (t = r), (e = void 0 === e ? r : ~~e) < 0 ? (e += r) < 0 && (e = 0) : e > r && (e = r), e < t && (e = t), q1.TYPED_ARRAY_SUPPORT) (n = this.subarray(t, e)).__proto__ = q1.prototype; + else { + var i = e - t; + n = new q1(i, void 0); + for(var o = 0; o < i; ++o)n[o] = this[o + t]; + } + return n; +}, q1.prototype.readUIntLE = function(t, e, n) { + t |= 0, e |= 0, n || Et(t, e, this.length); + for(var r = this[t], i = 1, o = 0; ++o < e && (i *= 256);)r += this[t + o] * i; + return r; +}, q1.prototype.readUIntBE = function(t, e, n) { + t |= 0, e |= 0, n || Et(t, e, this.length); + for(var r = this[t + --e], i = 1; e > 0 && (i *= 256);)r += this[t + --e] * i; + return r; +}, q1.prototype.readUInt8 = function(t, e) { + return e || Et(t, 1, this.length), this[t]; +}, q1.prototype.readUInt16LE = function(t, e) { + return e || Et(t, 2, this.length), this[t] | this[t + 1] << 8; +}, q1.prototype.readUInt16BE = function(t, e) { + return e || Et(t, 2, this.length), this[t] << 8 | this[t + 1]; +}, q1.prototype.readUInt32LE = function(t, e) { + return e || Et(t, 4, this.length), (this[t] | this[t + 1] << 8 | this[t + 2] << 16) + 16777216 * this[t + 3]; +}, q1.prototype.readUInt32BE = function(t, e) { + return e || Et(t, 4, this.length), 16777216 * this[t] + (this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3]); +}, q1.prototype.readIntLE = function(t, e, n) { + t |= 0, e |= 0, n || Et(t, e, this.length); + for(var r = this[t], i = 1, o = 0; ++o < e && (i *= 256);)r += this[t + o] * i; + return r >= (i *= 128) && (r -= Math.pow(2, 8 * e)), r; +}, q1.prototype.readIntBE = function(t, e, n) { + t |= 0, e |= 0, n || Et(t, e, this.length); + for(var r = e, i = 1, o = this[t + --r]; r > 0 && (i *= 256);)o += this[t + --r] * i; + return o >= (i *= 128) && (o -= Math.pow(2, 8 * e)), o; +}, q1.prototype.readInt8 = function(t, e) { + return e || Et(t, 1, this.length), 128 & this[t] ? -1 * (255 - this[t] + 1) : this[t]; +}, q1.prototype.readInt16LE = function(t, e) { + e || Et(t, 2, this.length); + var n = this[t] | this[t + 1] << 8; + return 32768 & n ? 4294901760 | n : n; +}, q1.prototype.readInt16BE = function(t, e) { + e || Et(t, 2, this.length); + var n = this[t + 1] | this[t] << 8; + return 32768 & n ? 4294901760 | n : n; +}, q1.prototype.readInt32LE = function(t, e) { + return e || Et(t, 4, this.length), this[t] | this[t + 1] << 8 | this[t + 2] << 16 | this[t + 3] << 24; +}, q1.prototype.readInt32BE = function(t, e) { + return e || Et(t, 4, this.length), this[t] << 24 | this[t + 1] << 16 | this[t + 2] << 8 | this[t + 3]; +}, q1.prototype.readFloatLE = function(t, e) { + return e || Et(t, 4, this.length), k1(this, t, !0, 23, 4); +}, q1.prototype.readFloatBE = function(t, e) { + return e || Et(t, 4, this.length), k1(this, t, !1, 23, 4); +}, q1.prototype.readDoubleLE = function(t, e) { + return e || Et(t, 8, this.length), k1(this, t, !0, 52, 8); +}, q1.prototype.readDoubleBE = function(t, e) { + return e || Et(t, 8, this.length), k1(this, t, !1, 52, 8); +}, q1.prototype.writeUIntLE = function(t, e, n, r) { + (t = +t, e |= 0, n |= 0, r) || vt(this, t, e, n, Math.pow(2, 8 * n) - 1, 0); + var i = 1, o = 0; + for(this[e] = 255 & t; ++o < n && (i *= 256);)this[e + o] = t / i & 255; + return e + n; +}, q1.prototype.writeUIntBE = function(t, e, n, r) { + (t = +t, e |= 0, n |= 0, r) || vt(this, t, e, n, Math.pow(2, 8 * n) - 1, 0); + var i = n - 1, o = 1; + for(this[e + i] = 255 & t; --i >= 0 && (o *= 256);)this[e + i] = t / o & 255; + return e + n; +}, q1.prototype.writeUInt8 = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 1, 255, 0), q1.TYPED_ARRAY_SUPPORT || (t = Math.floor(t)), this[e] = 255 & t, e + 1; +}, q1.prototype.writeUInt16LE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 2, 65535, 0), q1.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8) : Tt(this, t, e, !0), e + 2; +}, q1.prototype.writeUInt16BE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 2, 65535, 0), q1.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 8, this[e + 1] = 255 & t) : Tt(this, t, e, !1), e + 2; +}, q1.prototype.writeUInt32LE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 4, 4294967295, 0), q1.TYPED_ARRAY_SUPPORT ? (this[e + 3] = t >>> 24, this[e + 2] = t >>> 16, this[e + 1] = t >>> 8, this[e] = 255 & t) : mt(this, t, e, !0), e + 4; +}, q1.prototype.writeUInt32BE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 4, 4294967295, 0), q1.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 24, this[e + 1] = t >>> 16, this[e + 2] = t >>> 8, this[e + 3] = 255 & t) : mt(this, t, e, !1), e + 4; +}, q1.prototype.writeIntLE = function(t, e, n, r) { + if (t = +t, e |= 0, !r) { + var i = Math.pow(2, 8 * n - 1); + vt(this, t, e, n, i - 1, -i); + } + var o = 0, a = 1, s = 0; + for(this[e] = 255 & t; ++o < n && (a *= 256);)t < 0 && 0 === s && 0 !== this[e + o - 1] && (s = 1), this[e + o] = (t / a >> 0) - s & 255; + return e + n; +}, q1.prototype.writeIntBE = function(t, e, n, r) { + if (t = +t, e |= 0, !r) { + var i = Math.pow(2, 8 * n - 1); + vt(this, t, e, n, i - 1, -i); + } + var o = n - 1, a = 1, s = 0; + for(this[e + o] = 255 & t; --o >= 0 && (a *= 256);)t < 0 && 0 === s && 0 !== this[e + o + 1] && (s = 1), this[e + o] = (t / a >> 0) - s & 255; + return e + n; +}, q1.prototype.writeInt8 = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 1, 127, -128), q1.TYPED_ARRAY_SUPPORT || (t = Math.floor(t)), t < 0 && (t = 255 + t + 1), this[e] = 255 & t, e + 1; +}, q1.prototype.writeInt16LE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 2, 32767, -32768), q1.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8) : Tt(this, t, e, !0), e + 2; +}, q1.prototype.writeInt16BE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 2, 32767, -32768), q1.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 8, this[e + 1] = 255 & t) : Tt(this, t, e, !1), e + 2; +}, q1.prototype.writeInt32LE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 4, 2147483647, -2147483648), q1.TYPED_ARRAY_SUPPORT ? (this[e] = 255 & t, this[e + 1] = t >>> 8, this[e + 2] = t >>> 16, this[e + 3] = t >>> 24) : mt(this, t, e, !0), e + 4; +}, q1.prototype.writeInt32BE = function(t, e, n) { + return t = +t, e |= 0, n || vt(this, t, e, 4, 2147483647, -2147483648), t < 0 && (t = 4294967295 + t + 1), q1.TYPED_ARRAY_SUPPORT ? (this[e] = t >>> 24, this[e + 1] = t >>> 16, this[e + 2] = t >>> 8, this[e + 3] = 255 & t) : mt(this, t, e, !1), e + 4; +}, q1.prototype.writeFloatLE = function(t, e, n) { + return Ct(this, t, e, !0, n); +}, q1.prototype.writeFloatBE = function(t, e, n) { + return Ct(this, t, e, !1, n); +}, q1.prototype.writeDoubleLE = function(t, e, n) { + return It(this, t, e, !0, n); +}, q1.prototype.writeDoubleBE = function(t, e, n) { + return It(this, t, e, !1, n); +}, q1.prototype.copy = function(t, e, n, r) { + if (n || (n = 0), r || 0 === r || (r = this.length), e >= t.length && (e = t.length), e || (e = 0), r > 0 && r < n && (r = n), r === n) return 0; + if (0 === t.length || 0 === this.length) return 0; + if (e < 0) throw new RangeError("targetStart out of bounds"); + if (n < 0 || n >= this.length) throw new RangeError("sourceStart out of bounds"); + if (r < 0) throw new RangeError("sourceEnd out of bounds"); + r > this.length && (r = this.length), t.length - e < r - n && (r = t.length - e + n); + var i, o = r - n; + if (this === t && n < e && e < r) for(i = o - 1; i >= 0; --i)t[i + e] = this[i + n]; + else if (o < 1e3 || !q1.TYPED_ARRAY_SUPPORT) for(i = 0; i < o; ++i)t[i + e] = this[i + n]; + else Uint8Array.prototype.set.call(t, this.subarray(n, n + o), e); + return o; +}, q1.prototype.fill = function(t, e, n, r) { + if ("string" == typeof t) { + if ("string" == typeof e ? (r = e, e = 0, n = this.length) : "string" == typeof n && (r = n, n = this.length), 1 === t.length) { + var i = t.charCodeAt(0); + i < 256 && (t = i); + } + if (void 0 !== r && "string" != typeof r) throw new TypeError("encoding must be a string"); + if ("string" == typeof r && !q1.isEncoding(r)) throw new TypeError("Unknown encoding: " + r); + } else "number" == typeof t && (t &= 255); + if (e < 0 || this.length < e || this.length < n) throw new RangeError("Out of range index"); + if (n <= e) return this; + var o; + if (e >>>= 0, n = void 0 === n ? this.length : n >>> 0, t || (t = 0), "number" == typeof t) for(o = e; o < n; ++o)this[o] = t; + else { + var a = et1(t) ? t : Ot(new q1(t, r).toString()), s = a.length; + for(o = 0; o < n - e; ++o)this[o + e] = a[o % s]; + } + return this; +}; +var Nt = /[^+\/0-9A-Za-z-_]/g; +function Ut(t) { + return t < 16 ? "0" + t.toString(16) : t.toString(16); +} +function Ot(t, e) { + var n; + e = e || 1 / 0; + for(var r = t.length, i = null, o = [], a = 0; a < r; ++a){ + if ((n = t.charCodeAt(a)) > 55295 && n < 57344) { + if (!i) { + if (n > 56319) { + (e -= 3) > -1 && o.push(239, 191, 189); + continue; + } + if (a + 1 === r) { + (e -= 3) > -1 && o.push(239, 191, 189); + continue; + } + i = n; + continue; + } + if (n < 56320) { + (e -= 3) > -1 && o.push(239, 191, 189), i = n; + continue; + } + n = 65536 + (i - 55296 << 10 | n - 56320); + } else i && (e -= 3) > -1 && o.push(239, 191, 189); + if (i = null, n < 128) { + if ((e -= 1) < 0) break; + o.push(n); + } else if (n < 2048) { + if ((e -= 2) < 0) break; + o.push(n >> 6 | 192, 63 & n | 128); + } else if (n < 65536) { + if ((e -= 3) < 0) break; + o.push(n >> 12 | 224, n >> 6 & 63 | 128, 63 & n | 128); + } else { + if (!(n < 1114112)) throw new Error("Invalid code point"); + if ((e -= 4) < 0) break; + o.push(n >> 18 | 240, n >> 12 & 63 | 128, n >> 6 & 63 | 128, 63 & n | 128); + } + } + return o; +} +function Rt(t) { + return function(t) { + var e, n, r, i, o, a; + F1 || M1(); + var s = t.length; + if (s % 4 > 0) throw new Error("Invalid string. Length must be a multiple of 4"); + o = "=" === t[s - 2] ? 2 : "=" === t[s - 1] ? 1 : 0, a = new L1(3 * s / 4 - o), r = o > 0 ? s - 4 : s; + var u = 0; + for(e = 0, n = 0; e < r; e += 4, n += 3)i = H1[t.charCodeAt(e)] << 18 | H1[t.charCodeAt(e + 1)] << 12 | H1[t.charCodeAt(e + 2)] << 6 | H1[t.charCodeAt(e + 3)], a[u++] = i >> 16 & 255, a[u++] = i >> 8 & 255, a[u++] = 255 & i; + return 2 === o ? (i = H1[t.charCodeAt(e)] << 2 | H1[t.charCodeAt(e + 1)] >> 4, a[u++] = 255 & i) : 1 === o && (i = H1[t.charCodeAt(e)] << 10 | H1[t.charCodeAt(e + 1)] << 4 | H1[t.charCodeAt(e + 2)] >> 2, a[u++] = i >> 8 & 255, a[u++] = 255 & i), a; + }(function(t) { + if ((t = (function(t) { + return t.trim ? t.trim() : t.replace(/^\s+|\s+$/g, ""); + })(t).replace(Nt, "")).length < 2) return ""; + for(; t.length % 4 != 0;)t += "="; + return t; + }(t)); +} +function Pt(t, e, n, r) { + for(var i = 0; i < r && !(i + n >= e.length || i >= t.length); ++i)e[i + n] = t[i]; + return i; +} +function Bt(t) { + return null != t && (!!t._isBuffer || St(t) || function(t) { + return "function" == typeof t.readFloatLE && "function" == typeof t.slice && St(t.slice(0, 0)); + }(t)); +} +function St(t) { + return !!t.constructor && "function" == typeof t.constructor.isBuffer && t.constructor.isBuffer(t); +} +var Dt = { + Buffer: q1, + INSPECT_MAX_BYTES: 50, + SlowBuffer: tt1, + isBuffer: Bt, + kMaxLength: $1 +}, Ht = i3(Object.freeze({ + __proto__: null, + Buffer: q1, + INSPECT_MAX_BYTES: 50, + SlowBuffer: tt1, + isBuffer: Bt, + kMaxLength: Q1, + default: Dt +})); +Object.defineProperty(B1, "__esModule", { + value: !0 +}), B1.roundBuffer = B1.verifyBeacon = B1.verifySigOnG1 = void 0; +const Lt = null, Ft = null, Yt = Ht, jt = o4; +async function kt(t, e, n, r = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_") { + const i = (o = n) instanceof null.bls12_381.G2.ProjectivePoint ? o : null.bls12_381.G2.ProjectivePoint.fromHex(o); + var o; + const a = function(t, e) { + return t instanceof null.bls12_381.G1.ProjectivePoint ? t : null.bls12_381.G1.hashToCurve((0, null.ensureBytes)("point", t), { + DST: e + }); + }(e, r), s = null.bls12_381.G2.ProjectivePoint.BASE, u = function(t) { + return t instanceof null.bls12_381.G1.ProjectivePoint ? t : null.bls12_381.G1.ProjectivePoint.fromHex(t); + }(t), f = null.bls12_381.pairing(a, i.negate(), !0), c = null.bls12_381.pairing(u, s, !0), h = null.bls12_381.fields.Fp12.mul(c, f); + return null.bls12_381.fields.Fp12.eql(h, null.bls12_381.fields.Fp12.ONE); +} +async function xt(t) { + return (0, null.sha256)(Kt(t.round)); +} +function Gt(t) { + return Yt.Buffer.from(t, "hex"); +} +function Kt(t) { + const e = Yt.Buffer.alloc(8); + return e.writeBigUInt64BE(BigInt(t)), e; +} +B1.verifyBeacon = async function(t, e, n) { + const r = t.public_key; + return e.round !== n ? (console.error("round was not the expected round"), !1) : await async function(t) { + const e = (0, Ft.sha256)(Yt.Buffer.from(t.signature, "hex")); + return 0 == Yt.Buffer.from(t.randomness, "hex").compare(e); + }(e) ? (0, jt.isChainedBeacon)(e, t) ? Lt.bls12_381.verify(e.signature, await async function(t) { + const e = Yt.Buffer.concat([ + Gt(t.previous_signature), + Kt(t.round) + ]); + return (0, Ft.sha256)(e); + }(e), r) : (0, jt.isUnchainedBeacon)(e, t) ? Lt.bls12_381.verify(e.signature, await xt(e), r) : (0, jt.isG1G2SwappedBeacon)(e, t) ? kt(e.signature, await xt(e), r) : (0, jt.isG1Rfc9380)(e, t) ? kt(e.signature, await xt(e), r, "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_") : (console.error(`Beacon type ${t.schemeID} was not supported or the beacon was not of the purported type`), !1) : (console.error("randomness did not match the signature"), !1); +}, B1.verifySigOnG1 = kt, B1.roundBuffer = Kt; +var Qt = {}; +!function(t) { + var e = r3 && r3.__importDefault || function(t) { + return t && t.__esModule ? t : { + default: t + }; + }; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.testnetQuicknetClient = t.testnetDefaultClient = t.fastnetClient = t.quicknetClient = t.defaultClient = t.TESTNET_QUICKNET_CHAIN_INFO = t.TESTNET_QUICKNET_CHAIN_URL = t.TESTNET_DEFAULT_CHAIN_INFO = t.TESTNET_DEFAULT_CHAIN_URL = t.FASTNET_CHAIN_INFO = t.FASTNET_CHAIN_URL = t.QUICKNET_CHAIN_INFO = t.QUICKNET_CHAIN_URL = t.DEFAULT_CHAIN_INFO = t.DEFAULT_CHAIN_URL = void 0; + const n = o4, i = e(l3), s = e(a3); + t.DEFAULT_CHAIN_URL = "https://api.drand.sh", t.DEFAULT_CHAIN_INFO = { + public_key: "868f005eb8e6e4ca0a47c8a77ceaa5309a47978a7c71bc5cce96366b5d7a569937c529eeda66c7293784a9402801af31", + period: 30, + genesis_time: 1595431050, + hash: "8990e7a9aaed2ffed73dbd7092123d6f289930540d7651336225dc172e51b2ce", + groupHash: "176f93498eac9ca337150b46d21dd58673ea4e3581185f869672e59fa4cb390a", + schemeID: "pedersen-bls-chained", + metadata: { + beaconID: "default" + } + }, t.QUICKNET_CHAIN_URL = "https://api.drand.sh/52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971", t.QUICKNET_CHAIN_INFO = { + public_key: "83cf0f2896adee7eb8b5f01fcad3912212c437e0073e911fb90022d3e760183c8c4b450b6a0a6c3ac6a5776a2d1064510d1fec758c921cc22b0e17e63aaf4bcb5ed66304de9cf809bd274ca73bab4af5a6e9c76a4bc09e76eae8991ef5ece45a", + period: 3, + genesis_time: 1692803367, + hash: "52db9ba70e0cc0f6eaf7803dd07447a1f5477735fd3f661792ba94600c84e971", + groupHash: "f477d5c89f21a17c863a7f937c6a6d15859414d2be09cd448d4279af331c5d3e", + schemeID: "bls-unchained-g1-rfc9380", + metadata: { + beaconID: "quicknet" + } + }, t.FASTNET_CHAIN_URL = "https://api.drand.sh/dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493", t.FASTNET_CHAIN_INFO = { + hash: "dbd506d6ef76e5f386f41c651dcb808c5bcbd75471cc4eafa3f4df7ad4e4c493", + public_key: "a0b862a7527fee3a731bcb59280ab6abd62d5c0b6ea03dc4ddf6612fdfc9d01f01c31542541771903475eb1ec6615f8d0df0b8b6dce385811d6dcf8cbefb8759e5e616a3dfd054c928940766d9a5b9db91e3b697e5d70a975181e007f87fca5e", + period: 3, + genesis_time: 1677685200, + groupHash: "a81e9d63f614ccdb144b8ff79fbd4d5a2d22055c0bfe4ee9a8092003dab1c6c0", + schemeID: "bls-unchained-on-g1", + metadata: { + beaconID: "fastnet" + } + }, t.TESTNET_DEFAULT_CHAIN_URL = "https://pl-us.testnet.drand.sh", t.TESTNET_DEFAULT_CHAIN_INFO = { + public_key: "922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df", + period: 25, + genesis_time: 1590445175, + hash: "84b2234fb34e835dccd048255d7ad3194b81af7d978c3bf157e3469592ae4e02", + groupHash: "4dd408e5fdff9323c76a9b6f087ba8fdc5a6da907bd9217d9d10f2287d081957", + schemeID: "pedersen-bls-chained", + metadata: { + beaconID: "default" + } + }, t.TESTNET_QUICKNET_CHAIN_URL = "https://pl-us.testnet.drand.sh/cc9c398442737cbd141526600919edd69f1d6f9b4adb67e4d912fbc64341a9a5", t.TESTNET_QUICKNET_CHAIN_INFO = { + public_key: "b15b65b46fb29104f6a4b5d1e11a8da6344463973d423661bb0804846a0ecd1ef93c25057f1c0baab2ac53e56c662b66072f6d84ee791a3382bfb055afab1e6a375538d8ffc451104ac971d2dc9b168e2d3246b0be2015969cbaac298f6502da", + period: 3, + genesis_time: 1689232296, + hash: "cc9c398442737cbd141526600919edd69f1d6f9b4adb67e4d912fbc64341a9a5", + groupHash: "40d49d910472d4adb1d67f65db8332f11b4284eecf05c05c5eacd5eef7d40e2d", + schemeID: "bls-unchained-g1-rfc9380", + metadata: { + beaconID: "quicknet-t" + } + }, t.defaultClient = function() { + const e = { + ...n.defaultChainOptions, + chainVerificationParams: { + chainHash: t.DEFAULT_CHAIN_INFO.hash, + publicKey: t.DEFAULT_CHAIN_INFO.public_key + } + }, r = new s.default(t.DEFAULT_CHAIN_URL, e); + return new i.default(r, e); + }, t.quicknetClient = function() { + const e = { + ...n.defaultChainOptions, + chainVerificationParams: { + chainHash: t.QUICKNET_CHAIN_INFO.hash, + publicKey: t.QUICKNET_CHAIN_INFO.public_key + } + }, r = new s.default(t.QUICKNET_CHAIN_URL, e); + return new i.default(r, e); + }, t.fastnetClient = function() { + const e = { + ...n.defaultChainOptions, + chainVerificationParams: { + chainHash: t.FASTNET_CHAIN_INFO.hash, + publicKey: t.FASTNET_CHAIN_INFO.public_key + } + }, r = new s.default(t.FASTNET_CHAIN_URL, e); + return new i.default(r, e); + }, t.testnetDefaultClient = function() { + const e = { + ...n.defaultChainOptions, + chainVerificationParams: { + chainHash: t.TESTNET_DEFAULT_CHAIN_INFO.hash, + publicKey: t.TESTNET_DEFAULT_CHAIN_INFO.public_key + } + }, r = new s.default(t.TESTNET_DEFAULT_CHAIN_URL, e); + return new i.default(r, e); + }, t.testnetQuicknetClient = function() { + const e = { + ...n.defaultChainOptions, + chainVerificationParams: { + chainHash: t.TESTNET_QUICKNET_CHAIN_INFO.hash, + publicKey: t.TESTNET_QUICKNET_CHAIN_INFO.public_key + } + }, r = new s.default(t.TESTNET_QUICKNET_CHAIN_URL, e); + return new i.default(r, e); + }; +}(Qt), function(t) { + var e = r3 && r3.__importDefault || function(t) { + return t && t.__esModule ? t : { + default: t + }; + }; + Object.defineProperty(t, "__esModule", { + value: !0 + }), t.testnetQuicknetClient = t.testnetDefaultClient = t.fastnetClient = t.quicknetClient = t.defaultClient = t.roundTime = t.roundAt = t.FastestNodeClient = t.MultiBeaconNode = t.HttpCachingChain = t.HttpChainClient = t.HttpChain = t.isG1Rfc9380 = t.isG1G2SwappedBeacon = t.isUnchainedBeacon = t.isChainedBeacon = t.watch = t.fetchBeaconByTime = t.fetchBeacon = t.defaultChainOptions = void 0; + const n = e(a3); + t.HttpCachingChain = n.default; + const i = a3; + Object.defineProperty(t, "HttpChain", { + enumerable: !0, + get: function() { + return i.HttpChain; + } + }); + const o = e(l3); + t.HttpChainClient = o.default; + const u = e(g2); + t.FastestNodeClient = u.default; + const f = e(N10); + t.MultiBeaconNode = f.default; + const c = s3; + Object.defineProperty(t, "roundAt", { + enumerable: !0, + get: function() { + return c.roundAt; + } + }), Object.defineProperty(t, "roundTime", { + enumerable: !0, + get: function() { + return c.roundTime; + } + }); + const h = B1, d = Qt; + async function p(t, e) { + if (e || (e = (0, c.roundAt)(Date.now(), await t.chain().info())), e < 1) throw Error("Cannot request lower than round number 1"); + const n = await t.get(e); + return _(t, n, e); + } + Object.defineProperty(t, "defaultClient", { + enumerable: !0, + get: function() { + return d.defaultClient; + } + }), Object.defineProperty(t, "fastnetClient", { + enumerable: !0, + get: function() { + return d.fastnetClient; + } + }), Object.defineProperty(t, "quicknetClient", { + enumerable: !0, + get: function() { + return d.quicknetClient; + } + }), Object.defineProperty(t, "testnetDefaultClient", { + enumerable: !0, + get: function() { + return d.testnetDefaultClient; + } + }), Object.defineProperty(t, "testnetQuicknetClient", { + enumerable: !0, + get: function() { + return d.testnetQuicknetClient; + } + }), t.defaultChainOptions = { + disableBeaconVerification: !1, + noCache: !1 + }, t.fetchBeacon = p, t.fetchBeaconByTime = async function(t, e) { + const n = await t.chain().info(); + return p(t, (0, c.roundAt)(e, n)); + }, t.watch = async function*(t, e, n = b) { + const r = await t.chain().info(); + let i = (0, c.roundAt)(Date.now(), r); + for(; !e.signal.aborted;){ + const e = Date.now(); + await (0, c.sleep)((0, c.roundTime)(r, i) - e); + const o = await (0, c.retryOnError)(async ()=>t.get(i), n.retriesOnFailure); + yield _(t, o, i), i += 1; + } + }; + const b = { + retriesOnFailure: 3 + }; + async function _(t, e, n) { + if (t.options.disableBeaconVerification) return e; + const r = await t.chain().info(); + if (!await (0, h.verifyBeacon)(r, e, n)) throw Error("The beacon retrieved was not valid!"); + return e; + } + t.isChainedBeacon = function(t, e) { + return "pedersen-bls-chained" === e.schemeID && !!t.previous_signature && !!t.randomness && !!t.signature && t.round > 0; + }, t.isUnchainedBeacon = function(t, e) { + return "pedersen-bls-unchained" === e.schemeID && !!t.randomness && !!t.signature && void 0 === t.previous_signature && t.round > 0; + }, t.isG1G2SwappedBeacon = function(t, e) { + return "bls-unchained-on-g1" === e.schemeID && !!t.randomness && !!t.signature && void 0 === t.previous_signature && t.round > 0; + }, t.isG1Rfc9380 = function(t, e) { + return "bls-unchained-g1-rfc9380" === e.schemeID && !!t.randomness && !!t.signature && void 0 === t.previous_signature && t.round > 0; + }; +}(o4); +var $t = o4.FastestNodeClient, Vt = o4.HttpCachingChain, qt = o4.HttpChain, zt = o4.HttpChainClient, Xt = o4.MultiBeaconNode, Wt = o4.__esModule, Jt = o4.defaultChainOptions, Zt = o4.defaultClient, te1 = o4.fastnetClient, ee1 = o4.fetchBeacon, ne1 = o4.fetchBeaconByTime, re1 = o4.isChainedBeacon, ie1 = o4.isG1G2SwappedBeacon, oe1 = o4.isG1Rfc9380, ae1 = o4.isUnchainedBeacon, se1 = o4.quicknetClient, ue1 = o4.roundAt, fe1 = o4.roundTime, ce1 = o4.testnetDefaultClient, he1 = o4.testnetQuicknetClient, le1 = o4.watch; export { encodeHex as encodeHex }; export { decodeBase64 as decodeBase64 }; export { decode as decodeVarint }; export { CarBlockIterator as CarBlockIterator }; export { UnsupportedHashError as UnsupportedHashError, HashMismatchError as HashMismatchError, validateBlock as validateBlock }; +export { ne1 as fetchBeaconByTime, zt as HttpChainClient, Vt as HttpCachingChain }; From f9aa7ae519010206a6e4785c792a049ca72e2596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Mon, 22 Jul 2024 13:26:37 +0200 Subject: [PATCH 2/5] feat: deterministic tasking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- lib/http-assertions.js | 43 +++++++++++ lib/spark.js | 49 +++++-------- lib/tasker.js | 150 ++++++++++++++++++++++++++++++++++++++ test/drand-client.test.js | 2 +- test/spark.js | 44 ++++++++--- test/tasker.test.js | 47 ++++++++++++ 6 files changed, 291 insertions(+), 44 deletions(-) create mode 100644 lib/http-assertions.js create mode 100644 lib/tasker.js create mode 100644 test/tasker.test.js diff --git a/lib/http-assertions.js b/lib/http-assertions.js new file mode 100644 index 0000000..b2b8f29 --- /dev/null +++ b/lib/http-assertions.js @@ -0,0 +1,43 @@ +import { AssertionError } from 'zinnia:assert' + +/** + * @param {Response} res + * @param {string} [errorMsg] + */ +export async function assertOkResponse (res, errorMsg) { + if (res.ok) return + + let body + try { + body = await res.text() + } catch {} + const err = new Error(`${errorMsg ?? 'Fetch failed'} (${res.status}): ${body?.trimEnd()}`) + err.statusCode = res.status + err.serverMessage = body + throw err +} + +/** + * @param {Response} res + * @param {string} [errorMsg] + */ +export async function assertRedirectResponse (res, errorMsg) { + if ([301, 302, 303, 304, 307, 308].includes(res.status)) { + const location = res.headers.get('location') + if (!location) { + const msg = 'The server response is missing the Location header. Headers found:\n' + + Array.from(res.headers.keys()).join('\n') + throw new AssertionError(msg) + } + return location + } + + let body + try { + body = await res.text() + } catch {} + const err = new Error(`${errorMsg ?? 'Server did not respond with redirection'} (${res.status}): ${body?.trimEnd()}`) + err.statusCode = res.status + err.serverMessage = body + throw err +} diff --git a/lib/spark.js b/lib/spark.js index f8a6e66..e58fdf8 100644 --- a/lib/spark.js +++ b/lib/spark.js @@ -3,8 +3,10 @@ import { ActivityState } from './activity-state.js' import { SPARK_VERSION, MAX_CAR_SIZE, APPROX_ROUND_LENGTH_IN_MS } from './constants.js' import { queryTheIndex } from './ipni-client.js' +import { assertOkResponse } from './http-assertions.js' import { getMinerPeerId as defaultGetMinerPeerId } from './miner-info.js' import { multiaddrToHttpUrl } from './multiaddr.js' +import { Tasker } from './tasker.js' import { CarBlockIterator, @@ -20,7 +22,7 @@ export default class Spark { #fetch #getMinerPeerId #activity = new ActivityState() - #maxTasksPerNode = 360 + #tasker constructor ({ fetch = globalThis.fetch, @@ -28,25 +30,17 @@ export default class Spark { } = {}) { this.#fetch = fetch this.#getMinerPeerId = getMinerPeerId + this.#tasker = new Tasker({ + fetch: this.#fetch, + activityState: this.#activity + }) } async getRetrieval () { - console.log('Getting current SPARK round details...') - const res = await this.#fetch('https://api.filspark.com/rounds/current', { - method: 'GET', - headers: { 'Content-Type': 'application/json' }, - signal: AbortSignal.timeout(10_000) - }) - await assertOkResponse(res, 'Failed to fetch the current SPARK round') - this.#activity.onHealthy() - const { retrievalTasks, maxTasksPerNode, ...round } = await res.json() - console.log('Current SPARK round:', round) - console.log(' %s max tasks per node', maxTasksPerNode ?? '') - console.log(' %s retrieval tasks', retrievalTasks.length) - if (maxTasksPerNode) this.#maxTasksPerNode = maxTasksPerNode - - const retrieval = retrievalTasks[Math.floor(Math.random() * retrievalTasks.length)] - console.log({ retrieval }) + const retrieval = await this.#tasker.next() + if (retrieval) { + console.log({ retrieval }) + } return retrieval } @@ -190,7 +184,11 @@ export default class Spark { } async nextRetrieval () { - const { id: retrievalId, ...retrieval } = await this.getRetrieval() + const retrieval = await this.getRetrieval() + if (!retrieval) { + console.log('Completed all tasks for the current round. Waiting for the next round to start.') + return + } const stats = newStats() @@ -211,7 +209,7 @@ export default class Spark { this.handleRunError(err) } const duration = Date.now() - started - const baseDelay = APPROX_ROUND_LENGTH_IN_MS / this.#maxTasksPerNode + const baseDelay = APPROX_ROUND_LENGTH_IN_MS / this.#tasker.maxTasksPerRound const delay = baseDelay - duration if (delay > 0) { console.log('Sleeping for %s seconds before starting the next task...', Math.round(delay / 1000)) @@ -320,16 +318,3 @@ function mapErrorToStatusCode (err) { // Fallback code for unknown errors return 600 } - -async function assertOkResponse (res, errorMsg) { - if (res.ok) return - - let body - try { - body = await res.text() - } catch {} - const err = new Error(`${errorMsg ?? 'Fetch failed'} (${res.status}): ${body.trimEnd()}`) - err.statusCode = res.status - err.serverMessage = body - throw err -} diff --git a/lib/tasker.js b/lib/tasker.js new file mode 100644 index 0000000..43b5fc6 --- /dev/null +++ b/lib/tasker.js @@ -0,0 +1,150 @@ +/* global Zinnia */ + +import { ActivityState } from './activity-state.js' +import { encodeHex } from '../vendor/deno-deps.js' +import { assertOkResponse, assertRedirectResponse } from './http-assertions.js' +import { getRandomnessForSparkRound } from './drand-client.js' +import { assertEquals, assertInstanceOf } from 'zinnia:assert' + +/** @typedef {{cid: string; minerId: string;}} RetrievalTask */ +/** @typedef {RetrievalTask & { key: string}} KeyedRetrievalTask */ + +export class Tasker { + #lastRoundUrl + /** @type {Task[]} */ + #remainingRoundTasks + #fetch + #activity + + /** + * @param {object} args + * @param {globalThis.fetch} args.fetch + * @param {ActivityState} args.activityState + */ + constructor ({ + fetch = globalThis.fetch, + activityState = new ActivityState() + } = {}) { + this.#fetch = fetch + this.#activity = activityState + + this.maxTasksPerRound = 360 + + // TODO: persist these two values across module restarts + this.#lastRoundUrl = 'unknown' + this.#remainingRoundTasks = [] + } + + /** + * @returns {Task | undefined} + */ + async next () { + await this.#updateCurrentRound() + return this.#remainingRoundTasks.pop() + } + + async #updateCurrentRound () { + console.log('Checking the current SPARK round...') + let res = await this.#fetch('https://api.filspark.com/rounds/current', { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + redirect: 'manual', + signal: AbortSignal.timeout(10_000) + }) + + const roundUrl = await assertRedirectResponse(res, 'Failed to find the URL of the current SPARK round') + this.#activity.onHealthy() + if (roundUrl === this.#lastRoundUrl) { + console.log('Round did not change since the last iteration') + return + } + + console.log('Fetching round details at location %s', roundUrl) + this.#lastRoundUrl = roundUrl + res = await this.#fetch(`https://api.filspark.com${roundUrl}`, { + method: 'GET', + headers: { 'Content-Type': 'application/json' }, + signal: AbortSignal.timeout(10_000) + }) + await assertOkResponse(res, 'Failed to fetch the current SPARK round') + const { retrievalTasks, maxTasksPerNode, ...round } = await res.json() + console.log('Current SPARK round:', round) + console.log(' %s max tasks per round', maxTasksPerNode ?? '') + console.log(' %s retrieval tasks', retrievalTasks.length) + this.maxTasksPerRound = maxTasksPerNode + + const randomness = await getRandomnessForSparkRound(round.startEpoch) + console.log(' randomness: %s', randomness) + + this.#remainingRoundTasks = await pickTasksForNode({ + tasks: retrievalTasks, + maxTasksPerRound: this.maxTasksPerRound, + randomness, + stationId: Zinnia.stationId + }) + } +} + +const textEncoder = new TextEncoder() + +/** + * @param {Task} task + * @param {string} randomness + * @returns + */ +export async function getTaskKey (task, randomness) { + assertEquals(typeof task, 'object', 'task must be an object') + assertEquals(typeof task.cid, 'string', 'task.cid must be a string') + assertEquals(typeof task.minerId, 'string', 'task.minerId must be a string') + assertEquals(typeof randomness, 'string', 'randomness must be a string') + + const data = [task.cid, task.minerId, randomness].join('\n') + const hash = await crypto.subtle.digest('sha-256', textEncoder.encode(data)) + return BigInt('0x' + encodeHex(hash)) +} + +/** + * @param {string} stationId + */ +export async function getStationKey (stationId) { + assertEquals(typeof stationId, 'string', 'stationId must be a string') + + const hash = await crypto.subtle.digest('sha-256', textEncoder.encode(stationId)) + return BigInt('0x' + encodeHex(hash)) +} + +/** + * @param {object} args + * @param {Task[]} args.tasks + * @param {string} args.stationId + * @param {string} args.randomness + * @param {number} args.maxTasksPerRound + * @returns {Promise} + */ +export async function pickTasksForNode ({ tasks, stationId, randomness, maxTasksPerRound }) { + assertInstanceOf(tasks, Array, 'tasks must be an array') + assertEquals(typeof stationId, 'string', 'stationId must be a string') + assertEquals(typeof randomness, 'string', 'randomness must be a string') + assertEquals(typeof maxTasksPerRound, 'number', 'maxTasksPerRound must be a number') + + const keyedTasks = await Promise.all(tasks.map( + async (t) => ({ ...t, key: await getTaskKey(t, randomness) }) + )) + const stationKey = await getStationKey(stationId) + + /** + * @param {{key: bigint}} a + * @param {{key: bigint}} b + * @returns {number} + */ + const comparator = (a, b) => { + const ad = a.key ^ stationKey + const bd = b.key ^ stationKey + return ad > bd ? 1 : ad < bd ? -1 : 0 + } + + keyedTasks.sort(comparator) + keyedTasks.splice(maxTasksPerRound) + + return keyedTasks.map(({ key, ...t }) => (t)) +} diff --git a/test/drand-client.test.js b/test/drand-client.test.js index 77ee80b..79ba55a 100644 --- a/test/drand-client.test.js +++ b/test/drand-client.test.js @@ -1,6 +1,6 @@ import { test } from 'zinnia:test' import { assertEquals } from 'zinnia:assert' -import { getRandomnessForSparkRound } from '../lib/drand-client.js' +import { getRandomnessForSparkRound } from '../lib/drand-client.js' test('getRandomnessForSparkRound', async () => { const randomness = await getRandomnessForSparkRound(4111111) diff --git a/test/spark.js b/test/spark.js index 9f491b4..f73bc66 100644 --- a/test/spark.js +++ b/test/spark.js @@ -10,16 +10,16 @@ const KNOWN_CID = 'bafkreih25dih6ug3xtj73vswccw423b56ilrwmnos4cbwhrceudopdp5sq' test('getRetrieval', async () => { const round = { roundId: '123', + startEpoch: 4111111, + maxTasksPerNode: 1, retrievalTasks: [ { cid: 'bafkreidysaugf7iuvemebpzwxxas5rctbyiryykagup2ygkojmx7ag64gy', - providerAddress: '/ip4/38.70.220.96/tcp/10201/p2p/12D3KooWSekjEqdSeHXkpQraVY2STL885svgmh6r2zEFHQKeJ3KD', - protocol: 'graphsync' + minerId: 'f010' }, { cid: 'QmUMpWycKJ7GUDJp9GBRX4qWUFUePUmHzri9Tm1CQHEzbJ', - providerAddress: '/dns4/elastic.dag.house/tcp/443/wss/p2p/QmQzqxhK82kAmKvARFZSkUVS6fo9sySaiogAnx5EnZ6ZmC', - protocol: 'bitswap' + minerId: 'f020' } ] } @@ -27,6 +27,16 @@ test('getRetrieval', async () => { const fetch = async (url, allOpts) => { const { signal, ...opts } = allOpts requests.push({ url, opts }) + if (url === 'https://api.filspark.com/rounds/current') { + const headers = new Headers() + headers.set('location', '/rounds/meridian/0x84607/115') + return { + status: 302, + ok: false, + headers + } + } + return { status: 200, ok: true, @@ -37,14 +47,26 @@ test('getRetrieval', async () => { } const spark = new Spark({ fetch }) const retrieval = await spark.getRetrieval() - assertArrayIncludes(round.retrievalTasks, [retrieval]) - assertEquals(requests, [{ - url: 'https://api.filspark.com/rounds/current', - opts: { - method: 'GET', - headers: { 'Content-Type': 'application/json' } + assertArrayIncludes(round.retrievalTasks.map(JSON.stringify), [retrieval].map(JSON.stringify)) + assertEquals(requests, [ + { + url: 'https://api.filspark.com/rounds/current', + opts: { + method: 'GET', + redirect: 'manual', + headers: { 'Content-Type': 'application/json' } + } + }, + { + url: 'https://api.filspark.com/rounds/meridian/0x84607/115', + opts: { + headers: { + 'Content-Type': 'application/json' + }, + method: 'GET' + } } - }]) + ]) }) test('fetchCAR - http', async () => { diff --git a/test/tasker.test.js b/test/tasker.test.js new file mode 100644 index 0000000..1876817 --- /dev/null +++ b/test/tasker.test.js @@ -0,0 +1,47 @@ +/* global Zinnia */ + +import { test } from 'zinnia:test' +import { assertEquals } from 'zinnia:assert' +import { getStationKey, getTaskKey, pickTasks } from '../lib/tasker.js' + +const RANDOMNESS = 'fc90e50dcdf20886b56c038b30fa921a5e57c532ea448dadcc209e44eec0445e' + +test('getTaskKey', async () => { + const key = await getTaskKey( + { cid: 'bafyone', minerId: 'f0123' }, + RANDOMNESS + ) + assertEquals(key, 19408172415633384483144889917969030396168570904487614072975030553911283422991n) +}) + +test('getStationKey', async () => { + const key = await getStationKey(Zinnia.stationId) + assertEquals(key, 15730389902218173522122968096857080019341969656147255283496861606681823756880n) +}) + +test('pickTasksForNode', async () => { + const allTasks = [ + { cid: 'bafyone', minerId: 'f010' }, + { cid: 'bafyone', minerId: 'f020' }, + { cid: 'bafyone', minerId: 'f030' }, + { cid: 'bafyone', minerId: 'f040' }, + + { cid: 'bafytwo', minerId: 'f010' }, + { cid: 'bafytwo', minerId: 'f020' }, + { cid: 'bafytwo', minerId: 'f030' }, + { cid: 'bafytwo', minerId: 'f040' } + ] + + const selectedTasks = await pickTasks({ + tasks: allTasks, + stationId: 'some-station-id', + randomness: RANDOMNESS, + maxTasksPerRound: 3 + }) + + assertEquals(selectedTasks, [ + { cid: 'bafyone', minerId: 'f020' }, + { cid: 'bafyone', minerId: 'f010' }, + { cid: 'bafytwo', minerId: 'f020' } + ]) +}) From 4ea71d24c5d3119e050da485d8cbd75a7b3977f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Wed, 24 Jul 2024 08:19:25 +0200 Subject: [PATCH 3/5] Update lib/tasker.js Co-authored-by: Julian Gruber --- lib/tasker.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/tasker.js b/lib/tasker.js index 43b5fc6..1926128 100644 --- a/lib/tasker.js +++ b/lib/tasker.js @@ -52,7 +52,8 @@ export class Tasker { signal: AbortSignal.timeout(10_000) }) - const roundUrl = await assertRedirectResponse(res, 'Failed to find the URL of the current SPARK round') + await assertRedirectResponse(res, 'Failed to find the URL of the current SPARK round') + const roundUrl = res.headers.get('location') this.#activity.onHealthy() if (roundUrl === this.#lastRoundUrl) { console.log('Round did not change since the last iteration') From b4a04af886ca6ed7299ffa21703f220fca82dea7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Wed, 24 Jul 2024 08:36:59 +0200 Subject: [PATCH 4/5] fixup! address review comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- lib/drand-client.js | 1 + lib/http-assertions.js | 7 ++++--- lib/tasker.js | 5 ++++- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/lib/drand-client.js b/lib/drand-client.js index 0db3fba..4647a5a 100644 --- a/lib/drand-client.js +++ b/lib/drand-client.js @@ -11,6 +11,7 @@ const FIL_MAINNET_BLOCK_TIME = 30_000 // 30 seconds /** @type {import('https://cdn.skypack.dev/drand-client@1.2.6/?dts').ChainOptions} */ const DRAND_OPTIONS = { // FIXME: beacon verification does not work when using drand-client via CDN :( + // Without verification, we are blindly trusting https://api.drand.sh/ to provide honest responses. disableBeaconVerification: true, noCache: false, chainVerificationParams: { diff --git a/lib/http-assertions.js b/lib/http-assertions.js index b2b8f29..bcec437 100644 --- a/lib/http-assertions.js +++ b/lib/http-assertions.js @@ -25,18 +25,19 @@ export async function assertRedirectResponse (res, errorMsg) { if ([301, 302, 303, 304, 307, 308].includes(res.status)) { const location = res.headers.get('location') if (!location) { - const msg = 'The server response is missing the Location header. Headers found:\n' + + const msg = (errorMsg ? errorMsg + ' ' : '') + + 'The server response is missing the Location header. Headers found:\n' + Array.from(res.headers.keys()).join('\n') throw new AssertionError(msg) } - return location + return } let body try { body = await res.text() } catch {} - const err = new Error(`${errorMsg ?? 'Server did not respond with redirection'} (${res.status}): ${body?.trimEnd()}`) + const err = new Error(`${errorMsg ?? 'Server did not respond with redirect'} (${res.status}): ${body?.trimEnd()}`) err.statusCode = res.status err.serverMessage = body throw err diff --git a/lib/tasker.js b/lib/tasker.js index 1926128..0b50058 100644 --- a/lib/tasker.js +++ b/lib/tasker.js @@ -31,6 +31,8 @@ export class Tasker { this.maxTasksPerRound = 360 // TODO: persist these two values across module restarts + // Without persistence, after the Spark module is restarted, it will start executing the same + // retrieval tasks we have already executed this.#lastRoundUrl = 'unknown' this.#remainingRoundTasks = [] } @@ -61,7 +63,6 @@ export class Tasker { } console.log('Fetching round details at location %s', roundUrl) - this.#lastRoundUrl = roundUrl res = await this.#fetch(`https://api.filspark.com${roundUrl}`, { method: 'GET', headers: { 'Content-Type': 'application/json' }, @@ -83,6 +84,8 @@ export class Tasker { randomness, stationId: Zinnia.stationId }) + + this.#lastRoundUrl = roundUrl } } From 489a2134522ac1682d352cd21d75c48f2ed27f07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Wed, 24 Jul 2024 11:01:39 +0200 Subject: [PATCH 5/5] fixup! add a link to a GH issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miroslav Bajtoš --- lib/drand-client.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/drand-client.js b/lib/drand-client.js index 4647a5a..975b810 100644 --- a/lib/drand-client.js +++ b/lib/drand-client.js @@ -12,6 +12,7 @@ const FIL_MAINNET_BLOCK_TIME = 30_000 // 30 seconds const DRAND_OPTIONS = { // FIXME: beacon verification does not work when using drand-client via CDN :( // Without verification, we are blindly trusting https://api.drand.sh/ to provide honest responses. + // See https://github.com/filecoin-station/spark/issues/86 disableBeaconVerification: true, noCache: false, chainVerificationParams: {