go-snark/snark.go
snark.goRaw
1package snark
2
3import (
4 "crypto/rand"
5 "math/big"
6
7 "github.com/arnaucube/go-snark/bn128"
8 "github.com/arnaucube/go-snark/fields"
9)
10
11type Setup struct {
12 Toxic struct {
13 T *big.Int // trusted setup secret
14 Ka *big.Int // prover
15 Kb *big.Int // prover
16 Kc *big.Int // prover
17 Kbeta *big.Int
18 Kgamma *big.Int
19 RhoA *big.Int
20 RhoB *big.Int
21 RhoC *big.Int
22 }
23
24 // public
25 G1T [][3]*big.Int // t encrypted in G1 curve
26 G2T [][3][2]*big.Int // t encrypted in G2 curve
27 G1Kbg [3]*big.Int // g1 * Kbeta * Kgamma
28 G2Kbg [3][2]*big.Int // g2 * Kbeta * Kgamma
29 G2Kg [3][2]*big.Int // g2 * Kgamma
30}
31
32type Proof struct {
33 PiA [3]*big.Int
34 PiAp [3]*big.Int
35 PiB [3][2]*big.Int
36 PiBp [3]*big.Int
37 PiC [3]*big.Int
38 PiCp [3]*big.Int
39 PiH [3]*big.Int
40 PiK [3]*big.Int
41 Va [3][2]*big.Int
42 Vb [3]*big.Int
43 Vc [3][2]*big.Int
44 Vz [3][2]*big.Int
45}
46
47const bits = 512
48
49func GenerateTrustedSetup(bn bn128.Bn128, polLength int) (Setup, error) {
50 var setup Setup
51 var err error
52 // generate random t value
53 setup.Toxic.T, err = rand.Prime(rand.Reader, bits)
54 if err != nil {
55 return Setup{}, err
56 }
57
58 // k for calculating pi' and Vk
59 setup.Toxic.Ka, err = rand.Prime(rand.Reader, bits)
60 if err != nil {
61 return Setup{}, err
62 }
63 setup.Toxic.Kb, err = rand.Prime(rand.Reader, bits)
64 if err != nil {
65 return Setup{}, err
66 }
67 setup.Toxic.Kc, err = rand.Prime(rand.Reader, bits)
68 if err != nil {
69 return Setup{}, err
70 }
71
72 // generate Kβ (Kbeta) and Kγ (Kgamma)
73 setup.Toxic.Kbeta, err = rand.Prime(rand.Reader, bits)
74 if err != nil {
75 return Setup{}, err
76 }
77 setup.Toxic.Kgamma, err = rand.Prime(rand.Reader, bits)
78 if err != nil {
79 return Setup{}, err
80 }
81
82 // generate ρ (Rho): ρA, ρB, ρC
83 setup.Toxic.RhoA, err = rand.Prime(rand.Reader, bits)
84 if err != nil {
85 return Setup{}, err
86 }
87 setup.Toxic.RhoB, err = rand.Prime(rand.Reader, bits)
88 if err != nil {
89 return Setup{}, err
90 }
91 setup.Toxic.RhoC = bn.Fq1.Mul(setup.Toxic.RhoA, setup.Toxic.RhoB)
92
93 // encrypt t values with curve generators
94 var gt1 [][3]*big.Int
95 var gt2 [][3][2]*big.Int
96 for i := 0; i < polLength; i++ {
97 tPow := bn.Fq1.Exp(setup.Toxic.T, big.NewInt(int64(i)))
98 tEncr1 := bn.G1.MulScalar(bn.G1.G, tPow)
99 gt1 = append(gt1, tEncr1)
100 tEncr2 := bn.G2.MulScalar(bn.G2.G, tPow)
101 gt2 = append(gt2, tEncr2)
102 }
103 // gt1: g1, g1*t, g1*t^2, g1*t^3, ...
104 // gt2: g2, g2*t, g2*t^2, ...
105 setup.G1T = gt1
106 setup.G2T = gt2
107
108 /*
109 Verification keys:
110 - Vk_betagamma1: setup.G1Kbg = g1 * Kbeta*Kgamma
111 - Vk_betagamma2: setup.G2Kbg = g2 * Kbeta*Kgamma
112 - Vk_gamma: setup.G2Kg = g2 * Kgamma
113 */
114 kbg := bn.Fq1.Mul(setup.Toxic.Kbeta, setup.Toxic.Kgamma)
115 setup.G1Kbg = bn.G1.MulScalar(bn.G1.G, kbg)
116 setup.G2Kbg = bn.G2.MulScalar(bn.G2.G, kbg)
117 setup.G2Kg = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kgamma)
118
119 return setup, nil
120}
121
122func GenerateProofs(bn bn128.Bn128, f fields.Fq, setup Setup, w, ax, bx, cx, hx, zx []*big.Int) (Proof, error) {
123 var proof Proof
124
125 // g1*A(t)
126 proof.PiA = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
127 for i := 0; i < len(ax); i++ {
128 m := bn.G1.MulScalar(setup.G1T[i], ax[i])
129 proof.PiA = bn.G1.Add(proof.PiA, m)
130 }
131 proof.PiAp = bn.G1.MulScalar(proof.PiA, setup.Toxic.Ka) // move this in the setup step
132
133 // g2*B(t)
134 proof.PiB = bn.Fq6.Zero()
135 // g1*B(t)
136 pib1 := [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
137 for i := 0; i < len(bx); i++ {
138 m := bn.G2.MulScalar(setup.G2T[i], bx[i])
139 proof.PiB = bn.G2.Add(proof.PiB, m)
140 m1 := bn.G1.MulScalar(setup.G1T[i], bx[i])
141 pib1 = bn.G1.Add(pib1, m1)
142 }
143 proof.PiBp = bn.G1.MulScalar(pib1, setup.Toxic.Kb) // this in the setup step
144
145 // g1*C(t)
146 proof.PiC = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
147 for i := 0; i < len(cx); i++ {
148 m := bn.G1.MulScalar(setup.G1T[i], cx[i])
149 proof.PiC = bn.G1.Add(proof.PiC, m)
150 }
151 proof.PiCp = bn.G1.MulScalar(proof.PiC, setup.Toxic.Kc) // this in the setup step
152
153 // g1*H(t)
154 proof.PiH = [3]*big.Int{bn.G1.F.Zero(), bn.G1.F.Zero(), bn.G1.F.Zero()}
155 for i := 0; i < len(hx); i++ {
156 m := bn.G1.MulScalar(setup.G1T[i], hx[i])
157 proof.PiH = bn.G1.Add(proof.PiH, m)
158 }
159
160 proof.Vz = bn.Fq6.Zero()
161 for i := 0; i < len(bx); i++ {
162 m := bn.G2.MulScalar(setup.G2T[i], zx[i])
163 proof.Vz = bn.G2.Add(proof.Vz, m)
164 }
165 // proof.Vz = g2Zt
166 proof.Va = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Ka) // this in the setup step
167
168 proof.Vb = bn.G1.MulScalar(bn.G1.G, setup.Toxic.Kb) // this in the setup step
169
170 proof.Vc = bn.G2.MulScalar(bn.G2.G, setup.Toxic.Kc) // this in the setup step
171
172 return proof, nil
173}
174
175func VerifyProof(bn bn128.Bn128, setup Setup, proof Proof) bool {
176
177 // e(piA, Va) == e(piA', g2)
178 pairingPiaVa, err := bn.Pairing(proof.PiA, proof.Va)
179 if err != nil {
180 return false
181 }
182 pairingPiapG2, err := bn.Pairing(proof.PiAp, bn.G2.G)
183 if err != nil {
184 return false
185 }
186 if !bn.Fq12.Equal(pairingPiaVa, pairingPiapG2) {
187 return false
188 }
189
190 // e(Vb, piB) == e(piB', g2)
191 pairingVbPib, err := bn.Pairing(proof.Vb, proof.PiB)
192 if err != nil {
193 return false
194 }
195 pairingPibpG2, err := bn.Pairing(proof.PiBp, bn.G2.G)
196 if err != nil {
197 return false
198 }
199 if !bn.Fq12.Equal(pairingVbPib, pairingPibpG2) {
200 return false
201 }
202
203 // e(piC, Vc) == e(piC', g2)
204 pairingPicVc, err := bn.Pairing(proof.PiC, proof.Vc)
205 if err != nil {
206 return false
207 }
208 pairingPicpG2, err := bn.Pairing(proof.PiCp, bn.G2.G)
209 if err != nil {
210 return false
211 }
212 if !bn.Fq12.Equal(pairingPicVc, pairingPicpG2) {
213 return false
214 }
215
216 // e(piA+piC, g2KbetaKgamma) * e(g1KbetaKgamma, piB)
217 // == e(piK, g2Kgamma)
218 // piApiC := bn.G1.Add(proof.PiA, proof.PiC)
219 // pairingPiACG2Kbg, err := bn.Pairing(piApiC, setup.G2Kbg)
220 // if err != nil {
221 // return false
222 // }
223 // pairingG1KbgPiB, err := bn.Pairing(setup.G1Kbg, proof.PiB)
224 // if err != nil {
225 // return false
226 // }
227 // pairing1 := bn.Fq12.Mul(pairingPiACG2Kbg, pairingG1KbgPiB)
228
229 //
230
231 // e(piA, piB) == e(piH, Vz) * e(piC, g2)
232 // pairingPiaPib, err := bn.Pairing(proof.PiA, proof.PiB)
233 // if err != nil {
234 // return false
235 // }
236 // pairingPihVz, err := bn.Pairing(proof.PiH, proof.Vz)
237 // if err != nil {
238 // return false
239 // }
240 // pairingPicG2, err := bn.Pairing(proof.PiC, bn.G2.G)
241 // if err != nil {
242 // return false
243 // }
244 // if !bn.Fq12.Equal(pairingPiaPib, bn.Fq12.Mul(pairingPihVz, pairingPicG2)) {
245 // return false
246 // }
247
248 return true
249}