diff --git a/coins/monero/src/lib.rs b/coins/monero/src/lib.rs index 74b42f81..70c306aa 100644 --- a/coins/monero/src/lib.rs +++ b/coins/monero/src/lib.rs @@ -140,7 +140,7 @@ pub struct Commitment { } impl Commitment { - /// The zero commitment, defined as a mask of 1 (as to not be the identity) and a 0 amount. + /// A commitment to zero, defined with a mask of 1 (as to not be the identity). pub fn zero() -> Commitment { Commitment { mask: Scalar::one(), amount: 0 } } diff --git a/coins/monero/src/merkle.rs b/coins/monero/src/merkle.rs index 1671adf2..8123b902 100644 --- a/coins/monero/src/merkle.rs +++ b/coins/monero/src/merkle.rs @@ -2,7 +2,7 @@ use std_shims::vec::Vec; use crate::hash; -pub fn merkle_root(root: [u8; 32], leafs: &[[u8; 32]]) -> [u8; 32] { +pub(crate) fn merkle_root(root: [u8; 32], leafs: &[[u8; 32]]) -> [u8; 32] { match leafs.len() { 0 => root, 1 => hash(&[root, leafs[0]].concat()), diff --git a/coins/monero/src/ringct/borromean.rs b/coins/monero/src/ringct/borromean.rs index d0bf5b2a..3a5aa35f 100644 --- a/coins/monero/src/ringct/borromean.rs +++ b/coins/monero/src/ringct/borromean.rs @@ -35,10 +35,10 @@ impl BorromeanSignatures { } pub fn write(&self, w: &mut W) -> io::Result<()> { - for s0 in self.s0.iter() { + for s0 in &self.s0 { w.write_all(s0)?; } - for s1 in self.s1.iter() { + for s1 in &self.s1 { w.write_all(s1)?; } w.write_all(&self.ee) diff --git a/coins/monero/src/ringct/bulletproofs/core.rs b/coins/monero/src/ringct/bulletproofs/core.rs index 1f30567f..a3428bb8 100644 --- a/coins/monero/src/ringct/bulletproofs/core.rs +++ b/coins/monero/src/ringct/bulletproofs/core.rs @@ -50,7 +50,7 @@ pub(crate) fn vector_exponent( pub(crate) fn hash_cache(cache: &mut Scalar, mash: &[[u8; 32]]) -> Scalar { let slice = - &[cache.to_bytes().as_ref(), mash.iter().cloned().flatten().collect::>().as_ref()] + &[cache.to_bytes().as_ref(), mash.iter().copied().flatten().collect::>().as_ref()] .concat(); *cache = hash_to_scalar(slice); *cache @@ -118,9 +118,9 @@ pub(crate) fn LR_statements( let mut res = a .0 .iter() - .cloned() - .zip(G_i.iter().cloned()) - .chain(b.0.iter().cloned().zip(H_i.iter().cloned())) + .copied() + .zip(G_i.iter().copied()) + .chain(b.0.iter().copied().zip(H_i.iter().copied())) .collect::>(); res.push((cL, U)); res diff --git a/coins/monero/src/ringct/bulletproofs/original.rs b/coins/monero/src/ringct/bulletproofs/original.rs index 3fd15ef2..7c1439d3 100644 --- a/coins/monero/src/ringct/bulletproofs/original.rs +++ b/coins/monero/src/ringct/bulletproofs/original.rs @@ -190,7 +190,7 @@ impl OriginalStruct { } // Rebuild all challenges - let (mut cache, commitments) = hash_commitments(commitments.iter().cloned()); + let (mut cache, commitments) = hash_commitments(commitments.iter().copied()); let y = hash_cache(&mut cache, &[self.A.compress().to_bytes(), self.S.compress().to_bytes()]); let z = hash_to_scalar(&y.to_bytes()); diff --git a/coins/monero/src/ringct/bulletproofs/plus.rs b/coins/monero/src/ringct/bulletproofs/plus.rs index 0cccc549..4d8d2fce 100644 --- a/coins/monero/src/ringct/bulletproofs/plus.rs +++ b/coins/monero/src/ringct/bulletproofs/plus.rs @@ -196,7 +196,7 @@ impl PlusStruct { } // Rebuild all challenges - let (mut cache, commitments) = hash_plus(commitments.iter().cloned()); + let (mut cache, commitments) = hash_plus(commitments.iter().copied()); let y = hash_cache(&mut cache, &[self.A.compress().to_bytes()]); let yinv = y.invert().unwrap(); let z = hash_to_scalar(&y.to_bytes()); @@ -220,8 +220,6 @@ impl PlusStruct { let A1 = normalize(&self.A1); let B = normalize(&self.B); - let mut commitments = commitments.iter().map(|c| c.mul_by_cofactor()).collect::>(); - // Verify it let mut proof = Vec::with_capacity(logMN + 5 + (2 * (MN + logMN))); @@ -237,7 +235,7 @@ impl PlusStruct { let esq = e * e; let minus_esq = -esq; let commitment_weight = minus_esq * yMNy; - for (i, commitment) in commitments.drain(..).enumerate() { + for (i, commitment) in commitments.iter().map(EdwardsPoint::mul_by_cofactor).enumerate() { proof.push((commitment_weight * zpow[i], commitment)); } diff --git a/coins/monero/src/ringct/bulletproofs/scalar_vector.rs b/coins/monero/src/ringct/bulletproofs/scalar_vector.rs index 8fc9f18e..439e093f 100644 --- a/coins/monero/src/ringct/bulletproofs/scalar_vector.rs +++ b/coins/monero/src/ringct/bulletproofs/scalar_vector.rs @@ -119,7 +119,7 @@ impl Mul<&[EdwardsPoint]> for &ScalarVector { type Output = EdwardsPoint; fn mul(self, b: &[EdwardsPoint]) -> EdwardsPoint { debug_assert_eq!(self.len(), b.len()); - multiexp(&self.0.iter().cloned().zip(b.iter().cloned()).collect::>()) + multiexp(&self.0.iter().copied().zip(b.iter().copied()).collect::>()) } } diff --git a/coins/monero/src/ringct/mlsag.rs b/coins/monero/src/ringct/mlsag.rs index 6999251f..d2deaf50 100644 --- a/coins/monero/src/ringct/mlsag.rs +++ b/coins/monero/src/ringct/mlsag.rs @@ -19,7 +19,7 @@ pub struct Mlsag { impl Mlsag { pub fn write(&self, w: &mut W) -> io::Result<()> { - for ss in self.ss.iter() { + for ss in &self.ss { write_raw_vec(write_scalar, ss, w)?; } write_scalar(&self.cc, w) diff --git a/coins/monero/src/rpc/mod.rs b/coins/monero/src/rpc/mod.rs index d0936271..d3894c00 100644 --- a/coins/monero/src/rpc/mod.rs +++ b/coins/monero/src/rpc/mod.rs @@ -299,9 +299,9 @@ impl Rpc { match self.get_block(self.get_block_hash(number).await?).await { Ok(block) => { // Make sure this is actually the block for this number - match block.miner_tx.prefix.inputs[0] { - Input::Gen(actual) => { - if usize::try_from(actual).unwrap() == number { + match block.miner_tx.prefix.inputs.get(0) { + Some(Input::Gen(actual)) => { + if usize::try_from(*actual).unwrap() == number { Ok(block) } else { Err(RpcError::InvalidNode) diff --git a/coins/monero/src/serialize.rs b/coins/monero/src/serialize.rs index d3e983b0..29baaeed 100644 --- a/coins/monero/src/serialize.rs +++ b/coins/monero/src/serialize.rs @@ -125,7 +125,7 @@ pub(crate) fn read_point(r: &mut R) -> io::Result { pub(crate) fn read_torsion_free_point(r: &mut R) -> io::Result { read_point(r) .ok() - .filter(|point| point.is_torsion_free()) + .filter(EdwardsPoint::is_torsion_free) .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid point")) } diff --git a/coins/monero/src/transaction.rs b/coins/monero/src/transaction.rs index 882c8322..f6189ac9 100644 --- a/coins/monero/src/transaction.rs +++ b/coins/monero/src/transaction.rs @@ -345,14 +345,13 @@ impl Transaction { hashes.extend(hash(&buf)); buf.clear(); - match self.rct_signatures.prunable { - RctPrunable::Null => buf.resize(32, 0), + hashes.extend(&match self.rct_signatures.prunable { + RctPrunable::Null => [0; 32], _ => { self.rct_signatures.prunable.write(&mut buf, self.rct_signatures.rct_type()).unwrap(); - buf = hash(&buf).to_vec(); + hash(&buf) } - } - hashes.extend(&buf); + }); hash(&hashes) } diff --git a/coins/monero/src/wallet/mod.rs b/coins/monero/src/wallet/mod.rs index f953edd1..8c2a2530 100644 --- a/coins/monero/src/wallet/mod.rs +++ b/coins/monero/src/wallet/mod.rs @@ -241,9 +241,13 @@ impl ZeroizeOnDrop for Scanner {} impl Scanner { /// Create a Scanner from a ViewPair. + /// /// burning_bug is a HashSet of used keys, intended to prevent key reuse which would burn funds. + /// /// When an output is successfully scanned, the output key MUST be saved to disk. + /// /// When a new scanner is created, ALL saved output keys must be passed in to be secure. + /// /// If None is passed, a modified shared key derivation is used which is immune to the burning /// bug (specifically the Guaranteed feature from Featured Addresses). pub fn from_view(pair: ViewPair, burning_bug: Option>) -> Scanner { diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index 4816ed86..af325a63 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -263,6 +263,7 @@ impl Timelocked { } /// Return the outputs if they're not timelocked, or an empty vector if they are. + #[must_use] pub fn not_locked(&self) -> Vec { if self.0 == Timelock::None { return self.1.clone(); @@ -271,6 +272,7 @@ impl Timelocked { } /// Returns None if the Timelocks aren't comparable. Returns Some(vec![]) if none are unlocked. + #[must_use] pub fn unlocked(&self, timelock: Timelock) -> Option> { // If the Timelocks are comparable, return the outputs if they're now unlocked if self.0 <= timelock { @@ -280,6 +282,7 @@ impl Timelocked { } } + #[must_use] pub fn ignore_timelock(&self) -> Vec { self.1.clone() } @@ -293,16 +296,11 @@ impl Scanner { return Timelocked(tx.prefix.timelock, vec![]); } - let extra = Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref()); - let extra = if let Ok(extra) = extra { - extra - } else { + let Ok(extra) = Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref()) else { return Timelocked(tx.prefix.timelock, vec![]); }; - let (tx_key, additional) = if let Some((tx_key, additional)) = extra.keys() { - (tx_key, additional) - } else { + let Some((tx_key, additional)) = extra.keys() else { return Timelocked(tx.prefix.timelock, vec![]); }; @@ -453,7 +451,7 @@ impl Scanner { }; let mut res = vec![]; - for tx in txs.drain(..) { + for tx in txs { if let Some(timelock) = map(self.scan_transaction(&tx), index) { res.push(timelock); } diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index 7eb1fcf2..a2fc9309 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -296,7 +296,7 @@ impl SignableTransaction { protocol: Protocol, r_seed: Option>, inputs: Vec, - mut payments: Vec<(MoneroAddress, u64)>, + payments: Vec<(MoneroAddress, u64)>, change_address: Option, data: Vec>, fee_rate: Fee, @@ -382,7 +382,7 @@ impl SignableTransaction { Err(TransactionError::TooManyOutputs)?; } - let mut payments = payments.drain(..).map(InternalPayment::Payment).collect::>(); + let mut payments = payments.into_iter().map(InternalPayment::Payment).collect::>(); if let Some(change) = change_address { payments.push(InternalPayment::Change(change, in_amount - out_amount)); } @@ -562,11 +562,12 @@ impl SignableTransaction { } /// Returns the eventuality of this transaction. + /// /// The eventuality is defined as the TX extra/outputs this transaction will create, if signed /// with the specified seed. This eventuality can be compared to on-chain transactions to see /// if the transaction has already been signed and published. pub fn eventuality(&self) -> Option { - let inputs = self.inputs.iter().map(|input| input.key()).collect::>(); + let inputs = self.inputs.iter().map(SpendableOutput::key).collect::>(); let (tx_key, additional, outputs, id) = Self::prepare_payments( self.r_seed.as_ref()?, &inputs, @@ -606,7 +607,7 @@ impl SignableTransaction { let (tx_key, additional, outputs, id) = Self::prepare_payments( &r_seed, - &self.inputs.iter().map(|input| input.key()).collect::>(), + &self.inputs.iter().map(SpendableOutput::key).collect::>(), &mut self.payments, uniqueness, ); @@ -656,7 +657,7 @@ impl SignableTransaction { fee, encrypted_amounts, pseudo_outs: vec![], - commitments: commitments.iter().map(|commitment| commitment.calculate()).collect(), + commitments: commitments.iter().map(Commitment::calculate).collect(), }, prunable: RctPrunable::Clsag { bulletproofs: bp, clsags: vec![], pseudo_outs: vec![] }, }, @@ -713,13 +714,18 @@ impl SignableTransaction { impl Eventuality { /// Enables building a HashMap of Extra -> Eventuality for efficiently checking if an on-chain /// transaction may match this eventuality. + /// /// This extra is cryptographically bound to: /// 1) A specific set of inputs (via their output key) /// 2) A specific seed for the ephemeral keys + /// + /// This extra may be used in a transaction with a distinct set of inputs, yet no honest + /// transaction which doesn't satisfy this Eventuality will contain it. pub fn extra(&self) -> &[u8] { &self.extra } + #[must_use] pub fn matches(&self, tx: &Transaction) -> bool { if self.payments.len() != tx.prefix.outputs.len() { return false; @@ -752,9 +758,10 @@ impl Eventuality { } // TODO: Remove this when the following for loop is updated - if !rct_type.compact_encrypted_amounts() { - panic!("created an Eventuality for a very old RctType we don't support proving for"); - } + assert!( + rct_type.compact_encrypted_amounts(), + "created an Eventuality for a very old RctType we don't support proving for" + ); for (o, (expected, actual)) in outputs.iter().zip(tx.prefix.outputs.iter()).enumerate() { // Verify the output, commitment, and encrypted amount. @@ -815,7 +822,7 @@ impl Eventuality { String::from_utf8(read_vec(read_byte, r)?) .ok() .and_then(|str| MoneroAddress::from_str_raw(&str).ok()) - .ok_or(io::Error::new(io::ErrorKind::Other, "invalid address")) + .ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid address")) } fn read_payment(r: &mut R) -> io::Result { diff --git a/coins/monero/src/wallet/send/multisig.rs b/coins/monero/src/wallet/send/multisig.rs index 3694d507..d60d9a5a 100644 --- a/coins/monero/src/wallet/send/multisig.rs +++ b/coins/monero/src/wallet/send/multisig.rs @@ -274,7 +274,7 @@ impl SignMachine for TransactionSignMachine { // Find out who's included // This may not be a valid set of signers yet the algorithm machine will error if it's not commitments.remove(&self.i); // Remove, if it was included for some reason - let mut included = commitments.keys().cloned().collect::>(); + let mut included = commitments.keys().copied().collect::>(); included.push(self.i); included.sort_unstable(); @@ -325,7 +325,7 @@ impl SignMachine for TransactionSignMachine { // Remove our preprocess which shouldn't be here. It was just the easiest way to implement the // above - for map in commitments.iter_mut() { + for map in &mut commitments { map.remove(&self.i); } @@ -430,7 +430,9 @@ impl SignatureMachine for TransactionSignatureMachine { pseudo_outs.push(pseudo_out); } } - _ => unreachable!("attempted to sign a multisig TX which wasn't CLSAG"), + RctPrunable::MlsagBorromean { .. } | RctPrunable::MlsagBulletproofs { .. } => { + unreachable!("attempted to sign a multisig TX which wasn't CLSAG") + } } Ok(tx) } diff --git a/coins/monero/tests/add_data.rs b/coins/monero/tests/add_data.rs index 9f53b72d..ab45177b 100644 --- a/coins/monero/tests/add_data.rs +++ b/coins/monero/tests/add_data.rs @@ -12,8 +12,7 @@ test!( let arbitrary_data = vec![b'\0'; MAX_ARBITRARY_DATA_SIZE - 1]; // make sure we can add to tx - let result = builder.add_data(arbitrary_data.clone()); - assert!(result.is_ok()); + builder.add_data(arbitrary_data.clone()).unwrap(); builder.add_payment(addr, 5); (builder.build().unwrap(), (arbitrary_data,)) @@ -37,8 +36,7 @@ test!( // Add data multiple times for data in &data { - let result = builder.add_data(data.clone()); - assert!(result.is_ok()); + builder.add_data(data.clone()).unwrap(); } builder.add_payment(addr, 5); @@ -65,7 +63,7 @@ test!( // Reduce data size and retry. The data will now be 255 bytes long (including the added // marker), exactly data.pop(); - assert!(builder.add_data(data.clone()).is_ok()); + builder.add_data(data.clone()).unwrap(); builder.add_payment(addr, 5); (builder.build().unwrap(), data) diff --git a/coins/monero/tests/send.rs b/coins/monero/tests/send.rs index c210c59c..8acac581 100644 --- a/coins/monero/tests/send.rs +++ b/coins/monero/tests/send.rs @@ -37,8 +37,8 @@ test!( }, ), ( - |rpc, mut builder: Builder, addr, mut outputs: Vec| async move { - for output in outputs.drain(..) { + |rpc, mut builder: Builder, addr, outputs: Vec| async move { + for output in outputs { builder.add_input(SpendableOutput::from(&rpc, output).await.unwrap()); } builder.add_payment(addr, 6); diff --git a/coins/monero/tests/wallet2_compatibility.rs b/coins/monero/tests/wallet2_compatibility.rs index 57c73b16..9bd50161 100644 --- a/coins/monero/tests/wallet2_compatibility.rs +++ b/coins/monero/tests/wallet2_compatibility.rs @@ -70,7 +70,7 @@ async fn from_wallet_rpc_to_self(spec: AddressSpec) { // make an addr let (_, view_pair, _) = runner::random_address(); - let addr = Address::from_str(&view_pair.address(Network::Mainnet, spec).to_string()[..]).unwrap(); + let addr = Address::from_str(&view_pair.address(Network::Mainnet, spec).to_string()).unwrap(); // refresh & make a tx wallet_rpc.refresh(None).await.unwrap(); @@ -103,7 +103,9 @@ async fn from_wallet_rpc_to_self(spec: AddressSpec) { assert_eq!(output.metadata.payment_id, payment_id); assert_eq!(output.metadata.subaddress, None); } - _ => assert_eq!(output.metadata.subaddress, None), + AddressSpec::Standard | AddressSpec::Featured { .. } => { + assert_eq!(output.metadata.subaddress, None) + } } assert_eq!(output.commitment().amount, 1000000000000); } @@ -228,7 +230,7 @@ test!( for _ in 0 .. 2 { // Subtract 1 since we prefix data with 127 let data = vec![b'a'; MAX_TX_EXTRA_NONCE_SIZE - 1]; - assert!(builder.add_data(data).is_ok()); + builder.add_data(data).unwrap(); } (builder.build().unwrap(), (wallet_rpc,)) diff --git a/common/db/src/lib.rs b/common/db/src/lib.rs index 1ff5bb82..12f4977c 100644 --- a/common/db/src/lib.rs +++ b/common/db/src/lib.rs @@ -23,7 +23,7 @@ pub trait Db: 'static + Send + Sync + Clone + Debug + Get { fn key(db_dst: &'static [u8], item_dst: &'static [u8], key: impl AsRef<[u8]>) -> Vec { let db_len = u8::try_from(db_dst.len()).unwrap(); let dst_len = u8::try_from(item_dst.len()).unwrap(); - [[db_len].as_ref(), db_dst, [dst_len].as_ref(), item_dst, key.as_ref()].concat().to_vec() + [[db_len].as_ref(), db_dst, [dst_len].as_ref(), item_dst, key.as_ref()].concat() } fn txn(&mut self) -> Self::Transaction<'_>; } @@ -38,7 +38,11 @@ impl<'a> Get for MemDbTxn<'a> { if self.2.contains(key.as_ref()) { return None; } - self.1.get(key.as_ref()).cloned().or(self.0 .0.read().unwrap().get(key.as_ref()).cloned()) + self + .1 + .get(key.as_ref()) + .cloned() + .or_else(|| self.0 .0.read().unwrap().get(key.as_ref()).cloned()) } } impl<'a> DbTxn for MemDbTxn<'a> { diff --git a/common/std-shims/src/io.rs b/common/std-shims/src/io.rs index 4d33f135..5f13aff4 100644 --- a/common/std-shims/src/io.rs +++ b/common/std-shims/src/io.rs @@ -53,10 +53,7 @@ mod shims { impl Read for &[u8] { fn read(&mut self, buf: &mut [u8]) -> Result { - let mut read = buf.len(); - if self.len() < buf.len() { - read = self.len(); - } + let read = buf.len().min(self.len()); buf[.. read].copy_from_slice(&self[.. read]); *self = &self[read ..]; Ok(read) diff --git a/common/std-shims/src/lib.rs b/common/std-shims/src/lib.rs index 3eb2ec72..bccda3a0 100644 --- a/common/std-shims/src/lib.rs +++ b/common/std-shims/src/lib.rs @@ -2,33 +2,12 @@ #![doc = include_str!("../README.md")] #![cfg_attr(not(feature = "std"), no_std)] -#[cfg(not(feature = "std"))] -#[allow(unused_imports)] -#[doc(hidden)] -#[macro_use] pub extern crate alloc; pub mod sync; pub mod collections; pub mod io; -pub mod vec { - #[cfg(not(feature = "std"))] - pub use alloc::vec::*; - #[cfg(feature = "std")] - pub use std::vec::*; -} - -pub mod str { - #[cfg(not(feature = "std"))] - pub use alloc::str::*; - #[cfg(feature = "std")] - pub use std::str::*; -} - -pub mod string { - #[cfg(not(feature = "std"))] - pub use alloc::string::*; - #[cfg(feature = "std")] - pub use std::string::*; -} +pub use alloc::vec; +pub use alloc::str; +pub use alloc::string; diff --git a/common/std-shims/src/sync.rs b/common/std-shims/src/sync.rs index 05cf80ab..75cfe39a 100644 --- a/common/std-shims/src/sync.rs +++ b/common/std-shims/src/sync.rs @@ -1,4 +1,5 @@ pub use core::sync::*; +pub use alloc::sync::*; mod mutex_shim { #[cfg(feature = "std")] @@ -57,7 +58,7 @@ mod oncelock_shim { let mut lock = self.0.lock(); if !*lock { unsafe { - (core::ptr::addr_of!(self.1) as *mut Option<_>).write_unaligned(Some(f())); + core::ptr::addr_of!(self.1).cast_mut().write_unaligned(Some(f())); } } *lock = true; diff --git a/crypto/ciphersuite/src/kp256.rs b/crypto/ciphersuite/src/kp256.rs index e97a856b..37fdb2e4 100644 --- a/crypto/ciphersuite/src/kp256.rs +++ b/crypto/ciphersuite/src/kp256.rs @@ -134,7 +134,7 @@ fn test_secp256k1() { ) .to_repr() .iter() - .cloned() + .copied() .collect::>(), hex::decode("acc83278035223c1ba464e2d11bfacfc872b2b23e1041cf5f6130da21e4d8068").unwrap() ); @@ -167,7 +167,7 @@ f4e8cf80aec3f888d997900ac7e3e349944b5a6b47649fc32186d2f1238103c6\ ) .to_repr() .iter() - .cloned() + .copied() .collect::>(), hex::decode("f871dfcf6bcd199342651adc361b92c941cb6a0d8c8c1a3b91d79e2c1bf3722d").unwrap() ); diff --git a/crypto/dalek-ff-group/src/field.rs b/crypto/dalek-ff-group/src/field.rs index fb25281c..2e83f7bf 100644 --- a/crypto/dalek-ff-group/src/field.rs +++ b/crypto/dalek-ff-group/src/field.rs @@ -1,5 +1,5 @@ use core::{ - ops::{DerefMut, Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign}, + ops::{Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign}, iter::{Sum, Product}, }; @@ -234,7 +234,7 @@ impl FieldElement { let mut bits = 0; for (i, mut bit) in other.to_le_bits().iter_mut().rev().enumerate() { bits <<= 1; - let mut bit = u8_from_bool(bit.deref_mut()); + let mut bit = u8_from_bool(&mut bit); bits |= bit; bit.zeroize(); @@ -300,7 +300,7 @@ impl Sum for FieldElement { impl<'a> Sum<&'a FieldElement> for FieldElement { fn sum>(iter: I) -> FieldElement { - iter.cloned().sum() + iter.copied().sum() } } @@ -316,7 +316,7 @@ impl Product for FieldElement { impl<'a> Product<&'a FieldElement> for FieldElement { fn product>(iter: I) -> FieldElement { - iter.cloned().product() + iter.copied().product() } } diff --git a/crypto/dalek-ff-group/src/lib.rs b/crypto/dalek-ff-group/src/lib.rs index 21ed119e..c99a9d5d 100644 --- a/crypto/dalek-ff-group/src/lib.rs +++ b/crypto/dalek-ff-group/src/lib.rs @@ -4,7 +4,7 @@ use core::{ borrow::Borrow, - ops::{Deref, DerefMut, Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign}, + ops::{Deref, Add, AddAssign, Sub, SubAssign, Neg, Mul, MulAssign}, iter::{Iterator, Sum, Product}, hash::{Hash, Hasher}, }; @@ -201,7 +201,7 @@ impl Scalar { let mut bits = 0; for (i, mut bit) in other.to_le_bits().iter_mut().rev().enumerate() { bits <<= 1; - let mut bit = u8_from_bool(bit.deref_mut()); + let mut bit = u8_from_bool(&mut bit); bits |= bit; bit.zeroize(); @@ -337,7 +337,7 @@ impl PrimeField for Scalar { // methods does not // We do not use one of its methods to ensure we write via zeroize for mut bit in bits.iter_mut() { - bit.deref_mut().zeroize(); + bit.zeroize(); } res } diff --git a/crypto/dkg/src/encryption.rs b/crypto/dkg/src/encryption.rs index 99b039b8..caf899e8 100644 --- a/crypto/dkg/src/encryption.rs +++ b/crypto/dkg/src/encryption.rs @@ -390,9 +390,10 @@ impl Encryption { participant: Participant, msg: EncryptionKeyMessage, ) -> M { - if self.enc_keys.contains_key(&participant) { - panic!("Re-registering encryption key for a participant"); - } + assert!( + !self.enc_keys.contains_key(&participant), + "Re-registering encryption key for a participant" + ); self.enc_keys.insert(participant, msg.enc_key); msg.msg } diff --git a/crypto/dkg/src/frost.rs b/crypto/dkg/src/frost.rs index 868a7109..45450187 100644 --- a/crypto/dkg/src/frost.rs +++ b/crypto/dkg/src/frost.rs @@ -92,7 +92,8 @@ pub struct KeyGenMachine { impl KeyGenMachine { /// Create a new machine to generate a key. - // The context string should be unique among multisigs. + /// + /// The context string should be unique among multisigs. pub fn new(params: ThresholdParams, context: String) -> KeyGenMachine { KeyGenMachine { params, context, _curve: PhantomData } } @@ -171,7 +172,6 @@ fn polynomial( /// channel. /// /// If any participant sends multiple secret shares to another participant, they are faulty. - // This should presumably be written as SecretShare(Zeroizing). // It's unfortunately not possible as F::Repr doesn't have Zeroize as a bound. // The encryption system also explicitly uses Zeroizing so it can ensure anything being @@ -353,7 +353,7 @@ impl Zeroize for KeyMachine { fn zeroize(&mut self) { self.params.zeroize(); self.secret.zeroize(); - for (_, commitments) in self.commitments.iter_mut() { + for commitments in self.commitments.values_mut() { commitments.zeroize(); } self.encryption.zeroize(); @@ -499,7 +499,7 @@ impl fmt::Debug for BlameMachine { impl Zeroize for BlameMachine { fn zeroize(&mut self) { - for (_, commitments) in self.commitments.iter_mut() { + for commitments in self.commitments.values_mut() { commitments.zeroize(); } self.encryption.zeroize(); @@ -536,10 +536,9 @@ impl BlameMachine { Err(DecryptionError::InvalidProof) => return recipient, }; - let share = match Option::::from(C::F::from_repr(share_bytes.0)) { - Some(share) => share, + let Some(share) = Option::::from(C::F::from_repr(share_bytes.0)) else { // If this isn't a valid scalar, the sender is faulty - None => return sender, + return sender; }; // If this isn't a valid share, the sender is faulty diff --git a/crypto/dkg/src/tests/mod.rs b/crypto/dkg/src/tests/mod.rs index f78489ad..548b2fe0 100644 --- a/crypto/dkg/src/tests/mod.rs +++ b/crypto/dkg/src/tests/mod.rs @@ -25,7 +25,7 @@ pub const PARTICIPANTS: u16 = 5; pub const THRESHOLD: u16 = ((PARTICIPANTS * 2) / 3) + 1; /// Clone a map without a specific value. -pub fn clone_without( +pub fn clone_without( map: &HashMap, without: &K, ) -> HashMap { @@ -40,7 +40,7 @@ pub fn clone_without( pub fn recover_key(keys: &HashMap>) -> C::F { let first = keys.values().next().expect("no keys provided"); assert!(keys.len() >= first.params().t().into(), "not enough keys provided"); - let included = keys.keys().cloned().collect::>(); + let included = keys.keys().copied().collect::>(); let group_private = keys.iter().fold(C::F::ZERO, |accum, (i, keys)| { accum + (lagrange::(*i, &included) * keys.secret_share().deref()) diff --git a/crypto/dkg/src/tests/musig.rs b/crypto/dkg/src/tests/musig.rs index bbe47342..086b26be 100644 --- a/crypto/dkg/src/tests/musig.rs +++ b/crypto/dkg/src/tests/musig.rs @@ -24,9 +24,9 @@ pub fn test_musig(rng: &mut R) { const CONTEXT: &[u8] = b"MuSig Test"; // Empty signing set - assert!(musig::(CONTEXT, &Zeroizing::new(C::F::ZERO), &[]).is_err()); + musig::(CONTEXT, &Zeroizing::new(C::F::ZERO), &[]).unwrap_err(); // Signing set we're not part of - assert!(musig::(CONTEXT, &Zeroizing::new(C::F::ZERO), &[C::generator()]).is_err()); + musig::(CONTEXT, &Zeroizing::new(C::F::ZERO), &[C::generator()]).unwrap_err(); // Test with n keys { diff --git a/crypto/dleq/src/cross_group/mod.rs b/crypto/dleq/src/cross_group/mod.rs index c08ff7b2..08e92959 100644 --- a/crypto/dleq/src/cross_group/mod.rs +++ b/crypto/dleq/src/cross_group/mod.rs @@ -1,6 +1,6 @@ use core::ops::{Deref, DerefMut}; #[cfg(feature = "serialize")] -use std::io::{Read, Write}; +use std::io::{self, Read, Write}; use thiserror::Error; @@ -51,15 +51,15 @@ fn u8_from_bool(bit_ref: &mut bool) -> u8 { } #[cfg(feature = "serialize")] -pub(crate) fn read_point(r: &mut R) -> std::io::Result { +pub(crate) fn read_point(r: &mut R) -> io::Result { let mut repr = G::Repr::default(); r.read_exact(repr.as_mut())?; let point = G::from_bytes(&repr); let Some(point) = Option::::from(point) else { - Err(std::io::Error::new(std::io::ErrorKind::Other, "invalid point"))? + Err(io::Error::new(io::ErrorKind::Other, "invalid point"))? }; if point.to_bytes().as_ref() != repr.as_ref() { - Err(std::io::Error::new(std::io::ErrorKind::Other, "non-canonical point"))?; + Err(io::Error::new(io::ErrorKind::Other, "non-canonical point"))?; } Ok(point) } @@ -439,7 +439,7 @@ where /// Write a Cross-Group Discrete Log Equality proof to a type satisfying std::io::Write. #[cfg(feature = "serialize")] - pub fn write(&self, w: &mut W) -> std::io::Result<()> { + pub fn write(&self, w: &mut W) -> io::Result<()> { for bit in &self.bits { bit.write(w)?; } @@ -452,7 +452,7 @@ where /// Read a Cross-Group Discrete Log Equality proof from a type satisfying std::io::Read. #[cfg(feature = "serialize")] - pub fn read(r: &mut R) -> std::io::Result { + pub fn read(r: &mut R) -> io::Result { let capacity = usize::try_from(G0::Scalar::CAPACITY.min(G1::Scalar::CAPACITY)).unwrap(); let bits_per_group = BitSignature::from(SIGNATURE).bits(); diff --git a/crypto/dleq/src/tests/mod.rs b/crypto/dleq/src/tests/mod.rs index 104c2238..c80115de 100644 --- a/crypto/dleq/src/tests/mod.rs +++ b/crypto/dleq/src/tests/mod.rs @@ -77,7 +77,7 @@ fn test_dleq() { assert!(proof .verify( &mut transcript(), - generators[.. i].iter().cloned().rev().collect::>().as_ref(), + generators[.. i].iter().copied().rev().collect::>().as_ref(), &keys[.. i] ) .is_err()); @@ -86,7 +86,7 @@ fn test_dleq() { .verify( &mut transcript(), &generators[.. i], - keys[.. i].iter().cloned().rev().collect::>().as_ref() + keys[.. i].iter().copied().rev().collect::>().as_ref() ) .is_err()); } diff --git a/crypto/ed448/src/backend.rs b/crypto/ed448/src/backend.rs index 4b889d94..ad2d571f 100644 --- a/crypto/ed448/src/backend.rs +++ b/crypto/ed448/src/backend.rs @@ -80,7 +80,7 @@ macro_rules! field { $DELTA: expr, ) => { use core::{ - ops::{DerefMut, Add, AddAssign, Neg, Sub, SubAssign, Mul, MulAssign}, + ops::{Add, AddAssign, Neg, Sub, SubAssign, Mul, MulAssign}, iter::{Sum, Product}, }; @@ -150,7 +150,7 @@ macro_rules! field { let mut bits = 0; for (i, mut bit) in other.to_le_bits().iter_mut().rev().enumerate() { bits <<= 1; - let mut bit = u8_from_bool(bit.deref_mut()); + let mut bit = u8_from_bool(&mut bit); bits |= bit; bit.zeroize(); diff --git a/crypto/ed448/src/point.rs b/crypto/ed448/src/point.rs index fa250f90..3ea70b85 100644 --- a/crypto/ed448/src/point.rs +++ b/crypto/ed448/src/point.rs @@ -1,5 +1,5 @@ use core::{ - ops::{DerefMut, Add, AddAssign, Neg, Sub, SubAssign, Mul, MulAssign}, + ops::{Add, AddAssign, Neg, Sub, SubAssign, Mul, MulAssign}, iter::Sum, }; @@ -232,7 +232,7 @@ impl Mul for Point { let mut bits = 0; for (i, mut bit) in other.to_le_bits().iter_mut().rev().enumerate() { bits <<= 1; - let mut bit = u8_from_bool(bit.deref_mut()); + let mut bit = u8_from_bool(&mut bit); bits |= bit; bit.zeroize(); diff --git a/crypto/frost/src/tests/mod.rs b/crypto/frost/src/tests/mod.rs index f20196ce..e36bd711 100644 --- a/crypto/frost/src/tests/mod.rs +++ b/crypto/frost/src/tests/mod.rs @@ -27,7 +27,7 @@ pub const PARTICIPANTS: u16 = 5; pub const THRESHOLD: u16 = ((PARTICIPANTS * 2) / 3) + 1; /// Clone a map without a specific value. -pub fn clone_without( +pub fn clone_without( map: &HashMap, without: &K, ) -> HashMap { @@ -177,8 +177,8 @@ pub fn sign( machines, |rng, machines| { // Cache and rebuild half of the machines - let mut included = machines.keys().cloned().collect::>(); - for i in included.drain(..) { + let included = machines.keys().cloned().collect::>(); + for i in included { if (rng.next_u64() % 2) == 0 { let cache = machines.remove(&i).unwrap().cache(); machines.insert( @@ -226,7 +226,7 @@ pub fn test_offset_schnorr>(rng: &m let offset = C::F::from(5); let offset_key = group_key + (C::generator() * offset); - for (_, keys) in keys.iter_mut() { + for keys in keys.values_mut() { *keys = keys.offset(offset); assert_eq!(keys.group_key(), offset_key); } diff --git a/crypto/frost/src/tests/nonces.rs b/crypto/frost/src/tests/nonces.rs index 0091d97d..8031013c 100644 --- a/crypto/frost/src/tests/nonces.rs +++ b/crypto/frost/src/tests/nonces.rs @@ -176,13 +176,8 @@ pub fn test_invalid_commitment(rng: &mut R) { let nonce = preprocess.commitments.nonces.get_mut(usize::try_from(rng.next_u64()).unwrap() % 2).unwrap(); let generators_len = nonce.generators.len(); - *nonce - .generators - .get_mut(usize::try_from(rng.next_u64()).unwrap() % generators_len) - .unwrap() - .0 - .get_mut(usize::try_from(rng.next_u64()).unwrap() % 2) - .unwrap() = C::G::random(&mut *rng); + nonce.generators[usize::try_from(rng.next_u64()).unwrap() % generators_len].0 + [usize::try_from(rng.next_u64()).unwrap() % 2] = C::G::random(&mut *rng); // The commitments are validated at time of deserialization (read_preprocess) // Accordingly, serialize it and read it again to make sure that errors diff --git a/crypto/frost/src/tests/vectors.rs b/crypto/frost/src/tests/vectors.rs index 74ab8069..b152f2ad 100644 --- a/crypto/frost/src/tests/vectors.rs +++ b/crypto/frost/src/tests/vectors.rs @@ -166,8 +166,8 @@ pub fn test_with_vectors>( } let mut commitments = HashMap::new(); - let mut machines = machines - .drain(..) + let machines = machines + .into_iter() .enumerate() .map(|(c, (i, machine))| { let nonce = |i| { @@ -224,8 +224,8 @@ pub fn test_with_vectors>( .collect::>(); let mut shares = HashMap::new(); - let mut machines = machines - .drain(..) + let machines = machines + .into_iter() .enumerate() .map(|(c, (i, machine))| { let (machine, share) = machine @@ -242,9 +242,9 @@ pub fn test_with_vectors>( shares.insert(*i, machine.read_share::<&[u8]>(&mut share.as_ref()).unwrap()); (i, machine) }) - .collect::>(); + .collect::>(); - for (i, machine) in machines.drain() { + for (i, machine) in machines { let sig = machine.complete(clone_without(&shares, i)).unwrap(); let mut serialized = sig.R.to_bytes().as_ref().to_vec(); serialized.extend(sig.s.to_repr().as_ref()); @@ -347,7 +347,7 @@ pub fn test_with_vectors>( machines.push((i, AlgorithmMachine::new(IetfSchnorr::::ietf(), keys[i].clone()))); } - for (i, machine) in machines.drain(..) { + for (i, machine) in machines { let (_, preprocess) = machine.preprocess(&mut frosts.clone()); // Calculate the expected nonces diff --git a/crypto/multiexp/src/batch.rs b/crypto/multiexp/src/batch.rs index 09c0ebce..246ccb5d 100644 --- a/crypto/multiexp/src/batch.rs +++ b/crypto/multiexp/src/batch.rs @@ -18,7 +18,7 @@ fn flat( where ::Scalar: PrimeFieldBits + Zeroize, { - Zeroizing::new(slice.iter().flat_map(|pairs| pairs.1.iter()).cloned().collect::>()) + Zeroizing::new(slice.iter().flat_map(|pairs| pairs.1.iter()).copied().collect::>()) } /// A batch verifier intended to verify a series of statements are each equivalent to zero. @@ -35,7 +35,8 @@ where ::Scalar: PrimeFieldBits + Zeroize, { /// Create a new batch verifier, expected to verify the following amount of statements. - /// This is a size hint and is not required to be accurate. + /// + /// `capacity` is a size hint and is not required to be accurate. pub fn new(capacity: usize) -> BatchVerifier { BatchVerifier(Zeroizing::new(Vec::with_capacity(capacity))) } diff --git a/crypto/multiexp/src/lib.rs b/crypto/multiexp/src/lib.rs index b660ebb7..191977b6 100644 --- a/crypto/multiexp/src/lib.rs +++ b/crypto/multiexp/src/lib.rs @@ -2,7 +2,6 @@ #![doc = include_str!("../README.md")] #![cfg_attr(not(feature = "std"), no_std)] -use core::ops::DerefMut; #[cfg(not(feature = "std"))] #[macro_use] extern crate alloc; @@ -62,7 +61,7 @@ where groupings.push(vec![0; (bits.len() + (w_usize - 1)) / w_usize]); for (i, mut bit) in bits.iter_mut().enumerate() { - let mut bit = u8_from_bool(bit.deref_mut()); + let mut bit = u8_from_bool(&mut bit); groupings[p][i / w_usize] |= bit << (i % w_usize); bit.zeroize(); } diff --git a/crypto/schnorr/src/tests/mod.rs b/crypto/schnorr/src/tests/mod.rs index 42509ffd..47bd9bc3 100644 --- a/crypto/schnorr/src/tests/mod.rs +++ b/crypto/schnorr/src/tests/mod.rs @@ -106,7 +106,7 @@ pub(crate) fn aggregate() { keys .iter() .map(|key| C::generator() * key.deref()) - .zip(challenges.iter().cloned()) + .zip(challenges.iter().copied()) .collect::>() .as_ref(), ));