diff --git a/algorithms/src/crypto_hash/poseidon.rs b/algorithms/src/crypto_hash/poseidon.rs index 2f0ddee4a0..4f5bfaee64 100644 --- a/algorithms/src/crypto_hash/poseidon.rs +++ b/algorithms/src/crypto_hash/poseidon.rs @@ -379,6 +379,8 @@ impl PoseidonSponge { Self::get_limbs_representations_from_big_integer::(&elem.to_bigint(), optimization_type) } + // params.bits_per_limb is safe to cast as u32 because it will be less than `max_limb_size` + #[allow(clippy::cast_possible_truncation)] /// Obtain the limbs directly from a big int pub fn get_limbs_representations_from_big_integer( elem: &::BigInteger, diff --git a/algorithms/src/fft/domain.rs b/algorithms/src/fft/domain.rs index f03560655a..4068e3cb20 100644 --- a/algorithms/src/fft/domain.rs +++ b/algorithms/src/fft/domain.rs @@ -116,7 +116,7 @@ impl EvaluationDomain { /// having `num_coeffs` coefficients. pub fn new(num_coeffs: usize) -> Option { // Compute the size of our evaluation domain - let size = num_coeffs.checked_next_power_of_two()? as u64; + let size = num_coeffs.checked_next_power_of_two()?; let log_size_of_group = size.trailing_zeros(); // libfqfft uses > https://github.com/scipr-lab/libfqfft/blob/e0183b2cef7d4c5deb21a6eaf3fe3b586d738fe0/libfqfft/evaluation_domain/domains/basic_radix2_domain.tcc#L33 @@ -126,7 +126,8 @@ impl EvaluationDomain { // Compute the generator for the multiplicative subgroup. // It should be the 2^(log_size_of_group) root of unity. - let group_gen = F::get_root_of_unity(size as usize)?; + let group_gen = F::get_root_of_unity(size)?; + let size = size as u64; // Check that it is indeed the 2^(log_size_of_group) root of unity. debug_assert_eq!(group_gen.pow([size]), F::one()); @@ -152,6 +153,8 @@ impl EvaluationDomain { if size.trailing_zeros() <= F::FftParameters::TWO_ADICITY { Some(size) } else { None } } + // casting to usize is safe because it is originally a usize in self.new() + #[allow(clippy::cast_possible_truncation)] /// Return the size of `self`. pub fn size(&self) -> usize { self.size as usize @@ -256,7 +259,7 @@ impl EvaluationDomain { /// `tau`. pub fn evaluate_all_lagrange_coefficients(&self, tau: F) -> Vec { // Evaluate all Lagrange polynomials - let size = self.size as usize; + let size = self.size(); let t_size = tau.pow([self.size]); let one = F::one(); if t_size.is_one() { @@ -375,7 +378,7 @@ impl EvaluationDomain { // SNP TODO: how to set threshold and check that the type is Fr if self.size >= 32 && std::mem::size_of::() == 32 { let result = snarkvm_algorithms_cuda::NTT( - self.size as usize, + self.size(), x_s, snarkvm_algorithms_cuda::NTTInputOutputOrder::NN, snarkvm_algorithms_cuda::NTTDirection::Forward, @@ -404,7 +407,7 @@ impl EvaluationDomain { // SNP TODO: how to set threshold if self.size >= 32 && std::mem::size_of::() == 32 { let result = snarkvm_algorithms_cuda::NTT( - self.size as usize, + self.size(), x_s, snarkvm_algorithms_cuda::NTTInputOutputOrder::NN, snarkvm_algorithms_cuda::NTTDirection::Inverse, @@ -425,7 +428,7 @@ impl EvaluationDomain { // SNP TODO: how to set threshold if self.size >= 32 && std::mem::size_of::() == 32 { let result = snarkvm_algorithms_cuda::NTT( - self.size as usize, + self.size(), x_s, snarkvm_algorithms_cuda::NTTInputOutputOrder::NN, snarkvm_algorithms_cuda::NTTDirection::Inverse, @@ -452,7 +455,7 @@ impl EvaluationDomain { // SNP TODO: how to set threshold if self.size >= 32 && std::mem::size_of::() == 32 { let result = snarkvm_algorithms_cuda::NTT( - self.size as usize, + self.size(), x_s, snarkvm_algorithms_cuda::NTTInputOutputOrder::NN, snarkvm_algorithms_cuda::NTTDirection::Forward, @@ -483,7 +486,7 @@ impl EvaluationDomain { // SNP TODO: how to set threshold if self.size >= 32 && std::mem::size_of::() == 32 { let result = snarkvm_algorithms_cuda::NTT( - self.size as usize, + self.size(), x_s, snarkvm_algorithms_cuda::NTTInputOutputOrder::NN, snarkvm_algorithms_cuda::NTTDirection::Inverse, @@ -517,7 +520,7 @@ impl EvaluationDomain { // SNP TODO: how to set threshold if self.size >= 32 && std::mem::size_of::() == 32 { let result = snarkvm_algorithms_cuda::NTT( - self.size as usize, + self.size(), x_s, snarkvm_algorithms_cuda::NTTInputOutputOrder::NN, snarkvm_algorithms_cuda::NTTDirection::Inverse, @@ -585,17 +588,17 @@ impl EvaluationDomain { // [1, g, g^2, ..., g^{(n/2) - 1}] #[cfg(feature = "serial")] pub fn roots_of_unity(&self, root: F) -> Vec { - compute_powers_serial((self.size as usize) / 2, root) + compute_powers_serial((self.size()) / 2, root) } /// Computes the first `self.size / 2` roots of unity. #[cfg(not(feature = "serial"))] pub fn roots_of_unity(&self, root: F) -> Vec { // TODO: check if this method can replace parallel compute powers. - let log_size = log2(self.size as usize); + let log_size = log2(self.size()); // early exit for short inputs if log_size <= LOG_ROOTS_OF_UNITY_PARALLEL_SIZE { - compute_powers_serial((self.size as usize) / 2, root) + compute_powers_serial((self.size()) / 2, root) } else { let mut temp = root; // w, w^2, w^4, w^8, ..., w^(2^(log_size - 1)) @@ -793,6 +796,8 @@ pub(crate) fn derange(xi: &mut [T]) { derange_helper(xi, log2(xi.len())) } +// casting to usize is safe because xi.len() is at most domain.size() which uses usize in self.new() +#[allow(clippy::cast_possible_truncation)] fn derange_helper(xi: &mut [T], log_len: u32) { for idx in 1..(xi.len() as u64 - 1) { let ridx = bitrev(idx, log_len); diff --git a/algorithms/src/msm/variable_base/batched.rs b/algorithms/src/msm/variable_base/batched.rs index 944d60e651..ade8395ce9 100644 --- a/algorithms/src/msm/variable_base/batched.rs +++ b/algorithms/src/msm/variable_base/batched.rs @@ -172,6 +172,8 @@ fn batch_add_write( } #[inline] +// It is safe to cast num_buckets to u32 because it was small enough earlier in the callchain +#[allow(clippy::cast_possible_truncation)] pub(super) fn batch_add( num_buckets: usize, bases: &[G], @@ -325,6 +327,8 @@ pub(super) fn batch_add( } #[inline] +// It is safe to cast w_start and c to u32 because they were small enough earlier in the callchain +#[allow(clippy::cast_possible_truncation)] fn batched_window( bases: &[G], scalars: &[::BigInteger], diff --git a/algorithms/src/msm/variable_base/standard.rs b/algorithms/src/msm/variable_base/standard.rs index b449909633..590565b618 100644 --- a/algorithms/src/msm/variable_base/standard.rs +++ b/algorithms/src/msm/variable_base/standard.rs @@ -21,6 +21,9 @@ use snarkvm_utilities::{cfg_into_iter, BigInteger}; #[cfg(not(feature = "serial"))] use rayon::prelude::*; +// It is safe to cast w_start to u32 because it was small enough earlier in the callchain +// It is safe to cast scalar to usize because it is mod c, which is usize +#[allow(clippy::cast_possible_truncation)] fn update_buckets( base: &G, mut scalar: ::BigInteger, diff --git a/algorithms/src/polycommit/kzg10/data_structures.rs b/algorithms/src/polycommit/kzg10/data_structures.rs index 3e9e5e10da..288539fbf2 100644 --- a/algorithms/src/polycommit/kzg10/data_structures.rs +++ b/algorithms/src/polycommit/kzg10/data_structures.rs @@ -131,6 +131,8 @@ impl FromBytes for UniversalParams { } } +// It is safe to cast `supported_degree_bounds.len()` and individual bounds to a `u32` because they are read and used as u32 +#[allow(clippy::cast_possible_truncation)] impl ToBytes for UniversalParams { fn write_le(&self, mut writer: W) -> io::Result<()> { // Serialize powers. @@ -352,7 +354,7 @@ impl ToBytes for KZGCommitment { } impl ToMinimalBits for KZGCommitment { - fn to_minimal_bits(&self) -> Vec { + fn to_minimal_bits(&self) -> Result, std::num::TryFromIntError> { self.0.to_minimal_bits() } } diff --git a/algorithms/src/polycommit/sonic_pc/data_structures.rs b/algorithms/src/polycommit/sonic_pc/data_structures.rs index ef346ba073..ab8ba6af81 100644 --- a/algorithms/src/polycommit/sonic_pc/data_structures.rs +++ b/algorithms/src/polycommit/sonic_pc/data_structures.rs @@ -83,7 +83,7 @@ pub struct CommitterKey { pub enforced_degree_bounds: Option>, /// The maximum degree supported by the `UniversalParams` from which `self` was derived - pub max_degree: usize, + pub max_degree: u32, } impl FromBytes for CommitterKey { @@ -217,12 +217,14 @@ impl FromBytes for CommitterKey { shifted_powers_of_beta_g, shifted_powers_of_beta_times_gamma_g, enforced_degree_bounds, - max_degree: max_degree as usize, + max_degree, }) } } impl ToBytes for CommitterKey { + // Values are safe to cast to u32 because they are read as u32. + #[allow(clippy::cast_possible_truncation)] fn write_le(&self, mut writer: W) -> io::Result<()> { // Serialize `powers`. (self.powers_of_beta_g.len() as u32).write_le(&mut writer)?; @@ -258,10 +260,10 @@ impl ToBytes for CommitterKey { self.shifted_powers_of_beta_times_gamma_g.is_some().write_le(&mut writer)?; if let Some(shifted_powers_of_beta_times_gamma_g) = &self.shifted_powers_of_beta_times_gamma_g { (shifted_powers_of_beta_times_gamma_g.len() as u32).write_le(&mut writer)?; - for (key, shifted_powers_of_beta_g) in shifted_powers_of_beta_times_gamma_g { + for (key, shifted_powers_of_beta_times_gamma_g) in shifted_powers_of_beta_times_gamma_g { (*key as u32).write_le(&mut writer)?; - (shifted_powers_of_beta_g.len() as u32).write_le(&mut writer)?; - for shifted_power in shifted_powers_of_beta_g { + (shifted_powers_of_beta_times_gamma_g.len() as u32).write_le(&mut writer)?; + for shifted_power in shifted_powers_of_beta_times_gamma_g { shifted_power.write_le(&mut writer)?; } } @@ -277,7 +279,7 @@ impl ToBytes for CommitterKey { } // Serialize `max_degree`. - (self.max_degree as u32).write_le(&mut writer)?; + self.max_degree.write_le(&mut writer)?; // Construct the hash of the group elements. let mut hash_input = self.powers_of_beta_g.to_bytes_le().map_err(|_| error("Could not serialize powers"))?; @@ -343,7 +345,7 @@ pub struct CommitterUnionKey<'a, E: PairingEngine> { pub enforced_degree_bounds: Option>, /// The maximum degree supported by the `UniversalParams` from which `self` was derived - pub max_degree: usize, + pub max_degree: u32, } impl<'a, E: PairingEngine> CommitterUnionKey<'a, E> { @@ -389,7 +391,7 @@ impl<'a, E: PairingEngine> CommitterUnionKey<'a, E> { }) } - pub fn max_degree(&self) -> usize { + pub fn max_degree(&self) -> u32 { self.max_degree } diff --git a/algorithms/src/polycommit/sonic_pc/mod.rs b/algorithms/src/polycommit/sonic_pc/mod.rs index d6852992ff..8ed8deb7d1 100644 --- a/algorithms/src/polycommit/sonic_pc/mod.rs +++ b/algorithms/src/polycommit/sonic_pc/mod.rs @@ -158,7 +158,7 @@ impl> SonicKZG10 { shifted_powers_of_beta_g, shifted_powers_of_beta_times_gamma_g, enforced_degree_bounds, - max_degree, + max_degree: u32::try_from(max_degree)?, }; let g = pp.power_of_beta_g(0)?; @@ -246,7 +246,7 @@ impl> SonicKZG10 { kzg10::KZG10::::check_degrees_and_bounds( ck.supported_degree(), - ck.max_degree, + usize::try_from(ck.max_degree)?, ck.enforced_degree_bounds.as_deref(), p.clone(), )?; @@ -329,16 +329,12 @@ impl> SonicKZG10 { Randomness: 'a, Commitment: 'a, { + let max_degree = usize::try_from(ck.max_degree)?; Ok(Self::combine_polynomials(labeled_polynomials.into_iter().zip_eq(rands).map(|(p, r)| { let enforced_degree_bounds: Option<&[usize]> = ck.enforced_degree_bounds.as_deref(); - kzg10::KZG10::::check_degrees_and_bounds( - ck.supported_degree(), - ck.max_degree, - enforced_degree_bounds, - p, - ) - .unwrap(); + kzg10::KZG10::::check_degrees_and_bounds(ck.supported_degree(), max_degree, enforced_degree_bounds, p) + .unwrap(); let challenge = fs_rng.squeeze_short_nonnative_field_element::(); (challenge, p.polynomial().to_dense(), r) }))) diff --git a/algorithms/src/snark/marlin/data_structures/circuit_verifying_key.rs b/algorithms/src/snark/marlin/data_structures/circuit_verifying_key.rs index c04dcb0494..ef05051d2c 100644 --- a/algorithms/src/snark/marlin/data_structures/circuit_verifying_key.rs +++ b/algorithms/src/snark/marlin/data_structures/circuit_verifying_key.rs @@ -97,7 +97,7 @@ impl From> } impl ToMinimalBits for CircuitVerifyingKey { - fn to_minimal_bits(&self) -> Vec { + fn to_minimal_bits(&self) -> Result, std::num::TryFromIntError> { let constraint_domain = EvaluationDomain::::new(self.circuit_info.num_constraints) .ok_or(SynthesisError::PolynomialDegreeTooLarge) .unwrap(); @@ -111,15 +111,10 @@ impl ToMinimalBits for CircuitVerifyingKey ToMinimalBits for CircuitVerifyingKey> i) & 1u8 == 1u8)) .collect::>(); - let circuit_commitments_bits = self.circuit_commitments.to_minimal_bits(); + let circuit_commitments_bits = self.circuit_commitments.to_minimal_bits()?; - [ + Ok([ constraint_domain_size_bits, non_zero_domain_size_a_bits, non_zero_domain_size_b_bits, non_zero_domain_size_c_bits, circuit_commitments_bits, ] - .concat() + .concat()) } } diff --git a/algorithms/src/snark/marlin/data_structures/proof.rs b/algorithms/src/snark/marlin/data_structures/proof.rs index 6efc38da54..9c69136310 100644 --- a/algorithms/src/snark/marlin/data_structures/proof.rs +++ b/algorithms/src/snark/marlin/data_structures/proof.rs @@ -374,6 +374,7 @@ impl FromBytes for Proof { } #[cfg(test)] +#[allow(clippy::cast_possible_truncation)] mod test { #![allow(non_camel_case_types)] diff --git a/algorithms/src/snark/marlin/marlin.rs b/algorithms/src/snark/marlin/marlin.rs index d91faeba9a..36754fda25 100644 --- a/algorithms/src/snark/marlin/marlin.rs +++ b/algorithms/src/snark/marlin/marlin.rs @@ -887,7 +887,7 @@ where } let eval = proof .evaluations - .get(circuit_index as usize, &label)? + .get(usize::try_from(circuit_index)?, &label)? .ok_or_else(|| AHPError::MissingEval(label.clone()))?; evaluations.insert((label, q), eval); } diff --git a/curves/src/templates/short_weierstrass_jacobian/affine.rs b/curves/src/templates/short_weierstrass_jacobian/affine.rs index f8787521d7..b130e7d686 100644 --- a/curves/src/templates/short_weierstrass_jacobian/affine.rs +++ b/curves/src/templates/short_weierstrass_jacobian/affine.rs @@ -265,11 +265,11 @@ impl AffineCurve for Affine

{ } impl ToMinimalBits for Affine

{ - fn to_minimal_bits(&self) -> Vec { + fn to_minimal_bits(&self) -> Result, std::num::TryFromIntError> { let mut res_bits = self.x.to_bits_le(); res_bits.push(*self.y.to_bits_le().first().unwrap()); res_bits.push(self.infinity); - res_bits + Ok(res_bits) } } diff --git a/curves/src/templates/twisted_edwards_extended/affine.rs b/curves/src/templates/twisted_edwards_extended/affine.rs index b5c659c89f..0bda048dcf 100644 --- a/curves/src/templates/twisted_edwards_extended/affine.rs +++ b/curves/src/templates/twisted_edwards_extended/affine.rs @@ -258,8 +258,8 @@ impl AffineCurve for Affine

{ } impl ToMinimalBits for Affine

{ - fn to_minimal_bits(&self) -> Vec { - self.x.to_bits_le() + fn to_minimal_bits(&self) -> Result, std::num::TryFromIntError> { + Ok(self.x.to_bits_le()) } } diff --git a/utilities/src/bits.rs b/utilities/src/bits.rs index b827fe7bc3..ba6f8e3d1c 100644 --- a/utilities/src/bits.rs +++ b/utilities/src/bits.rs @@ -36,16 +36,16 @@ pub trait FromBits: Sized { pub trait ToMinimalBits: Sized { /// Returns `self` as a minimal boolean array. - fn to_minimal_bits(&self) -> Vec; + fn to_minimal_bits(&self) -> Result, std::num::TryFromIntError>; } impl ToMinimalBits for Vec { - fn to_minimal_bits(&self) -> Vec { + fn to_minimal_bits(&self) -> Result, std::num::TryFromIntError> { let mut res_bits = vec![]; for elem in self.iter() { - res_bits.extend(elem.to_minimal_bits()); + res_bits.extend(elem.to_minimal_bits()?); } - res_bits + Ok(res_bits) } }