2024-10-12 17:12:41 +01:00
|
|
|
import * as chai from "chai";
|
2020-07-07 19:21:41 +02:00
|
|
|
import buildBn128 from "../src/bn128.js";
|
2020-09-07 12:37:17 +02:00
|
|
|
import {log2} from "../src/utils.js";
|
2020-09-08 23:26:03 +02:00
|
|
|
import BigBuffer from "../src/bigbuffer.js";
|
2020-09-07 12:37:17 +02:00
|
|
|
|
2024-10-12 17:12:41 +01:00
|
|
|
const assert = chai.assert;
|
|
|
|
|
2020-09-09 08:21:57 +02:00
|
|
|
describe("bn128", async function () {
|
2022-06-08 15:37:12 -07:00
|
|
|
this.timeout(0);
|
2020-07-07 19:21:41 +02:00
|
|
|
|
2020-09-09 08:21:57 +02:00
|
|
|
const logger = {
|
|
|
|
error: (msg) => { console.log("ERROR: "+msg); },
|
|
|
|
warning: (msg) => { console.log("WARNING: "+msg); },
|
|
|
|
info: (msg) => { console.log("INFO: "+msg); },
|
|
|
|
debug: (msg) => { console.log("DEBUG: "+msg); },
|
|
|
|
};
|
|
|
|
|
2020-07-07 19:21:41 +02:00
|
|
|
let bn128;
|
|
|
|
before( async() => {
|
|
|
|
bn128 = await buildBn128();
|
2022-04-01 12:04:37 +02:00
|
|
|
console.log(bn128.Fr.toString(bn128.Fr.w[28]));
|
2020-07-07 19:21:41 +02:00
|
|
|
});
|
|
|
|
after( async() => {
|
|
|
|
bn128.terminate();
|
|
|
|
});
|
2020-09-09 08:21:57 +02:00
|
|
|
|
2020-05-26 21:39:19 +02:00
|
|
|
it("It shoud do an inverse FFT in G1", async () => {
|
|
|
|
const Fr = bn128.Fr;
|
|
|
|
const G1 = bn128.G1;
|
|
|
|
|
|
|
|
const a = [];
|
|
|
|
for (let i=0; i<8; i++) a[i] = Fr.e(i+1);
|
|
|
|
|
|
|
|
const aG_expected = [];
|
2020-07-07 19:21:41 +02:00
|
|
|
for (let i=0; i<8; i++) aG_expected[i] = G1.timesFr(G1.g, a[i]);
|
2020-05-26 21:39:19 +02:00
|
|
|
|
2020-07-07 19:21:41 +02:00
|
|
|
const A = await bn128.Fr.fft(a);
|
2020-06-18 19:15:05 +02:00
|
|
|
|
|
|
|
|
2020-05-26 21:39:19 +02:00
|
|
|
const AG = [];
|
2020-07-07 19:21:41 +02:00
|
|
|
for (let i=0; i<8; i++) AG[i] = G1.timesFr(G1.g, A[i]);
|
2020-05-26 21:39:19 +02:00
|
|
|
|
2020-07-07 19:21:41 +02:00
|
|
|
const aG_calculated = await G1.ifft(AG, "jacobian", "jacobian");
|
2020-05-26 21:39:19 +02:00
|
|
|
|
|
|
|
for (let i=0; i<8; i++) {
|
|
|
|
assert(G1.eq(aG_calculated[i], aG_expected[i]));
|
|
|
|
}
|
|
|
|
});
|
2020-09-09 08:21:57 +02:00
|
|
|
|
2020-09-08 23:26:03 +02:00
|
|
|
|
|
|
|
it("It shoud do a big FFT/IFFT in Fr", async () => {
|
|
|
|
const Fr = bn128.Fr;
|
|
|
|
|
2020-09-09 08:21:57 +02:00
|
|
|
const N = 1<<10;
|
2020-09-08 23:26:03 +02:00
|
|
|
|
|
|
|
const a = new BigBuffer(N*bn128.Fr.n8);
|
|
|
|
for (let i=0; i<N; i++) {
|
|
|
|
if (i%100000 == 0) logger.debug(`setup ${i}/${N}`);
|
|
|
|
const num = Fr.e(i+1);
|
|
|
|
a.set(num, i*bn128.Fr.n8);
|
|
|
|
}
|
|
|
|
|
|
|
|
const A = await bn128.Fr.fft(a, "", "", logger, "fft");
|
|
|
|
const Ainv = await bn128.Fr.ifft(A, "", "", logger, "ifft");
|
|
|
|
|
|
|
|
for (let i=0; i<N; i++) {
|
|
|
|
if (i%100000 == 0) logger.debug(`checking ${i}/${N}`);
|
2020-09-09 08:21:57 +02:00
|
|
|
// console.log(Fr.toString(Ainv[i]));
|
2020-09-08 23:26:03 +02:00
|
|
|
const num1 = Ainv.slice(i*Fr.n8, i*Fr.n8+Fr.n8);
|
|
|
|
const num2 = a.slice(i*Fr.n8, i*Fr.n8+Fr.n8);
|
2020-08-12 01:05:42 +02:00
|
|
|
|
2020-09-08 23:26:03 +02:00
|
|
|
assert(num1, num2);
|
|
|
|
}
|
|
|
|
});
|
2020-08-12 01:05:42 +02:00
|
|
|
|
2020-09-09 08:21:57 +02:00
|
|
|
|
|
|
|
|
2020-08-12 01:05:42 +02:00
|
|
|
it("It shoud do a big FFT/IFFT in Fr", async () => {
|
|
|
|
const Fr = bn128.Fr;
|
|
|
|
const N = 8192*16;
|
|
|
|
|
|
|
|
const a = [];
|
|
|
|
for (let i=0; i<N; i++) a[i] = Fr.e(i+1);
|
|
|
|
|
|
|
|
const A = await bn128.Fr.fft(a);
|
|
|
|
const Ainv = await bn128.Fr.ifft(A);
|
|
|
|
|
|
|
|
for (let i=0; i<N; i++) {
|
|
|
|
// console.log(Fr.toString(Ainv[i]));
|
|
|
|
assert(Fr.eq(a[i], Ainv[i]));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-09-07 12:37:17 +02:00
|
|
|
|
|
|
|
it("It shoud do a big FFTExt/IFFTExt in Fr", async () => {
|
|
|
|
const Fr = bn128.Fr;
|
|
|
|
const N = 16;
|
|
|
|
|
|
|
|
const oldS = Fr.s;
|
|
|
|
Fr.s = log2(N)-1; // Force ext
|
|
|
|
|
|
|
|
const a = [];
|
|
|
|
for (let i=0; i<N; i++) a[i] = Fr.e(i+1);
|
|
|
|
|
|
|
|
const A = await bn128.Fr.fft(a);
|
|
|
|
const Ainv = await bn128.Fr.ifft(A);
|
|
|
|
|
|
|
|
for (let i=0; i<N; i++) {
|
|
|
|
// console.log(Fr.toString(Ainv[i]));
|
|
|
|
assert(Fr.eq(a[i], Ainv[i]));
|
|
|
|
}
|
|
|
|
|
|
|
|
Fr.s = oldS;
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2020-08-12 01:05:42 +02:00
|
|
|
it("It shoud do a big FFT/IFFT in G1", async () => {
|
|
|
|
const Fr = bn128.Fr;
|
|
|
|
const G1 = bn128.G1;
|
2020-09-07 12:37:17 +02:00
|
|
|
const N = 512;
|
2020-08-12 01:05:42 +02:00
|
|
|
|
|
|
|
const a = [];
|
|
|
|
for (let i=0; i<N; i++) a[i] = Fr.e(i+1);
|
|
|
|
|
|
|
|
const aG = [];
|
|
|
|
for (let i=0; i<N; i++) aG[i] = G1.timesFr(G1.g, a[i]);
|
|
|
|
|
|
|
|
const AG = await G1.fft(aG, "jacobian", "jacobian");
|
|
|
|
const AGInv = await G1.ifft(AG, "jacobian", "affine");
|
|
|
|
|
|
|
|
for (let i=0; i<N; i++) {
|
|
|
|
assert(G1.eq(aG[i], AGInv[i]));
|
|
|
|
}
|
|
|
|
});
|
2020-09-07 12:37:17 +02:00
|
|
|
|
|
|
|
it("It shoud do a big FFT/IFFT in G1 ext", async () => {
|
|
|
|
const Fr = bn128.Fr;
|
|
|
|
const G1 = bn128.G1;
|
|
|
|
const N = 1<<13;
|
|
|
|
|
|
|
|
const oldS = Fr.s;
|
|
|
|
Fr.s = log2(N)-1;
|
|
|
|
|
|
|
|
const a = [];
|
|
|
|
for (let i=0; i<N; i++) a[i] = Fr.e(i+1);
|
|
|
|
|
|
|
|
const aG = [];
|
|
|
|
for (let i=0; i<N; i++) aG[i] = G1.timesFr(G1.g, a[i]);
|
|
|
|
|
|
|
|
const AG = await G1.fft(aG, "jacobian", "jacobian");
|
|
|
|
const AGInv = await G1.ifft(AG, "jacobian", "affine");
|
|
|
|
|
|
|
|
for (let i=0; i<N; i++) {
|
|
|
|
assert(G1.eq(aG[i], AGInv[i]));
|
|
|
|
}
|
|
|
|
|
|
|
|
Fr.s = oldS;
|
|
|
|
});
|
2020-09-09 08:21:57 +02:00
|
|
|
|
|
|
|
it("It shoud do Multiexp", async () => {
|
|
|
|
const Fr = bn128.Fr;
|
|
|
|
const G1 = bn128.G1;
|
|
|
|
const N = 1 << 10;
|
|
|
|
|
|
|
|
const scalars = new BigBuffer(N*bn128.Fr.n8);
|
|
|
|
const bases = new BigBuffer(N*G1.F.n8*2);
|
|
|
|
let acc = Fr.zero;
|
|
|
|
for (let i=0; i<N; i++) {
|
|
|
|
if (i%100000 == 0) logger.debug(`setup ${i}/${N}`);
|
|
|
|
const num = Fr.e(i+1);
|
|
|
|
scalars.set(Fr.fromMontgomery(num), i*bn128.Fr.n8);
|
|
|
|
bases.set(G1.toAffine(G1.timesFr(G1.g, num)), i*G1.F.n8*2);
|
|
|
|
acc = Fr.add(acc, Fr.square(num));
|
|
|
|
}
|
|
|
|
|
|
|
|
const accG = G1.timesFr(G1.g, acc);
|
2020-09-13 08:49:18 +02:00
|
|
|
const accG2 = await G1.multiExpAffine(bases, scalars, logger, "test");
|
2020-09-09 08:21:57 +02:00
|
|
|
|
|
|
|
assert(G1.eq(accG, accG2 ));
|
|
|
|
});
|
|
|
|
|
|
|
|
|
2020-05-26 21:39:19 +02:00
|
|
|
});
|
|
|
|
|