Add Verifier Groth16 compatible with circom

This commit is contained in:
arnaucube
2020-04-08 11:26:01 +02:00
parent 2a18bbd5fe
commit 0e453eb1ff
5 changed files with 79 additions and 25 deletions

View File

@@ -45,11 +45,11 @@ type ProofString struct {
// VkString is the Verification Key data structure in string format (from json) // VkString is the Verification Key data structure in string format (from json)
type VkString struct { type VkString struct {
Alpha []string `json:"vk_alfa_1"` Alpha []string `json:"vk_alfa_1"`
Beta [][]string `json:"vk_beta_2"` Beta [][]string `json:"vk_beta_2"`
Gamma [][]string `json:"vk_gamma_2"` Gamma [][]string `json:"vk_gamma_2"`
Delta [][]string `json:"vk_delta_2"` Delta [][]string `json:"vk_delta_2"`
GammaABC [][]string `json:"IC"` IC [][]string `json:"IC"`
} }
// ParseWitness parses the json []byte data into the Witness struct // ParseWitness parses the json []byte data into the Witness struct
@@ -236,12 +236,12 @@ func vkStringToVk(vr VkString) (*Vk, error) {
return nil, err return nil, err
} }
for i := 0; i < len(vr.GammaABC); i++ { for i := 0; i < len(vr.IC); i++ {
p, err := stringToG1(vr.GammaABC[i]) p, err := stringToG1(vr.IC[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
v.GammaABC = append(v.GammaABC, p) v.IC = append(v.IC, p)
} }
return &v, nil return &v, nil

View File

@@ -14,8 +14,8 @@ type Proof struct {
C *bn256.G1 C *bn256.G1
} }
// ProvingKey holds the data structure of the provingKey // Pk holds the data structure of the ProvingKey
type ProvingKey struct { type Pk struct {
A []*bn256.G1 A []*bn256.G1
B2 []*bn256.G2 B2 []*bn256.G2
B1 []*bn256.G1 B1 []*bn256.G1
@@ -54,7 +54,7 @@ func randBigInt() (*big.Int, error) {
} }
// GenerateProof generates the Groth16 zkSNARK proof // 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 var proof Proof
r, err := randBigInt() r, err := randBigInt()
@@ -105,7 +105,7 @@ func GenerateProof(pk *ProvingKey, w Witness) (*Proof, []*big.Int, error) {
return &proof, pubSignals, nil return &proof, pubSignals, nil
} }
func calculateH(pk *ProvingKey, w Witness) []*big.Int { func calculateH(pk *Pk, w Witness) []*big.Int {
m := pk.DomainSize m := pk.DomainSize
polAT := arrayOfZeroes(m) polAT := arrayOfZeroes(m)
polBT := arrayOfZeroes(m) polBT := arrayOfZeroes(m)

View File

@@ -2,7 +2,6 @@ package gocircomprover
import ( import (
"encoding/json" "encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"math/big" "math/big"
"testing" "testing"
@@ -14,13 +13,9 @@ import (
func TestSmallCircuitGenerateProf(t *testing.T) { func TestSmallCircuitGenerateProf(t *testing.T) {
provingKeyJson, err := ioutil.ReadFile("testdata/small/proving_key.json") provingKeyJson, err := ioutil.ReadFile("testdata/small/proving_key.json")
require.Nil(t, err) require.Nil(t, err)
pk, err := ParseProvingKey(provingKeyJson) pk, err := ParsePk(provingKeyJson)
require.Nil(t, err) 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") witnessJson, err := ioutil.ReadFile("testdata/small/witness.json")
require.Nil(t, err) require.Nil(t, err)
w, err := ParseWitness(witnessJson) w, err := ParseWitness(witnessJson)
@@ -30,12 +25,9 @@ func TestSmallCircuitGenerateProf(t *testing.T) {
proof, pubSignals, err := GenerateProof(pk, w) proof, pubSignals, err := GenerateProof(pk, w)
assert.Nil(t, err) assert.Nil(t, err)
fmt.Println("proof", proof)
fmt.Println("pubSignals", pubSignals)
proofStr, err := ProofToJson(proof) proofStr, err := ProofToJson(proof)
assert.Nil(t, err) assert.Nil(t, err)
fmt.Println("prover\n", string(proofStr))
err = ioutil.WriteFile("testdata/small/proof.json", proofStr, 0644) err = ioutil.WriteFile("testdata/small/proof.json", proofStr, 0644)
assert.Nil(t, err) assert.Nil(t, err)
@@ -51,7 +43,7 @@ func TestSmallCircuitGenerateProf(t *testing.T) {
func TestBigCircuitGenerateProf(t *testing.T) { func TestBigCircuitGenerateProf(t *testing.T) {
provingKeyJson, err := ioutil.ReadFile("testdata/big/proving_key.json") provingKeyJson, err := ioutil.ReadFile("testdata/big/proving_key.json")
require.Nil(t, err) require.Nil(t, err)
pk, err := ParseProvingKey(provingKeyJson) pk, err := ParsePk(provingKeyJson)
require.Nil(t, err) require.Nil(t, err)
witnessJson, err := ioutil.ReadFile("testdata/big/witness.json") witnessJson, err := ioutil.ReadFile("testdata/big/witness.json")
@@ -61,12 +53,9 @@ func TestBigCircuitGenerateProf(t *testing.T) {
proof, pubSignals, err := GenerateProof(pk, w) proof, pubSignals, err := GenerateProof(pk, w)
assert.Nil(t, err) assert.Nil(t, err)
fmt.Println("proof", proof)
fmt.Println("pubSignals", pubSignals)
proofStr, err := ProofToJson(proof) proofStr, err := ProofToJson(proof)
assert.Nil(t, err) assert.Nil(t, err)
fmt.Println("prover\n", string(proofStr))
err = ioutil.WriteFile("testdata/big/proof.json", proofStr, 0644) err = ioutil.WriteFile("testdata/big/proof.json", proofStr, 0644)
assert.Nil(t, err) assert.Nil(t, err)

37
verifier.go Normal file
View File

@@ -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)
}

28
verifier_test.go Normal file
View File

@@ -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)
}