From f4c3faefba3a366aee922660e6cb3aca30af1c64 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 3 Oct 2023 06:00:48 +0100 Subject: [PATCH 1/5] noir merkle insert bench --- flake.lock | 73 +++++- flake.nix | 10 +- noir/Cargo.lock | 229 +++++++++++++++++++ noir/Cargo.toml | 1 + noir/benches/bench.rs | 49 +++++ noir/pkgs/merkle_insert/Nargo.toml | 7 + noir/pkgs/merkle_insert/src/main.nr | 329 ++++++++++++++++++++++++++++ shared/Cargo.lock | 165 +++++++++++++- shared/src/hash.rs | 6 +- shared/src/lib.rs | 32 +++ 10 files changed, 873 insertions(+), 28 deletions(-) create mode 100644 noir/pkgs/merkle_insert/Nargo.toml create mode 100644 noir/pkgs/merkle_insert/src/main.nr diff --git a/flake.lock b/flake.lock index 8bee820..f9a249b 100644 --- a/flake.lock +++ b/flake.lock @@ -1,6 +1,25 @@ { "nodes": { "barretenberg": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + }, + "locked": { + "lastModified": 1694614616, + "narHash": "sha256-Y7UnacsGVlMIiTOwHcU7w1Wae8PHn596VLpbReWLePM=", + "owner": "AztecProtocol", + "repo": "barretenberg", + "rev": "7edb1644d0ae472a70fc3554b7d2cfc6c5496168", + "type": "github" + }, + "original": { + "owner": "AztecProtocol", + "repo": "barretenberg", + "type": "github" + } + }, + "barretenberg_2": { "inputs": { "flake-utils": [ "noir", @@ -75,6 +94,21 @@ } }, "flake-utils": { + "locked": { + "lastModified": 1678901627, + "narHash": "sha256-U02riOqrKKzwjsxc/400XnElV+UtPUQWpANPlyazjH0=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "93a2b84fc4b70d9e089d029deacc3583435c2ed6", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "flake-utils_2": { "inputs": { "systems": "systems" }, @@ -92,7 +126,7 @@ "type": "github" } }, - "flake-utils_2": { + "flake-utils_3": { "inputs": { "systems": "systems_2" }, @@ -110,7 +144,7 @@ "type": "github" } }, - "flake-utils_3": { + "flake-utils_4": { "inputs": { "systems": "systems_3" }, @@ -129,6 +163,22 @@ } }, "nixpkgs": { + "locked": { + "lastModified": 1680498889, + "narHash": "sha256-4nGFBm+oILOO6DPoKTPxVlfkZSxCOY4W25zSRHESK48=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "799d153e4f316143a9db0eb869ecf44d8d4c0356", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-22.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs_2": { "locked": { "lastModified": 1694179405, "narHash": "sha256-L/f5rWT5Yiy3Mux+n5YvK6OWLpC43yXZUSiZll1pjUI=", @@ -143,7 +193,7 @@ "type": "github" } }, - "nixpkgs_2": { + "nixpkgs_3": { "locked": { "lastModified": 1681269223, "narHash": "sha256-i6OeI2f7qGvmLfD07l1Az5iBL+bFeP0RHixisWtpUGo=", @@ -159,7 +209,7 @@ "type": "github" } }, - "nixpkgs_3": { + "nixpkgs_4": { "locked": { "lastModified": 1681358109, "narHash": "sha256-eKyxW4OohHQx9Urxi7TQlFBTDWII+F+x2hklDOQPB50=", @@ -177,11 +227,11 @@ }, "noir": { "inputs": { - "barretenberg": "barretenberg", + "barretenberg": "barretenberg_2", "crane": "crane", "flake-compat": "flake-compat", - "flake-utils": "flake-utils_2", - "nixpkgs": "nixpkgs_2", + "flake-utils": "flake-utils_3", + "nixpkgs": "nixpkgs_3", "rust-overlay": "rust-overlay" }, "locked": { @@ -200,8 +250,9 @@ }, "root": { "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs", + "barretenberg": "barretenberg", + "flake-utils": "flake-utils_2", + "nixpkgs": "nixpkgs_2", "noir": "noir", "rust-overlay": "rust-overlay_2" } @@ -233,8 +284,8 @@ }, "rust-overlay_2": { "inputs": { - "flake-utils": "flake-utils_3", - "nixpkgs": "nixpkgs_3" + "flake-utils": "flake-utils_4", + "nixpkgs": "nixpkgs_4" }, "locked": { "lastModified": 1694139063, diff --git a/flake.nix b/flake.nix index 5b59bcf..d634311 100644 --- a/flake.nix +++ b/flake.nix @@ -5,9 +5,10 @@ flake-utils.url = "github:numtide/flake-utils"; rust-overlay.url = "github:oxalica/rust-overlay"; noir.url = "github:noir-lang/noir"; + barretenberg.url = "github:AztecProtocol/barretenberg"; }; - outputs = { nixpkgs, flake-utils, rust-overlay, ... } @ inputs: + outputs = { nixpkgs, flake-utils, rust-overlay, barretenberg, ... } @ inputs: flake-utils.lib.eachDefaultSystem (system: let pkgs = import nixpkgs { @@ -22,13 +23,14 @@ in { devShells.default = pkgs.mkShell { + # inputsFrom = [ noir.devShells.${system}.default ]; packages = with pkgs; [ - rustup + rustToolchain pkg-config openssl - - noir.packages."${system}".noir-native + + noir.packages."${system}".default ]; RUST_SRC_PATH = "${rustToolchain}/lib/rustlib/src/rust/library"; diff --git a/noir/Cargo.lock b/noir/Cargo.lock index 1ff56ae..55e6a58 100644 --- a/noir/Cargo.lock +++ b/noir/Cargo.lock @@ -197,6 +197,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" + [[package]] name = "arena" version = "0.10.3" @@ -508,6 +514,26 @@ version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" +[[package]] +name = "bytemuck" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965ab7eb5f8f97d2a083c799f3a1b994fc397b2fe2da5d1da1626ce15a39f2b1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "bytes" version = "1.4.0" @@ -797,6 +823,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", "subtle", ] @@ -819,6 +846,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "elf" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2b183d6ce6ca4cf30e3db37abf5b52568b5f9015c97d9fbdd7026aa5dcdd758" + [[package]] name = "elliptic-curve" version = "0.12.3" @@ -854,6 +887,27 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +[[package]] +name = "errno" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "eyre" version = "0.6.8" @@ -864,6 +918,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + [[package]] name = "ff" version = "0.12.1" @@ -1332,6 +1392,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "libm" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" + [[package]] name = "link-cplusplus" version = "1.0.9" @@ -1341,6 +1407,12 @@ dependencies = [ "cc", ] +[[package]] +name = "linux-raw-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" + [[package]] name = "log" version = "0.4.20" @@ -1439,6 +1511,7 @@ dependencies = [ "rand", "serde", "serde_json", + "shared", "tokio", "zstd", ] @@ -1556,6 +1629,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-derive" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e6a0fd4f737c707bd9086cc16c925f294943eb62eb71499e9fd4cf71f8b9f4e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -1725,6 +1809,15 @@ dependencies = [ "rand_core", ] +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "regex" version = "1.9.4" @@ -1819,6 +1912,95 @@ dependencies = [ "winapi", ] +[[package]] +name = "risc0-binfmt" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ede27631e6b2a946a43db812063453c9701d5d2544d82f9abec2cc12574ebb8e" +dependencies = [ + "anyhow", + "elf", + "log", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", +] + +[[package]] +name = "risc0-circuit-rv32im" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68e00222152fdc94cacc9b6682b5c0cbe8138f1ee82e80c24a64d9ad2c6d7415" +dependencies = [ + "anyhow", + "log", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "tracing", +] + +[[package]] +name = "risc0-core" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08605aec93ea22ed83f7f81f42e2d7287a5b0c749d8671f94de9d5994020045c" +dependencies = [ + "bytemuck", + "rand_core", +] + +[[package]] +name = "risc0-zkp" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28166926bb177824939f4e91083198f9f3da8137aeac32361bd34548c0526fa5" +dependencies = [ + "anyhow", + "blake2", + "bytemuck", + "digest", + "hex", + "log", + "paste", + "rand_core", + "risc0-core", + "risc0-zkvm-platform", + "serde", + "sha2", + "tracing", +] + +[[package]] +name = "risc0-zkvm" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec972152bcaa1a2967e412e22a84f6e2984a95c701bcc7943ca8ca10126ee0a2" +dependencies = [ + "anyhow", + "bytemuck", + "cfg-if", + "getrandom", + "hex", + "libm", + "log", + "num-derive", + "risc0-binfmt", + "risc0-circuit-rv32im", + "risc0-core", + "risc0-zkp", + "risc0-zkvm-platform", + "serde", + "tempfile", + "tracing", +] + +[[package]] +name = "risc0-zkvm-platform" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8524b46783b58b00e9b2a4712e837093c975b23cf25bfaf99e1cf69e9011bf6b" + [[package]] name = "rust-embed" version = "6.8.1" @@ -1874,6 +2056,19 @@ dependencies = [ "semver", ] +[[package]] +name = "rustix" +version = "0.38.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + [[package]] name = "rustls" version = "0.21.7" @@ -2070,6 +2265,15 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shared" +version = "0.1.0" +dependencies = [ + "risc0-zkvm", + "serde", + "serde_json", +] + [[package]] name = "shlex" version = "1.1.0" @@ -2212,6 +2416,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + [[package]] name = "termcolor" version = "1.2.0" @@ -2381,9 +2598,21 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" dependencies = [ "cfg-if", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.32", +] + [[package]] name = "tracing-core" version = "0.1.31" diff --git a/noir/Cargo.toml b/noir/Cargo.toml index 7c39c5a..ee358f7 100644 --- a/noir/Cargo.toml +++ b/noir/Cargo.toml @@ -16,6 +16,7 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.0", features = ["io-std"] } zstd = "0.12.4" +shared = { path = "../shared"} [dev-dependencies] benchy = "0.1.1" diff --git a/noir/benches/bench.rs b/noir/benches/bench.rs index 561e1d9..e473433 100644 --- a/noir/benches/bench.rs +++ b/noir/benches/bench.rs @@ -4,6 +4,10 @@ extern crate rand; use benchy::{benchmark, BenchmarkRun}; use noir::{InputMap, InputValue, Proof}; use rand::Rng; +use shared::{ + hash::{random_hashes, HashFn, Sha}, + tree_size_n, Tree, +}; #[benchmark] fn assert(b: &mut BenchmarkRun) { @@ -84,6 +88,51 @@ fn merkle_membership(b: &mut BenchmarkRun) { ); } +#[benchmark("Merkle Insert", [ + ("1k tree", ( tree_size_n(9), tree_size_n(9) )) +])] +fn merkle_insert(b: &mut BenchmarkRun, (tree1, tree2): (Tree, Tree)) { + let backend = noir::backends::ConcreteBackend::default(); + let dir = std::env::current_dir().expect("current dir to exist"); + + let proofs = b.run(|| { + let mut proofs = vec![]; + + let mut tree_before = tree1; + + for node in tree2.leaves() { + let mut leaves = vec![Sha::null(); 1024]; + for (index, hash) in tree_before.leaves().enumerate() { + leaves[index] = hash; + } + + let root_hash = tree_before.digest(); + + let mut inputs = InputMap::new(); + inputs.insert("node".to_string(), node); + inputs.insert("leaves".to_string(), leaves); + inputs.insert("root_hash".to_string(), root_hash); + + let proof = Proof::new(&backend, "sha256", dir.join("pkgs/merkle_insert")); + let proof_bytes = proof.run_and_prove(&inputs); + + proofs.push(proof_bytes); + tree_before.insert(node); + } + + proofs + }); + + // this isn't a real encoding, but it's probably close enough w.r.t. proof size/compressed size + let proof_bytes: Vec<_> = proofs.into_iter().flatten().collect(); + + b.log("proof_size_bytes", proof_bytes.len()); + b.log( + "compressed_proof_size_bytes", + zstd::encode_all(&proof_bytes[..], 21).unwrap().len(), + ); +} + #[benchmark("SHA256", [ ("1k bytes", 1000), ("10k bytes", 10000), diff --git a/noir/pkgs/merkle_insert/Nargo.toml b/noir/pkgs/merkle_insert/Nargo.toml new file mode 100644 index 0000000..e79180d --- /dev/null +++ b/noir/pkgs/merkle_insert/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "merkle_insert" +type = "bin" +authors = [""] +compiler_version = "0.11.1" + +[dependencies] \ No newline at end of file diff --git a/noir/pkgs/merkle_insert/src/main.nr b/noir/pkgs/merkle_insert/src/main.nr new file mode 100644 index 0000000..37f7eb6 --- /dev/null +++ b/noir/pkgs/merkle_insert/src/main.nr @@ -0,0 +1,329 @@ +use dep::std::option::Option; +use dep::std; + +fn main(leaves: [Hash; 1024], root_hash: pub Hash, node: Hash) -> pub Hash { + let tree = parse_tree(leaves); + assert(tree.hash == root_hash); + + let success = tree.insert(node); + + assert(success); + + tree.hash +} + +type Hash = [u8; 32]; +type Leaf = Hash; + +global NULL: Hash = [0; 32]; + +struct Tree1 { + left: Leaf, + right: Leaf, + hash: Hash, +} + +struct Tree2 { + left: Tree1, + right: Tree1, + hash: Hash, +} + +struct Tree3 { + left: Tree2, + right: Tree2, + hash: Hash, +} + +struct Tree4 { + left: Tree3, + right: Tree3, + hash: Hash, +} + +struct Tree5 { + left: Tree4, + right: Tree4, + hash: Hash, +} + +struct Tree6 { + left: Tree5, + right: Tree5, + hash: Hash, +} + +struct Tree7 { + left: Tree6, + right: Tree6, + hash: Hash, +} + +struct Tree8 { + left: Tree7, + right: Tree7, + hash: Hash, +} + +struct Tree9 { + left: Tree8, + right: Tree8, + hash: Hash, +} + +struct Tree10 { + left: Tree9, + right: Tree9, + hash: Hash, +} + +impl Tree10 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree9 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree8 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree7 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree6 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree5 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree4 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + + +impl Tree3 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree2 { + fn insert(mut self, hash: Hash) -> bool { + let success = self.left.insert(hash); + if success { + true + } else { + self.right.insert(hash) + } + } +} + +impl Tree1 { + fn insert(mut self, hash: Hash) -> bool { + if self.left == NULL { + self.left = hash; + true + } else if self.right == NULL { + self.right = hash; + true + } else { + false + } + } +} + + + +fn merge_hash(a: Hash, b: Hash) -> Hash { + let mut buf = [0; 64]; + + for i in 0..32 { + buf[i] = a[i]; + buf[i + 32] = b[i]; + } + + std::hash::sha256(buf) +} + +fn parse_tree(leaves: [Hash; 1024]) -> Tree10 { + + // tree1s + + let mut tree1s = [Option::none(); 512]; + + for i in 0..512 { + let left = leaves[i * 2]; + let right = leaves[( i * 2 ) + 1]; + let hash = merge_hash(left, right); + + tree1s[i] = Option::some(Tree1 { left, right, hash }); + } + + // tree2s + + let mut tree2s = [Option::none(); 256]; + + for i in 0..256 { + let left = tree1s[i * 2].unwrap(); + let right = tree1s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree2s[i] = Option::some(Tree2 { left, right, hash }); + } + + // tree3s + + let mut tree3s = [Option::none(); 128]; + + for i in 0..128 { + let left = tree2s[i * 2].unwrap(); + let right = tree2s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree3s[i] = Option::some(Tree3 { left, right, hash }); + } + + // tree4s + + let mut tree4s = [Option::none(); 64]; + + for i in 0..64 { + let left = tree3s[i * 2].unwrap(); + let right = tree3s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree4s[i] = Option::some(Tree4 { left, right, hash }); + } + + // tree5s + + let mut tree5s = [Option::none(); 32]; + + for i in 0..32 { + let left = tree4s[i * 2].unwrap(); + let right = tree4s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree5s[i] = Option::some(Tree5 { left, right, hash }); + } + + // tree6s + + let mut tree6s = [Option::none(); 16]; + + for i in 0..16 { + let left = tree5s[i * 2].unwrap(); + let right = tree5s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree6s[i] = Option::some(Tree6 { left, right, hash }); + } + + // tree7s + + let mut tree7s = [Option::none(); 8]; + + for i in 0..8 { + let left = tree6s[i * 2].unwrap(); + let right = tree6s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree7s[i] = Option::some(Tree7 { left, right, hash }); + } + + // tree8s + + let mut tree8s = [Option::none(); 4]; + + for i in 0..4 { + let left = tree7s[i * 2].unwrap(); + let right = tree7s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree8s[i] = Option::some(Tree8 { left, right, hash }); + } + + // tree9s + + let mut tree9s = [Option::none(); 2]; + + for i in 0..2 { + let left = tree8s[i * 2].unwrap(); + let right = tree8s[( i * 2 ) + 1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + tree9s[i] = Option::some(Tree9 { left, right, hash }); + } + + let left = tree9s[0].unwrap(); + let right = tree9s[1].unwrap(); + let hash = merge_hash(left.hash, right.hash); + + Tree10 { left, right, hash } +} + + + + + + + diff --git a/shared/Cargo.lock b/shared/Cargo.lock index 5b4f7a8..8b3514c 100644 --- a/shared/Cargo.lock +++ b/shared/Cargo.lock @@ -20,6 +20,18 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + [[package]] name = "blake2" version = "0.10.6" @@ -136,6 +148,27 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2b183d6ce6ca4cf30e3db37abf5b52568b5f9015c97d9fbdd7026aa5dcdd758" +[[package]] +name = "errno" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" +dependencies = [ + "errno-dragonfly", + "libc", + "windows-sys", +] + +[[package]] +name = "errno-dragonfly" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" +dependencies = [ + "cc", + "libc", +] + [[package]] name = "fastrand" version = "2.0.0" @@ -196,6 +229,12 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +[[package]] +name = "linux-raw-sys" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" + [[package]] name = "log" version = "0.4.20" @@ -261,11 +300,20 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +[[package]] +name = "redox_syscall" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" +dependencies = [ + "bitflags 1.3.2", +] + [[package]] name = "risc0-binfmt" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47552e56df694790ef3fc91b4e0bb40de97f1ad6916e8545a17b6740f40c31fb" +checksum = "ede27631e6b2a946a43db812063453c9701d5d2544d82f9abec2cc12574ebb8e" dependencies = [ "anyhow", "elf", @@ -277,9 +325,9 @@ dependencies = [ [[package]] name = "risc0-circuit-rv32im" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbb3685e42e4bf1e987b8f52de3606eb26792f4fe76d3ae07c5530b8fac14884" +checksum = "68e00222152fdc94cacc9b6682b5c0cbe8138f1ee82e80c24a64d9ad2c6d7415" dependencies = [ "anyhow", "log", @@ -291,9 +339,9 @@ dependencies = [ [[package]] name = "risc0-core" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16ef34344403c55e33095513948ab4f4e034ce5cb940d62470b58d44618603d3" +checksum = "08605aec93ea22ed83f7f81f42e2d7287a5b0c749d8671f94de9d5994020045c" dependencies = [ "bytemuck", "rand_core", @@ -301,9 +349,9 @@ dependencies = [ [[package]] name = "risc0-zkp" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd3454c4dfb4573178e7d802c0969e658f0bf38e793948b7d77cb57455a52993" +checksum = "28166926bb177824939f4e91083198f9f3da8137aeac32361bd34548c0526fa5" dependencies = [ "anyhow", "blake2", @@ -322,9 +370,9 @@ dependencies = [ [[package]] name = "risc0-zkvm" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3363c73f05de3d3474b1796ebce5c19094820bc155f808f3172864991964758f" +checksum = "ec972152bcaa1a2967e412e22a84f6e2984a95c701bcc7943ca8ca10126ee0a2" dependencies = [ "anyhow", "bytemuck", @@ -340,14 +388,28 @@ dependencies = [ "risc0-zkp", "risc0-zkvm-platform", "serde", + "tempfile", "tracing", ] [[package]] name = "risc0-zkvm-platform" -version = "0.17.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be7dfd4644e051a450f2d4acecb37409fbdfb9a520cd6e96da3b17d415b92771" +checksum = "8524b46783b58b00e9b2a4712e837093c975b23cf25bfaf99e1cf69e9011bf6b" + +[[package]] +name = "rustix" +version = "0.38.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7db8590df6dfcd144d22afd1b83b36c21a18d7cbc1dc4bb5295a8712e9eb662" +dependencies = [ + "bitflags 2.4.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] [[package]] name = "ryu" @@ -435,6 +497,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall", + "rustix", + "windows-sys", +] + [[package]] name = "tracing" version = "0.1.37" @@ -488,6 +563,72 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + [[package]] name = "winter-crypto" version = "0.6.4" diff --git a/shared/src/hash.rs b/shared/src/hash.rs index 8b6b6c1..a658155 100644 --- a/shared/src/hash.rs +++ b/shared/src/hash.rs @@ -2,7 +2,7 @@ use risc0_zkvm::sha::{self, Sha256}; use serde::{Deserialize, Serialize}; pub trait HashFn: Clone { - type Digest: Copy; + type Digest: Eq + Copy + 'static; fn merge(a: Self::Digest, b: Self::Digest) -> Self::Digest; @@ -11,6 +11,10 @@ pub trait HashFn: Clone { fn null() -> Self::Digest; } +pub fn random_hashes() -> [H::Digest; N] { + core::array::from_fn(|_| H::random()) +} + #[cfg(feature = "std")] pub mod rpo { diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 1b6ebbe..f6ddab8 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -94,6 +94,13 @@ impl Tree { } } + pub fn leaves(&self) -> Box> { + match self { + Tree::Leaf(hash) => Box::new(once(*hash)), + Tree::Node { left, right, .. } => Box::new(left.leaves().chain(right.leaves())), + } + } + pub fn to_json(&self) -> String where H::Digest: Serialize, @@ -107,6 +114,31 @@ impl Tree { { serde_json::from_str(s).ok() } + + pub fn insert(&mut self, hash: H::Digest) -> bool { + match self { + Self::Leaf(leaf) if *leaf == H::null() => { + *leaf = hash; + true + } + Self::Leaf(_) => false, + Self::Node { + left, + right, + digest, + } => { + let result = if left.insert(hash) { + false + } else { + right.insert(hash) + }; + + *digest = H::merge(left.digest(), right.digest()); + + result + } + } + } } /// actually 2^n From 73dfa937ce477f9188353c7be4cb563cc290fea5 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 3 Oct 2023 06:10:39 +0100 Subject: [PATCH 2/5] fix input values --- noir/benches/bench.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/noir/benches/bench.rs b/noir/benches/bench.rs index e473433..185d51c 100644 --- a/noir/benches/bench.rs +++ b/noir/benches/bench.rs @@ -106,12 +106,24 @@ fn merkle_insert(b: &mut BenchmarkRun, (tree1, tree2): (Tree, Tree)) { leaves[index] = hash; } + let leaves = leaves + .into_iter() + .map(|hash| InputValue::Vec(hash.as_bytes().to_vec())) + .collect(); + let leaves = InputValue::Vec(leaves); + let root_hash = tree_before.digest(); let mut inputs = InputMap::new(); - inputs.insert("node".to_string(), node); + inputs.insert( + "node".to_string(), + InputValue::Vec(node.as_bytes().to_vec()), + ); inputs.insert("leaves".to_string(), leaves); - inputs.insert("root_hash".to_string(), root_hash); + inputs.insert( + "root_hash".to_string(), + InputValue::Vec(root_hash.as_bytes().to_vec()), + ); let proof = Proof::new(&backend, "sha256", dir.join("pkgs/merkle_insert")); let proof_bytes = proof.run_and_prove(&inputs); From bfe69e166c7f610455828b1896ff07672515a1d9 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 3 Oct 2023 06:21:55 +0100 Subject: [PATCH 3/5] fix input values --- noir/benches/bench.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/noir/benches/bench.rs b/noir/benches/bench.rs index 185d51c..9f6ffce 100644 --- a/noir/benches/bench.rs +++ b/noir/benches/bench.rs @@ -1,6 +1,7 @@ extern crate noir; extern crate rand; +use acvm::FieldElement; use benchy::{benchmark, BenchmarkRun}; use noir::{InputMap, InputValue, Proof}; use rand::Rng; @@ -108,21 +109,18 @@ fn merkle_insert(b: &mut BenchmarkRun, (tree1, tree2): (Tree, Tree)) { let leaves = leaves .into_iter() - .map(|hash| InputValue::Vec(hash.as_bytes().to_vec())) + .map(|hash| slice_to_input(hash.as_bytes())) .collect(); let leaves = InputValue::Vec(leaves); let root_hash = tree_before.digest(); let mut inputs = InputMap::new(); - inputs.insert( - "node".to_string(), - InputValue::Vec(node.as_bytes().to_vec()), - ); + inputs.insert("node".to_string(), slice_to_input(node.as_bytes())); inputs.insert("leaves".to_string(), leaves); inputs.insert( "root_hash".to_string(), - InputValue::Vec(root_hash.as_bytes().to_vec()), + slice_to_input(root_hash.as_bytes()), ); let proof = Proof::new(&backend, "sha256", dir.join("pkgs/merkle_insert")); @@ -182,4 +180,16 @@ fn generate_random_u8_slice(len: usize) -> Vec { vec } +fn slice_to_input(slice: &[u8]) -> InputValue { + let vec = slice + .iter() + .map(|i| { + let i = u128::from(*i); + InputValue::Field(i.into()) + }) + .collect(); + + InputValue::Vec(vec) +} + benchy::main!("noir", assert, fibonacci, sha256, merkle_membership); From f19d1f135463ba83c05fbe6faf45157c0a6b5e5e Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 3 Oct 2023 06:35:36 +0100 Subject: [PATCH 4/5] actually run the bench :)))))) --- noir/benches/bench.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/noir/benches/bench.rs b/noir/benches/bench.rs index 9f6ffce..9313cf5 100644 --- a/noir/benches/bench.rs +++ b/noir/benches/bench.rs @@ -192,4 +192,11 @@ fn slice_to_input(slice: &[u8]) -> InputValue { InputValue::Vec(vec) } -benchy::main!("noir", assert, fibonacci, sha256, merkle_membership); +benchy::main!( + "noir", + assert, + fibonacci, + sha256, + merkle_membership, + merkle_insert +); From 87150d8a637f16d1b66f84fe3bab33b60ba01b52 Mon Sep 17 00:00:00 2001 From: Cameron Date: Tue, 3 Oct 2023 06:44:08 +0100 Subject: [PATCH 5/5] enable std feature --- noir/Cargo.lock | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ noir/Cargo.toml | 2 +- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/noir/Cargo.lock b/noir/Cargo.lock index 55e6a58..abe3baa 100644 --- a/noir/Cargo.lock +++ b/noir/Cargo.lock @@ -328,6 +328,18 @@ dependencies = [ "rand", ] +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "async-trait" version = "0.1.73" @@ -477,6 +489,19 @@ dependencies = [ "digest", ] +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + [[package]] name = "block-buffer" version = "0.10.4" @@ -705,6 +730,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + [[package]] name = "core-foundation-sys" version = "0.8.4" @@ -1435,6 +1466,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "miden-crypto" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf95db953ee5fc8ef5a1df2d2e6e55e41587861c793fa26b45a214d3cc0f798" +dependencies = [ + "blake3", + "winter-crypto", + "winter-math", + "winter-utils", +] + [[package]] name = "mime" version = "0.3.17" @@ -2269,6 +2312,8 @@ dependencies = [ name = "shared" version = "0.1.0" dependencies = [ + "fastrand", + "miden-crypto", "risc0-zkvm", "serde", "serde_json", @@ -2963,6 +3008,33 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "winter-crypto" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a20b2a4499797cbaeb38c980f9f34e6e60d993e8e170a6deb354345f50cbfb" +dependencies = [ + "blake3", + "sha3", + "winter-math", + "winter-utils", +] + +[[package]] +name = "winter-math" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1795f5323f03c987a6aada6e8229f2c7f9353956cfa1b648b9c6cf5440958caa" +dependencies = [ + "winter-utils", +] + +[[package]] +name = "winter-utils" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b903fda6a50cce2aa5a172a9269aca0f09b25df20afb1faa427db76d40779671" + [[package]] name = "zeroize" version = "1.6.0" diff --git a/noir/Cargo.toml b/noir/Cargo.toml index ee358f7..9661d4f 100644 --- a/noir/Cargo.toml +++ b/noir/Cargo.toml @@ -16,7 +16,7 @@ serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } tokio = { version = "1.0", features = ["io-std"] } zstd = "0.12.4" -shared = { path = "../shared"} +shared = { path = "../shared", features = ["std"] } [dev-dependencies] benchy = "0.1.1"