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