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