go-snark/zk/zk.go
zk/zk.goRaw
1package zk
2
3import (
4 "crypto/rand"
5 "fmt"
6 "math/big"
7
8 "github.com/arnaucube/go-snark/bn128"
9 "github.com/arnaucube/go-snark/fields"
10)
11
12type Setup struct {
13 Toxic struct {
14 T *big.Int // trusted setup secret
15 Ka *big.Int // prover
16 Kb *big.Int // prover
17 Kc *big.Int // prover
18 }
19
20 // public
21 G1T [][3]*big.Int // t encrypted in G1 curve
22 G2T [][3][2]*big.Int // t encrypted in G2 curve
23}
24type Proof struct {
25 PiA [3]*big.Int
26 PiAp [3]*big.Int
27 PiB [3][2]*big.Int
28 PiBp [3]*big.Int
29 PiC [3]*big.Int
30 PiCp [3]*big.Int
31 PiH [3]*big.Int
32 Va [3][2]*big.Int
33 Vb [3]*big.Int
34 Vc [3][2]*big.Int
35 Vz [3][2]*big.Int
36}
37
38const bits = 512
39
40func GenerateTrustedSetup(bn bn128.Bn128, pollength int) (Setup, error) {
41 var setup Setup
42 var err error
43 // generate random t value
44 setup.Toxic.T, err = rand.Prime(rand.Reader, bits)
45 if err != nil {
46 return Setup{}, err
47 }
48 fmt.Print("trusted t: ")
49 fmt.Println(setup.Toxic.T)
50
51 // encrypt t values with curve generators
52 var gt1 [][3]*big.Int
53 var gt2 [][3][2]*big.Int
54 for i := 0; i < pollength; i++ {
55 tPow := bn.Fq1.Exp(setup.Toxic.T, big.NewInt(int64(i)))
56 tEncr1 := bn.G1.MulScalar(bn.G1.G, tPow)
57 gt1 = append(gt1, tEncr1)
58 tEncr2 := bn.G2.MulScalar(bn.G2.G, tPow)
59 gt2 = append(gt2, tEncr2)
60 }
61 // gt1: g1, g1*t, g1*t^2, g1*t^3, ...
62 // gt2: g2, g2*t, g2*t^2, ...
63 setup.G1T = gt1
64 setup.G2T = gt2
65
66 return setup, nil
67}
68
69func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, ax, bx, cx, hx, zx []*big.Int) (Proof, error) {
70 var proof Proof
71 var err error
72
73 // k for calculating pi' and Vk
74 setup.Toxic.Ka, err = rand.Prime(rand.Reader, bits)
75 if err != nil {
76 return Proof{}, err
77 }
78 setup.Toxic.Kb, err = rand.Prime(rand.Reader, bits)
79 if err != nil {
80 return Proof{}, err
81 }
82 setup.Toxic.Kc, err = rand.Prime(rand.Reader, bits)
83 if err != nil {
84 return Proof{}, err
85 }
86
87 // g1*A(t)
88 proof.PiA = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
89 for i := 0; i < len(ax); i++ {
90 m := bn.G1.MulScalar(setup.G1T[i], ax[i])
91 proof.PiA = bn.G1.Add(proof.PiA, m)
92 }
93 proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Toxic.Ka)
94
95 // g2*B(t)
96 proof.PiB = bn.Fq6.Zero()
97 // g1*B(t)
98 pib1 := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
99 for i := 0; i < len(bx); i++ {
100 m := bn.G2.MulScalar(setup.G2T[i], bx[i])
101 proof.PiB = bn.G2.Add(proof.PiB, m)
102 m1 := bn.G1.MulScalar(setup.G1T[i], bx[i])
103 pib1 = bn.G1.Add(pib1, m1)
104 }
105 proof.PiBp = bn.G1.MulScalar(pib1, setup.Toxic.Kb)
106
107 // g1*C(t)
108 proof.PiC = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
109 for i := 0; i < len(cx); i++ {
110 m := bn.G1.MulScalar(setup.G1T[i], cx[i])
111 proof.PiC = bn.G1.Add(proof.PiC, m)
112 }
113 proof.PiCp = bn.G1.MulScalar(proof.PiC, setup.Toxic.Kc)
114
115 // g1*H(t)
116 proof.PiH = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
117 for i := 0; i < len(hx); i++ {
118 m := bn.G1.MulScalar(setup.G1T[i], hx[i])
119 proof.PiH = bn.G1.Add(proof.PiH, m)
120 }
121
122 g2Zt := bn.Fq6.Zero()
123 for i := 0; i < len(bx); i++ {
124 m := bn.G2.MulScalar(setup.G2T[i], zx[i])
125 g2Zt = bn.G2.Add(g2Zt, m)
126 }
127 proof.Vz = g2Zt
128 proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Ka)
129 proof.Vb = bn.G1.MulScalar(bn.G1.G, setup.Toxic.Kb)
130 proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kc)
131
132 return proof, nil
133}
134
135func VerifyProof(bn bn128.Bn128, setup Setup, proof Proof) bool {
136
137 // e(piA, Va) == e(piA', g2)
138 pairingPiaVa, err := bn.Pairing(proof.PiA, proof.Va)
139 if err != nil {
140 return false
141 }
142 pairingPiapG2, err := bn.Pairing(proof.PiAp, bn.G2.G)
143 if err != nil {
144 return false
145 }
146 if !bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) {
147 return false
148 }
149
150 // e(Vb, piB) == e(piB', g2)
151 pairingVbPib, err := bn.Pairing(proof.Vb, proof.PiB)
152 if err != nil {
153 return false
154 }
155 pairingPibpG2, err := bn.Pairing(proof.PiBp, bn.G2.G)
156 if err != nil {
157 return false
158 }
159 if !bn.Fq12.Equal(pairingVbPib, pairingPibpG2) {
160 return false
161 }
162
163 // e(piC, Vc) == e(piC', g2)
164 pairingPicVc, err := bn.Pairing(proof.PiC, proof.Vc)
165 if err != nil {
166 return false
167 }
168 pairingPicpG2, err := bn.Pairing(proof.PiCp, bn.G2.G)
169 if err != nil {
170 return false
171 }
172 if !bn.Fq12.Equal(pairingPicVc, pairingPicpG2) {
173 return false
174 }
175
176 // e(piA, piB) == e(piH, Vz) * e(piC, g2)
177 // pairingPiaPib, err := bn.Pairing(proof.PiA, proof.PiB)
178 // if err != nil {
179 // return false
180 // }
181 // pairingPihVz, err := bn.Pairing(proof.PiH, proof.Vz)
182 // if err != nil {
183 // return false
184 // }
185 // pairingPicG2, err := bn.Pairing(proof.PiC, bn.G2.G)
186 // if err != nil {
187 // return false
188 // }
189 // if !bn.Fq12.Equal(pairingPiaPib, bn.Fq12.Mul(pairingPihVz, pairingPicG2)) {
190 // return false
191 // }
192
193 return true
194}