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