From d613c79584a599f4adbd11d2ce3b61403c185b73 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 19 May 2023 12:56:54 +0100 Subject: [PATCH] feat!: Update to acvm 0.12.0 (#165) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat!: update to target acvm-84b5d18d * chore: update to use new black box solver interface * use patch syntax * update to latest changes * feat!: update to acvm with non-homogeneous bb calls (#169) * feat: update acvm * feat!: updated acvm to latest master * chore: update cargo toml * Update src/barretenberg_structures.rs Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> --------- Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> * fix bad rebase * feat!: Update backend to rely on WitnessMap (#152) Co-authored-by: Tom French * update acvm * feat!: Implement CommonReferenceString trait (#139) * chore!: Remove filesystem access and utilize async fetch with range requests Co-authored-by: Tom French * chore: Switch to tokio test macro for async function (#191) * chore: Remove `sled` & `tempfile` dev-dependencies (#190) * chore: Remove sled & tempfile dev-dependencies * chore: space out functions --------- Co-authored-by: Tom French * chore: bump to crates.io release * Update src/crs.rs * chore: Remove streaming CRS download & indicator (#194) * Update src/acvm_interop/common_reference_string.rs * code review --------- Co-authored-by: Blaine Bublitz Co-authored-by: Álvaro Rodríguez --- Cargo.lock | 289 +++++-------- Cargo.toml | 41 +- cspell.json | 3 +- flake.nix | 41 +- src/acvm_interop/common_reference_string.rs | 34 ++ src/acvm_interop/mod.rs | 1 + src/acvm_interop/proof_system.rs | 78 ++-- src/acvm_interop/pwg.rs | 446 +++++++++++--------- src/acvm_interop/pwg/merkle.rs | 6 +- src/acvm_interop/smart_contract.rs | 104 +++-- src/barretenberg_structures.rs | 276 ++++++------ src/composer.rs | 140 +++--- src/crs.rs | 263 ++++++------ src/lib.rs | 27 ++ src/merkle.rs | 10 +- 15 files changed, 917 insertions(+), 842 deletions(-) create mode 100644 src/acvm_interop/common_reference_string.rs diff --git a/Cargo.lock b/Cargo.lock index 25400755..de104a3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,21 +4,22 @@ version = 3 [[package]] name = "acir" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "084577e67b44c72d1cdfabe286d48adac6f5e0ad441ef134c5c467f4b6eee291" +checksum = "c831802bad8d6810bfdb57cd00913157dfe710a185dc360c9a94eecd043bbf12" dependencies = [ "acir_field", "flate2", "rmp-serde", "serde", + "thiserror", ] [[package]] name = "acir_field" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a267ef529f4b132293199ecdf8c232ade817f01d916039f2d34562cab39e75e9" +checksum = "d455746f51b4421548e42d34e2ce46b6db637cb048095d78766612d26bf526db" dependencies = [ "ark-bn254", "ark-ff", @@ -30,19 +31,19 @@ dependencies = [ [[package]] name = "acvm" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e1d6795105b50b13fa0dd1779b5191c4d8e9cd98b357b0b9a0b04a847baacf0" +checksum = "fd8e75cf737b52195a8c109e0ee776e468e1c2ec42f0f88aa4465cd76a09b4ed" dependencies = [ "acir", "acvm_stdlib", + "async-trait", "blake2", - "crc32fast", "indexmap", "k256", "num-bigint", "num-traits", - "sha2 0.9.9", + "sha2 0.10.6", "sha3", "thiserror", ] @@ -53,14 +54,14 @@ version = "0.1.2" dependencies = [ "acvm", "barretenberg-sys", + "bincode", "blake2", - "dirs 3.0.2", - "futures-util", + "bytesize", "getrandom", - "indicatif", "pkg-config", "reqwest", "rust-embed", + "serde", "thiserror", "tokio", "wasmer", @@ -68,9 +69,9 @@ dependencies = [ [[package]] name = "acvm_stdlib" -version = "0.11.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3131af53d17ac12340c0ff50f8555d8e040321f8078b8ee3cd8846560b6a44a9" +checksum = "a2e87549b987593eeb1902990006443f2fe5817db927035f081008e4b8a46a49" dependencies = [ "acir", ] @@ -176,7 +177,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" dependencies = [ "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -189,7 +190,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -225,7 +226,7 @@ checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -238,6 +239,17 @@ dependencies = [ "rand", ] +[[package]] +name = "async-trait" +version = "0.1.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9ccdd8f2a161be9bd5c023df56f1b2a0bd1d83872ae53b71a84a12c9bf6e842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -254,7 +266,7 @@ dependencies = [ "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.6.2", "object 0.30.3", "rustc-demangle", ] @@ -279,6 +291,15 @@ version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bindgen" version = "0.64.0" @@ -297,7 +318,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn", + "syn 1.0.107", "which", ] @@ -320,13 +341,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.9.2" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a4e37d16930f5459780f5621038b6382b9bb37c19016f39fb6b5808d831f174" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" dependencies = [ - "crypto-mac 0.8.0", - "digest 0.9.0", - "opaque-debug", + "digest 0.10.6", ] [[package]] @@ -335,7 +354,6 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" dependencies = [ - "block-padding", "generic-array", ] @@ -348,12 +366,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-padding" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" - [[package]] name = "bstr" version = "1.3.0" @@ -388,7 +400,7 @@ checksum = "13e576ebe98e605500b3c8041bb888e966653577172df6dd97398714eb30b9bf" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -403,6 +415,12 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "bytesize" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38fcc2979eff34a4b84e1cf9a1e3da42a7d44b3b690a40cdcb23e3d556cfb2e5" + [[package]] name = "cc" version = "1.0.79" @@ -462,19 +480,6 @@ dependencies = [ "tracing-error", ] -[[package]] -name = "console" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3d79fbe8970a77e3e34151cc13d3b3e248aa0faaecb9f6091fa07ebefe5ad60" -dependencies = [ - "encode_unicode", - "lazy_static", - "libc", - "unicode-width", - "windows-sys 0.42.0", -] - [[package]] name = "const-oid" version = "0.4.5" @@ -624,16 +629,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" -dependencies = [ - "generic-array", - "subtle", -] - [[package]] name = "crypto-mac" version = "0.10.1" @@ -664,7 +659,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -675,7 +670,7 @@ checksum = "b36230598a2d5de7ec1c6f51f72d8a99a9208daff41de2084d06e3fd3ea56685" dependencies = [ "darling_core", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -695,7 +690,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -715,15 +710,7 @@ checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" dependencies = [ "block-buffer 0.10.4", "crypto-common", -] - -[[package]] -name = "dirs" -version = "3.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30baa043103c9d0c2a57cf537cc2f35623889dc0d405e6c3cccfadbc81c71309" -dependencies = [ - "dirs-sys", + "subtle", ] [[package]] @@ -781,12 +768,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "encode_unicode" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" - [[package]] name = "encoding_rs" version = "0.8.32" @@ -813,7 +794,7 @@ checksum = "c134c37760b27a871ba422106eedbb8247da973a09e82558bf26d619c882b159" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -834,7 +815,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -875,12 +856,12 @@ dependencies = [ [[package]] name = "flate2" -version = "1.0.25" +version = "1.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841" +checksum = "3b9429470923de8e8cbd4d2dc513535400b4b3fef0319fb5c4e1f520a7bef743" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.7.1", ] [[package]] @@ -919,23 +900,6 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec90ff4d0fe1f57d600049061dc6bb68ed03c7d2fbd697274c41805dcb3f8608" -[[package]] -name = "futures-io" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfb8371b6fb2aeb2d280374607aeabfc99d95c72edfe51692e42d3d7f0d08531" - -[[package]] -name = "futures-macro" -version = "0.3.26" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95a73af87da33b5acf53acfebdc339fe592ecf5357ac7c0a7734ab9d8c876a70" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - [[package]] name = "futures-sink" version = "0.3.26" @@ -955,14 +919,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c1d6de3acfef38d2be4b1f543f553131788603495be83da675e180c8d6b7bd1" dependencies = [ "futures-core", - "futures-io", - "futures-macro", - "futures-sink", "futures-task", - "memchr", "pin-project-lite", "pin-utils", - "slab", ] [[package]] @@ -1100,7 +1059,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1441c6b1e930e2817404b5046f1f989899143a12bf92de603b69f4e0aee1e15" dependencies = [ - "crypto-mac 0.10.1", + "crypto-mac", "digest 0.9.0", ] @@ -1208,18 +1167,6 @@ dependencies = [ "serde", ] -[[package]] -name = "indicatif" -version = "0.17.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef509aa9bc73864d6756f0d34d35504af3cf0844373afe9b8669a5b8005a729" -dependencies = [ - "console", - "number_prefix", - "portable-atomic", - "unicode-width", -] - [[package]] name = "instant" version = "0.1.12" @@ -1350,7 +1297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0fbfc88337168279f2e9ae06e157cfed4efd3316e14dc96ed074d4f2e6c5952" dependencies = [ "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1416,6 +1363,15 @@ dependencies = [ "adler", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.6" @@ -1484,12 +1440,6 @@ dependencies = [ "libc", ] -[[package]] -name = "number_prefix" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" - [[package]] name = "object" version = "0.28.4" @@ -1574,12 +1524,6 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ac9a59f73473f1b8d852421e59e64809f025994837ef743615c6d0c5b305160" -[[package]] -name = "portable-atomic" -version = "0.3.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26f6a7b87c2e435a3241addceeeff740ff8b7e76b74c13bf9acb17fa454ea00b" - [[package]] name = "ppv-lite86" version = "0.2.17" @@ -1595,7 +1539,7 @@ dependencies = [ "proc-macro-error-attr", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "version_check", ] @@ -1612,9 +1556,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.51" +version = "1.0.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" +checksum = "c4ec6d5fe0b140acb27c9a0444118cf55bfbb4e0b259739429abb4521dd67c16" dependencies = [ "unicode-ident", ] @@ -1636,14 +1580,14 @@ checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] name = "quote" -version = "1.0.23" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "8f4f29d145265ec1c483c7c654450edde0bfe043d3938d6972630663356d9500" dependencies = [ "proc-macro2", ] @@ -1816,12 +1760,10 @@ dependencies = [ "serde_urlencoded", "tokio", "tokio-rustls", - "tokio-util", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", - "wasm-streams", "web-sys", "webpki-roots", "winreg", @@ -1864,7 +1806,7 @@ checksum = "ff26ed6c7c4dfc2aa9480b86a60e3c7233543a270a680e10758a507c5a4ce476" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -1910,7 +1852,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn", + "syn 1.0.107", "walkdir", ] @@ -2042,7 +1984,7 @@ checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2094,14 +2036,12 @@ dependencies = [ [[package]] name = "sha3" -version = "0.9.1" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81199417d4e5de3f04b1e871023acea7389672c4135918f05aa9cbf2f2fa809" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ - "block-buffer 0.9.0", - "digest 0.9.0", + "digest 0.10.6", "keccak", - "opaque-debug", ] [[package]] @@ -2119,7 +2059,7 @@ version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ccc8076840c4da029af4f87e4e8daeb0fca6b87bbb02e10cb60b791450e11e4" dependencies = [ - "dirs 4.0.0", + "dirs", ] [[package]] @@ -2192,6 +2132,17 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6f671d4b5ffdb8eadec19c0ae67fe2639df8684bd7bc4b83d986b8db549cf01" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "synstructure" version = "0.12.6" @@ -2200,7 +2151,7 @@ checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "unicode-xid", ] @@ -2241,7 +2192,7 @@ checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2281,9 +2232,21 @@ dependencies = [ "mio", "pin-project-lite", "socket2", + "tokio-macros", "windows-sys 0.45.0", ] +[[package]] +name = "tokio-macros" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61a573bdc87985e9d6ddeed1b3d864e8a302c847e40d647746df2f1de209d1ce" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.16", +] + [[package]] name = "tokio-rustls" version = "0.23.4" @@ -2336,7 +2299,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2492,7 +2455,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-shared", ] @@ -2526,7 +2489,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2546,19 +2509,6 @@ dependencies = [ "leb128", ] -[[package]] -name = "wasm-streams" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6bbae3363c08332cadccd13b67db371814cd214c2524020932f0804b8cf7c078" -dependencies = [ - "futures-util", - "js-sys", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", -] - [[package]] name = "wasmer" version = "2.3.0" @@ -2647,7 +2597,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn", + "syn 1.0.107", ] [[package]] @@ -2902,21 +2852,6 @@ dependencies = [ "windows_x86_64_msvc 0.33.0", ] -[[package]] -name = "windows-sys" -version = "0.42.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc 0.42.1", - "windows_i686_gnu 0.42.1", - "windows_i686_msvc 0.42.1", - "windows_x86_64_gnu 0.42.1", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc 0.42.1", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -3045,6 +2980,6 @@ checksum = "44bf07cb3e50ea2003396695d58bf46bc9887a1f362260446fad6bc4e79bd36c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 1.0.107", "synstructure", ] diff --git a/Cargo.toml b/Cargo.toml index 6e1c5302..4ff06804 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,19 +10,13 @@ license = "MIT OR Apache-2.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -acvm = { version = "0.11.0", features = ["bn254"] } +acvm = { version = "0.12.0", features = ["bn254"] } +bincode = "1.3.3" +bytesize = "1.2" +reqwest = { version = "0.11.16", default-features = false, features = ["rustls-tls"] } +serde = { version = "1.0.136", features = ["derive"] } thiserror = "1.0.21" -blake2 = "0.9.1" -dirs = { version = "3.0", optional = true } -reqwest = { version = "0.11.16", optional = true, default-features = false, features = [ - "stream", - "rustls-tls", -] } -tokio = { version = "1.0", optional = true } -futures-util = { version = "0.3.14", optional = true } -indicatif = { version = "0.17.3", optional = true } - # Native barretenberg-sys = { version = "0.1.2", optional = true } @@ -38,15 +32,14 @@ getrandom = { version = "0.2", optional = true } [build-dependencies] pkg-config = "0.3" +[dev-dependencies] +blake2 = "0.10.6" +tokio = { version = "1.0", features = [ "macros" ] } + [features] default = ["native"] native = [ - "dep:barretenberg-sys", - "dep:reqwest", - "dep:tokio", - "dep:futures-util", - "dep:dirs", - "dep:indicatif", + "dep:barretenberg-sys" ] wasm = [ "wasmer", @@ -56,11 +49,11 @@ wasm = [ "wasmer/cranelift", "wasmer/default-compiler", "wasmer/default-cranelift", - "wasmer/default-universal", - "dep:reqwest", - "dep:tokio", - "dep:futures-util", - "dep:dirs", - "dep:indicatif", + "wasmer/default-universal" +] +js = [ + "wasmer", + "dep:rust-embed", + "dep:getrandom", + "wasmer/js-default" ] -js = ["wasmer", "dep:rust-embed", "dep:getrandom", "wasmer/js-default"] diff --git a/cspell.json b/cspell.json index 1904bf5e..304e6db4 100644 --- a/cspell.json +++ b/cspell.json @@ -55,6 +55,7 @@ "envrc", "subshell", "thiserror", + "bincode", // In Solidity // "addmod", @@ -72,7 +73,7 @@ "acir", "acvm", "barretenberg", - "indicatif", + "bytesize", "wasmer", "getrandom" ] diff --git a/flake.nix b/flake.nix index 25f3b62a..a477a70b 100644 --- a/flake.nix +++ b/flake.nix @@ -75,10 +75,6 @@ # Note: Setting this allows for consistent behavior across build and shells, but is mostly # hidden from the developer - i.e. when they see the command being run via `nix flake check` RUST_TEST_THREADS = "1"; - - # We provide `barretenberg-transcript00` from the overlay to the build. - # This is necessary because the Nix sandbox is read-only and downloading during tests would fail - BARRETENBERG_TRANSCRIPT = pkgs.barretenberg-transcript00; }; nativeEnvironment = sharedEnvironment // { @@ -153,6 +149,27 @@ buildInputs = [ ] ++ extraBuildInputs; }; + # The `port` is parameterized to support parallel test runs without colliding static servers + networkTestArgs = port: { + # We provide `barretenberg-transcript00` from the overlay to the tests as a URL hosted via a static server + # This is necessary because the Nix sandbox has no network access and downloading during tests would fail + TRANSCRIPT_URL = "http://0.0.0.0:${toString port}/${builtins.baseNameOf pkgs.barretenberg-transcript00}"; + + # This copies the `barretenberg-transcript00` from the Nix store into this sandbox + # which avoids exposing the entire Nix store to the static server it starts + # The static server is moved to the background and killed after checks are completed + preCheck = '' + cp ${pkgs.barretenberg-transcript00} . + echo "Starting simple static server" + ${pkgs.simple-http-server}/bin/simple-http-server --port ${toString port} --silent & + HTTP_SERVER_PID=$! + ''; + + postCheck = '' + kill $HTTP_SERVER_PID + ''; + }; + # Build *just* the cargo dependencies, so we can reuse all of that work between runs native-cargo-artifacts = craneLib.buildDepsOnly nativeArgs; wasm-cargo-artifacts = craneLib.buildDepsOnly wasmArgs; @@ -167,12 +184,18 @@ rec { checks = { cargo-clippy-native = craneLib.cargoClippy (nativeArgs // { + # Crane appends "clippy" + pname = "native"; + cargoArtifacts = native-cargo-artifacts; cargoClippyExtraArgs = "--all-targets -- -D warnings"; }); - cargo-test-native = craneLib.cargoTest (nativeArgs // { + cargo-test-native = craneLib.cargoTest (nativeArgs // (networkTestArgs 8000) // { + # Crane appends "test" + pname = "native"; + cargoArtifacts = native-cargo-artifacts; # It's unclear why doCheck needs to be enabled for tests to run but not clippy @@ -180,12 +203,18 @@ }); cargo-clippy-wasm = craneLib.cargoClippy (wasmArgs // { + # Crane appends "clippy" + pname = "wasm"; + cargoArtifacts = wasm-cargo-artifacts; cargoClippyExtraArgs = "--all-targets -- -D warnings"; }); - cargo-test-wasm = craneLib.cargoTest (wasmArgs // { + cargo-test-wasm = craneLib.cargoTest (wasmArgs // (networkTestArgs 8001) // { + # Crane appends "test" + pname = "wasm"; + cargoArtifacts = wasm-cargo-artifacts; # It's unclear why doCheck needs to be enabled for tests to run but not clippy diff --git a/src/acvm_interop/common_reference_string.rs b/src/acvm_interop/common_reference_string.rs new file mode 100644 index 00000000..2122ce00 --- /dev/null +++ b/src/acvm_interop/common_reference_string.rs @@ -0,0 +1,34 @@ +use acvm::{acir::circuit::Circuit, async_trait, CommonReferenceString}; + +use crate::{composer::Composer, BackendError, Barretenberg}; + +// TODO(#185): Ensure CRS download works in JS +#[async_trait] +impl CommonReferenceString for Barretenberg { + type Error = BackendError; + + async fn generate_common_reference_string( + &self, + circuit: &Circuit, + ) -> Result, Self::Error> { + let constraint_system = &circuit.try_into()?; + let common_reference_string = self.get_crs(constraint_system).await?.try_into()?; + // Separated to have nicer coercion on error types + Ok(common_reference_string) + } + + async fn update_common_reference_string( + &self, + common_reference_string: Vec, + circuit: &Circuit, + ) -> Result, Self::Error> { + let mut crs = common_reference_string.try_into()?; + let constraint_system = &circuit.try_into()?; + let common_reference_string = self + .update_crs(&mut crs, constraint_system) + .await? + .try_into()?; + // Separated to have nicer coercion on error types + Ok(common_reference_string) + } +} diff --git a/src/acvm_interop/mod.rs b/src/acvm_interop/mod.rs index b63a6422..010bacc6 100644 --- a/src/acvm_interop/mod.rs +++ b/src/acvm_interop/mod.rs @@ -1,5 +1,6 @@ use crate::Barretenberg; +mod common_reference_string; mod proof_system; mod pwg; mod smart_contract; diff --git a/src/acvm_interop/proof_system.rs b/src/acvm_interop/proof_system.rs index 613bc25f..74d670ea 100644 --- a/src/acvm_interop/proof_system.rs +++ b/src/acvm_interop/proof_system.rs @@ -1,11 +1,9 @@ -use acvm::acir::{circuit::Circuit, native_types::Witness, BlackBoxFunc}; +use acvm::acir::circuit::Opcode; +use acvm::acir::{circuit::Circuit, native_types::WitnessMap, BlackBoxFunc}; use acvm::FieldElement; use acvm::{Language, ProofSystemCompiler}; -use std::collections::BTreeMap; -use crate::barretenberg_structures::Assignments; -use crate::composer::Composer; -use crate::{BackendError, Barretenberg}; +use crate::{barretenberg_structures::Assignments, composer::Composer, BackendError, Barretenberg}; impl ProofSystemCompiler for Barretenberg { type Error = BackendError; @@ -21,58 +19,77 @@ impl ProofSystemCompiler for Barretenberg { )?) } - fn black_box_function_supported(&self, opcode: &BlackBoxFunc) -> bool { + fn supports_opcode(&self, opcode: &Opcode) -> bool { match opcode { - BlackBoxFunc::AND - | BlackBoxFunc::XOR - | BlackBoxFunc::RANGE - | BlackBoxFunc::SHA256 - | BlackBoxFunc::Blake2s - | BlackBoxFunc::Keccak256 - | BlackBoxFunc::ComputeMerkleRoot - | BlackBoxFunc::SchnorrVerify - | BlackBoxFunc::Pedersen - | BlackBoxFunc::HashToField128Security - | BlackBoxFunc::EcdsaSecp256k1 - | BlackBoxFunc::FixedBaseScalarMul => true, - - BlackBoxFunc::AES => false, + Opcode::Arithmetic(_) => true, + Opcode::Directive(_) => true, + Opcode::Block(_) => false, + Opcode::ROM(_) => true, + Opcode::RAM(_) => true, + Opcode::Oracle(_) => true, + Opcode::BlackBoxFuncCall(func) => match func.get_black_box_func() { + BlackBoxFunc::AND + | BlackBoxFunc::XOR + | BlackBoxFunc::RANGE + | BlackBoxFunc::SHA256 + | BlackBoxFunc::Blake2s + | BlackBoxFunc::Keccak256 + | BlackBoxFunc::ComputeMerkleRoot + | BlackBoxFunc::SchnorrVerify + | BlackBoxFunc::Pedersen + | BlackBoxFunc::HashToField128Security + | BlackBoxFunc::EcdsaSecp256k1 + | BlackBoxFunc::FixedBaseScalarMul => true, + + BlackBoxFunc::AES => false, + }, } } - fn preprocess(&self, circuit: &Circuit) -> Result<(Vec, Vec), Self::Error> { + fn preprocess( + &self, + common_reference_string: &[u8], + circuit: &Circuit, + ) -> Result<(Vec, Vec), Self::Error> { + let crs = common_reference_string.try_into()?; let constraint_system = &circuit.try_into()?; let proving_key = self.compute_proving_key(constraint_system)?; - let verification_key = self.compute_verification_key(constraint_system, &proving_key)?; + let verification_key = self.compute_verification_key(&crs, &proving_key)?; Ok((proving_key, verification_key)) } fn prove_with_pk( &self, + common_reference_string: &[u8], circuit: &Circuit, - witness_values: BTreeMap, + witness_values: WitnessMap, proving_key: &[u8], ) -> Result, Self::Error> { + let crs = common_reference_string.try_into()?; let assignments = flatten_witness_map(circuit, witness_values); - Ok(self.create_proof_with_pk(&circuit.try_into()?, assignments, proving_key)?) + Ok(self.create_proof_with_pk(&crs, &circuit.try_into()?, assignments, proving_key)?) } fn verify_with_vk( &self, + common_reference_string: &[u8], proof: &[u8], - public_inputs: BTreeMap, + public_inputs: WitnessMap, circuit: &Circuit, verification_key: &[u8], ) -> Result { + let crs = common_reference_string.try_into()?; // Unlike when proving, we omit any unassigned witnesses. // Witness values should be ordered by their index but we skip over any indices without an assignment. - let flattened_public_inputs: Vec = public_inputs.into_values().collect(); + let flattened_public_inputs: Vec = + public_inputs.into_iter().map(|(_, el)| el).collect(); Ok(Composer::verify_with_vk( self, + &crs, &circuit.try_into()?, proof, flattened_public_inputs.into(), @@ -82,10 +99,7 @@ impl ProofSystemCompiler for Barretenberg { } /// Flatten a witness map into a vector of witness assignments. -fn flatten_witness_map( - circuit: &Circuit, - witness_values: BTreeMap, -) -> Assignments { +fn flatten_witness_map(circuit: &Circuit, witness_values: WitnessMap) -> Assignments { let num_witnesses = circuit.num_vars(); // Note: The witnesses are sorted via their witness index @@ -94,10 +108,10 @@ fn flatten_witness_map( .map(|witness_index| { // Get the value if it exists. If i does not, then we fill it with the zero value witness_values - .get(&Witness(witness_index)) + .get_index(witness_index) .map_or(FieldElement::zero(), |field| *field) }) .collect(); - Assignments::from(witness_assignments) + witness_assignments.into() } diff --git a/src/acvm_interop/pwg.rs b/src/acvm_interop/pwg.rs index 3e6df850..3d7c2928 100644 --- a/src/acvm_interop/pwg.rs +++ b/src/acvm_interop/pwg.rs @@ -1,211 +1,271 @@ +use acvm::acir::circuit::opcodes::FunctionInput; +use acvm::acir::native_types::{Witness, WitnessMap}; use acvm::acir::BlackBoxFunc; -use acvm::acir::{circuit::opcodes::BlackBoxFuncCall, native_types::Witness}; use acvm::pwg::{hash, logic, range, signature, witness_to_value}; -use acvm::{FieldElement, OpcodeResolution}; +use acvm::{pwg::OpcodeResolution, FieldElement}; use acvm::{OpcodeResolutionError, PartialWitnessGenerator}; -use std::collections::BTreeMap; - use crate::pedersen::Pedersen; use crate::scalar_mul::ScalarMul; use crate::schnorr::SchnorrSig; use crate::Barretenberg; -use blake2::{Blake2s, Digest}; - mod merkle; impl PartialWitnessGenerator for Barretenberg { - fn solve_black_box_function_call( + fn aes( + &self, + _initial_witness: &mut WitnessMap, + _inputs: &[FunctionInput], + _outputs: &[Witness], + ) -> Result { + Err(OpcodeResolutionError::UnsupportedBlackBoxFunc( + BlackBoxFunc::AES, + )) + } + + fn and( + &self, + initial_witness: &mut WitnessMap, + lhs: &FunctionInput, + rhs: &FunctionInput, + output: &Witness, + ) -> Result { + logic::and(initial_witness, lhs, rhs, output) + } + + fn xor( + &self, + initial_witness: &mut WitnessMap, + lhs: &FunctionInput, + rhs: &FunctionInput, + output: &Witness, + ) -> Result { + logic::xor(initial_witness, lhs, rhs, output) + } + + fn range( + &self, + initial_witness: &mut WitnessMap, + input: &FunctionInput, + ) -> Result { + range::solve_range_opcode(initial_witness, input) + } + + fn sha256( &self, - initial_witness: &mut BTreeMap, - func_call: &BlackBoxFuncCall, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + outputs: &[Witness], ) -> Result { - match func_call.name { - BlackBoxFunc::SHA256 => hash::sha256(initial_witness, func_call), - BlackBoxFunc::Blake2s => hash::blake2s(initial_witness, func_call), - BlackBoxFunc::Keccak256 => hash::keccak256(initial_witness, func_call), - BlackBoxFunc::EcdsaSecp256k1 => { - signature::ecdsa::secp256k1_prehashed(initial_witness, func_call) - } - - BlackBoxFunc::AND | BlackBoxFunc::XOR => { - logic::solve_logic_opcode(initial_witness, func_call) - } - BlackBoxFunc::RANGE => range::solve_range_opcode(initial_witness, func_call), - BlackBoxFunc::AES => Err(OpcodeResolutionError::UnsupportedBlackBoxFunc( - func_call.name, - )), - BlackBoxFunc::ComputeMerkleRoot => { - let mut inputs_iter = func_call.inputs.iter(); - - let _leaf = inputs_iter.next().expect("expected a leaf"); - let leaf = witness_to_value(initial_witness, _leaf.witness)?; - - let _index = inputs_iter.next().expect("expected an index"); - let index = witness_to_value(initial_witness, _index.witness)?; - - let hash_path: Result, _> = inputs_iter - .map(|input| witness_to_value(initial_witness, input.witness)) - .collect(); - - let computed_merkle_root = merkle::compute_merkle_root( - |left, right| self.compress_native(left, right), - hash_path?, - index, - leaf, + hash::sha256(initial_witness, inputs, outputs) + } + + fn blake2s( + &self, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + outputs: &[Witness], + ) -> Result { + hash::blake2s256(initial_witness, inputs, outputs) + } + + fn compute_merkle_root( + &self, + initial_witness: &mut WitnessMap, + leaf: &FunctionInput, + index: &FunctionInput, + hash_path: &[FunctionInput], + output: &Witness, + ) -> Result { + let leaf = witness_to_value(initial_witness, leaf.witness)?; + + let index = witness_to_value(initial_witness, index.witness)?; + + let hash_path: Result, _> = hash_path + .iter() + .map(|input| witness_to_value(initial_witness, input.witness)) + .collect(); + + let computed_merkle_root = merkle::compute_merkle_root( + |left, right| self.compress_native(left, right), + hash_path?, + index, + leaf, + ) + .map_err(|err| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::ComputeMerkleRoot, + err.to_string(), + ) + })?; + + initial_witness.insert(*output, computed_merkle_root); + Ok(OpcodeResolution::Solved) + } + + fn schnorr_verify( + &self, + initial_witness: &mut WitnessMap, + public_key_x: &FunctionInput, + public_key_y: &FunctionInput, + signature: &[FunctionInput], + message: &[FunctionInput], + output: &Witness, + ) -> Result { + // In barretenberg, if the signature fails, then the whole thing fails. + + let pub_key_x = witness_to_value(initial_witness, public_key_x.witness)?.to_be_bytes(); + let pub_key_y = witness_to_value(initial_witness, public_key_y.witness)?.to_be_bytes(); + + let pub_key_bytes: Vec = pub_key_x + .iter() + .copied() + .chain(pub_key_y.to_vec()) + .collect(); + let pub_key: [u8; 64] = pub_key_bytes.try_into().map_err(|v: Vec| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::SchnorrVerify, + format!("expected pubkey size {} but received {}", 64, v.len()), + ) + })?; + + let mut signature = signature.iter(); + let mut sig_s = [0u8; 32]; + for (i, sig) in sig_s.iter_mut().enumerate() { + let _sig_i = signature.next().ok_or_else(|| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::SchnorrVerify, + format!("sig_s should be 32 bytes long, found only {i} bytes"), + ) + })?; + let sig_i = witness_to_value(initial_witness, _sig_i.witness)?; + *sig = *sig_i.to_be_bytes().last().ok_or_else(|| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::SchnorrVerify, + "could not get last bytes".into(), + ) + })?; + } + let mut sig_e = [0u8; 32]; + for (i, sig) in sig_e.iter_mut().enumerate() { + let _sig_i = signature.next().ok_or_else(|| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::SchnorrVerify, + format!("sig_e should be 32 bytes long, found only {i} bytes"), + ) + })?; + let sig_i = witness_to_value(initial_witness, _sig_i.witness)?; + *sig = *sig_i.to_be_bytes().last().ok_or_else(|| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::SchnorrVerify, + "could not get last bytes".into(), + ) + })?; + } + + let mut message_bytes = Vec::new(); + for msg in message.iter() { + let msg_i_field = witness_to_value(initial_witness, msg.witness)?; + let msg_i = *msg_i_field.to_be_bytes().last().ok_or_else(|| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::SchnorrVerify, + "could not get last bytes".into(), + ) + })?; + message_bytes.push(msg_i); + } + + let valid_signature = self + .verify_signature(pub_key, sig_s, sig_e, &message_bytes) + .map_err(|err| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::SchnorrVerify, + err.to_string(), ) - .map_err(|err| { - OpcodeResolutionError::BlackBoxFunctionFailed(func_call.name, err.to_string()) - })?; - - initial_witness.insert(func_call.outputs[0], computed_merkle_root); - Ok(OpcodeResolution::Solved) - } - BlackBoxFunc::SchnorrVerify => { - // In barretenberg, if the signature fails, then the whole thing fails. - // - - let mut inputs_iter = func_call.inputs.iter(); - - let _pub_key_x = inputs_iter - .next() - .expect("expected `x` component for public key"); - let pub_key_x = - witness_to_value(initial_witness, _pub_key_x.witness)?.to_be_bytes(); - - let _pub_key_y = inputs_iter - .next() - .expect("expected `y` component for public key"); - let pub_key_y = - witness_to_value(initial_witness, _pub_key_y.witness)?.to_be_bytes(); - - let pub_key_bytes: Vec = pub_key_x - .iter() - .copied() - .chain(pub_key_y.to_vec()) - .collect(); - let pub_key: [u8; 64] = pub_key_bytes.try_into().map_err(|v: Vec| { - OpcodeResolutionError::BlackBoxFunctionFailed( - func_call.name, - format!("expected pubkey size {} but received {}", 64, v.len()), - ) - })?; - - let mut sig_s: [u8; 32] = [0u8; 32]; - for (i, sig) in sig_s.iter_mut().enumerate() { - let _sig_i = inputs_iter.next().ok_or_else(|| { - OpcodeResolutionError::BlackBoxFunctionFailed( - func_call.name, - format!("sig_s should be 32 bytes long, found only {i} bytes"), - ) - })?; - let sig_i = witness_to_value(initial_witness, _sig_i.witness)?; - *sig = *sig_i.to_be_bytes().last().ok_or_else(|| { - OpcodeResolutionError::BlackBoxFunctionFailed( - func_call.name, - "could not get last bytes".into(), - ) - })?; - } - let mut sig_e: [u8; 32] = [0u8; 32]; - for (i, sig) in sig_e.iter_mut().enumerate() { - let _sig_i = inputs_iter.next().ok_or_else(|| { - OpcodeResolutionError::BlackBoxFunctionFailed( - func_call.name, - format!("sig_e should be 32 bytes long, found only {i} bytes"), - ) - })?; - let sig_i = witness_to_value(initial_witness, _sig_i.witness)?; - *sig = *sig_i.to_be_bytes().last().ok_or_else(|| { - OpcodeResolutionError::BlackBoxFunctionFailed( - func_call.name, - "could not get last bytes".into(), - ) - })?; - } - - let mut message = Vec::new(); - for msg in inputs_iter { - let msg_i_field = witness_to_value(initial_witness, msg.witness)?; - let msg_i = *msg_i_field.to_be_bytes().last().ok_or_else(|| { - OpcodeResolutionError::BlackBoxFunctionFailed( - func_call.name, - "could not get last bytes".into(), - ) - })?; - message.push(msg_i); - } - - let valid_signature = self - .verify_signature(pub_key, sig_s, sig_e, &message) - .map_err(|err| { - OpcodeResolutionError::BlackBoxFunctionFailed( - func_call.name, - err.to_string(), - ) - })?; - if !valid_signature { - dbg!("signature has failed to verify"); - } - - let result = if valid_signature { - FieldElement::one() - } else { - FieldElement::zero() - }; - - initial_witness.insert(func_call.outputs[0], result); - Ok(OpcodeResolution::Solved) - } - BlackBoxFunc::Pedersen => { - let inputs_iter = func_call.inputs.iter(); - - let scalars: Result, _> = inputs_iter - .map(|input| witness_to_value(initial_witness, input.witness)) - .collect(); - let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); - - let (res_x, res_y) = self.encrypt(scalars).map_err(|err| { - OpcodeResolutionError::BlackBoxFunctionFailed(func_call.name, err.to_string()) - })?; - initial_witness.insert(func_call.outputs[0], res_x); - initial_witness.insert(func_call.outputs[1], res_y); - Ok(OpcodeResolution::Solved) - } - BlackBoxFunc::HashToField128Security => { - let mut hasher = ::new(); - - // 0. For each input in the vector of inputs, check if we have their witness assignments (Can do this outside of match, since they all have inputs) - for input_index in func_call.inputs.iter() { - let witness = &input_index.witness; - let num_bits = input_index.num_bits; - - let assignment = witness_to_value(initial_witness, *witness)?; - - let bytes = assignment.fetch_nearest_bytes(num_bits as usize); - - hasher.update(bytes); - } - let result = hasher.finalize(); - - let reduced_res = FieldElement::from_be_bytes_reduce(&result); - assert_eq!(func_call.outputs.len(), 1); - - initial_witness.insert(func_call.outputs[0], reduced_res); - Ok(OpcodeResolution::Solved) - } - BlackBoxFunc::FixedBaseScalarMul => { - let scalar = witness_to_value(initial_witness, func_call.inputs[0].witness)?; - - let (pub_x, pub_y) = self.fixed_base(scalar).map_err(|err| { - OpcodeResolutionError::BlackBoxFunctionFailed(func_call.name, err.to_string()) - })?; - - initial_witness.insert(func_call.outputs[0], pub_x); - initial_witness.insert(func_call.outputs[1], pub_y); - Ok(OpcodeResolution::Solved) - } + })?; + if !valid_signature { + dbg!("signature has failed to verify"); } + + initial_witness.insert(*output, FieldElement::from(valid_signature)); + Ok(OpcodeResolution::Solved) + } + + fn pedersen( + &self, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + outputs: &[Witness], + ) -> Result { + let scalars: Result, _> = inputs + .iter() + .map(|input| witness_to_value(initial_witness, input.witness)) + .collect(); + let scalars: Vec<_> = scalars?.into_iter().cloned().collect(); + + let (res_x, res_y) = self.encrypt(scalars).map_err(|err| { + OpcodeResolutionError::BlackBoxFunctionFailed(BlackBoxFunc::Pedersen, err.to_string()) + })?; + initial_witness.insert(outputs[0], res_x); + initial_witness.insert(outputs[1], res_y); + Ok(OpcodeResolution::Solved) + } + + fn hash_to_field_128_security( + &self, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + output: &Witness, + ) -> Result { + hash::hash_to_field_128_security(initial_witness, inputs, output) + } + + fn ecdsa_secp256k1( + &self, + initial_witness: &mut WitnessMap, + public_key_x: &[FunctionInput], + public_key_y: &[FunctionInput], + signature: &[FunctionInput], + message: &[FunctionInput], + outputs: &Witness, + ) -> Result { + signature::ecdsa::secp256k1_prehashed( + initial_witness, + public_key_x, + public_key_y, + signature, + message, + *outputs, + ) + } + + fn fixed_base_scalar_mul( + &self, + initial_witness: &mut WitnessMap, + input: &FunctionInput, + outputs: &[Witness], + ) -> Result { + let scalar = witness_to_value(initial_witness, input.witness)?; + + let (pub_x, pub_y) = self.fixed_base(scalar).map_err(|err| { + OpcodeResolutionError::BlackBoxFunctionFailed( + BlackBoxFunc::FixedBaseScalarMul, + err.to_string(), + ) + })?; + + initial_witness.insert(outputs[0], pub_x); + initial_witness.insert(outputs[1], pub_y); + Ok(OpcodeResolution::Solved) + } + + fn keccak256( + &self, + initial_witness: &mut WitnessMap, + inputs: &[FunctionInput], + outputs: &[Witness], + ) -> Result { + hash::keccak256(initial_witness, inputs, outputs) } } diff --git a/src/acvm_interop/pwg/merkle.rs b/src/acvm_interop/pwg/merkle.rs index 765dc85c..d194ccb3 100644 --- a/src/acvm_interop/pwg/merkle.rs +++ b/src/acvm_interop/pwg/merkle.rs @@ -92,9 +92,9 @@ mod tests { }, ]; - let mut msg_hasher: blake2::Blake2s = MessageHasher::new(); + let mut msg_hasher: blake2::Blake2s256 = MessageHasher::new(); - let mut tree: MerkleTree = MerkleTree::new(3); + let mut tree: MerkleTree = MerkleTree::new(3); for test_vector in tests { let index = FieldElement::try_from_str(test_vector.index).unwrap(); @@ -140,7 +140,7 @@ mod tests { // This test uses `update_leaf` directly rather than `update_message` #[test] fn simple_shield() -> Result<(), Error> { - let mut tree: MerkleTree = MerkleTree::new(3); + let mut tree: MerkleTree = MerkleTree::new(3); let barretenberg = Barretenberg::new(); let pubkey_x = FieldElement::from_hex( diff --git a/src/acvm_interop/smart_contract.rs b/src/acvm_interop/smart_contract.rs index 34d64efc..b612e3a0 100644 --- a/src/acvm_interop/smart_contract.rs +++ b/src/acvm_interop/smart_contract.rs @@ -1,7 +1,6 @@ use acvm::SmartContract; -use crate::crs::G2; -use crate::{BackendError, Barretenberg}; +use crate::{crs::CRS, BackendError, Barretenberg}; /// Embed the Solidity verifier file const ULTRA_VERIFIER_CONTRACT: &str = include_str!("contract.sol"); @@ -10,10 +9,14 @@ const ULTRA_VERIFIER_CONTRACT: &str = include_str!("contract.sol"); impl SmartContract for Barretenberg { type Error = BackendError; - fn eth_contract_from_vk(&self, verification_key: &[u8]) -> Result { + fn eth_contract_from_vk( + &self, + common_reference_string: &[u8], + verification_key: &[u8], + ) -> Result { use std::slice; - let g2 = G2::new(); + let CRS { g2_data, .. } = common_reference_string.try_into()?; let mut contract_ptr: *mut u8 = std::ptr::null_mut(); let p_contract_ptr = &mut contract_ptr as *mut *mut u8; @@ -22,7 +25,7 @@ impl SmartContract for Barretenberg { let contract_size; unsafe { contract_size = barretenberg_sys::composer::get_solidity_verifier( - &g2.data, + &g2_data, &verification_key, p_contract_ptr, ); @@ -40,10 +43,14 @@ impl SmartContract for Barretenberg { impl SmartContract for Barretenberg { type Error = BackendError; - fn eth_contract_from_vk(&self, verification_key: &[u8]) -> Result { - let g2 = G2::new(); + fn eth_contract_from_vk( + &self, + common_reference_string: &[u8], + verification_key: &[u8], + ) -> Result { + let CRS { g2_data, .. } = common_reference_string.try_into()?; - let g2_ptr = self.allocate(&g2.data)?; + let g2_ptr = self.allocate(&g2_data)?; let vk_ptr = self.allocate(verification_key)?; // The smart contract string is not actually written to this pointer. @@ -68,39 +75,50 @@ impl SmartContract for Barretenberg { } } -#[test] -fn test_smart_contract() -> Result<(), BackendError> { - use crate::barretenberg_structures::{Constraint, ConstraintSystem}; - use crate::composer::Composer; - use crate::Barretenberg; - use acvm::FieldElement; - - let constraint = Constraint { - a: 1, - b: 2, - c: 3, - qm: FieldElement::zero(), - ql: FieldElement::one(), - qr: FieldElement::one(), - qo: -FieldElement::one(), - qc: FieldElement::zero(), - }; - - let constraint_system = ConstraintSystem::new() - .var_num(4) - .public_inputs(vec![1, 2]) - .constraints(vec![constraint]); - - let bb = Barretenberg::new(); - - let proving_key = bb.compute_proving_key(&constraint_system)?; - let verification_key = bb.compute_verification_key(&constraint_system, &proving_key)?; - - let contract = bb.eth_contract_from_vk(&verification_key)?; - - assert!(contract.contains("contract BaseUltraVerifier")); - assert!(contract.contains("contract UltraVerifier")); - assert!(contract.contains("library UltraVerificationKey")); - - Ok(()) +#[cfg(test)] +mod tests { + use acvm::SmartContract; + use tokio::test; + + use crate::BackendError; + + #[test] + async fn test_smart_contract() -> Result<(), BackendError> { + use crate::barretenberg_structures::{Constraint, ConstraintSystem}; + use crate::composer::Composer; + use crate::Barretenberg; + use acvm::FieldElement; + + let constraint = Constraint { + a: 1, + b: 2, + c: 3, + qm: FieldElement::zero(), + ql: FieldElement::one(), + qr: FieldElement::one(), + qo: -FieldElement::one(), + qc: FieldElement::zero(), + }; + + let constraint_system = ConstraintSystem::new() + .var_num(4) + .public_inputs(vec![1, 2]) + .constraints(vec![constraint]); + + let bb = Barretenberg::new(); + let crs = bb.get_crs(&constraint_system).await?; + + let proving_key = bb.compute_proving_key(&constraint_system)?; + let verification_key = bb.compute_verification_key(&crs, &proving_key)?; + + let common_reference_string: Vec = crs.try_into()?; + + let contract = bb.eth_contract_from_vk(&common_reference_string, &verification_key)?; + + assert!(contract.contains("contract BaseUltraVerifier")); + assert!(contract.contains("contract UltraVerifier")); + assert!(contract.contains("library UltraVerificationKey")); + + Ok(()) + } } diff --git a/src/barretenberg_structures.rs b/src/barretenberg_structures.rs index 18af9d15..394f6822 100644 --- a/src/barretenberg_structures.rs +++ b/src/barretenberg_structures.rs @@ -1,4 +1,4 @@ -use acvm::acir::circuit::opcodes::MemoryBlock; +use acvm::acir::circuit::opcodes::{BlackBoxFuncCall, MemoryBlock}; use acvm::acir::circuit::{Circuit, Opcode}; use acvm::acir::native_types::Expression; use acvm::acir::BlackBoxFunc; @@ -757,14 +757,10 @@ impl TryFrom<&Circuit> for ConstraintSystem { constraints.push(constraint); } Opcode::BlackBoxFuncCall(gadget_call) => { - match gadget_call.name { - BlackBoxFunc::RANGE => { - assert_eq!(gadget_call.inputs.len(), 1); - assert_eq!(gadget_call.outputs.len(), 0); - - let function_input = &gadget_call.inputs[0]; - let witness = function_input.witness; - let num_bits = function_input.num_bits; + match gadget_call { + BlackBoxFuncCall::RANGE { input } => { + let witness = input.witness; + let num_bits = input.num_bits; let range_constraint = RangeConstraint { a: witness.witness_index() as i32, @@ -772,57 +768,52 @@ impl TryFrom<&Circuit> for ConstraintSystem { }; range_constraints.push(range_constraint); } - BlackBoxFunc::AND | BlackBoxFunc::XOR => { - assert_eq!(gadget_call.inputs.len(), 2); - assert_eq!(gadget_call.outputs.len(), 1); - - let function_input_lhs = &gadget_call.inputs[0]; - let witness_lhs = function_input_lhs.witness; - - let function_input_rhs = &gadget_call.inputs[1]; - let witness_rhs = function_input_rhs.witness; - - let function_output = &gadget_call.outputs[0]; - - assert_eq!(function_input_lhs.num_bits, function_input_rhs.num_bits); - let num_bits = function_input_rhs.num_bits; - - if gadget_call.name == BlackBoxFunc::AND { - let and = LogicConstraint::and( - witness_lhs.witness_index() as i32, - witness_rhs.witness_index() as i32, - function_output.witness_index() as i32, - num_bits as i32, - ); - logic_constraints.push(and); - } else if gadget_call.name == BlackBoxFunc::XOR { - let xor = LogicConstraint::xor( - witness_lhs.witness_index() as i32, - witness_rhs.witness_index() as i32, - function_output.witness_index() as i32, - num_bits as i32, - ); - logic_constraints.push(xor); - } else { - unreachable!("expected either an AND or XOR opcode") + BlackBoxFuncCall::AND { lhs, rhs, output } + | BlackBoxFuncCall::XOR { lhs, rhs, output } => { + let witness_lhs = lhs.witness; + let witness_rhs = rhs.witness; + + assert_eq!(lhs.num_bits, rhs.num_bits); + let num_bits = rhs.num_bits; + + match gadget_call { + BlackBoxFuncCall::AND { .. } => { + let and = LogicConstraint::and( + witness_lhs.witness_index() as i32, + witness_rhs.witness_index() as i32, + output.witness_index() as i32, + num_bits as i32, + ); + logic_constraints.push(and); + } + BlackBoxFuncCall::XOR { .. } => { + let xor = LogicConstraint::xor( + witness_lhs.witness_index() as i32, + witness_rhs.witness_index() as i32, + output.witness_index() as i32, + num_bits as i32, + ); + logic_constraints.push(xor); + } + _ => unreachable!("expected either an AND or XOR opcode"), } } - BlackBoxFunc::SHA256 => { + BlackBoxFuncCall::SHA256 { inputs, outputs } => { let mut sha256_inputs: Vec<(i32, i32)> = Vec::new(); - for input in gadget_call.inputs.iter() { + for input in inputs.iter() { let witness_index = input.witness.witness_index() as i32; let num_bits = input.num_bits as i32; sha256_inputs.push((witness_index, num_bits)); } - assert_eq!(gadget_call.outputs.len(), 32); + assert_eq!(outputs.len(), 32); - let mut outputs_iter = gadget_call.outputs.iter(); + let mut outputs_iter = outputs.iter(); let mut result = [0i32; 32]; for (i, res) in result.iter_mut().enumerate() { let out_byte = outputs_iter.next().ok_or_else(|| { Error::MalformedBlackBoxFunc( - gadget_call.name, + BlackBoxFunc::SHA256, format!("Missing rest of output. Tried to get byte {i} but failed"), ) })?; @@ -837,23 +828,23 @@ impl TryFrom<&Circuit> for ConstraintSystem { sha256_constraints.push(sha256_constraint); } - BlackBoxFunc::Blake2s => { + BlackBoxFuncCall::Blake2s { inputs, outputs } => { let mut blake2s_inputs: Vec<(i32, i32)> = Vec::new(); - for input in gadget_call.inputs.iter() { + for input in inputs.iter() { let witness_index = input.witness.witness_index() as i32; let num_bits = input.num_bits as i32; blake2s_inputs.push((witness_index, num_bits)); } - assert_eq!(gadget_call.outputs.len(), 32); + assert_eq!(outputs.len(), 32); - let mut outputs_iter = gadget_call.outputs.iter(); + let mut outputs_iter = outputs.iter(); let mut result = [0i32; 32]; for (i, res) in result.iter_mut().enumerate() { let out_byte = outputs_iter.next().ok_or_else(|| { Error::MalformedBlackBoxFunc( - gadget_call.name, + BlackBoxFunc::Blake2s, format!("Missing rest of output. Tried to get byte {i} but failed"), ) })?; @@ -868,43 +859,26 @@ impl TryFrom<&Circuit> for ConstraintSystem { blake2s_constraints.push(blake2s_constraint); } - BlackBoxFunc::ComputeMerkleRoot => { - let mut inputs_iter = gadget_call.inputs.iter().peekable(); - + BlackBoxFuncCall::ComputeMerkleRoot { + leaf, + index, + hash_path: hash_path_inputs, + output, + } => { // leaf - let leaf = { - let leaf_input = inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - "Missing leaf to check membership for".into(), - ) - })?; - leaf_input.witness.witness_index() as i32 - }; + let leaf = leaf.witness.witness_index() as i32; // index - let index = { - let index_input = inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - "Missing index for leaf".into(), - ) - })?; - index_input.witness.witness_index() as i32 - }; - - if inputs_iter.peek().is_none() { - unreachable!("cannot check membership without a hash path") - } + let index = index.witness.witness_index() as i32; let mut hash_path = Vec::new(); - for path_elem in inputs_iter { + for path_elem in hash_path_inputs.iter() { let path_elem_index = path_elem.witness.witness_index() as i32; hash_path.push(path_elem_index); } // computed root - let result = gadget_call.outputs[0].witness_index() as i32; + let result = output.witness_index() as i32; let constraint = ComputeMerkleRootConstraint { hash_path, @@ -915,53 +889,39 @@ impl TryFrom<&Circuit> for ConstraintSystem { compute_merkle_root_constraints.push(constraint); } - BlackBoxFunc::SchnorrVerify => { - let mut inputs_iter = gadget_call.inputs.iter(); - + BlackBoxFuncCall::SchnorrVerify { + public_key_x, + public_key_y, + signature, + message: message_inputs, + output, + } => { // pub_key_x - let public_key_x = { - let pub_key_x = inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - "Missing `x` component for public key".into(), - ) - })?; - pub_key_x.witness.witness_index() as i32 - }; + let public_key_x = public_key_x.witness.witness_index() as i32; // pub_key_y - let public_key_y = { - let pub_key_y = inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - "Missing `y` component for public key".into(), - ) - })?; - pub_key_y.witness.witness_index() as i32 - }; + let public_key_y = public_key_y.witness.witness_index() as i32; // signature - + let mut signature_iter = signature.iter(); let mut signature = [0i32; 64]; for (i, sig) in signature.iter_mut().enumerate() { let sig_byte = - inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - format!("Missing rest of signature. Tried to get byte {i} but failed"), - ) - })?; + signature_iter.next().ok_or_else(||Error::MalformedBlackBoxFunc( + BlackBoxFunc::SchnorrVerify, + format!("Missing rest of signature. Tried to get byte {i} but failed"), + ))?; let sig_byte_index = sig_byte.witness.witness_index() as i32; *sig = sig_byte_index } // The rest of the input is the message let mut message = Vec::new(); - for msg in inputs_iter { + for msg in message_inputs.iter() { let msg_byte_index = msg.witness.witness_index() as i32; message.push(msg_byte_index); } // result - let result = gadget_call.outputs[0].witness_index() as i32; + let result = output.witness_index() as i32; let constraint = SchnorrConstraint { message, @@ -973,15 +933,19 @@ impl TryFrom<&Circuit> for ConstraintSystem { schnorr_constraints.push(constraint); } - BlackBoxFunc::Pedersen => { + BlackBoxFuncCall::Pedersen { + inputs: gadget_call_inputs, + outputs, + } => { let mut inputs = Vec::new(); - for scalar in gadget_call.inputs.iter() { + for scalar in gadget_call_inputs.iter() { let scalar_index = scalar.witness.witness_index() as i32; inputs.push(scalar_index); } - let result_x = gadget_call.outputs[0].witness_index() as i32; - let result_y = gadget_call.outputs[1].witness_index() as i32; + assert_eq!(outputs.len(), 2); + let result_x = outputs[0].witness_index() as i32; + let result_y = outputs[1].witness_index() as i32; let constraint = PedersenConstraint { inputs, @@ -991,17 +955,15 @@ impl TryFrom<&Circuit> for ConstraintSystem { pedersen_constraints.push(constraint); } - BlackBoxFunc::HashToField128Security => { + BlackBoxFuncCall::HashToField128Security { inputs, output } => { let mut hash_to_field_inputs: Vec<(i32, i32)> = Vec::new(); - for input in gadget_call.inputs.iter() { + for input in inputs.iter() { let witness_index = input.witness.witness_index() as i32; let num_bits = input.num_bits as i32; hash_to_field_inputs.push((witness_index, num_bits)); } - assert_eq!(gadget_call.outputs.len(), 1); - - let result = gadget_call.outputs[0].witness_index() as i32; + let result = output.witness_index() as i32; let hash_to_field_constraint = HashToFieldConstraint { inputs: hash_to_field_inputs, @@ -1010,60 +972,63 @@ impl TryFrom<&Circuit> for ConstraintSystem { hash_to_field_constraints.push(hash_to_field_constraint); } - BlackBoxFunc::EcdsaSecp256k1 => { - let mut inputs_iter = gadget_call.inputs.iter(); - + BlackBoxFuncCall::EcdsaSecp256k1 { + public_key_x: public_key_x_inputs, + public_key_y: public_key_y_inputs, + signature: signature_inputs, + hashed_message: hashed_message_inputs, + output, + } => { // public key x + let mut public_key_x_inputs = public_key_x_inputs.iter(); let mut public_key_x = [0i32; 32]; for (i, pkx) in public_key_x.iter_mut().enumerate() { - let x_byte = - inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - format!("Missing rest of `x` component for public key. Tried to get byte {i} but failed"), - ) - })?; + let x_byte = public_key_x_inputs + .next() + .ok_or_else(|| Error::MalformedBlackBoxFunc( + BlackBoxFunc::EcdsaSecp256k1, + format!("Missing rest of `x` component for public key. Tried to get byte {i} but failed"), + ))?; let x_byte_index = x_byte.witness.witness_index() as i32; *pkx = x_byte_index; } // public key y + let mut public_key_y_inputs = public_key_y_inputs.iter(); let mut public_key_y = [0i32; 32]; for (i, pky) in public_key_y.iter_mut().enumerate() { - let y_byte = - inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - format!("Missing rest of `y` component for public key. Tried to get byte {i} but failed"), - ) - })?; + let y_byte = public_key_y_inputs + .next() + .ok_or_else(|| Error::MalformedBlackBoxFunc( + BlackBoxFunc::EcdsaSecp256k1, + format!("Missing rest of `y` component for public key. Tried to get byte {i} but failed"), + ))?; let y_byte_index = y_byte.witness.witness_index() as i32; *pky = y_byte_index; } // signature + let mut signature_inputs = signature_inputs.iter(); let mut signature = [0i32; 64]; for (i, sig) in signature.iter_mut().enumerate() { let sig_byte = - inputs_iter.next().ok_or_else(|| { - Error::MalformedBlackBoxFunc( - gadget_call.name, - format!("Missing rest of signature. Tried to get byte {i} but failed"), - ) - })?; + signature_inputs.next().ok_or_else(|| Error::MalformedBlackBoxFunc( + BlackBoxFunc::EcdsaSecp256k1, + format!("Missing rest of signature. Tried to get byte {i} but failed"), + ))?; let sig_byte_index = sig_byte.witness.witness_index() as i32; *sig = sig_byte_index; } // The rest of the input is the message let mut hashed_message = Vec::new(); - for msg in inputs_iter { + for msg in hashed_message_inputs.iter() { let msg_byte_index = msg.witness.witness_index() as i32; hashed_message.push(msg_byte_index); } // result - let result = gadget_call.outputs[0].witness_index() as i32; + let result = output.witness_index() as i32; let constraint = EcdsaConstraint { hashed_message, @@ -1075,13 +1040,12 @@ impl TryFrom<&Circuit> for ConstraintSystem { ecdsa_secp256k1_constraints.push(constraint); } - BlackBoxFunc::FixedBaseScalarMul => { - assert_eq!(gadget_call.inputs.len(), 1); - let scalar = gadget_call.inputs[0].witness.witness_index() as i32; + BlackBoxFuncCall::FixedBaseScalarMul { input, outputs } => { + let scalar = input.witness.witness_index() as i32; - assert_eq!(gadget_call.outputs.len(), 2); - let pubkey_x = gadget_call.outputs[0].witness_index() as i32; - let pubkey_y = gadget_call.outputs[1].witness_index() as i32; + assert_eq!(outputs.len(), 2); + let pubkey_x = outputs[0].witness_index() as i32; + let pubkey_y = outputs[1].witness_index() as i32; let fixed_base_scalar_mul = FixedBaseScalarMulConstraint { scalar, @@ -1091,23 +1055,23 @@ impl TryFrom<&Circuit> for ConstraintSystem { fixed_base_scalar_mul_constraints.push(fixed_base_scalar_mul); } - BlackBoxFunc::Keccak256 => { + BlackBoxFuncCall::Keccak256 { inputs, outputs } => { let mut keccak_inputs: Vec<(i32, i32)> = Vec::new(); - for input in gadget_call.inputs.iter() { + for input in inputs.iter() { let witness_index = input.witness.witness_index() as i32; let num_bits = input.num_bits as i32; keccak_inputs.push((witness_index, num_bits)); } - assert_eq!(gadget_call.outputs.len(), 32); + assert_eq!(outputs.len(), 32); - let mut outputs_iter = gadget_call.outputs.iter(); + let mut outputs_iter = outputs.iter(); let mut result = [0i32; 32]; for (i, res) in result.iter_mut().enumerate() { let out_byte = outputs_iter.next().ok_or_else(|| { Error::MalformedBlackBoxFunc( - gadget_call.name, + BlackBoxFunc::Keccak256, format!("Missing rest of output. Tried to get byte {i} but failed"), ) })?; @@ -1122,8 +1086,8 @@ impl TryFrom<&Circuit> for ConstraintSystem { keccak_constraints.push(keccak_constraint); } - BlackBoxFunc::AES => { - return Err(Error::UnsupportedBlackBoxFunc(gadget_call.name)) + BlackBoxFuncCall::AES { .. } => { + return Err(Error::UnsupportedBlackBoxFunc(BlackBoxFunc::AES)) } }; } diff --git a/src/composer.rs b/src/composer.rs index a0b5ea28..dcc772ef 100644 --- a/src/composer.rs +++ b/src/composer.rs @@ -1,23 +1,43 @@ +use acvm::async_trait; + use crate::barretenberg_structures::{Assignments, ConstraintSystem}; -use crate::crs::{CRS, G2}; -use crate::{Barretenberg, Error, FIELD_BYTES}; +use crate::crs::download_crs; +use crate::{crs::CRS, Barretenberg, Error, FIELD_BYTES}; const NUM_RESERVED_GATES: u32 = 4; // this must be >= num_roots_cut_out_of_vanishing_polynomial (found under prover settings in barretenberg) +#[async_trait] pub(crate) trait Composer { fn get_circuit_size(&self, constraint_system: &ConstraintSystem) -> Result; fn get_exact_circuit_size(&self, constraint_system: &ConstraintSystem) -> Result; - fn compute_proving_key(&self, constraint_system: &ConstraintSystem) -> Result, Error>; - fn compute_verification_key( + async fn get_crs(&self, constraint_system: &ConstraintSystem) -> Result { + let num_points = self.get_circuit_size(constraint_system)?; + + download_crs(num_points as usize).await + } + + async fn update_crs<'a>( &self, + crs: &'a mut CRS, constraint_system: &ConstraintSystem, - proving_key: &[u8], - ) -> Result, Error>; + ) -> Result<&'a CRS, Error> { + let num_points = self.get_circuit_size(constraint_system)?; + + if crs.num_points < num_points as usize { + crs.update(num_points as usize).await?; + } + + Ok(crs) + } + + fn compute_proving_key(&self, constraint_system: &ConstraintSystem) -> Result, Error>; + fn compute_verification_key(&self, crs: &CRS, proving_key: &[u8]) -> Result, Error>; fn create_proof_with_pk( &self, + crs: &CRS, constraint_system: &ConstraintSystem, witness: Assignments, proving_key: &[u8], @@ -25,6 +45,7 @@ pub(crate) trait Composer { fn verify_with_vk( &self, + crs: &CRS, constraint_system: &ConstraintSystem, // XXX: Important: This assumes that the proof does not have the public inputs pre-pended to it // This is not the case, if you take the proof directly from Barretenberg @@ -88,16 +109,11 @@ impl Composer for Barretenberg { Ok(result) } - fn compute_verification_key( - &self, - constraint_system: &ConstraintSystem, - proving_key: &[u8], - ) -> Result, Error> { - let circuit_size = self.get_circuit_size(constraint_system)?; + fn compute_verification_key(&self, crs: &CRS, proving_key: &[u8]) -> Result, Error> { let CRS { g1_data, g2_data, .. - } = CRS::new(circuit_size as usize); - let pippenger_ptr = self.get_pippenger(&g1_data)?.pointer(); + } = crs; + let pippenger_ptr = self.get_pippenger(g1_data)?.pointer(); let mut vk_addr: *mut u8 = std::ptr::null_mut(); let vk_ptr = &mut vk_addr as *mut *mut u8; @@ -106,7 +122,7 @@ impl Composer for Barretenberg { unsafe { vk_size = barretenberg_sys::composer::init_verification_key( pippenger_ptr, - &g2_data, + g2_data, proving_key, vk_ptr, ) @@ -121,15 +137,15 @@ impl Composer for Barretenberg { fn create_proof_with_pk( &self, + crs: &CRS, constraint_system: &ConstraintSystem, witness: Assignments, proving_key: &[u8], ) -> Result, Error> { - let circuit_size = self.get_circuit_size(constraint_system)?; let CRS { g1_data, g2_data, .. - } = CRS::new(circuit_size as usize); - let pippenger_ptr = self.get_pippenger(&g1_data)?.pointer(); + } = crs; + let pippenger_ptr = self.get_pippenger(g1_data)?.pointer(); let cs_buf: Vec = constraint_system.to_bytes(); let witness_buf = witness.to_bytes(); @@ -140,7 +156,7 @@ impl Composer for Barretenberg { unsafe { proof_size = barretenberg_sys::composer::create_proof_with_pk( pippenger_ptr, - &g2_data, + g2_data, proving_key, &cs_buf, &witness_buf, @@ -163,6 +179,7 @@ impl Composer for Barretenberg { fn verify_with_vk( &self, + crs: &CRS, constraint_system: &ConstraintSystem, // XXX: Important: This assumes that the proof does not have the public inputs pre-pended to it // This is not the case, if you take the proof directly from Barretenberg @@ -170,7 +187,7 @@ impl Composer for Barretenberg { public_inputs: Assignments, verification_key: &[u8], ) -> Result { - let g2_data = G2::new().data; + let CRS { g2_data, .. } = crs; // Barretenberg expects public inputs to be prepended onto the proof let proof = prepend_public_inputs(proof.to_vec(), public_inputs); @@ -179,7 +196,7 @@ impl Composer for Barretenberg { let verified; unsafe { verified = barretenberg_sys::composer::verify_with_vk( - &g2_data, + g2_data, verification_key, &cs_buf, &proof, @@ -247,18 +264,13 @@ impl Composer for Barretenberg { Ok(self.read_memory_variable_length(pk_ptr, pk_size.try_into()?)) } - fn compute_verification_key( - &self, - constraint_system: &ConstraintSystem, - proving_key: &[u8], - ) -> Result, Error> { - let circuit_size = self.get_circuit_size(constraint_system)?; + fn compute_verification_key(&self, crs: &CRS, proving_key: &[u8]) -> Result, Error> { let CRS { g1_data, g2_data, .. - } = CRS::new(circuit_size as usize); - let pippenger_ptr = self.get_pippenger(&g1_data)?.pointer(); + } = crs; + let pippenger_ptr = self.get_pippenger(g1_data)?.pointer(); - let g2_ptr = self.allocate(&g2_data)?; + let g2_ptr = self.allocate(g2_data)?; let pk_ptr = self.allocate(proving_key)?; // The verification key is not actually written to this pointer. @@ -279,21 +291,21 @@ impl Composer for Barretenberg { fn create_proof_with_pk( &self, + crs: &CRS, constraint_system: &ConstraintSystem, witness: Assignments, proving_key: &[u8], ) -> Result, Error> { - let circuit_size = self.get_circuit_size(constraint_system)?; let CRS { g1_data, g2_data, .. - } = CRS::new(circuit_size as usize); - let pippenger_ptr = self.get_pippenger(&g1_data)?.pointer(); + } = crs; + let pippenger_ptr = self.get_pippenger(g1_data)?.pointer(); let cs_buf: Vec = constraint_system.to_bytes(); let witness_buf = witness.to_bytes(); let cs_ptr = self.allocate(&cs_buf)?; let witness_ptr = self.allocate(&witness_buf)?; - let g2_ptr = self.allocate(&g2_data)?; + let g2_ptr = self.allocate(g2_data)?; let pk_ptr = self.allocate(proving_key)?; // The proof data is not actually written to this pointer. @@ -328,6 +340,7 @@ impl Composer for Barretenberg { fn verify_with_vk( &self, + crs: &CRS, constraint_system: &ConstraintSystem, // XXX: Important: This assumes that the proof does not have the public inputs pre-pended to it // This is not the case, if you take the proof directly from Barretenberg @@ -335,7 +348,7 @@ impl Composer for Barretenberg { public_inputs: Assignments, verification_key: &[u8], ) -> Result { - let g2_data = G2::new().data; + let CRS { g2_data, .. } = crs; // Barretenberg expects public inputs to be prepended onto the proof let proof = prepend_public_inputs(proof.to_vec(), public_inputs); @@ -343,7 +356,7 @@ impl Composer for Barretenberg { let cs_ptr = self.allocate(&cs_buf)?; let proof_ptr = self.allocate(&proof)?; - let g2_ptr = self.allocate(&g2_data)?; + let g2_ptr = self.allocate(g2_data)?; let vk_ptr = self.allocate(verification_key)?; // This doesn't unwrap the result because we need to free even if there is a failure @@ -394,6 +407,7 @@ fn prepend_public_inputs(proof: Vec, public_inputs: Assignments) -> Vec #[cfg(test)] mod test { use acvm::FieldElement; + use tokio::test; use super::*; use crate::{ @@ -406,7 +420,7 @@ mod test { }; #[test] - fn test_no_constraints_no_pub_inputs() -> Result<(), Error> { + async fn test_no_constraints_no_pub_inputs() -> Result<(), Error> { let constraint_system = ConstraintSystem::new(); let case_1 = WitnessResult { @@ -416,11 +430,11 @@ mod test { }; let test_cases = vec![case_1]; - test_composer_with_pk_vk(constraint_system, test_cases) + test_composer_with_pk_vk(constraint_system, test_cases).await } #[test] - fn test_a_single_constraint_no_pub_inputs() -> Result<(), Error> { + async fn test_a_single_constraint_no_pub_inputs() -> Result<(), Error> { let constraint = Constraint { a: 1, b: 2, @@ -473,10 +487,11 @@ mod test { }; let test_cases = vec![case_1, case_2, case_3, case_4, case_5]; - test_composer_with_pk_vk(constraint_system, test_cases) + test_composer_with_pk_vk(constraint_system, test_cases).await } + #[test] - fn test_a_single_constraint_with_pub_inputs() -> Result<(), Error> { + async fn test_a_single_constraint_with_pub_inputs() -> Result<(), Error> { let constraint = Constraint { a: 1, b: 2, @@ -545,11 +560,11 @@ mod test { /*case_1,*/ case_2, case_3, /*case_4,*/ case_5, case_6, ]; - test_composer_with_pk_vk(constraint_system, test_cases) + test_composer_with_pk_vk(constraint_system, test_cases).await } #[test] - fn test_multiple_constraints() -> Result<(), Error> { + async fn test_multiple_constraints() -> Result<(), Error> { let constraint = Constraint { a: 1, b: 2, @@ -587,11 +602,11 @@ mod test { result: false, }; - test_composer_with_pk_vk(constraint_system, vec![case_1, case_2]) + test_composer_with_pk_vk(constraint_system, vec![case_1, case_2]).await } #[test] - fn test_schnorr_constraints() -> Result<(), Error> { + async fn test_schnorr_constraints() -> Result<(), Error> { let mut signature_indices = [0i32; 64]; for i in 13..(13 + 64) { signature_indices[i - 13] = i as i32; @@ -664,11 +679,11 @@ mod test { result: true, }; - test_composer_with_pk_vk(constraint_system, vec![case_1]) + test_composer_with_pk_vk(constraint_system, vec![case_1]).await } #[test] - fn test_keccak256_constraint() -> Result<(), Error> { + async fn test_keccak256_constraint() -> Result<(), Error> { let input_value: u128 = 0xbd; let input_index = 1; @@ -715,10 +730,11 @@ mod test { result: true, }; - test_composer_with_pk_vk(constraint_system, vec![case_1]) + test_composer_with_pk_vk(constraint_system, vec![case_1]).await } + #[test] - fn test_ped_constraints() -> Result<(), Error> { + async fn test_ped_constraints() -> Result<(), Error> { let constraint = PedersenConstraint { inputs: vec![1, 2], result_x: 3, @@ -767,11 +783,11 @@ mod test { result: true, }; - test_composer_with_pk_vk(constraint_system, vec![case_1]) + test_composer_with_pk_vk(constraint_system, vec![case_1]).await } #[test] - fn test_memory_constraints() -> Result<(), Error> { + async fn test_memory_constraints() -> Result<(), Error> { let two_field = FieldElement::one() + FieldElement::one(); let one = Constraint { a: 0, @@ -873,14 +889,14 @@ mod test { result: false, }; - test_composer_with_pk_vk(constraint_system, vec![case_1, case_2]) + test_composer_with_pk_vk(constraint_system, vec![case_1, case_2]).await } #[test] - fn test_compute_merkle_root_constraint() -> Result<(), Error> { - let mut msg_hasher: blake2::Blake2s = MessageHasher::new(); + async fn test_compute_merkle_root_constraint() -> Result<(), Error> { + let mut msg_hasher: blake2::Blake2s256 = MessageHasher::new(); - let tree: MerkleTree = MerkleTree::new(3); + let tree: MerkleTree = MerkleTree::new(3); let empty_leaf = vec![0; 64]; @@ -922,11 +938,11 @@ mod test { result: true, }; - test_composer_with_pk_vk(constraint_system, vec![case_1]) + test_composer_with_pk_vk(constraint_system, vec![case_1]).await } #[test] - fn test_logic_constraints() -> Result<(), Error> { + async fn test_logic_constraints() -> Result<(), Error> { /* * constraints produced by Noir program: * fn main(x : u32, y : pub u32) { @@ -1012,7 +1028,7 @@ mod test { result: true, }; - test_composer_with_pk_vk(constraint_system, vec![case_1]) + test_composer_with_pk_vk(constraint_system, vec![case_1]).await } #[derive(Clone, Debug)] @@ -1022,19 +1038,21 @@ mod test { result: bool, } - fn test_composer_with_pk_vk( + async fn test_composer_with_pk_vk( constraint_system: ConstraintSystem, test_cases: Vec, ) -> Result<(), Error> { let bb = Barretenberg::new(); + let crs = bb.get_crs(&constraint_system).await?; let proving_key = bb.compute_proving_key(&constraint_system)?; - let verification_key = bb.compute_verification_key(&constraint_system, &proving_key)?; + let verification_key = bb.compute_verification_key(&crs, &proving_key)?; for test_case in test_cases.into_iter() { let proof = - bb.create_proof_with_pk(&constraint_system, test_case.witness, &proving_key)?; + bb.create_proof_with_pk(&crs, &constraint_system, test_case.witness, &proving_key)?; let verified = bb.verify_with_vk( + &crs, &constraint_system, &proof, test_case.public_inputs, diff --git a/src/crs.rs b/src/crs.rs index e1f293a7..6e073a42 100644 --- a/src/crs.rs +++ b/src/crs.rs @@ -1,194 +1,175 @@ -use std::{env, fs::File, io::Write, path::PathBuf}; +use bytesize::ByteSize; +use reqwest::Client; +use serde::{Deserialize, Serialize}; +use std::env; -use futures_util::StreamExt; +use crate::{CRSError, Error}; -// TODO(blaine): Use manifest parsing in BB instead of hardcoding these +// TODO(#175): Use manifest parsing in BB instead of hardcoding these const G1_START: usize = 28; const G2_START: usize = 28 + (5_040_001 * 64); const G2_END: usize = G2_START + 128 - 1; -const BACKEND_IDENTIFIER: &str = "acvm-backend-barretenberg"; -const TRANSCRIPT_NAME: &str = "transcript00.dat"; -const TRANSCRIPT_URL: &str = - "http://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/monomial/transcript00.dat"; - -fn transcript_location() -> PathBuf { - match env::var("BARRETENBERG_TRANSCRIPT") { - Ok(dir) => PathBuf::from(dir), - Err(_) => dirs::home_dir() - .unwrap() - .join(".nargo") - .join("backends") - .join(BACKEND_IDENTIFIER) - .join(TRANSCRIPT_NAME), - } -} +const TRANSCRIPT_URL_ENV_VAR: &str = "TRANSCRIPT_URL"; +const TRANSCRIPT_URL_FALLBACK: &str = + "https://aztec-ignition.s3.amazonaws.com/MAIN%20IGNITION/monomial/transcript00.dat"; #[allow(clippy::upper_case_acronyms)] -#[derive(Clone, Default)] +#[derive(Clone, Default, Debug, PartialEq, Serialize, Deserialize)] pub(crate) struct CRS { pub(crate) g1_data: Vec, pub(crate) g2_data: Vec, - // num_points: usize, + pub(crate) num_points: usize, } impl CRS { - pub(crate) fn new(num_points: usize) -> CRS { + pub(crate) async fn update(&mut self, num_points: usize) -> Result<(), Error> { + // We already have some data, so start at the end of our list + let g1_start = G1_START + self.g1_data.len(); // UltraPlonk requires a CRS equal to circuit size plus one! // We need to bump our polynomial degrees by 1 to handle zero knowledge let g1_end = G1_START + ((num_points + 1) * 64) - 1; - // If the CRS does not exist, then download it from S3 - if !transcript_location().exists() { - download_crs(transcript_location()).unwrap(); - } + // If the `g1_end` is <= the `g1_start`, we already have enough CRS + if g1_end > g1_start { + let mut g1_data = download(g1_start, g1_end).await?; - // Read CRS, if it's incomplete, download it - let mut crs = read_crs(transcript_location()); - if crs.len() < G2_END + 1 { - download_crs(transcript_location()).unwrap(); - crs = read_crs(transcript_location()); + self.g1_data.append(&mut g1_data); + self.num_points = num_points; } - let g1_data = crs[G1_START..=g1_end].to_vec(); - let g2_data = crs[G2_START..=G2_END].to_vec(); - - CRS { - g1_data, - g2_data, - // num_points, - } + Ok(()) } } -// TODO(blaine): Come up with a better abstraction for the CRS so we don't need to read the -// file everytime we need the G2 -pub(crate) struct G2 { - pub(crate) data: Vec, -} - -impl G2 { - pub(crate) fn new() -> G2 { - // If the CRS does not exist, then download it from S3 - if !transcript_location().exists() { - download_crs(transcript_location()).unwrap(); - } - - // Read CRS, if it's incomplete, download it - let mut crs = read_crs(transcript_location()); - if crs.len() < G2_END + 1 { - download_crs(transcript_location()).unwrap(); - crs = read_crs(transcript_location()); - } +impl TryFrom<&[u8]> for CRS { + type Error = CRSError; - let data = crs[G2_START..=G2_END].to_vec(); - - G2 { data } + fn try_from(value: &[u8]) -> Result { + bincode::deserialize(value).map_err(|source| CRSError::Deserialize { source }) } } -impl Default for G2 { - fn default() -> Self { - Self::new() - } -} +impl TryFrom> for CRS { + type Error = CRSError; -fn read_crs(path: PathBuf) -> Vec { - match std::fs::read(&path) { - Ok(bytes) => bytes, - Err(e) => { - assert!( - e.kind() != std::io::ErrorKind::PermissionDenied, - "please run again with appropriate permissions." - ); - panic!( - "Could not find transcript at location {}.\n Starting Download", - path.display() - ); - } + fn try_from(value: Vec) -> Result { + bincode::deserialize(&value).map_err(|source| CRSError::Deserialize { source }) } } -// XXX: Below is the logic to download the CRS if it is not already present +impl TryFrom for Vec { + type Error = CRSError; -pub(crate) fn download_crs(path_to_transcript: PathBuf) -> Result<(), String> { - tokio::runtime::Builder::new_current_thread() - .enable_all() - .build() - .unwrap() - .block_on(download_crs_async(path_to_transcript)) + fn try_from(value: CRS) -> Result { + bincode::serialize(&value).map_err(|source| CRSError::Serialize { source }) + } } -async fn download_crs_async(path_to_transcript: PathBuf) -> Result<(), String> { - // Remove old crs - if path_to_transcript.exists() { - let _ = std::fs::remove_file(path_to_transcript.as_path()); +impl TryFrom<&CRS> for Vec { + type Error = CRSError; + + fn try_from(value: &CRS) -> Result { + bincode::serialize(value).map_err(|source| CRSError::Serialize { source }) } +} - // Pop off the transcript component to get just the directory - let transcript_dir = path_to_transcript - .parent() - .expect("transcript file should have parent"); +async fn download(start: usize, end: usize) -> Result, CRSError> { + // TODO(#187): Allow downloading from more than just the first transcript + // We try to load a URL from the environment and otherwise fallback to a hardcoded URL to allow + // Nix to override the URL for testing in the sandbox, where there is no network access on Linux + let transcript_url = match env::var(TRANSCRIPT_URL_ENV_VAR) { + Ok(url) => url, + Err(_) => TRANSCRIPT_URL_FALLBACK.into(), + }; - if !transcript_dir.exists() { - std::fs::create_dir_all(transcript_dir).unwrap(); - } + let client = Client::new(); - let res = reqwest::get(TRANSCRIPT_URL) + let request = client + .get(&transcript_url) + .header(reqwest::header::RANGE, format!("bytes={start}-{end}")) + .build() + .map_err(|source| CRSError::Request { + url: transcript_url.to_string(), + source, + })?; + let response = client + .execute(request) .await - .map_err(|err| format!("Failed to GET from '{}' ({})", TRANSCRIPT_URL, err))?; - let total_size = res.content_length().ok_or(format!( - "Failed to get content length from '{}'", - TRANSCRIPT_URL - ))?; - - // Indicatif setup - use indicatif::{HumanBytes, ProgressBar, ProgressStyle}; - let pb = ProgressBar::new(total_size).with_style( - ProgressStyle::default_bar() - .template("[{elapsed_precise}] {bar:40.cyan/blue} {bytes:>7}/{total_bytes:7} {msg}") - .unwrap() - .progress_chars("##-"), - ); - - // download chunks - let mut file = File::create(path_to_transcript.clone()).map_err(|err| { - format!( - "Failed to create file '{}' ({})", - path_to_transcript.display(), - err - ) + .map_err(|source| CRSError::Fetch { + url: transcript_url.to_string(), + source, + })?; + let total_size = response.content_length().ok_or(CRSError::Length { + url: transcript_url.to_string(), })?; - let mut stream = res.bytes_stream(); + // TODO(#195): We probably want to consider an injectable logger so we can have logging in JS println!( - "\nDownloading the Ignite SRS ({})\n", - HumanBytes(total_size) + "\nDownloading the Ignite SRS ({})", + ByteSize(total_size).to_string_as(false) ); - while let Some(item) = stream.next().await { - let chunk = item.map_err(|_| "Error while downloading file".to_string())?; - file.write_all(&chunk) - .map_err(|_| "Error while writing to file".to_string())?; - pb.inc(chunk.len() as u64); - } - pb.finish_with_message("Downloaded the SRS successfully!\n"); + let crs_bytes = response + .bytes() + .await + .map_err(|source| CRSError::Download { source })?; + println!("Downloaded the SRS successfully!"); - println!("SRS is located at: {:?}", &path_to_transcript); + Ok(crs_bytes.into()) +} + +pub(crate) async fn download_crs(num_points: usize) -> Result { + // UltraPlonk requires a CRS equal to circuit size plus one! + // We need to bump our polynomial degrees by 1 to handle zero knowledge + let g1_end = G1_START + ((num_points + 1) * 64) - 1; - Ok(()) + let g1_data = download(G1_START, g1_end).await?; + let g2_data = download(G2_START, G2_END).await?; + + Ok(CRS { + g1_data, + g2_data, + num_points, + }) } -#[cfg(feature = "native")] -#[test] -fn does_not_panic() { - let num_points = 4 * 1024; +#[cfg(test)] +mod tests { + use tokio::test; + + use crate::{crs::download_crs, Error}; + + #[test] + async fn does_not_panic() -> Result<(), Error> { + use crate::Barretenberg; + + let backend = Barretenberg::default(); + let num_points = 4 * 1024; + + let crs = download_crs(num_points).await?; + + let _pippenger = backend.get_pippenger(&crs.g1_data)?; + + // TODO(#193) check that p_points memory is properly free + + Ok(()) + } + + #[test] + async fn crs_update() -> Result<(), Error> { + let partial_num_points = 2; + let full_num_points = 12; + + // Create a partial CRS + let mut partial_crs = download_crs(partial_num_points).await?; - let crs = CRS::new(num_points); + // Update the partial CRS to the full number of points + partial_crs.update(full_num_points).await?; - let p_points = barretenberg_sys::pippenger::new(&crs.g1_data); + // Fetch a full CRS to compare + let full_crs = download_crs(full_num_points).await?; - unsafe { - Vec::from_raw_parts(p_points as *mut u8, num_points * 32, num_points * 32); + assert_eq!(partial_crs, full_crs); + Ok(()) } - //TODO check that p_points memory is properly free } diff --git a/src/lib.rs b/src/lib.rs index 0ca43c27..6690b437 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -65,6 +65,24 @@ enum FeatureError { InvalidBool, } +#[derive(Debug, Error)] +enum CRSError { + #[error("Failed to deserialize CRS")] + Deserialize { source: Box }, + #[error("Failed to serialize CRS")] + Serialize { source: Box }, + + #[error("Failed to build request '{url}' ({source})")] + Request { url: String, source: reqwest::Error }, + #[error("Failed to GET from '{url}' ({source})")] + Fetch { url: String, source: reqwest::Error }, + #[error("Failed to get content length from '{url}'")] + Length { url: String }, + #[error("Error while downloading file")] + Download { source: reqwest::Error }, +} + +#[allow(clippy::upper_case_acronyms)] #[derive(Debug, Error)] enum Error { #[error("The value {0} overflows in the pow2ceil function")] @@ -78,6 +96,9 @@ enum Error { #[error(transparent)] FromFeature(#[from] FeatureError), + + #[error(transparent)] + CRS(#[from] CRSError), } #[derive(Debug, Error)] @@ -90,6 +111,12 @@ impl From for BackendError { } } +impl From for BackendError { + fn from(value: CRSError) -> Self { + value.into() + } +} + /// The number of bytes necessary to store a `FieldElement`. const FIELD_BYTES: usize = 32; diff --git a/src/merkle.rs b/src/merkle.rs index 4446f47b..60edc29b 100644 --- a/src/merkle.rs +++ b/src/merkle.rs @@ -26,10 +26,10 @@ pub(crate) trait MessageHasher { fn hash(&mut self, msg: &[u8]) -> FieldElement; } -impl MessageHasher for blake2::Blake2s { +impl MessageHasher for blake2::Blake2s256 { fn new() -> Self { use blake2::Digest; - ::new() + ::new() } fn hash(&mut self, msg: &[u8]) -> FieldElement { @@ -315,7 +315,7 @@ impl MerkleTree { #[test] fn basic_interop_initial_root() { // Test that the initial root is computed correctly - let tree: MerkleTree = MerkleTree::new(3); + let tree: MerkleTree = MerkleTree::new(3); // Copied from barretenberg by copying the stdout from MemoryTree let expected_hex = "04ccfbbb859b8605546e03dcaf41393476642859ff7f99446c054b841f0e05c8"; assert_eq!(tree.root().to_hex(), expected_hex) @@ -324,7 +324,7 @@ fn basic_interop_initial_root() { #[test] fn basic_interop_hashpath() { // Test that the hashpath is correct - let tree: MerkleTree = MerkleTree::new(3); + let tree: MerkleTree = MerkleTree::new(3); let path = tree.get_hash_path(0); @@ -352,7 +352,7 @@ fn basic_interop_hashpath() { #[test] fn basic_interop_update() -> Result<(), Error> { // Test that computing the HashPath is correct - let mut tree: MerkleTree = MerkleTree::new(3); + let mut tree: MerkleTree = MerkleTree::new(3); tree.update_message(0, &[0; 64])?; tree.update_message(1, &[1; 64])?;