All Projects → jjyr → restricted-sparse-merkle-tree

jjyr / restricted-sparse-merkle-tree

Licence: other
An optimized sparse merkle tree.

Programming Languages

rust
11053 projects
Makefile
30231 projects

Projects that are alternatives of or similar to restricted-sparse-merkle-tree

Pin Project
A crate for safe and ergonomic pin-projection.
Stars: ✭ 174 (+270.21%)
Mutual labels:  no-std
register-rs
Unified interface for type-safe MMIO and CPU register access in Rust
Stars: ✭ 48 (+2.13%)
Mutual labels:  no-std
m
Deprecated in favor of the libm crate.
Stars: ✭ 27 (-42.55%)
Mutual labels:  no-std
Beef
Faster, more compact implementation of std::borrow::Cow
Stars: ✭ 189 (+302.13%)
Mutual labels:  no-std
stm32f103xx
DEPRECATED
Stars: ✭ 31 (-34.04%)
Mutual labels:  no-std
qed
The scalable, auditable and high-performance tamper-evident log project
Stars: ✭ 87 (+85.11%)
Mutual labels:  sparse-merkle-tree
Drone
CLI utility for Drone, an Embedded Operating System.
Stars: ✭ 114 (+142.55%)
Mutual labels:  no-std
core2
The bare essentials of std::io for use in no_std. Alloc support is optional.
Stars: ✭ 67 (+42.55%)
Mutual labels:  no-std
rust-amplify
Amplifying Rust language capabilities: multiple generic trait implementations, type wrappers, bit-precise numerics, derive macros
Stars: ✭ 38 (-19.15%)
Mutual labels:  no-std
m4vga-rs
VGA-style video output for STM32F4 processors, in Rust
Stars: ✭ 122 (+159.57%)
Mutual labels:  no-std
Rust Lexical
Lexical, to- and from-string conversion routines.
Stars: ✭ 192 (+308.51%)
Mutual labels:  no-std
mfrc522
A platform agnostic driver to interface the MFRC522 (RFID reader/writer)
Stars: ✭ 27 (-42.55%)
Mutual labels:  no-std
fixedvec-rs
Heapless vector implementation for Rust
Stars: ✭ 39 (-17.02%)
Mutual labels:  no-std
Auto enums
A library for to allow multiple return types by automatically generated enum.
Stars: ✭ 188 (+300%)
Mutual labels:  no-std
vcell
Just like `Cell` but with volatile read / write operations
Stars: ✭ 16 (-65.96%)
Mutual labels:  no-std
Utest
Unit `#[test]`ing for microcontrollers and other `no_std` systems
Stars: ✭ 119 (+153.19%)
Mutual labels:  no-std
alloc-cortex-m
A heap allocator for Cortex-M processors
Stars: ✭ 139 (+195.74%)
Mutual labels:  no-std
metric
This library provides zero-cost dimensional analysis for safe, unit-aware numeric computations in Rust.
Stars: ✭ 23 (-51.06%)
Mutual labels:  no-std
semval
Semantic validation for Rust
Stars: ✭ 77 (+63.83%)
Mutual labels:  no-std
drone-stm32-map
STM32 peripheral mappings for Drone, an Embedded Operating System.
Stars: ✭ 16 (-65.96%)
Mutual labels:  no-std

Sparse merkle tree

Crates.io Docs

An optimized sparse merkle tree.

size proof size update get merkle proof verify proof
2n + log(n) log(n) log(n) log(n) log(n) log(n)

Features:

  • Multi-leaves membership merkle proof
  • Customizable hash function
  • Rust no_std support

This article describes algorithm of this data structure An optimized compacted sparse merkle tree

Notice this library is not stabled yet. The API and the format of the proof may be changed in the future. Make sure you know what you are doing before using this library.

Known issues

This library do not support non-membership proving. We take some aggressive optimizing methods which do not works well with the non-membership proving feature.

Please check this library for non-membership proving sparse merkle tree.

Construction

A sparse merkle tree is a perfectly balanced tree contains 2 ^ N leaves:

# N = 256 sparse merkle tree
height:
255                0
                /     \
254            0        1

.............................

           /   \          /  \
2         0     1        0    1
1        / \   / \      / \   / \
0       0   1 0  1 ... 0   1 0   1 
       0x00..00 0x00..01   ...   0x11..11

The above graph demonstrates a sparse merkle tree with 2 ^ 256 leaves, which can mapping every possible H256 value into leaves. The height of the tree is 256, from top to bottom, we denote 0 for each left branch and denote 1 for each right branch, so we can get a 256 bits path, which also can represent in H256, we use the path as the key of leaves, the most left leaf's key is 0x00..00, and the next key is 0x00..01, the most right key is 0x11..11.

We use a H256 root and a map map[(usize, H256)] -> (H256, H256) to represent the tree, the map's key is node and its height, the map's values are node's children, an empty tree represented in an empty map plus a zero H256 root.

To update a key with value, we walk the tree from root to leaf, push every non-zero sibling into merkle_path vector, since the tree height is N = 256, the merkle_path contains 256 siblings. Then we reconstruct the tree from bottom to top: map[(height, parent)] = merge(lhs, rhs), after do 256 times calculation we got the new root.

A sparse merkle tree contains few efficient nodes and others are zeros, we can specialize the merge function for zero value. We redefine the merge function, only do the actual computing when lhs and rhs are both non-zero values, otherwise if one of them is zero, we just return another one as the result.

fn merge(lhs: H256, rhs: H256) -> H256 {
    if lhs.is_zero() {
        return rhs;
    } else if rhs.is_zero() {
        return lhs;
    }

    // only do actual computing when lhs and rhs both are non-zero
    merge_hash(lhs, rhs)
}

This optimized merge function still has one issue, merge(x, zero) equals to merge(zero, x), which means the merkle root is broken since an attacker can easily construct a collision of merkle root.

To fix this, instead of update key with an H256 value, we use hash(key | value) as the value to merge, so for different keys, no matter what the value is, the leaves' hashes are unique. Since all leaves have a unique hash, nodes at each height will either merged by two different hashes or merged by a hash with a zero; for a non-zero parent, either situation we get a unique hash at the parent's height. Until the root, if the tree is empty, we get zero, or if the tree is not empty, the root must be merged from two hashes or a hash with a zero, because of the hash of two children nodes are unique, the root hash is also unique. Thus, an attacker can't construct a collision attack.

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].