From 8a7842099ab0fd11e18db48bca35e3253e430221 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Wed, 4 Nov 2020 13:41:21 +0100 Subject: [PATCH 1/5] PoseidonLeaf tree setter A setter for the position of the poseidon leaf is consistent with the phoenix API. Besides, a mutable reference to a u64 doesn't make sense since a pointer consume the same resources as a u64 --- README.md | 4 ++-- src/tree/mod.rs | 4 ++-- src/tree/tests.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e970755..bc6552c 100644 --- a/README.md +++ b/README.md @@ -112,8 +112,8 @@ impl PoseidonLeaf for DataLeaf { } // Method used to set the position on the tree after the `PoseidonTree::push` call - fn tree_pos_mut(&mut self) -> &mut u64 { - &mut self.pos + fn tree_pos_set(&mut self, pos: u64) { + self.pos = pos; } } diff --git a/src/tree/mod.rs b/src/tree/mod.rs index ee26a12..27008ba 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -47,7 +47,7 @@ where /// /// This method is internally used to set the index after the data has been inserted in the /// merkle tree. - fn tree_pos_mut(&mut self) -> &mut u64; + fn tree_pos_set(&mut self, pos: u64); } /// Represents a Merkle Tree with a given depth that will be calculated using poseidon hash @@ -117,7 +117,7 @@ where .sum(), }; - *leaf.tree_pos_mut() = size as u64; + leaf.tree_pos_set(size as u64); self.inner .push(leaf) .map_err(|e| anyhow!("Error pushing to the tree: {:?}", e))?; diff --git a/src/tree/tests.rs b/src/tree/tests.rs index 03250b2..ab232ba 100644 --- a/src/tree/tests.rs +++ b/src/tree/tests.rs @@ -43,8 +43,8 @@ impl PoseidonLeaf for MockLeaf { self.pos } - fn tree_pos_mut(&mut self) -> &mut u64 { - &mut self.pos + fn tree_pos_set(&mut self, pos: u64) { + self.pos = pos; } } From c4f5688163be71635c0f493e35952bbd7efbd05d Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Wed, 4 Nov 2020 13:47:25 +0100 Subject: [PATCH 2/5] PoseidonCipher - Removal of io::{Read, Write} Standard io read and write implementations for poseidon cipher are obsolete since the serialization will be fully handled by canon instead --- src/cipher/cipher.rs | 53 +------------------------------------------- src/cipher/mod.rs | 3 --- src/cipher/tests.rs | 29 +----------------------- 3 files changed, 2 insertions(+), 83 deletions(-) diff --git a/src/cipher/cipher.rs b/src/cipher/cipher.rs index 2b06338..742ae7c 100644 --- a/src/cipher/cipher.rs +++ b/src/cipher/cipher.rs @@ -12,11 +12,7 @@ use dusk_plonk::jubjub::AffinePoint; use dusk_plonk::prelude::*; use hades252::{ScalarStrategy, Strategy, WIDTH}; -use super::{ - CIPHER_BYTES_SIZE, CIPHER_SIZE, ENCRYPTED_DATA_SIZE, MESSAGE_CAPACITY, -}; - -use std::io; +use super::{CIPHER_BYTES_SIZE, CIPHER_SIZE, MESSAGE_CAPACITY}; pub use super::CipherError; @@ -147,11 +143,6 @@ impl PoseidonCipher { MESSAGE_CAPACITY } - /// Bytes consumed on serialization of the poseidon cipher - pub fn serialized_size() -> usize { - ENCRYPTED_DATA_SIZE - } - /// Encrypt a slice of scalars into an internal cipher representation /// /// The message size will be truncated to [`MESSAGE_CAPACITY`] bits @@ -251,45 +242,3 @@ impl PoseidonCipher { [domain, length, ks0, ks1, nonce] } } - -impl io::Write for PoseidonCipher { - fn write(&mut self, buf: &[u8]) -> Result { - if buf.len() < ENCRYPTED_DATA_SIZE { - return Err(io::Error::from(io::ErrorKind::UnexpectedEof)); - } - - let mut bytes = [0u8; 32]; - self.cipher.iter_mut().try_fold(0usize, |mut n, x| { - n += bytes.as_mut().write(&buf[n..n + 32])?; - - // Constant time option is REALLY inflexible, so this is required - let scalar = BlsScalar::from_bytes(&bytes); - - if scalar.is_none().into() { - return Err(io::Error::from(io::ErrorKind::InvalidData)); - } - - *x = scalar.unwrap(); - - Ok(n) - }) - } - - fn flush(&mut self) -> Result<(), io::Error> { - Ok(()) - } -} - -impl io::Read for PoseidonCipher { - fn read(&mut self, buf: &mut [u8]) -> Result { - if buf.len() < ENCRYPTED_DATA_SIZE { - return Err(io::Error::from(io::ErrorKind::UnexpectedEof)); - } - - self.cipher.iter_mut().try_fold(0usize, |n, x| { - let s = (&mut x.to_bytes().as_ref()).read(&mut buf[n..n + 32])?; - - Ok(n + s) - }) - } -} diff --git a/src/cipher/mod.rs b/src/cipher/mod.rs index 8b18b67..33734c5 100644 --- a/src/cipher/mod.rs +++ b/src/cipher/mod.rs @@ -16,9 +16,6 @@ pub const CIPHER_SIZE: usize = MESSAGE_CAPACITY + 1; /// Number of bytes used by from/to bytes `PoseidonCipher` function pub const CIPHER_BYTES_SIZE: usize = CIPHER_SIZE * 32; -/// Bytes consumed on serialization of the poseidon cipher -pub const ENCRYPTED_DATA_SIZE: usize = CIPHER_SIZE * 32; - /// [`PoseidonCipher`] definition pub mod cipher; diff --git a/src/cipher/tests.rs b/src/cipher/tests.rs index 2468793..f5d92a7 100644 --- a/src/cipher/tests.rs +++ b/src/cipher/tests.rs @@ -4,15 +4,12 @@ // // Copyright (c) DUSK NETWORK. All rights reserved. -use super::{ - PoseidonCipher, CIPHER_SIZE, ENCRYPTED_DATA_SIZE, MESSAGE_CAPACITY, -}; +use super::{PoseidonCipher, CIPHER_SIZE, MESSAGE_CAPACITY}; use anyhow::Result; use dusk_plonk::jubjub::{AffinePoint, Fr, GENERATOR}; use dusk_plonk::prelude::*; use hades252::WIDTH; use rand::RngCore; -use std::io::{Read, Write}; use std::ops::Mul; fn gen() -> ([BlsScalar; MESSAGE_CAPACITY], AffinePoint, BlsScalar) { @@ -93,30 +90,6 @@ fn wrong_key_fail() { assert!(cipher.decrypt(&wrong_secret, &nonce).is_err()); } -#[test] -fn serialization() -> Result<()> { - let (message, secret, nonce) = gen(); - - let mut cipher = PoseidonCipher::encrypt(&message, &secret, &nonce); - - let mut bytes = vec![0u8; ENCRYPTED_DATA_SIZE]; - - let n = cipher.read(bytes.as_mut_slice())?; - assert_eq!(n, PoseidonCipher::serialized_size()); - - let mut deser_cipher = PoseidonCipher::default(); - let n = deser_cipher.write(bytes.as_slice())?; - assert_eq!(n, PoseidonCipher::serialized_size()); - - assert_eq!(cipher, deser_cipher); - - let decrypt = deser_cipher.decrypt(&secret, &nonce)?; - - assert_eq!(message, decrypt); - - Ok(()) -} - #[test] fn bytes() -> Result<()> { let (message, secret, nonce) = gen(); From 7224dd809dbce83a7e36c9a31b726d705f61b929 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Wed, 4 Nov 2020 13:50:14 +0100 Subject: [PATCH 3/5] Publish version v0.13.0 --- CHANGELOG.md | 7 +++++++ Cargo.toml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 03a24dd..2d50616 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [0.13.0] - 04-11-20 +### Changed +- PoseidonLeaf pos setter for API consistency with Phoenix + +### Removed +- PoseidonCipher std::io implementations + ## [0.12.0] - 03-11-20 ### Added - Gate-featured `canonical` impl. diff --git a/Cargo.toml b/Cargo.toml index 23dc483..d758566 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "poseidon252" -version = "0.12.0" +version = "0.13.0" authors = [ "zer0 ", "vlopes11 ", "CPerezz ", "Kristoffer Ström " ] From 9dba7e152822206fb7ad7a4151db40eb1fec7e0e Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Wed, 4 Nov 2020 15:20:45 +0100 Subject: [PATCH 4/5] PoseidonLeaf getter and setter style for pos --- README.md | 4 ++-- src/cipher/mod.rs | 6 ++++++ src/tree/mod.rs | 8 ++++---- src/tree/tests.rs | 8 ++++---- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index bc6552c..c50c6b1 100644 --- a/README.md +++ b/README.md @@ -107,12 +107,12 @@ impl PoseidonLeaf for DataLeaf { } // Position on the tree - fn tree_pos(&self) -> u64 { + fn pos(&self) -> u64 { self.pos } // Method used to set the position on the tree after the `PoseidonTree::push` call - fn tree_pos_set(&mut self, pos: u64) { + fn set_pos(&mut self, pos: u64) { self.pos = pos; } } diff --git a/src/cipher/mod.rs b/src/cipher/mod.rs index 33734c5..1cbad7c 100644 --- a/src/cipher/mod.rs +++ b/src/cipher/mod.rs @@ -16,6 +16,12 @@ pub const CIPHER_SIZE: usize = MESSAGE_CAPACITY + 1; /// Number of bytes used by from/to bytes `PoseidonCipher` function pub const CIPHER_BYTES_SIZE: usize = CIPHER_SIZE * 32; +/// Bytes consumed on serialization of the poseidon cipher +/// +/// This is kept for backwards compatibility since the constant definition is +/// redundant to [`CIPHER_BYTES_SIZE`] +pub const ENCRYPTED_DATA_SIZE: usize = CIPHER_SIZE * 32; + /// [`PoseidonCipher`] definition pub mod cipher; diff --git a/src/tree/mod.rs b/src/tree/mod.rs index 27008ba..b9fa9c3 100644 --- a/src/tree/mod.rs +++ b/src/tree/mod.rs @@ -41,13 +41,13 @@ where fn poseidon_hash(&self) -> BlsScalar; /// Index of the leaf structure on the merkle tree. - fn tree_pos(&self) -> u64; + fn pos(&self) -> u64; /// Index of the leaf structure on the merkle tree. /// /// This method is internally used to set the index after the data has been inserted in the /// merkle tree. - fn tree_pos_set(&mut self, pos: u64); + fn set_pos(&mut self, pos: u64); } /// Represents a Merkle Tree with a given depth that will be calculated using poseidon hash @@ -117,7 +117,7 @@ where .sum(), }; - leaf.tree_pos_set(size as u64); + leaf.set_pos(size as u64); self.inner .push(leaf) .map_err(|e| anyhow!("Error pushing to the tree: {:?}", e))?; @@ -210,7 +210,7 @@ where A::poseidon_walk(w, data.clone()) }) .map_err(|e| anyhow!("Error fetching the branch: {:?}", e))? - .map(|l| l.tree_pos()) + .map(|l| l.pos()) .unwrap_or(u64::max_value()) as usize; Ok(Self { tree, pos, data }) diff --git a/src/tree/tests.rs b/src/tree/tests.rs index ab232ba..10ff50a 100644 --- a/src/tree/tests.rs +++ b/src/tree/tests.rs @@ -39,11 +39,11 @@ impl PoseidonLeaf for MockLeaf { self.s } - fn tree_pos(&self) -> u64 { + fn pos(&self) -> u64 { self.pos } - fn tree_pos_set(&mut self, pos: u64) { + fn set_pos(&mut self, pos: u64) { self.pos = pos; } } @@ -102,7 +102,7 @@ fn tree_max_walk() { .map(|l| l.unwrap()) .enumerate() .for_each(|(i, leaf)| { - assert_eq!(pos + i as u64, leaf.tree_pos()); + assert_eq!(pos + i as u64, leaf.pos()); }); assert!(tree.iter_walk((max + 1) as u64).unwrap().next().is_none()); @@ -137,7 +137,7 @@ fn tree_max_walk_non_continuous() { if pos % 4 == 0 { pos += 1; } - assert_eq!(pos, leaf.tree_pos()); + assert_eq!(pos, leaf.pos()); pos += 1; }); From 04c00bc7c9b8a92514a7390d2a315c4538ccc689 Mon Sep 17 00:00:00 2001 From: Victor Lopez Date: Wed, 4 Nov 2020 15:38:33 +0100 Subject: [PATCH 5/5] Re-add serialized size const fn for cipher --- src/cipher/cipher.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/cipher/cipher.rs b/src/cipher/cipher.rs index 742ae7c..9ec9f5b 100644 --- a/src/cipher/cipher.rs +++ b/src/cipher/cipher.rs @@ -12,7 +12,9 @@ use dusk_plonk::jubjub::AffinePoint; use dusk_plonk::prelude::*; use hades252::{ScalarStrategy, Strategy, WIDTH}; -use super::{CIPHER_BYTES_SIZE, CIPHER_SIZE, MESSAGE_CAPACITY}; +use super::{ + CIPHER_BYTES_SIZE, CIPHER_SIZE, ENCRYPTED_DATA_SIZE, MESSAGE_CAPACITY, +}; pub use super::CipherError; @@ -143,6 +145,11 @@ impl PoseidonCipher { MESSAGE_CAPACITY } + /// Bytes consumed on serialization of the poseidon cipher + pub const fn serialized_size() -> usize { + ENCRYPTED_DATA_SIZE + } + /// Encrypt a slice of scalars into an internal cipher representation /// /// The message size will be truncated to [`MESSAGE_CAPACITY`] bits