/* Copyright 2018 0KIMS association. This file is part of circom (Zero Knowledge Circuit Compiler). circom is a free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. circom is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with circom. If not, see . */ const assert = require("assert"); const utils = require("./utils"); const gen = require("./gencode").gen; const createRefs = require("./gencode").createRefs; const BigArray = require("./bigarray"); module.exports = build; function build(ctx) { ctx.definedFunctions = {}; ctx.functionCodes = []; ctx.buildFunction = buildFunction; ctx.conditionalCodeHeader = ""; ctx.codes_sizes = []; ctx.definedSizes = {}; ctx.addSizes = addSizes; ctx.addConstant = addConstant; ctx.addConstant(ctx.F.zero); ctx.addConstant(ctx.F.one); if (ctx.verbose) console.log("buildHeader..."); buildHeader(ctx); if (ctx.verbose) console.log("buildEntryTables..."); buildEntryTables(ctx); ctx.globalNames = ctx.uniqueNames; if (ctx.verbose) console.log("buildCode..."); buildCode(ctx); if (ctx.verbose) console.log("buildComponentsArray..."); buildComponentsArray(ctx); if (ctx.verbose) console.log("buildMapIsInput..."); buildMapIsInput(ctx); if (ctx.verbose) console.log("buildWit2Sig..."); buildWit2Sig(ctx); } function buildEntryTables(ctx) { const definedHashMaps = {}; for (let i=0; i ((a>b) ? 1 : -1)); const h = utils.fnvHash(keys.join(",")); if (definedHashMaps[h]) return definedHashMaps[h]; definedHashMaps[h] = {}; definedHashMaps[h].htName = ctx.getUniqueName("_ht"+ctx.components[cIdx].template); definedHashMaps[h].htMap = []; const t = []; for (let i=0; i=0) continue; // If has an alias, continue.. 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; } } ctx.builder.setWit2Sig(arr); } function addSizes(_sizes) { const sizes = _sizes || []; let name = "sizes"; for (let i=0; i0) code += ","; code += accSizes[i]; } code += "};\n"; this.codes_sizes.push(code); return labelName; } function addConstant(c) { return this.builder.addConstant(c); } function buildFunction(name, paramValues) { const ctx = this; const {h, instanceDef} = hashFunctionCall(ctx, name, paramValues); if (ctx.definedFunctions[h]) return ctx.definedFunctions[h]; const res = { fnName: `${name}_${h}` }; const oldRefs = ctx.refs; const oldConditionalCode = ctx.conditionalCode; const oldCodeBuilder = ctx.codeBuilder; const oldFnBuilder = ctx.fnBuilder; const oldUniqueNames = ctx.uniqueNames; const oldFileName = ctx.fileName; const oldFilePath = ctx.oldFilePath; const oldReturnSizes = ctx.returnSizes; const oldReturnValue = ctx.returnValue; ctx.scopes = [{}]; ctx.refs = []; ctx.conditionalCode = false; ctx.fnBuilder = ctx.builder.newFunctionBuilder(`${name}_${h}`, instanceDef, ctx.functions[name].params); ctx.codeBuilder = ctx.fnBuilder.newCodeBuilder(); ctx.uniqueNames = Object.assign({},ctx.globalNames); ctx.returnValue = null; ctx.returnSizes = null; ctx.fileName = ctx.functions[name].fileName; ctx.filePath = ctx.functions[name].filePath; let paramLabels = []; for (let i=0; i { if (utils.isDefined(ctx.signals[offset].v)) { constParams.push(prefix + "=" + ctx.F.e(ctx.signals[offset].v)); } }); } } 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; i0) S+=","; S+=value2str(F, v[i]); } S+="]"; return S; } else { return F.toString(F.e(v)); } }