Files
ffjavascript/test/algebra.js
2020-04-18 20:07:29 +02:00

241 lines
7.1 KiB
JavaScript

/*
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 <https://www.gnu.org/licenses/>.
*/
const chai = require("chai");
const Scalar = require("../src/scalar.js");
const bn128 = require("../src/bn128.js");
const F1Field = require("../src/f1field.js");
const assert = chai.assert;
describe("F1 testing", () => {
it("Should compute euclidean", () => {
const F = new F1Field(Scalar.fromString("7"));
const res = F.inv(F.e(4));
assert(F.eq(res, F.e(2)));
});
it("Should multiply and divide in F1", () => {
const a = bn128.F1.e("1");
const b = bn128.F1.e("-1");
const c = bn128.F1.mul(a,b);
const d = bn128.F1.div(c,b);
assert(bn128.F1.eq(a, d));
});
it("Should compute sqrts", () => {
const F = new F1Field(bn128.r);
const a = F.e("4");
let b = F.sqrt(a);
assert(F.eq(F.e(0), F.sqrt(F.e("0"))));
assert(F.eq(b, F.e("2")));
assert(F.sqrt(F.nqr) === null);
});
it("Should compute sqrt of 100 random numbers", () => {
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.eq(F.square(s), a));
}
}
});
});
describe("Curve G1 Test", () => {
it("r*one == 0", () => {
const res = bn128.G1.mulScalar(bn128.G1.g, bn128.r);
assert(bn128.G1.eq(res, bn128.G1.zero), "G1 does not have range r");
});
it("Should add match in various in G1", () => {
const r1 = bn128.Fr.e(33);
const r2 = bn128.Fr.e(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, bn128.Fr.add(r1, r2));
assert(bn128.G1.eq(grsum1, grsum2));
});
});
describe("Curve G2 Test", () => {
it ("r*one == 0", () => {
const res = bn128.G2.mulScalar(bn128.G2.g, bn128.r);
assert(bn128.G2.eq(res, bn128.G2.zero), "G2 does not have range r");
});
it("Should add match in various in G2", () => {
const r1 = bn128.Fr.e(33);
const r2 = bn128.Fr.e(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, bn128.Fr.add(r1, r2));
/*
console.log(G2.toString(grsum1));
console.log(G2.toString(grsum2));
*/
assert(bn128.G2.eq(grsum1, grsum2));
});
});
describe("F6 testing", () => {
it("Should multiply and divide in F6", () => {
const a =
[
[bn128.F1.e("1"), bn128.F1.e("2")],
[bn128.F1.e("3"), bn128.F1.e("4")],
[bn128.F1.e("5"), bn128.F1.e("6")]
];
const b =
[
[bn128.F1.e("12"), bn128.F1.e("11")],
[bn128.F1.e("10"), bn128.F1.e("9")],
[bn128.F1.e("8"), bn128.F1.e("7")]
];
const c = bn128.F6.mul(a,b);
const d = bn128.F6.div(c,b);
assert(bn128.F6.eq(a, d));
});
});
describe("F12 testing", () => {
it("Should multiply and divide in F12", () => {
const a =
[
[
[bn128.F1.e("1"), bn128.F1.e("2")],
[bn128.F1.e("3"), bn128.F1.e("4")],
[bn128.F1.e("5"), bn128.F1.e("6")]
],
[
[bn128.F1.e("7"), bn128.F1.e("8")],
[bn128.F1.e("9"), bn128.F1.e("10")],
[bn128.F1.e("11"), bn128.F1.e("12")]
]
];
const b =
[
[
[bn128.F1.e("12"), bn128.F1.e("11")],
[bn128.F1.e("10"), bn128.F1.e("9")],
[bn128.F1.e("8"), bn128.F1.e("7")]
],
[
[bn128.F1.e("6"), bn128.F1.e("5")],
[bn128.F1.e("4"), bn128.F1.e("3")],
[bn128.F1.e("2"), bn128.F1.e("1")]
]
];
const c = bn128.F12.mul(a,b);
const d = bn128.F12.div(c,b);
assert(bn128.F12.eq(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.eq(res, bn128.F12.one));
}
}).timeout(10000);
*/
it("Should generate another pairing pairing", () => {
for (let i=0; i<1; i++) {
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: " ,bn128.F12.toString(r1));
console.log("FE1: " ,bn128.F12.toString(r2));
console.log("ML2: " ,bn128.F12.toString(r3));
console.log("FE2: " ,bn128.F12.toString(r4));
assert(bn128.F12.eq(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.eq(res, bn128.F12.one)); */
}
}).timeout(10000);
});