|
|
const chai = require("chai"); const assert = chai.assert;
const fs = require("fs"); var tmp = require("tmp-promise"); const path = require("path"); const util = require("util"); const exec = util.promisify(require("child_process").exec);
const bigInt = require("big-integer"); const BuildZqField = require("./buildzqfield"); const ZqField = require("fflib").ZqField;
module.exports = testField;
function toMontgomeryStr(a, prime) { const n64 = Math.floor((prime.bitLength() - 1) / 64)+1; return a.shiftLeft(n64*64).mod(prime).toString(10); }
function fromMontgomeryStr(a, prime) { const n64 = Math.floor((prime.bitLength() - 1) / 64)+1; const R = bigInt.one.shiftLeft(n64*64).mod(prime); const RI = R.modInv(prime); return bigInt(a).times(RI).mod(prime); }
async function testField(prime, test) { tmp.setGracefulCleanup();
const F = new ZqField(prime);
const dir = await tmp.dir({prefix: "circom_", unsafeCleanup: true });
const [hSource, cSource] = BuildZqField(prime, "Fr");
await fs.promises.writeFile(path.join(dir.path, "fr.h"), hSource, "utf8"); await fs.promises.writeFile(path.join(dir.path, "fr.c"), cSource, "utf8");
await exec("g++" + ` ${path.join(__dirname, "tester.c")}` + ` ${path.join(dir.path, "fr.c")}` + ` -o ${path.join(dir.path, "tester")}` + " -lgmp" );
for (let i=0; i<test.length; i++) { let a = bigInt(test[i][1]).mod(prime); if (a.isNegative()) a = prime.add(a); let b = bigInt(test[i][2]).mod(prime); if (b.isNegative()) b = prime.add(b); const ec = F[test[i][0]](a,b); // console.log(toMontgomeryStr(a, prime));
// console.log(toMontgomeryStr(b, prime));
const res = await exec(`${path.join(dir.path, "tester")}` + ` ${test[i][0]}` + ` ${toMontgomeryStr(a, prime)}` + ` ${toMontgomeryStr(b, prime)}` ); // console.log(res.stdout);
const c=fromMontgomeryStr(res.stdout, prime);
assert.equal(ec.toString(), c.toString()); }
}
|