1use 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 dev_println,
30};
31
32use anyhow::{Result, anyhow, bail, ensure};
33#[cfg(feature = "locktick")]
34use locktick::parking_lot::RwLock;
35#[cfg(not(feature = "locktick"))]
36use parking_lot::RwLock;
37use std::{collections::BTreeMap, ops::Range, sync::Arc};
38
39const NUM_POWERS_15: usize = 1 << 15;
40const NUM_POWERS_16: usize = 1 << 16;
41const NUM_POWERS_17: usize = 1 << 17;
42const NUM_POWERS_18: usize = 1 << 18;
43const NUM_POWERS_19: usize = 1 << 19;
44const NUM_POWERS_20: usize = 1 << 20;
45const NUM_POWERS_21: usize = 1 << 21;
46const NUM_POWERS_22: usize = 1 << 22;
47const NUM_POWERS_23: usize = 1 << 23;
48const NUM_POWERS_24: usize = 1 << 24;
49const NUM_POWERS_25: usize = 1 << 25;
50#[cfg(feature = "large_params")]
56const NUM_POWERS_26: usize = 1 << 26;
57#[cfg(feature = "large_params")]
58const NUM_POWERS_27: usize = 1 << 27;
59const NUM_POWERS_28: usize = 1 << 28;
60
61pub const MAX_NUM_POWERS: usize = NUM_POWERS_28;
63
64lazy_static::lazy_static! {
65 static ref POWERS_OF_BETA_G_15: Vec<u8> = Degree15::load_bytes().expect("Failed to load powers of beta in universal SRS");
66 static ref SHIFTED_POWERS_OF_BETA_G_15: Vec<u8> = ShiftedDegree15::load_bytes().expect("Failed to load powers of beta in universal SRS");
67 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");
68 static ref NEG_POWERS_OF_BETA_H: Vec<u8> = NegBeta::load_bytes().expect("Failed to load negative powers of beta in universal SRS");
69 static ref BETA_H: Vec<u8> = BetaH::load_bytes().expect("Failed to load negative powers of beta in universal SRS");
70}
71
72pub type PowersSnapshot<E> = Arc<Vec<<E as PairingEngine>::G1Affine>>;
75
76#[derive(Debug)]
78pub struct PowersOfG<E: PairingEngine> {
79 powers_of_beta_g: RwLock<PowersOfBetaG<E>>,
83 powers_of_beta_times_gamma_g: BTreeMap<usize, E::G1Affine>,
86 negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine>,
89 prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>>,
93 beta_h: E::G2Affine,
95}
96
97impl<E: PairingEngine> PowersOfG<E> {
98 pub fn load() -> Result<Self> {
100 let powers_of_beta_g = RwLock::new(PowersOfBetaG::load()?);
101
102 let powers_of_beta_times_gamma_g = BTreeMap::deserialize_uncompressed_unchecked(&**POWERS_OF_BETA_GAMMA_G)?;
104
105 let negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine> =
107 BTreeMap::deserialize_uncompressed_unchecked(&**NEG_POWERS_OF_BETA_H)?;
108
109 let prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> =
111 Arc::new(negative_powers_of_beta_h.iter().map(|(d, affine)| (*d, affine.prepare())).collect());
112
113 let beta_h = E::G2Affine::deserialize_uncompressed_unchecked(&**BETA_H)?;
114
115 Ok(Self {
117 powers_of_beta_g,
118 powers_of_beta_times_gamma_g,
119 negative_powers_of_beta_h,
120 prepared_negative_powers_of_beta_h,
121 beta_h,
122 })
123 }
124
125 pub fn download_powers_for(&self, range: Range<usize>) -> Result<()> {
127 if range.is_empty() || self.powers_of_beta_g.read().contains_powers(&range) {
128 return Ok(());
129 }
130 ensure!(range.end <= MAX_NUM_POWERS, "Upper bound must be less than the maximum number of powers");
131 self.powers_of_beta_g.write().download_powers_for(&range)
132 }
133
134 pub fn num_powers(&self) -> usize {
136 self.powers_of_beta_g.read().num_powers()
137 }
138
139 pub fn max_num_powers(&self) -> usize {
141 MAX_NUM_POWERS
142 }
143
144 pub fn powers_of_beta_gamma_g(&self) -> &BTreeMap<usize, E::G1Affine> {
146 &self.powers_of_beta_times_gamma_g
147 }
148
149 pub fn power_of_beta_g(&self, index: usize) -> Result<E::G1Affine> {
151 self.download_powers_for(index..index + 1)?;
152 Ok(self.powers_of_beta_g.read().held_powers(index..index + 1)?[0])
153 }
154
155 pub fn powers_of_beta_g(&self, range: Range<usize>) -> Result<Vec<E::G1Affine>> {
157 self.download_powers_for(range.clone())?;
158 Ok(self.powers_of_beta_g.read().held_powers(range)?.to_vec())
159 }
160
161 pub fn shared_powers_of_beta_g(&self, range: Range<usize>) -> Result<(PowersSnapshot<E>, Range<usize>)> {
165 if range.is_empty() {
166 return Ok((Arc::new(Vec::new()), 0..0));
167 }
168 self.download_powers_for(range.clone())?;
169 let powers = self.powers_of_beta_g.read();
170 let (store, within) = powers.locate(range)?;
171 Ok((store.clone(), within))
172 }
173
174 pub fn negative_powers_of_beta_h(&self) -> &BTreeMap<usize, E::G2Affine> {
175 &self.negative_powers_of_beta_h
176 }
177
178 pub fn prepared_negative_powers_of_beta_h(&self) -> Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> {
179 self.prepared_negative_powers_of_beta_h.clone()
180 }
181
182 pub fn beta_h(&self) -> E::G2Affine {
183 self.beta_h
184 }
185}
186
187impl<E: PairingEngine> CanonicalSerialize for PowersOfG<E> {
188 fn serialize_with_mode<W: Write>(&self, mut writer: W, mode: Compress) -> Result<(), SerializationError> {
189 self.powers_of_beta_g.read().serialize_with_mode(&mut writer, mode)?;
190 self.powers_of_beta_times_gamma_g.serialize_with_mode(&mut writer, mode)?;
191 self.negative_powers_of_beta_h.serialize_with_mode(&mut writer, mode)?;
192 self.beta_h.serialize_with_mode(&mut writer, mode)?;
193 Ok(())
194 }
195
196 fn serialized_size(&self, mode: Compress) -> usize {
197 self.powers_of_beta_g.read().serialized_size(mode)
198 + self.powers_of_beta_times_gamma_g.serialized_size(mode)
199 + self.negative_powers_of_beta_h.serialized_size(mode)
200 + self.beta_h.serialized_size(mode)
201 }
202}
203
204impl<E: PairingEngine> CanonicalDeserialize for PowersOfG<E> {
205 fn deserialize_with_mode<R: Read>(mut reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> {
206 let powers_of_beta_g = RwLock::new(PowersOfBetaG::deserialize_with_mode(&mut reader, compress, Validate::No)?);
207
208 let powers_of_beta_times_gamma_g = BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?;
210
211 let negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine> =
213 BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?;
214
215 let prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> =
217 Arc::new(negative_powers_of_beta_h.iter().map(|(d, affine)| (*d, affine.prepare())).collect());
218
219 let beta_h = E::G2Affine::deserialize_with_mode(&mut reader, compress, Validate::No)?;
220
221 let powers = Self {
222 powers_of_beta_g,
223 powers_of_beta_times_gamma_g,
224 negative_powers_of_beta_h,
225 prepared_negative_powers_of_beta_h,
226 beta_h,
227 };
228 if let Validate::Yes = validate {
229 powers.check()?;
230 }
231 Ok(powers)
232 }
233}
234
235impl<E: PairingEngine> Valid for PowersOfG<E> {
236 fn check(&self) -> Result<(), SerializationError> {
237 self.powers_of_beta_g.read().check()?;
238 self.powers_of_beta_times_gamma_g.check()?;
239 self.negative_powers_of_beta_h.check()?;
240 self.prepared_negative_powers_of_beta_h.check()?;
241 self.beta_h.check()
242 }
243}
244
245impl<E: PairingEngine> FromBytes for PowersOfG<E> {
246 fn read_le<R: Read>(reader: R) -> std::io::Result<Self> {
248 Self::deserialize_with_mode(reader, Compress::No, Validate::No).map_err(|e| e.into())
249 }
250}
251
252impl<E: PairingEngine> ToBytes for PowersOfG<E> {
253 fn write_le<W: Write>(&self, writer: W) -> std::io::Result<()> {
255 self.serialize_with_mode(writer, Compress::No).map_err(|e| e.into())
256 }
257}
258
259#[derive(Debug)]
260pub struct PowersOfBetaG<E: PairingEngine> {
261 powers_of_beta_g: PowersSnapshot<E>,
263 shifted_powers_of_beta_g: PowersSnapshot<E>,
266}
267
268impl<E: PairingEngine> CanonicalSerialize for PowersOfBetaG<E> {
269 fn serialize_with_mode<W: Write>(&self, mut writer: W, mode: Compress) -> Result<(), SerializationError> {
270 self.powers_of_beta_g.as_ref().serialize_with_mode(&mut writer, mode)?;
271 self.shifted_powers_of_beta_g.as_ref().serialize_with_mode(&mut writer, mode)
272 }
273
274 fn serialized_size(&self, mode: Compress) -> usize {
275 self.powers_of_beta_g.as_ref().serialized_size(mode) + self.shifted_powers_of_beta_g.as_ref().serialized_size(mode)
276 }
277}
278
279impl<E: PairingEngine> CanonicalDeserialize for PowersOfBetaG<E> {
280 fn deserialize_with_mode<R: Read>(mut reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> {
281 let powers_of_beta_g = Vec::deserialize_with_mode(&mut reader, compress, validate)?;
282 let shifted_powers_of_beta_g = Vec::deserialize_with_mode(&mut reader, compress, validate)?;
283 Ok(Self { powers_of_beta_g: Arc::new(powers_of_beta_g), shifted_powers_of_beta_g: Arc::new(shifted_powers_of_beta_g) })
284 }
285}
286
287impl<E: PairingEngine> Valid for PowersOfBetaG<E> {
288 fn check(&self) -> Result<(), SerializationError> {
289 self.powers_of_beta_g.as_ref().check()?;
290 self.shifted_powers_of_beta_g.as_ref().check()
291 }
292}
293
294impl<E: PairingEngine> PowersOfBetaG<E> {
295 pub fn num_powers(&self) -> usize {
297 self.powers_of_beta_g.len()
298 }
299
300 fn load() -> Result<Self> {
302 let powers_of_beta_g = Vec::deserialize_uncompressed_unchecked(&**POWERS_OF_BETA_G_15)?;
304
305 ensure!(powers_of_beta_g.len() == NUM_POWERS_15, "Incorrect number of powers in the recovered SRS");
307
308 let shifted_powers_of_beta_g = Vec::deserialize_uncompressed_unchecked(&**SHIFTED_POWERS_OF_BETA_G_15)?;
309 ensure!(shifted_powers_of_beta_g.len() == NUM_POWERS_15, "Incorrect number of powers in the recovered SRS");
310 Ok(PowersOfBetaG {
311 powers_of_beta_g: Arc::new(powers_of_beta_g),
312 shifted_powers_of_beta_g: Arc::new(shifted_powers_of_beta_g),
313 })
314 }
315
316 pub fn available_powers(&self) -> (Range<usize>, Range<usize>) {
325 if !self.shifted_powers_of_beta_g.is_empty() {
326 let lower_shifted_bound = MAX_NUM_POWERS - self.shifted_powers_of_beta_g.len();
327 ((0..self.powers_of_beta_g.len()), (lower_shifted_bound..MAX_NUM_POWERS))
328 } else {
329 assert_eq!(self.powers_of_beta_g.len(), MAX_NUM_POWERS, "Incorrect number of powers in the recovered SRS");
331 ((0..MAX_NUM_POWERS), (0..MAX_NUM_POWERS))
332 }
333 }
334
335 fn contains_in_normal_powers(&self, range: &Range<usize>) -> bool {
336 let (normal, _) = self.available_powers();
337 normal.contains(&range.start) && (normal.end >= range.end)
338 }
339
340 fn contains_in_shifted_powers(&self, range: &Range<usize>) -> bool {
341 let (_, shifted) = self.available_powers();
342 shifted.contains(&range.start) && (shifted.end >= range.end)
343 }
344
345 fn contains_powers(&self, range: &Range<usize>) -> bool {
346 self.contains_in_normal_powers(range) || self.contains_in_shifted_powers(range)
347 }
348
349 fn distance_from_normal_of(&self, range: &Range<usize>) -> usize {
350 (range.end as isize - self.available_powers().0.end as isize).unsigned_abs()
351 }
352
353 fn distance_from_shifted_of(&self, range: &Range<usize>) -> usize {
354 (range.start as isize - self.available_powers().1.start as isize).unsigned_abs()
355 }
356
357 fn locate(&self, range: Range<usize>) -> Result<(&PowersSnapshot<E>, Range<usize>)> {
360 if range.is_empty() {
361 return Ok((&self.powers_of_beta_g, 0..0));
362 }
363 ensure!(range.end <= MAX_NUM_POWERS, "Upper bound must be less than the maximum number of powers");
364 if self.contains_in_normal_powers(&range) {
365 return Ok((&self.powers_of_beta_g, range));
366 }
367 ensure!(self.contains_in_shifted_powers(&range), "Requested range is not contained in the available powers");
368 if range.start < MAX_NUM_POWERS / 2 {
369 ensure!(self.shifted_powers_of_beta_g.is_empty());
370 Ok((&self.powers_of_beta_g, range))
373 } else {
374 let lower = self.shifted_powers_of_beta_g.len() - (MAX_NUM_POWERS - range.start);
376 let upper = self.shifted_powers_of_beta_g.len() - (MAX_NUM_POWERS - range.end);
377 Ok((&self.shifted_powers_of_beta_g, lower..upper))
378 }
379 }
380
381 fn held_powers(&self, range: Range<usize>) -> Result<&[E::G1Affine]> {
383 let (store, within) = self.locate(range)?;
384 Ok(&store[within])
385 }
386
387 pub fn download_powers_for(&mut self, range: &Range<usize>) -> Result<()> {
388 if self.contains_in_normal_powers(range) || self.contains_in_shifted_powers(range) {
389 return Ok(());
390 }
391 let half_max = MAX_NUM_POWERS / 2;
392 if (range.start <= half_max) && (range.end > half_max) {
393 self.download_powers_up_to(range.end)?;
396 self.shifted_powers_of_beta_g = Arc::new(Vec::new());
397 } else if self.distance_from_shifted_of(range) < self.distance_from_normal_of(range) {
398 self.download_shifted_powers_from(range.start)?;
400 } else {
401 self.download_powers_up_to(range.end)?;
403 }
404 Ok(())
405 }
406
407 fn download_powers_up_to(&mut self, end: usize) -> Result<()> {
410 let final_power_of_two = end.checked_next_power_of_two().ok_or_else(|| anyhow!("Requesting too many powers"))?;
412 ensure!(final_power_of_two <= MAX_NUM_POWERS, "Requesting more powers than exist in the SRS");
414
415 let current_power_of_two =
417 self.powers_of_beta_g.len().checked_next_power_of_two().ok_or_else(|| anyhow!("The current degree is too large"))?;
418
419 let mut download_queue = Vec::with_capacity(14);
421
422 let mut accumulator = current_power_of_two * 2;
424 while accumulator <= final_power_of_two {
426 download_queue.push(accumulator);
427 accumulator = accumulator.checked_mul(2).ok_or_else(|| anyhow!("Overflowed while requesting a larger degree"))?;
428 }
429 ensure!(final_power_of_two * 2 == accumulator, "Ensure the loop terminates at the right power of two");
430
431 let additional_size = final_power_of_two
436 .checked_sub(self.powers_of_beta_g.len())
437 .ok_or_else(|| anyhow!("final_power_of_two is smaller than existing powers"))?;
438 let mut copy = Arc::get_mut(&mut self.powers_of_beta_g).is_none().then(|| {
439 let mut copy = Vec::with_capacity(final_power_of_two);
440 copy.extend_from_slice(&self.powers_of_beta_g);
441 copy
442 });
443 let powers_of_beta_g = match copy.as_mut() {
444 Some(copy) => copy,
445 None => Arc::get_mut(&mut self.powers_of_beta_g).expect("an unshared snapshot stays unshared under &mut self"),
448 };
449 powers_of_beta_g.reserve(additional_size);
450
451 let downloaded = download_queue.iter().try_for_each(|&num_powers| -> Result<()> {
454 dev_println!("Loading {num_powers} powers");
455
456 let additional_bytes = match num_powers {
458 NUM_POWERS_16 => Degree16::load_bytes()?,
459 NUM_POWERS_17 => Degree17::load_bytes()?,
460 NUM_POWERS_18 => Degree18::load_bytes()?,
461 NUM_POWERS_19 => Degree19::load_bytes()?,
462 NUM_POWERS_20 => Degree20::load_bytes()?,
463 NUM_POWERS_21 => Degree21::load_bytes()?,
464 NUM_POWERS_22 => Degree22::load_bytes()?,
465 NUM_POWERS_23 => Degree23::load_bytes()?,
466 NUM_POWERS_24 => Degree24::load_bytes()?,
467 NUM_POWERS_25 => Degree25::load_bytes()?,
468 #[cfg(feature = "large_params")]
470 NUM_POWERS_26 => Degree26::load_bytes()?,
471 #[cfg(feature = "large_params")]
472 NUM_POWERS_27 => Degree27::load_bytes()?,
473 #[cfg(feature = "large_params")]
474 NUM_POWERS_28 => Degree28::load_bytes()?,
475 _ => bail!("Cannot download an invalid degree of '{num_powers}'"),
476 };
477
478 let additional_powers: Vec<E::G1Affine> = Vec::deserialize_uncompressed_unchecked(&*additional_bytes)?;
480 powers_of_beta_g.extend(additional_powers);
482 Ok(())
483 });
484 if let Some(copy) = copy {
486 self.powers_of_beta_g = Arc::new(copy);
487 }
488 downloaded?;
489 ensure!(self.powers_of_beta_g.len() == final_power_of_two, "Loaded an incorrect number of powers");
490 Ok(())
491 }
492
493 fn download_shifted_powers_from(&mut self, start: usize) -> Result<()> {
497 ensure!(start <= MAX_NUM_POWERS, "Requesting more powers than exist in the SRS");
499
500 let final_num_powers = MAX_NUM_POWERS
521 .checked_sub(start)
522 .ok_or_else(|| anyhow!("Requesting too many powers: `start ({start}) > MAX_NUM_POWERS ({MAX_NUM_POWERS})`"))?
523 .checked_next_power_of_two()
524 .ok_or_else(|| anyhow!("Requesting too many powers"))?; let mut download_queue = Vec::with_capacity(14);
527 let mut existing_num_powers = self.shifted_powers_of_beta_g.len();
528 while existing_num_powers < final_num_powers {
529 existing_num_powers =
530 existing_num_powers.checked_mul(2).ok_or_else(|| anyhow!("Overflowed while requesting additional powers"))?;
531 download_queue.push(existing_num_powers);
532 }
533 download_queue.reverse(); let mut final_powers = Vec::with_capacity(final_num_powers);
536 for num_powers in &download_queue {
538 dev_println!("Loading {num_powers} shifted powers");
539
540 let additional_bytes = match *num_powers {
542 NUM_POWERS_16 => ShiftedDegree16::load_bytes()?,
543 NUM_POWERS_17 => ShiftedDegree17::load_bytes()?,
544 NUM_POWERS_18 => ShiftedDegree18::load_bytes()?,
545 NUM_POWERS_19 => ShiftedDegree19::load_bytes()?,
546 NUM_POWERS_20 => ShiftedDegree20::load_bytes()?,
547 NUM_POWERS_21 => ShiftedDegree21::load_bytes()?,
548 NUM_POWERS_22 => ShiftedDegree22::load_bytes()?,
549 NUM_POWERS_23 => ShiftedDegree23::load_bytes()?,
550 NUM_POWERS_24 => ShiftedDegree24::load_bytes()?,
551 NUM_POWERS_25 => ShiftedDegree25::load_bytes()?,
552 #[cfg(feature = "large_params")]
554 NUM_POWERS_26 => ShiftedDegree26::load_bytes()?,
555 #[cfg(feature = "large_params")]
556 NUM_POWERS_27 => ShiftedDegree27::load_bytes()?,
557 _ => bail!("Cannot download an invalid degree of '{num_powers}'"),
558 };
559
560 let additional_powers = Vec::deserialize_uncompressed_unchecked(&*additional_bytes)?;
562
563 final_powers.extend(additional_powers.iter());
564 }
565 final_powers.extend(self.shifted_powers_of_beta_g.iter());
566 self.shifted_powers_of_beta_g = Arc::new(final_powers);
567
568 ensure!(self.shifted_powers_of_beta_g.len() == final_num_powers, "Loaded an incorrect number of shifted powers");
569 Ok(())
570 }
571}
572
573impl<E: PairingEngine> FromBytes for PowersOfBetaG<E> {
574 fn read_le<R: Read>(reader: R) -> std::io::Result<Self> {
576 Self::deserialize_with_mode(reader, Compress::No, Validate::No).map_err(|e| e.into())
577 }
578}
579
580impl<E: PairingEngine> ToBytes for PowersOfBetaG<E> {
581 fn write_le<W: Write>(&self, writer: W) -> std::io::Result<()> {
583 self.serialize_with_mode(writer, Compress::No).map_err(|e| e.into())
584 }
585}