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