mirror of
https://github.com/arnaucube/go-circom-prover-verifier.git
synced 2026-02-06 19:06:43 +01:00
Add Verifier Groth16 compatible with circom
This commit is contained in:
16
parsers.go
16
parsers.go
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
37
verifier.go
Normal 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
28
verifier_test.go
Normal 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)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user