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}