gnark-plonky2-verifier/plonky2_verifier/deserialize.go
plonky2_verifier/deserialize.goRaw
1package plonky2_verifier
2
3import (
4 "encoding/json"
5 . "gnark-ed25519/field"
6 "gnark-ed25519/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 []interface{} `json:"commit_phase_merkle_caps"`
33 QueryRoundProofs []struct {
34 InitialTreesProof struct {
35 EvalsProofs []EvalProofRaw `json:"evals_proofs"`
36 } `json:"initial_trees_proof"`
37 Steps []interface{} `json:"steps"`
38 } `json:"query_round_proofs"`
39 FinalPoly struct {
40 Coeffs [][]uint64 `json:"coeffs"`
41 } `json:"final_poly"`
42 PowWitness uint64 `json:"pow_witness"`
43 } `json:"opening_proof"`
44 } `json:"proof"`
45 PublicInputs []uint64 `json:"public_inputs"`
46}
47
48type EvalProofRaw struct {
49 leafElements []uint64
50 merkleProof MerkleProofRaw
51}
52
53func (e *EvalProofRaw) UnmarshalJSON(data []byte) error {
54 return json.Unmarshal(data, &[]interface{}{&e.leafElements, &e.merkleProof})
55}
56
57type MerkleProofRaw struct {
58 hash [][]uint64
59}
60
61func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error {
62 type SiblingObject struct {
63 Siblings []map[string][]uint64 // "siblings"
64 }
65
66 var siblings SiblingObject
67 if err := json.Unmarshal(data, &siblings); err != nil {
68 panic(err)
69 }
70
71 m.hash = make([][]uint64, len(siblings.Siblings))
72 for siblingIdx, sibling := range siblings.Siblings {
73 m.hash[siblingIdx] = sibling["elements"]
74 }
75
76 return nil
77}
78
79type CommonCircuitDataRaw struct {
80 Config struct {
81 NumWires uint64 `json:"num_wires"`
82 NumRoutedWires uint64 `json:"num_routed_wires"`
83 NumConstants uint64 `json:"num_constants"`
84 UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"`
85 SecurityBits uint64 `json:"security_bits"`
86 NumChallenges uint64 `json:"num_challenges"`
87 ZeroKnowledge bool `json:"zero_knowledge"`
88 MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"`
89 FriConfig struct {
90 RateBits uint64 `json:"rate_bits"`
91 CapHeight uint64 `json:"cap_height"`
92 ProofOfWorkBits uint64 `json:"proof_of_work_bits"`
93 ReductionStrategy struct {
94 ConstantArityBits []int `json:"ConstantArityBits"`
95 } `json:"reduction_strategy"`
96 NumQueryRounds uint64 `json:"num_query_rounds"`
97 } `json:"fri_config"`
98 } `json:"config"`
99 FriParams struct {
100 Config struct {
101 RateBits uint64 `json:"rate_bits"`
102 CapHeight uint64 `json:"cap_height"`
103 ProofOfWorkBits uint64 `json:"proof_of_work_bits"`
104 ReductionStrategy struct {
105 ConstantArityBits []uint64 `json:"ConstantArityBits"`
106 } `json:"reduction_strategy"`
107 NumQueryRounds uint64 `json:"num_query_rounds"`
108 } `json:"config"`
109 Hiding bool `json:"hiding"`
110 DegreeBits uint64 `json:"degree_bits"`
111 ReductionArityBits []interface{} `json:"reduction_arity_bits"`
112 } `json:"fri_params"`
113 DegreeBits uint64 `json:"degree_bits"`
114 SelectorsInfo struct {
115 SelectorIndices []uint64 `json:"selector_indices"`
116 Groups []struct {
117 Start uint64 `json:"start"`
118 End uint64 `json:"end"`
119 } `json:"groups"`
120 } `json:"selectors_info"`
121 QuotientDegreeFactor uint64 `json:"quotient_degree_factor"`
122 NumGateConstraints uint64 `json:"num_gate_constraints"`
123 NumConstants uint64 `json:"num_constants"`
124 NumPublicInputs uint64 `json:"num_public_inputs"`
125 KIs []uint64 `json:"k_is"`
126 NumPartialProducts uint64 `json:"num_partial_products"`
127 CircuitDigest struct {
128 Elements []uint64 `json:"elements"`
129 } `json:"circuit_digest"`
130}
131
132type VerifierOnlyCircuitDataRaw struct {
133 ConstantsSigmasCap []struct {
134 Elements []uint64 `json:"elements"`
135 } `json:"constants_sigmas_cap"`
136}
137
138func DeserializeMerkleCap(merkleCapRaw []struct{ Elements []uint64 }) MerkleCap {
139 n := len(merkleCapRaw)
140 merkleCap := make([]Hash, n)
141 for i := 0; i < n; i++ {
142 copy(merkleCap[i][:], utils.Uint64ArrayToFArray(merkleCapRaw[i].Elements))
143 }
144 return merkleCap
145}
146
147func DeserializeMerkleProof(merkleProofRaw struct{ Siblings []interface{} }) MerkleProof {
148 n := len(merkleProofRaw.Siblings)
149 var mp MerkleProof
150 mp.Siblings = make([]Hash, n)
151 for i := 0; i < n; i++ {
152 element := merkleProofRaw.Siblings[i].(struct{ Elements []uint64 })
153 copy(mp.Siblings[i][:], utils.Uint64ArrayToFArray(element.Elements))
154 }
155 return mp
156}
157
158func DeserializeOpeningSet(openingSetRaw struct {
159 Constants [][]uint64
160 PlonkSigmas [][]uint64
161 Wires [][]uint64
162 PlonkZs [][]uint64
163 PlonkZsNext [][]uint64
164 PartialProducts [][]uint64
165 QuotientPolys [][]uint64
166}) OpeningSet {
167 return OpeningSet{
168 Constants: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Constants),
169 PlonkSigmas: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkSigmas),
170 Wires: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.Wires),
171 PlonkZs: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZs),
172 PlonkZsNext: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PlonkZsNext),
173 PartialProducts: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.PartialProducts),
174 QuotientPolys: utils.Uint64ArrayToQuadraticExtensionArray(openingSetRaw.QuotientPolys),
175 }
176}
177
178func DeserializeFriProof(openingProofRaw struct {
179 CommitPhaseMerkleCaps []interface{}
180 QueryRoundProofs []struct {
181 InitialTreesProof struct {
182 EvalsProofs []EvalProofRaw
183 }
184 Steps []interface{}
185 }
186 FinalPoly struct {
187 Coeffs [][]uint64
188 }
189 PowWitness uint64
190}) FriProof {
191 var openingProof FriProof
192 openingProof.PowWitness = NewFieldElement(openingProofRaw.PowWitness)
193 openingProof.FinalPoly.Coeffs = utils.Uint64ArrayToQuadraticExtensionArray(openingProofRaw.FinalPoly.Coeffs)
194
195 numQueryRoundProofs := len(openingProofRaw.QueryRoundProofs)
196 openingProof.QueryRoundProofs = make([]FriQueryRound, numQueryRoundProofs)
197
198 for i := 0; i < numQueryRoundProofs; i++ {
199 numEvalProofs := len(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs)
200 openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs = make([]EvalProof, numEvalProofs)
201 for j := 0; j < numEvalProofs; j++ {
202 openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].Elements = utils.Uint64ArrayToFArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].leafElements)
203 openingProof.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].MerkleProof.Siblings = utils.Uint64ArrayToHashArray(openingProofRaw.QueryRoundProofs[i].InitialTreesProof.EvalsProofs[j].merkleProof.hash)
204 }
205 }
206
207 return openingProof
208}
209
210func DeserializeProofWithPublicInputs(path string) ProofWithPublicInputs {
211 jsonFile, err := os.Open(path)
212 if err != nil {
213 panic(err)
214 }
215
216 defer jsonFile.Close()
217 rawBytes, _ := ioutil.ReadAll(jsonFile)
218
219 var raw ProofWithPublicInputsRaw
220 err = json.Unmarshal(rawBytes, &raw)
221 if err != nil {
222 panic(err)
223 }
224
225 var proofWithPis ProofWithPublicInputs
226 proofWithPis.Proof.WiresCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.WiresCap))
227 proofWithPis.Proof.PlonkZsPartialProductsCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.PlonkZsPartialProductsCap))
228 proofWithPis.Proof.QuotientPolysCap = DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.Proof.QuotientPolysCap))
229 proofWithPis.Proof.Openings = DeserializeOpeningSet(struct {
230 Constants [][]uint64
231 PlonkSigmas [][]uint64
232 Wires [][]uint64
233 PlonkZs [][]uint64
234 PlonkZsNext [][]uint64
235 PartialProducts [][]uint64
236 QuotientPolys [][]uint64
237 }(raw.Proof.Openings))
238 proofWithPis.Proof.OpeningProof = DeserializeFriProof(struct {
239 CommitPhaseMerkleCaps []interface{}
240 QueryRoundProofs []struct {
241 InitialTreesProof struct {
242 EvalsProofs []EvalProofRaw
243 }
244 Steps []interface{}
245 }
246 FinalPoly struct{ Coeffs [][]uint64 }
247 PowWitness uint64
248 }(raw.Proof.OpeningProof))
249 proofWithPis.PublicInputs = utils.Uint64ArrayToFArray(raw.PublicInputs)
250
251 return proofWithPis
252}
253
254func ReductionArityBits(
255 arityBits uint64,
256 finalPolyBits uint64,
257 degreeBits uint64,
258 rateBits uint64,
259 capHeight uint64,
260 numQueries uint64,
261) []uint64 {
262 returnArr := make([]uint64, 0)
263
264 for degreeBits > finalPolyBits && degreeBits+rateBits-arityBits >= capHeight {
265 returnArr = append(returnArr, arityBits)
266 if degreeBits < arityBits {
267 panic("degreeBits < arityBits")
268 }
269 degreeBits -= arityBits
270 }
271
272 return returnArr
273}
274
275func DeserializeCommonCircuitData(path string) CommonCircuitData {
276 jsonFile, err := os.Open(path)
277 if err != nil {
278 panic(err)
279 }
280
281 defer jsonFile.Close()
282 rawBytes, _ := ioutil.ReadAll(jsonFile)
283
284 var raw CommonCircuitDataRaw
285 err = json.Unmarshal(rawBytes, &raw)
286 if err != nil {
287 panic(err)
288 }
289
290 var commonCircuitData CommonCircuitData
291 commonCircuitData.Config.NumWires = raw.Config.NumWires
292 commonCircuitData.Config.NumRoutedWires = raw.Config.NumRoutedWires
293 commonCircuitData.Config.NumConstants = raw.Config.NumConstants
294 commonCircuitData.Config.UseBaseArithmeticGate = raw.Config.UseBaseArithmeticGate
295 commonCircuitData.Config.SecurityBits = raw.Config.SecurityBits
296 commonCircuitData.Config.NumChallenges = raw.Config.NumChallenges
297 commonCircuitData.Config.ZeroKnowledge = raw.Config.ZeroKnowledge
298 commonCircuitData.Config.MaxQuotientDegreeFactor = raw.Config.MaxQuotientDegreeFactor
299
300 commonCircuitData.Config.FriConfig.RateBits = raw.Config.FriConfig.RateBits
301 commonCircuitData.Config.FriConfig.CapHeight = raw.Config.FriConfig.CapHeight
302 commonCircuitData.Config.FriConfig.ProofOfWorkBits = raw.Config.FriConfig.ProofOfWorkBits
303 commonCircuitData.Config.FriConfig.NumQueryRounds = raw.Config.FriConfig.NumQueryRounds
304
305 commonCircuitData.FriParams.DegreeBits = raw.FriParams.DegreeBits
306 commonCircuitData.FriParams.Config.RateBits = raw.FriParams.Config.RateBits
307 commonCircuitData.FriParams.Config.CapHeight = raw.FriParams.Config.CapHeight
308 commonCircuitData.FriParams.Config.ProofOfWorkBits = raw.FriParams.Config.ProofOfWorkBits
309 commonCircuitData.FriParams.Config.NumQueryRounds = raw.FriParams.Config.NumQueryRounds
310 commonCircuitData.FriParams.ReductionArityBits = ReductionArityBits(
311 raw.FriParams.ReductionArityBits[0].(uint64),
312 raw.FriParams.ReductionArityBits[1].(uint64),
313 raw.FriParams.DegreeBits,
314 raw.FriParams.Config.RateBits,
315 raw.FriParams.Config.CapHeight,
316 raw.FriParams.Config.NumQueryRounds,
317 )
318
319 commonCircuitData.DegreeBits = raw.DegreeBits
320 commonCircuitData.QuotientDegreeFactor = raw.QuotientDegreeFactor
321 commonCircuitData.NumGateConstraints = raw.NumGateConstraints
322 commonCircuitData.NumConstants = raw.NumConstants
323 commonCircuitData.NumPublicInputs = raw.NumPublicInputs
324 commonCircuitData.KIs = utils.Uint64ArrayToFArray(raw.KIs)
325 commonCircuitData.NumPartialProducts = raw.NumPartialProducts
326 copy(commonCircuitData.CircuitDigest[:], utils.Uint64ArrayToFArray(raw.CircuitDigest.Elements))
327
328 return commonCircuitData
329}
330
331func DeserializeVerifierOnlyCircuitData(path string) VerifierOnlyCircuitData {
332 jsonFile, err := os.Open(path)
333 if err != nil {
334 panic(err)
335 }
336
337 defer jsonFile.Close()
338 rawBytes, _ := ioutil.ReadAll(jsonFile)
339
340 var raw VerifierOnlyCircuitDataRaw
341 err = json.Unmarshal(rawBytes, &raw)
342 if err != nil {
343 panic(err)
344 }
345
346 return VerifierOnlyCircuitData{
347 ConstantSigmasCap: DeserializeMerkleCap([]struct{ Elements []uint64 }(raw.ConstantsSigmasCap)),
348 }
349}