Skip to content

Commit

Permalink
Merge pull request #39 from dusk-network/to_from_bytes
Browse files Browse the repository at this point in the history
Add to/from bytes impls for Fee & Crossover
  • Loading branch information
CPerezz authored Dec 4, 2020
2 parents 7552aad + de7492c commit b70873a
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 5 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## [0.5.0] - 27-11-20
### Added
- To/From bytes impl for `Fee` & `Crossover`.

## [0.5.0-alpha] - 27-11-20
### Changed
- No-Std compatibility.
Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
[package]
name = "phoenix-core"
version = "0.5.0-alpha"
version = "0.5.0"
authors = ["zer0 <matteo@dusk.network>", "Victor Lopez <victor@dusk.network"]
edition = "2018"

[dependencies]
rand_core = "0.5.1"
dusk-bls12_381 = {version = "0.3", default-features = false}
dusk-jubjub = {version = "0.5", default-features = false}
poseidon252 = {git = "https://github.com/dusk-network/Poseidon252", tag = "v0.14.1", default-features = false}
poseidon252 = {git = "https://github.com/dusk-network/Poseidon252", tag = "v0.15.0", default-features = false}
dusk-pki = {git = "https://github.com/dusk-network/dusk-pki", tag = "v0.4.1", default-features = false}
canonical = {version = "0.4", optional = true}
canonical_derive = {version = "0.4", optional = true}
Expand Down
65 changes: 64 additions & 1 deletion src/crossover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@

//! Fee module contains the logic related to `Crossover` structure

use crate::{BlsScalar, JubJubExtended, JubJubScalar};
use crate::{BlsScalar, Error, JubJubExtended, JubJubScalar};

#[cfg(feature = "canon")]
use canonical::Canon;
#[cfg(feature = "canon")]
use canonical_derive::Canon;

use dusk_jubjub::JubJubAffine;
use dusk_pki::jubjub_decode;
use poseidon252::cipher::PoseidonCipher;
use poseidon252::sponge::hash;

Expand All @@ -34,6 +36,11 @@ impl PartialEq for Crossover {
impl Eq for Crossover {}

impl Crossover {
/// Returns the serialized size of the Crossover
pub const fn serialized_size() -> usize {
32 * 2 + PoseidonCipher::cipher_size_bytes()
}

/// Returns a hash represented by `H(value_commitment)`
pub fn hash(&self) -> BlsScalar {
let value_commitment = self.value_commitment().to_hash_inputs();
Expand All @@ -55,4 +62,60 @@ impl Crossover {
pub fn encrypted_data(&self) -> &PoseidonCipher {
&self.encrypted_data
}

/// Converts a Crossover into it's byte representation
pub fn to_bytes(&self) -> [u8; Crossover::serialized_size()] {
let mut buf = [0u8; Crossover::serialized_size()];
let mut n = 0;

buf[n..n + 32].copy_from_slice(
&JubJubAffine::from(&self.value_commitment).to_bytes()[..],
);
n += 32;

buf[n..n + 32].copy_from_slice(&self.nonce.to_bytes()[..]);
n += 32;

buf[n..n + PoseidonCipher::cipher_size_bytes()]
.copy_from_slice(&self.encrypted_data.to_bytes()[..]);
n += PoseidonCipher::cipher_size_bytes();

debug_assert_eq!(n, Crossover::serialized_size());

buf
}

/// Attempts to convert a byte representation of a note into a `Note`,
/// failing if the input is invalid
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
if bytes.len() < Crossover::serialized_size() {
return Err(Error::InvalidCrossoverConversion);
}

let mut bytes_32 = [0u8; 32];
let mut one_cipher = [0u8; PoseidonCipher::cipher_size_bytes()];

let mut n = 0;

bytes_32.copy_from_slice(&bytes[n..n + 32]);
let value_commitment =
JubJubExtended::from(jubjub_decode::<JubJubAffine>(&bytes_32)?);
n += 32;

bytes_32.copy_from_slice(&bytes[n..n + 32]);
let nonce = jubjub_decode::<JubJubScalar>(&bytes_32)?;
n += 32;

one_cipher.copy_from_slice(
&bytes[n..n + PoseidonCipher::cipher_size_bytes()],
);
let encrypted_data = PoseidonCipher::from_bytes(&one_cipher)
.ok_or(Error::InvalidCipher)?;

Ok(Crossover {
value_commitment,
nonce,
encrypted_data,
})
}
}
4 changes: 4 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ pub enum Error {
MissingViewKey,
/// Invalid Note Type for conversion
InvalidNoteConversion,
/// Invalid Crossover for conversion
InvalidCrossoverConversion,
/// Invalid Fee for conversion
InvalidFeeConversion,
/// Dusk-Pki Error
PKIError(PkiError),
/// Poseidon Error
Expand Down
59 changes: 58 additions & 1 deletion src/fee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use canonical_derive::Canon;

use core::cmp;

use crate::{BlsScalar, JubJubScalar};
use crate::{BlsScalar, Error, JubJubScalar};

mod remainder;
pub use remainder::Remainder;
Expand All @@ -42,6 +42,11 @@ impl PartialEq for Fee {
impl Eq for Fee {}

impl Fee {
/// Returns the serialized size of the Fee.
pub const fn serialized_size() -> usize {
8 * 2 + 64
}

/// Create a new Fee with inner randomness
pub fn new<R: RngCore + CryptoRng>(
rng: &mut R,
Expand Down Expand Up @@ -97,6 +102,58 @@ impl Fee {
stealth_address: self.stealth_address,
}
}

/// Converts a Fee into it's byte representation
pub fn to_bytes(&self) -> [u8; Fee::serialized_size()] {
let mut buf = [0u8; Fee::serialized_size()];
let mut n = 0;

buf[n..n + 8].copy_from_slice(&self.gas_limit.to_le_bytes()[..]);
n += 8;

buf[n..n + 8].copy_from_slice(&self.gas_price.to_le_bytes()[..]);
n += 8;

buf[n..n + 64].copy_from_slice(&self.stealth_address.to_bytes()[..]);
n += 64;

debug_assert_eq!(n, Fee::serialized_size());

buf
}

/// Attempts to convert a byte representation of a note into a `Note`,
/// failing if the input is invalid
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
if bytes.len() < Fee::serialized_size() {
return Err(Error::InvalidFeeConversion);
}

let mut one_u64 = [0u8; 8];
let mut one_stealth_addr = [0u8; 64];

let mut n = 0;

one_u64.copy_from_slice(&bytes[n..n + 8]);
let gas_limit = u64::from_le_bytes(one_u64);
n += 8;

one_u64.copy_from_slice(&bytes[n..n + 8]);
let gas_price = u64::from_le_bytes(one_u64);
n += 8;

one_stealth_addr.copy_from_slice(&bytes[n..n + 64]);
let stealth_address = StealthAddress::from_bytes(&one_stealth_addr)?;
n += 64;

debug_assert_eq!(n, Fee::serialized_size());

Ok(Fee {
gas_limit,
gas_price,
stealth_address,
})
}
}

impl Ownable for Fee {
Expand Down
2 changes: 1 addition & 1 deletion src/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ impl Note {
.copy_from_slice(&self.encrypted_data.to_bytes()[..]);
n += PoseidonCipher::cipher_size_bytes();

assert_eq!(n, Note::serialized_size());
debug_assert_eq!(n, Note::serialized_size());

buf
}
Expand Down

0 comments on commit b70873a

Please sign in to comment.