arnaucube
arnaucube/gnark-plonky2-verifierPublic Self-hosted repository
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.NewFieldElement(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.NewFieldElement(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}