mirror-jetstream/bigint/noble-bls12-381-bundle.js
Camillo Bruni 97f348ec9d Merge main
- Merge upstream main branch
- Partially merge https://github.com/WebKit/JetStream/pull/167/ to
  display sub-times

Change-Id: I9f30772ff2d6d068b09e43df3cb57da35b231ca2
Reviewed-on: https://chromium-review.googlesource.com/c/external/github.com/WebKit/JetStream/+/6911418
Reviewed-by: Victor Gomes <victorgomes@chromium.org>
2025-09-03 04:51:51 -07:00

2081 lines
87 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.

// 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.c1}×i)`;
}
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]);