Skip to content

Commit

Permalink
Make progress on #235
Browse files Browse the repository at this point in the history
I'm still not exactly sure where the trap handler in Monero for this is...
until then, this remains potentially fingerprintable.
  • Loading branch information
kayabaNerve committed Jan 28, 2023
1 parent 9241bdc commit a4fdff3
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
14 changes: 9 additions & 5 deletions coins/monero/src/wallet/extra.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,20 @@ impl ExtraField {
#[derive(Clone, PartialEq, Eq, Debug, Zeroize)]
pub(crate) struct Extra(Vec<ExtraField>);
impl Extra {
pub(crate) fn keys(&self) -> Vec<EdwardsPoint> {
let mut keys = Vec::with_capacity(2);
pub(crate) fn keys(&self) -> Option<(EdwardsPoint, Option<Vec<EdwardsPoint>>)> {
let mut key = None;
let mut additional = None;
for field in &self.0 {
match field.clone() {
ExtraField::PublicKey(key) => keys.push(key),
ExtraField::PublicKeys(additional) => keys.extend(additional),
ExtraField::PublicKey(this_key) => key = key.or(Some(this_key)),
ExtraField::PublicKeys(these_additional) => {
additional = additional.or(Some(these_additional))
}
_ => (),
}
}
keys
// Don't return any keys if this was non-standard and didn't include the primary key
key.map(|key| (key, additional))
}

pub(crate) fn payment_id(&self) -> Option<PaymentId> {
Expand Down
24 changes: 20 additions & 4 deletions coins/monero/src/wallet/scan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,13 +272,18 @@ impl Scanner {
/// Scan a transaction to discover the received outputs.
pub fn scan_transaction(&mut self, tx: &Transaction) -> Timelocked<ReceivedOutput> {
let extra = Extra::read::<&[u8]>(&mut tx.prefix.extra.as_ref());
let keys;
let extra = if let Ok(extra) = extra {
keys = extra.keys();
extra
} else {
return Timelocked(tx.prefix.timelock, vec![]);
};

let (tx_key, additional) = if let Some((tx_key, additional)) = extra.keys() {
(tx_key, additional)
} else {
return Timelocked(tx.prefix.timelock, vec![]);
};

let payment_id = extra.payment_id();

let mut res = vec![];
Expand All @@ -296,8 +301,19 @@ impl Scanner {
}
let output_key = output_key.unwrap();

// TODO: Only use THE key or the matching additional key. Not any key
for key in &keys {
for key in [Some(Some(&tx_key)), additional.as_ref().map(|additional| additional.get(o))] {
let key = if let Some(Some(key)) = key {
key
} else if let Some(None) = key {
// This is non-standard. There were additional keys, yet not one for this output
// https://github.com/monero-project/monero/
// blob/04a1e2875d6e35e27bb21497988a6c822d319c28/
// src/cryptonote_basic/cryptonote_format_utils.cpp#L1062
// TODO: Should this return? Where does Monero set the trap handler for this exception?
continue;
} else {
break;
};
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,
Expand Down

0 comments on commit a4fdff3

Please sign in to comment.