Browse Source

Add Groth16 proof verification

master
arnaucube 4 years ago
parent
commit
b3f1e735a9
6 changed files with 94 additions and 1 deletions
  1. +6
    -0
      testdata/proof1.json
  2. +3
    -0
      testdata/public0.json
  3. +1
    -0
      testdata/public1.json
  4. +1
    -0
      testdata/vk1.json
  5. +25
    -1
      verifier.go
  6. +58
    -0
      verifier_test.go

+ 6
- 0
testdata/proof1.json

@ -0,0 +1,6 @@
{
"a": ["0x1dca74fcf694ed936db05adcdef51b3c2014764e99c5703d5e69d76c87810422","0x2c9ba9c02cf6955ca2c772664df5768a7b0cc77576d7e9b81e095fb3c08b9c16"],
"b": [["0x0aa0f61f43f154d035a48f348789a16f5d4005f76467691f974a8a2e8edb1742","0x026e7e1392d435dd3e73ea37add798405d5cd48f8721f9573c12a2c51258ec8b"],["0x303d397f66efd9dce45e5de04637b106870a7e057d183184939bd44fab28a431","0x257512bdc1bba713498a5981ccc2d5bb833a8cc6e5981e3d71a37fbac31e8b0b"]],
"c": ["0x07a8feff8de7347c93685684dd4e8854fc02a64b221602f6b0afe9b5bf6e1e01","0x258e96099adc2ba4411009449e714eaf112a4fe6afefdb85ff06c36db83adb43"],
"public": ["6"]
}

+ 3
- 0
testdata/public0.json

@ -0,0 +1,3 @@
[
"6"
]

+ 1
- 0
testdata/public1.json

@ -0,0 +1 @@
["6"]

+ 1
- 0
testdata/vk1.json

@ -0,0 +1 @@
{"alpha_g1":["0x1cf86a02b7de239051e6c51ceeef1d8a5d2089e9a2f7cbc5c6074f5fd2b0d777","0x041778937c8a6268ddc1b4eb4912f9edb017e22d8701f91b053d7b05c2f1471a"],"beta_g1":["0x154706ec1e025b39e8bfb4d1d223df46ed7b7458e1575c075f3c9501c6c2115e","0x2b80a63d18b3f22b729d86c8f1bf49a374b0871d5342f8fc1eabea301222f224"],"beta_g2":[["0x2039525c2c75b0c369bbd397481e8321ab82ee611c0ecde9ad64501395b65bb6","0x20d752b48b87705ee8e036a1c21afc80ce1fbf08fc61eb54fe840f0bc2d28704"],["0x17e4c8fb30585247872275e139da64316745190ffcd123a90484a85502d27c5f","0x04ad1008299254713101063744973903c9bdba5ab3c4def72331a53f9e45b261"]],"delta_g1":["0x1e87e5fa36ceb48346448d7bde273bf0e68b938068714ae5b9a34b5f06189ba5","0x0c39864a5a4e5f1dc74c0ec7235f36bdefc7f1a5c34277fbbab675210e1456f8"],"delta_g2":[["0x202d1f6118c936b072d21ee1c39326b72950e342c29e28770abbbe82bf6f9bfc","0x122bedfe76fd47a7d9af22c48acce6e39542c4e639234cd21f8dcf1ad857d2a1"],["0x216d0c805652dbb0ab1d46aad44f4230a614ec4eec8c8bdae84c94b94d1e30be","0x0cf19a6f199fd19aa2aed4e78c8813201e7821a3e4d7d94897639e0630f8e406"]],"gamma_g2":[["0x06119f2fc5e0c76f9722417fedb2a267385e63a5f48c37684e379790db770d4b","0x220a1e37e224859a0d4af6f29f9909f84b02dfed9b29bd376e94f44964379d70"],["0x02ba5f26131b4787569ae4075f817a8b395de987f3887fe5c55cefa4a00c1d29","0x139b91c637580b238cde5e6d0e3472a21453a9394fd9e35dfb0b343a0f9c9880"]],"ic":[["0x0e480b0119f8eaeaeb944752f1ae2ff13da7b78fdd0b04d5fa12e1422d1d8a29","0x153471558ba605e153a9b6230f14dfad9e401c0313e7ac0917e27ce26aa69fd0"],["0x062a1efbae92eef025288ecb23437f1ad3edc9aa490ec33d8a3dde5f09d8a66b","0x18eab07ce28c80f7c49bbcbdb5e3f6c8c61651f13230742a7eb25b0efa830332"]],"input_names":["main.r"]}

+ 25
- 1
verifier.go

@ -102,7 +102,8 @@ func stringToBigInt(s string) *big.Int {
return n return n
} }
func parsePublicRaw(pj []byte) ([]*big.Int, error) {
// ParsePublicRaw takes a json []byte and outputs the []*big.Int struct
func ParsePublicRaw(pj []byte) ([]*big.Int, error) {
var pr []string var pr []string
err := json.Unmarshal(pj, &pr) err := json.Unmarshal(pj, &pr)
if err != nil { if err != nil {
@ -191,3 +192,26 @@ func proofRawToProof(pr ProofRaw) (*Proof, error) {
return &p, nil return &p, nil
} }
var q = stringToBigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617")
// Verify performs the Groth16 zkSnark verification
func Verify(vk *Vk, proof *Proof, inputs []*big.Int) bool {
if len(inputs)+1 != len(vk.GammaABC) {
fmt.Println("len(inputs)+1 != len(vk.GammaABC)")
return false
}
vkX := new(bn256.G1).ScalarBaseMult(stringToBigInt("0"))
for i := 0; i < len(inputs); i++ {
// check input inside field
if inputs[0].Cmp(q) != -1 {
return false
}
vkX = new(bn256.G1).Add(vkX, new(bn256.G1).ScalarMult(vk.GammaABC[i+1], inputs[i]))
}
vkX = new(bn256.G1).Add(vkX, vk.GammaABC[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)
}

+ 58
- 0
verifier_test.go

@ -60,3 +60,61 @@ func TestParseProof(t *testing.T) {
assert.Equal(t, "bn256.G2((2275d97dce5445433ec7bc6d01c35f0afad9afcf6f3350cd15eeef1023242c01, 0b5f21c2d981916cd5e1037b446b170b6c60dd184fdbb3381b7d0880fb48300d), (2c2a08a60032f536afbcb21c079b563cdce68b7ef906e973c52f574121a95df0, 1690100372c53776b60c0ee56926debb4d0acee90f7952ecc63861e0269a098a))", vk.Beta.String()) assert.Equal(t, "bn256.G2((2275d97dce5445433ec7bc6d01c35f0afad9afcf6f3350cd15eeef1023242c01, 0b5f21c2d981916cd5e1037b446b170b6c60dd184fdbb3381b7d0880fb48300d), (2c2a08a60032f536afbcb21c079b563cdce68b7ef906e973c52f574121a95df0, 1690100372c53776b60c0ee56926debb4d0acee90f7952ecc63861e0269a098a))", vk.Beta.String())
assert.Equal(t, "bn256.G2((15c9b1123841897787badbe858eb00943fc8a99454666f21acf4e79e13547471, 2d0c4fa1239184802aeda1f206e49104940aa3eccc1b3e0141c25b2dba8e7caf), (2bc9bc381cf68badd992338c637b36b54936b69cb8560eaf5a8cbe2c20ff8522, 256ad09ecb0abc15fd48f20c37d28ffcf0f8eb3b23cb10cdeee7365b598963ac))", vk.Gamma.String()) assert.Equal(t, "bn256.G2((15c9b1123841897787badbe858eb00943fc8a99454666f21acf4e79e13547471, 2d0c4fa1239184802aeda1f206e49104940aa3eccc1b3e0141c25b2dba8e7caf), (2bc9bc381cf68badd992338c637b36b54936b69cb8560eaf5a8cbe2c20ff8522, 256ad09ecb0abc15fd48f20c37d28ffcf0f8eb3b23cb10cdeee7365b598963ac))", vk.Gamma.String())
} }
func TestVerify0(t *testing.T) {
proofJson, err := ioutil.ReadFile("testdata/proof0.json")
require.Nil(t, err)
vkJson, err := ioutil.ReadFile("testdata/vk0.json")
require.Nil(t, err)
publicJson, err := ioutil.ReadFile("testdata/public0.json")
require.Nil(t, err)
public, err := ParsePublicRaw(publicJson)
require.Nil(t, err)
proof, err := ParseProofRaw(proofJson)
require.Nil(t, err)
vk, err := ParseVkRaw(vkJson)
require.Nil(t, err)
v := Verify(vk, proof, public)
assert.True(t, v)
}
func TestVerify1(t *testing.T) {
proofJson, err := ioutil.ReadFile("testdata/proof1.json")
require.Nil(t, err)
vkJson, err := ioutil.ReadFile("testdata/vk1.json")
require.Nil(t, err)
publicJson, err := ioutil.ReadFile("testdata/public1.json")
require.Nil(t, err)
public, err := ParsePublicRaw(publicJson)
require.Nil(t, err)
proof, err := ParseProofRaw(proofJson)
require.Nil(t, err)
vk, err := ParseVkRaw(vkJson)
require.Nil(t, err)
v := Verify(vk, proof, public)
assert.True(t, v)
}
func BenchmarkVerify(b *testing.B) {
proofJson, err := ioutil.ReadFile("testdata/proof0.json")
require.Nil(b, err)
vkJson, err := ioutil.ReadFile("testdata/vk0.json")
require.Nil(b, err)
publicJson, err := ioutil.ReadFile("testdata/public0.json")
require.Nil(b, err)
public, err := ParsePublicRaw(publicJson)
require.Nil(b, err)
proof, err := ParseProofRaw(proofJson)
require.Nil(b, err)
vk, err := ParseVkRaw(vkJson)
require.Nil(b, err)
for i := 0; i < b.N; i++ {
Verify(vk, proof, public)
}
}

Loading…
Cancel
Save