From 299c89d36f0e9cb21ef723899e434990a2c90ee5 Mon Sep 17 00:00:00 2001 From: David Banks <47112877+dbanks12@users.noreply.github.com> Date: Wed, 31 Jan 2024 13:39:59 -0500 Subject: [PATCH] feat(avm-transpiler): Brillig to AVM transpiler (#4227) Resolves #4270 1. Transpiler module 2. Docker & CI for transpiler module 3. Auto-transpile contracts starting with `avm_test_*` 4. AVM test contract for transpilation & simulation 5. AVM Simulator test with transpiled contract 6. Small fix in TS TaggedMemory --------- Co-authored-by: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> --- .circleci/config.yml | 15 + avm-transpiler/.gitignore | 2 + avm-transpiler/Cargo.lock | 2019 +++++++++++++++++ avm-transpiler/Cargo.toml | 21 + avm-transpiler/Dockerfile | 13 + avm-transpiler/Dockerfile.dockerignore | 7 + avm-transpiler/README.md | 15 + avm-transpiler/bootstrap.sh | 19 + avm-transpiler/scripts/bootstrap_native.sh | 20 + avm-transpiler/src/instructions.rs | 115 + avm-transpiler/src/main.rs | 46 + avm-transpiler/src/opcodes.rs | 168 ++ avm-transpiler/src/transpile.rs | 289 +++ avm-transpiler/src/transpile_contract.rs | 120 + avm-transpiler/src/utils.rs | 41 + bootstrap.sh | 1 + build_manifest.yml | 7 + .../src/avm/avm_memory_types.ts | 6 +- .../acir-simulator/src/avm/index.test.ts | 26 +- .../cli/src/cmds/example_contracts.ts | 2 +- yarn-project/noir-contracts/Nargo.toml | 7 +- .../contracts/avm_test_contract/Nargo.toml | 8 + .../contracts/avm_test_contract/src/main.nr | 26 + yarn-project/noir-contracts/package.json | 2 +- .../noir-contracts/package.local.json | 2 +- .../noir-contracts/scripts/transpile.sh | 8 + yarn-project/yarn-project-base/Dockerfile | 3 + 27 files changed, 2999 insertions(+), 9 deletions(-) create mode 100644 avm-transpiler/.gitignore create mode 100644 avm-transpiler/Cargo.lock create mode 100644 avm-transpiler/Cargo.toml create mode 100644 avm-transpiler/Dockerfile create mode 100644 avm-transpiler/Dockerfile.dockerignore create mode 100644 avm-transpiler/README.md create mode 100755 avm-transpiler/bootstrap.sh create mode 100755 avm-transpiler/scripts/bootstrap_native.sh create mode 100644 avm-transpiler/src/instructions.rs create mode 100644 avm-transpiler/src/main.rs create mode 100644 avm-transpiler/src/opcodes.rs create mode 100644 avm-transpiler/src/transpile.rs create mode 100644 avm-transpiler/src/transpile_contract.rs create mode 100644 avm-transpiler/src/utils.rs create mode 100644 yarn-project/noir-contracts/contracts/avm_test_contract/Nargo.toml create mode 100644 yarn-project/noir-contracts/contracts/avm_test_contract/src/main.nr create mode 100755 yarn-project/noir-contracts/scripts/transpile.sh diff --git a/.circleci/config.yml b/.circleci/config.yml index 0fae211493d..b036b70684a 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -125,6 +125,17 @@ jobs: name: "Build" command: cond_spot_run_build noir-compile-acir-tests 32 + avm-transpiler: + docker: + - image: aztecprotocol/alpine-build-image + resource_class: small + steps: + - *checkout + - *setup_env + - run: + name: "Build" + command: cond_spot_run_build avm-transpiler 32 + # Barretenberg barretenberg-wasm-linux-clang: docker: @@ -1137,6 +1148,9 @@ workflows: - noir-ecr-manifest <<: *defaults + # Transpiler + - avm-transpiler: *defaults + # Barretenberg - barretenberg-x86_64-linux-gcc: *defaults - barretenberg-x86_64-linux-clang: *defaults @@ -1185,6 +1199,7 @@ workflows: # Yarn Project - yarn-project-base: requires: + - avm-transpiler - l1-contracts - bb-js - noir-ecr-manifest diff --git a/avm-transpiler/.gitignore b/avm-transpiler/.gitignore new file mode 100644 index 00000000000..212de442f4e --- /dev/null +++ b/avm-transpiler/.gitignore @@ -0,0 +1,2 @@ +/target +.DS_Store \ No newline at end of file diff --git a/avm-transpiler/Cargo.lock b/avm-transpiler/Cargo.lock new file mode 100644 index 00000000000..ea35df3013e --- /dev/null +++ b/avm-transpiler/Cargo.lock @@ -0,0 +1,2019 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "acir" +version = "0.39.0" +dependencies = [ + "acir_field", + "base64 0.21.7", + "bincode", + "brillig", + "flate2", + "serde", + "thiserror", +] + +[[package]] +name = "acir_field" +version = "0.39.0" +dependencies = [ + "ark-bn254", + "ark-ff", + "cfg-if", + "hex", + "num-bigint", + "num-traits", + "serde", +] + +[[package]] +name = "acvm" +version = "0.39.0" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "brillig_vm", + "indexmap 1.9.3", + "num-bigint", + "thiserror", + "tracing", +] + +[[package]] +name = "acvm_blackbox_solver" +version = "0.39.0" +dependencies = [ + "acir", + "blake2", + "blake3", + "k256", + "keccak", + "p256", + "sha2", + "sha3", + "thiserror", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "arena" +version = "0.23.0" +dependencies = [ + "generational-arena", +] + +[[package]] +name = "ark-bn254" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a22f4561524cd949590d78d7d4c5df8f592430d221f7f3c9497bbafd8972120f" +dependencies = [ + "ark-ec", + "ark-ff", + "ark-std", +] + +[[package]] +name = "ark-ec" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defd9a439d56ac24968cca0571f598a61bc8c55f71d50a89cda591cb750670ba" +dependencies = [ + "ark-ff", + "ark-poly", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", + "itertools", + "num-traits", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", + "derivative", + "digest", + "itertools", + "num-bigint", + "num-traits", + "paste", + "rustc_version", + "zeroize", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-poly" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d320bfc44ee185d899ccbadfa8bc31aab923ce1558716e1997a1e74057fe86bf" +dependencies = [ + "ark-ff", + "ark-serialize", + "ark-std", + "derivative", + "hashbrown 0.13.2", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-serialize-derive", + "ark-std", + "digest", + "num-bigint", +] + +[[package]] +name = "ark-serialize-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae3281bc6d0fd7e549af32b52511e1302185bd688fd3359fa36423346ff682ea" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "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 = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "avm-transpiler" +version = "0.1.0" +dependencies = [ + "acvm", + "base64 0.21.7", + "env_logger", + "log", + "noirc_driver", + "regex", + "serde", + "serde_json", +] + +[[package]] +name = "aztec_macros" +version = "0.23.0" +dependencies = [ + "iter-extended", + "noirc_frontend", +] + +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bitmaps" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" +dependencies = [ + "typenum", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brillig" +version = "0.39.0" +dependencies = [ + "acir_field", + "serde", +] + +[[package]] +name = "brillig_vm" +version = "0.39.0" +dependencies = [ + "acir", + "acvm_blackbox_solver", + "num-bigint", + "num-traits", +] + +[[package]] +name = "build-data" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aed3884e2cab7c973c8fd2d150314b6a932df7fdc830edcaf1e8e7c4ae9db3c0" +dependencies = [ + "chrono", + "safe-lock", + "safe-regex", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "num-traits", + "serde", + "windows-targets", +] + +[[package]] +name = "chumsky" +version = "0.8.0" +source = "git+https://github.com/jfecher/chumsky?rev=ad9d312#ad9d312d9ffbc66c14514fa2b5752f4127b44f1e" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "codespan" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3362992a0d9f1dd7c3d0e89e0ab2bb540b7a95fea8cd798090e758fda2899b5e" +dependencies = [ + "codespan-reporting", + "serde", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "serde", + "termcolor", + "unicode-width", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array", + "rand_core", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "darling" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.48", +] + +[[package]] +name = "darling_macro" +version = "0.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", + "serde", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der", + "elliptic-curve", + "rfc6979", + "signature", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct", + "crypto-bigint", + "der", + "digest", + "ff", + "generic-array", + "group", + "pkcs8", + "rand_core", + "sec1", + "subtle", + "zeroize", +] + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05e7cf40684ae96ade6232ed84582f40ce0a66efcd43a5117aef610534f8e0b8" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core", + "subtle", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fm" +version = "0.23.0" +dependencies = [ + "codespan-reporting", + "serde", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generational-arena" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877e94aff08e743b651baaea359664321055749b398adff8740a7399af7796e7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff", + "rand_core", + "subtle", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash 0.8.7", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "iana-time-zone" +version = "0.1.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "im" +version = "15.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0acd33ff0285af998aaf9b57342af478078f53492322fafc47450e09397e0e9" +dependencies = [ + "bitmaps", + "rand_core", + "rand_xoshiro", + "serde", + "sized-chunks", + "typenum", + "version_check", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", + "serde", +] + +[[package]] +name = "iter-extended" +version = "0.23.0" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "jsonrpc" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34efde8d2422fb79ed56db1d3aea8fa5b583351d15a26770cdee2f88813dd702" +dependencies = [ + "base64 0.13.1", + "minreq", + "serde", + "serde_json", +] + +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "minreq" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb3371dfc7b772c540da1380123674a8e20583aca99907087d990ca58cf44203" +dependencies = [ + "log", + "serde", + "serde_json", +] + +[[package]] +name = "noirc_abi" +version = "0.23.0" +dependencies = [ + "acvm", + "iter-extended", + "noirc_frontend", + "num-bigint", + "num-traits", + "serde", + "serde_json", + "thiserror", + "toml", +] + +[[package]] +name = "noirc_driver" +version = "0.23.0" +dependencies = [ + "acvm", + "aztec_macros", + "build-data", + "clap", + "fm", + "fxhash", + "iter-extended", + "noirc_abi", + "noirc_errors", + "noirc_evaluator", + "noirc_frontend", + "rust-embed", + "serde", + "tracing", +] + +[[package]] +name = "noirc_errors" +version = "0.23.0" +dependencies = [ + "acvm", + "base64 0.21.7", + "chumsky", + "codespan", + "codespan-reporting", + "flate2", + "fm", + "serde", + "serde_json", + "serde_with", + "tracing", +] + +[[package]] +name = "noirc_evaluator" +version = "0.23.0" +dependencies = [ + "acvm", + "fxhash", + "im", + "iter-extended", + "noirc_errors", + "noirc_frontend", + "num-bigint", + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "noirc_frontend" +version = "0.23.0" +dependencies = [ + "acvm", + "arena", + "chumsky", + "fm", + "iter-extended", + "noirc_errors", + "noirc_printable_type", + "regex", + "rustc-hash", + "serde", + "serde_json", + "small-ord-set", + "smol_str", + "thiserror", + "tracing", +] + +[[package]] +name = "noirc_printable_type" +version = "0.23.0" +dependencies = [ + "acvm", + "iter-extended", + "jsonrpc", + "regex", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "p256" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51f44edd08f51e2ade572f141051021c5af22677e42b7dd28a88155151c33594" +dependencies = [ + "ecdsa", + "elliptic-curve", + "sha2", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro2" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xoshiro" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" +dependencies = [ + "rand_core", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint", + "hmac", + "zeroize", +] + +[[package]] +name = "rust-embed" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a36224c3276f8c4ebc8c20f158eca7ca4359c8db89991c4925132aaaf6702661" +dependencies = [ + "rust-embed-impl", + "rust-embed-utils", + "walkdir", +] + +[[package]] +name = "rust-embed-impl" +version = "6.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49b94b81e5b2c284684141a2fb9e2a31be90638caf040bf9afbc5a0416afe1ac" +dependencies = [ + "proc-macro2", + "quote", + "rust-embed-utils", + "syn 2.0.48", + "walkdir", +] + +[[package]] +name = "rust-embed-utils" +version = "7.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d38ff6bf570dc3bb7100fce9f7b60c33fa71d80e88da3f2580df4ff2bdded74" +dependencies = [ + "sha2", + "walkdir", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "safe-lock" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "077d73db7973cccf63eb4aff1e5a34dc2459baa867512088269ea5f2f4253c90" + +[[package]] +name = "safe-proc-macro2" +version = "1.0.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fd85be67db87168aa3c13fd0da99f48f2ab005dccad5af5626138dc1df20eb6" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "safe-quote" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77e530f7831f3feafcd5f1aae406ac205dd998436b4007c8e80f03eca78a88f7" +dependencies = [ + "safe-proc-macro2", +] + +[[package]] +name = "safe-regex" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15289bf322e0673d52756a18194167f2378ec1a15fe884af6e2d2cb934822b0" +dependencies = [ + "safe-regex-macro", +] + +[[package]] +name = "safe-regex-compiler" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba76fae590a2aa665279deb1f57b5098cbace01a0c5e60e262fcf55f7c51542" +dependencies = [ + "safe-proc-macro2", + "safe-quote", +] + +[[package]] +name = "safe-regex-macro" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c2e96b5c03f158d1b16ba79af515137795f4ad4e8de3f790518aae91f1d127" +dependencies = [ + "safe-proc-macro2", + "safe-regex-compiler", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "subtle", + "zeroize", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" + +[[package]] +name = "serde" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_json" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_with" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5c9fdb6b00a489875b22efd4b78fe2b363b72265cc5f6eb2e2b9ee270e6140c" +dependencies = [ + "base64 0.21.7", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.1.0", + "serde", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbff351eb4b33600a2e138dfa0b10b65a238ea8ff8fb2387c422c5022a3e8298" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "sized-chunks" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" +dependencies = [ + "bitmaps", + "typenum", +] + +[[package]] +name = "small-ord-set" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf7035a2b2268a5be8c1395738565b06beda836097e12021cdefc06b127a0e7e" +dependencies = [ + "smallvec", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "smol_str" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fad6c857cbab2627dcf01ec85a623ca4e7dcb5691cbaa3d7fb7653671f0d09c9" +dependencies = [ + "serde", +] + +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "itoa", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +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.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +dependencies = [ + "memchr", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] diff --git a/avm-transpiler/Cargo.toml b/avm-transpiler/Cargo.toml new file mode 100644 index 00000000000..9d4f0a001ea --- /dev/null +++ b/avm-transpiler/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "avm-transpiler" +version = "0.1.0" +authors = ["The Aztec Team "] +edition = "2021" +license = "MIT OR Apache-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +# local +acvm = { path = "../noir/acvm-repo/acvm" } +noirc_driver = { path = "../noir/compiler/noirc_driver" } + +# external +base64 = "0.21" +regex = "1.10" +env_logger = "0.11" +log = "0.4" +serde_json = "1.0" +serde = { version = "1.0.136", features = ["derive"]} \ No newline at end of file diff --git a/avm-transpiler/Dockerfile b/avm-transpiler/Dockerfile new file mode 100644 index 00000000000..1f55f8ba40d --- /dev/null +++ b/avm-transpiler/Dockerfile @@ -0,0 +1,13 @@ +FROM rust:bookworm + +WORKDIR /usr/src +COPY ./avm-transpiler ./avm-transpiler +COPY ./noir ./noir + +WORKDIR /usr/src/avm-transpiler +RUN apt-get update && apt-get install -y git +RUN ./scripts/bootstrap_native.sh + +FROM ubuntu:lunar +COPY --from=0 /usr/src/avm-transpiler/target/release/avm-transpiler /usr/src/avm-transpiler/target/release/avm-transpiler +ENTRYPOINT ["sh", "-c"] \ No newline at end of file diff --git a/avm-transpiler/Dockerfile.dockerignore b/avm-transpiler/Dockerfile.dockerignore new file mode 100644 index 00000000000..8edf9d12d62 --- /dev/null +++ b/avm-transpiler/Dockerfile.dockerignore @@ -0,0 +1,7 @@ +** + +!avm-transpiler/ +!noir/ +**/target/ +**/node_modules/ +**/packages/ \ No newline at end of file diff --git a/avm-transpiler/README.md b/avm-transpiler/README.md new file mode 100644 index 00000000000..2cd932c2451 --- /dev/null +++ b/avm-transpiler/README.md @@ -0,0 +1,15 @@ +# AVM Transpiler + +This component transpiles Aztec public contracts code from Noir's Brillig bytecode to AVM (Aztec Virtual Machine) bytecode. + +## Build + +``` +./boostrap.sh +``` + +## Run + +``` +cargo run +``` diff --git a/avm-transpiler/bootstrap.sh b/avm-transpiler/bootstrap.sh new file mode 100755 index 00000000000..916d8107876 --- /dev/null +++ b/avm-transpiler/bootstrap.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -eu + +cd $(dirname "$0") + +CMD=${1:-} + +if [ -n "$CMD" ]; then + if [ "$CMD" = "clean" ]; then + cargo clean + git clean -fdx + exit 0 + else + echo "Unknown command: $CMD" + exit 1 + fi +fi + +./scripts/bootstrap_native.sh \ No newline at end of file diff --git a/avm-transpiler/scripts/bootstrap_native.sh b/avm-transpiler/scripts/bootstrap_native.sh new file mode 100755 index 00000000000..3e0e2ed853a --- /dev/null +++ b/avm-transpiler/scripts/bootstrap_native.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -eu + +cd $(dirname "$0")/.. + +# If this project has been subrepod into another project, set build data manually. +export SOURCE_DATE_EPOCH=$(date +%s) +export GIT_DIRTY=false +if [ -f ".gitrepo" ]; then + export GIT_COMMIT=$(awk '/commit =/ {print $3}' .gitrepo) +else + export GIT_COMMIT=$(git rev-parse --verify HEAD) +fi + +# Build native. +if [ -n "${DEBUG:-}" ]; then + cargo build +else + cargo build --release +fi diff --git a/avm-transpiler/src/instructions.rs b/avm-transpiler/src/instructions.rs new file mode 100644 index 00000000000..efc195cc5b0 --- /dev/null +++ b/avm-transpiler/src/instructions.rs @@ -0,0 +1,115 @@ +use crate::opcodes::AvmOpcode; + +/// Common values of the indirect instruction flag +pub const ZEROTH_OPERAND_INDIRECT: u8 = 0b00000001; +pub const FIRST_OPERAND_INDIRECT: u8 = 0b00000010; +pub const ZEROTH_FIRST_OPERANDS_INDIRECT: u8 = 0b00000011; + +/// A simple representation of an AVM instruction for the purpose +/// of generating an AVM bytecode from Brillig. +/// Note: this does structure not impose rules like "ADD instruction must have 3 operands" +/// That job is left to the instruction decoder, not this thin transpiler. +pub struct AvmInstruction { + pub opcode: AvmOpcode, + + /// Any instructions with memory offset operands have the indirect flag + /// Each bit is a boolean: 0:direct, 1:indirect + /// The 0th bit corresponds to an instruction's 0th offset arg, 1st to 1st, etc... + pub indirect: Option, + + /// Some instructions have a destination or input tag + // TODO(4271): add in_tag alongside its support in TS + //pub in_tag: Option, + pub dst_tag: Option, + + /// Different instructions have different numbers of operands + pub operands: Vec, +} +impl AvmInstruction { + /// String representation for printing AVM programs + pub fn to_string(&self) -> String { + let mut out_str = format!("opcode {}", self.opcode.name()); + if let Some(indirect) = self.indirect { + out_str += format!(", indirect: {}", indirect).as_str(); + } + // TODO(4271): add in_tag alongside its support in TS + if let Some(dst_tag) = self.dst_tag { + out_str += format!(", dst_tag: {}", dst_tag as u8).as_str(); + } + if self.operands.len() > 0 { + out_str += ", operands: ["; + for operand in &self.operands { + out_str += format!("{}, ", operand.to_string()).as_str(); + } + out_str += "]"; + } + out_str + } + /// Bytes representation for generating AVM bytecode + pub fn to_bytes(&self) -> Vec { + let mut bytes = Vec::new(); + bytes.push(self.opcode as u8); + if let Some(indirect) = self.indirect { + bytes.push(indirect); + } + // TODO(4271): add in_tag alongside its support in TS + if let Some(dst_tag) = self.dst_tag { + // TODO(4271): make 8 bits when TS supports deserialization of 8 bit flags + //bytes.push(dst_tag as u8); + bytes.extend_from_slice(&(dst_tag as u32).to_be_bytes()); + } + for operand in &self.operands { + bytes.extend_from_slice(&operand.to_be_bytes()); + } + bytes + } +} +impl Default for AvmInstruction { + fn default() -> Self { + AvmInstruction { + opcode: AvmOpcode::ADD, + // TODO(4266): default to Some(0), since all instructions have indirect flag except jumps + indirect: None, + dst_tag: None, + operands: vec![], + } + } +} + +/// AVM instructions may include a type tag +#[derive(Copy, Clone)] +pub enum AvmTypeTag { + UNINITIALIZED, + UINT8, + UINT16, + UINT32, + UINT64, + UINT128, + FIELD, + INVALID, +} + +/// Operands are usually 32 bits (offsets or jump destinations) +/// Constants (as used by the SET instruction) can have size +/// different from 32 bits +pub enum AvmOperand { + U32 { value: u32 }, + // TODO(4267): Support operands of size other than 32 bits (for SET) + //U128 { value: u128 }, +} +impl AvmOperand { + pub fn to_string(&self) -> String { + match self { + AvmOperand::U32 { value } => format!(" U32:{}", value), + // TODO(4267): Support operands of size other than 32 bits (for SET) + //AvmOperand::U128 { value } => format!("U128:{}", value), + } + } + pub fn to_be_bytes(&self) -> Vec { + match self { + AvmOperand::U32 { value } => value.to_be_bytes().to_vec(), + // TODO(4267): Support operands of size other than 32 bits (for SET) + //AvmOperand::U128 { value } => value.to_be_bytes().to_vec(), + } + } +} diff --git a/avm-transpiler/src/main.rs b/avm-transpiler/src/main.rs new file mode 100644 index 00000000000..064bf343bbf --- /dev/null +++ b/avm-transpiler/src/main.rs @@ -0,0 +1,46 @@ +use log::warn; +use std::env; +use std::fs; +use std::path::Path; + +mod instructions; +mod opcodes; +mod transpile; +mod transpile_contract; +mod utils; + +use transpile_contract::{CompiledAcirContract, TranspiledContract}; + +fn main() { + env_logger::init(); + + let args: Vec = env::args().collect(); + let in_contract_artifact_path = &args[1]; + let out_transpiled_artifact_path = &args[2]; + + // Parse original (pre-transpile) contract + let contract_json = + fs::read_to_string(Path::new(in_contract_artifact_path)).expect("Unable to read file"); + let raw_json_obj: serde_json::Value = + serde_json::from_str(&contract_json).expect("Unable to parse json"); + + // Skip if contract has "transpiled: true" flag! + if let Some(transpiled) = raw_json_obj.get("transpiled") { + match transpiled { + serde_json::Value::Bool(true) => { + warn!("Contract already transpiled. Skipping."); + return; // nothing to transpile + } + _ => (), + } + } + // Parse json into contract object + let contract: CompiledAcirContract = + serde_json::from_str(&contract_json).expect("Unable to parse json"); + + // Transpile contract to AVM bytecode + let transpiled_contract = TranspiledContract::from(contract); + let transpiled_json = + serde_json::to_string(&transpiled_contract).expect("Unable to serialize json"); + fs::write(out_transpiled_artifact_path, transpiled_json).expect("Unable to write file"); +} diff --git a/avm-transpiler/src/opcodes.rs b/avm-transpiler/src/opcodes.rs new file mode 100644 index 00000000000..cc3c828d2ec --- /dev/null +++ b/avm-transpiler/src/opcodes.rs @@ -0,0 +1,168 @@ +/// All AVM opcodes +/// Keep updated with TS and yellow paper! +#[derive(Copy, Clone)] +pub enum AvmOpcode { + // Compute + // Compute - Arithmetic + ADD, + SUB, + MUL, + DIV, + // Compute - Comparators + EQ, + LT, + LTE, + // Compute - Bitwise + AND, + OR, + XOR, + NOT, + SHL, + SHR, + // Compute - Type Conversions + CAST, + + // Execution Environment + ADDRESS, + STORAGEADDRESS, + ORIGIN, + SENDER, + PORTAL, + FEEPERL1GAS, + FEEPERL2GAS, + FEEPERDAGAS, + CONTRACTCALLDEPTH, + // Execution Environment - Globals + CHAINID, + VERSION, + BLOCKNUMBER, + TIMESTAMP, + COINBASE, + BLOCKL1GASLIMIT, + BLOCKL2GASLIMIT, + BLOCKDAGASLIMIT, + // Execution Environment - Calldata + CALLDATACOPY, + + // Machine State + // Machine State - Gas + L1GASLEFT, + L2GASLEFT, + DAGASLEFT, + // Machine State - Internal Control Flow + JUMP, + JUMPI, + INTERNALCALL, + INTERNALRETURN, + // Machine State - Memory + SET, + MOV, + CMOV, + + // World State + BLOCKHEADERBYNUMBER, + SLOAD, // Public Storage + SSTORE, // Public Storage + READL1TOL2MSG, // Messages + SENDL2TOL1MSG, // Messages + EMITNOTEHASH, // Notes & Nullifiers + EMITNULLIFIER, // Notes & Nullifiers + + // Accrued Substate + EMITUNENCRYPTEDLOG, + + // Control Flow - Contract Calls + CALL, + STATICCALL, + RETURN, + REVERT, + + // Gadgets + KECCAK, + POSEIDON, +} + +impl AvmOpcode { + pub fn name(&self) -> &'static str { + match self { + // Compute + // Compute - Arithmetic + AvmOpcode::ADD => "ADD", + AvmOpcode::SUB => "SUB", + AvmOpcode::MUL => "MUL", + AvmOpcode::DIV => "DIV", + // Compute - Comparators + AvmOpcode::EQ => "EQ", + AvmOpcode::LT => "LT", + AvmOpcode::LTE => "LTE", + // Compute - Bitwise + AvmOpcode::AND => "AND", + AvmOpcode::OR => "OR", + AvmOpcode::XOR => "XOR", + AvmOpcode::NOT => "NOT", + AvmOpcode::SHL => "SHL", + AvmOpcode::SHR => "SHR", + // Compute - Type Conversions + AvmOpcode::CAST => "CAST", + + // Execution Environment + AvmOpcode::ADDRESS => "ADDRESS", + AvmOpcode::STORAGEADDRESS => "STORAGEADDRESS", + AvmOpcode::ORIGIN => "ORIGIN", + AvmOpcode::SENDER => "SENDER", + AvmOpcode::PORTAL => "PORTAL", + AvmOpcode::FEEPERL1GAS => "FEEPERL1GAS", + AvmOpcode::FEEPERL2GAS => "FEEPERL2GAS", + AvmOpcode::FEEPERDAGAS => "FEEPERDAGAS", + AvmOpcode::CONTRACTCALLDEPTH => "CONTRACTCALLDEPTH", + // Execution Environment - Globals + AvmOpcode::CHAINID => "CHAINID", + AvmOpcode::VERSION => "VERSION", + AvmOpcode::BLOCKNUMBER => "BLOCKNUMBER", + AvmOpcode::TIMESTAMP => "TIMESTAMP", + AvmOpcode::COINBASE => "COINBASE", + AvmOpcode::BLOCKL1GASLIMIT => "BLOCKL1GASLIMIT", + AvmOpcode::BLOCKL2GASLIMIT => "BLOCKL2GASLIMIT", + AvmOpcode::BLOCKDAGASLIMIT => "BLOCKDAGASLIMIT", + // Execution Environment - Calldata + AvmOpcode::CALLDATACOPY => "CALLDATACOPY", + + // Machine State + // Machine State - Gas + AvmOpcode::L1GASLEFT => "L1GASLEFT", + AvmOpcode::L2GASLEFT => "L2GASLEFT", + AvmOpcode::DAGASLEFT => "DAGASLEFT", + // Machine State - Internal Control Flow + AvmOpcode::JUMP => "JUMP", + AvmOpcode::JUMPI => "JUMPI", + AvmOpcode::INTERNALCALL => "INTERNALCALL", + AvmOpcode::INTERNALRETURN => "INTERNALRETURN", + // Machine State - Memory + AvmOpcode::SET => "SET", + AvmOpcode::MOV => "MOV", + AvmOpcode::CMOV => "CMOV", + + // World State + AvmOpcode::BLOCKHEADERBYNUMBER => "BLOCKHEADERBYNUMBER", + AvmOpcode::SLOAD => "SLOAD", // Public Storage + AvmOpcode::SSTORE => "SSTORE", // Public Storage + AvmOpcode::READL1TOL2MSG => "READL1TOL2MSG", // Messages + AvmOpcode::SENDL2TOL1MSG => "SENDL2TOL1MSG", // Messages + AvmOpcode::EMITNOTEHASH => "EMITNOTEHASH", // Notes & Nullifiers + AvmOpcode::EMITNULLIFIER => "EMITNULLIFIER", // Notes & Nullifiers + + // Accrued Substate + AvmOpcode::EMITUNENCRYPTEDLOG => "EMITUNENCRYPTEDLOG", + + // Control Flow - Contract Calls + AvmOpcode::CALL => "CALL", + AvmOpcode::STATICCALL => "STATICCALL", + AvmOpcode::RETURN => "RETURN", + AvmOpcode::REVERT => "REVERT", + + // Gadgets + AvmOpcode::KECCAK => "KECCAK", + AvmOpcode::POSEIDON => "POSEIDON", + } + } +} diff --git a/avm-transpiler/src/transpile.rs b/avm-transpiler/src/transpile.rs new file mode 100644 index 00000000000..9785e41c7a1 --- /dev/null +++ b/avm-transpiler/src/transpile.rs @@ -0,0 +1,289 @@ +use acvm::acir::brillig::Opcode as BrilligOpcode; +use acvm::acir::circuit::brillig::Brillig; + +use acvm::brillig_vm::brillig::{BinaryFieldOp, BinaryIntOp}; + +use crate::instructions::{ + AvmInstruction, AvmOperand, AvmTypeTag, FIRST_OPERAND_INDIRECT, ZEROTH_OPERAND_INDIRECT, +}; +use crate::opcodes::AvmOpcode; +use crate::utils::{dbg_print_avm_program, dbg_print_brillig_program}; + +/// Transpile a Brillig program to AVM bytecode +pub fn brillig_to_avm(brillig: &Brillig) -> Vec { + dbg_print_brillig_program(&brillig); + + let mut avm_instrs: Vec = Vec::new(); + + // Map Brillig pcs to AVM pcs + // (some Brillig instructions map to >1 AVM instruction) + let brillig_pcs_to_avm_pcs = map_brillig_pcs_to_avm_pcs(avm_instrs.len(), brillig); + + // Transpile a Brillig instruction to one or more AVM instructions + for brillig_instr in &brillig.bytecode { + match brillig_instr { + BrilligOpcode::BinaryFieldOp { + destination, + op, + lhs, + rhs, + } => { + let avm_opcode = match op { + BinaryFieldOp::Add => AvmOpcode::ADD, + BinaryFieldOp::Sub => AvmOpcode::SUB, + BinaryFieldOp::Mul => AvmOpcode::MUL, + BinaryFieldOp::Div => AvmOpcode::DIV, + BinaryFieldOp::Equals => AvmOpcode::EQ, + }; + // TODO(4268): set in_tag to `field` + avm_instrs.push(AvmInstruction { + opcode: avm_opcode, + operands: vec![ + AvmOperand::U32 { + value: lhs.to_usize() as u32, + }, + AvmOperand::U32 { + value: rhs.to_usize() as u32, + }, + AvmOperand::U32 { + value: destination.to_usize() as u32, + }, + ], + ..Default::default() + }); + } + BrilligOpcode::BinaryIntOp { + destination, + op, + bit_size: _, // TODO(4268): support u8..u128 and use in_tag + lhs, + rhs, + } => { + let avm_opcode = match op { + BinaryIntOp::Add => AvmOpcode::ADD, + BinaryIntOp::Sub => AvmOpcode::SUB, + BinaryIntOp::Mul => AvmOpcode::MUL, + BinaryIntOp::UnsignedDiv => AvmOpcode::DIV, + BinaryIntOp::Equals => AvmOpcode::EQ, + BinaryIntOp::LessThan => AvmOpcode::LT, + BinaryIntOp::LessThanEquals => AvmOpcode::LTE, + BinaryIntOp::And => AvmOpcode::AND, + BinaryIntOp::Or => AvmOpcode::OR, + BinaryIntOp::Xor => AvmOpcode::XOR, + BinaryIntOp::Shl => AvmOpcode::SHL, + BinaryIntOp::Shr => AvmOpcode::SHR, + _ => panic!( + "Transpiler doesn't know how to process BinaryIntOp {:?}", + brillig_instr + ), + }; + // TODO(4268): support u8..u128 and use in_tag + avm_instrs.push(AvmInstruction { + opcode: avm_opcode, + operands: vec![ + AvmOperand::U32 { + value: lhs.to_usize() as u32, + }, + AvmOperand::U32 { + value: rhs.to_usize() as u32, + }, + AvmOperand::U32 { + value: destination.to_usize() as u32, + }, + ], + ..Default::default() + }); + } + BrilligOpcode::CalldataCopy { destination_address, size, offset } => { + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::CALLDATACOPY, + operands: vec![ + AvmOperand::U32 { + value: *offset as u32, // cdOffset (calldata offset) + }, AvmOperand::U32 { + value: *size as u32, + }, AvmOperand::U32 { + value: destination_address.to_usize() as u32, // dstOffset + }], + ..Default::default() + }); + } + BrilligOpcode::Jump { location } => { + let avm_loc = brillig_pcs_to_avm_pcs[*location]; + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::JUMP, + operands: vec![AvmOperand::U32 { + value: avm_loc as u32, + }], + ..Default::default() + }); + } + BrilligOpcode::JumpIf { + condition, + location, + } => { + let avm_loc = brillig_pcs_to_avm_pcs[*location]; + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::JUMPI, + operands: vec![ + AvmOperand::U32 { + value: avm_loc as u32, + }, + AvmOperand::U32 { + value: condition.to_usize() as u32, + }, + ], + ..Default::default() + }); + } + BrilligOpcode::Const { destination, value } => { + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::SET, + dst_tag: Some(AvmTypeTag::UINT32), + operands: vec![ + // TODO(4267): support u8..u128 and use dst_tag + AvmOperand::U32 { + value: value.to_usize() as u32, + }, + AvmOperand::U32 { + value: destination.to_usize() as u32, + }, + ], + ..Default::default() + }); + } + BrilligOpcode::Mov { + destination, + source, + } => { + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::MOV, + operands: vec![ + AvmOperand::U32 { + value: source.to_usize() as u32, + }, + AvmOperand::U32 { + value: destination.to_usize() as u32, + }, + ], + ..Default::default() + }); + } + BrilligOpcode::Load { + destination, + source_pointer, + } => { + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::MOV, + indirect: Some(ZEROTH_OPERAND_INDIRECT), // indirect srcOffset operand + operands: vec![ + AvmOperand::U32 { + value: source_pointer.to_usize() as u32, + }, + AvmOperand::U32 { + value: destination.to_usize() as u32, + }, + ], + ..Default::default() + }); + } + BrilligOpcode::Store { + destination_pointer, + source, + } => { + // INDIRECT dstOffset operand (bit 1 set high) + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::MOV, + indirect: Some(FIRST_OPERAND_INDIRECT), // indirect dstOffset operand + operands: vec![ + AvmOperand::U32 { + value: source.to_usize() as u32, + }, + AvmOperand::U32 { + value: destination_pointer.to_usize() as u32, + }, + ], + ..Default::default() + }); + } + BrilligOpcode::Call { location } => { + let avm_loc = brillig_pcs_to_avm_pcs[*location]; + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::INTERNALCALL, + operands: vec![AvmOperand::U32 { + value: avm_loc as u32, + }], + ..Default::default() + }); + } + BrilligOpcode::Return {} => avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::INTERNALRETURN, + ..Default::default() + }), + BrilligOpcode::Stop { return_data_offset, return_data_size } => { + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::RETURN, + operands: vec![ + AvmOperand::U32 { value: *return_data_offset as u32}, + AvmOperand::U32 { value: *return_data_size as u32}, + ], + ..Default::default() + }); + } + BrilligOpcode::Trap { /*return_data_offset, return_data_size*/ } => { + // TODO(https://github.com/noir-lang/noir/issues/3113): Trap should support return data + avm_instrs.push(AvmInstruction { + opcode: AvmOpcode::REVERT, + operands: vec![ + //AvmOperand::U32 { value: *return_data_offset as u32}, + //AvmOperand::U32 { value: *return_data_size as u32}, + AvmOperand::U32 { value: 0}, + AvmOperand::U32 { value: 0}, + ], + ..Default::default() + }); + } + _ => panic!( + "Transpiler doesn't know how to process {:?} brillig instruction", + brillig_instr + ), + } + } + + dbg_print_avm_program(&avm_instrs); + + // Constructing bytecode from instructions + let mut bytecode = Vec::new(); + for i in 0..avm_instrs.len() { + let instr_bytes = avm_instrs[i].to_bytes(); + bytecode.extend_from_slice(&instr_bytes); + } + bytecode +} + +/// Compute an array that maps each Brillig pc to an AVM pc. +/// This must be done before transpiling to properly transpile jump destinations. +/// This is necessary for two reasons: +/// 1. The transpiler injects `initial_offset` instructions at the beginning of the program. +/// 2. Some brillig instructions (_e.g._ Stop, or certain ForeignCalls) map to multiple AVM instructions +/// args: +/// initial_offset: how many AVM instructions were inserted at the start of the program +/// brillig: the Brillig program +/// returns: an array where each index is a Brillig pc, +/// and each value is the corresponding AVM pc. +fn map_brillig_pcs_to_avm_pcs(initial_offset: usize, brillig: &Brillig) -> Vec { + let mut pc_map = Vec::with_capacity(brillig.bytecode.len()); + pc_map.resize(brillig.bytecode.len(), 0); + pc_map[0] = initial_offset; + for i in 0..brillig.bytecode.len() - 1 { + let num_avm_instrs_for_this_brillig_instr = match &brillig.bytecode[i] { + BrilligOpcode::Load { .. } => 2, + BrilligOpcode::Store { .. } => 2, + _ => 1, + }; + // next Brillig pc will map to an AVM pc offset by the + // number of AVM instructions generated for this Brillig one + pc_map[i + 1] = pc_map[i] + num_avm_instrs_for_this_brillig_instr; + } + pc_map +} diff --git a/avm-transpiler/src/transpile_contract.rs b/avm-transpiler/src/transpile_contract.rs new file mode 100644 index 00000000000..2a8b762139f --- /dev/null +++ b/avm-transpiler/src/transpile_contract.rs @@ -0,0 +1,120 @@ +use log::info; +use regex::Regex; +use serde::{Deserialize, Serialize}; + +use acvm::acir::circuit::Circuit; +use noirc_driver::ContractFunctionType; + +use crate::transpile::brillig_to_avm; +use crate::utils::extract_brillig_from_acir; + +/// Representation of a contract with some transpiled functions +#[derive(Debug, Serialize, Deserialize)] +pub struct TranspiledContract { + pub transpiled: bool, + pub noir_version: String, + pub name: String, + // Functions can be ACIR or AVM + pub functions: Vec, + pub events: serde_json::Value, + pub file_map: serde_json::Value, + //pub warnings: serde_json::Value, +} + +/// A regular contract with ACIR+Brillig functions +/// but with fields irrelevant to transpilation +/// represented as catch-all serde Values +#[derive(Debug, Serialize, Deserialize)] +pub struct CompiledAcirContract { + pub noir_version: String, + pub name: String, + pub functions: Vec, + pub events: serde_json::Value, + pub file_map: serde_json::Value, + //pub warnings: serde_json::Value, +} + +/// Representation of a contract function +/// with AVM bytecode as a base64 string +#[derive(Debug, Serialize, Deserialize)] +pub struct AvmContractFunction { + pub name: String, + pub function_type: ContractFunctionType, + pub is_internal: bool, + pub abi: serde_json::Value, + pub bytecode: String, // base64 + pub debug_symbols: serde_json::Value, +} + +/// Representation of an ACIR contract function but with +/// catch-all serde Values for fields irrelevant to transpilation +#[derive(Debug, Serialize, Deserialize)] +pub struct AcirContractFunction { + pub name: String, + pub function_type: ContractFunctionType, + pub is_internal: bool, + pub abi: serde_json::Value, + #[serde( + serialize_with = "Circuit::serialize_circuit_base64", + deserialize_with = "Circuit::deserialize_circuit_base64" + )] + pub bytecode: Circuit, + pub debug_symbols: serde_json::Value, +} + +/// An enum that allows the TranspiledContract struct to contain +/// functions with either ACIR or AVM bytecode +#[derive(Debug, Serialize, Deserialize)] +#[serde(untagged)] // omit Acir/Avm tag for these objects in json +pub enum AvmOrAcirContractFunction { + Acir(AcirContractFunction), + Avm(AvmContractFunction), +} + +/// Transpilation is performed when a TranspiledContract +/// is constructed from a CompiledAcirContract +impl From for TranspiledContract { + fn from(contract: CompiledAcirContract) -> Self { + let mut functions = Vec::new(); + for function in contract.functions { + // TODO(4269): once functions are tagged for transpilation to AVM, check tag + let re = Regex::new(r"avm_.*$").unwrap(); + if function.function_type == ContractFunctionType::Unconstrained + && re.is_match(function.name.as_str()) + { + info!( + "Transpiling AVM function {} on contract {}", + function.name, contract.name + ); + // Extract Brillig Opcodes from acir + let acir_circuit = function.bytecode.clone(); + let brillig = extract_brillig_from_acir(&acir_circuit.opcodes); + + // Transpile to AVM + let avm_bytecode = brillig_to_avm(&brillig); + + // Push modified function entry to ABI + functions.push(AvmOrAcirContractFunction::Avm(AvmContractFunction { + name: function.name, + function_type: function.function_type, + is_internal: function.is_internal, + abi: function.abi, + bytecode: base64::encode(avm_bytecode), + debug_symbols: function.debug_symbols, + })); + } else { + // This function is not flagged for transpilation. Push original entry. + functions.push(AvmOrAcirContractFunction::Acir(function)); + } + } + TranspiledContract { + transpiled: true, + noir_version: contract.noir_version, + name: contract.name, + functions, // some acir, some transpiled avm functions + events: contract.events, + file_map: contract.file_map, + //warnings: contract.warnings, + } + } +} diff --git a/avm-transpiler/src/utils.rs b/avm-transpiler/src/utils.rs new file mode 100644 index 00000000000..2f31c900450 --- /dev/null +++ b/avm-transpiler/src/utils.rs @@ -0,0 +1,41 @@ +use log::debug; + +use acvm::acir::circuit::brillig::Brillig; +use acvm::acir::circuit::Opcode; + +use crate::instructions::AvmInstruction; + +/// Extract the Brillig program from its ACIR wrapper instruction. +/// An Noir unconstrained function compiles to one ACIR instruction +/// wrapping a Brillig program. This function just extracts that Brillig +/// assuming the 0th ACIR opcode is the wrapper. +pub fn extract_brillig_from_acir(opcodes: &Vec) -> &Brillig { + if opcodes.len() != 1 { + panic!("There should only be one brillig opcode"); + } + let opcode = &opcodes[0]; + let brillig = match opcode { + Opcode::Brillig(brillig) => brillig, + _ => panic!("Tried to extract a Brillig program from its ACIR wrapper opcode, but the opcode doesn't contain Brillig!"), + }; + brillig +} + +/// Print inputs, outputs, and instructions in a Brillig program +pub fn dbg_print_brillig_program(brillig: &Brillig) { + debug!("Printing Brillig program..."); + debug!("\tInputs: {:?}", brillig.inputs); + for i in 0..brillig.bytecode.len() { + let instr = &brillig.bytecode[i]; + debug!("\tPC:{0} {1:?}", i, instr); + } + debug!("\tOutputs: {:?}", brillig.outputs); +} + +/// Print each instruction in an AVM program +pub fn dbg_print_avm_program(avm_program: &Vec) { + debug!("Printing AVM program..."); + for i in 0..avm_program.len() { + debug!("\tPC:{0}: {1}", i, &avm_program[i].to_string()); + } +} diff --git a/bootstrap.sh b/bootstrap.sh index 8e8b31e9b0d..502bdc19956 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -54,6 +54,7 @@ PROJECTS=( barretenberg noir l1-contracts + avm-transpiler yarn-project ) diff --git a/build_manifest.yml b/build_manifest.yml index 861b632af04..00af54931b9 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -133,6 +133,7 @@ yarn-project-base: - noir - noir-packages - boxes-files + - avm-transpiler yarn-project: buildDir: yarn-project @@ -209,3 +210,9 @@ yellow-paper: buildDir: yellow-paper rebuildPatterns: - ^yellow-paper/ + +avm-transpiler: + buildDir: . + dockerfile: avm-transpiler/Dockerfile + rebuildPatterns: + - ^avm-transpiler/ \ No newline at end of file diff --git a/yarn-project/acir-simulator/src/avm/avm_memory_types.ts b/yarn-project/acir-simulator/src/avm/avm_memory_types.ts index 8963276813b..40c02b65463 100644 --- a/yarn-project/acir-simulator/src/avm/avm_memory_types.ts +++ b/yarn-project/acir-simulator/src/avm/avm_memory_types.ts @@ -220,11 +220,13 @@ export enum TypeTag { // TODO: Consider automatic conversion when getting undefined values. export class TaggedMemory { - static readonly MAX_MEMORY_SIZE = 1n << 32n; + // FIXME: memory should be 2^32, but TS doesn't allow for arrays that big. + static readonly MAX_MEMORY_SIZE = Number(1n << 31n); // 1n << 32n private _mem: MemoryValue[]; constructor() { - this._mem = []; + // Initialize memory size, but leave all entries undefined. + this._mem = new Array(TaggedMemory.MAX_MEMORY_SIZE); } public get(offset: number): MemoryValue { diff --git a/yarn-project/acir-simulator/src/avm/index.test.ts b/yarn-project/acir-simulator/src/avm/index.test.ts index 8fb3a49dab0..f085bc0bc00 100644 --- a/yarn-project/acir-simulator/src/avm/index.test.ts +++ b/yarn-project/acir-simulator/src/avm/index.test.ts @@ -1,4 +1,5 @@ import { Fr } from '@aztec/foundation/fields'; +import { AvmTestContractArtifact } from '@aztec/noir-contracts'; import { mock } from 'jest-mock-extended'; @@ -11,7 +12,7 @@ import { encodeToBytecode } from './opcodes/encode_to_bytecode.js'; import { Opcode } from './opcodes/opcodes.js'; describe('avm', () => { - it('Should execute bytecode', async () => { + it('Should execute bytecode that performs basic addition', async () => { const calldata: Fr[] = [new Fr(1), new Fr(2)]; const journal = mock(); @@ -38,4 +39,27 @@ describe('avm', () => { expect(returnData.length).toBe(1); expect(returnData).toEqual([new Fr(3)]); }); + + describe('testing transpiled Noir contracts', () => { + it('Should execute contract function that performs addition', async () => { + const calldata: Fr[] = [new Fr(1), new Fr(2)]; + const journal = mock(); + + // Get contract function artifact + const addArtifact = AvmTestContractArtifact.functions.find(f => f.name === 'avm_addArgsReturn')!; + + // Decode bytecode into instructions + const instructions = decodeBytecode(Buffer.from(addArtifact.bytecode, 'base64')); + + // Execute instructions + const context = new AvmMachineState(initExecutionEnvironment({ calldata })); + const avmReturnData = await executeAvm(context, journal, instructions); + + expect(avmReturnData.reverted).toBe(false); + + const returnData = avmReturnData.output; + expect(returnData.length).toBe(1); + expect(returnData).toEqual([new Fr(3)]); + }); + }); }); diff --git a/yarn-project/cli/src/cmds/example_contracts.ts b/yarn-project/cli/src/cmds/example_contracts.ts index 5b40c5c60c3..c7ee019eccc 100644 --- a/yarn-project/cli/src/cmds/example_contracts.ts +++ b/yarn-project/cli/src/cmds/example_contracts.ts @@ -4,6 +4,6 @@ import { getExampleContractArtifacts } from '../utils.js'; export async function exampleContracts(log: LogFn) { const abisList = await getExampleContractArtifacts(); - const names = Object.keys(abisList); + const names = Object.keys(abisList).filter(name => name !== 'AvmTestContractArtifact'); names.forEach(name => log(name)); } diff --git a/yarn-project/noir-contracts/Nargo.toml b/yarn-project/noir-contracts/Nargo.toml index 1b980b3dad3..4c919e77911 100644 --- a/yarn-project/noir-contracts/Nargo.toml +++ b/yarn-project/noir-contracts/Nargo.toml @@ -1,8 +1,9 @@ [workspace] members = [ - "contracts/benchmarking_contract", - "contracts/card_game_contract", - "contracts/child_contract", + "contracts/avm_test_contract", + "contracts/benchmarking_contract", + "contracts/card_game_contract", + "contracts/child_contract", "contracts/counter_contract", "contracts/docs_example_contract", "contracts/easy_private_token_contract", diff --git a/yarn-project/noir-contracts/contracts/avm_test_contract/Nargo.toml b/yarn-project/noir-contracts/contracts/avm_test_contract/Nargo.toml new file mode 100644 index 00000000000..f3d8583d433 --- /dev/null +++ b/yarn-project/noir-contracts/contracts/avm_test_contract/Nargo.toml @@ -0,0 +1,8 @@ +[package] +name = "avm_test_contract" +authors = [""] +compiler_version = ">=0.18.0" +type = "contract" + +[dependencies] +aztec = { path = "../../../aztec-nr/aztec" } diff --git a/yarn-project/noir-contracts/contracts/avm_test_contract/src/main.nr b/yarn-project/noir-contracts/contracts/avm_test_contract/src/main.nr new file mode 100644 index 00000000000..00e35dfe6ba --- /dev/null +++ b/yarn-project/noir-contracts/contracts/avm_test_contract/src/main.nr @@ -0,0 +1,26 @@ +// + +contract AvmTest { + // Libs + use dep::aztec::protocol_types::{ + address::AztecAddress, + }; + + #[aztec(private)] + fn constructor() {} + + // Function name prefix "avm_" flags it for transpilation + unconstrained fn avm_addArgsReturn(argA: Field, argB: Field) -> pub Field { + argA + argB + } + + // Function required for all contracts + unconstrained fn compute_note_hash_and_nullifier( + _contract_address: AztecAddress, + _nonce: Field, + _storage_slot: Field, + _serialized_note: [Field; 1] + ) -> pub [Field; 4] { + [0, 0, 0, 0] + } +} diff --git a/yarn-project/noir-contracts/package.json b/yarn-project/noir-contracts/package.json index 6845b1f90ff..38bf26e463b 100644 --- a/yarn-project/noir-contracts/package.json +++ b/yarn-project/noir-contracts/package.json @@ -14,7 +14,7 @@ "formatting": "run -T prettier --check ./src && run -T eslint ./src", "formatting:fix": "run -T eslint --fix ./src && run -T prettier -w ./src", "test": "NODE_NO_WARNINGS=1 node --experimental-vm-modules $(yarn bin jest) --passWithNoTests", - "build:contracts": "./scripts/compile.sh && ./scripts/generate-types.sh" + "build:contracts": "./scripts/compile.sh && ./scripts/transpile.sh && ./scripts/generate-types.sh" }, "inherits": [ "../package.common.json", diff --git a/yarn-project/noir-contracts/package.local.json b/yarn-project/noir-contracts/package.local.json index 6fb912b0da8..9ea766d3f11 100644 --- a/yarn-project/noir-contracts/package.local.json +++ b/yarn-project/noir-contracts/package.local.json @@ -1,7 +1,7 @@ { "scripts": { "build": "yarn clean && yarn build:contracts && tsc -b", - "build:contracts": "./scripts/compile.sh && ./scripts/generate-types.sh", + "build:contracts": "./scripts/compile.sh && ./scripts/transpile.sh && ./scripts/generate-types.sh", "clean": "rm -rf ./dest .tsbuildinfo ./src ./target" } } diff --git a/yarn-project/noir-contracts/scripts/transpile.sh b/yarn-project/noir-contracts/scripts/transpile.sh new file mode 100755 index 00000000000..c330ee0f654 --- /dev/null +++ b/yarn-project/noir-contracts/scripts/transpile.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash +set -euo pipefail + +echo "Transpiling contracts..." +for contract_json in target/avm_test_*.json; do + echo Transpiling $contract_json... + ../../avm-transpiler/target/release/avm-transpiler $contract_json $contract_json +done \ No newline at end of file diff --git a/yarn-project/yarn-project-base/Dockerfile b/yarn-project/yarn-project-base/Dockerfile index b373d429178..fb2b49237e6 100644 --- a/yarn-project/yarn-project-base/Dockerfile +++ b/yarn-project/yarn-project-base/Dockerfile @@ -47,6 +47,7 @@ FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/bb.js as bb.js FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/noir as noir FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/noir-packages as noir-packages FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/boxes-files as boxes-files +FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/avm-transpiler as transpiler FROM node:18.19.0 RUN apt update && apt install -y jq curl perl && rm -rf /var/lib/apt/lists/* && apt-get clean @@ -61,6 +62,8 @@ COPY --from=noir /usr/src/noir/target/release/nargo /usr/src/noir/target/release COPY --from=noir-packages /usr/src/noir/packages /usr/src/noir/packages # Copy in boxes COPY --from=boxes-files /usr/src/boxes /usr/src/boxes +# Copy in transpiler +COPY --from=transpiler /usr/src/avm-transpiler/target/release/avm-transpiler /usr/src/avm-transpiler/target/release/avm-transpiler # We install a symlink to yarn-project's node_modules at a location that all portalled packages can find as they # walk up the tree as part of module resolution. The supposedly idiomatic way of supporting module resolution