Merge pull request #50 from 0xPolygonMiden/next
Tracking PR for release v0.1.1
This commit is contained in:
commit
398af59045
8 changed files with 72 additions and 7 deletions
13
CHANGELOG.md
Normal file
13
CHANGELOG.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
## 0.1.1 (2023-02-06)
|
||||
|
||||
- Introduced `merge_in_domain` for the RPO hash function, to allow using a specified domain value in the second capacity register when hashing two digests together.
|
||||
- Added a simple sparse Merkle tree implementation.
|
||||
- Added re-exports of Winterfell RandomCoin and RandomCoinError.
|
||||
|
||||
## 0.1.0 (2022-12-02)
|
||||
|
||||
- Initial release on crates.io containing the cryptographic primitives used in Miden VM and the Miden Rollup.
|
||||
- Hash module with the BLAKE3 and Rescue Prime Optimized hash functions.
|
||||
- BLAKE3 is implemented with 256-bit, 192-bit, or 160-bit output.
|
||||
- RPO is implemented with 256-bit output.
|
||||
- Merkle module, with a set of data structures related to Merkle trees, implemented using the RPO hash function.
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "miden-crypto"
|
||||
version = "0.1.0"
|
||||
version = "0.1.1"
|
||||
description="Miden Cryptographic primitives"
|
||||
authors = ["miden contributors"]
|
||||
readme="README.md"
|
||||
|
|
|
@ -294,6 +294,28 @@ impl Rpo256 {
|
|||
<Self as ElementHasher>::hash_elements(elements)
|
||||
}
|
||||
|
||||
// DOMAIN IDENTIFIER
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
/// Returns a hash of two digests and a domain identifier.
|
||||
pub fn merge_in_domain(values: &[RpoDigest; 2], domain: Felt) -> RpoDigest {
|
||||
// initialize the state by copying the digest elements into the rate portion of the state
|
||||
// (8 total elements), and set the capacity elements to 0.
|
||||
let mut state = [ZERO; STATE_WIDTH];
|
||||
let it = RpoDigest::digests_as_elements(values.iter());
|
||||
for (i, v) in it.enumerate() {
|
||||
state[RATE_RANGE.start + i] = *v;
|
||||
}
|
||||
|
||||
// set the second capacity element to the domain value. The first capacity element is used
|
||||
// for padding purposes.
|
||||
state[CAPACITY_RANGE.start + 1] = domain;
|
||||
|
||||
// apply the RPO permutation and return the first four elements of the state
|
||||
Self::apply_permutation(&mut state);
|
||||
RpoDigest::new(state[DIGEST_RANGE].try_into().unwrap())
|
||||
}
|
||||
|
||||
// RESCUE PERMUTATION
|
||||
// --------------------------------------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::{
|
||||
Felt, FieldElement, Hasher, Rpo256, RpoDigest, StarkField, ALPHA, INV_ALPHA, STATE_WIDTH, ZERO,
|
||||
Felt, FieldElement, Hasher, Rpo256, RpoDigest, StarkField, ALPHA, INV_ALPHA, ONE, STATE_WIDTH,
|
||||
ZERO,
|
||||
};
|
||||
use core::convert::TryInto;
|
||||
use rand_utils::rand_value;
|
||||
|
@ -51,6 +52,33 @@ fn hash_elements_vs_merge() {
|
|||
assert_eq!(m_result, h_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn merge_vs_merge_in_domain() {
|
||||
let elements = [Felt::new(rand_value()); 8];
|
||||
|
||||
let digests: [RpoDigest; 2] = [
|
||||
RpoDigest::new(elements[..4].try_into().unwrap()),
|
||||
RpoDigest::new(elements[4..].try_into().unwrap()),
|
||||
];
|
||||
let merge_result = Rpo256::merge(&digests);
|
||||
|
||||
// ------------- merge with domain = 0 ----------------------------------------------------------
|
||||
|
||||
// set domain to ZERO. This should not change the result.
|
||||
let domain = ZERO;
|
||||
|
||||
let merge_in_domain_result = Rpo256::merge_in_domain(&digests, domain);
|
||||
assert_eq!(merge_result, merge_in_domain_result);
|
||||
|
||||
// ------------- merge with domain = 1 ----------------------------------------------------------
|
||||
|
||||
// set domain to ONE. This should change the result.
|
||||
let domain = ONE;
|
||||
|
||||
let merge_in_domain_result = Rpo256::merge_in_domain(&digests, domain);
|
||||
assert_ne!(merge_result, merge_in_domain_result);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hash_elements_vs_merge_with_int() {
|
||||
let tmp = [Felt::new(rand_value()); 4];
|
||||
|
|
|
@ -10,6 +10,8 @@ pub mod merkle;
|
|||
// RE-EXPORTS
|
||||
// ================================================================================================
|
||||
|
||||
pub use winter_crypto::{RandomCoin, RandomCoinError};
|
||||
|
||||
pub use winter_math::{fields::f64::BaseElement as Felt, FieldElement, StarkField};
|
||||
|
||||
pub mod utils {
|
||||
|
|
|
@ -4,7 +4,7 @@ use super::{BTreeMap, MerkleError, Rpo256, Vec, Word, ZERO};
|
|||
// ================================================================================================
|
||||
|
||||
/// A set of Merkle paths.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MerklePathSet {
|
||||
root: Word,
|
||||
total_depth: u32,
|
||||
|
|
|
@ -7,7 +7,7 @@ use winter_math::log2;
|
|||
// ================================================================================================
|
||||
|
||||
/// A fully-balanced binary Merkle tree (i.e., a tree where the number of leaves is a power of two).
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MerkleTree {
|
||||
nodes: Vec<Word>,
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ mod tests;
|
|||
/// A sparse Merkle tree with 63-bit keys and 4-element leaf values, without compaction.
|
||||
/// Manipulation and retrieval of leaves and internal nodes is provided by its internal `Store`.
|
||||
/// The root of the tree is recomputed on each new leaf update.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct SimpleSmt {
|
||||
root: Word,
|
||||
depth: u32,
|
||||
|
@ -186,7 +186,7 @@ impl SimpleSmt {
|
|||
/// Leaves and branch nodes are stored separately in B-tree maps, indexed by key and (key, depth)
|
||||
/// respectively. Hashes for blank subtrees at each layer are stored in `empty_hashes`, beginning
|
||||
/// with the root hash of an empty tree, and ending with the zero value of a leaf node.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
struct Store {
|
||||
branches: BTreeMap<(u64, u32), BranchNode>,
|
||||
leaves: BTreeMap<u64, Word>,
|
||||
|
@ -194,7 +194,7 @@ struct Store {
|
|||
depth: u32,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
struct BranchNode {
|
||||
left: RpoDigest,
|
||||
right: RpoDigest,
|
||||
|
|
Loading…
Add table
Reference in a new issue