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