From 917eecaee05a5855373190139ffd8e303b20a407 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Thu, 6 Dec 2018 17:39:21 +0100 Subject: [PATCH] proofs --- README.md | 2 +- zk/zk.go | 130 ++++++++++++++++++++++++++++++++++++++++++-------- zk/zk_test.go | 33 ++++--------- 3 files changed, 121 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index f71a7bc..f12d369 100644 --- a/README.md +++ b/README.md @@ -112,4 +112,4 @@ assert.True(t, bn128.Fq12.Equal(pA, pB)) ## Caution Not finished, work in progress (implementing this in my free time to understand it better, so I don't have much time). -Thanks to @jbaylina, @bellesmarta, @adriamb for their explanations that helped to understand a little bit this. +Thanks to [@jbaylina](https://github.com/jbaylina), [@bellesmarta](https://github.com/bellesmarta), [@adriamb](https://github.com/adriamb) for their explanations that helped to understand this a little bit. diff --git a/zk/zk.go b/zk/zk.go index dd47a61..28cbe38 100644 --- a/zk/zk.go +++ b/zk/zk.go @@ -8,22 +8,48 @@ import ( "github.com/arnaucube/go-snark/bn128" ) +type Setup struct { + T *big.Int // trusted setup secret + Ka *big.Int // trusted setup + Kb *big.Int // trusted setup + Kc *big.Int // trusted setup + + // public + G1T [][3]*big.Int // t encrypted in G1 curve + G2T [][3][2]*big.Int // t encrypted in G2 curve +} +type Proof struct { + PiA [3]*big.Int + PiAp [3]*big.Int + PiB [3][2]*big.Int + PiBp [3][2]*big.Int + PiC [3]*big.Int + PiCp [3]*big.Int + PiH [3]*big.Int + Va [3][2]*big.Int + Vb [3][2]*big.Int + Vc [3][2]*big.Int + Vz [3][2]*big.Int +} + const bits = 512 -func GenerateTrustedSetup(bn bn128.Bn128, pollength int) ([][3]*big.Int, [][3][2]*big.Int, error) { +func GenerateTrustedSetup(bn bn128.Bn128, pollength int) (Setup, error) { + var setup Setup + var err error // generate random t value - t, err := rand.Prime(rand.Reader, bits) + setup.T, err = rand.Prime(rand.Reader, bits) if err != nil { - return [][3]*big.Int{}, [][3][2]*big.Int{}, err + return Setup{}, err } fmt.Print("trusted t: ") - fmt.Println(t) + fmt.Println(setup.T) // encrypt t values with curve generators var gt1 [][3]*big.Int var gt2 [][3][2]*big.Int for i := 0; i < pollength; i++ { - tPow := bn.Fq1.Exp(t, big.NewInt(int64(i))) + tPow := bn.Fq1.Exp(setup.T, big.NewInt(int64(i))) tEncr1 := bn.G1.MulScalar(bn.G1.G, tPow) gt1 = append(gt1, tEncr1) tEncr2 := bn.G2.MulScalar(bn.G2.G, tPow) @@ -31,39 +57,103 @@ func GenerateTrustedSetup(bn bn128.Bn128, pollength int) ([][3]*big.Int, [][3][2 } // gt1: g1, g1*t, g1*t^2, g1*t^3, ... // gt2: g2, g2*t, g2*t^2, ... - return gt1, gt2, nil + setup.G1T = gt1 + setup.G2T = gt2 + + // k for pi' + setup.Ka, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + setup.Kb, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + setup.Kc, err = rand.Prime(rand.Reader, bits) + if err != nil { + return Setup{}, err + } + + return setup, nil } -func GenerateProofs(bn bn128.Bn128, gt1 [][3]*big.Int, gt2 [][3][2]*big.Int, ax, bx, cx, hx, zx []*big.Int) ([3]*big.Int, [3][2]*big.Int, [3]*big.Int, [3]*big.Int, [3][2]*big.Int) { - // multiply g1*A(x), g2*B(x), g1*C(x), g1*H(x) +func GenerateProofs(bn bn128.Bn128, setup Setup, ax, bx, cx, hx, zx []*big.Int) Proof { + var proof Proof // g1*A(x) - g1At := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} + proof.PiA = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} for i := 0; i < len(ax); i++ { - m := bn.G1.MulScalar(gt1[i], ax[i]) - g1At = bn.G1.Add(g1At, m) + m := bn.G1.MulScalar(setup.G1T[i], ax[i]) + proof.PiA = bn.G1.Add(proof.PiA, m) } - g2Bt := bn.Fq6.Zero() + proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Ka) + + // g1*B(x) + proof.PiB = bn.Fq6.Zero() for i := 0; i < len(bx); i++ { - m := bn.G2.MulScalar(gt2[i], bx[i]) - g2Bt = bn.G2.Add(g2Bt, m) + m := bn.G2.MulScalar(setup.G2T[i], bx[i]) + proof.PiB = bn.G2.Add(proof.PiB, m) } + proof.PiBp = bn.G2.MulScalar(proof.PiB, setup.Kb) - g1Ct := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} + // g1*C(x) + proof.PiC = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} for i := 0; i < len(cx); i++ { - m := bn.G1.MulScalar(gt1[i], cx[i]) - g1Ct = bn.G1.Add(g1Ct, m) + 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.Kc) + g1Ht := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()} for i := 0; i < len(hx); i++ { - m := bn.G1.MulScalar(gt1[i], hx[i]) + m := bn.G1.MulScalar(setup.G1T[i], hx[i]) g1Ht = bn.G1.Add(g1Ht, m) } g2Zt := bn.Fq6.Zero() for i := 0; i < len(bx); i++ { - m := bn.G2.MulScalar(gt2[i], zx[i]) + m := bn.G2.MulScalar(setup.G2T[i], zx[i]) g2Zt = bn.G2.Add(g2Zt, m) } + proof.PiH = g1Ht + proof.Vz = g2Zt + proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Ka) + proof.Vb = bn.G2.MulScalar(bn.G2.G, setup.Kb) + proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Kc) + + return proof +} + +func VerifyProof(bn bn128.Bn128, setup Setup, proof Proof) bool { + + // e(piA, Va) == e(piA', g2) + pairingPiaVa, err := bn.Pairing(proof.PiA, proof.Va) + if err != nil { + return false + } + pairingPiapG2, err := bn.Pairing(proof.PiAp, bn.G2.G) + if err != nil { + return false + } + if !bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) { + return false + } + + // e(piB, Vb) == e(piB', g2) + + // e(piC, Vc) == e(piC', g2) + pairingPicVc, err := bn.Pairing(proof.PiC, proof.Vc) + if err != nil { + return false + } + pairingPicpG2, err := bn.Pairing(proof.PiCp, bn.G2.G) + if err != nil { + return false + } + if !bn.Fq12.Equal(pairingPicVc, pairingPicpG2) { + return false + } + + // - return g1At, g2Bt, g1Ct, g1Ht, g2Zt + return true } diff --git a/zk/zk_test.go b/zk/zk_test.go index a18fa82..8063f4f 100644 --- a/zk/zk_test.go +++ b/zk/zk_test.go @@ -64,33 +64,20 @@ func TestZk(t *testing.T) { assert.Equal(t, abc, hz) // calculate trusted setup - gt1, gt2, err := GenerateTrustedSetup(bn, len(ax)) + setup, err := GenerateTrustedSetup(bn, len(ax)) assert.Nil(t, err) fmt.Println("trusted setup:") - fmt.Println(gt1) - fmt.Println(gt2) + fmt.Println(setup.G1T) + fmt.Println(setup.G2T) // piA = g1 * A(t), piB = g2 * B(t), piC = g1 * C(t), piH = g1 * H(t) - piA, piB, piC, piH, piZ := GenerateProofs(bn, gt1, gt2, ax, bx, cx, hx, zx) + proof := GenerateProofs(bn, setup, ax, bx, cx, hx, zx) fmt.Println("proofs:") - fmt.Println(piA) - fmt.Println(piB) - fmt.Println(piC) - fmt.Println(piH) - fmt.Println(piZ) + fmt.Println(proof.PiA) + fmt.Println(proof.PiB) + fmt.Println(proof.PiC) + fmt.Println(proof.PiH) + fmt.Println(proof.Vz) - // pairing - fmt.Println("pairing") - pairingAB, err := bn.Pairing(piA, piB) - assert.Nil(t, err) - pairingCg2, err := bn.Pairing(piC, bn.G2.G) - assert.Nil(t, err) - pairingLeft := bn.Fq12.Div(pairingAB, pairingCg2) - pairingHg2Z, err := bn.Pairing(piH, piZ) - assert.Nil(t, err) - - fmt.Println(bn.Fq12.Affine(pairingLeft)) - fmt.Println(bn.Fq12.Affine(pairingHg2Z)) - - assert.True(t, bn.Fq12.Equal(pairingLeft, pairingHg2Z)) + assert.True(t, VerifyProof(bn, setup, proof)) }