snarkvm_parameters/mainnet/
powers.rs1use super::*;
17use snarkvm_curves::traits::{PairingCurve, PairingEngine};
18use snarkvm_utilities::{
19 CanonicalDeserialize,
20 CanonicalSerialize,
21 Compress,
22 FromBytes,
23 Read,
24 SerializationError,
25 ToBytes,
26 Valid,
27 Validate,
28 Write,
29};
30
31use anyhow::{Result, anyhow, bail, ensure};
32use parking_lot::RwLock;
33use std::{collections::BTreeMap, ops::Range, sync::Arc};
34
35const NUM_POWERS_15: usize = 1 << 15;
36const NUM_POWERS_16: usize = 1 << 16;
37const NUM_POWERS_17: usize = 1 << 17;
38const NUM_POWERS_18: usize = 1 << 18;
39const NUM_POWERS_19: usize = 1 << 19;
40const NUM_POWERS_20: usize = 1 << 20;
41const NUM_POWERS_21: usize = 1 << 21;
42const NUM_POWERS_22: usize = 1 << 22;
43const NUM_POWERS_23: usize = 1 << 23;
44const NUM_POWERS_24: usize = 1 << 24;
45const NUM_POWERS_25: usize = 1 << 25;
46#[cfg(feature = "large_params")]
52const NUM_POWERS_26: usize = 1 << 26;
53#[cfg(feature = "large_params")]
54const NUM_POWERS_27: usize = 1 << 27;
55const NUM_POWERS_28: usize = 1 << 28;
56
57const MAX_NUM_POWERS: usize = NUM_POWERS_28;
59
60lazy_static::lazy_static! {
61 static ref POWERS_OF_BETA_G_15: Vec<u8> = Degree15::load_bytes().expect("Failed to load powers of beta in universal SRS");
62 static ref SHIFTED_POWERS_OF_BETA_G_15: Vec<u8> = ShiftedDegree15::load_bytes().expect("Failed to load powers of beta in universal SRS");
63 static ref POWERS_OF_BETA_GAMMA_G: Vec<u8> = Gamma::load_bytes().expect("Failed to load powers of beta wrt gamma * G in universal SRS");
64 static ref NEG_POWERS_OF_BETA_H: Vec<u8> = NegBeta::load_bytes().expect("Failed to load negative powers of beta in universal SRS");
65 static ref BETA_H: Vec<u8> = BetaH::load_bytes().expect("Failed to load negative powers of beta in universal SRS");
66}
67
68#[derive(Debug)]
70pub struct PowersOfG<E: PairingEngine> {
71 powers_of_beta_g: RwLock<PowersOfBetaG<E>>,
73 powers_of_beta_times_gamma_g: BTreeMap<usize, E::G1Affine>,
76 negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine>,
79 prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>>,
83 beta_h: E::G2Affine,
85}
86
87impl<E: PairingEngine> PowersOfG<E> {
88 pub fn load() -> Result<Self> {
90 let powers_of_beta_g = RwLock::new(PowersOfBetaG::load()?);
91
92 let powers_of_beta_times_gamma_g = BTreeMap::deserialize_uncompressed_unchecked(&**POWERS_OF_BETA_GAMMA_G)?;
94
95 let negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine> =
97 BTreeMap::deserialize_uncompressed_unchecked(&**NEG_POWERS_OF_BETA_H)?;
98
99 let prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> =
101 Arc::new(negative_powers_of_beta_h.iter().map(|(d, affine)| (*d, affine.prepare())).collect());
102
103 let beta_h = E::G2Affine::deserialize_uncompressed_unchecked(&**BETA_H)?;
104
105 Ok(Self {
107 powers_of_beta_g,
108 powers_of_beta_times_gamma_g,
109 negative_powers_of_beta_h,
110 prepared_negative_powers_of_beta_h,
111 beta_h,
112 })
113 }
114
115 pub fn download_powers_for(&self, range: Range<usize>) -> Result<()> {
117 self.powers_of_beta_g.write().download_powers_for(&range)
118 }
119
120 pub fn num_powers(&self) -> usize {
122 self.powers_of_beta_g.read().num_powers()
123 }
124
125 pub fn max_num_powers(&self) -> usize {
127 MAX_NUM_POWERS
128 }
129
130 pub fn powers_of_beta_gamma_g(&self) -> &BTreeMap<usize, E::G1Affine> {
132 &self.powers_of_beta_times_gamma_g
133 }
134
135 pub fn power_of_beta_g(&self, index: usize) -> Result<E::G1Affine> {
137 self.powers_of_beta_g.write().power(index)
138 }
139
140 pub fn powers_of_beta_g(&self, range: Range<usize>) -> Result<Vec<E::G1Affine>> {
142 Ok(self.powers_of_beta_g.write().powers(range)?.to_vec())
143 }
144
145 pub fn negative_powers_of_beta_h(&self) -> &BTreeMap<usize, E::G2Affine> {
146 &self.negative_powers_of_beta_h
147 }
148
149 pub fn prepared_negative_powers_of_beta_h(&self) -> Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> {
150 self.prepared_negative_powers_of_beta_h.clone()
151 }
152
153 pub fn beta_h(&self) -> E::G2Affine {
154 self.beta_h
155 }
156}
157
158impl<E: PairingEngine> CanonicalSerialize for PowersOfG<E> {
159 fn serialize_with_mode<W: Write>(&self, mut writer: W, mode: Compress) -> Result<(), SerializationError> {
160 self.powers_of_beta_g.read().serialize_with_mode(&mut writer, mode)?;
161 self.powers_of_beta_times_gamma_g.serialize_with_mode(&mut writer, mode)?;
162 self.negative_powers_of_beta_h.serialize_with_mode(&mut writer, mode)?;
163 self.beta_h.serialize_with_mode(&mut writer, mode)?;
164 Ok(())
165 }
166
167 fn serialized_size(&self, mode: Compress) -> usize {
168 self.powers_of_beta_g.read().serialized_size(mode)
169 + self.powers_of_beta_times_gamma_g.serialized_size(mode)
170 + self.negative_powers_of_beta_h.serialized_size(mode)
171 + self.beta_h.serialized_size(mode)
172 }
173}
174
175impl<E: PairingEngine> CanonicalDeserialize for PowersOfG<E> {
176 fn deserialize_with_mode<R: Read>(
177 mut reader: R,
178 compress: Compress,
179 validate: Validate,
180 ) -> Result<Self, SerializationError> {
181 let powers_of_beta_g = RwLock::new(PowersOfBetaG::deserialize_with_mode(&mut reader, compress, Validate::No)?);
182
183 let powers_of_beta_times_gamma_g = BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?;
185
186 let negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine> =
188 BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?;
189
190 let prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> =
192 Arc::new(negative_powers_of_beta_h.iter().map(|(d, affine)| (*d, affine.prepare())).collect());
193
194 let beta_h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
195
196 let powers = Self {
197 powers_of_beta_g,
198 powers_of_beta_times_gamma_g,
199 negative_powers_of_beta_h,
200 prepared_negative_powers_of_beta_h,
201 beta_h,
202 };
203 if let Validate::Yes = validate {
204 powers.check()?;
205 }
206 Ok(powers)
207 }
208}
209
210impl<E: PairingEngine> Valid for PowersOfG<E> {
211 fn check(&self) -> Result<(), SerializationError> {
212 self.powers_of_beta_g.read().check()?;
213 self.powers_of_beta_times_gamma_g.check()?;
214 self.negative_powers_of_beta_h.check()?;
215 self.prepared_negative_powers_of_beta_h.check()?;
216 self.beta_h.check()
217 }
218}
219
220impl<E: PairingEngine> FromBytes for PowersOfG<E> {
221 fn read_le<R: Read>(reader: R) -> std::io::Result<Self> {
223 Self::deserialize_with_mode(reader, Compress::No, Validate::No).map_err(|e| e.into())
224 }
225}
226
227impl<E: PairingEngine> ToBytes for PowersOfG<E> {
228 fn write_le<W: Write>(&self, writer: W) -> std::io::Result<()> {
230 self.serialize_with_mode(writer, Compress::No).map_err(|e| e.into())
231 }
232}
233
234#[derive(Debug, CanonicalSerialize, CanonicalDeserialize)]
235pub struct PowersOfBetaG<E: PairingEngine> {
236 powers_of_beta_g: Vec<E::G1Affine>,
238 shifted_powers_of_beta_g: Vec<E::G1Affine>,
241}
242
243impl<E: PairingEngine> PowersOfBetaG<E> {
244 pub fn num_powers(&self) -> usize {
246 self.powers_of_beta_g.len()
247 }
248
249 fn load() -> Result<Self> {
251 let powers_of_beta_g = Vec::deserialize_uncompressed_unchecked(&**POWERS_OF_BETA_G_15)?;
253
254 ensure!(powers_of_beta_g.len() == NUM_POWERS_15, "Incorrect number of powers in the recovered SRS");
256
257 let shifted_powers_of_beta_g = Vec::deserialize_uncompressed_unchecked(&**SHIFTED_POWERS_OF_BETA_G_15)?;
258 ensure!(shifted_powers_of_beta_g.len() == NUM_POWERS_15, "Incorrect number of powers in the recovered SRS");
259 Ok(PowersOfBetaG { powers_of_beta_g, shifted_powers_of_beta_g })
260 }
261
262 pub fn available_powers(&self) -> (Range<usize>, Range<usize>) {
271 if !self.shifted_powers_of_beta_g.is_empty() {
272 let lower_shifted_bound = MAX_NUM_POWERS - self.shifted_powers_of_beta_g.len();
273 ((0..self.powers_of_beta_g.len()), (lower_shifted_bound..MAX_NUM_POWERS))
274 } else {
275 assert_eq!(self.powers_of_beta_g.len(), MAX_NUM_POWERS, "Incorrect number of powers in the recovered SRS");
277 ((0..MAX_NUM_POWERS), (0..MAX_NUM_POWERS))
278 }
279 }
280
281 fn contains_in_normal_powers(&self, range: &Range<usize>) -> bool {
282 let (normal, _) = self.available_powers();
283 normal.contains(&range.start) && (normal.end >= range.end)
284 }
285
286 fn contains_in_shifted_powers(&self, range: &Range<usize>) -> bool {
287 let (_, shifted) = self.available_powers();
288 shifted.contains(&range.start) && (shifted.end >= range.end)
289 }
290
291 fn contains_powers(&self, range: &Range<usize>) -> bool {
292 self.contains_in_normal_powers(range) || self.contains_in_shifted_powers(range)
293 }
294
295 fn distance_from_normal_of(&self, range: &Range<usize>) -> usize {
296 (range.end as isize - self.available_powers().0.end as isize).unsigned_abs()
297 }
298
299 fn distance_from_shifted_of(&self, range: &Range<usize>) -> usize {
300 (range.start as isize - self.available_powers().1.start as isize).unsigned_abs()
301 }
302
303 fn shifted_powers(&self, range: Range<usize>) -> Result<&[E::G1Affine]> {
305 ensure!(
306 self.contains_in_shifted_powers(&range),
307 "Requested range is not contained in the available shifted powers"
308 );
309
310 if range.start < MAX_NUM_POWERS / 2 {
311 ensure!(self.shifted_powers_of_beta_g.is_empty());
312 Ok(&self.powers_of_beta_g[range])
315 } else {
316 let lower = self.shifted_powers_of_beta_g.len() - (MAX_NUM_POWERS - range.start);
318 let upper = self.shifted_powers_of_beta_g.len() - (MAX_NUM_POWERS - range.end);
319 Ok(&self.shifted_powers_of_beta_g[lower..upper])
320 }
321 }
322
323 fn normal_powers(&self, range: Range<usize>) -> Result<&[E::G1Affine]> {
325 ensure!(self.contains_in_normal_powers(&range), "Requested range is not contained in the available powers");
326 Ok(&self.powers_of_beta_g[range])
327 }
328
329 fn power(&mut self, target: usize) -> Result<E::G1Affine> {
331 self.powers(target..(target + 1)).map(|s| s[0])
332 }
333
334 fn powers(&mut self, range: Range<usize>) -> Result<&[E::G1Affine]> {
336 if range.is_empty() {
337 return Ok(&self.powers_of_beta_g[0..0]);
338 }
339 ensure!(range.start < range.end, "Lower power must be less than upper power");
340 ensure!(range.end <= MAX_NUM_POWERS, "Upper bound must be less than the maximum number of powers");
341 if !self.contains_powers(&range) {
342 self.download_powers_for(&range)?;
344 }
345 match self.contains_in_normal_powers(&range) {
346 true => self.normal_powers(range),
347 false => self.shifted_powers(range),
348 }
349 }
350
351 pub fn download_powers_for(&mut self, range: &Range<usize>) -> Result<()> {
352 if self.contains_in_normal_powers(range) || self.contains_in_shifted_powers(range) {
353 return Ok(());
354 }
355 let half_max = MAX_NUM_POWERS / 2;
356 if (range.start <= half_max) && (range.end > half_max) {
357 self.download_powers_up_to(range.end)?;
360 self.shifted_powers_of_beta_g = Vec::new();
361 } else if self.distance_from_shifted_of(range) < self.distance_from_normal_of(range) {
362 self.download_shifted_powers_from(range.start)?;
364 } else {
365 self.download_powers_up_to(range.end)?;
367 }
368 Ok(())
369 }
370
371 fn download_powers_up_to(&mut self, end: usize) -> Result<()> {
374 let final_power_of_two =
376 end.checked_next_power_of_two().ok_or_else(|| anyhow!("Requesting too many powers"))?;
377 ensure!(final_power_of_two <= MAX_NUM_POWERS, "Requesting more powers than exist in the SRS");
379
380 let current_power_of_two = self
382 .powers_of_beta_g
383 .len()
384 .checked_next_power_of_two()
385 .ok_or_else(|| anyhow!("The current degree is too large"))?;
386
387 let mut download_queue = Vec::with_capacity(14);
389
390 let mut accumulator = current_power_of_two * 2;
392 while accumulator <= final_power_of_two {
394 download_queue.push(accumulator);
395 accumulator =
396 accumulator.checked_mul(2).ok_or_else(|| anyhow!("Overflowed while requesting a larger degree"))?;
397 }
398 ensure!(final_power_of_two * 2 == accumulator, "Ensure the loop terminates at the right power of two");
399
400 let additional_size = final_power_of_two
402 .checked_sub(self.powers_of_beta_g.len())
403 .ok_or_else(|| anyhow!("final_power_of_two is smaller than existing powers"))?;
404 self.powers_of_beta_g.reserve(additional_size);
405
406 for num_powers in &download_queue {
408 #[cfg(debug_assertions)]
409 println!("Loading {num_powers} powers");
410
411 let additional_bytes = match *num_powers {
413 NUM_POWERS_16 => Degree16::load_bytes()?,
414 NUM_POWERS_17 => Degree17::load_bytes()?,
415 NUM_POWERS_18 => Degree18::load_bytes()?,
416 NUM_POWERS_19 => Degree19::load_bytes()?,
417 NUM_POWERS_20 => Degree20::load_bytes()?,
418 NUM_POWERS_21 => Degree21::load_bytes()?,
419 NUM_POWERS_22 => Degree22::load_bytes()?,
420 NUM_POWERS_23 => Degree23::load_bytes()?,
421 NUM_POWERS_24 => Degree24::load_bytes()?,
422 NUM_POWERS_25 => Degree25::load_bytes()?,
423 #[cfg(feature = "large_params")]
425 NUM_POWERS_26 => Degree26::load_bytes()?,
426 #[cfg(feature = "large_params")]
427 NUM_POWERS_27 => Degree27::load_bytes()?,
428 #[cfg(feature = "large_params")]
429 NUM_POWERS_28 => Degree28::load_bytes()?,
430 _ => bail!("Cannot download an invalid degree of '{num_powers}'"),
431 };
432
433 let additional_powers = Vec::deserialize_uncompressed_unchecked(&*additional_bytes)?;
435 self.powers_of_beta_g.extend(&additional_powers);
437 }
438 ensure!(self.powers_of_beta_g.len() == final_power_of_two, "Loaded an incorrect number of powers");
439 Ok(())
440 }
441
442 fn download_shifted_powers_from(&mut self, start: usize) -> Result<()> {
446 ensure!(start <= MAX_NUM_POWERS, "Requesting more powers than exist in the SRS");
448
449 let final_num_powers = MAX_NUM_POWERS
470 .checked_sub(start)
471 .ok_or_else(|| {
472 anyhow!("Requesting too many powers: `start ({start}) > MAX_NUM_POWERS ({MAX_NUM_POWERS})`")
473 })?
474 .checked_next_power_of_two()
475 .ok_or_else(|| anyhow!("Requesting too many powers"))?; let mut download_queue = Vec::with_capacity(14);
478 let mut existing_num_powers = self.shifted_powers_of_beta_g.len();
479 while existing_num_powers < final_num_powers {
480 existing_num_powers = existing_num_powers
481 .checked_mul(2)
482 .ok_or_else(|| anyhow!("Overflowed while requesting additional powers"))?;
483 download_queue.push(existing_num_powers);
484 }
485 download_queue.reverse(); let mut final_powers = Vec::with_capacity(final_num_powers);
488 for num_powers in &download_queue {
490 #[cfg(debug_assertions)]
491 println!("Loading {num_powers} shifted powers");
492
493 let additional_bytes = match *num_powers {
495 NUM_POWERS_16 => ShiftedDegree16::load_bytes()?,
496 NUM_POWERS_17 => ShiftedDegree17::load_bytes()?,
497 NUM_POWERS_18 => ShiftedDegree18::load_bytes()?,
498 NUM_POWERS_19 => ShiftedDegree19::load_bytes()?,
499 NUM_POWERS_20 => ShiftedDegree20::load_bytes()?,
500 NUM_POWERS_21 => ShiftedDegree21::load_bytes()?,
501 NUM_POWERS_22 => ShiftedDegree22::load_bytes()?,
502 NUM_POWERS_23 => ShiftedDegree23::load_bytes()?,
503 NUM_POWERS_24 => ShiftedDegree24::load_bytes()?,
504 NUM_POWERS_25 => ShiftedDegree25::load_bytes()?,
505 #[cfg(feature = "large_params")]
507 NUM_POWERS_26 => ShiftedDegree26::load_bytes()?,
508 #[cfg(feature = "large_params")]
509 NUM_POWERS_27 => ShiftedDegree27::load_bytes()?,
510 _ => bail!("Cannot download an invalid degree of '{num_powers}'"),
511 };
512
513 let additional_powers = Vec::deserialize_uncompressed_unchecked(&*additional_bytes)?;
515
516 final_powers.extend(additional_powers.iter());
517 }
518 final_powers.extend(self.shifted_powers_of_beta_g.iter());
519 self.shifted_powers_of_beta_g = final_powers;
520
521 ensure!(
522 self.shifted_powers_of_beta_g.len() == final_num_powers,
523 "Loaded an incorrect number of shifted powers"
524 );
525 Ok(())
526 }
527}
528
529impl<E: PairingEngine> FromBytes for PowersOfBetaG<E> {
530 fn read_le<R: Read>(reader: R) -> std::io::Result<Self> {
532 Self::deserialize_with_mode(reader, Compress::No, Validate::No).map_err(|e| e.into())
533 }
534}
535
536impl<E: PairingEngine> ToBytes for PowersOfBetaG<E> {
537 fn write_le<W: Write>(&self, writer: W) -> std::io::Result<()> {
539 self.serialize_with_mode(writer, Compress::No).map_err(|e| e.into())
540 }
541}