gnark-plonky2-verifier/verifier/internal/plonk/challenger_test.go
verifier/internal/plonk/challenger_test.goRaw
1package plonk
2
3import (
4 "math/big"
5 "testing"
6
7 "github.com/consensys/gnark/backend/groth16"
8 "github.com/consensys/gnark/frontend"
9 "github.com/consensys/gnark/frontend/cs/r1cs"
10 "github.com/consensys/gnark/test"
11 "github.com/succinctlabs/gnark-plonky2-verifier/field"
12 "github.com/succinctlabs/gnark-plonky2-verifier/poseidon"
13 "github.com/succinctlabs/gnark-plonky2-verifier/verifier/common"
14 "github.com/succinctlabs/gnark-plonky2-verifier/verifier/internal/fri"
15 "github.com/succinctlabs/gnark-plonky2-verifier/verifier/utils"
16)
17
18type TestChallengerCircuit struct {
19 commonCircuitDataFilename string `gnark:"-"`
20
21 CircuitDigest frontend.Variable `gnark:",public"`
22 PublicInputs []field.F `gnark:",public"`
23 WiresCap []frontend.Variable
24 PlonkZsPartialProductsCap []frontend.Variable
25 QuotientPolysCap []frontend.Variable
26 FriOpenings fri.FriOpenings
27 CommitPhaseMerkleCaps [][]frontend.Variable
28 FinalPoly common.PolynomialCoeffs
29 PowWitness field.F
30}
31
32func (circuit *TestChallengerCircuit) Define(api frontend.API) error {
33 commonCircuitData := utils.DeserializeCommonCircuitData(circuit.commonCircuitDataFilename)
34
35 config := commonCircuitData.Config
36 numChallenges := config.NumChallenges
37 fieldAPI := field.NewFieldAPI(api)
38 qeAPI := field.NewQuadraticExtensionAPI(api, fieldAPI)
39 poseidonChip := poseidon.NewPoseidonChip(api, fieldAPI, qeAPI)
40 poseidonBN128Chip := poseidon.NewPoseidonBN128Chip(api, fieldAPI)
41 challenger := NewChallengerChip(api, fieldAPI, poseidonChip, poseidonBN128Chip)
42
43 challenger.ObserveBN128Hash(circuit.CircuitDigest)
44 challenger.ObserveHash(poseidonChip.HashNoPad(circuit.PublicInputs))
45 challenger.ObserveCap(circuit.WiresCap)
46 plonkBetas := challenger.GetNChallenges(numChallenges)
47 plonkGammas := challenger.GetNChallenges(numChallenges)
48
49 challenger.ObserveCap(circuit.PlonkZsPartialProductsCap)
50 plonkAlphas := challenger.GetNChallenges(numChallenges)
51
52 challenger.ObserveCap(circuit.QuotientPolysCap)
53 plonkZeta := challenger.GetExtensionChallenge()
54
55 challenger.ObserveOpenings(circuit.FriOpenings)
56
57 friChallenges := challenger.GetFriChallenges(
58 circuit.CommitPhaseMerkleCaps,
59 circuit.FinalPoly,
60 circuit.PowWitness,
61 commonCircuitData.DegreeBits,
62 config.FriConfig,
63 )
64
65 expectedPlonkBetas := [2]field.F{
66 field.NewFieldConstFromString("17615363392879944733"),
67 field.NewFieldConstFromString("9422446877322953047"),
68 }
69
70 expectedPlonkGammas := [2]field.F{
71 field.NewFieldConstFromString("15174493176564484303"),
72 field.NewFieldConstFromString("6175150444166239851"),
73 }
74
75 for i := 0; i < 2; i++ {
76 fieldAPI.AssertIsEqual(plonkBetas[i], expectedPlonkBetas[i])
77 fieldAPI.AssertIsEqual(plonkGammas[i], expectedPlonkGammas[i])
78 }
79
80 expectedPlonkAlphas := [2]field.F{
81 field.NewFieldConstFromString("9276470834414745550"),
82 field.NewFieldConstFromString("5302812342351431915"),
83 }
84
85 for i := 0; i < 2; i++ {
86 fieldAPI.AssertIsEqual(plonkAlphas[i], expectedPlonkAlphas[i])
87 }
88
89 expectedPlonkZeta := field.QuadraticExtension{
90 field.NewFieldConstFromString("3892795992421241388"),
91 field.NewFieldConstFromString("15786647757418200302"),
92 }
93
94 for i := 0; i < 2; i++ {
95 fieldAPI.AssertIsEqual(plonkZeta[i], expectedPlonkZeta[i])
96 }
97
98 fieldAPI.AssertIsEqual(friChallenges.FriAlpha[0], field.NewFieldConst(885535811531859621))
99
100 fieldAPI.AssertIsEqual(friChallenges.FriBetas[0][0], field.NewFieldConst(5231781384587895507))
101
102 fieldAPI.AssertIsEqual(friChallenges.FriPowResponse, field.NewFieldConst(70715523064019))
103
104 fieldAPI.AssertIsEqual(friChallenges.FriQueryIndices[0], field.NewFieldConst(11890500485816111017))
105
106 return nil
107}
108
109func StringToBN128Hash(hashStr string) poseidon.PoseidonBN128HashOut {
110 hashBigInt, ok := new(big.Int).SetString(hashStr, 10)
111 if !(ok) {
112 panic("Invalid hash: " + hashStr)
113 }
114
115 hashVar := frontend.Variable(*hashBigInt)
116 return poseidon.PoseidonBN128HashOut(hashVar)
117}
118
119func TestChallengerWitness(t *testing.T) {
120 assert := test.NewAssert(t)
121
122 testCase := func() {
123 proofWithPis := utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json")
124 verifierData := utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json")
125
126 circuit := TestChallengerCircuit{
127 commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json",
128
129 CircuitDigest: verifierData.CircuitDigest,
130 PublicInputs: proofWithPis.PublicInputs,
131 WiresCap: proofWithPis.Proof.WiresCap,
132 PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
133 QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
134 FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
135 CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
136 FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
137 PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
138 }
139 witness := TestChallengerCircuit{
140 CircuitDigest: verifierData.CircuitDigest,
141 PublicInputs: proofWithPis.PublicInputs,
142 WiresCap: proofWithPis.Proof.WiresCap,
143 PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
144 QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
145 FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
146 CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
147 FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
148 PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
149 }
150 err := test.IsSolved(&circuit, &witness, field.TEST_CURVE.ScalarField())
151 assert.NoError(err)
152 }
153
154 testCase()
155}
156
157func TestChallengerProver(t *testing.T) {
158 proofWithPis := utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json")
159 verifierData := utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json")
160
161 circuit := TestChallengerCircuit{
162 commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json",
163
164 CircuitDigest: verifierData.CircuitDigest,
165 PublicInputs: proofWithPis.PublicInputs,
166 WiresCap: proofWithPis.Proof.WiresCap,
167 PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
168 QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
169 FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
170 CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
171 FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
172 PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
173 }
174
175 proofWithPis = utils.DeserializeProofWithPublicInputs("../../data/decode_block/proof_with_public_inputs.json")
176 verifierData = utils.DeserializeVerifierOnlyCircuitData("../../data/decode_block/verifier_only_circuit_data.json")
177
178 assignment := TestChallengerCircuit{
179 commonCircuitDataFilename: "../../data/decode_block/common_circuit_data.json",
180
181 CircuitDigest: verifierData.CircuitDigest,
182 PublicInputs: proofWithPis.PublicInputs,
183 WiresCap: proofWithPis.Proof.WiresCap,
184 PlonkZsPartialProductsCap: proofWithPis.Proof.PlonkZsPartialProductsCap,
185 QuotientPolysCap: proofWithPis.Proof.QuotientPolysCap,
186 FriOpenings: fri.ToFriOpenings(proofWithPis.Proof.Openings),
187 CommitPhaseMerkleCaps: proofWithPis.Proof.OpeningProof.CommitPhaseMerkleCaps,
188 FinalPoly: proofWithPis.Proof.OpeningProof.FinalPoly,
189 PowWitness: proofWithPis.Proof.OpeningProof.PowWitness,
190 }
191
192 r1cs, err := frontend.Compile(field.TEST_CURVE.ScalarField(), r1cs.NewBuilder, &circuit)
193 if err != nil {
194 panic(err)
195 }
196
197 println("num constraints is ", r1cs.GetNbConstraints())
198
199 assert := test.NewAssert(t)
200 err = test.IsSolved(&circuit, &assignment, field.TEST_CURVE.ScalarField())
201 assert.NoError(err)
202
203 witness, err := frontend.NewWitness(&assignment, field.TEST_CURVE.ScalarField())
204 if err != nil {
205 panic(err)
206 }
207
208 pk, vk, err := groth16.Setup(r1cs)
209 if err != nil {
210 panic(err)
211 }
212
213 proof, err := groth16.Prove(r1cs, pk, witness)
214 if err != nil {
215 panic(err)
216 }
217
218 publicWitness, err := witness.Public()
219 if err != nil {
220 panic(err)
221 }
222
223 err = groth16.Verify(proof, vk, publicWitness)
224 if err != nil {
225 panic(err)
226 }
227}