arnaucube
arnaucube/go-circom-prover-verifierPublic Self-hosted repository
go-circom-prover-verifier/parsers/parsers.go
parsers/parsers.goRaw
  1package parsers
  2
  3import (
  4	"bytes"
  5	"encoding/hex"
  6	"encoding/json"
  7	"fmt"
  8	"math/big"
  9	"strconv"
 10	"strings"
 11
 12	bn256 "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare"
 13	"github.com/iden3/go-circom-prover-verifier/types"
 14)
 15
 16// PkString is the equivalent to the Pk struct in string representation, containing the ProvingKey
 17type PkString struct {
 18	A          [][]string          `json:"A"`
 19	B2         [][][]string        `json:"B2"`
 20	B1         [][]string          `json:"B1"`
 21	C          [][]string          `json:"C"`
 22	NVars      int                 `json:"nVars"`
 23	NPublic    int                 `json:"nPublic"`
 24	VkAlpha1   []string            `json:"vk_alfa_1"`
 25	VkDelta1   []string            `json:"vk_delta_1"`
 26	VkBeta1    []string            `json:"vk_beta_1"`
 27	VkBeta2    [][]string          `json:"vk_beta_2"`
 28	VkDelta2   [][]string          `json:"vk_delta_2"`
 29	HExps      [][]string          `json:"hExps"`
 30	DomainSize int                 `json:"domainSize"`
 31	PolsA      []map[string]string `json:"polsA"`
 32	PolsB      []map[string]string `json:"polsB"`
 33	PolsC      []map[string]string `json:"polsC"`
 34}
 35
 36// WitnessString contains the Witness in string representation
 37type WitnessString []string
 38
 39// ProofString is the equivalent to the Proof struct in string representation
 40type ProofString struct {
 41	A        []string   `json:"pi_a"`
 42	B        [][]string `json:"pi_b"`
 43	C        []string   `json:"pi_c"`
 44	Protocol string     `json:"protocol"`
 45}
 46
 47// VkString is the Verification Key data structure in string format (from json)
 48type VkString struct {
 49	Alpha []string   `json:"vk_alfa_1"`
 50	Beta  [][]string `json:"vk_beta_2"`
 51	Gamma [][]string `json:"vk_gamma_2"`
 52	Delta [][]string `json:"vk_delta_2"`
 53	IC    [][]string `json:"IC"`
 54}
 55
 56// ParseWitness parses the json []byte data into the Witness struct
 57func ParseWitness(wJson []byte) (types.Witness, error) {
 58	var ws WitnessString
 59	err := json.Unmarshal(wJson, &ws)
 60	if err != nil {
 61		return nil, err
 62	}
 63
 64	var w types.Witness
 65	for i := 0; i < len(ws); i++ {
 66		bi, err := stringToBigInt(ws[i])
 67		if err != nil {
 68			return nil, err
 69		}
 70		w = append(w, bi)
 71	}
 72	return w, nil
 73}
 74
 75// ParsePk parses the json []byte data into the Pk struct
 76func ParsePk(pkJson []byte) (*types.Pk, error) {
 77	var pkStr PkString
 78	err := json.Unmarshal(pkJson, &pkStr)
 79	if err != nil {
 80		return nil, err
 81	}
 82	pk, err := pkStringToPk(pkStr)
 83	return pk, err
 84}
 85
 86func pkStringToPk(ps PkString) (*types.Pk, error) {
 87	var p types.Pk
 88	var err error
 89
 90	p.A, err = arrayStringToG1(ps.A)
 91	if err != nil {
 92		return nil, err
 93	}
 94	p.B2, err = arrayStringToG2(ps.B2)
 95	if err != nil {
 96		return nil, err
 97	}
 98	p.B1, err = arrayStringToG1(ps.B1)
 99	if err != nil {
100		return nil, err
101	}
102	p.C, err = arrayStringToG1(ps.C)
103	if err != nil {
104		return nil, err
105	}
106
107	p.NVars = ps.NVars
108	p.NPublic = ps.NPublic
109
110	p.VkAlpha1, err = stringToG1(ps.VkAlpha1)
111	if err != nil {
112		return nil, err
113	}
114
115	p.VkDelta1, err = stringToG1(ps.VkDelta1)
116	if err != nil {
117		return nil, err
118	}
119
120	p.VkBeta1, err = stringToG1(ps.VkBeta1)
121	if err != nil {
122		return nil, err
123	}
124	p.VkBeta2, err = stringToG2(ps.VkBeta2)
125	if err != nil {
126		return nil, err
127	}
128	p.VkDelta2, err = stringToG2(ps.VkDelta2)
129	if err != nil {
130		return nil, err
131	}
132
133	p.HExps, err = arrayStringToG1(ps.HExps)
134	if err != nil {
135		return nil, err
136	}
137
138	p.DomainSize = ps.DomainSize
139
140	p.PolsA, err = polsStringToBigInt(ps.PolsA)
141	if err != nil {
142		return nil, err
143	}
144	p.PolsB, err = polsStringToBigInt(ps.PolsB)
145	if err != nil {
146		return nil, err
147	}
148	p.PolsC, err = polsStringToBigInt(ps.PolsC)
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 addZPadding(b []byte) []byte {
309	var z [32]byte
310	var r []byte
311	r = append(r, z[len(b):]...) // add padding on the left
312	r = append(r, b...)
313	return r[:32]
314}
315
316func stringToBytes(s string) ([]byte, error) {
317	if s == "1" {
318		s = "0"
319	}
320	bi, ok := new(big.Int).SetString(s, 10)
321	if !ok {
322		return nil, fmt.Errorf("error parsing bigint stringToBytes")
323	}
324	b := bi.Bytes()
325	if len(b) != 32 {
326		b = addZPadding(b)
327	}
328	return b, nil
329
330}
331
332func arrayStringToG1(h [][]string) ([]*bn256.G1, error) {
333	var o []*bn256.G1
334	for i := 0; i < len(h); i++ {
335		hi, err := stringToG1(h[i])
336		if err != nil {
337			return o, err
338		}
339		o = append(o, hi)
340	}
341	return o, nil
342}
343
344func arrayStringToG2(h [][][]string) ([]*bn256.G2, error) {
345	var o []*bn256.G2
346	for i := 0; i < len(h); i++ {
347		hi, err := stringToG2(h[i])
348		if err != nil {
349			return o, err
350		}
351		o = append(o, hi)
352	}
353	return o, nil
354}
355
356func stringToG1(h []string) (*bn256.G1, error) {
357	if len(h) <= 2 {
358		return nil, fmt.Errorf("not enought data for stringToG1")
359	}
360	h = h[:2]
361	hexa := false
362	if len(h[0]) > 1 {
363		if "0x" == h[0][:2] {
364			hexa = true
365		}
366	}
367	in := ""
368
369	var b []byte
370	var err error
371	if hexa {
372		for i := range h {
373			in += strings.TrimPrefix(h[i], "0x")
374		}
375		b, err = hex.DecodeString(in)
376		if err != nil {
377			return nil, err
378		}
379	} else {
380		// TODO TMP
381		// TODO use stringToBytes()
382		if h[0] == "1" {
383			h[0] = "0"
384		}
385		if h[1] == "1" {
386			h[1] = "0"
387		}
388		bi0, ok := new(big.Int).SetString(h[0], 10)
389		if !ok {
390			return nil, fmt.Errorf("error parsing stringToG1")
391		}
392		bi1, ok := new(big.Int).SetString(h[1], 10)
393		if !ok {
394			return nil, fmt.Errorf("error parsing stringToG1")
395		}
396		b0 := bi0.Bytes()
397		b1 := bi1.Bytes()
398		if len(b0) != 32 {
399			b0 = addZPadding(b0)
400		}
401		if len(b1) != 32 {
402			b1 = addZPadding(b1)
403		}
404
405		b = append(b, b0...)
406		b = append(b, b1...)
407	}
408	p := new(bn256.G1)
409	_, err = p.Unmarshal(b)
410
411	return p, err
412}
413
414func stringToG2(h [][]string) (*bn256.G2, error) {
415	if len(h) <= 2 {
416		return nil, fmt.Errorf("not enought data for stringToG2")
417	}
418	h = h[:2]
419	hexa := false
420	if len(h[0][0]) > 1 {
421		if "0x" == h[0][0][:2] {
422			hexa = true
423		}
424	}
425	in := ""
426	var b []byte
427	var err error
428	if hexa {
429		for i := 0; i < len(h); i++ {
430			for j := 0; j < len(h[i]); j++ {
431				in += strings.TrimPrefix(h[i][j], "0x")
432			}
433		}
434		b, err = hex.DecodeString(in)
435		if err != nil {
436			return nil, err
437		}
438	} else {
439		// TODO TMP
440		bH, err := stringToBytes(h[0][1])
441		if err != nil {
442			return nil, err
443		}
444		b = append(b, bH...)
445		bH, err = stringToBytes(h[0][0])
446		if err != nil {
447			return nil, err
448		}
449		b = append(b, bH...)
450		bH, err = stringToBytes(h[1][1])
451		if err != nil {
452			return nil, err
453		}
454		b = append(b, bH...)
455		bH, err = stringToBytes(h[1][0])
456		if err != nil {
457			return nil, err
458		}
459		b = append(b, bH...)
460	}
461
462	p := new(bn256.G2)
463	_, err = p.Unmarshal(b)
464	return p, err
465}
466
467// ProofToJson outputs the Proof i Json format
468func ProofToJson(p *types.Proof) ([]byte, error) {
469	var ps ProofString
470	ps.A = make([]string, 3)
471	ps.B = make([][]string, 3)
472	ps.B[0] = make([]string, 2)
473	ps.B[1] = make([]string, 2)
474	ps.B[2] = make([]string, 2)
475	ps.C = make([]string, 3)
476
477	a := p.A.Marshal()
478	ps.A[0] = new(big.Int).SetBytes(a[:32]).String()
479	ps.A[1] = new(big.Int).SetBytes(a[32:64]).String()
480	ps.A[2] = "1"
481
482	b := p.B.Marshal()
483	ps.B[0][1] = new(big.Int).SetBytes(b[:32]).String()
484	ps.B[0][0] = new(big.Int).SetBytes(b[32:64]).String()
485	ps.B[1][1] = new(big.Int).SetBytes(b[64:96]).String()
486	ps.B[1][0] = new(big.Int).SetBytes(b[96:128]).String()
487	ps.B[2][0] = "1"
488	ps.B[2][1] = "0"
489
490	c := p.C.Marshal()
491	ps.C[0] = new(big.Int).SetBytes(c[:32]).String()
492	ps.C[1] = new(big.Int).SetBytes(c[32:64]).String()
493	ps.C[2] = "1"
494
495	ps.Protocol = "groth"
496
497	return json.Marshal(ps)
498}