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}