diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 00000000..2a0f1bea Binary files /dev/null and b/.DS_Store differ diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1691bfea..eb91e755 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,14 +20,29 @@ jobs: steps: - name: Checkout sources uses: actions/checkout@v4 + # install rust + - name: Install Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + profile: minimal + override: true - name: Install Nargo uses: noir-lang/noirup@v0.1.3 with: toolchain: ${{ matrix.toolchain }} - - - name: Run Noir tests - run: nargo test + # run the PRC server in the oracles directory in the background + - name: run the PRC server + run: | + cd oracles && cargo build + RUST_LOG=info cargo run & + echo "Waiting for server to start..." + # Wait for port 3000 to become available + timeout 30 bash -c 'until nc -z localhost 3000; do sleep 1; done' + echo "Server is ready!" + - name: Run Noir tests with oracle resolver. + run: nargo test --oracle-resolver http://127.0.0.1:3000 format: runs-on: ubuntu-latest diff --git a/Nargo.toml b/Nargo.toml index 337a2e09..567caf95 100644 --- a/Nargo.toml +++ b/Nargo.toml @@ -2,6 +2,6 @@ name = "bignum" type = "lib" authors = [""] -compiler_version = ">=0.36.0" +compiler_version = ">= 0.36.0" [dependencies] diff --git a/oracles/.DS_Store b/oracles/.DS_Store new file mode 100644 index 00000000..cea205be Binary files /dev/null and b/oracles/.DS_Store differ diff --git a/oracles/Cargo.lock b/oracles/Cargo.lock new file mode 100644 index 00000000..26552aef --- /dev/null +++ b/oracles/Cargo.lock @@ -0,0 +1,2168 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775" + +[[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 = "async-trait" +version = "0.1.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" + +[[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 = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "cc" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f34d93e62b03caf570cccc334cbc6c2fceca82f39211051345108adcba3eebdc" +dependencies = [ + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b80225097f2e5ae4e7179dd2266824648f3e2f49d9134d584b76389d31c4c3" +dependencies = [ + "libc", +] + +[[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 = "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", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-timer" +version = "3.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[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.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a3c133739dddd0d2990f9a4bdf8eb4b21ef50e4851ca85ab661199821d510e" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97818827ef4f364230e16705d4706e2897df2bb60617d6ca15d598025a3c481f" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" +dependencies = [ + "futures-util", + "http", + "hyper", + "hyper-util", + "log", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" +dependencies = [ + "equivalent", + "hashbrown 0.15.2", +] + +[[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.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "jni" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6df18c2e3db7e453d3c6ac5b3e9d5182664d28788126d39b91f2d1e22b017ec" +dependencies = [ + "cesu8", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jsonrpsee" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5c71d8c1a731cc4227c2f698d377e7848ca12c8a48866fc5e6951c43a4db843" +dependencies = [ + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-http-client", + "jsonrpsee-proc-macros", + "jsonrpsee-server", + "jsonrpsee-types", + "jsonrpsee-ws-client", + "tokio", + "tracing", +] + +[[package]] +name = "jsonrpsee-client-transport" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "548125b159ba1314104f5bb5f38519e03a41862786aa3925cf349aae9cdd546e" +dependencies = [ + "base64", + "futures-util", + "http", + "jsonrpsee-core", + "pin-project", + "rustls", + "rustls-pki-types", + "rustls-platform-verifier", + "soketto", + "thiserror", + "tokio", + "tokio-rustls", + "tokio-util", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-core" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2882f6f8acb9fdaec7cefc4fd607119a9bd709831df7d7672a1d3b644628280" +dependencies = [ + "async-trait", + "bytes", + "futures-timer", + "futures-util", + "http", + "http-body", + "http-body-util", + "jsonrpsee-types", + "parking_lot", + "pin-project", + "rand", + "rustc-hash", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tracing", +] + +[[package]] +name = "jsonrpsee-http-client" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3638bc4617f96675973253b3a45006933bde93c2fd8a6170b33c777cc389e5b" +dependencies = [ + "async-trait", + "base64", + "http-body", + "hyper", + "hyper-rustls", + "hyper-util", + "jsonrpsee-core", + "jsonrpsee-types", + "rustls", + "rustls-platform-verifier", + "serde", + "serde_json", + "thiserror", + "tokio", + "tower", + "tracing", + "url", +] + +[[package]] +name = "jsonrpsee-proc-macros" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06c01ae0007548e73412c08e2285ffe5d723195bf268bce67b1b77c3bb2a14d" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "jsonrpsee-server" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82ad8ddc14be1d4290cd68046e7d1d37acd408efed6d3ca08aefcc3ad6da069c" +dependencies = [ + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "jsonrpsee-core", + "jsonrpsee-types", + "pin-project", + "route-recognizer", + "serde", + "serde_json", + "soketto", + "thiserror", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tracing", +] + +[[package]] +name = "jsonrpsee-types" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a178c60086f24cc35bb82f57c651d0d25d99c4742b4d335de04e97fa1f08a8a1" +dependencies = [ + "http", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "jsonrpsee-ws-client" +version = "0.24.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fe322e0896d0955a3ebdd5bf813571c53fea29edd713bc315b76620b327e86d" +dependencies = [ + "http", + "jsonrpsee-client-transport", + "jsonrpsee-core", + "jsonrpsee-types", + "url", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.167" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09d6582e104315a817dff97f75133544b2e094ee22447d2acf4a74e189ba06fc" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "lock_api" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi", + "windows-sys 0.52.0", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "oracle" +version = "0.1.0" +dependencies = [ + "anyhow", + "ark-bn254", + "ark-ff", + "jsonrpsee", + "num-bigint", + "num-traits", + "serde", + "serde_json", + "tokio", + "tokio-stream", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "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 = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "route-recognizer" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afab94fb28594581f62d981211a9a4d53cc8130bbcbbb89a0440d9b8e81a7746" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustls" +version = "0.23.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "934b404430bb06b3fae2cba809eb45a1ab1aecd64491213d7c3301b88393f8d1" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-native-certs" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "rustls-pki-types", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" + +[[package]] +name = "rustls-platform-verifier" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afbb878bdfdf63a336a5e63561b1835e7a8c91524f51621db870169eac84b490" +dependencies = [ + "core-foundation", + "core-foundation-sys", + "jni", + "log", + "once_cell", + "rustls", + "rustls-native-certs", + "rustls-platform-verifier-android", + "rustls-webpki", + "security-framework", + "security-framework-sys", + "webpki-roots", + "winapi", +] + +[[package]] +name = "rustls-platform-verifier-android" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[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 = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "num-bigint", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" + +[[package]] +name = "serde" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.215" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "serde_json" +version = "1.0.133" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "socket2" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "soketto" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37468c595637c10857701c990f93a40ce0e357cedb0953d1c26c8d8027f9bb53" +dependencies = [ + "base64", + "bytes", + "futures", + "http", + "httparse", + "log", + "rand", + "sha1", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[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.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d46482f1c1c87acd84dea20c1bf5ebff4c757009ed6bf19cfd36fb10e92c4e" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" +dependencies = [ + "rustls", + "rustls-pki-types", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-util" +version = "0.7.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "pin-project", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[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.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "webpki-roots" +version = "0.26.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" +dependencies = [ + "rustls-pki-types", +] + +[[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.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys 0.59.0", +] + +[[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-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +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.89", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] diff --git a/oracles/Cargo.toml b/oracles/Cargo.toml new file mode 100644 index 00000000..f99e662f --- /dev/null +++ b/oracles/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "oracle" +version = "0.1.0" +edition = "2021" + +[dependencies] +# For the server +anyhow = "1" +# hyper = "1.5.0" +jsonrpsee = { version = "0.24.7", features = ["server", "http-client", "ws-client", "macros", "client-ws-transport-tls"] } +serde = "1.0.213" +serde_json = "1.0.132" +tokio = "1.41.0" +tokio-stream = { version = "0.1.16", features = ["sync"] } +# tower = { version = "0.4.13", features= ["full"]} +# tower-http = { version = "0.6.1", features = ["full"] } +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } + +# For the example ops +ark-bn254 = "0.4.0" +ark-ff = "0.4.2" +num-bigint = "0.4.6" # todo: find a way to remove this dep +num-traits = "0.2.19" # todo: find a way to remove this dep diff --git a/oracles/src/foreign_call.rs b/oracles/src/foreign_call.rs new file mode 100644 index 00000000..41b9b1e1 --- /dev/null +++ b/oracles/src/foreign_call.rs @@ -0,0 +1,99 @@ +// This is basically a copy of noir/acvm-repo/brillig/src/foreign_call.rs + +use serde::{de::value, Deserialize, Serialize}; + +/// Single output of a [foreign call][crate::Opcode::ForeignCall]. +#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone)] +#[serde(untagged)] +pub enum ForeignCallParam { + Single(F), + Array(Vec), +} + +impl From for ForeignCallParam { + fn from(value: F) -> Self { + ForeignCallParam::Single(value) + } +} + +impl From> for ForeignCallParam { + fn from(values: Vec) -> Self { + ForeignCallParam::Array(values) + } +} + +impl ForeignCallParam +where + F: Clone, +{ + pub fn len(&self) -> usize { + match self { + ForeignCallParam::Single(_) => 1, + ForeignCallParam::Array(values) => values.len(), + } + } + + pub fn get_values(&self) -> Vec { + match self { + ForeignCallParam::Single(value) => vec![value.clone()], + ForeignCallParam::Array(values) => values.clone(), + } + } +} + +// impl len> for ForeignCallParam { +// fn len(&self) -> usize { +// match self { +// ForeignCallParam::Single(_) => 1, +// ForeignCallParam::Array(values) => values.len(), +// } +// } +// } + +// /// Represents the full output of a [foreign call][crate::Opcode::ForeignCall]. +// #[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, Default)] +// pub struct ForeignCallResult { +// /// Resolved output values of the foreign call. +// pub values: Vec>, +// } + +// impl From for ForeignCallResult { +// fn from(value: F) -> Self { +// ForeignCallResult { +// values: vec![value.into()], +// } +// } +// } + +// impl From> for ForeignCallResult { +// fn from(values: Vec) -> Self { +// ForeignCallResult { +// values: vec![values.into()], +// } +// } +// } + +// impl From>> for ForeignCallResult { +// fn from(values: Vec>) -> Self { +// ForeignCallResult { values } +// } +// } + +// impl ForeignCallParam +// where +// F: Clone + Copy, +// { +// pub fn unwrap_fields(&self) -> Vec { +// match self { +// ForeignCallParam::Single(value) => vec![*value], +// ForeignCallParam::Array(values) => values.to_vec(), +// } +// } + +// pub fn unwrap_field(&self) -> F { +// match self { +// ForeignCallParam::Single(value) => *value, +// ForeignCallParam::Array(_) => panic!("Expected single value, found array"), +// } +// } +// } diff --git a/oracles/src/handlers.rs b/oracles/src/handlers.rs new file mode 100644 index 00000000..ecedb8f2 --- /dev/null +++ b/oracles/src/handlers.rs @@ -0,0 +1,516 @@ +use ark_bn254::Fr; +use ark_ff::Zero; +use jsonrpsee::core::params; +use num_bigint::BigInt; +use num_bigint::BigUint; +use num_traits::ConstZero; +// It's pretty disgusting that I've introduced this library, just to convert to/from radix 16. I wonder if there's a better way with arkworks? +use num_traits::Num; // It's pretty disgusting that I've introduced this library, just to convert to/from radix 16. I wonder if there's a better way with arkworks? +use serde_json::{json, Value}; +// use std::str::FromStr; + +use crate::foreign_call::ForeignCallParam; +use crate::ops::batch_invert; +use crate::ops::extended_gcd; +use crate::ops::invert; +use crate::ops::is_zero; +use crate::ops::pow_bn; +use crate::ops::sqrt; + +// a struct that emulates the bignum Params params from the params.nr file +struct Params { + has_multiplicative_inverse: bool, + modulus: BigUint, + double_modulus: Vec, + redc_param: Vec, +} + +/**** THERE'S A LOT OF BOILERPLATE INSIDE THESE "HANDLERS", THAT WE CAN PROBABLY PUT INTO COMMON HELPER FUNCTIONS ****/ + +/** Note: I _think_ the type `Vec>` will be generically applicable to _any_ oracle call arguments, so I've made _all_ handlers receive this type. */ +pub(crate) fn handle_get_sqrt(inputs: &Vec>) -> Value { + /**** EXTRACT INPUT STRING(S) ****/ + println!("inputs: {:?}", inputs); + assert!(inputs.len() == 1); + + let input_param = &inputs[0]; + + let input_string = match input_param { + ForeignCallParam::Single(value) => value.trim_start_matches('0'), // Trimming leading zeroes turned out to be very important, otherwise `from_str` on the next line was erroring! + ForeignCallParam::Array(_) => panic!("Expected single value, found array"), + }; + + println!("input_string: {:?}", input_string); + + /**** CONVERT INPUT STRING(S) TO MEANINGFUL TYPE(S) ****/ + let x_big_uint: BigUint = BigUint::from_str_radix(input_string, 16).unwrap(); + let x: Fr = x_big_uint.into(); + // let x: Fr = Fr::from_str(input_string).unwrap(); // This was incorrectly assuming the input_string to be decimal. + println!("x: {:?}", x); + + /**** OPERATE ****/ + let sqrt = sqrt(x); + println!("Computed sqrt: {:?}", sqrt); + + /**** ENSURE HEX ****/ + let as_big_uint: BigUint = sqrt.unwrap().into(); + let as_hex_str = as_big_uint.to_str_radix(16); + + let oracle_return_data_the_noir_program_expects = as_hex_str; + + /**** FORMAT RESULT FOR NOIR CONSUMPTION, AND CONVERT RESULT TO JSON `Value` TYPE ****/ + //** Note: I'm converting to `Value` within these "handler" functions, instead of within the main callback (the callback inside run_server --> module.register_method --> resolve_foreign_call), because the return types can be subtly different: Vec, or Vec>, or maybe some more-complex arrangement of Strings and Vec. It felt easiest to have the "hander" functions figure out how to serialise their return data. */ + let return_vec = vec![oracle_return_data_the_noir_program_expects]; + println!("return_vec: {:?}", return_vec); + + let json_response = json!({"values" : return_vec}); + println!("json_response: {:?}", json_response); + json_response +} + +pub(crate) fn handle_get_sqrts(inputs: &Vec>) -> Value { + /**** EXTRACT INPUT STRING(S) ****/ + println!("inputs: {:?}", inputs); + + let input_param = &inputs[0]; + let input_strings: Vec<&str> = match input_param { + ForeignCallParam::Single(_value) => panic!("Expected array, found single value"), + ForeignCallParam::Array(values) => values + .into_iter() + .map(|v| v.trim_start_matches('0')) + .collect(), + }; + + println!("input_strings: {:?}", input_strings); + + let mut sqrts: Vec = vec![]; + + for input_string in input_strings { + /**** CONVERT INPUT STRING(S) TO MEANINGFUL TYPE(S) ****/ + println!("input_string: {:?}", input_string); + + let x_big_uint: BigUint = BigUint::from_str_radix(input_string, 16).unwrap(); + let x: Fr = x_big_uint.into(); + // let x: Fr = Fr::from_str(input_string).unwrap(); // This was incorrectly assuming the input_string to be decimal. + println!("x: {:?}", x); + + /**** OPERATE ****/ + let sqrt = sqrt(x); + println!("Computed sqrt: {:?}", sqrt); + + /**** ENSURE HEX ****/ + let as_big_uint: BigUint = sqrt.unwrap().into(); + let as_hex_str = as_big_uint.to_str_radix(16); + + sqrts.push(as_hex_str); + } + + let oracle_return_data_the_noir_program_expects = sqrts; + + /**** FORMAT RESULT FOR NOIR CONSUMPTION, AND CONVERT RESULT TO JSON `Value` TYPE ****/ + let return_vec = vec![oracle_return_data_the_noir_program_expects]; // Notice! This is a different type from the singular handle_get_sqrt function! Hence why the `Value` is being computed inside this function, instead in the calling function. + println!("return_vec: {:?}", return_vec); + + let json_response = json!({"values" : return_vec}); + println!("json_response: {:?}", json_response); + json_response +} + +// ============================== +// ============================== +// ============================== +// call handler for is_zero +pub(crate) fn handle_is_zero(inputs: &Vec>) -> Value { + // Create a vector with a single boolean value (true) as the result + let input_param = &inputs[0]; + // parse the input into strings + let mut input_strings = vec![]; + for input in inputs { + input_strings.push(callparam_to_string(input)[0]); + } + let limbs = gets_limbs(input_strings); + // call the is_zero function from the ops.rs + let result = is_zero(limbs); + // print the result + /**** ENSURE HEX ****/ + let as_big_uint: BigUint = result.into(); + let as_hex_str = as_big_uint.to_str_radix(16); + let mut results: Vec = vec![]; + results.push(as_hex_str); + let oracle_return_data_the_noir_program_expects = results; + + /**** FORMAT RESULT FOR NOIR CONSUMPTION, AND CONVERT RESULT TO JSON `Value` TYPE ****/ + let return_vec = oracle_return_data_the_noir_program_expects; // Notice! This is a different type from the singular handle_get_sqrt function! Hence why the `Value` is being computed inside this function, instead in the calling function. + + let json_response = json!({"values" : return_vec}); + json_response +} + +// ============================== +// ============================== +// ============================== +// call handler for add +pub(crate) fn handle_mul_with_quotient(inputs: &Vec>) -> Value { + // parse the input, the last 2 elements of the input are the modulus bits and the number of limbs + let num_limbs_fc = &inputs[inputs.len() - 2]; + let num_limbs = get_u32_from_callparam(&num_limbs_fc); + // create the params struct + let params: Params = Params::from_foreign_call_params(&inputs); + // get the lhs and rhs + let lhs_fc = &inputs[inputs.len() - 3]; + let lhs_str = callparam_to_string(lhs_fc); + let lhs_biguint = cast_to_biguint(lhs_str); + let rhs_fc = &inputs[inputs.len() - 4]; + let rhs_str = callparam_to_string(rhs_fc); + let rhs_biguint = cast_to_biguint(rhs_str); + let mul_res = lhs_biguint * rhs_biguint; + let modulus = params.modulus; + let q = &mul_res / &modulus; + let r = &mul_res % &modulus; + // cast the q and r to limbs + let q_limbs = cast_biguint_to_bignum_limbs(&q, num_limbs); + let r_limbs = cast_biguint_to_bignum_limbs(&r, num_limbs); + // call the mul_with_quotient function from the ops.rs file + let return_vec: Vec> = vec![q_limbs, r_limbs]; + let json_response = json!({"values" : return_vec}); + json_response +} + +// ============================== +// ============================== +// ============================== +// call handler for add +// the inputs of the function are params, lhs, rhs, num_limbs, mod_bits, returns the result of the addition which is a vector of hex limbs +// params are of form +// lhs and rhs are vector of limbs +// the input is 8 elements +pub(crate) fn handle_add(inputs: &Vec>) -> Value { + // parse the input, the last 2 elements of the input are the modulus bits and the number of limbs + // get the number of limbs from the input + // let num_limbs_fc = &inputs[inputs.len()-2]; + // let num_limbs = get_u32_from_callparam(&num_limbs_fc); + // convert the lhs and rhs to biguints + let lhs_fc = &inputs[inputs.len() - 3]; + let lhs_str = callparam_to_string(lhs_fc); + let num_limbs = lhs_str.len(); + let lhs_biguint = cast_to_biguint(lhs_str); + let rhs_fc = &inputs[inputs.len() - 4]; + let rhs_str = callparam_to_string(rhs_fc); + let rhs_biguint = cast_to_biguint(rhs_str); + // lastly parse out the params + // create the params struct + let params: Params = Params::from_foreign_call_params(&inputs); + let modulus = params.modulus; + let result = lhs_biguint + rhs_biguint; + let result_mod = result % modulus; + // cast the result to limbs + let limbs = cast_biguint_to_bignum_limbs(&result_mod, num_limbs as u32); + // pack it in a json response + let return_vec: Vec> = vec![limbs]; + let json_response = json!({"values" : return_vec}); + + json_response +} + +pub(crate) fn handle_neg(inputs: &Vec>) -> Value { + // parse the input, the last 2 elements of the input are the modulus bits and the number of limbs + // create the params struct + + let params: Params = Params::from_foreign_call_params(&inputs); + let modulus = params.modulus; + let limbs_fc = &inputs[inputs.len() - 3]; + let num_limbs = limbs_fc.len(); + let mut limbs_biguint = cast_to_biguint(callparam_to_string(limbs_fc)); + if limbs_biguint > modulus { + limbs_biguint = limbs_biguint % &modulus; + } + let neg = &modulus - &limbs_biguint; + let neg_limbs = cast_biguint_to_bignum_limbs(&neg, num_limbs as u32); + let return_vec: Vec> = vec![neg_limbs]; + let json_response = json!({"values" : return_vec}); + json_response +} + +pub(crate) fn handle_udiv_mod(inputs: &Vec>) -> Value { + // get the numerator and the divisor + let numerator_fc = &inputs[0]; + let numerator_str = callparam_to_string(&numerator_fc); + let numerator = cast_to_biguint(numerator_str); + let divisor_fc = &inputs[1]; + let divisor_str = callparam_to_string(divisor_fc); + let divisor = cast_to_biguint(divisor_str); + // get the number of limbs + let num_limbs = numerator_fc.len(); + + // divide the numerator by the divisor + let quotient = &numerator / &divisor; + let remainder = &numerator % &divisor; + + // cast the quotient and the remainder to limbs + let quotient_limbs = cast_biguint_to_bignum_limbs("ient, num_limbs as u32); + let remainder_limbs = cast_biguint_to_bignum_limbs(&remainder, num_limbs as u32); + + let return_vec: Vec> = vec![quotient_limbs, remainder_limbs]; + let json_response = json!({"values" : return_vec}); + json_response +} + +// a handler for modular inversion +pub(crate) fn handle_invmod(inputs: &Vec>) -> Value { + // get the params + let params: Params = Params::from_foreign_call_params(&inputs); + // get the value to be inverted + let val_fc = &inputs[inputs.len() - 3]; + let val_str = callparam_to_string(val_fc); + let val = cast_to_biguint(val_str); + let num_limbs = val_fc.len(); + // invert the value + let inv = invert(&val, ¶ms.modulus); + // cast the inverse to limbs + let limbs = cast_bigint_to_bignum_limbs(&inv, num_limbs as u32); + // return the json response for now + let return_vec: Vec> = vec![limbs]; + let json_response = json!({"values" : return_vec}); + json_response +} + +// a handler for modular exponentiation +pub(crate) fn handle_pow(inputs: &Vec>) -> Value { + // return an empty json response for now + let params: Params = Params::from_foreign_call_params(&inputs); + let exponent_fc = &inputs[inputs.len() - 3]; + let exponent_str = callparam_to_string(exponent_fc); + let exponent = cast_to_biguint(exponent_str); + let num_limbs = exponent_fc.len(); + let val_fc = &inputs[inputs.len() - 4]; + let val_str = callparam_to_string(val_fc); + let val = cast_to_biguint(val_str); + + let res = pow_bn(&val, &exponent, ¶ms.modulus); + let limbs = cast_biguint_to_bignum_limbs(&res, num_limbs as u32); + let return_vec: Vec> = vec![limbs]; + let json_response = json!({"values" : return_vec}); + json_response +} + +// a handler for modular division +pub(crate) fn handle_div(inputs: &Vec>) -> Value { + let params: Params = Params::from_foreign_call_params(&inputs); + let numerator_fc = &inputs[inputs.len() - 4]; + let numerator_str = callparam_to_string(numerator_fc); + let numerator = cast_to_biguint(numerator_str); + let divisor_fc = &inputs[inputs.len() - 3]; + let divisor_str = callparam_to_string(divisor_fc); + let divisor = cast_to_biguint(divisor_str); + let num_limbs = numerator_fc.len(); + + // compute the inverse of the divisor with respect to the modulus + let inv = invert(&divisor, ¶ms.modulus); + // multiply the numerator by the inverse + let result = (BigInt::from(numerator.clone())) * &inv; + let reduced = result % BigInt::from(params.modulus.clone()); + // cast the result to limbs + let limbs = cast_bigint_to_bignum_limbs(&reduced, num_limbs as u32); + let return_vec: Vec> = vec![limbs]; + let json_response = json!({"values" : return_vec}); + json_response +} + +pub(crate) fn handle_barrett_reduction(inputs: &Vec>) -> Value { + // return an empty json response for now + // the inputs are x , modulus + let x_fc = &inputs[0]; + let x_str = callparam_to_string(x_fc); + let modulus_fc = &inputs[1]; + let modulus_str = callparam_to_string(modulus_fc); + let x = cast_to_biguint(x_str); + let modulus = cast_to_biguint(modulus_str); + let num_limbs = modulus_fc.len(); + let quotient = &x / &modulus; + let remainder = &x % &modulus; + //cast the quotient and the remainder to limbs + let quotient_limbs = cast_biguint_to_bignum_limbs("ient, num_limbs as u32); + let remainder_limbs = cast_biguint_to_bignum_limbs(&remainder, num_limbs as u32); + let return_vec: Vec> = vec![quotient_limbs, remainder_limbs]; + let json_response = json!({"values" : return_vec}); + json_response +} + +pub(crate) fn handle_batch_invert(inputs: &Vec>) -> Value { + // get the params + let params: Params = Params::from_foreign_call_params(&inputs); + // get the number of input bignums + let m_fc = &inputs[inputs.len() - 1]; + let m = get_u32_from_callparam(&m_fc); + // get the number of limbs + let num_limbs_fc = &inputs[inputs.len() - 3]; + let num_limbs = get_u32_from_callparam(&num_limbs_fc); + // get the array of bignums + let xs = &inputs[inputs.len() - 4]; + let xs_vec = xs.get_values(); + // cast the xs_vec into a vector of &str + // this is gross but we have to switch back to &str + // and then we push them into a vector of bignum elements + let mut x_str: Vec<&str> = vec![]; + let mut inputs_bns: Vec = vec![]; + for i in 0..xs_vec.len() { + let y = xs_vec[i].as_str(); + x_str.push(y); + if x_str.len() as u32 % num_limbs == 0 { + let bn = cast_to_biguint(x_str); + x_str = vec![]; + inputs_bns.push(bn); + } + } + let results = batch_invert(&inputs_bns, ¶ms.modulus); + // cast BigInt to bignum limbs + let mut results_formatted: Vec = vec![]; + for result in results { + let limbs = cast_bigint_to_bignum_limbs(&result, num_limbs); + for limb in limbs { + results_formatted.push(limb); + } + } + + // println!("xs_str: {:?}", x_str); + // split the xs_vec into arrays of size num_limbs + + // let res = batch_invert(&chunks, ¶ms.modulus); + let return_vec: Vec> = vec![results_formatted]; + let json_response = json!({"values" : return_vec}); + json_response +} + +// ============================== +// ============================== +// ============================== +// helper functions + +pub(crate) fn cast_to_biguint(input_strings: Vec<&str>) -> BigUint { + // split the limbs + let mut limbs: Vec = vec![]; + for input_string in input_strings { + // handle the case of a zero input + if input_string == "" { + let x_big_uint = BigUint::from_str_radix("0", 16).unwrap(); + limbs.push(x_big_uint); + } else { + let x_big_uint: BigUint = BigUint::from_str_radix(input_string, 16).unwrap(); + limbs.push(x_big_uint); + } + } + // a constant 2^120 as biguint + let base: BigUint = BigUint::from(2u32); + let exp = 120u32; + let shift_constant = base.pow(exp); + let mut res = BigUint::ZERO; + for i in 0..limbs.len() { + res = res + &limbs[i] * &shift_constant.pow(i as u32); + } + res +} + +// helper function to get limbs of a big num and pack them into a vector of Fr elements +pub(crate) fn gets_limbs(input_strings: Vec<&str>) -> Vec { + let mut limbs: Vec = vec![]; + for input_string in input_strings { + // handle the case of a zero input + if input_string == "" { + let x_big_uint = BigUint::from_str_radix("0", 16).unwrap(); + let limb: Fr = x_big_uint.into(); + limbs.push(limb); + } else { + let x_big_uint: BigUint = BigUint::from_str_radix(input_string, 16).unwrap(); + let limb: Fr = x_big_uint.into(); + limbs.push(limb); + } + } + limbs +} + +pub(crate) fn callparam_to_string(input: &ForeignCallParam) -> Vec<&str> { + match input { + ForeignCallParam::Single(value) => vec![value.trim_start_matches('0')], + ForeignCallParam::Array(values) => values + .into_iter() + .map(|v| v.trim_start_matches('0')) + .collect(), + } +} + +pub(crate) fn get_u32_from_callparam(input: &ForeignCallParam) -> u32 { + let input_string = callparam_to_string(input)[0]; + u32::from_str_radix(input_string, 16).unwrap() +} + +pub(crate) fn get_bool_from_callparam(input: &ForeignCallParam) -> bool { + let mut input_string = callparam_to_string(input)[0]; + if input_string == "" { + input_string = "0"; + } + let res = u32::from_str_radix(input_string, 16).unwrap(); + res == 1 +} + +pub(crate) fn cast_biguint_to_bignum_limbs(input: &BigUint, num_limbs: u32) -> Vec { + // a constant 2^120 as biguint + let base: BigUint = BigUint::from(2u32); + let exp = 120u32; + let shift_constant = base.pow(exp); + let mut input_copy = input.clone(); + // an empty array of size num_limbs of type hex limbs + let mut limbs_hex: Vec = vec![]; + for i in 0..num_limbs { + let remainder = &input_copy % &shift_constant; + limbs_hex.push(remainder.to_str_radix(16)); + let quetient: BigUint = input_copy / &shift_constant; + input_copy = quetient.clone(); + } + limbs_hex +} + +pub(crate) fn cast_bigint_to_bignum_limbs(input: &BigInt, num_limbs: u32) -> Vec { + // a constant 2^120 as biguint + let base: BigInt = BigInt::from(2u32); + let exp = 120u32; + let shift_constant = base.pow(exp); + let mut input_copy = input.clone(); + // an empty array of size num_limbs of type hex limbs + let mut limbs_hex: Vec = vec![]; + for i in 0..num_limbs { + let remainder = &input_copy % &shift_constant; + limbs_hex.push(remainder.to_str_radix(16)); + let quetient: BigInt = input_copy / &shift_constant; + input_copy = quetient.clone(); + } + limbs_hex +} + +impl Params { + // this function takes the foreign call params and returns a Params struct + pub fn from_foreign_call_params(inputs: &Vec>) -> Params { + let has_multiplicative_inverse_fc = &inputs[0]; + let has_multiplicative_inverse = get_bool_from_callparam(&has_multiplicative_inverse_fc); + let modulus_fc = &inputs[1]; + // let modulus = gets_limbs(callparam_to_string(modulus_fc)); + let modulus_str = callparam_to_string(modulus_fc); + let modulus = cast_to_biguint(modulus_str); + let double_modulus_fc = &inputs[4]; + let double_modulus = gets_limbs(callparam_to_string(double_modulus_fc)); + let redc_param_fc = &inputs[5]; + let redc_param = gets_limbs(callparam_to_string(redc_param_fc)); + + Params { + has_multiplicative_inverse: has_multiplicative_inverse, + modulus: modulus, + double_modulus: double_modulus, + redc_param: redc_param, + } + } +} + +impl std::fmt::Debug for Params { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Params {{ has_multiplicative_inverse: {:?}, modulus: {:?}, double_modulus: {:?}, redc_param: {:?}", self.has_multiplicative_inverse, self.modulus, self.double_modulus, self.redc_param) + } +} diff --git a/oracles/src/main.rs b/oracles/src/main.rs new file mode 100644 index 00000000..e807e05d --- /dev/null +++ b/oracles/src/main.rs @@ -0,0 +1,143 @@ +// This copyright notice relates to the `jsonrpsee` boilerplate that was used to kickstart this project: + +// Copyright 2019-2021 Parity Technologies (UK) Ltd. +// +// Permission is hereby granted, free of charge, to any +// person obtaining a copy of this software and associated +// documentation files (the "Software"), to deal in the +// Software without restriction, including without +// limitation the rights to use, copy, modify, merge, +// publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice +// shall be included in all copies or substantial portions +// of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +// ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +// TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +// SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +// IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. + +mod foreign_call; +mod handlers; +mod ops; + +use jsonrpsee::server::{RpcModule, Server}; +use std::net::SocketAddr; +use tracing_subscriber::util::SubscriberInitExt; + +use serde::Deserialize; +use serde_json::{json, Value}; + +use crate::foreign_call::ForeignCallParam; +use crate::handlers::{ + handle_add, handle_barrett_reduction, handle_batch_invert, handle_div, handle_get_sqrt, + handle_get_sqrts, handle_invmod, handle_is_zero, handle_mul_with_quotient, handle_neg, + handle_pow, handle_udiv_mod, +}; + +// SPIN UP THE SERVER +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let filter = tracing_subscriber::EnvFilter::try_from_default_env()? + .add_directive("jsonrpsee[method_call{name = \"say_hello\"}]=trace".parse()?); + tracing_subscriber::FmtSubscriber::builder() + .with_env_filter(filter) + .finish() + .try_init()?; + + let _server_addr = run_server().await?; + + Ok(()) +} + +fn print_type(_: &T) { + println!("{:?}", std::any::type_name::()); +} + +#[derive(Debug, Deserialize)] +struct RequestData { + session_id: u64, + function: String, + inputs: Vec>, + root_path: String, + package_name: String, +} + +#[derive(Debug, Deserialize)] +struct Requests(Vec); // Wrap it in a struct to handle the array + +pub(crate) fn handle_unknown_function(_input: &RequestData) -> Value { + println!("oops"); + json!(vec![String::from("oops")]) +} + +async fn run_server() -> anyhow::Result { + let server = Server::builder() + .build("127.0.0.1:3000".parse::()?) + .await?; + let mut module = RpcModule::new(()); + + module.register_method("say_hello", |_, _, _| "hello, world")?; + + module.register_method("resolve_foreign_call", |params, _, _| { + // println!("\n\nNEW REQUEST!!!"); + // print_type(¶ms); + // println!("params{:?}", params); + + let response: Value = if let Some(json_string) = params.as_str() { + // Deserialize the JSON string into the Requests struct: + let requests: Requests = + serde_json::from_str(&json_string).expect("Failed to parse JSON"); + + let request = &requests.0[0]; + + // println!("Request function{:?}", request.function); + + let result: Value = match request.function.as_str() { + "get_sqrt" => handle_get_sqrt(&request.inputs), // the inputs to this are effectively a Vec + "get_sqrts" => handle_get_sqrts(&request.inputs), // the inputs to this are effectively a Vec> + "is_zero" => handle_is_zero(&request.inputs), // the inputs to this are effectively a Vec + "add" => handle_add(&request.inputs), // the inputs to this are effectively a Vec + "neg" => handle_neg(&request.inputs), // the inputs to this are effectively a Vec + "mul_with_quotient" => handle_mul_with_quotient(&request.inputs), // the inputs to this are effectively a Vec + "udiv_mod" => handle_udiv_mod(&request.inputs), // the inputs to this are effectively a Vec + "invmod" => handle_invmod(&request.inputs), // the inputs to this are effectively a Vec + "pow" => handle_pow(&request.inputs), // the inputs to this are effectively a Vec + "div" => handle_div(&request.inputs), // the inputs to this are effectively a Vec + "barrett_reduction" => handle_barrett_reduction(&request.inputs), // the inputs to this are effectively a Vec + "batch_invert" => handle_batch_invert(&request.inputs), // the inputs to this are effectively a Vec + _ => handle_unknown_function(&request), + }; + + result + } else { + println!("No parameters provided"); + json!(vec![String::from("Bad query")]) + }; + + response + })?; + + let addr = server.local_addr()?; + let handle = server.start(module); + + println!("Server is running on 127.0.0.1:3000"); + + // In this example we don't care about doing shutdown so let's it run forever. + // You may use the `ServerHandle` to shut it down or manage it yourself. + // tokio::spawn(handle.stopped()); + + // Keep the server running until it's interrupted + handle.stopped().await; + + Ok(addr) +} diff --git a/oracles/src/ops.rs b/oracles/src/ops.rs new file mode 100644 index 00000000..6895ab96 --- /dev/null +++ b/oracles/src/ops.rs @@ -0,0 +1,148 @@ +use core::fmt; + +use ark_bn254::Fr; +use ark_ff::Field; +use ark_ff::Zero as ZeroField; +use num_bigint::BigInt; +use num_bigint::BigUint; +use num_bigint::ToBigInt; +use num_traits::{One, Zero}; + +pub(crate) fn sqrt(x: Fr) -> Option { + let sqrt: Option = if x.legendre().is_qr() { + let sqrt = x.sqrt().unwrap(); + assert_eq!(sqrt.square(), x); + + Some(sqrt) + } else { + assert_eq!(x.sqrt(), None); + + None + }; + + if sqrt == None { + // I can't be bothered figuring out how to serialise an `Option::None` back to Noir-land, so I'm panicking in this case, instead. + panic!("NO SQUARE ROOT EXISTS"); + } + + sqrt +} + +pub(crate) fn is_zero(limbs: Vec) -> bool { + let mut result: bool = true; + for limb in limbs { + result = result & (limb == ZeroField::zero()); + } + result +} + +pub(crate) fn extended_gcd(_a: &BigInt, _b: &BigInt) -> (BigInt, BigInt, BigInt) { + let (mut x, mut y) = (BigInt::from(0), BigInt::from(1)); + let (mut u, mut v) = (BigInt::from(1), BigInt::from(0)); + let mut a = _a.clone(); + let mut b = _b.clone(); + while a != BigInt::from(0) { + let q = &b / &a; + let r = &b % &a; + let m = &x - &u * &q; + let n = &y - &v * &q; + b = a.clone(); + a = r; + x = u; + y = v; + u = m; + v = n; + } + (b.clone(), x.clone(), y.clone()) +} + +pub(crate) fn invert(a: &BigUint, modulus: &BigUint) -> BigInt { + // perform a -> BigInt conversion + let a_bigint = BigInt::from(a.clone()); + let modulus_bigint = BigInt::from(modulus.clone()); + let (gcd, r, _) = extended_gcd(&a_bigint, &modulus_bigint); + assert_eq!(gcd, BigInt::from(1), "input and modulus are not coprime"); + let mut res = r.clone(); + while res < BigInt::from(0) { + res = res + &modulus_bigint; + } + res +} + +pub(crate) fn pow_bn(base: &BigUint, exponent: &BigUint, modulus: &BigUint) -> BigUint { + // cast the exponent into bytes + let exponent_bytes = exponent.to_bytes_be(); + // do a square and multiply type algorithm + let mut result = BigUint::from(1u64); + for exponent_byte in exponent_bytes { + // this will be potentially horribly slow + result = result.pow(256); + result = result % modulus; + result = result * base.pow(exponent_byte as u32); + result = result % modulus; + } + result +} + +pub(crate) fn batch_invert(xs: &Vec, modulus: &BigUint) -> Vec { + // start with an array with 1 at position 0 + let mut intermediates: Vec = vec![BigUint::from(1u32)]; + let m = xs.len(); + let mut temp: BigUint = BigUint::from(1u64); + for i in 0..m { + // the intermediates array will hold the multiplication of the first i elements in position i + temp = (&temp * &xs[i]) % modulus; + intermediates.push(temp.clone()); + } + + // invert the final multiplication + let mut mul_inv = invert(&intermediates[m], modulus); + // set up a vector of responses that will hold the results + let mut inverses: Vec = vec![BigInt::zero(); m]; + // loop over m and compute the inverses + for i in 0..m { + inverses[m - i - 1] = (&mul_inv * &BigInt::from(intermediates[m - i - 1].clone())) + % BigInt::from(modulus.clone()); + mul_inv = &mul_inv * &BigInt::from(xs[m - i - 1].clone()); + } + + assert_eq!( + (BigInt::from(xs[0].clone()) * &inverses[0]) % BigInt::from(modulus.clone()), + BigInt::from(1u32) + ); + inverses +} + +// some tests to check the behaviour of the extended gcd +#[test] +fn test_extended_euclidean() { + let (s, r, t) = extended_gcd(&mut BigInt::from(10u64), &mut BigInt::from(6u64)); + assert_eq!(s, BigInt::from(2u64)); +} + +#[test] +fn test_invert() { + let a = BigUint::from(5u64); + let modulus = BigUint::from(6u64); + let r = invert(&a, &modulus); + let modulus_bigint = BigInt::from(modulus.clone()); + let a_bigint = BigInt::from(a.clone()); + assert_eq!((r * a_bigint) % modulus_bigint, BigInt::from(1u64)); +} + +#[test] +fn test_pow_bn() { + let base = BigUint::from(3u64); + let exponent = BigUint::from(10u64); + let modulus = BigUint::from(1000000000u64); + let result = pow_bn(&base, &exponent, &modulus); + assert_eq!(result, BigUint::from(59049u64)); +} + +// #[test] +// #[should_panic(expected = "input and modulus are no coprime")] +// fn test_invert_fail() { +// let a = BigUint::from(4u64); +// let modulus = BigUint::from(8u64); +// invert(&a, &modulus); +// } diff --git a/oracles/src/params.rs b/oracles/src/params.rs new file mode 100644 index 00000000..d5e27bfe --- /dev/null +++ b/oracles/src/params.rs @@ -0,0 +1,38 @@ + + +// a struct that emulates the bignum Params params from the params.nr file +pub (crate) struct Params { + has_multiplicative_inverse: bool, + modulus: Vec, + double_modulus: Vec, + redc_param: Vec, +} + +impl Params { + // this function takes the foreign call params and returns a Params struct + pub fn from_foreign_call_params(inputs: &Vec>) -> Params { + let has_multiplicative_inverse_fc = &inputs[0]; + let has_multiplicative_inverse = get_bool_from_callparam(&has_multiplicative_inverse_fc); + let modulus_fc = &inputs[1]; + let modulus = gets_limbs(callparam_to_string(modulus_fc)); + let double_modulus_fc = &inputs[4]; + let double_modulus = gets_limbs(callparam_to_string(double_modulus_fc)); + let redc_param_fc = &inputs[5]; + let redc_param = gets_limbs(callparam_to_string(redc_param_fc)); + + Params { + has_multiplicative_inverse: has_multiplicative_inverse, + modulus: modulus, + double_modulus: double_modulus, + redc_param: redc_param, + } + } +} + +impl std::fmt::Debug for Params { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "Params {{ has_multiplicative_inverse: {:?}, modulus: {:?}, double_modulus: {:?}, redc_param: {:?}", self.has_multiplicative_inverse, self.modulus, self.double_modulus, self.redc_param) + } +} + + diff --git a/src/.DS_Store b/src/.DS_Store new file mode 100644 index 00000000..5227a72e Binary files /dev/null and b/src/.DS_Store differ diff --git a/src/bignum.nr b/src/bignum.nr index 52002bd7..d4196021 100644 --- a/src/bignum.nr +++ b/src/bignum.nr @@ -165,7 +165,8 @@ where } unconstrained fn __is_zero(self) -> bool { - __is_zero(self.limbs) + let a = __is_zero(self.limbs); + a } unconstrained fn __neg(self) -> Self { diff --git a/src/fns/constrained_ops.nr b/src/fns/constrained_ops.nr index 758e23dc..de934743 100644 --- a/src/fns/constrained_ops.nr +++ b/src/fns/constrained_ops.nr @@ -445,7 +445,7 @@ pub(crate) fn udiv_mod( numerator: [Field; N], divisor: [Field; N], ) -> ([Field; N], [Field; N]) { - let (quotient, remainder) = unsafe { __udiv_mod(numerator, divisor) }; + let (quotient, remainder) = unsafe { __udiv_mod::(numerator, divisor) }; // self / divisor = quotient rounded // quotient * divisor + remainder - self = 0 diff --git a/src/fns/unconstrained_helpers.nr b/src/fns/unconstrained_helpers.nr index 0afcfb40..5f7103ec 100644 --- a/src/fns/unconstrained_helpers.nr +++ b/src/fns/unconstrained_helpers.nr @@ -189,12 +189,96 @@ pub(crate) unconstrained fn __sub_with_flags( (result, carry_flags, borrow_flags, underflow) } +// instead of using barrett reduction, we use the oracle to do the reduction + /** * @brief BARRETT_REDUCTION_OVERFLOW_BITS defines how large an input to barrett reduction can be * @details maximum value = modulus^2 <( +// x: [Field; 2 * N], +// redc_param: [Field; N], +// k: u32, +// modulus: [Field; N], +// modulus_u60: U60Repr, +// ) -> ([Field; N], [Field; N]) { +// let mut mulout: [Field; 3 * N] = [0; 3 * N]; +// for i in 0..(N + N) { +// for j in 0..N { +// mulout[i + j] += x[i] * redc_param[j]; +// } +// } +// mulout = split_bits::__normalize_limbs(mulout, 3 * N - 1); +// let mulout_u60: U60Repr = U60Repr::new(mulout); + +// // When we apply the barrett reduction, the maximum value of the output will be +// // <= p * (1 + x/2^{2k}) +// // where p = modulus, +// // x = reduction input +// // if x > p * p, we need k to be larger than modulus_bits() +// // we hardcode k = 4, which means that the maximum value of x is approx. 16 * p * p +// // this should be larger than most values put into `evaluate_quadratic_expression` +// // TODO: try and detect cases where x might be too large at comptime +// // N.B. BARRETT_REDUCTION_OVERFLOW_BITS affects how `redc_param` is generated. +// // `redc_param` = 2^{modulus_bits() * 2 + BARRETT_REDUCTION_OVERFLOW_BITS} / modulus +// // NOTE: very niche edge case error that we need to be aware of: +// // N must be large enough to cover the modulus *plus* BARRETT_REDUCTION_OVERFLOW_BITS +// // i.e. a 359-bit prime needs (I think) 4 limbs to represent or we may overflow when calling __barrett_reduction +// let mut quotient_u60 = mulout_u60.shr((k + k + BARRETT_REDUCTION_OVERFLOW_BITS)); + +// // N.B. we assume that the shifted quotient cannot exceed 2 times original bit size. +// // (partial_quotient should be just slightly larger than the modulus, we could probably represent with a size N+1 array) +// let partial_quotient_full: [Field; 3 * N] = quotient_u60.into_field_array(); +// let mut partial_quotient: [Field; 2 * N] = [0; 2 * N]; +// for i in 0..2 * N { +// partial_quotient[i] = partial_quotient_full[i]; +// } +// // quotient_mul_modulus can never exceed input value `x` so can fit into size-2 array +// let mut quotient_mul_modulus: [Field; 2 * N] = [0; 2 * N]; +// let mut quotient_mul_modulus_normalized: [Field; 2 * N] = [0; 2 * N]; +// for j in 0..N { +// for i in 0..(N + N - j) { +// quotient_mul_modulus[i + j] += partial_quotient[i] * modulus[j]; +// } +// } + +// for i in 0..(N + N) { +// let (lo, hi) = split_bits::split_120_bits(quotient_mul_modulus[i]); +// quotient_mul_modulus_normalized[i] = lo; +// // TODO: what is faster, leaving this if statement in or out? +// // (array is size-1 too large so we can tolerate adding 0 into max element) +// if (i + 1 < N + N) { +// quotient_mul_modulus[i + 1] += hi; +// } +// } +// let quotient_mul_modulus_u60: U60Repr = U60Repr::new(quotient_mul_modulus_normalized); + +// let x_u60: U60Repr = U60Repr::new(x); +// let mut remainder_u60 = x_u60 - quotient_mul_modulus_u60; + +// if (remainder_u60.gte(modulus_u60)) { +// remainder_u60 = remainder_u60 - modulus_u60; +// quotient_u60.increment(); +// } else {} + +// if (remainder_u60.gte(modulus_u60)) { +// remainder_u60 = remainder_u60 - modulus_u60; +// quotient_u60.increment(); +// } else {} + +// if (remainder_u60.gte(modulus_u60)) { +// remainder_u60 = remainder_u60 - modulus_u60; +// quotient_u60.increment(); +// } else {} + +// let q: [Field; N] = U60Repr::into(quotient_u60); +// let r: [Field; N] = U60Repr::into(remainder_u60); + +// (q, r) +// } pub(crate) unconstrained fn __barrett_reduction( x: [Field; 2 * N], @@ -203,81 +287,15 @@ pub(crate) unconstrained fn __barrett_reduction( modulus: [Field; N], modulus_u60: U60Repr, ) -> ([Field; N], [Field; N]) { - // for each i in 0..(N + N), adds x[i] * redc_param[j] to mulout[i + j] for each j in 0..N - let mut mulout: [Field; 3 * N] = [0; 3 * N]; - for i in 0..(N + N) { - for j in 0..N { - mulout[i + j] += x[i] * redc_param[j]; - } - } - - mulout = split_bits::__normalize_limbs(mulout, 3 * N - 1); - let mulout_u60: U60Repr = U60Repr::new(mulout); - - // When we apply the barrett reduction, the maximum value of the output will be - // <= p * (1 + x/2^{2k}) - // where p = modulus, - // x = reduction input - // if x > p * p, we need k to be larger than modulus_bits() - // we hardcode k = 4, which means that the maximum value of x is approx. 16 * p * p - // this should be larger than most values put into `evaluate_quadratic_expression` - // TODO: try and detect cases where x might be too large at comptime - // N.B. BARRETT_REDUCTION_OVERFLOW_BITS affects how `redc_param` is generated. - // `redc_param` = 2^{modulus_bits() * 2 + BARRETT_REDUCTION_OVERFLOW_BITS} / modulus - // NOTE: very niche edge case error that we need to be aware of: - // N must be large enough to cover the modulus *plus* BARRETT_REDUCTION_OVERFLOW_BITS - // i.e. a 359-bit prime needs (I think) 4 limbs to represent or we may overflow when calling __barrett_reduction - let mut quotient_u60 = mulout_u60.shr((k + k + BARRETT_REDUCTION_OVERFLOW_BITS)); - - // N.B. we assume that the shifted quotient cannot exceed 2 times original bit size. - // (partial_quotient_full should be just slightly larger than the modulus, we could probably represent with a size N+1 array) - let partial_quotient_full: [Field; 3 * N] = quotient_u60.into_field_array(); - - // quotient_mul_modulus_normalized can never exceed input value `x` so can fit into size-2 array - let mut quotient_mul_modulus_normalized: [Field; 2 * N] = [0; 2 * N]; - - // First, accumulate the products into quotient_mul_modulus_normalized - for j in 0..N { - for i in 0..(N + N - j) { - quotient_mul_modulus_normalized[i + j] += partial_quotient_full[i] * modulus[j]; - } - } - - // Then, split the accumulated values and propagate higher bits - for i in 0..(N + N) { - let (lo, hi) = split_bits::split_120_bits(quotient_mul_modulus_normalized[i]); - quotient_mul_modulus_normalized[i] = lo; - - // Propagate higher bits to the next index - // TODO: what is faster, leaving this if statement in or out? - // (array is size-1 too large so we can tolerate adding 0 into max element) - if (i + 1 < N + N) { - quotient_mul_modulus_normalized[i + 1] += hi; - } - } - - let quotient_mul_modulus_u60: U60Repr = U60Repr::new(quotient_mul_modulus_normalized); - // convert the input into U60Repr - let x_u60: U60Repr = U60Repr::new(x); - let mut remainder_u60 = x_u60 - quotient_mul_modulus_u60; - // barrett reduction is quircky so might need to remove a few modulus_u60 from the remainder - if (remainder_u60.gte(modulus_u60)) { - remainder_u60 = remainder_u60 - modulus_u60; - quotient_u60.increment(); - } else {} - if (remainder_u60.gte(modulus_u60)) { - remainder_u60 = remainder_u60 - modulus_u60; - quotient_u60.increment(); - } - if (remainder_u60.gte(modulus_u60)) { - remainder_u60 = remainder_u60 - modulus_u60; - quotient_u60.increment(); - } - - let q: [Field; N] = U60Repr::into(quotient_u60); - let r: [Field; N] = U60Repr::into(remainder_u60); + barrett_reduction_oracle(x, modulus) +} - (q, r) +#[oracle(barrett_reduction)] +pub(crate) unconstrained fn barrett_reduction_oracle( + x: [Field; 2 * N], + modulus: [Field; N], +) -> ([Field; N], [Field; N]) { + // return an empty array for now } /** diff --git a/src/fns/unconstrained_ops.nr b/src/fns/unconstrained_ops.nr index 68e12df0..927b807c 100644 --- a/src/fns/unconstrained_ops.nr +++ b/src/fns/unconstrained_ops.nr @@ -33,17 +33,6 @@ pub(crate) unconstrained fn __one() -> [Field; N] { limbs } -/// Deterministically derives a big_num from a seed value. -/// -/// Takes a seed byte array and generates a big_num in the range [0, modulus-1]. -/// -/// ## Value Parameters -/// -/// - `params`: The BigNum parameters containing modulus and reduction info -/// - `seed`: Input seed bytes to derive from. -/// -/// ## Returns -/// /// An array of field elements derived from the seed (the limbs of the big_num) pub(crate) unconstrained fn __derive_from_seed( params: P, @@ -57,15 +46,24 @@ pub(crate) unconstrained fn __eq(lhs: [Field; N], rhs: [Field; N]) - lhs == rhs } -pub(crate) unconstrained fn __is_zero(limbs: [Field; N]) -> bool { - let mut result: bool = true; - for i in 0..N { - result = result & (limbs[i] == 0); - } - - result -} - +//switching this function to use oracles instead +// pub(crate) unconstrained fn __is_zero(limbs: [Field; N]) -> bool { +// let mut result: bool = true; +// for i in 0..N { +// result = result & (limbs[i] == 0); +// } +// result +// } +//switching this function to use oracles instead +// pub(crate) unconstrained fn __is_zero(limbs: [Field; N]) -> bool { +// let mut result: bool = true; +// for i in 0..N { +// result = result & (limbs[i] == 0); +// } +// result +// } +#[oracle(is_zero)] +pub(crate) unconstrained fn __is_zero(limbs: [Field; N]) -> bool {} /** * @brief given an input `x`, compute `2p - x` (unconstrained) * @@ -76,30 +74,86 @@ pub(crate) unconstrained fn __is_zero(limbs: [Field; N]) -> bool { * N.B. constrained BigNum operations do not fully constrain outputs to be in the range [0, p-1] * because such a check is expensive and usually unneccesary. */ +// pub(crate) unconstrained fn __neg( +// params: P, +// limbs: [Field; N], +// ) -> [Field; N] { +// let f: [Field; N] = limbs; +// let x_u60: U60Repr = U60Repr::from(f); +// U60Repr::into(params.modulus_u60 - x_u60) +// } pub(crate) unconstrained fn __neg( params: P, limbs: [Field; N], ) -> [Field; N] { - let f: [Field; N] = limbs; - let x_u60: U60Repr = U60Repr::from(f); - U60Repr::into(params.modulus_u60 - x_u60) + neg_oracle(params, limbs, N, MOD_BITS) } +#[oracle(neg)] +unconstrained fn neg_oracle( + params: P, + limbs: [Field; N], + num_limbs: u32, + mod_bits: u32, +) -> [Field; N] {} + +// switching this function to use oracles instead +// pub(crate) unconstrained fn __add( +// params: P, +// lhs: [Field; N], +// rhs: [Field; N], +// ) -> [Field; N] { +// let x_u60: U60Repr = U60Repr::from(lhs); +// let y_u60: U60Repr = U60Repr::from(rhs); + +// let mut z_u60 = x_u60 + y_u60; + +// if z_u60.gte(params.modulus_u60) { +// z_u60 = z_u60 - params.modulus_u60; +// } +// U60Repr::into(z_u60) +// } +// the oracle function to get the add result + +#[oracle(add)] +pub(crate) unconstrained fn add_oracle( + params: P, + lhs: [Field; N], + rhs: [Field; N], + num_limbs: u32, + mod_bits: u32, +) -> [Field; N] {} + +//this is the actual function that be changed to use oracles +// pub (crate) unconstrained fn __add( +// switching this function to use oracles instead pub(crate) unconstrained fn __add( params: P, lhs: [Field; N], rhs: [Field; N], ) -> [Field; N] { - let x_u60: U60Repr = U60Repr::from(lhs); - let y_u60: U60Repr = U60Repr::from(rhs); - - let mut z_u60 = x_u60 + y_u60; - - if z_u60.gte(params.modulus_u60) { - z_u60 = z_u60 - params.modulus_u60; - } - U60Repr::into(z_u60) + // let x_u60: U60Repr = U60Repr::from(lhs); + // let y_u60: U60Repr = U60Repr::from(rhs); + // let mut z_u60 = x_u60 + y_u60; + // if z_u60.gte(params.modulus_u60) { + // z_u60 = z_u60 - params.modulus_u60; + // } + // U60Repr::into(z_u60) + add_oracle(params, lhs, rhs, N, MOD_BITS) } +// the oracle function to get the add result + +// pub (crate) unconstrained fn __add( +// params: P, +// lhs: [Field; N], +// rhs: [Field; N], +// ) -> [Field; N] { +// println("N is: "); +// println(N); +// let res = add_oracle(params, lhs, rhs, N, MOD_BITS); +// println(res); +// res +// } /** * @brief given inputs `x, y` compute 2p + x - y (unconstrained) @@ -118,23 +172,35 @@ pub(crate) unconstrained fn __mul_with_quotient( lhs: [Field; N], rhs: [Field; N], ) -> ([Field; N], [Field; N]) { - let mut mul: [Field; 2 * N] = [0; 2 * N]; - for i in 0..N { - for j in 0..N { - mul[i + j] += lhs[i] * rhs[j]; - } - } - let to_reduce = split_bits::__normalize_limbs(mul, 2 * N); - let (q, r) = __barrett_reduction( - to_reduce, - params.redc_param, - MOD_BITS, - params.modulus, - params.modulus_u60_x4, - ); - - (q, r) + let res = mul_with_quotient_oracle(params, lhs, rhs, N, MOD_BITS); + res } +// let mut mul: [Field; 2 * N] = [0; 2 * N]; +// for i in 0..N { +// for j in 0..N { +// mul[i + j] += lhs[i] * rhs[j]; +// } +// } +// let to_reduce = split_bits::__normalize_limbs(mul, 2 * N); +// let (q, r) = __barrett_reduction( +// to_reduce, +// params.redc_param, +// MOD_BITS, +// params.modulus, +// params.modulus_u60_x4, +// ); + +// (q, r) +// } + +#[oracle(mul_with_quotient)] +pub(crate) unconstrained fn mul_with_quotient_oracle( + params: P, + lhs: [Field; N], + rhs: [Field; N], + num_limbs: u32, + mod_bits: u32, +) -> ([Field; N], [Field; N]) {} pub(crate) unconstrained fn __mul( params: P, @@ -145,15 +211,32 @@ pub(crate) unconstrained fn __mul( b } +// pub(crate) unconstrained fn __div( +// params: P, +// numerator: [Field; N], +// divisor: [Field; N], +// ) -> [Field; N] { +// let inv_divisor = __invmod::<_, MOD_BITS>(params, divisor); +// __mul::<_, MOD_BITS>(params, numerator, inv_divisor) +// } + pub(crate) unconstrained fn __div( params: P, numerator: [Field; N], divisor: [Field; N], ) -> [Field; N] { - let inv_divisor = __invmod::<_, MOD_BITS>(params, divisor); - __mul::<_, MOD_BITS>(params, numerator, inv_divisor) + div_oracle(params, numerator, divisor, N, MOD_BITS) } +#[oracle(div)] +pub(crate) unconstrained fn div_oracle( + params: P, + numerator: [Field; N], + divisor: [Field; N], + num_limbs: u32, + mod_bits: u32, +) -> [Field; N] {} + /** * @brief __udiv_mod performs *unconstrained* integer division between numerator, divisor * @@ -161,105 +244,172 @@ pub(crate) unconstrained fn __div( * 2. numerator % divisor = remainder * 3. divisor * quotient + remainder = numerator **/ -pub(crate) unconstrained fn __udiv_mod( +// pub(crate) unconstrained fn __udiv_mod( +// numerator: [Field; N], +// divisor: [Field; N], +// ) -> ([Field; N], [Field; N]) { +// let mut quotient_u60: U60Repr = U60Repr::from([0; N]); +// let mut remainder_u60: U60Repr = U60Repr::from(numerator); + +// let mut divisor_u60: U60Repr = U60Repr::from(divisor); +// let b = divisor_u60; + +// let mut bit_difference = remainder_u60.get_msb() - divisor_u60.get_msb(); + +// let mut accumulator_u60: U60Repr = U60Repr::one(); +// divisor_u60 = divisor_u60.shl(bit_difference); +// accumulator_u60 = accumulator_u60.shl(bit_difference); + +// if (divisor_u60.gte(remainder_u60 + U60Repr::one())) { +// divisor_u60.shr1(); +// accumulator_u60.shr1(); +// } +// for _ in 0..(N * 120) { +// if (remainder_u60.gte(b) == false) { +// break; +// } + +// // we've shunted 'divisor' up to have the same bit length as our remainder. +// // If remainder >= divisor, then a is at least '1 << bit_difference' multiples of b +// if (remainder_u60.gte(divisor_u60)) { +// remainder_u60 -= divisor_u60; +// // we can use OR here instead of +, as +// // accumulator is always a nice power of two +// quotient_u60 = quotient_u60 + accumulator_u60; +// } +// divisor_u60.shr1(); // >>= 1; +// accumulator_u60.shr1(); // >>= 1; +// } + +// (U60Repr::into(quotient_u60), U60Repr::into(remainder_u60)) +// } + +pub(crate) unconstrained fn __udiv_mod( numerator: [Field; N], divisor: [Field; N], ) -> ([Field; N], [Field; N]) { - let mut quotient_u60: U60Repr = U60Repr::from([0; N]); - let mut remainder_u60: U60Repr = U60Repr::from(numerator); - - let mut divisor_u60: U60Repr = U60Repr::from(divisor); - let b = divisor_u60; - - let mut bit_difference = remainder_u60.get_msb() - divisor_u60.get_msb(); - - let mut accumulator_u60: U60Repr = U60Repr::one(); - divisor_u60 = divisor_u60.shl(bit_difference); - accumulator_u60 = accumulator_u60.shl(bit_difference); - - if (divisor_u60.gte(remainder_u60 + U60Repr::one())) { - divisor_u60.shr1(); - accumulator_u60.shr1(); - } - for _ in 0..(N * 120) { - if (remainder_u60.gte(b) == false) { - break; - } - - // we've shunted 'divisor' up to have the same bit length as our remainder. - // If remainder >= divisor, then a is at least '1 << bit_difference' multiples of b - if (remainder_u60.gte(divisor_u60)) { - remainder_u60 -= divisor_u60; - // we can use OR here instead of +, as - // accumulator is always a nice power of two - quotient_u60 = quotient_u60 + accumulator_u60; - } - divisor_u60.shr1(); // >>= 1; - accumulator_u60.shr1(); // >>= 1; - } - - (U60Repr::into(quotient_u60), U60Repr::into(remainder_u60)) + let res: ([Field; N], [Field; N]) = + udiv_mod_oracle::(numerator, divisor, N, MOD_BITS); + res } +#[oracle(udiv_mod)] +pub(crate) unconstrained fn udiv_mod_oracle( + numerator: [Field; N], + divisor: [Field; N], + num_limbs: u32, + mod_bits: u32, +) -> ([Field; N], [Field; N]) {} + +// current implementation of invmod only works for prime fields +// we could use xgcd to extend this to all fields +// pub(crate) unconstrained fn __invmod( +// params: P, +// val: [Field; N], +// ) -> [Field; N] { +// let one: [Field; N] = __one::(); +// let one_u60: U60Repr = U60Repr::from(one); +// let exp_u60 = params.modulus_u60.sub(one_u60.add(one_u60)); +// let exp = U60Repr::into(exp_u60); +// __pow::<_, MOD_BITS>(params, val, exp) +// } pub(crate) unconstrained fn __invmod( params: P, val: [Field; N], ) -> [Field; N] { - let one: [Field; N] = __one::(); - let one_u60: U60Repr = U60Repr::from(one); - let exp_u60 = params.modulus_u60.sub(one_u60.add(one_u60)); - let exp = U60Repr::into(exp_u60); - __pow::<_, MOD_BITS>(params, val, exp) + let res = invmod_oracle::(params, val, N, MOD_BITS); + res } +#[oracle(invmod)] +pub(crate) unconstrained fn invmod_oracle( + params: P, + val: [Field; N], + num_limbs: u32, + mod_bits: u32, +) -> [Field; N] {} + +// pub(crate) unconstrained fn __pow( +// params: P, +// val: [Field; N], +// exponent: [Field; N], +// ) -> [Field; N] { +// let x: U60Repr = U60Repr::from(exponent); + +// let num_bits = MOD_BITS + 1; + +// let mut accumulator: [Field; N] = __one::(); + +// for i in 0..num_bits { +// accumulator = __mul::<_, MOD_BITS>(params, accumulator, accumulator); +// if x.get_bit(num_bits - i - 1) { +// accumulator = __mul::<_, MOD_BITS>(params, accumulator, val); +// } +// } +// accumulator +// } + pub(crate) unconstrained fn __pow( params: P, val: [Field; N], exponent: [Field; N], ) -> [Field; N] { - let x: U60Repr = U60Repr::from(exponent); - - let num_bits = MOD_BITS + 1; - - let mut accumulator: [Field; N] = __one::(); - - for i in 0..num_bits { - accumulator = __mul::<_, MOD_BITS>(params, accumulator, accumulator); - if x.get_bit(num_bits - i - 1) { - accumulator = __mul::<_, MOD_BITS>(params, accumulator, val); - } - } - accumulator + pow_oracle(params, val, exponent, N, MOD_BITS) } +#[oracle(pow)] +pub(crate) unconstrained fn pow_oracle( + params: P, + val: [Field; N], + exponent: [Field; N], + num_limbs: u32, + mod_bits: u32, +) -> [Field; N] {} + +// pub(crate) unconstrained fn __batch_invert( +// params: P, +// x: [[Field; N]; M], +// ) -> [[Field; N]; M] { +// // TODO: ugly! Will fail if input slice is empty +// let mut accumulator: [Field; N] = __one::(); +// let mut result: [[Field; N]; M] = [[0; N]; M]; +// let mut temporaries: [[Field; N]] = &[]; +// for i in 0..x.len() { +// temporaries = temporaries.push_back(accumulator); +// if (__is_zero(x[i]) == false) { +// accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[i]); +// } +// } + +// accumulator = __invmod::<_, MOD_BITS>(params, accumulator); +// let mut T0: [Field; N] = [0; N]; +// for i in 0..x.len() { +// let idx = x.len() - 1 - i; +// if (__is_zero(x[idx]) == false) { +// T0 = __mul::<_, MOD_BITS>(params, accumulator, temporaries[idx]); +// accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[idx]); +// result[idx] = T0; +// } +// } +// result +// } + pub(crate) unconstrained fn __batch_invert( params: P, x: [[Field; N]; M], ) -> [[Field; N]; M] { - // TODO: ugly! Will fail if input slice is empty - let mut accumulator: [Field; N] = __one::(); - let mut result: [[Field; N]; M] = [[0; N]; M]; - let mut temporaries: [[Field; N]] = &[]; - for i in 0..x.len() { - temporaries = temporaries.push_back(accumulator); - if (__is_zero(x[i]) == false) { - accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[i]); - } - } - - accumulator = __invmod::<_, MOD_BITS>(params, accumulator); - let mut T0: [Field; N] = [0; N]; - for i in 0..x.len() { - let idx = x.len() - 1 - i; - if (__is_zero(x[idx]) == false) { - T0 = __mul::<_, MOD_BITS>(params, accumulator, temporaries[idx]); - accumulator = __mul::<_, MOD_BITS>(params, accumulator, x[idx]); - result[idx] = T0; - } - } - result + batch_invert_oracle(params, x, N, MOD_BITS, M) } +#[oracle(batch_invert)] +pub(crate) unconstrained fn batch_invert_oracle( + params: P, + x: [[Field; N]; M], + num_limbs: u32, + mod_bits: u32, + m: u32, +) -> [[Field; N]; M] {} + pub(crate) unconstrained fn __batch_invert_slice( params: P, x: [[Field; N]], diff --git a/src/tests/runtime_bignum_test.nr b/src/tests/runtime_bignum_test.nr index 3b7fe4f0..855e4bc0 100644 --- a/src/tests/runtime_bignum_test.nr +++ b/src/tests/runtime_bignum_test.nr @@ -1,4 +1,5 @@ use crate::fns::unconstrained_helpers::__barrett_reduction; +use crate::fns::unconstrained_ops::__batch_invert; use crate::params::{BigNumParams, BigNumParamsGetter}; use crate::runtime_bignum::RuntimeBigNum; use crate::utils::u60_representation::U60Repr; @@ -569,6 +570,20 @@ fn test_invmod_BN() { unsafe { test_invmod(params) }; } +#[test] +fn test_batch_invert() { + let params = BN254_Fq_Params::get_params(); + let N = 3; + let MOD_BITS = 254; + let u: RuntimeBigNum<3, 254> = RuntimeBigNum::__derive_from_seed(params, [1, 2, 3, 4]); + let v: RuntimeBigNum<3, 254> = RuntimeBigNum::__derive_from_seed(params, [2, 3, 4, 5]); + let w: RuntimeBigNum<3, 254> = RuntimeBigNum::__derive_from_seed(params, [3, 4, 5, 6]); + let batch = unsafe { __batch_invert::<3, 254, 3>(params, [u.limbs, v.limbs, w.limbs]) }; + assert(batch[0] == u.__invmod().limbs); + assert(batch[1] == v.__invmod().limbs); + assert(batch[2] == w.__invmod().limbs); +} + // N.B. witness generation times make these tests take ~15 minutes each! Uncomment at your peril // #[test] // fn test_div_2048() {