Make progress on #235

I'm still not exactly sure where the trap handler in Monero for this is...
until then, this remains potentially fingerprintable.
This commit is contained in:
Luke Parker 2023-01-28 03:18:41 -05:00
parent 9241bdc3b5
commit a4fdff3e3b
No known key found for this signature in database
2 changed files with 29 additions and 9 deletions

View file

@ -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> {

View file

@ -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![];
@ -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,