diff --git a/plonky2_verifier/structs.go b/plonky2_verifier/structs.go new file mode 100644 index 0000000..8e97b3f --- /dev/null +++ b/plonky2_verifier/structs.go @@ -0,0 +1,162 @@ +package plonky2_verifier + +import ( + . "gnark-ed25519/goldilocks" +) + +type Hash = [4]GoldilocksElement +type QuadraticExtension = [2]GoldilocksElement +type MerkleCap = []Hash + +type MerkleProof struct { + Siblings []Hash +} + +type EvalProof struct { + Elements []GoldilocksElement + MerkleProof MerkleProof +} + +type FriInitialTreeProof struct { + EvalsProofs []EvalProof +} + +type FriQueryStep struct { + Evals []QuadraticExtension + MerkleProof MerkleProof +} + +type FriQueryRound struct { + InitialTreesProof FriInitialTreeProof + Steps []FriQueryStep +} + +type PolynomialCoeffs struct { + Coeffs []GoldilocksElement +} + +type FriProof struct { + CommitPhaseMerkleCaps []MerkleCap + QueryRoundProofs FriQueryRound + FinalPoly PolynomialCoeffs + PowWitness GoldilocksElement +} + +type OpeningSet struct { + Constants []QuadraticExtension + PlonkSigmas []QuadraticExtension + Wires []QuadraticExtension + PlonkZs []QuadraticExtension + PlonkZsNext []QuadraticExtension + PartialProducts []QuadraticExtension + QuotientPolys []QuadraticExtension +} + +type Proof struct { + WiresCap MerkleCap + PlonkZsPartialProductsCap MerkleCap + QuotientPolysCap MerkleCap + Openings OpeningSet + OpeningProof FriProof +} + +type ProofWithPublicInputs struct { + Proof Proof + PublicInputs []GoldilocksElement +} + +type ProofWithPublicInputsRaw struct { + Proof struct { + WiresCap []struct { + Elements []uint64 `json:"elements"` + } `json:"wires_cap"` + PlonkZsPartialProductsCap []struct { + Elements []uint64 `json:"elements"` + } `json:"plonk_zs_partial_products_cap"` + QuotientPolysCap []struct { + Elements []uint64 `json:"elements"` + } `json:"quotient_polys_cap"` + Openings struct { + Constants [][]uint64 `json:"constants"` + PlonkSigmas [][]uint64 `json:"plonk_sigmas"` + Wires [][]uint64 `json:"wires"` + PlonkZs [][]uint64 `json:"plonk_zs"` + PlonkZsNext [][]uint64 `json:"plonk_zs_next"` + PartialProducts [][]uint64 `json:"partial_products"` + QuotientPolys [][]uint64 `json:"quotient_polys"` + } `json:"openings"` + OpeningProof struct { + CommitPhaseMerkleCaps []interface{} `json:"commit_phase_merkle_caps"` + QueryRoundProofs []struct { + InitialTreesProof struct { + EvalsProofs [][]interface{} `json:"evals_proofs"` + } `json:"initial_trees_proof"` + Steps []interface{} `json:"steps"` + } `json:"query_round_proofs"` + FinalPoly struct { + Coeffs [][]uint64 `json:"coeffs"` + } `json:"final_poly"` + PowWitness uint64 `json:"pow_witness"` + } `json:"opening_proof"` + } `json:"proof"` + PublicInputs []uint64 `json:"public_inputs"` +} + +type CommonCircuitData struct { + Config struct { + NumWires uint64 `json:"num_wires"` + NumRoutedWires uint64 `json:"num_routed_wires"` + NumConstants uint64 `json:"num_constants"` + UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"` + SecurityBits uint64 `json:"security_bits"` + NumChallenges uint64 `json:"num_challenges"` + ZeroKnowledge bool `json:"zero_knowledge"` + MaxQuotientDegreeFactor uint64 `json:"max_quotient_degree_factor"` + FriConfig struct { + RateBits uint64 `json:"rate_bits"` + CapHeight uint64 `json:"cap_height"` + ProofOfWorkBits uint64 `json:"proof_of_work_bits"` + ReductionStrategy struct { + ConstantArityBits []uint64 `json:"ConstantArityBits"` + } `json:"reduction_strategy"` + NumQueryRounds uint64 `json:"num_query_rounds"` + } `json:"fri_config"` + } `json:"config"` + FriParams struct { + Config struct { + RateBits uint64 `json:"rate_bits"` + CapHeight uint64 `json:"cap_height"` + ProofOfWorkBits uint64 `json:"proof_of_work_bits"` + ReductionStrategy struct { + ConstantArityBits []uint64 `json:"ConstantArityBits"` + } `json:"reduction_strategy"` + NumQueryRounds uint64 `json:"num_query_rounds"` + } `json:"config"` + Hiding bool `json:"hiding"` + DegreeBits uint64 `json:"degree_bits"` + ReductionArityBits []interface{} `json:"reduction_arity_bits"` + } `json:"fri_params"` + DegreeBits uint64 `json:"degree_bits"` + SelectorsInfo struct { + SelectorIndices []uint64 `json:"selector_indices"` + Groups []struct { + Start uint64 `json:"start"` + End uint64 `json:"end"` + } `json:"groups"` + } `json:"selectors_info"` + QuotientDegreeFactor uint64 `json:"quotient_degree_factor"` + NumGateConstraints uint64 `json:"num_gate_constraints"` + NumConstants uint64 `json:"num_constants"` + NumPublicInputs uint64 `json:"num_public_inputs"` + KIs []interface{} `json:"k_is"` + NumPartialProducts uint64 `json:"num_partial_products"` + CircuitDigest struct { + Elements []uint64 `json:"elements"` + } `json:"circuit_digest"` +} + +type VerifierOnlyCircuitData struct { + ConstantsSigmasCap []struct { + Elements []uint64 `json:"elements"` + } `json:"constants_sigmas_cap"` +} diff --git a/plonky2_verifier/verifier.go b/plonky2_verifier/verifier.go index 5fbdfb3..98c23df 100644 --- a/plonky2_verifier/verifier.go +++ b/plonky2_verifier/verifier.go @@ -1,94 +1,47 @@ package plonky2_verifier -type Proof struct { - WiresCap []struct { - Elements []uint64 `json:"elements"` - } `json:"wires_cap"` - PlonkZsPartialProductsCap []struct { - Elements []uint64 `json:"elements"` - } `json:"plonk_zs_partial_products_cap"` - QuotientPolysCap []struct { - Elements []uint64 `json:"elements"` - } `json:"quotient_polys_cap"` - Openings struct { - Constants [][]uint64 `json:"constants"` - PlonkSigmas [][]uint64 `json:"plonk_sigmas"` - Wires [][]uint64 `json:"wires"` - PlonkZs [][]uint64 `json:"plonk_zs"` - PlonkZsNext [][]uint64 `json:"plonk_zs_next"` - PartialProducts [][]uint64 `json:"partial_products"` - QuotientPolys [][]uint64 `json:"quotient_polys"` - } `json:"openings"` - OpeningProof struct { - CommitPhaseMerkleCaps []interface{} `json:"commit_phase_merkle_caps"` - QueryRoundProofs []struct { - InitialTreesProof struct { - EvalsProofs [][]interface{} `json:"evals_proofs"` - } `json:"initial_trees_proof"` - Steps []interface{} `json:"steps"` - } `json:"query_round_proofs"` - FinalPoly struct { - Coeffs [][]uint64 `json:"coeffs"` - } `json:"final_poly"` - PowWitness uint64 `json:"pow_witness"` - } `json:"opening_proof"` +import ( + . "gnark-ed25519/goldilocks" + "gnark-ed25519/poseidon" + "gnark-ed25519/utils" + + "github.com/consensys/gnark/frontend" +) + +type VerifierChip struct { + api frontend.API + field frontend.API + poseidonChip poseidon.PoseidonChip } -type CommonCircuitData struct { - Config struct { - NumWires int `json:"num_wires"` - NumRoutedWires int `json:"num_routed_wires"` - NumConstants int `json:"num_constants"` - UseBaseArithmeticGate bool `json:"use_base_arithmetic_gate"` - SecurityBits int `json:"security_bits"` - NumChallenges int `json:"num_challenges"` - ZeroKnowledge bool `json:"zero_knowledge"` - MaxQuotientDegreeFactor int `json:"max_quotient_degree_factor"` - FriConfig struct { - RateBits int `json:"rate_bits"` - CapHeight int `json:"cap_height"` - ProofOfWorkBits int `json:"proof_of_work_bits"` - ReductionStrategy struct { - ConstantArityBits []int `json:"ConstantArityBits"` - } `json:"reduction_strategy"` - NumQueryRounds int `json:"num_query_rounds"` - } `json:"fri_config"` - } `json:"config"` - FriParams struct { - Config struct { - RateBits int `json:"rate_bits"` - CapHeight int `json:"cap_height"` - ProofOfWorkBits int `json:"proof_of_work_bits"` - ReductionStrategy struct { - ConstantArityBits []int `json:"ConstantArityBits"` - } `json:"reduction_strategy"` - NumQueryRounds int `json:"num_query_rounds"` - } `json:"config"` - Hiding bool `json:"hiding"` - DegreeBits int `json:"degree_bits"` - ReductionArityBits []interface{} `json:"reduction_arity_bits"` - } `json:"fri_params"` - DegreeBits int `json:"degree_bits"` - SelectorsInfo struct { - SelectorIndices []int `json:"selector_indices"` - Groups []struct { - Start int `json:"start"` - End int `json:"end"` - } `json:"groups"` - } `json:"selectors_info"` - QuotientDegreeFactor int `json:"quotient_degree_factor"` - NumGateConstraints int `json:"num_gate_constraints"` - NumConstants int `json:"num_constants"` - NumPublicInputs int `json:"num_public_inputs"` - KIs []interface{} `json:"k_is"` - NumPartialProducts int `json:"num_partial_products"` - CircuitDigest struct { - Elements []int64 `json:"elements"` - } `json:"circuit_digest"` +func (c *VerifierChip) GetPublicInputsHash(publicInputs []GoldilocksElement) poseidon.HashOutput { + return c.poseidonChip.HashNoPad(publicInputs) +} + +func (c *VerifierChip) GetChallenges(proofWithPis ProofWithPublicInputs, publicInputsHash Hash, commonData CommonCircuitData) { + config := commonData.Config + numChallenges := int(config.NumChallenges) + challenger := NewChallengerChip(c.api, c.field, c.poseidonChip) + + var circuitDigest Hash + copy(circuitDigest[:], utils.Uint64ArrayToGoldilocksElementArray(commonData.CircuitDigest.Elements)) + + challenger.ObserveHash(circuitDigest) + challenger.ObserveHash(publicInputsHash) + challenger.ObserveCap(proofWithPis.Proof.WiresCap) + plonkBetas := challenger.GetNChallenges(numChallenges) + plonkGammas := challenger.GetNChallenges(numChallenges) + + challenger.ObserveCap(proofWithPis.Proof.PlonkZsPartialProductsCap) + plonkAlphas := challenger.GetNChallenges(numChallenges) + + challenger.ObserveCap(proofWithPis.Proof.QuotientPolysCap) + plonkZeta := challenger.GetNChallenges(numChallenges) + + challenger.ObserveOpenings(proofWithPis.Proof.Openings) } -type VerifierOnlyCircuitData struct { - ConstantsSigmasCap []struct { - Elements []int64 `json:"elements"` - } `json:"constants_sigmas_cap"` +func (c *VerifierChip) Verify(proofWithPis ProofWithPublicInputs, verifierData VerifierOnlyCircuitData, commonData CommonCircuitData) { + publicInputsHash := c.GetPublicInputsHash(proofWithPis.PublicInputs) + challenges := c.GetChallenges(proofWithPis, publicInputsHash, commonData) } diff --git a/utils/utils.go b/utils/utils.go index d02085a..33a498e 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -1,9 +1,11 @@ package utils import ( + . "gnark-ed25519/goldilocks" "math/big" "github.com/consensys/gnark/frontend" + "github.com/consensys/gnark/std/math/emulated" ) func StrArrayToBigIntArray(input []string) []big.Int { @@ -23,3 +25,11 @@ func StrArrayToFrontendVariableArray(input []string) []frontend.Variable { } return output } + +func Uint64ArrayToGoldilocksElementArray(input []uint64) []GoldilocksElement { + var output []GoldilocksElement + for i := 0; i < len(input); i++ { + output = append(output, emulated.NewElement[emulated.Goldilocks](input[i])) + } + return output +}