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// ProvingKeyString is the equivalent to the ProvingKey struct in string representation
 16type ProvingKeyString 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        [3]string    `json:"pi_a"`
 41	B        [3][2]string `json:"pi_b"`
 42	C        [3]string    `json:"pi_c"`
 43	Protocol string       `json:"protocol"`
 44}
 45
 46// ParseWitness parses the json []byte data into the Witness struct
 47func ParseWitness(wJson []byte) (Witness, error) {
 48	var ws WitnessString
 49	err := json.Unmarshal(wJson, &ws)
 50	if err != nil {
 51		return nil, err
 52	}
 53
 54	var w Witness
 55	for i := 0; i < len(ws); i++ {
 56		bi, err := stringToBigInt(ws[i])
 57		if err != nil {
 58			return nil, err
 59		}
 60		w = append(w, bi)
 61	}
 62	return w, nil
 63}
 64
 65// ParseProvingKey parses the json []byte data into the ProvingKey struct
 66func ParseProvingKey(pkJson []byte) (*ProvingKey, error) {
 67	var pkStr ProvingKeyString
 68	err := json.Unmarshal(pkJson, &pkStr)
 69	if err != nil {
 70		return nil, err
 71	}
 72	pk, err := provingKeyStringToProvingKey(pkStr)
 73	return pk, err
 74}
 75
 76func provingKeyStringToProvingKey(ps ProvingKeyString) (*ProvingKey, error) {
 77	var p ProvingKey
 78	var err error
 79
 80	p.A, err = arrayStringToG1(ps.A)
 81	if err != nil {
 82		return nil, err
 83	}
 84	p.B2, err = arrayStringToG2(ps.B2)
 85	if err != nil {
 86		return nil, err
 87	}
 88	p.B1, err = arrayStringToG1(ps.B1)
 89	if err != nil {
 90		return nil, err
 91	}
 92	p.C, err = arrayStringToG1(ps.C)
 93	if err != nil {
 94		return nil, err
 95	}
 96
 97	p.NVars = ps.NVars
 98	p.NPublic = ps.NPublic
 99
100	p.VkAlpha1, err = stringToG1(ps.VkAlpha1)
101	if err != nil {
102		return nil, err
103	}
104
105	p.VkDelta1, err = stringToG1(ps.VkDelta1)
106	if err != nil {
107		return nil, err
108	}
109
110	p.VkBeta1, err = stringToG1(ps.VkBeta1)
111	if err != nil {
112		return nil, err
113	}
114	p.VkBeta2, err = stringToG2(ps.VkBeta2)
115	if err != nil {
116		return nil, err
117	}
118	p.VkDelta2, err = stringToG2(ps.VkDelta2)
119	if err != nil {
120		return nil, err
121	}
122
123	p.HExps, err = arrayStringToG1(ps.HExps)
124	if err != nil {
125		return nil, err
126	}
127
128	p.DomainSize = ps.DomainSize
129
130	p.PolsA, err = polsStringToBigInt(ps.PolsA)
131	if err != nil {
132		return nil, err
133	}
134	p.PolsB, err = polsStringToBigInt(ps.PolsB)
135	if err != nil {
136		return nil, err
137	}
138	p.PolsC, err = polsStringToBigInt(ps.PolsC)
139	if err != nil {
140		return nil, err
141	}
142
143	return &p, nil
144}
145
146// polsStringToBigInt is for taking string polynomials and converting it to *big.Int polynomials
147func polsStringToBigInt(s []map[string]string) ([]map[int]*big.Int, error) {
148	var o []map[int]*big.Int
149	for i := 0; i < len(s); i++ {
150		// var oi map[int]*big.Int
151		oi := make(map[int]*big.Int)
152		for j, v := range s[i] {
153			si, err := stringToBigInt(v)
154			if err != nil {
155				return o, err
156			}
157			// oi = append(oi, si)
158			jInt, err := strconv.Atoi(j)
159			if err != nil {
160				return o, err
161			}
162			oi[jInt] = si
163		}
164		o = append(o, oi)
165	}
166	return o, nil
167}
168
169func arrayStringToBigInt(s []string) ([]*big.Int, error) {
170	var o []*big.Int
171	for i := 0; i < len(s); i++ {
172		si, err := stringToBigInt(s[i])
173		if err != nil {
174			return o, nil
175		}
176		o = append(o, si)
177	}
178	return o, nil
179}
180
181func stringToBigInt(s string) (*big.Int, error) {
182	base := 10
183	if bytes.HasPrefix([]byte(s), []byte("0x")) {
184		base = 16
185		s = strings.TrimPrefix(s, "0x")
186	}
187	n, ok := new(big.Int).SetString(s, base)
188	if !ok {
189		return nil, fmt.Errorf("Can not parse string to *big.Int: %s", s)
190	}
191	return n, nil
192}
193
194func addZPadding(b []byte) []byte {
195	var z [32]byte
196	var r []byte
197	r = append(r, z[len(b):]...) // add padding on the left
198	r = append(r, b...)
199	return r[:32]
200}
201
202func stringToBytes(s string) ([]byte, error) {
203	if s == "1" {
204		s = "0"
205	}
206	bi, ok := new(big.Int).SetString(s, 10)
207	if !ok {
208		return nil, fmt.Errorf("error parsing bigint stringToBytes")
209	}
210	b := bi.Bytes()
211	if len(b) != 32 {
212		b = addZPadding(b)
213	}
214	return b, nil
215
216}
217
218func arrayStringToG1(h [][]string) ([]*bn256.G1, error) {
219	var o []*bn256.G1
220	for i := 0; i < len(h); i++ {
221		hi, err := stringToG1(h[i])
222		if err != nil {
223			return o, err
224		}
225		o = append(o, hi)
226	}
227	return o, nil
228}
229
230func arrayStringToG2(h [][][]string) ([]*bn256.G2, error) {
231	var o []*bn256.G2
232	for i := 0; i < len(h); i++ {
233		hi, err := stringToG2(h[i])
234		if err != nil {
235			return o, err
236		}
237		o = append(o, hi)
238	}
239	return o, nil
240}
241
242func stringToG1(h []string) (*bn256.G1, error) {
243	if len(h) <= 2 {
244		return nil, fmt.Errorf("not enought data for stringToG1")
245	}
246	h = h[:2]
247	hexa := false
248	if len(h[0]) > 1 {
249		if "0x" == h[0][:2] {
250			hexa = true
251		}
252	}
253	in := ""
254
255	var b []byte
256	var err error
257	if hexa {
258		for i := range h {
259			in += strings.TrimPrefix(h[i], "0x")
260		}
261		b, err = hex.DecodeString(in)
262		if err != nil {
263			return nil, err
264		}
265	} else {
266		// TODO TMP
267		// TODO use stringToBytes()
268		if h[0] == "1" {
269			h[0] = "0"
270		}
271		if h[1] == "1" {
272			h[1] = "0"
273		}
274		bi0, ok := new(big.Int).SetString(h[0], 10)
275		if !ok {
276			return nil, fmt.Errorf("error parsing stringToG1")
277		}
278		bi1, ok := new(big.Int).SetString(h[1], 10)
279		if !ok {
280			return nil, fmt.Errorf("error parsing stringToG1")
281		}
282		b0 := bi0.Bytes()
283		b1 := bi1.Bytes()
284		if len(b0) != 32 {
285			b0 = addZPadding(b0)
286		}
287		if len(b1) != 32 {
288			b1 = addZPadding(b1)
289		}
290
291		b = append(b, b0...)
292		b = append(b, b1...)
293	}
294	p := new(bn256.G1)
295	_, err = p.Unmarshal(b)
296
297	return p, err
298}
299
300func stringToG2(h [][]string) (*bn256.G2, error) {
301	if len(h) <= 2 {
302		return nil, fmt.Errorf("not enought data for stringToG2")
303	}
304	h = h[:2]
305	hexa := false
306	if len(h[0][0]) > 1 {
307		if "0x" == h[0][0][:2] {
308			hexa = true
309		}
310	}
311	in := ""
312	var b []byte
313	var err error
314	if hexa {
315		for i := 0; i < len(h); i++ {
316			for j := 0; j < len(h[i]); j++ {
317				in += strings.TrimPrefix(h[i][j], "0x")
318			}
319		}
320		b, err = hex.DecodeString(in)
321		if err != nil {
322			return nil, err
323		}
324	} else {
325		// TODO TMP
326		bH, err := stringToBytes(h[0][1])
327		if err != nil {
328			return nil, err
329		}
330		b = append(b, bH...)
331		bH, err = stringToBytes(h[0][0])
332		if err != nil {
333			return nil, err
334		}
335		b = append(b, bH...)
336		bH, err = stringToBytes(h[1][1])
337		if err != nil {
338			return nil, err
339		}
340		b = append(b, bH...)
341		bH, err = stringToBytes(h[1][0])
342		if err != nil {
343			return nil, err
344		}
345		b = append(b, bH...)
346	}
347
348	p := new(bn256.G2)
349	_, err = p.Unmarshal(b)
350	return p, err
351}
352
353func proofToString(p *Proof) ([]byte, error) {
354	var ps ProofString
355
356	a := p.A.Marshal()
357	ps.A[0] = new(big.Int).SetBytes(a[:32]).String()
358	ps.A[1] = new(big.Int).SetBytes(a[32:64]).String()
359	ps.A[2] = "1"
360
361	b := p.B.Marshal()
362	ps.B[0][1] = new(big.Int).SetBytes(b[:32]).String()
363	ps.B[0][0] = new(big.Int).SetBytes(b[32:64]).String()
364	ps.B[1][1] = new(big.Int).SetBytes(b[64:96]).String()
365	ps.B[1][0] = new(big.Int).SetBytes(b[96:128]).String()
366	ps.B[2][0] = "1"
367	ps.B[2][1] = "0"
368
369	c := p.C.Marshal()
370	ps.C[0] = new(big.Int).SetBytes(c[:32]).String()
371	ps.C[1] = new(big.Int).SetBytes(c[32:64]).String()
372	ps.C[2] = "1"
373
374	ps.Protocol = "groth"
375
376	return json.Marshal(ps)
377}