const assert = require("assert"); const bigInt = require("big-integer"); const buildF1 = require("../index.js").buildF1; const buildF1m = require("../src/build_f1m"); const buildProtoboard = require("../src/protoboard.js"); const buildTest = require("../src/build_test.js"); describe("Basic tests for Zq", () => { it("It should do a basic addition", async () => { const f1 = await buildF1(101); const pA = f1.allocInt(3); const pB = f1.allocInt(4); const pC = f1.allocInt(); f1.f1_add(pA, pB, pC); const c = f1.getInt(pC); assert.equal(c, 7); }); it("Should add with 2 chunks", async () => { const f1 = await buildF1(bigInt("100000000000000000001", 16)); const pA = f1.allocInt(bigInt("FFFFFFFFFFFFFFFF", 16)); const pB = f1.allocInt(1); const pC = f1.allocInt(); f1.f1_add(pA, pB, pC); const c = f1.getInt(pC); assert(c.equals(bigInt("10000000000000000", 16))); }); it("Should add with 2 chunks overflow", async () => { const q = bigInt("10000000000000001", 16); const f1 = await buildF1(q); const pA = f1.allocInt(bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16).mod(q)); const pB = f1.allocInt(1); const pC = f1.allocInt(); f1.f1_add(pA, pB, pC); const c = f1.getInt(pC); assert(c.equals(1)); }); it("Should add with double overflow", async () => { const q = bigInt(1).shiftLeft(255).add(1); const a = bigInt(1).shiftLeft(256).minus(1).mod(q); const f1 = await buildF1(q); const pA = f1.allocInt(a); const pC = f1.allocInt(); f1.f1_add(pA, pA, pC); const c = f1.getInt(pC); assert(c.equals(a.add(a).mod(q))); }); it("It should do a basic substraction", async () => { const f1 = await buildF1(101); const pA = f1.allocInt(5); const pB = f1.allocInt(3); const pC = f1.allocInt(); f1.f1_sub(pA, pB, pC); const c = f1.getInt(pC); assert.equal(c, 2); }); it("It should do a basic substraction with negative result", async () => { const f1 = await buildF1(101); const pA = f1.allocInt(3); const pB = f1.allocInt(5); const pC = f1.allocInt(); f1.f1_sub(pA, pB, pC); const c = f1.getInt(pC); assert.equal(c.mod(101), 99); }); it("Should substract with 2 chunks overflow", async () => { const q = bigInt("10000000000000001", 16); const a = bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 16).mod(q); const f1 = await buildF1(q); const pA = f1.allocInt(1); const pB = f1.allocInt(a); const pC = f1.allocInt(); f1.f1_sub(pA, pB, pC); const c = f1.getInt(pC); let d = bigInt.one.minus(a).mod(q); if (d.isNegative()) d = d.add(q); assert(c.equals(d)); }); it("It should Substract a big number", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const a = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808495617"); const b = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808234523"); const pA = f1.allocInt(a); const pB = f1.allocInt(b); const pC = f1.allocInt(); f1.f1_sub(pA, pB, pC); const c = f1.getInt(pC); let cc = a.minus(b).mod(q); if (cc.isNegative()) cc = cc.add(q); assert(cc.equals(c.mod(q))); const pAA = f1.allocInt(b); const pBB = f1.allocInt(a); const pCC = f1.allocInt(); f1.f1_sub(pAA, pBB, pCC); const d = f1.getInt(pCC); let dd = b.minus(a).mod(q); if (dd.isNegative()) dd = dd.add(q); assert(dd.equals(d.mod(q))); }); it("It should do a basic multiplication", async () => { const f1 = await buildF1(101); const pA = f1.allocInt(3); const pB = f1.allocInt(4); const pC = f1.allocInt2(); f1.int_mul(pA, pB, pC); const c = f1.getInt2(pC); assert.equal(c, 12); }); it("It should do a basic division", async () => { const f1 = await buildF1(101); const pA = f1.allocInt(12); const pB = f1.allocInt(6); const pC = f1.allocInt(); f1.int_div(pA, pB, pC); const c = f1.getInt(pC); assert.equal(c, 2); }); it("It should do a more complex division", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const pA = f1.allocInt(bigInt("FFFF00000000", 16)); const pB = f1.allocInt(bigInt("100000000", 16)); const pC = f1.allocInt(); f1.int_div(pA, pB, pC); const c = f1.getInt(pC); assert(c.equals(bigInt("FFFF", 16))); }); it("It should do a division by zero", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const pA = f1.allocInt(bigInt("FFFF00000000", 16)); const pB = f1.allocInt(0); const pC = f1.allocInt(); try { f1.int_div(pA, pB, pC); assert(false, "Didn't throw..."); } catch (err) { assert.equal(err.toString(), "RuntimeError: divide by zero"); } }); it("It should do a various division", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const v= [ bigInt.zero, q.minus(1), q.minus(2), q.minus(1).shiftRight(1), q.minus(1).shiftRight(1).add(1), q.minus(1).shiftRight(1).add(2), q.minus(1).shiftRight(1).minus(1), q.minus(1).shiftRight(1).minus(2), bigInt(bigInt("F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0", 16)), bigInt(bigInt("10101010101010101010101010101010", 16)), bigInt(bigInt("FF00FF00FF00FF00FF00FF00FF00FF00", 16)), bigInt(bigInt("11001100110011001100110011001100", 16)), bigInt(bigInt("F0F0F0F0F0F0F0F0", 16)), bigInt(bigInt("1010101010101010", 16)), bigInt(bigInt("FF00FF00FF00FF00", 16)), bigInt(bigInt("1100110011001100", 16)), bigInt(2), bigInt.one, ]; const pA = f1.allocInt(); const pB = f1.allocInt(); const pC = f1.allocInt(); const pR = f1.allocInt(); for (let i=0; i { const f1 = await buildF1(bigInt("FFFFFFFFFFFFFFFF",16)); const pA = f1.allocInt2(bigInt(0x10000000000000000)); const pC = f1.allocInt(); f1.f1m_mReduct(pA, pC); const c = f1.getInt(pC); assert.equal(c, 1); }); it("It should do a basic reduction 2", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const a = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808495617"); const b = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808234523"); const pA = f1.allocInt(a); const pB = f1.allocInt(b); const pC = f1.allocInt2(); const pD = f1.allocInt(); f1.int_mul(pA, pB, pC); const c = f1.getInt2(pC); f1.f1m_mReduct(pC, pD); const d = f1.getInt(pD); const r = bigInt.one.shiftLeft(256).mod(q); const r2 = r.times(r).mod(q); const pR2 = f1.allocInt(r2); const pE = f1.allocInt2(); f1.int_mul(pD, pR2, pE); const pF = f1.allocInt(); f1.f1m_mReduct(pE, pF); const f = f1.getInt2(pF); assert(a.times(b).mod(q).equals(f.mod(q))); }); it("It should do a basic reduction 3", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const a = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808495617"); const b = bigInt("10000242871839275222246405745257275088548364400416034343698204186575808234523"); const pA = f1.allocInt(a); const pB = f1.allocInt(b); const pC = f1.allocInt(); f1.f1_mul(pA, pB, pC); const c = f1.getInt2(pC); assert(a.times(b).mod(q).equals(c.mod(q))); }); it("It should do various test in zq Snarks modules", async () => { const q = bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583"); const f1 = await buildF1(q); const v= [ q.minus(1), q.minus(2), q.minus(1).shiftRight(1), q.minus(1).shiftRight(1).add(1), q.minus(1).shiftRight(1).add(2), q.minus(1).shiftRight(1).minus(1), q.minus(1).shiftRight(1).minus(2), bigInt(2), bigInt.one, bigInt.zero ]; const pA = f1.allocInt(); const pB = f1.allocInt(); const pC = f1.allocInt(); let c; for (let i=0; i { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const t = f1.test_F1(1000000); console.log(t); }).timeout(10000000); it("Should test to montgomery", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const f1 = await buildF1(q); const r = bigInt(11); const pR = f1.allocInt(r); const pRes = f1.allocInt(); const pRes2 = f1.allocInt(); f1.f1m_toMontgomery(pR, pRes); const res = f1.getInt(pRes); f1.f1m_fromMontgomery(pRes, pRes2); const res2 = f1.getInt(pRes2); assert(res.equals(r.times( bigInt.one.shiftLeft(256)).mod(q))); assert(res2.equals(r)); }); it("Should convert back and forth montgomery", async () => { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const v= [ q.minus(1), q.minus(2), q.minus(1).shiftRight(1), q.minus(1).shiftRight(1).add(1), q.minus(1).shiftRight(1).add(2), q.minus(1).shiftRight(1).minus(1), q.minus(1).shiftRight(1).minus(2), bigInt(2), bigInt.one, bigInt.zero ]; const f1 = await buildF1(q); const pA = f1.allocInt(); for (let i=0; i { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const v= [ bigInt.one, q.minus(1), q.minus(2), q.minus(1).shiftRight(1), q.minus(1).shiftRight(1).add(1), q.minus(1).shiftRight(1).add(2), q.minus(1).shiftRight(1).minus(1), q.minus(1).shiftRight(1).minus(2), bigInt(2), ]; const f1 = await buildF1(q); const pA = f1.allocInt(); const pB = f1.allocInt(); const pQ = f1.allocInt(); f1.putInt(pQ, q); for (let i=0; i { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const v= [ bigInt.one, q.minus(1), q.minus(2), q.minus(1).shiftRight(1), q.minus(1).shiftRight(1).add(1), q.minus(1).shiftRight(1).add(2), q.minus(1).shiftRight(1).minus(1), q.minus(1).shiftRight(1).minus(2), bigInt(2), ]; const f1 = await buildF1(q); const pA = f1.allocInt(); const pB = f1.allocInt(); const pC = f1.allocInt(); for (let i=0; i { const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const v= [ bigInt.one, q.minus(1), q.minus(2), q.minus(1).shiftRight(1), q.minus(1).shiftRight(1).add(1), q.minus(1).shiftRight(1).add(2), q.minus(1).shiftRight(1).minus(1), q.minus(1).shiftRight(1).minus(2), bigInt(2), ]; const f1 = await buildF1(q); const pA = f1.allocInt(); for (let i=0; i { let start,end,time; const q = bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617"); const A=q.minus(1); const B=q.minus(1).shiftRight(1); const pbF1m = await buildProtoboard((module) => { buildF1m(module, q); buildTest(module, "f1m_mul"); buildTest(module, "f1m_mulOld"); }, 32); const pA = pbF1m.alloc(); const pB = pbF1m.alloc(); const pC = pbF1m.alloc(); pbF1m.set(pA, A); pbF1m.f1m_toMontgomery(pA, pA); pbF1m.set(pB, B); pbF1m.f1m_toMontgomery(pB, pB); start = new Date().getTime(); pbF1m.test_f1m_mul(pA, pB, pC, 50000000); end = new Date().getTime(); time = end - start; pbF1m.f1m_fromMontgomery(pC, pC); const c1 = pbF1m.get(pC, 1, 32); assert(c1.equals(A.times(B).mod(q))); console.log("Mul Time (ms): " + time); start = new Date().getTime(); pbF1m.test_f1m_mulOld(pA, pB, pC, 50000000); end = new Date().getTime(); time = end - start; pbF1m.f1m_fromMontgomery(pC, pC); const c2 = pbF1m .get(pC, 1, 32); assert(c2.equals(A.times(B).mod(q))); console.log("Mul Old Time (ms): " + time); }).timeout(10000000); });