//! This module provides an implementation of a variant of (Turbo)[PLONK][plonk] //! that is designed specifically for the polynomial commitment scheme described //! in the [Halo][halo] paper. //! //! [halo]: https://eprint.iacr.org/2019/1021 //! [plonk]: https://eprint.iacr.org/2019/953 use blake2b_simd::Params as Blake2bParams; use crate::arithmetic::{CurveAffine, FieldExt}; use crate::helpers::CurveRead; use crate::poly::{ commitment::Params, Coeff, EvaluationDomain, ExtendedLagrangeCoeff, LagrangeCoeff, PinnedEvaluationDomain, Polynomial, }; use crate::transcript::{ChallengeScalar, EncodedChallenge, Transcript}; mod assigned; mod circuit; mod error; mod keygen; mod lookup; pub(crate) mod permutation; mod vanishing; mod prover; mod verifier; pub use assigned::*; pub use circuit::*; pub use error::*; pub use keygen::*; pub use prover::*; pub use verifier::*; use std::io; /// This is a verifying key which allows for the verification of proofs for a /// particular circuit. #[derive(Debug)] pub struct VerifyingKey { domain: EvaluationDomain, fixed_commitments: Vec, permutation: permutation::VerifyingKey, cs: ConstraintSystem, } impl VerifyingKey { /// Hashes a verification key into a transcript. pub fn hash_into, T: Transcript>( &self, transcript: &mut T, ) -> io::Result<()> { let mut hasher = Blake2bParams::new() .hash_length(64) .personal(b"Halo2-Verify-Key") .to_state(); let s = format!("{:?}", self.pinned()); hasher.update(&(s.len() as u64).to_le_bytes()); hasher.update(s.as_bytes()); // Hash in final Blake2bState transcript.common_scalar(C::Scalar::from_bytes_wide(hasher.finalize().as_array()))?; Ok(()) } /// Obtains a pinned representation of this verification key that contains /// the minimal information necessary to reconstruct the verification key. pub fn pinned(&self) -> PinnedVerificationKey<'_, C> { PinnedVerificationKey { base_modulus: C::Base::MODULUS, scalar_modulus: C::Scalar::MODULUS, domain: self.domain.pinned(), fixed_commitments: &self.fixed_commitments, permutation: &self.permutation, cs: self.cs.pinned(), } } } /// Minimal representation of a verification key that can be used to identify /// its active contents. #[allow(dead_code)] #[derive(Debug)] pub struct PinnedVerificationKey<'a, C: CurveAffine> { base_modulus: &'static str, scalar_modulus: &'static str, domain: PinnedEvaluationDomain<'a, C::Scalar>, cs: PinnedConstraintSystem<'a, C::Scalar>, fixed_commitments: &'a Vec, permutation: &'a permutation::VerifyingKey, } /// This is a proving key which allows for the creation of proofs for a /// particular circuit. #[derive(Debug)] pub struct ProvingKey { vk: VerifyingKey, l0: Polynomial, l_blind: Polynomial, l_last: Polynomial, fixed_values: Vec>, fixed_polys: Vec>, fixed_cosets: Vec>, permutation: permutation::ProvingKey, } impl ProvingKey { /// Get the underlying [`VerifyingKey`]. pub fn get_vk(&self) -> &VerifyingKey { &self.vk } } impl VerifyingKey { /// Get the underlying [`EvaluationDomain`]. pub fn get_domain(&self) -> &EvaluationDomain { &self.domain } } #[derive(Clone, Copy, Debug)] struct Theta; type ChallengeTheta = ChallengeScalar; #[derive(Clone, Copy, Debug)] struct Beta; type ChallengeBeta = ChallengeScalar; #[derive(Clone, Copy, Debug)] struct Gamma; type ChallengeGamma = ChallengeScalar; #[derive(Clone, Copy, Debug)] struct Y; type ChallengeY = ChallengeScalar; #[derive(Clone, Copy, Debug)] struct X; type ChallengeX = ChallengeScalar;