Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjust the API to read better, and improve some of the top code heirarchy #148

Merged
merged 34 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
b58ebe0
Adjust data size conversion function
Stentonian Jan 11, 2024
082d6ed
Initialize logging and parallelism detector
Stentonian Jan 11, 2024
d673948
Merge branch 'stent/bench-updates' into stent/neaten-up
Stentonian Jan 12, 2024
83ec303
Move node_content to binary_tree dir
Stentonian Jan 12, 2024
6a8ac73
Rename TreeBuilder to BinaryTreeBuilder
Stentonian Jan 12, 2024
ab8f561
[wip] New Salt abstraction type
Stentonian Jan 12, 2024
45f660c
[!compiling] New DapolTree type, move Accumulator logic to new type
Stentonian Jan 12, 2024
f4211b2
Rename ndm_smt.tree to binary_tree & format
Stentonian Jan 12, 2024
60338e1
[wip] Add dapol config type, which copies code from NdmSmtConfig
Stentonian Jan 12, 2024
5c8a580
Add more to salt.rs, copying from secret.rs
Stentonian Jan 12, 2024
2f93459
Add additional AccumulatorType, and adjust pub api
Stentonian Jan 12, 2024
b5be734
Pipe construction from dapol_tree to ndm_smt
Stentonian Jan 12, 2024
0ff1a41
Mark files for deletion
Stentonian Jan 12, 2024
0356998
Delete ndm_smt_config
Stentonian Jan 12, 2024
ba97fbb
Delete ndm_smt_secrets
Stentonian Jan 12, 2024
4a1d524
Change the config file format
Stentonian Jan 12, 2024
602e401
Delete accumulator config & move some of the code to DapolConfig
Stentonian Jan 12, 2024
e17874a
Make Secret & Salt values strings in the config, to aid deserialization
Stentonian Jan 12, 2024
e7a1167
Delete ndm_smt_secrets_parser
Stentonian Jan 12, 2024
0d21bd8
Revert "Delete ndm_smt_secrets_parser"
Stentonian Jan 12, 2024
760b5d0
Revert "Revert "Delete ndm_smt_secrets_parser""
Stentonian Jan 12, 2024
8659229
Grab some code from deleted ndm_smt_secrets_parser for dapol_config
Stentonian Jan 12, 2024
169cfa5
Use serde_with for deserializing secret & salt
Stentonian Jan 14, 2024
190f9f4
Change some naming & types in ndm_smt
Stentonian Jan 14, 2024
710feb9
[compiling now] Update main & cli
Stentonian Jan 14, 2024
9e7927e
Add extra few params to cli, & clean some of the docs
Stentonian Jan 14, 2024
800b0a9
Layer of abstraction for max_liability
Stentonian Jan 15, 2024
1efafc2
Rename & adjust example config files
Stentonian Jan 15, 2024
0bea4cc
Get unit tests compiling, and add dapol_config tests
Stentonian Jan 15, 2024
f2a2498
Fix all doc tests & examples, and bug with bulletproofs bit length
Stentonian Jan 16, 2024
de4eff5
Use max_liability for range proof bound & remove Accumulator from API
Stentonian Jan 16, 2024
396ee44
Add unit test on salt.rs
Stentonian Jan 16, 2024
d96d5f3
Bunch 'o smol todos
Stentonian Jan 16, 2024
13900f2
Get benches building
Stentonian Jan 16, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ bench = false
[dependencies]

primitive-types = { version = "0.12.1", features = ["serde"] } # H256 & U256 (I think parity uses this so maybe we just use that crate instead)
thiserror = "1.0"

# crypto
rand = "0.8.5"
Expand All @@ -40,7 +41,6 @@ bulletproofs = "4.0.0"
curve25519-dalek-ng = "4.1.1"

# concurrency
thiserror = "1.0"
displaydoc = "0.2"
rayon = "1.7.0"
dashmap = { version = "5.5.3", features = ["serde"] }
Expand All @@ -57,9 +57,10 @@ patharg = "0.3.0"

# files & serialization
serde = { version = "1.0.188", features = ["derive"] }
serde_with = "3.4.0"
serde_bytes = "0.11.12"
toml = "0.8.2"
csv = "1.3.0"
serde_bytes = "0.11.12"
bincode = "1.3.3"
chrono = "0.4.31"
derive_builder = "0.12.0"
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,18 @@ The CLI offers 3 main operations: tree building, proof generation & proof verifi
#### Tree building

Building a tree can be done:
- from a config file (see tree_config_example.toml)
- from a config file (see dapol_config_example.toml)
- from CLI arguments
- by deserializing an already-built tree

Build a tree using config file (full log verbosity):
```bash
./target/release/dapol -vvv build-tree config-file ./examples/tree_config_example.toml
./target/release/dapol -vvv build-tree config-file ./examples/dapol_config_example.toml
```

Add serialization:
```bash
./target/release/dapol -vvv build-tree config-file ./examples/tree_config_example.toml --serialize .
./target/release/dapol -vvv build-tree config-file ./examples/dapol_config_example.toml --serialize .
```

Deserialize a tree from a file:
Expand All @@ -87,7 +87,7 @@ Deserialize a tree from a file:

Generate proofs (proofs will live in the `./inclusion_proofs/` directory):
```bash
./target/release/dapol -vvv build-tree config-file ./examples/tree_config_example.toml --gen-proofs ./examples/entities_example.csv
./target/release/dapol -vvv build-tree config-file ./examples/dapol_config_example.toml --gen-proofs ./examples/entities_example.csv
```

Build a tree using cli args as apposed to a config file:
Expand Down
55 changes: 39 additions & 16 deletions benches/criterion_benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
//! long (see large_input_benches.rs).

use std::path::Path;
use std::str::FromStr;

use criterion::measurement::Measurement;
use criterion::{criterion_group, criterion_main};
use criterion::{BenchmarkId, Criterion, SamplingMode};
use statistical::*;

use dapol::accumulators::{NdmSmt, NdmSmtConfigBuilder};
use dapol::{Accumulator, InclusionProof};
use dapol::{DapolConfigBuilder, DapolTree, InclusionProof, Secret};

mod inputs;
use inputs::{max_thread_counts_greater_than, num_entities_in_range, tree_heights_in_range};
Expand Down Expand Up @@ -43,6 +43,8 @@ pub fn bench_build_tree<T: Measurement>(c: &mut Criterion<T>) {
let epoch = jemalloc_ctl::epoch::mib().unwrap();
let allocated = jemalloc_ctl::stats::allocated::mib().unwrap();

let master_secret = Secret::from_str("secret").unwrap();

dapol::initialize_machine_parallelism();
dapol::utils::activate_logging(*LOG_VERBOSITY);

Expand Down Expand Up @@ -103,7 +105,7 @@ pub fn bench_build_tree<T: Measurement>(c: &mut Criterion<T>) {
// Tree build.

let mut memory_readings = vec![];
let mut ndm_smt = Option::<NdmSmt>::None;
let mut dapol_tree = Option::<DapolTree>::None;

group.bench_with_input(
BenchmarkId::new(
Expand All @@ -119,17 +121,20 @@ pub fn bench_build_tree<T: Measurement>(c: &mut Criterion<T>) {
|bench, tup| {
bench.iter(|| {
// this is necessary for the memory readings to work
ndm_smt = None;
dapol_tree = None;

epoch.advance().unwrap();
let before = allocated.read().unwrap();

ndm_smt = Some(
NdmSmtConfigBuilder::default()
dapol_tree = Some(
DapolConfigBuilder::default()
.accumulator_type(dapol::AccumulatorType::NdmSmt)
.height(tup.0)
.max_thread_count(tup.1)
.num_random_entities(tup.2)
.master_secret(master_secret.clone())
.build()
.expect("Unable to build DapolConfig")
.parse()
.expect("Unable to parse NdmSmtConfig"),
);
Expand Down Expand Up @@ -160,8 +165,8 @@ pub fn bench_build_tree<T: Measurement>(c: &mut Criterion<T>) {
let src_dir = env!("CARGO_MANIFEST_DIR");
let target_dir = Path::new(&src_dir).join("target");
let dir = target_dir.join("serialized_trees");
let path = Accumulator::parse_accumulator_serialization_path(dir).unwrap();
let acc = Accumulator::NdmSmt(ndm_smt.expect("Tree should have been built"));
let path = DapolTree::parse_serialization_path(dir).unwrap();
let tree = dapol_tree.expect("Tree should have been built");

group.bench_function(
BenchmarkId::new(
Expand All @@ -174,7 +179,7 @@ pub fn bench_build_tree<T: Measurement>(c: &mut Criterion<T>) {
),
),
|bench| {
bench.iter(|| acc.serialize(path.clone()).unwrap());
bench.iter(|| tree.serialize(path.clone()).unwrap());
},
);

Expand All @@ -196,6 +201,11 @@ pub fn bench_build_tree<T: Measurement>(c: &mut Criterion<T>) {
pub fn bench_generate_proof<T: Measurement>(c: &mut Criterion<T>) {
let mut group = c.benchmark_group("proofs");

let master_secret = Secret::from_str("secret").unwrap();

dapol::initialize_machine_parallelism();
dapol::utils::activate_logging(*LOG_VERBOSITY);

for h in tree_heights_in_range(*MIN_HEIGHT, *MAX_HEIGHT).into_iter() {
for n in num_entities_in_range(*MIN_ENTITIES, *MAX_ENTITIES).into_iter() {
{
Expand Down Expand Up @@ -238,15 +248,19 @@ pub fn bench_generate_proof<T: Measurement>(c: &mut Criterion<T>) {
continue;
}

let ndm_smt = NdmSmtConfigBuilder::default()
let dapol_tree = DapolConfigBuilder::default()
.accumulator_type(dapol::AccumulatorType::NdmSmt)
.master_secret(master_secret.clone())
.height(h)
.num_random_entities(n)
.build()
.expect("Unable to build DapolConfig")
.parse()
.expect("Unable to parse NdmSmtConfig");

let entity_id = ndm_smt
let entity_id = dapol_tree
.entity_mapping()
.unwrap()
.keys()
.next()
.expect("Tree should have at least 1 entity");
Expand All @@ -261,7 +275,7 @@ pub fn bench_generate_proof<T: Measurement>(c: &mut Criterion<T>) {
|bench| {
bench.iter(|| {
proof = Some(
ndm_smt
dapol_tree
.generate_inclusion_proof(entity_id)
.expect("Proof should have been generated successfully"),
);
Expand Down Expand Up @@ -296,6 +310,11 @@ pub fn bench_generate_proof<T: Measurement>(c: &mut Criterion<T>) {
pub fn bench_verify_proof<T: Measurement>(c: &mut Criterion<T>) {
let mut group = c.benchmark_group("proofs");

let master_secret = Secret::from_str("secret").unwrap();

dapol::initialize_machine_parallelism();
dapol::utils::activate_logging(*LOG_VERBOSITY);

for h in tree_heights_in_range(*MIN_HEIGHT, *MAX_HEIGHT).into_iter() {
for n in num_entities_in_range(*MIN_ENTITIES, *MAX_ENTITIES).into_iter() {
{
Expand Down Expand Up @@ -338,22 +357,26 @@ pub fn bench_verify_proof<T: Measurement>(c: &mut Criterion<T>) {
continue;
}

let ndm_smt = NdmSmtConfigBuilder::default()
let dapol_tree = DapolConfigBuilder::default()
.accumulator_type(dapol::AccumulatorType::NdmSmt)
.master_secret(master_secret.clone())
.height(h)
.num_random_entities(n)
.build()
.expect("Unable to build DapolConfig")
.parse()
.expect("Unable to parse NdmSmtConfig");

let root_hash = ndm_smt.root_hash();
let root_hash = dapol_tree.root_hash();

let entity_id = ndm_smt
let entity_id = dapol_tree
.entity_mapping()
.unwrap()
.keys()
.next()
.expect("Tree should have at least 1 entity");

let proof = ndm_smt
let proof = dapol_tree
.generate_inclusion_proof(entity_id)
.expect("Proof should have been generated successfully");

Expand Down
27 changes: 17 additions & 10 deletions benches/manual_benches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
//! unfortunately, but this is the trade-off.

use std::path::Path;
use std::str::FromStr;
use std::time::Instant;

use statistical::*;

use dapol::accumulators::{Accumulator, NdmSmt, NdmSmtConfigBuilder};
use dapol::{DapolConfigBuilder, DapolTree, Secret};

mod inputs;
use inputs::{max_thread_counts_greater_than, num_entities_in_range, tree_heights_in_range};
Expand All @@ -36,6 +37,8 @@ fn main() {

let total_mem = system_total_memory_mb();

let master_secret = Secret::from_str("secret").unwrap();

dapol::initialize_machine_parallelism();
dapol::utils::activate_logging(*LOG_VERBOSITY);

Expand Down Expand Up @@ -100,14 +103,14 @@ fn main() {
// ==============================================================
// Tree build.

let mut ndm_smt = Option::<NdmSmt>::None;
let mut dapol_tree = Option::<DapolTree>::None;
let mut memory_readings = vec![];
let mut timings = vec![];

// Do 3 readings (Criterion does 10 minimum).
for _i in 0..3 {
// this is necessary for the memory readings to work
ndm_smt = None;
dapol_tree = None;

println!(
"building tree i {} time {}",
Expand All @@ -119,14 +122,17 @@ fn main() {
let mem_before = allocated.read().unwrap();
let time_start = Instant::now();

ndm_smt = Some(
NdmSmtConfigBuilder::default()
dapol_tree = Some(
DapolConfigBuilder::default()
.accumulator_type(dapol::AccumulatorType::NdmSmt)
.height(h)
.max_thread_count(t)
.master_secret(master_secret.clone())
.num_random_entities(n)
.build()
.expect("Unable to build DapolConfig")
.parse()
.expect("Unable to parse NdmSmtConfig"),
.expect("Unable to parse DapolConfig"),
);

let tree_build_time = time_start.elapsed();
Expand Down Expand Up @@ -154,12 +160,13 @@ fn main() {
let src_dir = env!("CARGO_MANIFEST_DIR");
let target_dir = Path::new(&src_dir).join("target");
let dir = target_dir.join("serialized_trees");
let path = Accumulator::parse_accumulator_serialization_path(dir).unwrap();
let acc =
Accumulator::NdmSmt(ndm_smt.expect("NDM SMT should have been set in loop"));
let path = DapolTree::parse_serialization_path(dir).unwrap();

let time_start = Instant::now();
acc.serialize(path.clone()).unwrap();
dapol_tree
.expect("DapolTree should have been set in loop")
.serialize(path.clone())
.unwrap();
let serialization_time = time_start.elapsed();

let file_size = std::fs::metadata(path)
Expand Down
8 changes: 4 additions & 4 deletions benches/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,13 @@ pub fn bytes_to_string(num_bytes: usize) -> String {
if n < kb {
format!("{} bytes", num_bytes)
} else if n < mb {
format!("{} kB", n / kb)
format!("{:.3} kB", n as f64 / kb as f64)
} else if n < gb {
format!("{:.2} MB", n as f64 / mb as f64)
format!("{:.3} MB", n as f64 / mb as f64)
} else if n < tb {
format!("{:.2} GB", n as f64 / gb as f64)
format!("{:.3} GB", n as f64 / gb as f64)
} else {
format!("{:.2} TB", n as f64 / tb as f64)
format!("{:.3} TB", n as f64 / tb as f64)
}
}

Expand Down
66 changes: 66 additions & 0 deletions examples/dapol_config_example.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# There are various different accumulator types (e.g. NDM-SMT).
#
# This value must be set.
accumulator_type = "ndm-smt"

# This is a public value that is used to aid the KDF when generating secret
# blinding factors for the Pedersen commitments.
#
# If it is not set then it will be randomly generated.
salt_b = "salt_b"

# This is a public value that is used to aid the KDF when generating secret
# salt values, which are in turn used in the hash function when generating
# node hashes.
#
# If it is not set then it will be randomly generated.
salt_s = "salt_s"

# Height of the tree.
#
# If not set the default height will be used:
# `dapol::Height::default()`.
height = 16

# This is a public value representing the maximum amount that any single
# entity's liability can be, and is used in the range proofs:
# $[0, 2^{\text{height}} \times \text{max_liability}]$
#
# If not set then the default value will be used:
# `2.pow(dapol::DEFAULT_RANGE_PROOF_UPPER_BOUND_BIT_LENGTH)`.
max_liability = 10_000_000

# Max number of threads to be spawned for multi-threading algorithms.
#
# If not set the max parallelism of the underlying machine will be used.
max_thread_count = 8

# Can be a file or directory (default file name given in this case)
#
# If not set then no serialization is done.
serialization_path = "./tree.dapoltree"

# At least one of file_path or generate_random must be present.
#
# If both are given then file_path is preferred and generate_random is ignored.
[entities]

# Path to a file containing a list of entity IDs and their liabilities.
file_path = "./entities_example.csv"

# Generate the given number of entities, with random IDs & liabilities.
# This is useful for testing.
num_random_entities= 100

# At least on of file_path or master_secret must be present.
# The master secret is known only to the tree generator and is used to
# generate all other secret values required by the tree.
#
# If both are given then file_path is preferred and master_secret is ignored.
[secrets]

# Path to a file containing a list of entity IDs and their liabilities.
file_path = "./dapol_secrets_example.toml"

# String value of the master secret.
master_secret = "master_secret"
1 change: 1 addition & 0 deletions examples/dapol_secrets_example.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
master_secret = "master_secret"
Loading