From d6ab367d32918da9ee6d8d3c2981f60f67e9b4e6 Mon Sep 17 00:00:00 2001 From: Elias Rad <146735585+nnsW3@users.noreply.github.com> Date: Wed, 24 Jul 2024 21:35:57 +0300 Subject: [PATCH 1/4] chore: fix typos (#321) --- src/dsa/rpo_falcon512/keys/secret_key.rs | 2 +- src/dsa/rpo_falcon512/signature.rs | 2 +- src/merkle/mmr/full.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/dsa/rpo_falcon512/keys/secret_key.rs b/src/dsa/rpo_falcon512/keys/secret_key.rs index d3ca339..e67449a 100644 --- a/src/dsa/rpo_falcon512/keys/secret_key.rs +++ b/src/dsa/rpo_falcon512/keys/secret_key.rs @@ -28,7 +28,7 @@ const WIDTH_SMALL_POLY_COEFFICIENT: usize = 6; // ================================================================================================ /// The secret key is a quadruple [[g, -f], [G, -F]] of polynomials with integer coefficients. Each -/// polynomial is of degree at most N = 512 and computations with these polynomials is done modulo +/// polynomial is of degree at most N = 512 and computations with these polynomials are done modulo /// the monic irreducible polynomial ϕ = x^N + 1. The secret key is a basis for a lattice and has /// the property of being short with respect to a certain norm and an upper bound appropriate for /// a given security parameter. The public key on the other hand is another basis for the same diff --git a/src/dsa/rpo_falcon512/signature.rs b/src/dsa/rpo_falcon512/signature.rs index 035776d..04ba465 100644 --- a/src/dsa/rpo_falcon512/signature.rs +++ b/src/dsa/rpo_falcon512/signature.rs @@ -43,7 +43,7 @@ use num::Zero; /// 2. 40 bytes for the nonce. /// 4. 625 bytes encoding the `s2` polynomial above. /// -/// The total size of the signature is (including the extended public key) is 1563 bytes. +/// The total size of the signature (including the extended public key) is 1563 bytes. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Signature { header: SignatureHeader, diff --git a/src/merkle/mmr/full.rs b/src/merkle/mmr/full.rs index b2ea2df..06dd5e6 100644 --- a/src/merkle/mmr/full.rs +++ b/src/merkle/mmr/full.rs @@ -7,7 +7,7 @@ //! //! Additionally the structure only supports adding leaves to the right-most tree, the one with the //! least number of leaves. The structure preserves the invariant that each tree has different -//! depths, i.e. as part of adding adding a new element to the forest the trees with same depth are +//! depths, i.e. as part of adding a new element to the forest the trees with same depth are //! merged, creating a new tree with depth d+1, this process is continued until the property is //! reestablished. use super::{ From 8bb893345b078b8b71d9047f011b81ee29f6263f Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Tue, 6 Aug 2024 17:00:17 -0700 Subject: [PATCH 2/4] chore: update rust version badge --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f5a554f..5fb73e1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![LICENSE](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/0xPolygonMiden/crypto/blob/main/LICENSE) [![test](https://github.com/0xPolygonMiden/crypto/actions/workflows/test.yml/badge.svg)](https://github.com/0xPolygonMiden/crypto/actions/workflows/test.yml) [![no-std](https://github.com/0xPolygonMiden/crypto/actions/workflows/no-std.yml/badge.svg)](https://github.com/0xPolygonMiden/crypto/actions/workflows/no-std.yml) -[![RUST_VERSION](https://img.shields.io/badge/rustc-1.75+-lightgray.svg)]() +[![RUST_VERSION](https://img.shields.io/badge/rustc-1.80+-lightgray.svg)]() [![CRATE](https://img.shields.io/crates/v/miden-crypto)](https://crates.io/crates/miden-crypto) This crate contains cryptographic primitives used in Polygon Miden. From 2b184cd4ca6e00d9a89fcfdb633c27c8c7d103ff Mon Sep 17 00:00:00 2001 From: Santiago Pittella <87827390+SantiagoPittella@users.noreply.github.com> Date: Fri, 13 Sep 2024 12:47:46 -0300 Subject: [PATCH 3/4] feat: add de/serialization to `InOrderIndex` and `PartialMmr` (#329) --- CHANGELOG.md | 4 ++++ src/merkle/mmr/inorder.rs | 26 ++++++++++++++++++++ src/merkle/mmr/partial.rs | 50 +++++++++++++++++++++++++++++++++++---- 3 files changed, 75 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4612b0c..7192bee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.10.1 (TBD) + +* Added `Serializable` and `Deserializable` implementations for `PartialMmr` and `InOrderIndex` (#329). + ## 0.10.0 (2024-08-06) * Added more `RpoDigest` and `RpxDigest` conversions (#311). diff --git a/src/merkle/mmr/inorder.rs b/src/merkle/mmr/inorder.rs index 655f364..37b4884 100644 --- a/src/merkle/mmr/inorder.rs +++ b/src/merkle/mmr/inorder.rs @@ -6,6 +6,8 @@ //! leaves count. use core::num::NonZeroUsize; +use winter_utils::{Deserializable, Serializable}; + // IN-ORDER INDEX // ================================================================================================ @@ -112,6 +114,21 @@ impl InOrderIndex { } } +impl Serializable for InOrderIndex { + fn write_into(&self, target: &mut W) { + target.write_usize(self.idx); + } +} + +impl Deserializable for InOrderIndex { + fn read_from( + source: &mut R, + ) -> Result { + let idx = source.read_usize()?; + Ok(InOrderIndex { idx }) + } +} + // CONVERSIONS FROM IN-ORDER INDEX // ------------------------------------------------------------------------------------------------ @@ -127,6 +144,7 @@ impl From for u64 { #[cfg(test)] mod test { use proptest::prelude::*; + use winter_utils::{Deserializable, Serializable}; use super::InOrderIndex; @@ -162,4 +180,12 @@ mod test { assert_eq!(left.sibling(), right); assert_eq!(left, right.sibling()); } + + #[test] + fn test_inorder_index_serialization() { + let index = InOrderIndex::from_leaf_pos(5); + let bytes = index.to_bytes(); + let index2 = InOrderIndex::read_from_bytes(&bytes).unwrap(); + assert_eq!(index, index2); + } } diff --git a/src/merkle/mmr/partial.rs b/src/merkle/mmr/partial.rs index c2c4464..6739c3c 100644 --- a/src/merkle/mmr/partial.rs +++ b/src/merkle/mmr/partial.rs @@ -1,12 +1,15 @@ +use alloc::{ + collections::{BTreeMap, BTreeSet}, + vec::Vec, +}; + +use winter_utils::{Deserializable, Serializable}; + use super::{MmrDelta, MmrProof, Rpo256, RpoDigest}; use crate::merkle::{ mmr::{leaf_to_corresponding_tree, nodes_in_forest}, InOrderIndex, InnerNodeInfo, MerklePath, MmrError, MmrPeaks, }; -use alloc::{ - collections::{BTreeMap, BTreeSet}, - vec::Vec, -}; // TYPE ALIASES // ================================================================================================ @@ -572,6 +575,28 @@ impl<'a, I: Iterator> Iterator for InnerNodeIterator< } } +impl Serializable for PartialMmr { + fn write_into(&self, target: &mut W) { + self.forest.write_into(target); + self.peaks.write_into(target); + self.nodes.write_into(target); + target.write_bool(self.track_latest); + } +} + +impl Deserializable for PartialMmr { + fn read_from( + source: &mut R, + ) -> Result { + let forest = usize::read_from(source)?; + let peaks = Vec::::read_from(source)?; + let nodes = NodeMap::read_from(source)?; + let track_latest = source.read_bool()?; + + Ok(Self { forest, peaks, nodes, track_latest }) + } +} + // UTILS // ================================================================================================ @@ -613,12 +638,15 @@ fn forest_to_rightmost_index(forest: usize) -> InOrderIndex { #[cfg(test)] mod tests { + use alloc::{collections::BTreeSet, vec::Vec}; + + use winter_utils::{Deserializable, Serializable}; + use super::{ forest_to_rightmost_index, forest_to_root_index, InOrderIndex, MmrPeaks, PartialMmr, RpoDigest, }; use crate::merkle::{int_to_node, MerkleStore, Mmr, NodeIndex}; - use alloc::{collections::BTreeSet, vec::Vec}; const LEAVES: [RpoDigest; 7] = [ int_to_node(0), @@ -907,4 +935,16 @@ mod tests { // the openings should be the same assert_eq!(mmr.open(5, mmr.forest()).unwrap(), partial_mmr.open(5).unwrap().unwrap()); } + + #[test] + fn test_partial_mmr_serialization() { + let mmr = Mmr::from((0..7).map(int_to_node)); + let forest_size = mmr.forest(); + let partial_mmr = PartialMmr::from_peaks(mmr.peaks(forest_size).unwrap()); + + let bytes = partial_mmr.to_bytes(); + let decoded = PartialMmr::read_from_bytes(&bytes).unwrap(); + + assert_eq!(partial_mmr, decoded); + } } From e34900c7d86e3f77536975fcdb1c3b816e205e37 Mon Sep 17 00:00:00 2001 From: Bobbin Threadbare Date: Fri, 13 Sep 2024 10:58:06 -0700 Subject: [PATCH 4/4] chore: update version to v0.10.1 --- CHANGELOG.md | 2 +- Cargo.lock | 2 +- Cargo.toml | 4 ++-- src/dsa/rpo_falcon512/keys/secret_key.rs | 15 ++++++++------- src/merkle/mmr/partial.rs | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7192bee..1a29f47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.10.1 (TBD) +## 0.10.1 (2024-09-13) * Added `Serializable` and `Deserializable` implementations for `PartialMmr` and `InOrderIndex` (#329). diff --git a/Cargo.lock b/Cargo.lock index e10bdb2..5b80a8a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -518,7 +518,7 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "miden-crypto" -version = "0.10.0" +version = "0.10.1" dependencies = [ "blake3", "cc", diff --git a/Cargo.toml b/Cargo.toml index 2616341..d1010f4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,12 +1,12 @@ [package] name = "miden-crypto" -version = "0.10.0" +version = "0.10.1" description = "Miden Cryptographic primitives" authors = ["miden contributors"] readme = "README.md" license = "MIT" repository = "https://github.com/0xPolygonMiden/crypto" -documentation = "https://docs.rs/miden-crypto/0.10.0" +documentation = "https://docs.rs/miden-crypto/0.10.1" categories = ["cryptography", "no-std"] keywords = ["miden", "crypto", "hash", "merkle"] edition = "2021" diff --git a/src/dsa/rpo_falcon512/keys/secret_key.rs b/src/dsa/rpo_falcon512/keys/secret_key.rs index 6fc667d..9c6c07e 100644 --- a/src/dsa/rpo_falcon512/keys/secret_key.rs +++ b/src/dsa/rpo_falcon512/keys/secret_key.rs @@ -27,13 +27,14 @@ const WIDTH_SMALL_POLY_COEFFICIENT: usize = 6; // SECRET KEY // ================================================================================================ -/// The secret key is a quadruple [[g, -f], [G, -F]] of polynomials with integer coefficients. Each -/// polynomial is of degree at most N = 512 and computations with these polynomials are done modulo -/// the monic irreducible polynomial ϕ = x^N + 1. The secret key is a basis for a lattice and has -/// the property of being short with respect to a certain norm and an upper bound appropriate for -/// a given security parameter. The public key on the other hand is another basis for the same -/// lattice and can be described by a single polynomial h with integer coefficients modulo ϕ. -/// The two keys are related by the following relation: +/// The secret key is a quadruple [[g, -f], [G, -F]] of polynomials with integer coefficients. +/// +/// Each polynomial is of degree at most N = 512 and computations with these polynomials are done +/// modulo the monic irreducible polynomial ϕ = x^N + 1. The secret key is a basis for a lattice +/// and has the property of being short with respect to a certain norm and an upper bound +/// appropriate for a given security parameter. The public key on the other hand is another basis +/// for the same lattice and can be described by a single polynomial h with integer coefficients +/// modulo ϕ. The two keys are related by the following relation: /// /// 1. h = g /f [mod ϕ][mod p] /// 2. f.G - g.F = p [mod ϕ] diff --git a/src/merkle/mmr/partial.rs b/src/merkle/mmr/partial.rs index 6739c3c..c191aa5 100644 --- a/src/merkle/mmr/partial.rs +++ b/src/merkle/mmr/partial.rs @@ -186,7 +186,7 @@ impl PartialMmr { pub fn inner_nodes<'a, I: Iterator + 'a>( &'a self, mut leaves: I, - ) -> impl Iterator + '_ { + ) -> impl Iterator + 'a { let stack = if let Some((pos, leaf)) = leaves.next() { let idx = InOrderIndex::from_leaf_pos(pos); vec![(idx, leaf)]