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