diff --git a/.gitmodules b/.gitmodules index f643e34f4ca5..32f3fa66dd1a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -12,4 +12,4 @@ url = https://github.com/Arachnid/solidity-stringutils [submodule "barretenberg/sol/lib/openzeppelin-contracts"] path = barretenberg/sol/lib/openzeppelin-contracts - url = https://github.com/OpenZeppelin/openzeppelin-contracts + url = https://github.com/OpenZeppelin/openzeppelin-contracts \ No newline at end of file diff --git a/barretenberg/acir_tests/Dockerfile.bb b/barretenberg/acir_tests/Dockerfile.bb index 3afa93c0ed9b..c0122be4ddca 100644 --- a/barretenberg/acir_tests/Dockerfile.bb +++ b/barretenberg/acir_tests/Dockerfile.bb @@ -8,4 +8,4 @@ COPY . . # Run every acir test through native bb build "prove_and_verify". RUN FLOW=all_cmds ./run_acir_tests.sh # Run 1_mul through native bb build, all_cmds flow, to test all cli args. -RUN VERBOSE=1 FLOW=all_cmds ./run_acir_tests.sh 1_mul +RUN VERBOSE=1 FLOW=all_cmds ./run_acir_tests.sh 1_mul \ No newline at end of file diff --git a/barretenberg/acir_tests/Dockerfile.bb.sol b/barretenberg/acir_tests/Dockerfile.bb.sol new file mode 100644 index 000000000000..bbe4a8a03cde --- /dev/null +++ b/barretenberg/acir_tests/Dockerfile.bb.sol @@ -0,0 +1,13 @@ +FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/barretenberg-x86_64-linux-clang-assert +FROM 278380418400.dkr.ecr.eu-west-2.amazonaws.com/barretenberg-x86_64-linux-clang-sol + +FROM node:18-alpine +RUN apk update && apk add git bash curl jq +COPY --from=0 /usr/src/barretenberg/cpp/build /usr/src/barretenberg/cpp/build +COPY --from=1 /usr/src/barretenberg/sol/src/ultra/BaseUltraVerifier.sol /usr/src/barretenberg/sol/src/ultra/BaseUltraVerifier.sol +COPY --from=ghcr.io/foundry-rs/foundry:latest /usr/local/bin/anvil /usr/local/bin/anvil +WORKDIR /usr/src/barretenberg/acir_tests +COPY . . +# Run every acir test through a solidity verifier". +RUN (cd sol-test && yarn) +RUN PARALLEL=1 FLOW=sol ./run_acir_tests.sh diff --git a/barretenberg/acir_tests/bash_helpers/catch.sh b/barretenberg/acir_tests/bash_helpers/catch.sh new file mode 100644 index 000000000000..888af3cbb44e --- /dev/null +++ b/barretenberg/acir_tests/bash_helpers/catch.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# Handler for SIGCHLD, cleanup if child exit with error +handle_sigchild() { + for pid in "${pids[@]}"; do + # If process is no longer running + if ! kill -0 "$pid" 2>/dev/null; then + # Wait for the process and get exit status + wait "$pid" + status=$? + + # If exit status is error + if [ $status -ne 0 ]; then + # Create error file + touch "$error_file" + fi + fi + done +} + +check_error_file() { + # If error file exists, exit with error + if [ -f "$error_file" ]; then + rm "$error_file" + echo "Error occurred in one or more child processes. Exiting..." + exit 1 + fi +} \ No newline at end of file diff --git a/barretenberg/acir_tests/flows/sol.sh b/barretenberg/acir_tests/flows/sol.sh new file mode 100755 index 000000000000..d95c9039eea1 --- /dev/null +++ b/barretenberg/acir_tests/flows/sol.sh @@ -0,0 +1,23 @@ +#!/bin/sh +set -eu + +export PROOF="$(pwd)/proof" +export PROOF_AS_FIELDS="$(pwd)/proof_fields.json" + +# Create a proof, write the solidity contract, write the proof as fields in order to extract the public inputs +$BIN prove -o proof +$BIN write_vk -o vk +$BIN proof_as_fields -k vk -c $CRS_PATH -p $PROOF +$BIN contract -k vk -c $CRS_PATH -b ./target/acir.gz -o Key.sol + +# Export the paths to the environment variables for the js test runner +export KEY_PATH="$(pwd)/Key.sol" +export VERIFIER_PATH=$(realpath "../../sol-test/Verifier.sol") +export TEST_PATH=$(realpath "../../sol-test/Test.sol") +export BASE_PATH=$(realpath "../../../sol/src/ultra/BaseUltraVerifier.sol") + +# Use solcjs to compile the generated key contract with the template verifier and test contract +# index.js will start an anvil, on a random port +# Deploy the verifier then send a test transaction +export TEST_NAME=$(basename $(pwd)) +node ../../sol-test/src/index.js \ No newline at end of file diff --git a/barretenberg/acir_tests/run_acir_tests.sh b/barretenberg/acir_tests/run_acir_tests.sh index 6121588d3919..722957d6ed4e 100755 --- a/barretenberg/acir_tests/run_acir_tests.sh +++ b/barretenberg/acir_tests/run_acir_tests.sh @@ -4,6 +4,12 @@ # VERBOSE: to enable logging for each test. set -eu +# Catch when running in parallel +error_file="/tmp/error.$$" +pids=() +source ./bash_helpers/catch.sh +trap handle_sigchild SIGCHLD + BIN=${BIN:-../cpp/build/bin/bb} FLOW=${FLOW:-prove_and_verify} CRS_PATH=~/.bb-crs @@ -58,6 +64,7 @@ function test() { echo -e "\033[32mPASSED\033[0m ($duration ms)" else echo -e "\033[31mFAILED\033[0m" + touch "$error_file" exit 1 fi @@ -83,6 +90,16 @@ else continue fi - test $TEST_NAME + # If parallel flag is set, run in parallel + if [ -n "${PARALLEL:-}" ]; then + test $TEST_NAME & + else + test $TEST_NAME + fi done fi + +wait + +# Check for parallel errors +check_error_file \ No newline at end of file diff --git a/barretenberg/acir_tests/sol-test/Test.sol b/barretenberg/acir_tests/sol-test/Test.sol new file mode 100644 index 000000000000..a6988291f78f --- /dev/null +++ b/barretenberg/acir_tests/sol-test/Test.sol @@ -0,0 +1,19 @@ +// THIS FILE WILL NOT COMPILE BY ITSELF +// Compilation is handled in `src/index.js` where solcjs gathers the dependencies + +pragma solidity >=0.8.4; + +import {Verifier} from "./Verifier.sol"; + +contract Test { + Verifier verifier; + + constructor() { + verifier = new Verifier(); + } + + function test(bytes calldata proof, bytes32[] calldata publicInputs) view public returns(bool) { + return verifier.verify(proof, publicInputs); + } +} + diff --git a/barretenberg/acir_tests/sol-test/Verifier.sol b/barretenberg/acir_tests/sol-test/Verifier.sol new file mode 100644 index 000000000000..b187e16f47e7 --- /dev/null +++ b/barretenberg/acir_tests/sol-test/Verifier.sol @@ -0,0 +1,19 @@ +// THIS FILE WILL NOT COMPILE BY ITSELF +// Compilation is handled in `src/index.js` where solcjs gathers the dependencies + +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022 Aztec +pragma solidity >=0.8.4; + +import {UltraVerificationKey} from "./Key.sol"; +import {BaseUltraVerifier} from "./BaseUltraVerifier.sol"; + +contract Verifier is BaseUltraVerifier { + function getVerificationKeyHash() public pure override(BaseUltraVerifier) returns (bytes32) { + return UltraVerificationKey.verificationKeyHash(); + } + + function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BaseUltraVerifier) { + UltraVerificationKey.loadVerificationKey(vk, _omegaInverseLoc); + } +} \ No newline at end of file diff --git a/barretenberg/acir_tests/sol-test/package.json b/barretenberg/acir_tests/sol-test/package.json new file mode 100644 index 000000000000..f346b9e42f6a --- /dev/null +++ b/barretenberg/acir_tests/sol-test/package.json @@ -0,0 +1,14 @@ +{ + "name": "headless-test", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "type": "module", + "scripts": { + "start": "node ./src/index.js" + }, + "dependencies": { + "ethers": "^6.8.1", + "solc": "^0.8.22" + } +} diff --git a/barretenberg/acir_tests/sol-test/src/index.js b/barretenberg/acir_tests/sol-test/src/index.js new file mode 100644 index 000000000000..f59ef1545055 --- /dev/null +++ b/barretenberg/acir_tests/sol-test/src/index.js @@ -0,0 +1,191 @@ +import fs from "fs"; +const {readFileSync, promises: fsPromises} = fs; +import {spawn} from "child_process"; +import {ethers} from "ethers"; +import solc from "solc"; + +const NUMBER_OF_FIELDS_IN_PROOF = 93; + +// We use the solcjs compiler version in this test, although it is slower than foundry, to run the test end to end +// it simplifies of parallelising the test suite + +// What does this file do? +// +// 1. Launch an instance of anvil { on a random port, for parallelism } +// 2. Compile the solidity files using solcjs +// 3. Deploy the contract +// 4. Read the previously created proof, and append public inputs +// 5. Run the test against the deployed contract +// 6. Kill the anvil instance + +const getEnvVar = (envvar) => { + const varVal = process.env[envvar]; + if (!varVal) { + throw new Error(`Missing environment variable ${envvar}`); + } + return varVal; +} + +// Test name is passed into environment from `flows/sol.sh` +const testName = getEnvVar("TEST_NAME"); + +// Get solidity files, passed into environment from `flows/sol.sh` +const keyPath = getEnvVar("KEY_PATH"); +const verifierPath = getEnvVar("VERIFIER_PATH"); +const testPath = getEnvVar("TEST_PATH"); +const basePath = getEnvVar("BASE_PATH"); +const encoding = {encoding: "utf8"}; +const [key, test, verifier, base] = await Promise.all( + [ + fsPromises.readFile(keyPath, encoding), + fsPromises.readFile(testPath, encoding), + fsPromises.readFile(verifierPath, encoding), + fsPromises.readFile(basePath, encoding) + ]); + +var input = { + language: 'Solidity', + sources: { + 'Key.sol': { + content: key + }, + 'Test.sol': { + content: test + }, + 'Verifier.sol': { + content: verifier + }, + 'BaseUltraVerifier.sol': { + content: base + } + }, + settings: { // we require the optimiser + optimizer: { + enabled: true, + runs: 200 + }, + outputSelection: { + '*': { + '*': ['evm.bytecode.object', 'abi'] + } + } + } +}; + +var output = JSON.parse(solc.compile(JSON.stringify(input))); +const contract = output.contracts['Test.sol']['Test']; +const bytecode = contract.evm.bytecode.object; +const abi = contract.abi; + +/** + * Launch anvil on the given port, + * Resolves when ready, rejects when port is already allocated + * @param {Number} port + */ +const launchAnvil = async (port) => { + const handle = spawn("anvil", ["-p", port]); + + // wait until the anvil instance is ready on port + await new Promise((resolve, reject) => { + // If we get an error reject, which will cause the caller to retry on a new port + handle.stderr.on("data", (data) => { + const str = data.toString(); + if (str.includes("error binding")) { + reject("we go again baby") + } + }); + + // If we get a success resolve, anvil is ready + handle.stdout.on("data", (data) => { + const str = data.toString(); + if (str.includes("Listening on")) { + resolve(undefined); + } + }); + }); + + return handle; +} + +/** + * Deploys the contract + * @param {ethers.Signer} signer + */ +const deploy = async (signer) => { + const factory = new ethers.ContractFactory(abi, bytecode, signer); + const deployment = await factory.deploy(); + const deployed = await deployment.waitForDeployment(); + return await deployed.getAddress(); +} + +/** + * Takes in a proof as fields, and returns the public inputs, as well as the number of public inputs + * @param {Array} proofAsFields + * @return {Array} [number, Array] + */ +const readPublicInputs = (proofAsFields) => { + const publicInputs = []; + // A proof with no public inputs is 93 fields long + const numPublicInputs = proofAsFields.length - NUMBER_OF_FIELDS_IN_PROOF; + for (let i = 0; i < numPublicInputs; i++) { + publicInputs.push(proofAsFields[i]); + } + return [numPublicInputs, publicInputs]; +} + +/** + * Get Anvil + * + * Creates an anvil instance on a random port, and returns the instance and the port + * If the port is alredy allocated, it will try again + * @returns {[ChildProcess, Number]} [anvil, port] + */ +const getAnvil = async () => { + const port = Math.floor(Math.random() * 10000) + 10000; + try { + return [await launchAnvil(port), port]; + } catch (e) { + // Recursive call should try again on a new port in the rare case the port is already taken + // yes this looks dangerous, but it relies on 0-10000 being hard to collide on + return getAnvil(); + } +} + +const [anvil, randomPort] = await getAnvil(); +const killAnvil = () => { + anvil.kill(); + console.log(testName, " complete") +} + +try { + const proofAsFieldsPath = getEnvVar("PROOF_AS_FIELDS"); + const proofAsFields = readFileSync(proofAsFieldsPath); + const [numPublicInputs, publicInputs] = readPublicInputs(JSON.parse(proofAsFields.toString())); + + const proofPath = getEnvVar("PROOF"); + const proof = readFileSync(proofPath); + + // Cut the number of public inputs off of the proof string + const proofStr = `0x${proof.toString("hex").substring(64*numPublicInputs)}`; + + const key = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; + const provider = new ethers.JsonRpcProvider(`http://localhost:${randomPort}`); + const signer = new ethers.Wallet(key, provider); + + // deploy + const address = await deploy(signer); + const contract = new ethers.Contract(address, abi, signer); + + const result = await contract.test(proofStr, publicInputs); + if (!result) throw new Error("Test failed"); +} +catch (e) { + console.error(testName, " failed") + console.log(e) + throw e; +} +finally { + // Kill anvil at the end of running + killAnvil(); +} + diff --git a/barretenberg/acir_tests/sol-test/yarn.lock b/barretenberg/acir_tests/sol-test/yarn.lock new file mode 100644 index 000000000000..af80282ea956 --- /dev/null +++ b/barretenberg/acir_tests/sol-test/yarn.lock @@ -0,0 +1,108 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@adraffy/ens-normalize@1.10.0": + version "1.10.0" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.10.0.tgz#d2a39395c587e092d77cbbc80acf956a54f38bf7" + integrity sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q== + +"@noble/curves@1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" + integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== + dependencies: + "@noble/hashes" "1.3.2" + +"@noble/hashes@1.3.2": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + +"@types/node@18.15.13": + version "18.15.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.13.tgz#f64277c341150c979e42b00e4ac289290c9df469" + integrity sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q== + +aes-js@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-4.0.0-beta.5.tgz#8d2452c52adedebc3a3e28465d858c11ca315873" + integrity sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q== + +command-exists@^1.2.8: + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== + +commander@^8.1.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +ethers@^6.8.1: + version "6.8.1" + resolved "https://registry.yarnpkg.com/ethers/-/ethers-6.8.1.tgz#ee2a1a39b5f62a13678f90ccd879175391d0a2b4" + integrity sha512-iEKm6zox5h1lDn6scuRWdIdFJUCGg3+/aQWu0F4K0GVyEZiktFkqrJbRjTn1FlYEPz7RKA707D6g5Kdk6j7Ljg== + dependencies: + "@adraffy/ens-normalize" "1.10.0" + "@noble/curves" "1.2.0" + "@noble/hashes" "1.3.2" + "@types/node" "18.15.13" + aes-js "4.0.0-beta.5" + tslib "2.4.0" + ws "8.5.0" + +follow-redirects@^1.12.1: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + +memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + +semver@^5.5.0: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +solc@^0.8.22: + version "0.8.22" + resolved "https://registry.yarnpkg.com/solc/-/solc-0.8.22.tgz#6df0bb688b9a58bbf10932730301374a6ccfb862" + integrity sha512-bA2tMZXx93R8L5LUH7TlB/f+QhkVyxrrY6LmgJnFFZlRknrhYVlBK1e3uHIdKybwoFabOFSzeaZjPeL/GIpFGQ== + dependencies: + command-exists "^1.2.8" + commander "^8.1.0" + follow-redirects "^1.12.1" + js-sha3 "0.8.0" + memorystream "^0.3.1" + semver "^5.5.0" + tmp "0.0.33" + +tmp@0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tslib@2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +ws@8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== diff --git a/barretenberg/cpp/src/barretenberg/bb/main.cpp b/barretenberg/cpp/src/barretenberg/bb/main.cpp index c996c90063e8..69834bdff8cd 100644 --- a/barretenberg/cpp/src/barretenberg/bb/main.cpp +++ b/barretenberg/cpp/src/barretenberg/bb/main.cpp @@ -74,6 +74,7 @@ bool proveAndVerify(const std::string& bytecodePath, const std::string& witnessP { auto constraint_system = get_constraint_system(bytecodePath); auto witness = get_witness(witnessPath); + auto acir_composer = init(constraint_system); Timer pk_timer; @@ -170,7 +171,6 @@ bool verify(const std::string& proof_path, bool recursive, const std::string& vk auto verified = acir_composer.verify_proof(read_file(proof_path), recursive); vinfo("verified: ", verified); - return verified; } diff --git a/barretenberg/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt b/barretenberg/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt index d0281e4e1a29..76bbe00dc571 100644 --- a/barretenberg/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt +++ b/barretenberg/cpp/src/barretenberg/solidity_helpers/CMakeLists.txt @@ -1,4 +1,4 @@ -barretenberg_module(stdlib_solidity_helpers plonk proof_system transcript crypto_pedersen_commitment polynomials crypto_sha256 ecc crypto_blake3s stdlib_primitives stdlib_pedersen_commitment stdlib_blake3s stdlib_blake2s srs) +barretenberg_module(stdlib_solidity_helpers plonk proof_system transcript crypto_pedersen_commitment polynomials crypto_sha256 ecc crypto_blake3s stdlib_primitives stdlib_pedersen_commitment stdlib_blake3s stdlib_blake2s stdlib_sha256 srs) if (NOT(FUZZING)) add_executable(solidity_key_gen key_gen.cpp) diff --git a/barretenberg/cpp/src/barretenberg/solidity_helpers/circuits/ecdsa_circuit.hpp b/barretenberg/cpp/src/barretenberg/solidity_helpers/circuits/ecdsa_circuit.hpp new file mode 100644 index 000000000000..23e0a3a71838 --- /dev/null +++ b/barretenberg/cpp/src/barretenberg/solidity_helpers/circuits/ecdsa_circuit.hpp @@ -0,0 +1,96 @@ + +#pragma once +#include "barretenberg/crypto/ecdsa/ecdsa.hpp" +#include "barretenberg/crypto/hashers/hashers.hpp" +#include "barretenberg/ecc/curves/grumpkin/grumpkin.hpp" +#include "barretenberg/stdlib/encryption/ecdsa/ecdsa.hpp" +#include "barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp" +#include "barretenberg/stdlib/primitives/bigfield/bigfield.hpp" +#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" +#include "barretenberg/stdlib/primitives/bool/bool.hpp" +#include "barretenberg/stdlib/primitives/curves/secp256k1.hpp" +#include "barretenberg/stdlib/primitives/field/field.hpp" +#include "barretenberg/stdlib/primitives/witness/witness.hpp" + +using namespace proof_system::plonk; +using namespace stdlib; +using numeric::uint256_t; + +template class EcdsaCircuit { + public: + using field_ct = stdlib::field_t; + using bool_ct = stdlib::bool_t; + using public_witness_ct = stdlib::public_witness_t; + using byte_array_ct = stdlib::byte_array; + using curve = stdlib::secp256k1; + + static constexpr size_t NUM_PUBLIC_INPUTS = 6; + + static Builder generate(uint256_t public_inputs[]) + { + Builder builder; + + // IN CIRCUIT + // Create an input buffer the same size as our inputs + typename curve::byte_array_ct input_buffer(&builder, NUM_PUBLIC_INPUTS); + for (size_t i = 0; i < NUM_PUBLIC_INPUTS; ++i) { + input_buffer.set_byte(i, public_witness_ct(&builder, public_inputs[i])); + } + + // This is the message that we would like to confirm + std::string message_string = "goblin"; + auto message = typename curve::byte_array_ct(&builder, message_string); + + // Assert that the public inputs buffer matches the message we want + for (size_t i = 0; i < NUM_PUBLIC_INPUTS; ++i) { + input_buffer[i].assert_equal(message[i]); + } + + // UNCONSTRAINED: create a random keypair to sign with + crypto::ecdsa::key_pair account; + account.private_key = curve::fr::random_element(); + account.public_key = curve::g1::one * account.private_key; + + // UNCONSTRAINED: create a sig + crypto::ecdsa::signature signature = crypto::ecdsa:: + construct_signature( + message_string, account); + + // UNCONSTRAINED: verify the created signature + bool dry_run = + crypto::ecdsa::verify_signature( + message_string, account.public_key, signature); + if (!dry_run) { + throw_or_abort("[non circuit]: Sig verification failed"); + } + + // IN CIRCUIT: create a witness with the pub key in our circuit + typename curve::g1_bigfr_ct public_key = curve::g1_bigfr_ct::from_witness(&builder, account.public_key); + + std::vector rr(signature.r.begin(), signature.r.end()); + std::vector ss(signature.s.begin(), signature.s.end()); + uint8_t vv = signature.v; + + // IN CIRCUIT: create a witness with the sig in our circuit + stdlib::ecdsa::signature sig{ typename curve::byte_array_ct(&builder, rr), + typename curve::byte_array_ct(&builder, ss), + stdlib::uint8(&builder, vv) }; + + // IN CIRCUIT: verify the signature + typename curve::bool_ct signature_result = stdlib::ecdsa::verify_signature( + // input_buffer, public_key, sig); + input_buffer, + public_key, + sig); + + // Assert the signature is true, we hash the message inside the verify sig stdlib call + bool_ct is_true = bool_ct(1); + signature_result.must_imply(is_true, "signature verification failed"); + + return builder; + } +}; \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/solidity_helpers/key_gen.cpp b/barretenberg/cpp/src/barretenberg/solidity_helpers/key_gen.cpp index b62198ed9164..ff7601e7fc4c 100644 --- a/barretenberg/cpp/src/barretenberg/solidity_helpers/key_gen.cpp +++ b/barretenberg/cpp/src/barretenberg/solidity_helpers/key_gen.cpp @@ -6,6 +6,7 @@ #include "circuits/add_2_circuit.hpp" #include "circuits/blake_circuit.hpp" +#include "circuits/ecdsa_circuit.hpp" #include "circuits/recursive_circuit.hpp" #include "utils/instance_sol_gen.hpp" @@ -69,18 +70,21 @@ int main(int argc, char** argv) if (plonk_flavour != "ultra") { info("Only ultra plonk flavour is supported at the moment"); return 1; + } + + info("Generating ultra plonk keys for ", circuit_flavour, " circuit"); + + if (circuit_flavour == "blake") { + generate_keys(output_path, plonk_flavour, circuit_flavour); + } else if (circuit_flavour == "add2") { + generate_keys(output_path, plonk_flavour, circuit_flavour); + } else if (circuit_flavour == "recursive") { + generate_keys(output_path, plonk_flavour, circuit_flavour); + } else if (circuit_flavour == "ecdsa") { + generate_keys(output_path, plonk_flavour, circuit_flavour); } else { - info("Generating ultra plonk keys for ", circuit_flavour, " circuit"); - - if (circuit_flavour == "blake") { - generate_keys(output_path, plonk_flavour, circuit_flavour); - } else if (circuit_flavour == "add2") { - generate_keys(output_path, plonk_flavour, circuit_flavour); - } else if (circuit_flavour == "recursive") { - generate_keys(output_path, plonk_flavour, circuit_flavour); - } else { - info("Only blake, add2 and recursive circuits are supported at the moment"); - return 1; - } + info("Unsupported circuit are supported at the moment"); + return 1; } + return 0; } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/solidity_helpers/proof_gen.cpp b/barretenberg/cpp/src/barretenberg/solidity_helpers/proof_gen.cpp index d052b1b7f07a..8bd33bb6560d 100644 --- a/barretenberg/cpp/src/barretenberg/solidity_helpers/proof_gen.cpp +++ b/barretenberg/cpp/src/barretenberg/solidity_helpers/proof_gen.cpp @@ -7,6 +7,7 @@ #include "circuits/add_2_circuit.hpp" #include "circuits/blake_circuit.hpp" +#include "circuits/ecdsa_circuit.hpp" #include "circuits/recursive_circuit.hpp" #include "utils/utils.hpp" @@ -64,7 +65,7 @@ int main(int argc, char** argv) barretenberg::srs::init_crs_factory(srs_path); // @todo dynamically allocate this - uint256_t inputs[] = { 0, 0, 0, 0, 0 }; + uint256_t inputs[] = { 0, 0, 0, 0, 0, 0 }; size_t count = 0; std::stringstream s_stream(string_input); @@ -81,16 +82,18 @@ int main(int argc, char** argv) if (plonk_flavour != "ultra") { info("Only ultra plonk flavour is supported at the moment"); return 1; + } + + if (circuit_flavour == "blake") { + generate_proof(inputs); + } else if (circuit_flavour == "add2") { + generate_proof(inputs); + } else if (circuit_flavour == "ecdsa") { + generate_proof(inputs); + } else if (circuit_flavour == "recursive") { + generate_proof(inputs); } else { - if (circuit_flavour == "blake") { - generate_proof(inputs); - } else if (circuit_flavour == "add2") { - generate_proof(inputs); - } else if (circuit_flavour == "recursive") { - generate_proof(inputs); - } else { - info("Invalid circuit flavour: " + circuit_flavour); - return 1; - } + info("Invalid circuit flavour: " + circuit_flavour); + return 1; } } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp index e1975a514235..ff0929711bd1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/encryption/ecdsa/ecdsa_impl.hpp @@ -1,7 +1,8 @@ #pragma once -#include "../../hash/sha256/sha256.hpp" -#include "../../primitives/bit_array/bit_array.hpp" +#include "barretenberg/stdlib/encryption/ecdsa/ecdsa.hpp" +#include "barretenberg/stdlib/hash/sha256/sha256.hpp" +#include "barretenberg/stdlib/primitives//bit_array/bit_array.hpp" namespace proof_system::plonk { namespace stdlib { diff --git a/barretenberg/cpp/yarn.lock b/barretenberg/cpp/yarn.lock new file mode 100644 index 000000000000..fb57ccd13afb --- /dev/null +++ b/barretenberg/cpp/yarn.lock @@ -0,0 +1,4 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + diff --git a/barretenberg/sol/scripts/init.sh b/barretenberg/sol/scripts/init.sh index fa00f288bd2f..147adc9ae219 100755 --- a/barretenberg/sol/scripts/init.sh +++ b/barretenberg/sol/scripts/init.sh @@ -7,4 +7,5 @@ OUTPUT_PATH="./src/ultra" ../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR add2 $OUTPUT_PATH $SRS_PATH ../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR blake $OUTPUT_PATH $SRS_PATH +../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR ecdsa $OUTPUT_PATH $SRS_PATH ../cpp/build/bin/solidity_key_gen $PLONK_FLAVOUR recursive $OUTPUT_PATH $SRS_PATH \ No newline at end of file diff --git a/barretenberg/sol/src/ultra/BaseUltraVerifier.sol b/barretenberg/sol/src/ultra/BaseUltraVerifier.sol index a907385c1578..e00052d6a8ef 100644 --- a/barretenberg/sol/src/ultra/BaseUltraVerifier.sol +++ b/barretenberg/sol/src/ultra/BaseUltraVerifier.sol @@ -288,6 +288,7 @@ abstract contract BaseUltraVerifier { // y^2 = x^3 + ax + b // for Grumpkin, a = 0 and b = -17. We use b in a custom gate relation that evaluates elliptic curve arithmetic uint256 internal constant GRUMPKIN_CURVE_B_PARAMETER_NEGATED = 17; + error PUBLIC_INPUT_COUNT_INVALID(uint256 expected, uint256 actual); error PUBLIC_INPUT_INVALID_BN128_G1_POINT(); error PUBLIC_INPUT_GE_P(); @@ -1173,37 +1174,14 @@ abstract contract BaseUltraVerifier { mulmod(x_diff, x_diff, p), p ), - addmod( - sub( - p, - addmod(y2_sqr, y1_sqr, p) - ), - addmod(y1y2, y1y2, p), - p - ), + addmod(sub(p, addmod(y2_sqr, y1_sqr, p)), addmod(y1y2, y1y2, p), p), p ) x_add_identity := - mulmod( - mulmod( - x_add_identity, - addmod( - 1, - sub(p, mload(QM_EVAL_LOC)), - p - ), - p - ), - mload(C_ALPHA_BASE_LOC), - p - ) + mulmod(mulmod(x_add_identity, addmod(1, sub(p, mload(QM_EVAL_LOC)), p), p), mload(C_ALPHA_BASE_LOC), p) // q_elliptic * (x3 + x2 + x1)(x2 - x1)(x2 - x1) - y2^2 - y1^2 + 2(y2y1)*q_sign = 0 - let y1_plus_y3 := addmod( - mload(Y1_EVAL_LOC), - mload(Y3_EVAL_LOC), - p - ) + let y1_plus_y3 := addmod(mload(Y1_EVAL_LOC), mload(Y3_EVAL_LOC), p) let y_diff := addmod(mulmod(mload(Y2_EVAL_LOC), mload(QSIGN_LOC), p), sub(p, mload(Y1_EVAL_LOC)), p) let y_add_identity := addmod( diff --git a/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol b/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol index 44894f12f1d8..1bbaed721670 100644 --- a/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol +++ b/barretenberg/sol/src/ultra/instance/Add2UltraVerifier.sol @@ -11,6 +11,6 @@ contract Add2UltraVerifier is BASE { } function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BASE) { - VK.loadVerificationKey(vk, _omegaInverseLoc); + VK.loadVerificationKey(vk, _omegaInverseLoc); } } diff --git a/barretenberg/sol/src/ultra/instance/BlakeUltraVerifier.sol b/barretenberg/sol/src/ultra/instance/BlakeUltraVerifier.sol index c8531be2ff9a..5442c999e16e 100644 --- a/barretenberg/sol/src/ultra/instance/BlakeUltraVerifier.sol +++ b/barretenberg/sol/src/ultra/instance/BlakeUltraVerifier.sol @@ -11,6 +11,6 @@ contract BlakeUltraVerifier is BASE { } function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BASE) { - VK.loadVerificationKey(vk, _omegaInverseLoc); + VK.loadVerificationKey(vk, _omegaInverseLoc); } } diff --git a/barretenberg/sol/src/ultra/instance/EcdsaUltraVerifier.sol b/barretenberg/sol/src/ultra/instance/EcdsaUltraVerifier.sol new file mode 100644 index 000000000000..ed7bb8e58de7 --- /dev/null +++ b/barretenberg/sol/src/ultra/instance/EcdsaUltraVerifier.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2023 Aztec +pragma solidity >=0.8.4; + +import {EcdsaUltraVerificationKey as VK} from "../keys/EcdsaUltraVerificationKey.sol"; +import {BaseUltraVerifier as BASE} from "../BaseUltraVerifier.sol"; + +contract EcdsaUltraVerifier is BASE { + function getVerificationKeyHash() public pure override(BASE) returns (bytes32) { + return VK.verificationKeyHash(); + } + + function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BASE) { + VK.loadVerificationKey(vk, _omegaInverseLoc); + } +} diff --git a/barretenberg/sol/src/ultra/instance/RecursiveUltraVerifier.sol b/barretenberg/sol/src/ultra/instance/RecursiveUltraVerifier.sol index 807893dc55f8..f2147aada62d 100644 --- a/barretenberg/sol/src/ultra/instance/RecursiveUltraVerifier.sol +++ b/barretenberg/sol/src/ultra/instance/RecursiveUltraVerifier.sol @@ -11,6 +11,6 @@ contract RecursiveUltraVerifier is BASE { } function loadVerificationKey(uint256 vk, uint256 _omegaInverseLoc) internal pure virtual override(BASE) { - VK.loadVerificationKey(vk, _omegaInverseLoc); + VK.loadVerificationKey(vk, _omegaInverseLoc); } } diff --git a/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol b/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol index 51927724a48f..67c3b6080a15 100644 --- a/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol +++ b/barretenberg/sol/src/ultra/keys/Add2UltraVerificationKey.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.4; library Add2UltraVerificationKey { - function verificationKeyHash() internal pure returns(bytes32) { + function verificationKeyHash() internal pure returns (bytes32) { return 0xa0e940165bfc708013d5b4f7940f3b07f3bcf3c0f57ee21d8b4bdb78630817a3; } @@ -62,10 +62,10 @@ library Add2UltraVerificationKey { mstore(add(_vk, 0x620), 0x0ab49886c2b94bd0bd3f6ed1dbbe2cb2671d2ae51d31c1210433c3972bb64578) // vk.ID4.y mstore(add(_vk, 0x640), 0x00) // vk.contains_recursive_proof mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices - mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 - mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 - mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 - mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 + mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 + mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 + mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 + mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 mstore(_omegaInverseLoc, 0x02e40daf409556c02bfc85eb303402b774954d30aeb0337eb85a71e6373428de) // vk.work_root_inverse } } diff --git a/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol b/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol index c35456a75bc7..0b8676e4dabc 100644 --- a/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol +++ b/barretenberg/sol/src/ultra/keys/BlakeUltraVerificationKey.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.4; library BlakeUltraVerificationKey { - function verificationKeyHash() internal pure returns(bytes32) { + function verificationKeyHash() internal pure returns (bytes32) { return 0xab0e7eca8953a659e04b83b3e1eb0525036ab76b5c6c53b090c8e3e568df3912; } @@ -62,10 +62,10 @@ library BlakeUltraVerificationKey { mstore(add(_vk, 0x620), 0x04f57e846a88c4a0254841cf7b6226e878e7a4ea49c34c3732870f1d8c4f6c18) // vk.ID4.y mstore(add(_vk, 0x640), 0x00) // vk.contains_recursive_proof mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices - mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 - mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 - mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 - mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 + mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 + mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 + mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 + mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 mstore(_omegaInverseLoc, 0x05d33766e4590b3722701b6f2fa43d0dc3f028424d384e68c92a742fb2dbc0b4) // vk.work_root_inverse } } diff --git a/barretenberg/sol/src/ultra/keys/EcdsaUltraVerificationKey.sol b/barretenberg/sol/src/ultra/keys/EcdsaUltraVerificationKey.sol new file mode 100644 index 000000000000..d226d196bf55 --- /dev/null +++ b/barretenberg/sol/src/ultra/keys/EcdsaUltraVerificationKey.sol @@ -0,0 +1,72 @@ +// Verification Key Hash: e30e949f5160482ce231cd52882ea6e3146c3ef53d7a2e7a1ead236a058d5a78 +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022 Aztec +pragma solidity >=0.8.4; + +library EcdsaUltraVerificationKey { + function verificationKeyHash() internal pure returns (bytes32) { + return 0xe30e949f5160482ce231cd52882ea6e3146c3ef53d7a2e7a1ead236a058d5a78; + } + + function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure { + assembly { + mstore(add(_vk, 0x00), 0x0000000000000000000000000000000000000000000000000000000000010000) // vk.circuit_size + mstore(add(_vk, 0x20), 0x0000000000000000000000000000000000000000000000000000000000000006) // vk.num_inputs + mstore(add(_vk, 0x40), 0x00eeb2cb5981ed45649abebde081dcff16c8601de4347e7dd1628ba2daac43b7) // vk.work_root + mstore(add(_vk, 0x60), 0x30641e0e92bebef818268d663bcad6dbcfd6c0149170f6d7d350b1b1fa6c1001) // vk.domain_inverse + mstore(add(_vk, 0x80), 0x21e3003d8b8316c4ce71fb5419a9ae911da948bb43cf79b6f77db537b680c442) // vk.Q1.x + mstore(add(_vk, 0xa0), 0x3005267a5059be6fde8f88bbd95321c8ddea179df2a11dc1df2e77f740ca8f1f) // vk.Q1.y + mstore(add(_vk, 0xc0), 0x024526d9500f6edf685a057c97b8cff30a2ed489a002f7f35d1856da3ac42e01) // vk.Q2.x + mstore(add(_vk, 0xe0), 0x016b7763c0fba3bb1e445895adfb07bf26cbd99e202b0d8f93a8f7004a306bbc) // vk.Q2.y + mstore(add(_vk, 0x100), 0x2ff3496186b9586a042939286d9d83596cdd074f6df473613951ce5229fa31bc) // vk.Q3.x + mstore(add(_vk, 0x120), 0x28d41b097e1c8a0863f5593d6cc4a804e5f748b38443cb7909c6cbe2f9d1ab84) // vk.Q3.y + mstore(add(_vk, 0x140), 0x19a9e44ac41213223362bbedd7b6d61adf942a0a5880be9c7c53943b4e280640) // vk.Q4.x + mstore(add(_vk, 0x160), 0x1fa921169505614db374a60d1bbea0a08815b4804542bcbf3309506b8b0507f0) // vk.Q4.y + mstore(add(_vk, 0x180), 0x2035284dbb7544e5a0c1f5b56084267b165b23f541c038979555b82e0f2607ea) // vk.Q_M.x + mstore(add(_vk, 0x1a0), 0x02ff6b514c7fa2c20ba949ea94c08c5f5e146e09336b65de3d5fccfcaaf56b96) // vk.Q_M.y + mstore(add(_vk, 0x1c0), 0x098709b45abc886af6902f48ba0ae3587c9ebd298ceab3183e0aeb6068e96dcb) // vk.Q_C.x + mstore(add(_vk, 0x1e0), 0x2767a84ab297d7757b53fb08492d0a5f657d44b47c944a080c7c42ab890732f1) // vk.Q_C.y + mstore(add(_vk, 0x200), 0x0e5bc77185f9a211ce4dba62562d072d88600ba25fbd13028829cb916af11030) // vk.Q_ARITHMETIC.x + mstore(add(_vk, 0x220), 0x2039506dca5969fc929e7ed9ab162f17294f7e0d7c56959508562d9556357a6e) // vk.Q_ARITHMETIC.y + mstore(add(_vk, 0x240), 0x1d2501b2fa086e00afea57bf974ab9df0e259dc30aebf0021c17b8189c42d50c) // vk.QSORT.x + mstore(add(_vk, 0x260), 0x13cdd55a7fa83f59db568fdc67f4b07e7adddd403b975edcb7b4bf2ad2dcf453) // vk.QSORT.y + mstore(add(_vk, 0x280), 0x21245d6c0a4d2ff12b21a825f39f30e8f8cf9b259448d111183e975828539576) // vk.Q_ELLIPTIC.x + mstore(add(_vk, 0x2a0), 0x16a409532c8a1693536e93b6ce9920bfc2e6796e8dfe404675a0cdf6ee77ee7a) // vk.Q_ELLIPTIC.y + mstore(add(_vk, 0x2c0), 0x2a5e88249e7a11c5011cdca34920359e9442a5ae3aae68e56e8cdfc4062c8b52) // vk.Q_AUX.x + mstore(add(_vk, 0x2e0), 0x12065cc874d23213d1ccbef7087359fa4c75a87d9a25df50a05dce8e635073d5) // vk.Q_AUX.y + mstore(add(_vk, 0x300), 0x2e5b641397b2265450974ac68cdd0f151bd66d9c9854ab6f64e84671f3e0c267) // vk.SIGMA1.x + mstore(add(_vk, 0x320), 0x0fe1186570db78e9d0c24fa2f5582c43d1ca518567caa9e033007612c8245873) // vk.SIGMA1.y + mstore(add(_vk, 0x340), 0x0d5bbea26d87e9fadc9c3b860123ca849abba8e0e41c4e55998022b51d95d8a1) // vk.SIGMA2.x + mstore(add(_vk, 0x360), 0x1b503ef8d777b251c32e63d17a76e9ebd7efb586063bc52d6f75c86d3722efe9) // vk.SIGMA2.y + mstore(add(_vk, 0x380), 0x07c2dae78ad3943d62867423792d1cdaa68df83ebc974863ae3be3f90c490aae) // vk.SIGMA3.x + mstore(add(_vk, 0x3a0), 0x15301e4d92461354d18ac6208dcfea4967feac437435efa613183fb84007c6ae) // vk.SIGMA3.y + mstore(add(_vk, 0x3c0), 0x272d645226dbce24fcbaf241b18ebcd6c745f5f462f4f17b1b0d05deb1b342f0) // vk.SIGMA4.x + mstore(add(_vk, 0x3e0), 0x2a9f2b440f257f3e4619df6f3cb0c0cf1e8026061b4071249ae178447eb51b9e) // vk.SIGMA4.y + mstore(add(_vk, 0x400), 0x18f7cf965339d9c9d190296fa92f915767b0a8da455975f3e03fa98439fd7110) // vk.TABLE1.x + mstore(add(_vk, 0x420), 0x0eecc02f9d44125407adbf00d56b086afd1adc5de536450afe05de382761b32f) // vk.TABLE1.y + mstore(add(_vk, 0x440), 0x0bdfe662ea9f40f125ca5f7e99a8c6ba09b87ba8313864316745df862946c5c4) // vk.TABLE2.x + mstore(add(_vk, 0x460), 0x0c5313c5b17634332920f54081fd46464a5ce9399e507c8fece9df28bff19033) // vk.TABLE2.y + mstore(add(_vk, 0x480), 0x232ab86409f60c50fd5f04e879fbcbe60e358eb0337c5d0db1934277e1d8b1f2) // vk.TABLE3.x + mstore(add(_vk, 0x4a0), 0x1fda66dfb58273345f2471dff55c51b6856241460272e64b4cc67cde65231e89) // vk.TABLE3.y + mstore(add(_vk, 0x4c0), 0x024ccc0fcff3b515cdc97dde2fae5c516bf3c97207891801707142af02538a83) // vk.TABLE4.x + mstore(add(_vk, 0x4e0), 0x27827250d02b7b67d084bfc52b26c722f33f75ae5098c109573bfe92b782e559) // vk.TABLE4.y + mstore(add(_vk, 0x500), 0x1ae2687fae0bfbb8b923aee57fd70697da8239d170e3dd9e903c5d2141073acc) // vk.TABLE_TYPE.x + mstore(add(_vk, 0x520), 0x2bc2419b9c6badd0755da06b3f73fba761bf5fc6708b1d9ebf8024ba7f95a2f6) // vk.TABLE_TYPE.y + mstore(add(_vk, 0x540), 0x1006cbbc3a187f1d286337a2a5851481ad736ddc9708de146b0c16af67af55f5) // vk.ID1.x + mstore(add(_vk, 0x560), 0x11cc4086b8c85a1c1cb633e148743dd35026dcb5d78b2d95c1d82235b4aa3f55) // vk.ID1.y + mstore(add(_vk, 0x580), 0x1280e0e41489a0689eca740eb87c2a956d7e5e01490d4ab8bed22cf702b868f5) // vk.ID2.x + mstore(add(_vk, 0x5a0), 0x1ee6fba2609e79fd8c183a090740d594b31ff64d1fa417d5b257e073d158dded) // vk.ID2.y + mstore(add(_vk, 0x5c0), 0x2b9204f05f51933d2aee0d9b4d6abb90fc8b647d2867191259b6b1180081d75e) // vk.ID3.x + mstore(add(_vk, 0x5e0), 0x0ae99a82bb35dbde21c2930925f571f81f41e1fb7afe103a52c01b830c042449) // vk.ID3.y + mstore(add(_vk, 0x600), 0x12dcf5c41e156844037bb35b2eb4b0b0c0e40c75b8374a1800387dbf399b4bc9) // vk.ID4.x + mstore(add(_vk, 0x620), 0x2c1e133ab13d64c88e3ac0dd7e4c29f4cb517ed81f84053a824608cc5fc3c3b0) // vk.ID4.y + mstore(add(_vk, 0x640), 0x00) // vk.contains_recursive_proof + mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices + mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 + mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 + mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 + mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 + mstore(_omegaInverseLoc, 0x0b5d56b77fe704e8e92338c0082f37e091126414c830e4c6922d5ac802d842d4) // vk.work_root_inverse + } + } +} diff --git a/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol b/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol index e64c8e685707..10094d20df73 100644 --- a/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol +++ b/barretenberg/sol/src/ultra/keys/RecursiveUltraVerificationKey.sol @@ -1,11 +1,11 @@ -// Verification Key Hash: d25c78098b361876a80895103d19d0586b8ffa8d154cf5b300eda3045a21f200 +// Verification Key Hash: e22392a1f3bddc5d1f000fd4920b5c0e7f8282ee348c68538ea51321fda78a6f // SPDX-License-Identifier: Apache-2.0 // Copyright 2022 Aztec pragma solidity >=0.8.4; library RecursiveUltraVerificationKey { - function verificationKeyHash() internal pure returns(bytes32) { - return 0xd25c78098b361876a80895103d19d0586b8ffa8d154cf5b300eda3045a21f200; + function verificationKeyHash() internal pure returns (bytes32) { + return 0xe22392a1f3bddc5d1f000fd4920b5c0e7f8282ee348c68538ea51321fda78a6f; } function loadVerificationKey(uint256 _vk, uint256 _omegaInverseLoc) internal pure { @@ -14,58 +14,58 @@ library RecursiveUltraVerificationKey { mstore(add(_vk, 0x20), 0x0000000000000000000000000000000000000000000000000000000000000010) // vk.num_inputs mstore(add(_vk, 0x40), 0x19ddbcaf3a8d46c15c0176fbb5b95e4dc57088ff13f4d1bd84c6bfa57dcdc0e0) // vk.work_root mstore(add(_vk, 0x60), 0x30644259cd94e7dd5045d7a27013b7fcd21c9e3b7fa75222e7bda49b729b0401) // vk.domain_inverse - mstore(add(_vk, 0x80), 0x2e99805b70f3d61c991b8fd84874e57103c7d7ba60cf60cfe871c92ea7cf3248) // vk.Q1.x - mstore(add(_vk, 0xa0), 0x2359a1c894e0f2af06830fb0d9879b974ec6afa1c95cb8f018780238f8b937e9) // vk.Q1.y - mstore(add(_vk, 0xc0), 0x19b500db732e56fd76e45c1608de1a2d10bce43dbac9ee868a578d68c908c332) // vk.Q2.x - mstore(add(_vk, 0xe0), 0x12de1d2b47110c7e547f2c7dbcb1a229e16333a513afea3226cac0e4f4a50157) // vk.Q2.y - mstore(add(_vk, 0x100), 0x258112db8f43fcd49b658d699abf5990b03e09ef7f55063ec0a1ff303aa59734) // vk.Q3.x - mstore(add(_vk, 0x120), 0x2ce5f9e6ce609b428c6b5f17e39dd6947af4073516dd61de721f000bed6b7bc3) // vk.Q3.y - mstore(add(_vk, 0x140), 0x06984f6692d241b7213fe774c3082e54ca2f254cbb5183f5d213ab93eb527541) // vk.Q4.x - mstore(add(_vk, 0x160), 0x224652f2a786bcc81dfeba13da0a3ffc1bce4abb2870e9cd91f4c26215b878a1) // vk.Q4.y - mstore(add(_vk, 0x180), 0x047220d936cff4715b088a0876b290f52a08aedfc88eb111d59cfa88b716a702) // vk.Q_M.x - mstore(add(_vk, 0x1a0), 0x218375143e04327f9c84e1896dc1eb64cdc13a32aafa1ab7dc9e4c84fbbc61e5) // vk.Q_M.y - mstore(add(_vk, 0x1c0), 0x0555d41fe3fab5369c4251a1b72b185256fc49fed670153b3aaec40dd7237e38) // vk.Q_C.x - mstore(add(_vk, 0x1e0), 0x1f83575b2fb33a6e90caedcbd326c1a53ee984eaebd0ec73ebb1a89d2aceb708) // vk.Q_C.y - mstore(add(_vk, 0x200), 0x096c8dfb84e1e95247740d3a2924cef13cb580706db4b1cb242fd883efdb3023) // vk.Q_ARITHMETIC.x - mstore(add(_vk, 0x220), 0x056a3687ebe14a74c8529fbb845e86e609a8de9d0b0c92dc838541259dc0f770) // vk.Q_ARITHMETIC.y - mstore(add(_vk, 0x240), 0x131e9caa1a0182cacf248327946f2b9bb5a2f13ea7d9195f17b534878a719be2) // vk.QSORT.x - mstore(add(_vk, 0x260), 0x13dc17885405d6756deda93c8d20517dd3a9c93c1ff41a20bf692bbf25696d90) // vk.QSORT.y - mstore(add(_vk, 0x280), 0x1cb14db2c39a1500c4ddb1a75622ca726f2abb263b14245a3fa9804e1530ceac) // vk.Q_ELLIPTIC.x - mstore(add(_vk, 0x2a0), 0x181d870ffe1445d30819a652326e80354eba031560fb2168f75fd59adeaa964e) // vk.Q_ELLIPTIC.y - mstore(add(_vk, 0x2c0), 0x15d25401297c7f1d09ebdedae5140ede85d6a93ffcbdcec78f1d4a94905223bb) // vk.Q_AUX.x - mstore(add(_vk, 0x2e0), 0x27f3275e48c07d6a03bb03d5bbc658b7ff658fee03fb7939e45bbcbc1f70cd15) // vk.Q_AUX.y - mstore(add(_vk, 0x300), 0x193112d61b03cb7a9e4f7af25c3c78a3548a7a64de864168141f21a298a1b872) // vk.SIGMA1.x - mstore(add(_vk, 0x320), 0x178cdc334092b41699bf1f7cb41965f5089dda63fc10ed5b4b6be111c6064d98) // vk.SIGMA1.y - mstore(add(_vk, 0x340), 0x1c066e533ca2632e3cb88f56e853b8eb8dfc4f037394aaa2b34fd90b0a52767b) // vk.SIGMA2.x - mstore(add(_vk, 0x360), 0x0407098851cf2da7d0e0d8ae37ef9e32e6cae22f641ae71bd1dc312be948cd8a) // vk.SIGMA2.y - mstore(add(_vk, 0x380), 0x1ead1faf379b317c6f778a29ebaa9344f3f2c7aeb42a84a284f32e315b429c63) // vk.SIGMA3.x - mstore(add(_vk, 0x3a0), 0x1b49e9a04ab1870e6c25cecb5090f1cf5a39d62b393b0e45ca6c0481483958da) // vk.SIGMA3.y - mstore(add(_vk, 0x3c0), 0x0c9d9aadf730ecc1d7deb4ea1ab82744f34fe6c3e8bc5a078aee1829b5e36fda) // vk.SIGMA4.x - mstore(add(_vk, 0x3e0), 0x25d36ed174687ce321258b6bdac4ae924ad792a03b9aec923eef6f5093657d1f) // vk.SIGMA4.y - mstore(add(_vk, 0x400), 0x215a055ec0bf7d7ab5e005b4260258aaadfd8ae9005a09060fdd0cee02dc3fea) // vk.TABLE1.x - mstore(add(_vk, 0x420), 0x1841eba177a34b1eb908727fe2e54bf33fc82b6e58dfd044acd4ba05ca80c837) // vk.TABLE1.y - mstore(add(_vk, 0x440), 0x018eb037682044ebf9cad76f777bf379b94c4d31d4351ce9677ff146a744555c) // vk.TABLE2.x - mstore(add(_vk, 0x460), 0x2bf87d72f0aef257c728503c900516f9274ab06eb54804651218438e40f06c25) // vk.TABLE2.y - mstore(add(_vk, 0x480), 0x13b003b384fb50e00994bf62a0057f44344be47383d59a7e9f1319d710ab5263) // vk.TABLE3.x - mstore(add(_vk, 0x4a0), 0x1a5f338a3d05fb46ea46855e6c36dbdb23c5f20a56acc795324fe2958189ec39) // vk.TABLE3.y - mstore(add(_vk, 0x4c0), 0x1365fd683dbad2c4c55b02dd33c4b96fde00e5bb3f52be20ead95484e130aee1) // vk.TABLE4.x - mstore(add(_vk, 0x4e0), 0x2da2ba1d27548e452cc863758acf156eb268f577b7d08ba58e7bbf2d28f6f23c) // vk.TABLE4.y - mstore(add(_vk, 0x500), 0x16e9fe7ac7109f057245ceb22e31e1e1b8a8fbf1c6962e926ba5b2505e982d05) // vk.TABLE_TYPE.x - mstore(add(_vk, 0x520), 0x009a46821fcbdf82b50e323c21ea282115016a12ae0f7f59149cd89eb2357407) // vk.TABLE_TYPE.y - mstore(add(_vk, 0x540), 0x2066e5c64cb0534e6e825d7852d74375602da9d08c69e11ad65e0ccc194adfd7) // vk.ID1.x - mstore(add(_vk, 0x560), 0x23735d2cb88ddb998c9209a5bd0dc753c3d3bdf908490e7cdb24d053a15558de) // vk.ID1.y - mstore(add(_vk, 0x580), 0x29cf07d995b647c3b4a8dbd458ec65ad20f4b38cb193258938b5164ae9bc31a3) // vk.ID2.x - mstore(add(_vk, 0x5a0), 0x16ee1de144c9d73a3827323482c0d6882c6ffdd3f21f485a801218e30cdaf143) // vk.ID2.y - mstore(add(_vk, 0x5c0), 0x1eb4743b386c88a74762c47d79e0c6f1aac09dc83797c0ff06aae5e77ca93b72) // vk.ID3.x - mstore(add(_vk, 0x5e0), 0x1361f17743eeee4cd094e4663957646a3766880e287cacb7a6a4378f51408520) // vk.ID3.y - mstore(add(_vk, 0x600), 0x1ea01b590a95e3b4d542356cc095198a2710aded8b1b4e58f4de2cb21e82b3e3) // vk.ID4.x - mstore(add(_vk, 0x620), 0x12b17964421b96b6a35f58cf3b88e22ba39765300bd2a7ebd25e19a0ba80664f) // vk.ID4.y + mstore(add(_vk, 0x80), 0x1955384fa963070c967ff2c960277b4e296aae8d72c72e01930356b9e66e82f0) // vk.Q1.x + mstore(add(_vk, 0xa0), 0x1abfdcc530bde7617e8bdacdb27582d2c313b5ac663a9d47075ccd7ea20be189) // vk.Q1.y + mstore(add(_vk, 0xc0), 0x019e10458c6caa9d5be700d9b289766239bef8ef7f9608300f75e4db84014d7b) // vk.Q2.x + mstore(add(_vk, 0xe0), 0x2c8b6fc311eb5850c154e438fc9ffba848c332d3b1f517266751cff56f711890) // vk.Q2.y + mstore(add(_vk, 0x100), 0x16087fc135eeed06f55acc3a59da6eff09599c013fbc397e742e7e7c3e34529a) // vk.Q3.x + mstore(add(_vk, 0x120), 0x025586359ebb3a81602ac1266da2503f320d26b9b18a3835a75f5ea587363d9b) // vk.Q3.y + mstore(add(_vk, 0x140), 0x049008f625581a490bb8fcf4ea3c648c6fd4d802cdffe7866175efd7b5664185) // vk.Q4.x + mstore(add(_vk, 0x160), 0x25e38e7a8cda67d926bdf8db7ebdd535499f4354f1e902ef27aeb79c63d2c233) // vk.Q4.y + mstore(add(_vk, 0x180), 0x113e080e177eeabec67380d0d0ecfdbfd9a8f7cc9e02c8d8445c328abbfeb9a5) // vk.Q_M.x + mstore(add(_vk, 0x1a0), 0x10f95dae13bfe0c0a3efbe10855b52c43269d8aa611525dbbcb1f1d0eb42f848) // vk.Q_M.y + mstore(add(_vk, 0x1c0), 0x23f14dc05ec047d53df22710cdfd3cb4a44963811078a600811aa06d9576b4c0) // vk.Q_C.x + mstore(add(_vk, 0x1e0), 0x0821bba87eb570b4f41b432624bb2bf013a9b129e7bc0c0178bcc2adc1c47606) // vk.Q_C.y + mstore(add(_vk, 0x200), 0x26486dece09dab5a8e4e757625088433f1d8123e8fda3693d4a7993f621f1eed) // vk.Q_ARITHMETIC.x + mstore(add(_vk, 0x220), 0x286019a7e6055aef52b91c449a1c2b9abbcb92595118160efc96ced10ac4b6e4) // vk.Q_ARITHMETIC.y + mstore(add(_vk, 0x240), 0x2ca5a08c8d2cc428aa539aab26c0ae71d28ed89e61fff9ef5c9eb896748e01c0) // vk.QSORT.x + mstore(add(_vk, 0x260), 0x124d0e50734e64db09937d992e57c88c3d82f17786ee7691191da883af81f7cb) // vk.QSORT.y + mstore(add(_vk, 0x280), 0x1ade93a940dab58eb305c26f147e387aa2ce033cd98b3f6d92d440a7ec159d7e) // vk.Q_ELLIPTIC.x + mstore(add(_vk, 0x2a0), 0x0bfe74216774dc130b6219ffd3ca3d716dde56532ef454e002b5e7cc1a714f06) // vk.Q_ELLIPTIC.y + mstore(add(_vk, 0x2c0), 0x11aa3c2e6abd71b46496cc7258ffb26e454779dd7a861c9b170df7b6d19866bb) // vk.Q_AUX.x + mstore(add(_vk, 0x2e0), 0x078a7416251f2354b81f7f23674a442733beaa73928c52482e09af67e4266630) // vk.Q_AUX.y + mstore(add(_vk, 0x300), 0x18b0d041e64959a1b4c8aec2988ed0781a8e71e3b399e9e6f1519553e7d4b844) // vk.SIGMA1.x + mstore(add(_vk, 0x320), 0x051faec8bc66561eb3dd53d7e9f062a69726ee92df29f337c1152b4838a6ecb5) // vk.SIGMA1.y + mstore(add(_vk, 0x340), 0x1b3db046a836a946d73153637681ae12a3747e76100a973ba3e57a60bf05f8b8) // vk.SIGMA2.x + mstore(add(_vk, 0x360), 0x2a0d1cb0659525e3e515020d4728b9deb1aac70c1286eb565e2589da5700caac) // vk.SIGMA2.y + mstore(add(_vk, 0x380), 0x2da060ec79d4280499b69fde005a3712a9b694118f9332af6e1611659ea05d10) // vk.SIGMA3.x + mstore(add(_vk, 0x3a0), 0x0de556d12e70d90ed705a5542c16a55a44910532e1f24c2252649f0b061af019) // vk.SIGMA3.y + mstore(add(_vk, 0x3c0), 0x101702660aecee7905d290afb56978ff8756662cb0589bf1260b7aa0feb8e044) // vk.SIGMA4.x + mstore(add(_vk, 0x3e0), 0x29d27af726556b6b97d2998f0ed57fecbb2fa27cefc51fee5a96a4ada07c0d2d) // vk.SIGMA4.y + mstore(add(_vk, 0x400), 0x09796190fd3ba909c6530c89811df9b5b4f5f2fe6501ec21dd864b20673fc02c) // vk.TABLE1.x + mstore(add(_vk, 0x420), 0x00b9c2423e310caa43e1eb83b55f53977fccbed85422df8935635d77d146bf39) // vk.TABLE1.y + mstore(add(_vk, 0x440), 0x217dad26ccc0c543ec5750513e9365a5cae8164b08d364efcf4b5890ff05f334) // vk.TABLE2.x + mstore(add(_vk, 0x460), 0x1db28433f6bde424423f3587787f81c48101d2dc6e54b431332cb275f8518c62) // vk.TABLE2.y + mstore(add(_vk, 0x480), 0x2cc2d90f2da7f4ec16b7fe61babd4fb9b580ecff03c471764dd67a8c433afab5) // vk.TABLE3.x + mstore(add(_vk, 0x4a0), 0x3032b9ff096a43ce326cc63ffc6a86dcb913fb1f7700939f5304f6c6beb24574) // vk.TABLE3.y + mstore(add(_vk, 0x4c0), 0x1f4c58502ca713ed0bffb4ff31ed55e557e83a37d31b8e703aa9219d6158e2d2) // vk.TABLE4.x + mstore(add(_vk, 0x4e0), 0x0b0d5ed5432c5e7b56344c1d26ce0d9f632e8f8aa52505d6c89f6da89f357fa8) // vk.TABLE4.y + mstore(add(_vk, 0x500), 0x1ec56cfb03ca703e6c5b12bc25735a6277ba8e195789f871273e0ab6108c69dc) // vk.TABLE_TYPE.x + mstore(add(_vk, 0x520), 0x15dd65957a13632642739159f99cb0bc793a3e9fd3317b11de1887305b1f0ba0) // vk.TABLE_TYPE.y + mstore(add(_vk, 0x540), 0x1132be2c2fba72cd6196c25c3f9e4a2607225e1dd9b1df156278bc70eaef9833) // vk.ID1.x + mstore(add(_vk, 0x560), 0x15ac1cf6f0d69580d63e3cef0fbe784daddf5d89cd0532e6c3bac8110f713739) // vk.ID1.y + mstore(add(_vk, 0x580), 0x0a54083d0241492b018ff651dd4a94f694ac29815be96788bbcc1f6731da2c2f) // vk.ID2.x + mstore(add(_vk, 0x5a0), 0x1ac60ad10f90e6a3dae7fc97aa1e86be376a8e477e320ce1a2c5c667587414b0) // vk.ID2.y + mstore(add(_vk, 0x5c0), 0x1499c048e87fea28057e1ec5c3a23c11556bdc658626b07edfedf2739ef2eae2) // vk.ID3.x + mstore(add(_vk, 0x5e0), 0x280fec47ce5e775c01ebfb880fed2fa60ae7c7434d5de1d54dfe3f66cf7e1186) // vk.ID3.y + mstore(add(_vk, 0x600), 0x2daba5e0c0a440cc134049635e97d3f4fdbe0709c73f0480fad500f51542c5ae) // vk.ID4.x + mstore(add(_vk, 0x620), 0x064089effdda7af9ea5de9407b5e96f826001c7d7cef054877ff0203e7ad229e) // vk.ID4.y mstore(add(_vk, 0x640), 0x01) // vk.contains_recursive_proof mstore(add(_vk, 0x660), 0) // vk.recursive_proof_public_input_indices - mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 - mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 - mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 - mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 + mstore(add(_vk, 0x680), 0x260e01b251f6f1c7e7ff4e580791dee8ea51d87a358e038b4efe30fac09383c1) // vk.g2_x.X.c1 + mstore(add(_vk, 0x6a0), 0x0118c4d5b837bcc2bc89b5b398b5974e9f5944073b32078b7e231fec938883b0) // vk.g2_x.X.c0 + mstore(add(_vk, 0x6c0), 0x04fc6369f7110fe3d25156c1bb9a72859cf2a04641f99ba4ee413c80da6a5fe4) // vk.g2_x.Y.c1 + mstore(add(_vk, 0x6e0), 0x22febda3c0c0632a56475b4214e5615e11e6dd3f96e6cea2854a87d4dacc5e55) // vk.g2_x.Y.c0 mstore(_omegaInverseLoc, 0x036853f083780e87f8d7c71d111119c57dbe118c22d5ad707a82317466c5174c) // vk.work_root_inverse } } diff --git a/barretenberg/sol/test/base/DifferentialFuzzer.sol b/barretenberg/sol/test/base/DifferentialFuzzer.sol index 451fc8ee21b2..c23d9ceb9685 100644 --- a/barretenberg/sol/test/base/DifferentialFuzzer.sol +++ b/barretenberg/sol/test/base/DifferentialFuzzer.sol @@ -17,6 +17,7 @@ contract DifferentialFuzzer is TestBase { Invalid, Blake, Add2, + Ecdsa, Recursive } @@ -63,6 +64,8 @@ contract DifferentialFuzzer is TestBase { return "add2"; } else if (circuitFlavour == CircuitFlavour.Recursive) { return "recursive"; + } else if (circuitFlavour == CircuitFlavour.Ecdsa) { + return "ecdsa"; } else { revert("Invalid circuit flavour"); } diff --git a/barretenberg/sol/test/ultra/ECDSA.t.sol b/barretenberg/sol/test/ultra/ECDSA.t.sol new file mode 100644 index 000000000000..a055801615ce --- /dev/null +++ b/barretenberg/sol/test/ultra/ECDSA.t.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright 2022 Aztec +pragma solidity >=0.8.4; + +import {TestBaseUltra} from "./TestBaseUltra.sol"; +import {EcdsaUltraVerifier} from "../../src/ultra/instance/EcdsaUltraVerifier.sol"; +import {DifferentialFuzzer} from "../base/DifferentialFuzzer.sol"; +import {IVerifier} from "../../src/interfaces/IVerifier.sol"; + +contract EcdsaUltraTest is TestBaseUltra { + function setUp() public override(TestBaseUltra) { + super.setUp(); + + verifier = IVerifier(address(new EcdsaUltraVerifier())); + fuzzer = fuzzer.with_circuit_flavour(DifferentialFuzzer.CircuitFlavour.Ecdsa); + + PUBLIC_INPUT_COUNT = 6; + + // Add default inputs to the fuzzer (we will override these in fuzz test) + uint256[] memory inputs = new uint256[](6); + inputs[0] = uint256(0x67); + inputs[1] = uint256(0x6f); + inputs[2] = uint256(0x62); + inputs[3] = uint256(0x6c); + inputs[4] = uint256(0x69); + inputs[5] = uint256(0x6e); + + fuzzer = fuzzer.with_inputs(inputs); + } + + function testFuzzProof() public { + // NOTE we do not fuzz here yet + // "goblin" + // 67 6f 62 6c 69 6e + uint256[] memory inputs = new uint256[](6); + inputs[0] = uint256(0x67); + inputs[1] = uint256(0x6f); + inputs[2] = uint256(0x62); + inputs[3] = uint256(0x6c); + inputs[4] = uint256(0x69); + inputs[5] = uint256(0x6e); + + // Construct Ecdsa siganture + bytes memory proofData = fuzzer.with_inputs(inputs).generate_proof(); + (bytes32[] memory publicInputs, bytes memory proof) = splitProof(proofData, PUBLIC_INPUT_COUNT); + + assertTrue(verifier.verify(proof, publicInputs), "The proof is not valid"); + } +} diff --git a/barretenberg/ts/src/main.ts b/barretenberg/ts/src/main.ts index a985ea59e796..513748a2f974 100755 --- a/barretenberg/ts/src/main.ts +++ b/barretenberg/ts/src/main.ts @@ -124,6 +124,7 @@ export async function prove( debug(`creating proof...`); const bytecode = getBytecode(bytecodePath); const witness = getWitness(witnessPath); + await api.acirInitProvingKey(acirComposer, bytecode); const proof = await api.acirCreateProof(acirComposer, bytecode, witness, isRecursive); debug(`done.`); diff --git a/build_manifest.yml b/build_manifest.yml index ee4ff6b60cc4..f5c5d9689c77 100644 --- a/build_manifest.yml +++ b/build_manifest.yml @@ -39,6 +39,13 @@ barretenberg-acir-tests-bb: dependencies: - barretenberg-x86_64-linux-clang-assert +barretenberg-acir-tests-bb-sol: + buildDir: barretenberg/acir_tests + dockerfile: Dockerfile.bb.sol + dependencies: + - barretenberg-x86_64-linux-clang-assert + - barretenberg-x86_64-linux-clang-sol + barretenberg-acir-tests-bb.js: buildDir: barretenberg/acir_tests dockerfile: Dockerfile.bb.js diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp index dd2298537ac5..a5109cabf3b9 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -258,7 +258,7 @@ TEST_F(base_rollup_tests, native_new_commitments_tree) // Then get sibling path so we can verify insert them into the tree. std::array, 2> kernel_data = { get_empty_kernel(), get_empty_kernel() }; - std::array new_commitments = { 0, 1, 2, 3, 4, 5, 6, 7 }; + std::array new_commitments = { 0, 1, 2, 3, 4, 5, 6, 7 }; for (uint8_t i = 0; i < 2; i++) { std::array kernel_commitments; for (uint8_t j = 0; j < MAX_NEW_COMMITMENTS_PER_TX; j++) { @@ -481,7 +481,7 @@ TEST_F(base_rollup_tests, native_nullifier_tree_regression) initial_values[7] = uint256_t("2bb9aa4a22a6ae7204f2c67abaab59cead6558cde4ee25ce3464704cb2e38136"); initial_values[8] = uint256_t("16a732095298ccca828c4d747813f8bd46e188079ed17904e2c9de50760833c8"); - std::array new_nullifiers = { 0 }; + std::array new_nullifiers = { 0 }; new_nullifiers[0] = uint256_t("16da4f27fb78de7e0db4c5a04b569bc46382c5f471da2f7d670beff1614e0118"), new_nullifiers[1] = uint256_t("26ab07ce103a55e29f11478eaa36cebd10c4834b143a7debcc7ef53bfdb547dd"); @@ -519,7 +519,7 @@ TEST_F(base_rollup_tests, native_nullifier_tree_regression) TEST_F(base_rollup_tests, nullifier_tree_regression_2) { // Regression test caught when testing the typescript nullifier tree implementation - std::array new_nullifiers = { 0 }; + std::array new_nullifiers = { 0 }; new_nullifiers[0] = uint256_t("2a7d956c1365d259646d2d85babe1abb793bb8789e98df7e2336a29a0c91fd01"); new_nullifiers[1] = uint256_t("236bf2d113f9ffee89df1a7a04890c9ad3583c6773eb9cdec484184f66abd4c6"); new_nullifiers[4] = uint256_t("2f5c8a1ee33c7104b244e22a3e481637cd501c9eae868cfab6b16e3b4ef3d635"); @@ -530,7 +530,7 @@ TEST_F(base_rollup_tests, nullifier_tree_regression_2) TEST_F(base_rollup_tests, nullifier_tree_regression_3) { - std::array new_nullifiers = { 0 }; + std::array new_nullifiers = { 0 }; new_nullifiers[0] = uint256_t("0740a17aa6437e71836d2adcdcb3f52879bb869cdd9c8fb8dc39a12846cd17f2"); new_nullifiers[1] = uint256_t("282e0e2f38310a7c7c98b636830b66f3276294560e26ef2499da10892f00af8f"); new_nullifiers[4] = uint256_t("0f117936e888bd3befb4435f4d65300d25609e95a3d1563f62ef7e58c294f578");