// Copyright (c) 2023 Espresso Systems (espressosys.com) // This file is part of the HyperPlonk library. // You should have received a copy of the MIT License // along with the HyperPlonk library. If not, see . //! Main module for the HyperPlonk PolyIOP. use crate::{custom_gate::CustomizedGates, prelude::HyperPlonkErrors, selectors::SelectorColumn}; use ark_ec::pairing::Pairing; use ark_ff::PrimeField; use ark_poly::DenseMultilinearExtension; use ark_std::log2; use std::sync::Arc; use subroutines::{ pcs::PolynomialCommitmentScheme, poly_iop::prelude::{PermutationCheck, ZeroCheck}, }; /// The proof for the HyperPlonk PolyIOP, consists of the following: /// - the commitments to all witness MLEs /// - a batch opening to all the MLEs at certain index /// - the zero-check proof for checking custom gate-satisfiability /// - the permutation-check proof for checking the copy constraints #[derive(Clone, Debug, PartialEq)] pub struct HyperPlonkProof where E: Pairing, PC: PermutationCheck, PCS: PolynomialCommitmentScheme, { // PCS commit for witnesses pub witness_commits: Vec, pub batch_openings: PCS::BatchProof, // ======================================================================= // IOP proofs // ======================================================================= // the custom gate zerocheck proof pub zero_check_proof: >::ZeroCheckProof, // the permutation check proof for copy constraints pub perm_check_proof: PC::PermutationProof, } /// The HyperPlonk instance parameters, consists of the following: /// - the number of constraints /// - number of public input columns /// - the customized gate function #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct HyperPlonkParams { /// the number of constraints pub num_constraints: usize, /// number of public input // public input is only 1 column and is implicitly the first witness column. // this size must not exceed number of constraints. pub num_pub_input: usize, /// customized gate function pub gate_func: CustomizedGates, } impl HyperPlonkParams { /// Number of variables in a multilinear system pub fn num_variables(&self) -> usize { log2(self.num_constraints) as usize } /// number of selector columns pub fn num_selector_columns(&self) -> usize { self.gate_func.num_selector_columns() } /// number of witness columns pub fn num_witness_columns(&self) -> usize { self.gate_func.num_witness_columns() } /// evaluate the identical polynomial pub fn eval_id_oracle(&self, point: &[F]) -> Result { let len = self.num_variables() + (log2(self.num_witness_columns()) as usize); if point.len() != len { return Err(HyperPlonkErrors::InvalidParameters(format!( "ID oracle point length = {}, expected {}", point.len(), len, ))); } let mut res = F::zero(); let mut base = F::one(); for &v in point.iter() { res += base * v; base += base; } Ok(res) } } /// The HyperPlonk index, consists of the following: /// - HyperPlonk parameters /// - the wire permutation /// - the selector vectors #[derive(Clone, Debug, Default, PartialEq, Eq)] pub struct HyperPlonkIndex { pub params: HyperPlonkParams, pub permutation: Vec, pub selectors: Vec>, } impl HyperPlonkIndex { /// Number of variables in a multilinear system pub fn num_variables(&self) -> usize { self.params.num_variables() } /// number of selector columns pub fn num_selector_columns(&self) -> usize { self.params.num_selector_columns() } /// number of witness columns pub fn num_witness_columns(&self) -> usize { self.params.num_witness_columns() } } /// The HyperPlonk proving key, consists of the following: /// - the hyperplonk instance parameters /// - the preprocessed polynomials output by the indexer /// - the commitment to the selectors and permutations /// - the parameters for polynomial commitment #[derive(Clone, Debug, Default, PartialEq)] pub struct HyperPlonkProvingKey> { /// Hyperplonk instance parameters pub params: HyperPlonkParams, /// The preprocessed permutation polynomials pub permutation_oracles: Vec>>, /// The preprocessed selector polynomials pub selector_oracles: Vec>>, /// Commitments to the preprocessed selector polynomials pub selector_commitments: Vec, /// Commitments to the preprocessed permutation polynomials pub permutation_commitments: Vec, /// The parameters for PCS commitment pub pcs_param: PCS::ProverParam, } /// The HyperPlonk verifying key, consists of the following: /// - the hyperplonk instance parameters /// - the commitments to the preprocessed polynomials output by the indexer /// - the parameters for polynomial commitment #[derive(Clone, Debug, Default, PartialEq)] pub struct HyperPlonkVerifyingKey> { /// Hyperplonk instance parameters pub params: HyperPlonkParams, /// The parameters for PCS commitment pub pcs_param: PCS::VerifierParam, /// A commitment to the preprocessed selector polynomials pub selector_commitments: Vec, /// Permutation oracles' commitments pub perm_commitments: Vec, }