From ee0addb07dfc74dfbf11a6786e8fe426b8852ee4 Mon Sep 17 00:00:00 2001 From: Jordi Baylina Date: Sat, 28 Mar 2020 21:28:43 +0100 Subject: [PATCH] fields and bn128 moved to ffjavascript --- cli.js | 2 +- index.js | 7 +- package.json | 2 +- src/bigint_old.js | 522 --------------------- src/bn128.js | 445 ------------------ src/calculateWitness_old.js | 233 ---------- src/circuit_old.js | 191 -------- src/f2field.js | 133 ------ src/f3field.js | 177 -------- src/futils.js | 53 --- src/gcurve.js | 186 -------- src/polfield.js | 527 ---------------------- src/prover_groth.js | 5 +- src/prover_kimleeoh.js | 5 +- src/prover_original.js | 5 +- src/r1cs_parser_old.js | 296 ------------ src/ratfield.js | 127 ------ src/setup_groth.js | 5 +- src/setup_kimleeoh.js | 5 +- src/setup_original.js | 5 +- src/stringifybigint.js | 55 --- src/utils.js | 47 +- src/verifier.js | 67 --- src/verifier_groth.js | 3 +- src/verifier_kimleeoh.js | 3 +- src/verifier_original.js | 3 +- src/zqfield_old.js | 151 ------- test/algebra.js | 254 ----------- test/calculatewitness.js | 40 -- test/circuit/circuit.circom | 4 +- test/circuit/circuit.r1cs | Bin 164136 -> 16536 bytes test/circuit/circuit.wasm | Bin 35606 -> 31872 bytes test/{zksnark_groth.js => groth.js} | 0 test/{zksnark_kimleeoh.js => kimleeoh.js} | 0 test/{zksnark.js => original.js} | 0 test/pols.js | 217 --------- test/r1cs/circuit.json | 126 ------ test/r1cs/circuit.r1cs | Bin 443 -> 0 bytes test/ratzqfield.js | 89 ---- 39 files changed, 64 insertions(+), 3926 deletions(-) delete mode 100644 src/bigint_old.js delete mode 100644 src/bn128.js delete mode 100644 src/calculateWitness_old.js delete mode 100644 src/circuit_old.js delete mode 100644 src/f2field.js delete mode 100644 src/f3field.js delete mode 100644 src/futils.js delete mode 100644 src/gcurve.js delete mode 100644 src/polfield.js delete mode 100644 src/r1cs_parser_old.js delete mode 100644 src/ratfield.js delete mode 100644 src/stringifybigint.js delete mode 100644 src/verifier.js delete mode 100644 src/zqfield_old.js delete mode 100644 test/algebra.js delete mode 100644 test/calculatewitness.js rename test/{zksnark_groth.js => groth.js} (100%) rename test/{zksnark_kimleeoh.js => kimleeoh.js} (100%) rename test/{zksnark.js => original.js} (100%) delete mode 100644 test/pols.js delete mode 100644 test/r1cs/circuit.json delete mode 100644 test/r1cs/circuit.r1cs delete mode 100644 test/ratzqfield.js diff --git a/cli.js b/cli.js index 6a388ad..16f0caa 100755 --- a/cli.js +++ b/cli.js @@ -25,7 +25,7 @@ const fs = require("fs"); const path = require("path"); const zkSnark = require("./index.js"); -const {stringifyBigInts, unstringifyBigInts} = require("./src/stringifybigint.js"); +const {stringifyBigInts, unstringifyBigInts} = require("./src/utils.js"); const loadR1cs = require("r1csfile").load; const WitnessCalculatorBuilder = require("circom_runtime").WitnessCalculatorBuilder; diff --git a/index.js b/index.js index 5fc82e1..a7238d8 100644 --- a/index.js +++ b/index.js @@ -33,9 +33,6 @@ exports.kimleeoh = { isValid: require("./src/verifier_kimleeoh.js") }; -exports.stringifyBigInts = require("./src/stringifybigint.js").stringifyBigInts; -exports.unstringifyBigInts = require("./src/stringifybigint.js").unstringifyBigInts; +exports.stringifyBigInts = require("./src/utils.js").stringifyBigInts; +exports.unstringifyBigInts = require("./src/utils.js").unstringifyBigInts; - -const Bn128 = require("./src/bn128.js"); -exports.bn128 = new Bn128(); diff --git a/package.json b/package.json index a75b780..f2b804b 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "chai": "^4.2.0", "circom_runtime": "0.0.3", "escape-string-regexp": "^1.0.5", - "ffjavascript": "0.0.3", + "ffjavascript": "0.0.4", "keccak": "^3.0.0", "r1csfile": "0.0.3", "yargs": "^12.0.5" diff --git a/src/bigint_old.js b/src/bigint_old.js deleted file mode 100644 index 54bfac8..0000000 --- a/src/bigint_old.js +++ /dev/null @@ -1,522 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -/* global BigInt */ -const bigInt = require("big-integer"); - -let wBigInt; - -if (typeof(BigInt) != "undefined") { - wBigInt = BigInt; - wBigInt.one = wBigInt(1); - wBigInt.zero = wBigInt(0); - - // Affine - wBigInt.genAffine = (q) => { - const nq = -q; - return (a) => { - let aux = a; - if (aux < 0) { - if (aux <= nq) { - aux = aux % q; - } - if (aux < wBigInt.zero) { - aux = aux + q; - } - } else { - if (aux >= q) { - aux = aux % q; - } - } - return aux.valueOf(); - }; - }; - - - // Inverse - wBigInt.genInverse = (q) => { - return (a) => { - let t = wBigInt.zero; - let r = q; - let newt = wBigInt.one; - let newr = wBigInt.affine(a, q); - while (newr!=wBigInt.zero) { - let q = r/newr; - [t, newt] = [newt, t-q*newt]; - [r, newr] = [newr, r-q*newr]; - } - if (t { - if (q) { - return (a,b) => (a+b) % q; - } else { - return (a,b) => a+b; - } - }; - - // Sub - wBigInt.genSub = (q) => { - if (q) { - return (a,b) => (a-b) % q; - } else { - return (a,b) => a-b; - } - }; - - - // Neg - wBigInt.genNeg = (q) => { - if (q) { - return (a) => (-a) % q; - } else { - return (a) => -a; - } - }; - - // Mul - wBigInt.genMul = (q) => { - if (q) { - return (a,b) => (a*b) % q; - } else { - return (a,b) => a*b; - } - }; - - // Shr - wBigInt.genShr = () => { - return (a,b) => a >> wBigInt(b); - }; - - // Shl - wBigInt.genShl = (q) => { - if (q) { - return (a,b) => (a << wBigInt(b)) % q; - } else { - return (a,b) => a << wBigInt(b); - } - }; - - // Equals - wBigInt.genEquals = (q) => { - if (q) { - return (a,b) => (a.affine(q) == b.affine(q)); - } else { - return (a,b) => a == b; - } - }; - - // Square - wBigInt.genSquare = (q) => { - if (q) { - return (a) => (a*a) %q; - } else { - return (a) => a*a; - } - }; - - - // Double - wBigInt.genDouble = (q) => { - if (q) { - return (a) => (a+a) %q; - } else { - return (a) => a+a; - } - }; - - // IsZero - wBigInt.genIsZero = (q) => { - if (q) { - return (a) => (a.affine(q) == wBigInt.zero); - } else { - return (a) => a == wBigInt.zero; - } - }; - - - // Other minor functions - wBigInt.prototype.isOdd = function() { - return (this & wBigInt.one) == wBigInt(1); - }; - - wBigInt.prototype.isNegative = function() { - return this < wBigInt.zero; - }; - - wBigInt.prototype.and = function(m) { - return this & m; - }; - - wBigInt.prototype.div = function(c) { - return this / c; - }; - - wBigInt.prototype.mod = function(c) { - return this % c; - }; - - wBigInt.prototype.pow = function(c) { - return this ** c; - }; - - wBigInt.prototype.abs = function() { - return (this > wBigInt.zero) ? this : -this; - }; - - wBigInt.prototype.modPow = function(e, m) { - let acc = wBigInt.one; - let exp = this; - let rem = e; - while (rem) { - if (rem & wBigInt.one) { - acc = (acc * exp) %m; - } - exp = (exp * exp) % m; - rem = rem >> wBigInt.one; - } - return acc; - }; - - wBigInt.prototype.greaterOrEquals = function(b) { - return this >= b; - }; - - wBigInt.prototype.greater = function(b) { - return this > b; - }; - wBigInt.prototype.gt = wBigInt.prototype.greater; - - wBigInt.prototype.lesserOrEquals = function(b) { - return this <= b; - }; - - wBigInt.prototype.lesser = function(b) { - return this < b; - }; - wBigInt.prototype.lt = wBigInt.prototype.lesser; - - wBigInt.prototype.equals = function(b) { - return this == b; - }; - wBigInt.prototype.eq = wBigInt.prototype.equals; - - wBigInt.prototype.neq = function(b) { - return this != b; - }; - - wBigInt.prototype.toJSNumber = function() { - return Number(this); - }; - - -} else { - - var oldProto = bigInt.prototype; - wBigInt = function(a) { - if ((typeof a == "string") && (a.slice(0,2) == "0x")) { - return bigInt(a.slice(2), 16); - } else { - return bigInt(a); - } - }; - wBigInt.one = bigInt.one; - wBigInt.zero = bigInt.zero; - wBigInt.prototype = oldProto; - - wBigInt.prototype.div = function(c) { - return this.divide(c); - }; - - // Affine - wBigInt.genAffine = (q) => { - const nq = wBigInt.zero.minus(q); - return (a) => { - let aux = a; - if (aux.isNegative()) { - if (aux.lesserOrEquals(nq)) { - aux = aux.mod(q); - } - if (aux.isNegative()) { - aux = aux.add(q); - } - } else { - if (aux.greaterOrEquals(q)) { - aux = aux.mod(q); - } - } - return aux; - }; - }; - - - // Inverse - wBigInt.genInverse = (q) => { - return (a) => a.affine(q).modInv(q); - }; - - // Add - wBigInt.genAdd = (q) => { - if (q) { - return (a,b) => { - const r = a.add(b); - return r.greaterOrEquals(q) ? r.minus(q) : r; - }; - } else { - return (a,b) => a.add(b); - } - }; - - // Sub - wBigInt.genSub = (q) => { - if (q) { - return (a,b) => a.greaterOrEquals(b) ? a.minus(b) : a.minus(b).add(q); - } else { - return (a,b) => a.minus(b); - } - }; - - wBigInt.genNeg = (q) => { - if (q) { - return (a) => a.isZero() ? a : q.minus(a); - } else { - return (a) => wBigInt.zero.minus(a); - } - }; - - // Mul - wBigInt.genMul = (q) => { - if (q) { - return (a,b) => a.times(b).mod(q); - } else { - return (a,b) => a.times(b); - } - }; - - // Shr - wBigInt.genShr = () => { - return (a,b) => a.shiftRight(wBigInt(b).value); - }; - - // Shr - wBigInt.genShl = (q) => { - if (q) { - return (a,b) => a.shiftLeft(wBigInt(b).value).mod(q); - } else { - return (a,b) => a.shiftLeft(wBigInt(b).value); - } - }; - - // Square - wBigInt.genSquare = (q) => { - if (q) { - return (a) => a.square().mod(q); - } else { - return (a) => a.square(); - } - }; - - // Double - wBigInt.genDouble = (q) => { - if (q) { - return (a) => a.add(a).mod(q); - } else { - return (a) => a.add(a); - } - }; - - // Equals - wBigInt.genEquals = (q) => { - if (q) { - return (a,b) => a.affine(q).equals(b.affine(q)); - } else { - return (a,b) => a.equals(b); - } - }; - - // IsZero - wBigInt.genIsZero = (q) => { - if (q) { - return (a) => (a.affine(q).isZero()); - } else { - return (a) => a.isZero(); - } - }; -} - - - -wBigInt.affine = function(a, q) { - return wBigInt.genAffine(q)(a); -}; - -wBigInt.prototype.affine = function (q) { - return wBigInt.affine(this, q); -}; - -wBigInt.inverse = function(a, q) { - return wBigInt.genInverse(q)(a); -}; - -wBigInt.prototype.inverse = function (q) { - return wBigInt.genInverse(q)(this); -}; - -wBigInt.add = function(a, b, q) { - return wBigInt.genAdd(q)(a,b); -}; - -wBigInt.prototype.add = function (a, q) { - return wBigInt.genAdd(q)(this, a); -}; - -wBigInt.sub = function(a, b, q) { - return wBigInt.genSub(q)(a,b); -}; - -wBigInt.prototype.sub = function (a, q) { - return wBigInt.genSub(q)(this, a); -}; - -wBigInt.neg = function(a, q) { - return wBigInt.genNeg(q)(a); -}; - -wBigInt.prototype.neg = function (q) { - return wBigInt.genNeg(q)(this); -}; - -wBigInt.mul = function(a, b, q) { - return wBigInt.genMul(q)(a,b); -}; - -wBigInt.prototype.mul = function (a, q) { - return wBigInt.genMul(q)(this, a); -}; - -wBigInt.shr = function(a, b, q) { - return wBigInt.genShr(q)(a,b); -}; - -wBigInt.prototype.shr = function (a, q) { - return wBigInt.genShr(q)(this, a); -}; - -wBigInt.shl = function(a, b, q) { - return wBigInt.genShl(q)(a,b); -}; - -wBigInt.prototype.shl = function (a, q) { - return wBigInt.genShl(q)(this, a); -}; - -wBigInt.equals = function(a, b, q) { - return wBigInt.genEquals(q)(a,b); -}; - -wBigInt.prototype.equals = function (a, q) { - return wBigInt.genEquals(q)(this, a); -}; - -wBigInt.square = function(a, q) { - return wBigInt.genSquare(q)(a); -}; - -wBigInt.prototype.square = function (q) { - return wBigInt.genSquare(q)(this); -}; - -wBigInt.double = function(a, q) { - return wBigInt.genDouble(q)(a); -}; - -wBigInt.prototype.double = function (q) { - return wBigInt.genDouble(q)(this); -}; - -wBigInt.isZero = function(a, q) { - return wBigInt.genIsZero(q)(a); -}; - -wBigInt.prototype.isZero = function (q) { - return wBigInt.genIsZero(q)(this); -}; - -wBigInt.leBuff2int = function(buff) { - let res = wBigInt.zero; - for (let i=0; i=0)) { - let c = Number(r.and(wBigInt("255"))); - buff[o] = c; - o--; - r = r.shr(8); - } - if (r.greater(wBigInt.zero)) throw new Error("Number does not feed in buffer"); - return buff; -}; - -wBigInt.prototype.beInt2Buff = function (len) { - return wBigInt.beInt2Buff(this,len); -}; - -module.exports = wBigInt; - diff --git a/src/bn128.js b/src/bn128.js deleted file mode 100644 index 97ab4f5..0000000 --- a/src/bn128.js +++ /dev/null @@ -1,445 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const bigInt = require("big-integer"); - -const F1Field = require("ffjavascript").ZqField; -const F2Field = require("./f2field.js"); -const F3Field = require("./f3field.js"); -const GCurve = require("./gcurve.js"); - -class BN128 { - - constructor() { - - this.q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583"); - this.r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); - this.g1 = [ bigInt(1), bigInt(2), bigInt(1)]; - this.g2 = [ - [ - bigInt("10857046999023057135944570762232829481370756359578518086990519993285655852781"), - bigInt("11559732032986387107991004021392285783925812861821192530917403151452391805634") - ], - [ - bigInt("8495653923123431417604973247489272438418190587263600148770280649306958101930"), - bigInt("4082367875863433681332203403145435568316851327593401208105741076214120093531") - ], - [ - bigInt("1"), - bigInt("0") - ] - ]; - - this.nonResidueF2 = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - this.nonResidueF6 = [ bigInt("9"), bigInt("1") ]; - - this.F1 = new F1Field(this.q); - this.F2 = new F2Field(this.F1, this.nonResidueF2); - this.G1 = new GCurve(this.F1, this.g1); - this.G2 = new GCurve(this.F2, this.g2); - this.F6 = new F3Field(this.F2, this.nonResidueF6); - this.F12 = new F2Field(this.F6, this.nonResidueF6); - this.Fr = new F1Field(this.r); - const self = this; - this.F12._mulByNonResidue = function(a) { - return [self.F2.mul(this.nonResidue, a[2]), a[0], a[1]]; - }; - - this._preparePairing(); - - } - - _preparePairing() { - this.loopCount = bigInt("29793968203157093288");// CONSTANT - - // Set loopCountNeg - if (this.loopCount.isNegative()) { - this.loopCount = this.loopCount.neg(); - this.loopCountNeg = true; - } else { - this.loopCountNeg = false; - } - - // Set loop_count_bits - let lc = this.loopCount; - this.loop_count_bits = []; // Constant - while (!lc.isZero()) { - this.loop_count_bits.push( lc.isOdd() ); - lc = lc.shiftRight(1); - } - - this.two_inv = this.F1.inv(bigInt(2)); - - this.coef_b = bigInt(3); - this.twist = [bigInt(9) , bigInt(1)]; - this.twist_coeff_b = this.F2.mulScalar( this.F2.inv(this.twist), this.coef_b ); - - this.frobenius_coeffs_c1_1 = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208582"); - this.twist_mul_by_q_X = - [ - bigInt("21575463638280843010398324269430826099269044274347216827212613867836435027261"), - bigInt("10307601595873709700152284273816112264069230130616436755625194854815875713954") - ]; - this.twist_mul_by_q_Y = - [ - bigInt("2821565182194536844548159561693502659359617185244120367078079554186484126554"), - bigInt("3505843767911556378687030309984248845540243509899259641013678093033130930403") - ]; - - this.final_exponent = bigInt("552484233613224096312617126783173147097382103762957654188882734314196910839907541213974502761540629817009608548654680343627701153829446747810907373256841551006201639677726139946029199968412598804882391702273019083653272047566316584365559776493027495458238373902875937659943504873220554161550525926302303331747463515644711876653177129578303191095900909191624817826566688241804408081892785725967931714097716709526092261278071952560171111444072049229123565057483750161460024353346284167282452756217662335528813519139808291170539072125381230815729071544861602750936964829313608137325426383735122175229541155376346436093930287402089517426973178917569713384748081827255472576937471496195752727188261435633271238710131736096299798168852925540549342330775279877006784354801422249722573783561685179618816480037695005515426162362431072245638324744480"); - - } - - - pairing(p1, p2) { - - const pre1 = this.precomputeG1(p1); - const pre2 = this.precomputeG2(p2); - - const r1 = this.millerLoop(pre1, pre2); - - const res = this.finalExponentiation(r1); - - return res; - } - - - precomputeG1(p) { - const Pcopy = this.G1.affine(p); - - const res = {}; - res.PX = Pcopy[0]; - res.PY = Pcopy[1]; - - return res; - } - - precomputeG2(p) { - - const Qcopy = this.G2.affine(p); - - const res = { - QX: Qcopy[0], - QY: Qcopy[1], - coeffs: [] - }; - - const R = { - X: Qcopy[0], - Y: Qcopy[1], - Z: this.F2.one - }; - - let c; - - for (let i = this.loop_count_bits.length-2; i >= 0; --i) - { - const bit = this.loop_count_bits[i]; - - c = this._doubleStep(R); - res.coeffs.push(c); - - if (bit) - { - c = this._addStep(Qcopy, R); - res.coeffs.push(c); - } - } - - const Q1 = this.G2.affine(this._g2MulByQ(Qcopy)); - if (!this.F2.eq(Q1[2], this.F2.one)) - { - throw new Error("Expected values are not equal"); - } - const Q2 = this.G2.affine(this._g2MulByQ(Q1)); - if (!this.F2.eq(Q2[2], this.F2.one)) - { - throw new Error("Expected values are not equal"); - } - - if (this.loopCountNeg) - { - R.Y = this.F2.neg(R.Y); - } - Q2[1] = this.F2.neg(Q2[1]); - - c = this._addStep(Q1, R); - res.coeffs.push(c); - - c = this._addStep(Q2, R); - res.coeffs.push(c); - - return res; - } - - millerLoop(pre1, pre2) { - let f = this.F12.one; - - let idx = 0; - - let c; - - for (let i = this.loop_count_bits.length-2; i >= 0; --i) - { - const bit = this.loop_count_bits[i]; - - /* code below gets executed for all bits (EXCEPT the MSB itself) of - alt_bn128_param_p (skipping leading zeros) in MSB to LSB - order */ - - c = pre2.coeffs[idx++]; - f = this.F12.square(f); - f = this._mul_by_024( - f, - c.ell_0, - this.F2.mulScalar(c.ell_VW , pre1.PY), - this.F2.mulScalar(c.ell_VV , pre1.PX)); - - if (bit) - { - c = pre2.coeffs[idx++]; - f = this._mul_by_024( - f, - c.ell_0, - this.F2.mulScalar(c.ell_VW, pre1.PY), - this.F2.mulScalar(c.ell_VV, pre1.PX)); - } - - } - - if (this.loopCountNeg) - { - f = this.F12.inverse(f); - } - - c = pre2.coeffs[idx++]; - f = this._mul_by_024( - f, - c.ell_0, - this.F2.mulScalar(c.ell_VW, pre1.PY), - this.F2.mulScalar(c.ell_VV, pre1.PX)); - - c = pre2.coeffs[idx++]; - f = this._mul_by_024( - f, - c.ell_0, - this.F2.mulScalar(c.ell_VW, pre1.PY), - this.F2.mulScalar(c.ell_VV, pre1.PX)); - - return f; - } - - finalExponentiation(elt) { - // TODO: There is an optimization in FF - - const res = this.F12.exp(elt,this.final_exponent); - - return res; - } - - _doubleStep(current) { - const X = current.X; - const Y = current.Y; - const Z = current.Z; - - const A = this.F2.mulScalar(this.F2.mul(X,Y), this.two_inv); // A = X1 * Y1 / 2 - const B = this.F2.square(Y); // B = Y1^2 - const C = this.F2.square(Z); // C = Z1^2 - const D = this.F2.add(C, this.F2.add(C,C)); // D = 3 * C - const E = this.F2.mul(this.twist_coeff_b, D); // E = twist_b * D - const F = this.F2.add(E, this.F2.add(E,E)); // F = 3 * E - const G = - this.F2.mulScalar( - this.F2.add( B , F ), - this.two_inv); // G = (B+F)/2 - const H = - this.F2.sub( - this.F2.square( this.F2.add(Y,Z) ), - this.F2.add( B , C)); // H = (Y1+Z1)^2-(B+C) - const I = this.F2.sub(E, B); // I = E-B - const J = this.F2.square(X); // J = X1^2 - const E_squared = this.F2.square(E); // E_squared = E^2 - - current.X = this.F2.mul( A, this.F2.sub(B,F) ); // X3 = A * (B-F) - current.Y = - this.F2.sub( - this.F2.sub( this.F2.square(G) , E_squared ), - this.F2.add( E_squared , E_squared )); // Y3 = G^2 - 3*E^2 - current.Z = this.F2.mul( B, H ); // Z3 = B * H - - const c = { - ell_0 : this.F2.mul( I, this.twist), // ell_0 = xi * I - ell_VW: this.F2.neg( H ), // ell_VW = - H (later: * yP) - ell_VV: this.F2.add( J , this.F2.add(J,J) ) // ell_VV = 3*J (later: * xP) - }; - - return c; - } - - _addStep(base, current) { - - const X1 = current.X; - const Y1 = current.Y; - const Z1 = current.Z; - const x2 = base[0]; - const y2 = base[1]; - - const D = this.F2.sub( X1, this.F2.mul(x2,Z1) ); // D = X1 - X2*Z1 - -// console.log("Y: "+ A[0].affine(this.q).toString(16)); - - const E = this.F2.sub( Y1, this.F2.mul(y2,Z1) ); // E = Y1 - Y2*Z1 - const F = this.F2.square(D); // F = D^2 - const G = this.F2.square(E); // G = E^2 - const H = this.F2.mul(D,F); // H = D*F - const I = this.F2.mul(X1,F); // I = X1 * F - const J = - this.F2.sub( - this.F2.add( H, this.F2.mul(Z1,G) ), - this.F2.add( I, I )); // J = H + Z1*G - (I+I) - - current.X = this.F2.mul( D , J ); // X3 = D*J - current.Y = - this.F2.sub( - this.F2.mul( E , this.F2.sub(I,J) ), - this.F2.mul( H , Y1)); // Y3 = E*(I-J)-(H*Y1) - current.Z = this.F2.mul(Z1,H); - const c = { - ell_0 : - this.F2.mul( - this.twist, - this.F2.sub( - this.F2.mul(E , x2), - this.F2.mul(D , y2))), // ell_0 = xi * (E * X2 - D * Y2) - ell_VV : this.F2.neg(E), // ell_VV = - E (later: * xP) - ell_VW : D // ell_VW = D (later: * yP ) - }; - - return c; - } - - _mul_by_024(a, ell_0, ell_VW, ell_VV) { - - // Old implementation -/* - const b = [ - [ell_0, this.F2.zero, ell_VV], - [this.F2.zero, ell_VW, this.F2.zero] - ]; - - return this.F12.mul(a,b); -*/ - - // This is a new implementation, - // But it does not look worthy - // at least in javascript. - - let z0 = a[0][0]; - let z1 = a[0][1]; - let z2 = a[0][2]; - let z3 = a[1][0]; - let z4 = a[1][1]; - let z5 = a[1][2]; - - const x0 = ell_0; - const x2 = ell_VV; - const x4 = ell_VW; - - const D0 = this.F2.mul(z0, x0); - const D2 = this.F2.mul(z2, x2); - const D4 = this.F2.mul(z4, x4); - const t2 = this.F2.add(z0, z4); - let t1 = this.F2.add(z0, z2); - const s0 = this.F2.add(this.F2.add(z1,z3),z5); - - // For z.a_.a_ = z0. - let S1 = this.F2.mul(z1, x2); - let T3 = this.F2.add(S1, D4); - let T4 = this.F2.add( this.F2.mul(this.nonResidueF6, T3),D0); - z0 = T4; - - // For z.a_.b_ = z1 - T3 = this.F2.mul(z5, x4); - S1 = this.F2.add(S1, T3); - T3 = this.F2.add(T3, D2); - T4 = this.F2.mul(this.nonResidueF6, T3); - T3 = this.F2.mul(z1, x0); - S1 = this.F2.add(S1, T3); - T4 = this.F2.add(T4, T3); - z1 = T4; - - // For z.a_.c_ = z2 - let t0 = this.F2.add(x0, x2); - T3 = this.F2.sub( - this.F2.mul(t1, t0), - this.F2.add(D0, D2)); - T4 = this.F2.mul(z3, x4); - S1 = this.F2.add(S1, T4); - - // For z.b_.a_ = z3 (z3 needs z2) - t0 = this.F2.add(z2, z4); - z2 = this.F2.add(T3, T4); - t1 = this.F2.add(x2, x4); - T3 = this.F2.sub( - this.F2.mul(t0,t1), - this.F2.add(D2, D4)); - - T4 = this.F2.mul(this.nonResidueF6, T3); - T3 = this.F2.mul(z3, x0); - S1 = this.F2.add(S1, T3); - T4 = this.F2.add(T4, T3); - z3 = T4; - - // For z.b_.b_ = z4 - T3 = this.F2.mul(z5, x2); - S1 = this.F2.add(S1, T3); - T4 = this.F2.mul(this.nonResidueF6, T3); - t0 = this.F2.add(x0, x4); - T3 = this.F2.sub( - this.F2.mul(t2,t0), - this.F2.add(D0, D4)); - T4 = this.F2.add(T4, T3); - z4 = T4; - - // For z.b_.c_ = z5. - t0 = this.F2.add(this.F2.add(x0, x2), x4); - T3 = this.F2.sub(this.F2.mul(s0, t0), S1); - z5 = T3; - - return [ - [z0, z1, z2], - [z3, z4, z5] - ]; - - - } - - _g2MulByQ(p) { - const fmx = [p[0][0], this.F1.mul(p[0][1], this.frobenius_coeffs_c1_1 )]; - const fmy = [p[1][0], this.F1.mul(p[1][1], this.frobenius_coeffs_c1_1 )]; - const fmz = [p[2][0], this.F1.mul(p[2][1], this.frobenius_coeffs_c1_1 )]; - return [ - this.F2.mul(this.twist_mul_by_q_X , fmx), - this.F2.mul(this.twist_mul_by_q_Y , fmy), - fmz - ]; - } -} - -module.exports = BN128; diff --git a/src/calculateWitness_old.js b/src/calculateWitness_old.js deleted file mode 100644 index 97e5313..0000000 --- a/src/calculateWitness_old.js +++ /dev/null @@ -1,233 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const bigInt = require("big-integer"); - -module.exports = calculateWitness; - -function calculateWitness(circuit, inputSignals, options) { - options = options || {}; - if (!options.logFunction) options.logFunction = console.log; - const ctx = new RTCtx(circuit, options); - - function iterateSelector(values, sels, cb) { - if (!Array.isArray(values)) { - return cb(sels, values); - } - for (let i=0; i " + ctx.witness[i].toString()); - } - return ctx.witness.slice(0, circuit.nVars); -// return ctx.witness; -} - -class RTCtx { - constructor(circuit, options) { - this.options = options; - this.scopes = []; - this.circuit = circuit; - this.witness = new Array(circuit.nSignals); - this.notInitSignals = {}; - for (let c in this.circuit.components) { - this.notInitSignals[c] = this.circuit.components[c].inputSignals; - } - } - - _sels2str(sels) { - let res = ""; - for (let i=0; i { - if (this.notInitSignals[c] == 0) this.triggerComponent(c); - }); - return this.witness[sId]; - } - - setVar(name, sels, value) { - function setVarArray(a, sels2, value) { - if (sels2.length == 1) { - a[sels2[0]] = value; - } else { - if (typeof(a[sels2[0]]) == "undefined") a[sels2[0]] = []; - setVarArray(a[sels2[0]], sels2.slice(1), value); - } - } - const scope = this.scopes[this.scopes.length-1]; - if (sels.length == 0) { - scope[name] = value; - } else { - if (typeof(scope[name]) == "undefined") scope[name] = []; - setVarArray(scope[name], sels, value); - } - return value; - } - - getVar(name, sels) { - function select(a, sels2) { - return (sels2.length == 0) ? a : select(a[sels2[0]], sels2.slice(1)); - } - for (let i=this.scopes.length-1; i>=0; i--) { - if (typeof(this.scopes[i][name]) != "undefined") return select(this.scopes[i][name], sels); - } - throw new Error("Variable not defined: " + name); - } - - getSignal(name, sels) { - let fullName = name=="one" ? "one" : this.currentComponent + "." + name; - fullName += this._sels2str(sels); - return this.getSignalFullName(fullName); - } - - - getPin(componentName, componentSels, signalName, signalSels) { - let fullName = componentName=="one" ? "one" : this.currentComponent + "." + componentName; - fullName += this._sels2str(componentSels) + - "."+ - signalName+ - this._sels2str(signalSels); - return this.getSignalFullName(fullName); - } - - getSignalFullName(fullName) { - const sId = this.circuit.getSignalIdx(fullName); - if (typeof(this.witness[sId]) == "undefined") { - throw new Error("Signal not initialized: "+fullName); - } - if (this.options.logGet) this.options.logFunction("get --->" + fullName + " = " + this.witness[sId].toString() ); - return this.witness[sId]; - } - - assert(a,b,errStr) { - const ba = bigInt(a); - const bb = bigInt(b); - if (!ba.equals(bb)) { - throw new Error("Constraint doesn't match "+ this.currentComponent+": "+ errStr + " -> "+ ba.toString() + " != " + bb.toString()); - } - } -} diff --git a/src/circuit_old.js b/src/circuit_old.js deleted file mode 100644 index 1906ced..0000000 --- a/src/circuit_old.js +++ /dev/null @@ -1,191 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const bigInt = require("big-integer"); - -const __P__ = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); -const __MASK__ = bigInt("28948022309329048855892746252171976963317496166410141009864396001978282409983"); // 0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF -const calculateWitness = require("./calculateWitness.js"); - -module.exports = class Circuit { - constructor(circuitDef) { - this.nPubInputs = circuitDef.nPubInputs; - this.nPrvInputs = circuitDef.nPrvInputs; - this.nInputs = circuitDef.nInputs; - this.nOutputs = circuitDef.nOutputs; - this.nVars = circuitDef.nVars; - this.nSignals = circuitDef.nSignals; - this.nConstants = circuitDef.nConstants; - - this.nConstraints = circuitDef.constraints.length; - - this.signalName2Idx = circuitDef.signalName2Idx; - this.components = circuitDef.components; - this.componentName2Idx = circuitDef.componentName2Idx; - this.signals = circuitDef.signals; - this.constraints = circuitDef.constraints; - - this.templates = {}; - for (let t in circuitDef.templates) { - this.templates[t] = eval(" const __f= " +circuitDef.templates[t] + "\n__f"); - } - - this.functions = {}; - for (let f in circuitDef.functions) { - this.functions[f] = { - params: circuitDef.functions[f].params, - func: eval(" const __f= " +circuitDef.functions[f].func + "\n__f;") - }; - } - } - - calculateWitness(input, log) { - return calculateWitness(this, input, log); - } - - checkWitness(w) { - const evalLC = (lc, w) => { - let acc = bigInt(0); - for (let k in lc) { - acc= acc.add(bigInt(w[k]).mul(bigInt(lc[k]))).mod(__P__); - } - return acc; - } - - const checkConstraint = (ct, w) => { - const a=evalLC(ct[0],w); - const b=evalLC(ct[1],w); - const c=evalLC(ct[2],w); - const res = (a.mul(b).sub(c)).affine(__P__); - if (!res.isZero()) return false; - return true; - } - - - for (let i=0; i { - let S = ""; - for (let k in lc) { - let name = this.signals[k].names[0]; - if (name == "one") name = ""; - let v = bigInt(lc[k]); - let vs; - if (!v.lesserOrEquals(__P__.shr(bigInt(1)))) { - v = __P__.sub(v); - vs = "-"+v.toString(); - } else { - if (S!="") { - vs = "+"+v.toString(); - } else { - vs = ""; - } - if (vs!="1") { - vs = vs + v.toString(); - } - } - - S= S + " " + vs + name; - } - return S; - }; - const S = `[ ${lc2str(c[0])} ] * [ ${lc2str(c[1])} ] - [ ${lc2str(c[2])} ] = 0`; - console.log(S); - } - - printConstraints() { - for (let i=0; i=this.nOutputs) throw new Error("Accessing an invalid output: "+i); - return i+1; - } - - // returns the index of the i'th input - inputIdx(i) { - if (i>=this.nInputs) throw new Error("Accessing an invalid input: "+i); - return this.nOutputs + 1 + i; - } - - // returns the index of the i'th public input - pubInputIdx(i) { - if (i>=this.nPubInputs) throw new Error("Accessing an invalid pubInput: "+i); - return this.inputIdx(i); - } - - // returns the index of the i'th private input - prvInputIdx(i) { - if (i>=this.nPrvInputs) throw new Error("Accessing an invalid prvInput: "+i); - return this.inputIdx(this.nPubInputs + i); - } - - // returns the index of the i'th variable - varIdx(i) { - if (i>=this.nVars) throw new Error("Accessing an invalid variable: "+i); - return i; - } - - // returns the index of the i'th constant - constantIdx(i) { - if (i>=this.nConstants) throw new Error("Accessing an invalid constant: "+i); - return this.nVars + i; - } - - // returns the index of the i'th signal - signalIdx(i) { - if (i>=this.nSignls) throw new Error("Accessing an invalid signal: "+i); - return i; - } - - signalNames(i) { - return this.signals[ this.getSignalIdx(i) ].names.join(", "); - } - - a(constraint, signalIdx) { - return bigInt(this.constraints[constraint][0][signalIdx] || 0 ); - } - - b(constraint, signalIdx) { - return bigInt(this.constraints[constraint][1][signalIdx] || 0); - } - - c(constraint, signalIdx) { - return bigInt(this.constraints[constraint][2][signalIdx] || 0); - } -}; diff --git a/src/f2field.js b/src/f2field.js deleted file mode 100644 index 2420239..0000000 --- a/src/f2field.js +++ /dev/null @@ -1,133 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const fUtils = require("./futils.js"); - -class F2Field { - constructor(F, nonResidue) { - this.F = F; - this.zero = [this.F.zero, this.F.zero]; - this.one = [this.F.one, this.F.zero]; - this.nonResidue = nonResidue; - } - - _mulByNonResidue(a) { - return this.F.mul(this.nonResidue, a); - } - - copy(a) { - return [this.F.copy(a[0]), this.F.copy(a[1])]; - } - - add(a, b) { - return [ - this.F.add(a[0], b[0]), - this.F.add(a[1], b[1]) - ]; - } - - double(a) { - return this.add(a,a); - } - - sub(a, b) { - return [ - this.F.sub(a[0], b[0]), - this.F.sub(a[1], b[1]) - ]; - } - - neg(a) { - return this.sub(this.zero, a); - } - - mul(a, b) { - const aA = this.F.mul(a[0] , b[0]); - const bB = this.F.mul(a[1] , b[1]); - - return [ - this.F.add( aA , this._mulByNonResidue(bB)), - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]), - this.F.add(b[0], b[1])), - this.F.add(aA, bB))]; - } - - inv(a) { - const t0 = this.F.square(a[0]); - const t1 = this.F.square(a[1]); - const t2 = this.F.sub(t0, this._mulByNonResidue(t1)); - const t3 = this.F.inv(t2); - return [ - this.F.mul(a[0], t3), - this.F.neg(this.F.mul( a[1], t3)) ]; - } - - div(a, b) { - return this.mul(a, this.inv(b)); - } - - square(a) { - const ab = this.F.mul(a[0] , a[1]); - - /* - [ - (a + b) * (a + non_residue * b) - ab - non_residue * ab, - ab + ab - ]; - */ - - return [ - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]) , - this.F.add( - a[0] , - this._mulByNonResidue(a[1]))), - this.F.add( - ab, - this._mulByNonResidue(ab))), - this.F.add(ab, ab) - ]; - } - - isZero(a) { - return this.F.isZero(a[0]) && this.F.isZero(a[1]); - } - - eq(a, b) { - return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]); - } - - mulScalar(base, e) { - return fUtils.mulScalar(this, base, e); - } - - exp(base, e) { - return fUtils.exp(this, base, e); - } - - toString(a) { - const cp = this.affine(a); - return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`; - } -} - -module.exports = F2Field; diff --git a/src/f3field.js b/src/f3field.js deleted file mode 100644 index 49f4cac..0000000 --- a/src/f3field.js +++ /dev/null @@ -1,177 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const fUtils = require("./futils.js"); - -class F3Field { - constructor(F, nonResidue) { - this.F = F; - this.zero = [this.F.zero, this.F.zero, this.F.zero]; - this.one = [this.F.one, this.F.zero, this.F.zero]; - this.nonResidue = nonResidue; - } - - _mulByNonResidue(a) { - return this.F.mul(this.nonResidue, a); - } - - copy(a) { - return [this.F.copy(a[0]), this.F.copy(a[1]), this.F.copy(a[2])]; - } - - add(a, b) { - return [ - this.F.add(a[0], b[0]), - this.F.add(a[1], b[1]), - this.F.add(a[2], b[2]) - ]; - } - - double(a) { - return this.add(a,a); - } - - sub(a, b) { - return [ - this.F.sub(a[0], b[0]), - this.F.sub(a[1], b[1]), - this.F.sub(a[2], b[2]) - ]; - } - - neg(a) { - return this.sub(this.zero, a); - } - - mul(a, b) { - - const aA = this.F.mul(a[0] , b[0]); - const bB = this.F.mul(a[1] , b[1]); - const cC = this.F.mul(a[2] , b[2]); - - return [ - this.F.add( - aA, - this._mulByNonResidue( - this.F.sub( - this.F.mul( - this.F.add(a[1], a[2]), - this.F.add(b[1], b[2])), - this.F.add(bB, cC)))), // aA + non_residue*((b+c)*(B+C)-bB-cC), - - this.F.add( - this.F.sub( - this.F.mul( - this.F.add(a[0], a[1]), - this.F.add(b[0], b[1])), - this.F.add(aA, bB)), - this._mulByNonResidue( cC)), // (a+b)*(A+B)-aA-bB+non_residue*cC - - this.F.add( - this.F.sub( - this.F.mul( - this.F.add(a[0], a[2]), - this.F.add(b[0], b[2])), - this.F.add(aA, cC)), - bB)]; // (a+c)*(A+C)-aA+bB-cC) - } - - inv(a) { - const t0 = this.F.square(a[0]); // t0 = a^2 ; - const t1 = this.F.square(a[1]); // t1 = b^2 ; - const t2 = this.F.square(a[2]); // t2 = c^2; - const t3 = this.F.mul(a[0],a[1]); // t3 = ab - const t4 = this.F.mul(a[0],a[2]); // t4 = ac - const t5 = this.F.mul(a[1],a[2]); // t5 = bc; - // c0 = t0 - non_residue * t5; - const c0 = this.F.sub(t0, this._mulByNonResidue(t5)); - // c1 = non_residue * t2 - t3; - const c1 = this.F.sub(this._mulByNonResidue(t2), t3); - const c2 = this.F.sub(t1, t4); // c2 = t1-t4 - - // t6 = (a * c0 + non_residue * (c * c1 + b * c2)).inv(); - const t6 = - this.F.inv( - this.F.add( - this.F.mul(a[0], c0), - this._mulByNonResidue( - this.F.add( - this.F.mul(a[2], c1), - this.F.mul(a[1], c2))))); - - return [ - this.F.mul(t6, c0), // t6*c0 - this.F.mul(t6, c1), // t6*c1 - this.F.mul(t6, c2)]; // t6*c2 - } - - div(a, b) { - return this.mul(a, this.inv(b)); - } - - square(a) { - const s0 = this.F.square(a[0]); // s0 = a^2 - const ab = this.F.mul(a[0], a[1]); // ab = a*b - const s1 = this.F.add(ab, ab); // s1 = 2ab; - const s2 = this.F.square( - this.F.add(this.F.sub(a[0],a[1]), a[2])); // s2 = (a - b + c)^2; - const bc = this.F.mul(a[1],a[2]); // bc = b*c - const s3 = this.F.add(bc, bc); // s3 = 2*bc - const s4 = this.F.square(a[2]); // s4 = c^2 - - - return [ - this.F.add( - s0, - this._mulByNonResidue(s3)), // s0 + non_residue * s3, - this.F.add( - s1, - this._mulByNonResidue(s4)), // s1 + non_residue * s4, - this.F.sub( - this.F.add( this.F.add(s1, s2) , s3 ), - this.F.add(s0, s4))]; // s1 + s2 + s3 - s0 - s4 - } - - isZero(a) { - return this.F.isZero(a[0]) && this.F.isZero(a[1]) && this.F.isZero(a[2]); - } - - eq(a, b) { - return this.F.eq(a[0], b[0]) && this.F.eq(a[1], b[1]) && this.F.eq(a[2], b[2]); - } - - affine(a) { - return [this.F.affine(a[0]), this.F.affine(a[1]), this.F.affine(a[2])]; - } - - mulScalar(base, e) { - return fUtils.mulScalar(this, base, e); - } - - exp(base, e) { - return fUtils.exp(this, base, e); - } - - toString(a) { - const cp = this.affine(a); - return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])}, ${this.F.toString(cp[2])} ]`; - } -} - -module.exports = F3Field; diff --git a/src/futils.js b/src/futils.js deleted file mode 100644 index 71710ef..0000000 --- a/src/futils.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const bigInt = require("big-integer"); - -exports.mulScalar = (F, base, e) =>{ - let res = F.zero; - let rem = bigInt(e); - let exp = base; - - while (! rem.isZero()) { - if (rem.isOdd()) { - res = F.add(res, exp); - } - exp = F.double(exp); - rem = rem.shiftRight(1); - } - - return res; -}; - - -exports.exp = (F, base, e) =>{ - let res = F.one; - let rem = bigInt(e); - let exp = base; - - while (! rem.isZero()) { - if (rem.isOdd()) { - res = F.mul(res, exp); - } - exp = F.square(exp); - rem = rem.shiftRight(1); - } - - return res; -}; diff --git a/src/gcurve.js b/src/gcurve.js deleted file mode 100644 index d08491c..0000000 --- a/src/gcurve.js +++ /dev/null @@ -1,186 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const fUtils = require("./futils.js"); - -class GCurve { - - constructor(F, g) { - this.F = F; - this.g = g; - if (this.g.length == 2) this.g[2] = this.F.one; - this.zero = [this.F.zero, this.F.one, this.F.zero]; - } - - add(p1, p2) { - - const F = this.F; - - if (this.eq(p1, this.zero)) return p2; - if (this.eq(p2, this.zero)) return p1; - - const res = new Array(3); - - const Z1Z1 = F.square( p1[2] ); - const Z2Z2 = F.square( p2[2] ); - - const U1 = F.mul( p1[0] , Z2Z2 ); // U1 = X1 * Z2Z2 - const U2 = F.mul( p2[0] , Z1Z1 ); // U2 = X2 * Z1Z1 - - const Z1_cubed = F.mul( p1[2] , Z1Z1); - const Z2_cubed = F.mul( p2[2] , Z2Z2); - - const S1 = F.mul( p1[1] , Z2_cubed); // S1 = Y1 * Z2 * Z2Z2 - const S2 = F.mul( p2[1] , Z1_cubed); // S2 = Y2 * Z1 * Z1Z1 - - if (F.eq(U1,U2) && F.eq(S1,S2)) { - return this.double(p1); - } - - const H = F.sub( U2 , U1 ); // H = U2-U1 - - const S2_minus_S1 = F.sub( S2 , S1 ); - - const I = F.square( F.add(H,H) ); // I = (2 * H)^2 - const J = F.mul( H , I ); // J = H * I - - const r = F.add( S2_minus_S1 , S2_minus_S1 ); // r = 2 * (S2-S1) - const V = F.mul( U1 , I ); // V = U1 * I - - res[0] = - F.sub( - F.sub( F.square(r) , J ), - F.add( V , V )); // X3 = r^2 - J - 2 * V - - const S1_J = F.mul( S1 , J ); - - res[1] = - F.sub( - F.mul( r , F.sub(V,res[0])), - F.add( S1_J,S1_J )); // Y3 = r * (V-X3)-2 S1 J - - res[2] = - F.mul( - H, - F.sub( - F.square( F.add(p1[2],p2[2]) ), - F.add( Z1Z1 , Z2Z2 ))); // Z3 = ((Z1+Z2)^2-Z1Z1-Z2Z2) * H - - return res; - } - - neg(p) { - return [p[0], this.F.neg(p[1]), p[2]]; - } - - sub(a, b) { - return this.add(a, this.neg(b)); - } - - double(p) { - const F = this.F; - - const res = new Array(3); - - if (this.eq(p, this.zero)) return p; - - const A = F.square( p[0] ); // A = X1^2 - const B = F.square( p[1] ); // B = Y1^2 - const C = F.square( B ); // C = B^2 - - let D = - F.sub( - F.square( F.add(p[0] , B )), - F.add( A , C)); - D = F.add(D,D); // D = 2 * ((X1 + B)^2 - A - C) - - const E = F.add( F.add(A,A), A); // E = 3 * A - const FF =F.square( E ); // F = E^2 - - res[0] = F.sub( FF , F.add(D,D) ); // X3 = F - 2 D - - let eightC = F.add( C , C ); - eightC = F.add( eightC , eightC ); - eightC = F.add( eightC , eightC ); - - res[1] = - F.sub( - F.mul( - E, - F.sub( D, res[0] )), - eightC); // Y3 = E * (D - X3) - 8 * C - - const Y1Z1 = F.mul( p[1] , p[2] ); - res[2] = F.add( Y1Z1 , Y1Z1 ); // Z3 = 2 * Y1 * Z1 - - return res; - } - - mulScalar(base, e) { - return fUtils.mulScalar(this, base, e); - } - - affine(p) { - const F = this.F; - if (this.eq(p, this.zero)) { - return this.zero; - } else { - const Z_inv = F.inv(p[2]); - const Z2_inv = F.square(Z_inv); - const Z3_inv = F.mul(Z2_inv, Z_inv); - - const res = new Array(3); - res[0] = F.mul(p[0],Z2_inv); - res[1] = F.mul(p[1],Z3_inv); - res[2] = F.one; - - return res; - } - } - - eq(p1, p2) { - const F = this.F; - - if (this.F.eq(p1[2], this.F.zero)) return this.F.eq(p2[2], this.F.zero); - if (this.F.eq(p2[2], this.F.zero)) return false; - - const Z1Z1 = F.square( p1[2] ); - const Z2Z2 = F.square( p2[2] ); - - const U1 = F.mul( p1[0] , Z2Z2 ); - const U2 = F.mul( p2[0] , Z1Z1 ); - - const Z1_cubed = F.mul( p1[2] , Z1Z1); - const Z2_cubed = F.mul( p2[2] , Z2Z2); - - const S1 = F.mul( p1[1] , Z2_cubed); - const S2 = F.mul( p2[1] , Z1_cubed); - - return (F.eq(U1,U2) && F.eq(S1,S2)); - } - - toString(p) { - const cp = this.affine(p); - return `[ ${this.F.toString(cp[0])} , ${this.F.toString(cp[1])} ]`; - } - -} - -module.exports = GCurve; - diff --git a/src/polfield.js b/src/polfield.js deleted file mode 100644 index 426bda7..0000000 --- a/src/polfield.js +++ /dev/null @@ -1,527 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -/* - This library does operations on polynomials with coefficients in a field F. - - A polynomial P(x) = p0 + p1 * x + p2 * x^2 + ... + pn * x^n is represented - by the array [ p0, p1, p2, ... , pn ]. - */ - -const bigInt = require("big-integer"); - -class PolField { - constructor (F) { - this.F = F; - - const q = this.F.p; - let rem = q.minus(bigInt(1)); - let s = 0; - while (!rem.isOdd()) { - s ++; - rem = rem.shiftRight(1); - } - - const five = this.F.add(this.F.add(this.F.two, this.F.two), this.F.one); - - this.w = new Array(s+1); - this.wi = new Array(s+1); - this.w[s] = this.F.pow(five, rem); - this.wi[s] = this.F.inv(this.w[s]); - - let n=s-1; - while (n>=0) { - this.w[n] = this.F.square(this.w[n+1]); - this.wi[n] = this.F.square(this.wi[n+1]); - n--; - } - - - this.roots = []; -/* for (let i=0; i<16; i++) { - let r = this.F.one; - n = 1 << i; - const rootsi = new Array(n); - for (let j=0; j=0) && (!this.roots[i]); i--) { - let r = this.F.one; - const nroots = 1 << i; - const rootsi = new Array(nroots); - for (let j=0; j a.length) { - [b, a] = [a, b]; - } - - if ((b.length <= 2) || (b.length < log2(a.length))) { - return this.mulNormal(a,b); - } else { - return this.mulFFT(a,b); - } - } - - mulNormal(a, b) { - let res = []; - b = this.affine(b); - for (let i=0; i0) { - const z = new Array(n).fill(this.F.zero); - return z.concat(p); - } else { - if (-n >= p.length) return []; - return p.slice(-n); - } - } - - eval2(p, x) { - let v = this.F.zero; - let ix = this.F.one; - for (let i=0; i> 1), - F.mul( - x, - _eval(p, newX, offset+step , step << 1, n >> 1))); - return res; - } - } - - lagrange(points) { - let roots = [this.F.one]; - for (let i=0; i> 1; - const p1 = this._fft(pall, bits-1, offset, step*2); - const p2 = this._fft(pall, bits-1, offset+step, step*2); - - const out = new Array(n); - - let m= this.F.one; - for (let i=0; i0 && this.F.eq(p[i], this.F.zero) ) i--; - return p.slice(0, i+1); - } - - equals(a, b) { - const pa = this.reduce(this.affine(a)); - const pb = this.reduce(this.affine(b)); - - if (pa.length != pb.length) return false; - for (let i=0; i=0; i--) { - res[i] = this.F.add(this.F.mul(res[i+1], r), p[i+1]); - } - return res; - } - - _next2Power(v) { - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - v++; - return v; - } - - toString(p) { - const ap = this.affine(p); - let S = ""; - for (let i=ap.length-1; i>=0; i--) { - if (!this.F.eq(p[i], this.F.zero)) { - if (S!="") S += " + "; - S = S + p[i].toString(10); - if (i>0) { - S = S + "x"; - if (i>1) { - S = S + "^" +i; - } - } - } - } - return S; - } - - - _reciprocal(p, bits) { - const k = 1 << bits; - if (k==1) { - return [ this.F.inv(p[0]) ]; - } - const np = this.scaleX(p, -k/2); - const q = this._reciprocal(np, bits-1); - const a = this.scaleX(this.double(q), 3*k/2-2); - const b = this.mul( this.square(q), p); - - return this.scaleX(this.sub(a,b), -(k-2)); - } - - // divides x^m / v - _div2(m, v) { - const kbits = log2(v.length-1)+1; - const k = 1 << kbits; - - const scaleV = k - v.length; - - // rec = x^(k - 2) / v* x^scaleV => - // rec = x^(k-2-scaleV)/ v - // - // res = x^m/v = x^(m + (2*k-2 - scaleV) - (2*k-2 - scaleV)) /v => - // res = rec * x^(m - (2*k-2 - scaleV)) => - // res = rec * x^(m - 2*k + 2 + scaleV) - - const rec = this._reciprocal(this.scaleX(v, scaleV), kbits); - const res = this.scaleX(rec, m - 2*k + 2 + scaleV); - - return res; - } - - div(_u, _v) { - if (_u.length < _v.length) return []; - const kbits = log2(_v.length-1)+1; - const k = 1 << kbits; - - const u = this.scaleX(_u, k-_v.length); - const v = this.scaleX(_v, k-_v.length); - - const n = v.length-1; - let m = u.length-1; - - const s = this._reciprocal(v, kbits); - let t; - if (m>2*n) { - t = this.sub(this.scaleX([this.F.one], 2*n), this.mul(s, v)); - } - - let q = []; - let rem = u; - let us, ut; - let finish = false; - - while (!finish) { - us = this.mul(rem, s); - q = this.add(q, this.scaleX(us, -2*n)); - - if ( m > 2*n ) { - ut = this.mul(rem, t); - rem = this.scaleX(ut, -2*n); - m = rem.length-1; - } else { - finish = true; - } - } - - return q; - } - - - // returns the ith nth-root of one - oneRoot(n, i) { - let nbits = log2(n-1)+1; - let res = this.F.one; - let r = i; - - if(i>=n) { - throw new Error("Given 'i' should be lower than 'n'"); - } - else if (1<0) { - if (r & 1 == 1) { - res = this.F.mul(res, this.w[nbits]); - } - r = r >> 1; - nbits --; - } - return res; - } - - computeVanishingPolinomial(bits, t) { - const m = 1 << bits; - return this.F.sub(this.F.pow(t, bigInt(m)), this.F.one); - } - - evaluateLagrangePolynomials(bits, t) { - const m= 1 << bits; - const tm = this.F.pow(t, bigInt(m)); - const u= new Array(m).fill(this.F.zero); - this._setRoots(bits); - const omega = this.w[bits]; - - if (this.F.eq(tm, this.F.one)) { - for (let i = 0; i < m; i++) { - if (this.F.eq(this.roots[bits][0],t)) { // i.e., t equals omega^i - u[i] = this.F.one; - return u; - } - } - } - - const z = this.F.sub(tm, this.F.one); -// let l = this.F.mul(z, this.F.pow(this.F.twoinv, m)); - let l = this.F.mul(z, this.F.inv(bigInt(m))); - for (let i = 0; i < m; i++) { - u[i] = this.F.mul(l, this.F.inv(this.F.sub(t,this.roots[bits][i]))); - l = this.F.mul(l, omega); - } - - return u; - } - - log2(V) { - return log2(V); - } -} - -function log2( V ) -{ - return( ( ( V & 0xFFFF0000 ) !== 0 ? ( V &= 0xFFFF0000, 16 ) : 0 ) | ( ( V & 0xFF00FF00 ) !== 0 ? ( V &= 0xFF00FF00, 8 ) : 0 ) | ( ( V & 0xF0F0F0F0 ) !== 0 ? ( V &= 0xF0F0F0F0, 4 ) : 0 ) | ( ( V & 0xCCCCCCCC ) !== 0 ? ( V &= 0xCCCCCCCC, 2 ) : 0 ) | ( ( V & 0xAAAAAAAA ) !== 0 ) ); -} - - -function __fft(PF, pall, bits, offset, step) { - - const n = 1 << bits; - if (n==1) { - return [ pall[offset] ]; - } else if (n==2) { - return [ - PF.F.add(pall[offset], pall[offset + step]), - PF.F.sub(pall[offset], pall[offset + step])]; - } - - const ndiv2 = n >> 1; - const p1 = __fft(PF, pall, bits-1, offset, step*2); - const p2 = __fft(PF, pall, bits-1, offset+step, step*2); - - const out = new Array(n); - - for (let i=0; i. */ -const BN128 = require("./bn128.js"); -const PolField = require("./polfield.js"); +const bn128 = require("ffjavascript").bn128; +const PolField = require("ffjavascript").PolField; const ZqField = require("ffjavascript").ZqField; -const bn128 = new BN128(); const PolF = new PolField(new ZqField(bn128.r)); const G1 = bn128.G1; const G2 = bn128.G2; diff --git a/src/r1cs_parser_old.js b/src/r1cs_parser_old.js deleted file mode 100644 index 8a18d29..0000000 --- a/src/r1cs_parser_old.js +++ /dev/null @@ -1,296 +0,0 @@ -const fs = require("fs"); -const assert = require("assert"); -const bigInt = require("big-integer"); - -module.exports.loadR1cs = loadR1cs; -module.exports.loadR1csSynch = loadR1csSync; - -async function loadR1cs(fileName) { - const res = {}; - const fd = await fs.promises.open(fileName, "r"); - - const b = Buffer.allocUnsafe(4); - await fd.read(b, 0, 4, 0); - if (b.toString() != "r1cs") assert(false, "Invalid File format"); - - let p=4; - - let v = await readU32(); - - if (v>1) assert(false, "Version not supported"); - - const nSections = await readU32(); - - let pHeader; - let pConstraints; - let headerSize; - let constraintsSize; - let pMap; - let mapSize; - for (let i=0; i1) assert(false, "Version not supported"); - - const nSections = readU32(); - - let pHeader; - let pConstraints; - let headerSize; - let constraintsSize; - for (let i=0; i. -*/ - -const fUtils = require("./futils.js"); - -class RatField { - constructor(F) { - this.F = F; - this.zero = [F.zero, F.one]; - this.one = [F.one, F.one]; - this.two = [F.two, F.one]; - this.twoinv = [F.one, F.two]; - this.q = F.q; - } - - add(a,b) { - return [ - this.F.add( - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0])), - this.F.mul(a[1], b[1])]; - } - - double(a) { - return [this.F.add(a[0], a[0]), a[1]]; - } - - sub(a,b) { - return [ - this.F.sub( - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0])), - this.F.mul(a[1], b[1])]; - } - - neg(a) { - return [this.F.neg(a[0]), a[1]]; - } - - mul(a,b) { - return [ - this.F.mul(a[0], b[0]), - this.F.mul(a[1], b[1]), - ]; - } - - copy(a) { - return [a[0], a[1]]; - } - - div(a, b) { - return [ - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0]), - ]; - } - - inv(a) { - return [a[1], a[0]]; - } - - square(a) { - return [ - this.F.square(a[0]), - this.F.square(a[1]) - ]; - } - - mulScalar(base, e) { - return [this.F.mulScalar(base[0], e) , base[1]]; - } - - exp(base, e) { - return fUtils.exp(this, base, e); - } - - equals(a, b) { - return this.F.equals( - this.F.mul(a[0], b[1]), - this.F.mul(a[1], b[0]) - ); - } - - isZero(a) { - return this.F.isZero(a[0]); - } - - affine(a) { - return [this.F.div(a[0], a[1]), this.F.one]; - } - - toString(a) { - const ca = this.affine(a); - return `"0x${ca[0].toString(16)}"`; - } - - random() { - return [this.F.random(), this.F.one]; - } - - fromF(a) { - return [a, this.F.one]; - } - - toF(a) { - return this.affine(a)[0]; - } -} - - -module.exports = RatField; diff --git a/src/setup_groth.js b/src/setup_groth.js index f69d896..d8caa72 100644 --- a/src/setup_groth.js +++ b/src/setup_groth.js @@ -21,11 +21,10 @@ const bigInt = require("big-integer"); -const BN128 = require("./bn128.js"); -const PolField = require("./polfield.js"); +const bn128 = require("ffjavascript").bn128; +const PolField = require("ffjavascript").PolField; const ZqField = require("ffjavascript").ZqField; -const bn128 = new BN128(); const G1 = bn128.G1; const G2 = bn128.G2; const PolF = new PolField(new ZqField(bn128.r)); diff --git a/src/setup_kimleeoh.js b/src/setup_kimleeoh.js index 0a2a617..7ca1fa6 100644 --- a/src/setup_kimleeoh.js +++ b/src/setup_kimleeoh.js @@ -21,11 +21,10 @@ const bigInt = require("big-integer"); -const BN128 = require("./bn128.js"); -const PolField = require("./polfield.js"); +const bn128 = require("ffjavascript").bn128; +const PolField = require("ffjavascript").PolField; const ZqField = require("ffjavascript").ZqField; -const bn128 = new BN128(); const G1 = bn128.G1; const G2 = bn128.G2; const PolF = new PolField(new ZqField(bn128.r)); diff --git a/src/setup_original.js b/src/setup_original.js index 9370715..94d4ee8 100644 --- a/src/setup_original.js +++ b/src/setup_original.js @@ -19,11 +19,10 @@ const bigInt = require("big-integer"); -const BN128 = require("./bn128.js"); -const PolField = require("./polfield.js"); +const bn128 = require("ffjavascript").bn128; +const PolField = require("ffjavascript").PolField; const ZqField = require("ffjavascript").ZqField; -const bn128 = new BN128(); const G1 = bn128.G1; const G2 = bn128.G2; const PolF = new PolField(new ZqField(bn128.r)); diff --git a/src/stringifybigint.js b/src/stringifybigint.js deleted file mode 100644 index 13c75d6..0000000 --- a/src/stringifybigint.js +++ /dev/null @@ -1,55 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const bigInt = require("big-integer"); - -module.exports.stringifyBigInts = stringifyBigInts; -module.exports.unstringifyBigInts = unstringifyBigInts; - -function stringifyBigInts(o) { - if ((typeof(o) == "bigint") || o.isZero !== undefined) { - return o.toString(10); - } else if (Array.isArray(o)) { - return o.map(stringifyBigInts); - } else if (typeof o == "object") { - const res = {}; - for (let k in o) { - res[k] = stringifyBigInts(o[k]); - } - return res; - } else { - return o; - } -} - -function unstringifyBigInts(o) { - if ((typeof(o) == "string") && (/^[0-9]+$/.test(o) )) { - return bigInt(o); - } else if (Array.isArray(o)) { - return o.map(unstringifyBigInts); - } else if (typeof o == "object") { - const res = {}; - for (let k in o) { - res[k] = unstringifyBigInts(o[k]); - } - return res; - } else { - return o; - } -} diff --git a/src/utils.js b/src/utils.js index 55eb0a3..63e6106 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,15 +1,21 @@ const bigInt = require("big-integer"); -exports.beBuff2int = function(buff) { + +module.exports.stringifyBigInts = stringifyBigInts; +module.exports.unstringifyBigInts = unstringifyBigInts; +module.exports.beBuff2int = beBuff2int; +module.exports.beInt2Buff = beInt2Buff; + +function beBuff2int(buff) { let res = bigInt.zero; for (let i=0; i. -*/ - -const BN128 = require("./bn128.js"); - -const bn128 = new BN128(); -const G1 = bn128.G1; -const G2 = bn128.G2; - -module.exports = function isValid(vk_verifier, proof, publicSignals) { - - let full_pi_a = vk_verifier.A[0]; - for (let s= 0; s< vk_verifier.nPublic; s++) { - full_pi_a = G1.add( full_pi_a, G1.mulScalar( vk_verifier.A[s+1], publicSignals[s])); - } - - full_pi_a = G1.add( full_pi_a, proof.pi_a); - - if (! bn128.F12.equals( - bn128.pairing( proof.pi_a , vk_verifier.vk_a ), - bn128.pairing( proof.pi_ap , G2.g ))) - return false; - - if (! bn128.F12.equals( - bn128.pairing( vk_verifier.vk_b, proof.pi_b ), - bn128.pairing( proof.pi_bp , G2.g ))) - return false; - - if (! bn128.F12.equals( - bn128.pairing( proof.pi_c , vk_verifier.vk_c ), - bn128.pairing( proof.pi_cp , G2.g ))) - return false; - - if (! bn128.F12.equals( - bn128.F12.mul( - bn128.pairing( G1.add(full_pi_a, proof.pi_c) , vk_verifier.vk_gb_2 ), - bn128.pairing( vk_verifier.vk_gb_1 , proof.pi_b ), - ), - bn128.pairing( proof.pi_kp , vk_verifier.vk_g ))) - return false; - - if (! bn128.F12.equals( - bn128.pairing( full_pi_a , proof.pi_b ), - bn128.F12.mul( - bn128.pairing( proof.pi_h , vk_verifier.vk_z ), - bn128.pairing( proof.pi_c , G2.g ), - ))) - return false; - - return true; -}; diff --git a/src/verifier_groth.js b/src/verifier_groth.js index bc155cc..061b546 100644 --- a/src/verifier_groth.js +++ b/src/verifier_groth.js @@ -20,9 +20,8 @@ /* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */ -const BN128 = require("./bn128.js"); +const bn128 = require("ffjavascript").bn128; -const bn128 = new BN128(); const G1 = bn128.G1; module.exports = function isValid(vk_verifier, proof, publicSignals) { diff --git a/src/verifier_kimleeoh.js b/src/verifier_kimleeoh.js index 7724f26..de868ff 100644 --- a/src/verifier_kimleeoh.js +++ b/src/verifier_kimleeoh.js @@ -20,11 +20,10 @@ /* Implementation of this paper: https://eprint.iacr.org/2016/260.pdf */ -const BN128 = require("./bn128.js"); +const bn128 = require("ffjavascript").bn128; const createKeccakHash = require("keccak"); const utils = require("./utils"); -const bn128 = new BN128(); const G1 = bn128.G1; const G2 = bn128.G2; diff --git a/src/verifier_original.js b/src/verifier_original.js index c6eb55c..da7f995 100644 --- a/src/verifier_original.js +++ b/src/verifier_original.js @@ -17,9 +17,8 @@ snarkjs. If not, see . */ -const BN128 = require("./bn128.js"); +const bn128 = require("ffjavascript").bn128; -const bn128 = new BN128(); const G1 = bn128.G1; const G2 = bn128.G2; diff --git a/src/zqfield_old.js b/src/zqfield_old.js deleted file mode 100644 index 3ec1ec4..0000000 --- a/src/zqfield_old.js +++ /dev/null @@ -1,151 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of snarkjs. - - snarkjs 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. - - snarkjs 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. - - You should have received a copy of the GNU General Public License along with - snarkjs. If not, see . -*/ - -const bigInt = require("big-integer"); -const fUtils = require("./futils.js"); - -function getRandomByte() { - if (typeof window !== "undefined") { // Browser - if (typeof window.crypto !== "undefined") { // Supported - let array = new Uint8Array(1); - window.crypto.getRandomValues(array); - return array[0]; - } - else { // fallback - return Math.floor(Math.random() * 256); - } - } - else { // NodeJS - return module.require("crypto").randomBytes(1)[0]; - } -} - -class ZqField { - constructor(q) { - this.q = bigInt(q); - this.zero = bigInt.zero; - this.one = bigInt.one; - this.minusone = this.q.sub(this.one); - this.add = bigInt.genAdd(); - this.double = bigInt.genDouble(); - this.sub = bigInt.genSub(); - this.neg = bigInt.genNeg(); - this.mul = bigInt.genMul(q); - this.inverse = bigInt.genInverse(q); - this.square = bigInt.genSquare(q); - this.equals = bigInt.genEquals(q); - this.affine = bigInt.genAffine(q); - this.isZero = bigInt.genIsZero(q); - this.two = this.add(this.one, this.one); - this.twoinv = this.inverse(this.two); - - const e = this.minusone.shr(this.one); - this.nqr = this.two; - let r = this.exp(this.nqr, e); - while (!r.equals(this.minusone)) { - this.nqr = this.nqr.add(this.one); - r = this.exp(this.nqr, e); - } - - this.s = this.zero; - this.t = this.minusone; - - while (!this.t.isOdd()) { - this.s = this.s.add(this.one); - this.t = this.t.shr(this.one); - } - - this.nqr_to_t = this.exp(this.nqr, this.t); - } - - copy(a) { - return bigInt(a); - } - - div(a, b) { - return this.mul(a, this.inverse(b)); - } - - mulScalar(base, e) { - return this.mul(base, bigInt(e)); - } - - exp(base, e) { - return fUtils.exp(this, base, e); - } - - toString(a) { - const ca = this.affine(a); - return `"0x${ca.toString(16)}"`; - } - - random() { - let res = bigInt(0); - let n = bigInt(this.q); - while (!n.isZero()) { - res = res.shl(8).add(bigInt(getRandomByte())); - n = n.shr(8); - } - return res; - } - - sqrt(n) { - - n = this.affine(n); - - if (n.equals(this.zero)) return this.zero; - - // Test that have solution - const res = this.exp(n, this.minusone.shr(this.one)); - if (!res.equals(this.one)) return null; - - let m = parseInt(this.s); - let c = this.nqr_to_t; - let t = this.exp(n, this.t); - let r = this.exp(n, this.add(this.t, this.one).shr(this.one) ); - - while (!t.equals(this.one)) { - let sq = this.square(t); - let i = 1; - while (!sq.equals(this.one)) { - i++; - sq = this.square(sq); - } - - // b = c ^ m-i-1 - let b = c; - for (let j=0; j< m-i-1; j ++) b = this.square(b); - - m = i; - c = this.square(b); - t = this.mul(t, c); - r = this.mul(r, b); - } - - if (r.greater(this.q.shr(this.one))) { - r = this.neg(r); - } - - return r; - } - -} - - -module.exports = ZqField; diff --git a/test/algebra.js b/test/algebra.js deleted file mode 100644 index 47dfc4e..0000000 --- a/test/algebra.js +++ /dev/null @@ -1,254 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of zksnark JavaScript library. - - zksnark JavaScript library 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. - - zksnark JavaScript library 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. - - You should have received a copy of the GNU General Public License along with - zksnark JavaScript library. If not, see . -*/ - -const chai = require("chai"); - -const bigInt = require("big-integer"); -const BN128 = require("../src/bn128.js"); -const F1Field = require("ffjavascript").ZqField; - -const assert = chai.assert; - - -describe("F1 testing", () => { - it("Should compute euclidean", () => { - const F = new F1Field(bigInt(7)); - const res = F.inv(bigInt(4)); - - assert(F.equals(res, bigInt(2))); - }); - - it("Should multiply and divide in F1", () => { - const bn128 = new BN128(); - const a = bigInt("1"); - const b = bn128.F1.affine(bigInt("-3")); - const c = bn128.F1.mul(a,b); - const d = bn128.F1.div(c,b); - - assert(bn128.F1.equals(a, d)); - }); - - it("Should compute sqrts", () => { - const bn128 = new BN128(); - const F = new F1Field(bn128.r); - const a = bigInt("4"); - let b = F.sqrt(a); - assert(F.equals(bigInt(0), F.sqrt(bigInt("0")))); - assert(F.equals(b, bigInt("2"))); - assert(F.sqrt(F.nqr) === null); - }); - - it("Should compute sqrt of 100 random numbers", () => { - const bn128 = new BN128(); - const F = new F1Field(bn128.r); - for (let j=0;j<100; j++) { - let a = F.random(); - let s = F.sqrt(a); - if (s != null) { - assert(F.equals(F.square(s), a)); - } - } - }); -}); - -describe("Curve G1 Test", () => { - it("r*one == 0", () => { - const bn128 = new BN128(); - - const res = bn128.G1.mulScalar(bn128.G1.g, bn128.r); - - assert(bn128.G1.equals(res, bn128.G1.zero), "G1 does not have range r"); - }); - - it("Should add match in various in G1", () => { - - const bn128 = new BN128(); - - const r1 = bigInt(33); - const r2 = bigInt(44); - - const gr1 = bn128.G1.mulScalar(bn128.G1.g, r1); - const gr2 = bn128.G1.mulScalar(bn128.G1.g, r2); - - const grsum1 = bn128.G1.add(gr1, gr2); - - const grsum2 = bn128.G1.mulScalar(bn128.G1.g, r1.add(r2)); - - assert(bn128.G1.equals(grsum1, grsum2)); - }); -}); - -describe("Curve G2 Test", () => { - it ("r*one == 0", () => { - const bn128 = new BN128(); - - const res = bn128.G2.mulScalar(bn128.G2.g, bn128.r); - - assert(bn128.G2.equals(res, bn128.G2.zero), "G2 does not have range r"); - }); - - it("Should add match in various in G2", () => { - const bn128 = new BN128(); - - const r1 = bigInt(33); - const r2 = bigInt(44); - - const gr1 = bn128.G2.mulScalar(bn128.G2.g, r1); - const gr2 = bn128.G2.mulScalar(bn128.G2.g, r2); - - const grsum1 = bn128.G2.add(gr1, gr2); - - const grsum2 = bn128.G2.mulScalar(bn128.G2.g, r1.add(r2)); - - /* - console.log(G2.toString(grsum1)); - console.log(G2.toString(grsum2)); - */ - - assert(bn128.G2.equals(grsum1, grsum2)); - }); -}); - -describe("F6 testing", () => { - it("Should multiply and divide in F6", () => { - const bn128 = new BN128(); - const a = - [ - [bigInt("1"), bigInt("2")], - [bigInt("3"), bigInt("4")], - [bigInt("5"), bigInt("6")] - ]; - const b = - [ - [bigInt("12"), bigInt("11")], - [bigInt("10"), bigInt("9")], - [bigInt("8"), bigInt("7")] - ]; - const c = bn128.F6.mul(a,b); - const d = bn128.F6.div(c,b); - - assert(bn128.F6.equals(a, d)); - }); -}); - -describe("F12 testing", () => { - it("Should multiply and divide in F12", () => { - const bn128 = new BN128(); - const a = - [ - [ - [bigInt("1"), bigInt("2")], - [bigInt("3"), bigInt("4")], - [bigInt("5"), bigInt("6")] - ], - [ - [bigInt("7"), bigInt("8")], - [bigInt("9"), bigInt("10")], - [bigInt("11"), bigInt("12")] - ] - ]; - const b = - [ - [ - [bigInt("12"), bigInt("11")], - [bigInt("10"), bigInt("9")], - [bigInt("8"), bigInt("7")] - ], - [ - [bigInt("6"), bigInt("5")], - [bigInt("4"), bigInt("3")], - [bigInt("2"), bigInt("1")] - ] - ]; - const c = bn128.F12.mul(a,b); - const d = bn128.F12.div(c,b); - - assert(bn128.F12.equals(a, d)); - }); -}); - -describe("Pairing", () => { -/* - it("Should match pairing", () => { - for (let i=0; i<1; i++) { - const bn128 = new BN128(); - - const g1a = bn128.G1.mulScalar(bn128.G1.g, 25); - const g2a = bn128.G2.mulScalar(bn128.G2.g, 30); - - const g1b = bn128.G1.mulScalar(bn128.G1.g, 30); - const g2b = bn128.G2.mulScalar(bn128.G2.g, 25); - - const pre1a = bn128.precomputeG1(g1a); - const pre2a = bn128.precomputeG2(g2a); - const pre1b = bn128.precomputeG1(g1b); - const pre2b = bn128.precomputeG2(g2b); - - const r1 = bn128.millerLoop(pre1a, pre2a); - const r2 = bn128.millerLoop(pre1b, pre2b); - - const rbe = bn128.F12.mul(r1, bn128.F12.inverse(r2)); - - const res = bn128.finalExponentiation(rbe); - - assert(bn128.F12.equals(res, bn128.F12.one)); - } - }).timeout(10000); -*/ - it("Should generate another pairing pairing", () => { - for (let i=0; i<1; i++) { - const bn128 = new BN128(); - - const g1a = bn128.G1.mulScalar(bn128.G1.g, 10); - const g2a = bn128.G2.mulScalar(bn128.G2.g, 1); - - const g1b = bn128.G1.mulScalar(bn128.G1.g, 1); - const g2b = bn128.G2.mulScalar(bn128.G2.g, 10); - - const pre1a = bn128.precomputeG1(g1a); - const pre2a = bn128.precomputeG2(g2a); - const pre1b = bn128.precomputeG1(g1b); - const pre2b = bn128.precomputeG2(g2b); - - const r1 = bn128.millerLoop(pre1a, pre2a); - const r2 = bn128.finalExponentiation(r1); - - const r3 = bn128.millerLoop(pre1b, pre2b); - - const r4 = bn128.finalExponentiation(r3); - - - console.log("ML1: " ,r1[0][0][0].affine(bn128.q).toString(16)); - console.log("FE1: " ,r2[0][0][0].affine(bn128.q).toString(16)); - console.log("ML2: " ,r3[0][0][0].affine(bn128.q).toString(16)); - console.log("FE2: " ,r4[0][0][0].affine(bn128.q).toString(16)); - - assert(bn128.F12.equals(r2, r4)); - - -/* const r2 = bn128.millerLoop(pre1b, pre2b); - - const rbe = bn128.F12.mul(r1, bn128.F12.inverse(r2)); - - const res = bn128.finalExponentiation(rbe); - - assert(bn128.F12.equals(res, bn128.F12.one)); */ - } - }).timeout(10000); -}); diff --git a/test/calculatewitness.js b/test/calculatewitness.js deleted file mode 100644 index 0077cec..0000000 --- a/test/calculatewitness.js +++ /dev/null @@ -1,40 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of zksnark JavaScript library. - - zksnark JavaScript library 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. - - zksnark JavaScript library 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. - - You should have received a copy of the GNU General Public License along with - zksnark JavaScript library. If not, see . -*/ - -const chai = require("chai"); -const fs = require("fs"); -const path = require("path"); - -const Circuit = require("../src/circuit.js"); -const BN128 = require("../src/bn128.js"); -const F1Field = require("ffjavascript").ZqField; - -const assert = chai.assert; - - -describe("Calculate witness", () => { - it("Should calculate the witness of a sum circuit", () => { - - const cirDef = JSON.parse(fs.readFileSync(path.join(__dirname, "circuit", "sum.json"), "utf8")); - const cir = new Circuit(cirDef); - const witness = cir.calculateWitness({"a": "33", "b": "34"}); - - assert.equal(witness[cir.getSignalIdx("main.out")].toString(), "67"); - }); -}); diff --git a/test/circuit/circuit.circom b/test/circuit/circuit.circom index 80694ad..3c31978 100644 --- a/test/circuit/circuit.circom +++ b/test/circuit/circuit.circom @@ -2,7 +2,7 @@ template Multiplier(n) { signal private input a; signal private input b; signal output c; - + signal int[n]; int[0] <== a*a + b; @@ -13,4 +13,4 @@ template Multiplier(n) { c <== int[n-1]; } -component main = Multiplier(1000); +component main = Multiplier(100); diff --git a/test/circuit/circuit.r1cs b/test/circuit/circuit.r1cs index 588a57614e7548107898cc5e63bdc62ae66f0d00..0756e2ae35808fe4d64d1523664b52cda5a6de5f 100644 GIT binary patch delta 78 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%0DV@vqn6xRK%l3q{DV@vql(Z?G%N9u5 zl+I;)M%t9lWqVHAl+I;)LE4ngWqV25l+I;)McS0kWqVE9l+I;)L)w(iWqV87l+I;) zN7|ImWqVKBl+I=QK-!efW&4J-DV@vqEooCam+d>!rgSdbN7ANrF5CB{P3c^=A4r?h zxokg@Hl=gfej;s3=dyhwZA#~|{Y=`F&Sm?Bv?-m-_A6;qI+yJ?(x!AS+wY`J>0Guy zNSo5RY=4qArE}T-B5g|Nvi(ikl+I=QOxl#rWeXNESkUot#;3rN)4J{JU+zuLbdBo; z1ne$dZEyOe*#mo2X_f7t*AhCHEjam_O6RhLAZ<$LvV|mVO6RhLB5g|NvV|sXO6RhL zA#FNO6RhrAZ<$LvZW+#O6RhrB5g|NvZW?%O6RhrA#F;rE}S)lQyMu*=CS7rE}S4k~XDt*=CV8rE}S4lQyMu+2)WorE}Tlk~XDt+2)Zp zrE}TllQyMu*%pvCrE}R9k~XDt*%pyDrE}R9lQyMu*_MztrE}Sqk~XDt*_M$urE}Sq zlQyMu*;bG?rE}R;dN zrE}SKk~XDt*>;gOrE}SKlQyMu+4hh&rE}T#k~XDt+4hk(rE}T#lQyMu*$$94rE}R1 zk~XDt*$$C5rE}R1lQyMu*^ZDlrE}Sik~XDt*^ZGmrE}SilQyMu*-nr)rE}R%k~XDt z*-nu*rE}R%lQyMu+0KwQrE}TNk~XDt+0KzRrE}TNlQyMu*)EVarE}RXk~XDt*)EYb zrE}RXlQyMu*{+Z_rE}S?k~XDt*{+c`rE}S?lQyMu*=~?FrE}SCk~XDt*=~_GrE}SC zlQyMu+3t`wrE}Ttk~XDt+3t}xrE}TtlQyMu*&dKKrE}RHk~XDt*&dNLrE}RHlQyMu z*`AO#rE}Syk~XDt*#b$M(z$HUNSo5RY|lxX(z$FeNSo5RY%fWh(z$G}NSo5RY_Cb1 z(z$GJNSo5RY;Q@M(z$H!NSo5RY&g%y8J_}6PV2U>f4Mg~(>1Oa5U{&+wY}+=W)JL9 zrB${de!Zk$e*C}V{nz&t>|aL+JQfNY8XE>178?#59vcB05gQ2`85;!~6&np39UB81 z6B`Q~8yg237aI>7ADaN15Ss{_7@Gw9@7qs?+sUyhuqm;ru&J?WuxYXBu<5ZGuoG+E zumiD!u!FHfutTxKumRZN*b&%~*iqQg*fH3#*m2nL*a_H)*h$#Q*eTel*lF15*csTF z*jd=w*g4p_*m>Cb*ag^y*hSdI*d^Gd*k#z|*cI57*j3oo*frR-*mcU*elqp*lXD9*c;fJ*jw1!*gM#}*n8Of*az5$*hkpM*eBSh*g)(v z>~ri3>`Uw`>}%{B>|5+R?0f77>^InNvEN}oV!y}!fc+8s6ZRAKXY4Q7U$MVof5-lT z{S*5a_HXQG?7tuQ!GnLjBLp@iHWW5AHVif_HXJrQHUc&xHWD^6HVQT>HX1fMHU>5( zHWoHEHV!r}HXb%UHUTyvHW4;4HVHN3wg|Q;wivcJwgk2$wiLEBwhXo` zwj8!RwgR>ywi327whFc?wi>oNwg$E)widQFwhp!~wjQ=VwgI*wwh^{5wh6W=wi&iL zwgt8&wiUKDwhgu|wjH)Twga{!wiC89whOi^wi~uPwgPdmVcNdlP#LdmDQPdl!2TdmsA%`w;sG`xyHK`xG09eTIFG zeSv+6eT99EeS>|AeTRLI{eb-j`z`i6>__bP*dMSzVt>MZ!v2i?1^X-ZH|+1&Kd^sd z|HA%_{frG3;_K&raBK){NNgxjSd~5=2LTn;zVr&v@QfxA8a%>80N^B}@YHS*8T5LLOdTa)4MrQEV}6acl`}No*->X>1v6S!_9M zd29u2MQkN(Wo#8}RctkEb!-i6O>8Y}ZEPKEU2HvUeQX14Lu?~#V{8*_Q*1MAb8HK2 zOKdA_Yit{ATWmXQdu#`6M{Fl-XKWX2S8O+IcWe)APi!x2Z)_iIUu-{Yf9wG4Kl0CqTb1a>5L6m~Rr40bGb9Ckc*0(K&H5_U3n3U(@X8g@E%26iTP7Irpv z4t6ef9(F!<0d^sF5q2?l33e%V8Fo2#1$HHN6?Qdt4R$Sd9d@K9Qy+M z68j4K8v6$O7W)qS9{U0N4fb2?ci4~E@3B8%f5iTT{e=A)`wRA0>~GlLv43Fy#Quf- z8~Yg>EF?bvu_3S_v7xY`v0<=bvEi`cu@SHlv5~Nmu~D#5vC**6u`#eQv9YkRv2n0* zvGK6+u?esVv5ByWu}QE=vB|K>u_>@Av8k}Bv1zbrvFWhsu^F%#v6--$v01QLvHyG- z^W{&F9k+8}b7FI0b7S*h^J4R1^J5EO3t|gl3uB95i(-pmi(^Y*OJYl5OJmDm%VNu6 z%VR5GD`G2QD`Tr*t75BRt7B_mYhr6*Yh&wR>tgF+>th>W8)6$_8)KVbn_`<`n`2vG zTVh*bTVvZ`+hW^c+haRmJ7POwJ7c?GyJEXxyJLG`dt!TGdt>`x`(pcH`(p=S2Vw_d z2V;j|hhm3e1F*xfBd{Z}qp+i~W3Xef#*yw8?YO(o3NX)Td-TP z+pycQJFq*kyRf^ld$4=4`>^}52e1dRhp>mSN3ch+$FRq-C$J~6r?987XRv3n=dkCo z7qAzxm#~+ySFl&H*Ra>IH?TLcx3IUdcd&P{_ptY|53mohkFbxiPq0t1f!Jr*=hzq6 Rm)KX>*Vs4Mx7c^s{{xUcX*>V` diff --git a/test/circuit/circuit.wasm b/test/circuit/circuit.wasm index 002a4a5b5f150c0d1c554711f81cfbc1e6fc13a3..1d309ee2fb150355ad4af846841553d05bd4bf99 100644 GIT binary patch delta 573 zcmbO>jj7=$;|4Ak#)i$@EK+fdrzfi=X);|foE(&7%JG81jhE5!hT-H1NxDox>Ohhh zP-^qdBwa>cHwMQKj2cV~EDj(AA}LlT>lhgs>tTWlObW~bAiWAqjx0G@5QS`x3m6?4 zAW(pT8>F!%#SCQI-V`Yibt}b7Ob21`4-*AO1ttMA#~&t>ZBnI}o-<62NVNq~(^E|u zPfb3X8piv;R6t#U(QyZJmg5Gq%|>aeOiT| zOumrm&-FnCXbl55ONHiU&8*){N()T6IT#tBz;T5sH%|(XgAmzaI@vRKu|7x;2pr!3 z{m<{)DZJ}a^0{&wroC_K(|07_`zWt;inC)l3l_d$+RRcY#aZ8Q zo`Kr{WZnWPh`CHiY-S`j3y{46s)oUF15letgERv}gE~+g2teAv!0`l7N`MWpY|X;d`RX7|@`L{PIk`&GH_k=Gr%O4FU?%S+VlIu+sYuCo5g(u%ey8j0#mt<$RRwf)RiyRPlqwk{eSelC(avGpC1QyEh?wyvAy zVxm+i5sJqa?n}$l=1QdOp0km7rf}$=EpgD{^{1nu(0^U0b?x}~FgZ16hosad?R%CD z2HBG9r(c~NX|$!reJ8UoYnZEP)vH-5oLJta>eDA)96qVQ`Dz(Mi52G}@&0+z!kte? z(thZaH}kVA21ny%gBk0s{`-X@|CfVl|Lu>-4gMJuN*s0BO=Z`FLS;AWw*{A7+Y*L1SF&GpZkxHKdhUs^CYkseL!*K2Y(rKQ}8*0iB5?PyO2I?{>GbfGKV=uQt_rYEn^ zi{A91Fa1cNKLZ%ZAO^e?Uhyt(1aIh%1bmOrMadBEont-+R&DE zw5J0d=|pF`(3NgJ37{)S= z@l0SMsZ8QkCNqVpOk+ATc#WCNVm7by26LFpn?e2O3G-RNLKd-@B`oDFma&`_tYj5w zyv=IX@D6KvmvyXX1Ml%Z8~K1uY-S4|2FtRQZER-;AF-2<*~KS(%5L_smwoK#GY;@M zUvQ8^9Og^D;%mO)2uJyr?>I)vam@)%a*ETO;VkK#<9p8Y0~h#_pZJ+yxX7>k#w9NE zJ6HIFKlzKR1m8?yB19wV9}})40~yIgX0j0Hda{y@?BpOPH*h02aWlEdO&)F`FZsyN ztrVajNfe?mw?)*yh)|Sb6vyw8P)Tm*4oXp)GTcd7%5fLvsX#^iNDAG}J={xW?&E%{ z@BmdwCP6i-r)X;MAT_DQLp;nQ)TR!P@)&ig$KyP~lRU-K)aMx*@GQ^qJPm0?V_u*M zFVd8hmo&|2P77Mniq^EDE$wJe2RhP;&UB$G-RMpaUZy9n(2L&mp)dUiZn!@K7#P%l zkT94b3}qO@8No|rna*w1Gi;B&suNYPZIIyHEZn$+SU9_A5hQ-?=+jJnk0ah~8wp5kfh z^9&7mmgjh$hBTrvFVKXP7d1_JiDopX1ubbsYueD3cC@Dh9qB}8y3mzwbf*U|)00=| zMQ{4hmwp5{-an}S0AV157|alcGK}GjU?ig$%^1cqj`2)jBB@N`RVFiqsZ3)!GkA@e z%wjgL2lanLn8RG&WFGTbz(N+Wm?bRbEtavI6|7_xX}ry9*6xoB#>K835NUpvkpk6qdvoJfktnp_J-;<29BLWy{+Rqz)n XQ7RrApD74s. -*/ - -const chai = require("chai"); - -const bigInt = require("big-integer"); -const PolField = require("../src/polfield.js"); -const ZqField = require("ffjavascript").ZqField; - -const assert = chai.assert; - -const r = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); - -describe("Polynomial field", () => { - it("Should compute a multiplication", () => { - const PF = new PolField(new ZqField(r)); - - const a = [bigInt(1), bigInt(2), bigInt(3)]; - const b = [bigInt(1), bigInt(2), bigInt(3)]; - const res = PF.mul(a,b); - - assert(PF.equals(res, [bigInt(1), bigInt(4), bigInt(10), bigInt(12), bigInt(9)])); - }); - it("Should compute a multiplication 2", () => { - const PF = new PolField(new ZqField(r)); - - const a = [bigInt(5), bigInt(1)]; - const b = [bigInt(-5), bigInt(1)]; - const res = PF.mul(a,b); - - assert(PF.equals(res, [bigInt(-25), bigInt(0), bigInt(1)])); - }); - it("Should compute an addition", () => { - const PF = new PolField(new ZqField(r)); - - const a = [bigInt(5), bigInt(1)]; - const b = [bigInt(-5), bigInt(1)]; - const res = PF.add(a,b); - - assert(PF.equals(res, [bigInt(0), bigInt(2)])); - }); - it("Should compute a substraction", () => { - const PF = new PolField(new ZqField(r)); - - const a = [bigInt(5), bigInt(3), bigInt(4)]; - const b = [bigInt(5), bigInt(1)]; - const res = PF.sub(a,b); - - assert(PF.equals(res, [bigInt(0), bigInt(2), bigInt(4)])); - }); - it("Should compute reciprocal", () => { - const PF = new PolField(new ZqField(r)); - - const a = [bigInt(4), bigInt(1), bigInt(-3), bigInt(-1), bigInt(2),bigInt(1), bigInt(-1), bigInt(1)]; - const res = PF._reciprocal(a, 3, 0); - - assert(PF.equals(res, [bigInt(12), bigInt(15), bigInt(3), bigInt(-4), bigInt(-3), bigInt(0), bigInt(1), bigInt(1)])); - }); - it("Should div2", () => { - const PF = new PolField(new ZqField(r)); - - // x^6 - const a = [bigInt(0), bigInt(0), bigInt(0), bigInt(0), bigInt(0),bigInt(0), bigInt(1)]; - // x^5 - const b = [bigInt(0), bigInt(0), bigInt(0), bigInt(0), bigInt(0), bigInt(1)]; - - const res = PF._div2(6, b); - assert(PF.equals(res, [bigInt(0), bigInt(1)])); - - const res2 = PF.div(a,b); - assert(PF.equals(res2, [bigInt(0), bigInt(1)])); - }); - it("Should div", () => { - const PF = new PolField(new ZqField(r)); - - const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)]; - const b = [bigInt(8), bigInt(9), bigInt(10), bigInt(11), bigInt(12), bigInt(13)]; - - const c = PF.mul(a,b); - const d = PF.div(c,b); - - assert(PF.equals(a, d)); - }); - it("Should div big/small", () => { - const PF = new PolField(new ZqField(r)); - - const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)]; - const b = [bigInt(8), bigInt(9)]; - - const c = PF.mul(a,b); - const d = PF.div(c,b); - - assert(PF.equals(a, d)); - }); - it("Should div random big", () => { - const PF = new PolField(new ZqField(r)); - - const a = []; - const b = []; - for (let i=0; i<1000; i++) a.push(bigInt(Math.floor(Math.random()*100000) -500000)); - for (let i=0; i<900; i++) b.push(bigInt(Math.floor(Math.random()*100000) -500000)); - - const c = PF.mul(a,b); - - const d = PF.div(c,b); - - assert(PF.equals(a, d)); - }).timeout(10000); - it("Should evaluate and zero", () => { - const PF = new PolField(new ZqField(r)); - const p = [PF.F.neg(bigInt(2)), bigInt(1)]; - const v = PF.eval(p, bigInt(2)); - assert(PF.F.equals(v, bigInt(0))); - }); - it("Should evaluate bigger number", () => { - const PF = new PolField(new ZqField(r)); - const p = [bigInt(1), bigInt(2), bigInt(3)]; - const v = PF.eval(p, bigInt(2)); - assert(PF.F.equals(v, bigInt(17))); - }); - it("Should create lagrange polynomial minmal", () => { - const PF = new PolField(new ZqField(r)); - - const points=[]; - points.push([bigInt(1), bigInt(1)]); - points.push([bigInt(2), bigInt(2)]); - points.push([bigInt(3), bigInt(5)]); - - const p=PF.lagrange(points); - - for (let i=0; i { - const PF = new PolField(new ZqField(r)); - - const points=[]; - points.push([bigInt(1), bigInt(2)]); - points.push([bigInt(2), bigInt(-2)]); - points.push([bigInt(3), bigInt(0)]); - points.push([bigInt(4), bigInt(453345)]); - - const p=PF.lagrange(points); - - for (let i=0; i { - const PF = new PolField(new ZqField(r)); - const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)]; - - const b = PF.mul(a, [bigInt(-7), bigInt(1)]); - const c = PF.ruffini(b, bigInt(7)); - - assert(PF.equals(a, c)); - }); - it("Should test roots", () => { - const PF = new PolField(new ZqField(r)); - let rt; - - - rt = PF.oneRoot(256, 16); - for (let i=0; i<8; i++) { - rt = PF.F.mul(rt, rt); - } - assert(rt.equals(PF.F.one)); - - rt = PF.oneRoot(256, 15); - for (let i=0; i<8; i++) { - rt = PF.F.mul(rt, rt); - } - assert(rt.equals(PF.F.one)); - - rt = PF.oneRoot(8, 3); - for (let i=0; i<3; i++) { - rt = PF.F.mul(rt, rt); - } - assert(rt.equals(PF.F.one)); - - rt = PF.oneRoot(8, 0); - assert(rt.equals(PF.F.one)); - - }); - it("Should create a polynomial with values at roots with fft", () => { - const PF = new PolField(new ZqField(r)); - const a = [bigInt(1), bigInt(2), bigInt(3), bigInt(4), bigInt(5),bigInt(6), bigInt(7)]; - - const p = PF.ifft(a); - - for (let i=0; iK=L5x0szpJX&(Rp diff --git a/test/ratzqfield.js b/test/ratzqfield.js deleted file mode 100644 index c4cb380..0000000 --- a/test/ratzqfield.js +++ /dev/null @@ -1,89 +0,0 @@ -/* - Copyright 2018 0kims association. - - This file is part of zksnark JavaScript library. - - zksnark JavaScript library 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. - - zksnark JavaScript library 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. - - You should have received a copy of the GNU General Public License along with - zksnark JavaScript library. If not, see . -*/ - -const chai = require("chai"); - -const bigInt = require("big-integer"); -const ZqField = require("ffjavascript").ZqField; -const RatField = require("../src/ratfield.js"); - -const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); -const Z = new ZqField(q); -const R = new RatField(Z); - -const assert = chai.assert; - -function r(a,b) { - return [bigInt(a), bigInt(b)]; -} - - -describe("Rational zq Field", () => { - it("Should compare correctly", () => { - assert( R.equals(r(3,5), r(6,10))); - assert(!R.equals(r(3,5), r(6,11))); - }); - it("Should add correctly", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.equals( R.add(a,b), r(13, 6))); - }); - it("Should substract", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.equals( R.sub(a,b), r(4, 3))); - }); - it("Should multiply", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.equals( R.mul(a,b), r(35, 48))); - }); - it("Should div", () => { - const a = r(7,4); - const b = r(5,12); - - assert(R.equals( R.div(a,b), r(7*12, 5*4))); - }); - it("Should square", () => { - const a = r(7,4); - - assert(R.equals( R.square(a), r(49, 16))); - }); - it("Should affine", () => { - const a = r(12,4); - const aa = R.affine(a); - assert(Z.equals( aa[0], bigInt(3))); - assert(Z.equals( aa[1], Z.one)); - }); - it("Should convert from Z to R", () => { - const vz = bigInt(34); - const vr = R.fromF(vz); - - assert(R.equals( vr, r(34,1))); - }); - it("Should convert from R to Z", () => { - const vr = r(32, 2); - const vz = R.toF(vr); - - assert(Z.equals( vz, bigInt(16))); - }); -});