Skip to content

Commit

Permalink
Merge pull request #59 from dusk-network/mocello/58_crate_separation
Browse files Browse the repository at this point in the history
Separate this repo into multiple crates
  • Loading branch information
moCello authored Jun 28, 2023
2 parents f215bd7 + 988ace4 commit c494cff
Show file tree
Hide file tree
Showing 26 changed files with 707 additions and 417 deletions.
12 changes: 9 additions & 3 deletions .github/workflows/dusk_ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ jobs:
name: Dusk Analyzer
uses: dusk-network/.github/.github/workflows/dusk-analysis.yml@main

tests_std:
name: tests std
tests_dusk_merkle:
name: tests dusk-merkle
uses: dusk-network/.github/.github/workflows/run-tests.yml@main
with:
test_flags: --features=blake3,rkyv-impl,size_32,poseidon,zk
test_flags: -p dusk-merkle --features=rkyv-impl,size_32

tests_poseidon_merkle:
name: tests poseidon-merkle
uses: dusk-network/.github/.github/workflows/run-tests.yml@main
with:
test_flags: -p poseidon-merkle --features=zk,rkyv-impl,size_32
65 changes: 5 additions & 60 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,61 +1,6 @@
[package]
name = "dusk-merkle"
description = "Crate implementing Dusk Network's Merkle tree"
version = "0.4.1-rc.0"

categories = ["data-structures", "no-std"]
keywords = ["tree", "merkle", "hash", "data", "structure"]
repository = "https://github.com/dusk-network/merkle"
authors = [
"Eduardo Leegwater Simões <[email protected]>",
"Moana Marcello <[email protected]>",
[workspace]
members = [
"dusk-merkle",
"poseidon-merkle"
]

edition = "2021"
license = "MPL-2.0"

[dependencies]
dusk-bytes = "0.1"
rkyv = { version = "0.7", optional = true, default-features = false }
bytecheck = { version = "0.6", optional = true, default-features = false }
blake3 = { version = "1", optional = true, default-features = false }
dusk-poseidon = { version = "0.29.1-rc.0", optional = true, default-features = false }
dusk-plonk = { version = "0.13", optional = true, default-features = false }
dusk-bls12_381 = { version = "0.11", optional = true, default-features = false }

[dev-dependencies]
blake3 = "1"
rand = "0.8"
hex = "0.4"
dusk-poseidon = "0.29.1-rc.0"
dusk-bls12_381 = "0.11"
criterion = "0.3"

[features]
size_16 = ["rkyv/size_16"]
size_32 = ["rkyv/size_32"]
size_64 = ["rkyv/size_64"]
rkyv-impl = [
"rkyv/validation",
"rkyv/alloc",
"rkyv",
"bytecheck",
"dusk-bls12_381/rkyv-impl"
]
poseidon = ["dusk-poseidon/merkle", "dusk-bls12_381"]
zk = ["dusk-plonk", "dusk-poseidon/alloc"]

[[bench]]
name = "zk"
harness = false
required-features = ["zk", "poseidon"]

[[bench]]
name = "poseidon"
harness = false
required-features = ["poseidon"]

[[bench]]
name = "blake3"
harness = false
required-features = ["blake3"]
resolver = "2"
74 changes: 0 additions & 74 deletions README.md

This file was deleted.

1 change: 1 addition & 0 deletions README.md
10 changes: 8 additions & 2 deletions CHANGELOG.md → dusk-merkle/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

## Added
### Removed

- Remove features `blake3`, `poseidon` and `zk` [#58]
- Remove `Aggregate` implementations for blake3 and poseidon [#58]

### Added

- Add more comprehensive benchmarks for `blake3` tree [#54]
- Add `to_var_bytes` and `from_slice` to `Opening` [#55]

## Changed
### Changed

- Update to poseidon hash optimized for merkle openings [#62]

Expand Down Expand Up @@ -80,6 +85,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

<!-- ISSUES -->
[#62]: https://github.com/dusk-network/merkle/issues/62
[#58]: https://github.com/dusk-network/merkle/issues/58
[#55]: https://github.com/dusk-network/merkle/issues/55
[#54]: https://github.com/dusk-network/merkle/issues/54
[#49]: https://github.com/dusk-network/merkle/issues/49
Expand Down
43 changes: 43 additions & 0 deletions dusk-merkle/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
[package]
name = "dusk-merkle"
description = "Crate implementing Dusk Network's Merkle tree"
version = "0.4.1-rc.0"

categories = ["data-structures", "no-std"]
keywords = ["tree", "merkle", "hash", "data", "structure"]
repository = "https://github.com/dusk-network/merkle"
authors = [
"Eduardo Leegwater Simões <[email protected]>",
"Moana Marcello <[email protected]>",
]

edition = "2021"
license = "MPL-2.0"

[dependencies]
dusk-bytes = "0.1"
rkyv = { version = "0.7", optional = true, default-features = false }
bytecheck = { version = "0.6", optional = true, default-features = false }
dusk-bls12_381 = { version = "0.11", optional = true, default-features = false }

[dev-dependencies]
blake3 = "1"
rand = "0.8"
dusk-bls12_381 = "0.11"
criterion = "0.3"

[features]
size_16 = ["rkyv/size_16"]
size_32 = ["rkyv/size_32"]
size_64 = ["rkyv/size_64"]
rkyv-impl = [
"rkyv/validation",
"rkyv/alloc",
"rkyv",
"bytecheck",
"dusk-bls12_381/rkyv-impl"
]

[[bench]]
name = "blake3"
harness = false
104 changes: 104 additions & 0 deletions dusk-merkle/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# dusk-merkle

A sparsely populated Merkle Tree, parametrized over its height and arity.
```text
Height 0 h
/ \
/ \
/ \
/ \
/ \
Height 1 h h
/ \ / \
/ \ / \
Height 2 h x h h
/ \ / \ / \
Height 3 h x x h h h
Position 0 5 6 7
```
The `Aggregate` trait defines how to calculate a parent from its children.
There is no restrictions on the way the children are aggregated, it can be done
with a hash function or any other custom aggregation.
Empty subtrees (noted as `x` in the tree above) are filled with the constant
`EMPTY_SUBTREE` from `Aggregate`.

Here an example where the parent is the sum of its children:

## Usage
```rust
use dusk_merkle::{Tree, Aggregate};

#[derive(Debug, Clone, Copy, PartialEq)]
struct U8(u8);

impl From<u8> for U8 {
fn from(n: u8) -> Self {
Self(n)
}
}

const EMPTY_ITEM: U8 = U8(0);

impl Aggregate<A> for U8 {
const EMPTY_SUBTREE: U8 = EMPTY_ITEM;

fn aggregate(items: [&Self; A]) -> Self
{
items.into_iter().fold(U8(0), |acc, c| U8(acc.0 + c.0))
}
}

// Set the height and arity of the tree.
const H: usize = 3;
const A: usize = 2;

let mut tree = Tree::<U8, H, A>::new();

// No elements have been inserted so the root is the empty subtree.
assert_eq!(*tree.root(), U8::EMPTY_SUBTREE);

tree.insert(4, 21);
tree.insert(7, 21);

// After elements have been inserted, the root will be modified.
assert_eq!(*tree.root(), U8(42));
```

An implementation of a Merkle tree using the `blake3` hash algorithm is included
as an example.

Another implementation of a Merkle tree with the `poseidon252` hash and the
creation of the opening proof in zero-knowledge using PLONK is included as a
member of this workspace `poseidon_merkle`.

## Benchmarks

Benchmarks are also included and can be run using:

For the `blake3` tree:
```shell
cargo bench
```

For the `poseidon` tree:
```shell
cargo bench -p poseidon-merkle
```

For the opening proof creation in zero-knowledge:
```shell
cargo bench -p poseidon-merkle --features zk
```

This requires a nightly toolchain.

## Implementations

A merkle tree using the poseidon hash function for aggregation and plonk to
generate an opening proof in zero-knowledge can be found in the same workspace
under 'poseidon-merkle'.

## License

This project is licensed under the Mozilla Public License, version 2.0. See the
[license](./LICENSE) file for more details.
35 changes: 32 additions & 3 deletions benches/blake3.rs → dusk-merkle/benches/blake3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,39 @@ use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use rand::rngs::StdRng;
use rand::{RngCore, SeedableRng};

use blake3::Hasher;
use blake3::{Hash as Blake3Hash, Hasher};

use dusk_merkle::blake3::Item;
use dusk_merkle::Tree;
use dusk_merkle::{Aggregate, Tree};

const EMPTY_HASH: Item = Item([0; 32]);

#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Item([u8; 32]);

impl From<Blake3Hash> for Item {
fn from(h: Blake3Hash) -> Self {
Self(h.into())
}
}

impl<const A: usize> Aggregate<A> for Item {
const EMPTY_SUBTREE: Self = EMPTY_HASH;

fn aggregate(items: [&Self; A]) -> Self {
let mut hasher = Hasher::new();
for item in items {
hasher.update(&item.0);
}
hasher.finalize().into()
}
}

impl Item {
#[must_use]
pub fn new(bytes: [u8; 32]) -> Self {
Item(bytes)
}
}

const H: usize = 32;
const A: usize = 2;
Expand Down
File renamed without changes.
Loading

0 comments on commit c494cff

Please sign in to comment.