Browse Source

feat: added utility to format MerkleTree and MerklePath to hex

Example formatted MerkleTree:

```
880abe452320966617646e7740b014954300f19a28780a0889d62ff33f4b0534
  1ade1369091efa31201e9b60c9c28874d0ddce5362b335135a6bb4c917285983
  3e60a9c843b4bb19f7a0572102e6507195f5240767a396335fd21981b048b807
    0100000000000000000000000000000000000000000000000000000000000000
    0200000000000000000000000000000000000000000000000000000000000000
    0300000000000000000000000000000000000000000000000000000000000000
    0400000000000000000000000000000000000000000000000000000000000000
```

Example formatted MerklePath:

```
[0400000000000000000000000000000000000000000000000000000000000000, 1ade1369091efa31201e9b60c9c28874d0ddce5362b335135a6bb4c917285983]
```
al-gkr-basic-workflow
Augusto F. Hack 2 years ago
parent
commit
0375f31035
No known key found for this signature in database GPG Key ID: 3F3584B7FB1DFB76
4 changed files with 74 additions and 9 deletions
  1. +1
    -6
      src/lib.rs
  2. +51
    -2
      src/merkle/merkle_tree.rs
  3. +1
    -1
      src/merkle/mod.rs
  4. +21
    -0
      src/utils.rs

+ 1
- 6
src/lib.rs

@ -7,18 +7,13 @@ extern crate alloc;
mod bit;
pub mod hash;
pub mod merkle;
pub mod utils;
// RE-EXPORTS
// ================================================================================================
pub use winter_crypto::{RandomCoin, RandomCoinError};
pub use winter_math::{fields::f64::BaseElement as Felt, FieldElement, StarkField};
pub mod utils {
pub use winter_utils::{
collections, string, uninit_vector, ByteReader, ByteWriter, Deserializable,
DeserializationError, Serializable, SliceReader,
};
}
// TYPE ALIASES
// ================================================================================================

+ 51
- 2
src/merkle/merkle_tree.rs

@ -1,6 +1,9 @@
use super::{Felt, MerkleError, MerklePath, NodeIndex, Rpo256, RpoDigest, Vec, Word};
use crate::{utils::uninit_vector, FieldElement};
use core::slice;
use crate::{
utils::{string::String, uninit_vector, word_to_hex},
FieldElement,
};
use core::{fmt, slice};
use winter_math::log2;
// MERKLE TREE
@ -157,6 +160,52 @@ impl MerkleTree {
}
}
/// Utility to vizualize a [MerkleTree] in text.
pub fn tree_to_text(tree: &MerkleTree) -> Result<String, fmt::Error> {
let indent = " ";
let mut s = String::new();
s.push_str(&word_to_hex(&tree.root())?);
s.push('\n');
for d in 1..=tree.depth() {
let entries = 2u64.pow(d.into());
for i in 0..entries {
let index = NodeIndex::new(d, i);
let node = tree
.get_node(index)
.expect("The index must always be valid");
for _ in 0..d {
s.push_str(indent);
}
s.push_str(&word_to_hex(&node)?);
s.push('\n');
}
}
Ok(s)
}
/// Utility to vizualize a [MerklePath] in text.
pub fn path_to_text(path: &MerklePath) -> Result<String, fmt::Error> {
let mut s = String::new();
s.push('[');
for el in path.iter() {
s.push_str(&word_to_hex(el)?);
s.push_str(", ");
}
// remove the last ", "
if path.len() != 0 {
s.pop();
s.pop();
}
s.push(']');
Ok(s)
}
// TESTS
// ================================================================================================

+ 1
- 1
src/merkle/mod.rs

@ -15,7 +15,7 @@ mod index;
pub use index::NodeIndex;
mod merkle_tree;
pub use merkle_tree::MerkleTree;
pub use merkle_tree::{path_to_text, tree_to_text, MerkleTree};
mod path;
pub use path::{MerklePath, RootPath, ValuePath};

+ 21
- 0
src/utils.rs

@ -0,0 +1,21 @@
use super::Word;
use crate::utils::string::String;
use core::fmt::{self, Write};
// RE-EXPORTS
// ================================================================================================
pub use winter_utils::{
collections, string, uninit_vector, ByteReader, ByteWriter, Deserializable,
DeserializationError, Serializable, SliceReader,
};
/// Converts a [Word] into hex.
pub fn word_to_hex(w: &Word) -> Result<String, fmt::Error> {
let mut s = String::new();
for byte in w.iter().flat_map(|e| e.to_bytes()) {
write!(s, "{byte:02x}")?;
}
Ok(s)
}

Loading…
Cancel
Save