1use crate::{
17 AlgebraicSponge,
18 fft::{DensePolynomial, EvaluationDomain},
19};
20use snarkvm_curves::{AffineCurve, PairingCurve, PairingEngine, ProjectiveCurve};
21use snarkvm_fields::{ConstraintFieldError, ToConstraintField, Zero};
22use snarkvm_parameters::mainnet::PowersOfG;
23use snarkvm_utilities::{
24 FromBytes,
25 ToBytes,
26 borrow::Cow,
27 error,
28 io::{Read, Write},
29 serialize::{CanonicalDeserialize, CanonicalSerialize, Compress, SerializationError, Valid, Validate},
30};
31
32use crate::srs::{UniversalProver, UniversalVerifier};
33use anyhow::Result;
34use core::ops::{Add, AddAssign};
35use rand_core::RngCore;
36use std::{collections::BTreeMap, io, ops::Range, sync::Arc};
37
38#[derive(Clone, Debug)]
40pub struct UniversalParams<E: PairingEngine> {
41 powers: Arc<PowersOfG<E>>,
46 pub h: E::G2Affine,
48 pub prepared_h: <E::G2Affine as PairingCurve>::Prepared,
50 pub prepared_beta_h: <E::G2Affine as PairingCurve>::Prepared,
52}
53
54impl<E: PairingEngine> UniversalParams<E> {
55 pub fn load() -> Result<Self> {
56 let powers = Arc::new(PowersOfG::<E>::load()?);
57 let h = E::G2Affine::prime_subgroup_generator();
58 let prepared_h = h.prepare();
59 let prepared_beta_h = powers.beta_h().prepare();
60
61 Ok(Self { powers, h, prepared_h, prepared_beta_h })
62 }
63
64 pub fn download_powers_for(&self, range: Range<usize>) -> Result<()> {
65 self.powers.download_powers_for(range)
66 }
67
68 pub fn lagrange_basis(&self, domain: EvaluationDomain<E::Fr>) -> Result<Vec<E::G1Affine>> {
69 let basis = domain
70 .ifft(&self.powers_of_beta_g(0, domain.size())?.iter().map(|e| (*e).to_projective()).collect::<Vec<_>>());
71 Ok(E::G1Projective::batch_normalization_into_affine(basis))
72 }
73
74 pub fn power_of_beta_g(&self, index: usize) -> Result<E::G1Affine> {
75 self.powers.power_of_beta_g(index)
76 }
77
78 pub fn powers_of_beta_g(&self, lower: usize, upper: usize) -> Result<Vec<E::G1Affine>> {
79 self.powers.powers_of_beta_g(lower..upper)
80 }
81
82 pub fn powers_of_beta_times_gamma_g(&self) -> &BTreeMap<usize, E::G1Affine> {
83 self.powers.powers_of_beta_gamma_g()
84 }
85
86 pub fn beta_h(&self) -> E::G2Affine {
87 self.powers.beta_h()
88 }
89
90 pub fn max_degree(&self) -> usize {
91 self.powers.max_num_powers() - 1
92 }
93
94 pub fn to_universal_prover(&self) -> Result<UniversalProver<E>> {
95 Ok(UniversalProver::<E> { max_degree: self.max_degree(), _unused: None })
96 }
97
98 pub fn to_universal_verifier(&self) -> Result<UniversalVerifier<E>> {
99 let g = self.power_of_beta_g(0)?;
100 let h = self.h;
101 let beta_h = self.beta_h();
102 let gamma_g = self.powers_of_beta_times_gamma_g()[&0];
103 let prepared_h = self.prepared_h.clone();
104 let prepared_beta_h = self.prepared_beta_h.clone();
105
106 Ok(UniversalVerifier {
107 vk: VerifierKey::<E> { g, gamma_g, h, beta_h, prepared_h, prepared_beta_h },
108 prepared_negative_powers_of_beta_h: self.powers.prepared_negative_powers_of_beta_h(),
109 })
110 }
111}
112
113impl<E: PairingEngine> FromBytes for UniversalParams<E> {
114 fn read_le<R: Read>(mut reader: R) -> io::Result<Self> {
115 let powers = Arc::new(PowersOfG::read_le(&mut reader)?);
117
118 let h: E::G2Affine = FromBytes::read_le(&mut reader)?;
120
121 let prepared_h: <E::G2Affine as PairingCurve>::Prepared = FromBytes::read_le(&mut reader)?;
123
124 let prepared_beta_h: <E::G2Affine as PairingCurve>::Prepared = FromBytes::read_le(&mut reader)?;
126
127 Ok(Self { powers, h, prepared_h, prepared_beta_h })
128 }
129}
130
131impl<E: PairingEngine> ToBytes for UniversalParams<E> {
132 fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
133 self.powers.write_le(&mut writer)?;
135
136 self.h.write_le(&mut writer)?;
138
139 self.prepared_h.write_le(&mut writer)?;
141
142 self.prepared_beta_h.write_le(&mut writer)?;
144
145 Ok(())
146 }
147}
148
149#[derive(Clone, Debug, Default, Hash)]
151pub struct Powers<'a, E: PairingEngine> {
152 pub powers_of_beta_g: Cow<'a, [E::G1Affine]>,
154 pub powers_of_beta_times_gamma_g: Cow<'a, [E::G1Affine]>,
156}
157
158impl<E: PairingEngine> Powers<'_, E> {
159 pub fn size(&self) -> usize {
161 self.powers_of_beta_g.len()
162 }
163}
164#[derive(Clone, Debug, Hash)]
166pub struct LagrangeBasis<'a, E: PairingEngine> {
167 pub lagrange_basis_at_beta_g: Cow<'a, [E::G1Affine]>,
169 pub powers_of_beta_times_gamma_g: Cow<'a, [E::G1Affine]>,
171 pub domain: EvaluationDomain<E::Fr>,
174}
175
176impl<E: PairingEngine> LagrangeBasis<'_, E> {
177 pub fn size(&self) -> usize {
179 self.lagrange_basis_at_beta_g.len()
180 }
181}
182
183#[derive(Clone, Debug, Default, PartialEq, Eq)]
185pub struct VerifierKey<E: PairingEngine> {
186 pub g: E::G1Affine,
188 pub gamma_g: E::G1Affine,
190 pub h: E::G2Affine,
192 pub beta_h: E::G2Affine,
194 pub prepared_h: <E::G2Affine as PairingCurve>::Prepared,
196 pub prepared_beta_h: <E::G2Affine as PairingCurve>::Prepared,
198}
199
200impl<E: PairingEngine> CanonicalSerialize for VerifierKey<E> {
201 fn serialize_with_mode<W: Write>(&self, mut writer: W, compress: Compress) -> Result<(), SerializationError> {
202 self.g.serialize_with_mode(&mut writer, compress)?;
203 self.gamma_g.serialize_with_mode(&mut writer, compress)?;
204 self.h.serialize_with_mode(&mut writer, compress)?;
205 self.beta_h.serialize_with_mode(&mut writer, compress)?;
206 Ok(())
207 }
208
209 fn serialized_size(&self, compress: Compress) -> usize {
210 self.g.serialized_size(compress)
211 + self.gamma_g.serialized_size(compress)
212 + self.h.serialized_size(compress)
213 + self.beta_h.serialized_size(compress)
214 }
215}
216
217impl<E: PairingEngine> CanonicalDeserialize for VerifierKey<E> {
218 fn deserialize_with_mode<R: Read>(
219 mut reader: R,
220 compress: Compress,
221 validate: Validate,
222 ) -> Result<Self, SerializationError> {
223 let g = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
224 let gamma_g = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
225 let h: E::G2Affine = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
226 let beta_h: E::G2Affine = CanonicalDeserialize::deserialize_with_mode(&mut reader, compress, validate)?;
227 let prepared_h = h.prepare();
228 let prepared_beta_h = beta_h.prepare();
229 Ok(VerifierKey { g, gamma_g, h, beta_h, prepared_h, prepared_beta_h })
230 }
231}
232
233impl<E: PairingEngine> Valid for VerifierKey<E> {
234 fn check(&self) -> Result<(), SerializationError> {
235 Valid::check(&self.g)?;
236 Valid::check(&self.gamma_g)?;
237 Valid::check(&self.h)?;
238 Valid::check(&self.beta_h)?;
239 Ok(())
240 }
241
242 fn batch_check<'a>(batch: impl Iterator<Item = &'a Self> + Send) -> Result<(), SerializationError>
243 where
244 Self: 'a,
245 {
246 let batch: Vec<_> = batch.collect();
247 Valid::batch_check(batch.iter().map(|v| &v.g))?;
248 Valid::batch_check(batch.iter().map(|v| &v.gamma_g))?;
249 Valid::batch_check(batch.iter().map(|v| &v.h))?;
250 Valid::batch_check(batch.iter().map(|v| &v.beta_h))?;
251 Ok(())
252 }
253}
254
255impl<E: PairingEngine> FromBytes for VerifierKey<E> {
256 fn read_le<R: Read>(mut reader: R) -> io::Result<Self> {
257 CanonicalDeserialize::deserialize_compressed(&mut reader)
258 .map_err(|_| error("could not deserialize VerifierKey"))
259 }
260}
261
262impl<E: PairingEngine> ToBytes for VerifierKey<E> {
263 fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
264 CanonicalSerialize::serialize_compressed(self, &mut writer)
265 .map_err(|_| error("could not serialize VerifierKey"))
266 }
267}
268
269#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, CanonicalSerialize, CanonicalDeserialize)]
271pub struct KZGCommitment<E: PairingEngine>(
272 pub E::G1Affine,
274);
275
276impl<E: PairingEngine> FromBytes for KZGCommitment<E> {
277 fn read_le<R: Read>(mut reader: R) -> io::Result<Self> {
278 CanonicalDeserialize::deserialize_compressed(&mut reader)
279 .map_err(|_| error("could not deserialize KZGCommitment"))
280 }
281}
282
283impl<E: PairingEngine> ToBytes for KZGCommitment<E> {
284 fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
285 CanonicalSerialize::serialize_compressed(self, &mut writer)
286 .map_err(|_| error("could not serialize KZGCommitment"))
287 }
288}
289
290impl<E: PairingEngine> KZGCommitment<E> {
291 #[inline]
292 pub fn empty() -> Self {
293 KZGCommitment(E::G1Affine::zero())
294 }
295
296 pub fn has_degree_bound(&self) -> bool {
297 false
298 }
299
300 pub fn is_in_correct_subgroup_assuming_on_curve(&self) -> bool {
301 self.0.is_in_correct_subgroup_assuming_on_curve()
302 }
303}
304
305impl<E: PairingEngine> ToConstraintField<E::Fq> for KZGCommitment<E> {
306 fn to_field_elements(&self) -> Result<Vec<E::Fq>, ConstraintFieldError> {
307 self.0.to_field_elements()
308 }
309}
310
311#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, CanonicalSerialize, CanonicalDeserialize)]
313pub struct KZGRandomness<E: PairingEngine> {
314 pub blinding_polynomial: DensePolynomial<E::Fr>,
316}
317impl<E: PairingEngine> FromBytes for KZGRandomness<E> {
318 fn read_le<R: Read>(mut reader: R) -> io::Result<Self> {
319 CanonicalDeserialize::deserialize_compressed(&mut reader)
320 .map_err(|_| error("could not deserialize KZGRandomness"))
321 }
322}
323
324impl<E: PairingEngine> ToBytes for KZGRandomness<E> {
325 fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
326 CanonicalSerialize::serialize_compressed(self, &mut writer)
327 .map_err(|_| error("could not serialize KZGRandomness"))
328 }
329}
330
331impl<E: PairingEngine> KZGRandomness<E> {
332 #[inline]
335 pub fn is_hiding(&self) -> bool {
336 !self.blinding_polynomial.is_zero()
337 }
338
339 #[inline]
341 pub fn calculate_hiding_polynomial_degree(hiding_bound: usize) -> usize {
342 hiding_bound + 1
343 }
344}
345
346impl<E: PairingEngine> KZGRandomness<E> {
347 pub fn empty() -> Self {
348 Self { blinding_polynomial: DensePolynomial::zero() }
349 }
350
351 pub fn rand<R: RngCore>(hiding_bound: usize, _: bool, rng: &mut R) -> Self {
352 let mut randomness = KZGRandomness::empty();
353 let hiding_poly_degree = Self::calculate_hiding_polynomial_degree(hiding_bound);
354 randomness.blinding_polynomial = DensePolynomial::rand(hiding_poly_degree, rng);
355 randomness
356 }
357}
358
359impl<'a, E: PairingEngine> Add<&'a KZGRandomness<E>> for KZGRandomness<E> {
360 type Output = Self;
361
362 #[inline]
363 fn add(mut self, other: &'a Self) -> Self {
364 self.blinding_polynomial += &other.blinding_polynomial;
365 self
366 }
367}
368
369impl<'a, E: PairingEngine> Add<(E::Fr, &'a KZGRandomness<E>)> for KZGRandomness<E> {
370 type Output = Self;
371
372 #[inline]
373 fn add(mut self, other: (E::Fr, &'a KZGRandomness<E>)) -> Self {
374 self += other;
375 self
376 }
377}
378
379impl<'a, E: PairingEngine> AddAssign<&'a KZGRandomness<E>> for KZGRandomness<E> {
380 #[inline]
381 fn add_assign(&mut self, other: &'a Self) {
382 self.blinding_polynomial += &other.blinding_polynomial;
383 }
384}
385
386impl<'a, E: PairingEngine> AddAssign<(E::Fr, &'a KZGRandomness<E>)> for KZGRandomness<E> {
387 #[inline]
388 fn add_assign(&mut self, (f, other): (E::Fr, &'a KZGRandomness<E>)) {
389 self.blinding_polynomial += (f, &other.blinding_polynomial);
390 }
391}
392
393#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash, CanonicalSerialize, CanonicalDeserialize)]
395pub struct KZGProof<E: PairingEngine> {
396 pub w: E::G1Affine,
400 pub random_v: Option<E::Fr>,
403}
404
405impl<E: PairingEngine> KZGProof<E> {
406 pub fn absorb_into_sponge(&self, sponge: &mut impl AlgebraicSponge<E::Fq, 2>) {
407 sponge.absorb_native_field_elements(&self.w.to_field_elements().unwrap());
408 if let Some(random_v) = self.random_v {
409 sponge.absorb_nonnative_field_elements([random_v]);
410 }
411 }
412}
413
414impl<E: PairingEngine> FromBytes for KZGProof<E> {
415 fn read_le<R: Read>(mut reader: R) -> io::Result<Self> {
416 CanonicalDeserialize::deserialize_compressed(&mut reader).map_err(|_| error("could not deserialize KZG proof"))
417 }
418}
419
420impl<E: PairingEngine> ToBytes for KZGProof<E> {
421 fn write_le<W: Write>(&self, mut writer: W) -> io::Result<()> {
422 CanonicalSerialize::serialize_compressed(self, &mut writer).map_err(|_| error("could not serialize KZG proof"))
423 }
424}
425
426impl<E: PairingEngine> KZGProof<E> {
427 pub fn is_hiding(&self) -> bool {
428 self.random_v.is_some()
429 }
430}