powers.rs
1 // Copyright (c) 2019-2025 Alpha-Delta Network Inc. 2 // This file is part of the deltavm library. 3 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at: 7 8 // http://www.apache.org/licenses/LICENSE-2.0 9 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 use super::*; 17 use deltavm_curves::traits::{PairingCurve, PairingEngine}; 18 use deltavm_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 32 use anyhow::{Result, anyhow, bail, ensure}; 33 #[cfg(feature = "locktick")] 34 use locktick::parking_lot::RwLock; 35 #[cfg(not(feature = "locktick"))] 36 use parking_lot::RwLock; 37 use std::{collections::BTreeMap, ops::Range, sync::Arc}; 38 39 const NUM_POWERS_15: usize = 1 << 15; 40 const NUM_POWERS_16: usize = 1 << 16; 41 const NUM_POWERS_17: usize = 1 << 17; 42 const NUM_POWERS_18: usize = 1 << 18; 43 const NUM_POWERS_19: usize = 1 << 19; 44 const NUM_POWERS_20: usize = 1 << 20; 45 const NUM_POWERS_21: usize = 1 << 21; 46 const NUM_POWERS_22: usize = 1 << 22; 47 const NUM_POWERS_23: usize = 1 << 23; 48 const NUM_POWERS_24: usize = 1 << 24; 49 const NUM_POWERS_25: usize = 1 << 25; 50 // TODO (nkls): restore on CI. 51 // The SRS is only used for proving and we don't currently support provers of 52 // this size. When a users wants to create a proof, they load the appropriate 53 // powers for the circuit in `batch_circuit_setup` which calls `max_degree` 54 // based on the domain size. 55 #[cfg(feature = "large_params")] 56 const NUM_POWERS_26: usize = 1 << 26; 57 #[cfg(feature = "large_params")] 58 const NUM_POWERS_27: usize = 1 << 27; 59 const NUM_POWERS_28: usize = 1 << 28; 60 61 /// The maximum degree supported by the SRS. 62 pub const MAX_NUM_POWERS: usize = NUM_POWERS_28; 63 64 lazy_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 72 /// A vector of powers of beta G. 73 #[derive(Debug)] 74 pub struct PowersOfG<E: PairingEngine> { 75 /// The powers of beta G. 76 powers_of_beta_g: RwLock<PowersOfBetaG<E>>, 77 /// Group elements of form `{ \beta^i \gamma G }`, where `i` is from 0 to `degree`, 78 /// This is used for hiding. 79 powers_of_beta_times_gamma_g: BTreeMap<usize, E::G1Affine>, 80 /// Group elements of form `{ \beta^{max_degree - i} H }`, where `i` 81 /// is of the form `2^k - 1` for `k` in `1` to `log_2(max_degree)`. 82 negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine>, 83 /// Information required to enforce degree bounds. Each pair is of the form `(degree_bound, shifting_advice)`. 84 /// Each pair is in the form `(degree_bound, \beta^{max_degree - i} H),` where `H` is the generator of G2, 85 /// and `i` is of the form `2^k - 1` for `k` in `1` to `log_2(max_degree)`. 86 prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>>, 87 /// beta * h 88 beta_h: E::G2Affine, 89 } 90 91 impl<E: PairingEngine> PowersOfG<E> { 92 /// Initializes the hard-coded instance of the powers. 93 pub fn load() -> Result<Self> { 94 let powers_of_beta_g = RwLock::new(PowersOfBetaG::load()?); 95 96 // Reconstruct powers of beta_times_gamma_g. 97 let powers_of_beta_times_gamma_g = BTreeMap::deserialize_uncompressed_unchecked(&**POWERS_OF_BETA_GAMMA_G)?; 98 99 // Reconstruct negative powers of beta_h. 100 let negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine> = 101 BTreeMap::deserialize_uncompressed_unchecked(&**NEG_POWERS_OF_BETA_H)?; 102 103 // Compute the prepared negative powers of beta_h. 104 let prepared_negative_powers_of_beta_h: Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> = 105 Arc::new(negative_powers_of_beta_h.iter().map(|(d, affine)| (*d, affine.prepare())).collect()); 106 107 let beta_h = E::G2Affine::deserialize_uncompressed_unchecked(&**BETA_H)?; 108 109 // Return the powers. 110 Ok(Self { 111 powers_of_beta_g, 112 powers_of_beta_times_gamma_g, 113 negative_powers_of_beta_h, 114 prepared_negative_powers_of_beta_h, 115 beta_h, 116 }) 117 } 118 119 /// Download the powers of beta G specified by `range`. 120 pub fn download_powers_for(&self, range: Range<usize>) -> Result<()> { 121 self.powers_of_beta_g.write().download_powers_for(&range) 122 } 123 124 /// Returns the number of contiguous powers of beta G starting from the 0-th power. 125 pub fn num_powers(&self) -> usize { 126 self.powers_of_beta_g.read().num_powers() 127 } 128 129 /// Returns the maximum possible number of contiguous powers of beta G starting from the 0-th power. 130 pub fn max_num_powers(&self) -> usize { 131 MAX_NUM_POWERS 132 } 133 134 /// Returns the powers of beta * gamma G. 135 pub fn powers_of_beta_gamma_g(&self) -> &BTreeMap<usize, E::G1Affine> { 136 &self.powers_of_beta_times_gamma_g 137 } 138 139 /// Returns the `index`-th power of beta * G. 140 pub fn power_of_beta_g(&self, index: usize) -> Result<E::G1Affine> { 141 self.powers_of_beta_g.write().power(index) 142 } 143 144 /// Returns the powers of `beta * G` that lie within `range`. 145 pub fn powers_of_beta_g(&self, range: Range<usize>) -> Result<Vec<E::G1Affine>> { 146 Ok(self.powers_of_beta_g.write().powers(range)?.to_vec()) 147 } 148 149 pub fn negative_powers_of_beta_h(&self) -> &BTreeMap<usize, E::G2Affine> { 150 &self.negative_powers_of_beta_h 151 } 152 153 pub fn prepared_negative_powers_of_beta_h(&self) -> Arc<BTreeMap<usize, <E::G2Affine as PairingCurve>::Prepared>> { 154 self.prepared_negative_powers_of_beta_h.clone() 155 } 156 157 pub fn beta_h(&self) -> E::G2Affine { 158 self.beta_h 159 } 160 } 161 162 impl<E: PairingEngine> CanonicalSerialize for PowersOfG<E> { 163 fn serialize_with_mode<W: Write>(&self, mut writer: W, mode: Compress) -> Result<(), SerializationError> { 164 self.powers_of_beta_g.read().serialize_with_mode(&mut writer, mode)?; 165 self.powers_of_beta_times_gamma_g.serialize_with_mode(&mut writer, mode)?; 166 self.negative_powers_of_beta_h.serialize_with_mode(&mut writer, mode)?; 167 self.beta_h.serialize_with_mode(&mut writer, mode)?; 168 Ok(()) 169 } 170 171 fn serialized_size(&self, mode: Compress) -> usize { 172 self.powers_of_beta_g.read().serialized_size(mode) 173 + self.powers_of_beta_times_gamma_g.serialized_size(mode) 174 + self.negative_powers_of_beta_h.serialized_size(mode) 175 + self.beta_h.serialized_size(mode) 176 } 177 } 178 179 impl<E: PairingEngine> CanonicalDeserialize for PowersOfG<E> { 180 fn deserialize_with_mode<R: Read>(mut reader: R, compress: Compress, validate: Validate) -> Result<Self, SerializationError> { 181 let powers_of_beta_g = RwLock::new(PowersOfBetaG::deserialize_with_mode(&mut reader, compress, Validate::No)?); 182 183 // Reconstruct powers of beta_times_gamma_g. 184 let powers_of_beta_times_gamma_g = BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?; 185 186 // Reconstruct negative powers of beta_h. 187 let negative_powers_of_beta_h: BTreeMap<usize, E::G2Affine> = 188 BTreeMap::deserialize_with_mode(&mut reader, compress, Validate::No)?; 189 190 // Compute the prepared negative powers of beta_h. 191 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 210 impl<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 220 impl<E: PairingEngine> FromBytes for PowersOfG<E> { 221 /// Reads the powers from the buffer. 222 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 227 impl<E: PairingEngine> ToBytes for PowersOfG<E> { 228 /// Writes the powers to the buffer. 229 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)] 235 pub struct PowersOfBetaG<E: PairingEngine> { 236 /// Group elements of form `[G, \beta * G, \beta^2 * G, ..., \beta^d G]`. 237 powers_of_beta_g: Vec<E::G1Affine>, 238 /// Group elements of form `[\beta^i * G, \beta^2 * G, ..., \beta^D G]`. 239 /// where D is the maximum degree supported by the SRS. 240 shifted_powers_of_beta_g: Vec<E::G1Affine>, 241 } 242 243 impl<E: PairingEngine> PowersOfBetaG<E> { 244 /// Returns the number of contiguous powers of beta G starting from the 0-th power. 245 pub fn num_powers(&self) -> usize { 246 self.powers_of_beta_g.len() 247 } 248 249 /// Initializes the hard-coded instance of the powers. 250 fn load() -> Result<Self> { 251 // Deserialize the group elements. 252 let powers_of_beta_g = Vec::deserialize_uncompressed_unchecked(&**POWERS_OF_BETA_G_15)?; 253 254 // Ensure the number of elements is correct. 255 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 /// Returns the range of powers of beta G. 263 /// In detail, it returns the range of the available "normal" powers of beta G, i.e. the 264 /// contiguous range of powers of beta G starting from G, and, the range of shifted_powers. 265 /// 266 /// For example, if the output of this function is `(0..8, 24..32)`, then `self` 267 /// contains the powers 268 /// * `beta^0 * G, beta^1 * G, ..., beta^7 * G`, and 269 /// * `beta^24 * G, ..., beta^31 * G`. 270 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 // We can only be in this case if have downloaded all possible powers. 276 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 /// Assumes that we have the requisite powers. 304 fn shifted_powers(&self, range: Range<usize>) -> Result<&[E::G1Affine]> { 305 ensure!(self.contains_in_shifted_powers(&range), "Requested range is not contained in the available shifted powers"); 306 307 if range.start < MAX_NUM_POWERS / 2 { 308 ensure!(self.shifted_powers_of_beta_g.is_empty()); 309 // In this case, we have downloaded all the powers, and so 310 // all the powers reside in self.powers_of_beta_g. 311 Ok(&self.powers_of_beta_g[range]) 312 } else { 313 // In this case, the shifted powers still reside in self.shifted_powers_of_beta_g. 314 let lower = self.shifted_powers_of_beta_g.len() - (MAX_NUM_POWERS - range.start); 315 let upper = self.shifted_powers_of_beta_g.len() - (MAX_NUM_POWERS - range.end); 316 Ok(&self.shifted_powers_of_beta_g[lower..upper]) 317 } 318 } 319 320 /// Assumes that we have the requisite powers. 321 fn normal_powers(&self, range: Range<usize>) -> Result<&[E::G1Affine]> { 322 ensure!(self.contains_in_normal_powers(&range), "Requested range is not contained in the available powers"); 323 Ok(&self.powers_of_beta_g[range]) 324 } 325 326 /// Returns the power of beta times G specified by `target`. 327 fn power(&mut self, target: usize) -> Result<E::G1Affine> { 328 self.powers(target..(target + 1)).map(|s| s[0]) 329 } 330 331 /// Slices the underlying file to return a vector of affine elements between `lower` and `upper`. 332 fn powers(&mut self, range: Range<usize>) -> Result<&[E::G1Affine]> { 333 if range.is_empty() { 334 return Ok(&self.powers_of_beta_g[0..0]); 335 } 336 ensure!(range.start < range.end, "Lower power must be less than upper power"); 337 ensure!(range.end <= MAX_NUM_POWERS, "Upper bound must be less than the maximum number of powers"); 338 if !self.contains_powers(&range) { 339 // We must download the powers. 340 self.download_powers_for(&range)?; 341 } 342 match self.contains_in_normal_powers(&range) { 343 true => self.normal_powers(range), 344 false => self.shifted_powers(range), 345 } 346 } 347 348 pub fn download_powers_for(&mut self, range: &Range<usize>) -> Result<()> { 349 if self.contains_in_normal_powers(range) || self.contains_in_shifted_powers(range) { 350 return Ok(()); 351 } 352 let half_max = MAX_NUM_POWERS / 2; 353 if (range.start <= half_max) && (range.end > half_max) { 354 // If the range contains the midpoint, then we must download all the powers. 355 // (because we round up to the next power of two). 356 self.download_powers_up_to(range.end)?; 357 self.shifted_powers_of_beta_g = Vec::new(); 358 } else if self.distance_from_shifted_of(range) < self.distance_from_normal_of(range) { 359 // If the range is closer to the shifted powers, then we download the shifted powers. 360 self.download_shifted_powers_from(range.start)?; 361 } else { 362 // Otherwise, we download the normal powers. 363 self.download_powers_up_to(range.end)?; 364 } 365 Ok(()) 366 } 367 368 /// This method downloads the universal SRS powers up to the `next_power_of_two(target_degree)`, 369 /// and updates `Self` in place with the new powers. 370 fn download_powers_up_to(&mut self, end: usize) -> Result<()> { 371 // Determine the new power of two. 372 let final_power_of_two = end.checked_next_power_of_two().ok_or_else(|| anyhow!("Requesting too many powers"))?; 373 // Ensure the total number of powers is less than the maximum number of powers. 374 ensure!(final_power_of_two <= MAX_NUM_POWERS, "Requesting more powers than exist in the SRS"); 375 376 // Retrieve the current power of two. 377 let current_power_of_two = 378 self.powers_of_beta_g.len().checked_next_power_of_two().ok_or_else(|| anyhow!("The current degree is too large"))?; 379 380 // Initialize a vector for the powers of two to be downloaded. 381 let mut download_queue = Vec::with_capacity(14); 382 383 // Initialize the first degree to download. 384 let mut accumulator = current_power_of_two * 2; 385 // Determine the powers of two to download. 386 while accumulator <= final_power_of_two { 387 download_queue.push(accumulator); 388 accumulator = accumulator.checked_mul(2).ok_or_else(|| anyhow!("Overflowed while requesting a larger degree"))?; 389 } 390 ensure!(final_power_of_two * 2 == accumulator, "Ensure the loop terminates at the right power of two"); 391 392 // Reserve capacity for the new powers of two. 393 let additional_size = final_power_of_two 394 .checked_sub(self.powers_of_beta_g.len()) 395 .ok_or_else(|| anyhow!("final_power_of_two is smaller than existing powers"))?; 396 self.powers_of_beta_g.reserve(additional_size); 397 398 // Download the powers of two. 399 for num_powers in &download_queue { 400 dev_println!("Loading {num_powers} powers"); 401 402 // Download the universal SRS powers if they're not already on disk. 403 let additional_bytes = match *num_powers { 404 NUM_POWERS_16 => Degree16::load_bytes()?, 405 NUM_POWERS_17 => Degree17::load_bytes()?, 406 NUM_POWERS_18 => Degree18::load_bytes()?, 407 NUM_POWERS_19 => Degree19::load_bytes()?, 408 NUM_POWERS_20 => Degree20::load_bytes()?, 409 NUM_POWERS_21 => Degree21::load_bytes()?, 410 NUM_POWERS_22 => Degree22::load_bytes()?, 411 NUM_POWERS_23 => Degree23::load_bytes()?, 412 NUM_POWERS_24 => Degree24::load_bytes()?, 413 NUM_POWERS_25 => Degree25::load_bytes()?, 414 // TODO (nkls): restore on CI. 415 #[cfg(feature = "large_params")] 416 NUM_POWERS_26 => Degree26::load_bytes()?, 417 #[cfg(feature = "large_params")] 418 NUM_POWERS_27 => Degree27::load_bytes()?, 419 #[cfg(feature = "large_params")] 420 NUM_POWERS_28 => Degree28::load_bytes()?, 421 _ => bail!("Cannot download an invalid degree of '{num_powers}'"), 422 }; 423 424 // Deserialize the group elements. 425 let additional_powers = Vec::deserialize_uncompressed_unchecked(&*additional_bytes)?; 426 // Extend the powers. 427 self.powers_of_beta_g.extend(&additional_powers); 428 } 429 ensure!(self.powers_of_beta_g.len() == final_power_of_two, "Loaded an incorrect number of powers"); 430 Ok(()) 431 } 432 433 /// This method downloads the universal SRS powers from 434 /// `start` up to `MAXIMUM_NUM_POWERS - self.shifted_powers_of_beta_g.len()`, 435 /// and updates `Self` in place with the new powers. 436 fn download_shifted_powers_from(&mut self, start: usize) -> Result<()> { 437 // Ensure the total number of powers is less than the maximum number of powers. 438 ensure!(start <= MAX_NUM_POWERS, "Requesting more powers than exist in the SRS"); 439 440 // The possible powers are: 441 // (2^28 - 2^15)..=(2^28) = 2^15 powers 442 // (2^28 - 2^16)..(2^28 - 2^15) = 2^15 powers 443 // (2^28 - 2^17)..(2^28 - 2^16) = 2^16 powers 444 // (2^28 - 2^18)..(2^28 - 2^17) = 2^17 powers 445 // (2^28 - 2^19)..(2^28 - 2^18) = 2^18 powers 446 // (2^28 - 2^20)..(2^28 - 2^19) = 2^19 powers 447 // (2^28 - 2^21)..(2^28 - 2^20) = 2^20 powers 448 // (2^28 - 2^22)..(2^28 - 2^21) = 2^21 powers 449 // (2^28 - 2^23)..(2^28 - 2^22) = 2^22 powers 450 // (2^28 - 2^24)..(2^28 - 2^23) = 2^23 powers 451 // (2^28 - 2^25)..(2^28 - 2^24) = 2^24 powers 452 // (2^28 - 2^26)..(2^28 - 2^25) = 2^25 powers 453 // (2^28 - 2^27)..(2^28 - 2^26) = 2^26 powers 454 455 // Figure out the number of powers to download, as follows: 456 // Let `start := 2^28 - k`. 457 // We know that `shifted_powers_of_beta_g.len() = 2^s` such that `2^s < k`. 458 // That is, we have already downloaded the powers `2^28 - 2^s` up to `2^28`. 459 // Then, we have to download the powers 2^s..k.next_power_of_two(). 460 let final_num_powers = MAX_NUM_POWERS 461 .checked_sub(start) 462 .ok_or_else(|| anyhow!("Requesting too many powers: `start ({start}) > MAX_NUM_POWERS ({MAX_NUM_POWERS})`"))? 463 .checked_next_power_of_two() 464 .ok_or_else(|| anyhow!("Requesting too many powers"))?; // Calculated k.next_power_of_two(). 465 466 let mut download_queue = Vec::with_capacity(14); 467 let mut existing_num_powers = self.shifted_powers_of_beta_g.len(); 468 while existing_num_powers < final_num_powers { 469 existing_num_powers = 470 existing_num_powers.checked_mul(2).ok_or_else(|| anyhow!("Overflowed while requesting additional powers"))?; 471 download_queue.push(existing_num_powers); 472 } 473 download_queue.reverse(); // We want to download starting from the smallest power. 474 475 let mut final_powers = Vec::with_capacity(final_num_powers); 476 // If the `target_degree` exceeds the current `degree`, proceed to download the new powers. 477 for num_powers in &download_queue { 478 dev_println!("Loading {num_powers} shifted powers"); 479 480 // Download the universal SRS powers if they're not already on disk. 481 let additional_bytes = match *num_powers { 482 NUM_POWERS_16 => ShiftedDegree16::load_bytes()?, 483 NUM_POWERS_17 => ShiftedDegree17::load_bytes()?, 484 NUM_POWERS_18 => ShiftedDegree18::load_bytes()?, 485 NUM_POWERS_19 => ShiftedDegree19::load_bytes()?, 486 NUM_POWERS_20 => ShiftedDegree20::load_bytes()?, 487 NUM_POWERS_21 => ShiftedDegree21::load_bytes()?, 488 NUM_POWERS_22 => ShiftedDegree22::load_bytes()?, 489 NUM_POWERS_23 => ShiftedDegree23::load_bytes()?, 490 NUM_POWERS_24 => ShiftedDegree24::load_bytes()?, 491 NUM_POWERS_25 => ShiftedDegree25::load_bytes()?, 492 // TODO (nkls): restore on CI. 493 #[cfg(feature = "large_params")] 494 NUM_POWERS_26 => ShiftedDegree26::load_bytes()?, 495 #[cfg(feature = "large_params")] 496 NUM_POWERS_27 => ShiftedDegree27::load_bytes()?, 497 _ => bail!("Cannot download an invalid degree of '{num_powers}'"), 498 }; 499 500 // Deserialize the group elements. 501 let additional_powers = Vec::deserialize_uncompressed_unchecked(&*additional_bytes)?; 502 503 final_powers.extend(additional_powers.iter()); 504 } 505 final_powers.extend(self.shifted_powers_of_beta_g.iter()); 506 self.shifted_powers_of_beta_g = final_powers; 507 508 ensure!(self.shifted_powers_of_beta_g.len() == final_num_powers, "Loaded an incorrect number of shifted powers"); 509 Ok(()) 510 } 511 } 512 513 impl<E: PairingEngine> FromBytes for PowersOfBetaG<E> { 514 /// Reads the powers from the buffer. 515 fn read_le<R: Read>(reader: R) -> std::io::Result<Self> { 516 Self::deserialize_with_mode(reader, Compress::No, Validate::No).map_err(|e| e.into()) 517 } 518 } 519 520 impl<E: PairingEngine> ToBytes for PowersOfBetaG<E> { 521 /// Writes the powers to the buffer. 522 fn write_le<W: Write>(&self, writer: W) -> std::io::Result<()> { 523 self.serialize_with_mode(writer, Compress::No).map_err(|e| e.into()) 524 } 525 }