Files
crowd-funder-for-time-pwa/sw_scripts/noble-curves.js
Matthew Aaron Raymer d93299c352 Update worker dependencies
2023-12-01 17:04:14 +08:00

5249 lines
177 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use strict";
var nobleCurves = (() => {
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if ((from && typeof from === "object") || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, {
get: () => from[key],
enumerable:
!(desc = __getOwnPropDesc(from, key)) || desc.enumerable,
});
}
return to;
};
var __toCommonJS = (mod2) =>
__copyProps(__defProp({}, "__esModule", { value: true }), mod2);
// input.js
var input_exports = {};
__export(input_exports, {
bls12_381: () => bls12_381,
ed25519: () => ed25519,
ed25519_edwardsToMontgomeryPriv: () => edwardsToMontgomeryPriv,
ed25519_edwardsToMontgomeryPub: () => edwardsToMontgomeryPub,
ed448: () => ed448,
ed448_edwardsToMontgomeryPub: () => edwardsToMontgomeryPub2,
p256: () => p256,
p384: () => p384,
p521: () => p521,
secp256k1: () => secp256k1,
secp256k1_schnorr: () => schnorr,
utils: () => utils,
x25519: () => x25519,
x448: () => x448,
});
// ../esm/abstract/utils.js
var utils_exports = {};
__export(utils_exports, {
bitGet: () => bitGet,
bitLen: () => bitLen,
bitMask: () => bitMask,
bitSet: () => bitSet,
bytesToHex: () => bytesToHex,
bytesToNumberBE: () => bytesToNumberBE,
bytesToNumberLE: () => bytesToNumberLE,
concatBytes: () => concatBytes,
createHmacDrbg: () => createHmacDrbg,
ensureBytes: () => ensureBytes,
equalBytes: () => equalBytes,
hexToBytes: () => hexToBytes,
hexToNumber: () => hexToNumber,
numberToBytesBE: () => numberToBytesBE,
numberToBytesLE: () => numberToBytesLE,
numberToHexUnpadded: () => numberToHexUnpadded,
numberToVarBytesBE: () => numberToVarBytesBE,
utf8ToBytes: () => utf8ToBytes,
validateObject: () => validateObject,
});
var _0n = BigInt(0);
var _1n = BigInt(1);
var _2n = BigInt(2);
var u8a = (a) => a instanceof Uint8Array;
var hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) =>
i.toString(16).padStart(2, "0"),
);
function bytesToHex(bytes2) {
if (!u8a(bytes2)) throw new Error("Uint8Array expected");
let hex = "";
for (let i = 0; i < bytes2.length; i++) {
hex += hexes[bytes2[i]];
}
return hex;
}
function numberToHexUnpadded(num) {
const hex = num.toString(16);
return hex.length & 1 ? `0${hex}` : hex;
}
function hexToNumber(hex) {
if (typeof hex !== "string")
throw new Error("hex string expected, got " + typeof hex);
return BigInt(hex === "" ? "0" : `0x${hex}`);
}
function hexToBytes(hex) {
if (typeof hex !== "string")
throw new Error("hex string expected, got " + typeof hex);
const len = hex.length;
if (len % 2)
throw new Error(
"padded hex string expected, got unpadded hex of length " + len,
);
const array = new Uint8Array(len / 2);
for (let i = 0; i < array.length; i++) {
const j = i * 2;
const hexByte = hex.slice(j, j + 2);
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte) || byte < 0)
throw new Error("Invalid byte sequence");
array[i] = byte;
}
return array;
}
function bytesToNumberBE(bytes2) {
return hexToNumber(bytesToHex(bytes2));
}
function bytesToNumberLE(bytes2) {
if (!u8a(bytes2)) throw new Error("Uint8Array expected");
return hexToNumber(bytesToHex(Uint8Array.from(bytes2).reverse()));
}
function numberToBytesBE(n, len) {
return hexToBytes(n.toString(16).padStart(len * 2, "0"));
}
function numberToBytesLE(n, len) {
return numberToBytesBE(n, len).reverse();
}
function numberToVarBytesBE(n) {
return hexToBytes(numberToHexUnpadded(n));
}
function ensureBytes(title, hex, expectedLength) {
let res;
if (typeof hex === "string") {
try {
res = hexToBytes(hex);
} catch (e) {
throw new Error(
`${title} must be valid hex string, got "${hex}". Cause: ${e}`,
);
}
} else if (u8a(hex)) {
res = Uint8Array.from(hex);
} else {
throw new Error(`${title} must be hex string or Uint8Array`);
}
const len = res.length;
if (typeof expectedLength === "number" && len !== expectedLength)
throw new Error(`${title} expected ${expectedLength} bytes, got ${len}`);
return res;
}
function concatBytes(...arrays) {
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
let pad = 0;
arrays.forEach((a) => {
if (!u8a(a)) throw new Error("Uint8Array expected");
r.set(a, pad);
pad += a.length;
});
return r;
}
function equalBytes(b1, b2) {
if (b1.length !== b2.length) return false;
for (let i = 0; i < b1.length; i++) if (b1[i] !== b2[i]) return false;
return true;
}
function utf8ToBytes(str) {
if (typeof str !== "string")
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
return new Uint8Array(new TextEncoder().encode(str));
}
function bitLen(n) {
let len;
for (len = 0; n > _0n; n >>= _1n, len += 1);
return len;
}
function bitGet(n, pos) {
return (n >> BigInt(pos)) & _1n;
}
var bitSet = (n, pos, value) => {
return n | ((value ? _1n : _0n) << BigInt(pos));
};
var bitMask = (n) => (_2n << BigInt(n - 1)) - _1n;
var u8n = (data) => new Uint8Array(data);
var u8fr = (arr) => Uint8Array.from(arr);
function createHmacDrbg(hashLen, qByteLen, hmacFn) {
if (typeof hashLen !== "number" || hashLen < 2)
throw new Error("hashLen must be a number");
if (typeof qByteLen !== "number" || qByteLen < 2)
throw new Error("qByteLen must be a number");
if (typeof hmacFn !== "function")
throw new Error("hmacFn must be a function");
let v = u8n(hashLen);
let k = u8n(hashLen);
let i = 0;
const reset = () => {
v.fill(1);
k.fill(0);
i = 0;
};
const h = (...b) => hmacFn(k, v, ...b);
const reseed = (seed = u8n()) => {
k = h(u8fr([0]), seed);
v = h();
if (seed.length === 0) return;
k = h(u8fr([1]), seed);
v = h();
};
const gen2 = () => {
if (i++ >= 1e3) throw new Error("drbg: tried 1000 values");
let len = 0;
const out = [];
while (len < qByteLen) {
v = h();
const sl = v.slice();
out.push(sl);
len += v.length;
}
return concatBytes(...out);
};
const genUntil = (seed, pred) => {
reset();
reseed(seed);
let res = void 0;
while (!(res = pred(gen2()))) reseed();
reset();
return res;
};
return genUntil;
}
var validatorFns = {
bigint: (val) => typeof val === "bigint",
function: (val) => typeof val === "function",
boolean: (val) => typeof val === "boolean",
string: (val) => typeof val === "string",
stringOrUint8Array: (val) =>
typeof val === "string" || val instanceof Uint8Array,
isSafeInteger: (val) => Number.isSafeInteger(val),
array: (val) => Array.isArray(val),
field: (val, object) => object.Fp.isValid(val),
hash: (val) =>
typeof val === "function" && Number.isSafeInteger(val.outputLen),
};
function validateObject(object, validators, optValidators = {}) {
const checkField = (fieldName, type, isOptional) => {
const checkVal = validatorFns[type];
if (typeof checkVal !== "function")
throw new Error(`Invalid validator "${type}", expected function`);
const val = object[fieldName];
if (isOptional && val === void 0) return;
if (!checkVal(val, object)) {
throw new Error(
`Invalid param ${String(
fieldName,
)}=${val} (${typeof val}), expected ${type}`,
);
}
};
for (const [fieldName, type] of Object.entries(validators))
checkField(fieldName, type, false);
for (const [fieldName, type] of Object.entries(optValidators))
checkField(fieldName, type, true);
return object;
}
// ../node_modules/@noble/hashes/esm/_assert.js
function number(n) {
if (!Number.isSafeInteger(n) || n < 0)
throw new Error(`Wrong positive integer: ${n}`);
}
function bytes(b, ...lengths) {
if (!(b instanceof Uint8Array)) throw new Error("Expected Uint8Array");
if (lengths.length > 0 && !lengths.includes(b.length))
throw new Error(
`Expected Uint8Array of length ${lengths}, not of length=${b.length}`,
);
}
function hash(hash2) {
if (typeof hash2 !== "function" || typeof hash2.create !== "function")
throw new Error("Hash should be wrapped by utils.wrapConstructor");
number(hash2.outputLen);
number(hash2.blockLen);
}
function exists(instance, checkFinished = true) {
if (instance.destroyed) throw new Error("Hash instance has been destroyed");
if (checkFinished && instance.finished)
throw new Error("Hash#digest() has already been called");
}
function output(out, instance) {
bytes(out);
const min = instance.outputLen;
if (out.length < min) {
throw new Error(
`digestInto() expects output buffer of length at least ${min}`,
);
}
}
// ../node_modules/@noble/hashes/esm/crypto.js
var crypto =
typeof globalThis === "object" && "crypto" in globalThis
? globalThis.crypto
: void 0;
// ../node_modules/@noble/hashes/esm/utils.js
var u8a2 = (a) => a instanceof Uint8Array;
var u32 = (arr) =>
new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
var createView = (arr) =>
new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
var rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
var isLE = new Uint8Array(new Uint32Array([287454020]).buffer)[0] === 68;
if (!isLE) throw new Error("Non little-endian hardware is not supported");
function utf8ToBytes2(str) {
if (typeof str !== "string")
throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
return new Uint8Array(new TextEncoder().encode(str));
}
function toBytes(data) {
if (typeof data === "string") data = utf8ToBytes2(data);
if (!u8a2(data)) throw new Error(`expected Uint8Array, got ${typeof data}`);
return data;
}
function concatBytes2(...arrays) {
const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
let pad = 0;
arrays.forEach((a) => {
if (!u8a2(a)) throw new Error("Uint8Array expected");
r.set(a, pad);
pad += a.length;
});
return r;
}
var Hash = class {
// Safe version that clones internal state
clone() {
return this._cloneInto();
}
};
var toStr = {}.toString;
function wrapConstructor(hashCons) {
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
const tmp = hashCons();
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = () => hashCons();
return hashC;
}
function wrapXOFConstructorWithOpts(hashCons) {
const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
const tmp = hashCons({});
hashC.outputLen = tmp.outputLen;
hashC.blockLen = tmp.blockLen;
hashC.create = (opts) => hashCons(opts);
return hashC;
}
function randomBytes(bytesLength = 32) {
if (crypto && typeof crypto.getRandomValues === "function") {
return crypto.getRandomValues(new Uint8Array(bytesLength));
}
throw new Error("crypto.getRandomValues must be defined");
}
// ../node_modules/@noble/hashes/esm/_sha2.js
function setBigUint64(view, byteOffset, value, isLE2) {
if (typeof view.setBigUint64 === "function")
return view.setBigUint64(byteOffset, value, isLE2);
const _32n2 = BigInt(32);
const _u32_max = BigInt(4294967295);
const wh = Number((value >> _32n2) & _u32_max);
const wl = Number(value & _u32_max);
const h = isLE2 ? 4 : 0;
const l = isLE2 ? 0 : 4;
view.setUint32(byteOffset + h, wh, isLE2);
view.setUint32(byteOffset + l, wl, isLE2);
}
var SHA2 = class extends Hash {
constructor(blockLen, outputLen, padOffset, isLE2) {
super();
this.blockLen = blockLen;
this.outputLen = outputLen;
this.padOffset = padOffset;
this.isLE = isLE2;
this.finished = false;
this.length = 0;
this.pos = 0;
this.destroyed = false;
this.buffer = new Uint8Array(blockLen);
this.view = createView(this.buffer);
}
update(data) {
exists(this);
const { view, buffer, blockLen } = this;
data = toBytes(data);
const len = data.length;
for (let pos = 0; pos < len; ) {
const take = Math.min(blockLen - this.pos, len - pos);
if (take === blockLen) {
const dataView = createView(data);
for (; blockLen <= len - pos; pos += blockLen)
this.process(dataView, pos);
continue;
}
buffer.set(data.subarray(pos, pos + take), this.pos);
this.pos += take;
pos += take;
if (this.pos === blockLen) {
this.process(view, 0);
this.pos = 0;
}
}
this.length += data.length;
this.roundClean();
return this;
}
digestInto(out) {
exists(this);
output(out, this);
this.finished = true;
const { buffer, view, blockLen, isLE: isLE2 } = this;
let { pos } = this;
buffer[pos++] = 128;
this.buffer.subarray(pos).fill(0);
if (this.padOffset > blockLen - pos) {
this.process(view, 0);
pos = 0;
}
for (let i = pos; i < blockLen; i++) buffer[i] = 0;
setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE2);
this.process(view, 0);
const oview = createView(out);
const len = this.outputLen;
if (len % 4)
throw new Error("_sha2: outputLen should be aligned to 32bit");
const outLen = len / 4;
const state = this.get();
if (outLen > state.length)
throw new Error("_sha2: outputLen bigger than state");
for (let i = 0; i < outLen; i++) oview.setUint32(4 * i, state[i], isLE2);
}
digest() {
const { buffer, outputLen } = this;
this.digestInto(buffer);
const res = buffer.slice(0, outputLen);
this.destroy();
return res;
}
_cloneInto(to) {
to || (to = new this.constructor());
to.set(...this.get());
const { blockLen, buffer, length, finished, destroyed, pos } = this;
to.length = length;
to.pos = pos;
to.finished = finished;
to.destroyed = destroyed;
if (length % blockLen) to.buffer.set(buffer);
return to;
}
};
// ../node_modules/@noble/hashes/esm/sha256.js
var Chi = (a, b, c) => (a & b) ^ (~a & c);
var Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
var SHA256_K = /* @__PURE__ */ 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,
]);
var IV = /* @__PURE__ */ new Uint32Array([
1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924,
528734635, 1541459225,
]);
var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
var SHA256 = class extends SHA2 {
constructor() {
super(64, 32, 8, false);
this.A = IV[0] | 0;
this.B = IV[1] | 0;
this.C = IV[2] | 0;
this.D = IV[3] | 0;
this.E = IV[4] | 0;
this.F = IV[5] | 0;
this.G = IV[6] | 0;
this.H = IV[7] | 0;
}
get() {
const { A, B, C, D, E, F, G, H } = this;
return [A, B, C, D, E, F, G, H];
}
// prettier-ignore
set(A, B, C, D, E, F, G, H) {
this.A = A | 0;
this.B = B | 0;
this.C = C | 0;
this.D = D | 0;
this.E = E | 0;
this.F = F | 0;
this.G = G | 0;
this.H = H | 0;
}
process(view, offset) {
for (let i = 0; i < 16; i++, offset += 4)
SHA256_W[i] = view.getUint32(offset, false);
for (let i = 16; i < 64; i++) {
const W15 = SHA256_W[i - 15];
const W2 = SHA256_W[i - 2];
const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ (W15 >>> 3);
const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ (W2 >>> 10);
SHA256_W[i] = (s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16]) | 0;
}
let { A, B, C, D, E, F, G, H } = this;
for (let i = 0; i < 64; i++) {
const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
const T1 = (H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i]) | 0;
const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
const T2 = (sigma0 + Maj(A, B, C)) | 0;
H = G;
G = F;
F = E;
E = (D + T1) | 0;
D = C;
C = B;
B = A;
A = (T1 + T2) | 0;
}
A = (A + this.A) | 0;
B = (B + this.B) | 0;
C = (C + this.C) | 0;
D = (D + this.D) | 0;
E = (E + this.E) | 0;
F = (F + this.F) | 0;
G = (G + this.G) | 0;
H = (H + this.H) | 0;
this.set(A, B, C, D, E, F, G, H);
}
roundClean() {
SHA256_W.fill(0);
}
destroy() {
this.set(0, 0, 0, 0, 0, 0, 0, 0);
this.buffer.fill(0);
}
};
var sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
// ../esm/abstract/modular.js
var _0n2 = BigInt(0);
var _1n2 = BigInt(1);
var _2n2 = BigInt(2);
var _3n = BigInt(3);
var _4n = BigInt(4);
var _5n = BigInt(5);
var _8n = BigInt(8);
var _9n = BigInt(9);
var _16n = BigInt(16);
function mod(a, b) {
const result = a % b;
return result >= _0n2 ? result : b + result;
}
function pow(num, power, modulo) {
if (modulo <= _0n2 || power < _0n2)
throw new Error("Expected power/modulo > 0");
if (modulo === _1n2) return _0n2;
let res = _1n2;
while (power > _0n2) {
if (power & _1n2) res = (res * num) % modulo;
num = (num * num) % modulo;
power >>= _1n2;
}
return res;
}
function pow2(x, power, modulo) {
let res = x;
while (power-- > _0n2) {
res *= res;
res %= modulo;
}
return res;
}
function invert(number2, modulo) {
if (number2 === _0n2 || modulo <= _0n2) {
throw new Error(
`invert: expected positive integers, got n=${number2} mod=${modulo}`,
);
}
let a = mod(number2, modulo);
let b = modulo;
let x = _0n2,
y = _1n2,
u = _1n2,
v = _0n2;
while (a !== _0n2) {
const q = b / a;
const r = b % a;
const m = x - u * q;
const n = y - v * q;
(b = a), (a = r), (x = u), (y = v), (u = m), (v = n);
}
const gcd = b;
if (gcd !== _1n2) throw new Error("invert: does not exist");
return mod(x, modulo);
}
function tonelliShanks(P3) {
const legendreC = (P3 - _1n2) / _2n2;
let Q, S, Z;
for (Q = P3 - _1n2, S = 0; Q % _2n2 === _0n2; Q /= _2n2, S++);
for (Z = _2n2; Z < P3 && pow(Z, legendreC, P3) !== P3 - _1n2; Z++);
if (S === 1) {
const p1div4 = (P3 + _1n2) / _4n;
return function tonelliFast(Fp8, n) {
const root = Fp8.pow(n, p1div4);
if (!Fp8.eql(Fp8.sqr(root), n))
throw new Error("Cannot find square root");
return root;
};
}
const Q1div2 = (Q + _1n2) / _2n2;
return function tonelliSlow(Fp8, n) {
if (Fp8.pow(n, legendreC) === Fp8.neg(Fp8.ONE))
throw new Error("Cannot find square root");
let r = S;
let g = Fp8.pow(Fp8.mul(Fp8.ONE, Z), Q);
let x = Fp8.pow(n, Q1div2);
let b = Fp8.pow(n, Q);
while (!Fp8.eql(b, Fp8.ONE)) {
if (Fp8.eql(b, Fp8.ZERO)) return Fp8.ZERO;
let m = 1;
for (let t2 = Fp8.sqr(b); m < r; m++) {
if (Fp8.eql(t2, Fp8.ONE)) break;
t2 = Fp8.sqr(t2);
}
const ge2 = Fp8.pow(g, _1n2 << BigInt(r - m - 1));
g = Fp8.sqr(ge2);
x = Fp8.mul(x, ge2);
b = Fp8.mul(b, g);
r = m;
}
return x;
};
}
function FpSqrt(P3) {
if (P3 % _4n === _3n) {
const p1div4 = (P3 + _1n2) / _4n;
return function sqrt3mod4(Fp8, n) {
const root = Fp8.pow(n, p1div4);
if (!Fp8.eql(Fp8.sqr(root), n))
throw new Error("Cannot find square root");
return root;
};
}
if (P3 % _8n === _5n) {
const c1 = (P3 - _5n) / _8n;
return function sqrt5mod8(Fp8, n) {
const n2 = Fp8.mul(n, _2n2);
const v = Fp8.pow(n2, c1);
const nv = Fp8.mul(n, v);
const i = Fp8.mul(Fp8.mul(nv, _2n2), v);
const root = Fp8.mul(nv, Fp8.sub(i, Fp8.ONE));
if (!Fp8.eql(Fp8.sqr(root), n))
throw new Error("Cannot find square root");
return root;
};
}
if (P3 % _16n === _9n) {
}
return tonelliShanks(P3);
}
var isNegativeLE = (num, modulo) => (mod(num, modulo) & _1n2) === _1n2;
var FIELD_FIELDS = [
"create",
"isValid",
"is0",
"neg",
"inv",
"sqrt",
"sqr",
"eql",
"add",
"sub",
"mul",
"pow",
"div",
"addN",
"subN",
"mulN",
"sqrN",
];
function validateField(field) {
const initial = {
ORDER: "bigint",
MASK: "bigint",
BYTES: "isSafeInteger",
BITS: "isSafeInteger",
};
const opts = FIELD_FIELDS.reduce((map, val) => {
map[val] = "function";
return map;
}, initial);
return validateObject(field, opts);
}
function FpPow(f, num, power) {
if (power < _0n2) throw new Error("Expected power > 0");
if (power === _0n2) return f.ONE;
if (power === _1n2) return num;
let p = f.ONE;
let d = num;
while (power > _0n2) {
if (power & _1n2) p = f.mul(p, d);
d = f.sqr(d);
power >>= _1n2;
}
return p;
}
function FpInvertBatch(f, nums) {
const tmp = new Array(nums.length);
const lastMultiplied = nums.reduce((acc, num, i) => {
if (f.is0(num)) return acc;
tmp[i] = acc;
return f.mul(acc, num);
}, f.ONE);
const inverted = f.inv(lastMultiplied);
nums.reduceRight((acc, num, i) => {
if (f.is0(num)) return acc;
tmp[i] = f.mul(acc, tmp[i]);
return f.mul(acc, num);
}, inverted);
return tmp;
}
function nLength(n, nBitLength) {
const _nBitLength =
nBitLength !== void 0 ? nBitLength : n.toString(2).length;
const nByteLength = Math.ceil(_nBitLength / 8);
return { nBitLength: _nBitLength, nByteLength };
}
function Field(ORDER, bitLen2, isLE2 = false, redef = {}) {
if (ORDER <= _0n2)
throw new Error(`Expected Field ORDER > 0, got ${ORDER}`);
const { nBitLength: BITS, nByteLength: BYTES } = nLength(ORDER, bitLen2);
if (BYTES > 2048)
throw new Error("Field lengths over 2048 bytes are not supported");
const sqrtP = FpSqrt(ORDER);
const f = Object.freeze({
ORDER,
BITS,
BYTES,
MASK: bitMask(BITS),
ZERO: _0n2,
ONE: _1n2,
create: (num) => mod(num, ORDER),
isValid: (num) => {
if (typeof num !== "bigint")
throw new Error(
`Invalid field element: expected bigint, got ${typeof num}`,
);
return _0n2 <= num && num < ORDER;
},
is0: (num) => num === _0n2,
isOdd: (num) => (num & _1n2) === _1n2,
neg: (num) => mod(-num, ORDER),
eql: (lhs, rhs) => lhs === rhs,
sqr: (num) => mod(num * num, ORDER),
add: (lhs, rhs) => mod(lhs + rhs, ORDER),
sub: (lhs, rhs) => mod(lhs - rhs, ORDER),
mul: (lhs, rhs) => mod(lhs * rhs, ORDER),
pow: (num, power) => FpPow(f, num, power),
div: (lhs, rhs) => mod(lhs * invert(rhs, ORDER), ORDER),
// Same as above, but doesn't normalize
sqrN: (num) => num * num,
addN: (lhs, rhs) => lhs + rhs,
subN: (lhs, rhs) => lhs - rhs,
mulN: (lhs, rhs) => lhs * rhs,
inv: (num) => invert(num, ORDER),
sqrt: redef.sqrt || ((n) => sqrtP(f, n)),
invertBatch: (lst) => FpInvertBatch(f, lst),
// TODO: do we really need constant cmov?
// We don't have const-time bigints anyway, so probably will be not very useful
cmov: (a, b, c) => (c ? b : a),
toBytes: (num) =>
isLE2 ? numberToBytesLE(num, BYTES) : numberToBytesBE(num, BYTES),
fromBytes: (bytes2) => {
if (bytes2.length !== BYTES)
throw new Error(
`Fp.fromBytes: expected ${BYTES}, got ${bytes2.length}`,
);
return isLE2 ? bytesToNumberLE(bytes2) : bytesToNumberBE(bytes2);
},
});
return Object.freeze(f);
}
function FpSqrtEven(Fp8, elm) {
if (!Fp8.isOdd) throw new Error(`Field doesn't have isOdd`);
const root = Fp8.sqrt(elm);
return Fp8.isOdd(root) ? Fp8.neg(root) : root;
}
function getFieldBytesLength(fieldOrder) {
if (typeof fieldOrder !== "bigint")
throw new Error("field order must be bigint");
const bitLength = fieldOrder.toString(2).length;
return Math.ceil(bitLength / 8);
}
function getMinHashLength(fieldOrder) {
const length = getFieldBytesLength(fieldOrder);
return length + Math.ceil(length / 2);
}
function mapHashToField(key, fieldOrder, isLE2 = false) {
const len = key.length;
const fieldLen = getFieldBytesLength(fieldOrder);
const minLen = getMinHashLength(fieldOrder);
if (len < 16 || len < minLen || len > 1024)
throw new Error(`expected ${minLen}-1024 bytes of input, got ${len}`);
const num = isLE2 ? bytesToNumberBE(key) : bytesToNumberLE(key);
const reduced = mod(num, fieldOrder - _1n2) + _1n2;
return isLE2
? numberToBytesLE(reduced, fieldLen)
: numberToBytesBE(reduced, fieldLen);
}
// ../esm/abstract/curve.js
var _0n3 = BigInt(0);
var _1n3 = BigInt(1);
function wNAF(c, bits) {
const constTimeNegate = (condition, item) => {
const neg = item.negate();
return condition ? neg : item;
};
const opts = (W) => {
const windows = Math.ceil(bits / W) + 1;
const windowSize = 2 ** (W - 1);
return { windows, windowSize };
};
return {
constTimeNegate,
// non-const time multiplication ladder
unsafeLadder(elm, n) {
let p = c.ZERO;
let d = elm;
while (n > _0n3) {
if (n & _1n3) p = p.add(d);
d = d.double();
n >>= _1n3;
}
return p;
},
/**
* Creates a wNAF precomputation window. Used for caching.
* Default window size is set by `utils.precompute()` and is equal to 8.
* Number of precomputed points depends on the curve size:
* 2^(𝑊1) * (Math.ceil(𝑛 / 𝑊) + 1), where:
* - 𝑊 is the window size
* - 𝑛 is the bitlength of the curve order.
* For a 256-bit curve and window size 8, the number of precomputed points is 128 * 33 = 4224.
* @returns precomputed point tables flattened to a single array
*/
precomputeWindow(elm, W) {
const { windows, windowSize } = opts(W);
const points = [];
let p = elm;
let base = p;
for (let window = 0; window < windows; window++) {
base = p;
points.push(base);
for (let i = 1; i < windowSize; i++) {
base = base.add(p);
points.push(base);
}
p = base.double();
}
return points;
},
/**
* Implements ec multiplication using precomputed tables and w-ary non-adjacent form.
* @param W window size
* @param precomputes precomputed tables
* @param n scalar (we don't check here, but should be less than curve order)
* @returns real and fake (for const-time) points
*/
wNAF(W, precomputes, n) {
const { windows, windowSize } = opts(W);
let p = c.ZERO;
let f = c.BASE;
const mask = BigInt(2 ** W - 1);
const maxNumber = 2 ** W;
const shiftBy = BigInt(W);
for (let window = 0; window < windows; window++) {
const offset = window * windowSize;
let wbits = Number(n & mask);
n >>= shiftBy;
if (wbits > windowSize) {
wbits -= maxNumber;
n += _1n3;
}
const offset1 = offset;
const offset2 = offset + Math.abs(wbits) - 1;
const cond1 = window % 2 !== 0;
const cond2 = wbits < 0;
if (wbits === 0) {
f = f.add(constTimeNegate(cond1, precomputes[offset1]));
} else {
p = p.add(constTimeNegate(cond2, precomputes[offset2]));
}
}
return { p, f };
},
wNAFCached(P3, precomputesMap, n, transform) {
const W = P3._WINDOW_SIZE || 1;
let comp = precomputesMap.get(P3);
if (!comp) {
comp = this.precomputeWindow(P3, W);
if (W !== 1) {
precomputesMap.set(P3, transform(comp));
}
}
return this.wNAF(W, comp, n);
},
};
}
function validateBasic(curve) {
validateField(curve.Fp);
validateObject(
curve,
{
n: "bigint",
h: "bigint",
Gx: "field",
Gy: "field",
},
{
nBitLength: "isSafeInteger",
nByteLength: "isSafeInteger",
},
);
return Object.freeze({
...nLength(curve.n, curve.nBitLength),
...curve,
...{ p: curve.Fp.ORDER },
});
}
// ../esm/abstract/weierstrass.js
function validatePointOpts(curve) {
const opts = validateBasic(curve);
validateObject(
opts,
{
a: "field",
b: "field",
},
{
allowedPrivateKeyLengths: "array",
wrapPrivateKey: "boolean",
isTorsionFree: "function",
clearCofactor: "function",
allowInfinityPoint: "boolean",
fromBytes: "function",
toBytes: "function",
},
);
const { endo, Fp: Fp8, a } = opts;
if (endo) {
if (!Fp8.eql(a, Fp8.ZERO)) {
throw new Error(
"Endomorphism can only be defined for Koblitz curves that have a=0",
);
}
if (
typeof endo !== "object" ||
typeof endo.beta !== "bigint" ||
typeof endo.splitScalar !== "function"
) {
throw new Error(
"Expected endomorphism with beta: bigint and splitScalar: function",
);
}
}
return Object.freeze({ ...opts });
}
var { bytesToNumberBE: b2n, hexToBytes: h2b } = utils_exports;
var DER = {
// asn.1 DER encoding utils
Err: class DERErr extends Error {
constructor(m = "") {
super(m);
}
},
_parseInt(data) {
const { Err: E } = DER;
if (data.length < 2 || data[0] !== 2)
throw new E("Invalid signature integer tag");
const len = data[1];
const res = data.subarray(2, len + 2);
if (!len || res.length !== len)
throw new E("Invalid signature integer: wrong length");
if (res[0] & 128) throw new E("Invalid signature integer: negative");
if (res[0] === 0 && !(res[1] & 128))
throw new E("Invalid signature integer: unnecessary leading zero");
return { d: b2n(res), l: data.subarray(len + 2) };
},
toSig(hex) {
const { Err: E } = DER;
const data = typeof hex === "string" ? h2b(hex) : hex;
if (!(data instanceof Uint8Array)) throw new Error("ui8a expected");
let l = data.length;
if (l < 2 || data[0] != 48) throw new E("Invalid signature tag");
if (data[1] !== l - 2) throw new E("Invalid signature: incorrect length");
const { d: r, l: sBytes } = DER._parseInt(data.subarray(2));
const { d: s, l: rBytesLeft } = DER._parseInt(sBytes);
if (rBytesLeft.length)
throw new E("Invalid signature: left bytes after parsing");
return { r, s };
},
hexFromSig(sig) {
const slice = (s2) => (Number.parseInt(s2[0], 16) & 8 ? "00" + s2 : s2);
const h = (num) => {
const hex = num.toString(16);
return hex.length & 1 ? `0${hex}` : hex;
};
const s = slice(h(sig.s));
const r = slice(h(sig.r));
const shl = s.length / 2;
const rhl = r.length / 2;
const sl = h(shl);
const rl = h(rhl);
return `30${h(rhl + shl + 4)}02${rl}${r}02${sl}${s}`;
},
};
var _0n4 = BigInt(0);
var _1n4 = BigInt(1);
var _2n3 = BigInt(2);
var _3n2 = BigInt(3);
var _4n2 = BigInt(4);
function weierstrassPoints(opts) {
const CURVE2 = validatePointOpts(opts);
const { Fp: Fp8 } = CURVE2;
const toBytes2 =
CURVE2.toBytes ||
((_c, point, _isCompressed) => {
const a = point.toAffine();
return concatBytes(
Uint8Array.from([4]),
Fp8.toBytes(a.x),
Fp8.toBytes(a.y),
);
});
const fromBytes =
CURVE2.fromBytes ||
((bytes2) => {
const tail = bytes2.subarray(1);
const x = Fp8.fromBytes(tail.subarray(0, Fp8.BYTES));
const y = Fp8.fromBytes(tail.subarray(Fp8.BYTES, 2 * Fp8.BYTES));
return { x, y };
});
function weierstrassEquation(x) {
const { a, b } = CURVE2;
const x2 = Fp8.sqr(x);
const x3 = Fp8.mul(x2, x);
return Fp8.add(Fp8.add(x3, Fp8.mul(x, a)), b);
}
if (!Fp8.eql(Fp8.sqr(CURVE2.Gy), weierstrassEquation(CURVE2.Gx)))
throw new Error("bad generator point: equation left != right");
function isWithinCurveOrder(num) {
return typeof num === "bigint" && _0n4 < num && num < CURVE2.n;
}
function assertGE(num) {
if (!isWithinCurveOrder(num))
throw new Error("Expected valid bigint: 0 < bigint < curve.n");
}
function normPrivateKeyToScalar(key) {
const {
allowedPrivateKeyLengths: lengths,
nByteLength,
wrapPrivateKey,
n,
} = CURVE2;
if (lengths && typeof key !== "bigint") {
if (key instanceof Uint8Array) key = bytesToHex(key);
if (typeof key !== "string" || !lengths.includes(key.length))
throw new Error("Invalid key");
key = key.padStart(nByteLength * 2, "0");
}
let num;
try {
num =
typeof key === "bigint"
? key
: bytesToNumberBE(ensureBytes("private key", key, nByteLength));
} catch (error) {
throw new Error(
`private key must be ${nByteLength} bytes, hex or bigint, not ${typeof key}`,
);
}
if (wrapPrivateKey) num = mod(num, n);
assertGE(num);
return num;
}
const pointPrecomputes = /* @__PURE__ */ new Map();
function assertPrjPoint(other) {
if (!(other instanceof Point2))
throw new Error("ProjectivePoint expected");
}
class Point2 {
constructor(px, py, pz) {
this.px = px;
this.py = py;
this.pz = pz;
if (px == null || !Fp8.isValid(px)) throw new Error("x required");
if (py == null || !Fp8.isValid(py)) throw new Error("y required");
if (pz == null || !Fp8.isValid(pz)) throw new Error("z required");
}
// Does not validate if the point is on-curve.
// Use fromHex instead, or call assertValidity() later.
static fromAffine(p) {
const { x, y } = p || {};
if (!p || !Fp8.isValid(x) || !Fp8.isValid(y))
throw new Error("invalid affine point");
if (p instanceof Point2)
throw new Error("projective point not allowed");
const is0 = (i) => Fp8.eql(i, Fp8.ZERO);
if (is0(x) && is0(y)) return Point2.ZERO;
return new Point2(x, y, Fp8.ONE);
}
get x() {
return this.toAffine().x;
}
get y() {
return this.toAffine().y;
}
/**
* Takes a bunch of Projective Points but executes only one
* inversion on all of them. Inversion is very slow operation,
* so this improves performance massively.
* Optimization: converts a list of projective points to a list of identical points with Z=1.
*/
static normalizeZ(points) {
const toInv = Fp8.invertBatch(points.map((p) => p.pz));
return points
.map((p, i) => p.toAffine(toInv[i]))
.map(Point2.fromAffine);
}
/**
* Converts hash string or Uint8Array to Point.
* @param hex short/long ECDSA hex
*/
static fromHex(hex) {
const P3 = Point2.fromAffine(fromBytes(ensureBytes("pointHex", hex)));
P3.assertValidity();
return P3;
}
// Multiplies generator point by privateKey.
static fromPrivateKey(privateKey) {
return Point2.BASE.multiply(normPrivateKeyToScalar(privateKey));
}
// "Private method", don't use it directly
_setWindowSize(windowSize) {
this._WINDOW_SIZE = windowSize;
pointPrecomputes.delete(this);
}
// A point on curve is valid if it conforms to equation.
assertValidity() {
if (this.is0()) {
if (CURVE2.allowInfinityPoint && !Fp8.is0(this.py)) return;
throw new Error("bad point: ZERO");
}
const { x, y } = this.toAffine();
if (!Fp8.isValid(x) || !Fp8.isValid(y))
throw new Error("bad point: x or y not FE");
const left = Fp8.sqr(y);
const right = weierstrassEquation(x);
if (!Fp8.eql(left, right))
throw new Error("bad point: equation left != right");
if (!this.isTorsionFree())
throw new Error("bad point: not in prime-order subgroup");
}
hasEvenY() {
const { y } = this.toAffine();
if (Fp8.isOdd) return !Fp8.isOdd(y);
throw new Error("Field doesn't support isOdd");
}
/**
* Compare one point to another.
*/
equals(other) {
assertPrjPoint(other);
const { px: X1, py: Y1, pz: Z1 } = this;
const { px: X2, py: Y2, pz: Z2 } = other;
const U1 = Fp8.eql(Fp8.mul(X1, Z2), Fp8.mul(X2, Z1));
const U2 = Fp8.eql(Fp8.mul(Y1, Z2), Fp8.mul(Y2, Z1));
return U1 && U2;
}
/**
* Flips point to one corresponding to (x, -y) in Affine coordinates.
*/
negate() {
return new Point2(this.px, Fp8.neg(this.py), this.pz);
}
// Renes-Costello-Batina exception-free doubling formula.
// There is 30% faster Jacobian formula, but it is not complete.
// https://eprint.iacr.org/2015/1060, algorithm 3
// Cost: 8M + 3S + 3*a + 2*b3 + 15add.
double() {
const { a, b } = CURVE2;
const b3 = Fp8.mul(b, _3n2);
const { px: X1, py: Y1, pz: Z1 } = this;
let X3 = Fp8.ZERO,
Y3 = Fp8.ZERO,
Z3 = Fp8.ZERO;
let t0 = Fp8.mul(X1, X1);
let t1 = Fp8.mul(Y1, Y1);
let t2 = Fp8.mul(Z1, Z1);
let t3 = Fp8.mul(X1, Y1);
t3 = Fp8.add(t3, t3);
Z3 = Fp8.mul(X1, Z1);
Z3 = Fp8.add(Z3, Z3);
X3 = Fp8.mul(a, Z3);
Y3 = Fp8.mul(b3, t2);
Y3 = Fp8.add(X3, Y3);
X3 = Fp8.sub(t1, Y3);
Y3 = Fp8.add(t1, Y3);
Y3 = Fp8.mul(X3, Y3);
X3 = Fp8.mul(t3, X3);
Z3 = Fp8.mul(b3, Z3);
t2 = Fp8.mul(a, t2);
t3 = Fp8.sub(t0, t2);
t3 = Fp8.mul(a, t3);
t3 = Fp8.add(t3, Z3);
Z3 = Fp8.add(t0, t0);
t0 = Fp8.add(Z3, t0);
t0 = Fp8.add(t0, t2);
t0 = Fp8.mul(t0, t3);
Y3 = Fp8.add(Y3, t0);
t2 = Fp8.mul(Y1, Z1);
t2 = Fp8.add(t2, t2);
t0 = Fp8.mul(t2, t3);
X3 = Fp8.sub(X3, t0);
Z3 = Fp8.mul(t2, t1);
Z3 = Fp8.add(Z3, Z3);
Z3 = Fp8.add(Z3, Z3);
return new Point2(X3, Y3, Z3);
}
// Renes-Costello-Batina exception-free addition formula.
// There is 30% faster Jacobian formula, but it is not complete.
// https://eprint.iacr.org/2015/1060, algorithm 1
// Cost: 12M + 0S + 3*a + 3*b3 + 23add.
add(other) {
assertPrjPoint(other);
const { px: X1, py: Y1, pz: Z1 } = this;
const { px: X2, py: Y2, pz: Z2 } = other;
let X3 = Fp8.ZERO,
Y3 = Fp8.ZERO,
Z3 = Fp8.ZERO;
const a = CURVE2.a;
const b3 = Fp8.mul(CURVE2.b, _3n2);
let t0 = Fp8.mul(X1, X2);
let t1 = Fp8.mul(Y1, Y2);
let t2 = Fp8.mul(Z1, Z2);
let t3 = Fp8.add(X1, Y1);
let t4 = Fp8.add(X2, Y2);
t3 = Fp8.mul(t3, t4);
t4 = Fp8.add(t0, t1);
t3 = Fp8.sub(t3, t4);
t4 = Fp8.add(X1, Z1);
let t5 = Fp8.add(X2, Z2);
t4 = Fp8.mul(t4, t5);
t5 = Fp8.add(t0, t2);
t4 = Fp8.sub(t4, t5);
t5 = Fp8.add(Y1, Z1);
X3 = Fp8.add(Y2, Z2);
t5 = Fp8.mul(t5, X3);
X3 = Fp8.add(t1, t2);
t5 = Fp8.sub(t5, X3);
Z3 = Fp8.mul(a, t4);
X3 = Fp8.mul(b3, t2);
Z3 = Fp8.add(X3, Z3);
X3 = Fp8.sub(t1, Z3);
Z3 = Fp8.add(t1, Z3);
Y3 = Fp8.mul(X3, Z3);
t1 = Fp8.add(t0, t0);
t1 = Fp8.add(t1, t0);
t2 = Fp8.mul(a, t2);
t4 = Fp8.mul(b3, t4);
t1 = Fp8.add(t1, t2);
t2 = Fp8.sub(t0, t2);
t2 = Fp8.mul(a, t2);
t4 = Fp8.add(t4, t2);
t0 = Fp8.mul(t1, t4);
Y3 = Fp8.add(Y3, t0);
t0 = Fp8.mul(t5, t4);
X3 = Fp8.mul(t3, X3);
X3 = Fp8.sub(X3, t0);
t0 = Fp8.mul(t3, t1);
Z3 = Fp8.mul(t5, Z3);
Z3 = Fp8.add(Z3, t0);
return new Point2(X3, Y3, Z3);
}
subtract(other) {
return this.add(other.negate());
}
is0() {
return this.equals(Point2.ZERO);
}
wNAF(n) {
return wnaf.wNAFCached(this, pointPrecomputes, n, (comp) => {
const toInv = Fp8.invertBatch(comp.map((p) => p.pz));
return comp
.map((p, i) => p.toAffine(toInv[i]))
.map(Point2.fromAffine);
});
}
/**
* Non-constant-time multiplication. Uses double-and-add algorithm.
* It's faster, but should only be used when you don't care about
* an exposed private key e.g. sig verification, which works over *public* keys.
*/
multiplyUnsafe(n) {
const I = Point2.ZERO;
if (n === _0n4) return I;
assertGE(n);
if (n === _1n4) return this;
const { endo } = CURVE2;
if (!endo) return wnaf.unsafeLadder(this, n);
let { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
let k1p = I;
let k2p = I;
let d = this;
while (k1 > _0n4 || k2 > _0n4) {
if (k1 & _1n4) k1p = k1p.add(d);
if (k2 & _1n4) k2p = k2p.add(d);
d = d.double();
k1 >>= _1n4;
k2 >>= _1n4;
}
if (k1neg) k1p = k1p.negate();
if (k2neg) k2p = k2p.negate();
k2p = new Point2(Fp8.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
return k1p.add(k2p);
}
/**
* Constant time multiplication.
* Uses wNAF method. Windowed method may be 10% faster,
* but takes 2x longer to generate and consumes 2x memory.
* Uses precomputes when available.
* Uses endomorphism for Koblitz curves.
* @param scalar by which the point would be multiplied
* @returns New point
*/
multiply(scalar) {
assertGE(scalar);
let n = scalar;
let point, fake;
const { endo } = CURVE2;
if (endo) {
const { k1neg, k1, k2neg, k2 } = endo.splitScalar(n);
let { p: k1p, f: f1p } = this.wNAF(k1);
let { p: k2p, f: f2p } = this.wNAF(k2);
k1p = wnaf.constTimeNegate(k1neg, k1p);
k2p = wnaf.constTimeNegate(k2neg, k2p);
k2p = new Point2(Fp8.mul(k2p.px, endo.beta), k2p.py, k2p.pz);
point = k1p.add(k2p);
fake = f1p.add(f2p);
} else {
const { p, f } = this.wNAF(n);
point = p;
fake = f;
}
return Point2.normalizeZ([point, fake])[0];
}
/**
* Efficiently calculate `aP + bQ`. Unsafe, can expose private key, if used incorrectly.
* Not using Strauss-Shamir trick: precomputation tables are faster.
* The trick could be useful if both P and Q are not G (not in our case).
* @returns non-zero affine point
*/
multiplyAndAddUnsafe(Q, a, b) {
const G = Point2.BASE;
const mul = (P3, a2) =>
a2 === _0n4 || a2 === _1n4 || !P3.equals(G)
? P3.multiplyUnsafe(a2)
: P3.multiply(a2);
const sum = mul(this, a).add(mul(Q, b));
return sum.is0() ? void 0 : sum;
}
// Converts Projective point to affine (x, y) coordinates.
// Can accept precomputed Z^-1 - for example, from invertBatch.
// (x, y, z) ∋ (x=x/z, y=y/z)
toAffine(iz) {
const { px: x, py: y, pz: z } = this;
const is0 = this.is0();
if (iz == null) iz = is0 ? Fp8.ONE : Fp8.inv(z);
const ax = Fp8.mul(x, iz);
const ay = Fp8.mul(y, iz);
const zz = Fp8.mul(z, iz);
if (is0) return { x: Fp8.ZERO, y: Fp8.ZERO };
if (!Fp8.eql(zz, Fp8.ONE)) throw new Error("invZ was invalid");
return { x: ax, y: ay };
}
isTorsionFree() {
const { h: cofactor, isTorsionFree } = CURVE2;
if (cofactor === _1n4) return true;
if (isTorsionFree) return isTorsionFree(Point2, this);
throw new Error(
"isTorsionFree() has not been declared for the elliptic curve",
);
}
clearCofactor() {
const { h: cofactor, clearCofactor } = CURVE2;
if (cofactor === _1n4) return this;
if (clearCofactor) return clearCofactor(Point2, this);
return this.multiplyUnsafe(CURVE2.h);
}
toRawBytes(isCompressed = true) {
this.assertValidity();
return toBytes2(Point2, this, isCompressed);
}
toHex(isCompressed = true) {
return bytesToHex(this.toRawBytes(isCompressed));
}
}
Point2.BASE = new Point2(CURVE2.Gx, CURVE2.Gy, Fp8.ONE);
Point2.ZERO = new Point2(Fp8.ZERO, Fp8.ONE, Fp8.ZERO);
const _bits = CURVE2.nBitLength;
const wnaf = wNAF(Point2, CURVE2.endo ? Math.ceil(_bits / 2) : _bits);
return {
CURVE: CURVE2,
ProjectivePoint: Point2,
normPrivateKeyToScalar,
weierstrassEquation,
isWithinCurveOrder,
};
}
function validateOpts(curve) {
const opts = validateBasic(curve);
validateObject(
opts,
{
hash: "hash",
hmac: "function",
randomBytes: "function",
},
{
bits2int: "function",
bits2int_modN: "function",
lowS: "boolean",
},
);
return Object.freeze({ lowS: true, ...opts });
}
function weierstrass(curveDef) {
const CURVE2 = validateOpts(curveDef);
const { Fp: Fp8, n: CURVE_ORDER } = CURVE2;
const compressedLen = Fp8.BYTES + 1;
const uncompressedLen = 2 * Fp8.BYTES + 1;
function isValidFieldElement(num) {
return _0n4 < num && num < Fp8.ORDER;
}
function modN2(a) {
return mod(a, CURVE_ORDER);
}
function invN(a) {
return invert(a, CURVE_ORDER);
}
const {
ProjectivePoint: Point2,
normPrivateKeyToScalar,
weierstrassEquation,
isWithinCurveOrder,
} = weierstrassPoints({
...CURVE2,
toBytes(_c, point, isCompressed) {
const a = point.toAffine();
const x = Fp8.toBytes(a.x);
const cat = concatBytes;
if (isCompressed) {
return cat(Uint8Array.from([point.hasEvenY() ? 2 : 3]), x);
} else {
return cat(Uint8Array.from([4]), x, Fp8.toBytes(a.y));
}
},
fromBytes(bytes2) {
const len = bytes2.length;
const head = bytes2[0];
const tail = bytes2.subarray(1);
if (len === compressedLen && (head === 2 || head === 3)) {
const x = bytesToNumberBE(tail);
if (!isValidFieldElement(x)) throw new Error("Point is not on curve");
const y2 = weierstrassEquation(x);
let y = Fp8.sqrt(y2);
const isYOdd = (y & _1n4) === _1n4;
const isHeadOdd = (head & 1) === 1;
if (isHeadOdd !== isYOdd) y = Fp8.neg(y);
return { x, y };
} else if (len === uncompressedLen && head === 4) {
const x = Fp8.fromBytes(tail.subarray(0, Fp8.BYTES));
const y = Fp8.fromBytes(tail.subarray(Fp8.BYTES, 2 * Fp8.BYTES));
return { x, y };
} else {
throw new Error(
`Point of length ${len} was invalid. Expected ${compressedLen} compressed bytes or ${uncompressedLen} uncompressed bytes`,
);
}
},
});
const numToNByteStr = (num) =>
bytesToHex(numberToBytesBE(num, CURVE2.nByteLength));
function isBiggerThanHalfOrder(number2) {
const HALF = CURVE_ORDER >> _1n4;
return number2 > HALF;
}
function normalizeS(s) {
return isBiggerThanHalfOrder(s) ? modN2(-s) : s;
}
const slcNum = (b, from, to) => bytesToNumberBE(b.slice(from, to));
class Signature {
constructor(r, s, recovery) {
this.r = r;
this.s = s;
this.recovery = recovery;
this.assertValidity();
}
// pair (bytes of r, bytes of s)
static fromCompact(hex) {
const l = CURVE2.nByteLength;
hex = ensureBytes("compactSignature", hex, l * 2);
return new Signature(slcNum(hex, 0, l), slcNum(hex, l, 2 * l));
}
// DER encoded ECDSA signature
// https://bitcoin.stackexchange.com/questions/57644/what-are-the-parts-of-a-bitcoin-transaction-input-script
static fromDER(hex) {
const { r, s } = DER.toSig(ensureBytes("DER", hex));
return new Signature(r, s);
}
assertValidity() {
if (!isWithinCurveOrder(this.r))
throw new Error("r must be 0 < r < CURVE.n");
if (!isWithinCurveOrder(this.s))
throw new Error("s must be 0 < s < CURVE.n");
}
addRecoveryBit(recovery) {
return new Signature(this.r, this.s, recovery);
}
recoverPublicKey(msgHash) {
const { r, s, recovery: rec } = this;
const h = bits2int_modN(ensureBytes("msgHash", msgHash));
if (rec == null || ![0, 1, 2, 3].includes(rec))
throw new Error("recovery id invalid");
const radj = rec === 2 || rec === 3 ? r + CURVE2.n : r;
if (radj >= Fp8.ORDER) throw new Error("recovery id 2 or 3 invalid");
const prefix = (rec & 1) === 0 ? "02" : "03";
const R = Point2.fromHex(prefix + numToNByteStr(radj));
const ir = invN(radj);
const u1 = modN2(-h * ir);
const u2 = modN2(s * ir);
const Q = Point2.BASE.multiplyAndAddUnsafe(R, u1, u2);
if (!Q) throw new Error("point at infinify");
Q.assertValidity();
return Q;
}
// Signatures should be low-s, to prevent malleability.
hasHighS() {
return isBiggerThanHalfOrder(this.s);
}
normalizeS() {
return this.hasHighS()
? new Signature(this.r, modN2(-this.s), this.recovery)
: this;
}
// DER-encoded
toDERRawBytes() {
return hexToBytes(this.toDERHex());
}
toDERHex() {
return DER.hexFromSig({ r: this.r, s: this.s });
}
// padded bytes of r, then padded bytes of s
toCompactRawBytes() {
return hexToBytes(this.toCompactHex());
}
toCompactHex() {
return numToNByteStr(this.r) + numToNByteStr(this.s);
}
}
const utils2 = {
isValidPrivateKey(privateKey) {
try {
normPrivateKeyToScalar(privateKey);
return true;
} catch (error) {
return false;
}
},
normPrivateKeyToScalar,
/**
* Produces cryptographically secure private key from random of size
* (groupLen + ceil(groupLen / 2)) with modulo bias being negligible.
*/
randomPrivateKey: () => {
const length = getMinHashLength(CURVE2.n);
return mapHashToField(CURVE2.randomBytes(length), CURVE2.n);
},
/**
* Creates precompute table for an arbitrary EC point. Makes point "cached".
* Allows to massively speed-up `point.multiply(scalar)`.
* @returns cached point
* @example
* const fast = utils.precompute(8, ProjectivePoint.fromHex(someonesPubKey));
* fast.multiply(privKey); // much faster ECDH now
*/
precompute(windowSize = 8, point = Point2.BASE) {
point._setWindowSize(windowSize);
point.multiply(BigInt(3));
return point;
},
};
function getPublicKey(privateKey, isCompressed = true) {
return Point2.fromPrivateKey(privateKey).toRawBytes(isCompressed);
}
function isProbPub(item) {
const arr = item instanceof Uint8Array;
const str = typeof item === "string";
const len = (arr || str) && item.length;
if (arr) return len === compressedLen || len === uncompressedLen;
if (str) return len === 2 * compressedLen || len === 2 * uncompressedLen;
if (item instanceof Point2) return true;
return false;
}
function getSharedSecret(privateA, publicB, isCompressed = true) {
if (isProbPub(privateA)) throw new Error("first arg must be private key");
if (!isProbPub(publicB)) throw new Error("second arg must be public key");
const b = Point2.fromHex(publicB);
return b
.multiply(normPrivateKeyToScalar(privateA))
.toRawBytes(isCompressed);
}
const bits2int =
CURVE2.bits2int ||
function (bytes2) {
const num = bytesToNumberBE(bytes2);
const delta = bytes2.length * 8 - CURVE2.nBitLength;
return delta > 0 ? num >> BigInt(delta) : num;
};
const bits2int_modN =
CURVE2.bits2int_modN ||
function (bytes2) {
return modN2(bits2int(bytes2));
};
const ORDER_MASK = bitMask(CURVE2.nBitLength);
function int2octets(num) {
if (typeof num !== "bigint") throw new Error("bigint expected");
if (!(_0n4 <= num && num < ORDER_MASK))
throw new Error(`bigint expected < 2^${CURVE2.nBitLength}`);
return numberToBytesBE(num, CURVE2.nByteLength);
}
function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
if (["recovered", "canonical"].some((k) => k in opts))
throw new Error("sign() legacy options not supported");
const { hash: hash2, randomBytes: randomBytes2 } = CURVE2;
let { lowS, prehash, extraEntropy: ent } = opts;
if (lowS == null) lowS = true;
msgHash = ensureBytes("msgHash", msgHash);
if (prehash) msgHash = ensureBytes("prehashed msgHash", hash2(msgHash));
const h1int = bits2int_modN(msgHash);
const d = normPrivateKeyToScalar(privateKey);
const seedArgs = [int2octets(d), int2octets(h1int)];
if (ent != null) {
const e = ent === true ? randomBytes2(Fp8.BYTES) : ent;
seedArgs.push(ensureBytes("extraEntropy", e));
}
const seed = concatBytes(...seedArgs);
const m = h1int;
function k2sig(kBytes) {
const k = bits2int(kBytes);
if (!isWithinCurveOrder(k)) return;
const ik = invN(k);
const q = Point2.BASE.multiply(k).toAffine();
const r = modN2(q.x);
if (r === _0n4) return;
const s = modN2(ik * modN2(m + r * d));
if (s === _0n4) return;
let recovery = (q.x === r ? 0 : 2) | Number(q.y & _1n4);
let normS = s;
if (lowS && isBiggerThanHalfOrder(s)) {
normS = normalizeS(s);
recovery ^= 1;
}
return new Signature(r, normS, recovery);
}
return { seed, k2sig };
}
const defaultSigOpts = { lowS: CURVE2.lowS, prehash: false };
const defaultVerOpts = { lowS: CURVE2.lowS, prehash: false };
function sign(msgHash, privKey, opts = defaultSigOpts) {
const { seed, k2sig } = prepSig(msgHash, privKey, opts);
const C = CURVE2;
const drbg = createHmacDrbg(C.hash.outputLen, C.nByteLength, C.hmac);
return drbg(seed, k2sig);
}
Point2.BASE._setWindowSize(8);
function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {
const sg = signature;
msgHash = ensureBytes("msgHash", msgHash);
publicKey = ensureBytes("publicKey", publicKey);
if ("strict" in opts)
throw new Error("options.strict was renamed to lowS");
const { lowS, prehash } = opts;
let _sig = void 0;
let P3;
try {
if (typeof sg === "string" || sg instanceof Uint8Array) {
try {
_sig = Signature.fromDER(sg);
} catch (derError) {
if (!(derError instanceof DER.Err)) throw derError;
_sig = Signature.fromCompact(sg);
}
} else if (
typeof sg === "object" &&
typeof sg.r === "bigint" &&
typeof sg.s === "bigint"
) {
const { r: r2, s: s2 } = sg;
_sig = new Signature(r2, s2);
} else {
throw new Error("PARSE");
}
P3 = Point2.fromHex(publicKey);
} catch (error) {
if (error.message === "PARSE")
throw new Error(
`signature must be Signature instance, Uint8Array or hex string`,
);
return false;
}
if (lowS && _sig.hasHighS()) return false;
if (prehash) msgHash = CURVE2.hash(msgHash);
const { r, s } = _sig;
const h = bits2int_modN(msgHash);
const is = invN(s);
const u1 = modN2(h * is);
const u2 = modN2(r * is);
const R = Point2.BASE.multiplyAndAddUnsafe(P3, u1, u2)?.toAffine();
if (!R) return false;
const v = modN2(R.x);
return v === r;
}
return {
CURVE: CURVE2,
getPublicKey,
getSharedSecret,
sign,
verify,
ProjectivePoint: Point2,
Signature,
utils: utils2,
};
}
function SWUFpSqrtRatio(Fp8, Z) {
const q = Fp8.ORDER;
let l = _0n4;
for (let o = q - _1n4; o % _2n3 === _0n4; o /= _2n3) l += _1n4;
const c1 = l;
const _2n_pow_c1_1 = _2n3 << (c1 - _1n4 - _1n4);
const _2n_pow_c1 = _2n_pow_c1_1 * _2n3;
const c2 = (q - _1n4) / _2n_pow_c1;
const c3 = (c2 - _1n4) / _2n3;
const c4 = _2n_pow_c1 - _1n4;
const c5 = _2n_pow_c1_1;
const c6 = Fp8.pow(Z, c2);
const c7 = Fp8.pow(Z, (c2 + _1n4) / _2n3);
let sqrtRatio = (u, v) => {
let tv1 = c6;
let tv2 = Fp8.pow(v, c4);
let tv3 = Fp8.sqr(tv2);
tv3 = Fp8.mul(tv3, v);
let tv5 = Fp8.mul(u, tv3);
tv5 = Fp8.pow(tv5, c3);
tv5 = Fp8.mul(tv5, tv2);
tv2 = Fp8.mul(tv5, v);
tv3 = Fp8.mul(tv5, u);
let tv4 = Fp8.mul(tv3, tv2);
tv5 = Fp8.pow(tv4, c5);
let isQR = Fp8.eql(tv5, Fp8.ONE);
tv2 = Fp8.mul(tv3, c7);
tv5 = Fp8.mul(tv4, tv1);
tv3 = Fp8.cmov(tv2, tv3, isQR);
tv4 = Fp8.cmov(tv5, tv4, isQR);
for (let i = c1; i > _1n4; i--) {
let tv52 = i - _2n3;
tv52 = _2n3 << (tv52 - _1n4);
let tvv5 = Fp8.pow(tv4, tv52);
const e1 = Fp8.eql(tvv5, Fp8.ONE);
tv2 = Fp8.mul(tv3, tv1);
tv1 = Fp8.mul(tv1, tv1);
tvv5 = Fp8.mul(tv4, tv1);
tv3 = Fp8.cmov(tv2, tv3, e1);
tv4 = Fp8.cmov(tvv5, tv4, e1);
}
return { isValid: isQR, value: tv3 };
};
if (Fp8.ORDER % _4n2 === _3n2) {
const c12 = (Fp8.ORDER - _3n2) / _4n2;
const c22 = Fp8.sqrt(Fp8.neg(Z));
sqrtRatio = (u, v) => {
let tv1 = Fp8.sqr(v);
const tv2 = Fp8.mul(u, v);
tv1 = Fp8.mul(tv1, tv2);
let y1 = Fp8.pow(tv1, c12);
y1 = Fp8.mul(y1, tv2);
const y2 = Fp8.mul(y1, c22);
const tv3 = Fp8.mul(Fp8.sqr(y1), v);
const isQR = Fp8.eql(tv3, u);
let y = Fp8.cmov(y2, y1, isQR);
return { isValid: isQR, value: y };
};
}
return sqrtRatio;
}
function mapToCurveSimpleSWU(Fp8, opts) {
validateField(Fp8);
if (!Fp8.isValid(opts.A) || !Fp8.isValid(opts.B) || !Fp8.isValid(opts.Z))
throw new Error("mapToCurveSimpleSWU: invalid opts");
const sqrtRatio = SWUFpSqrtRatio(Fp8, opts.Z);
if (!Fp8.isOdd) throw new Error("Fp.isOdd is not implemented!");
return (u) => {
let tv1, tv2, tv3, tv4, tv5, tv6, x, y;
tv1 = Fp8.sqr(u);
tv1 = Fp8.mul(tv1, opts.Z);
tv2 = Fp8.sqr(tv1);
tv2 = Fp8.add(tv2, tv1);
tv3 = Fp8.add(tv2, Fp8.ONE);
tv3 = Fp8.mul(tv3, opts.B);
tv4 = Fp8.cmov(opts.Z, Fp8.neg(tv2), !Fp8.eql(tv2, Fp8.ZERO));
tv4 = Fp8.mul(tv4, opts.A);
tv2 = Fp8.sqr(tv3);
tv6 = Fp8.sqr(tv4);
tv5 = Fp8.mul(tv6, opts.A);
tv2 = Fp8.add(tv2, tv5);
tv2 = Fp8.mul(tv2, tv3);
tv6 = Fp8.mul(tv6, tv4);
tv5 = Fp8.mul(tv6, opts.B);
tv2 = Fp8.add(tv2, tv5);
x = Fp8.mul(tv1, tv3);
const { isValid, value } = sqrtRatio(tv2, tv6);
y = Fp8.mul(tv1, u);
y = Fp8.mul(y, value);
x = Fp8.cmov(x, tv3, isValid);
y = Fp8.cmov(y, value, isValid);
const e1 = Fp8.isOdd(u) === Fp8.isOdd(y);
y = Fp8.cmov(Fp8.neg(y), y, e1);
x = Fp8.div(x, tv4);
return { x, y };
};
}
// ../esm/abstract/hash-to-curve.js
function validateDST(dst) {
if (dst instanceof Uint8Array) return dst;
if (typeof dst === "string") return utf8ToBytes(dst);
throw new Error("DST must be Uint8Array or string");
}
var os2ip = bytesToNumberBE;
function i2osp(value, length) {
if (value < 0 || value >= 1 << (8 * length)) {
throw new Error(`bad I2OSP call: value=${value} length=${length}`);
}
const res = Array.from({ length }).fill(0);
for (let i = length - 1; i >= 0; i--) {
res[i] = value & 255;
value >>>= 8;
}
return new Uint8Array(res);
}
function strxor(a, b) {
const arr = new Uint8Array(a.length);
for (let i = 0; i < a.length; i++) {
arr[i] = a[i] ^ b[i];
}
return arr;
}
function isBytes(item) {
if (!(item instanceof Uint8Array)) throw new Error("Uint8Array expected");
}
function isNum(item) {
if (!Number.isSafeInteger(item)) throw new Error("number expected");
}
function expand_message_xmd(msg, DST, lenInBytes, H) {
isBytes(msg);
isBytes(DST);
isNum(lenInBytes);
if (DST.length > 255)
DST = H(concatBytes(utf8ToBytes("H2C-OVERSIZE-DST-"), DST));
const { outputLen: b_in_bytes, blockLen: r_in_bytes } = H;
const ell = Math.ceil(lenInBytes / b_in_bytes);
if (ell > 255) throw new Error("Invalid xmd length");
const DST_prime = concatBytes(DST, i2osp(DST.length, 1));
const Z_pad = i2osp(0, r_in_bytes);
const l_i_b_str = i2osp(lenInBytes, 2);
const b = new Array(ell);
const b_0 = H(concatBytes(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
b[0] = H(concatBytes(b_0, i2osp(1, 1), DST_prime));
for (let i = 1; i <= ell; i++) {
const args = [strxor(b_0, b[i - 1]), i2osp(i + 1, 1), DST_prime];
b[i] = H(concatBytes(...args));
}
const pseudo_random_bytes = concatBytes(...b);
return pseudo_random_bytes.slice(0, lenInBytes);
}
function expand_message_xof(msg, DST, lenInBytes, k, H) {
isBytes(msg);
isBytes(DST);
isNum(lenInBytes);
if (DST.length > 255) {
const dkLen = Math.ceil((2 * k) / 8);
DST = H.create({ dkLen })
.update(utf8ToBytes("H2C-OVERSIZE-DST-"))
.update(DST)
.digest();
}
if (lenInBytes > 65535 || DST.length > 255)
throw new Error("expand_message_xof: invalid lenInBytes");
return H.create({ dkLen: lenInBytes })
.update(msg)
.update(i2osp(lenInBytes, 2))
.update(DST)
.update(i2osp(DST.length, 1))
.digest();
}
function hash_to_field(msg, count, options) {
validateObject(options, {
DST: "stringOrUint8Array",
p: "bigint",
m: "isSafeInteger",
k: "isSafeInteger",
hash: "hash",
});
const { p, k, m, hash: hash2, expand, DST: _DST } = options;
isBytes(msg);
isNum(count);
const DST = validateDST(_DST);
const log2p = p.toString(2).length;
const L = Math.ceil((log2p + k) / 8);
const len_in_bytes = count * m * L;
let prb;
if (expand === "xmd") {
prb = expand_message_xmd(msg, DST, len_in_bytes, hash2);
} else if (expand === "xof") {
prb = expand_message_xof(msg, DST, len_in_bytes, k, hash2);
} else if (expand === "_internal_pass") {
prb = msg;
} else {
throw new Error('expand must be "xmd" or "xof"');
}
const u = new Array(count);
for (let i = 0; i < count; i++) {
const e = new Array(m);
for (let j = 0; j < m; j++) {
const elm_offset = L * (j + i * m);
const tv = prb.subarray(elm_offset, elm_offset + L);
e[j] = mod(os2ip(tv), p);
}
u[i] = e;
}
return u;
}
function isogenyMap(field, map) {
const COEFF = map.map((i) => Array.from(i).reverse());
return (x, y) => {
const [xNum, xDen, yNum, yDen] = COEFF.map((val) =>
val.reduce((acc, i) => field.add(field.mul(acc, x), i)),
);
x = field.div(xNum, xDen);
y = field.mul(y, field.div(yNum, yDen));
return { x, y };
};
}
function createHasher(Point2, mapToCurve, def) {
if (typeof mapToCurve !== "function")
throw new Error("mapToCurve() must be defined");
return {
// Encodes byte string to elliptic curve.
// hash_to_curve from https://www.rfc-editor.org/rfc/rfc9380#section-3
hashToCurve(msg, options) {
const u = hash_to_field(msg, 2, { ...def, DST: def.DST, ...options });
const u0 = Point2.fromAffine(mapToCurve(u[0]));
const u1 = Point2.fromAffine(mapToCurve(u[1]));
const P3 = u0.add(u1).clearCofactor();
P3.assertValidity();
return P3;
},
// Encodes byte string to elliptic curve.
// encode_to_curve from https://www.rfc-editor.org/rfc/rfc9380#section-3
encodeToCurve(msg, options) {
const u = hash_to_field(msg, 1, {
...def,
DST: def.encodeDST,
...options,
});
const P3 = Point2.fromAffine(mapToCurve(u[0])).clearCofactor();
P3.assertValidity();
return P3;
},
};
}
// ../node_modules/@noble/hashes/esm/hmac.js
var HMAC = class extends Hash {
constructor(hash2, _key) {
super();
this.finished = false;
this.destroyed = false;
hash(hash2);
const key = toBytes(_key);
this.iHash = hash2.create();
if (typeof this.iHash.update !== "function")
throw new Error("Expected instance of class which extends utils.Hash");
this.blockLen = this.iHash.blockLen;
this.outputLen = this.iHash.outputLen;
const blockLen = this.blockLen;
const pad = new Uint8Array(blockLen);
pad.set(
key.length > blockLen ? hash2.create().update(key).digest() : key,
);
for (let i = 0; i < pad.length; i++) pad[i] ^= 54;
this.iHash.update(pad);
this.oHash = hash2.create();
for (let i = 0; i < pad.length; i++) pad[i] ^= 54 ^ 92;
this.oHash.update(pad);
pad.fill(0);
}
update(buf) {
exists(this);
this.iHash.update(buf);
return this;
}
digestInto(out) {
exists(this);
bytes(out, this.outputLen);
this.finished = true;
this.iHash.digestInto(out);
this.oHash.update(out);
this.oHash.digestInto(out);
this.destroy();
}
digest() {
const out = new Uint8Array(this.oHash.outputLen);
this.digestInto(out);
return out;
}
_cloneInto(to) {
to || (to = Object.create(Object.getPrototypeOf(this), {}));
const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
to = to;
to.finished = finished;
to.destroyed = destroyed;
to.blockLen = blockLen;
to.outputLen = outputLen;
to.oHash = oHash._cloneInto(to.oHash);
to.iHash = iHash._cloneInto(to.iHash);
return to;
}
destroy() {
this.destroyed = true;
this.oHash.destroy();
this.iHash.destroy();
}
};
var hmac = (hash2, key, message) =>
new HMAC(hash2, key).update(message).digest();
hmac.create = (hash2, key) => new HMAC(hash2, key);
// ../esm/_shortw_utils.js
function getHash(hash2) {
return {
hash: hash2,
hmac: (key, ...msgs) => hmac(hash2, key, concatBytes2(...msgs)),
randomBytes,
};
}
function createCurve(curveDef, defHash) {
const create = (hash2) => weierstrass({ ...curveDef, ...getHash(hash2) });
return Object.freeze({ ...create(defHash), create });
}
// ../esm/secp256k1.js
var secp256k1P = BigInt(
"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
);
var secp256k1N = BigInt(
"0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
);
var _1n5 = BigInt(1);
var _2n4 = BigInt(2);
var divNearest = (a, b) => (a + b / _2n4) / b;
function sqrtMod(y) {
const P3 = secp256k1P;
const _3n6 = BigInt(3),
_6n = BigInt(6),
_11n2 = BigInt(11),
_22n2 = BigInt(22);
const _23n = BigInt(23),
_44n2 = BigInt(44),
_88n2 = BigInt(88);
const b2 = (y * y * y) % P3;
const b3 = (b2 * b2 * y) % P3;
const b6 = (pow2(b3, _3n6, P3) * b3) % P3;
const b9 = (pow2(b6, _3n6, P3) * b3) % P3;
const b11 = (pow2(b9, _2n4, P3) * b2) % P3;
const b22 = (pow2(b11, _11n2, P3) * b11) % P3;
const b44 = (pow2(b22, _22n2, P3) * b22) % P3;
const b88 = (pow2(b44, _44n2, P3) * b44) % P3;
const b176 = (pow2(b88, _88n2, P3) * b88) % P3;
const b220 = (pow2(b176, _44n2, P3) * b44) % P3;
const b223 = (pow2(b220, _3n6, P3) * b3) % P3;
const t1 = (pow2(b223, _23n, P3) * b22) % P3;
const t2 = (pow2(t1, _6n, P3) * b2) % P3;
const root = pow2(t2, _2n4, P3);
if (!Fp.eql(Fp.sqr(root), y)) throw new Error("Cannot find square root");
return root;
}
var Fp = Field(secp256k1P, void 0, void 0, { sqrt: sqrtMod });
var secp256k1 = createCurve(
{
a: BigInt(0),
b: BigInt(7),
Fp,
n: secp256k1N,
// Base point (x, y) aka generator point
Gx: BigInt(
"55066263022277343669578718895168534326250603453777594175500187360389116729240",
),
Gy: BigInt(
"32670510020758816978083085130507043184471273380659243275938904335757337482424",
),
h: BigInt(1),
lowS: true,
/**
* secp256k1 belongs to Koblitz curves: it has efficiently computable endomorphism.
* Endomorphism uses 2x less RAM, speeds up precomputation by 2x and ECDH / key recovery by 20%.
* For precomputed wNAF it trades off 1/2 init time & 1/3 ram for 20% perf hit.
* Explanation: https://gist.github.com/paulmillr/eb670806793e84df628a7c434a873066
*/
endo: {
beta: BigInt(
"0x7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee",
),
splitScalar: (k) => {
const n = secp256k1N;
const a1 = BigInt("0x3086d221a7d46bcde86c90e49284eb15");
const b1 = -_1n5 * BigInt("0xe4437ed6010e88286f547fa90abfe4c3");
const a2 = BigInt("0x114ca50f7a8e2f3f657c1108d9d44cfd8");
const b2 = a1;
const POW_2_128 = BigInt("0x100000000000000000000000000000000");
const c1 = divNearest(b2 * k, n);
const c2 = divNearest(-b1 * k, n);
let k1 = mod(k - c1 * a1 - c2 * a2, n);
let k2 = mod(-c1 * b1 - c2 * b2, n);
const k1neg = k1 > POW_2_128;
const k2neg = k2 > POW_2_128;
if (k1neg) k1 = n - k1;
if (k2neg) k2 = n - k2;
if (k1 > POW_2_128 || k2 > POW_2_128) {
throw new Error("splitScalar: Endomorphism failed, k=" + k);
}
return { k1neg, k1, k2neg, k2 };
},
},
},
sha256,
);
var _0n5 = BigInt(0);
var fe = (x) => typeof x === "bigint" && _0n5 < x && x < secp256k1P;
var ge = (x) => typeof x === "bigint" && _0n5 < x && x < secp256k1N;
var TAGGED_HASH_PREFIXES = {};
function taggedHash(tag, ...messages) {
let tagP = TAGGED_HASH_PREFIXES[tag];
if (tagP === void 0) {
const tagH = sha256(Uint8Array.from(tag, (c) => c.charCodeAt(0)));
tagP = concatBytes(tagH, tagH);
TAGGED_HASH_PREFIXES[tag] = tagP;
}
return sha256(concatBytes(tagP, ...messages));
}
var pointToBytes = (point) => point.toRawBytes(true).slice(1);
var numTo32b = (n) => numberToBytesBE(n, 32);
var modP = (x) => mod(x, secp256k1P);
var modN = (x) => mod(x, secp256k1N);
var Point = secp256k1.ProjectivePoint;
var GmulAdd = (Q, a, b) => Point.BASE.multiplyAndAddUnsafe(Q, a, b);
function schnorrGetExtPubKey(priv) {
let d_ = secp256k1.utils.normPrivateKeyToScalar(priv);
let p = Point.fromPrivateKey(d_);
const scalar = p.hasEvenY() ? d_ : modN(-d_);
return { scalar, bytes: pointToBytes(p) };
}
function lift_x(x) {
if (!fe(x)) throw new Error("bad x: need 0 < x < p");
const xx = modP(x * x);
const c = modP(xx * x + BigInt(7));
let y = sqrtMod(c);
if (y % _2n4 !== _0n5) y = modP(-y);
const p = new Point(x, y, _1n5);
p.assertValidity();
return p;
}
function challenge(...args) {
return modN(bytesToNumberBE(taggedHash("BIP0340/challenge", ...args)));
}
function schnorrGetPublicKey(privateKey) {
return schnorrGetExtPubKey(privateKey).bytes;
}
function schnorrSign(message, privateKey, auxRand = randomBytes(32)) {
const m = ensureBytes("message", message);
const { bytes: px, scalar: d } = schnorrGetExtPubKey(privateKey);
const a = ensureBytes("auxRand", auxRand, 32);
const t = numTo32b(d ^ bytesToNumberBE(taggedHash("BIP0340/aux", a)));
const rand = taggedHash("BIP0340/nonce", t, px, m);
const k_ = modN(bytesToNumberBE(rand));
if (k_ === _0n5) throw new Error("sign failed: k is zero");
const { bytes: rx, scalar: k } = schnorrGetExtPubKey(k_);
const e = challenge(rx, px, m);
const sig = new Uint8Array(64);
sig.set(rx, 0);
sig.set(numTo32b(modN(k + e * d)), 32);
if (!schnorrVerify(sig, m, px))
throw new Error("sign: Invalid signature produced");
return sig;
}
function schnorrVerify(signature, message, publicKey) {
const sig = ensureBytes("signature", signature, 64);
const m = ensureBytes("message", message);
const pub = ensureBytes("publicKey", publicKey, 32);
try {
const P3 = lift_x(bytesToNumberBE(pub));
const r = bytesToNumberBE(sig.subarray(0, 32));
if (!fe(r)) return false;
const s = bytesToNumberBE(sig.subarray(32, 64));
if (!ge(s)) return false;
const e = challenge(numTo32b(r), pointToBytes(P3), m);
const R = GmulAdd(P3, s, modN(-e));
if (!R || !R.hasEvenY() || R.toAffine().x !== r) return false;
return true;
} catch (error) {
return false;
}
}
var schnorr = /* @__PURE__ */ (() => ({
getPublicKey: schnorrGetPublicKey,
sign: schnorrSign,
verify: schnorrVerify,
utils: {
randomPrivateKey: secp256k1.utils.randomPrivateKey,
lift_x,
pointToBytes,
numberToBytesBE,
bytesToNumberBE,
taggedHash,
mod,
},
}))();
// ../node_modules/@noble/hashes/esm/_u64.js
var U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
var _32n = /* @__PURE__ */ BigInt(32);
function fromBig(n, le = false) {
if (le)
return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
return {
h: Number((n >> _32n) & U32_MASK64) | 0,
l: Number(n & U32_MASK64) | 0,
};
}
function split(lst, le = false) {
let Ah = new Uint32Array(lst.length);
let Al = new Uint32Array(lst.length);
for (let i = 0; i < lst.length; i++) {
const { h, l } = fromBig(lst[i], le);
[Ah[i], Al[i]] = [h, l];
}
return [Ah, Al];
}
var toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
var shrSH = (h, _l, s) => h >>> s;
var shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
var rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
var rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
var rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
var rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
var rotr32H = (_h, l) => l;
var rotr32L = (h, _l) => h;
var rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
var rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
var rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
var rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
function add(Ah, Al, Bh, Bl) {
const l = (Al >>> 0) + (Bl >>> 0);
return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
}
var add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
var add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
var add4L = (Al, Bl, Cl, Dl) =>
(Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
var add4H = (low, Ah, Bh, Ch, Dh) =>
(Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
var add5L = (Al, Bl, Cl, Dl, El) =>
(Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
var add5H = (low, Ah, Bh, Ch, Dh, Eh) =>
(Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
var u64 = {
fromBig,
split,
toBig,
shrSH,
shrSL,
rotrSH,
rotrSL,
rotrBH,
rotrBL,
rotr32H,
rotr32L,
rotlSH,
rotlSL,
rotlBH,
rotlBL,
add,
add3L,
add3H,
add4L,
add4H,
add5H,
add5L,
};
var u64_default = u64;
// ../node_modules/@noble/hashes/esm/sha512.js
var [SHA512_Kh, SHA512_Kl] = /* @__PURE__ */ (() =>
u64_default.split(
[
"0x428a2f98d728ae22",
"0x7137449123ef65cd",
"0xb5c0fbcfec4d3b2f",
"0xe9b5dba58189dbbc",
"0x3956c25bf348b538",
"0x59f111f1b605d019",
"0x923f82a4af194f9b",
"0xab1c5ed5da6d8118",
"0xd807aa98a3030242",
"0x12835b0145706fbe",
"0x243185be4ee4b28c",
"0x550c7dc3d5ffb4e2",
"0x72be5d74f27b896f",
"0x80deb1fe3b1696b1",
"0x9bdc06a725c71235",
"0xc19bf174cf692694",
"0xe49b69c19ef14ad2",
"0xefbe4786384f25e3",
"0x0fc19dc68b8cd5b5",
"0x240ca1cc77ac9c65",
"0x2de92c6f592b0275",
"0x4a7484aa6ea6e483",
"0x5cb0a9dcbd41fbd4",
"0x76f988da831153b5",
"0x983e5152ee66dfab",
"0xa831c66d2db43210",
"0xb00327c898fb213f",
"0xbf597fc7beef0ee4",
"0xc6e00bf33da88fc2",
"0xd5a79147930aa725",
"0x06ca6351e003826f",
"0x142929670a0e6e70",
"0x27b70a8546d22ffc",
"0x2e1b21385c26c926",
"0x4d2c6dfc5ac42aed",
"0x53380d139d95b3df",
"0x650a73548baf63de",
"0x766a0abb3c77b2a8",
"0x81c2c92e47edaee6",
"0x92722c851482353b",
"0xa2bfe8a14cf10364",
"0xa81a664bbc423001",
"0xc24b8b70d0f89791",
"0xc76c51a30654be30",
"0xd192e819d6ef5218",
"0xd69906245565a910",
"0xf40e35855771202a",
"0x106aa07032bbd1b8",
"0x19a4c116b8d2d0c8",
"0x1e376c085141ab53",
"0x2748774cdf8eeb99",
"0x34b0bcb5e19b48a8",
"0x391c0cb3c5c95a63",
"0x4ed8aa4ae3418acb",
"0x5b9cca4f7763e373",
"0x682e6ff3d6b2b8a3",
"0x748f82ee5defb2fc",
"0x78a5636f43172f60",
"0x84c87814a1f0ab72",
"0x8cc702081a6439ec",
"0x90befffa23631e28",
"0xa4506cebde82bde9",
"0xbef9a3f7b2c67915",
"0xc67178f2e372532b",
"0xca273eceea26619c",
"0xd186b8c721c0c207",
"0xeada7dd6cde0eb1e",
"0xf57d4f7fee6ed178",
"0x06f067aa72176fba",
"0x0a637dc5a2c898a6",
"0x113f9804bef90dae",
"0x1b710b35131c471b",
"0x28db77f523047d84",
"0x32caab7b40c72493",
"0x3c9ebe0a15c9bebc",
"0x431d67c49c100d4c",
"0x4cc5d4becb3e42b6",
"0x597f299cfc657e2a",
"0x5fcb6fab3ad6faec",
"0x6c44198c4a475817",
].map((n) => BigInt(n)),
))();
var SHA512_W_H = /* @__PURE__ */ new Uint32Array(80);
var SHA512_W_L = /* @__PURE__ */ new Uint32Array(80);
var SHA512 = class extends SHA2 {
constructor() {
super(128, 64, 16, false);
this.Ah = 1779033703 | 0;
this.Al = 4089235720 | 0;
this.Bh = 3144134277 | 0;
this.Bl = 2227873595 | 0;
this.Ch = 1013904242 | 0;
this.Cl = 4271175723 | 0;
this.Dh = 2773480762 | 0;
this.Dl = 1595750129 | 0;
this.Eh = 1359893119 | 0;
this.El = 2917565137 | 0;
this.Fh = 2600822924 | 0;
this.Fl = 725511199 | 0;
this.Gh = 528734635 | 0;
this.Gl = 4215389547 | 0;
this.Hh = 1541459225 | 0;
this.Hl = 327033209 | 0;
}
// prettier-ignore
get() {
const { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } = this;
return [Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl];
}
// prettier-ignore
set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl) {
this.Ah = Ah | 0;
this.Al = Al | 0;
this.Bh = Bh | 0;
this.Bl = Bl | 0;
this.Ch = Ch | 0;
this.Cl = Cl | 0;
this.Dh = Dh | 0;
this.Dl = Dl | 0;
this.Eh = Eh | 0;
this.El = El | 0;
this.Fh = Fh | 0;
this.Fl = Fl | 0;
this.Gh = Gh | 0;
this.Gl = Gl | 0;
this.Hh = Hh | 0;
this.Hl = Hl | 0;
}
process(view, offset) {
for (let i = 0; i < 16; i++, offset += 4) {
SHA512_W_H[i] = view.getUint32(offset);
SHA512_W_L[i] = view.getUint32((offset += 4));
}
for (let i = 16; i < 80; i++) {
const W15h = SHA512_W_H[i - 15] | 0;
const W15l = SHA512_W_L[i - 15] | 0;
const s0h =
u64_default.rotrSH(W15h, W15l, 1) ^
u64_default.rotrSH(W15h, W15l, 8) ^
u64_default.shrSH(W15h, W15l, 7);
const s0l =
u64_default.rotrSL(W15h, W15l, 1) ^
u64_default.rotrSL(W15h, W15l, 8) ^
u64_default.shrSL(W15h, W15l, 7);
const W2h = SHA512_W_H[i - 2] | 0;
const W2l = SHA512_W_L[i - 2] | 0;
const s1h =
u64_default.rotrSH(W2h, W2l, 19) ^
u64_default.rotrBH(W2h, W2l, 61) ^
u64_default.shrSH(W2h, W2l, 6);
const s1l =
u64_default.rotrSL(W2h, W2l, 19) ^
u64_default.rotrBL(W2h, W2l, 61) ^
u64_default.shrSL(W2h, W2l, 6);
const SUMl = u64_default.add4L(
s0l,
s1l,
SHA512_W_L[i - 7],
SHA512_W_L[i - 16],
);
const SUMh = u64_default.add4H(
SUMl,
s0h,
s1h,
SHA512_W_H[i - 7],
SHA512_W_H[i - 16],
);
SHA512_W_H[i] = SUMh | 0;
SHA512_W_L[i] = SUMl | 0;
}
let { Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl } =
this;
for (let i = 0; i < 80; i++) {
const sigma1h =
u64_default.rotrSH(Eh, El, 14) ^
u64_default.rotrSH(Eh, El, 18) ^
u64_default.rotrBH(Eh, El, 41);
const sigma1l =
u64_default.rotrSL(Eh, El, 14) ^
u64_default.rotrSL(Eh, El, 18) ^
u64_default.rotrBL(Eh, El, 41);
const CHIh = (Eh & Fh) ^ (~Eh & Gh);
const CHIl = (El & Fl) ^ (~El & Gl);
const T1ll = u64_default.add5L(
Hl,
sigma1l,
CHIl,
SHA512_Kl[i],
SHA512_W_L[i],
);
const T1h = u64_default.add5H(
T1ll,
Hh,
sigma1h,
CHIh,
SHA512_Kh[i],
SHA512_W_H[i],
);
const T1l = T1ll | 0;
const sigma0h =
u64_default.rotrSH(Ah, Al, 28) ^
u64_default.rotrBH(Ah, Al, 34) ^
u64_default.rotrBH(Ah, Al, 39);
const sigma0l =
u64_default.rotrSL(Ah, Al, 28) ^
u64_default.rotrBL(Ah, Al, 34) ^
u64_default.rotrBL(Ah, Al, 39);
const MAJh = (Ah & Bh) ^ (Ah & Ch) ^ (Bh & Ch);
const MAJl = (Al & Bl) ^ (Al & Cl) ^ (Bl & Cl);
Hh = Gh | 0;
Hl = Gl | 0;
Gh = Fh | 0;
Gl = Fl | 0;
Fh = Eh | 0;
Fl = El | 0;
({ h: Eh, l: El } = u64_default.add(Dh | 0, Dl | 0, T1h | 0, T1l | 0));
Dh = Ch | 0;
Dl = Cl | 0;
Ch = Bh | 0;
Cl = Bl | 0;
Bh = Ah | 0;
Bl = Al | 0;
const All = u64_default.add3L(T1l, sigma0l, MAJl);
Ah = u64_default.add3H(All, T1h, sigma0h, MAJh);
Al = All | 0;
}
({ h: Ah, l: Al } = u64_default.add(
this.Ah | 0,
this.Al | 0,
Ah | 0,
Al | 0,
));
({ h: Bh, l: Bl } = u64_default.add(
this.Bh | 0,
this.Bl | 0,
Bh | 0,
Bl | 0,
));
({ h: Ch, l: Cl } = u64_default.add(
this.Ch | 0,
this.Cl | 0,
Ch | 0,
Cl | 0,
));
({ h: Dh, l: Dl } = u64_default.add(
this.Dh | 0,
this.Dl | 0,
Dh | 0,
Dl | 0,
));
({ h: Eh, l: El } = u64_default.add(
this.Eh | 0,
this.El | 0,
Eh | 0,
El | 0,
));
({ h: Fh, l: Fl } = u64_default.add(
this.Fh | 0,
this.Fl | 0,
Fh | 0,
Fl | 0,
));
({ h: Gh, l: Gl } = u64_default.add(
this.Gh | 0,
this.Gl | 0,
Gh | 0,
Gl | 0,
));
({ h: Hh, l: Hl } = u64_default.add(
this.Hh | 0,
this.Hl | 0,
Hh | 0,
Hl | 0,
));
this.set(Ah, Al, Bh, Bl, Ch, Cl, Dh, Dl, Eh, El, Fh, Fl, Gh, Gl, Hh, Hl);
}
roundClean() {
SHA512_W_H.fill(0);
SHA512_W_L.fill(0);
}
destroy() {
this.buffer.fill(0);
this.set(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
}
};
var SHA384 = class extends SHA512 {
constructor() {
super();
this.Ah = 3418070365 | 0;
this.Al = 3238371032 | 0;
this.Bh = 1654270250 | 0;
this.Bl = 914150663 | 0;
this.Ch = 2438529370 | 0;
this.Cl = 812702999 | 0;
this.Dh = 355462360 | 0;
this.Dl = 4144912697 | 0;
this.Eh = 1731405415 | 0;
this.El = 4290775857 | 0;
this.Fh = 2394180231 | 0;
this.Fl = 1750603025 | 0;
this.Gh = 3675008525 | 0;
this.Gl = 1694076839 | 0;
this.Hh = 1203062813 | 0;
this.Hl = 3204075428 | 0;
this.outputLen = 48;
}
};
var sha512 = /* @__PURE__ */ wrapConstructor(() => new SHA512());
var sha384 = /* @__PURE__ */ wrapConstructor(() => new SHA384());
// ../esm/abstract/edwards.js
var _0n6 = BigInt(0);
var _1n6 = BigInt(1);
var _2n5 = BigInt(2);
var _8n2 = BigInt(8);
var VERIFY_DEFAULT = { zip215: true };
function validateOpts2(curve) {
const opts = validateBasic(curve);
validateObject(
curve,
{
hash: "function",
a: "bigint",
d: "bigint",
randomBytes: "function",
},
{
adjustScalarBytes: "function",
domain: "function",
uvRatio: "function",
mapToCurve: "function",
},
);
return Object.freeze({ ...opts });
}
function twistedEdwards(curveDef) {
const CURVE2 = validateOpts2(curveDef);
const {
Fp: Fp8,
n: CURVE_ORDER,
prehash,
hash: cHash,
randomBytes: randomBytes2,
nByteLength,
h: cofactor,
} = CURVE2;
const MASK = _2n5 << (BigInt(nByteLength * 8) - _1n6);
const modP2 = Fp8.create;
const uvRatio3 =
CURVE2.uvRatio ||
((u, v) => {
try {
return { isValid: true, value: Fp8.sqrt(u * Fp8.inv(v)) };
} catch (e) {
return { isValid: false, value: _0n6 };
}
});
const adjustScalarBytes3 = CURVE2.adjustScalarBytes || ((bytes2) => bytes2);
const domain =
CURVE2.domain ||
((data, ctx, phflag) => {
if (ctx.length || phflag)
throw new Error("Contexts/pre-hash are not supported");
return data;
});
const inBig = (n) => typeof n === "bigint" && _0n6 < n;
const inRange = (n, max) => inBig(n) && inBig(max) && n < max;
const in0MaskRange = (n) => n === _0n6 || inRange(n, MASK);
function assertInRange(n, max) {
if (inRange(n, max)) return n;
throw new Error(`Expected valid scalar < ${max}, got ${typeof n} ${n}`);
}
function assertGE0(n) {
return n === _0n6 ? n : assertInRange(n, CURVE_ORDER);
}
const pointPrecomputes = /* @__PURE__ */ new Map();
function isPoint(other) {
if (!(other instanceof Point2)) throw new Error("ExtendedPoint expected");
}
class Point2 {
constructor(ex, ey, ez, et) {
this.ex = ex;
this.ey = ey;
this.ez = ez;
this.et = et;
if (!in0MaskRange(ex)) throw new Error("x required");
if (!in0MaskRange(ey)) throw new Error("y required");
if (!in0MaskRange(ez)) throw new Error("z required");
if (!in0MaskRange(et)) throw new Error("t required");
}
get x() {
return this.toAffine().x;
}
get y() {
return this.toAffine().y;
}
static fromAffine(p) {
if (p instanceof Point2) throw new Error("extended point not allowed");
const { x, y } = p || {};
if (!in0MaskRange(x) || !in0MaskRange(y))
throw new Error("invalid affine point");
return new Point2(x, y, _1n6, modP2(x * y));
}
static normalizeZ(points) {
const toInv = Fp8.invertBatch(points.map((p) => p.ez));
return points
.map((p, i) => p.toAffine(toInv[i]))
.map(Point2.fromAffine);
}
// "Private method", don't use it directly
_setWindowSize(windowSize) {
this._WINDOW_SIZE = windowSize;
pointPrecomputes.delete(this);
}
// Not required for fromHex(), which always creates valid points.
// Could be useful for fromAffine().
assertValidity() {
const { a, d } = CURVE2;
if (this.is0()) throw new Error("bad point: ZERO");
const { ex: X, ey: Y, ez: Z, et: T } = this;
const X2 = modP2(X * X);
const Y2 = modP2(Y * Y);
const Z2 = modP2(Z * Z);
const Z4 = modP2(Z2 * Z2);
const aX2 = modP2(X2 * a);
const left = modP2(Z2 * modP2(aX2 + Y2));
const right = modP2(Z4 + modP2(d * modP2(X2 * Y2)));
if (left !== right)
throw new Error("bad point: equation left != right (1)");
const XY = modP2(X * Y);
const ZT = modP2(Z * T);
if (XY !== ZT) throw new Error("bad point: equation left != right (2)");
}
// Compare one point to another.
equals(other) {
isPoint(other);
const { ex: X1, ey: Y1, ez: Z1 } = this;
const { ex: X2, ey: Y2, ez: Z2 } = other;
const X1Z2 = modP2(X1 * Z2);
const X2Z1 = modP2(X2 * Z1);
const Y1Z2 = modP2(Y1 * Z2);
const Y2Z1 = modP2(Y2 * Z1);
return X1Z2 === X2Z1 && Y1Z2 === Y2Z1;
}
is0() {
return this.equals(Point2.ZERO);
}
negate() {
return new Point2(modP2(-this.ex), this.ey, this.ez, modP2(-this.et));
}
// Fast algo for doubling Extended Point.
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#doubling-dbl-2008-hwcd
// Cost: 4M + 4S + 1*a + 6add + 1*2.
double() {
const { a } = CURVE2;
const { ex: X1, ey: Y1, ez: Z1 } = this;
const A = modP2(X1 * X1);
const B = modP2(Y1 * Y1);
const C = modP2(_2n5 * modP2(Z1 * Z1));
const D = modP2(a * A);
const x1y1 = X1 + Y1;
const E = modP2(modP2(x1y1 * x1y1) - A - B);
const G2 = D + B;
const F = G2 - C;
const H = D - B;
const X3 = modP2(E * F);
const Y3 = modP2(G2 * H);
const T3 = modP2(E * H);
const Z3 = modP2(F * G2);
return new Point2(X3, Y3, Z3, T3);
}
// Fast algo for adding 2 Extended Points.
// https://hyperelliptic.org/EFD/g1p/auto-twisted-extended.html#addition-add-2008-hwcd
// Cost: 9M + 1*a + 1*d + 7add.
add(other) {
isPoint(other);
const { a, d } = CURVE2;
const { ex: X1, ey: Y1, ez: Z1, et: T1 } = this;
const { ex: X2, ey: Y2, ez: Z2, et: T2 } = other;
if (a === BigInt(-1)) {
const A2 = modP2((Y1 - X1) * (Y2 + X2));
const B2 = modP2((Y1 + X1) * (Y2 - X2));
const F2 = modP2(B2 - A2);
if (F2 === _0n6) return this.double();
const C2 = modP2(Z1 * _2n5 * T2);
const D2 = modP2(T1 * _2n5 * Z2);
const E2 = D2 + C2;
const G3 = B2 + A2;
const H2 = D2 - C2;
const X32 = modP2(E2 * F2);
const Y32 = modP2(G3 * H2);
const T32 = modP2(E2 * H2);
const Z32 = modP2(F2 * G3);
return new Point2(X32, Y32, Z32, T32);
}
const A = modP2(X1 * X2);
const B = modP2(Y1 * Y2);
const C = modP2(T1 * d * T2);
const D = modP2(Z1 * Z2);
const E = modP2((X1 + Y1) * (X2 + Y2) - A - B);
const F = D - C;
const G2 = D + C;
const H = modP2(B - a * A);
const X3 = modP2(E * F);
const Y3 = modP2(G2 * H);
const T3 = modP2(E * H);
const Z3 = modP2(F * G2);
return new Point2(X3, Y3, Z3, T3);
}
subtract(other) {
return this.add(other.negate());
}
wNAF(n) {
return wnaf.wNAFCached(this, pointPrecomputes, n, Point2.normalizeZ);
}
// Constant-time multiplication.
multiply(scalar) {
const { p, f } = this.wNAF(assertInRange(scalar, CURVE_ORDER));
return Point2.normalizeZ([p, f])[0];
}
// Non-constant-time multiplication. Uses double-and-add algorithm.
// It's faster, but should only be used when you don't care about
// an exposed private key e.g. sig verification.
// Does NOT allow scalars higher than CURVE.n.
multiplyUnsafe(scalar) {
let n = assertGE0(scalar);
if (n === _0n6) return I;
if (this.equals(I) || n === _1n6) return this;
if (this.equals(G)) return this.wNAF(n).p;
return wnaf.unsafeLadder(this, n);
}
// Checks if point is of small order.
// If you add something to small order point, you will have "dirty"
// point with torsion component.
// Multiplies point by cofactor and checks if the result is 0.
isSmallOrder() {
return this.multiplyUnsafe(cofactor).is0();
}
// Multiplies point by curve order and checks if the result is 0.
// Returns `false` is the point is dirty.
isTorsionFree() {
return wnaf.unsafeLadder(this, CURVE_ORDER).is0();
}
// Converts Extended point to default (x, y) coordinates.
// Can accept precomputed Z^-1 - for example, from invertBatch.
toAffine(iz) {
const { ex: x, ey: y, ez: z } = this;
const is0 = this.is0();
if (iz == null) iz = is0 ? _8n2 : Fp8.inv(z);
const ax = modP2(x * iz);
const ay = modP2(y * iz);
const zz = modP2(z * iz);
if (is0) return { x: _0n6, y: _1n6 };
if (zz !== _1n6) throw new Error("invZ was invalid");
return { x: ax, y: ay };
}
clearCofactor() {
const { h: cofactor2 } = CURVE2;
if (cofactor2 === _1n6) return this;
return this.multiplyUnsafe(cofactor2);
}
// Converts hash string or Uint8Array to Point.
// Uses algo from RFC8032 5.1.3.
static fromHex(hex, zip215 = false) {
const { d, a } = CURVE2;
const len = Fp8.BYTES;
hex = ensureBytes("pointHex", hex, len);
const normed = hex.slice();
const lastByte = hex[len - 1];
normed[len - 1] = lastByte & ~128;
const y = bytesToNumberLE(normed);
if (y === _0n6) {
} else {
if (zip215) assertInRange(y, MASK);
else assertInRange(y, Fp8.ORDER);
}
const y2 = modP2(y * y);
const u = modP2(y2 - _1n6);
const v = modP2(d * y2 - a);
let { isValid, value: x } = uvRatio3(u, v);
if (!isValid) throw new Error("Point.fromHex: invalid y coordinate");
const isXOdd = (x & _1n6) === _1n6;
const isLastByteOdd = (lastByte & 128) !== 0;
if (!zip215 && x === _0n6 && isLastByteOdd)
throw new Error("Point.fromHex: x=0 and x_0=1");
if (isLastByteOdd !== isXOdd) x = modP2(-x);
return Point2.fromAffine({ x, y });
}
static fromPrivateKey(privKey) {
return getExtendedPublicKey(privKey).point;
}
toRawBytes() {
const { x, y } = this.toAffine();
const bytes2 = numberToBytesLE(y, Fp8.BYTES);
bytes2[bytes2.length - 1] |= x & _1n6 ? 128 : 0;
return bytes2;
}
toHex() {
return bytesToHex(this.toRawBytes());
}
}
Point2.BASE = new Point2(
CURVE2.Gx,
CURVE2.Gy,
_1n6,
modP2(CURVE2.Gx * CURVE2.Gy),
);
Point2.ZERO = new Point2(_0n6, _1n6, _1n6, _0n6);
const { BASE: G, ZERO: I } = Point2;
const wnaf = wNAF(Point2, nByteLength * 8);
function modN2(a) {
return mod(a, CURVE_ORDER);
}
function modN_LE(hash2) {
return modN2(bytesToNumberLE(hash2));
}
function getExtendedPublicKey(key) {
const len = nByteLength;
key = ensureBytes("private key", key, len);
const hashed = ensureBytes("hashed private key", cHash(key), 2 * len);
const head = adjustScalarBytes3(hashed.slice(0, len));
const prefix = hashed.slice(len, 2 * len);
const scalar = modN_LE(head);
const point = G.multiply(scalar);
const pointBytes = point.toRawBytes();
return { head, prefix, scalar, point, pointBytes };
}
function getPublicKey(privKey) {
return getExtendedPublicKey(privKey).pointBytes;
}
function hashDomainToScalar(context = new Uint8Array(), ...msgs) {
const msg = concatBytes(...msgs);
return modN_LE(
cHash(domain(msg, ensureBytes("context", context), !!prehash)),
);
}
function sign(msg, privKey, options = {}) {
msg = ensureBytes("message", msg);
if (prehash) msg = prehash(msg);
const { prefix, scalar, pointBytes } = getExtendedPublicKey(privKey);
const r = hashDomainToScalar(options.context, prefix, msg);
const R = G.multiply(r).toRawBytes();
const k = hashDomainToScalar(options.context, R, pointBytes, msg);
const s = modN2(r + k * scalar);
assertGE0(s);
const res = concatBytes(R, numberToBytesLE(s, Fp8.BYTES));
return ensureBytes("result", res, nByteLength * 2);
}
const verifyOpts = VERIFY_DEFAULT;
function verify(sig, msg, publicKey, options = verifyOpts) {
const { context, zip215 } = options;
const len = Fp8.BYTES;
sig = ensureBytes("signature", sig, 2 * len);
msg = ensureBytes("message", msg);
if (prehash) msg = prehash(msg);
const s = bytesToNumberLE(sig.slice(len, 2 * len));
let A, R, SB;
try {
A = Point2.fromHex(publicKey, zip215);
R = Point2.fromHex(sig.slice(0, len), zip215);
SB = G.multiplyUnsafe(s);
} catch (error) {
return false;
}
if (!zip215 && A.isSmallOrder()) return false;
const k = hashDomainToScalar(
context,
R.toRawBytes(),
A.toRawBytes(),
msg,
);
const RkA = R.add(A.multiplyUnsafe(k));
return RkA.subtract(SB).clearCofactor().equals(Point2.ZERO);
}
G._setWindowSize(8);
const utils2 = {
getExtendedPublicKey,
// ed25519 private keys are uniform 32b. No need to check for modulo bias, like in secp256k1.
randomPrivateKey: () => randomBytes2(Fp8.BYTES),
/**
* We're doing scalar multiplication (used in getPublicKey etc) with precomputed BASE_POINT
* values. This slows down first getPublicKey() by milliseconds (see Speed section),
* but allows to speed-up subsequent getPublicKey() calls up to 20x.
* @param windowSize 2, 4, 8, 16
*/
precompute(windowSize = 8, point = Point2.BASE) {
point._setWindowSize(windowSize);
point.multiply(BigInt(3));
return point;
},
};
return {
CURVE: CURVE2,
getPublicKey,
sign,
verify,
ExtendedPoint: Point2,
utils: utils2,
};
}
// ../esm/abstract/montgomery.js
var _0n7 = BigInt(0);
var _1n7 = BigInt(1);
function validateOpts3(curve) {
validateObject(
curve,
{
a: "bigint",
},
{
montgomeryBits: "isSafeInteger",
nByteLength: "isSafeInteger",
adjustScalarBytes: "function",
domain: "function",
powPminus2: "function",
Gu: "bigint",
},
);
return Object.freeze({ ...curve });
}
function montgomery(curveDef) {
const CURVE2 = validateOpts3(curveDef);
const { P: P3 } = CURVE2;
const modP2 = (n) => mod(n, P3);
const montgomeryBits = CURVE2.montgomeryBits;
const montgomeryBytes = Math.ceil(montgomeryBits / 8);
const fieldLen = CURVE2.nByteLength;
const adjustScalarBytes3 = CURVE2.adjustScalarBytes || ((bytes2) => bytes2);
const powPminus2 = CURVE2.powPminus2 || ((x) => pow(x, P3 - BigInt(2), P3));
function cswap(swap, x_2, x_3) {
const dummy = modP2(swap * (x_2 - x_3));
x_2 = modP2(x_2 - dummy);
x_3 = modP2(x_3 + dummy);
return [x_2, x_3];
}
function assertFieldElement(n) {
if (typeof n === "bigint" && _0n7 <= n && n < P3) return n;
throw new Error("Expected valid scalar 0 < scalar < CURVE.P");
}
const a24 = (CURVE2.a - BigInt(2)) / BigInt(4);
function montgomeryLadder(pointU, scalar) {
const u = assertFieldElement(pointU);
const k = assertFieldElement(scalar);
const x_1 = u;
let x_2 = _1n7;
let z_2 = _0n7;
let x_3 = u;
let z_3 = _1n7;
let swap = _0n7;
let sw;
for (let t = BigInt(montgomeryBits - 1); t >= _0n7; t--) {
const k_t = (k >> t) & _1n7;
swap ^= k_t;
sw = cswap(swap, x_2, x_3);
x_2 = sw[0];
x_3 = sw[1];
sw = cswap(swap, z_2, z_3);
z_2 = sw[0];
z_3 = sw[1];
swap = k_t;
const A = x_2 + z_2;
const AA = modP2(A * A);
const B = x_2 - z_2;
const BB = modP2(B * B);
const E = AA - BB;
const C = x_3 + z_3;
const D = x_3 - z_3;
const DA = modP2(D * A);
const CB = modP2(C * B);
const dacb = DA + CB;
const da_cb = DA - CB;
x_3 = modP2(dacb * dacb);
z_3 = modP2(x_1 * modP2(da_cb * da_cb));
x_2 = modP2(AA * BB);
z_2 = modP2(E * (AA + modP2(a24 * E)));
}
sw = cswap(swap, x_2, x_3);
x_2 = sw[0];
x_3 = sw[1];
sw = cswap(swap, z_2, z_3);
z_2 = sw[0];
z_3 = sw[1];
const z2 = powPminus2(z_2);
return modP2(x_2 * z2);
}
function encodeUCoordinate(u) {
return numberToBytesLE(modP2(u), montgomeryBytes);
}
function decodeUCoordinate(uEnc) {
const u = ensureBytes("u coordinate", uEnc, montgomeryBytes);
if (fieldLen === montgomeryBytes) u[fieldLen - 1] &= 127;
return bytesToNumberLE(u);
}
function decodeScalar(n) {
const bytes2 = ensureBytes("scalar", n);
if (bytes2.length !== montgomeryBytes && bytes2.length !== fieldLen)
throw new Error(
`Expected ${montgomeryBytes} or ${fieldLen} bytes, got ${bytes2.length}`,
);
return bytesToNumberLE(adjustScalarBytes3(bytes2));
}
function scalarMult(scalar, u) {
const pointU = decodeUCoordinate(u);
const _scalar = decodeScalar(scalar);
const pu = montgomeryLadder(pointU, _scalar);
if (pu === _0n7)
throw new Error("Invalid private or public key received");
return encodeUCoordinate(pu);
}
const GuBytes = encodeUCoordinate(CURVE2.Gu);
function scalarMultBase(scalar) {
return scalarMult(scalar, GuBytes);
}
return {
scalarMult,
scalarMultBase,
getSharedSecret: (privateKey, publicKey) =>
scalarMult(privateKey, publicKey),
getPublicKey: (privateKey) => scalarMultBase(privateKey),
utils: { randomPrivateKey: () => CURVE2.randomBytes(CURVE2.nByteLength) },
GuBytes,
};
}
// ../esm/ed25519.js
var ED25519_P = BigInt(
"57896044618658097711785492504343953926634992332820282019728792003956564819949",
);
var ED25519_SQRT_M1 = BigInt(
"19681161376707505956807079304988542015446066515923890162744021073123829784752",
);
var _0n8 = BigInt(0);
var _1n8 = BigInt(1);
var _2n6 = BigInt(2);
var _5n2 = BigInt(5);
var _10n = BigInt(10);
var _20n = BigInt(20);
var _40n = BigInt(40);
var _80n = BigInt(80);
function ed25519_pow_2_252_3(x) {
const P3 = ED25519_P;
const x2 = (x * x) % P3;
const b2 = (x2 * x) % P3;
const b4 = (pow2(b2, _2n6, P3) * b2) % P3;
const b5 = (pow2(b4, _1n8, P3) * x) % P3;
const b10 = (pow2(b5, _5n2, P3) * b5) % P3;
const b20 = (pow2(b10, _10n, P3) * b10) % P3;
const b40 = (pow2(b20, _20n, P3) * b20) % P3;
const b80 = (pow2(b40, _40n, P3) * b40) % P3;
const b160 = (pow2(b80, _80n, P3) * b80) % P3;
const b240 = (pow2(b160, _80n, P3) * b80) % P3;
const b250 = (pow2(b240, _10n, P3) * b10) % P3;
const pow_p_5_8 = (pow2(b250, _2n6, P3) * x) % P3;
return { pow_p_5_8, b2 };
}
function adjustScalarBytes(bytes2) {
bytes2[0] &= 248;
bytes2[31] &= 127;
bytes2[31] |= 64;
return bytes2;
}
function uvRatio(u, v) {
const P3 = ED25519_P;
const v3 = mod(v * v * v, P3);
const v7 = mod(v3 * v3 * v, P3);
const pow3 = ed25519_pow_2_252_3(u * v7).pow_p_5_8;
let x = mod(u * v3 * pow3, P3);
const vx2 = mod(v * x * x, P3);
const root1 = x;
const root2 = mod(x * ED25519_SQRT_M1, P3);
const useRoot1 = vx2 === u;
const useRoot2 = vx2 === mod(-u, P3);
const noRoot = vx2 === mod(-u * ED25519_SQRT_M1, P3);
if (useRoot1) x = root1;
if (useRoot2 || noRoot) x = root2;
if (isNegativeLE(x, P3)) x = mod(-x, P3);
return { isValid: useRoot1 || useRoot2, value: x };
}
var Fp2 = Field(ED25519_P, void 0, true);
var ed25519Defaults = {
// Param: a
a: BigInt(-1),
// d is equal to -121665/121666 over finite field.
// Negative number is P - number, and division is invert(number, P)
d: BigInt(
"37095705934669439343138083508754565189542113879843219016388785533085940283555",
),
// Finite field 𝔽p over which we'll do calculations; 2n**255n - 19n
Fp: Fp2,
// Subgroup order: how many points curve has
// 2n**252n + 27742317777372353535851937790883648493n;
n: BigInt(
"7237005577332262213973186563042994240857116359379907606001950938285454250989",
),
// Cofactor
h: BigInt(8),
// Base point (x, y) aka generator point
Gx: BigInt(
"15112221349535400772501151409588531511454012693041857206046113283949847762202",
),
Gy: BigInt(
"46316835694926478169428394003475163141307993866256225615783033603165251855960",
),
hash: sha512,
randomBytes,
adjustScalarBytes,
// dom2
// Ratio of u to v. Allows us to combine inversion and square root. Uses algo from RFC8032 5.1.3.
// Constant-time, u/√v
uvRatio,
};
var ed25519 = /* @__PURE__ */ twistedEdwards(ed25519Defaults);
function ed25519_domain(data, ctx, phflag) {
if (ctx.length > 255) throw new Error("Context is too big");
return concatBytes2(
utf8ToBytes2("SigEd25519 no Ed25519 collisions"),
new Uint8Array([phflag ? 1 : 0, ctx.length]),
ctx,
data,
);
}
var ed25519ctx = /* @__PURE__ */ twistedEdwards({
...ed25519Defaults,
domain: ed25519_domain,
});
var ed25519ph = /* @__PURE__ */ twistedEdwards({
...ed25519Defaults,
domain: ed25519_domain,
prehash: sha512,
});
var x25519 = /* @__PURE__ */ (() =>
montgomery({
P: ED25519_P,
a: BigInt(486662),
montgomeryBits: 255,
nByteLength: 32,
Gu: BigInt(9),
powPminus2: (x) => {
const P3 = ED25519_P;
const { pow_p_5_8, b2 } = ed25519_pow_2_252_3(x);
return mod(pow2(pow_p_5_8, BigInt(3), P3) * b2, P3);
},
adjustScalarBytes,
randomBytes,
}))();
function edwardsToMontgomeryPub(edwardsPub) {
const { y } = ed25519.ExtendedPoint.fromHex(edwardsPub);
const _1n12 = BigInt(1);
return Fp2.toBytes(Fp2.create((_1n12 + y) * Fp2.inv(_1n12 - y)));
}
function edwardsToMontgomeryPriv(edwardsPriv) {
const hashed = ed25519Defaults.hash(edwardsPriv.subarray(0, 32));
return ed25519Defaults.adjustScalarBytes(hashed).subarray(0, 32);
}
var ELL2_C1 = (Fp2.ORDER + BigInt(3)) / BigInt(8);
var ELL2_C2 = Fp2.pow(_2n6, ELL2_C1);
var ELL2_C3 = Fp2.sqrt(Fp2.neg(Fp2.ONE));
var ELL2_C4 = (Fp2.ORDER - BigInt(5)) / BigInt(8);
var ELL2_J = BigInt(486662);
var ELL2_C1_EDWARDS = FpSqrtEven(Fp2, Fp2.neg(BigInt(486664)));
var SQRT_AD_MINUS_ONE = BigInt(
"25063068953384623474111414158702152701244531502492656460079210482610430750235",
);
var INVSQRT_A_MINUS_D = BigInt(
"54469307008909316920995813868745141605393597292927456921205312896311721017578",
);
var ONE_MINUS_D_SQ = BigInt(
"1159843021668779879193775521855586647937357759715417654439879720876111806838",
);
var D_MINUS_ONE_SQ = BigInt(
"40440834346308536858101042469323190826248399146238708352240133220865137265952",
);
var MAX_255B = BigInt(
"0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
// ../node_modules/@noble/hashes/esm/sha3.js
var [SHA3_PI, SHA3_ROTL, _SHA3_IOTA] = [[], [], []];
var _0n9 = /* @__PURE__ */ BigInt(0);
var _1n9 = /* @__PURE__ */ BigInt(1);
var _2n7 = /* @__PURE__ */ BigInt(2);
var _7n = /* @__PURE__ */ BigInt(7);
var _256n = /* @__PURE__ */ BigInt(256);
var _0x71n = /* @__PURE__ */ BigInt(113);
for (let round = 0, R = _1n9, x = 1, y = 0; round < 24; round++) {
[x, y] = [y, (2 * x + 3 * y) % 5];
SHA3_PI.push(2 * (5 * y + x));
SHA3_ROTL.push((((round + 1) * (round + 2)) / 2) % 64);
let t = _0n9;
for (let j = 0; j < 7; j++) {
R = ((R << _1n9) ^ ((R >> _7n) * _0x71n)) % _256n;
if (R & _2n7) t ^= _1n9 << ((_1n9 << /* @__PURE__ */ BigInt(j)) - _1n9);
}
_SHA3_IOTA.push(t);
}
var [SHA3_IOTA_H, SHA3_IOTA_L] = /* @__PURE__ */ split(_SHA3_IOTA, true);
var rotlH = (h, l, s) => (s > 32 ? rotlBH(h, l, s) : rotlSH(h, l, s));
var rotlL = (h, l, s) => (s > 32 ? rotlBL(h, l, s) : rotlSL(h, l, s));
function keccakP(s, rounds = 24) {
const B = new Uint32Array(5 * 2);
for (let round = 24 - rounds; round < 24; round++) {
for (let x = 0; x < 10; x++)
B[x] = s[x] ^ s[x + 10] ^ s[x + 20] ^ s[x + 30] ^ s[x + 40];
for (let x = 0; x < 10; x += 2) {
const idx1 = (x + 8) % 10;
const idx0 = (x + 2) % 10;
const B0 = B[idx0];
const B1 = B[idx0 + 1];
const Th = rotlH(B0, B1, 1) ^ B[idx1];
const Tl = rotlL(B0, B1, 1) ^ B[idx1 + 1];
for (let y = 0; y < 50; y += 10) {
s[x + y] ^= Th;
s[x + y + 1] ^= Tl;
}
}
let curH = s[2];
let curL = s[3];
for (let t = 0; t < 24; t++) {
const shift = SHA3_ROTL[t];
const Th = rotlH(curH, curL, shift);
const Tl = rotlL(curH, curL, shift);
const PI = SHA3_PI[t];
curH = s[PI];
curL = s[PI + 1];
s[PI] = Th;
s[PI + 1] = Tl;
}
for (let y = 0; y < 50; y += 10) {
for (let x = 0; x < 10; x++) B[x] = s[y + x];
for (let x = 0; x < 10; x++)
s[y + x] ^= ~B[(x + 2) % 10] & B[(x + 4) % 10];
}
s[0] ^= SHA3_IOTA_H[round];
s[1] ^= SHA3_IOTA_L[round];
}
B.fill(0);
}
var Keccak = class _Keccak extends Hash {
// NOTE: we accept arguments in bytes instead of bits here.
constructor(blockLen, suffix, outputLen, enableXOF = false, rounds = 24) {
super();
this.blockLen = blockLen;
this.suffix = suffix;
this.outputLen = outputLen;
this.enableXOF = enableXOF;
this.rounds = rounds;
this.pos = 0;
this.posOut = 0;
this.finished = false;
this.destroyed = false;
number(outputLen);
if (0 >= this.blockLen || this.blockLen >= 200)
throw new Error("Sha3 supports only keccak-f1600 function");
this.state = new Uint8Array(200);
this.state32 = u32(this.state);
}
keccak() {
keccakP(this.state32, this.rounds);
this.posOut = 0;
this.pos = 0;
}
update(data) {
exists(this);
const { blockLen, state } = this;
data = toBytes(data);
const len = data.length;
for (let pos = 0; pos < len; ) {
const take = Math.min(blockLen - this.pos, len - pos);
for (let i = 0; i < take; i++) state[this.pos++] ^= data[pos++];
if (this.pos === blockLen) this.keccak();
}
return this;
}
finish() {
if (this.finished) return;
this.finished = true;
const { state, suffix, pos, blockLen } = this;
state[pos] ^= suffix;
if ((suffix & 128) !== 0 && pos === blockLen - 1) this.keccak();
state[blockLen - 1] ^= 128;
this.keccak();
}
writeInto(out) {
exists(this, false);
bytes(out);
this.finish();
const bufferOut = this.state;
const { blockLen } = this;
for (let pos = 0, len = out.length; pos < len; ) {
if (this.posOut >= blockLen) this.keccak();
const take = Math.min(blockLen - this.posOut, len - pos);
out.set(bufferOut.subarray(this.posOut, this.posOut + take), pos);
this.posOut += take;
pos += take;
}
return out;
}
xofInto(out) {
if (!this.enableXOF)
throw new Error("XOF is not possible for this instance");
return this.writeInto(out);
}
xof(bytes2) {
number(bytes2);
return this.xofInto(new Uint8Array(bytes2));
}
digestInto(out) {
output(out, this);
if (this.finished) throw new Error("digest() was already called");
this.writeInto(out);
this.destroy();
return out;
}
digest() {
return this.digestInto(new Uint8Array(this.outputLen));
}
destroy() {
this.destroyed = true;
this.state.fill(0);
}
_cloneInto(to) {
const { blockLen, suffix, outputLen, rounds, enableXOF } = this;
to || (to = new _Keccak(blockLen, suffix, outputLen, enableXOF, rounds));
to.state32.set(this.state32);
to.pos = this.pos;
to.posOut = this.posOut;
to.finished = this.finished;
to.rounds = rounds;
to.suffix = suffix;
to.outputLen = outputLen;
to.enableXOF = enableXOF;
to.destroyed = this.destroyed;
return to;
}
};
var gen = (suffix, blockLen, outputLen) =>
wrapConstructor(() => new Keccak(blockLen, suffix, outputLen));
var sha3_224 = /* @__PURE__ */ gen(6, 144, 224 / 8);
var sha3_256 = /* @__PURE__ */ gen(6, 136, 256 / 8);
var sha3_384 = /* @__PURE__ */ gen(6, 104, 384 / 8);
var sha3_512 = /* @__PURE__ */ gen(6, 72, 512 / 8);
var keccak_224 = /* @__PURE__ */ gen(1, 144, 224 / 8);
var keccak_256 = /* @__PURE__ */ gen(1, 136, 256 / 8);
var keccak_384 = /* @__PURE__ */ gen(1, 104, 384 / 8);
var keccak_512 = /* @__PURE__ */ gen(1, 72, 512 / 8);
var genShake = (suffix, blockLen, outputLen) =>
wrapXOFConstructorWithOpts(
(opts = {}) =>
new Keccak(
blockLen,
suffix,
opts.dkLen === void 0 ? outputLen : opts.dkLen,
true,
),
);
var shake128 = /* @__PURE__ */ genShake(31, 168, 128 / 8);
var shake256 = /* @__PURE__ */ genShake(31, 136, 256 / 8);
// ../esm/ed448.js
var shake256_114 = wrapConstructor(() => shake256.create({ dkLen: 114 }));
var shake256_64 = wrapConstructor(() => shake256.create({ dkLen: 64 }));
var ed448P = BigInt(
"726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018365439",
);
var _1n10 = BigInt(1);
var _2n8 = BigInt(2);
var _3n3 = BigInt(3);
var _4n3 = BigInt(4);
var _11n = BigInt(11);
var _22n = BigInt(22);
var _44n = BigInt(44);
var _88n = BigInt(88);
var _223n = BigInt(223);
function ed448_pow_Pminus3div4(x) {
const P3 = ed448P;
const b2 = (x * x * x) % P3;
const b3 = (b2 * b2 * x) % P3;
const b6 = (pow2(b3, _3n3, P3) * b3) % P3;
const b9 = (pow2(b6, _3n3, P3) * b3) % P3;
const b11 = (pow2(b9, _2n8, P3) * b2) % P3;
const b22 = (pow2(b11, _11n, P3) * b11) % P3;
const b44 = (pow2(b22, _22n, P3) * b22) % P3;
const b88 = (pow2(b44, _44n, P3) * b44) % P3;
const b176 = (pow2(b88, _88n, P3) * b88) % P3;
const b220 = (pow2(b176, _44n, P3) * b44) % P3;
const b222 = (pow2(b220, _2n8, P3) * b2) % P3;
const b223 = (pow2(b222, _1n10, P3) * x) % P3;
return (pow2(b223, _223n, P3) * b222) % P3;
}
function adjustScalarBytes2(bytes2) {
bytes2[0] &= 252;
bytes2[55] |= 128;
bytes2[56] = 0;
return bytes2;
}
function uvRatio2(u, v) {
const P3 = ed448P;
const u2v = mod(u * u * v, P3);
const u3v = mod(u2v * u, P3);
const u5v3 = mod(u3v * u2v * v, P3);
const root = ed448_pow_Pminus3div4(u5v3);
const x = mod(u3v * root, P3);
const x2 = mod(x * x, P3);
return { isValid: mod(x2 * v, P3) === u, value: x };
}
var Fp3 = Field(ed448P, 456, true);
var ED448_DEF = {
// Param: a
a: BigInt(1),
// -39081. Negative number is P - number
d: BigInt(
"726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018326358",
),
// Finite field 𝔽p over which we'll do calculations; 2n**448n - 2n**224n - 1n
Fp: Fp3,
// Subgroup order: how many points curve has;
// 2n**446n - 13818066809895115352007386748515426880336692474882178609894547503885n
n: BigInt(
"181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779",
),
nBitLength: 456,
// Cofactor
h: BigInt(4),
// Base point (x, y) aka generator point
Gx: BigInt(
"224580040295924300187604334099896036246789641632564134246125461686950415467406032909029192869357953282578032075146446173674602635247710",
),
Gy: BigInt(
"298819210078481492676017930443930673437544040154080242095928241372331506189835876003536878655418784733982303233503462500531545062832660",
),
// SHAKE256(dom4(phflag,context)||x, 114)
hash: shake256_114,
randomBytes,
adjustScalarBytes: adjustScalarBytes2,
// dom4
domain: (data, ctx, phflag) => {
if (ctx.length > 255)
throw new Error(`Context is too big: ${ctx.length}`);
return concatBytes2(
utf8ToBytes2("SigEd448"),
new Uint8Array([phflag ? 1 : 0, ctx.length]),
ctx,
data,
);
},
uvRatio: uvRatio2,
};
var ed448 = /* @__PURE__ */ twistedEdwards(ED448_DEF);
var ed448ph = /* @__PURE__ */ twistedEdwards({
...ED448_DEF,
prehash: shake256_64,
});
var x448 = /* @__PURE__ */ (() =>
montgomery({
a: BigInt(156326),
montgomeryBits: 448,
nByteLength: 57,
P: ed448P,
Gu: BigInt(5),
powPminus2: (x) => {
const P3 = ed448P;
const Pminus3div4 = ed448_pow_Pminus3div4(x);
const Pminus3 = pow2(Pminus3div4, BigInt(2), P3);
return mod(Pminus3 * x, P3);
},
adjustScalarBytes: adjustScalarBytes2,
randomBytes,
}))();
function edwardsToMontgomeryPub2(edwardsPub) {
const { y } = ed448.ExtendedPoint.fromHex(edwardsPub);
const _1n12 = BigInt(1);
return Fp3.toBytes(Fp3.create((y - _1n12) * Fp3.inv(y + _1n12)));
}
var ELL2_C12 = (Fp3.ORDER - BigInt(3)) / BigInt(4);
var ELL2_J2 = BigInt(156326);
var ONE_MINUS_D = BigInt("39082");
var ONE_MINUS_TWO_D = BigInt("78163");
var SQRT_MINUS_D = BigInt(
"98944233647732219769177004876929019128417576295529901074099889598043702116001257856802131563896515373927712232092845883226922417596214",
);
var INVSQRT_MINUS_D = BigInt(
"315019913931389607337177038330951043522456072897266928557328499619017160722351061360252776265186336876723201881398623946864393857820716",
);
var MAX_448B = BigInt(
"0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
// ../esm/p256.js
var Fp4 = Field(
BigInt(
"0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
),
);
var CURVE_A = Fp4.create(BigInt("-3"));
var CURVE_B = BigInt(
"0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
);
var p256 = createCurve(
{
a: CURVE_A,
b: CURVE_B,
Fp: Fp4,
// Curve order, total count of valid points in the field
n: BigInt(
"0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
),
// Base (generator) point (x, y)
Gx: BigInt(
"0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
),
Gy: BigInt(
"0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5",
),
h: BigInt(1),
lowS: false,
},
sha256,
);
// ../esm/p384.js
var P = BigInt(
"0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffeffffffff0000000000000000ffffffff",
);
var Fp5 = Field(P);
var CURVE_A2 = Fp5.create(BigInt("-3"));
var CURVE_B2 = BigInt(
"0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875ac656398d8a2ed19d2a85c8edd3ec2aef",
);
var p384 = createCurve(
{
a: CURVE_A2,
b: CURVE_B2,
Fp: Fp5,
// Curve order, total count of valid points in the field.
n: BigInt(
"0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973",
),
// Base (generator) point (x, y)
Gx: BigInt(
"0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a385502f25dbf55296c3a545e3872760ab7",
),
Gy: BigInt(
"0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c00a60b1ce1d7e819d7a431d7c90ea0e5f",
),
h: BigInt(1),
lowS: false,
},
sha384,
);
// ../esm/p521.js
var P2 = BigInt(
"0x1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
);
var Fp6 = Field(P2);
var CURVE = {
a: Fp6.create(BigInt("-3")),
b: BigInt(
"0x0051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
),
Fp: Fp6,
n: BigInt(
"0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
),
Gx: BigInt(
"0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
),
Gy: BigInt(
"0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650",
),
h: BigInt(1),
};
var p521 = createCurve(
{
a: CURVE.a,
b: CURVE.b,
Fp: Fp6,
// Curve order, total count of valid points in the field
n: CURVE.n,
Gx: CURVE.Gx,
Gy: CURVE.Gy,
h: CURVE.h,
lowS: false,
allowedPrivateKeyLengths: [130, 131, 132],
// P521 keys are variable-length. Normalize to 132b
},
sha512,
);
// ../esm/abstract/bls.js
var _2n9 = BigInt(2);
var _3n4 = BigInt(3);
function bls(CURVE2) {
const {
Fp: Fp8,
Fr: Fr2,
Fp2: Fp23,
Fp6: Fp63,
Fp12: Fp122,
} = CURVE2.fields;
const BLS_X_LEN2 = bitLen(CURVE2.params.x);
function calcPairingPrecomputes(p) {
const { x, y } = p;
const Qx = x,
Qy = y,
Qz = Fp23.ONE;
let Rx = Qx,
Ry = Qy,
Rz = Qz;
let ell_coeff = [];
for (let i = BLS_X_LEN2 - 2; i >= 0; i--) {
let t0 = Fp23.sqr(Ry);
let t1 = Fp23.sqr(Rz);
let t2 = Fp23.multiplyByB(Fp23.mul(t1, _3n4));
let t3 = Fp23.mul(t2, _3n4);
let t4 = Fp23.sub(Fp23.sub(Fp23.sqr(Fp23.add(Ry, Rz)), t1), t0);
ell_coeff.push([
Fp23.sub(t2, t0),
Fp23.mul(Fp23.sqr(Rx), _3n4),
Fp23.neg(t4),
// -T4
]);
Rx = Fp23.div(Fp23.mul(Fp23.mul(Fp23.sub(t0, t3), Rx), Ry), _2n9);
Ry = Fp23.sub(
Fp23.sqr(Fp23.div(Fp23.add(t0, t3), _2n9)),
Fp23.mul(Fp23.sqr(t2), _3n4),
);
Rz = Fp23.mul(t0, t4);
if (bitGet(CURVE2.params.x, i)) {
let t02 = Fp23.sub(Ry, Fp23.mul(Qy, Rz));
let t12 = Fp23.sub(Rx, Fp23.mul(Qx, Rz));
ell_coeff.push([
Fp23.sub(Fp23.mul(t02, Qx), Fp23.mul(t12, Qy)),
Fp23.neg(t02),
t12,
// T1
]);
let t22 = Fp23.sqr(t12);
let t32 = Fp23.mul(t22, t12);
let t42 = Fp23.mul(t22, Rx);
let t5 = Fp23.add(
Fp23.sub(t32, Fp23.mul(t42, _2n9)),
Fp23.mul(Fp23.sqr(t02), Rz),
);
Rx = Fp23.mul(t12, t5);
Ry = Fp23.sub(Fp23.mul(Fp23.sub(t42, t5), t02), Fp23.mul(t32, Ry));
Rz = Fp23.mul(Rz, t32);
}
}
return ell_coeff;
}
function millerLoop(ell, g1) {
const { x } = CURVE2.params;
const Px = g1[0];
const Py = g1[1];
let f12 = Fp122.ONE;
for (let j = 0, i = BLS_X_LEN2 - 2; i >= 0; i--, j++) {
const E = ell[j];
f12 = Fp122.multiplyBy014(
f12,
E[0],
Fp23.mul(E[1], Px),
Fp23.mul(E[2], Py),
);
if (bitGet(x, i)) {
j += 1;
const F = ell[j];
f12 = Fp122.multiplyBy014(
f12,
F[0],
Fp23.mul(F[1], Px),
Fp23.mul(F[2], Py),
);
}
if (i !== 0) f12 = Fp122.sqr(f12);
}
return Fp122.conjugate(f12);
}
const utils2 = {
randomPrivateKey: () => {
const length = getMinHashLength(Fr2.ORDER);
return mapHashToField(CURVE2.randomBytes(length), Fr2.ORDER);
},
calcPairingPrecomputes,
};
const G1_ = weierstrassPoints({ n: Fr2.ORDER, ...CURVE2.G1 });
const G1 = Object.assign(
G1_,
createHasher(G1_.ProjectivePoint, CURVE2.G1.mapToCurve, {
...CURVE2.htfDefaults,
...CURVE2.G1.htfDefaults,
}),
);
function pairingPrecomputes(point) {
const p = point;
if (p._PPRECOMPUTES) return p._PPRECOMPUTES;
p._PPRECOMPUTES = calcPairingPrecomputes(point.toAffine());
return p._PPRECOMPUTES;
}
const G2_ = weierstrassPoints({ n: Fr2.ORDER, ...CURVE2.G2 });
const G2 = Object.assign(
G2_,
createHasher(G2_.ProjectivePoint, CURVE2.G2.mapToCurve, {
...CURVE2.htfDefaults,
...CURVE2.G2.htfDefaults,
}),
);
const { Signature } = CURVE2.G2;
function pairing(Q, P3, withFinalExponent = true) {
if (
Q.equals(G1.ProjectivePoint.ZERO) ||
P3.equals(G2.ProjectivePoint.ZERO)
)
throw new Error("pairing is not available for ZERO point");
Q.assertValidity();
P3.assertValidity();
const Qa = Q.toAffine();
const looped = millerLoop(pairingPrecomputes(P3), [Qa.x, Qa.y]);
return withFinalExponent ? Fp122.finalExponentiate(looped) : looped;
}
function normP1(point) {
return point instanceof G1.ProjectivePoint
? point
: G1.ProjectivePoint.fromHex(point);
}
function normP2(point) {
return point instanceof G2.ProjectivePoint
? point
: Signature.fromHex(point);
}
function normP2Hash(point, htfOpts) {
return point instanceof G2.ProjectivePoint
? point
: G2.hashToCurve(ensureBytes("point", point), htfOpts);
}
function getPublicKey(privateKey) {
return G1.ProjectivePoint.fromPrivateKey(privateKey).toRawBytes(true);
}
function sign(message, privateKey, htfOpts) {
const msgPoint = normP2Hash(message, htfOpts);
msgPoint.assertValidity();
const sigPoint = msgPoint.multiply(G1.normPrivateKeyToScalar(privateKey));
if (message instanceof G2.ProjectivePoint) return sigPoint;
return Signature.toRawBytes(sigPoint);
}
function verify(signature, message, publicKey, htfOpts) {
const P3 = normP1(publicKey);
const Hm = normP2Hash(message, htfOpts);
const G = G1.ProjectivePoint.BASE;
const S = normP2(signature);
const ePHm = pairing(P3.negate(), Hm, false);
const eGS = pairing(G, S, false);
const exp = Fp122.finalExponentiate(Fp122.mul(eGS, ePHm));
return Fp122.eql(exp, Fp122.ONE);
}
function aggregatePublicKeys(publicKeys) {
if (!publicKeys.length) throw new Error("Expected non-empty array");
const agg = publicKeys
.map(normP1)
.reduce((sum, p) => sum.add(p), G1.ProjectivePoint.ZERO);
const aggAffine = agg;
if (publicKeys[0] instanceof G1.ProjectivePoint) {
aggAffine.assertValidity();
return aggAffine;
}
return aggAffine.toRawBytes(true);
}
function aggregateSignatures(signatures) {
if (!signatures.length) throw new Error("Expected non-empty array");
const agg = signatures
.map(normP2)
.reduce((sum, s) => sum.add(s), G2.ProjectivePoint.ZERO);
const aggAffine = agg;
if (signatures[0] instanceof G2.ProjectivePoint) {
aggAffine.assertValidity();
return aggAffine;
}
return Signature.toRawBytes(aggAffine);
}
function verifyBatch(signature, messages, publicKeys, htfOpts) {
if (!messages.length)
throw new Error("Expected non-empty messages array");
if (publicKeys.length !== messages.length)
throw new Error("Pubkey count should equal msg count");
const sig = normP2(signature);
const nMessages = messages.map((i) => normP2Hash(i, htfOpts));
const nPublicKeys = publicKeys.map(normP1);
try {
const paired = [];
for (const message of new Set(nMessages)) {
const groupPublicKey = nMessages.reduce(
(groupPublicKey2, subMessage, i) =>
subMessage === message
? groupPublicKey2.add(nPublicKeys[i])
: groupPublicKey2,
G1.ProjectivePoint.ZERO,
);
paired.push(pairing(groupPublicKey, message, false));
}
paired.push(pairing(G1.ProjectivePoint.BASE.negate(), sig, false));
const product = paired.reduce((a, b) => Fp122.mul(a, b), Fp122.ONE);
const exp = Fp122.finalExponentiate(product);
return Fp122.eql(exp, Fp122.ONE);
} catch {
return false;
}
}
G1.ProjectivePoint.BASE._setWindowSize(4);
return {
getPublicKey,
sign,
verify,
verifyBatch,
aggregatePublicKeys,
aggregateSignatures,
millerLoop,
pairing,
G1,
G2,
Signature,
fields: {
Fr: Fr2,
Fp: Fp8,
Fp2: Fp23,
Fp6: Fp63,
Fp12: Fp122,
},
params: {
x: CURVE2.params.x,
r: CURVE2.params.r,
G1b: CURVE2.G1.b,
G2b: CURVE2.G2.b,
},
utils: utils2,
};
}
// ../esm/bls12-381.js
var _0n10 = BigInt(0);
var _1n11 = BigInt(1);
var _2n10 = BigInt(2);
var _3n5 = BigInt(3);
var _4n4 = BigInt(4);
var _8n3 = BigInt(8);
var _16n2 = BigInt(16);
var Fp_raw = BigInt(
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab",
);
var Fp7 = Field(Fp_raw);
var Fr = Field(
BigInt(
"0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",
),
);
var Fp2Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
c0: Fp7.add(c0, r0),
c1: Fp7.add(c1, r1),
});
var Fp2Subtract = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
c0: Fp7.sub(c0, r0),
c1: Fp7.sub(c1, r1),
});
var Fp2Multiply = ({ c0, c1 }, rhs) => {
if (typeof rhs === "bigint")
return { c0: Fp7.mul(c0, rhs), c1: Fp7.mul(c1, rhs) };
const { c0: r0, c1: r1 } = rhs;
let t1 = Fp7.mul(c0, r0);
let t2 = Fp7.mul(c1, r1);
const o0 = Fp7.sub(t1, t2);
const o1 = Fp7.sub(
Fp7.mul(Fp7.add(c0, c1), Fp7.add(r0, r1)),
Fp7.add(t1, t2),
);
return { c0: o0, c1: o1 };
};
var Fp2Square = ({ c0, c1 }) => {
const a = Fp7.add(c0, c1);
const b = Fp7.sub(c0, c1);
const c = Fp7.add(c0, c0);
return { c0: Fp7.mul(a, b), c1: Fp7.mul(c, c1) };
};
var FP2_ORDER = Fp_raw * Fp_raw;
var Fp22 = {
ORDER: FP2_ORDER,
BITS: bitLen(FP2_ORDER),
BYTES: Math.ceil(bitLen(FP2_ORDER) / 8),
MASK: bitMask(bitLen(FP2_ORDER)),
ZERO: { c0: Fp7.ZERO, c1: Fp7.ZERO },
ONE: { c0: Fp7.ONE, c1: Fp7.ZERO },
create: (num) => num,
isValid: ({ c0, c1 }) => typeof c0 === "bigint" && typeof c1 === "bigint",
is0: ({ c0, c1 }) => Fp7.is0(c0) && Fp7.is0(c1),
eql: ({ c0, c1 }, { c0: r0, c1: r1 }) => Fp7.eql(c0, r0) && Fp7.eql(c1, r1),
neg: ({ c0, c1 }) => ({ c0: Fp7.neg(c0), c1: Fp7.neg(c1) }),
pow: (num, power) => FpPow(Fp22, num, power),
invertBatch: (nums) => FpInvertBatch(Fp22, nums),
// Normalized
add: Fp2Add,
sub: Fp2Subtract,
mul: Fp2Multiply,
sqr: Fp2Square,
// NonNormalized stuff
addN: Fp2Add,
subN: Fp2Subtract,
mulN: Fp2Multiply,
sqrN: Fp2Square,
// Why inversion for bigint inside Fp instead of Fp2? it is even used in that context?
div: (lhs, rhs) =>
Fp22.mul(
lhs,
typeof rhs === "bigint" ? Fp7.inv(Fp7.create(rhs)) : Fp22.inv(rhs),
),
inv: ({ c0: a, c1: b }) => {
const factor = Fp7.inv(Fp7.create(a * a + b * b));
return {
c0: Fp7.mul(factor, Fp7.create(a)),
c1: Fp7.mul(factor, Fp7.create(-b)),
};
},
sqrt: (num) => {
if (Fp22.eql(num, Fp22.ZERO)) return Fp22.ZERO;
const candidateSqrt = Fp22.pow(num, (Fp22.ORDER + _8n3) / _16n2);
const check = Fp22.div(Fp22.sqr(candidateSqrt), num);
const R = FP2_ROOTS_OF_UNITY;
const divisor = [R[0], R[2], R[4], R[6]].find((r) => Fp22.eql(r, check));
if (!divisor) throw new Error("No root");
const index = R.indexOf(divisor);
const root = R[index / 2];
if (!root) throw new Error("Invalid root");
const x1 = Fp22.div(candidateSqrt, root);
const x2 = Fp22.neg(x1);
const { re: re1, im: im1 } = Fp22.reim(x1);
const { re: re2, im: im2 } = Fp22.reim(x2);
if (im1 > im2 || (im1 === im2 && re1 > re2)) return x1;
return x2;
},
// Same as sgn0_m_eq_2 in RFC 9380
isOdd: (x) => {
const { re: x0, im: x1 } = Fp22.reim(x);
const sign_0 = x0 % _2n10;
const zero_0 = x0 === _0n10;
const sign_1 = x1 % _2n10;
return BigInt(sign_0 || (zero_0 && sign_1)) == _1n11;
},
// Bytes util
fromBytes(b) {
if (b.length !== Fp22.BYTES)
throw new Error(`fromBytes wrong length=${b.length}`);
return {
c0: Fp7.fromBytes(b.subarray(0, Fp7.BYTES)),
c1: Fp7.fromBytes(b.subarray(Fp7.BYTES)),
};
},
toBytes: ({ c0, c1 }) => concatBytes(Fp7.toBytes(c0), Fp7.toBytes(c1)),
cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
c0: Fp7.cmov(c0, r0, c),
c1: Fp7.cmov(c1, r1, c),
}),
// Specific utils
// toString() {
// return `Fp2(${this.c0} + ${this.c1}×i)`;
// }
reim: ({ c0, c1 }) => ({ re: c0, im: c1 }),
// multiply by u + 1
mulByNonresidue: ({ c0, c1 }) => ({
c0: Fp7.sub(c0, c1),
c1: Fp7.add(c0, c1),
}),
multiplyByB: ({ c0, c1 }) => {
let t0 = Fp7.mul(c0, _4n4);
let t1 = Fp7.mul(c1, _4n4);
return { c0: Fp7.sub(t0, t1), c1: Fp7.add(t0, t1) };
},
fromBigTuple: (tuple) => {
if (tuple.length !== 2) throw new Error("Invalid tuple");
const fps = tuple.map((n) => Fp7.create(n));
return { c0: fps[0], c1: fps[1] };
},
frobeniusMap: ({ c0, c1 }, power) => ({
c0,
c1: Fp7.mul(c1, FP2_FROBENIUS_COEFFICIENTS[power % 2]),
}),
};
var FP2_FROBENIUS_COEFFICIENTS = [
BigInt("0x1"),
BigInt(
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
),
].map((item) => Fp7.create(item));
var rv1 = BigInt(
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09",
);
var FP2_ROOTS_OF_UNITY = [
[_1n11, _0n10],
[rv1, -rv1],
[_0n10, _1n11],
[rv1, rv1],
[-_1n11, _0n10],
[-rv1, rv1],
[_0n10, -_1n11],
[-rv1, -rv1],
].map((pair) => Fp22.fromBigTuple(pair));
var Fp6Add = ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => ({
c0: Fp22.add(c0, r0),
c1: Fp22.add(c1, r1),
c2: Fp22.add(c2, r2),
});
var Fp6Subtract = ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) => ({
c0: Fp22.sub(c0, r0),
c1: Fp22.sub(c1, r1),
c2: Fp22.sub(c2, r2),
});
var Fp6Multiply = ({ c0, c1, c2 }, rhs) => {
if (typeof rhs === "bigint") {
return {
c0: Fp22.mul(c0, rhs),
c1: Fp22.mul(c1, rhs),
c2: Fp22.mul(c2, rhs),
};
}
const { c0: r0, c1: r1, c2: r2 } = rhs;
const t0 = Fp22.mul(c0, r0);
const t1 = Fp22.mul(c1, r1);
const t2 = Fp22.mul(c2, r2);
return {
// t0 + (c1 + c2) * (r1 * r2) - (T1 + T2) * (u + 1)
c0: Fp22.add(
t0,
Fp22.mulByNonresidue(
Fp22.sub(
Fp22.mul(Fp22.add(c1, c2), Fp22.add(r1, r2)),
Fp22.add(t1, t2),
),
),
),
// (c0 + c1) * (r0 + r1) - (T0 + T1) + T2 * (u + 1)
c1: Fp22.add(
Fp22.sub(
Fp22.mul(Fp22.add(c0, c1), Fp22.add(r0, r1)),
Fp22.add(t0, t1),
),
Fp22.mulByNonresidue(t2),
),
// T1 + (c0 + c2) * (r0 + r2) - T0 + T2
c2: Fp22.sub(
Fp22.add(t1, Fp22.mul(Fp22.add(c0, c2), Fp22.add(r0, r2))),
Fp22.add(t0, t2),
),
};
};
var Fp6Square = ({ c0, c1, c2 }) => {
let t0 = Fp22.sqr(c0);
let t1 = Fp22.mul(Fp22.mul(c0, c1), _2n10);
let t3 = Fp22.mul(Fp22.mul(c1, c2), _2n10);
let t4 = Fp22.sqr(c2);
return {
c0: Fp22.add(Fp22.mulByNonresidue(t3), t0),
c1: Fp22.add(Fp22.mulByNonresidue(t4), t1),
// T1 + (c0 - c1 + c2)² + T3 - T0 - T4
c2: Fp22.sub(
Fp22.sub(
Fp22.add(Fp22.add(t1, Fp22.sqr(Fp22.add(Fp22.sub(c0, c1), c2))), t3),
t0,
),
t4,
),
};
};
var Fp62 = {
ORDER: Fp22.ORDER,
BITS: 3 * Fp22.BITS,
BYTES: 3 * Fp22.BYTES,
MASK: bitMask(3 * Fp22.BITS),
ZERO: { c0: Fp22.ZERO, c1: Fp22.ZERO, c2: Fp22.ZERO },
ONE: { c0: Fp22.ONE, c1: Fp22.ZERO, c2: Fp22.ZERO },
create: (num) => num,
isValid: ({ c0, c1, c2 }) =>
Fp22.isValid(c0) && Fp22.isValid(c1) && Fp22.isValid(c2),
is0: ({ c0, c1, c2 }) => Fp22.is0(c0) && Fp22.is0(c1) && Fp22.is0(c2),
neg: ({ c0, c1, c2 }) => ({
c0: Fp22.neg(c0),
c1: Fp22.neg(c1),
c2: Fp22.neg(c2),
}),
eql: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }) =>
Fp22.eql(c0, r0) && Fp22.eql(c1, r1) && Fp22.eql(c2, r2),
sqrt: () => {
throw new Error("Not implemented");
},
// Do we need division by bigint at all? Should be done via order:
div: (lhs, rhs) =>
Fp62.mul(
lhs,
typeof rhs === "bigint" ? Fp7.inv(Fp7.create(rhs)) : Fp62.inv(rhs),
),
pow: (num, power) => FpPow(Fp62, num, power),
invertBatch: (nums) => FpInvertBatch(Fp62, nums),
// Normalized
add: Fp6Add,
sub: Fp6Subtract,
mul: Fp6Multiply,
sqr: Fp6Square,
// NonNormalized stuff
addN: Fp6Add,
subN: Fp6Subtract,
mulN: Fp6Multiply,
sqrN: Fp6Square,
inv: ({ c0, c1, c2 }) => {
let t0 = Fp22.sub(Fp22.sqr(c0), Fp22.mulByNonresidue(Fp22.mul(c2, c1)));
let t1 = Fp22.sub(Fp22.mulByNonresidue(Fp22.sqr(c2)), Fp22.mul(c0, c1));
let t2 = Fp22.sub(Fp22.sqr(c1), Fp22.mul(c0, c2));
let t4 = Fp22.inv(
Fp22.add(
Fp22.mulByNonresidue(Fp22.add(Fp22.mul(c2, t1), Fp22.mul(c1, t2))),
Fp22.mul(c0, t0),
),
);
return {
c0: Fp22.mul(t4, t0),
c1: Fp22.mul(t4, t1),
c2: Fp22.mul(t4, t2),
};
},
// Bytes utils
fromBytes: (b) => {
if (b.length !== Fp62.BYTES)
throw new Error(`fromBytes wrong length=${b.length}`);
return {
c0: Fp22.fromBytes(b.subarray(0, Fp22.BYTES)),
c1: Fp22.fromBytes(b.subarray(Fp22.BYTES, 2 * Fp22.BYTES)),
c2: Fp22.fromBytes(b.subarray(2 * Fp22.BYTES)),
};
},
toBytes: ({ c0, c1, c2 }) =>
concatBytes(Fp22.toBytes(c0), Fp22.toBytes(c1), Fp22.toBytes(c2)),
cmov: ({ c0, c1, c2 }, { c0: r0, c1: r1, c2: r2 }, c) => ({
c0: Fp22.cmov(c0, r0, c),
c1: Fp22.cmov(c1, r1, c),
c2: Fp22.cmov(c2, r2, c),
}),
// Utils
// fromTriple(triple: [Fp2, Fp2, Fp2]) {
// return new Fp6(...triple);
// }
// toString() {
// return `Fp6(${this.c0} + ${this.c1} * v, ${this.c2} * v^2)`;
// }
fromBigSix: (t) => {
if (!Array.isArray(t) || t.length !== 6)
throw new Error("Invalid Fp6 usage");
return {
c0: Fp22.fromBigTuple(t.slice(0, 2)),
c1: Fp22.fromBigTuple(t.slice(2, 4)),
c2: Fp22.fromBigTuple(t.slice(4, 6)),
};
},
frobeniusMap: ({ c0, c1, c2 }, power) => ({
c0: Fp22.frobeniusMap(c0, power),
c1: Fp22.mul(
Fp22.frobeniusMap(c1, power),
FP6_FROBENIUS_COEFFICIENTS_1[power % 6],
),
c2: Fp22.mul(
Fp22.frobeniusMap(c2, power),
FP6_FROBENIUS_COEFFICIENTS_2[power % 6],
),
}),
mulByNonresidue: ({ c0, c1, c2 }) => ({
c0: Fp22.mulByNonresidue(c2),
c1: c0,
c2: c1,
}),
// Sparse multiplication
multiplyBy1: ({ c0, c1, c2 }, b1) => ({
c0: Fp22.mulByNonresidue(Fp22.mul(c2, b1)),
c1: Fp22.mul(c0, b1),
c2: Fp22.mul(c1, b1),
}),
// Sparse multiplication
multiplyBy01({ c0, c1, c2 }, b0, b1) {
let t0 = Fp22.mul(c0, b0);
let t1 = Fp22.mul(c1, b1);
return {
// ((c1 + c2) * b1 - T1) * (u + 1) + T0
c0: Fp22.add(
Fp22.mulByNonresidue(Fp22.sub(Fp22.mul(Fp22.add(c1, c2), b1), t1)),
t0,
),
// (b0 + b1) * (c0 + c1) - T0 - T1
c1: Fp22.sub(
Fp22.sub(Fp22.mul(Fp22.add(b0, b1), Fp22.add(c0, c1)), t0),
t1,
),
// (c0 + c2) * b0 - T0 + T1
c2: Fp22.add(Fp22.sub(Fp22.mul(Fp22.add(c0, c2), b0), t0), t1),
};
},
multiplyByFp2: ({ c0, c1, c2 }, rhs) => ({
c0: Fp22.mul(c0, rhs),
c1: Fp22.mul(c1, rhs),
c2: Fp22.mul(c2, rhs),
}),
};
var FP6_FROBENIUS_COEFFICIENTS_1 = [
[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((pair) => Fp22.fromBigTuple(pair));
var FP6_FROBENIUS_COEFFICIENTS_2 = [
[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((pair) => Fp22.fromBigTuple(pair));
var BLS_X = BigInt("0xd201000000010000");
var BLS_X_LEN = bitLen(BLS_X);
var Fp12Add = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
c0: Fp62.add(c0, r0),
c1: Fp62.add(c1, r1),
});
var Fp12Subtract = ({ c0, c1 }, { c0: r0, c1: r1 }) => ({
c0: Fp62.sub(c0, r0),
c1: Fp62.sub(c1, r1),
});
var Fp12Multiply = ({ c0, c1 }, rhs) => {
if (typeof rhs === "bigint")
return { c0: Fp62.mul(c0, rhs), c1: Fp62.mul(c1, rhs) };
let { c0: r0, c1: r1 } = rhs;
let t1 = Fp62.mul(c0, r0);
let t2 = Fp62.mul(c1, r1);
return {
c0: Fp62.add(t1, Fp62.mulByNonresidue(t2)),
// (c0 + c1) * (r0 + r1) - (T1 + T2)
c1: Fp62.sub(
Fp62.mul(Fp62.add(c0, c1), Fp62.add(r0, r1)),
Fp62.add(t1, t2),
),
};
};
var Fp12Square = ({ c0, c1 }) => {
let ab = Fp62.mul(c0, c1);
return {
// (c1 * v + c0) * (c0 + c1) - AB - AB * v
c0: Fp62.sub(
Fp62.sub(
Fp62.mul(Fp62.add(Fp62.mulByNonresidue(c1), c0), Fp62.add(c0, c1)),
ab,
),
Fp62.mulByNonresidue(ab),
),
c1: Fp62.add(ab, ab),
};
};
function Fp4Square(a, b) {
const a2 = Fp22.sqr(a);
const b2 = Fp22.sqr(b);
return {
first: Fp22.add(Fp22.mulByNonresidue(b2), a2),
second: Fp22.sub(Fp22.sub(Fp22.sqr(Fp22.add(a, b)), a2), b2),
// (a + b)² - a² - b²
};
}
var Fp12 = {
ORDER: Fp22.ORDER,
BITS: 2 * Fp22.BITS,
BYTES: 2 * Fp22.BYTES,
MASK: bitMask(2 * Fp22.BITS),
ZERO: { c0: Fp62.ZERO, c1: Fp62.ZERO },
ONE: { c0: Fp62.ONE, c1: Fp62.ZERO },
create: (num) => num,
isValid: ({ c0, c1 }) => Fp62.isValid(c0) && Fp62.isValid(c1),
is0: ({ c0, c1 }) => Fp62.is0(c0) && Fp62.is0(c1),
neg: ({ c0, c1 }) => ({ c0: Fp62.neg(c0), c1: Fp62.neg(c1) }),
eql: ({ c0, c1 }, { c0: r0, c1: r1 }) =>
Fp62.eql(c0, r0) && Fp62.eql(c1, r1),
sqrt: () => {
throw new Error("Not implemented");
},
inv: ({ c0, c1 }) => {
let t = Fp62.inv(
Fp62.sub(Fp62.sqr(c0), Fp62.mulByNonresidue(Fp62.sqr(c1))),
);
return { c0: Fp62.mul(c0, t), c1: Fp62.neg(Fp62.mul(c1, t)) };
},
div: (lhs, rhs) =>
Fp12.mul(
lhs,
typeof rhs === "bigint" ? Fp7.inv(Fp7.create(rhs)) : Fp12.inv(rhs),
),
pow: (num, power) => FpPow(Fp12, num, power),
invertBatch: (nums) => FpInvertBatch(Fp12, nums),
// Normalized
add: Fp12Add,
sub: Fp12Subtract,
mul: Fp12Multiply,
sqr: Fp12Square,
// NonNormalized stuff
addN: Fp12Add,
subN: Fp12Subtract,
mulN: Fp12Multiply,
sqrN: Fp12Square,
// Bytes utils
fromBytes: (b) => {
if (b.length !== Fp12.BYTES)
throw new Error(`fromBytes wrong length=${b.length}`);
return {
c0: Fp62.fromBytes(b.subarray(0, Fp62.BYTES)),
c1: Fp62.fromBytes(b.subarray(Fp62.BYTES)),
};
},
toBytes: ({ c0, c1 }) => concatBytes(Fp62.toBytes(c0), Fp62.toBytes(c1)),
cmov: ({ c0, c1 }, { c0: r0, c1: r1 }, c) => ({
c0: Fp62.cmov(c0, r0, c),
c1: Fp62.cmov(c1, r1, c),
}),
// Utils
// toString() {
// return `Fp12(${this.c0} + ${this.c1} * w)`;
// },
// fromTuple(c: [Fp6, Fp6]) {
// return new Fp12(...c);
// }
fromBigTwelve: (t) => ({
c0: Fp62.fromBigSix(t.slice(0, 6)),
c1: Fp62.fromBigSix(t.slice(6, 12)),
}),
// Raises to q**i -th power
frobeniusMap(lhs, power) {
const r0 = Fp62.frobeniusMap(lhs.c0, power);
const { c0, c1, c2 } = Fp62.frobeniusMap(lhs.c1, power);
const coeff = FP12_FROBENIUS_COEFFICIENTS[power % 12];
return {
c0: r0,
c1: Fp62.create({
c0: Fp22.mul(c0, coeff),
c1: Fp22.mul(c1, coeff),
c2: Fp22.mul(c2, coeff),
}),
};
},
// Sparse multiplication
multiplyBy014: ({ c0, c1 }, o0, o1, o4) => {
let t0 = Fp62.multiplyBy01(c0, o0, o1);
let t1 = Fp62.multiplyBy1(c1, o4);
return {
c0: Fp62.add(Fp62.mulByNonresidue(t1), t0),
// (c1 + c0) * [o0, o1+o4] - T0 - T1
c1: Fp62.sub(
Fp62.sub(
Fp62.multiplyBy01(Fp62.add(c1, c0), o0, Fp22.add(o1, o4)),
t0,
),
t1,
),
};
},
multiplyByFp2: ({ c0, c1 }, rhs) => ({
c0: Fp62.multiplyByFp2(c0, rhs),
c1: Fp62.multiplyByFp2(c1, rhs),
}),
conjugate: ({ c0, c1 }) => ({ c0, c1: Fp62.neg(c1) }),
// A cyclotomic group is a subgroup of Fp^n defined by
// GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
// The result of any pairing is in a cyclotomic subgroup
// https://eprint.iacr.org/2009/565.pdf
_cyclotomicSquare: ({ c0, c1 }) => {
const { c0: c0c0, c1: c0c1, c2: c0c2 } = c0;
const { c0: c1c0, c1: c1c1, c2: c1c2 } = c1;
const { first: t3, second: t4 } = Fp4Square(c0c0, c1c1);
const { first: t5, second: t6 } = Fp4Square(c1c0, c0c2);
const { first: t7, second: t8 } = Fp4Square(c0c1, c1c2);
let t9 = Fp22.mulByNonresidue(t8);
return {
c0: Fp62.create({
c0: Fp22.add(Fp22.mul(Fp22.sub(t3, c0c0), _2n10), t3),
c1: Fp22.add(Fp22.mul(Fp22.sub(t5, c0c1), _2n10), t5),
c2: Fp22.add(Fp22.mul(Fp22.sub(t7, c0c2), _2n10), t7),
}),
c1: Fp62.create({
c0: Fp22.add(Fp22.mul(Fp22.add(t9, c1c0), _2n10), t9),
c1: Fp22.add(Fp22.mul(Fp22.add(t4, c1c1), _2n10), t4),
c2: Fp22.add(Fp22.mul(Fp22.add(t6, c1c2), _2n10), t6),
}),
};
},
_cyclotomicExp(num, n) {
let z = Fp12.ONE;
for (let i = BLS_X_LEN - 1; i >= 0; i--) {
z = Fp12._cyclotomicSquare(z);
if (bitGet(n, i)) z = Fp12.mul(z, num);
}
return z;
},
// https://eprint.iacr.org/2010/354.pdf
// https://eprint.iacr.org/2009/565.pdf
finalExponentiate: (num) => {
const x = BLS_X;
const t0 = Fp12.div(Fp12.frobeniusMap(num, 6), num);
const t1 = Fp12.mul(Fp12.frobeniusMap(t0, 2), t0);
const t2 = Fp12.conjugate(Fp12._cyclotomicExp(t1, x));
const t3 = Fp12.mul(Fp12.conjugate(Fp12._cyclotomicSquare(t1)), t2);
const t4 = Fp12.conjugate(Fp12._cyclotomicExp(t3, x));
const t5 = Fp12.conjugate(Fp12._cyclotomicExp(t4, x));
const t6 = Fp12.mul(
Fp12.conjugate(Fp12._cyclotomicExp(t5, x)),
Fp12._cyclotomicSquare(t2),
);
const t7 = Fp12.conjugate(Fp12._cyclotomicExp(t6, x));
const t2_t5_pow_q2 = Fp12.frobeniusMap(Fp12.mul(t2, t5), 2);
const t4_t1_pow_q3 = Fp12.frobeniusMap(Fp12.mul(t4, t1), 3);
const t6_t1c_pow_q1 = Fp12.frobeniusMap(
Fp12.mul(t6, Fp12.conjugate(t1)),
1,
);
const t7_t3c_t1 = Fp12.mul(Fp12.mul(t7, Fp12.conjugate(t3)), t1);
return Fp12.mul(
Fp12.mul(Fp12.mul(t2_t5_pow_q2, t4_t1_pow_q3), t6_t1c_pow_q1),
t7_t3c_t1,
);
},
};
var FP12_FROBENIUS_COEFFICIENTS = [
[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((n) => Fp22.fromBigTuple(n));
var isogenyMapG2 = isogenyMap(
Fp22,
[
// xNum
[
[
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6",
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6",
],
[
"0x0",
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71a",
],
[
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71e",
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38d",
],
[
"0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1",
"0x0",
],
],
// xDen
[
[
"0x0",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63",
],
[
"0xc",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9f",
],
["0x1", "0x0"],
// LAST 1
],
// yNum
[
[
"0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706",
"0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706",
],
[
"0x0",
"0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97be",
],
[
"0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71c",
"0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38f",
],
[
"0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10",
"0x0",
],
],
// yDen
[
[
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fb",
],
[
"0x0",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3",
],
[
"0x12",
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99",
],
["0x1", "0x0"],
// LAST 1
],
].map((i) => i.map((pair) => Fp22.fromBigTuple(pair.map(BigInt)))),
);
var isogenyMapG1 = isogenyMap(
Fp7,
[
// xNum
[
"0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7",
"0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bb",
"0xd54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0",
"0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861",
"0xe99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9",
"0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983",
"0xd6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84",
"0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88e",
"0x80d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317",
"0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9e",
"0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7b",
"0x6e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229",
],
// xDen
[
"0x8ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1c",
"0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bff",
"0xb2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19",
"0x3425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8",
"0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21e",
"0xe7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5",
"0x772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3a",
"0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5e",
"0xa10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641",
"0x95fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0a",
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
// LAST 1
],
// yNum
[
"0x90d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33",
"0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696",
"0xcc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6",
"0x1f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cb",
"0x8cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedb",
"0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0",
"0x4ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2",
"0x987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29",
"0x9fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587",
"0xe1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30",
"0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132",
"0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8e",
"0xb182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8",
"0x245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133",
"0x5c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224b",
"0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604",
],
// yDen
[
"0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1",
"0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03d",
"0x58df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2",
"0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416",
"0xbe0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001d",
"0x8d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7ac",
"0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775c",
"0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9",
"0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4a",
"0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55",
"0x4d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8",
"0xaccbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092",
"0xad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345cc",
"0x2660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7",
"0xe0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8f",
"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001",
// LAST 1
],
].map((i) => i.map((j) => BigInt(j))),
);
var G2_SWU = mapToCurveSimpleSWU(Fp22, {
A: Fp22.create({ c0: Fp7.create(_0n10), c1: Fp7.create(BigInt(240)) }),
B: Fp22.create({
c0: Fp7.create(BigInt(1012)),
c1: Fp7.create(BigInt(1012)),
}),
Z: Fp22.create({ c0: Fp7.create(BigInt(-2)), c1: Fp7.create(BigInt(-1)) }),
// Z: -(2 + I)
});
var G1_SWU = mapToCurveSimpleSWU(Fp7, {
A: Fp7.create(
BigInt(
"0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1d",
),
),
B: Fp7.create(
BigInt(
"0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0",
),
),
Z: Fp7.create(BigInt(11)),
});
var ut_root = Fp62.create({ c0: Fp22.ZERO, c1: Fp22.ONE, c2: Fp22.ZERO });
var wsq = Fp12.create({ c0: ut_root, c1: Fp62.ZERO });
var wcu = Fp12.create({ c0: Fp62.ZERO, c1: ut_root });
var [wsq_inv, wcu_inv] = Fp12.invertBatch([wsq, wcu]);
function psi(x, y) {
const x2 = Fp12.mul(
Fp12.frobeniusMap(Fp12.multiplyByFp2(wsq_inv, x), 1),
wsq,
).c0.c0;
const y2 = Fp12.mul(
Fp12.frobeniusMap(Fp12.multiplyByFp2(wcu_inv, y), 1),
wcu,
).c0.c0;
return [x2, y2];
}
function G2psi(c, P3) {
const affine = P3.toAffine();
const p = psi(affine.x, affine.y);
return new c(p[0], p[1], Fp22.ONE);
}
var PSI2_C1 = BigInt(
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac",
);
function psi2(x, y) {
return [Fp22.mul(x, PSI2_C1), Fp22.neg(y)];
}
function G2psi2(c, P3) {
const affine = P3.toAffine();
const p = psi2(affine.x, affine.y);
return new c(p[0], p[1], Fp22.ONE);
}
var htfDefaults = Object.freeze({
// DST: a domain separation tag
// defined in section 2.2.5
// Use utils.getDSTLabel(), utils.setDSTLabel(value)
DST: "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_",
encodeDST: "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_",
// p: the characteristic of F
// where F is a finite field of characteristic p and order q = p^m
p: Fp7.ORDER,
// m: the extension degree of F, m >= 1
// where F is a finite field of characteristic p and order q = p^m
m: 2,
// k: the target security level for the suite in bits
// defined in section 5.1
k: 128,
// option to use a message that has already been processed by
// expand_message_xmd
expand: "xmd",
// Hash functions for: expand_message_xmd is appropriate for use with a
// wide range of hash functions, including SHA-2, SHA-3, BLAKE2, and others.
// BBS+ uses blake2: https://github.com/hyperledger/aries-framework-go/issues/2247
hash: sha256,
});
var C_BIT_POS = Fp7.BITS;
var I_BIT_POS = Fp7.BITS + 1;
var S_BIT_POS = Fp7.BITS + 2;
var COMPRESSED_ZERO = Fp7.toBytes(
bitSet(bitSet(_0n10, I_BIT_POS, true), S_BIT_POS, true),
);
function signatureG2ToRawBytes(point) {
point.assertValidity();
const len = Fp7.BYTES;
if (point.equals(bls12_381.G2.ProjectivePoint.ZERO))
return concatBytes(COMPRESSED_ZERO, numberToBytesBE(_0n10, len));
const { x, y } = point.toAffine();
const { re: x0, im: x1 } = Fp22.reim(x);
const { re: y0, im: y1 } = Fp22.reim(y);
const tmp = y1 > _0n10 ? y1 * _2n10 : y0 * _2n10;
const aflag1 = Boolean((tmp / Fp7.ORDER) & _1n11);
const z1 = bitSet(bitSet(x1, 381, aflag1), S_BIT_POS, true);
const z2 = x0;
return concatBytes(numberToBytesBE(z1, len), numberToBytesBE(z2, len));
}
var bls12_381 = bls({
// Fields
fields: {
Fp: Fp7,
Fp2: Fp22,
Fp6: Fp62,
Fp12,
Fr,
},
// G1 is the order-q subgroup of E1(Fp) : y² = x³ + 4, #E1(Fp) = h1q, where
// characteristic; z + (z⁴ - z² + 1)(z - 1)²/3
G1: {
Fp: Fp7,
// cofactor; (z - 1)²/3
h: BigInt("0x396c8c005555e1568c00aaab0000aaab"),
// generator's coordinates
// x = 3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507
// y = 1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569
Gx: BigInt(
"0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb",
),
Gy: BigInt(
"0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1",
),
a: Fp7.ZERO,
b: _4n4,
htfDefaults: { ...htfDefaults, m: 1 },
wrapPrivateKey: true,
allowInfinityPoint: true,
// Checks is the point resides in prime-order subgroup.
// point.isTorsionFree() should return true for valid points
// It returns false for shitty points.
// https://eprint.iacr.org/2021/1130.pdf
isTorsionFree: (c, point) => {
const cubicRootOfUnityModP = BigInt(
"0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe",
);
const phi = new c(
Fp7.mul(point.px, cubicRootOfUnityModP),
point.py,
point.pz,
);
const xP = point.multiplyUnsafe(bls12_381.params.x).negate();
const u2P = xP.multiplyUnsafe(bls12_381.params.x);
return u2P.equals(phi);
},
// Clear cofactor of G1
// https://eprint.iacr.org/2019/403
clearCofactor: (_c, point) => {
return point.multiplyUnsafe(bls12_381.params.x).add(point);
},
mapToCurve: (scalars) => {
const { x, y } = G1_SWU(Fp7.create(scalars[0]));
return isogenyMapG1(x, y);
},
fromBytes: (bytes2) => {
bytes2 = bytes2.slice();
if (bytes2.length === 48) {
const P3 = Fp7.ORDER;
const compressedValue = bytesToNumberBE(bytes2);
const bflag = bitGet(compressedValue, I_BIT_POS);
if (bflag === _1n11) return { x: _0n10, y: _0n10 };
const x = Fp7.create(compressedValue & Fp7.MASK);
const right = Fp7.add(
Fp7.pow(x, _3n5),
Fp7.create(bls12_381.params.G1b),
);
let y = Fp7.sqrt(right);
if (!y) throw new Error("Invalid compressed G1 point");
const aflag = bitGet(compressedValue, C_BIT_POS);
if ((y * _2n10) / P3 !== aflag) y = Fp7.neg(y);
return { x: Fp7.create(x), y: Fp7.create(y) };
} else if (bytes2.length === 96) {
if ((bytes2[0] & (1 << 6)) !== 0)
return bls12_381.G1.ProjectivePoint.ZERO.toAffine();
const x = bytesToNumberBE(bytes2.subarray(0, Fp7.BYTES));
const y = bytesToNumberBE(bytes2.subarray(Fp7.BYTES));
return { x: Fp7.create(x), y: Fp7.create(y) };
} else {
throw new Error("Invalid point G1, expected 48/96 bytes");
}
},
toBytes: (c, point, isCompressed) => {
const isZero = point.equals(c.ZERO);
const { x, y } = point.toAffine();
if (isCompressed) {
if (isZero) return COMPRESSED_ZERO.slice();
const P3 = Fp7.ORDER;
let num;
num = bitSet(x, C_BIT_POS, Boolean((y * _2n10) / P3));
num = bitSet(num, S_BIT_POS, true);
return numberToBytesBE(num, Fp7.BYTES);
} else {
if (isZero) {
const x2 = concatBytes(
new Uint8Array([64]),
new Uint8Array(2 * Fp7.BYTES - 1),
);
return x2;
} else {
return concatBytes(
numberToBytesBE(x, Fp7.BYTES),
numberToBytesBE(y, Fp7.BYTES),
);
}
}
},
},
// G2 is the order-q subgroup of E2(Fp²) : y² = x³+4(1+√1),
// where Fp2 is Fp[√1]/(x2+1). #E2(Fp2 ) = h2q, where
// G² - 1
// h2q
G2: {
Fp: Fp22,
// cofactor
h: BigInt(
"0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5",
),
Gx: Fp22.fromBigTuple([
BigInt(
"0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8",
),
BigInt(
"0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e",
),
]),
// y =
// 927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582,
// 1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905
Gy: Fp22.fromBigTuple([
BigInt(
"0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801",
),
BigInt(
"0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be",
),
]),
a: Fp22.ZERO,
b: Fp22.fromBigTuple([_4n4, _4n4]),
hEff: BigInt(
"0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551",
),
htfDefaults: { ...htfDefaults },
wrapPrivateKey: true,
allowInfinityPoint: true,
mapToCurve: (scalars) => {
const { x, y } = G2_SWU(Fp22.fromBigTuple(scalars));
return isogenyMapG2(x, y);
},
// Checks is the point resides in prime-order subgroup.
// point.isTorsionFree() should return true for valid points
// It returns false for shitty points.
// https://eprint.iacr.org/2021/1130.pdf
isTorsionFree: (c, P3) => {
return P3.multiplyUnsafe(bls12_381.params.x)
.negate()
.equals(G2psi(c, P3));
},
// Maps the point into the prime-order subgroup G2.
// clear_cofactor_bls12381_g2 from cfrg-hash-to-curve-11
// https://eprint.iacr.org/2017/419.pdf
// prettier-ignore
clearCofactor: (c, P3) => {
const x = bls12_381.params.x;
let t1 = P3.multiplyUnsafe(x).negate();
let t2 = G2psi(c, P3);
let t3 = P3.double();
t3 = G2psi2(c, t3);
t3 = t3.subtract(t2);
t2 = t1.add(t2);
t2 = t2.multiplyUnsafe(x).negate();
t3 = t3.add(t2);
t3 = t3.subtract(t1);
const Q = t3.subtract(P3);
return Q;
},
fromBytes: (bytes2) => {
bytes2 = bytes2.slice();
const m_byte = bytes2[0] & 224;
if (m_byte === 32 || m_byte === 96 || m_byte === 224) {
throw new Error("Invalid encoding flag: " + m_byte);
}
const bitC = m_byte & 128;
const bitI = m_byte & 64;
const bitS = m_byte & 32;
const L = Fp7.BYTES;
const slc = (b, from, to) => bytesToNumberBE(b.slice(from, to));
if (bytes2.length === 96 && bitC) {
const b = bls12_381.params.G2b;
const P3 = Fp7.ORDER;
bytes2[0] = bytes2[0] & 31;
if (bitI) {
if (bytes2.reduce((p, c) => (p !== 0 ? c + 1 : c), 0) > 0) {
throw new Error("Invalid compressed G2 point");
}
return { x: Fp22.ZERO, y: Fp22.ZERO };
}
const x_1 = slc(bytes2, 0, L);
const x_0 = slc(bytes2, L, 2 * L);
const x = Fp22.create({ c0: Fp7.create(x_0), c1: Fp7.create(x_1) });
const right = Fp22.add(Fp22.pow(x, _3n5), b);
let y = Fp22.sqrt(right);
const Y_bit =
y.c1 === _0n10
? (y.c0 * _2n10) / P3
: (y.c1 * _2n10) / P3
? _1n11
: _0n10;
y = bitS > 0 && Y_bit > 0 ? y : Fp22.neg(y);
return { x, y };
} else if (bytes2.length === 192 && !bitC) {
if ((bytes2[0] & (1 << 6)) !== 0) {
return { x: Fp22.ZERO, y: Fp22.ZERO };
}
const x1 = slc(bytes2, 0, L);
const x0 = slc(bytes2, L, 2 * L);
const y1 = slc(bytes2, 2 * L, 3 * L);
const y0 = slc(bytes2, 3 * L, 4 * L);
return {
x: Fp22.fromBigTuple([x0, x1]),
y: Fp22.fromBigTuple([y0, y1]),
};
} else {
throw new Error("Invalid point G2, expected 96/192 bytes");
}
},
toBytes: (c, point, isCompressed) => {
const { BYTES: len, ORDER: P3 } = Fp7;
const isZero = point.equals(c.ZERO);
const { x, y } = point.toAffine();
if (isCompressed) {
if (isZero)
return concatBytes(COMPRESSED_ZERO, numberToBytesBE(_0n10, len));
const flag = Boolean(
y.c1 === _0n10 ? (y.c0 * _2n10) / P3 : (y.c1 * _2n10) / P3,
);
let x_1 = bitSet(x.c1, C_BIT_POS, flag);
x_1 = bitSet(x_1, S_BIT_POS, true);
return concatBytes(
numberToBytesBE(x_1, len),
numberToBytesBE(x.c0, len),
);
} else {
if (isZero)
return concatBytes(
new Uint8Array([64]),
new Uint8Array(4 * len - 1),
);
const { re: x0, im: x1 } = Fp22.reim(x);
const { re: y0, im: y1 } = Fp22.reim(y);
return concatBytes(
numberToBytesBE(x1, len),
numberToBytesBE(x0, len),
numberToBytesBE(y1, len),
numberToBytesBE(y0, len),
);
}
},
Signature: {
// TODO: Optimize, it's very slow because of sqrt.
fromHex(hex) {
hex = ensureBytes("signatureHex", hex);
const P3 = Fp7.ORDER;
const half = hex.length / 2;
if (half !== 48 && half !== 96)
throw new Error(
"Invalid compressed signature length, must be 96 or 192",
);
const z1 = bytesToNumberBE(hex.slice(0, half));
const z2 = bytesToNumberBE(hex.slice(half));
const bflag1 = bitGet(z1, I_BIT_POS);
if (bflag1 === _1n11) return bls12_381.G2.ProjectivePoint.ZERO;
const x1 = Fp7.create(z1 & Fp7.MASK);
const x2 = Fp7.create(z2);
const x = Fp22.create({ c0: x2, c1: x1 });
const y2 = Fp22.add(Fp22.pow(x, _3n5), bls12_381.params.G2b);
let y = Fp22.sqrt(y2);
if (!y) throw new Error("Failed to find a square root");
const { re: y0, im: y1 } = Fp22.reim(y);
const aflag1 = bitGet(z1, 381);
const isGreater = y1 > _0n10 && (y1 * _2n10) / P3 !== aflag1;
const isZero = y1 === _0n10 && (y0 * _2n10) / P3 !== aflag1;
if (isGreater || isZero) y = Fp22.neg(y);
const point = bls12_381.G2.ProjectivePoint.fromAffine({ x, y });
point.assertValidity();
return point;
},
toRawBytes(point) {
return signatureG2ToRawBytes(point);
},
toHex(point) {
return bytesToHex(signatureG2ToRawBytes(point));
},
},
},
params: {
x: BLS_X,
r: Fr.ORDER,
// order; z⁴ z² + 1; CURVE.n from other curves
},
htfDefaults,
hash: sha256,
randomBytes,
});
// input.js
var utils = { bytesToHex, concatBytes, hexToBytes };
return __toCommonJS(input_exports);
})();
/*! noble-curves - MIT License (c) 2022 Paul Miller (paulmillr.com) */
/*! Bundled license information:
@noble/hashes/esm/utils.js:
(*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) *)
*/