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