2023-05-19 19:49:14 -07:00
package verifier
2022-10-10 16:41:42 -07:00
2022-10-10 20:45:34 -07:00
import (
2025-05-27 10:51:28 +02:00
"github.com/codex-storage/gnark-plonky2-verifier/challenger"
"github.com/codex-storage/gnark-plonky2-verifier/fri"
gl "github.com/codex-storage/gnark-plonky2-verifier/goldilocks"
"github.com/codex-storage/gnark-plonky2-verifier/plonk"
"github.com/codex-storage/gnark-plonky2-verifier/poseidon"
"github.com/codex-storage/gnark-plonky2-verifier/types"
"github.com/codex-storage/gnark-plonky2-verifier/variables"
2022-10-10 20:45:34 -07:00
"github.com/consensys/gnark/frontend"
)
type VerifierChip struct {
2023-07-24 16:18:37 -07:00
api frontend . API ` gnark:"-" `
2023-10-11 12:01:26 -07:00
glChip * gl . Chip ` gnark:"-" `
2023-07-24 16:18:37 -07:00
poseidonGlChip * poseidon . GoldilocksChip ` gnark:"-" `
poseidonBN254Chip * poseidon . BN254Chip ` gnark:"-" `
plonkChip * plonk . PlonkChip ` gnark:"-" `
friChip * fri . Chip ` gnark:"-" `
2023-10-11 18:02:46 -07:00
commonData types . CommonCircuitData ` gnark:"-" `
2022-11-21 14:49:54 -08:00
}
2023-10-11 14:53:34 -07:00
func NewVerifierChip ( api frontend . API , commonCircuitData types . CommonCircuitData ) * VerifierChip {
2023-10-11 18:02:46 -07:00
glChip := gl . New ( api )
friChip := fri . NewChip ( api , & commonCircuitData , & commonCircuitData . FriParams )
2023-07-24 16:08:17 -07:00
plonkChip := plonk . NewPlonkChip ( api , commonCircuitData )
poseidonGlChip := poseidon . NewGoldilocksChip ( api )
poseidonBN254Chip := poseidon . NewBN254Chip ( api )
2022-11-21 14:49:54 -08:00
return & VerifierChip {
2023-06-06 17:36:51 -07:00
api : api ,
2023-07-24 16:18:37 -07:00
glChip : glChip ,
2023-07-24 16:08:17 -07:00
poseidonGlChip : poseidonGlChip ,
poseidonBN254Chip : poseidonBN254Chip ,
2023-06-06 17:36:51 -07:00
plonkChip : plonkChip ,
friChip : friChip ,
2023-10-11 18:02:46 -07:00
commonData : commonCircuitData ,
2022-11-21 14:49:54 -08:00
}
2022-10-10 20:45:34 -07:00
}
2023-10-11 11:37:45 -07:00
func ( c * VerifierChip ) GetPublicInputsHash ( publicInputs [ ] gl . Variable ) poseidon . GoldilocksHashOut {
2023-07-24 16:08:17 -07:00
return c . poseidonGlChip . HashNoPad ( publicInputs )
2022-10-10 20:45:34 -07:00
}
2023-05-19 19:49:14 -07:00
func ( c * VerifierChip ) GetChallenges (
2023-10-11 18:02:46 -07:00
proof variables . Proof ,
2023-07-24 16:08:17 -07:00
publicInputsHash poseidon . GoldilocksHashOut ,
2023-10-11 18:02:46 -07:00
verifierData variables . VerifierOnlyCircuitData ,
) variables . ProofChallenges {
config := c . commonData . Config
2022-10-10 20:45:34 -07:00
numChallenges := config . NumChallenges
2023-07-24 16:08:17 -07:00
challenger := challenger . NewChip ( c . api )
2022-10-10 20:45:34 -07:00
2025-05-27 10:27:40 +02:00
// observe the FRI config
var friParams = c . commonData . FriParams
var friConfig = friParams . Config
challenger . ObserveElement ( gl . NewVariable ( friConfig . RateBits ) )
challenger . ObserveElement ( gl . NewVariable ( friConfig . CapHeight ) )
challenger . ObserveElement ( gl . NewVariable ( friConfig . ProofOfWorkBits ) )
// here we fix the reduction strategy to the standard one:
// reduction_strategy: FriReductionStrategy::ConstantArityBits(4, 5)
// this is serialized as [1,4,5]
// TODO: make this work for all reduction strategies
challenger . ObserveElement ( gl . One ( ) )
challenger . ObserveElement ( gl . NewVariable ( 4 ) )
challenger . ObserveElement ( gl . NewVariable ( 5 ) )
challenger . ObserveElement ( gl . NewVariable ( friConfig . NumQueryRounds ) )
var hide uint64 = boolToUint64 ( friParams . Hiding )
challenger . ObserveElement ( gl . NewVariable ( hide ) )
challenger . ObserveElement ( gl . NewVariable ( friParams . DegreeBits ) )
for _ , arity := range friParams . ReductionArityBits {
challenger . ObserveElement ( gl . NewVariable ( arity ) )
}
2023-05-01 10:26:45 -07:00
var circuitDigest = verifierData . CircuitDigest
2022-10-10 22:44:59 -07:00
2023-07-24 16:08:17 -07:00
challenger . ObserveBN254Hash ( circuitDigest )
2022-10-10 20:45:34 -07:00
challenger . ObserveHash ( publicInputsHash )
2023-06-17 19:44:20 -07:00
challenger . ObserveCap ( proof . WiresCap )
2022-10-10 20:45:34 -07:00
plonkBetas := challenger . GetNChallenges ( numChallenges )
plonkGammas := challenger . GetNChallenges ( numChallenges )
2023-06-17 19:44:20 -07:00
challenger . ObserveCap ( proof . PlonkZsPartialProductsCap )
2022-10-10 20:45:34 -07:00
plonkAlphas := challenger . GetNChallenges ( numChallenges )
2023-06-17 19:44:20 -07:00
challenger . ObserveCap ( proof . QuotientPolysCap )
2022-10-10 20:45:34 -07:00
plonkZeta := challenger . GetExtensionChallenge ( )
2023-10-11 18:02:46 -07:00
challenger . ObserveOpenings ( c . friChip . ToOpenings ( proof . Openings ) )
2022-10-10 20:45:34 -07:00
2023-10-11 18:02:46 -07:00
return variables . ProofChallenges {
2022-10-10 20:45:34 -07:00
PlonkBetas : plonkBetas ,
PlonkGammas : plonkGammas ,
PlonkAlphas : plonkAlphas ,
PlonkZeta : plonkZeta ,
FriChallenges : challenger . GetFriChallenges (
2023-06-17 19:44:20 -07:00
proof . OpeningProof . CommitPhaseMerkleCaps ,
proof . OpeningProof . FinalPoly ,
proof . OpeningProof . PowWitness ,
2022-10-10 21:23:30 -07:00
config . FriConfig ,
2022-10-10 20:45:34 -07:00
) ,
}
}
2023-10-11 18:02:46 -07:00
func ( c * VerifierChip ) rangeCheckProof ( proof variables . Proof ) {
2023-07-24 16:18:37 -07:00
// Need to verify the plonky2 proof's openings, openings proof (other than the sibling elements), fri's final poly, pow witness.
// Note that this is NOT range checking the public inputs (first 32 elements should be no more than 8 bits and the last 4 elements should be no more than 64 bits). Since this is currently being inputted via the smart contract,
// we will assume that caller is doing that check.
// Range check the proof's openings.
for _ , constant := range proof . Openings . Constants {
c . glChip . RangeCheckQE ( constant )
}
for _ , plonkSigma := range proof . Openings . PlonkSigmas {
c . glChip . RangeCheckQE ( plonkSigma )
}
for _ , wire := range proof . Openings . Wires {
c . glChip . RangeCheckQE ( wire )
}
for _ , plonkZ := range proof . Openings . PlonkZs {
c . glChip . RangeCheckQE ( plonkZ )
}
for _ , plonkZNext := range proof . Openings . PlonkZsNext {
c . glChip . RangeCheckQE ( plonkZNext )
}
for _ , partialProduct := range proof . Openings . PartialProducts {
c . glChip . RangeCheckQE ( partialProduct )
}
for _ , quotientPoly := range proof . Openings . QuotientPolys {
c . glChip . RangeCheckQE ( quotientPoly )
}
// Range check the openings proof.
for _ , queryRound := range proof . OpeningProof . QueryRoundProofs {
2023-12-18 13:13:13 -08:00
for _ , evalsProof := range queryRound . InitialTreesProof . EvalsProofs {
for _ , evalsProofElement := range evalsProof . Elements {
c . glChip . RangeCheck ( evalsProofElement )
}
2023-07-24 16:18:37 -07:00
}
for _ , queryStep := range queryRound . Steps {
for _ , eval := range queryStep . Evals {
c . glChip . RangeCheckQE ( eval )
}
}
}
// Range check the fri's final poly.
for _ , coeff := range proof . OpeningProof . FinalPoly . Coeffs {
c . glChip . RangeCheckQE ( coeff )
}
// Range check the pow witness.
c . glChip . RangeCheck ( proof . OpeningProof . PowWitness )
}
2023-07-24 16:08:17 -07:00
func ( c * VerifierChip ) Verify (
2023-10-11 18:02:46 -07:00
proof variables . Proof ,
2023-10-11 11:37:45 -07:00
publicInputs [ ] gl . Variable ,
2023-10-11 18:02:46 -07:00
verifierData variables . VerifierOnlyCircuitData ,
2023-07-24 16:08:17 -07:00
) {
2023-07-24 16:18:37 -07:00
c . rangeCheckProof ( proof )
2023-06-17 19:44:20 -07:00
2023-05-25 07:39:06 -07:00
// Generate the parts of the witness that is for the plonky2 proof input
2023-06-17 19:44:20 -07:00
publicInputsHash := c . GetPublicInputsHash ( publicInputs )
2023-10-11 18:02:46 -07:00
proofChallenges := c . GetChallenges ( proof , publicInputsHash , verifierData )
2022-11-21 14:49:54 -08:00
2023-06-17 19:44:20 -07:00
c . plonkChip . Verify ( proofChallenges , proof . Openings , publicInputsHash )
2022-11-21 14:49:54 -08:00
2023-10-11 18:02:46 -07:00
initialMerkleCaps := [ ] variables . FriMerkleCap {
2022-11-21 14:49:54 -08:00
verifierData . ConstantSigmasCap ,
2023-06-17 19:44:20 -07:00
proof . WiresCap ,
proof . PlonkZsPartialProductsCap ,
proof . QuotientPolysCap ,
2022-11-21 14:49:54 -08:00
}
c . friChip . VerifyFriProof (
2023-10-11 18:02:46 -07:00
c . friChip . GetInstance ( proofChallenges . PlonkZeta ) ,
c . friChip . ToOpenings ( proof . Openings ) ,
2022-11-21 14:49:54 -08:00
& proofChallenges . FriChallenges ,
initialMerkleCaps ,
2023-06-17 19:44:20 -07:00
& proof . OpeningProof ,
2022-11-21 14:49:54 -08:00
)
2022-10-10 20:45:34 -07:00
}