gnark-plonky2-verifier/plonky2_verifier/deserialize.go
plonky2_verifier/deserialize.goRaw
1package plonky2_verifier
2
3import (
4 "encoding/json"
5 . "gnark-plonky2-verifier/field"
6 "gnark-plonky2-verifier/utils"
7 "io/ioutil"
8 "os"
9)
10
11type ProofWithPublicInputsRaw struct {
12 Proof struct {
13 WiresCap []struct {
14 Elements []uint64 `json:"elements"`
15 } `json:"wires_cap"`
16 PlonkZsPartialProductsCap []struct {
17 Elements []uint64 `json:"elements"`
18 } `json:"plonk_zs_partial_products_cap"`
19 QuotientPolysCap []struct {
20 Elements []uint64 `json:"elements"`
21 } `json:"quotient_polys_cap"`
22 Openings struct {
23 Constants [][]uint64 `json:"constants"`
24 PlonkSigmas [][]uint64 `json:"plonk_sigmas"`
25 Wires [][]uint64 `json:"wires"`
26 PlonkZs [][]uint64 `json:"plonk_zs"`
27 PlonkZsNext [][]uint64 `json:"plonk_zs_next"`
28 PartialProducts [][]uint64 `json:"partial_products"`
29 QuotientPolys [][]uint64 `json:"quotient_polys"`
30 } `json:"openings"`
31 OpeningProof struct {
32 CommitPhaseMerkleCaps []MerkleCapsRaw `json:"commit_phase_merkle_caps"`
33 QueryRoundProofs []struct {
34 InitialTreesProof struct {
35 EvalsProofs []EvalProofRaw `json:"evals_proofs"`
36 } `json:"initial_trees_proof"`
37 Steps []struct {
38 Evals [][]uint64 `json:"evals"`
39 MerkleProof MerkleProofRaw `json:"merkle_proof"`
40 } `json:"steps"`
41 } `json:"query_round_proofs"`
42 FinalPoly struct {
43 Coeffs [][]uint64 `json:"coeffs"`
44 } `json:"final_poly"`
45 PowWitness uint64 `json:"pow_witness"`
46 } `json:"opening_proof"`
47 } `json:"proof"`
48 PublicInputs []uint64 `json:"public_inputs"`
49}
50
51type MerkleCapsRaw struct {
52 hashes [][]uint64
53}
54
55func (m *MerkleCapsRaw) UnmarshalJSON(data []byte) error {
56 var merkleCaps []map[string][]uint64
57 if err := json.Unmarshal(data, &merkleCaps); err != nil {
58 panic(err)
59 }
60
61 m.hashes = make([][]uint64, len(merkleCaps))
62 for i := 0; i < len(merkleCaps); i++ {
63 m.hashes[i] = merkleCaps[i]["elements"]
64 }
65 return nil
66}
67
68type EvalProofRaw struct {
69 leafElements []uint64
70 merkleProof MerkleProofRaw
71}
72
73func (e *EvalProofRaw) UnmarshalJSON(data []byte) error {
74 return json.Unmarshal(data, &[]interface{}{&e.leafElements, &e.merkleProof})
75}
76
77type MerkleProofRaw struct {
78 hash [][]uint64
79}
80
81func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error {
82 type SiblingObject struct {
83 Siblings []map[string][]uint64 // "siblings"
84 }
85
86 var siblings SiblingObject
87 if err := json.Unmarshal(data, &siblings); err != nil {
88 panic(err)
89 }
90
91 m.hash = make([][]uint64, len(siblings.Siblings))
92 for siblingIdx, sibling := range siblings.Siblings {
93 m.hash[siblingIdx] = sibling["elements"]
94 }
95
96 return nil
97}
98
99type CommonCircuitDataRaw struct {
100 Config struct {
101 NumWires uint64 `json:"num_wires"`
102 NumRoutedWires uint64 `json:"num_routed_wires"`
103 NumConstants uint64 `json:"num_constants"`
104 UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"`
105 SecurityBits uint64 `json:"security_bits"`
106 NumChallenges uint64 `json:"num_challenges"`
107 ZeroKnowledge bool `json:"zero_knowledge"`
108 MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"`
109 FriConfig struct {
110 RateBits uint64 `json:"rate_bits"`
111 CapHeight uint64 `json:"cap_height"`
112 ProofOfWorkBits uint64 `json:"proof_of_work_bits"`
113 ReductionStrategy struct {
114 ConstantArityBits []uint64 `json:"ConstantArityBits"`
115 } `json:"reduction_strategy"`
116 NumQueryRounds uint64 `json:"num_query_rounds"`
117 } `json:"fri_config"`
118 } `json:"config"`
119 FriParams struct {
120 Config struct {
121 RateBits uint64 `json:"rate_bits"`
122 CapHeight uint64 `json:"cap_height"`
123 ProofOfWorkBits uint64 `json:"proof_of_work_bits"`
124 ReductionStrategy struct {
125 ConstantArityBits []uint64 `json:"ConstantArityBits"`
126 } `json:"reduction_strategy"`
127 NumQueryRounds uint64 `json:"num_query_rounds"`
128 } `json:"config"`
129 Hiding bool `json:"hiding"`
130 DegreeBits uint64 `json:"degree_bits"`
131 ReductionArityBits []uint64 `json:"reduction_arity_bits"`
132 } `json:"fri_params"`
133 Gates []string `json:"gates"`
134 SelectorsInfo struct {
135 SelectorIndices []uint64 `json:"selector_indices"`
136 Groups []struct {
137 Start uint64 `json:"start"`
138 End uint64 `json:"end"`
139 } `json:"groups"`
140 } `json:"selectors_info"`
141 QuotientDegreeFactor uint64 `json:"quotient_degree_factor"`
142 NumGateConstraints uint64 `json:"num_gate_constraints"`
143 NumConstants uint64 `json:"num_constants"`
144 NumPublicInputs uint64 `json:"num_public_inputs"`
145 KIs []uint64 `json:"k_is"`
146 NumPartialProducts uint64 `json:"num_partial_products"`
147 CircuitDigest struct {
148 Elements []uint64 `json:"elements"`
149 } `json:"circuit_digest"`
150}
151
152type ProofChallengesRaw struct {
153 PlonkBetas []uint64 `json:"plonk_betas"`
154 PlonkGammas []uint64 `json:"plonk_gammas"`
155 PlonkAlphas []uint64 `json:"plonk_alphas"`
156 PlonkZeta []uint64 `json:"plonk_zeta"`
157 FriChallenges struct {
158 FriAlpha []uint64 `json:"fri_alpha"`
159 FriBetas [][]uint64 `json:"fri_betas"`
160 FriPowResponse uint64 `json:"fri_pow_response"`
161 FriQueryIndices []uint64 `json:"fri_query_indices"`
162 } `json:"fri_challenges"`
163}
164
165type VerifierOnlyCircuitDataRaw struct {
166 ConstantsSigmasCap []struct {
167 Elements []uint64 `json:"elements"`
168 } `json:"constants_sigmas_cap"`
169}
170
171func DeserializeMerkleCap(merkleCapRaw []struct{ Elements []uint64 }) MerkleCap {
172 n := len(merkleCapRaw)
173 merkleCap := make([]Hash, n)
174 for i := 0; i < n; i++ {
175 copy(merkleCap[i][:], utils.Uint64ArrayToFArray(merkleCapRaw[i].Elements))
176 }
177 return merkleCap
178}
179
180func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) MerkleProof {
181 n := len(merkleProofRaw.Siblings)
182 var mp MerkleProof
183 mp.Siblings = make([]Hash, n)
184 for i := 0; i < n; i++ {
185 element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 })
186 copy(mp.Siblings[i][:], utils.Uint64ArrayToFArray(element.Elements))
187 }
188 return mp
189}
190
191func DeserializeOpeningSet(openingSetRaw struct {
192 Constants [][]uint64
193 PlonkSigmas [][]uint64
194 Wires [][]uint64
195 PlonkZs [][]uint64
196 PlonkZsNext [][]uint64
197 PartialProducts [][]uint64
198 QuotientPolys [][]uint64
199}) OpeningSet {
200 return OpeningSet{
201 Constants: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants),
202 PlonkSigmas: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas),
203 Wires: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires),
204 PlonkZs: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs),
205 PlonkZsNext: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext),
206 PartialProducts: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts),
207 QuotientPolys: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys),
208 }
209}
210
211func DeserializeFriProof(openingProofRaw struct {
212 CommitPhaseMerkleCaps []MerkleCapsRaw
213 QueryRoundProofs []struct {
214 InitialTreesProof struct {
215 EvalsProofs []EvalProofRaw
216 }
217 Steps []struct {
218 Evals [][]uint64
219 MerkleProof MerkleProofRaw
220 }
221 }
222 FinalPoly struct {
223 Coeffs [][]uint64
224 }
225 PowWitness uint64
226}) FriProof {
227 var openingProof FriProof
228 openingProof.PowWitness = NewFieldElement(openingProofRaw.PowWitness)
229 openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
230
231 openingProof.CommitPhaseMerkleCaps = make([]MerkleCap, len(openingProofRaw.CommitPhaseMerkleCaps))
232 for i := 0; i < len(openingProofRaw.CommitPhaseMerkleCaps); i++ {
233 openingProof.CommitPhaseMerkleCaps[i] = utils.Uint64ArrayToHashArray(openingProofRaw.CommitPhaseMerkleCaps[i].hashes)
234 }
235
236 numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs)
237 openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs)
238
239 for i := 0; i < numQueryRoundProofs; i++ {
240 numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs)
241 openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]EvalProof, numEvalProofs)
242 for j := 0; j < numEvalProofs; j++ {
243 openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = utils.Uint64ArrayToFArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].leafElements)
244 openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = utils.Uint64ArrayToHashArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].merkleProof.hash)
245 }
246
247 numSteps := len(openingProofRaw.QueryRoundProofs[i].Steps)
248 openingProof.QueryRoundProofs[i].Steps = make([]FriQueryStep, numSteps)
249 for j := 0; j < numSteps; j++ {
250 openingProof.QueryRoundProofs[i].Steps[j].Evals = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.QueryRoundProofs[i].Steps[j].Evals)
251 openingProof.QueryRoundProofs[i].Steps[j].MerkleProof.Siblings = utils.Uint64ArrayToHashArray(openingProofRaw.QueryRoundProofs[i].Steps[j].MerkleProof.hash)
252 }
253 }
254
255 return openingProof
256}
257
258func DeserializeProofWithPublicInputs(path string) ProofWithPublicInputs {
259 jsonFile, err := os.Open(path)
260 if err != nil {
261 panic(err)
262 }
263
264 defer jsonFile.Close()
265 rawBytes, _ := ioutil.ReadAll(jsonFile)
266
267 var raw ProofWithPublicInputsRaw
268 err = json.Unmarshal(rawBytes, &raw)
269 if err != nil {
270 panic(err)
271 }
272
273 var proofWithPis ProofWithPublicInputs
274 proofWithPis.Proof.WiresCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.WiresCap))
275 proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.PlonkZsPartialProductsCap))
276 proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.QuotientPolysCap))
277 proofWithPis.Proof.Openings = DeserializeOpeningSet(struct {
278 Constants [][]uint64
279 PlonkSigmas [][]uint64
280 Wires [][]uint64
281 PlonkZs [][]uint64
282 PlonkZsNext [][]uint64
283 PartialProducts [][]uint64
284 QuotientPolys [][]uint64
285 }(raw.Proof.Openings))
286 proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
287 CommitPhaseMerkleCaps []MerkleCapsRaw
288 QueryRoundProofs []struct {
289 InitialTreesProof struct {
290 EvalsProofs []EvalProofRaw
291 }
292 Steps []struct {
293 Evals [][]uint64
294 MerkleProof MerkleProofRaw
295 }
296 }
297 FinalPoly struct{ Coeffs [][]uint64 }
298 PowWitness uint64
299 }(raw.Proof.OpeningProof))
300 proofWithPis.PublicInputs = utils.Uint64ArrayToFArray(raw.PublicInputs)
301
302 return proofWithPis
303}
304
305func DeserializeProofChallenges(path string) ProofChallenges {
306 jsonFile, err := os.Open(path)
307 if err != nil {
308 panic(err)
309 }
310
311 defer jsonFile.Close()
312 rawBytes, _ := ioutil.ReadAll(jsonFile)
313
314 var raw ProofChallengesRaw
315 err = json.Unmarshal(rawBytes, &raw)
316 if err != nil {
317 panic(err)
318 }
319
320 var proofChallenges ProofChallenges
321 proofChallenges.PlonkBetas = utils.Uint64ArrayToFArray(raw.PlonkBetas)
322 proofChallenges.PlonkGammas = utils.Uint64ArrayToFArray(raw.PlonkGammas)
323 proofChallenges.PlonkAlphas = utils.Uint64ArrayToFArray(raw.PlonkAlphas)
324 proofChallenges.PlonkZeta = utils.Uint64ArrayToQuadraticExtension(raw.PlonkZeta)
325 proofChallenges.FriChallenges.FriAlpha = utils.Uint64ArrayToQuadraticExtension(raw.FriChallenges.FriAlpha)
326 proofChallenges.FriChallenges.FriBetas = utils.Uint64ArrayToQuadraticExtensionArray(raw.FriChallenges.FriBetas)
327 proofChallenges.FriChallenges.FriPowResponse = NewFieldElement(raw.FriChallenges.FriPowResponse)
328 proofChallenges.FriChallenges.FriQueryIndices = utils.Uint64ArrayToFArray(raw.FriChallenges.FriQueryIndices)
329
330 return proofChallenges
331}
332
333func ReductionArityBits(
334 arityBits uint64,
335 finalPolyBits uint64,
336 degreeBits uint64,
337 rateBits uint64,
338 capHeight uint64,
339) []uint64 {
340 returnArr := make([]uint64, 0)
341
342 for degreeBits > finalPolyBits && degreeBits+rateBits-arityBits >= capHeight {
343 returnArr = append(returnArr, arityBits)
344 if degreeBits < arityBits {
345 panic("degreeBits < arityBits")
346 }
347 degreeBits -= arityBits
348 }
349
350 return returnArr
351}
352
353func DeserializeCommonCircuitData(path string) CommonCircuitData {
354 jsonFile, err := os.Open(path)
355 if err != nil {
356 panic(err)
357 }
358
359 defer jsonFile.Close()
360 rawBytes, _ := ioutil.ReadAll(jsonFile)
361
362 var raw CommonCircuitDataRaw
363 err = json.Unmarshal(rawBytes, &raw)
364 if err != nil {
365 panic(err)
366 }
367
368 var commonCircuitData CommonCircuitData
369 commonCircuitData.Config.NumWires = raw.Config.NumWires
370 commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires
371 commonCircuitData.Config.NumConstants = raw.Config.NumConstants
372 commonCircuitData.Config.UseBaseArithmeticGate = raw.Config.UseBaseArithmeticGate
373 commonCircuitData.Config.SecurityBits = raw.Config.SecurityBits
374 commonCircuitData.Config.NumChallenges = raw.Config.NumChallenges
375 commonCircuitData.Config.ZeroKnowledge = raw.Config.ZeroKnowledge
376 commonCircuitData.Config.MaxQuotientDegreeFactor = raw.Config.MaxQuotientDegreeFactor
377
378 commonCircuitData.Config.FriConfig.RateBits = raw.Config.FriConfig.RateBits
379 commonCircuitData.Config.FriConfig.CapHeight = raw.Config.FriConfig.CapHeight
380 commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits
381 commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds
382
383 commonCircuitData.FriParams.DegreeBits = raw.FriParams.DegreeBits
384 commonCircuitData.DegreeBits = raw.FriParams.DegreeBits
385 commonCircuitData.FriParams.Config.RateBits = raw.FriParams.Config.RateBits
386 commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight
387 commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits
388 commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds
389 commonCircuitData.FriParams.ReductionArityBits = raw.FriParams.ReductionArityBits
390
391 commonCircuitData.Gates = []gate{}
392 for _, gate := range raw.Gates {
393 commonCircuitData.Gates = append(commonCircuitData.Gates, GateInstanceFromId(gate))
394 }
395
396 commonCircuitData.SelectorsInfo.selectorIndices = raw.SelectorsInfo.SelectorIndices
397 commonCircuitData.SelectorsInfo.groups = []Range{}
398 for _, group := range raw.SelectorsInfo.Groups {
399 commonCircuitData.SelectorsInfo.groups = append(commonCircuitData.SelectorsInfo.groups, Range{
400 start: group.Start,
401 end: group.End,
402 })
403 }
404
405 commonCircuitData.QuotientDegreeFactor = raw.QuotientDegreeFactor
406 commonCircuitData.NumGateConstraints = raw.NumGateConstraints
407 commonCircuitData.NumConstants = raw.NumConstants
408 commonCircuitData.NumPublicInputs = raw.NumPublicInputs
409 commonCircuitData.KIs = utils.Uint64ArrayToFArray(raw.KIs)
410 commonCircuitData.NumPartialProducts = raw.NumPartialProducts
411 copy(commonCircuitData.CircuitDigest[:], utils.Uint64ArrayToFArray(raw.CircuitDigest.Elements))
412
413 return commonCircuitData
414}
415
416func DeserializeVerifierOnlyCircuitData(path string) VerifierOnlyCircuitData {
417 jsonFile, err := os.Open(path)
418 if err != nil {
419 panic(err)
420 }
421
422 defer jsonFile.Close()
423 rawBytes, _ := ioutil.ReadAll(jsonFile)
424
425 var raw VerifierOnlyCircuitDataRaw
426 err = json.Unmarshal(rawBytes, &raw)
427 if err != nil {
428 panic(err)
429 }
430
431 return VerifierOnlyCircuitData{
432 ConstantSigmasCap: DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.ConstantsSigmasCap)),
433 }
434}