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