diff --git a/parsers.go b/parsers.go index c757ef3..44c6e49 100644 --- a/parsers.go +++ b/parsers.go @@ -45,11 +45,11 @@ type ProofString struct { // VkString is the Verification Key data structure in string format (from json) type VkString struct { - Alpha []string `json:"vk_alfa_1"` - Beta [][]string `json:"vk_beta_2"` - Gamma [][]string `json:"vk_gamma_2"` - Delta [][]string `json:"vk_delta_2"` - GammaABC [][]string `json:"IC"` + Alpha []string `json:"vk_alfa_1"` + Beta [][]string `json:"vk_beta_2"` + Gamma [][]string `json:"vk_gamma_2"` + Delta [][]string `json:"vk_delta_2"` + IC [][]string `json:"IC"` } // ParseWitness parses the json []byte data into the Witness struct @@ -236,12 +236,12 @@ func vkStringToVk(vr VkString) (*Vk, error) { return nil, err } - for i := 0; i < len(vr.GammaABC); i++ { - p, err := stringToG1(vr.GammaABC[i]) + for i := 0; i < len(vr.IC); i++ { + p, err := stringToG1(vr.IC[i]) if err != nil { return nil, err } - v.GammaABC = append(v.GammaABC, p) + v.IC = append(v.IC, p) } return &v, nil diff --git a/prover.go b/prover.go index 8d97328..8c1edfd 100644 --- a/prover.go +++ b/prover.go @@ -14,8 +14,8 @@ type Proof struct { C *bn256.G1 } -// ProvingKey holds the data structure of the provingKey -type ProvingKey struct { +// Pk holds the data structure of the ProvingKey +type Pk struct { A []*bn256.G1 B2 []*bn256.G2 B1 []*bn256.G1 @@ -54,7 +54,7 @@ func randBigInt() (*big.Int, error) { } // GenerateProof generates the Groth16 zkSNARK proof -func GenerateProof(pk *ProvingKey, w Witness) (*Proof, []*big.Int, error) { +func GenerateProof(pk *Pk, w Witness) (*Proof, []*big.Int, error) { var proof Proof r, err := randBigInt() @@ -105,7 +105,7 @@ func GenerateProof(pk *ProvingKey, w Witness) (*Proof, []*big.Int, error) { return &proof, pubSignals, nil } -func calculateH(pk *ProvingKey, w Witness) []*big.Int { +func calculateH(pk *Pk, w Witness) []*big.Int { m := pk.DomainSize polAT := arrayOfZeroes(m) polBT := arrayOfZeroes(m) diff --git a/prover_test.go b/prover_test.go index 2bd4c64..136052c 100644 --- a/prover_test.go +++ b/prover_test.go @@ -2,7 +2,6 @@ package gocircomprover import ( "encoding/json" - "fmt" "io/ioutil" "math/big" "testing" @@ -14,13 +13,9 @@ import ( func TestSmallCircuitGenerateProf(t *testing.T) { provingKeyJson, err := ioutil.ReadFile("testdata/small/proving_key.json") require.Nil(t, err) - pk, err := ParseProvingKey(provingKeyJson) + pk, err := ParsePk(provingKeyJson) require.Nil(t, err) - fmt.Println("polsA", pk.PolsA) - fmt.Println("polsB", pk.PolsB) - fmt.Println("polsC", pk.PolsC) - witnessJson, err := ioutil.ReadFile("testdata/small/witness.json") require.Nil(t, err) w, err := ParseWitness(witnessJson) @@ -30,12 +25,9 @@ func TestSmallCircuitGenerateProf(t *testing.T) { proof, pubSignals, err := GenerateProof(pk, w) assert.Nil(t, err) - fmt.Println("proof", proof) - fmt.Println("pubSignals", pubSignals) proofStr, err := ProofToJson(proof) assert.Nil(t, err) - fmt.Println("prover\n", string(proofStr)) err = ioutil.WriteFile("testdata/small/proof.json", proofStr, 0644) assert.Nil(t, err) @@ -51,7 +43,7 @@ func TestSmallCircuitGenerateProf(t *testing.T) { func TestBigCircuitGenerateProf(t *testing.T) { provingKeyJson, err := ioutil.ReadFile("testdata/big/proving_key.json") require.Nil(t, err) - pk, err := ParseProvingKey(provingKeyJson) + pk, err := ParsePk(provingKeyJson) require.Nil(t, err) witnessJson, err := ioutil.ReadFile("testdata/big/witness.json") @@ -61,12 +53,9 @@ func TestBigCircuitGenerateProf(t *testing.T) { proof, pubSignals, err := GenerateProof(pk, w) assert.Nil(t, err) - fmt.Println("proof", proof) - fmt.Println("pubSignals", pubSignals) proofStr, err := ProofToJson(proof) assert.Nil(t, err) - fmt.Println("prover\n", string(proofStr)) err = ioutil.WriteFile("testdata/big/proof.json", proofStr, 0644) assert.Nil(t, err) diff --git a/verifier.go b/verifier.go new file mode 100644 index 0000000..280877c --- /dev/null +++ b/verifier.go @@ -0,0 +1,37 @@ +package gocircomprover + +import ( + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/crypto/bn256" +) + +// Vk is the Verification Key data structure +type Vk struct { + Alpha *bn256.G1 + Beta *bn256.G2 + Gamma *bn256.G2 + Delta *bn256.G2 + IC []*bn256.G1 +} + +func Verify(vk *Vk, proof *Proof, inputs []*big.Int) bool { + if len(inputs)+1 != len(vk.IC) { + fmt.Println("len(inputs)+1 != len(vk.IC)") + return false + } + vkX := new(bn256.G1).ScalarBaseMult(big.NewInt(0)) + for i := 0; i < len(inputs); i++ { + // check input inside field + if inputs[0].Cmp(R) != -1 { + return false + } + vkX = new(bn256.G1).Add(vkX, new(bn256.G1).ScalarMult(vk.IC[i+1], inputs[i])) + } + vkX = new(bn256.G1).Add(vkX, vk.IC[0]) + + g1 := []*bn256.G1{proof.A, vk.Alpha.Neg(vk.Alpha), vkX.Neg(vkX), proof.C.Neg(proof.C)} + g2 := []*bn256.G2{proof.B, vk.Beta, vk.Gamma, vk.Delta} + return bn256.PairingCheck(g1, g2) +} diff --git a/verifier_test.go b/verifier_test.go new file mode 100644 index 0000000..cd80a75 --- /dev/null +++ b/verifier_test.go @@ -0,0 +1,28 @@ +package gocircomprover + +import ( + "io/ioutil" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestVerify1(t *testing.T) { + proofJson, err := ioutil.ReadFile("testdata/big/proof.json") + require.Nil(t, err) + vkJson, err := ioutil.ReadFile("testdata/big/verification_key.json") + require.Nil(t, err) + publicJson, err := ioutil.ReadFile("testdata/big/public.json") + require.Nil(t, err) + + public, err := ParsePublicSignals(publicJson) + require.Nil(t, err) + proof, err := ParseProof(proofJson) + require.Nil(t, err) + vk, err := ParseVk(vkJson) + require.Nil(t, err) + + v := Verify(vk, proof, public) + assert.True(t, v) +}