arnaucube
arnaucube/circomPublic Self-hosted repository
circom/src/circuit_generator.js
src/circuit_generator.jsRaw
  1
  2const fs = require("fs");
  3const path = require("path");
  4const bigInt = require("big-integer");
  5const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
  6const __MASK__ = new bigInt(2).pow(253).minus(1);
  7const assert = require("assert");
  8const gen = require("./gencode");
  9const exec = require("./exec");
 10const lc = require("./lcalgebra");
 11
 12
 13const argv = require("optimist")
 14    .alias("c", "circuit")
 15    .alias("o", "output")
 16    .alias("w", "witnes")
 17    .argv;
 18
 19const parser = require("../jaz.js").parser;
 20
 21const fullFileName = path.resolve(process.cwd(), argv.circuit);
 22const fullFilePath = path.dirname(fullFileName);
 23
 24const src = fs.readFileSync(fullFileName, "utf8");
 25const ast = parser.parse(src);
 26
 27assert(ast.type == "BLOCK");
 28
 29const ctx = {
 30    scopes: [{}],
 31    signals: {
 32        one: {
 33            fullName: "one",
 34            value: bigInt(1),
 35            equivalence: "",
 36            direction: ""
 37        }
 38    },
 39    currentComponent: "",
 40    constrains: [],
 41    components: {},
 42    templates: {},
 43    functions: {},
 44    functionParams: {},
 45    filePath: fullFilePath,
 46    fileName: fullFileName
 47};
 48
 49exec(ctx, ast);
 50
 51reduceConstrains(ctx);
 52generateWitnessNames(ctx);
 53generateWitnessConstrains(ctx);
 54
 55if (ctx.error) {
 56    console.log(`ERROR at ${ctx.error.errFile}:${ctx.error.pos.first_line},${ctx.error.pos.first_column}-${ctx.error.pos.last_line},${ctx.error.pos.last_column}   ${ctx.error.errStr}`);
 57    console.log(JSON.stringify(ctx.error.ast, null, 1));
 58    process.exit(1);
 59}
 60
 61/*
 62console.log("SIGNALS");
 63console.log("==========");
 64for (let key in ctx.signals) {
 65    const signal = ctx.signals[key];
 66    console.log(signal.fullName);
 67}
 68
 69console.log("CONSTRAINS");
 70console.log("==========");
 71for (let i=0; i<ctx.constrains.length; i++) {
 72    console.log(lc.toString(ctx.constrains[i], ctx) + " === 0");
 73}
 74*/
 75ctx.scopes = [{}];
 76
 77const mainCode = gen(ctx,ast);
 78if (ctx.error) {
 79    console.log(`ERROR at ${ctx.error.pos.first_line},${ctx.error.pos.first_column}-${ctx.error.pos.last_line},${ctx.error.pos.last_column}   ${ctx.error.errStr}`);
 80    console.log(JSON.stringify(ctx.error.ast, null, 1));
 81    process.exit(1);
 82}
 83
 84
 85let outCode = "";
 86outCode += "const bigInt = require(\"big-integer\");\n";
 87outCode += "const __P__ = new bigInt(\"21888242871839275222246405745257275088696311157297823662689037894645226208583\");\n";
 88outCode += "const __MASK__ = new bigInt(2).pow(253).minus(1);\n";
 89outCode += "const circuit = {};\n";
 90outCode += "module.exports = circuit;\n\n";
 91outCode += `circuit.signals=${JSON.stringify(ctx.signals, null, 1)};\n\n`;
 92outCode += `circuit.components=${JSON.stringify(ctx.components, null, 1)};\n\n`;
 93outCode += `circuit.signalConstrains=${JSON.stringify(ctx.constrains, null, 1)};\n\n`;
 94outCode += `circuit.witnessNames=${JSON.stringify(ctx.witnessNames, null, 1)};\n\n`;
 95outCode += mainCode;
 96outCode += "\ncircuit.templates = {};\n";
 97for (let t in ctx.templates) {
 98    outCode += `\ncircuit.templates["${t}"] = ${ctx.templates[t]};\n`;
 99}
100outCode += `circuit.functionParams=${JSON.stringify(ctx.functionParams, null, 1)};\n\n`;
101outCode += "\ncircuit.functions = {};\n";
102for (let f in ctx.functions) {
103    outCode += `\ncircuit.functions["${f}"] = ${ctx.functions[f]};\n`;
104}
105
106/*
107console.log("CODE");
108console.log("====");
109console.log(outCode);
110*/
111
112
113console.log("#Constrains:" +ctx.constrains.length);
114
115fs.writeFileSync(argv.output, outCode, "utf8");
116
117function generateWitnessNames(ctx) {
118    ctx.witnessNames = [];
119    for (let c in ctx.components) {
120        ctx.components[c].inputSignals = 0;
121    }
122    for (let s in ctx.signals) {
123        const signal = ctx.signals[s];
124        let lSignal = signal;
125        while (lSignal.equivalence) {
126            lSignal = ctx.signals[lSignal.equivalence];
127        }
128        if ( typeof(lSignal.id) === "undefined" ) {
129            lSignal.id = ctx.witnessNames.length;
130            ctx.witnessNames.push([]);
131        }
132        if (signal.direction == "IN") {
133            ctx.components[signal.component].inputSignals++;
134        }
135
136        signal.id = lSignal.id;
137        ctx.witnessNames[signal.id].push(signal.fullName);
138    }
139}
140
141function reduceConstrains(ctx) {
142    const newConstrains = [];
143    for (let i=0; i<ctx.constrains.length; i++) {
144        const c = lc.canonize(ctx, ctx.constrains[i]);
145        if (!lc.isZero(c)) {
146            newConstrains.push(c);
147        }
148    }
149    ctx.constrains = newConstrains;
150}
151
152function generateWitnessConstrains(ctx) {
153
154}
155
156