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 *= β
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}