From a52c86ad8108f6b13ea318539c5d0497cd325f7c Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 21 Aug 2023 03:07:20 -0400 Subject: [PATCH] Don't label Monero nodes invalid for returning invalid keys in outputs Only recently (I believe the most recent HF) were output keys checked to be valid. This means returned keys may be invalid points, despite being the legitimate keys for the specified outputs. Does still label the node as invalid if it doesn't return 32 bytes, hex-encoded. --- coins/monero/src/rpc/mod.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/coins/monero/src/rpc/mod.rs b/coins/monero/src/rpc/mod.rs index cacbd200..93aed26a 100644 --- a/coins/monero/src/rpc/mod.rs +++ b/coins/monero/src/rpc/mod.rs @@ -583,8 +583,22 @@ impl Rpc { .iter() .enumerate() .map(|(i, out)| { + // Allow keys to be invalid, though if they are, return None to trigger selection of a new + // decoy + // Only valid keys can be used in CLSAG proofs, hence the need for re-selection, yet + // invalid keys may honestly exist on the blockchain + // Only a recent hard fork checked output keys were valid points + let Some(key) = CompressedEdwardsY( + hex::decode(&out.key) + .map_err(|_| RpcError::InvalidNode)? + .try_into() + .map_err(|_| RpcError::InvalidNode)?, + ) + .decompress() else { + return Ok(None); + }; Ok( - Some([rpc_point(&out.key)?, rpc_point(&out.mask)?]) + Some([key, rpc_point(&out.mask)?]) .filter(|_| Timelock::Block(height) >= txs[i].prefix.timelock), ) })