From cc65b6e05543c1ea52cfe78e419181a6f3c2efcf Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Sun, 22 May 2022 02:24:24 -0400 Subject: [PATCH] Move RingCT code to a deciated folder Should help keep things ordered as more RingCT code is added. --- coins/monero/src/lib.rs | 3 +- coins/monero/src/{ => ringct}/bulletproofs.rs | 0 coins/monero/src/{ => ringct}/clsag/mod.rs | 0 .../monero/src/{ => ringct}/clsag/multisig.rs | 4 +- coins/monero/src/ringct/mod.rs | 126 ++++++++++++++++++ coins/monero/src/tests/clsag.rs | 4 +- coins/monero/src/transaction.rs | 123 +---------------- coins/monero/src/wallet/send/mod.rs | 9 +- coins/monero/src/wallet/send/multisig.rs | 4 +- 9 files changed, 141 insertions(+), 132 deletions(-) rename coins/monero/src/{ => ringct}/bulletproofs.rs (100%) rename coins/monero/src/{ => ringct}/clsag/mod.rs (100%) rename coins/monero/src/{ => ringct}/clsag/multisig.rs (98%) create mode 100644 coins/monero/src/ringct/mod.rs diff --git a/coins/monero/src/lib.rs b/coins/monero/src/lib.rs index 7534a3db..7425282d 100644 --- a/coins/monero/src/lib.rs +++ b/coins/monero/src/lib.rs @@ -14,8 +14,7 @@ pub mod frost; mod serialize; -pub mod bulletproofs; -pub mod clsag; +pub mod ringct; pub mod transaction; pub mod block; diff --git a/coins/monero/src/bulletproofs.rs b/coins/monero/src/ringct/bulletproofs.rs similarity index 100% rename from coins/monero/src/bulletproofs.rs rename to coins/monero/src/ringct/bulletproofs.rs diff --git a/coins/monero/src/clsag/mod.rs b/coins/monero/src/ringct/clsag/mod.rs similarity index 100% rename from coins/monero/src/clsag/mod.rs rename to coins/monero/src/ringct/clsag/mod.rs diff --git a/coins/monero/src/clsag/multisig.rs b/coins/monero/src/ringct/clsag/multisig.rs similarity index 98% rename from coins/monero/src/clsag/multisig.rs rename to coins/monero/src/ringct/clsag/multisig.rs index 12ed839d..ac0e49d4 100644 --- a/coins/monero/src/clsag/multisig.rs +++ b/coins/monero/src/ringct/clsag/multisig.rs @@ -14,13 +14,13 @@ use curve25519_dalek::{ use group::Group; use transcript::Transcript as TranscriptTrait; -use frost::{FrostError, algorithm::Algorithm, MultisigView}; +use frost::{FrostError, MultisigView, algorithm::Algorithm}; use dalek_ff_group as dfg; use crate::{ hash_to_point, frost::{Transcript, MultisigError, Ed25519, DLEqProof, read_dleq}, - clsag::{ClsagInput, Clsag} + ringct::clsag::{ClsagInput, Clsag} }; impl ClsagInput { diff --git a/coins/monero/src/ringct/mod.rs b/coins/monero/src/ringct/mod.rs new file mode 100644 index 00000000..e013e415 --- /dev/null +++ b/coins/monero/src/ringct/mod.rs @@ -0,0 +1,126 @@ +use curve25519_dalek::edwards::EdwardsPoint; + +pub mod bulletproofs; +pub mod clsag; + +use crate::{ + serialize::*, + ringct::{clsag::Clsag, bulletproofs::Bulletproofs} +}; + +#[derive(Clone, Debug)] +pub struct RctBase { + pub fee: u64, + pub ecdh_info: Vec<[u8; 8]>, + pub commitments: Vec +} + +impl RctBase { + pub fn serialize(&self, w: &mut W, rct_type: u8) -> std::io::Result<()> { + w.write_all(&[rct_type])?; + match rct_type { + 0 => Ok(()), + 5 => { + write_varint(&self.fee, w)?; + for ecdh in &self.ecdh_info { + w.write_all(ecdh)?; + } + write_raw_vec(write_point, &self.commitments, w) + }, + _ => panic!("Serializing unknown RctType's Base") + } + } + + pub fn deserialize(outputs: usize, r: &mut R) -> std::io::Result<(RctBase, u8)> { + let mut rct_type = [0]; + r.read_exact(&mut rct_type)?; + Ok(( + if rct_type[0] == 0 { + RctBase { fee: 0, ecdh_info: vec![], commitments: vec![] } + } else { + RctBase { + fee: read_varint(r)?, + ecdh_info: (0 .. outputs).map( + |_| { let mut ecdh = [0; 8]; r.read_exact(&mut ecdh).map(|_| ecdh) } + ).collect::>()?, + commitments: read_raw_vec(read_point, outputs, r)? + } + }, + rct_type[0] + )) + } +} + +#[derive(Clone, Debug)] +pub enum RctPrunable { + Null, + Clsag { + bulletproofs: Vec, + clsags: Vec, + pseudo_outs: Vec + } +} + +impl RctPrunable { + pub fn rct_type(&self) -> u8 { + match self { + RctPrunable::Null => 0, + RctPrunable::Clsag { .. } => 5 + } + } + + pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + match self { + RctPrunable::Null => Ok(()), + RctPrunable::Clsag { bulletproofs, clsags, pseudo_outs } => { + write_vec(Bulletproofs::serialize, &bulletproofs, w)?; + write_raw_vec(Clsag::serialize, &clsags, w)?; + write_raw_vec(write_point, &pseudo_outs, w) + } + } + } + + pub fn deserialize( + rct_type: u8, + decoys: &[usize], + r: &mut R + ) -> std::io::Result { + Ok( + match rct_type { + 0 => RctPrunable::Null, + 5 => RctPrunable::Clsag { + // TODO: Can the amount of outputs be calculated from the BPs for any validly formed TX? + bulletproofs: read_vec(Bulletproofs::deserialize, r)?, + clsags: (0 .. decoys.len()).map(|o| Clsag::deserialize(decoys[o], r)).collect::>()?, + pseudo_outs: read_raw_vec(read_point, decoys.len(), r)? + }, + _ => Err(std::io::Error::new(std::io::ErrorKind::Other, "Tried to deserialize unknown RCT type"))? + } + ) + } + + pub fn signature_serialize(&self, w: &mut W) -> std::io::Result<()> { + match self { + RctPrunable::Null => panic!("Serializing RctPrunable::Null for a signature"), + RctPrunable::Clsag { bulletproofs, .. } => bulletproofs.iter().map(|bp| bp.signature_serialize(w)).collect(), + } + } +} + +#[derive(Clone, Debug)] +pub struct RctSignatures { + pub base: RctBase, + pub prunable: RctPrunable +} + +impl RctSignatures { + pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { + self.base.serialize(w, self.prunable.rct_type())?; + self.prunable.serialize(w) + } + + pub fn deserialize(decoys: Vec, outputs: usize, r: &mut R) -> std::io::Result { + let base = RctBase::deserialize(outputs, r)?; + Ok(RctSignatures { base: base.0, prunable: RctPrunable::deserialize(base.1, &decoys, r)? }) + } +} diff --git a/coins/monero/src/tests/clsag.rs b/coins/monero/src/tests/clsag.rs index 78cead76..6fbab695 100644 --- a/coins/monero/src/tests/clsag.rs +++ b/coins/monero/src/tests/clsag.rs @@ -9,10 +9,10 @@ use crate::{ Commitment, random_scalar, generate_key_image, wallet::Decoys, - clsag::{ClsagInput, Clsag} + ringct::clsag::{ClsagInput, Clsag} }; #[cfg(feature = "multisig")] -use crate::{frost::{MultisigError, Transcript}, clsag::{ClsagDetails, ClsagMultisig}}; +use crate::{frost::{MultisigError, Transcript}, ringct::clsag::{ClsagDetails, ClsagMultisig}}; #[cfg(feature = "multisig")] use crate::tests::frost::{THRESHOLD, generate_keys, sign}; diff --git a/coins/monero/src/transaction.rs b/coins/monero/src/transaction.rs index baa9c6e1..5c90ae34 100644 --- a/coins/monero/src/transaction.rs +++ b/coins/monero/src/transaction.rs @@ -1,10 +1,6 @@ use curve25519_dalek::edwards::EdwardsPoint; -use crate::{ - hash, - serialize::*, - bulletproofs::Bulletproofs, clsag::Clsag, -}; +use crate::{hash, serialize::*, ringct::{RctPrunable, RctSignatures}}; #[derive(Clone, Debug)] pub enum Input { @@ -124,123 +120,6 @@ impl TransactionPrefix { } } -#[derive(Clone, Debug)] -pub struct RctBase { - pub fee: u64, - pub ecdh_info: Vec<[u8; 8]>, - pub commitments: Vec -} - -impl RctBase { - pub fn serialize(&self, w: &mut W, rct_type: u8) -> std::io::Result<()> { - w.write_all(&[rct_type])?; - match rct_type { - 0 => Ok(()), - 5 => { - write_varint(&self.fee, w)?; - for ecdh in &self.ecdh_info { - w.write_all(ecdh)?; - } - write_raw_vec(write_point, &self.commitments, w) - }, - _ => panic!("Serializing unknown RctType's Base") - } - } - - pub fn deserialize(outputs: usize, r: &mut R) -> std::io::Result<(RctBase, u8)> { - let mut rct_type = [0]; - r.read_exact(&mut rct_type)?; - Ok(( - if rct_type[0] == 0 { - RctBase { fee: 0, ecdh_info: vec![], commitments: vec![] } - } else { - RctBase { - fee: read_varint(r)?, - ecdh_info: (0 .. outputs).map( - |_| { let mut ecdh = [0; 8]; r.read_exact(&mut ecdh).map(|_| ecdh) } - ).collect::>()?, - commitments: read_raw_vec(read_point, outputs, r)? - } - }, - rct_type[0] - )) - } -} - -#[derive(Clone, Debug)] -pub enum RctPrunable { - Null, - Clsag { - bulletproofs: Vec, - clsags: Vec, - pseudo_outs: Vec - } -} - -impl RctPrunable { - pub fn rct_type(&self) -> u8 { - match self { - RctPrunable::Null => 0, - RctPrunable::Clsag { .. } => 5 - } - } - - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { - match self { - RctPrunable::Null => Ok(()), - RctPrunable::Clsag { bulletproofs, clsags, pseudo_outs } => { - write_vec(Bulletproofs::serialize, &bulletproofs, w)?; - write_raw_vec(Clsag::serialize, &clsags, w)?; - write_raw_vec(write_point, &pseudo_outs, w) - } - } - } - - pub fn deserialize( - rct_type: u8, - decoys: &[usize], - r: &mut R - ) -> std::io::Result { - Ok( - match rct_type { - 0 => RctPrunable::Null, - 5 => RctPrunable::Clsag { - // TODO: Can the amount of outputs be calculated from the BPs for any validly formed TX? - bulletproofs: read_vec(Bulletproofs::deserialize, r)?, - clsags: (0 .. decoys.len()).map(|o| Clsag::deserialize(decoys[o], r)).collect::>()?, - pseudo_outs: read_raw_vec(read_point, decoys.len(), r)? - }, - _ => Err(std::io::Error::new(std::io::ErrorKind::Other, "Tried to deserialize unknown RCT type"))? - } - ) - } - - pub fn signature_serialize(&self, w: &mut W) -> std::io::Result<()> { - match self { - RctPrunable::Null => panic!("Serializing RctPrunable::Null for a signature"), - RctPrunable::Clsag { bulletproofs, .. } => bulletproofs.iter().map(|bp| bp.signature_serialize(w)).collect(), - } - } -} - -#[derive(Clone, Debug)] -pub struct RctSignatures { - pub base: RctBase, - pub prunable: RctPrunable -} - -impl RctSignatures { - pub fn serialize(&self, w: &mut W) -> std::io::Result<()> { - self.base.serialize(w, self.prunable.rct_type())?; - self.prunable.serialize(w) - } - - pub fn deserialize(decoys: Vec, outputs: usize, r: &mut R) -> std::io::Result { - let base = RctBase::deserialize(outputs, r)?; - Ok(RctSignatures { base: base.0, prunable: RctPrunable::deserialize(base.1, &decoys, r)? }) - } -} - #[derive(Clone, Debug)] pub struct Transaction { pub prefix: TransactionPrefix, diff --git a/coins/monero/src/wallet/send/mod.rs b/coins/monero/src/wallet/send/mod.rs index bddb7117..9d3a31c3 100644 --- a/coins/monero/src/wallet/send/mod.rs +++ b/coins/monero/src/wallet/send/mod.rs @@ -21,9 +21,14 @@ use frost::FrostError; use crate::{ Commitment, random_scalar, - generate_key_image, bulletproofs::Bulletproofs, clsag::{ClsagError, ClsagInput, Clsag}, + generate_key_image, + ringct::{ + clsag::{ClsagError, ClsagInput, Clsag}, + bulletproofs::Bulletproofs, + RctBase, RctPrunable, RctSignatures + }, + transaction::{Input, Output, TransactionPrefix, Transaction}, rpc::{Rpc, RpcError}, - transaction::*, wallet::{SpendableOutput, Decoys, key_image_sort, uniqueness, shared_key, commitment_mask, amount_encryption} }; #[cfg(feature = "multisig")] diff --git a/coins/monero/src/wallet/send/multisig.rs b/coins/monero/src/wallet/send/multisig.rs index 6e2d57f3..16fb7c5c 100644 --- a/coins/monero/src/wallet/send/multisig.rs +++ b/coins/monero/src/wallet/send/multisig.rs @@ -10,9 +10,9 @@ use frost::{FrostError, MultisigKeys, MultisigParams, sign::{State, StateMachine use crate::{ frost::{Transcript, Ed25519}, - random_scalar, bulletproofs::Bulletproofs, clsag::{ClsagInput, ClsagDetails, ClsagMultisig}, + random_scalar, ringct::{clsag::{ClsagInput, ClsagDetails, ClsagMultisig}, bulletproofs::Bulletproofs, RctPrunable}, + transaction::{Input, Transaction}, rpc::Rpc, - transaction::{Input, RctPrunable, Transaction}, wallet::{TransactionError, SignableTransaction, Decoys, key_image_sort, uniqueness} };