gnark-plonky2-verifier/plonky2_verifier/fri.go
plonky2_verifier/fri.goRaw
1package plonky2_verifier
2
3import (
4 "fmt"
5 "gnark-ed25519/field"
6 . "gnark-ed25519/field"
7 "math"
8
9 "github.com/consensys/gnark/frontend"
10)
11
12type FriOpeningBatch struct {
13 values []QuadraticExtension
14}
15
16type FriOpenings struct {
17 Batches []FriOpeningBatch
18}
19
20func (c *OpeningSet) ToFriOpenings() FriOpenings {
21 values := c.Constants
22 values = append(values, c.PlonkSigmas...)
23 values = append(values, c.Wires...)
24 values = append(values, c.PlonkZs...)
25 values = append(values, c.PartialProducts...)
26 values = append(values, c.QuotientPolys...)
27 zetaBatch := FriOpeningBatch{values: values}
28 zetaNextBatch := FriOpeningBatch{values: c.PlonkZsNext}
29 return FriOpenings{Batches: []FriOpeningBatch{zetaBatch, zetaNextBatch}}
30}
31
32type FriChip struct {
33 api frontend.API
34 field frontend.API
35 qe *QuadraticExtensionAPI
36
37 friParams *FriParams
38 verifierOnlyCircuitData *VerifierOnlyCircuitData
39}
40
41func NewFriChip(api frontend.API, field frontend.API, qe *QuadraticExtensionAPI, friParams *FriParams) *FriChip {
42 return &FriChip{
43 api: api,
44 field: field,
45 qe: qe,
46 friParams: friParams,
47 }
48}
49
50func (f *FriChip) assertLeadingZeros(powWitness F, friConfig FriConfig) {
51 // Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros.
52 // Note that this is assuming that the Goldilocks field is being used. Specfically that the
53 // field is 64 bits long
54 maxPowWitness := uint64(math.Pow(2, float64(64-friConfig.ProofOfWorkBits))) - 1
55 f.field.Println(powWitness)
56 fmt.Println(maxPowWitness)
57 fmt.Println(friConfig.ProofOfWorkBits)
58 f.field.AssertIsLessOrEqual(powWitness, field.NewFieldElement(maxPowWitness))
59}
60
61func (f *FriChip) fromOpeningsAndAlpha(openings *FriOpenings, alpha QuadraticExtension) []QuadraticExtension {
62 // One reduced opening for all openings evaluated at point Zeta.
63 // Another one for all openings evaluated at point Zeta * Omega (which is only PlonkZsNext polynomial)
64
65 reducedOpenings := make([]QuadraticExtension, 0, 2)
66 for _, batch := range openings.Batches {
67 reducedOpenings = append(reducedOpenings, reduceWithPowers(f.qe, batch.values, alpha))
68 }
69
70 return reducedOpenings
71}
72
73func (f *FriChip) verifyMerkleProofToCap(leafData []F, leafIndex F, merkleCap MerkleCap, proof *MerkleProof) {
74}
75
76func (f *FriChip) verifyInitialProof(xIndex F, proof *FriInitialTreeProof, initialMerkleCaps []MerkleCap) {
77 if len(proof.EvalsProofs) != len(initialMerkleCaps) {
78 panic("length of eval proofs in fri proof should equal length of initial merkle caps")
79 }
80
81 for i := 0; i < len(initialMerkleCaps); i++ {
82 evals := proof.EvalsProofs[i].Elements
83 merkleProof := proof.EvalsProofs[i].MerkleProof
84 cap := initialMerkleCaps[i]
85 f.verifyMerkleProofToCap(evals, xIndex, cap, &merkleProof)
86 }
87}
88
89func (f *FriChip) verifyQueryRound(
90 challenges *FriChallenges,
91 precomputedReducedEval []QuadraticExtension,
92 initialMerkleCaps []MerkleCap,
93 proof *FriProof,
94 xIndex F,
95 n uint64,
96 roundProof *FriQueryRound,
97) {
98 f.verifyInitialProof(xIndex, &roundProof.InitialTreesProof, initialMerkleCaps)
99}
100
101func (f *FriChip) VerifyFriProof(
102 openings *FriOpenings,
103 friChallenges *FriChallenges,
104 initialMerkleCaps []MerkleCap,
105 friProof *FriProof,
106) {
107 // TODO: Check fri config
108 /* if let Some(max_arity_bits) = params.max_arity_bits() {
109 self.check_recursion_config::<C>(max_arity_bits);
110 }
111
112 debug_assert_eq!(
113 params.final_poly_len(),
114 proof.final_poly.len(),
115 "Final polynomial has wrong degree."
116 ); */
117
118 // Check POW
119 f.assertLeadingZeros(friProof.PowWitness, f.friParams.Config)
120
121 precomputedReducedEvals := f.fromOpeningsAndAlpha(openings, friChallenges.FriAlpha)
122
123 // Size of the LDE domain.
124 n := uint64(math.Pow(2, float64(f.friParams.DegreeBits+f.friParams.Config.RateBits)))
125
126 if len(friChallenges.FriQueryIndicies) != len(precomputedReducedEvals) {
127 panic("Number of queryRoundProofs should equal number of precomputedReducedEvals")
128 }
129
130 for idx, xIndex := range friChallenges.FriQueryIndicies {
131 roundProof := friProof.QueryRoundProofs[idx]
132
133 f.verifyQueryRound(
134 friChallenges,
135 precomputedReducedEvals,
136 initialMerkleCaps,
137 friProof,
138 xIndex,
139 n,
140 &roundProof,
141 )
142 }
143}