diff --git a/poly-iop/src/hyperplonk/mod.rs b/poly-iop/src/hyperplonk/mod.rs new file mode 100644 index 0000000..2401adc --- /dev/null +++ b/poly-iop/src/hyperplonk/mod.rs @@ -0,0 +1,128 @@ +//! Main module for the HyperPlonk PolyIOP. + +use crate::{ + errors::PolyIOPErrors, perm_check::PermutationCheck, transcript::IOPTranscript, + zero_check::ZeroCheck, +}; +use ark_ff::PrimeField; +use ark_poly::DenseMultilinearExtension; +use std::rc::Rc; + +/// A trait for HyperPlonk Poly-IOPs +pub trait HyperPlonkPIOP { + type Parameters; + type ProvingKey; + type Proof; + type SubClaim; + + /// Generate the preprocessed polynomials output by the indexer. + /// + /// Inputs: + /// - `params`: HyperPlonk instance parameters + /// - `permutation`: the permutation for the copy constraints + /// - `selectors`: the list of selector vectors for custom gates + /// Outputs: + /// - The HyperPlonk proving key, which includes the preprocessed + /// polynomials. + fn preprocess( + params: &Self::Parameters, + permutation: &[F], + selectors: &[&[F]], + ) -> Result; + + /// Generate HyperPlonk PIOP proof. + /// + /// Inputs: + /// - `pk`: circuit proving key + /// - `pub_input`: online public input + /// - `witness`: witness assignement + /// - `transcript`: the transcript used for generating pseudorandom + /// challenges + /// Outputs: + /// - The HyperPlonk PIOP proof. + fn prove( + pk: &Self::ProvingKey, + pub_input: &[F], + witness: &[&[F]], + transcript: &mut IOPTranscript, + ) -> Result; + + /// Verify the HyperPlonk proof and generate the evaluation subclaims to be + /// checked later by the SNARK verifier. + /// + /// Inputs: + /// - `params`: instance parameter + /// - `pub_input`: online public input + /// - `proof`: HyperPlonk PIOP proof + /// - `transcript`: the transcript used for generating pseudorandom + /// challenges + /// Outputs: + /// - Return error if the verification fails, otherwise return the + /// evaluation subclaim + fn verify( + params: &Self::Parameters, + pub_input: &[F], + proof: &Self::Proof, + transcript: &mut IOPTranscript, + ) -> Result; +} + +/// The sub-claim for the HyperPlonk PolyIOP, consists of the following: +/// - the SubClaim for the zero-check PIOP +/// - the SubClaim for the permutation-check PIOP +/// - the SubClaim for public input consistency +#[derive(Clone, Debug, Default, PartialEq)] +pub struct HyperPlonkSubClaim, PC: PermutationCheck> { + /// the SubClaim for the custom gate zerocheck + pub zero_check_sub_claim: ZC::ZeroCheckSubClaim, + /// the SubClaim for the permutation check + pub perm_check_sub_claim: PC::PermutationCheckSubClaim, + /// the public input consistency check + pub pub_input_sub_claim: (Vec, F), // (point, expected_eval) +} + +/// The proof for the HyperPlonk PolyIOP, consists of the following: +/// - the zero-check proof for checking custom gate-satisfiability +/// - the permutation-check proof for checking the copy constraints +#[derive(Clone, Debug, Default, PartialEq)] +pub struct HyperPlonkProof, PC: PermutationCheck> { + /// the custom gate zerocheck proof + pub zero_check_proof: ZC::Proof, + /// the permutation check proof for copy constraints + pub perm_check_proof: PC::Proof, +} + +/// The HyperPlonk instance parameters, consists of the following: +/// - the number of variables in the poly-IOP +/// - binary log of the number of public input variables +/// - binary log of the number of selectors +/// - binary log of the number of witness wires +/// - the customized gate function +#[derive(Clone, Debug, Default, PartialEq)] +pub struct HyperPlonkParams { + /// the number of variables in polys + pub nv: usize, + /// binary log of the public input length + pub log_pub_input_len: usize, + // binary log of the number of selectors + pub log_n_selectors: usize, + /// binary log of the number of witness wires + pub log_n_wires: usize, + /// customized gate function + // TODO: define a struct for it. + pub gate_func: Vec>, +} + +/// The HyperPlonk proving key, consists of the following: +/// - the hyperplonk instance parameters +/// - the preprocessed polynomials output by the indexer +#[derive(Clone, Debug, Default, PartialEq)] +pub struct HyperPlonkProvingKey { + /// hyperplonk instance parameters + pub params: HyperPlonkParams, + /// the preprocessed index polynomials + pub index_oracles: Vec>>, +} + +#[cfg(test)] +mod test {} diff --git a/poly-iop/src/lib.rs b/poly-iop/src/lib.rs index 326dff1..319f06d 100644 --- a/poly-iop/src/lib.rs +++ b/poly-iop/src/lib.rs @@ -2,6 +2,7 @@ use ark_ff::PrimeField; use std::marker::PhantomData; mod errors; +mod hyperplonk; mod perm_check; mod structs; mod sum_check; @@ -11,6 +12,7 @@ mod virtual_poly; mod zero_check; pub use errors::PolyIOPErrors; +pub use hyperplonk::HyperPlonkPIOP; pub use perm_check::{ util::{identity_permutation_mle, random_permutation_mle}, PermutationCheck, diff --git a/poly-iop/src/perm_check/mod.rs b/poly-iop/src/perm_check/mod.rs index c0e6aa0..d6c33e8 100644 --- a/poly-iop/src/perm_check/mod.rs +++ b/poly-iop/src/perm_check/mod.rs @@ -31,6 +31,18 @@ pub trait PermutationCheck: ZeroCheck { type PermutationCheckSubClaim; type PermutationChallenge; + /// Generate the preprocessed polynomial for the permutation check. + /// + /// The algorithm takes as input a permutation and outputs a merged + /// multilinear polynomial s(X0, X1, ..., Xn) such that + /// - s(0, X1, ..., Xn) = s_id(X1, ..., Xn) (identity permutation + /// polynomial) + /// - s(1, X1, ..., Xn) = s_perm(X1, ..., Xn) (permutation polynomial) + fn preprocess( + permutation: &[F], + aux_info: &Self::VPAuxInfo, + ) -> Result, PolyIOPErrors>; + /// Initialize the system with a transcript /// /// This function is optional -- in the case where a PermutationCheck is @@ -81,6 +93,8 @@ pub trait PermutationCheck: ZeroCheck { /// /// The caller needs to check num_vars matches in f/g/s_id/s_perm /// Cost: linear in N. + /// + /// TODO: replace argument `s_perm` with the merged polynomial `s`. fn compute_products( challenge: &Self::PermutationChallenge, fx: &DenseMultilinearExtension, @@ -162,6 +176,20 @@ impl PermutationCheck for PolyIOP { type PermutationChallenge = PermutationChallenge; + /// Generate the preprocessed polynomial for the permutation check. + /// + /// The algorithm takes as input a permutation and outputs a merged + /// multilinear polynomial s(X0, X1, ..., Xn) such that + /// - s(0, X1, ..., Xn) = s_id(X1, ..., Xn) (identity permutation + /// polynomial) + /// - s(1, X1, ..., Xn) = s_perm(X1, ..., Xn) (permutation polynomial) + fn preprocess( + _permutation: &[F], + _aux_info: &Self::VPAuxInfo, + ) -> Result, PolyIOPErrors> { + unimplemented!(); + } + /// Initialize the system with a transcript /// /// This function is optional -- in the case where a PermutationCheck is @@ -229,6 +257,8 @@ impl PermutationCheck for PolyIOP { /// /// The caller needs to check num_vars matches in f/g/s_id/s_perm /// Cost: linear in N. + /// + /// TODO: replace argument `s_perm` with the merged polynomial `s`. fn compute_products( challenge: &Self::PermutationChallenge, fx: &DenseMultilinearExtension, diff --git a/poly-iop/src/perm_check/util.rs b/poly-iop/src/perm_check/util.rs index b3955c8..520080f 100644 --- a/poly-iop/src/perm_check/util.rs +++ b/poly-iop/src/perm_check/util.rs @@ -25,6 +25,8 @@ use ark_std::{end_timer, rand::RngCore, start_timer}; /// /// The caller needs to check num_vars matches in f/g/s_id/s_perm /// Cost: linear in N. +/// +/// TODO: replace `s_perm` with the merged poly `s`. #[allow(clippy::type_complexity)] pub(super) fn compute_prod_0( beta: &F, @@ -47,6 +49,7 @@ pub(super) fn compute_prod_0( let mut numerator_evals = vec![]; let mut denominator_evals = vec![]; + // TODO: remove this line after replacing `s_perm` with `s`. let s_id = identity_permutation_mle::(num_vars); for (&fi, (&gi, (&s_id_i, &s_perm_i))) in