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