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