constants

This commit is contained in:
Jordi Baylina
2019-11-30 22:59:14 +01:00
parent f4bbcfd90c
commit 6cdb006909
11 changed files with 166 additions and 908 deletions

View File

@@ -140,7 +140,7 @@ function buildCode(ctx) {
const fnComponents = [];
for (let i=0; i<ctx.components.length; i++) {
const h = hashComponentCall(ctx, i);
const {h, instanceDef} = hashComponentCall(ctx, i);
const fName = ctx.components[i].template+"_"+h;
if (!fDefined[fName]) {
@@ -159,15 +159,20 @@ function buildCode(ctx) {
gen(ctx, ctx.templates[ctx.components[i].template].block);
const S = `void ${fName}(Circom_CalcWit *ctx) {\n` +
const S =
"/*\n" +
instanceDef +
"\n*/\n" +
`void ${fName}(Circom_CalcWit *ctx) {\n` +
utils.ident(
ctx.codeHeader + "\n" +
ctx.code + "\n" +
ctx.codeFooter
) +
"}\n";
"}\n";
fnComponents.push(S);
fDefined[fName] = true;
}
ctx.components[i].fnName = fName;
}
@@ -269,9 +274,9 @@ function buildWit2Sig(ctx) {
const arr = Array(NVars);
for (let i=0; i<ctx.signals.length; i++) {
const outIdx = ctx.signals[i].id;
if (typeof outIdx == "undefined") continue;
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
assert(outIdx<NVars);
assert(typeof outIdx != "undefined", `Signal ${i} does not have index`);
if (outIdx>=NVars) continue; // Is a constant or a discarded variable
if (typeof arr[ctx.signals[i].id] == "undefined") {
arr[outIdx] = i;
}
@@ -312,11 +317,6 @@ function buildCircuitVar() {
function hashComponentCall(ctx, cIdx) {
// TODO: At the moment generate a diferent function for each instance of the component
return cIdx;
}
function getTmpName(_suggestedName) {
let suggestedName;
@@ -374,7 +374,7 @@ function addSizes(_sizes) {
function buildFunction(name, paramValues) {
const ctx = this;
const h = hashFunctionCall(ctx, name, paramValues);
const {h, instanceDef} = hashFunctionCall(ctx, name, paramValues);
if (ctx.definedFunctions[h]) return ctx.definedFunctions[h];
@@ -430,7 +430,11 @@ function buildFunction(name, paramValues) {
if (ctx.returnValue == null) {
if (ctx.returnSizes == null) assert(false, `Funciont ${name} does not return any value`);
res.type = "VARVAL_CONSTSIZE";
let code = `void ${name}_${h}(Circom_CalcWit *ctx, PBigInt __retValue ${paramsStr}) {`;
let code =
"/*\n" +
instanceDef +
"\n*/\n" +
`void ${name}_${h}(Circom_CalcWit *ctx, PBigInt __retValue ${paramsStr}) {`;
code += utils.ident(ctx.codeHeader);
code += utils.ident(ctx.code);
code += utils.ident("returnFunc:\n");
@@ -455,7 +459,77 @@ function buildFunction(name, paramValues) {
return res;
}
function hashComponentCall(ctx, cIdx) {
// TODO: At the moment generate a diferent function for each instance of the component
const constParams = [];
for (let p in ctx.components[cIdx].params) {
constParams.push(p + "=" + value2str(ctx.components[cIdx].params[p]));
}
for (let n in ctx.components[cIdx].names.o) {
const entry = ctx.components[cIdx].names.o[n];
if ((entry.type == "S")&&(ctx.signals[entry.offset].o & ctx.IN)) {
travelSizes(n, entry.offset, entry.sizes, (prefix, offset) => {
if (utils.isDefined(ctx.signals[offset].v)) {
constParams.push(prefix + "=" + bigInt(ctx.signals[offset].value));
}
});
}
}
let instanceDef = ctx.components[cIdx].template;
if (constParams.length>0) {
instanceDef += "\n";
constParams.sort();
instanceDef += constParams.join("\n");
}
const h = utils.fnvHash(instanceDef);
return {h, instanceDef};
function travelSizes(prefix, offset, sizes, fn) {
if (sizes.length == 0) {
fn(prefix, offset);
return 1;
} else {
let o = offset;
for (let i=0; i<sizes[0]; i++) {
o += travelSizes(prefix + "[" + i + "]", o, sizes.slice(1), fn);
}
return o-offset;
}
}
}
function hashFunctionCall(ctx, name, paramValues) {
// TODO
return "1234";
const constParams = [];
for (let i=0; i<ctx.functions[name].params.length; i++) {
if (!paramValues[i].used) {
constParams.push(ctx.functions[name].params[i] + "=" + value2str(paramValues[i]));
}
}
let instanceDef = name;
if (constParams.length>0) {
instanceDef += "\n";
constParams.sort();
instanceDef += constParams.join("\n");
}
const h = utils.fnvHash(instanceDef);
return {h, instanceDef};
}
function value2str(v) {
if (Array.isArray(v)) {
let S="[";
for (let i=0; i<v.length; i++) {
if (i>0) S+=",";
S+=value2str(v[i]);
}
return S;
} else {
return bigInt(v).toString();
}
}

View File

@@ -6,7 +6,6 @@ module.exports.gen = gen;
module.exports.newRef = newRef;
function newRef(ctx, type, _name, value, sizes) {
const isValue = ((typeof(value) != "undefined")&&(value != null));
let name;
if (!_name) {
name = ctx.getTmpName();
@@ -19,7 +18,7 @@ function newRef(ctx, type, _name, value, sizes) {
}
if (Array.isArray(sizes)) {
sizes = utils.accSizes(sizes);
} else if (isValue) {
} else if (utils.isDefined(value)) {
sizes = utils.accSizes(utils.extractSizes(value));
} else {
sizes = [1, 0];
@@ -37,7 +36,7 @@ function newRef(ctx, type, _name, value, sizes) {
label: label
};
if (isValue) {
if (utils.isDefined(value)) {
scope[name].value = value;
}
@@ -59,7 +58,7 @@ function instantiateRef(ctx, name, initValue) {
ctx.codeHeader += `Circom_Sizes ${v.label};\n`;
}
v.used = true;
if ((typeof initValue!= "undefined")&&(initValue != null)) {
if (utils.isDefined(initValue)) {
const flatedValue = utils.flatArray(initValue);
for (let i=0; i<flatedValue.length; i++) {
const c = `mpz_set_str(${v.label}[${i}], "${flatedValue[i].toString(10)}", 10);\n`;
@@ -738,7 +737,7 @@ function genFor(ctx, ast) {
`${condVar} = ctx->field->isTrue(${condName});\n` +
`while (${condVar}) {\n`;
} else {
if ((typeof cond.value == "undefined")||(cond.value == null)) return error(ctx, ast, "condition value not assigned");
if (!utils.isDefined(cond.value)) return error(ctx, ast, "condition value not assigned");
if (cond.value.isZero()) end=true;
}
@@ -834,8 +833,8 @@ function genReturn(ctx, ast) {
if (v.used) {
ctx.code += `ctx->field->copyn(__retValue, ${vName}, ${v.sizes[0]});\n`;
} else {
if ((typeof v.value == "undefined") || v == null) return error(ctx, ast, "Returning an unknown value");
if ((typeof ctx.returnValue == "undefined") || (ctx.returnValue == null)) {
if (!utils.isDefined(v.value)) return error(ctx, ast, "Returning an unknown value");
if (!utils.isDefined(ctx.returnValue)) {
ctx.returnValue = v.value;
}
}
@@ -885,8 +884,8 @@ function genBinaryOp(ctx, ast, op) {
if (ctx.error) return;
const b = getScope(ctx, bName);
if ((!a.used)&&(typeof a.value == "undefined")) return error(ctx, ast, "Using a not assigned varialble: "+aName);
if ((!b.used)&&(typeof b.value == "undefined")) return error(ctx, ast, "Using a not assigned varialble: "+bName);
if ((!a.used)&&(!utils.isDefined(a.value))) return error(ctx, ast, "Using a not assigned varialble: "+aName);
if ((!b.used)&&(!utils.isDefined(b.value))) return error(ctx, ast, "Using a not assigned varialble: "+bName);
let rName;
if (a.used || b.used) {

View File

@@ -29,6 +29,7 @@ const exec = require("./exec");
const lc = require("./lcalgebra");
const Ctx = require("./ctx");
const ZqField = require("./zqfield");
const utils = require("./utils");
module.exports = compile;
@@ -130,6 +131,7 @@ function classifySignals(ctx) {
return t1;
}
if ((t1 == ctx.stONE) || (t2 == ctx.stONE)) return ctx.stONE;
if ((t1 == ctx.stOUTPUT) || (t2 == ctx.stOUTPUT)) return ctx.stOUTPUT;
if ((t1 == ctx.stCONSTANT) || (t2 == ctx.stCONSTANT)) return ctx.stCONSTANT;
if ((t1 == ctx.stDISCARDED) || (t2 == ctx.stDISCARDED)) return ctx.stDISCARDED;
if (t1!=t2) return ERROR;
@@ -146,8 +148,6 @@ function classifySignals(ctx) {
let t = lSignal.c || ctx.stINTERNAL;
if (s == 0) {
t = ctx.stONE;
} else if (lSignal.v) {
t = ctx.stCONSTANT;
} else if (lSignal.o & ctx.MAIN) {
if (lSignal.o & ctx.IN) {
if (lSignal.o & ctx.PRV) {
@@ -158,6 +158,8 @@ function classifySignals(ctx) {
} else if (lSignal.o & ctx.OUT) {
t = ctx.stOUTPUT;
}
} else if (utils.isDefined(lSignal.v)) {
t = ctx.stCONSTANT;
}
tAll = priorize(t,tAll);
if (lSignal.e>=0) {

View File

@@ -20,6 +20,8 @@
const path = require("path");
const fs = require("fs");
const utils = require("./utils");
const bigInt = require("big-integer");
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
const __MASK__ = new bigInt(2).pow(253).minus(1);
@@ -495,15 +497,15 @@ function execDeclareSignal(ctx, ast) {
if (ast.name.type != "VARIABLE") return error(ctx, ast, "Invalid component name");
if (getScope(ctx, ast.name.name)) return error(ctx, ast, "Name already exists: "+ast.name.name);
let totalSize = 1;
const sizes=[];
let totalSize=1;
for (let i=0; i< ast.name.selectors.length; i++) {
const size = exec(ctx, ast.name.selectors[i]);
if (ctx.error) return;
if (size.type != "NUMBER") return error(ctx, ast.name.selectors[i], "expected a number");
const s = size.value.toJSNumber();
totalSize *= s;
totalSize = totalSize * s;
sizes.push( s );
}
@@ -529,7 +531,7 @@ function execDeclareSignal(ctx, ast) {
ctx.signals[i].o |= ctx.MAIN;
}
// ctx.components[ctx.currentComponent].signals.push(i);
// ctx.components[ctx.currentComponent].signals.push(i);
}
scope[ast.name.name] = {
type: "SIGNAL",
@@ -584,10 +586,10 @@ function execVariable(ctx, ast) {
if (!v) return error(ctx, ast, "Variable not defined");
// If the signal has an assigned value (constant) just return the constant
if ((v.type == "SIGNAL") && (ctx.signals[v.sIdx].value)) {
if ((v.type == "SIGNAL") && (utils.isDefined(ctx.signals[v.sIdx].v))) {
return {
type: "NUMBER",
value: ctx.signals[v.sIdx].value
value: ctx.signals[v.sIdx].v
};
}
let res;
@@ -1121,7 +1123,7 @@ function execSignalAssign(ctx, ast) {
const v = lc.evaluate(ctx, src);
if (v.value) {
sDest.value = v.value;
sDest.v = v.value;
}
}

View File

@@ -12,6 +12,7 @@ module.exports.fnvHash = fnvHash;
module.exports.stringifyBigInts = stringifyBigInts;
module.exports.unstringifyBigInts = unstringifyBigInts;
module.exports.sameSizes = sameSizes;
module.exports.isDefined = isDefined;
function ident(text) {
let lines = text.split("\n");
@@ -116,5 +117,9 @@ function sameSizes(s1, s2) {
return true;
}
function isDefined(v) {
return ((typeof(v) != "undefined")&&(v != null));
}