From 5b2940e161ba1ae072b820fa505c8a0896969c8f Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 22 Aug 2022 13:35:49 -0400 Subject: [PATCH] Lint previous commit --- coins/monero/src/rpc.rs | 2 +- coins/monero/src/wallet/decoys.rs | 2 +- coins/monero/src/wallet/scan.rs | 40 +++++++++++++++++------- coins/monero/src/wallet/send/mod.rs | 8 ++--- coins/monero/src/wallet/send/multisig.rs | 8 ++--- coins/monero/tests/send.rs | 2 +- 6 files changed, 40 insertions(+), 22 deletions(-) diff --git a/coins/monero/src/rpc.rs b/coins/monero/src/rpc.rs index 68e533ba..b8e66778 100644 --- a/coins/monero/src/rpc.rs +++ b/coins/monero/src/rpc.rs @@ -165,7 +165,7 @@ impl Rpc { ) .await?; - if txs.missed_tx.len() != 0 { + if !txs.missed_tx.is_empty() { Err(RpcError::TransactionsNotFound( txs.missed_tx.iter().map(|hash| hex::decode(&hash).unwrap().try_into().unwrap()).collect(), ))?; diff --git a/coins/monero/src/wallet/decoys.rs b/coins/monero/src/wallet/decoys.rs index 9debb473..c3d34a1d 100644 --- a/coins/monero/src/wallet/decoys.rs +++ b/coins/monero/src/wallet/decoys.rs @@ -141,7 +141,7 @@ impl Decoys { let mut outputs = Vec::with_capacity(inputs.len()); for input in inputs { real.push(input.global_index); - outputs.push((real[real.len() - 1], [input.output.data.key, input.commitment().calculate()])); + outputs.push((real[real.len() - 1], [input.key(), input.commitment().calculate()])); } let distribution_len = { diff --git a/coins/monero/src/wallet/scan.rs b/coins/monero/src/wallet/scan.rs index f8de7aa2..fc4061ac 100644 --- a/coins/monero/src/wallet/scan.rs +++ b/coins/monero/src/wallet/scan.rs @@ -94,6 +94,14 @@ pub struct ReceivedOutput { } impl ReceivedOutput { + pub fn key(&self) -> EdwardsPoint { + self.data.key + } + + pub fn key_offset(&self) -> Scalar { + self.data.key_offset + } + pub fn commitment(&self) -> Commitment { self.data.commitment.clone() } @@ -133,6 +141,14 @@ impl SpendableOutput { Ok(output) } + pub fn key(&self) -> EdwardsPoint { + self.output.key() + } + + pub fn key_offset(&self) -> Scalar { + self.output.key_offset() + } + pub fn commitment(&self) -> Commitment { self.output.commitment() } @@ -182,7 +198,7 @@ impl Timelocked { } impl Scanner { - pub fn scan_stateless(&mut self, tx: &Transaction) -> Timelocked { + pub fn scan_transaction(&mut self, tx: &Transaction) -> Timelocked { let extra = Extra::deserialize(&mut Cursor::new(&tx.prefix.extra)); let keys; let extra = if let Ok(extra) = extra { @@ -204,7 +220,7 @@ impl Scanner { } for key in &keys { - let (view_tag, key_offset, payment_id_xor) = shared_key( + let (view_tag, shared_key, payment_id_xor) = shared_key( if self.burning_bug.is_none() { Some(uniqueness(&tx.prefix.inputs)) } else { None }, &self.pair.view, key, @@ -227,11 +243,17 @@ impl Scanner { // P - shared == spend let subaddress = self .subaddresses - .get(&(output.key - (&key_offset * &ED25519_BASEPOINT_TABLE)).compress()); + .get(&(output.key - (&shared_key * &ED25519_BASEPOINT_TABLE)).compress()); if subaddress.is_none() { continue; } + // If it has torsion, it'll substract the non-torsioned shared key to a torsioned key + // We will not have a torsioned key in our HashMap of keys, so we wouldn't identify it as + // ours + // If we did, it'd enable bypassing the included burning bug protection however + debug_assert!(output.key.is_torsion_free()); + let key_offset = shared_key + self.pair.subaddress(*subaddress.unwrap()); // Since we've found an output to us, get its amount let mut commitment = Commitment::zero(); @@ -241,14 +263,14 @@ impl Scanner { // Regular transaction } else { let amount = match tx.rct_signatures.base.ecdh_info.get(o) { - Some(amount) => amount_decryption(*amount, key_offset), + Some(amount) => amount_decryption(*amount, shared_key), // This should never happen, yet it may be possible with miner transactions? // Using get just decreases the possibility of a panic and lets us move on in that case None => break, }; // Rebuild the commitment to verify it - commitment = Commitment::new(commitment_mask(key_offset), amount); + commitment = Commitment::new(commitment_mask(shared_key), amount); // If this is a malicious commitment, move to the next output // Any other R value will calculate to a different spend key and are therefore ignorable if Some(&commitment.calculate()) != tx.rct_signatures.base.commitments.get(o) { @@ -260,11 +282,7 @@ impl Scanner { res.push(ReceivedOutput { absolute: AbsoluteId { tx: tx.hash(), o: o.try_into().unwrap() }, - data: OutputData { - key: output.key, - key_offset: key_offset + self.pair.subaddress(*subaddress.unwrap()), - commitment, - }, + data: OutputData { key: output.key, key_offset, commitment }, metadata: Metadata { subaddress: (0, 0), payment_id }, }); @@ -311,7 +329,7 @@ impl Scanner { let mut res = vec![]; for tx in txs { - if let Some(timelock) = map(self.scan_stateless(&tx), index) { + if let Some(timelock) = map(self.scan_transaction(&tx), index) { res.push(timelock); } index += u64::try_from(tx.prefix.outputs.len()).unwrap(); diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index 4dee38ae..1ad09a91 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -129,8 +129,8 @@ async fn prepare_inputs( for (i, input) in inputs.iter().enumerate() { signable.push(( - spend + input.output.data.key_offset, - generate_key_image(spend + input.output.data.key_offset), + spend + input.key_offset(), + generate_key_image(spend + input.key_offset()), ClsagInput::new(input.commitment().clone(), decoys[i].clone()) .map_err(TransactionError::ClsagError)?, )); @@ -345,8 +345,8 @@ impl SignableTransaction { ) -> Result { let mut images = Vec::with_capacity(self.inputs.len()); for input in &self.inputs { - let mut offset = spend + input.output.data.key_offset; - if (&offset * &ED25519_BASEPOINT_TABLE) != input.output.data.key { + let mut offset = spend + input.key_offset(); + if (&offset * &ED25519_BASEPOINT_TABLE) != input.key() { Err(TransactionError::WrongPrivateKey)?; } diff --git a/coins/monero/src/wallet/send/multisig.rs b/coins/monero/src/wallet/send/multisig.rs index 64575ce0..825e2951 100644 --- a/coins/monero/src/wallet/send/multisig.rs +++ b/coins/monero/src/wallet/send/multisig.rs @@ -104,7 +104,7 @@ impl SignableTransaction { transcript.append_message(b"input_output_index", &[input.output.absolute.o]); // Not including this, with a doxxed list of payments, would allow brute forcing the inputs // to determine RNG seeds and therefore the true spends - transcript.append_message(b"input_shared_key", &input.output.data.key_offset.to_bytes()); + transcript.append_message(b"input_shared_key", &input.key_offset().to_bytes()); } for payment in &self.payments { transcript.append_message(b"payment_address", payment.0.to_string().as_bytes()); @@ -116,14 +116,14 @@ impl SignableTransaction { for (i, input) in self.inputs.iter().enumerate() { // Check this the right set of keys - let offset = keys.offset(dalek_ff_group::Scalar(input.output.data.key_offset)); - if offset.group_key().0 != input.output.data.key { + let offset = keys.offset(dalek_ff_group::Scalar(input.key_offset())); + if offset.group_key().0 != input.key() { Err(TransactionError::WrongPrivateKey)?; } clsags.push( AlgorithmMachine::new( - ClsagMultisig::new(transcript.clone(), input.output.data.key, inputs[i].clone()) + ClsagMultisig::new(transcript.clone(), input.key(), inputs[i].clone()) .map_err(TransactionError::MultisigError)?, offset, &included, diff --git a/coins/monero/tests/send.rs b/coins/monero/tests/send.rs index e24a747a..18bcd3e5 100644 --- a/coins/monero/tests/send.rs +++ b/coins/monero/tests/send.rs @@ -98,7 +98,7 @@ async fn send_core(test: usize, multisig: bool) { // Grab the largest output available let output = { - let mut outputs = scanner.scan_stateless(tx.as_ref().unwrap()).ignore_timelock(); + let mut outputs = scanner.scan_transaction(tx.as_ref().unwrap()).ignore_timelock(); outputs.sort_by(|x, y| x.commitment().amount.cmp(&y.commitment().amount).reverse()); outputs.swap_remove(0) };