mirror of
https://github.com/logos-storage/gnark-plonky2-verifier.git
synced 2026-01-07 07:33:12 +00:00
initial commit for fri verification chip
This commit is contained in:
parent
1d7f151cc1
commit
d194d3860f
@ -1,7 +1,12 @@
|
||||
package plonky2_verifier
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"gnark-ed25519/field"
|
||||
. "gnark-ed25519/field"
|
||||
"math"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
)
|
||||
|
||||
type FriOpeningBatch struct {
|
||||
@ -23,3 +28,116 @@ func (c *OpeningSet) ToFriOpenings() FriOpenings {
|
||||
zetaNextBatch := FriOpeningBatch{values: c.PlonkZsNext}
|
||||
return FriOpenings{Batches: []FriOpeningBatch{zetaBatch, zetaNextBatch}}
|
||||
}
|
||||
|
||||
type FriChip struct {
|
||||
api frontend.API
|
||||
field frontend.API
|
||||
qe *QuadraticExtensionAPI
|
||||
|
||||
friParams *FriParams
|
||||
verifierOnlyCircuitData *VerifierOnlyCircuitData
|
||||
}
|
||||
|
||||
func NewFriChip(api frontend.API, field frontend.API, qe *QuadraticExtensionAPI, friParams *FriParams) *FriChip {
|
||||
return &FriChip{
|
||||
api: api,
|
||||
field: field,
|
||||
qe: qe,
|
||||
friParams: friParams,
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FriChip) assertLeadingZeros(powWitness F, friConfig FriConfig) {
|
||||
// Asserts that powWitness'es big-endian bit representation has at least `leading_zeros` leading zeros.
|
||||
// Note that this is assuming that the Goldilocks field is being used. Specfically that the
|
||||
// field is 64 bits long
|
||||
maxPowWitness := uint64(math.Pow(2, float64(64-friConfig.ProofOfWorkBits))) - 1
|
||||
f.field.Println(powWitness)
|
||||
fmt.Println(maxPowWitness)
|
||||
fmt.Println(friConfig.ProofOfWorkBits)
|
||||
f.field.AssertIsLessOrEqual(powWitness, field.NewFieldElement(maxPowWitness))
|
||||
}
|
||||
|
||||
func (f *FriChip) fromOpeningsAndAlpha(openings *FriOpenings, alpha QuadraticExtension) []QuadraticExtension {
|
||||
// One reduced opening for all openings evaluated at point Zeta.
|
||||
// Another one for all openings evaluated at point Zeta * Omega (which is only PlonkZsNext polynomial)
|
||||
|
||||
reducedOpenings := make([]QuadraticExtension, 0, 2)
|
||||
for _, batch := range openings.Batches {
|
||||
reducedOpenings = append(reducedOpenings, reduceWithPowers(f.qe, batch.values, alpha))
|
||||
}
|
||||
|
||||
return reducedOpenings
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyMerkleProofToCap(leafData []F, leafIndex F, merkleCap MerkleCap, proof *MerkleProof) {
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyInitialProof(xIndex F, proof *FriInitialTreeProof, initialMerkleCaps []MerkleCap) {
|
||||
if len(proof.EvalsProofs) != len(initialMerkleCaps) {
|
||||
panic("length of eval proofs in fri proof should equal length of initial merkle caps")
|
||||
}
|
||||
|
||||
for i := 0; i < len(initialMerkleCaps); i++ {
|
||||
evals := proof.EvalsProofs[i].Elements
|
||||
merkleProof := proof.EvalsProofs[i].MerkleProof
|
||||
cap := initialMerkleCaps[i]
|
||||
f.verifyMerkleProofToCap(evals, xIndex, cap, &merkleProof)
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FriChip) verifyQueryRound(
|
||||
challenges *FriChallenges,
|
||||
precomputedReducedEval []QuadraticExtension,
|
||||
initialMerkleCaps []MerkleCap,
|
||||
proof *FriProof,
|
||||
xIndex F,
|
||||
n uint64,
|
||||
roundProof *FriQueryRound,
|
||||
) {
|
||||
f.verifyInitialProof(xIndex, &roundProof.InitialTreesProof, initialMerkleCaps)
|
||||
}
|
||||
|
||||
func (f *FriChip) VerifyFriProof(
|
||||
openings *FriOpenings,
|
||||
friChallenges *FriChallenges,
|
||||
initialMerkleCaps []MerkleCap,
|
||||
friProof *FriProof,
|
||||
) {
|
||||
// TODO: Check fri config
|
||||
/* if let Some(max_arity_bits) = params.max_arity_bits() {
|
||||
self.check_recursion_config::<C>(max_arity_bits);
|
||||
}
|
||||
|
||||
debug_assert_eq!(
|
||||
params.final_poly_len(),
|
||||
proof.final_poly.len(),
|
||||
"Final polynomial has wrong degree."
|
||||
); */
|
||||
|
||||
// Check POW
|
||||
f.assertLeadingZeros(friProof.PowWitness, f.friParams.Config)
|
||||
|
||||
precomputedReducedEvals := f.fromOpeningsAndAlpha(openings, friChallenges.FriAlpha)
|
||||
|
||||
// Size of the LDE domain.
|
||||
n := uint64(math.Pow(2, float64(f.friParams.DegreeBits+f.friParams.Config.RateBits)))
|
||||
|
||||
if len(friChallenges.FriQueryIndicies) != len(precomputedReducedEvals) {
|
||||
panic("Number of queryRoundProofs should equal number of precomputedReducedEvals")
|
||||
}
|
||||
|
||||
for idx, xIndex := range friChallenges.FriQueryIndicies {
|
||||
roundProof := friProof.QueryRoundProofs[idx]
|
||||
|
||||
f.verifyQueryRound(
|
||||
friChallenges,
|
||||
precomputedReducedEvals,
|
||||
initialMerkleCaps,
|
||||
friProof,
|
||||
xIndex,
|
||||
n,
|
||||
&roundProof,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
35
plonky2_verifier/fri_test.go
Normal file
35
plonky2_verifier/fri_test.go
Normal file
@ -0,0 +1,35 @@
|
||||
package plonky2_verifier
|
||||
|
||||
import (
|
||||
. "gnark-ed25519/field"
|
||||
"testing"
|
||||
|
||||
"github.com/consensys/gnark/frontend"
|
||||
"github.com/consensys/gnark/test"
|
||||
)
|
||||
|
||||
type TestFriCircuit struct{}
|
||||
|
||||
func (circuit *TestFriCircuit) Define(api frontend.API) error {
|
||||
proofWithPis := DeserializeProofWithPublicInputs("./data/fibonacci/proof_with_public_inputs.json")
|
||||
commonCircuitData := DeserializeCommonCircuitData("./data/fibonacci/common_circuit_data.json")
|
||||
|
||||
field := NewFieldAPI(api)
|
||||
|
||||
friChip := NewFriChip(api, field, commonCircuitData.Config.FriConfig)
|
||||
friChip.VerifyFriProof(&proofWithPis.Proof.OpeningProof)
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestFriProof(t *testing.T) {
|
||||
assert := test.NewAssert(t)
|
||||
|
||||
testCase := func() {
|
||||
circuit := TestFriCircuit{}
|
||||
witness := TestFriCircuit{}
|
||||
err := test.IsSolved(&circuit, &witness, TEST_CURVE.ScalarField())
|
||||
assert.NoError(err)
|
||||
}
|
||||
|
||||
testCase()
|
||||
}
|
||||
@ -180,22 +180,6 @@ func (p *PlonkChip) evalVanishingPoly(zetaPowN QuadraticExtension) []QuadraticEx
|
||||
return reducedValues
|
||||
}
|
||||
|
||||
func (p *PlonkChip) reduceWithPowers(terms []QuadraticExtension, scalar QuadraticExtension) QuadraticExtension {
|
||||
sum := p.qe.ZERO_QE
|
||||
|
||||
for i := len(terms) - 1; i >= 0; i-- {
|
||||
sum = p.qe.AddExtension(
|
||||
p.qe.MulExtension(
|
||||
sum,
|
||||
scalar,
|
||||
),
|
||||
terms[i],
|
||||
)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
|
||||
func (p *PlonkChip) Verify() {
|
||||
// Calculate zeta^n
|
||||
zetaPowN := p.expPowerOf2Extension(p.proofChallenges.PlonkZeta)
|
||||
@ -213,7 +197,8 @@ func (p *PlonkChip) Verify() {
|
||||
for i := 0; i < len(p.openings.QuotientPolys); i += int(p.commonData.QuotientDegreeFactor) {
|
||||
prod := p.qe.MulExtension(
|
||||
zHZeta,
|
||||
p.reduceWithPowers(
|
||||
reduceWithPowers(
|
||||
p.qe,
|
||||
p.openings.QuotientPolys[i:i+int(p.commonData.QuotientDegreeFactor)],
|
||||
zetaPowN,
|
||||
),
|
||||
|
||||
@ -35,7 +35,7 @@ type PolynomialCoeffs struct {
|
||||
|
||||
type FriProof struct {
|
||||
CommitPhaseMerkleCaps []MerkleCap
|
||||
QueryRoundProofs FriQueryRound
|
||||
QueryRoundProofs []FriQueryRound
|
||||
FinalPoly PolynomialCoeffs
|
||||
PowWitness F
|
||||
}
|
||||
|
||||
21
plonky2_verifier/utils.go
Normal file
21
plonky2_verifier/utils.go
Normal file
@ -0,0 +1,21 @@
|
||||
package plonky2_verifier
|
||||
|
||||
import (
|
||||
. "gnark-ed25519/field"
|
||||
)
|
||||
|
||||
func reduceWithPowers(qe *QuadraticExtensionAPI, terms []QuadraticExtension, scalar QuadraticExtension) QuadraticExtension {
|
||||
sum := qe.ZERO_QE
|
||||
|
||||
for i := len(terms) - 1; i >= 0; i-- {
|
||||
sum = qe.AddExtension(
|
||||
qe.MulExtension(
|
||||
sum,
|
||||
scalar,
|
||||
),
|
||||
terms[i],
|
||||
)
|
||||
}
|
||||
|
||||
return sum
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user