go-circom-prover-verifier/parsers/parsers.go
parsers/parsers.goRaw
1package parsers
2
3import (
4 "bufio"
5 "bytes"
6 "encoding/binary"
7 "encoding/hex"
8 "encoding/json"
9 "fmt"
10 "io"
11 "math/big"
12 "os"
13 "strconv"
14 "strings"
15
16 bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
17 "github.com/iden3/go-circom-prover-verifier/types"
18)
19
20// PkString is the equivalent to the Pk struct in string representation, containing the ProvingKey
21type PkString struct {
22 A [][]string `json:"A"`
23 B2 [][][]string `json:"B2"`
24 B1 [][]string `json:"B1"`
25 C [][]string `json:"C"`
26 NVars int `json:"nVars"`
27 NPublic int `json:"nPublic"`
28 VkAlpha1 []string `json:"vk_alfa_1"`
29 VkDelta1 []string `json:"vk_delta_1"`
30 VkBeta1 []string `json:"vk_beta_1"`
31 VkBeta2 [][]string `json:"vk_beta_2"`
32 VkDelta2 [][]string `json:"vk_delta_2"`
33 HExps [][]string `json:"hExps"`
34 DomainSize int `json:"domainSize"`
35 PolsA []map[string]string `json:"polsA"`
36 PolsB []map[string]string `json:"polsB"`
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
152 return &p, nil
153}
154
155func proofStringToProof(pr ProofString) (*types.Proof, error) {
156 var p types.Proof
157 var err error
158 p.A, err = stringToG1(pr.A)
159 if err != nil {
160 return nil, err
161 }
162
163 p.B, err = stringToG2(pr.B)
164 if err != nil {
165 return nil, err
166 }
167
168 p.C, err = stringToG1(pr.C)
169 if err != nil {
170 return nil, err
171 }
172
173 return &p, nil
174}
175
176// ParseProof takes a json []byte and outputs the *Proof struct
177func ParseProof(pj []byte) (*types.Proof, error) {
178 var pr ProofString
179 err := json.Unmarshal(pj, &pr)
180 if err != nil {
181 return nil, err
182 }
183 p, err := proofStringToProof(pr)
184 return p, err
185}
186
187// ParsePublicSignals takes a json []byte and outputs the []*big.Int struct
188func ParsePublicSignals(pj []byte) ([]*big.Int, error) {
189 var pr []string
190 err := json.Unmarshal(pj, &pr)
191 if err != nil {
192 return nil, err
193 }
194 var public []*big.Int
195 for _, s := range pr {
196 sb, err := stringToBigInt(s)
197 if err != nil {
198 return nil, err
199 }
200 public = append(public, sb)
201 }
202 return public, nil
203}
204
205// ParseVk takes a json []byte and outputs the *Vk struct
206func ParseVk(vj []byte) (*types.Vk, error) {
207 var vr VkString
208 err := json.Unmarshal(vj, &vr)
209 if err != nil {
210 return nil, err
211 }
212 v, err := vkStringToVk(vr)
213 return v, err
214}
215
216func vkStringToVk(vr VkString) (*types.Vk, error) {
217 var v types.Vk
218 var err error
219 v.Alpha, err = stringToG1(vr.Alpha)
220 if err != nil {
221 return nil, err
222 }
223
224 v.Beta, err = stringToG2(vr.Beta)
225 if err != nil {
226 return nil, err
227 }
228
229 v.Gamma, err = stringToG2(vr.Gamma)
230 if err != nil {
231 return nil, err
232 }
233
234 v.Delta, err = stringToG2(vr.Delta)
235 if err != nil {
236 return nil, err
237 }
238
239 for i := 0; i < len(vr.IC); i++ {
240 p, err := stringToG1(vr.IC[i])
241 if err != nil {
242 return nil, err
243 }
244 v.IC = append(v.IC, p)
245 }
246
247 return &v, nil
248}
249
250// polsStringToBigInt is for taking string polynomials and converting it to *big.Int polynomials
251func polsStringToBigInt(s []map[string]string) ([]map[int]*big.Int, error) {
252 var o []map[int]*big.Int
253 for i := 0; i < len(s); i++ {
254 // var oi map[int]*big.Int
255 oi := make(map[int]*big.Int)
256 for j, v := range s[i] {
257 si, err := stringToBigInt(v)
258 if err != nil {
259 return o, err
260 }
261 // oi = append(oi, si)
262 jInt, err := strconv.Atoi(j)
263 if err != nil {
264 return o, err
265 }
266 oi[jInt] = si
267 }
268 o = append(o, oi)
269 }
270 return o, nil
271}
272
273// ArrayBigIntToString converts an []*big.Int into []string, used to output the Public Signals
274func ArrayBigIntToString(bi []*big.Int) []string {
275 var s []string
276 for i := 0; i < len(bi); i++ {
277 s = append(s, bi[i].String())
278 }
279 return s
280}
281
282func arrayStringToBigInt(s []string) ([]*big.Int, error) {
283 var o []*big.Int
284 for i := 0; i < len(s); i++ {
285 si, err := stringToBigInt(s[i])
286 if err != nil {
287 return o, nil
288 }
289 o = append(o, si)
290 }
291 return o, nil
292}
293
294func stringToBigInt(s string) (*big.Int, error) {
295 base := 10
296 if bytes.HasPrefix([]byte(s), []byte("0x")) {
297 base = 16
298 s = strings.TrimPrefix(s, "0x")
299 }
300 n, ok := new(big.Int).SetString(s, base)
301 if !ok {
302 return nil, fmt.Errorf("Can not parse string to *big.Int: %s", s)
303 }
304 return n, nil
305}
306
307func addPadding32(b []byte) []byte {
308 if len(b) != 32 {
309 b = addZPadding(b)
310 }
311 return b
312}
313
314func addZPadding(b []byte) []byte {
315 var z [32]byte
316 var r []byte
317 r = append(r, z[len(b):]...) // add padding on the left
318 r = append(r, b...)
319 return r[:32]
320}
321
322func stringToBytes(s string) ([]byte, error) {
323 if s == "1" {
324 s = "0"
325 }
326 bi, ok := new(big.Int).SetString(s, 10)
327 if !ok {
328 return nil, fmt.Errorf("error parsing bigint stringToBytes")
329 }
330 b := bi.Bytes()
331 if len(b) != 32 {
332 b = addZPadding(b)
333 }
334 return b, nil
335
336}
337
338func arrayStringToG1(h [][]string) ([]*bn256.G1, error) {
339 var o []*bn256.G1
340 for i := 0; i < len(h); i++ {
341 hi, err := stringToG1(h[i])
342 if err != nil {
343 return o, err
344 }
345 o = append(o, hi)
346 }
347 return o, nil
348}
349
350func arrayStringToG2(h [][][]string) ([]*bn256.G2, error) {
351 var o []*bn256.G2
352 for i := 0; i < len(h); i++ {
353 hi, err := stringToG2(h[i])
354 if err != nil {
355 return o, err
356 }
357 o = append(o, hi)
358 }
359 return o, nil
360}
361
362func stringToG1(h []string) (*bn256.G1, error) {
363 if len(h) <= 2 {
364 return nil, fmt.Errorf("not enought data for stringToG1")
365 }
366 h = h[:2]
367 hexa := false
368 if len(h[0]) > 1 {
369 if "0x" == h[0][:2] {
370 hexa = true
371 }
372 }
373 in := ""
374
375 var b []byte
376 var err error
377 if hexa {
378 for i := range h {
379 in += strings.TrimPrefix(h[i], "0x")
380 }
381 b, err = hex.DecodeString(in)
382 if err != nil {
383 return nil, err
384 }
385 } else {
386 // TODO TMP
387 // TODO use stringToBytes()
388 if h[0] == "1" {
389 h[0] = "0"
390 }
391 if h[1] == "1" {
392 h[1] = "0"
393 }
394 bi0, ok := new(big.Int).SetString(h[0], 10)
395 if !ok {
396 return nil, fmt.Errorf("error parsing stringToG1")
397 }
398 bi1, ok := new(big.Int).SetString(h[1], 10)
399 if !ok {
400 return nil, fmt.Errorf("error parsing stringToG1")
401 }
402 b0 := bi0.Bytes()
403 b1 := bi1.Bytes()
404 if len(b0) != 32 {
405 b0 = addZPadding(b0)
406 }
407 if len(b1) != 32 {
408 b1 = addZPadding(b1)
409 }
410
411 b = append(b, b0...)
412 b = append(b, b1...)
413 }
414 p := new(bn256.G1)
415 _, err = p.Unmarshal(b)
416
417 return p, err
418}
419
420func stringToG2(h [][]string) (*bn256.G2, error) {
421 if len(h) <= 2 {
422 return nil, fmt.Errorf("not enought data for stringToG2")
423 }
424 h = h[:2]
425 hexa := false
426 if len(h[0][0]) > 1 {
427 if "0x" == h[0][0][:2] {
428 hexa = true
429 }
430 }
431 in := ""
432 var b []byte
433 var err error
434 if hexa {
435 for i := 0; i < len(h); i++ {
436 for j := 0; j < len(h[i]); j++ {
437 in += strings.TrimPrefix(h[i][j], "0x")
438 }
439 }
440 b, err = hex.DecodeString(in)
441 if err != nil {
442 return nil, err
443 }
444 } else {
445 // TODO TMP
446 bH, err := stringToBytes(h[0][1])
447 if err != nil {
448 return nil, err
449 }
450 b = append(b, bH...)
451 bH, err = stringToBytes(h[0][0])
452 if err != nil {
453 return nil, err
454 }
455 b = append(b, bH...)
456 bH, err = stringToBytes(h[1][1])
457 if err != nil {
458 return nil, err
459 }
460 b = append(b, bH...)
461 bH, err = stringToBytes(h[1][0])
462 if err != nil {
463 return nil, err
464 }
465 b = append(b, bH...)
466 }
467
468 p := new(bn256.G2)
469 _, err = p.Unmarshal(b)
470 return p, err
471}
472
473// ProofStringToSmartContractFormat converts the ProofString to a ProofString in the SmartContract format in a ProofString structure
474func ProofStringToSmartContractFormat(s ProofString) ProofString {
475 var rs ProofString
476 rs.A = make([]string, 2)
477 rs.B = make([][]string, 2)
478 rs.B[0] = make([]string, 2)
479 rs.B[1] = make([]string, 2)
480 rs.C = make([]string, 2)
481
482 rs.A[0] = s.A[0]
483 rs.A[1] = s.A[1]
484 rs.B[0][0] = s.B[0][1]
485 rs.B[0][1] = s.B[0][0]
486 rs.B[1][0] = s.B[1][1]
487 rs.B[1][1] = s.B[1][0]
488 rs.C[0] = s.C[0]
489 rs.C[1] = s.C[1]
490 rs.Protocol = s.Protocol
491 return rs
492}
493
494// ProofToSmartContractFormat converts the *types.Proof to a ProofString in the SmartContract format in a ProofString structure
495func ProofToSmartContractFormat(p *types.Proof) ProofString {
496 s := ProofToString(p)
497 return ProofStringToSmartContractFormat(s)
498}
499
500// ProofToString converts the Proof to ProofString
501func ProofToString(p *types.Proof) ProofString {
502 var ps ProofString
503 ps.A = make([]string, 3)
504 ps.B = make([][]string, 3)
505 ps.B[0] = make([]string, 2)
506 ps.B[1] = make([]string, 2)
507 ps.B[2] = make([]string, 2)
508 ps.C = make([]string, 3)
509
510 a := p.A.Marshal()
511 ps.A[0] = new(big.Int).SetBytes(a[:32]).String()
512 ps.A[1] = new(big.Int).SetBytes(a[32:64]).String()
513 ps.A[2] = "1"
514
515 b := p.B.Marshal()
516 ps.B[0][1] = new(big.Int).SetBytes(b[:32]).String()
517 ps.B[0][0] = new(big.Int).SetBytes(b[32:64]).String()
518 ps.B[1][1] = new(big.Int).SetBytes(b[64:96]).String()
519 ps.B[1][0] = new(big.Int).SetBytes(b[96:128]).String()
520 ps.B[2][0] = "1"
521 ps.B[2][1] = "0"
522
523 c := p.C.Marshal()
524 ps.C[0] = new(big.Int).SetBytes(c[:32]).String()
525 ps.C[1] = new(big.Int).SetBytes(c[32:64]).String()
526 ps.C[2] = "1"
527
528 ps.Protocol = "groth"
529
530 return ps
531}
532
533// ProofToJson outputs the Proof i Json format
534func ProofToJson(p *types.Proof) ([]byte, error) {
535 ps := ProofToString(p)
536 return json.Marshal(ps)
537}
538
539// ProofToHex converts the Proof to ProofString with hexadecimal strings
540func ProofToHex(p *types.Proof) ProofString {
541 var ps ProofString
542 ps.A = make([]string, 3)
543 ps.B = make([][]string, 3)
544 ps.B[0] = make([]string, 2)
545 ps.B[1] = make([]string, 2)
546 ps.B[2] = make([]string, 2)
547 ps.C = make([]string, 3)
548
549 a := p.A.Marshal()
550 ps.A[0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(a[:32]).Bytes())
551 ps.A[1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(a[32:64]).Bytes())
552 ps.A[2] = "1"
553
554 b := p.B.Marshal()
555 ps.B[0][1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[:32]).Bytes())
556 ps.B[0][0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[32:64]).Bytes())
557 ps.B[1][1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[64:96]).Bytes())
558 ps.B[1][0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(b[96:128]).Bytes())
559 ps.B[2][0] = "1"
560 ps.B[2][1] = "0"
561
562 c := p.C.Marshal()
563 ps.C[0] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(c[:32]).Bytes())
564 ps.C[1] = "0x" + hex.EncodeToString(new(big.Int).SetBytes(c[32:64]).Bytes())
565 ps.C[2] = "1"
566
567 ps.Protocol = "groth"
568
569 return ps
570}
571
572// ProofToJsonHex outputs the Proof i Json format with hexadecimal strings
573func ProofToJsonHex(p *types.Proof) ([]byte, error) {
574 ps := ProofToHex(p)
575 return json.Marshal(ps)
576}
577
578// ParseWitnessBin parses binary file representation of the Witness into the Witness struct
579func ParseWitnessBin(f *os.File) (types.Witness, error) {
580 var w types.Witness
581 r := bufio.NewReader(f)
582 for {
583 b := make([]byte, 32)
584 n, err := r.Read(b)
585 if err == io.EOF {
586 return w, nil
587 } else if err != nil {
588 return nil, err
589 }
590 if n != 32 {
591 return nil, fmt.Errorf("error on value format, expected 32 bytes, got %v", n)
592 }
593 w = append(w, new(big.Int).SetBytes(swapEndianness(b[0:32])))
594 }
595}
596
597// swapEndianness swaps the order of the bytes in the slice.
598func swapEndianness(b []byte) []byte {
599 o := make([]byte, len(b))
600 for i := range b {
601 o[len(b)-1-i] = b[i]
602 }
603 return o
604}
605
606func readNBytes(r io.Reader, n int) ([]byte, error) {
607 b := make([]byte, n)
608 _, err := io.ReadFull(r, b)
609 if err != nil {
610 return b, err
611 }
612 return b, nil
613}
614
615// ParsePkBin parses binary file representation of the ProvingKey into the ProvingKey struct
616func ParsePkBin(f *os.File) (*types.Pk, error) {
617 o := 0
618 var pk types.Pk
619 r := bufio.NewReader(f)
620
621 b, err := readNBytes(r, 12)
622 if err != nil {
623 return nil, err
624 }
625 pk.NVars = int(binary.LittleEndian.Uint32(b[:4]))
626 pk.NPublic = int(binary.LittleEndian.Uint32(b[4:8]))
627 pk.DomainSize = int(binary.LittleEndian.Uint32(b[8:12]))
628 o += 12
629
630 b, err = readNBytes(r, 8)
631 if err != nil {
632 return nil, err
633 }
634 pPolsA := int(binary.LittleEndian.Uint32(b[:4]))
635 pPolsB := int(binary.LittleEndian.Uint32(b[4:8]))
636 o += 8
637
638 b, err = readNBytes(r, 20)
639 if err != nil {
640 return nil, err
641 }
642 pPointsA := int(binary.LittleEndian.Uint32(b[:4]))
643 pPointsB1 := int(binary.LittleEndian.Uint32(b[4:8]))
644 pPointsB2 := int(binary.LittleEndian.Uint32(b[8:12]))
645 pPointsC := int(binary.LittleEndian.Uint32(b[12:16]))
646 pPointsHExps := int(binary.LittleEndian.Uint32(b[16:20]))
647 o += 20
648
649 b, err = readNBytes(r, 64)
650 if err != nil {
651 return nil, err
652 }
653 pk.VkAlpha1 = new(bn256.G1)
654 _, err = pk.VkAlpha1.Unmarshal(fromMont1Q(b))
655 if err != nil {
656 return nil, err
657 }
658
659 b, err = readNBytes(r, 64)
660 if err != nil {
661 return nil, err
662 }
663 pk.VkBeta1 = new(bn256.G1)
664 _, err = pk.VkBeta1.Unmarshal(fromMont1Q(b))
665 if err != nil {
666 return nil, err
667 }
668
669 b, err = readNBytes(r, 64)
670 if err != nil {
671 return nil, err
672 }
673 pk.VkDelta1 = new(bn256.G1)
674 _, err = pk.VkDelta1.Unmarshal(fromMont1Q(b))
675 if err != nil {
676 return nil, err
677 }
678 b, err = readNBytes(r, 128)
679 if err != nil {
680 return nil, err
681 }
682 pk.VkBeta2 = new(bn256.G2)
683 _, err = pk.VkBeta2.Unmarshal(fromMont2Q(b))
684 if err != nil {
685 return nil, err
686 }
687 b, err = readNBytes(r, 128)
688 if err != nil {
689 return nil, err
690 }
691 pk.VkDelta2 = new(bn256.G2)
692 _, err = pk.VkDelta2.Unmarshal(fromMont2Q(b))
693 if err != nil {
694 return nil, err
695 }
696 o += 448
697 if o != pPolsA {
698 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsA, o)
699 }
700
701 // PolsA
702 for i := 0; i < pk.NVars; i++ {
703 b, err = readNBytes(r, 4)
704 if err != nil {
705 return nil, err
706 }
707 keysLength := int(binary.LittleEndian.Uint32(b[:4]))
708 o += 4
709 polsMap := make(map[int]*big.Int)
710 for j := 0; j < keysLength; j++ {
711 bK, err := readNBytes(r, 4)
712 if err != nil {
713 return nil, err
714 }
715 key := int(binary.LittleEndian.Uint32(bK[:4]))
716 o += 4
717
718 b, err := readNBytes(r, 32)
719 if err != nil {
720 return nil, err
721 }
722 polsMap[key] = new(big.Int).SetBytes(fromMont1R(b[:32]))
723 o += 32
724 }
725 pk.PolsA = append(pk.PolsA, polsMap)
726 }
727 if o != pPolsB {
728 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsB, o)
729 }
730 // PolsB
731 for i := 0; i < pk.NVars; i++ {
732 b, err = readNBytes(r, 4)
733 if err != nil {
734 return nil, err
735 }
736 keysLength := int(binary.LittleEndian.Uint32(b[:4]))
737 o += 4
738 polsMap := make(map[int]*big.Int)
739 for j := 0; j < keysLength; j++ {
740 bK, err := readNBytes(r, 4)
741 if err != nil {
742 return nil, err
743 }
744 key := int(binary.LittleEndian.Uint32(bK[:4]))
745 o += 4
746
747 b, err := readNBytes(r, 32)
748 if err != nil {
749 return nil, err
750 }
751 polsMap[key] = new(big.Int).SetBytes(fromMont1R(b[:32]))
752 o += 32
753 }
754 pk.PolsB = append(pk.PolsB, polsMap)
755 }
756 if o != pPointsA {
757 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsA, o)
758 }
759 // A
760 for i := 0; i < pk.NVars; i++ {
761 b, err = readNBytes(r, 64)
762 if err != nil {
763 return nil, err
764 }
765 p1 := new(bn256.G1)
766 _, err = p1.Unmarshal(fromMont1Q(b))
767 if err != nil {
768 return nil, err
769 }
770 pk.A = append(pk.A, p1)
771 o += 64
772 }
773 if o != pPointsB1 {
774 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB1, o)
775 }
776 // B1
777 for i := 0; i < pk.NVars; i++ {
778 b, err = readNBytes(r, 64)
779 if err != nil {
780 return nil, err
781 }
782 p1 := new(bn256.G1)
783 _, err = p1.Unmarshal(fromMont1Q(b))
784 if err != nil {
785 return nil, err
786 }
787 pk.B1 = append(pk.B1, p1)
788 o += 64
789 }
790 if o != pPointsB2 {
791 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB2, o)
792 }
793 // B2
794 for i := 0; i < pk.NVars; i++ {
795 b, err = readNBytes(r, 128)
796 if err != nil {
797 return nil, err
798 }
799 p2 := new(bn256.G2)
800 _, err = p2.Unmarshal(fromMont2Q(b))
801 if err != nil {
802 return nil, err
803 }
804 pk.B2 = append(pk.B2, p2)
805 o += 128
806 }
807 if o != pPointsC {
808 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsC, o)
809 }
810 // C
811 zb := make([]byte, 64)
812 z := new(bn256.G1)
813 _, err = z.Unmarshal(zb)
814 if err != nil {
815 return nil, err
816 }
817 pk.C = append(pk.C, z) // circom behaviour (3x null==["0", "0", "0"])
818 pk.C = append(pk.C, z)
819 pk.C = append(pk.C, z)
820 for i := pk.NPublic + 1; i < pk.NVars; i++ {
821 b, err = readNBytes(r, 64)
822 if err != nil {
823 return nil, err
824 }
825 p1 := new(bn256.G1)
826 _, err = p1.Unmarshal(fromMont1Q(b))
827 if err != nil {
828 return nil, err
829 }
830 pk.C = append(pk.C, p1)
831 o += 64
832 }
833 if o != pPointsHExps {
834 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsHExps, o)
835 }
836 // HExps
837 for i := 0; i < pk.DomainSize; i++ {
838 b, err = readNBytes(r, 64)
839 if err != nil {
840 return nil, err
841 }
842 p1 := new(bn256.G1)
843 _, err = p1.Unmarshal(fromMont1Q(b))
844 if err != nil {
845 return nil, err
846 }
847 pk.HExps = append(pk.HExps, p1)
848 }
849 return &pk, nil
850}
851
852func fromMont1Q(m []byte) []byte {
853 a := new(big.Int).SetBytes(swapEndianness(m[:32]))
854 b := new(big.Int).SetBytes(swapEndianness(m[32:64]))
855
856 x := coordFromMont(a, types.Q)
857 y := coordFromMont(b, types.Q)
858 if bytes.Equal(x.Bytes(), big.NewInt(1).Bytes()) {
859 x = big.NewInt(0)
860 }
861 if bytes.Equal(y.Bytes(), big.NewInt(1).Bytes()) {
862 y = big.NewInt(0)
863 }
864
865 xBytes := x.Bytes()
866 yBytes := y.Bytes()
867 if len(xBytes) != 32 {
868 xBytes = addZPadding(xBytes)
869 }
870 if len(yBytes) != 32 {
871 yBytes = addZPadding(yBytes)
872 }
873
874 var p []byte
875 p = append(p, xBytes...)
876 p = append(p, yBytes...)
877
878 return p
879}
880
881func fromMont2Q(m []byte) []byte {
882 a := new(big.Int).SetBytes(swapEndianness(m[:32]))
883 b := new(big.Int).SetBytes(swapEndianness(m[32:64]))
884 c := new(big.Int).SetBytes(swapEndianness(m[64:96]))
885 d := new(big.Int).SetBytes(swapEndianness(m[96:128]))
886
887 x := coordFromMont(a, types.Q)
888 y := coordFromMont(b, types.Q)
889 z := coordFromMont(c, types.Q)
890 t := coordFromMont(d, types.Q)
891
892 if bytes.Equal(x.Bytes(), big.NewInt(1).Bytes()) {
893 x = big.NewInt(0)
894 }
895 if bytes.Equal(y.Bytes(), big.NewInt(1).Bytes()) {
896 y = big.NewInt(0)
897 }
898 if bytes.Equal(z.Bytes(), big.NewInt(1).Bytes()) {
899 z = big.NewInt(0)
900 }
901 if bytes.Equal(t.Bytes(), big.NewInt(1).Bytes()) {
902 t = big.NewInt(0)
903 }
904
905 xBytes := x.Bytes()
906 yBytes := y.Bytes()
907 zBytes := z.Bytes()
908 tBytes := t.Bytes()
909 if len(xBytes) != 32 {
910 xBytes = addZPadding(xBytes)
911 }
912 if len(yBytes) != 32 {
913 yBytes = addZPadding(yBytes)
914 }
915 if len(zBytes) != 32 {
916 zBytes = addZPadding(zBytes)
917 }
918 if len(tBytes) != 32 {
919 tBytes = addZPadding(tBytes)
920 }
921
922 var p []byte
923 p = append(p, yBytes...) // swap
924 p = append(p, xBytes...)
925 p = append(p, tBytes...)
926 p = append(p, zBytes...)
927
928 return p
929}
930
931func fromMont1R(m []byte) []byte {
932 a := new(big.Int).SetBytes(swapEndianness(m[:32]))
933
934 x := coordFromMont(a, types.R)
935
936 return x.Bytes()
937}
938
939func fromMont2R(m []byte) []byte {
940 a := new(big.Int).SetBytes(swapEndianness(m[:32]))
941 b := new(big.Int).SetBytes(swapEndianness(m[32:64]))
942 c := new(big.Int).SetBytes(swapEndianness(m[64:96]))
943 d := new(big.Int).SetBytes(swapEndianness(m[96:128]))
944
945 x := coordFromMont(a, types.R)
946 y := coordFromMont(b, types.R)
947 z := coordFromMont(c, types.R)
948 t := coordFromMont(d, types.R)
949
950 var p []byte
951 p = append(p, y.Bytes()...) // swap
952 p = append(p, x.Bytes()...)
953 p = append(p, t.Bytes()...)
954 p = append(p, z.Bytes()...)
955
956 return p
957}
958
959func coordFromMont(u, q *big.Int) *big.Int {
960 return new(big.Int).Mod(
961 new(big.Int).Mul(
962 u,
963 new(big.Int).ModInverse(
964 new(big.Int).Lsh(big.NewInt(1), 256),
965 q,
966 ),
967 ),
968 q,
969 )
970}
971
972// PkToGoBin converts the ProvingKey (*types.Pk) into binary format defined by
973// go-circom-prover-verifier. PkGoBin is a own go-circom-prover-verifier
974// binary format that allows to go faster when parsing.
975func PkToGoBin(pk *types.Pk) ([]byte, error) {
976 var r []byte
977 o := 0
978 var b [4]byte
979 binary.LittleEndian.PutUint32(b[:], uint32(pk.NVars))
980 r = append(r, b[:]...)
981
982 binary.LittleEndian.PutUint32(b[:], uint32(pk.NPublic))
983 r = append(r, b[:]...)
984
985 binary.LittleEndian.PutUint32(b[:], uint32(pk.DomainSize))
986 r = append(r, b[:]...)
987 o += 12
988
989 // reserve space for pols (A, B) pos
990 b = [4]byte{}
991 r = append(r, b[:]...) // 12:16
992 r = append(r, b[:]...) // 16:20
993 o += 8
994 // reserve space for points (A, B1, B2, C, HExps) pos
995 r = append(r, b[:]...) // 20:24
996 r = append(r, b[:]...) // 24
997 r = append(r, b[:]...) // 28
998 r = append(r, b[:]...) // 32
999 r = append(r, b[:]...) // 36:40
1000 o += 20
1001
1002 pb1 := pk.VkAlpha1.Marshal()
1003 r = append(r, pb1[:]...)
1004 pb1 = pk.VkBeta1.Marshal()
1005 r = append(r, pb1[:]...)
1006 pb1 = pk.VkDelta1.Marshal()
1007 r = append(r, pb1[:]...)
1008 pb2 := pk.VkBeta2.Marshal()
1009 r = append(r, pb2[:]...)
1010 pb2 = pk.VkDelta2.Marshal()
1011 r = append(r, pb2[:]...)
1012 o += 448
1013
1014 // polsA
1015 binary.LittleEndian.PutUint32(r[12:16], uint32(o))
1016 for i := 0; i < pk.NVars; i++ {
1017 binary.LittleEndian.PutUint32(b[:], uint32(len(pk.PolsA[i])))
1018 r = append(r, b[:]...)
1019 o += 4
1020 for j, v := range pk.PolsA[i] {
1021 binary.LittleEndian.PutUint32(b[:], uint32(j))
1022 r = append(r, b[:]...)
1023 r = append(r, addPadding32(v.Bytes())...)
1024 o += 32 + 4
1025 }
1026 }
1027 // polsB
1028 binary.LittleEndian.PutUint32(r[16:20], uint32(o))
1029 for i := 0; i < pk.NVars; i++ {
1030 binary.LittleEndian.PutUint32(b[:], uint32(len(pk.PolsB[i])))
1031 r = append(r, b[:]...)
1032 o += 4
1033 for j, v := range pk.PolsB[i] {
1034 binary.LittleEndian.PutUint32(b[:], uint32(j))
1035 r = append(r, b[:]...)
1036 r = append(r, addPadding32(v.Bytes())...)
1037 o += 32 + 4
1038 }
1039 }
1040 // A
1041 binary.LittleEndian.PutUint32(r[20:24], uint32(o))
1042 for i := 0; i < pk.NVars; i++ {
1043 pb1 = pk.A[i].Marshal()
1044 r = append(r, pb1[:]...)
1045 o += 64
1046 }
1047 // B1
1048 binary.LittleEndian.PutUint32(r[24:28], uint32(o))
1049 for i := 0; i < pk.NVars; i++ {
1050 pb1 = pk.B1[i].Marshal()
1051 r = append(r, pb1[:]...)
1052 o += 64
1053 }
1054 // B2
1055 binary.LittleEndian.PutUint32(r[28:32], uint32(o))
1056 for i := 0; i < pk.NVars; i++ {
1057 pb2 = pk.B2[i].Marshal()
1058 r = append(r, pb2[:]...)
1059 o += 128
1060 }
1061 // C
1062 binary.LittleEndian.PutUint32(r[32:36], uint32(o))
1063 for i := pk.NPublic + 1; i < pk.NVars; i++ {
1064 pb1 = pk.C[i].Marshal()
1065 r = append(r, pb1[:]...)
1066 o += 64
1067 }
1068 // HExps
1069 binary.LittleEndian.PutUint32(r[36:40], uint32(o))
1070 for i := 0; i < pk.DomainSize+1; i++ {
1071 pb1 = pk.HExps[i].Marshal()
1072 r = append(r, pb1[:]...)
1073 o += 64
1074 }
1075
1076 return r[:], nil
1077}
1078
1079// ParsePkGoBin parses go-circom-prover-verifier binary file representation of
1080// the ProvingKey into ProvingKey struct (*types.Pk). PkGoBin is a own
1081// go-circom-prover-verifier binary format that allows to go faster when
1082// parsing.
1083func ParsePkGoBin(f *os.File) (*types.Pk, error) {
1084 o := 0
1085 var pk types.Pk
1086 r := bufio.NewReader(f)
1087
1088 b, err := readNBytes(r, 12)
1089 if err != nil {
1090 return nil, err
1091 }
1092 pk.NVars = int(binary.LittleEndian.Uint32(b[:4]))
1093 pk.NPublic = int(binary.LittleEndian.Uint32(b[4:8]))
1094 pk.DomainSize = int(binary.LittleEndian.Uint32(b[8:12]))
1095 o += 12
1096
1097 b, err = readNBytes(r, 8)
1098 if err != nil {
1099 return nil, err
1100 }
1101 pPolsA := int(binary.LittleEndian.Uint32(b[:4]))
1102 pPolsB := int(binary.LittleEndian.Uint32(b[4:8]))
1103 o += 8
1104
1105 b, err = readNBytes(r, 20)
1106 if err != nil {
1107 return nil, err
1108 }
1109 pPointsA := int(binary.LittleEndian.Uint32(b[:4]))
1110 pPointsB1 := int(binary.LittleEndian.Uint32(b[4:8]))
1111 pPointsB2 := int(binary.LittleEndian.Uint32(b[8:12]))
1112 pPointsC := int(binary.LittleEndian.Uint32(b[12:16]))
1113 pPointsHExps := int(binary.LittleEndian.Uint32(b[16:20]))
1114 o += 20
1115
1116 b, err = readNBytes(r, 64)
1117 if err != nil {
1118 return nil, err
1119 }
1120 pk.VkAlpha1 = new(bn256.G1)
1121 _, err = pk.VkAlpha1.Unmarshal(b)
1122 if err != nil {
1123 return &pk, err
1124 }
1125 b, err = readNBytes(r, 64)
1126 if err != nil {
1127 return nil, err
1128 }
1129 pk.VkBeta1 = new(bn256.G1)
1130 _, err = pk.VkBeta1.Unmarshal(b)
1131 if err != nil {
1132 return &pk, err
1133 }
1134 b, err = readNBytes(r, 64)
1135 if err != nil {
1136 return nil, err
1137 }
1138 pk.VkDelta1 = new(bn256.G1)
1139 _, err = pk.VkDelta1.Unmarshal(b)
1140 if err != nil {
1141 return &pk, err
1142 }
1143 b, err = readNBytes(r, 128)
1144 if err != nil {
1145 return nil, err
1146 }
1147 pk.VkBeta2 = new(bn256.G2)
1148 _, err = pk.VkBeta2.Unmarshal(b)
1149 if err != nil {
1150 return &pk, err
1151 }
1152 b, err = readNBytes(r, 128)
1153 if err != nil {
1154 return nil, err
1155 }
1156 pk.VkDelta2 = new(bn256.G2)
1157 _, err = pk.VkDelta2.Unmarshal(b)
1158 if err != nil {
1159 return &pk, err
1160 }
1161 o += 448
1162 if o != pPolsA {
1163 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsA, o)
1164 }
1165
1166 // PolsA
1167 for i := 0; i < pk.NVars; i++ {
1168 b, err = readNBytes(r, 4)
1169 if err != nil {
1170 return nil, err
1171 }
1172 keysLength := int(binary.LittleEndian.Uint32(b[:4]))
1173 o += 4
1174 polsMap := make(map[int]*big.Int)
1175 for j := 0; j < keysLength; j++ {
1176 bK, err := readNBytes(r, 4)
1177 if err != nil {
1178 return nil, err
1179 }
1180 key := int(binary.LittleEndian.Uint32(bK[:4]))
1181 o += 4
1182
1183 b, err := readNBytes(r, 32)
1184 if err != nil {
1185 return nil, err
1186 }
1187 polsMap[key] = new(big.Int).SetBytes(b[:32])
1188 o += 32
1189 }
1190 pk.PolsA = append(pk.PolsA, polsMap)
1191 }
1192 if o != pPolsB {
1193 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPolsB, o)
1194 }
1195 // PolsB
1196 for i := 0; i < pk.NVars; i++ {
1197 b, err = readNBytes(r, 4)
1198 if err != nil {
1199 return nil, err
1200 }
1201 keysLength := int(binary.LittleEndian.Uint32(b[:4]))
1202 o += 4
1203 polsMap := make(map[int]*big.Int)
1204 for j := 0; j < keysLength; j++ {
1205 bK, err := readNBytes(r, 4)
1206 if err != nil {
1207 return nil, err
1208 }
1209 key := int(binary.LittleEndian.Uint32(bK[:4]))
1210 o += 4
1211
1212 b, err := readNBytes(r, 32)
1213 if err != nil {
1214 return nil, err
1215 }
1216 polsMap[key] = new(big.Int).SetBytes(b[:32])
1217 o += 32
1218 }
1219 pk.PolsB = append(pk.PolsB, polsMap)
1220 }
1221 if o != pPointsA {
1222 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsA, o)
1223 }
1224 // A
1225 for i := 0; i < pk.NVars; i++ {
1226 b, err = readNBytes(r, 64)
1227 if err != nil {
1228 return nil, err
1229 }
1230 p1 := new(bn256.G1)
1231 _, err = p1.Unmarshal(b)
1232 if err != nil {
1233 return nil, err
1234 }
1235 pk.A = append(pk.A, p1)
1236 o += 64
1237 }
1238 if o != pPointsB1 {
1239 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB1, o)
1240 }
1241 // B1
1242 for i := 0; i < pk.NVars; i++ {
1243 b, err = readNBytes(r, 64)
1244 if err != nil {
1245 return nil, err
1246 }
1247 p1 := new(bn256.G1)
1248 _, err = p1.Unmarshal(b)
1249 if err != nil {
1250 return nil, err
1251 }
1252 pk.B1 = append(pk.B1, p1)
1253 o += 64
1254 }
1255 if o != pPointsB2 {
1256 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsB2, o)
1257 }
1258 // B2
1259 for i := 0; i < pk.NVars; i++ {
1260 b, err = readNBytes(r, 128)
1261 if err != nil {
1262 return nil, err
1263 }
1264 p2 := new(bn256.G2)
1265 _, err = p2.Unmarshal(b)
1266 if err != nil {
1267 return nil, err
1268 }
1269 pk.B2 = append(pk.B2, p2)
1270 o += 128
1271 }
1272 if o != pPointsC {
1273 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsC, o)
1274 }
1275 // C
1276 zb := make([]byte, 64)
1277 z := new(bn256.G1)
1278 _, err = z.Unmarshal(zb)
1279 if err != nil {
1280 return nil, err
1281 }
1282 pk.C = append(pk.C, z)
1283 pk.C = append(pk.C, z)
1284 pk.C = append(pk.C, z)
1285 for i := pk.NPublic + 1; i < pk.NVars; i++ {
1286 b, err = readNBytes(r, 64)
1287 if err != nil {
1288 return nil, err
1289 }
1290 p1 := new(bn256.G1)
1291 _, err = p1.Unmarshal(b)
1292 if err != nil {
1293 return nil, err
1294 }
1295 pk.C = append(pk.C, p1)
1296 o += 64
1297 }
1298 if o != pPointsHExps {
1299 return nil, fmt.Errorf("Unexpected offset, expected: %v, actual: %v", pPointsHExps, o)
1300 }
1301 // HExps
1302 for i := 0; i < pk.DomainSize+1; i++ {
1303 b, err = readNBytes(r, 64)
1304 if err != nil {
1305 return nil, err
1306 }
1307 p1 := new(bn256.G1)
1308 _, err = p1.Unmarshal(b)
1309 if err != nil {
1310 return nil, err
1311 }
1312 pk.HExps = append(pk.HExps, p1)
1313 }
1314
1315 return &pk, nil
1316}