1use crate::{PCSError, StructuredReferenceString};
10use ark_ec::pairing::Pairing;
11use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
12use ark_std::{string::ToString, vec::Vec};
13
14#[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize, Default)]
18pub struct UnivariateUniversalParams<E: Pairing> {
19 pub powers_of_g: Vec<E::G1Affine>,
22 pub h: E::G2Affine,
25 pub beta_h: E::G2Affine,
27 pub powers_of_h: Vec<E::G2Affine>,
29}
30
31impl<E: Pairing> UnivariateUniversalParams<E> {
32 pub fn max_degree(&self) -> usize {
34 self.powers_of_g.len()
35 }
36}
37
38#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, Eq, PartialEq, Default)]
40pub struct UnivariateProverParam<E: Pairing> {
41 pub powers_of_g: Vec<E::G1Affine>,
43}
44
45#[derive(Derivative, Clone, Debug, Eq, CanonicalSerialize, CanonicalDeserialize, PartialEq)]
48#[derivative(Default)]
49pub struct UnivariateVerifierParam<E: Pairing> {
50 pub g: E::G1Affine,
53 pub h: E::G2Affine,
55 pub beta_h: E::G2Affine,
57 pub powers_of_h: Vec<E::G2Affine>,
60 pub powers_of_g: Vec<E::G1Affine>,
63}
64
65impl<E: Pairing> StructuredReferenceString for UnivariateUniversalParams<E> {
66 type ProverParam = UnivariateProverParam<E>;
67 type VerifierParam = UnivariateVerifierParam<E>;
68
69 fn extract_prover_param(&self, supported_degree: usize) -> Self::ProverParam {
71 let powers_of_g = self.powers_of_g[..=supported_degree].to_vec();
72
73 Self::ProverParam { powers_of_g }
74 }
75
76 fn extract_verifier_param(&self, supported_degree: usize) -> Self::VerifierParam {
78 Self::VerifierParam {
79 g: self.powers_of_g[0],
80 h: self.h,
81 beta_h: self.beta_h,
82 powers_of_h: self.powers_of_h[..=supported_degree].to_vec(),
83 powers_of_g: self.powers_of_g[..=supported_degree].to_vec(),
84 }
85 }
86
87 fn trim_with_verifier_degree(
92 &self,
93 prover_supported_degree: usize,
94 verifier_supported_degree: usize,
95 ) -> Result<(Self::ProverParam, Self::VerifierParam), PCSError> {
96 if self.powers_of_g.len() <= prover_supported_degree {
97 return Err(PCSError::InvalidParameters(ark_std::format!(
98 "Largest supported prover degree by the SRS is: {}, but requested: {}",
99 self.powers_of_g.len() - 1,
100 prover_supported_degree,
101 )));
102 }
103 if self.powers_of_h.len() <= verifier_supported_degree {
104 return Err(PCSError::InvalidParameters(ark_std::format!(
105 "Largest supported verifier degree by the SRS is: {}, but requested: {}",
106 self.powers_of_h.len() - 1,
107 verifier_supported_degree,
108 )));
109 }
110 if verifier_supported_degree == 0 {
111 return Err(PCSError::InvalidParameters(
112 "Verifier supported degree should be larger than zero".to_string(),
113 ));
114 }
115 let powers_of_g = self.powers_of_g[..=prover_supported_degree].to_vec();
116
117 let pk = Self::ProverParam { powers_of_g };
118 let vk = Self::VerifierParam {
119 g: self.powers_of_g[0],
120 h: self.h,
121 beta_h: self.beta_h,
122 powers_of_h: self.powers_of_h[..=verifier_supported_degree].to_vec(),
123 powers_of_g: self.powers_of_g[..=verifier_supported_degree].to_vec(),
124 };
125 Ok((pk, vk))
126 }
127
128 fn trim(
133 &self,
134 supported_degree: usize,
135 ) -> Result<(Self::ProverParam, Self::VerifierParam), PCSError> {
136 self.trim_with_verifier_degree(supported_degree, 1)
137 }
138
139 #[cfg(any(test, feature = "test-srs"))]
142 fn gen_srs_for_testing<R>(rng: &mut R, max_degree: usize) -> Result<Self, PCSError>
143 where
144 R: ark_std::rand::RngCore + ark_std::rand::CryptoRng,
145 {
146 tests::gen_srs_for_testing(rng, max_degree, 1)
147 }
148
149 #[cfg(any(test, feature = "test-srs"))]
150 fn gen_srs_for_testing_with_verifier_degree<
151 R: ark_std::rand::prelude::RngCore + ark_std::rand::prelude::CryptoRng,
152 >(
153 rng: &mut R,
154 prover_supported_degree: usize,
155 verifier_supported_degree: usize,
156 ) -> Result<Self, PCSError> {
157 tests::gen_srs_for_testing(rng, prover_supported_degree, verifier_supported_degree)
158 }
159}
160
161#[cfg(any(test, feature = "test-srs"))]
162mod tests {
163 use super::UnivariateUniversalParams;
164 use crate::PCSError;
165 use ark_ec::{pairing::Pairing, scalar_mul::fixed_base::FixedBase, CurveGroup};
166 use ark_ff::PrimeField;
167 use ark_std::{
168 end_timer,
169 rand::{CryptoRng, RngCore},
170 start_timer, vec, One, UniformRand,
171 };
172
173 pub(crate) fn gen_srs_for_testing<E: Pairing, R: RngCore + CryptoRng>(
174 rng: &mut R,
175 prover_degree: usize,
176 verifier_degree: usize,
177 ) -> Result<UnivariateUniversalParams<E>, PCSError> {
178 let setup_time = start_timer!(|| ark_std::format!(
179 "KZG10::Setup with prover degree {} and verifier degree {}",
180 prover_degree,
181 verifier_degree
182 ));
183 let beta = E::ScalarField::rand(rng);
184 let g = E::G1::rand(rng);
185 let h = E::G2::rand(rng);
186
187 let mut powers_of_beta = vec![E::ScalarField::one()];
188
189 let mut cur = beta;
190 let max_degree = ark_std::cmp::max(prover_degree, verifier_degree);
191 for _ in 0..max_degree {
192 powers_of_beta.push(cur);
193 cur *= β
194 }
195
196 let window_size = FixedBase::get_mul_window_size(prover_degree + 1);
197
198 let scalar_bits = E::ScalarField::MODULUS_BIT_SIZE as usize;
199 let g_time = start_timer!(|| "Generating powers of G");
200 let g_table = FixedBase::get_window_table(scalar_bits, window_size, g);
202 let powers_of_g =
203 FixedBase::msm::<E::G1>(scalar_bits, window_size, &g_table, &powers_of_beta);
204 end_timer!(g_time);
205
206 let powers_of_g = E::G1::normalize_batch(&powers_of_g);
207
208 let h = h.into_affine();
209 let beta_h = (h * beta).into_affine();
210
211 let powers_of_h = powers_of_beta
212 .iter()
213 .take(verifier_degree + 1)
214 .map(|x| (h * x).into_affine())
215 .collect();
216
217 let pp = UnivariateUniversalParams {
218 powers_of_g,
219 h,
220 beta_h,
221 powers_of_h,
222 };
223 end_timer!(setup_time);
224 Ok(pp)
225 }
226}