Add necessary checks to Eventuality re: supported protocols

This commit is contained in:
Luke Parker
2023-07-04 11:59:50 -04:00
parent d9f145cd72
commit 9ebf438645
3 changed files with 36 additions and 10 deletions

View File

@@ -25,6 +25,7 @@ use serialize::{read_byte, read_u16};
/// RingCT structs and functionality. /// RingCT structs and functionality.
pub mod ringct; pub mod ringct;
use ringct::RctType;
/// Transaction structs. /// Transaction structs.
pub mod transaction; pub mod transaction;
@@ -45,14 +46,16 @@ pub(crate) fn INV_EIGHT() -> Scalar {
*INV_EIGHT_CELL.get_or_init(|| Scalar::from(8u8).invert()) *INV_EIGHT_CELL.get_or_init(|| Scalar::from(8u8).invert())
} }
/// Monero protocol version. v15 is omitted as v15 was simply v14 and v16 being active at the same /// Monero protocol version.
/// time, with regards to the transactions supported. Accordingly, v16 should be used during v15. ///
/// v15 is omitted as v15 was simply v14 and v16 being active at the same time, with regards to the
/// transactions supported. Accordingly, v16 should be used during v15.
#[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
#[allow(non_camel_case_types)] #[allow(non_camel_case_types)]
pub enum Protocol { pub enum Protocol {
v14, v14,
v16, v16,
Custom { ring_len: usize, bp_plus: bool }, Custom { ring_len: usize, bp_plus: bool, optimal_rct_type: RctType },
} }
impl Protocol { impl Protocol {
@@ -66,6 +69,7 @@ impl Protocol {
} }
/// Whether or not the specified version uses Bulletproofs or Bulletproofs+. /// Whether or not the specified version uses Bulletproofs or Bulletproofs+.
///
/// This method will likely be reworked when versions not using Bulletproofs at all are added. /// This method will likely be reworked when versions not using Bulletproofs at all are added.
pub fn bp_plus(&self) -> bool { pub fn bp_plus(&self) -> bool {
match self { match self {
@@ -75,15 +79,25 @@ impl Protocol {
} }
} }
// TODO: Make this an Option when we support pre-RCT protocols
pub fn optimal_rct_type(&self) -> RctType {
match self {
Protocol::v14 => RctType::Clsag,
Protocol::v16 => RctType::BulletproofsPlus,
Protocol::Custom { optimal_rct_type, .. } => *optimal_rct_type,
}
}
pub(crate) fn write<W: io::Write>(&self, w: &mut W) -> io::Result<()> { pub(crate) fn write<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
match self { match self {
Protocol::v14 => w.write_all(&[0, 14]), Protocol::v14 => w.write_all(&[0, 14]),
Protocol::v16 => w.write_all(&[0, 16]), Protocol::v16 => w.write_all(&[0, 16]),
Protocol::Custom { ring_len, bp_plus } => { Protocol::Custom { ring_len, bp_plus, optimal_rct_type } => {
// Custom, version 0 // Custom, version 0
w.write_all(&[1, 0])?; w.write_all(&[1, 0])?;
w.write_all(&u16::try_from(*ring_len).unwrap().to_le_bytes())?; w.write_all(&u16::try_from(*ring_len).unwrap().to_le_bytes())?;
w.write_all(&[u8::from(*bp_plus)]) w.write_all(&[u8::from(*bp_plus)])?;
w.write_all(&[optimal_rct_type.to_byte()])
} }
} }
} }
@@ -105,6 +119,8 @@ impl Protocol {
1 => true, 1 => true,
_ => Err(io::Error::new(io::ErrorKind::Other, "invalid bool serialization"))?, _ => Err(io::Error::new(io::ErrorKind::Other, "invalid bool serialization"))?,
}, },
optimal_rct_type: RctType::from_byte(read_byte(r)?)
.ok_or_else(|| io::Error::new(io::ErrorKind::Other, "invalid RctType serialization"))?,
}, },
_ => { _ => {
Err(io::Error::new(io::ErrorKind::Other, "unrecognized custom protocol serialization"))? Err(io::Error::new(io::ErrorKind::Other, "unrecognized custom protocol serialization"))?

View File

@@ -4,7 +4,7 @@ use std_shims::{
io::{self, Read, Write}, io::{self, Read, Write},
}; };
use zeroize::Zeroizing; use zeroize::{Zeroize, Zeroizing};
use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint}; use curve25519_dalek::{constants::ED25519_BASEPOINT_TABLE, scalar::Scalar, edwards::EdwardsPoint};
@@ -57,7 +57,7 @@ impl EncryptedAmount {
} }
} }
#[derive(Clone, Copy, PartialEq, Eq, Debug)] #[derive(Clone, Copy, PartialEq, Eq, Debug, Zeroize)]
pub enum RctType { pub enum RctType {
/// No RCT proofs. /// No RCT proofs.
Null, Null,
@@ -77,7 +77,7 @@ pub enum RctType {
} }
impl RctType { impl RctType {
fn to_byte(self) -> u8 { pub fn to_byte(self) -> u8 {
match self { match self {
RctType::Null => 0, RctType::Null => 0,
RctType::MlsagAggregate => 1, RctType::MlsagAggregate => 1,
@@ -89,7 +89,7 @@ impl RctType {
} }
} }
fn from_byte(byte: u8) -> Option<Self> { pub fn from_byte(byte: u8) -> Option<Self> {
Some(match byte { Some(match byte {
0 => RctType::Null, 0 => RctType::Null,
1 => RctType::MlsagAggregate, 1 => RctType::MlsagAggregate,
@@ -102,7 +102,7 @@ impl RctType {
}) })
} }
fn compact_encrypted_amounts(&self) -> bool { pub fn compact_encrypted_amounts(&self) -> bool {
match self { match self {
RctType::Null => false, RctType::Null => false,
RctType::MlsagAggregate => false, RctType::MlsagAggregate => false,

View File

@@ -746,6 +746,16 @@ impl Eventuality {
uniqueness(&tx.prefix.inputs), uniqueness(&tx.prefix.inputs),
); );
let rct_type = tx.rct_signatures.rct_type();
if rct_type != self.protocol.optimal_rct_type() {
return false;
}
// 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");
}
for (o, (expected, actual)) in outputs.iter().zip(tx.prefix.outputs.iter()).enumerate() { for (o, (expected, actual)) in outputs.iter().zip(tx.prefix.outputs.iter()).enumerate() {
// Verify the output, commitment, and encrypted amount. // Verify the output, commitment, and encrypted amount.
if (&Output { if (&Output {