arnaucube
arnaucube/hyperplonkPublic Self-hosted repository
hyperplonk/pcs/src/univariate_kzg/srs.rs
pcs/src/univariate_kzg/srs.rsRaw
  1//! Implementing Structured Reference Strings for univariate polynomial KZG
  2
  3use crate::{prelude::PCSErrors, StructuredReferenceString};
  4use ark_ec::{msm::FixedBaseMSM, AffineCurve, PairingEngine, ProjectiveCurve};
  5use ark_ff::PrimeField;
  6use ark_serialize::{CanonicalDeserialize, CanonicalSerialize, Read, SerializationError, Write};
  7use ark_std::{end_timer, rand::RngCore, start_timer, One, UniformRand};
  8
  9/// `UniversalParams` are the universal parameters for the KZG10 scheme.
 10/// Adapted from
 11/// https://github.com/arkworks-rs/poly-commit/blob/master/src/kzg10/data_structures.rs#L20
 12#[derive(Clone, Debug)]
 13pub struct UnivariateUniversalParams<E: PairingEngine> {
 14    /// Group elements of the form `{ \beta^i G }`, where `i` ranges from 0 to
 15    /// `degree`.
 16    pub powers_of_g: Vec<E::G1Affine>,
 17    /// The generator of G2.
 18    pub h: E::G2Affine,
 19    /// \beta times the above generator of G2.
 20    pub beta_h: E::G2Affine,
 21}
 22
 23/// Prover Parameters
 24#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug)]
 25pub struct UnivariateProverParam<C: AffineCurve> {
 26    pub powers_of_g: Vec<C>,
 27}
 28
 29/// `VerifierKey` is used to check evaluation proofs for a given commitment.
 30/// https://github.com/arkworks-rs/poly-commit/blob/master/src/kzg10/data_structures.rs#L236
 31#[derive(Clone, Debug)]
 32pub struct UnivariateVerifierParam<E: PairingEngine> {
 33    /// The generator of G1.
 34    pub g: E::G1Affine,
 35    /// The generator of G2.
 36    pub h: E::G2Affine,
 37    /// \beta times the above generator of G2.
 38    pub beta_h: E::G2Affine,
 39}
 40
 41impl<E: PairingEngine> StructuredReferenceString<E> for UnivariateUniversalParams<E> {
 42    type ProverParam = UnivariateProverParam<E::G1Affine>;
 43    type VerifierParam = UnivariateVerifierParam<E>;
 44
 45    /// Extract the prover parameters from the public parameters.
 46    fn extract_prover_param(&self, supported_log_size: usize) -> Self::ProverParam {
 47        let support_size = 1usize << supported_log_size;
 48        let powers_of_g = self.powers_of_g[..=support_size].to_vec();
 49
 50        Self::ProverParam { powers_of_g }
 51    }
 52
 53    /// Extract the verifier parameters from the public parameters.
 54    fn extract_verifier_param(&self, _supported_log_size: usize) -> Self::VerifierParam {
 55        Self::VerifierParam {
 56            g: self.powers_of_g[0],
 57            h: self.h,
 58            beta_h: self.beta_h,
 59        }
 60    }
 61
 62    /// Trim the universal parameters to specialize the public parameters
 63    /// for univariate polynomials to the given `supported_log_size`, and
 64    /// returns committer key and verifier key. `supported_log_size` should
 65    /// be in range `1..log(params.len())`
 66    fn trim(
 67        &self,
 68        supported_log_size: usize,
 69    ) -> Result<(Self::ProverParam, Self::VerifierParam), PCSErrors> {
 70        let support_size = 1usize << supported_log_size;
 71        let powers_of_g = self.powers_of_g[..=support_size].to_vec();
 72
 73        let pk = Self::ProverParam { powers_of_g };
 74        let vk = Self::VerifierParam {
 75            g: self.powers_of_g[0],
 76            h: self.h,
 77            beta_h: self.beta_h,
 78        };
 79        Ok((pk, vk))
 80    }
 81
 82    /// Build SRS for testing.
 83    /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY.
 84    /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION.
 85    fn gen_srs_for_testing<R: RngCore>(rng: &mut R, log_degree: usize) -> Result<Self, PCSErrors> {
 86        let max_degree = 1usize << log_degree;
 87        let setup_time = start_timer!(|| format!("KZG10::Setup with degree {}", max_degree));
 88        let beta = E::Fr::rand(rng);
 89        let g = E::G1Projective::rand(rng);
 90        let h = E::G2Projective::rand(rng);
 91
 92        let mut powers_of_beta = vec![E::Fr::one()];
 93
 94        let mut cur = beta;
 95        for _ in 0..max_degree {
 96            powers_of_beta.push(cur);
 97            cur *= &beta;
 98        }
 99
100        let window_size = FixedBaseMSM::get_mul_window_size(max_degree + 1);
101
102        let scalar_bits = E::Fr::size_in_bits();
103        let g_time = start_timer!(|| "Generating powers of G");
104        // TODO: parallelization
105        let g_table = FixedBaseMSM::get_window_table(scalar_bits, window_size, g);
106        let powers_of_g = FixedBaseMSM::multi_scalar_mul::<E::G1Projective>(
107            scalar_bits,
108            window_size,
109            &g_table,
110            &powers_of_beta,
111        );
112        end_timer!(g_time);
113
114        let powers_of_g = E::G1Projective::batch_normalization_into_affine(&powers_of_g);
115
116        let h = h.into_affine();
117        let beta_h = h.mul(beta).into_affine();
118
119        let pp = Self {
120            powers_of_g,
121            h,
122            beta_h,
123        };
124        end_timer!(setup_time);
125        Ok(pp)
126    }
127}