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