diff --git a/src/circom/circuit.rs b/src/circom/circuit.rs index 32a0466..05c4b33 100644 --- a/src/circom/circuit.rs +++ b/src/circom/circuit.rs @@ -96,7 +96,7 @@ mod tests { #[tokio::test] async fn satisfied() { let cfg = CircomConfig::::new( - "./test-vectors/mycircuit.wasm", + "./test-vectors/mycircuit_js/mycircuit.wasm", "./test-vectors/mycircuit.r1cs", ) .unwrap(); diff --git a/src/witness/witness_calculator.rs b/src/witness/witness_calculator.rs index 009702a..17078bc 100644 --- a/src/witness/witness_calculator.rs +++ b/src/witness/witness_calculator.rs @@ -268,7 +268,7 @@ mod tests { #[tokio::test] async fn multiplier_1() { run_test(TestCase { - circuit_path: root_path("test-vectors/mycircuit.wasm").as_str(), + circuit_path: root_path("test-vectors/mycircuit_js/mycircuit.wasm").as_str(), inputs_path: root_path("test-vectors/mycircuit-input1.json").as_str(), n64: 4, witness: &["1", "33", "3", "11"], @@ -278,7 +278,7 @@ mod tests { #[tokio::test] async fn multiplier_2() { run_test(TestCase { - circuit_path: root_path("test-vectors/mycircuit.wasm").as_str(), + circuit_path: root_path("test-vectors/mycircuit_js/mycircuit.wasm").as_str(), inputs_path: root_path("test-vectors/mycircuit-input2.json").as_str(), n64: 4, witness: &[ @@ -293,7 +293,7 @@ mod tests { #[tokio::test] async fn multiplier_3() { run_test(TestCase { - circuit_path: root_path("test-vectors/mycircuit.wasm").as_str(), + circuit_path: root_path("test-vectors/mycircuit_js/mycircuit.wasm").as_str(), inputs_path: root_path("test-vectors/mycircuit-input3.json").as_str(), n64: 4, witness: &[ diff --git a/test-vectors/calculatewitness.js b/test-vectors/calculatewitness.js deleted file mode 100755 index d562d27..0000000 --- a/test-vectors/calculatewitness.js +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env node - -const fs = require("fs"); -const {stringifyBigInts, unstringifyBigInts} = require("snarkjs"); -const WitnessCalculatorBuilder = require("./witness_calculator.js"); - -// const wasmName = "smtverifier10.wasm" -// const inputName = "smtverifier10-input.json" - -const wasmName = "nconstraints.wasm" -const inputName = "nconstraints-input.json" - -async function run () { - const wasm = await fs.promises.readFile(wasmName); - const input = unstringifyBigInts(JSON.parse(await fs.promises.readFile(inputName, "utf8"))); - - console.log("input:", input); - let options; - const wc = await WitnessCalculatorBuilder(wasm, options); - - const w = await wc.calculateWitness(input); - - console.log("witness:\n", JSON.stringify(stringifyBigInts(w))); - - // const wb = await wc.calculateBinWitness(input); - - // console.log("witnessBin:", Buffer.from(wb).toString('hex')); - - // await fs.promises.writeFile(witnessName, JSON.stringify(stringifyBigInts(w), null, 1)); - -} - -run().then(() => { - process.exit(); -}); diff --git a/test-vectors/circom2_multiplier2.r1cs b/test-vectors/circom2_multiplier2.r1cs deleted file mode 100644 index e61b9b0..0000000 Binary files a/test-vectors/circom2_multiplier2.r1cs and /dev/null differ diff --git a/test-vectors/circom2_multiplier2.wasm b/test-vectors/circom2_multiplier2.wasm deleted file mode 100644 index 7ea487c..0000000 Binary files a/test-vectors/circom2_multiplier2.wasm and /dev/null differ diff --git a/test-vectors/circuit2.r1cs b/test-vectors/circuit2.r1cs new file mode 100644 index 0000000..cb3fbdf Binary files /dev/null and b/test-vectors/circuit2.r1cs differ diff --git a/test-vectors/circuit2.wasm b/test-vectors/circuit2_js/circuit2.wasm similarity index 100% rename from test-vectors/circuit2.wasm rename to test-vectors/circuit2_js/circuit2.wasm diff --git a/test-vectors/circuit2_js/generate_witness.js b/test-vectors/circuit2_js/generate_witness.js new file mode 100644 index 0000000..eabb86e --- /dev/null +++ b/test-vectors/circuit2_js/generate_witness.js @@ -0,0 +1,20 @@ +const wc = require("./witness_calculator.js"); +const { readFileSync, writeFile } = require("fs"); + +if (process.argv.length != 5) { + console.log("Usage: node generate_witness.js "); +} else { + const input = JSON.parse(readFileSync(process.argv[3], "utf8")); + + const buffer = readFileSync(process.argv[2]); + wc(buffer).then(async witnessCalculator => { + // const w= await witnessCalculator.calculateWitness(input,0); + // for (let i=0; i< w.length; i++){ + // console.log(w[i]); + // } + const buff= await witnessCalculator.calculateWTNSBin(input,0); + writeFile(process.argv[4], buff, function(err) { + if (err) throw err; + }); + }); +} diff --git a/test-vectors/circuit2_js/witness.wtns b/test-vectors/circuit2_js/witness.wtns new file mode 100644 index 0000000..d9dce5d Binary files /dev/null and b/test-vectors/circuit2_js/witness.wtns differ diff --git a/test-vectors/circuit2_js/witness_calculator.js b/test-vectors/circuit2_js/witness_calculator.js new file mode 100644 index 0000000..20e6e20 --- /dev/null +++ b/test-vectors/circuit2_js/witness_calculator.js @@ -0,0 +1,337 @@ +module.exports = async function builder(code, options) { + + options = options || {}; + + let wasmModule; + try { + wasmModule = await WebAssembly.compile(code); + } catch (err) { + console.log(err); + console.log("\nTry to run circom --c in order to generate c++ code instead\n"); + throw new Error(err); + } + + let wc; + + let errStr = ""; + let msgStr = ""; + + const instance = await WebAssembly.instantiate(wasmModule, { + runtime: { + exceptionHandler : function(code) { + let err; + if (code == 1) { + err = "Signal not found.\n"; + } else if (code == 2) { + err = "Too many signals set.\n"; + } else if (code == 3) { + err = "Signal already set.\n"; + } else if (code == 4) { + err = "Assert Failed.\n"; + } else if (code == 5) { + err = "Not enough memory.\n"; + } else if (code == 6) { + err = "Input signal array access exceeds the size.\n"; + } else { + err = "Unknown error.\n"; + } + throw new Error(err + errStr); + }, + printErrorMessage : function() { + errStr += getMessage() + "\n"; + // console.error(getMessage()); + }, + writeBufferMessage : function() { + const msg = getMessage(); + // Any calls to `log()` will always end with a `\n`, so that's when we print and reset + if (msg === "\n") { + console.log(msgStr); + msgStr = ""; + } else { + // If we've buffered other content, put a space in between the items + if (msgStr !== "") { + msgStr += " " + } + // Then append the message to the message we are creating + msgStr += msg; + } + }, + showSharedRWMemory : function() { + printSharedRWMemory (); + } + + } + }); + + const sanityCheck = + options +// options && +// ( +// options.sanityCheck || +// options.logGetSignal || +// options.logSetSignal || +// options.logStartComponent || +// options.logFinishComponent +// ); + + + wc = new WitnessCalculator(instance, sanityCheck); + return wc; + + function getMessage() { + var message = ""; + var c = instance.exports.getMessageChar(); + while ( c != 0 ) { + message += String.fromCharCode(c); + c = instance.exports.getMessageChar(); + } + return message; + } + + function printSharedRWMemory () { + const shared_rw_memory_size = instance.exports.getFieldNumLen32(); + const arr = new Uint32Array(shared_rw_memory_size); + for (let j=0; j { + const h = fnvHash(k); + const hMSB = parseInt(h.slice(0,8), 16); + const hLSB = parseInt(h.slice(8,16), 16); + const fArr = flatArray(input[k]); + let signalSize = this.instance.exports.getInputSignalSize(hMSB, hLSB); + if (signalSize < 0){ + throw new Error(`Signal ${k} not found\n`); + } + if (fArr.length < signalSize) { + throw new Error(`Not enough values for input signal ${k}\n`); + } + if (fArr.length > signalSize) { + throw new Error(`Too many values for input signal ${k}\n`); + } + for (let i=0; i0) { + res.unshift(0); + i--; + } + } + return res; +} + +function fromArray32(arr) { //returns a BigInt + var res = BigInt(0); + const radix = BigInt(0x100000000); + for (let i = 0; i "); +} else { + const input = JSON.parse(readFileSync(process.argv[3], "utf8")); + + const buffer = readFileSync(process.argv[2]); + wc(buffer).then(async witnessCalculator => { + // const w= await witnessCalculator.calculateWitness(input,0); + // for (let i=0; i< w.length; i++){ + // console.log(w[i]); + // } + const buff= await witnessCalculator.calculateWTNSBin(input,0); + writeFile(process.argv[4], buff, function(err) { + if (err) throw err; + }); + }); +} diff --git a/test-vectors/mycircuit.wasm b/test-vectors/mycircuit_js/mycircuit.wasm similarity index 100% rename from test-vectors/mycircuit.wasm rename to test-vectors/mycircuit_js/mycircuit.wasm diff --git a/test-vectors/mycircuit_js/witness_calculator.js b/test-vectors/mycircuit_js/witness_calculator.js new file mode 100644 index 0000000..20e6e20 --- /dev/null +++ b/test-vectors/mycircuit_js/witness_calculator.js @@ -0,0 +1,337 @@ +module.exports = async function builder(code, options) { + + options = options || {}; + + let wasmModule; + try { + wasmModule = await WebAssembly.compile(code); + } catch (err) { + console.log(err); + console.log("\nTry to run circom --c in order to generate c++ code instead\n"); + throw new Error(err); + } + + let wc; + + let errStr = ""; + let msgStr = ""; + + const instance = await WebAssembly.instantiate(wasmModule, { + runtime: { + exceptionHandler : function(code) { + let err; + if (code == 1) { + err = "Signal not found.\n"; + } else if (code == 2) { + err = "Too many signals set.\n"; + } else if (code == 3) { + err = "Signal already set.\n"; + } else if (code == 4) { + err = "Assert Failed.\n"; + } else if (code == 5) { + err = "Not enough memory.\n"; + } else if (code == 6) { + err = "Input signal array access exceeds the size.\n"; + } else { + err = "Unknown error.\n"; + } + throw new Error(err + errStr); + }, + printErrorMessage : function() { + errStr += getMessage() + "\n"; + // console.error(getMessage()); + }, + writeBufferMessage : function() { + const msg = getMessage(); + // Any calls to `log()` will always end with a `\n`, so that's when we print and reset + if (msg === "\n") { + console.log(msgStr); + msgStr = ""; + } else { + // If we've buffered other content, put a space in between the items + if (msgStr !== "") { + msgStr += " " + } + // Then append the message to the message we are creating + msgStr += msg; + } + }, + showSharedRWMemory : function() { + printSharedRWMemory (); + } + + } + }); + + const sanityCheck = + options +// options && +// ( +// options.sanityCheck || +// options.logGetSignal || +// options.logSetSignal || +// options.logStartComponent || +// options.logFinishComponent +// ); + + + wc = new WitnessCalculator(instance, sanityCheck); + return wc; + + function getMessage() { + var message = ""; + var c = instance.exports.getMessageChar(); + while ( c != 0 ) { + message += String.fromCharCode(c); + c = instance.exports.getMessageChar(); + } + return message; + } + + function printSharedRWMemory () { + const shared_rw_memory_size = instance.exports.getFieldNumLen32(); + const arr = new Uint32Array(shared_rw_memory_size); + for (let j=0; j { + const h = fnvHash(k); + const hMSB = parseInt(h.slice(0,8), 16); + const hLSB = parseInt(h.slice(8,16), 16); + const fArr = flatArray(input[k]); + let signalSize = this.instance.exports.getInputSignalSize(hMSB, hLSB); + if (signalSize < 0){ + throw new Error(`Signal ${k} not found\n`); + } + if (fArr.length < signalSize) { + throw new Error(`Not enough values for input signal ${k}\n`); + } + if (fArr.length > signalSize) { + throw new Error(`Too many values for input signal ${k}\n`); + } + for (let i=0; i0) { + res.unshift(0); + i--; + } + } + return res; +} + +function fromArray32(arr) { //returns a BigInt + var res = BigInt(0); + const radix = BigInt(0x100000000); + for (let i = 0; i Result<()> { #[tokio::test] async fn groth16_proof_circom() -> Result<()> { let cfg = CircomConfig::::new( - "./test-vectors/circom2_multiplier2.wasm", - "./test-vectors/circom2_multiplier2.r1cs", + "test-vectors/circuit2_js/circuit2.wasm", + "test-vectors/circuit2.r1cs", )?; let mut builder = CircomBuilder::new(cfg); builder.push_input("a", 3); @@ -106,8 +106,8 @@ async fn groth16_proof_circom() -> Result<()> { #[tokio::test] async fn witness_generation_circom() -> Result<()> { let cfg = CircomConfig::::new( - "./test-vectors/circom2_multiplier2.wasm", - "./test-vectors/circom2_multiplier2.r1cs", + "test-vectors/circuit2_js/circuit2.wasm", + "test-vectors/circuit2.r1cs", )?; let mut builder = CircomBuilder::new(cfg); builder.push_input("a", 3); diff --git a/tests/solidity.rs b/tests/solidity.rs index c183709..244557b 100644 --- a/tests/solidity.rs +++ b/tests/solidity.rs @@ -17,7 +17,7 @@ use std::{convert::TryFrom, sync::Arc}; #[tokio::test] async fn solidity_verifier() -> Result<()> { let cfg = CircomConfig::::new( - "./test-vectors/mycircuit.wasm", + "./test-vectors/mycircuit_js/mycircuit.wasm", "./test-vectors/mycircuit.r1cs", )?; let mut builder = CircomBuilder::new(cfg);