mirror of
https://github.com/serai-dex/serai.git
synced 2024-11-17 09:27:36 +00:00
Move RingCT code to a deciated folder
Should help keep things ordered as more RingCT code is added.
This commit is contained in:
parent
790e89902a
commit
cc65b6e055
9 changed files with 141 additions and 132 deletions
|
@ -14,8 +14,7 @@ pub mod frost;
|
||||||
|
|
||||||
mod serialize;
|
mod serialize;
|
||||||
|
|
||||||
pub mod bulletproofs;
|
pub mod ringct;
|
||||||
pub mod clsag;
|
|
||||||
|
|
||||||
pub mod transaction;
|
pub mod transaction;
|
||||||
pub mod block;
|
pub mod block;
|
||||||
|
|
|
@ -14,13 +14,13 @@ use curve25519_dalek::{
|
||||||
use group::Group;
|
use group::Group;
|
||||||
|
|
||||||
use transcript::Transcript as TranscriptTrait;
|
use transcript::Transcript as TranscriptTrait;
|
||||||
use frost::{FrostError, algorithm::Algorithm, MultisigView};
|
use frost::{FrostError, MultisigView, algorithm::Algorithm};
|
||||||
use dalek_ff_group as dfg;
|
use dalek_ff_group as dfg;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
hash_to_point,
|
hash_to_point,
|
||||||
frost::{Transcript, MultisigError, Ed25519, DLEqProof, read_dleq},
|
frost::{Transcript, MultisigError, Ed25519, DLEqProof, read_dleq},
|
||||||
clsag::{ClsagInput, Clsag}
|
ringct::clsag::{ClsagInput, Clsag}
|
||||||
};
|
};
|
||||||
|
|
||||||
impl ClsagInput {
|
impl ClsagInput {
|
126
coins/monero/src/ringct/mod.rs
Normal file
126
coins/monero/src/ringct/mod.rs
Normal file
|
@ -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<EdwardsPoint>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RctBase {
|
||||||
|
pub fn serialize<W: std::io::Write>(&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<R: std::io::Read>(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::<Result<_, _>>()?,
|
||||||
|
commitments: read_raw_vec(read_point, outputs, r)?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rct_type[0]
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum RctPrunable {
|
||||||
|
Null,
|
||||||
|
Clsag {
|
||||||
|
bulletproofs: Vec<Bulletproofs>,
|
||||||
|
clsags: Vec<Clsag>,
|
||||||
|
pseudo_outs: Vec<EdwardsPoint>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RctPrunable {
|
||||||
|
pub fn rct_type(&self) -> u8 {
|
||||||
|
match self {
|
||||||
|
RctPrunable::Null => 0,
|
||||||
|
RctPrunable::Clsag { .. } => 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn serialize<W: std::io::Write>(&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<R: std::io::Read>(
|
||||||
|
rct_type: u8,
|
||||||
|
decoys: &[usize],
|
||||||
|
r: &mut R
|
||||||
|
) -> std::io::Result<RctPrunable> {
|
||||||
|
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::<Result<_, _>>()?,
|
||||||
|
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<W: std::io::Write>(&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<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||||
|
self.base.serialize(w, self.prunable.rct_type())?;
|
||||||
|
self.prunable.serialize(w)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<R: std::io::Read>(decoys: Vec<usize>, outputs: usize, r: &mut R) -> std::io::Result<RctSignatures> {
|
||||||
|
let base = RctBase::deserialize(outputs, r)?;
|
||||||
|
Ok(RctSignatures { base: base.0, prunable: RctPrunable::deserialize(base.1, &decoys, r)? })
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,10 +9,10 @@ use crate::{
|
||||||
Commitment,
|
Commitment,
|
||||||
random_scalar, generate_key_image,
|
random_scalar, generate_key_image,
|
||||||
wallet::Decoys,
|
wallet::Decoys,
|
||||||
clsag::{ClsagInput, Clsag}
|
ringct::clsag::{ClsagInput, Clsag}
|
||||||
};
|
};
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use crate::{frost::{MultisigError, Transcript}, clsag::{ClsagDetails, ClsagMultisig}};
|
use crate::{frost::{MultisigError, Transcript}, ringct::clsag::{ClsagDetails, ClsagMultisig}};
|
||||||
|
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
use crate::tests::frost::{THRESHOLD, generate_keys, sign};
|
use crate::tests::frost::{THRESHOLD, generate_keys, sign};
|
||||||
|
|
|
@ -1,10 +1,6 @@
|
||||||
use curve25519_dalek::edwards::EdwardsPoint;
|
use curve25519_dalek::edwards::EdwardsPoint;
|
||||||
|
|
||||||
use crate::{
|
use crate::{hash, serialize::*, ringct::{RctPrunable, RctSignatures}};
|
||||||
hash,
|
|
||||||
serialize::*,
|
|
||||||
bulletproofs::Bulletproofs, clsag::Clsag,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum Input {
|
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<EdwardsPoint>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RctBase {
|
|
||||||
pub fn serialize<W: std::io::Write>(&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<R: std::io::Read>(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::<Result<_, _>>()?,
|
|
||||||
commitments: read_raw_vec(read_point, outputs, r)?
|
|
||||||
}
|
|
||||||
},
|
|
||||||
rct_type[0]
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub enum RctPrunable {
|
|
||||||
Null,
|
|
||||||
Clsag {
|
|
||||||
bulletproofs: Vec<Bulletproofs>,
|
|
||||||
clsags: Vec<Clsag>,
|
|
||||||
pseudo_outs: Vec<EdwardsPoint>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RctPrunable {
|
|
||||||
pub fn rct_type(&self) -> u8 {
|
|
||||||
match self {
|
|
||||||
RctPrunable::Null => 0,
|
|
||||||
RctPrunable::Clsag { .. } => 5
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn serialize<W: std::io::Write>(&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<R: std::io::Read>(
|
|
||||||
rct_type: u8,
|
|
||||||
decoys: &[usize],
|
|
||||||
r: &mut R
|
|
||||||
) -> std::io::Result<RctPrunable> {
|
|
||||||
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::<Result<_, _>>()?,
|
|
||||||
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<W: std::io::Write>(&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<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
|
||||||
self.base.serialize(w, self.prunable.rct_type())?;
|
|
||||||
self.prunable.serialize(w)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deserialize<R: std::io::Read>(decoys: Vec<usize>, outputs: usize, r: &mut R) -> std::io::Result<RctSignatures> {
|
|
||||||
let base = RctBase::deserialize(outputs, r)?;
|
|
||||||
Ok(RctSignatures { base: base.0, prunable: RctPrunable::deserialize(base.1, &decoys, r)? })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Transaction {
|
pub struct Transaction {
|
||||||
pub prefix: TransactionPrefix,
|
pub prefix: TransactionPrefix,
|
||||||
|
|
|
@ -21,9 +21,14 @@ use frost::FrostError;
|
||||||
use crate::{
|
use crate::{
|
||||||
Commitment,
|
Commitment,
|
||||||
random_scalar,
|
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},
|
rpc::{Rpc, RpcError},
|
||||||
transaction::*,
|
|
||||||
wallet::{SpendableOutput, Decoys, key_image_sort, uniqueness, shared_key, commitment_mask, amount_encryption}
|
wallet::{SpendableOutput, Decoys, key_image_sort, uniqueness, shared_key, commitment_mask, amount_encryption}
|
||||||
};
|
};
|
||||||
#[cfg(feature = "multisig")]
|
#[cfg(feature = "multisig")]
|
||||||
|
|
|
@ -10,9 +10,9 @@ use frost::{FrostError, MultisigKeys, MultisigParams, sign::{State, StateMachine
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
frost::{Transcript, Ed25519},
|
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,
|
rpc::Rpc,
|
||||||
transaction::{Input, RctPrunable, Transaction},
|
|
||||||
wallet::{TransactionError, SignableTransaction, Decoys, key_image_sort, uniqueness}
|
wallet::{TransactionError, SignableTransaction, Decoys, key_image_sort, uniqueness}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue