From e440feedf8d2749bf59d6cf4a075374af332ada5 Mon Sep 17 00:00:00 2001 From: p4u Date: Fri, 26 Dec 2025 01:45:32 +0100 Subject: [PATCH] Add BLS12-377 support - Added src/bls12377.js with curve parameters. - Updated src/curves.js to support 'bls12377' curve name. - Exposed new curve in main entry point. --- build/browser.esm.js | 2128 ++++++++++++++++++++++++++++++++++++------ build/main.cjs | 168 +++- main.js | 2 +- src/bls12377.js | 62 ++ src/curves.js | 9 + 5 files changed, 2017 insertions(+), 352 deletions(-) create mode 100644 src/bls12377.js diff --git a/build/browser.esm.js b/build/browser.esm.js index 09713f3..3be9999 100644 --- a/build/browser.esm.js +++ b/build/browser.esm.js @@ -24,12 +24,12 @@ function fromArray(a, radix) { return acc; } -function bitLength$6(a) { +function bitLength$7(a) { const aS =a.toString(16); return (aS.length-1)*4 +hexLen[parseInt(aS[0], 16)]; } -function isNegative$4(a) { +function isNegative$5(a) { return BigInt(a) < BigInt(0); } @@ -48,7 +48,7 @@ function shiftRight(a, n) { const shl = shiftLeft; const shr = shiftRight; -function isOdd$5(a) { +function isOdd$6(a) { return (BigInt(a) & BigInt(1)) == BigInt(1); } @@ -237,7 +237,7 @@ function toString(a, radix) { } function toLEBuff(a) { - const buff = new Uint8Array(Math.floor((bitLength$6(a) - 1) / 8) +1); + const buff = new Uint8Array(Math.floor((bitLength$7(a) - 1) / 8) +1); toRprLE(buff, 0, a, buff.byteLength); return buff; } @@ -247,51 +247,51 @@ const one = e(1); var _Scalar = /*#__PURE__*/Object.freeze({ __proto__: null, - abs: abs$1, - add: add, - band: band, - bitLength: bitLength$6, - bits: bits, - bor: bor, - bxor: bxor, - div: div, + fromString: fromString, e: e, - eq: eq, - exp: exp$1, fromArray: fromArray, - fromRprBE: fromRprBE, - fromRprLE: fromRprLE, - fromString: fromString, - geq: geq, - gt: gt, - isNegative: isNegative$4, - isOdd: isOdd$5, + bitLength: bitLength$7, + isNegative: isNegative$5, isZero: isZero$1, - land: land, - leq: leq, - lnot: lnot, - lor: lor, - lt: lt, - mod: mod, - mul: mul, - naf: naf, - neg: neg, - neq: neq, - one: one, - pow: pow, shiftLeft: shiftLeft, shiftRight: shiftRight, shl: shl, shr: shr, - square: square$2, - sub: sub, - toArray: toArray, - toLEBuff: toLEBuff, + isOdd: isOdd$6, + naf: naf, + bits: bits, toNumber: toNumber$1, - toRprBE: toRprBE, + toArray: toArray, + add: add, + sub: sub, + neg: neg, + mul: mul, + square: square$2, + pow: pow, + exp: exp$1, + abs: abs$1, + div: div, + mod: mod, + eq: eq, + neq: neq, + lt: lt, + gt: gt, + leq: leq, + geq: geq, + band: band, + bor: bor, + bxor: bxor, + land: land, + lor: lor, + lnot: lnot, toRprLE: toRprLE, + toRprBE: toRprBE, + fromRprLE: fromRprLE, + fromRprBE: fromRprBE, toString: toString, - zero: zero + toLEBuff: toLEBuff, + zero: zero, + one: one }); /* @@ -931,7 +931,6 @@ function __bitReverse(p, bits) { */ - function mulScalar(F, base, e) { let res; @@ -1045,7 +1044,7 @@ function alg5_tonelliShanks(F) { F.sqrt_s = 0; F.sqrt_t = sub(F.sqrt_q, 1); - while (!isOdd$5(F.sqrt_t)) { + while (!isOdd$6(F.sqrt_t)) { F.sqrt_s = F.sqrt_s + 1; F.sqrt_t = div(F.sqrt_t, 2); } @@ -1453,7 +1452,7 @@ class ZqField { this.negone = this.p-this.one; this.two = BigInt(2); this.half = this.p >> this.one; - this.bitLength = bitLength$6(this.p); + this.bitLength = bitLength$7(this.p); this.mask = (this.one << BigInt(this.bitLength)) - this.one; this.n64 = Math.floor((this.bitLength - 1) / 64)+1; @@ -1822,7 +1821,6 @@ class ZqField { snarkjs. If not, see . */ - class F2Field { constructor(F, nonResidue) { this.type="F2"; @@ -2060,7 +2058,6 @@ class F2Field { snarkjs. If not, see . */ - class F3Field { constructor(F, nonResidue) { this.type="F3"; @@ -2345,7 +2342,6 @@ class F3Field { */ - function isGreatest(F, a) { if (Array.isArray(a)) { for (let i=a.length-1; i>=0; i--) { @@ -2757,7 +2753,7 @@ class EC { } -var utils$6 = {}; +var utils$7 = {}; /* Copyright 2019 0KIMS association. @@ -2778,7 +2774,7 @@ var utils$6 = {}; along with wasmsnark. If not, see . */ -utils$6.bigInt2BytesLE = function bigInt2BytesLE(_a, len) { +utils$7.bigInt2BytesLE = function bigInt2BytesLE(_a, len) { const b = Array(len); let v = BigInt(_a); for (let i=0; i 0n; } -function bitLength$5(n) { - if (isNegative$3(n)) { +function bitLength$6(n) { + if (isNegative$4(n)) { return n.toString(2).length - 1; // discard the - sign } else { return n.toString(2).length; @@ -4354,7 +4350,7 @@ function modInv$3(a, n) { if (compare(t, 0n) === -1) { t = t + n; } - if (isNegative$3(a)) { + if (isNegative$4(a)) { return -t; } return t; @@ -4364,13 +4360,13 @@ function modPow$2(n, exp, mod) { if (mod === 0n) throw new Error("Cannot take modPow with modulus 0"); var r = 1n, base = n % mod; - if (isNegative$3(exp)) { + if (isNegative$4(exp)) { exp = exp * -1n; base = modInv$3(base, mod); } while (isPositive(exp)) { if (base === 0n) return 0n; - if (isOdd$4(exp)) r = r * base % mod; + if (isOdd$5(exp)) r = r * base % mod; exp = exp / 2n; base = square$1(base) % mod; } @@ -4427,7 +4423,7 @@ function isPrime$1(p) { var isPrime = isBasicPrime(p); if (isPrime !== undefined) return isPrime; var n = abs(p); - var bits = bitLength$5(n); + var bits = bitLength$6(n); if (bits <= 64) return millerRabinTest(n, [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37]); var logN = Math.log(2) * Number(bits); @@ -4438,9 +4434,9 @@ function isPrime$1(p) { return millerRabinTest(n, a); } -bigint.bitLength = bitLength$5; -bigint.isOdd = isOdd$4; -bigint.isNegative = isNegative$3; +bigint.bitLength = bitLength$6; +bigint.isOdd = isOdd$5; +bigint.isNegative = isNegative$4; bigint.abs = abs; bigint.isUnit = isUnit; bigint.compare = compare; @@ -4469,16 +4465,16 @@ bigint.square = square$1; */ const buildInt = build_int; -const utils$5 = utils$6; +const utils$6 = utils$7; const buildExp$2 = build_timesscalar; const buildBatchInverse$2 = build_batchinverse; const buildBatchConvertion$1 = build_batchconvertion; const buildBatchOp = build_batchop; -const { bitLength: bitLength$4, modInv: modInv$2, modPow: modPow$1, isPrime, isOdd: isOdd$3, square } = bigint; +const { bitLength: bitLength$5, modInv: modInv$2, modPow: modPow$1, isPrime, isOdd: isOdd$4, square } = bigint; var build_f1m = function buildF1m(module, _q, _prefix, _intPrefix) { const q = BigInt(_q); - const n64 = Math.floor((bitLength$4(q - 1n) - 1)/64) +1; + const n64 = Math.floor((bitLength$5(q - 1n) - 1)/64) +1; const n32 = n64*2; const n8 = n64*8; @@ -4486,17 +4482,17 @@ var build_f1m = function buildF1m(module, _q, _prefix, _intPrefix) { if (module.modules[prefix]) return prefix; // already builded const intPrefix = buildInt(module, n64, _intPrefix); - const pq = module.alloc(n8, utils$5.bigInt2BytesLE(q, n8)); + const pq = module.alloc(n8, utils$6.bigInt2BytesLE(q, n8)); - const pR2 = module.alloc(utils$5.bigInt2BytesLE(square(1n << BigInt(n64*64)) % q, n8)); - const pOne = module.alloc(utils$5.bigInt2BytesLE((1n << BigInt(n64*64)) % q, n8)); - const pZero = module.alloc(utils$5.bigInt2BytesLE(0n, n8)); + const pR2 = module.alloc(utils$6.bigInt2BytesLE(square(1n << BigInt(n64*64)) % q, n8)); + const pOne = module.alloc(utils$6.bigInt2BytesLE((1n << BigInt(n64*64)) % q, n8)); + const pZero = module.alloc(utils$6.bigInt2BytesLE(0n, n8)); const _minusOne = q - 1n; const _e = _minusOne >> 1n; // e = (p-1)/2 - const pe = module.alloc(n8, utils$5.bigInt2BytesLE(_e, n8)); + const pe = module.alloc(n8, utils$6.bigInt2BytesLE(_e, n8)); const _ePlusOne = _e + 1n; // e = (p-1)/2 - const pePlusOne = module.alloc(n8, utils$5.bigInt2BytesLE(_ePlusOne, n8)); + const pePlusOne = module.alloc(n8, utils$6.bigInt2BytesLE(_ePlusOne, n8)); module.modules[prefix] = { pq: pq, @@ -5247,17 +5243,17 @@ var build_f1m = function buildF1m(module, _q, _prefix, _intPrefix) { let s2 = 0; let _t = _minusOne; - while ((!isOdd$3(_t))&&(_t !== 0n)) { + while ((!isOdd$4(_t))&&(_t !== 0n)) { s2++; _t = _t >> 1n; } - const pt = module.alloc(n8, utils$5.bigInt2BytesLE(_t, n8)); + const pt = module.alloc(n8, utils$6.bigInt2BytesLE(_t, n8)); const _nqrToT = modPow$1(_nqr, _t, q); - const pNqrToT = module.alloc(utils$5.bigInt2BytesLE((_nqrToT << BigInt(n64*64)) % q, n8)); + const pNqrToT = module.alloc(utils$6.bigInt2BytesLE((_nqrToT << BigInt(n64*64)) % q, n8)); const _tPlusOneOver2 = (_t + 1n) >> 1n; - const ptPlusOneOver2 = module.alloc(n8, utils$5.bigInt2BytesLE(_tPlusOneOver2, n8)); + const ptPlusOneOver2 = module.alloc(n8, utils$6.bigInt2BytesLE(_tPlusOneOver2, n8)); function buildSqrt() { @@ -5530,13 +5526,13 @@ var build_f1m = function buildF1m(module, _q, _prefix, _intPrefix) { along with wasmsnark. If not, see . */ -const buildF1m$2 =build_f1m; -const { bitLength: bitLength$3 } = bigint; +const buildF1m$3 =build_f1m; +const { bitLength: bitLength$4 } = bigint; var build_f1 = function buildF1(module, _q, _prefix, _f1mPrefix, _intPrefix) { const q = BigInt(_q); - const n64 = Math.floor((bitLength$3(q - 1n) - 1)/64) +1; + const n64 = Math.floor((bitLength$4(q - 1n) - 1)/64) +1; const n8 = n64*8; const prefix = _prefix || "f1"; @@ -5546,7 +5542,7 @@ var build_f1 = function buildF1(module, _q, _prefix, _f1mPrefix, _intPrefix) { }; const intPrefix = _intPrefix || "int"; - const f1mPrefix = buildF1m$2(module, q, _f1mPrefix, intPrefix); + const f1mPrefix = buildF1m$3(module, q, _f1mPrefix, intPrefix); const pR2 = module.modules[f1mPrefix].pR2; @@ -5641,7 +5637,7 @@ var build_f1 = function buildF1(module, _q, _prefix, _f1mPrefix, _intPrefix) { const buildExp$1 = build_timesscalar; const buildBatchInverse$1 = build_batchinverse; -const utils$4 = utils$6; +const utils$5 = utils$7; var build_f2m = function buildF2m(module, mulNonResidueFn, prefix, f1mPrefix) { @@ -6082,9 +6078,9 @@ var build_f2m = function buildF2m(module, mulNonResidueFn, prefix, f1mPrefix) { const c = f.getCodeBuilder(); // BigInt can't take `undefined` so we use `|| 0` - const e34 = c.i32_const(module.alloc(utils$4.bigInt2BytesLE((BigInt(q || 0) - 3n) / 4n, f1n8 ))); + const e34 = c.i32_const(module.alloc(utils$5.bigInt2BytesLE((BigInt(q || 0) - 3n) / 4n, f1n8 ))); // BigInt can't take `undefined` so we use `|| 0` - const e12 = c.i32_const(module.alloc(utils$4.bigInt2BytesLE((BigInt(q || 0) - 1n) / 2n, f1n8 ))); + const e12 = c.i32_const(module.alloc(utils$5.bigInt2BytesLE((BigInt(q || 0) - 1n) / 2n, f1n8 ))); const a = c.getLocal("a"); const a1 = c.i32_const(module.alloc(f1n8*2)); @@ -6152,7 +6148,7 @@ var build_f2m = function buildF2m(module, mulNonResidueFn, prefix, f1mPrefix) { const c = f.getCodeBuilder(); // BigInt can't take `undefined` so we use `|| 0` - const e34 = c.i32_const(module.alloc(utils$4.bigInt2BytesLE((BigInt(q || 0) - 3n) / 4n, f1n8 ))); + const e34 = c.i32_const(module.alloc(utils$5.bigInt2BytesLE((BigInt(q || 0) - 3n) / 4n, f1n8 ))); const a = c.getLocal("a"); const a1 = c.i32_const(module.alloc(f1n8*2)); @@ -9067,8 +9063,8 @@ var build_curve_jacobian_a0 = function buildCurve(module, prefix, prefixField, p along with wasmsnark. If not, see . */ -const { isOdd: isOdd$2, modInv: modInv$1, modPow } = bigint; -const utils$3 = utils$6; +const { isOdd: isOdd$3, modInv: modInv$1, modPow } = bigint; +const utils$4 = utils$7; var build_fft = function buildFFT(module, prefix, gPrefix, fPrefix, opGtimesF) { @@ -9082,7 +9078,7 @@ var build_fft = function buildFFT(module, prefix, gPrefix, fPrefix, opGtimesF) { let rem = q - 1n; let maxBits = 0; - while (!isOdd$2(rem)) { + while (!isOdd$3(rem)) { maxBits ++; rem = rem >> 1n; } @@ -9107,7 +9103,7 @@ var build_fft = function buildFFT(module, prefix, gPrefix, fPrefix, opGtimesF) { for (let i=0; i 0n) { - if (isOdd$1(E)) { + if (isOdd$2(E)) { const z = 2 - Number(E % 4n); res.push( z ); E = E - BigInt(z); @@ -11296,7 +11292,7 @@ var build_bn128 = function buildBN128(module, _prefix) { let E = n; const res = []; while (E > 0n) { - if (isOdd$1(E)) { + if (isOdd$2(E)) { res.push( 1 ); } else { res.push( 0 ); @@ -11515,13 +11511,13 @@ var build_bn128 = function buildBN128(module, _prefix) { const z3 = c.i32_add(c.getLocal("pr"), c.i32_const(f2size*2)); const MulByQX = c.i32_const(module.alloc([ - ...utils$2.bigInt2BytesLE( toMontgomery("21575463638280843010398324269430826099269044274347216827212613867836435027261"), f1size ), - ...utils$2.bigInt2BytesLE( toMontgomery("10307601595873709700152284273816112264069230130616436755625194854815875713954"), f1size ), + ...utils$3.bigInt2BytesLE( toMontgomery("21575463638280843010398324269430826099269044274347216827212613867836435027261"), f1size ), + ...utils$3.bigInt2BytesLE( toMontgomery("10307601595873709700152284273816112264069230130616436755625194854815875713954"), f1size ), ])); const MulByQY = c.i32_const(module.alloc([ - ...utils$2.bigInt2BytesLE( toMontgomery("2821565182194536844548159561693502659359617185244120367078079554186484126554"), f1size ), - ...utils$2.bigInt2BytesLE( toMontgomery("3505843767911556378687030309984248845540243509899259641013678093033130930403"), f1size ), + ...utils$3.bigInt2BytesLE( toMontgomery("2821565182194536844548159561693502659359617185244120367078079554186484126554"), f1size ), + ...utils$3.bigInt2BytesLE( toMontgomery("3505843767911556378687030309984248845540243509899259641013678093033130930403"), f1size ), ])); f.addCode( @@ -11936,8 +11932,8 @@ var build_bn128 = function buildBN128(module, _prefix) { const Rc1 = c.i32_add(c.getLocal("r"), c.i32_const(i*f2size + f1size)); const coef = mul2(F12[Math.floor(i/3)][n%12] , F6[i%3][n%6]); const pCoef = module.alloc([ - ...utils$2.bigInt2BytesLE(toMontgomery(coef[0]), 32), - ...utils$2.bigInt2BytesLE(toMontgomery(coef[1]), 32), + ...utils$3.bigInt2BytesLE(toMontgomery(coef[0]), 32), + ...utils$3.bigInt2BytesLE(toMontgomery(coef[1]), 32), ]); if (n%2 == 1) { f.addCode( @@ -11959,7 +11955,7 @@ var build_bn128 = function buildBN128(module, _prefix) { (ac0 * bc0 - ( ac1 * bc1) ) % q, (ac0 * bc1 + ( ac1 * bc0) ) % q, ]; - if (isNegative$2(res[0])) res[0] = res[0] + q; + if (isNegative$3(res[0])) res[0] = res[0] + q; return res; } @@ -12289,7 +12285,7 @@ var build_bn128 = function buildBN128(module, _prefix) { const exponent = 552484233613224096312617126783173147097382103762957654188882734314196910839907541213974502761540629817009608548654680343627701153829446747810907373256841551006201639677726139946029199968412598804882391702273019083653272047566316584365559776493027495458238373902875937659943504873220554161550525926302303331747463515644711876653177129578303191095900909191624817826566688241804408081892785725967931714097716709526092261278071952560171111444072049229123565057483750161460024353346284167282452756217662335528813519139808291170539072125381230815729071544861602750936964829313608137325426383735122175229541155376346436093930287402089517426973178917569713384748081827255472576937471496195752727188261435633271238710131736096299798168852925540549342330775279877006784354801422249722573783561685179618816480037695005515426162362431072245638324744480n; - const pExponent = module.alloc(utils$2.bigInt2BytesLE( exponent, 352 )); + const pExponent = module.alloc(utils$3.bigInt2BytesLE( exponent, 352 )); const c = f.getCodeBuilder(); @@ -12397,18 +12393,18 @@ var build_bn128 = function buildBN128(module, _prefix) { }; -const utils$1 = utils$6; +const utils$2 = utils$7; -const buildF1m =build_f1m; -const buildF1 =build_f1; -const buildF2m =build_f2m; -const buildF3m =build_f3m; -const buildCurve =build_curve_jacobian_a0; -const buildFFT$1 = build_fft; -const buildPol = build_pol; -const buildQAP = build_qap; -const buildApplyKey = build_applykey; -const { bitLength: bitLength$1, isOdd, isNegative: isNegative$1 } = bigint; +const buildF1m$1 =build_f1m; +const buildF1$1 =build_f1; +const buildF2m$1 =build_f2m; +const buildF3m$1 =build_f3m; +const buildCurve$1 =build_curve_jacobian_a0; +const buildFFT$2 = build_fft; +const buildPol$1 = build_pol; +const buildQAP$1 = build_qap; +const buildApplyKey$1 = build_applykey; +const { bitLength: bitLength$2, isOdd: isOdd$1, isNegative: isNegative$2 } = bigint; // Definition here: https://electriccoin.co/blog/new-snark-curve/ @@ -12421,35 +12417,35 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const q = 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn; const r = 0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001n; - const n64q = Math.floor((bitLength$1(q - 1n) - 1)/64) +1; + const n64q = Math.floor((bitLength$2(q - 1n) - 1)/64) +1; const n8q = n64q*8; const f1size = n8q; const f2size = f1size * 2; const ftsize = f1size * 12; - const n64r = Math.floor((bitLength$1(r - 1n) - 1)/64) +1; + const n64r = Math.floor((bitLength$2(r - 1n) - 1)/64) +1; const n8r = n64r*8; const frsize = n8r; - const pr = module.alloc(utils$1.bigInt2BytesLE( r, frsize )); + const pr = module.alloc(utils$2.bigInt2BytesLE( r, frsize )); - const f1mPrefix = buildF1m(module, q, "f1m", "intq"); - buildF1(module, r, "fr", "frm", "intr"); - const pG1b = module.alloc(utils$1.bigInt2BytesLE( toMontgomery(4n), f1size )); - const g1mPrefix = buildCurve(module, "g1m", "f1m", pG1b); + const f1mPrefix = buildF1m$1(module, q, "f1m", "intq"); + buildF1$1(module, r, "fr", "frm", "intr"); + const pG1b = module.alloc(utils$2.bigInt2BytesLE( toMontgomery(4n), f1size )); + const g1mPrefix = buildCurve$1(module, "g1m", "f1m", pG1b); - buildFFT$1(module, "frm", "frm", "frm", "frm_mul"); + buildFFT$2(module, "frm", "frm", "frm", "frm_mul"); - buildPol(module, "pol", "frm"); - buildQAP(module, "qap", "frm"); + buildPol$1(module, "pol", "frm"); + buildQAP$1(module, "qap", "frm"); - const f2mPrefix = buildF2m(module, "f1m_neg", "f2m", "f1m"); + const f2mPrefix = buildF2m$1(module, "f1m_neg", "f2m", "f1m"); const pG2b = module.alloc([ - ...utils$1.bigInt2BytesLE( toMontgomery(4n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(4n), f1size ) + ...utils$2.bigInt2BytesLE( toMontgomery(4n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(4n), f1size ) ]); - const g2mPrefix = buildCurve(module, "g2m", "f2m", pG2b); + const g2mPrefix = buildCurve$1(module, "g2m", "f2m", pG2b); function buildGTimesFr(fnName, opMul) { @@ -12476,19 +12472,19 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { module.exportFunction(fnName); } buildGTimesFr("g1m_timesFr", "g1m_timesScalar"); - buildFFT$1(module, "g1m", "g1m", "frm", "g1m_timesFr"); + buildFFT$2(module, "g1m", "g1m", "frm", "g1m_timesFr"); buildGTimesFr("g2m_timesFr", "g2m_timesScalar"); - buildFFT$1(module, "g2m", "g2m", "frm", "g2m_timesFr"); + buildFFT$2(module, "g2m", "g2m", "frm", "g2m_timesFr"); buildGTimesFr("g1m_timesFrAffine", "g1m_timesScalarAffine"); buildGTimesFr("g2m_timesFrAffine", "g2m_timesScalarAffine"); - buildApplyKey(module, "frm_batchApplyKey", "fmr", "frm", n8r, n8r, n8r, "frm_mul"); - buildApplyKey(module, "g1m_batchApplyKey", "g1m", "frm", n8q*3, n8q*3, n8r, "g1m_timesFr"); - buildApplyKey(module, "g1m_batchApplyKeyMixed", "g1m", "frm", n8q*2, n8q*3, n8r, "g1m_timesFrAffine"); - buildApplyKey(module, "g2m_batchApplyKey", "g2m", "frm", n8q*2*3, n8q*3*2, n8r, "g2m_timesFr"); - buildApplyKey(module, "g2m_batchApplyKeyMixed", "g2m", "frm", n8q*2*2, n8q*3*2, n8r, "g2m_timesFrAffine"); + buildApplyKey$1(module, "frm_batchApplyKey", "fmr", "frm", n8r, n8r, n8r, "frm_mul"); + buildApplyKey$1(module, "g1m_batchApplyKey", "g1m", "frm", n8q*3, n8q*3, n8r, "g1m_timesFr"); + buildApplyKey$1(module, "g1m_batchApplyKeyMixed", "g1m", "frm", n8q*2, n8q*3, n8r, "g1m_timesFrAffine"); + buildApplyKey$1(module, "g2m_batchApplyKey", "g2m", "frm", n8q*2*3, n8q*3*2, n8r, "g2m_timesFr"); + buildApplyKey$1(module, "g2m_batchApplyKeyMixed", "g2m", "frm", n8q*2*2, n8q*3*2, n8r, "g2m_timesFrAffine"); function toMontgomery(a) { @@ -12503,9 +12499,9 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const pG1gen = module.alloc( [ - ...utils$1.bigInt2BytesLE( toMontgomery(G1gen[0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G1gen[1]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G1gen[2]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G1gen[0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G1gen[1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G1gen[2]), f1size ), ] ); @@ -12517,9 +12513,9 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const pG1zero = module.alloc( [ - ...utils$1.bigInt2BytesLE( toMontgomery(G1zero[0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G1zero[1]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G1zero[2]), f1size ) + ...utils$2.bigInt2BytesLE( toMontgomery(G1zero[0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G1zero[1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G1zero[2]), f1size ) ] ); @@ -12538,12 +12534,12 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const pG2gen = module.alloc( [ - ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[0][0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[0][1]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[1][0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[1][1]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[2][0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[2][1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2gen[0][0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2gen[0][1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2gen[1][0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2gen[1][1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2gen[2][0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2gen[2][1]), f1size ), ] ); @@ -12562,33 +12558,33 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const pG2zero = module.alloc( [ - ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[0][0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[0][1]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[1][0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[1][1]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[2][0]), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[2][1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2zero[0][0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2zero[0][1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2zero[1][0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2zero[1][1]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2zero[2][0]), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(G2zero[2][1]), f1size ), ] ); const pOneT = module.alloc([ - ...utils$1.bigInt2BytesLE( toMontgomery(1n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(1n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(0n), f1size ), ]); const pBls12381Twist = module.alloc([ - ...utils$1.bigInt2BytesLE( toMontgomery(1n), f1size ), - ...utils$1.bigInt2BytesLE( toMontgomery(1n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(1n), f1size ), + ...utils$2.bigInt2BytesLE( toMontgomery(1n), f1size ), ]); function build_mulNR2() { @@ -12612,7 +12608,7 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { } build_mulNR2(); - const f6mPrefix = buildF3m(module, f2mPrefix+"_mulNR", "f6m", "f2m"); + const f6mPrefix = buildF3m$1(module, f2mPrefix+"_mulNR", "f6m", "f2m"); function build_mulNR6() { const f = module.addFunction(f6mPrefix + "_mulNR"); @@ -12648,7 +12644,7 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { } build_mulNR6(); - const ftmPrefix = buildF2m(module, f6mPrefix+"_mulNR", "ftm", f6mPrefix); + const ftmPrefix = buildF2m$1(module, f6mPrefix+"_mulNR", "ftm", f6mPrefix); const ateLoopCount = 0xd201000000010000n; const ateLoopBitBytes = bits(ateLoopCount); @@ -12690,7 +12686,7 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { let E = n; const res = []; while (E > 0n) { - if (isOdd(E)) { + if (isOdd$1(E)) { const z = 2 - Number(E % 4n); res.push( z ); E = E - BigInt(z); @@ -12706,7 +12702,7 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { let E = n; const res = []; while (E > 0n) { - if (isOdd(E)) { + if (isOdd$1(E)) { res.push( 1 ); } else { res.push( 0 ); @@ -13373,8 +13369,8 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const Rc1 = c.i32_add(c.getLocal("r"), c.i32_const(i*f2size + f1size)); const coef = mul2(F12[Math.floor(i/3)][n%12] , F6[i%3][n%6]); const pCoef = module.alloc([ - ...utils$1.bigInt2BytesLE(toMontgomery(coef[0]), n8q), - ...utils$1.bigInt2BytesLE(toMontgomery(coef[1]), n8q), + ...utils$2.bigInt2BytesLE(toMontgomery(coef[0]), n8q), + ...utils$2.bigInt2BytesLE(toMontgomery(coef[1]), n8q), ]); if (n%2 == 1) { f.addCode( @@ -13396,7 +13392,7 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { (ac0 * bc0 - (ac1 * bc1)) % q, (ac0 * bc1 + (ac1 * bc0)) % q, ]; - if (isNegative$1(res[0])) res[0] = res[0] + q; + if (isNegative$2(res[0])) res[0] = res[0] + q; return res; } @@ -13693,7 +13689,7 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const exponent = 322277361516934140462891564586510139908379969514828494218366688025288661041104682794998680497580008899973249814104447692778988208376779573819485263026159588510513834876303014016798809919343532899164848730280942609956670917565618115867287399623286813270357901731510188149934363360381614501334086825442271920079363289954510565375378443704372994881406797882676971082200626541916413184642520269678897559532260949334760604962086348898118982248842634379637598665468817769075878555493752214492790122785850202957575200176084204422751485957336465472324810982833638490904279282696134323072515220044451592646885410572234451732790590013479358343841220074174848221722017083597872017638514103174122784843925578370430843522959600095676285723737049438346544753168912974976791528535276317256904336520179281145394686565050419250614107803233314658825463117900250701199181529205942363159325765991819433914303908860460720581408201373164047773794825411011922305820065611121544561808414055302212057471395719432072209245600258134364584636810093520285711072578721435517884103526483832733289802426157301542744476740008494780363354305116978805620671467071400711358839553375340724899735460480144599782014906586543813292157922220645089192130209334926661588737007768565838519456601560804957985667880395221049249803753582637708560n; - const pExponent = module.alloc(utils$1.bigInt2BytesLE( exponent, 544 )); + const pExponent = module.alloc(utils$2.bigInt2BytesLE( exponent, 544 )); const c = f.getCodeBuilder(); @@ -13789,17 +13785,17 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { ]; const wInv = c.i32_const(module.alloc([ - ...utils$1.bigInt2BytesLE(toMontgomery(WINV[0]), n8q), - ...utils$1.bigInt2BytesLE(toMontgomery(WINV[1]), n8q), + ...utils$2.bigInt2BytesLE(toMontgomery(WINV[0]), n8q), + ...utils$2.bigInt2BytesLE(toMontgomery(WINV[1]), n8q), ])); - const frob2X = c.i32_const(module.alloc(utils$1.bigInt2BytesLE(toMontgomery(FROB2X), n8q))); + const frob2X = c.i32_const(module.alloc(utils$2.bigInt2BytesLE(toMontgomery(FROB2X), n8q))); const frob3Y = c.i32_const(module.alloc([ - ...utils$1.bigInt2BytesLE(toMontgomery(FROB3Y[0]), n8q), - ...utils$1.bigInt2BytesLE(toMontgomery(FROB3Y[1]), n8q), + ...utils$2.bigInt2BytesLE(toMontgomery(FROB3Y[0]), n8q), + ...utils$2.bigInt2BytesLE(toMontgomery(FROB3Y[1]), n8q), ])); - const z = c.i32_const(module.alloc(utils$1.bigInt2BytesLE(finalExpZ, 8))); + const z = c.i32_const(module.alloc(utils$2.bigInt2BytesLE(finalExpZ, 8))); const px = c.getLocal("p"); const py = c.i32_add(c.getLocal("p"), c.i32_const(f2size)); @@ -13900,10 +13896,10 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { const BETA2 = 793479390729215512621379701633421447060886740281060493010456487427281649075476305620758731620350n; const Z2M1D3 = (finalExpZ * finalExpZ - 1n) / 3n; - const beta = c.i32_const(module.alloc(utils$1.bigInt2BytesLE(toMontgomery(BETA), n8q))); - const beta2 = c.i32_const(module.alloc(utils$1.bigInt2BytesLE(toMontgomery(BETA2), n8q))); + const beta = c.i32_const(module.alloc(utils$2.bigInt2BytesLE(toMontgomery(BETA), n8q))); + const beta2 = c.i32_const(module.alloc(utils$2.bigInt2BytesLE(toMontgomery(BETA2), n8q))); - const z2m1d3 = c.i32_const(module.alloc(utils$1.bigInt2BytesLE(Z2M1D3, 16))); + const z2m1d3 = c.i32_const(module.alloc(utils$2.bigInt2BytesLE(Z2M1D3, 16))); const px = c.getLocal("p"); @@ -14015,52 +14011,1518 @@ var build_bls12381 = function buildBLS12381(module, _prefix) { // console.log(module.functionIdxByName); }; -/* - Copyright 2019 0KIMS association. +const utils$1 = utils$7; - This file is part of wasmsnark (Web Assembly zkSnark Prover). +const buildF1m = build_f1m; +const buildF1 = build_f1; +const buildF2m = build_f2m; +const buildF3m = build_f3m; +const buildCurve = build_curve_jacobian_a0; +const buildFFT$1 = build_fft; +const buildPol = build_pol; +const buildQAP = build_qap; +const buildApplyKey = build_applykey; +const { bitLength: bitLength$1, isOdd, isNegative: isNegative$1 } = bigint; - wasmsnark is a free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. +// Definition here: https://electriccoin.co/blog/new-snark-curve/ - wasmsnark is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public - License for more details. +var build_bls12377 = function buildBLS12377(module, _prefix) { - You should have received a copy of the GNU General Public License - along with wasmsnark. If not, see . -*/ + const prefix = _prefix || "bls12377"; -// module.exports.bn128_wasm = require("./build/bn128_wasm.js"); -// module.exports.bls12381_wasm = require("./build/bls12381_wasm.js"); -// module.exports.mnt6753_wasm = require("./build/mnt6753_wasm.js"); + if (module.modules[prefix]) return prefix; // already builded -var buildBn128$1 = build_bn128; -var buildBls12381$1 = build_bls12381; + const q = 0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001n; + const r = 0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001n; -/* global BigInt */ + const n64q = Math.floor((bitLength$1(q - 1n) - 1)/64) +1; + const n8q = n64q*8; + const f1size = n8q; + const f2size = f1size * 2; + const ftsize = f1size * 12; -function stringifyBigInts(o) { - if (typeof o == "bigint" || o.eq !== undefined) { - return o.toString(10); - } else if (o instanceof Uint8Array) { - return fromRprLE(o, 0); - } else if (Array.isArray(o)) { - return o.map(stringifyBigInts); - } else if (typeof o == "object") { - const res = {}; - const keys = Object.keys(o); - keys.forEach((k) => { - res[k] = stringifyBigInts(o[k]); - }); - return res; - } else { - return o; - } -} + const n64r = Math.floor((bitLength$1(r - 1n) - 1)/64) +1; + const n8r = n64r*8; + const frsize = n8r; + + + const pr = module.alloc(utils$1.bigInt2BytesLE( r, frsize )); + + const f1mPrefix = buildF1m(module, q, "f1m", "intq"); + buildF1(module, r, "fr", "frm", "intr"); + const pG1b = module.alloc(utils$1.bigInt2BytesLE( toMontgomery(1n), f1size )); + const g1mPrefix = buildCurve(module, "g1m", "f1m", pG1b); + + buildFFT$1(module, "frm", "frm", "frm", "frm_mul"); + + buildPol(module, "pol", "frm"); + buildQAP(module, "qap", "frm"); + + + function buildMulByXi() { + const f = module.addFunction("f1m_mulByXi"); + f.addParam("src", "i32"); + f.addParam("dest", "i32"); + const c = f.getCodeBuilder(); + // q - 5n = -5 mod q + const pXi = module.alloc(utils$1.bigInt2BytesLE(toMontgomery(q-5n), f1size)); + f.addCode( + c.call(f1mPrefix + "_mul", c.getLocal("src"), c.i32_const(pXi), c.getLocal("dest")) + ); + } + buildMulByXi(); + + const f2mPrefix = buildF2m(module, "f1m_mulByXi", "f2m", "f1m"); + + const pG2b = module.alloc([ + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0x10222f6db0fd6f343bd03737460c589dc7b4f91cd5fd889129207b63c6bf8000dd39e5c1ccccccd1c9ed9999999999an), f1size ) + ]); + const g2mPrefix = buildCurve(module, "g2m", "f2m", pG2b); + + + function buildGTimesFr(fnName, opMul) { + const f = module.addFunction(fnName); + f.addParam("pG", "i32"); + f.addParam("pFr", "i32"); + f.addParam("pr", "i32"); + + const c = f.getCodeBuilder(); + + const AUX = c.i32_const(module.alloc(n8r)); + + f.addCode( + c.call("frm_fromMontgomery", c.getLocal("pFr"), AUX), + c.call( + opMul, + c.getLocal("pG"), + AUX, + c.i32_const(n8r), + c.getLocal("pr") + ) + ); + + module.exportFunction(fnName); + } + buildGTimesFr("g1m_timesFr", "g1m_timesScalar"); + buildFFT$1(module, "g1m", "g1m", "frm", "g1m_timesFr"); + + buildGTimesFr("g2m_timesFr", "g2m_timesScalar"); + buildFFT$1(module, "g2m", "g2m", "frm", "g2m_timesFr"); + + buildGTimesFr("g1m_timesFrAffine", "g1m_timesScalarAffine"); + buildGTimesFr("g2m_timesFrAffine", "g2m_timesScalarAffine"); + + buildApplyKey(module, "frm_batchApplyKey", "fmr", "frm", n8r, n8r, n8r, "frm_mul"); + buildApplyKey(module, "g1m_batchApplyKey", "g1m", "frm", n8q*3, n8q*3, n8r, "g1m_timesFr"); + buildApplyKey(module, "g1m_batchApplyKeyMixed", "g1m", "frm", n8q*2, n8q*3, n8r, "g1m_timesFrAffine"); + buildApplyKey(module, "g2m_batchApplyKey", "g2m", "frm", n8q*2*3, n8q*3*2, n8r, "g2m_timesFr"); + buildApplyKey(module, "g2m_batchApplyKeyMixed", "g2m", "frm", n8q*2*2, n8q*3*2, n8r, "g2m_timesFrAffine"); + + + function toMontgomery(a) { + return BigInt(a) * (1n << BigInt(f1size*8)) % q; + } + + const G1gen = [ + 0x8848defe740a67c8fc6225bf87ff5485951e2caa9d41bb188282c8bd37cb5cd5481512ffcd394eeab9b16eb21be9efn, + 0x1914a69c5102eff1f674f5d30afeec4bd7fb348ca3e52d96d182ad44fb82305c2fe3d3634a9591afd82de55559c8ea6n, + 1n + ]; + + const pG1gen = module.alloc( + [ + ...utils$1.bigInt2BytesLE( toMontgomery(G1gen[0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G1gen[1]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G1gen[2]), f1size ), + ] + ); + + const G1zero = [ + 0n, + 1n, + 0n + ]; + + const pG1zero = module.alloc( + [ + ...utils$1.bigInt2BytesLE( toMontgomery(G1zero[0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G1zero[1]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G1zero[2]), f1size ) + ] + ); + + const G2gen = [ + [ + 0x018480be71c785fec89630a2a3841d01c565f071203e50317ea501f557db6b9b71889f52bb53540274e3e48f7c005196n, + 0x00ea6040e700403170dc5a51b1b140d5532777ee6651cecbe7223ece0799c9de5cf89984bff76fe6b26bfefa6ea16afen + ], + [ + 0x00690d665d446f7bd960736bcbb2efb4de03ed7274b49a58e458c282f832d204f2cf88886d8c7c2ef094094409fd4ddfn, + 0x00f8169fd28355189e549da3151a70aa61ef11ac3d591bf12463b01acee304c24279b83f5e52270bd9a1cdd185eb8f93n + ], + [ + 1n, 0n + ] + ]; + + const pG2gen = module.alloc( + [ + ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[0][0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[0][1]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[1][0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[1][1]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[2][0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2gen[2][1]), f1size ), + ] + ); + + const G2zero = [ + [ + 0n, + 0n, + ],[ + 1n, + 0n, + ],[ + 0n, + 0n, + ] + ]; + + const pG2zero = module.alloc( + [ + ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[0][0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[0][1]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[1][0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[1][1]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[2][0]), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(G2zero[2][1]), f1size ), + ] + ); + + const pOneT = module.alloc([ + ...utils$1.bigInt2BytesLE( toMontgomery(1n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ]); + + const pBls12377Twist = module.alloc([ + ...utils$1.bigInt2BytesLE( toMontgomery(0n), f1size ), + ...utils$1.bigInt2BytesLE( toMontgomery(0x10222f6db0fd6f343bd03737460c589dc7b4f91cd5fd889129207b63c6bf8000dd39e5c1ccccccd1c9ed9999999999an), f1size ) + ]); + + + function build_mulNR2() { + const f = module.addFunction(f2mPrefix + "_mulNR"); + f.addParam("pIn", "i32"); + f.addParam("pOut", "i32"); + + const c = f.getCodeBuilder(); + + const x0 = c.getLocal("pIn"); + const x1 = c.i32_add(c.getLocal("pIn"), c.i32_const(f1size)); + + const r0 = c.getLocal("pOut"); + const r1 = c.i32_add(c.getLocal("pOut"), c.i32_const(f1size)); + + const x0c = c.i32_const(module.alloc(f1size)); + + // Multiply by tau = (0, invXi) = invXi * u + // (x0 + x1 u) * invXi u = x0 invXi u + x1 invXi u^2 + // u^2 = xi = -5 + // x1 invXi xi + x0 invXi u = x1 + x0 invXi u + + // r0 = x1 + // r1 = x0 * invXi + + const pInvXi = module.alloc(utils$1.bigInt2BytesLE(toMontgomery(0x10222f6db0fd6f343bd03737460c589dc7b4f91cd5fd889129207b63c6bf8000dd39e5c1ccccccd1c9ed9999999999an), f1size)); + + f.addCode( + // Support in-place usage (pIn === pOut). + c.call(f1mPrefix + "_copy", x0, x0c), + c.call(f1mPrefix + "_copy", x1, r0), + c.call(f1mPrefix + "_mul", x0c, c.i32_const(pInvXi), r1) + ); + } + + build_mulNR2(); + + const f6mPrefix = buildF3m(module, f2mPrefix+"_mulNR", "f6m", "f2m"); + + function build_mulNR6() { + const f = module.addFunction(f6mPrefix + "_mulNR"); + f.addParam("x", "i32"); + f.addParam("pr", "i32"); + + const c = f.getCodeBuilder(); + + const c0copy = c.i32_const(module.alloc(f1size*2)); + + f.addCode( + c.call( + f2mPrefix + "_copy", + c.getLocal("x"), + c0copy + ), + c.call( + f2mPrefix + "_mulNR", + c.i32_add(c.getLocal("x"), c.i32_const(n8q*4)), + c.getLocal("pr") + ), + c.call( + f2mPrefix + "_copy", + c.i32_add(c.getLocal("x"), c.i32_const(n8q*2)), + c.i32_add(c.getLocal("pr"), c.i32_const(n8q*4)), + ), + c.call( + f2mPrefix + "_copy", + c0copy, + c.i32_add(c.getLocal("pr"), c.i32_const(n8q*2)), + ), + ); + } + build_mulNR6(); + + const ftmPrefix = buildF2m(module, f6mPrefix+"_mulNR", "ftm", f6mPrefix); + + const ateLoopCount = 0x8508C00000000001n; + const ateLoopBitBytes = bits(ateLoopCount); + const pAteLoopBitBytes = module.alloc(ateLoopBitBytes); + + const ateCoefSize = 3 * f2size; + const ateNDblCoefs = ateLoopBitBytes.length-1; + const ateNAddCoefs = ateLoopBitBytes.reduce((acc, b) => acc + ( b!=0 ? 1 : 0) ,0); + const ateNCoefs = ateNAddCoefs + ateNDblCoefs + 1; + const prePSize = 3*2*n8q; + const preQSize = 3*n8q*2 + ateNCoefs*ateCoefSize; + const finalExpIsNegative = false; + + const finalExpZ = 9586122913090633729n; + + + module.modules[prefix] = { + n64q: n64q, + n64r: n64r, + n8q: n8q, + n8r: n8r, + pG1gen: pG1gen, + pG1zero: pG1zero, + pG1b: pG1b, + pG2gen: pG2gen, + pG2zero: pG2zero, + pG2b: pG2b, + pq: module.modules["f1m"].pq, + pr: pr, + pOneT: pOneT, + r: r, + q: q, + prePSize: prePSize, + preQSize: preQSize + }; + + + function naf(n) { + let E = n; + const res = []; + while (E > 0n) { + if (isOdd(E)) { + const z = 2 - Number(E % 4n); + res.push( z ); + E = E - BigInt(z); + } else { + res.push( 0 ); + } + E = E >> 1n; + } + return res; + } + + function bits(n) { + let E = n; + const res = []; + while (E > 0n) { + if (isOdd(E)) { + res.push( 1 ); + } else { + res.push( 0 ); + } + E = E >> 1n; + } + return res; + } + + function buildPrepareG1() { + const f = module.addFunction(prefix+ "_prepareG1"); + f.addParam("pP", "i32"); + f.addParam("ppreP", "i32"); + + const c = f.getCodeBuilder(); + + f.addCode( + c.call(g1mPrefix + "_normalize", c.getLocal("pP"), c.getLocal("ppreP")), // TODO Remove if already in affine + ); + } + + + + function buildPrepDoubleStep() { + const f = module.addFunction(prefix+ "_prepDblStep"); + f.addParam("R", "i32"); + f.addParam("r", "i32"); + + const c = f.getCodeBuilder(); + + const Rx = c.getLocal("R"); + const Ry = c.i32_add(c.getLocal("R"), c.i32_const(2*n8q)); + const Rz = c.i32_add(c.getLocal("R"), c.i32_const(4*n8q)); + + const t0 = c.getLocal("r"); + const t3 = c.i32_add(c.getLocal("r"), c.i32_const(2*n8q)); + const t6 = c.i32_add(c.getLocal("r"), c.i32_const(4*n8q)); + + + const zsquared = c.i32_const(module.alloc(f2size)); + const t1 = c.i32_const(module.alloc(f2size)); + const t2 = c.i32_const(module.alloc(f2size)); + const t4 = c.i32_const(module.alloc(f2size)); + const t5 = c.i32_const(module.alloc(f2size)); + + f.addCode( + + // tmp0 = r.x.square(); + c.call(f2mPrefix + "_square", Rx, t0), + + // tmp1 = r.y.square(); + c.call(f2mPrefix + "_square", Ry, t1), + + // tmp2 = tmp1.square(); + c.call(f2mPrefix + "_square", t1, t2), + + // tmp3 = (tmp1 + r.x).square() - tmp0 - tmp2; + c.call(f2mPrefix + "_add", t1, Rx, t3), + c.call(f2mPrefix + "_square", t3, t3), + c.call(f2mPrefix + "_sub", t3, t0, t3), + c.call(f2mPrefix + "_sub", t3, t2, t3), + + // tmp3 = tmp3 + tmp3; + c.call(f2mPrefix + "_add", t3, t3, t3), + + // tmp4 = tmp0 + tmp0 + tmp0; + c.call(f2mPrefix + "_add", t0, t0, t4), + c.call(f2mPrefix + "_add", t4, t0, t4), + + // tmp6 = r.x + tmp4; + c.call(f2mPrefix + "_add", Rx, t4, t6), + + // tmp5 = tmp4.square(); + c.call(f2mPrefix + "_square", t4, t5), + + // zsquared = r.z.square(); + c.call(f2mPrefix + "_square", Rz, zsquared), + + // r.x = tmp5 - tmp3 - tmp3; + c.call(f2mPrefix + "_sub", t5, t3, Rx), + c.call(f2mPrefix + "_sub", Rx, t3, Rx), + + // r.z = (r.z + r.y).square() - tmp1 - zsquared; + c.call(f2mPrefix + "_add", Rz, Ry, Rz), + c.call(f2mPrefix + "_square", Rz, Rz), + c.call(f2mPrefix + "_sub", Rz, t1, Rz), + c.call(f2mPrefix + "_sub", Rz, zsquared, Rz), + + // r.y = (tmp3 - r.x) * tmp4; + c.call(f2mPrefix + "_sub", t3, Rx, Ry), + c.call(f2mPrefix + "_mul", Ry, t4, Ry), + + // tmp2 = tmp2 + tmp2; + c.call(f2mPrefix + "_add", t2, t2, t2), + + // tmp2 = tmp2 + tmp2; + c.call(f2mPrefix + "_add", t2, t2, t2), + + // tmp2 = tmp2 + tmp2; + c.call(f2mPrefix + "_add", t2, t2, t2), + + // r.y -= tmp2; + c.call(f2mPrefix + "_sub", Ry, t2, Ry), + + // tmp3 = tmp4 * zsquared; + c.call(f2mPrefix + "_mul", t4, zsquared, t3), + + // tmp3 = tmp3 + tmp3; + c.call(f2mPrefix + "_add", t3, t3, t3), + + // tmp3 = -tmp3; + c.call(f2mPrefix + "_neg", t3, t3), + + // tmp6 = tmp6.square() - tmp0 - tmp5; + c.call(f2mPrefix + "_square", t6, t6), + c.call(f2mPrefix + "_sub", t6, t0, t6), + c.call(f2mPrefix + "_sub", t6, t5, t6), + + // tmp1 = tmp1 + tmp1; + c.call(f2mPrefix + "_add", t1, t1, t1), + + // tmp1 = tmp1 + tmp1; + c.call(f2mPrefix + "_add", t1, t1, t1), + + // tmp6 = tmp6 - tmp1; + c.call(f2mPrefix + "_sub", t6, t1, t6), + + // tmp0 = r.z * zsquared; + c.call(f2mPrefix + "_mul", Rz, zsquared, t0), + + // tmp0 = tmp0 + tmp0; + c.call(f2mPrefix + "_add", t0, t0, t0), + + ); + } + + function buildPrepAddStep() { + const f = module.addFunction(prefix+ "_prepAddStep"); + f.addParam("R", "i32"); + f.addParam("Q", "i32"); + f.addParam("r", "i32"); + + const c = f.getCodeBuilder(); + + const Rx = c.getLocal("R"); + const Ry = c.i32_add(c.getLocal("R"), c.i32_const(2*n8q)); + const Rz = c.i32_add(c.getLocal("R"), c.i32_const(4*n8q)); + + const Qx = c.getLocal("Q"); + const Qy = c.i32_add(c.getLocal("Q"), c.i32_const(2*n8q)); + + const t10 = c.getLocal("r"); + const t1 = c.i32_add(c.getLocal("r"), c.i32_const(2*n8q)); + const t9 = c.i32_add(c.getLocal("r"), c.i32_const(4*n8q)); + + const zsquared = c.i32_const(module.alloc(f2size)); + const ysquared = c.i32_const(module.alloc(f2size)); + const ztsquared = c.i32_const(module.alloc(f2size)); + const t0 = c.i32_const(module.alloc(f2size)); + const t2 = c.i32_const(module.alloc(f2size)); + const t3 = c.i32_const(module.alloc(f2size)); + const t4 = c.i32_const(module.alloc(f2size)); + const t5 = c.i32_const(module.alloc(f2size)); + const t6 = c.i32_const(module.alloc(f2size)); + const t7 = c.i32_const(module.alloc(f2size)); + const t8 = c.i32_const(module.alloc(f2size)); + + f.addCode( + + // zsquared = r.z.square(); + c.call(f2mPrefix + "_square", Rz, zsquared), + + // ysquared = q.y.square(); + c.call(f2mPrefix + "_square", Qy, ysquared), + + // t0 = zsquared * q.x; + c.call(f2mPrefix + "_mul", zsquared, Qx, t0), + + // t1 = ((q.y + r.z).square() - ysquared - zsquared) * zsquared; + c.call(f2mPrefix + "_add", Qy, Rz, t1), + c.call(f2mPrefix + "_square", t1, t1), + c.call(f2mPrefix + "_sub", t1, ysquared, t1), + c.call(f2mPrefix + "_sub", t1, zsquared, t1), + c.call(f2mPrefix + "_mul", t1, zsquared, t1), + + // t2 = t0 - r.x; + c.call(f2mPrefix + "_sub", t0, Rx, t2), + + // t3 = t2.square(); + c.call(f2mPrefix + "_square", t2, t3), + + // t4 = t3 + t3; + c.call(f2mPrefix + "_add", t3, t3, t4), + + // t4 = t4 + t4; + c.call(f2mPrefix + "_add", t4, t4, t4), + + // t5 = t4 * t2; + c.call(f2mPrefix + "_mul", t4, t2, t5), + + // t6 = t1 - r.y - r.y; + c.call(f2mPrefix + "_sub", t1, Ry, t6), + c.call(f2mPrefix + "_sub", t6, Ry, t6), + + // t9 = t6 * q.x; + c.call(f2mPrefix + "_mul", t6, Qx, t9), + + // t7 = t4 * r.x; + c.call(f2mPrefix + "_mul", t4, Rx, t7), + + // r.x = t6.square() - t5 - t7 - t7; + c.call(f2mPrefix + "_square", t6, Rx), + c.call(f2mPrefix + "_sub", Rx, t5, Rx), + c.call(f2mPrefix + "_sub", Rx, t7, Rx), + c.call(f2mPrefix + "_sub", Rx, t7, Rx), + + // r.z = (r.z + t2).square() - zsquared - t3; + c.call(f2mPrefix + "_add", Rz, t2, Rz), + c.call(f2mPrefix + "_square", Rz, Rz), + c.call(f2mPrefix + "_sub", Rz, zsquared, Rz), + c.call(f2mPrefix + "_sub", Rz, t3, Rz), + + // t10 = q.y + r.z; + c.call(f2mPrefix + "_add", Qy, Rz, t10), + + // t8 = (t7 - r.x) * t6; + c.call(f2mPrefix + "_sub", t7, Rx, t8), + c.call(f2mPrefix + "_mul", t8, t6, t8), + + // t0 = r.y * t5; + c.call(f2mPrefix + "_mul", Ry, t5, t0), + + // t0 = t0 + t0; + c.call(f2mPrefix + "_add", t0, t0, t0), + + // r.y = t8 - t0; + c.call(f2mPrefix + "_sub", t8, t0, Ry), + + // t10 = t10.square() - ysquared; + c.call(f2mPrefix + "_square", t10, t10), + c.call(f2mPrefix + "_sub", t10, ysquared, t10), + + // ztsquared = r.z.square(); + c.call(f2mPrefix + "_square", Rz, ztsquared), + + // t10 = t10 - ztsquared; + c.call(f2mPrefix + "_sub", t10, ztsquared, t10), + + // t9 = t9 + t9 - t10; + c.call(f2mPrefix + "_add", t9, t9, t9), + c.call(f2mPrefix + "_sub", t9, t10, t9), + + // t10 = r.z + r.z; + c.call(f2mPrefix + "_add", Rz, Rz, t10), + + // t6 = -t6; + c.call(f2mPrefix + "_neg", t6, t6), + + // t1 = t6 + t6; + c.call(f2mPrefix + "_add", t6, t6, t1), + ); + } + + + function buildPrepareG2() { + const f = module.addFunction(prefix+ "_prepareG2"); + f.addParam("pQ", "i32"); + f.addParam("ppreQ", "i32"); + f.addLocal("pCoef", "i32"); + f.addLocal("i", "i32"); + + const c = f.getCodeBuilder(); + + + const Q = c.getLocal("pQ"); + + const pR = module.alloc(f2size*3); + const R = c.i32_const(pR); + + const base = c.getLocal("ppreQ"); + + f.addCode( + c.call(g2mPrefix + "_normalize", Q, base), + c.if( + c.call(g2mPrefix + "_isZero", base), + c.ret([]) + ), + c.call(g2mPrefix + "_copy", base, R), + c.setLocal("pCoef", c.i32_add(c.getLocal("ppreQ"), c.i32_const(f2size*3))), + ); + + f.addCode( + c.setLocal("i", c.i32_const(ateLoopBitBytes.length-2)), + c.block(c.loop( + + c.call(prefix + "_prepDblStep", R, c.getLocal("pCoef")), + c.setLocal("pCoef", c.i32_add(c.getLocal("pCoef"), c.i32_const(ateCoefSize))), + + c.if( + c.i32_load8_s(c.getLocal("i"), pAteLoopBitBytes), + [ + ...c.call(prefix + "_prepAddStep", R, base, c.getLocal("pCoef")), + ...c.setLocal("pCoef", c.i32_add(c.getLocal("pCoef"), c.i32_const(ateCoefSize))), + ] + ), + c.br_if(1, c.i32_eqz ( c.getLocal("i") )), + c.setLocal("i", c.i32_sub(c.getLocal("i"), c.i32_const(1))), + c.br(0) + )) + ); + } + + + function buildF6Mul1() { + const f = module.addFunction(f6mPrefix+ "_mul1"); + f.addParam("pA", "i32"); // F6 + f.addParam("pC1", "i32"); // F2 + f.addParam("pR", "i32"); // F6 + + const c = f.getCodeBuilder(); + + const A_c0 = c.getLocal("pA"); + const A_c1 = c.i32_add(c.getLocal("pA"), c.i32_const(f1size*2)); + const A_c2 = c.i32_add(c.getLocal("pA"), c.i32_const(f1size*4)); + + const c1 = c.getLocal("pC1"); + + const t1 = c.getLocal("pR"); + const t2 = c.i32_add(c.getLocal("pR"), c.i32_const(f1size*2)); + const b_b = c.i32_add(c.getLocal("pR"), c.i32_const(f1size*4)); + + const Ac0_Ac1 = c.i32_const(module.alloc(f1size*2)); + const Ac1_Ac2 = c.i32_const(module.alloc(f1size*2)); + + f.addCode( + + c.call(f2mPrefix + "_add", A_c0, A_c1, Ac0_Ac1), + c.call(f2mPrefix + "_add", A_c1, A_c2, Ac1_Ac2), + + // let b_b = self.c1 * c1; + c.call(f2mPrefix + "_mul", A_c1, c1, b_b), + + // let t1 = (self.c1 + self.c2) * c1 - b_b; + c.call(f2mPrefix + "_mul", Ac1_Ac2, c1, t1), + c.call(f2mPrefix + "_sub", t1, b_b, t1), + + // let t1 = t1.mul_by_nonresidue(); + c.call(f2mPrefix + "_mulNR", t1, t1), + + // let t2 = (self.c0 + self.c1) * c1 - b_b; + c.call(f2mPrefix + "_mul", Ac0_Ac1, c1, t2), + c.call(f2mPrefix + "_sub", t2, b_b, t2), + ); + } + buildF6Mul1(); + + function buildF6Mul01() { + const f = module.addFunction(f6mPrefix+ "_mul01"); + f.addParam("pA", "i32"); // F6 + f.addParam("pC0", "i32"); // F2 + f.addParam("pC1", "i32"); // F2 + f.addParam("pR", "i32"); // F6 + + const c = f.getCodeBuilder(); + + const A_c0 = c.getLocal("pA"); + const A_c1 = c.i32_add(c.getLocal("pA"), c.i32_const(f1size*2)); + const A_c2 = c.i32_add(c.getLocal("pA"), c.i32_const(f1size*4)); + + const c0 = c.getLocal("pC0"); + const c1 = c.getLocal("pC1"); + + const t1 = c.getLocal("pR"); + const t2 = c.i32_add(c.getLocal("pR"), c.i32_const(f1size*2)); + const t3 = c.i32_add(c.getLocal("pR"), c.i32_const(f1size*4)); + + const a_a = c.i32_const(module.alloc(f1size*2)); + const b_b = c.i32_const(module.alloc(f1size*2)); + const Ac0_Ac1 = c.i32_const(module.alloc(f1size*2)); + const Ac0_Ac2 = c.i32_const(module.alloc(f1size*2)); + + f.addCode( + // let a_a = self.c0 * c0; + c.call(f2mPrefix + "_mul", A_c0, c0, a_a), + + // let b_b = self.c1 * c1; + c.call(f2mPrefix + "_mul", A_c1, c1, b_b), + + + c.call(f2mPrefix + "_add", A_c0, A_c1, Ac0_Ac1), + c.call(f2mPrefix + "_add", A_c0, A_c2, Ac0_Ac2), + + // let t1 = (self.c1 + self.c2) * c1 - b_b; + c.call(f2mPrefix + "_add", A_c1, A_c2, t1), + c.call(f2mPrefix + "_mul", t1, c1, t1), + c.call(f2mPrefix + "_sub", t1, b_b, t1), + + // let t1 = t1.mul_by_nonresidue() + a_a; + c.call(f2mPrefix + "_mulNR", t1, t1), + c.call(f2mPrefix + "_add", t1, a_a, t1), + + // let t2 = (c0 + c1) * (self.c0 + self.c1) - a_a - b_b; + c.call(f2mPrefix + "_add", c0, c1, t2), + c.call(f2mPrefix + "_mul", t2, Ac0_Ac1, t2), + c.call(f2mPrefix + "_sub", t2, a_a, t2), + c.call(f2mPrefix + "_sub", t2, b_b, t2), + + // let t3 = (self.c0 + self.c2) * c0 - a_a + b_b; + c.call(f2mPrefix + "_mul", Ac0_Ac2, c0, t3), + c.call(f2mPrefix + "_sub", t3, a_a, t3), + c.call(f2mPrefix + "_add", t3, b_b, t3), + + + ); + } + buildF6Mul01(); + + + function buildF12Mul014() { + + const f = module.addFunction(ftmPrefix+ "_mul014"); + f.addParam("pA", "i32"); // F12 + f.addParam("pC0", "i32"); // F2 + f.addParam("pC1", "i32"); // F2 + f.addParam("pC4", "i32"); // F2 + f.addParam("pR", "i32"); // F12 + + const c = f.getCodeBuilder(); + + + const A_c0 = c.getLocal("pA"); + const A_c1 = c.i32_add(c.getLocal("pA"), c.i32_const(f1size*6)); + + const c0 = c.getLocal("pC0"); + const c1 = c.getLocal("pC1"); + const c4 = c.getLocal("pC4"); + + const aa = c.i32_const(module.alloc(f1size*6)); + const bb = c.i32_const(module.alloc(f1size*6)); + const o = c.i32_const(module.alloc(f1size*2)); + + const R_c0 = c.getLocal("pR"); + const R_c1 = c.i32_add(c.getLocal("pR"), c.i32_const(f1size*6)); + + f.addCode( + // let aa = self.c0.mul_by_01(c0, c1); + c.call(f6mPrefix + "_mul01", A_c0, c0, c1, aa), + + // let bb = self.c1.mul_by_1(c4); + c.call(f6mPrefix + "_mul1", A_c1, c4, bb), + + // let o = c1 + c4; + c.call(f2mPrefix + "_add", c1, c4, o), + + // let c1 = self.c1 + self.c0; + c.call(f6mPrefix + "_add", A_c1, A_c0, R_c1), + + // let c1 = c1.mul_by_01(c0, &o); + c.call(f6mPrefix + "_mul01", R_c1, c0, o, R_c1), + + // let c1 = c1 - aa - bb; + c.call(f6mPrefix + "_sub", R_c1, aa, R_c1), + c.call(f6mPrefix + "_sub", R_c1, bb, R_c1), + + // let c0 = bb; + c.call(f6mPrefix + "_copy", bb, R_c0), + + // let c0 = c0.mul_by_nonresidue(); + c.call(f6mPrefix + "_mulNR", R_c0, R_c0), + + // let c0 = c0 + aa; + c.call(f6mPrefix + "_add", R_c0, aa, R_c0), + ); + } + buildF12Mul014(); + + + function buildELL() { + const f = module.addFunction(prefix+ "_ell"); + f.addParam("pP", "i32"); + f.addParam("pCoefs", "i32"); + f.addParam("pF", "i32"); + + const c = f.getCodeBuilder(); + + const Px = c.getLocal("pP"); + const Py = c.i32_add(c.getLocal("pP"), c.i32_const(n8q)); + + const F = c.getLocal("pF"); + + const coef0_0 = c.getLocal("pCoefs"); + const coef0_1 = c.i32_add(c.getLocal("pCoefs"), c.i32_const(f1size)); + const coef1_0 = c.i32_add(c.getLocal("pCoefs"), c.i32_const(f1size*2)); + const coef1_1 = c.i32_add(c.getLocal("pCoefs"), c.i32_const(f1size*3)); + const coef2 = c.i32_add(c.getLocal("pCoefs"), c.i32_const(f1size*4)); + + const pc0 = module.alloc(f1size*2); + const c0 = c.i32_const(pc0); + const c0_c0 = c.i32_const(pc0); + const c0_c1 = c.i32_const(pc0+f1size); + + const pc1 = module.alloc(f1size*2); + const c1 = c.i32_const(pc1); + const c1_c0 = c.i32_const(pc1); + const c1_c1 = c.i32_const(pc1+f1size); + f.addCode( + // let mut c0 = coeffs.0; + // let mut c1 = coeffs.1; + // + // c0.c0 *= p.y; + // c0.c1 *= p.y; + // + // c1.c0 *= p.x; + // c1.c1 *= p.x; + // + // f.mul_by_014(&coeffs.2, &c1, &c0) + + c.call(f1mPrefix + "_mul", coef0_0, Py, c0_c0), + c.call(f1mPrefix + "_mul", coef0_1, Py, c0_c1), + c.call(f1mPrefix + "_mul", coef1_0, Px, c1_c0), + c.call(f1mPrefix + "_mul", coef1_1, Px, c1_c1), + c.call(ftmPrefix + "_mul014", F, coef2, c1, c0, F), + + ); + + } + buildELL(); + + function buildMillerLoop() { + const f = module.addFunction(prefix+ "_millerLoop"); + f.addParam("ppreP", "i32"); + f.addParam("ppreQ", "i32"); + f.addParam("r", "i32"); + f.addLocal("pCoef", "i32"); + f.addLocal("i", "i32"); + + const c = f.getCodeBuilder(); + + const preP = c.getLocal("ppreP"); + + const coefs = c.getLocal("pCoef"); + + const F = c.getLocal("r"); + + + f.addCode( + c.call(ftmPrefix + "_one", F), + + c.if( + c.call(g1mPrefix + "_isZero", preP), + c.ret([]) + ), + c.if( + c.call(g1mPrefix + "_isZero", c.getLocal("ppreQ")), + c.ret([]) + ), + c.setLocal("pCoef", c.i32_add( c.getLocal("ppreQ"), c.i32_const(f2size*3))), + + c.setLocal("i", c.i32_const(ateLoopBitBytes.length-2)), + c.block(c.loop( + + + c.call(prefix + "_ell", preP, coefs, F), + c.setLocal("pCoef", c.i32_add(c.getLocal("pCoef"), c.i32_const(ateCoefSize))), + + c.if( + c.i32_load8_s(c.getLocal("i"), pAteLoopBitBytes), + [ + ...c.call(prefix + "_ell", preP, coefs, F), + ...c.setLocal("pCoef", c.i32_add(c.getLocal("pCoef"), c.i32_const(ateCoefSize))), + ] + ), + c.call(ftmPrefix + "_square", F, F), + + c.br_if(1, c.i32_eq ( c.getLocal("i"), c.i32_const(1) )), + c.setLocal("i", c.i32_sub(c.getLocal("i"), c.i32_const(1))), + c.br(0) + )), + // Last step (i == 0): no squaring. For odd loop parameters, we also need + // the final add step when bit 0 is set. + c.call(prefix + "_ell", preP, coefs, F), + c.setLocal("pCoef", c.i32_add(c.getLocal("pCoef"), c.i32_const(ateCoefSize))), + c.if( + c.i32_load8_s(c.i32_const(0), pAteLoopBitBytes), + [ + ...c.call(prefix + "_ell", preP, coefs, F), + ...c.setLocal("pCoef", c.i32_add(c.getLocal("pCoef"), c.i32_const(ateCoefSize))), + ] + ), + + ); + } + + + + function buildFrobeniusMap(n) { + const f = module.addFunction(ftmPrefix + "_frobeniusMap"+n); + f.addParam("x", "i32"); + f.addParam("r", "i32"); + + const c = f.getCodeBuilder(); + + const gamma = 0xe0c97ad7fbdab63937b3ebd47e0a1b36a986deef71f15c288ed7951a488e3b332941cfc8f883faffca93e41f1603cfn; + + // Helper to compute power + function power(base, exp) { + if (exp === 0n) return 1n; + let res = 1n; + let b = base; + while (exp > 0n) { + if (exp % 2n === 1n) res = (res * b) % q; + b = (b * b) % q; + exp = exp / 2n; + } + return res; + } + + // F12 basis in wasmcurves is (Fp6 + Fp6*w), with Fp6 basis (1, v, v^2) and w^2 = v. + // For our parameters, the required Frobenius multipliers are scalar powers of + // gamma = tau^((q-1)/6) (with tau the Fp6 non-residue). + // The exponent pattern per coefficient is: + // [1, v, v^2, w, v*w, v^2*w] -> gamma^[0, 2, 4, 1, 3, 5] + const expMap = [0n, 2n, 4n, 1n, 3n, 5n]; + + for (let i=0; i<6; i++) { + const X = (i==0) ? c.getLocal("x") : c.i32_add(c.getLocal("x"), c.i32_const(i*f2size)); + const Xc0 = X; + const Xc1 = c.i32_add(c.getLocal("x"), c.i32_const(i*f2size + f1size)); + + const R = (i==0) ? c.getLocal("r") : c.i32_add(c.getLocal("r"), c.i32_const(i*f2size)); + const Rc0 = R; + const Rc1 = c.i32_add(c.getLocal("r"), c.i32_const(i*f2size + f1size)); + + const coefScalar = power(gamma, BigInt(n) * expMap[i]); + + const pCoef = module.alloc([ + ...utils$1.bigInt2BytesLE(toMontgomery(coefScalar), n8q), + ...utils$1.bigInt2BytesLE(toMontgomery(0n), n8q), + ]); + + if (n % 2 == 1) { + f.addCode( + c.call(f1mPrefix + "_copy", Xc0, Rc0), + c.call(f1mPrefix + "_neg", Xc1, Rc1), + c.call(f2mPrefix + "_mul", R, c.i32_const(pCoef), R), + ); + } else { + f.addCode(c.call(f2mPrefix + "_mul", X, c.i32_const(pCoef), R)); + } + } + } + + + + function buildCyclotomicSquare() { + const f = module.addFunction(prefix+ "__cyclotomicSquare"); + f.addParam("x", "i32"); + f.addParam("r", "i32"); + + const c = f.getCodeBuilder(); + + const x0 = c.getLocal("x"); + const x4 = c.i32_add(c.getLocal("x"), c.i32_const(f2size)); + const x3 = c.i32_add(c.getLocal("x"), c.i32_const(2*f2size)); + const x2 = c.i32_add(c.getLocal("x"), c.i32_const(3*f2size)); + const x1 = c.i32_add(c.getLocal("x"), c.i32_const(4*f2size)); + const x5 = c.i32_add(c.getLocal("x"), c.i32_const(5*f2size)); + + const r0 = c.getLocal("r"); + const r4 = c.i32_add(c.getLocal("r"), c.i32_const(f2size)); + const r3 = c.i32_add(c.getLocal("r"), c.i32_const(2*f2size)); + const r2 = c.i32_add(c.getLocal("r"), c.i32_const(3*f2size)); + const r1 = c.i32_add(c.getLocal("r"), c.i32_const(4*f2size)); + const r5 = c.i32_add(c.getLocal("r"), c.i32_const(5*f2size)); + + const t0 = c.i32_const(module.alloc(f2size)); + const t1 = c.i32_const(module.alloc(f2size)); + const t2 = c.i32_const(module.alloc(f2size)); + const t3 = c.i32_const(module.alloc(f2size)); + const t4 = c.i32_const(module.alloc(f2size)); + const t5 = c.i32_const(module.alloc(f2size)); + const tmp = c.i32_const(module.alloc(f2size)); + const AUX = c.i32_const(module.alloc(f2size)); + + + f.addCode( + // // t0 + t1*y = (z0 + z1*y)^2 = a^2 + // tmp = z0 * z1; + // t0 = (z0 + z1) * (z0 + my_Fp6::non_residue * z1) - tmp - my_Fp6::non_residue * tmp; + // t1 = tmp + tmp; + c.call(f2mPrefix + "_mul", x0, x1, tmp), + c.call(f2mPrefix + "_mulNR", x1, t0), + c.call(f2mPrefix + "_add", x0, t0, t0), + c.call(f2mPrefix + "_add", x0, x1, AUX), + c.call(f2mPrefix + "_mul", AUX, t0, t0), + c.call(f2mPrefix + "_mulNR", tmp, AUX), + c.call(f2mPrefix + "_add", tmp, AUX, AUX), + c.call(f2mPrefix + "_sub", t0, AUX, t0), + c.call(f2mPrefix + "_add", tmp, tmp, t1), + + // // t2 + t3*y = (z2 + z3*y)^2 = b^2 + // tmp = z2 * z3; + // t2 = (z2 + z3) * (z2 + my_Fp6::non_residue * z3) - tmp - my_Fp6::non_residue * tmp; + // t3 = tmp + tmp; + c.call(f2mPrefix + "_mul", x2, x3, tmp), + c.call(f2mPrefix + "_mulNR", x3, t2), + c.call(f2mPrefix + "_add", x2, t2, t2), + c.call(f2mPrefix + "_add", x2, x3, AUX), + c.call(f2mPrefix + "_mul", AUX, t2, t2), + c.call(f2mPrefix + "_mulNR", tmp, AUX), + c.call(f2mPrefix + "_add", tmp, AUX, AUX), + c.call(f2mPrefix + "_sub", t2, AUX, t2), + c.call(f2mPrefix + "_add", tmp, tmp, t3), + + // // t4 + t5*y = (z4 + z5*y)^2 = c^2 + // tmp = z4 * z5; + // t4 = (z4 + z5) * (z4 + my_Fp6::non_residue * z5) - tmp - my_Fp6::non_residue * tmp; + // t5 = tmp + tmp; + c.call(f2mPrefix + "_mul", x4, x5, tmp), + c.call(f2mPrefix + "_mulNR", x5, t4), + c.call(f2mPrefix + "_add", x4, t4, t4), + c.call(f2mPrefix + "_add", x4, x5, AUX), + c.call(f2mPrefix + "_mul", AUX, t4, t4), + c.call(f2mPrefix + "_mulNR", tmp, AUX), + c.call(f2mPrefix + "_add", tmp, AUX, AUX), + c.call(f2mPrefix + "_sub", t4, AUX, t4), + c.call(f2mPrefix + "_add", tmp, tmp, t5), + + // For A + // z0 = 3 * t0 - 2 * z0 + c.call(f2mPrefix + "_sub", t0, x0, r0), + c.call(f2mPrefix + "_add", r0, r0, r0), + c.call(f2mPrefix + "_add", t0, r0, r0), + // z1 = 3 * t1 + 2 * z1 + c.call(f2mPrefix + "_add", t1, x1, r1), + c.call(f2mPrefix + "_add", r1, r1, r1), + c.call(f2mPrefix + "_add", t1, r1, r1), + + // For B + // z2 = 3 * (xi * t5) + 2 * z2 + c.call(f2mPrefix + "_mul", t5, c.i32_const(pBls12377Twist), AUX), + c.call(f2mPrefix + "_add", AUX, x2, r2), + c.call(f2mPrefix + "_add", r2, r2, r2), + c.call(f2mPrefix + "_add", AUX, r2, r2), + // z3 = 3 * t4 - 2 * z3 + c.call(f2mPrefix + "_sub", t4, x3, r3), + c.call(f2mPrefix + "_add", r3, r3, r3), + c.call(f2mPrefix + "_add", t4, r3, r3), + + // For C + // z4 = 3 * t2 - 2 * z4 + c.call(f2mPrefix + "_sub", t2, x4, r4), + c.call(f2mPrefix + "_add", r4, r4, r4), + c.call(f2mPrefix + "_add", t2, r4, r4), + // z5 = 3 * t3 + 2 * z5 + c.call(f2mPrefix + "_add", t3, x5, r5), + c.call(f2mPrefix + "_add", r5, r5, r5), + c.call(f2mPrefix + "_add", t3, r5, r5), + + ); + } + + + function buildCyclotomicExp(exponent, isExpNegative, fnName) { + const exponentNafBytes = naf(exponent).map( (b) => (b==-1 ? 0xFF: b) ); + const pExponentNafBytes = module.alloc(exponentNafBytes); + // const pExponent = module.alloc(utils.bigInt2BytesLE(exponent, n8)); + + const f = module.addFunction(prefix+ "__cyclotomicExp_"+fnName); + f.addParam("x", "i32"); + f.addParam("r", "i32"); + f.addLocal("bit", "i32"); + f.addLocal("i", "i32"); + + const c = f.getCodeBuilder(); + + const x = c.getLocal("x"); + + const res = c.getLocal("r"); + + const inverse = c.i32_const(module.alloc(ftsize)); + + + f.addCode( + c.call(ftmPrefix + "_conjugate", x, inverse), + c.call(ftmPrefix + "_one", res), + + c.if( + c.teeLocal("bit", c.i32_load8_s(c.i32_const(exponentNafBytes.length-1), pExponentNafBytes)), + c.if( + c.i32_eq( + c.getLocal("bit"), + c.i32_const(1) + ), + c.call(ftmPrefix + "_mul", res, x, res), + c.call(ftmPrefix + "_mul", res, inverse, res), + ) + ), + + c.setLocal("i", c.i32_const(exponentNafBytes.length-2)), + c.block(c.loop( + c.call(prefix + "__cyclotomicSquare", res, res), + c.if( + c.teeLocal("bit", c.i32_load8_s(c.getLocal("i"), pExponentNafBytes)), + c.if( + c.i32_eq( + c.getLocal("bit"), + c.i32_const(1) + ), + c.call(ftmPrefix + "_mul", res, x, res), + c.call(ftmPrefix + "_mul", res, inverse, res), + ) + ), + c.br_if(1, c.i32_eqz ( c.getLocal("i") )), + c.setLocal("i", c.i32_sub(c.getLocal("i"), c.i32_const(1))), + c.br(0) + )) + ); + + if (isExpNegative) { + f.addCode( + c.call(ftmPrefix + "_conjugate", res, res), + ); + } + + } + + function buildFinalExponentiation() { + buildCyclotomicSquare(); + buildCyclotomicExp(finalExpZ, finalExpIsNegative, "w0"); + + const f = module.addFunction(prefix+ "_finalExponentiation"); + f.addParam("x", "i32"); + f.addParam("r", "i32"); + + const c = f.getCodeBuilder(); + const elt = c.getLocal("x"); + const res = c.getLocal("r"); + const t0 = c.i32_const(module.alloc(ftsize)); + const t1 = c.i32_const(module.alloc(ftsize)); + const t2 = c.i32_const(module.alloc(ftsize)); + const t3 = c.i32_const(module.alloc(ftsize)); + const t4 = c.i32_const(module.alloc(ftsize)); + const t5 = c.i32_const(module.alloc(ftsize)); + const t6 = c.i32_const(module.alloc(ftsize)); + + f.addCode( + // let mut t0 = f.frobenius_map(6) + c.call(ftmPrefix + "_frobeniusMap6", elt, t0), + + // let t1 = f.invert() + c.call(ftmPrefix + "_inverse", elt, t1), + + // let mut t2 = t0 * t1; + c.call(ftmPrefix + "_mul", t0, t1, t2), + + // t1 = t2.clone(); + c.call(ftmPrefix + "_copy", t2, t1), + + // t2 = t2.frobenius_map().frobenius_map(); + c.call(ftmPrefix + "_frobeniusMap2", t2, t2), + + // t2 *= t1; + c.call(ftmPrefix + "_mul", t2, t1, t2), + + // t1 = cyclotomic_square(t2).conjugate(); + c.call(prefix + "__cyclotomicSquare", t2, t1), + c.call(ftmPrefix + "_conjugate", t1, t1), + + // let mut t3 = cycolotomic_exp(t2); + c.call(prefix + "__cyclotomicExp_w0", t2, t3), + + // let mut t4 = cyclotomic_square(t3); + c.call(prefix + "__cyclotomicSquare", t3, t4), + + // let mut t5 = t1 * t3; + c.call(ftmPrefix + "_mul", t1, t3, t5), + + // t1 = cycolotomic_exp(t5); + c.call(prefix + "__cyclotomicExp_w0", t5, t1), + + // t0 = cycolotomic_exp(t1); + c.call(prefix + "__cyclotomicExp_w0", t1, t0), + + // let mut t6 = cycolotomic_exp(t0); + c.call(prefix + "__cyclotomicExp_w0", t0, t6), + + // t6 *= t4; + c.call(ftmPrefix + "_mul", t6, t4, t6), + + // t4 = cycolotomic_exp(t6); + c.call(prefix + "__cyclotomicExp_w0", t6, t4), + + // t5 = t5.conjugate(); + c.call(ftmPrefix + "_conjugate", t5, t5), + + // t4 *= t5 * t2; + c.call(ftmPrefix + "_mul", t4, t5, t4), + c.call(ftmPrefix + "_mul", t4, t2, t4), + + // t5 = t2.conjugate(); + c.call(ftmPrefix + "_conjugate", t2, t5), + + // t1 *= t2; + c.call(ftmPrefix + "_mul", t1, t2, t1), + + // t1 = t1.frobenius_map().frobenius_map().frobenius_map(); + c.call(ftmPrefix + "_frobeniusMap3", t1, t1), + + // t6 *= t5; + c.call(ftmPrefix + "_mul", t6, t5, t6), + + // t6 = t6.frobenius_map(); + c.call(ftmPrefix + "_frobeniusMap1", t6, t6), + + // t3 *= t0; + c.call(ftmPrefix + "_mul", t3, t0, t3), + + // t3 = t3.frobenius_map().frobenius_map(); + c.call(ftmPrefix + "_frobeniusMap2", t3, t3), + + // t3 *= t1; + c.call(ftmPrefix + "_mul", t3, t1, t3), + + // t3 *= t6; + c.call(ftmPrefix + "_mul", t3, t6, t3), + + // f = t3 * t4; + c.call(ftmPrefix + "_mul", t3, t4, res), + ); + } + + + const pPreP = module.alloc(prePSize); + const pPreQ = module.alloc(preQSize); + + function buildPairingEquation(nPairings) { + + const f = module.addFunction(prefix+ "_pairingEq"+nPairings); + for (let i=0; i. +*/ + +// module.exports.bn128_wasm = require("./build/bn128_wasm.js"); +// module.exports.bls12381_wasm = require("./build/bls12381_wasm.js"); +// module.exports.mnt6753_wasm = require("./build/mnt6753_wasm.js"); + +var buildBn128$1 = build_bn128; +var buildBls12381$1 = build_bls12381; +var buildBls12377$1 = build_bls12377; + +/* global BigInt */ + +function stringifyBigInts(o) { + if (typeof o == "bigint" || o.eq !== undefined) { + return o.toString(10); + } else if (o instanceof Uint8Array) { + return fromRprLE(o, 0); + } else if (Array.isArray(o)) { + return o.map(stringifyBigInts); + } else if (typeof o == "object") { + const res = {}; + const keys = Object.keys(o); + keys.forEach((k) => { + res[k] = stringifyBigInts(o[k]); + }); + return res; + } else { + return o; + } +} function unstringifyBigInts(o) { if (typeof o == "string" && /^[0-9]+$/.test(o)) { @@ -14153,7 +15615,7 @@ function leBuff2int(buff) { function leInt2Buff(n, len) { let r = n; if (typeof len === "undefined") { - len = Math.floor((bitLength$6(n) - 1) / 8) + 1; + len = Math.floor((bitLength$7(n) - 1) / 8) + 1; if (len == 0) len = 1; } const buff = new Uint8Array(len); @@ -14292,19 +15754,19 @@ function buffer2array(buff, sG) { var _utils = /*#__PURE__*/Object.freeze({ __proto__: null, - array2buffer: array2buffer, + stringifyBigInts: stringifyBigInts, + unstringifyBigInts: unstringifyBigInts, beBuff2int: beBuff2int, beInt2Buff: beInt2Buff, - bitReverse: bitReverse, - buffReverseBits: buffReverseBits, - buffer2array: buffer2array, leBuff2int: leBuff2int, leInt2Buff: leInt2Buff, - log2: log2, - stringifyBigInts: stringifyBigInts, stringifyFElements: stringifyFElements, - unstringifyBigInts: unstringifyBigInts, - unstringifyFElements: unstringifyFElements + unstringifyFElements: unstringifyFElements, + bitReverse: bitReverse, + log2: log2, + buffReverseBits: buffReverseBits, + array2buffer: array2buffer, + buffer2array: buffer2array }); const PAGE_SIZE = 1<<30; @@ -14459,7 +15921,7 @@ class WasmField1 { this.m = 1; this.half = shiftRight(p, one); - this.bitLength = bitLength$6(p); + this.bitLength = bitLength$7(p); this.mask = sub(shiftLeft(one, this.bitLength), one); this.pOp1 = tm.alloc(n8); @@ -14494,7 +15956,7 @@ class WasmField1 { this.s = 0; let t = sub(this.p, one); - while ( !isOdd$5(t) ) { + while ( !isOdd$6(t) ) { this.s = this.s + 1; t = shiftRight(t, one); } @@ -14613,7 +16075,7 @@ class WasmField1 { e(a, b) { if (a instanceof Uint8Array) return a; let ra = e(a, b); - if (isNegative$4(ra)) { + if (isNegative$5(ra)) { ra = neg(ra); if (gt(ra, this.p)) { ra = mod(ra, this.p); @@ -17279,7 +18741,6 @@ function toHexString(byteArray) { along with wasmbuilder. If not, see . */ - class CodeBuilder { constructor(func) { this.func = func; @@ -17627,7 +19088,6 @@ class CodeBuilder { along with wasmbuilder. If not, see . */ - const typeCodes = { "i32": 0x7f, "i64": 0x7e, @@ -17741,7 +19201,6 @@ class FunctionBuilder { along with wasmbuilder. If not, see . */ - class ModuleBuilder { constructor() { @@ -18140,11 +19599,70 @@ async function buildBls12381(singleThread, plugins) { return curve; } +globalThis.curve_bls12377 = null; + +async function buildBls12377(singleThread, plugins) { + if ((!singleThread) && (globalThis.curve_bls12377)) return globalThis.curve_bls12377; + + const moduleBuilder = new ModuleBuilder(); + moduleBuilder.setMemory(25); + buildBls12377$1(moduleBuilder); + + if (plugins) plugins(moduleBuilder); + + const bls12377wasm = {}; + + bls12377wasm.code = moduleBuilder.build(); + bls12377wasm.pq = moduleBuilder.modules.f1m.pq; + bls12377wasm.pr = moduleBuilder.modules.frm.pq; + bls12377wasm.pG1gen = moduleBuilder.modules.bls12377.pG1gen; + bls12377wasm.pG1zero = moduleBuilder.modules.bls12377.pG1zero; + bls12377wasm.pG1b = moduleBuilder.modules.bls12377.pG1b; + bls12377wasm.pG2gen = moduleBuilder.modules.bls12377.pG2gen; + bls12377wasm.pG2zero = moduleBuilder.modules.bls12377.pG2zero; + bls12377wasm.pG2b = moduleBuilder.modules.bls12377.pG2b; + bls12377wasm.pOneT = moduleBuilder.modules.bls12377.pOneT; + bls12377wasm.prePSize = moduleBuilder.modules.bls12377.prePSize; + bls12377wasm.preQSize = moduleBuilder.modules.bls12377.preQSize; + bls12377wasm.n8q = 48; + bls12377wasm.n8r = 32; + bls12377wasm.q = moduleBuilder.modules.bls12377.q; + bls12377wasm.r = moduleBuilder.modules.bls12377.r; + + const params = { + name: "bls12377", + wasm: bls12377wasm, + q: e("01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001", 16), + r: e("12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001", 16), + n8q: 48, + n8r: 32, + cofactorG1: e("0x170b5d44300000000000000000000000", 16), + cofactorG2: e("0x26ba558ae9562addd88d99a6f6a829fbb36b00e1dcc40c8c505634fae2e189d693e8c36676bd09a0f3622fba094800452217cc900000000000000000000001", 16), + singleThread: singleThread ? true : false + }; + + const curve = await buildEngine(params); + curve.terminate = async function () { + if (!params.singleThread) { + globalThis.curve_bls12377 = null; + await this.tm.terminate(); + } + }; + + if (!singleThread) { + globalThis.curve_bls12377 = curve; + } + + return curve; +} + const bls12381r = e("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16); const bn128r = e("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const bls12377r = e("12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001", 16); const bls12381q = e("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16); const bn128q = e("21888242871839275222246405745257275088696311157297823662689037894645226208583"); +const bls12377q = e("01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001", 16); async function getCurveFromR(r, singleThread, plugins) { let curve; @@ -18152,6 +19670,8 @@ async function getCurveFromR(r, singleThread, plugins) { curve = await buildBn128(singleThread, plugins); } else if (eq(r, bls12381r)) { curve = await buildBls12381(singleThread, plugins); + } else if (eq(r, bls12377r)) { + curve = await buildBls12377(singleThread, plugins); } else { throw new Error(`Curve not supported: ${toString(r)}`); } @@ -18164,6 +19684,8 @@ async function getCurveFromQ(q, singleThread, plugins) { curve = await buildBn128(singleThread, plugins); } else if (eq(q, bls12381q)) { curve = await buildBls12381(singleThread, plugins); + } else if (eq(q, bls12377q)) { + curve = await buildBls12377(singleThread, plugins); } else { throw new Error(`Curve not supported: ${toString(q, 16)}`); } @@ -18177,6 +19699,8 @@ async function getCurveFromName(name, singleThread, plugins) { curve = await buildBn128(singleThread, plugins); } else if (["BLS12381"].indexOf(normName) >= 0) { curve = await buildBls12381(singleThread, plugins); + } else if (["BLS12377"].indexOf(normName) >= 0) { + curve = await buildBls12377(singleThread, plugins); } else { throw new Error(`Curve not supported: ${name}`); } @@ -18191,4 +19715,4 @@ async function getCurveFromName(name, singleThread, plugins) { const Scalar=_Scalar; const utils = _utils; -export { BigBuffer, ChaCha, EC, ZqField as F1Field, F2Field, F3Field, PolField, Scalar, ZqField, buildBls12381, buildBn128, getCurveFromName, getCurveFromQ, getCurveFromR, utils }; +export { BigBuffer, ChaCha, EC, ZqField as F1Field, F2Field, F3Field, PolField, Scalar, ZqField, buildBls12377, buildBls12381, buildBn128, getCurveFromName, getCurveFromQ, getCurveFromR, utils }; diff --git a/build/main.cjs b/build/main.cjs index 5bb247b..23beaae 100644 --- a/build/main.cjs +++ b/build/main.cjs @@ -1,11 +1,19 @@ 'use strict'; +Object.defineProperty(exports, '__esModule', { value: true }); + var crypto = require('crypto'); var wasmcurves = require('wasmcurves'); var os = require('os'); var Worker = require('web-worker'); var wasmbuilder = require('wasmbuilder'); +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto); +var os__default = /*#__PURE__*/_interopDefaultLegacy(os); +var Worker__default = /*#__PURE__*/_interopDefaultLegacy(Worker); + /* global BigInt */ const hexLen = [ 0, 1, 2, 2, 3, 3, 3, 3, 4 ,4 ,4 ,4 ,4 ,4 ,4 ,4]; @@ -255,51 +263,51 @@ const one = e(1); var _Scalar = /*#__PURE__*/Object.freeze({ __proto__: null, - abs: abs, - add: add, - band: band, - bitLength: bitLength, - bits: bits, - bor: bor, - bxor: bxor, - div: div, + fromString: fromString, e: e, - eq: eq, - exp: exp$1, fromArray: fromArray, - fromRprBE: fromRprBE, - fromRprLE: fromRprLE, - fromString: fromString, - geq: geq, - gt: gt, + bitLength: bitLength, isNegative: isNegative, - isOdd: isOdd, isZero: isZero, - land: land, - leq: leq, - lnot: lnot, - lor: lor, - lt: lt, - mod: mod, - mul: mul, - naf: naf, - neg: neg, - neq: neq, - one: one, - pow: pow, shiftLeft: shiftLeft, shiftRight: shiftRight, shl: shl, shr: shr, - square: square, - sub: sub, - toArray: toArray, - toLEBuff: toLEBuff, + isOdd: isOdd, + naf: naf, + bits: bits, toNumber: toNumber, - toRprBE: toRprBE, + toArray: toArray, + add: add, + sub: sub, + neg: neg, + mul: mul, + square: square, + pow: pow, + exp: exp$1, + abs: abs, + div: div, + mod: mod, + eq: eq, + neq: neq, + lt: lt, + gt: gt, + leq: leq, + geq: geq, + band: band, + bor: bor, + bxor: bxor, + land: land, + lor: lor, + lnot: lnot, toRprLE: toRprLE, + toRprBE: toRprBE, + fromRprLE: fromRprLE, + fromRprBE: fromRprBE, toString: toString, - zero: zero + toLEBuff: toLEBuff, + zero: zero, + one: one }); /* @@ -939,7 +947,6 @@ function __bitReverse(p, bits) { */ - function mulScalar(F, base, e) { let res; @@ -1281,7 +1288,7 @@ function getRandomBytes(n) { } } else { // NodeJS - crypto.randomFillSync(array); + crypto__default["default"].randomFillSync(array); } return array; } @@ -1833,7 +1840,6 @@ class ZqField { snarkjs. If not, see . */ - class F2Field { constructor(F, nonResidue) { this.type="F2"; @@ -2071,7 +2077,6 @@ class F2Field { snarkjs. If not, see . */ - class F3Field { constructor(F, nonResidue) { this.type="F3"; @@ -2356,7 +2361,6 @@ class F3Field { */ - function isGreatest(F, a) { if (Array.isArray(a)) { for (let i=a.length-1; i>=0; i--) { @@ -3019,19 +3023,19 @@ function buffer2array(buff, sG) { var _utils = /*#__PURE__*/Object.freeze({ __proto__: null, - array2buffer: array2buffer, + stringifyBigInts: stringifyBigInts, + unstringifyBigInts: unstringifyBigInts, beBuff2int: beBuff2int, beInt2Buff: beInt2Buff, - bitReverse: bitReverse, - buffReverseBits: buffReverseBits, - buffer2array: buffer2array, leBuff2int: leBuff2int, leInt2Buff: leInt2Buff, - log2: log2, - stringifyBigInts: stringifyBigInts, stringifyFElements: stringifyFElements, - unstringifyBigInts: unstringifyBigInts, - unstringifyFElements: unstringifyFElements + unstringifyFElements: unstringifyFElements, + bitReverse: bitReverse, + log2: log2, + buffReverseBits: buffReverseBits, + array2buffer: array2buffer, + buffer2array: buffer2array }); const PAGE_SIZE = 1<<30; @@ -4473,7 +4477,7 @@ async function buildThreadManager(wasm, singleThread) { concurrency = navigator.hardwareConcurrency; } } else { - concurrency = os.cpus().length; + concurrency = os__default["default"].cpus().length; } if(concurrency == 0){ @@ -4486,7 +4490,7 @@ async function buildThreadManager(wasm, singleThread) { for (let i = 0; i= 0) { curve = await buildBls12381(singleThread, plugins); + } else if (["BLS12377"].indexOf(normName) >= 0) { + curve = await buildBls12377(singleThread, plugins); } else { throw new Error(`Curve not supported: ${name}`); } @@ -6011,6 +6080,7 @@ exports.F3Field = F3Field; exports.PolField = PolField; exports.Scalar = Scalar; exports.ZqField = ZqField; +exports.buildBls12377 = buildBls12377; exports.buildBls12381 = buildBls12381; exports.buildBn128 = buildBn128; exports.getCurveFromName = getCurveFromName; diff --git a/main.js b/main.js index 1981557..bde0b05 100644 --- a/main.js +++ b/main.js @@ -13,6 +13,7 @@ export {default as EC} from "./src/ec.js"; export {default as buildBn128} from "./src/bn128.js"; export {default as buildBls12381} from "./src/bls12381.js"; +export {default as buildBls12377} from "./src/bls12377.js"; import * as _utils from "./src/utils.js"; export const utils = _utils; @@ -21,4 +22,3 @@ export {default as ChaCha} from "./src/chacha.js"; export {default as BigBuffer} from "./src/bigbuffer.js"; export {getCurveFromR, getCurveFromQ, getCurveFromName} from "./src/curves.js"; - diff --git a/src/bls12377.js b/src/bls12377.js new file mode 100644 index 0000000..96d6ba2 --- /dev/null +++ b/src/bls12377.js @@ -0,0 +1,62 @@ +import { buildBls12377 as buildBls12377wasm } from "wasmcurves"; +import buildEngine from "./engine.js"; +import * as Scalar from "./scalar.js"; +import { ModuleBuilder } from "wasmbuilder"; + +globalThis.curve_bls12377 = null; + +export default async function buildBls12377(singleThread, plugins) { + if ((!singleThread) && (globalThis.curve_bls12377)) return globalThis.curve_bls12377; + + const moduleBuilder = new ModuleBuilder(); + moduleBuilder.setMemory(25); + buildBls12377wasm(moduleBuilder); + + if (plugins) plugins(moduleBuilder); + + const bls12377wasm = {}; + + bls12377wasm.code = moduleBuilder.build(); + bls12377wasm.pq = moduleBuilder.modules.f1m.pq; + bls12377wasm.pr = moduleBuilder.modules.frm.pq; + bls12377wasm.pG1gen = moduleBuilder.modules.bls12377.pG1gen; + bls12377wasm.pG1zero = moduleBuilder.modules.bls12377.pG1zero; + bls12377wasm.pG1b = moduleBuilder.modules.bls12377.pG1b; + bls12377wasm.pG2gen = moduleBuilder.modules.bls12377.pG2gen; + bls12377wasm.pG2zero = moduleBuilder.modules.bls12377.pG2zero; + bls12377wasm.pG2b = moduleBuilder.modules.bls12377.pG2b; + bls12377wasm.pOneT = moduleBuilder.modules.bls12377.pOneT; + bls12377wasm.prePSize = moduleBuilder.modules.bls12377.prePSize; + bls12377wasm.preQSize = moduleBuilder.modules.bls12377.preQSize; + bls12377wasm.n8q = 48; + bls12377wasm.n8r = 32; + bls12377wasm.q = moduleBuilder.modules.bls12377.q; + bls12377wasm.r = moduleBuilder.modules.bls12377.r; + + const params = { + name: "bls12377", + wasm: bls12377wasm, + q: Scalar.e("01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001", 16), + r: Scalar.e("12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001", 16), + n8q: 48, + n8r: 32, + cofactorG1: Scalar.e("0x170b5d44300000000000000000000000", 16), + cofactorG2: Scalar.e("0x26ba558ae9562addd88d99a6f6a829fbb36b00e1dcc40c8c505634fae2e189d693e8c36676bd09a0f3622fba094800452217cc900000000000000000000001", 16), + singleThread: singleThread ? true : false + }; + + const curve = await buildEngine(params); + curve.terminate = async function () { + if (!params.singleThread) { + globalThis.curve_bls12377 = null; + await this.tm.terminate(); + } + }; + + if (!singleThread) { + globalThis.curve_bls12377 = curve; + } + + return curve; +} + diff --git a/src/curves.js b/src/curves.js index 164702e..c681fbd 100644 --- a/src/curves.js +++ b/src/curves.js @@ -1,12 +1,15 @@ import * as Scalar from "./scalar.js"; import {default as buildBn128} from "./bn128.js"; import {default as buildBls12381} from "./bls12381.js"; +import {default as buildBls12377} from "./bls12377.js"; const bls12381r = Scalar.e("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16); const bn128r = Scalar.e("21888242871839275222246405745257275088548364400416034343698204186575808495617"); +const bls12377r = Scalar.e("12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001", 16); const bls12381q = Scalar.e("1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab", 16); const bn128q = Scalar.e("21888242871839275222246405745257275088696311157297823662689037894645226208583"); +const bls12377q = Scalar.e("01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001", 16); export async function getCurveFromR(r, singleThread, plugins) { let curve; @@ -14,6 +17,8 @@ export async function getCurveFromR(r, singleThread, plugins) { curve = await buildBn128(singleThread, plugins); } else if (Scalar.eq(r, bls12381r)) { curve = await buildBls12381(singleThread, plugins); + } else if (Scalar.eq(r, bls12377r)) { + curve = await buildBls12377(singleThread, plugins); } else { throw new Error(`Curve not supported: ${Scalar.toString(r)}`); } @@ -26,6 +31,8 @@ export async function getCurveFromQ(q, singleThread, plugins) { curve = await buildBn128(singleThread, plugins); } else if (Scalar.eq(q, bls12381q)) { curve = await buildBls12381(singleThread, plugins); + } else if (Scalar.eq(q, bls12377q)) { + curve = await buildBls12377(singleThread, plugins); } else { throw new Error(`Curve not supported: ${Scalar.toString(q, 16)}`); } @@ -39,6 +46,8 @@ export async function getCurveFromName(name, singleThread, plugins) { curve = await buildBn128(singleThread, plugins); } else if (["BLS12381"].indexOf(normName) >= 0) { curve = await buildBls12381(singleThread, plugins); + } else if (["BLS12377"].indexOf(normName) >= 0) { + curve = await buildBls12377(singleThread, plugins); } else { throw new Error(`Curve not supported: ${name}`); }