blob: 2a0c163f33e860830cea101356ba187b4d419496 [file] [log] [blame]
// The MIT License (MIT)
// Copyright (c) 2019 Paul Miller (https://paulmillr.com)
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the “Software”), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
/*! noble-bls12-381 - MIT License (c) 2019 Paul Miller (paulmillr.com) */
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyBatch = exports.aggregateSignatures = exports.aggregatePublicKeys = exports.verify = exports.sign = exports.getPublicKey = exports.pairing = exports.PointG2 = exports.PointG1 = exports.utils = exports.CURVE = exports.Fp12 = exports.Fp2 = exports.Fr = exports.Fp = void 0;
const crypto_1 = __importDefault(require("crypto"));
const math_js_1 = require("./math.js");
Object.defineProperty(exports, "Fp", { enumerable: true, get: function () { return math_js_1.Fp; } });
Object.defineProperty(exports, "Fr", { enumerable: true, get: function () { return math_js_1.Fr; } });
Object.defineProperty(exports, "Fp2", { enumerable: true, get: function () { return math_js_1.Fp2; } });
Object.defineProperty(exports, "Fp12", { enumerable: true, get: function () { return math_js_1.Fp12; } });
Object.defineProperty(exports, "CURVE", { enumerable: true, get: function () { return math_js_1.CURVE; } });
const POW_2_381 = 2n ** 381n;
const POW_2_382 = POW_2_381 * 2n;
const POW_2_383 = POW_2_382 * 2n;
const PUBLIC_KEY_LENGTH = 48;
function wrapHash(outputLen, h) {
let tmp = h;
tmp.outputLen = outputLen;
return tmp;
}
const sha256 = wrapHash(32, async (message) => {
if (crypto.web) {
const buffer = await crypto.web.subtle.digest('SHA-256', message);
return new Uint8Array(buffer);
}
else if (crypto.node) {
return Uint8Array.from(crypto.node.createHash('sha256').update(message).digest());
}
else {
throw new Error("The environment doesn't have sha256 function");
}
});
const htfDefaults = {
DST: 'BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_',
p: math_js_1.CURVE.P,
m: 2,
k: 128,
expand: true,
hash: sha256,
};
function isWithinCurveOrder(num) {
return 0 < num && num < math_js_1.CURVE.r;
}
const crypto = {
node: undefined,
web: typeof self === 'object' && 'crypto' in self ? self.crypto : undefined,
};
exports.utils = {
hashToField: hash_to_field,
expandMessageXMD: expand_message_xmd,
hashToPrivateKey: (hash) => {
hash = ensureBytes(hash);
if (hash.length < 40 || hash.length > 1024)
throw new Error('Expected 40-1024 bytes of private key as per FIPS 186');
const num = (0, math_js_1.mod)((0, math_js_1.bytesToNumberBE)(hash), math_js_1.CURVE.r);
if (num === 0n || num === 1n)
throw new Error('Invalid private key');
return numberTo32BytesBE(num);
},
stringToBytes,
bytesToHex: math_js_1.bytesToHex,
hexToBytes: math_js_1.hexToBytes,
randomBytes: (bytesLength = 32) => {
if (crypto.web) {
return crypto.web.getRandomValues(new Uint8Array(bytesLength));
}
else if (crypto.node) {
const { randomBytes } = crypto.node;
return new Uint8Array(randomBytes(bytesLength).buffer);
}
else {
throw new Error("The environment doesn't have randomBytes function");
}
},
randomPrivateKey: () => {
return exports.utils.hashToPrivateKey(exports.utils.randomBytes(40));
},
sha256,
mod: math_js_1.mod,
getDSTLabel() {
return htfDefaults.DST;
},
setDSTLabel(newLabel) {
if (typeof newLabel !== 'string' || newLabel.length > 2048 || newLabel.length === 0) {
throw new TypeError('Invalid DST');
}
htfDefaults.DST = newLabel;
},
};
function numberTo32BytesBE(num) {
const length = 32;
const hex = num.toString(16).padStart(length * 2, '0');
return (0, math_js_1.hexToBytes)(hex);
}
function toPaddedHex(num, padding) {
if (typeof num !== 'bigint' || num < 0n)
throw new Error('Expected valid bigint');
if (typeof padding !== 'number')
throw new TypeError('Expected valid padding');
return num.toString(16).padStart(padding * 2, '0');
}
function ensureBytes(hex) {
return hex instanceof Uint8Array ? Uint8Array.from(hex) : (0, math_js_1.hexToBytes)(hex);
}
function stringToBytes(str) {
const bytes = new Uint8Array(str.length);
for (let i = 0; i < str.length; i++) {
bytes[i] = str.charCodeAt(i);
}
return bytes;
}
function os2ip(bytes) {
let result = 0n;
for (let i = 0; i < bytes.length; i++) {
result <<= 8n;
result += BigInt(bytes[i]);
}
return result;
}
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 & 0xff;
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;
}
async function expand_message_xmd(msg, DST, lenInBytes, H = exports.utils.sha256) {
if (DST.length > 255)
DST = await H((0, math_js_1.concatBytes)(stringToBytes('H2C-OVERSIZE-DST-'), DST));
const b_in_bytes = H.outputLen;
const r_in_bytes = b_in_bytes * 2;
const ell = Math.ceil(lenInBytes / b_in_bytes);
if (ell > 255)
throw new Error('Invalid xmd length');
const DST_prime = (0, math_js_1.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 = await H((0, math_js_1.concatBytes)(Z_pad, msg, l_i_b_str, i2osp(0, 1), DST_prime));
b[0] = await H((0, math_js_1.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] = await H((0, math_js_1.concatBytes)(...args));
}
const pseudo_random_bytes = (0, math_js_1.concatBytes)(...b);
return pseudo_random_bytes.slice(0, lenInBytes);
}
async function hash_to_field(msg, count, options = {}) {
const htfOptions = { ...htfDefaults, ...options };
const log2p = htfOptions.p.toString(2).length;
const L = Math.ceil((log2p + htfOptions.k) / 8);
const len_in_bytes = count * htfOptions.m * L;
const DST = stringToBytes(htfOptions.DST);
let pseudo_random_bytes = msg;
if (htfOptions.expand) {
pseudo_random_bytes = await expand_message_xmd(msg, DST, len_in_bytes, htfOptions.hash);
}
const u = new Array(count);
for (let i = 0; i < count; i++) {
const e = new Array(htfOptions.m);
for (let j = 0; j < htfOptions.m; j++) {
const elm_offset = L * (j + i * htfOptions.m);
const tv = pseudo_random_bytes.subarray(elm_offset, elm_offset + L);
e[j] = (0, math_js_1.mod)(os2ip(tv), htfOptions.p);
}
u[i] = e;
}
return u;
}
function normalizePrivKey(key) {
let int;
if (key instanceof Uint8Array && key.length === 32)
int = (0, math_js_1.bytesToNumberBE)(key);
else if (typeof key === 'string' && key.length === 64)
int = BigInt(`0x${key}`);
else if (typeof key === 'number' && key > 0 && Number.isSafeInteger(key))
int = BigInt(key);
else if (typeof key === 'bigint' && key > 0n)
int = key;
else
throw new TypeError('Expected valid private key');
int = (0, math_js_1.mod)(int, math_js_1.CURVE.r);
if (!isWithinCurveOrder(int))
throw new Error('Private key must be 0 < key < CURVE.r');
return int;
}
function assertType(item, type) {
if (!(item instanceof type))
throw new Error('Expected Fp* argument, not number/bigint');
}
class PointG1 extends math_js_1.ProjectivePoint {
constructor(x, y, z = math_js_1.Fp.ONE) {
super(x, y, z, math_js_1.Fp);
assertType(x, math_js_1.Fp);
assertType(y, math_js_1.Fp);
assertType(z, math_js_1.Fp);
}
static fromHex(bytes) {
bytes = ensureBytes(bytes);
let point;
if (bytes.length === 48) {
const { P } = math_js_1.CURVE;
const compressedValue = (0, math_js_1.bytesToNumberBE)(bytes);
const bflag = (0, math_js_1.mod)(compressedValue, POW_2_383) / POW_2_382;
if (bflag === 1n) {
return PointG1.ZERO;
}
const x = new math_js_1.Fp((0, math_js_1.mod)(compressedValue, POW_2_381));
const right = x.pow(3n).add(new math_js_1.Fp(math_js_1.CURVE.b));
let y = right.sqrt();
if (!y)
throw new Error('Invalid compressed G1 point');
const aflag = (0, math_js_1.mod)(compressedValue, POW_2_382) / POW_2_381;
if ((y.value * 2n) / P !== aflag)
y = y.negate();
point = new PointG1(x, y);
}
else if (bytes.length === 96) {
if ((bytes[0] & (1 << 6)) !== 0)
return PointG1.ZERO;
const x = (0, math_js_1.bytesToNumberBE)(bytes.slice(0, PUBLIC_KEY_LENGTH));
const y = (0, math_js_1.bytesToNumberBE)(bytes.slice(PUBLIC_KEY_LENGTH));
point = new PointG1(new math_js_1.Fp(x), new math_js_1.Fp(y));
}
else {
throw new Error('Invalid point G1, expected 48/96 bytes');
}
point.assertValidity();
return point;
}
static async hashToCurve(msg, options) {
msg = ensureBytes(msg);
const [[u0], [u1]] = await hash_to_field(msg, 2, { m: 1, ...options });
const [x0, y0] = (0, math_js_1.map_to_curve_simple_swu_3mod4)(new math_js_1.Fp(u0));
const [x1, y1] = (0, math_js_1.map_to_curve_simple_swu_3mod4)(new math_js_1.Fp(u1));
const [x2, y2] = new PointG1(x0, y0).add(new PointG1(x1, y1)).toAffine();
const [x3, y3] = (0, math_js_1.isogenyMapG1)(x2, y2);
return new PointG1(x3, y3).clearCofactor();
}
static async encodeToCurve(msg, options) {
msg = ensureBytes(msg);
const u = await hash_to_field(msg, 1, {
m: 1,
...options,
});
const [x0, y0] = (0, math_js_1.map_to_curve_simple_swu_3mod4)(new math_js_1.Fp(u[0][0]));
const [x1, y1] = (0, math_js_1.isogenyMapG1)(x0, y0);
return new PointG1(x1, y1).clearCofactor();
}
static fromPrivateKey(privateKey) {
return this.BASE.multiplyPrecomputed(normalizePrivKey(privateKey));
}
toRawBytes(isCompressed = false) {
return (0, math_js_1.hexToBytes)(this.toHex(isCompressed));
}
toHex(isCompressed = false) {
this.assertValidity();
if (isCompressed) {
const { P } = math_js_1.CURVE;
let hex;
if (this.isZero()) {
hex = POW_2_383 + POW_2_382;
}
else {
const [x, y] = this.toAffine();
const flag = (y.value * 2n) / P;
hex = x.value + flag * POW_2_381 + POW_2_383;
}
return toPaddedHex(hex, PUBLIC_KEY_LENGTH);
}
else {
if (this.isZero()) {
return '4'.padEnd(2 * 2 * PUBLIC_KEY_LENGTH, '0');
}
else {
const [x, y] = this.toAffine();
return toPaddedHex(x.value, PUBLIC_KEY_LENGTH) + toPaddedHex(y.value, PUBLIC_KEY_LENGTH);
}
}
}
assertValidity() {
if (this.isZero())
return this;
if (!this.isOnCurve())
throw new Error('Invalid G1 point: not on curve Fp');
if (!this.isTorsionFree())
throw new Error('Invalid G1 point: must be of prime-order subgroup');
return this;
}
[Symbol.for('nodejs.util.inspect.custom')]() {
return this.toString();
}
millerLoop(P) {
return (0, math_js_1.millerLoop)(P.pairingPrecomputes(), this.toAffine());
}
clearCofactor() {
const t = this.mulCurveMinusX();
return t.add(this);
}
isOnCurve() {
const b = new math_js_1.Fp(math_js_1.CURVE.b);
const { x, y, z } = this;
const left = y.pow(2n).multiply(z).subtract(x.pow(3n));
const right = b.multiply(z.pow(3n));
return left.subtract(right).isZero();
}
sigma() {
const BETA = 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn;
const [x, y] = this.toAffine();
return new PointG1(x.multiply(BETA), y);
}
phi() {
const cubicRootOfUnityModP = 0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen;
return new PointG1(this.x.multiply(cubicRootOfUnityModP), this.y, this.z);
}
mulCurveX() {
return this.multiplyUnsafe(math_js_1.CURVE.x).negate();
}
mulCurveMinusX() {
return this.multiplyUnsafe(math_js_1.CURVE.x);
}
isTorsionFree() {
const xP = this.mulCurveX();
const u2P = xP.mulCurveMinusX();
return u2P.equals(this.phi());
}
}
exports.PointG1 = PointG1;
PointG1.BASE = new PointG1(new math_js_1.Fp(math_js_1.CURVE.Gx), new math_js_1.Fp(math_js_1.CURVE.Gy), math_js_1.Fp.ONE);
PointG1.ZERO = new PointG1(math_js_1.Fp.ONE, math_js_1.Fp.ONE, math_js_1.Fp.ZERO);
class PointG2 extends math_js_1.ProjectivePoint {
constructor(x, y, z = math_js_1.Fp2.ONE) {
super(x, y, z, math_js_1.Fp2);
assertType(x, math_js_1.Fp2);
assertType(y, math_js_1.Fp2);
assertType(z, math_js_1.Fp2);
}
static async hashToCurve(msg, options) {
msg = ensureBytes(msg);
const u = await hash_to_field(msg, 2, options);
const [x0, y0] = (0, math_js_1.map_to_curve_simple_swu_9mod16)(math_js_1.Fp2.fromBigTuple(u[0]));
const [x1, y1] = (0, math_js_1.map_to_curve_simple_swu_9mod16)(math_js_1.Fp2.fromBigTuple(u[1]));
const [x2, y2] = new PointG2(x0, y0).add(new PointG2(x1, y1)).toAffine();
const [x3, y3] = (0, math_js_1.isogenyMapG2)(x2, y2);
return new PointG2(x3, y3).clearCofactor();
}
static async encodeToCurve(msg, options) {
msg = ensureBytes(msg);
const u = await hash_to_field(msg, 1, options);
const [x0, y0] = (0, math_js_1.map_to_curve_simple_swu_9mod16)(math_js_1.Fp2.fromBigTuple(u[0]));
const [x1, y1] = (0, math_js_1.isogenyMapG2)(x0, y0);
return new PointG2(x1, y1).clearCofactor();
}
static fromSignature(hex) {
hex = ensureBytes(hex);
const { P } = math_js_1.CURVE;
const half = hex.length / 2;
if (half !== 48 && half !== 96)
throw new Error('Invalid compressed signature length, must be 96 or 192');
const z1 = (0, math_js_1.bytesToNumberBE)(hex.slice(0, half));
const z2 = (0, math_js_1.bytesToNumberBE)(hex.slice(half));
const bflag1 = (0, math_js_1.mod)(z1, POW_2_383) / POW_2_382;
if (bflag1 === 1n)
return PointG2.ZERO;
const x1 = new math_js_1.Fp(z1 % POW_2_381);
const x2 = new math_js_1.Fp(z2);
const x = new math_js_1.Fp2(x2, x1);
const y2 = x.pow(3n).add(math_js_1.Fp2.fromBigTuple(math_js_1.CURVE.b2));
let y = y2.sqrt();
if (!y)
throw new Error('Failed to find a square root');
const { re: y0, im: y1 } = y.reim();
const aflag1 = (z1 % POW_2_382) / POW_2_381;
const isGreater = y1 > 0n && (y1 * 2n) / P !== aflag1;
const isZero = y1 === 0n && (y0 * 2n) / P !== aflag1;
if (isGreater || isZero)
y = y.multiply(-1n);
const point = new PointG2(x, y, math_js_1.Fp2.ONE);
point.assertValidity();
return point;
}
static fromHex(bytes) {
bytes = ensureBytes(bytes);
const m_byte = bytes[0] & 0xe0;
if (m_byte === 0x20 || m_byte === 0x60 || m_byte === 0xe0) {
throw new Error('Invalid encoding flag: ' + m_byte);
}
const bitC = m_byte & 0x80;
const bitI = m_byte & 0x40;
const bitS = m_byte & 0x20;
let point;
if (bytes.length === 96 && bitC) {
const { P, b2 } = math_js_1.CURVE;
const b = math_js_1.Fp2.fromBigTuple(b2);
bytes[0] = bytes[0] & 0x1f;
if (bitI) {
if (bytes.reduce((p, c) => (p !== 0 ? c + 1 : c), 0) > 0) {
throw new Error('Invalid compressed G2 point');
}
return PointG2.ZERO;
}
const x_1 = (0, math_js_1.bytesToNumberBE)(bytes.slice(0, PUBLIC_KEY_LENGTH));
const x_0 = (0, math_js_1.bytesToNumberBE)(bytes.slice(PUBLIC_KEY_LENGTH));
const x = new math_js_1.Fp2(new math_js_1.Fp(x_0), new math_js_1.Fp(x_1));
const right = x.pow(3n).add(b);
let y = right.sqrt();
if (!y)
throw new Error('Invalid compressed G2 point');
const Y_bit = y.c1.value === 0n ? (y.c0.value * 2n) / P : (y.c1.value * 2n) / P ? 1n : 0n;
y = bitS > 0 && Y_bit > 0 ? y : y.negate();
return new PointG2(x, y);
}
else if (bytes.length === 192 && !bitC) {
if ((bytes[0] & (1 << 6)) !== 0) {
return PointG2.ZERO;
}
const x1 = (0, math_js_1.bytesToNumberBE)(bytes.slice(0, PUBLIC_KEY_LENGTH));
const x0 = (0, math_js_1.bytesToNumberBE)(bytes.slice(PUBLIC_KEY_LENGTH, 2 * PUBLIC_KEY_LENGTH));
const y1 = (0, math_js_1.bytesToNumberBE)(bytes.slice(2 * PUBLIC_KEY_LENGTH, 3 * PUBLIC_KEY_LENGTH));
const y0 = (0, math_js_1.bytesToNumberBE)(bytes.slice(3 * PUBLIC_KEY_LENGTH));
point = new PointG2(math_js_1.Fp2.fromBigTuple([x0, x1]), math_js_1.Fp2.fromBigTuple([y0, y1]));
}
else {
throw new Error('Invalid point G2, expected 96/192 bytes');
}
point.assertValidity();
return point;
}
static fromPrivateKey(privateKey) {
return this.BASE.multiplyPrecomputed(normalizePrivKey(privateKey));
}
toSignature() {
if (this.equals(PointG2.ZERO)) {
const sum = POW_2_383 + POW_2_382;
const h = toPaddedHex(sum, PUBLIC_KEY_LENGTH) + toPaddedHex(0n, PUBLIC_KEY_LENGTH);
return (0, math_js_1.hexToBytes)(h);
}
const [{ re: x0, im: x1 }, { re: y0, im: y1 }] = this.toAffine().map((a) => a.reim());
const tmp = y1 > 0n ? y1 * 2n : y0 * 2n;
const aflag1 = tmp / math_js_1.CURVE.P;
const z1 = x1 + aflag1 * POW_2_381 + POW_2_383;
const z2 = x0;
return (0, math_js_1.hexToBytes)(toPaddedHex(z1, PUBLIC_KEY_LENGTH) + toPaddedHex(z2, PUBLIC_KEY_LENGTH));
}
toRawBytes(isCompressed = false) {
return (0, math_js_1.hexToBytes)(this.toHex(isCompressed));
}
toHex(isCompressed = false) {
this.assertValidity();
if (isCompressed) {
const { P } = math_js_1.CURVE;
let x_1 = 0n;
let x_0 = 0n;
if (this.isZero()) {
x_1 = POW_2_383 + POW_2_382;
}
else {
const [x, y] = this.toAffine();
const flag = y.c1.value === 0n ? (y.c0.value * 2n) / P : (y.c1.value * 2n) / P ? 1n : 0n;
x_1 = x.c1.value + flag * POW_2_381 + POW_2_383;
x_0 = x.c0.value;
}
return toPaddedHex(x_1, PUBLIC_KEY_LENGTH) + toPaddedHex(x_0, PUBLIC_KEY_LENGTH);
}
else {
if (this.equals(PointG2.ZERO)) {
return '4'.padEnd(2 * 4 * PUBLIC_KEY_LENGTH, '0');
}
const [{ re: x0, im: x1 }, { re: y0, im: y1 }] = this.toAffine().map((a) => a.reim());
return (toPaddedHex(x1, PUBLIC_KEY_LENGTH) +
toPaddedHex(x0, PUBLIC_KEY_LENGTH) +
toPaddedHex(y1, PUBLIC_KEY_LENGTH) +
toPaddedHex(y0, PUBLIC_KEY_LENGTH));
}
}
assertValidity() {
if (this.isZero())
return this;
if (!this.isOnCurve())
throw new Error('Invalid G2 point: not on curve Fp2');
if (!this.isTorsionFree())
throw new Error('Invalid G2 point: must be of prime-order subgroup');
return this;
}
psi() {
return this.fromAffineTuple((0, math_js_1.psi)(...this.toAffine()));
}
psi2() {
return this.fromAffineTuple((0, math_js_1.psi2)(...this.toAffine()));
}
mulCurveX() {
return this.multiplyUnsafe(math_js_1.CURVE.x).negate();
}
clearCofactor() {
const P = this;
let t1 = P.mulCurveX();
let t2 = P.psi();
let t3 = P.double();
t3 = t3.psi2();
t3 = t3.subtract(t2);
t2 = t1.add(t2);
t2 = t2.mulCurveX();
t3 = t3.add(t2);
t3 = t3.subtract(t1);
const Q = t3.subtract(P);
return Q;
}
isOnCurve() {
const b = math_js_1.Fp2.fromBigTuple(math_js_1.CURVE.b2);
const { x, y, z } = this;
const left = y.pow(2n).multiply(z).subtract(x.pow(3n));
const right = b.multiply(z.pow(3n));
return left.subtract(right).isZero();
}
isTorsionFree() {
const P = this;
return P.mulCurveX().equals(P.psi());
}
[Symbol.for('nodejs.util.inspect.custom')]() {
return this.toString();
}
clearPairingPrecomputes() {
this._PPRECOMPUTES = undefined;
}
pairingPrecomputes() {
if (this._PPRECOMPUTES)
return this._PPRECOMPUTES;
this._PPRECOMPUTES = (0, math_js_1.calcPairingPrecomputes)(...this.toAffine());
return this._PPRECOMPUTES;
}
}
exports.PointG2 = PointG2;
PointG2.BASE = new PointG2(math_js_1.Fp2.fromBigTuple(math_js_1.CURVE.G2x), math_js_1.Fp2.fromBigTuple(math_js_1.CURVE.G2y), math_js_1.Fp2.ONE);
PointG2.ZERO = new PointG2(math_js_1.Fp2.ONE, math_js_1.Fp2.ONE, math_js_1.Fp2.ZERO);
function pairing(P, Q, withFinalExponent = true) {
if (P.isZero() || Q.isZero())
throw new Error('No pairings at point of Infinity');
P.assertValidity();
Q.assertValidity();
const looped = P.millerLoop(Q);
return withFinalExponent ? looped.finalExponentiate() : looped;
}
exports.pairing = pairing;
function normP1(point) {
return point instanceof PointG1 ? point : PointG1.fromHex(point);
}
function normP2(point) {
return point instanceof PointG2 ? point : PointG2.fromSignature(point);
}
async function normP2Hash(point) {
return point instanceof PointG2 ? point : PointG2.hashToCurve(point);
}
function getPublicKey(privateKey) {
return PointG1.fromPrivateKey(privateKey).toRawBytes(true);
}
exports.getPublicKey = getPublicKey;
async function sign(message, privateKey) {
const msgPoint = await normP2Hash(message);
msgPoint.assertValidity();
const sigPoint = msgPoint.multiply(normalizePrivKey(privateKey));
if (message instanceof PointG2)
return sigPoint;
return sigPoint.toSignature();
}
exports.sign = sign;
async function verify(signature, message, publicKey) {
const P = normP1(publicKey);
const Hm = await normP2Hash(message);
const G = PointG1.BASE;
const S = normP2(signature);
const ePHm = pairing(P.negate(), Hm, false);
const eGS = pairing(G, S, false);
const exp = eGS.multiply(ePHm).finalExponentiate();
return exp.equals(math_js_1.Fp12.ONE);
}
exports.verify = verify;
function aggregatePublicKeys(publicKeys) {
if (!publicKeys.length)
throw new Error('Expected non-empty array');
const agg = publicKeys.map(normP1).reduce((sum, p) => sum.add(p), PointG1.ZERO);
if (publicKeys[0] instanceof PointG1)
return agg.assertValidity();
return agg.toRawBytes(true);
}
exports.aggregatePublicKeys = aggregatePublicKeys;
function aggregateSignatures(signatures) {
if (!signatures.length)
throw new Error('Expected non-empty array');
const agg = signatures.map(normP2).reduce((sum, s) => sum.add(s), PointG2.ZERO);
if (signatures[0] instanceof PointG2)
return agg.assertValidity();
return agg.toSignature();
}
exports.aggregateSignatures = aggregateSignatures;
async function verifyBatch(signature, messages, publicKeys) {
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 = await Promise.all(messages.map(normP2Hash));
const nPublicKeys = publicKeys.map(normP1);
try {
const paired = [];
for (const message of new Set(nMessages)) {
const groupPublicKey = nMessages.reduce((groupPublicKey, subMessage, i) => subMessage === message ? groupPublicKey.add(nPublicKeys[i]) : groupPublicKey, PointG1.ZERO);
paired.push(pairing(groupPublicKey, message, false));
}
paired.push(pairing(PointG1.BASE.negate(), sig, false));
const product = paired.reduce((a, b) => a.multiply(b), math_js_1.Fp12.ONE);
const exp = product.finalExponentiate();
return exp.equals(math_js_1.Fp12.ONE);
}
catch {
return false;
}
}
exports.verifyBatch = verifyBatch;
PointG1.BASE.calcMultiplyPrecomputes(4);
},{"./math.js":2,"crypto":4}],2:[function(require,module,exports){
"use strict";
var _a, _b;
Object.defineProperty(exports, "__esModule", { value: true });
exports.psi2 = exports.psi = exports.millerLoop = exports.calcPairingPrecomputes = exports.isogenyMapG1 = exports.isogenyMapG2 = exports.map_to_curve_simple_swu_3mod4 = exports.map_to_curve_simple_swu_9mod16 = exports.ProjectivePoint = exports.Fp12 = exports.Fp6 = exports.Fp2 = exports.Fr = exports.Fp = exports.concatBytes = exports.bytesToNumberBE = exports.bytesToHex = exports.numberToBytesBE = exports.hexToBytes = exports.powMod = exports.mod = exports.CURVE = void 0;
exports.CURVE = {
P: 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn,
r: 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n,
h: 0x396c8c005555e1568c00aaab0000aaabn,
Gx: 0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bbn,
Gy: 0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1n,
b: 4n,
P2: 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn **
2n -
1n,
h2: 0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5n,
G2x: [
0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8n,
0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7en,
],
G2y: [
0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801n,
0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79ben,
],
b2: [4n, 4n],
x: 0xd201000000010000n,
h2Eff: 0xbc69f08f2ee75b3584c6a0ea91b352888e2a8e9145ad7689986ff031508ffe1329c2f178731db956d82bf015d1212b02ec0ec69d7477c1ae954cbc06689f6a359894c0adebbf6b4e8020005aaa95551n,
};
const BLS_X_LEN = bitLen(exports.CURVE.x);
function mod(a, b) {
const res = a % b;
return res >= 0n ? res : b + res;
}
exports.mod = mod;
function powMod(num, power, modulo) {
if (modulo <= 0n || power < 0n)
throw new Error('Expected power/modulo > 0');
if (modulo === 1n)
return 0n;
let res = 1n;
while (power > 0n) {
if (power & 1n)
res = (res * num) % modulo;
num = (num * num) % modulo;
power >>= 1n;
}
return res;
}
exports.powMod = powMod;
function genInvertBatch(cls, nums) {
const tmp = new Array(nums.length);
const lastMultiplied = nums.reduce((acc, num, i) => {
if (num.isZero())
return acc;
tmp[i] = acc;
return acc.multiply(num);
}, cls.ONE);
const inverted = lastMultiplied.invert();
nums.reduceRight((acc, num, i) => {
if (num.isZero())
return acc;
tmp[i] = acc.multiply(tmp[i]);
return acc.multiply(num);
}, inverted);
return tmp;
}
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;
}
function invert(number, modulo = exports.CURVE.P) {
const _0n = 0n;
const _1n = 1n;
if (number === _0n || modulo <= _0n) {
throw new Error(`invert: expected positive integers, got n=${number} mod=${modulo}`);
}
let a = mod(number, modulo);
let b = modulo;
let x = _0n, y = _1n, u = _1n, v = _0n;
while (a !== _0n) {
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 !== _1n)
throw new Error('invert: does not exist');
return mod(x, modulo);
}
function hexToBytes(hex) {
if (typeof hex !== 'string') {
throw new TypeError('hexToBytes: expected string, got ' + typeof hex);
}
if (hex.length % 2)
throw new Error('hexToBytes: received invalid unpadded hex');
const array = new Uint8Array(hex.length / 2);
for (let i = 0; i < array.length; i++) {
const j = i * 2;
const hexByte = hex.slice(j, j + 2);
if (hexByte.length !== 2)
throw new Error('Invalid byte sequence');
const byte = Number.parseInt(hexByte, 16);
if (Number.isNaN(byte) || byte < 0)
throw new Error('Invalid byte sequence');
array[i] = byte;
}
return array;
}
exports.hexToBytes = hexToBytes;
function numberToHex(num, byteLength) {
if (!byteLength)
throw new Error('byteLength target must be specified');
const hex = num.toString(16);
const p1 = hex.length & 1 ? `0${hex}` : hex;
return p1.padStart(byteLength * 2, '0');
}
function numberToBytesBE(num, byteLength) {
const res = hexToBytes(numberToHex(num, byteLength));
if (res.length !== byteLength)
throw new Error('numberToBytesBE: wrong byteLength');
return res;
}
exports.numberToBytesBE = numberToBytesBE;
const hexes = Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
function bytesToHex(uint8a) {
let hex = '';
for (let i = 0; i < uint8a.length; i++) {
hex += hexes[uint8a[i]];
}
return hex;
}
exports.bytesToHex = bytesToHex;
function bytesToNumberBE(bytes) {
return BigInt('0x' + bytesToHex(bytes));
}
exports.bytesToNumberBE = bytesToNumberBE;
function concatBytes(...arrays) {
if (arrays.length === 1)
return arrays[0];
const length = arrays.reduce((a, arr) => a + arr.length, 0);
const result = new Uint8Array(length);
for (let i = 0, pad = 0; i < arrays.length; i++) {
const arr = arrays[i];
result.set(arr, pad);
pad += arr.length;
}
return result;
}
exports.concatBytes = concatBytes;
class Fp {
constructor(value) {
this.value = mod(value, Fp.ORDER);
}
isZero() {
return this.value === 0n;
}
equals(rhs) {
return this.value === rhs.value;
}
negate() {
return new Fp(-this.value);
}
invert() {
return new Fp(invert(this.value, Fp.ORDER));
}
add(rhs) {
return new Fp(this.value + rhs.value);
}
square() {
return new Fp(this.value * this.value);
}
pow(n) {
return new Fp(powMod(this.value, n, Fp.ORDER));
}
sqrt() {
const root = this.pow((Fp.ORDER + 1n) / 4n);
if (!root.square().equals(this))
return;
return root;
}
subtract(rhs) {
return new Fp(this.value - rhs.value);
}
multiply(rhs) {
if (rhs instanceof Fp)
rhs = rhs.value;
return new Fp(this.value * rhs);
}
div(rhs) {
if (typeof rhs === 'bigint')
rhs = new Fp(rhs);
return this.multiply(rhs.invert());
}
toString() {
const str = this.value.toString(16).padStart(96, '0');
return str.slice(0, 2) + '.' + str.slice(-2);
}
static fromBytes(b) {
if (b.length !== Fp.BYTES_LEN)
throw new Error(`fromBytes wrong length=${b.length}`);
return new Fp(bytesToNumberBE(b));
}
toBytes() {
return numberToBytesBE(this.value, Fp.BYTES_LEN);
}
}
exports.Fp = Fp;
_a = Fp;
Fp.ORDER = exports.CURVE.P;
Fp.MAX_BITS = bitLen(exports.CURVE.P);
Fp.BYTES_LEN = Math.ceil(_a.MAX_BITS / 8);
Fp.ZERO = new Fp(0n);
Fp.ONE = new Fp(1n);
class Fr {
constructor(value) {
this.value = mod(value, Fr.ORDER);
}
static isValid(b) {
return b <= Fr.ORDER;
}
isZero() {
return this.value === 0n;
}
equals(rhs) {
return this.value === rhs.value;
}
negate() {
return new Fr(-this.value);
}
invert() {
return new Fr(invert(this.value, Fr.ORDER));
}
add(rhs) {
return new Fr(this.value + rhs.value);
}
square() {
return new Fr(this.value * this.value);
}
pow(n) {
return new Fr(powMod(this.value, n, Fr.ORDER));
}
subtract(rhs) {
return new Fr(this.value - rhs.value);
}
multiply(rhs) {
if (rhs instanceof Fr)
rhs = rhs.value;
return new Fr(this.value * rhs);
}
div(rhs) {
if (typeof rhs === 'bigint')
rhs = new Fr(rhs);
return this.multiply(rhs.invert());
}
legendre() {
return this.pow((Fr.ORDER - 1n) / 2n);
}
sqrt() {
if (!this.legendre().equals(Fr.ONE))
return;
const P = Fr.ORDER;
let q, s, z;
for (q = P - 1n, s = 0; q % 2n === 0n; q /= 2n, s++)
;
if (s === 1)
return this.pow((P + 1n) / 4n);
for (z = 2n; z < P && new Fr(z).legendre().value !== P - 1n; z++)
;
let c = powMod(z, q, P);
let r = powMod(this.value, (q + 1n) / 2n, P);
let t = powMod(this.value, q, P);
let t2 = 0n;
while (mod(t - 1n, P) !== 0n) {
t2 = mod(t * t, P);
let i;
for (i = 1; i < s; i++) {
if (mod(t2 - 1n, P) === 0n)
break;
t2 = mod(t2 * t2, P);
}
let b = powMod(c, BigInt(1 << (s - i - 1)), P);
r = mod(r * b, P);
c = mod(b * b, P);
t = mod(t * c, P);
s = i;
}
return new Fr(r);
}
toString() {
return '0x' + this.value.toString(16).padStart(64, '0');
}
}
exports.Fr = Fr;
Fr.ORDER = exports.CURVE.r;
Fr.ZERO = new Fr(0n);
Fr.ONE = new Fr(1n);
function powMod_FQP(fqp, fqpOne, n) {
const elm = fqp;
if (n === 0n)
return fqpOne;
if (n === 1n)
return elm;
let p = fqpOne;
let d = elm;
while (n > 0n) {
if (n & 1n)
p = p.multiply(d);
n >>= 1n;
d = d.square();
}
return p;
}
class Fp2 {
constructor(c0, c1) {
this.c0 = c0;
this.c1 = c1;
if (typeof c0 === 'bigint')
throw new Error('c0: Expected Fp');
if (typeof c1 === 'bigint')
throw new Error('c1: Expected Fp');
}
static fromBigTuple(tuple) {
const fps = tuple.map((n) => new Fp(n));
return new Fp2(...fps);
}
one() {
return Fp2.ONE;
}
isZero() {
return this.c0.isZero() && this.c1.isZero();
}
toString() {
return `Fp2(${this.c0} + ${this.c1i)`;
}
reim() {
return { re: this.c0.value, im: this.c1.value };
}
negate() {
const { c0, c1 } = this;
return new Fp2(c0.negate(), c1.negate());
}
equals(rhs) {
const { c0, c1 } = this;
const { c0: r0, c1: r1 } = rhs;
return c0.equals(r0) && c1.equals(r1);
}
add(rhs) {
const { c0, c1 } = this;
const { c0: r0, c1: r1 } = rhs;
return new Fp2(c0.add(r0), c1.add(r1));
}
subtract(rhs) {
const { c0, c1 } = this;
const { c0: r0, c1: r1 } = rhs;
return new Fp2(c0.subtract(r0), c1.subtract(r1));
}
multiply(rhs) {
const { c0, c1 } = this;
if (typeof rhs === 'bigint') {
return new Fp2(c0.multiply(rhs), c1.multiply(rhs));
}
const { c0: r0, c1: r1 } = rhs;
let t1 = c0.multiply(r0);
let t2 = c1.multiply(r1);
return new Fp2(t1.subtract(t2), c0.add(c1).multiply(r0.add(r1)).subtract(t1.add(t2)));
}
pow(n) {
return powMod_FQP(this, Fp2.ONE, n);
}
div(rhs) {
const inv = typeof rhs === 'bigint' ? new Fp(rhs).invert().value : rhs.invert();
return this.multiply(inv);
}
mulByNonresidue() {
const c0 = this.c0;
const c1 = this.c1;
return new Fp2(c0.subtract(c1), c0.add(c1));
}
square() {
const c0 = this.c0;
const c1 = this.c1;
const a = c0.add(c1);
const b = c0.subtract(c1);
const c = c0.add(c0);
return new Fp2(a.multiply(b), c.multiply(c1));
}
sqrt() {
const candidateSqrt = this.pow((Fp2.ORDER + 8n) / 16n);
const check = candidateSqrt.square().div(this);
const R = FP2_ROOTS_OF_UNITY;
const divisor = [R[0], R[2], R[4], R[6]].find((r) => r.equals(check));
if (!divisor)
return;
const index = R.indexOf(divisor);
const root = R[index / 2];
if (!root)
throw new Error('Invalid root');
const x1 = candidateSqrt.div(root);
const x2 = x1.negate();
const { re: re1, im: im1 } = x1.reim();
const { re: re2, im: im2 } = x2.reim();
if (im1 > im2 || (im1 === im2 && re1 > re2))
return x1;
return x2;
}
invert() {
const { re: a, im: b } = this.reim();
const factor = new Fp(a * a + b * b).invert();
return new Fp2(factor.multiply(new Fp(a)), factor.multiply(new Fp(-b)));
}
frobeniusMap(power) {
return new Fp2(this.c0, this.c1.multiply(FP2_FROBENIUS_COEFFICIENTS[power % 2]));
}
multiplyByB() {
let c0 = this.c0;
let c1 = this.c1;
let t0 = c0.multiply(4n);
let t1 = c1.multiply(4n);
return new Fp2(t0.subtract(t1), t0.add(t1));
}
static fromBytes(b) {
if (b.length !== Fp2.BYTES_LEN)
throw new Error(`fromBytes wrong length=${b.length}`);
return new Fp2(Fp.fromBytes(b.subarray(0, Fp.BYTES_LEN)), Fp.fromBytes(b.subarray(Fp.BYTES_LEN)));
}
toBytes() {
return concatBytes(this.c0.toBytes(), this.c1.toBytes());
}
}
exports.Fp2 = Fp2;
_b = Fp2;
Fp2.ORDER = exports.CURVE.P2;
Fp2.MAX_BITS = bitLen(exports.CURVE.P2);
Fp2.BYTES_LEN = Math.ceil(_b.MAX_BITS / 8);
Fp2.ZERO = new Fp2(Fp.ZERO, Fp.ZERO);
Fp2.ONE = new Fp2(Fp.ONE, Fp.ZERO);
class Fp6 {
constructor(c0, c1, c2) {
this.c0 = c0;
this.c1 = c1;
this.c2 = c2;
}
static fromBigSix(t) {
if (!Array.isArray(t) || t.length !== 6)
throw new Error('Invalid Fp6 usage');
const c = [t.slice(0, 2), t.slice(2, 4), t.slice(4, 6)].map((t) => Fp2.fromBigTuple(t));
return new Fp6(...c);
}
fromTriple(triple) {
return new Fp6(...triple);
}
one() {
return Fp6.ONE;
}
isZero() {
return this.c0.isZero() && this.c1.isZero() && this.c2.isZero();
}
negate() {
const { c0, c1, c2 } = this;
return new Fp6(c0.negate(), c1.negate(), c2.negate());
}
toString() {
return `Fp6(${this.c0} + ${this.c1} * v, ${this.c2} * v^2)`;
}
equals(rhs) {
const { c0, c1, c2 } = this;
const { c0: r0, c1: r1, c2: r2 } = rhs;
return c0.equals(r0) && c1.equals(r1) && c2.equals(r2);
}
add(rhs) {
const { c0, c1, c2 } = this;
const { c0: r0, c1: r1, c2: r2 } = rhs;
return new Fp6(c0.add(r0), c1.add(r1), c2.add(r2));
}
subtract(rhs) {
const { c0, c1, c2 } = this;
const { c0: r0, c1: r1, c2: r2 } = rhs;
return new Fp6(c0.subtract(r0), c1.subtract(r1), c2.subtract(r2));
}
multiply(rhs) {
if (typeof rhs === 'bigint') {
return new Fp6(this.c0.multiply(rhs), this.c1.multiply(rhs), this.c2.multiply(rhs));
}
let { c0, c1, c2 } = this;
let { c0: r0, c1: r1, c2: r2 } = rhs;
let t0 = c0.multiply(r0);
let t1 = c1.multiply(r1);
let t2 = c2.multiply(r2);
return new Fp6(t0.add(c1.add(c2).multiply(r1.add(r2)).subtract(t1.add(t2)).mulByNonresidue()), c0.add(c1).multiply(r0.add(r1)).subtract(t0.add(t1)).add(t2.mulByNonresidue()), t1.add(c0.add(c2).multiply(r0.add(r2)).subtract(t0.add(t2))));
}
pow(n) {
return powMod_FQP(this, Fp6.ONE, n);
}
div(rhs) {
const inv = typeof rhs === 'bigint' ? new Fp(rhs).invert().value : rhs.invert();
return this.multiply(inv);
}
mulByNonresidue() {
return new Fp6(this.c2.mulByNonresidue(), this.c0, this.c1);
}
multiplyBy1(b1) {
return new Fp6(this.c2.multiply(b1).mulByNonresidue(), this.c0.multiply(b1), this.c1.multiply(b1));
}
multiplyBy01(b0, b1) {
let { c0, c1, c2 } = this;
let t0 = c0.multiply(b0);
let t1 = c1.multiply(b1);
return new Fp6(c1.add(c2).multiply(b1).subtract(t1).mulByNonresidue().add(t0), b0.add(b1).multiply(c0.add(c1)).subtract(t0).subtract(t1), c0.add(c2).multiply(b0).subtract(t0).add(t1));
}
multiplyByFp2(rhs) {
let { c0, c1, c2 } = this;
return new Fp6(c0.multiply(rhs), c1.multiply(rhs), c2.multiply(rhs));
}
square() {
let { c0, c1, c2 } = this;
let t0 = c0.square();
let t1 = c0.multiply(c1).multiply(2n);
let t3 = c1.multiply(c2).multiply(2n);
let t4 = c2.square();
return new Fp6(t3.mulByNonresidue().add(t0), t4.mulByNonresidue().add(t1), t1.add(c0.subtract(c1).add(c2).square()).add(t3).subtract(t0).subtract(t4));
}
invert() {
let { c0, c1, c2 } = this;
let t0 = c0.square().subtract(c2.multiply(c1).mulByNonresidue());
let t1 = c2.square().mulByNonresidue().subtract(c0.multiply(c1));
let t2 = c1.square().subtract(c0.multiply(c2));
let t4 = c2.multiply(t1).add(c1.multiply(t2)).mulByNonresidue().add(c0.multiply(t0)).invert();
return new Fp6(t4.multiply(t0), t4.multiply(t1), t4.multiply(t2));
}
frobeniusMap(power) {
return new Fp6(this.c0.frobeniusMap(power), this.c1.frobeniusMap(power).multiply(FP6_FROBENIUS_COEFFICIENTS_1[power % 6]), this.c2.frobeniusMap(power).multiply(FP6_FROBENIUS_COEFFICIENTS_2[power % 6]));
}
static fromBytes(b) {
if (b.length !== Fp6.BYTES_LEN)
throw new Error(`fromBytes wrong length=${b.length}`);
return new Fp6(Fp2.fromBytes(b.subarray(0, Fp2.BYTES_LEN)), Fp2.fromBytes(b.subarray(Fp2.BYTES_LEN, 2 * Fp2.BYTES_LEN)), Fp2.fromBytes(b.subarray(2 * Fp2.BYTES_LEN)));
}
toBytes() {
return concatBytes(this.c0.toBytes(), this.c1.toBytes(), this.c2.toBytes());
}
}
exports.Fp6 = Fp6;
Fp6.ZERO = new Fp6(Fp2.ZERO, Fp2.ZERO, Fp2.ZERO);
Fp6.ONE = new Fp6(Fp2.ONE, Fp2.ZERO, Fp2.ZERO);
Fp6.BYTES_LEN = 3 * Fp2.BYTES_LEN;
class Fp12 {
constructor(c0, c1) {
this.c0 = c0;
this.c1 = c1;
}
static fromBigTwelve(t) {
return new Fp12(Fp6.fromBigSix(t.slice(0, 6)), Fp6.fromBigSix(t.slice(6, 12)));
}
fromTuple(c) {
return new Fp12(...c);
}
one() {
return Fp12.ONE;
}
isZero() {
return this.c0.isZero() && this.c1.isZero();
}
toString() {
return `Fp12(${this.c0} + ${this.c1} * w)`;
}
negate() {
const { c0, c1 } = this;
return new Fp12(c0.negate(), c1.negate());
}
equals(rhs) {
const { c0, c1 } = this;
const { c0: r0, c1: r1 } = rhs;
return c0.equals(r0) && c1.equals(r1);
}
add(rhs) {
const { c0, c1 } = this;
const { c0: r0, c1: r1 } = rhs;
return new Fp12(c0.add(r0), c1.add(r1));
}
subtract(rhs) {
const { c0, c1 } = this;
const { c0: r0, c1: r1 } = rhs;
return new Fp12(c0.subtract(r0), c1.subtract(r1));
}
multiply(rhs) {
if (typeof rhs === 'bigint')
return new Fp12(this.c0.multiply(rhs), this.c1.multiply(rhs));
let { c0, c1 } = this;
let { c0: r0, c1: r1 } = rhs;
let t1 = c0.multiply(r0);
let t2 = c1.multiply(r1);
return new Fp12(t1.add(t2.mulByNonresidue()), c0.add(c1).multiply(r0.add(r1)).subtract(t1.add(t2)));
}
pow(n) {
return powMod_FQP(this, Fp12.ONE, n);
}
div(rhs) {
const inv = typeof rhs === 'bigint' ? new Fp(rhs).invert().value : rhs.invert();
return this.multiply(inv);
}
multiplyBy014(o0, o1, o4) {
let { c0, c1 } = this;
let t0 = c0.multiplyBy01(o0, o1);
let t1 = c1.multiplyBy1(o4);
return new Fp12(t1.mulByNonresidue().add(t0), c1.add(c0).multiplyBy01(o0, o1.add(o4)).subtract(t0).subtract(t1));
}
multiplyByFp2(rhs) {
return new Fp12(this.c0.multiplyByFp2(rhs), this.c1.multiplyByFp2(rhs));
}
square() {
let { c0, c1 } = this;
let ab = c0.multiply(c1);
return new Fp12(c1.mulByNonresidue().add(c0).multiply(c0.add(c1)).subtract(ab).subtract(ab.mulByNonresidue()), ab.add(ab));
}
invert() {
let { c0, c1 } = this;
let t = c0.square().subtract(c1.square().mulByNonresidue()).invert();
return new Fp12(c0.multiply(t), c1.multiply(t).negate());
}
conjugate() {
return new Fp12(this.c0, this.c1.negate());
}
frobeniusMap(power) {
const r0 = this.c0.frobeniusMap(power);
const { c0, c1, c2 } = this.c1.frobeniusMap(power);
const coeff = FP12_FROBENIUS_COEFFICIENTS[power % 12];
return new Fp12(r0, new Fp6(c0.multiply(coeff), c1.multiply(coeff), c2.multiply(coeff)));
}
Fp4Square(a, b) {
const a2 = a.square();
const b2 = b.square();
return {
first: b2.mulByNonresidue().add(a2),
second: a.add(b).square().subtract(a2).subtract(b2),
};
}
cyclotomicSquare() {
const { c0: c0c0, c1: c0c1, c2: c0c2 } = this.c0;
const { c0: c1c0, c1: c1c1, c2: c1c2 } = this.c1;
const { first: t3, second: t4 } = this.Fp4Square(c0c0, c1c1);
const { first: t5, second: t6 } = this.Fp4Square(c1c0, c0c2);
const { first: t7, second: t8 } = this.Fp4Square(c0c1, c1c2);
let t9 = t8.mulByNonresidue();
return new Fp12(new Fp6(t3.subtract(c0c0).multiply(2n).add(t3), t5.subtract(c0c1).multiply(2n).add(t5), t7.subtract(c0c2).multiply(2n).add(t7)), new Fp6(t9.add(c1c0).multiply(2n).add(t9), t4.add(c1c1).multiply(2n).add(t4), t6.add(c1c2).multiply(2n).add(t6)));
}
cyclotomicExp(n) {
let z = Fp12.ONE;
for (let i = BLS_X_LEN - 1; i >= 0; i--) {
z = z.cyclotomicSquare();
if (bitGet(n, i))
z = z.multiply(this);
}
return z;
}
finalExponentiate() {
const { x } = exports.CURVE;
const t0 = this.frobeniusMap(6).div(this);
const t1 = t0.frobeniusMap(2).multiply(t0);
const t2 = t1.cyclotomicExp(x).conjugate();
const t3 = t1.cyclotomicSquare().conjugate().multiply(t2);
const t4 = t3.cyclotomicExp(x).conjugate();
const t5 = t4.cyclotomicExp(x).conjugate();
const t6 = t5.cyclotomicExp(x).conjugate().multiply(t2.cyclotomicSquare());
const t7 = t6.cyclotomicExp(x).conjugate();
const t2_t5_pow_q2 = t2.multiply(t5).frobeniusMap(2);
const t4_t1_pow_q3 = t4.multiply(t1).frobeniusMap(3);
const t6_t1c_pow_q1 = t6.multiply(t1.conjugate()).frobeniusMap(1);
const t7_t3c_t1 = t7.multiply(t3.conjugate()).multiply(t1);
return t2_t5_pow_q2.multiply(t4_t1_pow_q3).multiply(t6_t1c_pow_q1).multiply(t7_t3c_t1);
}
static fromBytes(b) {
if (b.length !== Fp12.BYTES_LEN)
throw new Error(`fromBytes wrong length=${b.length}`);
return new Fp12(Fp6.fromBytes(b.subarray(0, Fp6.BYTES_LEN)), Fp6.fromBytes(b.subarray(Fp6.BYTES_LEN)));
}
toBytes() {
return concatBytes(this.c0.toBytes(), this.c1.toBytes());
}
}
exports.Fp12 = Fp12;
Fp12.ZERO = new Fp12(Fp6.ZERO, Fp6.ZERO);
Fp12.ONE = new Fp12(Fp6.ONE, Fp6.ZERO);
Fp12.BYTES_LEN = 2 * Fp6.BYTES_LEN;
class ProjectivePoint {
constructor(x, y, z, C) {
this.x = x;
this.y = y;
this.z = z;
this.C = C;
}
isZero() {
return this.z.isZero();
}
createPoint(x, y, z) {
return new this.constructor(x, y, z);
}
getZero() {
return this.createPoint(this.C.ONE, this.C.ONE, this.C.ZERO);
}
equals(rhs) {
if (this.constructor !== rhs.constructor)
throw new Error(`ProjectivePoint#equals: this is ${this.constructor}, but rhs is ${rhs.constructor}`);
const a = this;
const b = rhs;
const xe = a.x.multiply(b.z).equals(b.x.multiply(a.z));
const ye = a.y.multiply(b.z).equals(b.y.multiply(a.z));
return xe && ye;
}
negate() {
return this.createPoint(this.x, this.y.negate(), this.z);
}
toString(isAffine = true) {
if (this.isZero()) {
return `Point<Zero>`;
}
if (!isAffine) {
return `Point<x=${this.x}, y=${this.y}, z=${this.z}>`;
}
const [x, y] = this.toAffine();
return `Point<x=${x}, y=${y}>`;
}
fromAffineTuple(xy) {
return this.createPoint(xy[0], xy[1], this.C.ONE);
}
toAffine(invZ = this.z.invert()) {
if (invZ.isZero())
throw new Error('Invalid inverted z');
return [this.x.multiply(invZ), this.y.multiply(invZ)];
}
toAffineBatch(points) {
const toInv = genInvertBatch(this.C, points.map((p) => p.z));
return points.map((p, i) => p.toAffine(toInv[i]));
}
normalizeZ(points) {
return this.toAffineBatch(points).map((t) => this.fromAffineTuple(t));
}
double() {
const { x, y, z } = this;
const W = x.multiply(x).multiply(3n);
const S = y.multiply(z);
const SS = S.multiply(S);
const SSS = SS.multiply(S);
const B = x.multiply(y).multiply(S);
const H = W.multiply(W).subtract(B.multiply(8n));
const X3 = H.multiply(S).multiply(2n);
const Y3 = W.multiply(B.multiply(4n).subtract(H)).subtract(y.multiply(y).multiply(8n).multiply(SS));
const Z3 = SSS.multiply(8n);
return this.createPoint(X3, Y3, Z3);
}
add(rhs) {
if (this.constructor !== rhs.constructor)
throw new Error(`ProjectivePoint#add: this is ${this.constructor}, but rhs is ${rhs.constructor}`);
const p1 = this;
const p2 = rhs;
if (p1.isZero())
return p2;
if (p2.isZero())
return p1;
const X1 = p1.x;
const Y1 = p1.y;
const Z1 = p1.z;
const X2 = p2.x;
const Y2 = p2.y;
const Z2 = p2.z;
const U1 = Y2.multiply(Z1);
const U2 = Y1.multiply(Z2);
const V1 = X2.multiply(Z1);
const V2 = X1.multiply(Z2);
if (V1.equals(V2) && U1.equals(U2))
return this.double();
if (V1.equals(V2))
return this.getZero();
const U = U1.subtract(U2);
const V = V1.subtract(V2);
const VV = V.multiply(V);
const VVV = VV.multiply(V);
const V2VV = V2.multiply(VV);
const W = Z1.multiply(Z2);
const A = U.multiply(U).multiply(W).subtract(VVV).subtract(V2VV.multiply(2n));
const X3 = V.multiply(A);
const Y3 = U.multiply(V2VV.subtract(A)).subtract(VVV.multiply(U2));
const Z3 = VVV.multiply(W);
return this.createPoint(X3, Y3, Z3);
}
subtract(rhs) {
if (this.constructor !== rhs.constructor)
throw new Error(`ProjectivePoint#subtract: this is ${this.constructor}, but rhs is ${rhs.constructor}`);
return this.add(rhs.negate());
}
validateScalar(n) {
if (typeof n === 'number')
n = BigInt(n);
if (typeof n !== 'bigint' || n <= 0 || n > exports.CURVE.r) {
throw new Error(`Point#multiply: invalid scalar, expected positive integer < CURVE.r. Got: ${n}`);
}
return n;
}
multiplyUnsafe(scalar) {
let n = this.validateScalar(scalar);
let point = this.getZero();
let d = this;
while (n > 0n) {
if (n & 1n)
point = point.add(d);
d = d.double();
n >>= 1n;
}
return point;
}
multiply(scalar) {
let n = this.validateScalar(scalar);
let point = this.getZero();
let fake = this.getZero();
let d = this;
let bits = Fp.ORDER;
while (bits > 0n) {
if (n & 1n) {
point = point.add(d);
}
else {
fake = fake.add(d);
}
d = d.double();
n >>= 1n;
bits >>= 1n;
}
return point;
}
maxBits() {
return this.C.MAX_BITS;
}
precomputeWindow(W) {
const windows = Math.ceil(this.maxBits() / W);
const windowSize = 2 ** (W - 1);
let points = [];
let p = this;
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;
}
calcMultiplyPrecomputes(W) {
if (this._MPRECOMPUTES)
throw new Error('This point already has precomputes');
this._MPRECOMPUTES = [W, this.normalizeZ(this.precomputeWindow(W))];
}
clearMultiplyPrecomputes() {
this._MPRECOMPUTES = undefined;
}
wNAF(n) {
let W, precomputes;
if (this._MPRECOMPUTES) {
[W, precomputes] = this._MPRECOMPUTES;
}
else {
W = 1;
precomputes = this.precomputeWindow(W);
}
let p = this.getZero();
let f = this.getZero();
const windows = Math.ceil(this.maxBits() / W);
const windowSize = 2 ** (W - 1);
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 += 1n;
}
if (wbits === 0) {
f = f.add(window % 2 ? precomputes[offset].negate() : precomputes[offset]);
}
else {
const cached = precomputes[offset + Math.abs(wbits) - 1];
p = p.add(wbits < 0 ? cached.negate() : cached);
}
}
return [p, f];
}
multiplyPrecomputed(scalar) {
return this.wNAF(this.validateScalar(scalar))[0];
}
}
exports.ProjectivePoint = ProjectivePoint;
function sgn0_fp2(x) {
const { re: x0, im: x1 } = x.reim();
const sign_0 = x0 % 2n;
const zero_0 = x0 === 0n;
const sign_1 = x1 % 2n;
return BigInt(sign_0 || (zero_0 && sign_1));
}
function sgn0_m_eq_1(x) {
return Boolean(x.value % 2n);
}
const P_MINUS_9_DIV_16 = (exports.CURVE.P ** 2n - 9n) / 16n;
function sqrt_div_fp2(u, v) {
const v7 = v.pow(7n);
const uv7 = u.multiply(v7);
const uv15 = uv7.multiply(v7.multiply(v));
const gamma = uv15.pow(P_MINUS_9_DIV_16).multiply(uv7);
let success = false;
let result = gamma;
const positiveRootsOfUnity = FP2_ROOTS_OF_UNITY.slice(0, 4);
positiveRootsOfUnity.forEach((root) => {
const candidate = root.multiply(gamma);
if (candidate.pow(2n).multiply(v).subtract(u).isZero() && !success) {
success = true;
result = candidate;
}
});
return { success, sqrtCandidateOrGamma: result };
}
function map_to_curve_simple_swu_9mod16(t) {
const iso_3_a = new Fp2(new Fp(0n), new Fp(240n));
const iso_3_b = new Fp2(new Fp(1012n), new Fp(1012n));
const iso_3_z = new Fp2(new Fp(-2n), new Fp(-1n));
if (Array.isArray(t))
t = Fp2.fromBigTuple(t);
const t2 = t.pow(2n);
const iso_3_z_t2 = iso_3_z.multiply(t2);
const ztzt = iso_3_z_t2.add(iso_3_z_t2.pow(2n));
let denominator = iso_3_a.multiply(ztzt).negate();
let numerator = iso_3_b.multiply(ztzt.add(Fp2.ONE));
if (denominator.isZero())
denominator = iso_3_z.multiply(iso_3_a);
let v = denominator.pow(3n);
let u = numerator
.pow(3n)
.add(iso_3_a.multiply(numerator).multiply(denominator.pow(2n)))
.add(iso_3_b.multiply(v));
const { success, sqrtCandidateOrGamma } = sqrt_div_fp2(u, v);
let y;
if (success)
y = sqrtCandidateOrGamma;
const sqrtCandidateX1 = sqrtCandidateOrGamma.multiply(t.pow(3n));
u = iso_3_z_t2.pow(3n).multiply(u);
let success2 = false;
FP2_ETAs.forEach((eta) => {
const etaSqrtCandidate = eta.multiply(sqrtCandidateX1);
const temp = etaSqrtCandidate.pow(2n).multiply(v).subtract(u);
if (temp.isZero() && !success && !success2) {
y = etaSqrtCandidate;
success2 = true;
}
});
if (!success && !success2)
throw new Error('Hash to Curve - Optimized SWU failure');
if (success2)
numerator = numerator.multiply(iso_3_z_t2);
y = y;
if (sgn0_fp2(t) !== sgn0_fp2(y))
y = y.negate();
return [numerator.div(denominator), y];
}
exports.map_to_curve_simple_swu_9mod16 = map_to_curve_simple_swu_9mod16;
function map_to_curve_simple_swu_3mod4(u) {
const A = new Fp(0x144698a3b8e9433d693a02c96d4982b0ea985383ee66a8d8e8981aefd881ac98936f8da0e0f97f5cf428082d584c1dn);
const B = new Fp(0x12e2908d11688030018b12e8753eee3b2016c1f0f24f4070a0b9c14fcef35ef55a23215a316ceaa5d1cc48e98e172be0n);
const Z = new Fp(11n);
const c1 = (Fp.ORDER - 3n) / 4n;
const c2 = Z.negate().pow(3n).sqrt();
const tv1 = u.square();
const tv3 = Z.multiply(tv1);
let xDen = tv3.square().add(tv3);
const xNum1 = xDen.add(Fp.ONE).multiply(B);
const xNum2 = tv3.multiply(xNum1);
xDen = A.negate().multiply(xDen);
if (xDen.isZero())
xDen = A.multiply(Z);
let tv2 = xDen.square();
const gxd = tv2.multiply(xDen);
tv2 = A.multiply(tv2);
let gx1 = xNum1.square().add(tv2).multiply(xNum1);
tv2 = B.multiply(gxd);
gx1 = gx1.add(tv2);
tv2 = gx1.multiply(gxd);
const tv4 = gxd.square().multiply(tv2);
const y1 = tv4.pow(c1).multiply(tv2);
const y2 = y1.multiply(c2).multiply(tv1).multiply(u);
let xNum, yPos;
if (y1.square().multiply(gxd).equals(gx1)) {
xNum = xNum1;
yPos = y1;
}
else {
xNum = xNum2;
yPos = y2;
}
const yNeg = yPos.negate();
const y = sgn0_m_eq_1(u) == sgn0_m_eq_1(yPos) ? yPos : yNeg;
return [xNum.div(xDen), y];
}
exports.map_to_curve_simple_swu_3mod4 = map_to_curve_simple_swu_3mod4;
function isogenyMap(COEFF, x, y) {
const [xNum, xDen, yNum, yDen] = COEFF.map((val) => val.reduce((acc, i) => acc.multiply(x).add(i)));
x = xNum.div(xDen);
y = y.multiply(yNum.div(yDen));
return [x, y];
}
const isogenyMapG2 = (x, y) => isogenyMap(ISOGENY_COEFFICIENTS_G2, x, y);
exports.isogenyMapG2 = isogenyMapG2;
const isogenyMapG1 = (x, y) => isogenyMap(ISOGENY_COEFFICIENTS_G1, x, y);
exports.isogenyMapG1 = isogenyMapG1;
function calcPairingPrecomputes(x, y) {
const Qx = x, Qy = y, Qz = Fp2.ONE;
let Rx = Qx, Ry = Qy, Rz = Qz;
let ell_coeff = [];
for (let i = BLS_X_LEN - 2; i >= 0; i--) {
let t0 = Ry.square();
let t1 = Rz.square();
let t2 = t1.multiply(3n).multiplyByB();
let t3 = t2.multiply(3n);
let t4 = Ry.add(Rz).square().subtract(t1).subtract(t0);
ell_coeff.push([
t2.subtract(t0),
Rx.square().multiply(3n),
t4.negate(),
]);
Rx = t0.subtract(t3).multiply(Rx).multiply(Ry).div(2n);
Ry = t0.add(t3).div(2n).square().subtract(t2.square().multiply(3n));
Rz = t0.multiply(t4);
if (bitGet(exports.CURVE.x, i)) {
let t0 = Ry.subtract(Qy.multiply(Rz));
let t1 = Rx.subtract(Qx.multiply(Rz));
ell_coeff.push([
t0.multiply(Qx).subtract(t1.multiply(Qy)),
t0.negate(),
t1,
]);
let t2 = t1.square();
let t3 = t2.multiply(t1);
let t4 = t2.multiply(Rx);
let t5 = t3.subtract(t4.multiply(2n)).add(t0.square().multiply(Rz));
Rx = t1.multiply(t5);
Ry = t4.subtract(t5).multiply(t0).subtract(t3.multiply(Ry));
Rz = Rz.multiply(t3);
}
}
return ell_coeff;
}
exports.calcPairingPrecomputes = calcPairingPrecomputes;
function millerLoop(ell, g1) {
const Px = g1[0].value;
const Py = g1[1].value;
let f12 = Fp12.ONE;
for (let j = 0, i = BLS_X_LEN - 2; i >= 0; i--, j++) {
const E = ell[j];
f12 = f12.multiplyBy014(E[0], E[1].multiply(Px), E[2].multiply(Py));
if (bitGet(exports.CURVE.x, i)) {
j += 1;
const F = ell[j];
f12 = f12.multiplyBy014(F[0], F[1].multiply(Px), F[2].multiply(Py));
}
if (i !== 0)
f12 = f12.square();
}
return f12.conjugate();
}
exports.millerLoop = millerLoop;
const ut_root = new Fp6(Fp2.ZERO, Fp2.ONE, Fp2.ZERO);
const wsq = new Fp12(ut_root, Fp6.ZERO);
const wcu = new Fp12(Fp6.ZERO, ut_root);
const [wsq_inv, wcu_inv] = genInvertBatch(Fp12, [wsq, wcu]);
function psi(x, y) {
const x2 = wsq_inv.multiplyByFp2(x).frobeniusMap(1).multiply(wsq).c0.c0;
const y2 = wcu_inv.multiplyByFp2(y).frobeniusMap(1).multiply(wcu).c0.c0;
return [x2, y2];
}
exports.psi = psi;
function psi2(x, y) {
return [x.multiply(PSI2_C1), y.negate()];
}
exports.psi2 = psi2;
const PSI2_C1 = 0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn;
const rv1 = 0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n;
const ev1 = 0x699be3b8c6870965e5bf892ad5d2cc7b0e85a117402dfd83b7f4a947e02d978498255a2aaec0ac627b5afbdf1bf1c90n;
const ev2 = 0x8157cd83046453f5dd0972b6e3949e4288020b5b8a9cc99ca07e27089a2ce2436d965026adad3ef7baba37f2183e9b5n;
const ev3 = 0xab1c2ffdd6c253ca155231eb3e71ba044fd562f6f72bc5bad5ec46a0b7a3b0247cf08ce6c6317f40edbc653a72dee17n;
const ev4 = 0xaa404866706722864480885d68ad0ccac1967c7544b447873cc37e0181271e006df72162a3d3e0287bf597fbf7f8fc1n;
const FP2_FROBENIUS_COEFFICIENTS = [
0x1n,
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
].map((item) => new Fp(item));
const FP2_ROOTS_OF_UNITY = [
[1n, 0n],
[rv1, -rv1],
[0n, 1n],
[rv1, rv1],
[-1n, 0n],
[-rv1, rv1],
[0n, -1n],
[-rv1, -rv1],
].map((pair) => Fp2.fromBigTuple(pair));
const FP2_ETAs = [
[ev1, ev2],
[-ev2, ev1],
[ev3, ev4],
[-ev4, ev3],
].map((pair) => Fp2.fromBigTuple(pair));
const FP6_FROBENIUS_COEFFICIENTS_1 = [
[0x1n, 0x0n],
[
0x0n,
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
],
[
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
0x0n,
],
[0x0n, 0x1n],
[
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
0x0n,
],
[
0x0n,
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
],
].map((pair) => Fp2.fromBigTuple(pair));
const FP6_FROBENIUS_COEFFICIENTS_2 = [
[0x1n, 0x0n],
[
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaadn,
0x0n,
],
[
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
0x0n,
],
[
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
0x0n,
],
[
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
0x0n,
],
[
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffffn,
0x0n,
],
].map((pair) => Fp2.fromBigTuple(pair));
const FP12_FROBENIUS_COEFFICIENTS = [
[0x1n, 0x0n],
[
0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8n,
0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3n,
],
[
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffffn,
0x0n,
],
[
0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2n,
0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
],
[
0x00000000000000005f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffen,
0x0n,
],
[
0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995n,
0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116n,
],
[
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaan,
0x0n,
],
[
0x00fc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3n,
0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8n,
],
[
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaacn,
0x0n,
],
[
0x06af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09n,
0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2n,
],
[
0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaadn,
0x0n,
],
[
0x05b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116n,
0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995n,
],
].map((n) => Fp2.fromBigTuple(n));
const xnum = [
[
0x171d6541fa38ccfaed6dea691f5fb614cb14b4e7f4e810aa22d6108f142b85757098e38d0f671c7188e2aaaaaaaa5ed1n,
0x0n,
],
[
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71en,
0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38dn,
],
[
0x0n,
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71an,
],
[
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6n,
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97d6n,
],
].map((pair) => Fp2.fromBigTuple(pair));
const xden = [
[0x0n, 0x0n],
[0x1n, 0x0n],
[
0xcn,
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa9fn,
],
[
0x0n,
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa63n,
],
].map((pair) => Fp2.fromBigTuple(pair));
const ynum = [
[
0x124c9ad43b6cf79bfbf7043de3811ad0761b0f37a1e26286b0e977c69aa274524e79097a56dc4bd9e1b371c71c718b10n,
0x0n,
],
[
0x11560bf17baa99bc32126fced787c88f984f87adf7ae0c7f9a208c6b4f20a4181472aaa9cb8d555526a9ffffffffc71cn,
0x8ab05f8bdd54cde190937e76bc3e447cc27c3d6fbd7063fcd104635a790520c0a395554e5c6aaaa9354ffffffffe38fn,
],
[
0x0n,
0x5c759507e8e333ebb5b7a9a47d7ed8532c52d39fd3a042a88b58423c50ae15d5c2638e343d9c71c6238aaaaaaaa97ben,
],
[
0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706n,
0x1530477c7ab4113b59a4c18b076d11930f7da5d4a07f649bf54439d87d27e500fc8c25ebf8c92f6812cfc71c71c6d706n,
],
].map((pair) => Fp2.fromBigTuple(pair));
const yden = [
[0x1n, 0x0n],
[
0x12n,
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa99n,
],
[
0x0n,
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa9d3n,
],
[
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fbn,
0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffa8fbn,
],
].map((pair) => Fp2.fromBigTuple(pair));
const ISOGENY_COEFFICIENTS_G2 = [xnum, xden, ynum, yden];
const ISOGENY_COEFFICIENTS_G1 = [
[
new Fp(0x06e08c248e260e70bd1e962381edee3d31d79d7e22c837bc23c0bf1bc24c6b68c24b1b80b64d391fa9c8ba2e8ba2d229n),
new Fp(0x10321da079ce07e272d8ec09d2565b0dfa7dccdde6787f96d50af36003b14866f69b771f8c285decca67df3f1605fb7bn),
new Fp(0x169b1f8e1bcfa7c42e0c37515d138f22dd2ecb803a0c5c99676314baf4bb1b7fa3190b2edc0327797f241067be390c9en),
new Fp(0x080d3cf1f9a78fc47b90b33563be990dc43b756ce79f5574a2c596c928c5d1de4fa295f296b74e956d71986a8497e317n),
new Fp(0x17b81e7701abdbe2e8743884d1117e53356de5ab275b4db1a682c62ef0f2753339b7c8f8c8f475af9ccb5618e3f0c88en),
new Fp(0x0d6ed6553fe44d296a3726c38ae652bfb11586264f0f8ce19008e218f9c86b2a8da25128c1052ecaddd7f225a139ed84n),
new Fp(0x1630c3250d7313ff01d1201bf7a74ab5db3cb17dd952799b9ed3ab9097e68f90a0870d2dcae73d19cd13c1c66f652983n),
new Fp(0x0e99726a3199f4436642b4b3e4118e5499db995a1257fb3f086eeb65982fac18985a286f301e77c451154ce9ac8895d9n),
new Fp(0x1778e7166fcc6db74e0609d307e55412d7f5e4656a8dbf25f1b33289f1b330835336e25ce3107193c5b388641d9b6861n),
new Fp(0x0d54005db97678ec1d1048c5d10a9a1bce032473295983e56878e501ec68e25c958c3e3d2a09729fe0179f9dac9edcb0n),
new Fp(0x17294ed3e943ab2f0588bab22147a81c7c17e75b2f6a8417f565e33c70d1e86b4838f2a6f318c356e834eef1b3cb83bbn),
new Fp(0x11a05f2b1e833340b809101dd99815856b303e88a2d7005ff2627b56cdb4e2c85610c2d5f2e62d6eaeac1662734649b7n),
],
[
new Fp(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n),
new Fp(0x095fc13ab9e92ad4476d6e3eb3a56680f682b4ee96f7d03776df533978f31c1593174e4b4b7865002d6384d168ecdd0an),
new Fp(0x0a10ecf6ada54f825e920b3dafc7a3cce07f8d1d7161366b74100da67f39883503826692abba43704776ec3a79a1d641n),
new Fp(0x14a7ac2a9d64a8b230b3f5b074cf01996e7f63c21bca68a81996e1cdf9822c580fa5b9489d11e2d311f7d99bbdcc5a5en),
new Fp(0x0772caacf16936190f3e0c63e0596721570f5799af53a1894e2e073062aede9cea73b3538f0de06cec2574496ee84a3an),
new Fp(0x0e7355f8e4e667b955390f7f0506c6e9395735e9ce9cad4d0a43bcef24b8982f7400d24bc4228f11c02df9a29f6304a5n),
new Fp(0x13a8e162022914a80a6f1d5f43e7a07dffdfc759a12062bb8d6b44e833b306da9bd29ba81f35781d539d395b3532a21en),
new Fp(0x03425581a58ae2fec83aafef7c40eb545b08243f16b1655154cca8abc28d6fd04976d5243eecf5c4130de8938dc62cd8n),
new Fp(0x0b2962fe57a3225e8137e629bff2991f6f89416f5a718cd1fca64e00b11aceacd6a3d0967c94fedcfcc239ba5cb83e19n),
new Fp(0x12561a5deb559c4348b4711298e536367041e8ca0cf0800c0126c2588c48bf5713daa8846cb026e9e5c8276ec82b3bffn),
new Fp(0x08ca8d548cff19ae18b2e62f4bd3fa6f01d5ef4ba35b48ba9c9588617fc8ac62b558d681be343df8993cf9fa40d21b1cn),
],
[
new Fp(0x15e6be4e990f03ce4ea50b3b42df2eb5cb181d8f84965a3957add4fa95af01b2b665027efec01c7704b456be69c8b604n),
new Fp(0x05c129645e44cf1102a159f748c4a3fc5e673d81d7e86568d9ab0f5d396a7ce46ba1049b6579afb7866b1e715475224bn),
new Fp(0x0245a394ad1eca9b72fc00ae7be315dc757b3b080d4c158013e6632d3c40659cc6cf90ad1c232a6442d9d3f5db980133n),
new Fp(0x0b182cac101b9399d155096004f53f447aa7b12a3426b08ec02710e807b4633f06c851c1919211f20d4c04f00b971ef8n),
new Fp(0x18b46a908f36f6deb918c143fed2edcc523559b8aaf0c2462e6bfe7f911f643249d9cdf41b44d606ce07c8a4d0074d8en),
new Fp(0x19713e47937cd1be0dfd0b8f1d43fb93cd2fcbcb6caf493fd1183e416389e61031bf3a5cce3fbafce813711ad011c132n),
new Fp(0x0e1bba7a1186bdb5223abde7ada14a23c42a0ca7915af6fe06985e7ed1e4d43b9b3f7055dd4eba6f2bafaaebca731c30n),
new Fp(0x09fc4018bd96684be88c9e221e4da1bb8f3abd16679dc26c1e8b6e6a1f20cabe69d65201c78607a360370e577bdba587n),
new Fp(0x0987c8d5333ab86fde9926bd2ca6c674170a05bfe3bdd81ffd038da6c26c842642f64550fedfe935a15e4ca31870fb29n),
new Fp(0x04ab0b9bcfac1bbcb2c977d027796b3ce75bb8ca2be184cb5231413c4d634f3747a87ac2460f415ec961f8855fe9d6f2n),
new Fp(0x16603fca40634b6a2211e11db8f0a6a074a7d0d4afadb7bd76505c3d3ad5544e203f6326c95a807299b23ab13633a5f0n),
new Fp(0x08cc03fdefe0ff135caf4fe2a21529c4195536fbe3ce50b879833fd221351adc2ee7f8dc099040a841b6daecf2e8fedbn),
new Fp(0x01f86376e8981c217898751ad8746757d42aa7b90eeb791c09e4a3ec03251cf9de405aba9ec61deca6355c77b0e5f4cbn),
new Fp(0x00cc786baa966e66f4a384c86a3b49942552e2d658a31ce2c344be4b91400da7d26d521628b00523b8dfe240c72de1f6n),
new Fp(0x134996a104ee5811d51036d776fb46831223e96c254f383d0f906343eb67ad34d6c56711962fa8bfe097e75a2e41c696n),
new Fp(0x090d97c81ba24ee0259d1f094980dcfa11ad138e48a869522b52af6c956543d3cd0c7aee9b3ba3c2be9845719707bb33n),
],
[
new Fp(0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001n),
new Fp(0x0e0fa1d816ddc03e6b24255e0d7819c171c40f65e273b853324efcd6356caa205ca2f570f13497804415473a1d634b8fn),
new Fp(0x02660400eb2e4f3b628bdd0d53cd76f2bf565b94e72927c1cb748df27942480e420517bd8714cc80d1fadc1326ed06f7n),
new Fp(0x0ad6b9514c767fe3c3613144b45f1496543346d98adf02267d5ceef9a00d9b8693000763e3b90ac11e99b138573345ccn),
new Fp(0x0accbb67481d033ff5852c1e48c50c477f94ff8aefce42d28c0f9a88cea7913516f968986f7ebbea9684b529e2561092n),
new Fp(0x04d2f259eea405bd48f010a01ad2911d9c6dd039bb61a6290e591b36e636a5c871a5c29f4f83060400f8b49cba8f6aa8n),
new Fp(0x167a55cda70a6e1cea820597d94a84903216f763e13d87bb5308592e7ea7d4fbc7385ea3d529b35e346ef48bb8913f55n),
new Fp(0x1866c8ed336c61231a1be54fd1d74cc4f9fb0ce4c6af5920abc5750c4bf39b4852cfe2f7bb9248836b233d9d55535d4an),
new Fp(0x16a3ef08be3ea7ea03bcddfabba6ff6ee5a4375efa1f4fd7feb34fd206357132b920f5b00801dee460ee415a15812ed9n),
new Fp(0x166007c08a99db2fc3ba8734ace9824b5eecfdfa8d0cf8ef5dd365bc400a0051d5fa9c01a58b1fb93d1a1399126a775cn),
new Fp(0x08d9e5297186db2d9fb266eaac783182b70152c65550d881c5ecd87b6f0f5a6449f38db9dfa9cce202c6477faaf9b7acn),
new Fp(0x0be0e079545f43e4b00cc912f8228ddcc6d19c9f0f69bbb0542eda0fc9dec916a20b15dc0fd2ededda39142311a5001dn),
new Fp(0x16b7d288798e5395f20d23bf89edb4d1d115c5dbddbcd30e123da489e726af41727364f2c28297ada8d26d98445f5416n),
new Fp(0x058df3306640da276faaae7d6e8eb15778c4855551ae7f310c35a5dd279cd2eca6757cd636f96f891e2538b53dbf67f2n),
new Fp(0x1962d75c2381201e1a0cbd6c43c348b885c84ff731c4d59ca4a10356f453e01f78a4260763529e3532f6102c2e49a03dn),
new Fp(0x16112c4c3a9c98b252181140fad0eae9601a6de578980be6eec3232b5be72e7a07f3688ef60c206d01479253b03663c1n),
],
];
},{}],3:[function(require,module,exports){
const bls = require('..');
const G2_VECTORS = `db29a6e1db5d6dcb485f26c174d11dd0ab1ecc54125e31dde2949b03e925ef23::8e49a02dc374bb1702ec4c8aa514c6d72e0884d3611334ae749462eb545a4d0a6086ef0a6b1bbc5db2934d297bf766c60dbe665dfc33d3aa765d071712075b4102a71f518e16376fc58c982d30a6196fdd8319090bcb2728c9bbbd8045fc7863
28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4c:09:8647aa9680cd0cdf065b94e818ff2bb948cc97838bcee987b9bc1b76d0a0a6e0d85db4e9d75aaedfc79d4ea2733a21ae0579014de7636dd2943d45b87c82b1c66a289006b0b9767921bb8edd3f6c5c5dec0d54cd65f61513113c50cc977849e5
177c50ec35b1da25f68b9f7bad8f1c443a01fa2b20de37be0caec8b62db5c902:d2:8166ef48e7c1de5f8256a670511aad114f956382eed36f3bb45a7a1bf473e982f0e399924b4dc92795d043d9475402aa0d065e10f05a2026a0961882b6c2e6c6ae429edd17c7a43586a814121044e41c5c1d3397452b2fc61fdc523cc943ef68
e99d0f7a4f8a9e3f74a6bd9677b3fd5be32f7cea4e5b898ed3dea735fa647632:0d98:a70b42352845ca47713a20a243ec2aeb63bab7c4126d9cbd390b6f59372de383b93698c66f7e75452cbc569147b1f9f70be3b03539a4d110c65082f7918942b962543494469a5271208cdec9c234689bcae9c88c7cdc3ef9eefdf11a522794c6
2c864f383cd664839ce6d7d049f8083870b628d7bb8a4539cc84a35bbd723736:4a35:88c76ed5872fb011f4fc0fc8ff2751513dd6f22a9b7cb125ed39bdfffdd996ba1b5d9ea6332e8b4c34e591cb9dcf4efe112a096754db0d723269bb1a758f986d5e0cfbdcc22f8678f72f1804459c98be59ee7632c666206255dcaa816188cf2b
cd8ccf5c229e37a4a4b5490c84882af890cdc4c70170ad5f0ee2f3a86ffa3080:05caf3:83b4087858c3585a2f978fe1c79b94d9eb927500066e6c793392f1d5be2eff1ebfdd893555f6a89934f4e27ec810489a07f0740124c065fb82246a6d6f924f70069edfaf04fc4d1021f3314b9d09dfadc344fd2dcafaeb09586b194b3ea73374
43a5b55a3823acebca9e55face42697b5cd0e2398a44a56ebc22d936a05c3893:94b0b9:8b4f817e0815a9ca1fb91a5fd9e88714d72c2d6b4ea037ab43cde4149691109336edca72fb55936b5ba8f4576ffd49780dde24d48f9a9d5a07d1527ac3a9bc38c05a0fc58bac710cd4983c6cd21e56175a6e597954ac68207db1a8b86efe84cf
e2654a38c0148b5f0de1b8266737fdb6706fedc436d5fb70dc34bebe25b43d01:06a63bfb:b4a224ac879b67d20f452c40adac0b993560842e4dce928ace30751bc38d2a3a46e1f84dd1c04c0417ebaf069f5618f210c0dce7ae478f83a664f231e141b3fc677842bae20df43409476dde8c6a81cd1067999e6fae2896afe9630bc7441d3a
736057053101fbb9240808bfe83121382a8cd559a97f8633ae170b3e1ac9efee:0d83b078:b028a3c5877113519d0da87fd67edebcb80b37869f58505997c459fad745194407e004503fb49f4d9e0ea289d5cd9c63151c2d40e09cd3988cf7b0191718d4f4d07fa149c965fdc4a25fece97efd72fb9337099b5f47979c6acb9b30f0c2fbe3
dc7f613ec82e641c58d8390963ccb4cd307da37417aca9eec15b060fccdf73f3:0611983835:b4d7a115e96b4da4616b54bff471d5a9f7002100b61214337662f0aabf08a45ecdcdb581325cba3b5141a4083c301dcc10eeac2da4cd430ab1882e44cec5f8f08a789eb670653ab8072795e3d5724405bb6ffebde2e73229b353b17119f46e9c
ba4eeeefe05a4515509d64f21639c24dde05122815a9d89f1d8d31ba90f7e7aa:64726e3da8:8d6d9d1ee5febfb549e1f7a2f3e69f01918fc105ea710bae881b60fec8dcdbbb2ae3e00249d5b82eb4c598f557c139e00bcc5dd098afc74303a54937a81e98b4d2e75ee792021200f291918980ea274ef8ea2d712e265089230042348dd4b872
5737b8adab24e7ec10fdd0a420c603392cb2c43f6466d6033eb14d1012470dbb:07d6e7a31a2f:99d2bc134b268397759e77b7f59c26862264454a659b90664cd7ff9fd5701b083ef6aee3df959643816958515059e42205abf0c959ea64910c3bdbb447a1afca4caf271f7dbd50085d886c2e3f5294167ea3631767acfee5d89cb6e04def2dd8
ecca05ab2c52c1b4861357c01d628a8a7b0ca0b6c72219cf47822e72858752bc:aa07552a7358:9023090506aa3ec0b14b0650d302baa54976e26104d011f3e131a066f3f7dacbd8831e4bcefe5702e4c83323e4e6f7700b343a29e7d4cb7277712c59e83fe6ee788967c4721f783b81024c8317b4042e0f4fad3c41fd861b6050654bc529af70
b54f380ef6485006e52c279335e9aeb7adcf1dd24b02f6be0a25b6d0a70627b0:04583025f1b7da:897da4929a4ed71b70ba65e68f39f6f7967dbecbb97b610bd3ab23f6a08906ca44661523212a598f9a1e12e128c184440d1a56c2b64260c871e25ae5135b53944f7820aa74d20d48d90976cf60090427a442fa61e20f45ec6d0f348f6684fd32
7865bb94878bac2960a60393588ce3c0e92d6d8eda6c4ac2da5fd4d2fbffa48f:9398f8937e1821:b8d60310a2c5cc322ed412f340c3fc05723c446c47cc529f7e914916a5cb7d78e8af8400a6d07d62bc280daca12988cb1073a88ea7b4aa2dff821ae011342aa8a8de691ddd370a8ba942fd5cc6892acec84db889f6421bb1d71f02f5b7830a0a
97ec105f9f2487fa4b360eb484c4398add4c1fe8e274853e530292290e9b7a59:00dd6efc58fcd4ee:86c7fd60798ddc58d59de487a1ac4221e61efe70c188e78ac50b4d89ea022b592e472895595aa4725c9be82770cc05050fb0feacd6e1a3c062dfed9e6e63ae58838025cae35dcd8b1eaa90a3714e800b2cd0740d7262119e7abec3b5822d4497
8e9b0e1280b0433182df7eca995a7279e704f728a88ad0b26518ed0a19f62113:1b3d4c68e007f478:ab1832ae67d695f941decf959ebbce93bb33e70d60dfb53321f582f81be7d4177d0aef680c56a587e905c051355a78ad14574e0adcb083e2d6c972dbc54b68290abfc8c7abb9472ee210078eb62a3148764defb967768ab5be36d36c5aaf6455
281c1297034c8aaa2ea6368dd038833429673b99dd4da4622908de8d9674f99d:033d69a90f6073fceb:8bd05333f0d076558b8a25a75b76b14af7454f69452918d363a905a49089663e23c0ede69b4882790178a02ff83b8a3d0c945e6ce0e18c5c3abfb22c32e2bee71145fd319f4daef46463471df9691a372a8f30427c427fb025155109269ef363
6fbbae45973a06226abf29b6d978429cc2775b4af6c736f6fa1eecb042c3b089:b28bfd61695d25590c:90f9298f281b350add0e8b1789e99d38a42021ea971d1a0b1a28f8d11906602bd0a22eeee4b149443541f149721a926b0ddd2a496a88ac47a9f59e0a80aa91f88baa129035d2f2d38028ab024ac38ec0ae1768c1bcd156c2349a26e01b94a516
91a60d4b2440622e10f5ba7dc9585894b2125980fd5072cec4bbcd47ea49c57a:00581bba4bc7f26227a7:a95a631b6ea74646d9659f0d27a1e8c877e4018d47f81a32d0d0b203a724b980597880a84cdbe88cf41be05a58101e7a11b6de7b9bf7433e6c947e571b595b4496fff37f8a48d3eccab904ee824b31dd984c3f6c2a19acb52e895f1e326e788e
b211045d27b3c191a7961f521dedbb6ac8f6a362ab19ec28969d583c9a2eb128:e02c048d0609137492b9:a1e3e50c7a70c9d1028996c5bc79343c5780b16310a8b930704d3107e93bc92f7b927393fcf55d64461369f95aff557d0f346db8d83d02f0d914b50b706908cb631114c279be622bbc801bf5bd93245827a3c7ac06a30fa88e579ba2c5adbf99
342fb513e70e2a7cdee072a9d8c1cfc86aa9691687dbef91fca2d15870e4adaa:011ddb2e7d45df2e05fb8a:96324a72624c99ae74fc334cb8fe70885d7e9c840e4608e5b19a8a5ef8fe68277e7cac7c4b6889e206f6244dc49fc19a0a3ac2992e51d0f0076a528fa6c11afb4a3f127286714c1548a3c4c9eac7e67eb32bcd2c480e2c7d36504a5fa52d6ea1
498f8139fa03ac326e5ff321a9c8083d22eb048de74fcec128de3621a1dd5675:64024e14b436cb94e3209c:8723e4effda2455dd5d552bcf6116f88dd70187b031edb7660fa673ce22bd0fbe9ccaf28be6d9c78b783fa6310a0fda00b29cbce1adcef4204d31694bb47cc84de102d2dfab833e907887bcc8371119244b5b69b791c9dcd667e899971a37295
e5bcc31a88b1d23772bb5a282b8d8f7c0dd645b45b940027c1111ee13e62cfdf:00ca1d50caa232ab9ad64644:ab1e90fecee91a4c12537041281e91190e8bba02d503c491da48ab7b2fc9af11b01b168c83154c04f59c3e6d815665d6120d2547f7fba57d43ad9993c99e54c0b5488166c41416e29e9588d6b7e6d67c7d93c9be7ba3c7d769e0ccedec71b3a4
e5bfacb0667cd3db0634fd1eaa35b362d827a205db6cdce6daecbd83413ac6cf:3f1e6ffc1d7ec3e890d52615:ac3dcdb2751d982d80b77a749cf2f1f698f4dee8c9007043766c602104cbb0f633a4ce437098775062bf64aff77b2d66071dbc770e6ea04b11809f24ef50e6ec3ae5a58d58896bf9e78de80194eb67ce0d44e0232014ec300b63f90ef5c335bb
055873520343a11f937aa23abfdfee0d1929c461bd2fcfc85d8d07ef44230c69:04f00076b77983d6ee7ab6979d:afd0d6908f62ce579dde390b463d535dcfd1f5ee6664d46a583952c50178a61f15cf072153a21b4e6044dece53a755b1025170d84046c57252ea6c0a9c45ca42b0c77544e80856634e552c1e2b86eabf1f92535e1b27ea43281f8dc3a8672211
d58dd7364d214cd9ca9a5188ff8ad95486f65bf642d857c902fc6fd32a843510:49c83ddfa5b465abca1a8b5c78:a087f6bb963265cb95ff4914d4bae832a4fc89ff0616bcd8a529badca39a2c85b0ff3e1c418ec7979bcaf93a6d3dfc35108c420956c0795bdd81d2ce6f53a2f0a0bc37876db80bd0b59ce2210404a5c84d16330621aaaaad718e518dff1ef3cb
13ed1173e146edb9ae6a77e289155354d6e0107aa2fcd4dc89441619553448a3:07c50e920e060f06243084d32afe:a89faa2c99e76386d80f709e1af822e830385d07b0cc4bf8b46315273f0b11c9f77845e431d5bbb86d07e4b0e15c66bb1958e8d0728a0a0961e5f233fcba72278f5b0ffbbd67fbf62aa7b7a1572d9dababed755a60d37906dc30bdfc3d9d4c2e
5c3f7aef904cd9aa5cf093f993f49d46c3f20b7450552d52b23569239849f31b:6f455d61ee48d1990ec61dd70dbd:aaede5d58e5c71c170b2fbff350cb596bf43f2d0ee6b0e83f8863350ea4fd756129150e856c83e45734db8649a3617150c4a7a37ec596d89ff6cc6749dbe6d54f41cb36662279b3a82335e3f4b946afd94740e3214e93a45643bbabdac93a25c
00cc17223e74b58d2e465bad2f5d0ecc5a85081d143fc4b8ab8eb10b44c6c45f:0800350f624966388e327b17cbb9fa:8333c0c7d9da5f79c67ed5fd13d92bbc91c5680837cd0cf816f2876106720a93323477ba28dbce0f554ffc0f37db9fc20386aa12d005be7a2ce5a660ef8ff46c7381bd0446cabcc4a3f4b8b75b9608615ab2497beb425415c778c278f38a6d81
21fa64295c0fc47d81f69ba31d4661604c4d9eae6d2077c094ff758b1757e3c1::845c89e3bc5350275cc5b2669bda8ae127b8bf731517bb1bd5ebf0670add6df037f6b8c382aa03f729c5e8049e817dab0cc310e8af80d78cff447f034d32e7e7a1e8f27c8df390c5b640a7e341d6ab94311c4ae35a754f3990371c9186f97f0e
dd7466232c0fc5581e319721d4e0c7b773417432b0a0b756c3dc4e5cdff4723b:06:95f8a6c56e2de4742144e2213e13411f1a2d03ca783e509353276292fc97e087062b3050e967593e569e6ef80741adae0c5a7ab5bf0b0f0e7cd92d5e17181176ec2fe111e8306b9643901e228f0187bc9d429ca8cbd23a39be4bbb99bf29d84b`
.split('\n')
.map((l) => l.split(':'));
globalThis.runNobleBenchmark = (async () => {
const x = 1;
const priv = '28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4c';
const pubs = G2_VECTORS.map((v) => bls.getPublicKey(v[0]));
const sigs = G2_VECTORS.map((v) => v[2]);
const p1 = bls.PointG1.BASE.multiply(0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4cn);
const p2 = bls.PointG2.BASE.multiply(0x28b90deaf189015d3a325908c5e0e4bf00f84f7e639b056ff82d7e70b6eede4dn);
for (var i = 0; i < x * 4; i++) {
bls.pairing(p1, p2);
}
for (var i = 0; i < x * 50; i++) {
bls.getPublicKey(priv);
}
const pubp = bls.PointG1.fromPrivateKey(priv);
const msgp = await bls.PointG2.hashToCurve('09');
const sigp = bls.PointG2.fromSignature(await bls.sign('09', priv));
for (var i = 0; i < x * 4; i++) {
await bls.sign(msgp, priv);
}
for (var i = 0; i < x * 4; i++) {
await bls.verify(sigp, msgp, pubp);
}
const pub32 = pubs.map(bls.PointG1.fromHex);
const sig32 = sigs.map(bls.PointG2.fromSignature);
for (var i = 0; i < x * 50; i++) {
bls.aggregatePublicKeys(pub32);
}
for (var i = 0; i < x * 50; i++) {
bls.aggregateSignatures(sig32);
}
await bls.PointG1.hashToCurve('abcd');
await bls.PointG2.hashToCurve('abcd');
});
},{"..":1}],4:[function(require,module,exports){
},{}]},{},[3]);