mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-11 05:29:25 +00:00
Standardize serialization within the Monero lib
read for R: Read
write for W: Write
serialize for -> Vec<u8>
Also uses std::io::{self, Read, Write} consistently.
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use rand_core::{RngCore, CryptoRng};
|
||||
|
||||
use zeroize::Zeroize;
|
||||
@@ -93,11 +95,11 @@ impl Bulletproofs {
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_core<W: std::io::Write, F: Fn(&[EdwardsPoint], &mut W) -> std::io::Result<()>>(
|
||||
fn write_core<W: Write, F: Fn(&[EdwardsPoint], &mut W) -> io::Result<()>>(
|
||||
&self,
|
||||
w: &mut W,
|
||||
specific_write_vec: F,
|
||||
) -> std::io::Result<()> {
|
||||
) -> io::Result<()> {
|
||||
match self {
|
||||
Bulletproofs::Original(bp) => {
|
||||
write_point(&bp.A, w)?;
|
||||
@@ -126,16 +128,22 @@ impl Bulletproofs {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn signature_serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
self.serialize_core(w, |points, w| write_raw_vec(write_point, points, w))
|
||||
pub(crate) fn signature_write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
self.write_core(w, |points, w| write_raw_vec(write_point, points, w))
|
||||
}
|
||||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
self.serialize_core(w, |points, w| write_vec(write_point, points, w))
|
||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
self.write_core(w, |points, w| write_vec(write_point, points, w))
|
||||
}
|
||||
|
||||
/// Deserialize non-plus Bulletproofs.
|
||||
pub fn deserialize<R: std::io::Read>(r: &mut R) -> std::io::Result<Bulletproofs> {
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let mut serialized = vec![];
|
||||
self.write(&mut serialized).unwrap();
|
||||
serialized
|
||||
}
|
||||
|
||||
/// Read Bulletproofs.
|
||||
pub fn read<R: Read>(r: &mut R) -> io::Result<Bulletproofs> {
|
||||
Ok(Bulletproofs::Original(OriginalStruct {
|
||||
A: read_point(r)?,
|
||||
S: read_point(r)?,
|
||||
@@ -151,8 +159,8 @@ impl Bulletproofs {
|
||||
}))
|
||||
}
|
||||
|
||||
/// Deserialize Bulletproofs+.
|
||||
pub fn deserialize_plus<R: std::io::Read>(r: &mut R) -> std::io::Result<Bulletproofs> {
|
||||
/// Read Bulletproofs+.
|
||||
pub fn read_plus<R: Read>(r: &mut R) -> io::Result<Bulletproofs> {
|
||||
Ok(Bulletproofs::Plus(PlusStruct {
|
||||
A: read_point(r)?,
|
||||
A1: read_point(r)?,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use core::ops::Deref;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use thiserror::Error;
|
||||
@@ -313,13 +314,13 @@ impl Clsag {
|
||||
(ring_len * 32) + 32 + 32
|
||||
}
|
||||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
pub fn write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
write_raw_vec(write_scalar, &self.s, w)?;
|
||||
w.write_all(&self.c1.to_bytes())?;
|
||||
write_point(&self.D, w)
|
||||
}
|
||||
|
||||
pub fn deserialize<R: std::io::Read>(decoys: usize, r: &mut R) -> std::io::Result<Clsag> {
|
||||
pub fn read<R: Read>(decoys: usize, r: &mut R) -> io::Result<Clsag> {
|
||||
Ok(Clsag { s: read_raw_vec(read_scalar, decoys, r)?, c1: read_scalar(r)?, D: read_point(r)? })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,18 +41,17 @@ impl ClsagInput {
|
||||
// Doesn't domain separate as this is considered part of the larger CLSAG proof
|
||||
|
||||
// Ring index
|
||||
transcript.append_message(b"ring_index", [self.decoys.i]);
|
||||
transcript.append_message(b"real_spend", [self.decoys.i]);
|
||||
|
||||
// Ring
|
||||
let mut ring = vec![];
|
||||
for pair in &self.decoys.ring {
|
||||
for (i, pair) in self.decoys.ring.iter().enumerate() {
|
||||
// Doesn't include global output indexes as CLSAG doesn't care and won't be affected by it
|
||||
// They're just a unreliable reference to this data which will be included in the message
|
||||
// if in use
|
||||
ring.extend(pair[0].compress().to_bytes());
|
||||
ring.extend(pair[1].compress().to_bytes());
|
||||
transcript.append_message(b"member", [u8::try_from(i).expect("ring size exceeded 255")]);
|
||||
transcript.append_message(b"key", pair[0].compress().to_bytes());
|
||||
transcript.append_message(b"commitment", pair[1].compress().to_bytes())
|
||||
}
|
||||
transcript.append_message(b"ring", ring);
|
||||
|
||||
// Doesn't include the commitment's parts as the above ring + index includes the commitment
|
||||
// The only potential malleability would be if the G/H relationship is known breaking the
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use core::ops::Deref;
|
||||
use std::io::{self, Read, Write};
|
||||
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
@@ -35,7 +36,7 @@ impl RctBase {
|
||||
1 + 8 + (outputs * (8 + 32))
|
||||
}
|
||||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W, rct_type: u8) -> std::io::Result<()> {
|
||||
pub fn write<W: Write>(&self, w: &mut W, rct_type: u8) -> io::Result<()> {
|
||||
w.write_all(&[rct_type])?;
|
||||
match rct_type {
|
||||
0 => Ok(()),
|
||||
@@ -50,10 +51,7 @@ impl RctBase {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize<R: std::io::Read>(
|
||||
outputs: usize,
|
||||
r: &mut R,
|
||||
) -> std::io::Result<(RctBase, u8)> {
|
||||
pub fn read<R: Read>(outputs: usize, r: &mut R) -> io::Result<(RctBase, u8)> {
|
||||
let rct_type = read_byte(r)?;
|
||||
Ok((
|
||||
if rct_type == 0 {
|
||||
@@ -96,46 +94,43 @@ impl RctPrunable {
|
||||
(inputs * (Clsag::fee_weight(protocol.ring_len()) + 32))
|
||||
}
|
||||
|
||||
pub fn serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
pub fn write<W: Write>(&self, w: &mut W) -> 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_vec(Bulletproofs::write, bulletproofs, w)?;
|
||||
write_raw_vec(Clsag::write, 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> {
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let mut serialized = vec![];
|
||||
self.write(&mut serialized).unwrap();
|
||||
serialized
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(rct_type: u8, decoys: &[usize], r: &mut R) -> io::Result<RctPrunable> {
|
||||
Ok(match rct_type {
|
||||
0 => RctPrunable::Null,
|
||||
5 | 6 => RctPrunable::Clsag {
|
||||
bulletproofs: read_vec(
|
||||
if rct_type == 5 { Bulletproofs::deserialize } else { Bulletproofs::deserialize_plus },
|
||||
if rct_type == 5 { Bulletproofs::read } else { Bulletproofs::read_plus },
|
||||
r,
|
||||
)?,
|
||||
clsags: (0 .. decoys.len())
|
||||
.map(|o| Clsag::deserialize(decoys[o], r))
|
||||
.collect::<Result<_, _>>()?,
|
||||
clsags: (0 .. decoys.len()).map(|o| Clsag::read(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",
|
||||
))?,
|
||||
_ => Err(io::Error::new(io::ErrorKind::Other, "Tried to deserialize unknown RCT type"))?,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn signature_serialize<W: std::io::Write>(&self, w: &mut W) -> std::io::Result<()> {
|
||||
pub(crate) fn signature_write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
match self {
|
||||
RctPrunable::Null => panic!("Serializing RctPrunable::Null for a signature"),
|
||||
RctPrunable::Clsag { bulletproofs, .. } => {
|
||||
bulletproofs.iter().try_for_each(|bp| bp.signature_serialize(w))
|
||||
bulletproofs.iter().try_for_each(|bp| bp.signature_write(w))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -152,17 +147,19 @@ impl RctSignatures {
|
||||
RctBase::fee_weight(outputs) + RctPrunable::fee_weight(protocol, inputs, outputs)
|
||||
}
|
||||
|
||||
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 write<W: Write>(&self, w: &mut W) -> io::Result<()> {
|
||||
self.base.write(w, self.prunable.rct_type())?;
|
||||
self.prunable.write(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)? })
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
let mut serialized = vec![];
|
||||
self.write(&mut serialized).unwrap();
|
||||
serialized
|
||||
}
|
||||
|
||||
pub fn read<R: Read>(decoys: Vec<usize>, outputs: usize, r: &mut R) -> io::Result<RctSignatures> {
|
||||
let base = RctBase::read(outputs, r)?;
|
||||
Ok(RctSignatures { base: base.0, prunable: RctPrunable::read(base.1, &decoys, r)? })
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user