From 439d894ee73f373692e3c52243598232ea576c65 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sun, 9 Dec 2018 21:36:05 +0100 Subject: [PATCH] key generation for proofs, snark files to the root directory --- .gitignore | 1 + README.md | 11 ++- bn128/README.md | 4 - zk/zk.go => snark.go | 137 +++++++++++++++++++++++---------- zk/zk_test.go => snark_test.go | 4 +- 5 files changed, 106 insertions(+), 51 deletions(-) create mode 100644 .gitignore rename zk/zk.go => snark.go (57%) rename zk/zk_test.go => snark_test.go (96%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9ebc0b7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.Backup diff --git a/README.md b/README.md index b2882d2..e7c2e5f 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,14 @@ zkSNARK library implementation in Go + +`Succinct Non-Interactive Zero Knowledge for a von Neumann Architecture`, Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza https://eprint.iacr.org/2013/879.pdf + ### Usage -- [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/zk?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/zk) zk (TrustedSetup, GenerateProof, VerifyProof) -- [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/bn128?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/bn128) bn128 (more details: https://github.com/arnaucube/go-snark/tree/master/bn128) -- [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/fields?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/fields) Finite Fields -- [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/r1csqap?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/r1csqap) R1CS to QAP (more details: https://github.com/arnaucube/go-snark/tree/master/r1csqap) +- [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark?status.svg)](https://godoc.org/github.com/arnaucube/go-snark) zkSnark + - [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/bn128?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/bn128) bn128 (more details: https://github.com/arnaucube/go-snark/tree/master/bn128) + - [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/fields?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/fields) Finite Fields operations + - [![GoDoc](https://godoc.org/github.com/arnaucube/go-snark/r1csqap?status.svg)](https://godoc.org/github.com/arnaucube/go-snark/r1csqap) R1CS to QAP (more details: https://github.com/arnaucube/go-snark/tree/master/r1csqap) Example: ```go diff --git a/bn128/README.md b/bn128/README.md index 0cedf3d..174fa83 100644 --- a/bn128/README.md +++ b/bn128/README.md @@ -26,10 +26,6 @@ over Elliptic Curves`, Matthieu Rivain https://eprint.iacr.org/2011/338.pdf - [x] MillerLoop - [x] Pairing -### Installation -``` -go get github.com/arnaucube/bn128 -``` #### Usage diff --git a/zk/zk.go b/snark.go similarity index 57% rename from zk/zk.go rename to snark.go index 3aa70d5..4840404 100644 --- a/zk/zk.go +++ b/snark.go @@ -1,8 +1,7 @@ -package zk +package snark import ( "crypto/rand" - "fmt" "math/big" "github.com/arnaucube/go-snark/bn128" @@ -11,16 +10,25 @@ import ( type Setup struct { Toxic struct { - T *big.Int // trusted setup secret - Ka *big.Int // prover - Kb *big.Int // prover - Kc *big.Int // prover + T *big.Int // trusted setup secret + Ka *big.Int // prover + Kb *big.Int // prover + Kc *big.Int // prover + Kbeta *big.Int + Kgamma *big.Int + RhoA *big.Int + RhoB *big.Int + RhoC *big.Int } // public - G1T [][3]*big.Int // t encrypted in G1 curve - G2T [][3][2]*big.Int // t encrypted in G2 curve + G1T [][3]*big.Int // t encrypted in G1 curve + G2T [][3][2]*big.Int // t encrypted in G2 curve + G1Kbg [3]*big.Int // g1 * Kbeta * Kgamma + G2Kbg [3][2]*big.Int // g2 * Kbeta * Kgamma + G2Kg [3][2]*big.Int // g2 * Kgamma } + type Proof struct { PiA [3]*big.Int PiAp [3]*big.Int @@ -29,6 +37,7 @@ type Proof struct { PiC [3]*big.Int PiCp [3]*big.Int PiH [3]*big.Int + PiK [3]*big.Int Va [3][2]*big.Int Vb [3]*big.Int Vc [3][2]*big.Int @@ -37,7 +46,7 @@ type Proof struct { const bits = 512 -func GenerateTrustedSetup(bn bn128.Bn128, pollength int) (Setup, error) { +func GenerateTrustedSetup(bn bn128.Bn128, polLength int) (Setup, error) { var setup Setup var err error // generate random t value @@ -45,13 +54,46 @@ func GenerateTrustedSetup(bn bn128.Bn128, pollength int) (Setup, error) { if err != nil { return Setup{}, err } - fmt.Print("trusted t: ") - fmt.Println(setup.Toxic.T) + + // k for calculating pi' and Vk + setup.Toxic.Ka, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + setup.Toxic.Kb, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + setup.Toxic.Kc, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + + // generate Kβ (Kbeta) and Kγ (Kgamma) + setup.Toxic.Kbeta, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + setup.Toxic.Kgamma, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + + // generate ρ (Rho): ρA, ρB, ρC + setup.Toxic.RhoA, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + setup.Toxic.RhoB, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + setup.Toxic.RhoC = bn.Fq1.Mul(setup.Toxic.RhoA, setup.Toxic.RhoB) // encrypt t values with curve generators var gt1 [][3]*big.Int var gt2 [][3][2]*big.Int - for i := 0; i < pollength; i++ { + for i := 0; i < polLength; i++ { tPow := bn.Fq1.Exp(setup.Toxic.T, big.NewInt(int64(i))) tEncr1 := bn.G1.MulScalar(bn.G1.G, tPow) gt1 = append(gt1, tEncr1) @@ -63,26 +105,22 @@ func GenerateTrustedSetup(bn bn128.Bn128, pollength int) (Setup, error) { setup.G1T = gt1 setup.G2T = gt2 + /* + Verification keys: + - Vk_betagamma1: setup.G1Kbg = g1 * Kbeta*Kgamma + - Vk_betagamma2: setup.G2Kbg = g2 * Kbeta*Kgamma + - Vk_gamma: setup.G2Kg = g2 * Kgamma + */ + kbg := bn.Fq1.Mul(setup.Toxic.Kbeta, setup.Toxic.Kgamma) + setup.G1Kbg = bn.G1.MulScalar(bn.G1.G, kbg) + setup.G2Kbg = bn.G2.MulScalar(bn.G2.G, kbg) + setup.G2Kg = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kgamma) + return setup, nil } -func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, ax, bx, cx, hx, zx []*big.Int) (Proof, error) { +func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, w, ax, bx, cx, hx, zx []*big.Int) (Proof, error) { var proof Proof - var err error - - // k for calculating pi' and Vk - setup.Toxic.Ka, err = rand.Prime(rand.Reader, bits) - if err != nil { - return Proof{}, err - } - setup.Toxic.Kb, err = rand.Prime(rand.Reader, bits) - if err != nil { - return Proof{}, err - } - setup.Toxic.Kc, err = rand.Prime(rand.Reader, bits) - if err != nil { - return Proof{}, err - } // g1*A(t) proof.PiA = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} @@ -90,7 +128,7 @@ func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, ax, bx, cx, hx, zx m := bn.G1.MulScalar(setup.G1T[i], ax[i]) proof.PiA = bn.G1.Add(proof.PiA, m) } - proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Toxic.Ka) + proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Toxic.Ka) // move this in the setup step // g2*B(t) proof.PiB = bn.Fq6.Zero() @@ -102,7 +140,7 @@ func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, ax, bx, cx, hx, zx m1 := bn.G1.MulScalar(setup.G1T[i], bx[i]) pib1 = bn.G1.Add(pib1, m1) } - proof.PiBp = bn.G1.MulScalar(pib1, setup.Toxic.Kb) + proof.PiBp = bn.G1.MulScalar(pib1, setup.Toxic.Kb) // this in the setup step // g1*C(t) proof.PiC = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} @@ -110,7 +148,7 @@ func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, ax, bx, cx, hx, zx m := bn.G1.MulScalar(setup.G1T[i], cx[i]) proof.PiC = bn.G1.Add(proof.PiC, m) } - proof.PiCp = bn.G1.MulScalar(proof.PiC, setup.Toxic.Kc) + proof.PiCp = bn.G1.MulScalar(proof.PiC, setup.Toxic.Kc) // this in the setup step // g1*H(t) proof.PiH = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} @@ -119,15 +157,17 @@ func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, ax, bx, cx, hx, zx proof.PiH = bn.G1.Add(proof.PiH, m) } - g2Zt := bn.Fq6.Zero() + proof.Vz = bn.Fq6.Zero() for i := 0; i < len(bx); i++ { m := bn.G2.MulScalar(setup.G2T[i], zx[i]) - g2Zt = bn.G2.Add(g2Zt, m) + proof.Vz = bn.G2.Add(proof.Vz, m) } - proof.Vz = g2Zt - proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Ka) - proof.Vb = bn.G1.MulScalar(bn.G1.G, setup.Toxic.Kb) - proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kc) + // proof.Vz = g2Zt + proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Ka) // this in the setup step + + proof.Vb = bn.G1.MulScalar(bn.G1.G, setup.Toxic.Kb) // this in the setup step + + proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kc) // this in the setup step return proof, nil } @@ -173,21 +213,36 @@ func VerifyProof(bn bn128.Bn128, setup Setup, proof Proof) bool { return false } + // e(piA+piC, g2KbetaKgamma) * e(g1KbetaKgamma, piB) + // == e(piK, g2Kgamma) + // piApiC := bn.G1.Add(proof.PiA, proof.PiC) + // pairingPiACG2Kbg, err := bn.Pairing(piApiC, setup.G2Kbg) + // if err != nil { + // return false + // } + // pairingG1KbgPiB, err := bn.Pairing(setup.G1Kbg, proof.PiB) + // if err != nil { + // return false + // } + // pairing1 := bn.Fq12.Mul(pairingPiACG2Kbg, pairingG1KbgPiB) + + // + // e(piA, piB) == e(piH, Vz) * e(piC, g2) // pairingPiaPib, err := bn.Pairing(proof.PiA, proof.PiB) // if err != nil { - // return false + // return false // } // pairingPihVz, err := bn.Pairing(proof.PiH, proof.Vz) // if err != nil { - // return false + // return false // } // pairingPicG2, err := bn.Pairing(proof.PiC, bn.G2.G) // if err != nil { - // return false + // return false // } // if !bn.Fq12.Equal(pairingPiaPib, bn.Fq12.Mul(pairingPihVz, pairingPicG2)) { - // return false + // return false // } return true diff --git a/zk/zk_test.go b/snark_test.go similarity index 96% rename from zk/zk_test.go rename to snark_test.go index 4d9c9b4..16417f8 100644 --- a/zk/zk_test.go +++ b/snark_test.go @@ -1,4 +1,4 @@ -package zk +package snark import ( "fmt" @@ -71,7 +71,7 @@ func TestZk(t *testing.T) { fmt.Println(setup.G2T) // piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t) - proof, err := GenerateProofs(bn, f, setup, ax, bx, cx, hx, zx) + proof, err := GenerateProofs(bn, f, setup, w, ax, bx, cx, hx, zx) assert.Nil(t, err) fmt.Println("proofs:") fmt.Println(proof.PiA)