1use crate::{PCSError, StructuredReferenceString};
10use ark_ec::pairing::Pairing;
11use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
12use ark_std::{string::ToString, vec::Vec};
13use derive_where::derive_where;
14
15#[derive(Debug, Clone, Eq, PartialEq, CanonicalSerialize, CanonicalDeserialize, Default)]
19pub struct UnivariateUniversalParams<E: Pairing> {
20 pub powers_of_g: Vec<E::G1Affine>,
23 pub h: E::G2Affine,
26 pub beta_h: E::G2Affine,
28 pub powers_of_h: Vec<E::G2Affine>,
30}
31
32impl<E: Pairing> UnivariateUniversalParams<E> {
33 pub fn max_degree(&self) -> usize {
35 self.powers_of_g.len()
36 }
37}
38
39#[derive(CanonicalSerialize, CanonicalDeserialize, Clone, Debug, Eq, PartialEq, Default)]
41pub struct UnivariateProverParam<E: Pairing> {
42 pub powers_of_g: Vec<E::G1Affine>,
44}
45
46#[derive(Clone, Debug, Eq, CanonicalSerialize, CanonicalDeserialize, PartialEq)]
49#[derive_where(Default)]
50pub struct UnivariateVerifierParam<E: Pairing> {
51 pub g: E::G1Affine,
54 pub h: E::G2Affine,
56 pub beta_h: E::G2Affine,
58 pub powers_of_h: Vec<E::G2Affine>,
61 pub powers_of_g: Vec<E::G1Affine>,
64}
65
66impl<E: Pairing> StructuredReferenceString for UnivariateUniversalParams<E> {
67 type ProverParam = UnivariateProverParam<E>;
68 type VerifierParam = UnivariateVerifierParam<E>;
69
70 fn extract_prover_param(&self, supported_degree: usize) -> Self::ProverParam {
72 let powers_of_g = self.powers_of_g[..=supported_degree].to_vec();
73
74 Self::ProverParam { powers_of_g }
75 }
76
77 fn extract_verifier_param(&self, supported_degree: usize) -> Self::VerifierParam {
79 Self::VerifierParam {
80 g: self.powers_of_g[0],
81 h: self.h,
82 beta_h: self.beta_h,
83 powers_of_h: self.powers_of_h[..=supported_degree].to_vec(),
84 powers_of_g: self.powers_of_g[..=supported_degree].to_vec(),
85 }
86 }
87
88 fn trim_with_verifier_degree(
93 &self,
94 prover_supported_degree: usize,
95 verifier_supported_degree: usize,
96 ) -> Result<(Self::ProverParam, Self::VerifierParam), PCSError> {
97 if self.powers_of_g.len() <= prover_supported_degree {
98 return Err(PCSError::InvalidParameters(ark_std::format!(
99 "Largest supported prover degree by the SRS is: {}, but requested: {}",
100 self.powers_of_g.len() - 1,
101 prover_supported_degree,
102 )));
103 }
104 if self.powers_of_h.len() <= verifier_supported_degree {
105 return Err(PCSError::InvalidParameters(ark_std::format!(
106 "Largest supported verifier degree by the SRS is: {}, but requested: {}",
107 self.powers_of_h.len() - 1,
108 verifier_supported_degree,
109 )));
110 }
111 if verifier_supported_degree == 0 {
112 return Err(PCSError::InvalidParameters(
113 "Verifier supported degree should be larger than zero".to_string(),
114 ));
115 }
116 let powers_of_g = self.powers_of_g[..=prover_supported_degree].to_vec();
117
118 let pk = Self::ProverParam { powers_of_g };
119 let vk = Self::VerifierParam {
120 g: self.powers_of_g[0],
121 h: self.h,
122 beta_h: self.beta_h,
123 powers_of_h: self.powers_of_h[..=verifier_supported_degree].to_vec(),
124 powers_of_g: self.powers_of_g[..=verifier_supported_degree].to_vec(),
125 };
126 Ok((pk, vk))
127 }
128
129 fn trim(
134 &self,
135 supported_degree: usize,
136 ) -> Result<(Self::ProverParam, Self::VerifierParam), PCSError> {
137 self.trim_with_verifier_degree(supported_degree, 1)
138 }
139
140 #[cfg(any(test, feature = "test-srs"))]
143 fn gen_srs_for_testing<R>(rng: &mut R, max_degree: usize) -> Result<Self, PCSError>
144 where
145 R: ark_std::rand::RngCore + ark_std::rand::CryptoRng,
146 {
147 tests::gen_srs_for_testing(rng, max_degree, 1)
148 }
149
150 #[cfg(any(test, feature = "test-srs"))]
151 fn gen_srs_for_testing_with_verifier_degree<
152 R: ark_std::rand::prelude::RngCore + ark_std::rand::prelude::CryptoRng,
153 >(
154 rng: &mut R,
155 prover_supported_degree: usize,
156 verifier_supported_degree: usize,
157 ) -> Result<Self, PCSError> {
158 tests::gen_srs_for_testing(rng, prover_supported_degree, verifier_supported_degree)
159 }
160}
161
162#[cfg(any(test, feature = "test-srs"))]
163mod tests {
164 use super::UnivariateUniversalParams;
165 use crate::PCSError;
166 use ark_ec::{pairing::Pairing, AffineRepr, CurveGroup, ScalarMul};
167 use ark_std::{
168 end_timer,
169 rand::{CryptoRng, RngCore},
170 start_timer, vec,
171 vec::Vec,
172 One, UniformRand,
173 };
174
175 pub(crate) fn gen_srs_for_testing<E: Pairing, R: RngCore + CryptoRng>(
176 rng: &mut R,
177 prover_degree: usize,
178 verifier_degree: usize,
179 ) -> Result<UnivariateUniversalParams<E>, PCSError> {
180 let setup_time = start_timer!(|| ark_std::format!(
181 "KZG10::Setup with prover degree {} and verifier degree {}",
182 prover_degree,
183 verifier_degree
184 ));
185 let beta = E::ScalarField::rand(rng);
186 let g = E::G1::rand(rng);
187 let h = E::G2::rand(rng);
188
189 let mut powers_of_beta = vec![E::ScalarField::one()];
190
191 let mut cur = beta;
192 let max_degree = ark_std::cmp::max(prover_degree, verifier_degree);
193 for _ in 0..max_degree {
194 powers_of_beta.push(cur);
195 cur *= β
196 }
197
198 let g_time = start_timer!(|| "Generating powers of G");
199 let powers_of_g = g
200 .batch_mul(&powers_of_beta)
201 .into_iter()
202 .map(|p| p.into_group())
203 .collect::<Vec<_>>();
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}