Almost ready for 0.5.0

This commit is contained in:
Jordi Baylina
2020-03-26 17:42:25 +01:00
parent ef899e618b
commit eb8cb0af74
62 changed files with 1249 additions and 15153 deletions

View File

@@ -56,11 +56,10 @@ describe("basic cases", function () {
});
}
/*
for (let i=0; i<basicCases.length; i++) {
it("wasm " + basicCases[i].name, async () => {
await doTest(wasm_tester, basicCases[i].circuit, basicCases[i].tv);
});
}
*/
});

View File

@@ -1,343 +0,0 @@
const path = require("path");
const bigInt = require("big-integer");
const c_tester = require("../index.js").c_tester;
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
function normalize(o) {
if ((typeof(o) == "bigint") || o.isZero !== undefined) {
const res = bigInt(o);
return norm(res);
} else if (Array.isArray(o)) {
return o.map(normalize);
} else if (typeof o == "object") {
const res = {};
for (let k in o) {
res[k] = normalize(o[k]);
}
return res;
} else {
const res = bigInt(o);
return norm(res);
}
function norm(n) {
let res = n.mod(__P__);
if (res.isNegative()) res = __P__.add(res);
return res;
}
}
async function doTest(circuit, testVectors) {
const cir = await c_tester(path.join(__dirname, "circuits", circuit));
for (let i=0; i<testVectors.length; i++) {
const w = await cir.calculateWitness(normalize(testVectors[i][0]));
await cir.assertOut(w, normalize(testVectors[i][1]) );
}
await cir.release();
}
describe("basic cases", function () {
this.timeout(100000);
it("inout", async () => {
await doTest(
"inout.circom",
[
[{in1: 1, in2: [2,3], in3:[[4,5], [6,7], [8,9]]}, {out1: 1, out2: [2,3], out3: [[4,5], [6,7],[8,9]]}],
]
);
});
it("add", async () => {
await doTest(
"add.circom",
[
[{in: [0,0]}, {out: 0}],
[{in: [0,1]}, {out: 1}],
[{in: [1,2]}, {out: 3}],
[{in: [__P__.minus(1),1]}, {out: 0}],
]
);
});
it("add constant", async () => {
await doTest(
"addconst1.circom",
[
[{in: 0}, {out: 15}],
[{in: 10}, {out: 25}],
[{in: __P__.minus(2)}, {out: 13}],
]
);
});
it("for unrolled", async () => {
await doTest(
"forunrolled.circom",
[
[{in: 0}, {out: [0,1,2]}],
[{in: 10}, {out: [10, 11, 12]}],
[{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
]
);
});
it("for rolled", async () => {
await doTest(
"forrolled.circom",
[
[{in: 0}, {out: 0}],
[{in: 10}, {out: 10}],
]
);
});
it("while unrolled", async () => {
await doTest(
"whileunrolled.circom",
[
[{in: 0}, {out: [0,1,2]}],
[{in: 10}, {out: [10, 11, 12]}],
[{in: __P__.minus(2)}, {out: [__P__.minus(2), __P__.minus(1), 0]}],
]
);
});
it("while rolled", async () => {
await doTest(
"whilerolled.circom",
[
[{in: 0}, {out: 0}],
[{in: 10}, {out: 10}],
]
);
});
it("function1", async () => {
await doTest(
"function1.circom",
[
[{in: 0}, {out: 3}],
[{in: 10}, {out: 13}],
[{in: __P__.minus(2)}, {out: 1}],
]
);
});
it("function2", async () => {
await doTest(
"function2.circom",
[
[{in: 0}, {out: 3}],
[{in: 10}, {out: 13}],
[{in: __P__.minus(2)}, {out: 1}],
]
);
});
it("constants1", async () => {
await doTest(
"constants1.circom",
[
[{in: 0}, {out: 42}],
[{in: 10}, {out: 52}],
[{in: __P__.minus(2)}, {out: 40}],
]
);
});
it("arrays", async () => {
await doTest(
"arrays.circom",
[
[{in: 0}, {out: [1, 8, 51]}],
[{in: 10}, {out: [11, 28, 111]}],
[{in: __P__.minus(2)}, {out: [__P__.minus(1), 4, 39]}],
]
);
});
it("if unrolled", async () => {
await doTest(
"ifunrolled.circom",
[
[{in: 0}, {out: [1, 3, 6]}],
[{in: 10}, {out: [11, 13, 16]}],
[{in: __P__.minus(2)}, {out: [__P__.minus(1), 1, 4]}],
]
);
});
it("if rolled", async () => {
await doTest(
"ifrolled.circom",
[
[{in: 0}, {out: [1, 0, 0]}],
[{in: 1}, {out: [0, 1, 0]}],
[{in: 2}, {out: [0, 0, 1]}],
[{in: 3}, {out: [0, 0, 0]}],
[{in: __P__.minus(2)}, {out: [0,0,0]}],
]
);
});
it("inc", async () => {
await doTest(
"inc.circom",
[
[{in: 0}, {out: [5, 2]}],
[{in: 1}, {out: [6, 4]}],
[{in: 2}, {out: [7, 6]}],
[{in: 3}, {out: [8, 8]}],
[{in: __P__.minus(2)}, {out: [3,__P__.minus(2)]}],
]
);
});
it("dec", async () => {
await doTest(
"dec.circom",
[
[{in: 0}, {out: [1, __P__.minus(2)]}],
[{in: 1}, {out: [2, 0]}],
[{in: 2}, {out: [3, 2]}],
[{in: 3}, {out: [4, 4]}],
[{in: __P__.minus(2)}, {out: [__P__.minus(1),__P__.minus(6)]}],
]
);
});
it("ops", async () => {
await doTest(
"ops.circom",
[
[{in: [-2, 2]}, {add: 0, sub: -4, mul: -4}],
[{in: [-1, 1]}, {add: 0, sub: -2, mul: -1}],
[{in: [ 0, 0]}, {add: 0, sub: 0, mul: 0}],
[{in: [ 1,-1]}, {add: 0, sub: 2, mul: -1}],
[{in: [ 2,-2]}, {add: 0, sub: 4, mul: -4}],
[{in: [-2,-3]}, {add: -5, sub: 1, mul: 6}],
[{in: [ 2, 3]}, {add: 5, sub: -1, mul: 6}],
]
);
});
it("ops2", async () => {
await doTest(
"ops2.circom",
[
[{in: [-2, 2]}, {div: -1, idiv: bigInt("10944121435919637611123202872628637544274182200208017171849102093287904247807"), mod: 1}],
[{in: [-1, 1]}, {div: -1, idiv: -1, mod: 0}],
[{in: [ 1,-1]}, {div: -1, idiv: 0, mod: 1}],
]
);
});
it("ops3", async () => {
await doTest(
"ops3.circom",
[
[{in: [-2, 2]}, {neg1: 2,neg2: -2, pow: 4}],
[{in: [0, 1]}, {neg1: 0, neg2: -1, pow: 0}],
[{in: [ 1,-1]}, {neg1: -1, neg2: 1, pow: 1}],
]
);
});
it("Comparation ops", async () => {
await doTest(
"opscmp.circom",
[
[{in: [ 8, 9]}, {lt: 1, leq: 1, eq:0, neq:1, geq: 0, gt:0}],
[{in: [-2,-2]}, {lt: 0, leq: 1, eq:1, neq:0, geq: 1, gt:0}],
[{in: [-1,-2]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}],
[{in: [ 1,-1]}, {lt: 0, leq: 0, eq:0, neq:1, geq: 1, gt:1}], // In mod, negative values are higher than positive.
]
);
});
it("Bit ops", async () => {
const mask = bigInt("14474011154664524427946373126085988481658748083205070504932198000989141204991");
const m1m = bigInt("7414231717174750794300032619171286606889616317210963838766006185586667290624");
await doTest(
"opsbit.circom",
[
[{in: [ 5, 3]}, {and: 1, or: 7, xor:6, not1:mask.minus(5), shl: 40, shr:0}],
[{in: [ 0, 0]}, {and: 0, or: 0, xor:0, not1:mask, shl: 0, shr:0}],
[{in: [-1, 1]}, {and: 0, or: m1m.add(bigInt.one), xor:m1m.add(bigInt.one), not1:mask.minus(m1m), shl: m1m.shiftLeft(1).and(mask), shr:__P__.shiftRight(1).and(mask)}],
]
);
});
it("Logical ops", async () => {
await doTest(
"opslog.circom",
[
[{in: [ 5, 0]}, {and: 0, or: 1, not1:0}],
[{in: [ 0, 1]}, {and: 0, or: 1, not1:1}],
[{in: [-1, 9]}, {and: 1, or: 1, not1:0}],
[{in: [ 0, 0]}, {and: 0, or: 0, not1:1}],
]
);
});
it("Conditional Ternary operator", async () => {
await doTest(
"condternary.circom",
[
[{in: 0}, {out: 21}],
[{in: 1}, {out: 1}],
[{in: 2}, {out: 23}],
[{in:-1}, {out: 20}],
]
);
});
it("Compute block", async () => {
await doTest(
"compute.circom",
[
[{x: 1}, {y: 7}],
[{x: 2}, {y: 7}],
[{x: 3}, {y: 11}],
[{x:-1}, {y: -5}],
]
);
});
it("Component array ", async () => {
await doTest(
"componentarray.circom",
[
[{in: 1}, {out: 1}],
[{in: 2}, {out: 256}],
[{in: 3}, {out: 6561}],
[{in:-1}, {out: 1}],
]
);
});
it("Component array 2d", async () => {
await doTest(
"componentarray2.circom",
[
[{in: [1,2]}, {out: [1, 256]}],
[{in: [0,3]}, {out: [0, 6561]}],
]
);
});
it("Constant circuit", async () => {
await doTest(
"constantcircuit.circom",
[
// 0xbb67ae85
[{}, {out: [1,0,1,0, 0,0,0,1, 0,1,1,1, 0,1,0,1, 1,1,1,0, 0,1,1,0, 1,1,0,1, 1,1,0,1]}],
]
);
});
it("Constant internal circuit", async () => {
await doTest(
"constantinternalcircuit.circom",
[
[{in: 1}, {out: 5}],
[{in: 0}, {out: 4}],
[{in: -2}, {out: 2}],
[{in: 10}, {out: 14}]
]
);
});
it("include", async () => {
await doTest(
"include.circom",
[
[{in: 3}, {out: 6}],
[{in: 6}, {out: 15}],
]
);
});
});

View File

@@ -1,67 +0,0 @@
const chai = require("chai");
const path = require("path");
const snarkjs = require("snarkjs");
const bigInt = snarkjs.bigInt;
const compiler = require("../index.js");
const assert = chai.assert;
async function assertThrowsAsync(fn, regExp) {
let f = () => {};
try {
await fn();
} catch(e) {
f = () => { throw e; };
} finally {
assert.throws(f, regExp);
}
}
describe("Sum test", () => {
it("Should compile a code with an undefined if", async () => {
await compiler(path.join(__dirname, "circuits", "undefinedif.circom"));
});
it("Should compile a code with vars inside a for", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "forvariables.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "in": 111});
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(114)));
assert(witness[2].equals(bigInt(111)));
});
it("Should compile a code with an undefined if", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "mixvarsignal.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "i": 111});
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(111*111)));
assert(witness[2].equals(bigInt(111)));
});
// it("Should assign signal ERROR", async () => {
// await assertThrowsAsync(async () => {
// await compiler(path.join(__dirname, "circuits", "assignsignal.circom"));
// }, /Cannot assign to a signal .*/);
// });
it("Should compile a code with compute", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "compute.circom"));
const circuit = new snarkjs.Circuit(cirDef);
const witness = circuit.calculateWitness({ "x": 6});
assert(witness[0].equals(bigInt(1)));
assert(witness[1].equals(bigInt(37)));
assert(witness[2].equals(bigInt(6)));
});
it("Should compile a code with compute", async () => {
const cirDef = await compiler(path.join(__dirname, "circuits", "inout.circom"));
assert.equal(cirDef.constraints.length, 1);
});
});

View File

@@ -1,453 +0,0 @@
const tester = require("../ports/c/buildasm/buildzqfieldtester.js");
const ZqField = require("fflib").ZqField;
const bigInt = require("big-integer");
const bn128q = new bigInt("21888242871839275222246405745257275088696311157297823662689037894645226208583");
const bn128r = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
const secp256k1q = new bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", 16);
const secp256k1r = new bigInt("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16);
const mnt6753q = new bigInt("41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888458477323173057491593855069696241854796396165721416325350064441470418137846398469611935719059908164220784476160001");
const mnt6753r = new bigInt("41898490967918953402344214791240637128170709919953949071783502921025352812571106773058893763790338921418070971888253786114353726529584385201591605722013126468931404347949840543007986327743462853720628051692141265303114721689601");
describe("field asm test", function () {
this.timeout(1000000000);
it("bn128r add", async () => {
const tv = buildTestVector2(bn128r, "add");
await tester(bn128r, tv);
});
/*
it("secp256k1q add", async () => {
const tv = buildTestVector2(secp256k1q, "add");
await tester(secp256k1q, tv);
});
it("mnt6753q add", async () => {
const tv = buildTestVector2(mnt6753q, "add");
await tester(mnt6753q, tv);
});
it("bn128r sub", async () => {
const tv = buildTestVector2(bn128r, "sub");
await tester(bn128r, tv);
});
it("secp256k1q sub", async () => {
const tv = buildTestVector2(secp256k1q, "sub");
await tester(secp256k1q, tv);
});
it("mnt6753q sub", async () => {
const tv = buildTestVector2(mnt6753q, "sub");
await tester(mnt6753q, tv);
});
it("bn128r neg", async () => {
const tv = buildTestVector1(bn128r, "neg");
await tester(bn128r, tv);
});
it("secp256k1q neg", async () => {
const tv = buildTestVector1(secp256k1q, "neg");
await tester(secp256k1q, tv);
});
it("mnt6753q neg", async () => {
const tv = buildTestVector1(mnt6753q, "neg");
await tester(mnt6753q, tv);
});
it("bn128r mul", async () => {
const tv = buildTestVector2(bn128r, "mul");
await tester(bn128r, tv);
});
it("secp256k1q mul", async () => {
const tv = buildTestVector2(secp256k1q, "mul");
await tester(secp256k1q, tv);
});
it("mnt6753q mul", async () => {
const tv = buildTestVector2(mnt6753q, "mul");
await tester(mnt6753q, tv);
});
it("bn128r binary and", async () => {
const tv = buildTestVector2(bn128r, "band");
await tester(bn128r, tv);
});
it("secp256k1q binary and", async () => {
const tv = buildTestVector2(secp256k1q, "band");
await tester(secp256k1q, tv);
});
it("mnt6753q binary and", async () => {
const tv = buildTestVector2(mnt6753q, "band");
await tester(mnt6753q, tv);
});
it("bn128r binary or", async () => {
const tv = buildTestVector2(bn128r, "bor");
await tester(bn128r, tv);
});
it("secp256k1q binary or", async () => {
const tv = buildTestVector2(secp256k1q, "bor");
await tester(secp256k1q, tv);
});
it("mnt6753q binary or", async () => {
const tv = buildTestVector2(mnt6753q, "bor");
await tester(mnt6753q, tv);
});
it("bn128r binary xor", async () => {
const tv = buildTestVector2(bn128r, "bxor");
await tester(bn128r, tv);
});
it("secp256k1q binary xor", async () => {
const tv = buildTestVector2(secp256k1q, "bxor");
await tester(secp256k1q, tv);
});
it("mnt6753q binary xor", async () => {
const tv = buildTestVector2(mnt6753q, "bxor");
await tester(mnt6753q, tv);
});
it("bn128r binary not", async () => {
const tv = buildTestVector1(bn128r, "bnot");
await tester(bn128r, tv);
});
it("secp256k1q binary not", async () => {
const tv = buildTestVector1(secp256k1q, "bnot");
await tester(secp256k1q, tv);
});
it("mnt6753q binary not", async () => {
const tv = buildTestVector1(mnt6753q, "bnot");
await tester(mnt6753q, tv);
});
it("bn128r eq", async () => {
const tv = buildTestVector2(bn128r, "eq");
await tester(bn128r, tv);
});
it("secp256k1q eq", async () => {
const tv = buildTestVector2(secp256k1q, "eq");
await tester(secp256k1q, tv);
});
it("mnt6753q eq", async () => {
const tv = buildTestVector2(mnt6753q, "eq");
await tester(mnt6753q, tv);
});
it("bn128r neq", async () => {
const tv = buildTestVector2(bn128r, "neq");
await tester(bn128r, tv);
});
it("secp256k1q neq", async () => {
const tv = buildTestVector2(secp256k1q, "neq");
await tester(secp256k1q, tv);
});
it("mnt6753q neq", async () => {
const tv = buildTestVector2(mnt6753q, "neq");
await tester(mnt6753q, tv);
});
it("bn128r lt", async () => {
const tv = buildTestVector2(bn128r, "lt");
await tester(bn128r, tv);
});
it("secp256k1q lt", async () => {
const tv = buildTestVector2(secp256k1q, "lt");
await tester(secp256k1q, tv);
});
it("mnt6753q lt", async () => {
const tv = buildTestVector2(mnt6753q, "lt");
await tester(mnt6753q, tv);
});
it("bn128r gt", async () => {
const tv = buildTestVector2(bn128r, "gt");
await tester(bn128r, tv);
});
it("secp256k1q gt", async () => {
const tv = buildTestVector2(secp256k1q, "gt");
await tester(secp256k1q, tv);
});
it("mnt6753q gt", async () => {
const tv = buildTestVector2(mnt6753q, "gt");
await tester(mnt6753q, tv);
});
it("bn128r leq", async () => {
const tv = buildTestVector2(bn128r, "leq");
await tester(bn128r, tv);
});
it("secp256k1q leq", async () => {
const tv = buildTestVector2(secp256k1q, "leq");
await tester(secp256k1q, tv);
});
it("mnt6753q leq", async () => {
const tv = buildTestVector2(mnt6753q, "leq");
await tester(mnt6753q, tv);
});
it("bn128r geq", async () => {
const tv = buildTestVector2(bn128r, "geq");
await tester(bn128r, tv);
});
it("secp256k1q geq", async () => {
const tv = buildTestVector2(secp256k1q, "geq");
await tester(secp256k1q, tv);
});
it("mnt6753q geq", async () => {
const tv = buildTestVector2(mnt6753q, "geq");
await tester(mnt6753q, tv);
});
it("bn128r logical and", async () => {
const tv = buildTestVector2(bn128r, "land");
await tester(bn128r, tv);
});
it("secp256k1q logical and", async () => {
const tv = buildTestVector2(secp256k1q, "land");
await tester(secp256k1q, tv);
});
it("mnt6753q logical and", async () => {
const tv = buildTestVector2(mnt6753q, "land");
await tester(mnt6753q, tv);
});
it("bn128r logical or", async () => {
const tv = buildTestVector2(bn128r, "lor");
await tester(bn128r, tv);
});
it("secp256k1q logical or", async () => {
const tv = buildTestVector2(secp256k1q, "lor");
await tester(secp256k1q, tv);
});
it("mnt6753q logical or", async () => {
const tv = buildTestVector2(mnt6753q, "lor");
await tester(mnt6753q, tv);
});
it("bn128r logical not", async () => {
const tv = buildTestVector1(bn128r, "lnot");
await tester(bn128r, tv);
});
it("secp256k1q logical not", async () => {
const tv = buildTestVector1(secp256k1q, "lnot");
await tester(secp256k1q, tv);
});
it("mnt6753q logical not", async () => {
const tv = buildTestVector1(mnt6753q, "lnot");
await tester(mnt6753q, tv);
});
it("bn128r idiv", async () => {
const tv = buildTestVector2(bn128r, "idiv");
await tester(bn128r, tv);
});
it("secp256k1q idiv", async () => {
const tv = buildTestVector2(secp256k1q, "idiv");
await tester(secp256k1q, tv);
});
it("mnt6753q idiv", async () => {
const tv = buildTestVector2(mnt6753q, "idiv");
await tester(mnt6753q, tv);
});
it("bn128r inv", async () => {
const tv = buildTestVector1(bn128r, "inv");
await tester(bn128r, tv);
});
it("secp256k1q inv", async () => {
const tv = buildTestVector1(secp256k1q, "inv");
await tester(secp256k1q, tv);
});
it("mnt6753q inv", async () => {
const tv = buildTestVector1(mnt6753q, "inv");
await tester(mnt6753q, tv);
});
it("bn128r div", async () => {
const tv = buildTestVector2(bn128r, "div");
await tester(bn128r, tv);
});
it("secp256k1q div", async () => {
const tv = buildTestVector2(secp256k1q, "div");
await tester(secp256k1q, tv);
});
it("mnt6753q div", async () => {
const tv = buildTestVector2(mnt6753q, "div");
await tester(mnt6753q, tv);
});
it("bn128r square", async () => {
const tv = buildTestVector1(bn128r, "square");
await tester(bn128r, tv);
});
it("secp256k1q square", async () => {
const tv = buildTestVector1(secp256k1q, "square");
await tester(secp256k1q, tv);
});
it("mnt6753q square", async () => {
const tv = buildTestVector1(mnt6753q, "square");
await tester(mnt6753q, tv);
});
*/
it("bn128r shl", async () => {
const tv = buildTestVector2(bn128r, "shl");
await tester(bn128r, tv);
});
/*
it("secp256k1q shl", async () => {
const tv = buildTestVector2(secp256k1q, "shl");
await tester(secp256k1q, tv);
});
it("mnt6753q shl", async () => {
const tv = buildTestVector2(mnt6753q, "shl");
await tester(mnt6753q, tv);
});
*/
it("bn128r shr", async () => {
const tv = buildTestVector2(bn128r, "shr");
await tester(bn128r, tv);
});
/*
it("secp256k1q shr", async () => {
const tv = buildTestVector2(secp256k1q, "shr");
await tester(secp256k1q, tv);
});
it("mnt6753q shr", async () => {
const tv = buildTestVector2(mnt6753q, "shr");
await tester(mnt6753q, tv);
});
it("mnt6753q band", async () => {
const tv = buildTestVector2(mnt6753q, "band");
await tester(mnt6753q, tv);
});
it("mnt6753q bor", async () => {
const tv = buildTestVector2(mnt6753q, "bor");
await tester(mnt6753q, tv);
});
it("mnt6753q bxor", async () => {
const tv = buildTestVector2(mnt6753q, "bxor");
await tester(mnt6753q, tv);
});
it("mnt6753q bnot", async () => {
const tv = buildTestVector1(mnt6753q, "bnot");
await tester(mnt6753q, tv);
});
*/
});
function buildTestVector2(p, op) {
const F = new ZqField(p);
const tv = [];
const nums = getCriticalNumbers(p, 2);
const excludeZero = ["div", "mod", "idiv"].indexOf(op) >= 0;
for (let i=0; i<nums.length; i++) {
for (let j=0; j<nums.length; j++) {
if ((excludeZero)&&(nums[j][0].isZero())) continue;
tv.push([
[nums[i][1], nums[j][1], op],
F[op](nums[i][0], nums[j][0])
]);
}
}
return tv;
}
function buildTestVector1(p, op) {
const F = new ZqField(p);
const tv = [];
const nums = getCriticalNumbers(p, 2);
const excludeZero = ["inv"].indexOf(op) >= 0;
for (let i=0; i<nums.length; i++) {
if ((excludeZero)&&(nums[i][0].isZero())) continue;
tv.push([
[nums[i][1], op],
F[op](nums[i][0])
]);
}
return tv;
}
function getCriticalNumbers(p, lim) {
const numbers = [];
addFrontier(0);
addFrontier(bigInt(32));
addFrontier(bigInt(64));
addFrontier(bigInt(p.bitLength()));
addFrontier(bigInt.one.shiftLeft(31));
addFrontier(p.minus(bigInt.one.shiftLeft(31)));
addFrontier(bigInt.one.shiftLeft(32));
addFrontier(p.minus(bigInt.one.shiftLeft(32)));
addFrontier(bigInt.one.shiftLeft(63));
addFrontier(p.minus(bigInt.one.shiftLeft(63)));
addFrontier(bigInt.one.shiftLeft(64));
addFrontier(p.minus(bigInt.one.shiftLeft(64)));
addFrontier(bigInt.one.shiftLeft(p.bitLength()-1));
addFrontier(p.shiftRight(1));
function addFrontier(f) {
for (let i=-lim; i<=lim; i++) {
let n = bigInt(f).add(bigInt(i));
n = n.mod(p);
if (n.isNegative()) n = p.add(n);
addNumber(n);
}
}
return numbers;
function addNumber(n) {
if (n.lt(bigInt("80000000", 16)) ) {
addShortPositive(n);
addShortMontgomeryPositive(n);
}
if (n.geq(p.minus(bigInt("80000000", 16))) ) {
addShortNegative(n);
addShortMontgomeryNegative(n);
}
addLongNormal(n);
addLongMontgomery(n);
function addShortPositive(a) {
numbers.push([a, "0x"+a.toString(16)]);
}
function addShortMontgomeryPositive(a) {
let S = "0x" + bigInt("40", 16).shiftLeft(56).add(a).toString(16);
S = S + "," + getLongString(toMontgomery(a));
numbers.push([a, S]);
}
function addShortNegative(a) {
const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
numbers.push([a, "0x"+b.toString(16)]);
}
function addShortMontgomeryNegative(a) {
const b = bigInt("80000000", 16 ).add(a.minus( p.minus(bigInt("80000000", 16 ))));
let S = "0x" + bigInt("40", 16).shiftLeft(56).add(b).toString(16);
S = S + "," + getLongString(toMontgomery(a));
numbers.push([a, S]);
}
function addLongNormal(a) {
let S = "0x" + bigInt("80", 16).shiftLeft(56).toString(16);
S = S + "," + getLongString(a);
numbers.push([a, S]);
}
function addLongMontgomery(a) {
let S = "0x" + bigInt("C0", 16).shiftLeft(56).toString(16);
S = S + "," + getLongString(toMontgomery(a));
numbers.push([a, S]);
}
function getLongString(a) {
if (a.isZero()) {
return "0x0";
}
let r = a;
let S = "";
while (!r.isZero()) {
if (S!= "") S = S+",";
S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16);
r = r.shiftRight(64);
}
return S;
}
function toMontgomery(a) {
const n64 = Math.floor((p.bitLength() - 1) / 64)+1;
const R = bigInt.one.shiftLeft(n64*64);
return a.times(R).mod(p);
}
}
}