go-circom-prover-verifier/parsers/parsers.go
parsers/parsers.goRaw
1package parsers
2
3import (
4 "bytes"
5 "encoding/hex"
6 "encoding/json"
7 "fmt"
8 "math/big"
9 "strconv"
10 "strings"
11
12 bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
13 "github.com/iden3/go-circom-prover-verifier/types"
14)
15
16// PkString is the equivalent to the Pk struct in string representation, containing the ProvingKey
17type PkString struct {
18 A [][]string `json:"A"`
19 B2 [][][]string `json:"B2"`
20 B1 [][]string `json:"B1"`
21 C [][]string `json:"C"`
22 NVars int `json:"nVars"`
23 NPublic int `json:"nPublic"`
24 VkAlpha1 []string `json:"vk_alfa_1"`
25 VkDelta1 []string `json:"vk_delta_1"`
26 VkBeta1 []string `json:"vk_beta_1"`
27 VkBeta2 [][]string `json:"vk_beta_2"`
28 VkDelta2 [][]string `json:"vk_delta_2"`
29 HExps [][]string `json:"hExps"`
30 DomainSize int `json:"domainSize"`
31 PolsA []map[string]string `json:"polsA"`
32 PolsB []map[string]string `json:"polsB"`
33 PolsC []map[string]string `json:"polsC"`
34}
35
36// WitnessString contains the Witness in string representation
37type WitnessString []string
38
39// ProofString is the equivalent to the Proof struct in string representation
40type ProofString struct {
41 A []string `json:"pi_a"`
42 B [][]string `json:"pi_b"`
43 C []string `json:"pi_c"`
44 Protocol string `json:"protocol"`
45}
46
47// VkString is the Verification Key data structure in string format (from json)
48type VkString struct {
49 Alpha []string `json:"vk_alfa_1"`
50 Beta [][]string `json:"vk_beta_2"`
51 Gamma [][]string `json:"vk_gamma_2"`
52 Delta [][]string `json:"vk_delta_2"`
53 IC [][]string `json:"IC"`
54}
55
56// ParseWitness parses the json []byte data into the Witness struct
57func ParseWitness(wJson []byte) (types.Witness, error) {
58 var ws WitnessString
59 err := json.Unmarshal(wJson, &ws)
60 if err != nil {
61 return nil, err
62 }
63
64 var w types.Witness
65 for i := 0; i < len(ws); i++ {
66 bi, err := stringToBigInt(ws[i])
67 if err != nil {
68 return nil, err
69 }
70 w = append(w, bi)
71 }
72 return w, nil
73}
74
75// ParsePk parses the json []byte data into the Pk struct
76func ParsePk(pkJson []byte) (*types.Pk, error) {
77 var pkStr PkString
78 err := json.Unmarshal(pkJson, &pkStr)
79 if err != nil {
80 return nil, err
81 }
82 pk, err := pkStringToPk(pkStr)
83 return pk, err
84}
85
86func pkStringToPk(ps PkString) (*types.Pk, error) {
87 var p types.Pk
88 var err error
89
90 p.A, err = arrayStringToG1(ps.A)
91 if err != nil {
92 return nil, err
93 }
94 p.B2, err = arrayStringToG2(ps.B2)
95 if err != nil {
96 return nil, err
97 }
98 p.B1, err = arrayStringToG1(ps.B1)
99 if err != nil {
100 return nil, err
101 }
102 p.C, err = arrayStringToG1(ps.C)
103 if err != nil {
104 return nil, err
105 }
106
107 p.NVars = ps.NVars
108 p.NPublic = ps.NPublic
109
110 p.VkAlpha1, err = stringToG1(ps.VkAlpha1)
111 if err != nil {
112 return nil, err
113 }
114
115 p.VkDelta1, err = stringToG1(ps.VkDelta1)
116 if err != nil {
117 return nil, err
118 }
119
120 p.VkBeta1, err = stringToG1(ps.VkBeta1)
121 if err != nil {
122 return nil, err
123 }
124 p.VkBeta2, err = stringToG2(ps.VkBeta2)
125 if err != nil {
126 return nil, err
127 }
128 p.VkDelta2, err = stringToG2(ps.VkDelta2)
129 if err != nil {
130 return nil, err
131 }
132
133 p.HExps, err = arrayStringToG1(ps.HExps)
134 if err != nil {
135 return nil, err
136 }
137
138 p.DomainSize = ps.DomainSize
139
140 p.PolsA, err = polsStringToBigInt(ps.PolsA)
141 if err != nil {
142 return nil, err
143 }
144 p.PolsB, err = polsStringToBigInt(ps.PolsB)
145 if err != nil {
146 return nil, err
147 }
148 p.PolsC, err = polsStringToBigInt(ps.PolsC)
149 if err != nil {
150 return nil, err
151 }
152
153 return &p, nil
154}
155
156func proofStringToProof(pr ProofString) (*types.Proof, error) {
157 var p types.Proof
158 var err error
159 p.A, err = stringToG1(pr.A)
160 if err != nil {
161 return nil, err
162 }
163
164 p.B, err = stringToG2(pr.B)
165 if err != nil {
166 return nil, err
167 }
168
169 p.C, err = stringToG1(pr.C)
170 if err != nil {
171 return nil, err
172 }
173
174 return &p, nil
175}
176
177// ParseProof takes a json []byte and outputs the *Proof struct
178func ParseProof(pj []byte) (*types.Proof, error) {
179 var pr ProofString
180 err := json.Unmarshal(pj, &pr)
181 if err != nil {
182 return nil, err
183 }
184 p, err := proofStringToProof(pr)
185 return p, err
186}
187
188// ParsePublicSignals takes a json []byte and outputs the []*big.Int struct
189func ParsePublicSignals(pj []byte) ([]*big.Int, error) {
190 var pr []string
191 err := json.Unmarshal(pj, &pr)
192 if err != nil {
193 return nil, err
194 }
195 var public []*big.Int
196 for _, s := range pr {
197 sb, err := stringToBigInt(s)
198 if err != nil {
199 return nil, err
200 }
201 public = append(public, sb)
202 }
203 return public, nil
204}
205
206// ParseVk takes a json []byte and outputs the *Vk struct
207func ParseVk(vj []byte) (*types.Vk, error) {
208 var vr VkString
209 err := json.Unmarshal(vj, &vr)
210 if err != nil {
211 return nil, err
212 }
213 v, err := vkStringToVk(vr)
214 return v, err
215}
216
217func vkStringToVk(vr VkString) (*types.Vk, error) {
218 var v types.Vk
219 var err error
220 v.Alpha, err = stringToG1(vr.Alpha)
221 if err != nil {
222 return nil, err
223 }
224
225 v.Beta, err = stringToG2(vr.Beta)
226 if err != nil {
227 return nil, err
228 }
229
230 v.Gamma, err = stringToG2(vr.Gamma)
231 if err != nil {
232 return nil, err
233 }
234
235 v.Delta, err = stringToG2(vr.Delta)
236 if err != nil {
237 return nil, err
238 }
239
240 for i := 0; i < len(vr.IC); i++ {
241 p, err := stringToG1(vr.IC[i])
242 if err != nil {
243 return nil, err
244 }
245 v.IC = append(v.IC, p)
246 }
247
248 return &v, nil
249}
250
251// polsStringToBigInt is for taking string polynomials and converting it to *big.Int polynomials
252func polsStringToBigInt(s []map[string]string) ([]map[int]*big.Int, error) {
253 var o []map[int]*big.Int
254 for i := 0; i < len(s); i++ {
255 // var oi map[int]*big.Int
256 oi := make(map[int]*big.Int)
257 for j, v := range s[i] {
258 si, err := stringToBigInt(v)
259 if err != nil {
260 return o, err
261 }
262 // oi = append(oi, si)
263 jInt, err := strconv.Atoi(j)
264 if err != nil {
265 return o, err
266 }
267 oi[jInt] = si
268 }
269 o = append(o, oi)
270 }
271 return o, nil
272}
273
274// ArrayBigIntToString converts an []*big.Int into []string, used to output the Public Signals
275func ArrayBigIntToString(bi []*big.Int) []string {
276 var s []string
277 for i := 0; i < len(bi); i++ {
278 s = append(s, bi[i].String())
279 }
280 return s
281}
282
283func arrayStringToBigInt(s []string) ([]*big.Int, error) {
284 var o []*big.Int
285 for i := 0; i < len(s); i++ {
286 si, err := stringToBigInt(s[i])
287 if err != nil {
288 return o, nil
289 }
290 o = append(o, si)
291 }
292 return o, nil
293}
294
295func stringToBigInt(s string) (*big.Int, error) {
296 base := 10
297 if bytes.HasPrefix([]byte(s), []byte("0x")) {
298 base = 16
299 s = strings.TrimPrefix(s, "0x")
300 }
301 n, ok := new(big.Int).SetString(s, base)
302 if !ok {
303 return nil, fmt.Errorf("Can not parse string to *big.Int: %s", s)
304 }
305 return n, nil
306}
307
308func addZPadding(b []byte) []byte {
309 var z [32]byte
310 var r []byte
311 r = append(r, z[len(b):]...) // add padding on the left
312 r = append(r, b...)
313 return r[:32]
314}
315
316func stringToBytes(s string) ([]byte, error) {
317 if s == "1" {
318 s = "0"
319 }
320 bi, ok := new(big.Int).SetString(s, 10)
321 if !ok {
322 return nil, fmt.Errorf("error parsing bigint stringToBytes")
323 }
324 b := bi.Bytes()
325 if len(b) != 32 {
326 b = addZPadding(b)
327 }
328 return b, nil
329
330}
331
332func arrayStringToG1(h [][]string) ([]*bn256.G1, error) {
333 var o []*bn256.G1
334 for i := 0; i < len(h); i++ {
335 hi, err := stringToG1(h[i])
336 if err != nil {
337 return o, err
338 }
339 o = append(o, hi)
340 }
341 return o, nil
342}
343
344func arrayStringToG2(h [][][]string) ([]*bn256.G2, error) {
345 var o []*bn256.G2
346 for i := 0; i < len(h); i++ {
347 hi, err := stringToG2(h[i])
348 if err != nil {
349 return o, err
350 }
351 o = append(o, hi)
352 }
353 return o, nil
354}
355
356func stringToG1(h []string) (*bn256.G1, error) {
357 if len(h) <= 2 {
358 return nil, fmt.Errorf("not enought data for stringToG1")
359 }
360 h = h[:2]
361 hexa := false
362 if len(h[0]) > 1 {
363 if "0x" == h[0][:2] {
364 hexa = true
365 }
366 }
367 in := ""
368
369 var b []byte
370 var err error
371 if hexa {
372 for i := range h {
373 in += strings.TrimPrefix(h[i], "0x")
374 }
375 b, err = hex.DecodeString(in)
376 if err != nil {
377 return nil, err
378 }
379 } else {
380 // TODO TMP
381 // TODO use stringToBytes()
382 if h[0] == "1" {
383 h[0] = "0"
384 }
385 if h[1] == "1" {
386 h[1] = "0"
387 }
388 bi0, ok := new(big.Int).SetString(h[0], 10)
389 if !ok {
390 return nil, fmt.Errorf("error parsing stringToG1")
391 }
392 bi1, ok := new(big.Int).SetString(h[1], 10)
393 if !ok {
394 return nil, fmt.Errorf("error parsing stringToG1")
395 }
396 b0 := bi0.Bytes()
397 b1 := bi1.Bytes()
398 if len(b0) != 32 {
399 b0 = addZPadding(b0)
400 }
401 if len(b1) != 32 {
402 b1 = addZPadding(b1)
403 }
404
405 b = append(b, b0...)
406 b = append(b, b1...)
407 }
408 p := new(bn256.G1)
409 _, err = p.Unmarshal(b)
410
411 return p, err
412}
413
414func stringToG2(h [][]string) (*bn256.G2, error) {
415 if len(h) <= 2 {
416 return nil, fmt.Errorf("not enought data for stringToG2")
417 }
418 h = h[:2]
419 hexa := false
420 if len(h[0][0]) > 1 {
421 if "0x" == h[0][0][:2] {
422 hexa = true
423 }
424 }
425 in := ""
426 var b []byte
427 var err error
428 if hexa {
429 for i := 0; i < len(h); i++ {
430 for j := 0; j < len(h[i]); j++ {
431 in += strings.TrimPrefix(h[i][j], "0x")
432 }
433 }
434 b, err = hex.DecodeString(in)
435 if err != nil {
436 return nil, err
437 }
438 } else {
439 // TODO TMP
440 bH, err := stringToBytes(h[0][1])
441 if err != nil {
442 return nil, err
443 }
444 b = append(b, bH...)
445 bH, err = stringToBytes(h[0][0])
446 if err != nil {
447 return nil, err
448 }
449 b = append(b, bH...)
450 bH, err = stringToBytes(h[1][1])
451 if err != nil {
452 return nil, err
453 }
454 b = append(b, bH...)
455 bH, err = stringToBytes(h[1][0])
456 if err != nil {
457 return nil, err
458 }
459 b = append(b, bH...)
460 }
461
462 p := new(bn256.G2)
463 _, err = p.Unmarshal(b)
464 return p, err
465}
466
467// ProofToJson outputs the Proof i Json format
468func ProofToJson(p *types.Proof) ([]byte, error) {
469 var ps ProofString
470 ps.A = make([]string, 3)
471 ps.B = make([][]string, 3)
472 ps.B[0] = make([]string, 2)
473 ps.B[1] = make([]string, 2)
474 ps.B[2] = make([]string, 2)
475 ps.C = make([]string, 3)
476
477 a := p.A.Marshal()
478 ps.A[0] = new(big.Int).SetBytes(a[:32]).String()
479 ps.A[1] = new(big.Int).SetBytes(a[32:64]).String()
480 ps.A[2] = "1"
481
482 b := p.B.Marshal()
483 ps.B[0][1] = new(big.Int).SetBytes(b[:32]).String()
484 ps.B[0][0] = new(big.Int).SetBytes(b[32:64]).String()
485 ps.B[1][1] = new(big.Int).SetBytes(b[64:96]).String()
486 ps.B[1][0] = new(big.Int).SetBytes(b[96:128]).String()
487 ps.B[2][0] = "1"
488 ps.B[2][1] = "0"
489
490 c := p.C.Marshal()
491 ps.C[0] = new(big.Int).SetBytes(c[:32]).String()
492 ps.C[1] = new(big.Int).SetBytes(c[32:64]).String()
493 ps.C[2] = "1"
494
495 ps.Protocol = "groth"
496
497 return json.Marshal(ps)
498}