mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 03:06:42 +01:00
Use native big int
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
const streamFromMultiArray = require("../../src/streamfromarray_txt.js");
|
||||
const bigInt = require("big-integer");
|
||||
const utils = require("../../src/utils");
|
||||
const assert = require("assert");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const F1Field = require("ffjavascript").F1Field;
|
||||
|
||||
function ref2src(c) {
|
||||
if ((c[0] == "R")||(c[0] == "RI")) {
|
||||
@@ -340,7 +341,9 @@ class FunctionBuilderC {
|
||||
}
|
||||
|
||||
class BuilderC {
|
||||
constructor() {
|
||||
constructor(p) {
|
||||
this.F = new F1Field(p);
|
||||
|
||||
this.hashMaps={};
|
||||
this.componentEntriesTables={};
|
||||
this.sizes ={};
|
||||
@@ -348,7 +351,6 @@ class BuilderC {
|
||||
this.functions = [];
|
||||
this.components = [];
|
||||
this.usedConstants = {};
|
||||
|
||||
}
|
||||
|
||||
setHeader(header) {
|
||||
@@ -369,9 +371,9 @@ class BuilderC {
|
||||
}
|
||||
|
||||
addConstant(c) {
|
||||
c = bigInt(c);
|
||||
c = this.F.e(c);
|
||||
const cS = c.toString();
|
||||
if (this.usedConstants[cS]) return this.usedConstants[cS];
|
||||
if (typeof this.usedConstants[cS] != "undefined") return this.usedConstants[cS];
|
||||
this.constants.push(c);
|
||||
this.usedConstants[cS] = this.constants.length - 1;
|
||||
return this.constants.length - 1;
|
||||
@@ -471,8 +473,6 @@ class BuilderC {
|
||||
|
||||
_buildConstants(code) {
|
||||
const self = this;
|
||||
const n64 = Math.floor((self.header.P.bitLength() - 1) / 64)+1;
|
||||
const R = bigInt.one.shiftLeft(n64*64);
|
||||
|
||||
code.push("// Constants");
|
||||
code.push(`FrElement _constants[${self.constants.length}] = {`);
|
||||
@@ -482,12 +482,19 @@ class BuilderC {
|
||||
code.push("};");
|
||||
|
||||
function number2Code(n) {
|
||||
if (n.lt(bigInt("80000000", 16)) ) {
|
||||
return addShortMontgomeryPositive(n);
|
||||
}
|
||||
if (n.geq(self.header.P.minus(bigInt("80000000", 16))) ) {
|
||||
return addShortMontgomeryNegative(n);
|
||||
const minShort = self.F.neg(self.F.e("80000000"));
|
||||
const maxShort = self.F.e("7FFFFFFF", 16);
|
||||
|
||||
if ( (self.F.geq(n, minShort))
|
||||
&&(self.F.leq(n, maxShort)))
|
||||
{
|
||||
if (self.F.geq(n, self.F.zero)) {
|
||||
return addShortMontgomeryPositive(n);
|
||||
} else {
|
||||
return addShortMontgomeryNegative(n);
|
||||
}
|
||||
}
|
||||
|
||||
return addLongMontgomery(n);
|
||||
|
||||
|
||||
@@ -506,25 +513,31 @@ class BuilderC {
|
||||
}
|
||||
|
||||
function getLongString(a) {
|
||||
let r = bigInt(a);
|
||||
let S = "";
|
||||
let i = 0;
|
||||
while (!r.isZero()) {
|
||||
if (S!= "") S = S+",";
|
||||
S += "0x" + r.and(bigInt("FFFFFFFFFFFFFFFF", 16)).toString(16) + "LL";
|
||||
i++;
|
||||
r = r.shiftRight(64);
|
||||
}
|
||||
while (i<n64) {
|
||||
if (S!= "") S = S+",";
|
||||
S += "0LL";
|
||||
i++;
|
||||
const arr = Scalar.toArray(a, 0x100000000);
|
||||
for (let i=0; i<self.F.n64*2; i+=2) {
|
||||
const idx = arr.length-2-i;
|
||||
|
||||
if (i>0) S = S + ",";
|
||||
|
||||
if ( idx >=0) {
|
||||
let msb = arr[idx].toString(16);
|
||||
while (msb.length<8) msb = "0" + msb;
|
||||
|
||||
let lsb = arr[idx+1].toString(16);
|
||||
while (lsb.length<8) lsb = "0" + lsb;
|
||||
|
||||
S += "0x" + msb + lsb + "LL";
|
||||
} else {
|
||||
S += "0LL";
|
||||
}
|
||||
}
|
||||
|
||||
return S;
|
||||
}
|
||||
|
||||
function toMontgomery(a) {
|
||||
return a.times(R).mod(self.header.P);
|
||||
return self.F.mul(a, self.F.R);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,12 +8,14 @@ const compiler = require("../../src/compiler");
|
||||
const util = require("util");
|
||||
const exec = util.promisify(require("child_process").exec);
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const Scalar = require("ffjavascript").Scalar;
|
||||
const utils = require("../../src/utils");
|
||||
const loadR1cs = require("r1csfile").load;
|
||||
const ZqField = require("ffjavascript").ZqField;
|
||||
const buildZqField = require("ffiasm").buildZqField;
|
||||
|
||||
const {stringifyBigInts, unstringifyBigInts } = require("ffjavascript").utils;
|
||||
|
||||
module.exports = c_tester;
|
||||
|
||||
|
||||
@@ -31,7 +33,7 @@ async function c_tester(circomFile, _options) {
|
||||
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
|
||||
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
|
||||
|
||||
options.p = options.p || bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
options.p = options.p || Scalar.fromString("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
await compiler(circomFile, options);
|
||||
|
||||
const source = await buildZqField(options.p, "Fr");
|
||||
@@ -87,7 +89,7 @@ class CTester {
|
||||
async calculateWitness(input) {
|
||||
await fs.promises.writeFile(
|
||||
path.join(this.dir.path, "in.json"),
|
||||
JSON.stringify(utils.stringifyBigInts(input), null, 1)
|
||||
JSON.stringify(stringifyBigInts(input), null, 1)
|
||||
);
|
||||
const r = await exec(`${path.join(this.dir.path, this.baseName)}` +
|
||||
` ${path.join(this.dir.path, "in.json")}` +
|
||||
@@ -100,7 +102,7 @@ class CTester {
|
||||
path.join(this.dir.path, "out.json")
|
||||
);
|
||||
|
||||
const res = utils.unstringifyBigInts(JSON.parse(resStr));
|
||||
const res = unstringifyBigInts(JSON.parse(resStr));
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -127,7 +129,7 @@ class CTester {
|
||||
const self = this;
|
||||
if (this.constraints) return;
|
||||
const r1cs = await loadR1cs(path.join(this.dir.path, this.baseName + ".r1cs"),true, false);
|
||||
self.field = new ZqField(r1cs.prime);
|
||||
self.F = new ZqField(r1cs.prime);
|
||||
self.nVars = r1cs.nVars;
|
||||
self.constraints = r1cs.constraints;
|
||||
}
|
||||
@@ -152,8 +154,8 @@ class CTester {
|
||||
if (typeof self.symbols[prefix] == "undefined") {
|
||||
assert(false, "Output variable not defined: "+ prefix);
|
||||
}
|
||||
const ba = bigInt(actualOut[self.symbols[prefix].varIdx]).toString();
|
||||
const be = bigInt(eOut).toString();
|
||||
const ba = actualOut[self.symbols[prefix].varIdx].toString();
|
||||
const be = eOut.toString();
|
||||
assert.strictEqual(ba, be, prefix);
|
||||
}
|
||||
}
|
||||
@@ -183,7 +185,7 @@ class CTester {
|
||||
}
|
||||
|
||||
function checkConstraint(constraint) {
|
||||
const F = self.field;
|
||||
const F = self.F;
|
||||
const a = evalLC(constraint[0]);
|
||||
const b = evalLC(constraint[1]);
|
||||
const c = evalLC(constraint[2]);
|
||||
@@ -192,7 +194,7 @@ class CTester {
|
||||
}
|
||||
|
||||
function evalLC(lc) {
|
||||
const F = self.field;
|
||||
const F = self.F;
|
||||
let v = F.zero;
|
||||
for (let w in lc) {
|
||||
v = F.add(
|
||||
|
||||
Reference in New Issue
Block a user