arnaucube
arnaucube/go-circom-prover-verifierPublic Self-hosted repository
Refactor circuits, update prover & verifier tests
arnaucube root@arnaucube.com
Sun, 26 Apr 2020 21:22:56 +0200
commit

d3f43ce1a0b59d9eb3f66222104694bbe4cf50ba

parent

5b77df54b7df9b16d20e2235523b87f007005f7a

M .github/workflows/main.yml → .github/workflows/main.yml

@@ -26,7 +26,7 @@ - name: Checkout code

uses: actions/checkout@v2 - name: Compile circuits and execute Go tests run: | - sh ./compile-circuits.sh - go run cli/cli.go -prove -provingkey=testdata/small/proving_key.json -witness=testdata/small/witness.json -proof=testdata/small/proof.json -public=testdata/small/public.json - go run cli/cli.go -prove -provingkey=testdata/big/proving_key.json -witness=testdata/big/witness.json -proof=testdata/big/proof.json -public=testdata/big/public.json + cd testdata && sh ./compile-circuits.sh && cd .. + go run cli/cli.go -prove -provingkey=testdata/circuit1k/proving_key.json -witness=testdata/circuit1k/witness.json -proof=testdata/circuit1k/proof.json -public=testdata/circuit1k/public.json + go run cli/cli.go -prove -provingkey=testdata/circuit5k/proving_key.json -witness=testdata/circuit5k/witness.json -proof=testdata/circuit5k/proof.json -public=testdata/circuit5k/public.json go test ./...
M .gitignore → .gitignore

@@ -4,5 +4,5 @@ testdata/*/*.cpp

testdata/*/*.sym testdata/*/*.r1cs testdata/*/*.sol -!testdata/*/input.json +!testdata/*/inputs.json cli/*.json
D compile-circuits.sh

@@ -1,21 +0,0 @@

-#!/bin/sh - -echo "testdata/small/circuit.circom" -cd testdata/small -echo "compiling circuit" -circom circuit.circom -r1cs --wasm --sym -echo "generating setup" -snarkjs setup -sed -i 's/null/["0","0","0"]/g' proving_key.json -echo "calculating witness" -snarkjs calculatewitness --wasm circuit.wasm --input input.json --witness witness.json - -echo "\ntestdata/big/circuit.circom" -cd ../big -echo "compiling circuit" -circom circuit.circom -r1cs --wasm --sym -echo "generating setup" -snarkjs setup -sed -i 's/null/["0","0","0"]/g' proving_key.json -echo "calculating witness" -snarkjs calculatewitness --wasm circuit.wasm --input input.json --witness witness.json
M prover/prover_test.go → prover/prover_test.go

@@ -4,65 +4,29 @@ import (

"encoding/json" "fmt" "io/ioutil" - "math/big" "testing" "time" "github.com/iden3/go-circom-prover-verifier/parsers" - "github.com/iden3/go-circom-prover-verifier/types" "github.com/iden3/go-circom-prover-verifier/verifier" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) -func TestSmallCircuitGenerateProof(t *testing.T) { - provingKeyJson, err := ioutil.ReadFile("../testdata/small/proving_key.json") - require.Nil(t, err) - pk, err := parsers.ParsePk(provingKeyJson) - require.Nil(t, err) - - witnessJson, err := ioutil.ReadFile("../testdata/small/witness.json") - require.Nil(t, err) - w, err := parsers.ParseWitness(witnessJson) - require.Nil(t, err) - - assert.Equal(t, types.Witness{big.NewInt(1), big.NewInt(33), big.NewInt(3), big.NewInt(11)}, w) - - beforeT := time.Now() - proof, pubSignals, err := GenerateProof(pk, w) - assert.Nil(t, err) - fmt.Println("proof generation time elapsed:", time.Since(beforeT)) - - proofStr, err := parsers.ProofToJson(proof) - assert.Nil(t, err) - - err = ioutil.WriteFile("../testdata/small/proof.json", proofStr, 0644) - assert.Nil(t, err) - publicStr, err := json.Marshal(parsers.ArrayBigIntToString(pubSignals)) - assert.Nil(t, err) - err = ioutil.WriteFile("../testdata/small/public.json", publicStr, 0644) - assert.Nil(t, err) - - // verify the proof - vkJson, err := ioutil.ReadFile("../testdata/small/verification_key.json") - require.Nil(t, err) - vk, err := parsers.ParseVk(vkJson) - require.Nil(t, err) - - v := verifier.Verify(vk, proof, pubSignals) - assert.True(t, v) - - // to verify the proof with snarkjs: - // snarkjs verify --vk testdata/small/verification_key.json -p testdata/small/proof.json --pub testdata/small/public.json +func TestCircuitsGenerateProof(t *testing.T) { + testCircuitGenerateProof(t, "circuit1k") // 1000 constraints + testCircuitGenerateProof(t, "circuit5k") // 5000 constraints + // testCircuitGenerateProof(t, "circuit10k") // 10000 constraints + // testCircuitGenerateProof(t, "circuit20k") // 20000 constraints } -func TestBigCircuitGenerateProof(t *testing.T) { - provingKeyJson, err := ioutil.ReadFile("../testdata/big/proving_key.json") +func testCircuitGenerateProof(t *testing.T, circuit string) { + provingKeyJson, err := ioutil.ReadFile("../testdata/" + circuit + "/proving_key.json") require.Nil(t, err) pk, err := parsers.ParsePk(provingKeyJson) require.Nil(t, err) - witnessJson, err := ioutil.ReadFile("../testdata/big/witness.json") + witnessJson, err := ioutil.ReadFile("../testdata/" + circuit + "/witness.json") require.Nil(t, err) w, err := parsers.ParseWitness(witnessJson) require.Nil(t, err)

@@ -75,15 +39,15 @@

proofStr, err := parsers.ProofToJson(proof) assert.Nil(t, err) - err = ioutil.WriteFile("../testdata/big/proof.json", proofStr, 0644) + err = ioutil.WriteFile("../testdata/"+circuit+"/proof.json", proofStr, 0644) assert.Nil(t, err) publicStr, err := json.Marshal(parsers.ArrayBigIntToString(pubSignals)) assert.Nil(t, err) - err = ioutil.WriteFile("../testdata/big/public.json", publicStr, 0644) + err = ioutil.WriteFile("../testdata/"+circuit+"/public.json", publicStr, 0644) assert.Nil(t, err) // verify the proof - vkJson, err := ioutil.ReadFile("../testdata/big/verification_key.json") + vkJson, err := ioutil.ReadFile("../testdata/" + circuit + "/verification_key.json") require.Nil(t, err) vk, err := parsers.ParseVk(vkJson) require.Nil(t, err)

@@ -92,62 +56,17 @@ v := verifier.Verify(vk, proof, pubSignals)

assert.True(t, v) // to verify the proof with snarkjs: - // snarkjs verify --vk testdata/big/verification_key.json -p testdata/big/proof.json --pub testdata/big/public.json -} - -func TestIdStateCircuitGenerateProof(t *testing.T) { - // this test is to execute the proof generation for a bigger circuit - // (arround 22500 constraints) - // - // to see the time needed to execute this - // test Will need the ../testdata/idstate-circuit compiled & - // trustedsetup files (generated in - // https://github.com/iden3/go-zksnark-full-flow-example) - if false { - fmt.Println("\nTestIdStateCircuitGenerateProof activated") - provingKeyJson, err := ioutil.ReadFile("../testdata/idstate-circuit/proving_key.json") - require.Nil(t, err) - pk, err := parsers.ParsePk(provingKeyJson) - require.Nil(t, err) - - witnessJson, err := ioutil.ReadFile("../testdata/idstate-circuit/witness.json") - require.Nil(t, err) - w, err := parsers.ParseWitness(witnessJson) - require.Nil(t, err) - - beforeT := time.Now() - proof, pubSignals, err := GenerateProof(pk, w) - assert.Nil(t, err) - fmt.Println("proof generation time elapsed:", time.Since(beforeT)) - - proofStr, err := parsers.ProofToJson(proof) - assert.Nil(t, err) - - err = ioutil.WriteFile("../testdata/idstate-circuit/proof.json", proofStr, 0644) - assert.Nil(t, err) - publicStr, err := json.Marshal(parsers.ArrayBigIntToString(pubSignals)) - assert.Nil(t, err) - err = ioutil.WriteFile("../testdata/idstate-circuit/public.json", publicStr, 0644) - assert.Nil(t, err) - - // verify the proof - vkJson, err := ioutil.ReadFile("../testdata/idstate-circuit/verification_key.json") - require.Nil(t, err) - vk, err := parsers.ParseVk(vkJson) - require.Nil(t, err) - - v := verifier.Verify(vk, proof, pubSignals) - assert.True(t, v) - } + // snarkjs verify --vk testdata/circuitX/verification_key.json -p testdata/circuitX/proof.json --pub testdata/circuitX/public.json } func BenchmarkGenerateProof(b *testing.B) { - provingKeyJson, err := ioutil.ReadFile("../testdata/big/proving_key.json") + // benchmark with a circuit of 10000 constraints + provingKeyJson, err := ioutil.ReadFile("../testdata/circuit1/proving_key.json") require.Nil(b, err) pk, err := parsers.ParsePk(provingKeyJson) require.Nil(b, err) - witnessJson, err := ioutil.ReadFile("../testdata/big/witness.json") + witnessJson, err := ioutil.ReadFile("../testdata/circuit1/witness.json") require.Nil(b, err) w, err := parsers.ParseWitness(witnessJson) require.Nil(b, err)
M testdata/big/circuit.circom → testdata/circuit20k/circuit.circom

@@ -1,4 +1,4 @@

-template A(n) { +template TestConstraints(n) { signal input in; signal output out;

@@ -11,4 +11,4 @@ }

out <== intermediate[n-1]; } -component main = A(1000); // bigger takes too much time on generating trusted setup +component main = TestConstraints(20000);
D testdata/big/input.json

@@ -1,1 +0,0 @@

-{ "in": 1}
A testdata/circuit10k/circuit.circom

@@ -0,0 +1,14 @@

+template TestConstraints(n) { + signal input in; + signal output out; + + signal intermediate[n]; + + intermediate[0] <== in; + for (var i=1; i<n; i++) { + intermediate[i] <== intermediate[i-1] * intermediate[i-1] + i; + } + out <== intermediate[n-1]; +} + +component main = TestConstraints(10000);
A testdata/circuit10k/inputs.json

@@ -0,0 +1,1 @@

+{"in":"1"}
A testdata/circuit1k/circuit.circom

@@ -0,0 +1,14 @@

+template TestConstraints(n) { + signal input in; + signal output out; + + signal intermediate[n]; + + intermediate[0] <== in; + for (var i=1; i<n; i++) { + intermediate[i] <== intermediate[i-1] * intermediate[i-1] + i; + } + out <== intermediate[n-1]; +} + +component main = TestConstraints(1000);
A testdata/circuit1k/inputs.json

@@ -0,0 +1,1 @@

+{"in":"1"}
A testdata/circuit20k/inputs.json

@@ -0,0 +1,1 @@

+{"in":"1"}
A testdata/circuit5k/circuit.circom

@@ -0,0 +1,14 @@

+template TestConstraints(n) { + signal input in; + signal output out; + + signal intermediate[n]; + + intermediate[0] <== in; + for (var i=1; i<n; i++) { + intermediate[i] <== intermediate[i-1] * intermediate[i-1] + i; + } + out <== intermediate[n-1]; +} + +component main = TestConstraints(5000);
A testdata/circuit5k/inputs.json

@@ -0,0 +1,1 @@

+{"in":"1"}
A testdata/clean-gereated-files.sh

@@ -0,0 +1,9 @@

+#!/bin/sh + +# rm */*.json +find */*.json -type f -not -name 'inputs.json' -delete +rm */*.wasm +rm */*.cpp +rm */*.sym +rm */*.r1cs +rm */*.sol
A testdata/compile-circuits.sh

@@ -0,0 +1,42 @@

+#!/bin/sh + +compile_and_ts_and_witness() { + echo $(date +"%T") "circom circuit.circom --r1cs --wasm --sym" + itime="$(date -u +%s)" + circom circuit.circom --r1cs --wasm --sym + ftime="$(date -u +%s)" + echo " ($(($(date -u +%s)-$itime))s)" + + echo $(date +"%T") "snarkjs info -r circuit.r1cs" + snarkjs info -r circuit.r1cs + + echo $(date +"%T") "snarkjs setup" + itime="$(date -u +%s)" + snarkjs setup + echo " ($(($(date -u +%s)-$itime))s)" + echo $(date +"%T") "trusted setup generated" + + sed -i 's/null/["0","0","0"]/g' proving_key.json + + echo "calculating witness" + snarkjs calculatewitness --wasm circuit.wasm --input inputs.json --witness witness.json + + echo $(date +"%T") "snarkjs generateverifier" + itime="$(date -u +%s)" + snarkjs generateverifier + echo " ($(($(date -u +%s)-$itime))s)" + echo $(date +"%T") "generateverifier generated" +} + +echo "compile & trustesetup for circuit1k" +cd circuit1k +compile_and_ts_and_witness +echo "compile & trustesetup for circuit5k" +cd ../circuit5k +compile_and_ts_and_witness +# echo "compile & trustesetup for circuit10k" +# cd ../circuit10k +# compile_and_ts_and_witness +# echo "compile & trustesetup for circuit20k" +# cd ../circuit20k +# compile_and_ts_and_witness
D testdata/small/circuit.circom

@@ -1,9 +0,0 @@

-template Multiplier() { - signal private input a; - signal private input b; - signal output c; - - c <== a*b; -} - -component main = Multiplier();
D testdata/small/input.json

@@ -1,1 +0,0 @@

-{ "a":3, "b": 11}
M verifier/verifier_test.go → verifier/verifier_test.go

@@ -10,12 +10,19 @@ "github.com/stretchr/testify/assert"

"github.com/stretchr/testify/require" ) -func TestVerify1(t *testing.T) { - proofJson, err := ioutil.ReadFile("../testdata/big/proof.json") +func TestVerify(t *testing.T) { + testVerifyCircuit(t, "circuit1k") + testVerifyCircuit(t, "circuit5k") + // testVerifyCircuit(t, "circuit10k") + // testVerifyCircuit(t, "circuit20k") +} + +func testVerifyCircuit(t *testing.T, circuit string) { + proofJson, err := ioutil.ReadFile("../testdata/" + circuit + "/proof.json") require.Nil(t, err) - vkJson, err := ioutil.ReadFile("../testdata/big/verification_key.json") + vkJson, err := ioutil.ReadFile("../testdata/" + circuit + "/verification_key.json") require.Nil(t, err) - publicJson, err := ioutil.ReadFile("../testdata/big/public.json") + publicJson, err := ioutil.ReadFile("../testdata/" + circuit + "/public.json") require.Nil(t, err) public, err := parsers.ParsePublicSignals(publicJson)

@@ -34,11 +41,12 @@ assert.True(t, v)

} func BenchmarkVerify(b *testing.B) { - proofJson, err := ioutil.ReadFile("../testdata/big/proof.json") + // benchmark with circuit2 (10000 constraints) + proofJson, err := ioutil.ReadFile("../testdata/circuit2/proof.json") require.Nil(b, err) - vkJson, err := ioutil.ReadFile("../testdata/big/verification_key.json") + vkJson, err := ioutil.ReadFile("../testdata/circuit2/verification_key.json") require.Nil(b, err) - publicJson, err := ioutil.ReadFile("../testdata/big/public.json") + publicJson, err := ioutil.ReadFile("../testdata/circuit2/public.json") require.Nil(b, err) public, err := parsers.ParsePublicSignals(publicJson)