From 55e60161ef2c45d04ca34132ea31d7fd224ef090 Mon Sep 17 00:00:00 2001 From: dbanks12 Date: Thu, 11 May 2023 23:41:54 +0000 Subject: [PATCH 01/36] prelim / very-broken commit where Jean and I started implementing the initial private kernel and moving logic between it and the inner kernel --- .../cpp/src/aztec3/circuits/abis/c_bind.cpp | 2 +- .../src/aztec3/circuits/abis/c_bind.test.cpp | 2 +- ...uts.hpp => private_kernel_inputs_init.hpp} | 32 +- .../private_kernel_inputs_inner.hpp | 68 ++++ circuits/cpp/src/aztec3/circuits/hash.hpp | 2 +- .../aztec3/circuits/kernel/private/.test.cpp | 16 +- .../aztec3/circuits/kernel/private/c_bind.cpp | 6 +- .../aztec3/circuits/kernel/private/common.hpp | 137 +++++++ .../aztec3/circuits/kernel/private/init.hpp | 1 - .../private/native_private_kernel_circuit.cpp | 151 ++------ .../private/native_private_kernel_circuit.hpp | 7 +- .../native_private_kernel_circuit_initial.cpp | 337 ++++++++++++++++++ .../native_private_kernel_circuit_initial.hpp | 20 ++ .../kernel/private/private_kernel_circuit.cpp | 20 +- .../kernel/private/private_kernel_circuit.hpp | 6 +- .../aztec3/circuits/kernel/public/common.hpp | 1 - ...blic_kernel_circuit_no_previous_kernel.cpp | 6 +- circuits/cpp/src/aztec3/constants.hpp | 1 + .../cpp/src/aztec3/utils/circuit_errors.hpp | 1 + 19 files changed, 633 insertions(+), 183 deletions(-) rename circuits/cpp/src/aztec3/circuits/abis/private_kernel/{private_inputs.hpp => private_kernel_inputs_init.hpp} (57%) create mode 100644 circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp index 68f52b52d925..59c2545e1238 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp @@ -465,7 +465,7 @@ WASM_EXPORT const char* abis__test_roundtrip_serialize_signed_tx_request(uint8_t WASM_EXPORT const char* abis__test_roundtrip_serialize_private_kernel_inputs(uint8_t const* input, uint32_t* size) { - return as_string_output>(input, size); + return as_string_output>(input, size); } WASM_EXPORT const char* abis__test_roundtrip_serialize_kernel_circuit_public_inputs(uint8_t const* input, diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp index e00f32e5c449..8573c33a39db 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp @@ -265,7 +265,7 @@ TEST(abi_tests, hash_constructor) // Calculate the expected hash in-test NT::fr const expected_hash = NT::compress( - { func_data.hash(), NT::compress(args, aztec3::GeneratorIndex::CONSTRUCTOR_ARGS), constructor_vk_hash }, + { func_data.hash(), NT::compress(args, aztec3::GeneratorIndex::FUNCTION_ARGS), constructor_vk_hash }, aztec3::GeneratorIndex::CONSTRUCTOR); // Confirm cbind output == expected hash diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_inputs.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp similarity index 57% rename from circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_inputs.hpp rename to circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp index 607b397a8b35..69985edefe20 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_inputs.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp @@ -1,13 +1,11 @@ #pragma once #include "private_call_data.hpp" -#include "../combined_accumulated_data.hpp" -#include "../previous_kernel_data.hpp" #include "../signed_tx_request.hpp" -#include -#include -#include +#include "aztec3/utils/types/circuit_types.hpp" +#include "aztec3/utils/types/convert.hpp" +#include "aztec3/utils/types/native_types.hpp" #include @@ -17,28 +15,26 @@ using aztec3::utils::types::CircuitTypes; using aztec3::utils::types::NativeTypes; using std::is_same; -template struct PrivateInputs { +template struct PrivateKernelInputsInit { using fr = typename NCT::fr; using boolean = typename NCT::boolean; SignedTxRequest signed_tx_request{}; - PreviousKernelData previous_kernel{}; PrivateCallData private_call{}; - boolean operator==(PrivateInputs const& other) const + boolean operator==(PrivateKernelInputsInit const& other) const { - return signed_tx_request == other.signed_tx_request && previous_kernel == other.previous_kernel && - private_call == other.private_call; + return signed_tx_request == other.signed_tx_request && private_call == other.private_call; }; - template PrivateInputs> to_circuit_type(Composer& composer) const + template + PrivateKernelInputsInit> to_circuit_type(Composer& composer) const { static_assert((std::is_same::value)); - PrivateInputs> private_inputs = { + PrivateKernelInputsInit> private_inputs = { // TODO to_ct(signature), signed_tx_request.to_circuit_type(composer), - previous_kernel.to_circuit_type(composer), private_call.to_circuit_type(composer), }; @@ -46,31 +42,27 @@ template struct PrivateInputs { }; }; -template void read(uint8_t const*& it, PrivateInputs& private_inputs) +template void read(uint8_t const*& it, PrivateKernelInputsInit& private_inputs) { using serialize::read; read(it, private_inputs.signed_tx_request); - read(it, private_inputs.previous_kernel); read(it, private_inputs.private_call); }; -template void write(std::vector& buf, PrivateInputs const& private_inputs) +template void write(std::vector& buf, PrivateKernelInputsInit const& private_inputs) { using serialize::write; write(buf, private_inputs.signed_tx_request); - write(buf, private_inputs.previous_kernel); write(buf, private_inputs.private_call); }; -template std::ostream& operator<<(std::ostream& os, PrivateInputs const& private_inputs) +template std::ostream& operator<<(std::ostream& os, PrivateKernelInputsInit const& private_inputs) { return os << "signed_tx_request:\n" << private_inputs.signed_tx_request << "\n" << "previous_kernel:\n" - << private_inputs.previous_kernel << "\n" - << "private_call:\n" << private_inputs.private_call << "\n"; } diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp new file mode 100644 index 000000000000..79c0d9235cc9 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp @@ -0,0 +1,68 @@ +#pragma once + +#include "private_call_data.hpp" +#include "../previous_kernel_data.hpp" + +#include "aztec3/utils/types/circuit_types.hpp" +#include "aztec3/utils/types/convert.hpp" +#include "aztec3/utils/types/native_types.hpp" + +#include + +namespace aztec3::circuits::abis::private_kernel { + +using aztec3::utils::types::CircuitTypes; +using aztec3::utils::types::NativeTypes; +using std::is_same; + +template struct PrivateKernelInputsInner { + using fr = typename NCT::fr; + using boolean = typename NCT::boolean; + + PreviousKernelData previous_kernel{}; + PrivateCallData private_call{}; + + boolean operator==(PrivateKernelInputsInner const& other) const + { + return previous_kernel == other.previous_kernel && private_call == other.private_call; + }; + + template + PrivateKernelInputsInner> to_circuit_type(Composer& composer) const + { + static_assert((std::is_same::value)); + + PrivateKernelInputsInner> private_inputs = { + previous_kernel.to_circuit_type(composer), + private_call.to_circuit_type(composer), + }; + + return private_inputs; + }; +}; + +template void read(uint8_t const*& it, PrivateKernelInputsInner& private_inputs) +{ + using serialize::read; + + read(it, private_inputs.previous_kernel); + read(it, private_inputs.private_call); +}; + +template void write(std::vector& buf, PrivateKernelInputsInner const& private_inputs) +{ + using serialize::write; + + write(buf, private_inputs.previous_kernel); + write(buf, private_inputs.private_call); +}; + +template std::ostream& operator<<(std::ostream& os, PrivateKernelInputsInner const& private_inputs) +{ + return os << "previous_kernel:\n" + << private_inputs.previous_kernel << "\n" + << "private_call:\n" + << private_inputs.private_call << "\n"; +} + +} // namespace aztec3::circuits::abis::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/hash.hpp b/circuits/cpp/src/aztec3/circuits/hash.hpp index 5696d8904199..7017ac0f99d4 100644 --- a/circuits/cpp/src/aztec3/circuits/hash.hpp +++ b/circuits/cpp/src/aztec3/circuits/hash.hpp @@ -16,7 +16,7 @@ using aztec3::circuits::abis::FunctionLeafPreimage; template typename NCT::fr compute_args_hash(std::array args) { - return NCT::compress(args, CONSTRUCTOR_ARGS); + return NCT::compress(args, FUNCTION_ARGS); } template typename NCT::fr compute_constructor_hash(FunctionData function_data, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 0ba2e29b7f6e..830997f631dc 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -52,7 +52,7 @@ using aztec3::circuits::abis::CombinedHistoricTreeRoots; using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::PrivateCallData; -using aztec3::circuits::abis::private_kernel::PrivateInputs; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using aztec3::circuits::apps::test_apps::basic_contract_deployment::constructor; using aztec3::circuits::apps::test_apps::escrow::deposit; @@ -168,10 +168,10 @@ std::shared_ptr gen_func_vk(bool is_constructor, private_function const& * @param args_vec the private call's args * @return PrivateInputs - the inputs to the private call circuit */ -PrivateInputs do_private_call_get_kernel_inputs(bool const is_constructor, - private_function const& func, - std::vector const& args_vec, - bool real_kernel_circuit = false) +PrivateKernelInputsInner do_private_call_get_kernel_inputs(bool const is_constructor, + private_function const& func, + std::vector const& args_vec, + bool real_kernel_circuit = false) { //*************************************************************************** // Initialize some inputs to private call and kernel circuits @@ -364,7 +364,7 @@ PrivateInputs do_private_call_get_kernel_inputs(bool const is_constructor, //*************************************************************************** // Now we can construct the full private inputs to the kernel circuit //*************************************************************************** - PrivateInputs kernel_private_inputs = PrivateInputs{ + PrivateKernelInputsInner kernel_private_inputs = PrivateInputs{ .signed_tx_request = signed_tx_request, .previous_kernel = mock_previous_kernel, @@ -403,7 +403,7 @@ PrivateInputs do_private_call_get_kernel_inputs(bool const is_constructor, * @param private_inputs to be used in manual computation * @param public_inputs that contain the expected new contract address */ -void validate_deployed_contract_address(PrivateInputs const& private_inputs, +void validate_deployed_contract_address(PrivateKernelInputsInner const& private_inputs, KernelCircuitPublicInputs const& public_inputs) { auto tx_request = private_inputs.signed_tx_request.tx_request; @@ -412,7 +412,7 @@ void validate_deployed_contract_address(PrivateInputs const& private_inputs, auto private_circuit_vk_hash = stdlib::recursion::verification_key::compress_native( private_inputs.private_call.vk, GeneratorIndex::VK); auto expected_constructor_hash = NT::compress({ private_inputs.private_call.call_stack_item.function_data.hash(), - NT::compress(tx_request.args, CONSTRUCTOR_ARGS), + NT::compress(tx_request.args, FUNCTION_ARGS), private_circuit_vk_hash }, CONSTRUCTOR); NT::fr const expected_contract_address = diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index 987b52b180af..2d1fad90e8d0 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -26,7 +26,7 @@ using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::PreviousKernelData; using aztec3::circuits::abis::SignedTxRequest; using aztec3::circuits::abis::private_kernel::PrivateCallData; -using aztec3::circuits::abis::private_kernel::PrivateInputs; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::utils::dummy_previous_kernel; @@ -114,7 +114,7 @@ WASM_EXPORT size_t private_kernel__sim(uint8_t const* signed_tx_request_buf, read(previous_kernel_buf, previous_kernel); } - PrivateInputs const private_inputs = PrivateInputs{ + PrivateKernelInputsInner const private_inputs = PrivateKernelInputsInner{ .signed_tx_request = signed_tx_request, .previous_kernel = previous_kernel, .private_call = private_call_data, @@ -166,7 +166,7 @@ WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, } else { read(previous_kernel_buf, previous_kernel); } - PrivateInputs const private_inputs = PrivateInputs{ + PrivateKernelInputsInner const private_inputs = PrivateKernelInputsInner{ .signed_tx_request = signed_tx_request, .previous_kernel = previous_kernel, .private_call = private_call_data, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp new file mode 100644 index 000000000000..1098ce385b80 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -0,0 +1,137 @@ +#pragma once + +#include "init.hpp" + +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/hash.hpp" +#include "aztec3/constants.hpp" +#include "aztec3/utils/array.hpp" +#include "aztec3/utils/dummy_composer.hpp" + +#include + +using DummyComposer = aztec3::utils::DummyComposer; + +using aztec3::circuits::abis::ContractLeafPreimage; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::NewContractData; + +using aztec3::utils::array_length; +using aztec3::utils::array_pop; +using aztec3::utils::array_push; +using aztec3::utils::is_array_empty; +using aztec3::utils::push_array_to_array; +using DummyComposer = aztec3::utils::DummyComposer; +using CircuitErrorCode = aztec3::utils::CircuitErrorCode; + +using aztec3::circuits::compute_constructor_hash; +using aztec3::circuits::compute_contract_address; +using aztec3::circuits::contract_tree_root_from_siblings; +using aztec3::circuits::function_tree_root_from_siblings; + + +namespace aztec3::circuits::kernel::private_kernel { + +template +void common_validate_call_stack(DummyComposer& composer, KernelPrivateInput const& private_inputs) +{ + const auto& stack = private_inputs.private_call.call_stack_item.public_inputs.private_call_stack; + const auto& preimages = private_inputs.private_call.private_call_stack_preimages; + for (size_t i = 0; i < stack.size(); ++i) { + const auto& hash = stack[i]; + const auto& preimage = preimages[i]; + + // Note: this assumes it's computationally infeasible to have `0` as a valid call_stack_item_hash. + // Assumes `hash == 0` means "this stack item is empty". + const auto calculated_hash = hash == 0 ? 0 : preimage.hash(); + composer.do_assert(hash != calculated_hash, + format("private_call_stack[", i, "] = ", hash, "; does not reconcile"), + CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_ITEM_HASH_MISMATCH); + } +} + +/** + * @brief Validates the kernel execution of the current iteration + * @tparam The type of kernel input + * @param composer The circuit composer + * @param public_kernel_inputs The inputs to this iteration of the kernel circuit + */ +template +void common_validate_kernel_execution(DummyComposer& composer, KernelInput const& private_inputs) +{ + common_validate_call_context(composer, private_inputs); + common_validate_call_stack(composer, private_inputs); +}; + +template void update_end_values(DummyComposer& composer, + KernelPrivateInput const& private_inputs, + KernelCircuitPublicInputs& public_inputs) +{ + const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; + + const auto& new_commitments = private_call_public_inputs.new_commitments; + const auto& new_nullifiers = private_call_public_inputs.new_nullifiers; + + const auto& is_static_call = private_call_public_inputs.call_context.is_static_call; + + if (is_static_call) { + // No state changes are allowed for static calls: + composer.do_assert(is_array_empty(new_commitments) == true, + "new_commitments must be empty for static calls", + CircuitErrorCode::PRIVATE_KERNEL__NEW_COMMITMENTS_NOT_EMPTY_FOR_STATIC_CALL); + composer.do_assert(is_array_empty(new_nullifiers) == true, + "new_nullifiers must be empty for static calls", + CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_FOR_STATIC_CALL); + } + + const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; + + { + // Nonce nullifier + // DANGER: This is terrible. This should not be part of the protocol. This is an intentional bodge to reach a + // milestone. This must not be the way we derive nonce nullifiers in production. It can be front-run by other + // users. It is not domain separated. Naughty. + array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); + } + + { // commitments & nullifiers + std::array siloed_new_commitments; + for (size_t i = 0; i < new_commitments.size(); ++i) { + siloed_new_commitments[i] = new_commitments[i] == 0 ? 0 + : add_contract_address_to_commitment( + storage_contract_address, new_commitments[i]); + } + + std::array siloed_new_nullifiers; + for (size_t i = 0; i < new_nullifiers.size(); ++i) { + siloed_new_nullifiers[i] = new_nullifiers[i] == 0 ? 0 + : add_contract_address_to_nullifier( + storage_contract_address, new_nullifiers[i]); + } + + push_array_to_array(siloed_new_commitments, public_inputs.end.new_commitments); + push_array_to_array(siloed_new_nullifiers, public_inputs.end.new_nullifiers); + } + + { // call stacks + const auto& this_private_call_stack = private_call_public_inputs.private_call_stack; + push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); + } + + // const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; + + // { + // const auto& new_l2_to_l1_msgs = private_call_public_inputs.new_l2_to_l1_msgs; + // std::array l1_call_stack; + + // for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) { + // l1_call_stack[i] = CT::fr::conditional_assign( + // new_l2_to_l1_msgs[i] == 0, + // 0, + // CT::compress({ portal_contract_address, new_l2_to_l1_msgs[i] }, GeneratorIndex::L2_TO_L1_MSG)); + // } + // } +} + +} // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp index 6da9911174d9..28d7eea000b6 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 808fb1342177..d08494dfcc9e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -16,7 +16,7 @@ namespace aztec3::circuits::kernel::private_kernel { using aztec3::circuits::abis::ContractLeafPreimage; using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::NewContractData; -using aztec3::circuits::abis::private_kernel::PrivateInputs; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using aztec3::utils::array_length; using aztec3::utils::array_pop; @@ -53,7 +53,8 @@ using aztec3::circuits::function_tree_root_from_siblings; // return aggregation_object; // } -void initialise_end_values(PrivateInputs const& private_inputs, KernelCircuitPublicInputs& public_inputs) +void initialise_end_values(PrivateKernelInputsInner const& private_inputs, + KernelCircuitPublicInputs& public_inputs) { public_inputs.constants = private_inputs.previous_kernel.public_inputs.constants; @@ -73,7 +74,7 @@ void initialise_end_values(PrivateInputs const& private_inputs, KernelCircui } void contract_logic(DummyComposer& composer, - PrivateInputs const& private_inputs, + PrivateKernelInputsInner const& private_inputs, KernelCircuitPublicInputs& public_inputs) { const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; @@ -178,78 +179,8 @@ void contract_logic(DummyComposer& composer, } } -void update_end_values(DummyComposer& composer, - PrivateInputs const& private_inputs, - KernelCircuitPublicInputs& public_inputs) -{ - const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; - - const auto& new_commitments = private_call_public_inputs.new_commitments; - const auto& new_nullifiers = private_call_public_inputs.new_nullifiers; - - const auto& is_static_call = private_call_public_inputs.call_context.is_static_call; - - if (is_static_call) { - // No state changes are allowed for static calls: - composer.do_assert(is_array_empty(new_commitments) == true, - "new_commitments must be empty for static calls", - CircuitErrorCode::PRIVATE_KERNEL__NEW_COMMITMENTS_NOT_EMPTY_FOR_STATIC_CALL); - composer.do_assert(is_array_empty(new_nullifiers) == true, - "new_nullifiers must be empty for static calls", - CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_FOR_STATIC_CALL); - } - - const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - - { - // Nonce nullifier - // DANGER: This is terrible. This should not be part of the protocol. This is an intentional bodge to reach a - // milestone. This must not be the way we derive nonce nullifiers in production. It can be front-run by other - // users. It is not domain separated. Naughty. - array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); - } - - { // commitments & nullifiers - std::array siloed_new_commitments; - for (size_t i = 0; i < new_commitments.size(); ++i) { - siloed_new_commitments[i] = new_commitments[i] == 0 ? 0 - : add_contract_address_to_commitment( - storage_contract_address, new_commitments[i]); - } - - std::array siloed_new_nullifiers; - for (size_t i = 0; i < new_nullifiers.size(); ++i) { - siloed_new_nullifiers[i] = new_nullifiers[i] == 0 ? 0 - : add_contract_address_to_nullifier( - storage_contract_address, new_nullifiers[i]); - } - - push_array_to_array(siloed_new_commitments, public_inputs.end.new_commitments); - push_array_to_array(siloed_new_nullifiers, public_inputs.end.new_nullifiers); - } - - { // call stacks - const auto& this_private_call_stack = private_call_public_inputs.private_call_stack; - push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); - } - - // const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; - - // { - // const auto& new_l2_to_l1_msgs = private_call_public_inputs.new_l2_to_l1_msgs; - // std::array l1_call_stack; - - // for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) { - // l1_call_stack[i] = CT::fr::conditional_assign( - // new_l2_to_l1_msgs[i] == 0, - // 0, - // CT::compress({ portal_contract_address, new_l2_to_l1_msgs[i] }, GeneratorIndex::L2_TO_L1_MSG)); - // } - // } -} - void validate_this_private_call_hash(DummyComposer& composer, - PrivateInputs const& private_inputs, + PrivateKernelInputsInner const& private_inputs, KernelCircuitPublicInputs& public_inputs) { // TODO: this logic might need to change to accommodate the weird edge 3 initial txs (the 'main' tx, the 'fee' tx, @@ -263,7 +194,7 @@ void validate_this_private_call_hash(DummyComposer& composer, CircuitErrorCode::PRIVATE_KERNEL__CALCULATED_PRIVATE_CALL_HASH_AND_PROVIDED_PRIVATE_CALL_HASH_MISMATCH); }; -void validate_this_private_call_stack(DummyComposer& composer, PrivateInputs const& private_inputs) +void validate_this_private_call_stack(DummyComposer& composer, PrivateKernelInputsInner const& private_inputs) { const auto& stack = private_inputs.private_call.call_stack_item.public_inputs.private_call_stack; const auto& preimages = private_inputs.private_call.private_call_stack_preimages; @@ -280,7 +211,7 @@ void validate_this_private_call_stack(DummyComposer& composer, PrivateInputs } }; -void validate_inputs(DummyComposer& composer, PrivateInputs const& private_inputs) +void validate_inputs(DummyComposer& composer, PrivateKernelInputsInner const& private_inputs) { const auto& this_call_stack_item = private_inputs.private_call.call_stack_item; @@ -290,8 +221,6 @@ void validate_inputs(DummyComposer& composer, PrivateInputs const& private_i const auto& start = private_inputs.previous_kernel.public_inputs.end; - const NT::boolean is_base_case = start.private_call_count == 0; - // TODO: we might want to range-constrain the call_count to prevent some kind of overflow errors. Having said that, // iterating 2^254 times isn't feasible. @@ -299,55 +228,17 @@ void validate_inputs(DummyComposer& composer, PrivateInputs const& private_i NT::fr const start_public_call_stack_length = array_length(start.public_call_stack); NT::fr const start_new_l2_to_l1_msgs_length = array_length(start.new_l2_to_l1_msgs); - // Base Case - if (is_base_case) { - // TODO: change to allow 3 initial calls on the private call stack, so a fee can be paid and a gas - // rebate can be paid. - - composer.do_assert(start_private_call_stack_length == 1, - "Private call stack must be length 1", - CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_LENGTH_MISMATCH); - - composer.do_assert(start_public_call_stack_length == 0, - "Public call stack must be empty", - CircuitErrorCode::PRIVATE_KERNEL__UNSUPPORTED_OP); - composer.do_assert(start_new_l2_to_l1_msgs_length == 0, - "L2 to L1 msgs must be empty", - CircuitErrorCode::PRIVATE_KERNEL__UNSUPPORTED_OP); - - composer.do_assert(this_call_stack_item.public_inputs.call_context.is_delegate_call == false, - "Users cannot make a delegatecall", - CircuitErrorCode::PRIVATE_KERNEL__UNSUPPORTED_OP); - composer.do_assert(this_call_stack_item.public_inputs.call_context.is_static_call == false, - "Users cannot make a static call", - CircuitErrorCode::PRIVATE_KERNEL__UNSUPPORTED_OP); - - // The below also prevents delegatecall/staticcall in the base case - composer.do_assert(this_call_stack_item.public_inputs.call_context.storage_contract_address == - this_call_stack_item.contract_address, - "Storage contract address must be that of the called contract", - CircuitErrorCode::PRIVATE_KERNEL__CONTRACT_ADDRESS_MISMATCH); - - composer.do_assert(private_inputs.previous_kernel.vk->contains_recursive_proof == false, - "Mock kernel proof must not contain a recursive proof", - CircuitErrorCode::PRIVATE_KERNEL__KERNEL_PROOF_CONTAINS_RECURSIVE_PROOF); - - // TODO: Assert that the previous kernel data is empty. (Or rather, the verify_proof() function needs a valid - // dummy proof and vk to complete execution, so actually what we want is for that mockvk to be - // hard-coded into the circuit and assert that that is the one which has been used in the base case). - } else { - // is_recursive_case - - composer.do_assert(private_inputs.previous_kernel.public_inputs.is_private == true, - "Cannot verify a non-private kernel snark in the private kernel circuit", - CircuitErrorCode::PRIVATE_KERNEL__NON_PRIVATE_KERNEL_VERIFIED_WITH_PRIVATE_KERNEL); - composer.do_assert(this_call_stack_item.function_data.is_constructor == false, - "A constructor must be executed as the first tx in the recursion", - CircuitErrorCode::PRIVATE_KERNEL__CONSTRUCTOR_EXECUTED_IN_RECURSION); - composer.do_assert(start_private_call_stack_length != 0, - "Cannot execute private kernel circuit with an empty private call stack", - CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_EMPTY); - } + // is_recursive_case + + composer.do_assert(private_inputs.previous_kernel.public_inputs.is_private == true, + "Cannot verify a non-private kernel snark in the private kernel circuit", + CircuitErrorCode::PRIVATE_KERNEL__NON_PRIVATE_KERNEL_VERIFIED_WITH_PRIVATE_KERNEL); + composer.do_assert(this_call_stack_item.function_data.is_constructor == false, + "A constructor must be executed as the first tx in the recursion", + CircuitErrorCode::PRIVATE_KERNEL__CONSTRUCTOR_EXECUTED_IN_RECURSION); + composer.do_assert(start_private_call_stack_length != 0, + "Cannot execute private kernel circuit with an empty private call stack", + CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_EMPTY); } // NOTE: THIS IS A VERY UNFINISHED WORK IN PROGRESS. @@ -355,7 +246,7 @@ void validate_inputs(DummyComposer& composer, PrivateInputs const& private_i // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, - PrivateInputs const& private_inputs) + PrivateKernelInputsInner const& private_inputs) { // We'll be pushing data to this during execution of this circuit. KernelCircuitPublicInputs public_inputs{}; @@ -367,9 +258,9 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo validate_this_private_call_hash(composer, private_inputs, public_inputs); - validate_this_private_call_stack(composer, private_inputs); + common_validate_call_stack(composer, private_inputs); - update_end_values(composer, private_inputs, public_inputs); + common_update_end_values(composer, private_inputs, public_inputs); contract_logic(composer, private_inputs, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp index cbe24653faf4..31631175078d 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp @@ -3,18 +3,17 @@ #include "init.hpp" #include -#include +#include #include namespace aztec3::circuits::kernel::private_kernel { using aztec3::circuits::abis::KernelCircuitPublicInputs; -using aztec3::circuits::abis::private_kernel::PrivateInputs; -// using abis::private_kernel::PublicInputs; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using DummyComposer = aztec3::utils::DummyComposer; // TODO: decide what to return. KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, - PrivateInputs const& _private_inputs); + PrivateKernelInputsInner const& _private_inputs); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp new file mode 100644 index 000000000000..a32368d25fdb --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -0,0 +1,337 @@ +#include "common.hpp" + +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" + +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; + +namespace aztec3::circuits::kernel::private_kernel { + +// using plonk::stdlib::merkle_tree:: + +// // TODO: NEED TO RECONCILE THE `proof`'s public inputs (which are uint8's) with the +// // private_call.call_stack_item.public_inputs! +// CT::AggregationObject verify_proofs(Composer& composer, +// PrivateKernelInputsInit const& private_inputs, +// size_t const& num_private_call_public_inputs, +// size_t const& num_private_kernel_public_inputs) +// { +// CT::AggregationObject aggregation_object = Aggregator::aggregate( +// &composer, private_inputs.private_call.vk, private_inputs.private_call.proof, +// num_private_call_public_inputs); + +// Aggregator::aggregate(&composer, +// private_inputs.previous_kernel.vk, +// private_inputs.previous_kernel.proof, +// num_private_kernel_public_inputs, +// aggregation_object); + +// return aggregation_object; +// } + +void initialise_end_values(PrivateKernelInputsInit const& private_inputs, + KernelCircuitPublicInputs& public_inputs) +{ + // TODO(dbanks12): where do constants come from + // might need to add these constants to PrivateKernelInputsInit + // public_inputs.constants = private_inputs.previous_kernel.public_inputs.constants; + (void)private_inputs; + (void)public_inputs; +} + +void contract_logic(DummyComposer& composer, + PrivateKernelInputsInit const& private_inputs, + KernelCircuitPublicInputs& public_inputs) +{ + const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; + const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; + const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; + const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; + const auto& contract_deployment_data = + private_inputs.signed_tx_request.tx_request.tx_context.contract_deployment_data; + + // contract deployment + + // input storage contract address must be 0 if its a constructor call and non-zero otherwise + auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; + + auto private_call_vk_hash = stdlib::recursion::verification_key::compress_native( + private_inputs.private_call.vk, GeneratorIndex::VK); + + auto constructor_hash = compute_constructor_hash(private_inputs.signed_tx_request.tx_request.function_data, + private_call_public_inputs.args, + private_call_vk_hash); + + if (is_contract_deployment) { + composer.do_assert(contract_deployment_data.constructor_vk_hash == private_call_vk_hash, + "constructor_vk_hash doesn't match private_call_vk_hash", + CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONSTRUCTOR_VK_HASH); + } + + auto const new_contract_address = compute_contract_address(deployer_address, + contract_deployment_data.contract_address_salt, + contract_deployment_data.function_tree_root, + constructor_hash); + + if (is_contract_deployment) { + // must imply == derived address + composer.do_assert(storage_contract_address == new_contract_address, + "contract address supplied doesn't match derived address", + CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); + } else { + // non-contract deployments must specify contract address being interacted with + composer.do_assert(storage_contract_address != 0, + "contract address can't be 0 for non-contract deployment related transactions", + CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); + } + + // compute contract address nullifier + auto const blake_input = new_contract_address.to_field().to_buffer(); + auto const new_contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); + + // push the contract address nullifier to nullifier vector + if (is_contract_deployment) { + array_push(public_inputs.end.new_nullifiers, new_contract_address_nullifier); + } + + // Add new contract data if its a contract deployment function + NewContractData const native_new_contract_data{ new_contract_address, + portal_contract_address, + contract_deployment_data.function_tree_root }; + + array_push, KERNEL_NEW_CONTRACTS_LENGTH>(public_inputs.end.new_contracts, + native_new_contract_data); + + /* We need to compute the root of the contract tree, starting from the function's VK: + * - Compute the vk_hash (done above) + * - Compute the function_leaf: hash(function_selector, is_private, vk_hash, acir_hash) + * - Hash the function_leaf with the function_leaf's sibling_path to get the function_tree_root + * - Compute the contract_leaf: hash(contract_address, portal_contract_address, function_tree_root) + * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root + */ + + // ensure that historic/purported contract tree root matches the one in previous kernel + auto const& purported_contract_tree_root = + private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; + auto const& previous_kernel_contract_tree_root = + private_inputs.previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots + .contract_tree_root; + composer.do_assert( + purported_contract_tree_root == previous_kernel_contract_tree_root, + "purported_contract_tree_root doesn't match previous_kernel_contract_tree_root", + CircuitErrorCode::PRIVATE_KERNEL__PURPORTED_CONTRACT_TREE_ROOT_AND_PREVIOUS_KERNEL_CONTRACT_TREE_ROOT_MISMATCH); + + // The logic below ensures that the contract exists in the contracts tree + if (!is_contract_deployment) { + auto const& computed_function_tree_root = function_tree_root_from_siblings( + private_inputs.private_call.call_stack_item.function_data.function_selector, + true, // is_private + private_call_vk_hash, + private_inputs.private_call.acir_hash, + private_inputs.private_call.function_leaf_membership_witness.leaf_index, + private_inputs.private_call.function_leaf_membership_witness.sibling_path); + + auto const& computed_contract_tree_root = contract_tree_root_from_siblings( + computed_function_tree_root, + storage_contract_address, + portal_contract_address, + private_inputs.private_call.contract_leaf_membership_witness.leaf_index, + private_inputs.private_call.contract_leaf_membership_witness.sibling_path); + + composer.do_assert( + computed_contract_tree_root == purported_contract_tree_root, + "computed_contract_tree_root doesn't match purported_contract_tree_root", + CircuitErrorCode::PRIVATE_KERNEL__COMPUTED_CONTRACT_TREE_ROOT_AND_PURPORTED_CONTRACT_TREE_ROOT_MISMATCH); + } +} + +void update_end_values(DummyComposer& composer, + PrivateKernelInputsInit const& private_inputs, + KernelCircuitPublicInputs& public_inputs) +{ + const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; + + const auto& new_commitments = private_call_public_inputs.new_commitments; + const auto& new_nullifiers = private_call_public_inputs.new_nullifiers; + + const auto& is_static_call = private_call_public_inputs.call_context.is_static_call; + + if (is_static_call) { + // No state changes are allowed for static calls: + composer.do_assert(is_array_empty(new_commitments) == true, + "new_commitments must be empty for static calls", + CircuitErrorCode::PRIVATE_KERNEL__NEW_COMMITMENTS_NOT_EMPTY_FOR_STATIC_CALL); + composer.do_assert(is_array_empty(new_nullifiers) == true, + "new_nullifiers must be empty for static calls", + CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_FOR_STATIC_CALL); + } + + const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; + + { + // Nonce nullifier + // DANGER: This is terrible. This should not be part of the protocol. This is an intentional bodge to reach a + // milestone. This must not be the way we derive nonce nullifiers in production. It can be front-run by other + // users. It is not domain separated. Naughty. + array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); + } + + { // commitments & nullifiers + std::array siloed_new_commitments; + for (size_t i = 0; i < new_commitments.size(); ++i) { + siloed_new_commitments[i] = new_commitments[i] == 0 ? 0 + : add_contract_address_to_commitment( + storage_contract_address, new_commitments[i]); + } + + std::array siloed_new_nullifiers; + for (size_t i = 0; i < new_nullifiers.size(); ++i) { + siloed_new_nullifiers[i] = new_nullifiers[i] == 0 ? 0 + : add_contract_address_to_nullifier( + storage_contract_address, new_nullifiers[i]); + } + + push_array_to_array(siloed_new_commitments, public_inputs.end.new_commitments); + push_array_to_array(siloed_new_nullifiers, public_inputs.end.new_nullifiers); + } + + { // call stacks + const auto& this_private_call_stack = private_call_public_inputs.private_call_stack; + push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); + } + + // const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; + + // { + // const auto& new_l2_to_l1_msgs = private_call_public_inputs.new_l2_to_l1_msgs; + // std::array l1_call_stack; + + // for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) { + // l1_call_stack[i] = CT::fr::conditional_assign( + // new_l2_to_l1_msgs[i] == 0, + // 0, + // CT::compress({ portal_contract_address, new_l2_to_l1_msgs[i] }, GeneratorIndex::L2_TO_L1_MSG)); + // } + // } +} + +void validate_this_private_call_against_tx_request(DummyComposer& composer, + PrivateKernelInputsInit const& private_inputs, + KernelCircuitPublicInputs& public_inputs) +{ + // TODO: this logic might need to change to accommodate the weird edge 3 initial txs (the 'main' tx, the 'fee' tx, + // and the 'gas rebate' tx). + const auto popped_private_call_hash = array_pop(public_inputs.end.private_call_stack); + const auto calculated_this_private_call_hash = private_inputs.private_call.call_stack_item.hash(); + // Confirm that the SignedTxRequest (user's intent) matches the private call being executed + const auto& tx_request = private_inputs.signed_tx_request.tx_request; + const auto& call_stack_item = private_inputs.private_call.call_stack_item; + + const auto tx_request_args_hash = NT::compress(tx_request.args, FUNCTION_ARGS); + const auto call_args_hash = NT::compress(call_stack_item.public_inputs.args, FUNCTION_ARGS); + + composer.do_assert( + tx_request.to == call_stack_item.contract_address, + "user's intent does not match initial private call (tx_request.to must match call_stack_item.contract_address)", + CircuitErrorCode::PRIVATE_KERNEL__USER_INTENT_MISMATCH_BETWEEN_TX_REQUEST_AND_CALL_STACK_ITEM); + + composer.do_assert(tx_request.function_data.hash() == call_stack_item.function_data.hash(), + "user's intent does not match initial private call (tx_request.function_data must match " + "call_stack_item.function_data)", + CircuitErrorCode::PRIVATE_KERNEL__USER_INTENT_MISMATCH_BETWEEN_TX_REQUEST_AND_CALL_STACK_ITEM); + + composer.do_assert(tx_request_args_hash == call_args_hash, + "user's intent does not match initial private call (tx_request.args must match " + "call_stack_item.public_inputs.args)", + CircuitErrorCode::PRIVATE_KERNEL__USER_INTENT_MISMATCH_BETWEEN_TX_REQUEST_AND_CALL_STACK_ITEM); +}; + +void validate_this_private_call_stack(DummyComposer& composer, PrivateKernelInputsInit const& private_inputs) +{ + const auto& stack = private_inputs.private_call.call_stack_item.public_inputs.private_call_stack; + const auto& preimages = private_inputs.private_call.private_call_stack_preimages; + for (size_t i = 0; i < stack.size(); ++i) { + const auto& hash = stack[i]; + const auto& preimage = preimages[i]; + + // Note: this assumes it's computationally infeasible to have `0` as a valid call_stack_item_hash. + // Assumes `hash == 0` means "this stack item is empty". + const auto calculated_hash = hash == 0 ? 0 : preimage.hash(); + composer.do_assert(hash != calculated_hash, + format("private_call_stack[", i, "] = ", hash, "; does not reconcile"), + CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_ITEM_HASH_MISMATCH); + } +}; + +void validate_inputs(DummyComposer& composer, PrivateKernelInputsInit const& private_inputs) +{ + const auto& this_call_stack_item = private_inputs.private_call.call_stack_item; + + composer.do_assert(this_call_stack_item.function_data.is_private == true, + "Cannot execute a non-private function with the private kernel circuit", + CircuitErrorCode::PRIVATE_KERNEL__NON_PRIVATE_FUNCTION_EXECUTED_WITH_PRIVATE_KERNEL); + + // TODO: change to allow 3 initial calls on the private call stack, so a fee can be paid and a gas + // rebate can be paid. + + /* If we are going to have 3 initial calls on the private call stack, + * then do we still need the `private_call_stack` + * despite no longer needing a full `previous_kernel` + */ + + composer.do_assert(this_call_stack_item.public_inputs.call_context.is_delegate_call == false, + "Users cannot make a delegatecall", + CircuitErrorCode::PRIVATE_KERNEL__UNSUPPORTED_OP); + composer.do_assert(this_call_stack_item.public_inputs.call_context.is_static_call == false, + "Users cannot make a static call", + CircuitErrorCode::PRIVATE_KERNEL__UNSUPPORTED_OP); + + // The below also prevents delegatecall/staticcall in the base case + composer.do_assert(this_call_stack_item.public_inputs.call_context.storage_contract_address == + this_call_stack_item.contract_address, + "Storage contract address must be that of the called contract", + CircuitErrorCode::PRIVATE_KERNEL__CONTRACT_ADDRESS_MISMATCH); + + // TODO: Assert that the previous kernel data is empty. (Or rather, the verify_proof() function needs a valid + // dummy proof and vk to complete execution, so actually what we want is for that mockvk to be + // hard-coded into the circuit and assert that that is the one which has been used in the base case). +} + +// NOTE: THIS IS A VERY UNFINISHED WORK IN PROGRESS. +// TODO: decide what to return. +// TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely +// ensure we're constraining everything. +KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, + PrivateKernelInputsInit const& private_inputs) +{ + // We'll be pushing data to this during execution of this circuit. + KernelCircuitPublicInputs public_inputs{}; + + // Do this before any functions can modify the inputs. + initialise_end_values(private_inputs, public_inputs); + + validate_inputs(composer, private_inputs); + + validate_this_private_call_against_tx_request(composer, private_inputs, public_inputs); + + common_validate_call_stack>(composer, private_inputs); + + common_update_end_values>(composer, private_inputs, public_inputs); + + contract_logic(composer, private_inputs, public_inputs); + + // We'll skip any verification in this native implementation, because for a Local Developer Testnet, there won't + // _be_ a valid proof to verify!!! auto aggregation_object = verify_proofs(composer, + // private_inputs, + // _private_inputs.private_call.vk->num_public_inputs, + // _private_inputs.previous_kernel.vk->num_public_inputs); + + // TODO: kernel vk membership check! + + // Note: given that we skipped the verify_proof function, the aggregation object we get at the end will just be the + // same as we had at the start. public_inputs.end.aggregation_object = aggregation_object; + public_inputs.end.aggregation_object = private_inputs.previous_kernel.public_inputs.end.aggregation_object; + + return public_inputs; +}; + +} // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp new file mode 100644 index 000000000000..6becea662549 --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include "init.hpp" + +#include +#include +#include + +namespace aztec3::circuits::kernel::private_kernel { + +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; +// using abis::private_kernel::PublicInputs; +using DummyComposer = aztec3::utils::DummyComposer; + +// TODO: decide what to return. +KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyComposer& composer, + PrivateKernelInputsInit const& _private_inputs); + +} // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp index b71c2c1de8c1..b05d7f4e88fb 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp @@ -12,7 +12,7 @@ namespace aztec3::circuits::kernel::private_kernel { using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::NewContractData; -using aztec3::circuits::abis::private_kernel::PrivateInputs; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using plonk::stdlib::array_length; using plonk::stdlib::array_pop; @@ -28,7 +28,7 @@ using aztec3::circuits::compute_contract_address; // TODO: NEED TO RECONCILE THE `proof`'s public inputs (which are uint8's) with the // private_call.call_stack_item.public_inputs! CT::AggregationObject verify_proofs(Composer& composer, - PrivateInputs const& private_inputs, + PrivateKernelInputsInner const& private_inputs, size_t const& num_private_call_public_inputs, size_t const& num_private_kernel_public_inputs) { @@ -55,7 +55,8 @@ CT::AggregationObject verify_proofs(Composer& composer, * as well as signed TX request and the private call information * @param public_inputs should be empty here since it is being initialized in this call */ -void initialise_end_values(PrivateInputs const& private_inputs, KernelCircuitPublicInputs& public_inputs) +void initialise_end_values(PrivateKernelInputsInner const& private_inputs, + KernelCircuitPublicInputs& public_inputs) { // TODO: Ensure public inputs is empty here public_inputs.constants = private_inputs.previous_kernel.public_inputs.constants; @@ -89,7 +90,7 @@ void initialise_end_values(PrivateInputs const& private_inputs, KernelCircui * and update its running callstack with all items in the current private-circuit/function's * callstack. */ -void update_end_values(PrivateInputs const& private_inputs, KernelCircuitPublicInputs& public_inputs) +void update_end_values(PrivateKernelInputsInner const& private_inputs, KernelCircuitPublicInputs& public_inputs) { const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; @@ -202,7 +203,7 @@ void update_end_values(PrivateInputs const& private_inputs, KernelCircuitPub * @brief Ensure that the function/call-stack-item currently being processed by the kernel * matches the one that the previous kernel iteration said should come next. */ -void validate_this_private_call_hash(PrivateInputs const& private_inputs) +void validate_this_private_call_hash(PrivateKernelInputsInner const& private_inputs) { const auto& start = private_inputs.previous_kernel.public_inputs.end; // TODO: this logic might need to change to accommodate the weird edge 3 initial txs (the 'main' tx, the 'fee' tx, @@ -221,7 +222,7 @@ void validate_this_private_call_hash(PrivateInputs const& private_inputs) * So here we just ensure that the callstack preimages in the kernel's private inputs * matches the function's CallStackItem hashes. */ -void validate_this_private_call_stack(PrivateInputs const& private_inputs) +void validate_this_private_call_stack(PrivateKernelInputsInner const& private_inputs) { const auto& stack = private_inputs.private_call.call_stack_item.public_inputs.private_call_stack; const auto& preimages = private_inputs.private_call.private_call_stack_preimages; @@ -237,7 +238,7 @@ void validate_this_private_call_stack(PrivateInputs const& private_inputs) } }; -void validate_inputs(PrivateInputs const& private_inputs) +void validate_inputs(PrivateKernelInputsInner const& private_inputs) { // this callstack represents the function currently being processed const auto& this_call_stack_item = private_inputs.private_call.call_stack_item; @@ -320,9 +321,10 @@ void validate_inputs(PrivateInputs const& private_inputs) // TODO: decide what to return. // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. -KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, PrivateInputs const& _private_inputs) +KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, + PrivateKernelInputsInner const& _private_inputs) { - const PrivateInputs private_inputs = _private_inputs.to_circuit_type(composer); + const PrivateKernelInputsInner private_inputs = _private_inputs.to_circuit_type(composer); // We'll be pushing data to this during execution of this circuit. KernelCircuitPublicInputs public_inputs = KernelCircuitPublicInputs{}.to_circuit_type(composer); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp index 858bf06e6907..c301fe37b29a 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp @@ -8,9 +8,9 @@ namespace aztec3::circuits::kernel::private_kernel { using aztec3::circuits::abis::KernelCircuitPublicInputs; -using aztec3::circuits::abis::private_kernel::PrivateInputs; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; -KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, PrivateInputs const& _private_inputs); -KernelCircuitPublicInputs private_kernel_native(PrivateInputs const& private_inputs); +KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, + PrivateKernelInputsInner const& _private_inputs); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp index 2cb3471e88f3..4d6bccf8b44e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/common.hpp @@ -158,7 +158,6 @@ template void common_validate_kernel_execution(DummyComposer& composer, KernelInput const& public_kernel_inputs) { common_validate_call_context(composer, public_kernel_inputs); - common_validate_call_stack(composer, public_kernel_inputs); }; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit_no_previous_kernel.cpp b/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit_no_previous_kernel.cpp index daaeeeeb0d65..bb5f3d86dce4 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit_no_previous_kernel.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/native_public_kernel_circuit_no_previous_kernel.cpp @@ -62,6 +62,10 @@ using DummyComposer = aztec3::utils::DummyComposer; KernelCircuitPublicInputs native_public_kernel_circuit_no_previous_kernel( DummyComposer& composer, PublicKernelInputsNoPreviousKernel const& public_kernel_inputs) { + // TODO(dbanks12): consider rename of public_kernel_inputs to just private_inputs? + // or consider other renaming options + // (confusing since they are private inputs to the public kernel) + // There is not circuit state carried over from previous iterations. // We are construcitng fresh state that will be added to during this circuit execution. KernelCircuitPublicInputs public_inputs{}; @@ -75,7 +79,7 @@ KernelCircuitPublicInputs native_public_kernel_circuit_no_previous_kernel( // validate the inputs unique to there being no previous kernel validate_inputs(composer, public_kernel_inputs); - // validate the kernel execution commonn to all invocation circumstances + // validate the kernel execution common to all invocation circumstances common_validate_kernel_execution(composer, public_kernel_inputs); // update the public end state of the circuit diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index 75aa3522d8e1..9ef664c79930 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -87,6 +87,7 @@ enum GeneratorIndex { PUBLIC_LEAF_INDEX, PUBLIC_DATA_LEAF, SIGNED_TX_REQUEST, + FUNCTION_ARGS, }; enum StorageSlotGeneratorIndex { diff --git a/circuits/cpp/src/aztec3/utils/circuit_errors.hpp b/circuits/cpp/src/aztec3/utils/circuit_errors.hpp index 0f33fad23ac9..8582561f4ca3 100644 --- a/circuits/cpp/src/aztec3/utils/circuit_errors.hpp +++ b/circuits/cpp/src/aztec3/utils/circuit_errors.hpp @@ -23,6 +23,7 @@ enum CircuitErrorCode : uint16_t { PRIVATE_KERNEL__CONSTRUCTOR_EXECUTED_IN_RECURSION = 2014, PRIVATE_KERNEL__PRIVATE_CALL_STACK_EMPTY = 2015, PRIVATE_KERNEL__KERNEL_PROOF_CONTAINS_RECURSIVE_PROOF = 2016, + PRIVATE_KERNEL__USER_INTENT_MISMATCH_BETWEEN_TX_REQUEST_AND_CALL_STACK_ITEM = 2017, // Public kernel related errors PUBLIC_KERNEL_CIRCUIT_FAILED = 3000, From ac8f8f08c382943b2799676730be612e369b5852 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 12 May 2023 12:21:57 +0000 Subject: [PATCH 02/36] wip - fix some compilation issues, remove unused imports, remove update_end_values leftover --- .../cpp/src/aztec3/circuits/abis/.test.cpp | 1 - .../cpp/src/aztec3/circuits/abis/c_bind.cpp | 2 +- .../private_kernel_inputs_init.hpp | 1 - .../aztec3/circuits/kernel/private/.test.cpp | 4 +- .../aztec3/circuits/kernel/private/common.hpp | 14 +-- .../aztec3/circuits/kernel/private/index.hpp | 1 + .../private/native_private_kernel_circuit.cpp | 4 +- .../private/native_private_kernel_circuit.hpp | 2 +- .../native_private_kernel_circuit_initial.cpp | 95 ++----------------- .../native_private_kernel_circuit_initial.hpp | 2 +- .../kernel/private/private_kernel_circuit.cpp | 2 +- .../kernel/private/private_kernel_circuit.hpp | 2 +- .../aztec3/circuits/kernel/public/.test.cpp | 1 - .../src/aztec3/circuits/rollup/base/.test.cpp | 2 - .../aztec3/circuits/rollup/base/c_bind.cpp | 1 - .../src/aztec3/circuits/rollup/root/.test.cpp | 1 - .../aztec3/circuits/rollup/root/c_bind.cpp | 1 - 17 files changed, 22 insertions(+), 114 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/abis/.test.cpp b/circuits/cpp/src/aztec3/circuits/abis/.test.cpp index 5a67848bd2be..f9de911c6ad5 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/.test.cpp @@ -1,6 +1,5 @@ #include "index.hpp" #include "previous_kernel_data.hpp" -#include "private_kernel/private_inputs.hpp" #include #include diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp index 59c2545e1238..986c4f55c033 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp @@ -8,7 +8,7 @@ #include "private_circuit_public_inputs.hpp" #include "tx_context.hpp" #include "tx_request.hpp" -#include "private_kernel/private_inputs.hpp" +#include "private_kernel/private_kernel_inputs_inner.hpp" #include "public_kernel/public_kernel_inputs.hpp" #include "public_kernel/public_kernel_inputs_no_previous_kernel.hpp" #include "rollup/base/base_or_merge_rollup_public_inputs.hpp" diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp index 69985edefe20..13d9990b31b3 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp @@ -4,7 +4,6 @@ #include "../signed_tx_request.hpp" #include "aztec3/utils/types/circuit_types.hpp" -#include "aztec3/utils/types/convert.hpp" #include "aztec3/utils/types/native_types.hpp" #include diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 15ea7ee02620..eaef1182caea 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -14,7 +14,7 @@ #include #include #include -#include +#include #include #include #include @@ -364,7 +364,7 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs(bool const is_con //*************************************************************************** // Now we can construct the full private inputs to the kernel circuit //*************************************************************************** - PrivateKernelInputsInner kernel_private_inputs = PrivateInputs{ + PrivateKernelInputsInner kernel_private_inputs = PrivateKernelInputsInner{ .signed_tx_request = signed_tx_request, .previous_kernel = mock_previous_kernel, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp index 1098ce385b80..938b53a030c9 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -15,21 +15,13 @@ using DummyComposer = aztec3::utils::DummyComposer; using aztec3::circuits::abis::ContractLeafPreimage; using aztec3::circuits::abis::KernelCircuitPublicInputs; -using aztec3::circuits::abis::NewContractData; -using aztec3::utils::array_length; -using aztec3::utils::array_pop; using aztec3::utils::array_push; using aztec3::utils::is_array_empty; using aztec3::utils::push_array_to_array; using DummyComposer = aztec3::utils::DummyComposer; using CircuitErrorCode = aztec3::utils::CircuitErrorCode; -using aztec3::circuits::compute_constructor_hash; -using aztec3::circuits::compute_contract_address; -using aztec3::circuits::contract_tree_root_from_siblings; -using aztec3::circuits::function_tree_root_from_siblings; - namespace aztec3::circuits::kernel::private_kernel { @@ -64,9 +56,9 @@ void common_validate_kernel_execution(DummyComposer& composer, KernelInput const common_validate_call_stack(composer, private_inputs); }; -template void update_end_values(DummyComposer& composer, - KernelPrivateInput const& private_inputs, - KernelCircuitPublicInputs& public_inputs) +template void common_update_end_values(DummyComposer& composer, + KernelPrivateInput const& private_inputs, + KernelCircuitPublicInputs& public_inputs) { const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp index 60f0e23967ef..2270dac947ea 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp @@ -1,3 +1,4 @@ #include "init.hpp" #include "native_private_kernel_circuit.hpp" +#include "native_private_kernel_circuit_initial.hpp" #include "private_kernel_circuit.hpp" \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 99d467940d9f..afaeed24c47b 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -1,10 +1,10 @@ +#include "common.hpp" #include "init.hpp" -#include "aztec3/circuits/abis/function_leaf_preimage.hpp" #include "aztec3/constants.hpp" #include #include -#include +#include #include #include #include diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp index 31631175078d..0206a1a6d5f9 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp @@ -3,7 +3,7 @@ #include "init.hpp" #include -#include +#include #include namespace aztec3::circuits::kernel::private_kernel { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index a32368d25fdb..52bc0ee57631 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -1,8 +1,11 @@ #include "common.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" +using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; +using aztec3::utils::array_pop; namespace aztec3::circuits::kernel::private_kernel { @@ -109,17 +112,6 @@ void contract_logic(DummyComposer& composer, * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root */ - // ensure that historic/purported contract tree root matches the one in previous kernel - auto const& purported_contract_tree_root = - private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; - auto const& previous_kernel_contract_tree_root = - private_inputs.previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots - .contract_tree_root; - composer.do_assert( - purported_contract_tree_root == previous_kernel_contract_tree_root, - "purported_contract_tree_root doesn't match previous_kernel_contract_tree_root", - CircuitErrorCode::PRIVATE_KERNEL__PURPORTED_CONTRACT_TREE_ROOT_AND_PREVIOUS_KERNEL_CONTRACT_TREE_ROOT_MISMATCH); - // The logic below ensures that the contract exists in the contracts tree if (!is_contract_deployment) { auto const& computed_function_tree_root = function_tree_root_from_siblings( @@ -137,6 +129,9 @@ void contract_logic(DummyComposer& composer, private_inputs.private_call.contract_leaf_membership_witness.leaf_index, private_inputs.private_call.contract_leaf_membership_witness.sibling_path); + auto const& purported_contract_tree_root = + private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; + composer.do_assert( computed_contract_tree_root == purported_contract_tree_root, "computed_contract_tree_root doesn't match purported_contract_tree_root", @@ -144,84 +139,12 @@ void contract_logic(DummyComposer& composer, } } -void update_end_values(DummyComposer& composer, - PrivateKernelInputsInit const& private_inputs, - KernelCircuitPublicInputs& public_inputs) -{ - const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; - - const auto& new_commitments = private_call_public_inputs.new_commitments; - const auto& new_nullifiers = private_call_public_inputs.new_nullifiers; - - const auto& is_static_call = private_call_public_inputs.call_context.is_static_call; - - if (is_static_call) { - // No state changes are allowed for static calls: - composer.do_assert(is_array_empty(new_commitments) == true, - "new_commitments must be empty for static calls", - CircuitErrorCode::PRIVATE_KERNEL__NEW_COMMITMENTS_NOT_EMPTY_FOR_STATIC_CALL); - composer.do_assert(is_array_empty(new_nullifiers) == true, - "new_nullifiers must be empty for static calls", - CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_FOR_STATIC_CALL); - } - - const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - - { - // Nonce nullifier - // DANGER: This is terrible. This should not be part of the protocol. This is an intentional bodge to reach a - // milestone. This must not be the way we derive nonce nullifiers in production. It can be front-run by other - // users. It is not domain separated. Naughty. - array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); - } - - { // commitments & nullifiers - std::array siloed_new_commitments; - for (size_t i = 0; i < new_commitments.size(); ++i) { - siloed_new_commitments[i] = new_commitments[i] == 0 ? 0 - : add_contract_address_to_commitment( - storage_contract_address, new_commitments[i]); - } - - std::array siloed_new_nullifiers; - for (size_t i = 0; i < new_nullifiers.size(); ++i) { - siloed_new_nullifiers[i] = new_nullifiers[i] == 0 ? 0 - : add_contract_address_to_nullifier( - storage_contract_address, new_nullifiers[i]); - } - - push_array_to_array(siloed_new_commitments, public_inputs.end.new_commitments); - push_array_to_array(siloed_new_nullifiers, public_inputs.end.new_nullifiers); - } - - { // call stacks - const auto& this_private_call_stack = private_call_public_inputs.private_call_stack; - push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); - } - - // const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; - - // { - // const auto& new_l2_to_l1_msgs = private_call_public_inputs.new_l2_to_l1_msgs; - // std::array l1_call_stack; - - // for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) { - // l1_call_stack[i] = CT::fr::conditional_assign( - // new_l2_to_l1_msgs[i] == 0, - // 0, - // CT::compress({ portal_contract_address, new_l2_to_l1_msgs[i] }, GeneratorIndex::L2_TO_L1_MSG)); - // } - // } -} - void validate_this_private_call_against_tx_request(DummyComposer& composer, - PrivateKernelInputsInit const& private_inputs, - KernelCircuitPublicInputs& public_inputs) + PrivateKernelInputsInit const& private_inputs) { // TODO: this logic might need to change to accommodate the weird edge 3 initial txs (the 'main' tx, the 'fee' tx, // and the 'gas rebate' tx). - const auto popped_private_call_hash = array_pop(public_inputs.end.private_call_stack); - const auto calculated_this_private_call_hash = private_inputs.private_call.call_stack_item.hash(); + // Confirm that the SignedTxRequest (user's intent) matches the private call being executed const auto& tx_request = private_inputs.signed_tx_request.tx_request; const auto& call_stack_item = private_inputs.private_call.call_stack_item; @@ -311,7 +234,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo validate_inputs(composer, private_inputs); - validate_this_private_call_against_tx_request(composer, private_inputs, public_inputs); + validate_this_private_call_against_tx_request(composer, private_inputs); common_validate_call_stack>(composer, private_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp index 6becea662549..065b85cd2b5a 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp @@ -3,7 +3,7 @@ #include "init.hpp" #include -#include +#include #include namespace aztec3::circuits::kernel::private_kernel { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp index b05d7f4e88fb..5ea30c6a131e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp @@ -3,7 +3,7 @@ #include "aztec3/constants.hpp" #include #include -#include +#include #include #include diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp index c301fe37b29a..c85e09b732cb 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp @@ -3,7 +3,7 @@ #include "init.hpp" #include -#include +#include namespace aztec3::circuits::kernel::private_kernel { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp index 153cbd29baf5..144ad836b1b9 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/public/.test.cpp @@ -14,7 +14,6 @@ #include #include #include -#include #include #include #include diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp index 9cb9ba707913..d3b023a5c0b2 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/.test.cpp @@ -7,7 +7,6 @@ #include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/abis/previous_kernel_data.hpp" #include "aztec3/circuits/abis/public_data_read.hpp" -#include "aztec3/circuits/abis/rollup/nullifier_leaf_preimage.hpp" #include "aztec3/circuits/kernel/private/utils.hpp" #include "aztec3/circuits/rollup/components/components.hpp" #include "aztec3/circuits/rollup/test_utils/utils.hpp" @@ -23,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp index a4335c1920ca..b9b2899adf35 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/base/c_bind.cpp @@ -8,7 +8,6 @@ #include "aztec3/circuits/abis/signed_tx_request.hpp" #include "aztec3/utils/dummy_composer.hpp" #include -#include #include #include #include diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp index 588e365251dd..e5f71dab3378 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/.test.cpp @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp index f1853b6fa61b..42bd400e364b 100644 --- a/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/rollup/root/c_bind.cpp @@ -6,7 +6,6 @@ #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include "aztec3/circuits/abis/signed_tx_request.hpp" #include -#include #include #include #include From ea7816d538f8a0f45ddd027c77466106878b8400 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 12 May 2023 16:22:29 +0000 Subject: [PATCH 03/36] wip - some minor changes and comments after pairing with David --- circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp | 4 ++++ .../kernel/private/native_private_kernel_circuit.cpp | 7 ++++--- .../private/native_private_kernel_circuit_initial.cpp | 2 ++ .../circuits/kernel/private/private_kernel_circuit.cpp | 5 ++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index 6a069e83e0f3..8d62af74e2e6 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -68,6 +68,10 @@ WASM_EXPORT size_t private_kernel__dummy_previous_kernel(uint8_t const** previou return previous_kernel_vec.size(); } + +// TODO(jeanmon) We will need two versions of this one to expose to ts. +// First let us try to get it compiled with one function (the inner one). + // TODO(dbanks12): comment about how public_inputs is a confusing name // returns size of public inputs WASM_EXPORT uint8_t* private_kernel__sim(uint8_t const* signed_tx_request_buf, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index afaeed24c47b..cb57fbf93641 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -81,18 +81,19 @@ void contract_logic(DummyComposer& composer, const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; - const auto& contract_deployment_data = - private_inputs.signed_tx_request.tx_request.tx_context.contract_deployment_data; + const auto& contract_deployment_data = private_call_public_inputs.contract_deployment_data; // contract deployment + // In general and long term, we probably need to support contract deployment in the inner kernel calls. + // input storage contract address must be 0 if its a constructor call and non-zero otherwise auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; auto private_call_vk_hash = stdlib::recursion::verification_key::compress_native( private_inputs.private_call.vk, GeneratorIndex::VK); - auto constructor_hash = compute_constructor_hash(private_inputs.signed_tx_request.tx_request.function_data, + auto constructor_hash = compute_constructor_hash(private_inputs.private_call.call_stack_item.function_data, private_call_public_inputs.args, private_call_vk_hash); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index 52bc0ee57631..7d77bfe44c42 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -252,6 +252,8 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo // Note: given that we skipped the verify_proof function, the aggregation object we get at the end will just be the // same as we had at the start. public_inputs.end.aggregation_object = aggregation_object; + + // TODO (jeanmon): Let us clarify with Suyash on how to init the aggregation object public_inputs.end.aggregation_object = private_inputs.previous_kernel.public_inputs.end.aggregation_object; return public_inputs; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp index 5ea30c6a131e..ada17bd091d8 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp @@ -108,15 +108,14 @@ void update_end_values(PrivateKernelInputsInner const& private_inputs, Kerne const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; - const auto& contract_deployment_data = - private_inputs.signed_tx_request.tx_request.tx_context.contract_deployment_data; + const auto& contract_deployment_data = private_call_public_inputs.contract_deployment_data; { // contract deployment // input storage contract address must be 0 if its a constructor call and non-zero otherwise auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; auto private_call_vk_hash = private_inputs.private_call.vk->compress(GeneratorIndex::VK); - auto constructor_hash = compute_constructor_hash(private_inputs.signed_tx_request.tx_request.function_data, + auto constructor_hash = compute_constructor_hash(private_inputs.private_call.call_stack_item.function_data, private_call_public_inputs.args, private_call_vk_hash); From 080d81425556c84d624e780972625114852f7eb6 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 16 May 2023 06:37:52 +0000 Subject: [PATCH 04/36] wip: additional compilation fixes --- .../src/aztec3/circuits/kernel/private/.test.cpp | 16 ++++++++++++---- .../aztec3/circuits/kernel/private/c_bind.cpp | 3 +-- .../aztec3/circuits/kernel/private/common.hpp | 9 +-------- .../private/native_private_kernel_circuit.cpp | 2 -- .../native_private_kernel_circuit_initial.cpp | 16 +++++++++++----- 5 files changed, 25 insertions(+), 21 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index eaef1182caea..96971587690d 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -160,6 +160,14 @@ std::shared_ptr gen_func_vk(bool is_constructor, private_function const& return dummy_composer.compute_verification_key(); } +// JEAMON: Most of the current tests should call this variant (init case) +PrivateKernelInputsInner do_private_call_get_kernel_inputs_init(bool const is_constructor, + private_function const& func, + std::vector const& args_vec, + bool real_kernel_circuit = false) +{} + + /** * @brief Perform a private circuit call and generate the inputs to private kernel * @@ -168,10 +176,10 @@ std::shared_ptr gen_func_vk(bool is_constructor, private_function const& * @param args_vec the private call's args * @return PrivateInputs - the inputs to the private call circuit */ -PrivateKernelInputsInner do_private_call_get_kernel_inputs(bool const is_constructor, - private_function const& func, - std::vector const& args_vec, - bool real_kernel_circuit = false) +PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const is_constructor, + private_function const& func, + std::vector const& args_vec, + bool real_kernel_circuit = false) { //*************************************************************************** // Initialize some inputs to private call and kernel circuits diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index 8d62af74e2e6..02e12b780230 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -110,7 +110,6 @@ WASM_EXPORT uint8_t* private_kernel__sim(uint8_t const* signed_tx_request_buf, } PrivateKernelInputsInner const private_inputs = PrivateKernelInputsInner{ - .signed_tx_request = signed_tx_request, .previous_kernel = previous_kernel, .private_call = private_call_data, }; @@ -129,6 +128,7 @@ WASM_EXPORT uint8_t* private_kernel__sim(uint8_t const* signed_tx_request_buf, return composer.alloc_and_serialize_first_failure(); } +// jeanmon: only support inner variant // returns size of proof data WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, uint8_t const* previous_kernel_buf, @@ -166,7 +166,6 @@ WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, read(previous_kernel_buf, previous_kernel); } PrivateKernelInputsInner const private_inputs = PrivateKernelInputsInner{ - .signed_tx_request = signed_tx_request, .previous_kernel = previous_kernel, .private_call = private_call_data, }; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp index 938b53a030c9..1062d73cf23b 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -79,14 +79,7 @@ template void common_update_end_values(DummyCompos const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - { - // Nonce nullifier - // DANGER: This is terrible. This should not be part of the protocol. This is an intentional bodge to reach a - // milestone. This must not be the way we derive nonce nullifiers in production. It can be front-run by other - // users. It is not domain separated. Naughty. - array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); - } - + // Enhance commitments and nullifiers with domain separation whereby domain is the contract. { // commitments & nullifiers std::array siloed_new_commitments; for (size_t i = 0; i < new_commitments.size(); ++i) { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index cb57fbf93641..fb77c3b8cc51 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -226,8 +226,6 @@ void validate_inputs(DummyComposer& composer, PrivateKernelInputsInner const // iterating 2^254 times isn't feasible. NT::fr const start_private_call_stack_length = array_length(start.private_call_stack); - NT::fr const start_public_call_stack_length = array_length(start.public_call_stack); - NT::fr const start_new_l2_to_l1_msgs_length = array_length(start.new_l2_to_l1_msgs); // is_recursive_case diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index 7d77bfe44c42..66625cc9c26b 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -2,6 +2,7 @@ #include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" +#include "aztec3/circuits/kernel/private/init.hpp" using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; @@ -238,6 +239,12 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo common_validate_call_stack>(composer, private_inputs); + // Nonce nullifier + // DANGER: This is terrible. This should not be part of the protocol. This is an intentional bodge to reach a + // milestone. This must not be the way we derive nonce nullifiers in production. It can be front-run by other + // users. It is not domain separated. Naughty. + array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); + common_update_end_values>(composer, private_inputs, public_inputs); contract_logic(composer, private_inputs, public_inputs); @@ -250,11 +257,10 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo // TODO: kernel vk membership check! - // Note: given that we skipped the verify_proof function, the aggregation object we get at the end will just be the - // same as we had at the start. public_inputs.end.aggregation_object = aggregation_object; - - // TODO (jeanmon): Let us clarify with Suyash on how to init the aggregation object - public_inputs.end.aggregation_object = private_inputs.previous_kernel.public_inputs.end.aggregation_object; + // In the native version, as there is no verify_proofs call, we can initialize aggregation object with the default + // constructor. + NT::AggregationObject empty_aggregation_object{}; + public_inputs.end.aggregation_object = empty_aggregation_object; return public_inputs; }; From 952095e65977757c65f6cff944633775b8f23b30 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 16 May 2023 12:25:07 +0000 Subject: [PATCH 05/36] Refactor helper functions in private kernel tests --- .../aztec3/circuits/kernel/private/.test.cpp | 181 ++++++++++++------ 1 file changed, 123 insertions(+), 58 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index c0b9079b08da..990d90229a72 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -2,6 +2,7 @@ #include "index.hpp" #include "init.hpp" +#include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include "aztec3/circuits/kernel/private/utils.hpp" #include "aztec3/constants.hpp" #include @@ -14,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -160,26 +162,11 @@ std::shared_ptr gen_func_vk(bool is_constructor, private_function const& return dummy_composer.compute_verification_key(); } -// JEAMON: Most of the current tests should call this variant (init case) -PrivateKernelInputsInner do_private_call_get_kernel_inputs_init(bool const is_constructor, - private_function const& func, - std::vector const& args_vec, - bool real_kernel_circuit = false) -{} - - -/** - * @brief Perform a private circuit call and generate the inputs to private kernel - * - * @param is_constructor whether this private circuit call is a constructor - * @param func the private circuit call being validated by this kernel iteration - * @param args_vec the private call's args - * @return PrivateInputs - the inputs to the private call circuit - */ -PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const is_constructor, - private_function const& func, - std::vector const& args_vec, - bool real_kernel_circuit = false) +std::pair, ContractDeploymentData> create_private_call_deploy_data( + bool const is_constructor, + private_function const& func, + std::vector const& args_vec, + NT::address const& msg_sender) { //*************************************************************************** // Initialize some inputs to private call and kernel circuits @@ -193,9 +180,6 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const const NT::fr acir_hash = 12341234; const NT::fr msg_sender_private_key = 123456789; - const NT::address msg_sender = - NT::fr(uint256_t(0x01071e9a23e0f7edULL, 0x5d77b35d1830fa3eULL, 0xc6ba3660bb1f0c0bULL, 0x2ef9f7f09867fd6eULL)); - const NT::address& tx_origin = msg_sender; FunctionData const function_data{ .function_selector = 1, // TODO: deduce this from the contract, somehow. @@ -308,22 +292,85 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const NT::Proof const private_circuit_proof = private_circuit_prover.construct_proof(); // info("\nproof: ", private_circuit_proof.proof_data); + + //*************************************************************************** + // We mock a kernel circuit proof for the base case of kernel recursion (because even the first iteration of the + // kernel circuit expects to verify some previous kernel circuit). + //*************************************************************************** + // TODO: we have a choice to make: + // Either the `end` state of the mock kernel's public inputs can be set equal to the public call we _want_ to + // verify in the first round of recursion, OR, we have some fiddly conditional logic in the circuit to ignore + // certain checks if we're handling the 'base case' of the recursion. + // I've chosen the former, for now. + const CallStackItem call_stack_item{ + .contract_address = contract_address, + .function_data = function_data, + .public_inputs = private_circuit_public_inputs, + }; + + //*************************************************************************** + // Now we can construct the full private inputs to the kernel circuit + //*************************************************************************** + + return std::pair, ContractDeploymentData>( + PrivateCallData{ + .call_stack_item = call_stack_item, + .private_call_stack_preimages = ctx.get_private_call_stack_items(), + + .proof = private_circuit_proof, + .vk = private_circuit_vk, + + .function_leaf_membership_witness = { + .leaf_index = function_leaf_index, + .sibling_path = get_empty_function_siblings(), + }, + + .contract_leaf_membership_witness = { + .leaf_index = contract_leaf_index, + .sibling_path = get_empty_contract_siblings(), + }, + + .portal_contract_address = portal_contract_address, + + .acir_hash = acir_hash + }, + contract_deployment_data); +} + +// JEAMON: Most of the current tests should call this variant (init case) +PrivateKernelInputsInit do_private_call_get_kernel_inputs_init(bool const is_constructor, + private_function const& func, + std::vector const& args_vec) +{ + //*************************************************************************** + // Initialize some inputs to private call and kernel circuits + //*************************************************************************** + // TODO randomize inputs + + const NT::address msg_sender = + NT::fr(uint256_t(0x01071e9a23e0f7edULL, 0x5d77b35d1830fa3eULL, 0xc6ba3660bb1f0c0bULL, 0x2ef9f7f09867fd6eULL)); + const NT::address& tx_origin = msg_sender; + + auto const& private_call_deploy = create_private_call_deploy_data(is_constructor, func, args_vec, msg_sender); + + auto const& private_call_data = private_call_deploy.first; + //*************************************************************************** // We can create a TxRequest from some of the above data. Users must sign a TxRequest in order to give permission // for a tx to take place - creating a SignedTxRequest. //*************************************************************************** auto const tx_request = TxRequest{ .from = tx_origin, - .to = contract_address, - .function_data = function_data, - .args = private_circuit_public_inputs.args, + .to = private_call_data.call_stack_item.contract_address, + .function_data = private_call_data.call_stack_item.function_data, + .args = private_call_data.call_stack_item.public_inputs.args, .nonce = 0, .tx_context = TxContext{ .is_fee_payment_tx = false, .is_rebate_payment_tx = false, .is_contract_deployment_tx = is_constructor, - .contract_deployment_data = contract_deployment_data, + .contract_deployment_data = private_call_deploy.second, }, .chain_id = 1, }; @@ -334,6 +381,50 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const //.signature = TODO: need a method for signing a TxRequest. }; + //*************************************************************************** + // Now we can construct the full private inputs to the kernel circuit + //*************************************************************************** + PrivateKernelInputsInit kernel_private_inputs = PrivateKernelInputsInit{ + .signed_tx_request = signed_tx_request, + + .private_call = private_call_data, + }; + + return kernel_private_inputs; +} + + +/** + * @brief Perform a private circuit call and generate the inputs to private kernel + * + * @param is_constructor whether this private circuit call is a constructor + * @param func the private circuit call being validated by this kernel iteration + * @param args_vec the private call's args + * @return PrivateInputs - the inputs to the private call circuit + */ +PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const is_constructor, + private_function const& func, + std::vector const& args_vec, + bool real_kernel_circuit = false) +{ + //*************************************************************************** + // Initialize some inputs to private call and kernel circuits + //*************************************************************************** + // TODO randomize inputs + + const NT::address msg_sender = + NT::fr(uint256_t(0x01071e9a23e0f7edULL, 0x5d77b35d1830fa3eULL, 0xc6ba3660bb1f0c0bULL, 0x2ef9f7f09867fd6eULL)); + + auto const& private_call_deploy = create_private_call_deploy_data(is_constructor, func, args_vec, msg_sender); + + auto const& private_call_data = private_call_deploy.first; + const TxContext tx_context = TxContext{ + .is_fee_payment_tx = false, + .is_rebate_payment_tx = false, + .is_contract_deployment_tx = is_constructor, + .contract_deployment_data = private_call_deploy.second, + }; + //*************************************************************************** // We mock a kernel circuit proof for the base case of kernel recursion (because even the first iteration of the // kernel circuit expects to verify some previous kernel circuit). @@ -343,15 +434,11 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const // verify in the first round of recursion, OR, we have some fiddly conditional logic in the circuit to ignore // certain checks if we're handling the 'base case' of the recursion. // I've chosen the former, for now. - const CallStackItem call_stack_item{ - .contract_address = tx_request.to, - .function_data = tx_request.function_data, - .public_inputs = private_circuit_public_inputs, - }; std::array initial_kernel_private_call_stack{}; - initial_kernel_private_call_stack[0] = call_stack_item.hash(); + initial_kernel_private_call_stack[0] = private_call_data.call_stack_item.hash(); + auto const& private_circuit_public_inputs = private_call_data.call_stack_item.public_inputs; // Get dummy previous kernel auto mock_previous_kernel = utils::dummy_previous_kernel(real_kernel_circuit); // Fill in some important fields in public inputs @@ -365,7 +452,7 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const .contract_tree_root = private_circuit_public_inputs.historic_contract_tree_root, }, }, - .tx_context = tx_request.tx_context, + .tx_context = tx_context, }; mock_previous_kernel.public_inputs.is_private = true; @@ -373,31 +460,9 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const // Now we can construct the full private inputs to the kernel circuit //*************************************************************************** PrivateKernelInputsInner kernel_private_inputs = PrivateKernelInputsInner{ - .signed_tx_request = signed_tx_request, - .previous_kernel = mock_previous_kernel, - .private_call = - PrivateCallData{ - .call_stack_item = call_stack_item, - .private_call_stack_preimages = ctx.get_private_call_stack_items(), - - .proof = private_circuit_proof, - .vk = private_circuit_vk, - - .function_leaf_membership_witness = { - .leaf_index = function_leaf_index, - .sibling_path = get_empty_function_siblings(), - }, - .contract_leaf_membership_witness = { - .leaf_index = contract_leaf_index, - .sibling_path = get_empty_contract_siblings(), - }, - - .portal_contract_address = portal_contract_address, - - .acir_hash = acir_hash, - }, + .private_call = private_call_data, }; return kernel_private_inputs; @@ -411,7 +476,7 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const * @param private_inputs to be used in manual computation * @param public_inputs that contain the expected new contract address */ -void validate_deployed_contract_address(PrivateKernelInputsInner const& private_inputs, +void validate_deployed_contract_address(PrivateKernelInputsInit const& private_inputs, KernelCircuitPublicInputs const& public_inputs) { auto tx_request = private_inputs.signed_tx_request.tx_request; From 1a4cfb63bcff497467e7b2d7ac8259ffef108b7e Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 16 May 2023 14:10:16 +0000 Subject: [PATCH 06/36] wip - Fix linking issue and comment out some tests --- .../aztec3/circuits/kernel/private/.test.cpp | 334 +++++++++--------- .../native_private_kernel_circuit_initial.cpp | 4 +- .../native_private_kernel_circuit_initial.hpp | 8 +- 3 files changed, 172 insertions(+), 174 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 990d90229a72..d60af2100091 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -1,31 +1,30 @@ #include "c_bind.h" #include "index.hpp" -#include "init.hpp" +#include "aztec3/circuits/abis/call_context.hpp" +#include "aztec3/circuits/abis/call_stack_item.hpp" +#include "aztec3/circuits/abis/combined_accumulated_data.hpp" +#include "aztec3/circuits/abis/combined_constant_data.hpp" +#include "aztec3/circuits/abis/contract_deployment_data.hpp" +#include "aztec3/circuits/abis/function_data.hpp" +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/private_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/private_historic_tree_roots.hpp" +#include "aztec3/circuits/abis/private_kernel/globals.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp" +#include "aztec3/circuits/abis/signed_tx_request.hpp" +#include "aztec3/circuits/abis/tx_context.hpp" +#include "aztec3/circuits/abis/tx_request.hpp" +#include "aztec3/circuits/abis/types.hpp" +#include "aztec3/circuits/apps/function_execution_context.hpp" +#include "aztec3/circuits/apps/test_apps/basic_contract_deployment/basic_contract_deployment.hpp" +#include "aztec3/circuits/apps/test_apps/escrow/deposit.hpp" +#include "aztec3/circuits/hash.hpp" #include "aztec3/circuits/kernel/private/utils.hpp" +#include "aztec3/circuits/mock/mock_kernel_circuit.hpp" #include "aztec3/constants.hpp" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include @@ -351,9 +350,8 @@ PrivateKernelInputsInit do_private_call_get_kernel_inputs_init(bool const is NT::fr(uint256_t(0x01071e9a23e0f7edULL, 0x5d77b35d1830fa3eULL, 0xc6ba3660bb1f0c0bULL, 0x2ef9f7f09867fd6eULL)); const NT::address& tx_origin = msg_sender; - auto const& private_call_deploy = create_private_call_deploy_data(is_constructor, func, args_vec, msg_sender); - - auto const& private_call_data = private_call_deploy.first; + auto const& [private_call_data, contract_deployment_data] = + create_private_call_deploy_data(is_constructor, func, args_vec, msg_sender); //*************************************************************************** // We can create a TxRequest from some of the above data. Users must sign a TxRequest in order to give permission @@ -370,7 +368,7 @@ PrivateKernelInputsInit do_private_call_get_kernel_inputs_init(bool const is .is_fee_payment_tx = false, .is_rebate_payment_tx = false, .is_contract_deployment_tx = is_constructor, - .contract_deployment_data = private_call_deploy.second, + .contract_deployment_data = contract_deployment_data, }, .chain_id = 1, }; @@ -497,7 +495,7 @@ void validate_deployed_contract_address(PrivateKernelInputsInit const& priva /** * @brief Some private circuit proof (`deposit`, in this case) */ -TEST(private_kernel_tests, circuit_deposit) +/* TEST(private_kernel_tests, circuit_deposit) { NT::fr const& amount = 5; NT::fr const& asset_id = 1; @@ -522,7 +520,7 @@ TEST(private_kernel_tests, circuit_deposit) debugComposer(private_kernel_composer); } - + */ /** * @brief Some private circuit simulation (`deposit`, in this case) */ @@ -532,9 +530,9 @@ TEST(private_kernel_tests, native_deposit) NT::fr const& asset_id = 1; NT::fr const& memo = 999; - auto const& private_inputs = do_private_call_get_kernel_inputs(false, deposit, { amount, asset_id, memo }); + auto const& private_inputs = do_private_call_get_kernel_inputs_init(false, deposit, { amount, asset_id, memo }); DummyComposer composer = DummyComposer("private_kernel_tests__native_deposit"); - auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); + auto const& public_inputs = native_private_kernel_circuit_initial(composer, private_inputs); validate_deployed_contract_address(private_inputs, public_inputs); } @@ -542,143 +540,143 @@ TEST(private_kernel_tests, native_deposit) /** * @brief Some private circuit proof (`constructor`, in this case) */ -TEST(private_kernel_tests, circuit_basic_contract_deployment) -{ - NT::fr const& arg0 = 5; - NT::fr const& arg1 = 1; - NT::fr const& arg2 = 999; - - auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }, true); - - // Execute and prove the first kernel iteration - Composer private_kernel_composer("../barretenberg/cpp/srs_db/ignition"); - auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); - - // Check contract address was correctly computed by the circuit - validate_deployed_contract_address(private_inputs, public_inputs); - - // Create the final kernel proof and verify it natively. - auto final_kernel_prover = private_kernel_composer.create_prover(); - auto const& final_kernel_proof = final_kernel_prover.construct_proof(); - - auto final_kernel_verifier = private_kernel_composer.create_verifier(); - auto const& final_result = final_kernel_verifier.verify_proof(final_kernel_proof); - EXPECT_EQ(final_result, true); - - debugComposer(private_kernel_composer); -} - -/** - * @brief Some private circuit simulation (`constructor`, in this case) - */ -TEST(private_kernel_tests, native_basic_contract_deployment) -{ - NT::fr const& arg0 = 5; - NT::fr const& arg1 = 1; - NT::fr const& arg2 = 999; - - auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }); - DummyComposer composer = DummyComposer("private_kernel_tests__native_basic_contract_deployment"); - auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); - - validate_deployed_contract_address(private_inputs, public_inputs); -} - -/** - * @brief Some private circuit simulation checked against its results via cbinds - */ -TEST(private_kernel_tests, circuit_create_proof_cbinds) -{ - NT::fr const& arg0 = 5; - NT::fr const& arg1 = 1; - NT::fr const& arg2 = 999; - - // first run actual simulation to get public inputs - auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }, true); - DummyComposer composer = DummyComposer("private_kernel_tests__circuit_create_proof_cbinds"); - auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); - - // serialize expected public inputs for later comparison - std::vector expected_public_inputs_vec; - write(expected_public_inputs_vec, public_inputs); - - //*************************************************************************** - // Now run the simulate/prove cbinds to make sure their outputs match - //*************************************************************************** - // TODO might be able to get rid of proving key buffer - uint8_t const* pk_buf = nullptr; - private_kernel__init_proving_key(&pk_buf); - // info("Proving key size: ", pk_size); - - // TODO might be able to get rid of verification key buffer - // uint8_t const* vk_buf; - // size_t vk_size = private_kernel__init_verification_key(pk_buf, &vk_buf); - // info("Verification key size: ", vk_size); - - std::vector signed_constructor_tx_request_vec; - write(signed_constructor_tx_request_vec, private_inputs.signed_tx_request); - - std::vector private_constructor_call_vec; - write(private_constructor_call_vec, private_inputs.private_call); - - uint8_t const* proof_data_buf = nullptr; - uint8_t const* public_inputs_buf = nullptr; - size_t public_inputs_size = 0; - // info("Simulating to generate public inputs..."); - uint8_t* const circuit_failure_ptr = private_kernel__sim(signed_constructor_tx_request_vec.data(), - nullptr, // no previous kernel on first iteration - private_constructor_call_vec.data(), - true, // first iteration - &public_inputs_size, - &public_inputs_buf); - ASSERT_TRUE(circuit_failure_ptr == nullptr); - - // TODO better equality check - // for (size_t i = 0; i < public_inputs_size; i++) - for (size_t i = 0; i < 10; i++) { - ASSERT_EQ(public_inputs_buf[i], expected_public_inputs_vec[i]); - } - (void)public_inputs_size; - // info("Proving"); - size_t const proof_data_size = private_kernel__prove(signed_constructor_tx_request_vec.data(), - nullptr, // no previous kernel on first iteration - private_constructor_call_vec.data(), - pk_buf, - true, // first iteration - &proof_data_buf); - (void)proof_data_size; - // info("Proof size: ", proof_data_size); - // info("PublicInputs size: ", public_inputs_size); - - free((void*)pk_buf); - // free((void*)vk_buf); - free((void*)proof_data_buf); - free((void*)public_inputs_buf); -} - -/** - * @brief Test this dummy cbind - */ -TEST(private_kernel_tests, native_dummy_previous_kernel_cbind) -{ - uint8_t const* cbind_previous_kernel_buf = nullptr; - size_t const cbind_buf_size = private_kernel__dummy_previous_kernel(&cbind_previous_kernel_buf); - - auto const& previous_kernel = utils::dummy_previous_kernel(); - std::vector expected_vec; - write(expected_vec, previous_kernel); - - // Just compare the first 10 bytes of the serialized public outputs - // TODO this is not a good test as it only checks a few bytes - // would be best if we could just check struct equality or check - // equality of an entire memory region (same as other similar TODOs - // in other test files) - // TODO better equality check - // for (size_t i = 0; i < cbind_buf_size; i++) { - for (size_t i = 0; i < 10; i++) { - ASSERT_EQ(cbind_previous_kernel_buf[i], expected_vec[i]); - } - (void)cbind_buf_size; -} +// TEST(private_kernel_tests, circuit_basic_contract_deployment) +// { +// NT::fr const& arg0 = 5; +// NT::fr const& arg1 = 1; +// NT::fr const& arg2 = 999; + +// auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }, true); + +// // Execute and prove the first kernel iteration +// Composer private_kernel_composer("../barretenberg/cpp/srs_db/ignition"); +// auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); + +// // Check contract address was correctly computed by the circuit +// validate_deployed_contract_address(private_inputs, public_inputs); + +// // Create the final kernel proof and verify it natively. +// auto final_kernel_prover = private_kernel_composer.create_prover(); +// auto const& final_kernel_proof = final_kernel_prover.construct_proof(); + +// auto final_kernel_verifier = private_kernel_composer.create_verifier(); +// auto const& final_result = final_kernel_verifier.verify_proof(final_kernel_proof); +// EXPECT_EQ(final_result, true); + +// debugComposer(private_kernel_composer); +// } + +// /** +// * @brief Some private circuit simulation (`constructor`, in this case) +// */ +// TEST(private_kernel_tests, native_basic_contract_deployment) +// { +// NT::fr const& arg0 = 5; +// NT::fr const& arg1 = 1; +// NT::fr const& arg2 = 999; + +// auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }); +// DummyComposer composer = DummyComposer("private_kernel_tests__native_basic_contract_deployment"); +// auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); + +// validate_deployed_contract_address(private_inputs, public_inputs); +// } + +// /** +// * @brief Some private circuit simulation checked against its results via cbinds +// */ +// TEST(private_kernel_tests, circuit_create_proof_cbinds) +// { +// NT::fr const& arg0 = 5; +// NT::fr const& arg1 = 1; +// NT::fr const& arg2 = 999; + +// // first run actual simulation to get public inputs +// auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }, true); +// DummyComposer composer = DummyComposer("private_kernel_tests__circuit_create_proof_cbinds"); +// auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); + +// // serialize expected public inputs for later comparison +// std::vector expected_public_inputs_vec; +// write(expected_public_inputs_vec, public_inputs); + +// //*************************************************************************** +// // Now run the simulate/prove cbinds to make sure their outputs match +// //*************************************************************************** +// // TODO might be able to get rid of proving key buffer +// uint8_t const* pk_buf = nullptr; +// private_kernel__init_proving_key(&pk_buf); +// // info("Proving key size: ", pk_size); + +// // TODO might be able to get rid of verification key buffer +// // uint8_t const* vk_buf; +// // size_t vk_size = private_kernel__init_verification_key(pk_buf, &vk_buf); +// // info("Verification key size: ", vk_size); + +// std::vector signed_constructor_tx_request_vec; +// write(signed_constructor_tx_request_vec, private_inputs.signed_tx_request); + +// std::vector private_constructor_call_vec; +// write(private_constructor_call_vec, private_inputs.private_call); + +// uint8_t const* proof_data_buf = nullptr; +// uint8_t const* public_inputs_buf = nullptr; +// size_t public_inputs_size = 0; +// // info("Simulating to generate public inputs..."); +// uint8_t* const circuit_failure_ptr = private_kernel__sim(signed_constructor_tx_request_vec.data(), +// nullptr, // no previous kernel on first iteration +// private_constructor_call_vec.data(), +// true, // first iteration +// &public_inputs_size, +// &public_inputs_buf); +// ASSERT_TRUE(circuit_failure_ptr == nullptr); + +// // TODO better equality check +// // for (size_t i = 0; i < public_inputs_size; i++) +// for (size_t i = 0; i < 10; i++) { +// ASSERT_EQ(public_inputs_buf[i], expected_public_inputs_vec[i]); +// } +// (void)public_inputs_size; +// // info("Proving"); +// size_t const proof_data_size = private_kernel__prove(signed_constructor_tx_request_vec.data(), +// nullptr, // no previous kernel on first iteration +// private_constructor_call_vec.data(), +// pk_buf, +// true, // first iteration +// &proof_data_buf); +// (void)proof_data_size; +// // info("Proof size: ", proof_data_size); +// // info("PublicInputs size: ", public_inputs_size); + +// free((void*)pk_buf); +// // free((void*)vk_buf); +// free((void*)proof_data_buf); +// free((void*)public_inputs_buf); +// } + +// /** +// * @brief Test this dummy cbind +// */ +// TEST(private_kernel_tests, native_dummy_previous_kernel_cbind) +// { +// uint8_t const* cbind_previous_kernel_buf = nullptr; +// size_t const cbind_buf_size = private_kernel__dummy_previous_kernel(&cbind_previous_kernel_buf); + +// auto const& previous_kernel = utils::dummy_previous_kernel(); +// std::vector expected_vec; +// write(expected_vec, previous_kernel); + +// // Just compare the first 10 bytes of the serialized public outputs +// // TODO this is not a good test as it only checks a few bytes +// // would be best if we could just check struct equality or check +// // equality of an entire memory region (same as other similar TODOs +// // in other test files) +// // TODO better equality check +// // for (size_t i = 0; i < cbind_buf_size; i++) { +// for (size_t i = 0; i < 10; i++) { +// ASSERT_EQ(cbind_previous_kernel_buf[i], expected_vec[i]); +// } +// (void)cbind_buf_size; +// } } // namespace aztec3::circuits::kernel::private_kernel diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index 66625cc9c26b..d1bb6996f40d 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -224,8 +224,8 @@ void validate_inputs(DummyComposer& composer, PrivateKernelInputsInit const& // TODO: decide what to return. // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. -KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, - PrivateKernelInputsInit const& private_inputs) +KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyComposer& composer, + PrivateKernelInputsInit const& private_inputs) { // We'll be pushing data to this during execution of this circuit. KernelCircuitPublicInputs public_inputs{}; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp index 065b85cd2b5a..cf3735d44de8 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp @@ -2,9 +2,9 @@ #include "init.hpp" -#include -#include -#include +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" +#include "aztec3/utils/dummy_composer.hpp" namespace aztec3::circuits::kernel::private_kernel { @@ -15,6 +15,6 @@ using DummyComposer = aztec3::utils::DummyComposer; // TODO: decide what to return. KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyComposer& composer, - PrivateKernelInputsInit const& _private_inputs); + PrivateKernelInputsInit const& private_inputs); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file From 75d5b17f76df872093415f76cbcfeaaad4fbe031 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 16 May 2023 15:54:47 +0000 Subject: [PATCH 07/36] wip - repair native and circuit tests --- .../aztec3/circuits/kernel/private/.test.cpp | 296 +++++++++--------- 1 file changed, 154 insertions(+), 142 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index d60af2100091..1080c873a8e3 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -495,20 +495,27 @@ void validate_deployed_contract_address(PrivateKernelInputsInit const& priva /** * @brief Some private circuit proof (`deposit`, in this case) */ -/* TEST(private_kernel_tests, circuit_deposit) +TEST(private_kernel_tests, circuit_deposit) { NT::fr const& amount = 5; NT::fr const& asset_id = 1; NT::fr const& memo = 999; - auto const& private_inputs = do_private_call_get_kernel_inputs(false, deposit, { amount, asset_id, memo }, true); + auto const& private_inputs = + do_private_call_get_kernel_inputs_inner(false, deposit, { amount, asset_id, memo }, true); // Execute and prove the first kernel iteration Composer private_kernel_composer("../barretenberg/cpp/srs_db/ignition"); auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); + // TODO(jeanmon): this is a temporary hack until we have private_kernel_circuit init and inner + // variant. Once this is supported, we will be able to generate public_inputs with + // a call to private_kernel_circuit_init(private_inputs_init, ...) + auto const& private_inputs_init = + do_private_call_get_kernel_inputs_init(false, deposit, { amount, asset_id, memo }); + // Check contract address was correctly computed by the circuit - validate_deployed_contract_address(private_inputs, public_inputs); + validate_deployed_contract_address(private_inputs_init, public_inputs); // Create the final kernel proof and verify it natively. auto final_kernel_prover = private_kernel_composer.create_prover(); @@ -520,7 +527,7 @@ void validate_deployed_contract_address(PrivateKernelInputsInit const& priva debugComposer(private_kernel_composer); } - */ + /** * @brief Some private circuit simulation (`deposit`, in this case) */ @@ -540,143 +547,148 @@ TEST(private_kernel_tests, native_deposit) /** * @brief Some private circuit proof (`constructor`, in this case) */ -// TEST(private_kernel_tests, circuit_basic_contract_deployment) -// { -// NT::fr const& arg0 = 5; -// NT::fr const& arg1 = 1; -// NT::fr const& arg2 = 999; - -// auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }, true); - -// // Execute and prove the first kernel iteration -// Composer private_kernel_composer("../barretenberg/cpp/srs_db/ignition"); -// auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); - -// // Check contract address was correctly computed by the circuit -// validate_deployed_contract_address(private_inputs, public_inputs); - -// // Create the final kernel proof and verify it natively. -// auto final_kernel_prover = private_kernel_composer.create_prover(); -// auto const& final_kernel_proof = final_kernel_prover.construct_proof(); - -// auto final_kernel_verifier = private_kernel_composer.create_verifier(); -// auto const& final_result = final_kernel_verifier.verify_proof(final_kernel_proof); -// EXPECT_EQ(final_result, true); - -// debugComposer(private_kernel_composer); -// } - -// /** -// * @brief Some private circuit simulation (`constructor`, in this case) -// */ -// TEST(private_kernel_tests, native_basic_contract_deployment) -// { -// NT::fr const& arg0 = 5; -// NT::fr const& arg1 = 1; -// NT::fr const& arg2 = 999; - -// auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }); -// DummyComposer composer = DummyComposer("private_kernel_tests__native_basic_contract_deployment"); -// auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); - -// validate_deployed_contract_address(private_inputs, public_inputs); -// } - -// /** -// * @brief Some private circuit simulation checked against its results via cbinds -// */ -// TEST(private_kernel_tests, circuit_create_proof_cbinds) -// { -// NT::fr const& arg0 = 5; -// NT::fr const& arg1 = 1; -// NT::fr const& arg2 = 999; - -// // first run actual simulation to get public inputs -// auto const& private_inputs = do_private_call_get_kernel_inputs(true, constructor, { arg0, arg1, arg2 }, true); -// DummyComposer composer = DummyComposer("private_kernel_tests__circuit_create_proof_cbinds"); -// auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); - -// // serialize expected public inputs for later comparison -// std::vector expected_public_inputs_vec; -// write(expected_public_inputs_vec, public_inputs); - -// //*************************************************************************** -// // Now run the simulate/prove cbinds to make sure their outputs match -// //*************************************************************************** -// // TODO might be able to get rid of proving key buffer -// uint8_t const* pk_buf = nullptr; -// private_kernel__init_proving_key(&pk_buf); -// // info("Proving key size: ", pk_size); - -// // TODO might be able to get rid of verification key buffer -// // uint8_t const* vk_buf; -// // size_t vk_size = private_kernel__init_verification_key(pk_buf, &vk_buf); -// // info("Verification key size: ", vk_size); - -// std::vector signed_constructor_tx_request_vec; -// write(signed_constructor_tx_request_vec, private_inputs.signed_tx_request); - -// std::vector private_constructor_call_vec; -// write(private_constructor_call_vec, private_inputs.private_call); - -// uint8_t const* proof_data_buf = nullptr; -// uint8_t const* public_inputs_buf = nullptr; -// size_t public_inputs_size = 0; -// // info("Simulating to generate public inputs..."); -// uint8_t* const circuit_failure_ptr = private_kernel__sim(signed_constructor_tx_request_vec.data(), -// nullptr, // no previous kernel on first iteration -// private_constructor_call_vec.data(), -// true, // first iteration -// &public_inputs_size, -// &public_inputs_buf); -// ASSERT_TRUE(circuit_failure_ptr == nullptr); - -// // TODO better equality check -// // for (size_t i = 0; i < public_inputs_size; i++) -// for (size_t i = 0; i < 10; i++) { -// ASSERT_EQ(public_inputs_buf[i], expected_public_inputs_vec[i]); -// } -// (void)public_inputs_size; -// // info("Proving"); -// size_t const proof_data_size = private_kernel__prove(signed_constructor_tx_request_vec.data(), -// nullptr, // no previous kernel on first iteration -// private_constructor_call_vec.data(), -// pk_buf, -// true, // first iteration -// &proof_data_buf); -// (void)proof_data_size; -// // info("Proof size: ", proof_data_size); -// // info("PublicInputs size: ", public_inputs_size); - -// free((void*)pk_buf); -// // free((void*)vk_buf); -// free((void*)proof_data_buf); -// free((void*)public_inputs_buf); -// } - -// /** -// * @brief Test this dummy cbind -// */ -// TEST(private_kernel_tests, native_dummy_previous_kernel_cbind) -// { -// uint8_t const* cbind_previous_kernel_buf = nullptr; -// size_t const cbind_buf_size = private_kernel__dummy_previous_kernel(&cbind_previous_kernel_buf); - -// auto const& previous_kernel = utils::dummy_previous_kernel(); -// std::vector expected_vec; -// write(expected_vec, previous_kernel); - -// // Just compare the first 10 bytes of the serialized public outputs -// // TODO this is not a good test as it only checks a few bytes -// // would be best if we could just check struct equality or check -// // equality of an entire memory region (same as other similar TODOs -// // in other test files) -// // TODO better equality check -// // for (size_t i = 0; i < cbind_buf_size; i++) { -// for (size_t i = 0; i < 10; i++) { -// ASSERT_EQ(cbind_previous_kernel_buf[i], expected_vec[i]); -// } -// (void)cbind_buf_size; -// } +TEST(private_kernel_tests, circuit_basic_contract_deployment) +{ + NT::fr const& arg0 = 5; + NT::fr const& arg1 = 1; + NT::fr const& arg2 = 999; + + auto const& private_inputs = do_private_call_get_kernel_inputs_inner(true, constructor, { arg0, arg1, arg2 }, true); + + // Execute and prove the first kernel iteration + Composer private_kernel_composer("../barretenberg/cpp/srs_db/ignition"); + auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); + + // TODO(jeanmon): this is a temporary hack until we have private_kernel_circuit init and inner + // variant. Once this is supported, we will be able to generate public_inputs with + // a call to private_kernel_circuit_init(private_inputs_init, ...) + auto const& private_inputs_init = do_private_call_get_kernel_inputs_init(true, constructor, { arg0, arg1, arg2 }); + + // Check contract address was correctly computed by the circuit + validate_deployed_contract_address(private_inputs_init, public_inputs); + + // Create the final kernel proof and verify it natively. + auto final_kernel_prover = private_kernel_composer.create_prover(); + auto const& final_kernel_proof = final_kernel_prover.construct_proof(); + + auto final_kernel_verifier = private_kernel_composer.create_verifier(); + auto const& final_result = final_kernel_verifier.verify_proof(final_kernel_proof); + EXPECT_EQ(final_result, true); + + debugComposer(private_kernel_composer); +} + +/** + * @brief Some private circuit simulation (`constructor`, in this case) + */ +TEST(private_kernel_tests, native_basic_contract_deployment) +{ + NT::fr const& arg0 = 5; + NT::fr const& arg1 = 1; + NT::fr const& arg2 = 999; + + auto const& private_inputs = do_private_call_get_kernel_inputs_init(true, constructor, { arg0, arg1, arg2 }); + DummyComposer composer = DummyComposer("private_kernel_tests__native_basic_contract_deployment"); + auto const& public_inputs = native_private_kernel_circuit_initial(composer, private_inputs); + + validate_deployed_contract_address(private_inputs, public_inputs); +} + +/** + * @brief Some private circuit simulation checked against its results via cbinds + */ +TEST(private_kernel_tests, circuit_create_proof_cbinds) +{ + NT::fr const& arg0 = 5; + NT::fr const& arg1 = 1; + NT::fr const& arg2 = 999; + + // first run actual simulation to get public inputs + auto const& private_inputs = do_private_call_get_kernel_inputs_init(true, constructor, { arg0, arg1, arg2 }); + DummyComposer composer = DummyComposer("private_kernel_tests__circuit_create_proof_cbinds"); + auto const& public_inputs = native_private_kernel_circuit_initial(composer, private_inputs); + + // serialize expected public inputs for later comparison + std::vector expected_public_inputs_vec; + write(expected_public_inputs_vec, public_inputs); + + //*************************************************************************** + // Now run the simulate/prove cbinds to make sure their outputs match + //*************************************************************************** + // TODO might be able to get rid of proving key buffer + uint8_t const* pk_buf = nullptr; + private_kernel__init_proving_key(&pk_buf); + // info("Proving key size: ", pk_size); + + // TODO might be able to get rid of verification key buffer + // uint8_t const* vk_buf; + // size_t vk_size = private_kernel__init_verification_key(pk_buf, &vk_buf); + // info("Verification key size: ", vk_size); + + std::vector signed_constructor_tx_request_vec; + write(signed_constructor_tx_request_vec, private_inputs.signed_tx_request); + + std::vector private_constructor_call_vec; + write(private_constructor_call_vec, private_inputs.private_call); + + uint8_t const* proof_data_buf = nullptr; + uint8_t const* public_inputs_buf = nullptr; + size_t public_inputs_size = 0; + // info("Simulating to generate public inputs..."); + uint8_t* const circuit_failure_ptr = private_kernel__sim(signed_constructor_tx_request_vec.data(), + nullptr, // no previous kernel on first iteration + private_constructor_call_vec.data(), + true, // first iteration + &public_inputs_size, + &public_inputs_buf); + ASSERT_TRUE(circuit_failure_ptr == nullptr); + + // TODO better equality check + // for (size_t i = 0; i < public_inputs_size; i++) + for (size_t i = 0; i < 10; i++) { + ASSERT_EQ(public_inputs_buf[i], expected_public_inputs_vec[i]); + } + (void)public_inputs_size; + // info("Proving"); + size_t const proof_data_size = private_kernel__prove(signed_constructor_tx_request_vec.data(), + nullptr, // no previous kernel on first iteration + private_constructor_call_vec.data(), + pk_buf, + true, // first iteration + &proof_data_buf); + (void)proof_data_size; + // info("Proof size: ", proof_data_size); + // info("PublicInputs size: ", public_inputs_size); + + free((void*)pk_buf); + // free((void*)vk_buf); + free((void*)proof_data_buf); + free((void*)public_inputs_buf); +} + +/** + * @brief Test this dummy cbind + */ +TEST(private_kernel_tests, native_dummy_previous_kernel_cbind) +{ + uint8_t const* cbind_previous_kernel_buf = nullptr; + size_t const cbind_buf_size = private_kernel__dummy_previous_kernel(&cbind_previous_kernel_buf); + + auto const& previous_kernel = utils::dummy_previous_kernel(); + std::vector expected_vec; + write(expected_vec, previous_kernel); + + // Just compare the first 10 bytes of the serialized public outputs + // TODO this is not a good test as it only checks a few bytes + // would be best if we could just check struct equality or check + // equality of an entire memory region (same as other similar TODOs + // in other test files) + // TODO better equality check + // for (size_t i = 0; i < cbind_buf_size; i++) { + for (size_t i = 0; i < 10; i++) { + ASSERT_EQ(cbind_previous_kernel_buf[i], expected_vec[i]); + } + (void)cbind_buf_size; +} } // namespace aztec3::circuits::kernel::private_kernel From f294a0a96b93825cef77145c041360181c774a86 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Wed, 17 May 2023 07:45:57 +0000 Subject: [PATCH 08/36] wip - include using double quotes and remove unused code --- .../aztec3/circuits/kernel/private/init.hpp | 14 +++++++------- .../private/native_private_kernel_circuit.cpp | 16 +++++++--------- .../private/native_private_kernel_circuit.hpp | 6 +++--- .../native_private_kernel_circuit_initial.cpp | 19 +------------------ .../kernel/private/private_kernel_circuit.cpp | 10 +++++----- .../kernel/private/private_kernel_circuit.hpp | 4 ++-- .../aztec3/circuits/kernel/private/utils.cpp | 2 +- 7 files changed, 26 insertions(+), 45 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp index 28d7eea000b6..991ba4ed6bda 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/init.hpp @@ -1,11 +1,11 @@ #pragma once -#include -#include -#include -#include -#include -#include -#include +#include "aztec3/circuits/apps/function_execution_context.hpp" +#include "aztec3/circuits/apps/oracle_wrapper.hpp" +#include "aztec3/circuits/recursion/aggregator.hpp" +#include "aztec3/oracle/oracle.hpp" +#include "aztec3/utils/types/circuit_types.hpp" +#include "aztec3/utils/types/convert.hpp" +#include "aztec3/utils/types/native_types.hpp" namespace aztec3::circuits::kernel::private_kernel { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index fb77c3b8cc51..fe1014b9b5e6 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -1,15 +1,15 @@ #include "common.hpp" #include "init.hpp" +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp" +#include "aztec3/circuits/hash.hpp" #include "aztec3/constants.hpp" -#include -#include -#include -#include -#include -#include +#include "aztec3/utils/array.hpp" +#include "aztec3/utils/dummy_composer.hpp" -#include +#include "barretenberg/stdlib/merkle_tree/membership.hpp" namespace aztec3::circuits::kernel::private_kernel { @@ -21,8 +21,6 @@ using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using aztec3::utils::array_length; using aztec3::utils::array_pop; using aztec3::utils::array_push; -using aztec3::utils::is_array_empty; -using aztec3::utils::push_array_to_array; using DummyComposer = aztec3::utils::DummyComposer; using CircuitErrorCode = aztec3::utils::CircuitErrorCode; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp index 0206a1a6d5f9..e7afa9e7c1d4 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp @@ -2,9 +2,9 @@ #include "init.hpp" -#include -#include -#include +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp" +#include "aztec3/utils/dummy_composer.hpp" namespace aztec3::circuits::kernel::private_kernel { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index d1bb6996f40d..d61fedcbacc3 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -6,7 +6,7 @@ using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; -using aztec3::utils::array_pop; +using aztec3::utils::array_push; namespace aztec3::circuits::kernel::private_kernel { @@ -169,23 +169,6 @@ void validate_this_private_call_against_tx_request(DummyComposer& composer, CircuitErrorCode::PRIVATE_KERNEL__USER_INTENT_MISMATCH_BETWEEN_TX_REQUEST_AND_CALL_STACK_ITEM); }; -void validate_this_private_call_stack(DummyComposer& composer, PrivateKernelInputsInit const& private_inputs) -{ - const auto& stack = private_inputs.private_call.call_stack_item.public_inputs.private_call_stack; - const auto& preimages = private_inputs.private_call.private_call_stack_preimages; - for (size_t i = 0; i < stack.size(); ++i) { - const auto& hash = stack[i]; - const auto& preimage = preimages[i]; - - // Note: this assumes it's computationally infeasible to have `0` as a valid call_stack_item_hash. - // Assumes `hash == 0` means "this stack item is empty". - const auto calculated_hash = hash == 0 ? 0 : preimage.hash(); - composer.do_assert(hash != calculated_hash, - format("private_call_stack[", i, "] = ", hash, "; does not reconcile"), - CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_ITEM_HASH_MISMATCH); - } -}; - void validate_inputs(DummyComposer& composer, PrivateKernelInputsInit const& private_inputs) { const auto& this_call_stack_item = private_inputs.private_call.call_stack_item; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp index ada17bd091d8..df693b659aa5 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp @@ -1,12 +1,12 @@ #include "init.hpp" +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp" +#include "aztec3/circuits/hash.hpp" #include "aztec3/constants.hpp" -#include -#include -#include -#include -#include +#include "barretenberg/stdlib/primitives/field/array.hpp" namespace aztec3::circuits::kernel::private_kernel { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp index c85e09b732cb..c505a4b71919 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp @@ -2,8 +2,8 @@ #include "init.hpp" -#include -#include +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp" namespace aztec3::circuits::kernel::private_kernel { diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp index ebbf95efec4b..852442808f50 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/utils.cpp @@ -2,7 +2,7 @@ #include "init.hpp" #include "aztec3/circuits/abis/new_contract_data.hpp" -#include +#include "aztec3/circuits/mock/mock_kernel_circuit.hpp" #include "barretenberg/proof_system/types/composer_type.hpp" From 6c73b8a22138d1a5f522d41efab5a71f9037325c Mon Sep 17 00:00:00 2001 From: jeanmon Date: Wed, 17 May 2023 11:11:24 +0000 Subject: [PATCH 09/36] wip - fixing circuit_create_proof_cbinds test and adapting private_kernel_sim function to the inner/init split --- .../private_kernel_inputs_init.hpp | 2 - .../aztec3/circuits/kernel/private/.test.cpp | 6 +-- .../aztec3/circuits/kernel/private/c_bind.cpp | 49 ++++++++++--------- .../aztec3/circuits/kernel/private/c_bind.h | 7 +-- .../aztec3/circuits/kernel/private/common.hpp | 5 +- .../private/native_private_kernel_circuit.cpp | 2 - .../native_private_kernel_circuit_initial.cpp | 27 ++++++++-- 7 files changed, 51 insertions(+), 47 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp index 13d9990b31b3..3a85cad051aa 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp @@ -6,8 +6,6 @@ #include "aztec3/utils/types/circuit_types.hpp" #include "aztec3/utils/types/native_types.hpp" -#include - namespace aztec3::circuits::abis::private_kernel { using aztec3::utils::types::CircuitTypes; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 1080c873a8e3..38b2a62c0cf7 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -10,7 +10,6 @@ #include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" #include "aztec3/circuits/abis/private_circuit_public_inputs.hpp" #include "aztec3/circuits/abis/private_historic_tree_roots.hpp" -#include "aztec3/circuits/abis/private_kernel/globals.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp" @@ -23,12 +22,9 @@ #include "aztec3/circuits/apps/test_apps/escrow/deposit.hpp" #include "aztec3/circuits/hash.hpp" #include "aztec3/circuits/kernel/private/utils.hpp" -#include "aztec3/circuits/mock/mock_kernel_circuit.hpp" #include "aztec3/constants.hpp" -#include -#include -#include +#include "barretenberg/stdlib/merkle_tree/hash.hpp" #include diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index ce9460ae1ef6..edfe6c983d67 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -3,6 +3,9 @@ #include "index.hpp" #include "utils.hpp" +#include "aztec3/circuits/abis/combined_constant_data.hpp" +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" + #include "barretenberg/srs/reference_string/env_reference_string.hpp" namespace { @@ -13,8 +16,10 @@ using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::PreviousKernelData; using aztec3::circuits::abis::SignedTxRequest; using aztec3::circuits::abis::private_kernel::PrivateCallData; +using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit; +using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit_initial; using aztec3::circuits::kernel::private_kernel::private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::utils::dummy_previous_kernel; @@ -82,39 +87,35 @@ WASM_EXPORT uint8_t* private_kernel__sim(uint8_t const* signed_tx_request_buf, uint8_t const** private_kernel_public_inputs_buf) { DummyComposer composer = DummyComposer("private_kernel__sim"); - SignedTxRequest signed_tx_request; - read(signed_tx_request_buf, signed_tx_request); - PrivateCallData private_call_data; read(private_call_buf, private_call_data); - PreviousKernelData previous_kernel; + KernelCircuitPublicInputs public_inputs = KernelCircuitPublicInputs{}; + if (first_iteration) { - previous_kernel = dummy_previous_kernel(); + SignedTxRequest signed_tx_request; + read(signed_tx_request_buf, signed_tx_request); - previous_kernel.public_inputs.end.private_call_stack[0] = private_call_data.call_stack_item.hash(); - previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.private_data_tree_root = - private_call_data.call_stack_item.public_inputs.historic_private_data_tree_root; - previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.nullifier_tree_root = - private_call_data.call_stack_item.public_inputs.historic_nullifier_tree_root; - previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots.contract_tree_root = - private_call_data.call_stack_item.public_inputs.historic_contract_tree_root; - previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots - .l1_to_l2_messages_tree_root = - private_call_data.call_stack_item.public_inputs.historic_l1_to_l2_messages_tree_root; - // previous_kernel.public_inputs.constants.historic_tree_roots.private_kernel_vk_tree_root = - previous_kernel.public_inputs.constants.tx_context = signed_tx_request.tx_request.tx_context; - previous_kernel.public_inputs.is_private = true; + // Assert that previous_kernel_buf is empty (i.e. nullptr) + ASSERT(previous_kernel_buf == nullptr); + + PrivateKernelInputsInit const private_inputs = PrivateKernelInputsInit{ + .signed_tx_request = signed_tx_request, + .private_call = private_call_data, + }; + + public_inputs = native_private_kernel_circuit_initial(composer, private_inputs); } else { + PreviousKernelData previous_kernel; read(previous_kernel_buf, previous_kernel); - } - PrivateKernelInputsInner const private_inputs = PrivateKernelInputsInner{ - .previous_kernel = previous_kernel, - .private_call = private_call_data, - }; + PrivateKernelInputsInner const private_inputs = PrivateKernelInputsInner{ + .previous_kernel = previous_kernel, + .private_call = private_call_data, + }; - KernelCircuitPublicInputs const public_inputs = native_private_kernel_circuit(composer, private_inputs); + public_inputs = native_private_kernel_circuit(composer, private_inputs); + } // serialize public inputs to bytes vec std::vector public_inputs_vec; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.h b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.h index 0cff3b052c51..16326774019f 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.h +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.h @@ -1,6 +1,6 @@ #pragma once -#include #include +#include #define WASM_EXPORT __attribute__((visibility("default"))) @@ -21,8 +21,5 @@ WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, uint8_t const* pk_buf, bool first, uint8_t const** proof_data_buf); -WASM_EXPORT size_t private_kernel__verify_proof(uint8_t const* vk_buf, - uint8_t const* proof, - uint32_t length); - +WASM_EXPORT size_t private_kernel__verify_proof(uint8_t const* vk_buf, uint8_t const* proof, uint32_t length); } \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp index 1062d73cf23b..1c312ae2155a 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -9,14 +9,11 @@ #include "aztec3/utils/array.hpp" #include "aztec3/utils/dummy_composer.hpp" -#include - using DummyComposer = aztec3::utils::DummyComposer; using aztec3::circuits::abis::ContractLeafPreimage; using aztec3::circuits::abis::KernelCircuitPublicInputs; -using aztec3::utils::array_push; using aztec3::utils::is_array_empty; using aztec3::utils::push_array_to_array; using DummyComposer = aztec3::utils::DummyComposer; @@ -37,7 +34,7 @@ void common_validate_call_stack(DummyComposer& composer, KernelPrivateInput cons // Note: this assumes it's computationally infeasible to have `0` as a valid call_stack_item_hash. // Assumes `hash == 0` means "this stack item is empty". const auto calculated_hash = hash == 0 ? 0 : preimage.hash(); - composer.do_assert(hash != calculated_hash, + composer.do_assert(hash == calculated_hash, format("private_call_stack[", i, "] = ", hash, "; does not reconcile"), CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_ITEM_HASH_MISMATCH); } diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index fe1014b9b5e6..92056724023f 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -9,8 +9,6 @@ #include "aztec3/utils/array.hpp" #include "aztec3/utils/dummy_composer.hpp" -#include "barretenberg/stdlib/merkle_tree/membership.hpp" - namespace aztec3::circuits::kernel::private_kernel { using aztec3::circuits::abis::ContractLeafPreimage; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index d61fedcbacc3..3f3a875155f6 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -1,10 +1,16 @@ #include "common.hpp" +#include "aztec3/circuits/abis/combined_constant_data.hpp" +#include "aztec3/circuits/abis/combined_historic_tree_roots.hpp" #include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/abis/private_historic_tree_roots.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" #include "aztec3/circuits/kernel/private/init.hpp" +using aztec3::circuits::abis::CombinedConstantData; +using aztec3::circuits::abis::CombinedHistoricTreeRoots; using aztec3::circuits::abis::NewContractData; +using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; using aztec3::utils::array_push; @@ -35,11 +41,22 @@ namespace aztec3::circuits::kernel::private_kernel { void initialise_end_values(PrivateKernelInputsInit const& private_inputs, KernelCircuitPublicInputs& public_inputs) { - // TODO(dbanks12): where do constants come from - // might need to add these constants to PrivateKernelInputsInit - // public_inputs.constants = private_inputs.previous_kernel.public_inputs.constants; - (void)private_inputs; - (void)public_inputs; + // Define the constants data. + auto const& private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; + auto const constants = CombinedConstantData{ + .historic_tree_roots = + CombinedHistoricTreeRoots{ + .private_historic_tree_roots = + PrivateHistoricTreeRoots{ + .private_data_tree_root = private_call_public_inputs.historic_private_data_tree_root, + .contract_tree_root = private_call_public_inputs.historic_contract_tree_root, + }, + }, + .tx_context = private_inputs.signed_tx_request.tx_request.tx_context, + }; + + // Set the constants in public_inputs. + public_inputs.constants = constants; } void contract_logic(DummyComposer& composer, From 64678eacd386f705470f25d55a6239f364fd09af Mon Sep 17 00:00:00 2001 From: jeanmon Date: Wed, 17 May 2023 11:31:07 +0000 Subject: [PATCH 10/36] wip - fix clang tidy issue --- .../kernel/private/native_private_kernel_circuit_initial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index 3f3a875155f6..40c5345208ff 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -259,7 +259,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyCompose // In the native version, as there is no verify_proofs call, we can initialize aggregation object with the default // constructor. - NT::AggregationObject empty_aggregation_object{}; + NT::AggregationObject const empty_aggregation_object{}; public_inputs.end.aggregation_object = empty_aggregation_object; return public_inputs; From 9f8ebe25ce20ff4296593dc06e148e08141ed41d Mon Sep 17 00:00:00 2001 From: jeanmon Date: Wed, 17 May 2023 16:19:24 +0000 Subject: [PATCH 11/36] wip - post master merger fixes and remove test on new nullifiers --- .../aztec3/circuits/kernel/private/.test.cpp | 38 ++----------------- .../private/native_private_kernel_circuit.cpp | 2 +- .../native_private_kernel_circuit_initial.cpp | 16 +++----- .../kernel/private/private_kernel_circuit.cpp | 5 ++- .../kernel/private/private_kernel_circuit.hpp | 3 +- .../cpp/src/aztec3/utils/circuit_errors.hpp | 3 +- 6 files changed, 17 insertions(+), 50 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 98bd2abe2ff8..1a5adf048a05 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -505,13 +505,7 @@ TEST(private_kernel_tests, circuit_deposit) // Execute and prove the first kernel iteration Composer private_kernel_composer("../barretenberg/cpp/srs_db/ignition"); - auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); - - // TODO(jeanmon): this is a temporary hack until we have private_kernel_circuit init and inner - // variant. Once this is supported, we will be able to generate public_inputs with - // a call to private_kernel_circuit_init(private_inputs_init, ...) - auto const& private_inputs_init = - do_private_call_get_kernel_inputs_init(false, deposit, { amount, asset_id, memo }); + auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs, true); // TODO(jeanmon): this is a temporary hack until we have private_kernel_circuit init and inner // variant. Once this is supported, we will be able to generate public_inputs with @@ -565,12 +559,7 @@ TEST(private_kernel_tests, circuit_basic_contract_deployment) // Execute and prove the first kernel iteration Composer private_kernel_composer("../barretenberg/cpp/srs_db/ignition"); - auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs); - - // TODO(jeanmon): this is a temporary hack until we have private_kernel_circuit init and inner - // variant. Once this is supported, we will be able to generate public_inputs with - // a call to private_kernel_circuit_init(private_inputs_init, ...) - auto const& private_inputs_init = do_private_call_get_kernel_inputs_init(true, constructor, { arg0, arg1, arg2 }); + auto const& public_inputs = private_kernel_circuit(private_kernel_composer, private_inputs, true); // TODO(jeanmon): this is a temporary hack until we have private_kernel_circuit init and inner // variant. Once this is supported, we will be able to generate public_inputs with @@ -602,7 +591,7 @@ TEST(private_kernel_tests, native_basic_contract_deployment) auto const& private_inputs = do_private_call_get_kernel_inputs_init(true, constructor, { arg0, arg1, arg2 }); DummyComposer composer = DummyComposer("private_kernel_tests__native_basic_contract_deployment"); - auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); + auto const& public_inputs = native_private_kernel_circuit_initial(composer, private_inputs); validate_deployed_contract_address(private_inputs, public_inputs); @@ -622,7 +611,7 @@ TEST(private_kernel_tests, circuit_create_proof_cbinds) // first run actual simulation to get public inputs auto const& private_inputs = do_private_call_get_kernel_inputs_init(true, constructor, { arg0, arg1, arg2 }); DummyComposer composer = DummyComposer("private_kernel_tests__circuit_create_proof_cbinds"); - auto const& public_inputs = native_private_kernel_circuit(composer, private_inputs); + auto const& public_inputs = native_private_kernel_circuit_initial(composer, private_inputs); // serialize expected public inputs for later comparison std::vector expected_public_inputs_vec; @@ -707,23 +696,4 @@ TEST(private_kernel_tests, native_dummy_previous_kernel_cbind) (void)cbind_buf_size; } -/** - * @brief Test error is registered when `new_nullifiers` are not empty in first iteration - */ -TEST(private_kernel_tests, native_registers_error_when_no_space_for_nullifier) -{ - NT::fr const& amount = 5; - NT::fr const& asset_id = 1; - NT::fr const& memo = 999; - - auto private_inputs = do_private_call_get_kernel_inputs_init(false, deposit, { amount, asset_id, memo }); - array_push(private_inputs.previous_kernel.public_inputs.end.new_nullifiers, NT::fr::random_element()); - - DummyComposer composer = DummyComposer("private_kernel_tests__native_registers_error_when_no_space_for_nullifier"); - native_private_kernel_circuit_initial(composer, private_inputs, true); - - ASSERT_EQ(composer.get_first_failure().code, - CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_IN_FIRST_ITERATION); -} - } // namespace aztec3::circuits::kernel::private_kernel diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index c52c1e1d4a17..92056724023f 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -249,7 +249,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo // Do this before any functions can modify the inputs. initialise_end_values(private_inputs, public_inputs); - validate_inputs(composer, private_inputs, first_iteration); + validate_inputs(composer, private_inputs); validate_this_private_call_hash(composer, private_inputs, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index ac42645babbf..b5c08203bf74 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -220,17 +220,13 @@ void validate_inputs(DummyComposer& composer, PrivateKernelInputsInit const& // hard-coded into the circuit and assert that that is the one which has been used in the base case). } -void update_end_values(DummyComposer& composer, - PrivateKernelInputsInit const& private_inputs, - KernelCircuitPublicInputs& public_inputs) +void update_end_values(PrivateKernelInputsInit const& private_inputs, KernelCircuitPublicInputs& public_inputs) { - // Since it's the first iteration, we need to push the the tx hash nullifier into the `new_nullifiers` array - - // If the nullifiers array is not empty a change was made and we need to rework this - composer.do_assert(is_array_empty(public_inputs.end.new_nullifiers), - "new_nullifiers array must be empty in a first iteration of private kernel", - CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_IN_FIRST_ITERATION); + // We only initialzed constants member of public_inputs so far. Therefore, there must not be any + // new nullifiers as part of public_inputs. + ASSERT(is_array_empty(public_inputs.end.new_nullifiers)); + // Since it's the first iteration, we need to push the the tx hash nullifier into the `new_nullifiers` array array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.hash()); // Nonce nullifier @@ -260,7 +256,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyCompose common_validate_call_stack>(composer, private_inputs); - update_end_values(composer, private_inputs, public_inputs); + update_end_values(private_inputs, public_inputs); common_update_end_values>(composer, private_inputs, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp index cc29903a3526..ce407e449e50 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp @@ -234,7 +234,7 @@ void validate_this_private_call_stack(PrivateKernelInputsInner const& privat } }; -void validate_inputs(PrivateKernelInputsInner const& private_inputs) +void validate_inputs(PrivateKernelInputsInner const& private_inputs, bool first_iteration) { // this callstack represents the function currently being processed const auto& this_call_stack_item = private_inputs.private_call.call_stack_item; @@ -318,7 +318,8 @@ void validate_inputs(PrivateKernelInputsInner const& private_inputs) // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, - PrivateKernelInputsInner const& _private_inputs) + PrivateKernelInputsInner const& _private_inputs, + bool first_iteration) { const PrivateKernelInputsInner private_inputs = _private_inputs.to_circuit_type(composer); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp index c505a4b71919..1f006c8ea3fd 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.hpp @@ -11,6 +11,7 @@ using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; KernelCircuitPublicInputs private_kernel_circuit(Composer& composer, - PrivateKernelInputsInner const& _private_inputs); + PrivateKernelInputsInner const& private_inputs, + bool first_iteration); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/utils/circuit_errors.hpp b/circuits/cpp/src/aztec3/utils/circuit_errors.hpp index d4d28c8b98ad..ec42461506b2 100644 --- a/circuits/cpp/src/aztec3/utils/circuit_errors.hpp +++ b/circuits/cpp/src/aztec3/utils/circuit_errors.hpp @@ -23,8 +23,7 @@ enum CircuitErrorCode : uint16_t { PRIVATE_KERNEL__CONSTRUCTOR_EXECUTED_IN_RECURSION = 2014, PRIVATE_KERNEL__PRIVATE_CALL_STACK_EMPTY = 2015, PRIVATE_KERNEL__KERNEL_PROOF_CONTAINS_RECURSIVE_PROOF = 2016, - PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_IN_FIRST_ITERATION = 2017, - PRIVATE_KERNEL__USER_INTENT_MISMATCH_BETWEEN_TX_REQUEST_AND_CALL_STACK_ITEM = 2018, + PRIVATE_KERNEL__USER_INTENT_MISMATCH_BETWEEN_TX_REQUEST_AND_CALL_STACK_ITEM = 2017, // Public kernel related errors PUBLIC_KERNEL_CIRCUIT_FAILED = 3000, From a5b378fa176fe81cfcb2c480cd7e3ab5d6c8cc40 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Wed, 17 May 2023 16:32:53 +0000 Subject: [PATCH 12/36] wip - fix clang tidy issue --- circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 1a5adf048a05..2d0b7a915d51 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -57,7 +57,6 @@ using aztec3::circuits::apps::test_apps::escrow::deposit; using DummyComposer = aztec3::utils::DummyComposer; -using aztec3::utils::array_push; using CircuitErrorCode = aztec3::utils::CircuitErrorCode; // A type representing any private circuit function From 9a6c83c221f5bf343000386a1de89a4aa7cf0454 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 19 May 2023 08:26:50 +0000 Subject: [PATCH 13/36] wip - fix clang tidy issue --- .../circuits/kernel/private/native_private_kernel_circuit.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 724e5d3c97c5..92056724023f 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -24,7 +24,6 @@ using CircuitErrorCode = aztec3::utils::CircuitErrorCode; using aztec3::circuits::compute_constructor_hash; using aztec3::circuits::compute_contract_address; -using aztec3::circuits::compute_l2_to_l1_hash; using aztec3::circuits::contract_tree_root_from_siblings; using aztec3::circuits::function_tree_root_from_siblings; From 7c07ed355386c3771364a18e719260a174b7f370 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 19 May 2023 09:55:38 +0000 Subject: [PATCH 14/36] wip - fix typescript tests and data structure split --- .../cpp/src/aztec3/circuits/abis/c_bind.cpp | 8 +- .../private_kernel_inputs_init.hpp | 2 +- .../src/abis/__snapshots__/abis.test.ts.snap | 120 ++--- .../kernel/__snapshots__/index.test.ts.snap | 487 ++++++++++++------ .../src/structs/kernel/index.test.ts | 17 +- .../src/structs/kernel/private_kernel.ts | 26 +- .../circuits.js/src/tests/factories.ts | 24 +- 7 files changed, 459 insertions(+), 225 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp index 225ebd6ec181..d122a22e913f 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp @@ -20,6 +20,7 @@ #include "aztec3/circuits/abis/function_data.hpp" #include "aztec3/circuits/abis/function_leaf_preimage.hpp" #include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" #include "aztec3/circuits/abis/signed_tx_request.hpp" #include "aztec3/circuits/abis/types.hpp" #include @@ -480,11 +481,16 @@ WASM_EXPORT const char* abis__test_roundtrip_serialize_signed_tx_request(uint8_t return as_string_output>(input, size); } -WASM_EXPORT const char* abis__test_roundtrip_serialize_private_kernel_inputs(uint8_t const* input, uint32_t* size) +WASM_EXPORT const char* abis__test_roundtrip_serialize_private_kernel_inputs_inner(uint8_t const* input, uint32_t* size) { return as_string_output>(input, size); } +WASM_EXPORT const char* abis__test_roundtrip_serialize_private_kernel_inputs_init(uint8_t const* input, uint32_t* size) +{ + return as_string_output>(input, size); +} + WASM_EXPORT const char* abis__test_roundtrip_serialize_kernel_circuit_public_inputs(uint8_t const* input, uint32_t* size) { diff --git a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp index 3a85cad051aa..c7e90cadd56d 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp +++ b/circuits/cpp/src/aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp @@ -59,7 +59,7 @@ template std::ostream& operator<<(std::ostream& os, PrivateKernel { return os << "signed_tx_request:\n" << private_inputs.signed_tx_request << "\n" - << "previous_kernel:\n" + << "private_call:\n" << private_inputs.private_call << "\n"; } diff --git a/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap b/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap index 3eb2b4dadc87..f1940738b366 100644 --- a/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap +++ b/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap @@ -75,38 +75,38 @@ Fr { exports[`abis wasm bindings hash constructor info (max args) 1`] = ` { "data": [ - 6, - 127, - 250, - 108, + 17, + 65, + 239, + 79, + 136, + 212, + 189, + 51, + 170, + 242, + 156, 115, - 140, - 194, - 58, - 155, - 126, - 77, - 172, - 138, - 33, - 56, - 45, - 60, - 49, - 53, - 1, 132, - 78, - 225, - 189, - 96, - 36, + 149, + 107, + 201, + 106, + 251, + 197, + 32, + 17, + 83, + 157, + 60, 20, - 194, - 195, - 179, - 254, - 239, + 193, + 76, + 148, + 91, + 0, + 240, + 107, ], "type": "Buffer", } @@ -115,38 +115,38 @@ exports[`abis wasm bindings hash constructor info (max args) 1`] = ` exports[`abis wasm bindings hash constructor info 2 args 1`] = ` { "data": [ - 8, - 32, - 166, - 70, - 82, - 251, - 130, - 41, - 118, - 69, - 174, - 93, - 168, - 126, - 225, - 80, - 199, - 219, - 105, - 158, + 6, + 68, 51, - 11, - 131, - 193, - 242, - 88, - 148, - 45, - 101, - 116, - 190, - 202, + 2, + 184, + 173, + 157, + 181, + 176, + 237, + 231, + 126, + 239, + 178, + 163, + 129, + 192, + 31, + 3, + 224, + 40, + 166, + 132, + 231, + 115, + 188, + 48, + 223, + 230, + 76, + 176, + 44, ], "type": "Buffer", } diff --git a/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap b/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap index 31597a9bfa14..e7ee6e413ad0 100644 --- a/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap +++ b/yarn-project/circuits.js/src/structs/kernel/__snapshots__/index.test.ts.snap @@ -288,7 +288,7 @@ vk_path: [ 0x1000 0x1001 0x1002 ] " `; -exports[`structs/kernel serializes and prints private_kernel_inputs 1`] = ` +exports[`structs/kernel serializes and prints private_kernel_inputs_init 1`] = ` "signed_tx_request: tx_request: from: 0x1 @@ -312,87 +312,274 @@ chain_id: 0x501 signature: { 0101010101010101010101010101010101010101010101010101010101010101, 0202020202020202020202020202020202020202020202020202020202020202, 3 } -previous_kernel: +private_call: +call_stack_item: +contract_address: 0x1001 +function_data: function_selector: 4098 +is_private: 1 +is_constructor: 1 + +public_inputs: call_context: msg_sender: 0x1012 +storage_contract_address: 0x1013 +portal_contract_address: 0x1014 +is_delegate_call: 1 +is_static_call: 1 +is_contract_deployment: 1 + +args: [ 0x1111 0x1112 0x1113 0x1114 0x1115 0x1116 0x1117 0x1118 ] +return_values: [ 0x1311 0x1312 0x1313 0x1314 ] +emitted_events: [ 0x1211 0x1212 0x1213 0x1214 ] +new_commitments: [ 0x1411 0x1412 0x1413 0x1414 ] +new_nullifiers: [ 0x1511 0x1512 0x1513 0x1514 ] +private_call_stack: [ 0x1611 0x1612 0x1613 0x1614 ] +public_call_stack: [ 0x1711 0x1712 0x1713 0x1714 ] +new_l2_to_l1_msgs: [ 0x1811 0x1812 ] +historic_private_data_tree_root: 0x2011 +historic_nullifier_tree_root: 0x2111 +historic_contract_tree_root: 0x1911 +historic_l1_to_l2_messages_tree_root: 0x2211 +contract_deployment_data: constructor_vk_hash: 0x1 +function_tree_root: 0x2 +contract_address_salt: 0x3 +portal_contract_address: 0x4 + + +is_execution_request: 0 + +private_call_stack_preimages: +[ contract_address: 0x1011 +function_data: function_selector: 1012 +is_private: 1 +is_constructor: 1 + +public_inputs: call_context: msg_sender: 0x1022 +storage_contract_address: 0x1023 +portal_contract_address: 0x1024 +is_delegate_call: 1 +is_static_call: 1 +is_contract_deployment: 1 + +args: [ 0x1121 0x1122 0x1123 0x1124 0x1125 0x1126 0x1127 0x1128 ] +return_values: [ 0x1321 0x1322 0x1323 0x1324 ] +emitted_events: [ 0x1221 0x1222 0x1223 0x1224 ] +new_commitments: [ 0x1421 0x1422 0x1423 0x1424 ] +new_nullifiers: [ 0x1521 0x1522 0x1523 0x1524 ] +private_call_stack: [ 0x1621 0x1622 0x1623 0x1624 ] +public_call_stack: [ 0x1721 0x1722 0x1723 0x1724 ] +new_l2_to_l1_msgs: [ 0x1821 0x1822 ] +historic_private_data_tree_root: 0x2021 +historic_nullifier_tree_root: 0x2121 +historic_contract_tree_root: 0x1921 +historic_l1_to_l2_messages_tree_root: 0x2221 +contract_deployment_data: constructor_vk_hash: 0x1 +function_tree_root: 0x2 +contract_address_salt: 0x3 +portal_contract_address: 0x4 + + +is_execution_request: 0 + contract_address: 0x1012 +function_data: function_selector: 1013 +is_private: 1 +is_constructor: 1 + +public_inputs: call_context: msg_sender: 0x1023 +storage_contract_address: 0x1024 +portal_contract_address: 0x1025 +is_delegate_call: 1 +is_static_call: 1 +is_contract_deployment: 1 + +args: [ 0x1122 0x1123 0x1124 0x1125 0x1126 0x1127 0x1128 0x1129 ] +return_values: [ 0x1322 0x1323 0x1324 0x1325 ] +emitted_events: [ 0x1222 0x1223 0x1224 0x1225 ] +new_commitments: [ 0x1422 0x1423 0x1424 0x1425 ] +new_nullifiers: [ 0x1522 0x1523 0x1524 0x1525 ] +private_call_stack: [ 0x1622 0x1623 0x1624 0x1625 ] +public_call_stack: [ 0x1722 0x1723 0x1724 0x1725 ] +new_l2_to_l1_msgs: [ 0x1822 0x1823 ] +historic_private_data_tree_root: 0x2022 +historic_nullifier_tree_root: 0x2122 +historic_contract_tree_root: 0x1922 +historic_l1_to_l2_messages_tree_root: 0x2222 +contract_deployment_data: constructor_vk_hash: 0x1 +function_tree_root: 0x2 +contract_address_salt: 0x3 +portal_contract_address: 0x4 + + +is_execution_request: 0 + contract_address: 0x1013 +function_data: function_selector: 1014 +is_private: 1 +is_constructor: 1 + +public_inputs: call_context: msg_sender: 0x1024 +storage_contract_address: 0x1025 +portal_contract_address: 0x1026 +is_delegate_call: 1 +is_static_call: 1 +is_contract_deployment: 1 + +args: [ 0x1123 0x1124 0x1125 0x1126 0x1127 0x1128 0x1129 0x112a ] +return_values: [ 0x1323 0x1324 0x1325 0x1326 ] +emitted_events: [ 0x1223 0x1224 0x1225 0x1226 ] +new_commitments: [ 0x1423 0x1424 0x1425 0x1426 ] +new_nullifiers: [ 0x1523 0x1524 0x1525 0x1526 ] +private_call_stack: [ 0x1623 0x1624 0x1625 0x1626 ] +public_call_stack: [ 0x1723 0x1724 0x1725 0x1726 ] +new_l2_to_l1_msgs: [ 0x1823 0x1824 ] +historic_private_data_tree_root: 0x2023 +historic_nullifier_tree_root: 0x2123 +historic_contract_tree_root: 0x1923 +historic_l1_to_l2_messages_tree_root: 0x2223 +contract_deployment_data: constructor_vk_hash: 0x1 +function_tree_root: 0x2 +contract_address_salt: 0x3 +portal_contract_address: 0x4 + + +is_execution_request: 0 + contract_address: 0x1014 +function_data: function_selector: 1015 +is_private: 1 +is_constructor: 1 + +public_inputs: call_context: msg_sender: 0x1025 +storage_contract_address: 0x1026 +portal_contract_address: 0x1027 +is_delegate_call: 1 +is_static_call: 1 +is_contract_deployment: 1 + +args: [ 0x1124 0x1125 0x1126 0x1127 0x1128 0x1129 0x112a 0x112b ] +return_values: [ 0x1324 0x1325 0x1326 0x1327 ] +emitted_events: [ 0x1224 0x1225 0x1226 0x1227 ] +new_commitments: [ 0x1424 0x1425 0x1426 0x1427 ] +new_nullifiers: [ 0x1524 0x1525 0x1526 0x1527 ] +private_call_stack: [ 0x1624 0x1625 0x1626 0x1627 ] +public_call_stack: [ 0x1724 0x1725 0x1726 0x1727 ] +new_l2_to_l1_msgs: [ 0x1824 0x1825 ] +historic_private_data_tree_root: 0x2024 +historic_nullifier_tree_root: 0x2124 +historic_contract_tree_root: 0x1924 +historic_l1_to_l2_messages_tree_root: 0x2224 +contract_deployment_data: constructor_vk_hash: 0x1 +function_tree_root: 0x2 +contract_address_salt: 0x3 +portal_contract_address: 0x4 + + +is_execution_request: 0 + ] +proof: +[ 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 51 ] +vk: +key.composer_type: 0 +key.circuit_size: 101 +key.num_public_inputs: 102 +key.commitments: [ + A: { 0x200, 0x300 } +] +key.contains_recursive_proof: 1 +key.recursive_proof_public_input_indices: [ 400 401 402 403 404 ] + +function_leaf_membership_witness: +leaf_index: 0x1031 +sibling_path: [ 0x1031 0x1032 0x1033 0x1034 ] + +contract_leaf_membership_witness: +leaf_index: 0x1021 +sibling_path: [ 0x1021 0x1022 0x1023 0x1024 ] + +portal_contract_address: 0x4141414141414141414141414141414141414141 +acir_hash: 0x1061 + +" +`; + +exports[`structs/kernel serializes and prints private_kernel_inputs_inner 1`] = ` +"previous_kernel: public_inputs: end: aggregation_object: -P0: { 0x1001, 0x1002 } -P1: { 0x1101, 0x1102 } +P0: { 0x1, 0x2 } +P1: { 0x101, 0x102 } public_inputs: [ - 0x1003 - 0x1004 - 0x1005 - 0x1006 + 0x3 + 0x4 + 0x5 + 0x6 ] -proof_witness_indices: [ 4103 4104 4105 4106 4107 4108 ] +proof_witness_indices: [ 7 8 9 10 11 12 ] has_data: 0 new_commitments: -[ 0x1101 0x1102 0x1103 0x1104 ] +[ 0x101 0x102 0x103 0x104 ] new_nullifiers: -[ 0x1201 0x1202 0x1203 0x1204 ] +[ 0x201 0x202 0x203 0x204 ] private_call_stack: -[ 0x1301 0x1302 0x1303 0x1304 0x1305 0x1306 0x1307 0x1308 ] +[ 0x301 0x302 0x303 0x304 0x305 0x306 0x307 0x308 ] public_call_stack: -[ 0x1401 0x1402 0x1403 0x1404 0x1405 0x1406 0x1407 0x1408 ] +[ 0x401 0x402 0x403 0x404 0x405 0x406 0x407 0x408 ] new_l2_to_l1_msgs: -[ 0x1501 0x1502 ] +[ 0x501 0x502 ] new_contracts: -[ contract_address: 0x1601 +[ contract_address: 0x601 portal_contract_address: 0x202020202020202020202020202020202020202 -function_tree_root: 0x1603 +function_tree_root: 0x603 ] optionally_revealed_data: -[ call_stack_item_hash: 0x1701 +[ call_stack_item_hash: 0x701 function_data: -function_selector: 1702 +function_selector: 702 is_private: 1 is_constructor: 1 emitted_events: -[ 0x1801 0x1802 0x1803 0x1804 ] -vk_hash: 0x1703 +[ 0x801 0x802 0x803 0x804 ] +vk_hash: 0x703 portal_contract_address: 0x404040404040404040404040404040404040404 pay_fee_from_l1: 1 pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 - call_stack_item_hash: 0x1702 + call_stack_item_hash: 0x702 function_data: -function_selector: 1703 +function_selector: 703 is_private: 1 is_constructor: 1 emitted_events: -[ 0x1802 0x1803 0x1804 0x1805 ] -vk_hash: 0x1704 +[ 0x802 0x803 0x804 0x805 ] +vk_hash: 0x704 portal_contract_address: 0x505050505050505050505050505050505050505 pay_fee_from_l1: 1 pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 - call_stack_item_hash: 0x1703 + call_stack_item_hash: 0x703 function_data: -function_selector: 1704 +function_selector: 704 is_private: 1 is_constructor: 1 emitted_events: -[ 0x1803 0x1804 0x1805 0x1806 ] -vk_hash: 0x1705 +[ 0x803 0x804 0x805 0x806 ] +vk_hash: 0x705 portal_contract_address: 0x606060606060606060606060606060606060606 pay_fee_from_l1: 1 pay_fee_from_public_l2: 0 called_from_l1: 1 called_from_public_l2: 0 - call_stack_item_hash: 0x1704 + call_stack_item_hash: 0x704 function_data: -function_selector: 1705 +function_selector: 705 is_private: 1 is_constructor: 1 emitted_events: -[ 0x1804 0x1805 0x1806 0x1807 ] -vk_hash: 0x1706 +[ 0x804 0x805 0x806 0x807 ] +vk_hash: 0x706 portal_contract_address: 0x707070707070707070707070707070707070707 pay_fee_from_l1: 1 pay_fee_from_public_l2: 0 @@ -400,45 +587,45 @@ called_from_l1: 1 called_from_public_l2: 0 ] public_data_update_requests: -[ leaf_index: 0x1801 -old_value: 0x1802 -new_value: 0x1803 - leaf_index: 0x1802 -old_value: 0x1803 -new_value: 0x1804 - leaf_index: 0x1803 -old_value: 0x1804 -new_value: 0x1805 - leaf_index: 0x1804 -old_value: 0x1805 -new_value: 0x1806 +[ leaf_index: 0x801 +old_value: 0x802 +new_value: 0x803 + leaf_index: 0x802 +old_value: 0x803 +new_value: 0x804 + leaf_index: 0x803 +old_value: 0x804 +new_value: 0x805 + leaf_index: 0x804 +old_value: 0x805 +new_value: 0x806 ] public_data_reads: -[ leaf_index: 0x1901 -value: 0x1902 - leaf_index: 0x1902 -value: 0x1903 - leaf_index: 0x1903 -value: 0x1904 - leaf_index: 0x1904 -value: 0x1905 +[ leaf_index: 0x901 +value: 0x902 + leaf_index: 0x902 +value: 0x903 + leaf_index: 0x903 +value: 0x904 + leaf_index: 0x904 +value: 0x905 ] constants: -historic_tree_roots: private_historic_tree_roots: private_data_tree_root: 0x1101 -nullifier_tree_root: 0x1102 -contract_tree_root: 0x1103 -l1_to_l2_messages_tree_root: 0x1104 -private_kernel_vk_tree_root: 0x1105 +historic_tree_roots: private_historic_tree_roots: private_data_tree_root: 0x101 +nullifier_tree_root: 0x102 +contract_tree_root: 0x103 +l1_to_l2_messages_tree_root: 0x104 +private_kernel_vk_tree_root: 0x105 tx_context: is_fee_payment_tx: 0 is_rebate_payment_tx: 0 is_contract_deployment_tx: 1 contract_deployment_data: -constructor_vk_hash: 0x1105 -function_tree_root: 0x1106 -contract_address_salt: 0x1107 +constructor_vk_hash: 0x105 +function_tree_root: 0x106 +contract_address_salt: 0x107 portal_contract_address: 0x808080808080808080808080808080808080808 @@ -460,30 +647,30 @@ vk_path: [ 0x1000 0x1001 0x1002 ] private_call: call_stack_item: -contract_address: 0x2001 -function_data: function_selector: 8194 +contract_address: 0x1001 +function_data: function_selector: 4098 is_private: 1 is_constructor: 1 -public_inputs: call_context: msg_sender: 0x2012 -storage_contract_address: 0x2013 -portal_contract_address: 0x2014 +public_inputs: call_context: msg_sender: 0x1012 +storage_contract_address: 0x1013 +portal_contract_address: 0x1014 is_delegate_call: 1 is_static_call: 1 is_contract_deployment: 1 -args: [ 0x2111 0x2112 0x2113 0x2114 0x2115 0x2116 0x2117 0x2118 ] -return_values: [ 0x2311 0x2312 0x2313 0x2314 ] -emitted_events: [ 0x2211 0x2212 0x2213 0x2214 ] -new_commitments: [ 0x2411 0x2412 0x2413 0x2414 ] -new_nullifiers: [ 0x2511 0x2512 0x2513 0x2514 ] -private_call_stack: [ 0x2611 0x2612 0x2613 0x2614 ] -public_call_stack: [ 0x2711 0x2712 0x2713 0x2714 ] -new_l2_to_l1_msgs: [ 0x2811 0x2812 ] -historic_private_data_tree_root: 0x3011 -historic_nullifier_tree_root: 0x3111 -historic_contract_tree_root: 0x2911 -historic_l1_to_l2_messages_tree_root: 0x3211 +args: [ 0x1111 0x1112 0x1113 0x1114 0x1115 0x1116 0x1117 0x1118 ] +return_values: [ 0x1311 0x1312 0x1313 0x1314 ] +emitted_events: [ 0x1211 0x1212 0x1213 0x1214 ] +new_commitments: [ 0x1411 0x1412 0x1413 0x1414 ] +new_nullifiers: [ 0x1511 0x1512 0x1513 0x1514 ] +private_call_stack: [ 0x1611 0x1612 0x1613 0x1614 ] +public_call_stack: [ 0x1711 0x1712 0x1713 0x1714 ] +new_l2_to_l1_msgs: [ 0x1811 0x1812 ] +historic_private_data_tree_root: 0x2011 +historic_nullifier_tree_root: 0x2111 +historic_contract_tree_root: 0x1911 +historic_l1_to_l2_messages_tree_root: 0x2211 contract_deployment_data: constructor_vk_hash: 0x1 function_tree_root: 0x2 contract_address_salt: 0x3 @@ -493,30 +680,30 @@ portal_contract_address: 0x4 is_execution_request: 0 private_call_stack_preimages: -[ contract_address: 0x2011 -function_data: function_selector: 2012 +[ contract_address: 0x1011 +function_data: function_selector: 1012 is_private: 1 is_constructor: 1 -public_inputs: call_context: msg_sender: 0x2022 -storage_contract_address: 0x2023 -portal_contract_address: 0x2024 +public_inputs: call_context: msg_sender: 0x1022 +storage_contract_address: 0x1023 +portal_contract_address: 0x1024 is_delegate_call: 1 is_static_call: 1 is_contract_deployment: 1 -args: [ 0x2121 0x2122 0x2123 0x2124 0x2125 0x2126 0x2127 0x2128 ] -return_values: [ 0x2321 0x2322 0x2323 0x2324 ] -emitted_events: [ 0x2221 0x2222 0x2223 0x2224 ] -new_commitments: [ 0x2421 0x2422 0x2423 0x2424 ] -new_nullifiers: [ 0x2521 0x2522 0x2523 0x2524 ] -private_call_stack: [ 0x2621 0x2622 0x2623 0x2624 ] -public_call_stack: [ 0x2721 0x2722 0x2723 0x2724 ] -new_l2_to_l1_msgs: [ 0x2821 0x2822 ] -historic_private_data_tree_root: 0x3021 -historic_nullifier_tree_root: 0x3121 -historic_contract_tree_root: 0x2921 -historic_l1_to_l2_messages_tree_root: 0x3221 +args: [ 0x1121 0x1122 0x1123 0x1124 0x1125 0x1126 0x1127 0x1128 ] +return_values: [ 0x1321 0x1322 0x1323 0x1324 ] +emitted_events: [ 0x1221 0x1222 0x1223 0x1224 ] +new_commitments: [ 0x1421 0x1422 0x1423 0x1424 ] +new_nullifiers: [ 0x1521 0x1522 0x1523 0x1524 ] +private_call_stack: [ 0x1621 0x1622 0x1623 0x1624 ] +public_call_stack: [ 0x1721 0x1722 0x1723 0x1724 ] +new_l2_to_l1_msgs: [ 0x1821 0x1822 ] +historic_private_data_tree_root: 0x2021 +historic_nullifier_tree_root: 0x2121 +historic_contract_tree_root: 0x1921 +historic_l1_to_l2_messages_tree_root: 0x2221 contract_deployment_data: constructor_vk_hash: 0x1 function_tree_root: 0x2 contract_address_salt: 0x3 @@ -524,30 +711,30 @@ portal_contract_address: 0x4 is_execution_request: 0 - contract_address: 0x2012 -function_data: function_selector: 2013 + contract_address: 0x1012 +function_data: function_selector: 1013 is_private: 1 is_constructor: 1 -public_inputs: call_context: msg_sender: 0x2023 -storage_contract_address: 0x2024 -portal_contract_address: 0x2025 +public_inputs: call_context: msg_sender: 0x1023 +storage_contract_address: 0x1024 +portal_contract_address: 0x1025 is_delegate_call: 1 is_static_call: 1 is_contract_deployment: 1 -args: [ 0x2122 0x2123 0x2124 0x2125 0x2126 0x2127 0x2128 0x2129 ] -return_values: [ 0x2322 0x2323 0x2324 0x2325 ] -emitted_events: [ 0x2222 0x2223 0x2224 0x2225 ] -new_commitments: [ 0x2422 0x2423 0x2424 0x2425 ] -new_nullifiers: [ 0x2522 0x2523 0x2524 0x2525 ] -private_call_stack: [ 0x2622 0x2623 0x2624 0x2625 ] -public_call_stack: [ 0x2722 0x2723 0x2724 0x2725 ] -new_l2_to_l1_msgs: [ 0x2822 0x2823 ] -historic_private_data_tree_root: 0x3022 -historic_nullifier_tree_root: 0x3122 -historic_contract_tree_root: 0x2922 -historic_l1_to_l2_messages_tree_root: 0x3222 +args: [ 0x1122 0x1123 0x1124 0x1125 0x1126 0x1127 0x1128 0x1129 ] +return_values: [ 0x1322 0x1323 0x1324 0x1325 ] +emitted_events: [ 0x1222 0x1223 0x1224 0x1225 ] +new_commitments: [ 0x1422 0x1423 0x1424 0x1425 ] +new_nullifiers: [ 0x1522 0x1523 0x1524 0x1525 ] +private_call_stack: [ 0x1622 0x1623 0x1624 0x1625 ] +public_call_stack: [ 0x1722 0x1723 0x1724 0x1725 ] +new_l2_to_l1_msgs: [ 0x1822 0x1823 ] +historic_private_data_tree_root: 0x2022 +historic_nullifier_tree_root: 0x2122 +historic_contract_tree_root: 0x1922 +historic_l1_to_l2_messages_tree_root: 0x2222 contract_deployment_data: constructor_vk_hash: 0x1 function_tree_root: 0x2 contract_address_salt: 0x3 @@ -555,30 +742,30 @@ portal_contract_address: 0x4 is_execution_request: 0 - contract_address: 0x2013 -function_data: function_selector: 2014 + contract_address: 0x1013 +function_data: function_selector: 1014 is_private: 1 is_constructor: 1 -public_inputs: call_context: msg_sender: 0x2024 -storage_contract_address: 0x2025 -portal_contract_address: 0x2026 +public_inputs: call_context: msg_sender: 0x1024 +storage_contract_address: 0x1025 +portal_contract_address: 0x1026 is_delegate_call: 1 is_static_call: 1 is_contract_deployment: 1 -args: [ 0x2123 0x2124 0x2125 0x2126 0x2127 0x2128 0x2129 0x212a ] -return_values: [ 0x2323 0x2324 0x2325 0x2326 ] -emitted_events: [ 0x2223 0x2224 0x2225 0x2226 ] -new_commitments: [ 0x2423 0x2424 0x2425 0x2426 ] -new_nullifiers: [ 0x2523 0x2524 0x2525 0x2526 ] -private_call_stack: [ 0x2623 0x2624 0x2625 0x2626 ] -public_call_stack: [ 0x2723 0x2724 0x2725 0x2726 ] -new_l2_to_l1_msgs: [ 0x2823 0x2824 ] -historic_private_data_tree_root: 0x3023 -historic_nullifier_tree_root: 0x3123 -historic_contract_tree_root: 0x2923 -historic_l1_to_l2_messages_tree_root: 0x3223 +args: [ 0x1123 0x1124 0x1125 0x1126 0x1127 0x1128 0x1129 0x112a ] +return_values: [ 0x1323 0x1324 0x1325 0x1326 ] +emitted_events: [ 0x1223 0x1224 0x1225 0x1226 ] +new_commitments: [ 0x1423 0x1424 0x1425 0x1426 ] +new_nullifiers: [ 0x1523 0x1524 0x1525 0x1526 ] +private_call_stack: [ 0x1623 0x1624 0x1625 0x1626 ] +public_call_stack: [ 0x1723 0x1724 0x1725 0x1726 ] +new_l2_to_l1_msgs: [ 0x1823 0x1824 ] +historic_private_data_tree_root: 0x2023 +historic_nullifier_tree_root: 0x2123 +historic_contract_tree_root: 0x1923 +historic_l1_to_l2_messages_tree_root: 0x2223 contract_deployment_data: constructor_vk_hash: 0x1 function_tree_root: 0x2 contract_address_salt: 0x3 @@ -586,30 +773,30 @@ portal_contract_address: 0x4 is_execution_request: 0 - contract_address: 0x2014 -function_data: function_selector: 2015 + contract_address: 0x1014 +function_data: function_selector: 1015 is_private: 1 is_constructor: 1 -public_inputs: call_context: msg_sender: 0x2025 -storage_contract_address: 0x2026 -portal_contract_address: 0x2027 +public_inputs: call_context: msg_sender: 0x1025 +storage_contract_address: 0x1026 +portal_contract_address: 0x1027 is_delegate_call: 1 is_static_call: 1 is_contract_deployment: 1 -args: [ 0x2124 0x2125 0x2126 0x2127 0x2128 0x2129 0x212a 0x212b ] -return_values: [ 0x2324 0x2325 0x2326 0x2327 ] -emitted_events: [ 0x2224 0x2225 0x2226 0x2227 ] -new_commitments: [ 0x2424 0x2425 0x2426 0x2427 ] -new_nullifiers: [ 0x2524 0x2525 0x2526 0x2527 ] -private_call_stack: [ 0x2624 0x2625 0x2626 0x2627 ] -public_call_stack: [ 0x2724 0x2725 0x2726 0x2727 ] -new_l2_to_l1_msgs: [ 0x2824 0x2825 ] -historic_private_data_tree_root: 0x3024 -historic_nullifier_tree_root: 0x3124 -historic_contract_tree_root: 0x2924 -historic_l1_to_l2_messages_tree_root: 0x3224 +args: [ 0x1124 0x1125 0x1126 0x1127 0x1128 0x1129 0x112a 0x112b ] +return_values: [ 0x1324 0x1325 0x1326 0x1327 ] +emitted_events: [ 0x1224 0x1225 0x1226 0x1227 ] +new_commitments: [ 0x1424 0x1425 0x1426 0x1427 ] +new_nullifiers: [ 0x1524 0x1525 0x1526 0x1527 ] +private_call_stack: [ 0x1624 0x1625 0x1626 0x1627 ] +public_call_stack: [ 0x1724 0x1725 0x1726 0x1727 ] +new_l2_to_l1_msgs: [ 0x1824 0x1825 ] +historic_private_data_tree_root: 0x2024 +historic_nullifier_tree_root: 0x2124 +historic_contract_tree_root: 0x1924 +historic_l1_to_l2_messages_tree_root: 0x2224 contract_deployment_data: constructor_vk_hash: 0x1 function_tree_root: 0x2 contract_address_salt: 0x3 @@ -631,15 +818,15 @@ key.contains_recursive_proof: 1 key.recursive_proof_public_input_indices: [ 400 401 402 403 404 ] function_leaf_membership_witness: -leaf_index: 0x2031 -sibling_path: [ 0x2031 0x2032 0x2033 0x2034 ] +leaf_index: 0x1031 +sibling_path: [ 0x1031 0x1032 0x1033 0x1034 ] contract_leaf_membership_witness: -leaf_index: 0x2021 -sibling_path: [ 0x2021 0x2022 0x2023 0x2024 ] +leaf_index: 0x1021 +sibling_path: [ 0x1021 0x1022 0x1023 0x1024 ] portal_contract_address: 0x4141414141414141414141414141414141414141 -acir_hash: 0x2061 +acir_hash: 0x1061 " `; diff --git a/yarn-project/circuits.js/src/structs/kernel/index.test.ts b/yarn-project/circuits.js/src/structs/kernel/index.test.ts index 31e65d701b1a..ec27d316c3ad 100644 --- a/yarn-project/circuits.js/src/structs/kernel/index.test.ts +++ b/yarn-project/circuits.js/src/structs/kernel/index.test.ts @@ -3,7 +3,8 @@ import { makeSignedTxRequest } from '../../tests/factories.js'; import { makeEcdsaSignature } from '../../tests/factories.js'; import { makePreviousKernelData, - makePrivateKernelInputs, + makePrivateKernelInputsInner, + makePrivateKernelInputsInit, makeKernelPublicInputs, makePublicKernelInputsNoKernelInput, makePublicKernelInputs, @@ -19,11 +20,19 @@ describe('structs/kernel', () => { ); }); - it(`serializes and prints private_kernel_inputs`, async () => { - const kernelInputs = makePrivateKernelInputs(); + it(`serializes and prints private_kernel_inputs_init`, async () => { + const kernelInputs = makePrivateKernelInputsInit(); await expectSerializeToMatchSnapshot( kernelInputs.toBuffer(), - 'abis__test_roundtrip_serialize_private_kernel_inputs', + 'abis__test_roundtrip_serialize_private_kernel_inputs_init', + ); + }); + + it(`serializes and prints private_kernel_inputs_inner`, async () => { + const kernelInputs = makePrivateKernelInputsInner(); + await expectSerializeToMatchSnapshot( + kernelInputs.toBuffer(), + 'abis__test_roundtrip_serialize_private_kernel_inputs_inner', ); }); diff --git a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts index cf3cc940bcfe..adacf70d672e 100644 --- a/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts +++ b/yarn-project/circuits.js/src/structs/kernel/private_kernel.ts @@ -86,14 +86,34 @@ export class PrivateCallData { } /** - * Input to the private kernel circuit. + * Input to the private kernel circuit - initial call. */ -export class PrivateKernelInputs { +export class PrivateKernelInputsInit { constructor( /** * The transaction request which led to the creation of these inputs. */ public signedTxRequest: SignedTxRequest, + /** + * Private calldata corresponding to this iteration of the kernel. + */ + public privateCall: PrivateCallData, + ) {} + + /** + * Serialize this as a buffer. + * @returns The buffer. + */ + toBuffer() { + return serializeToBuffer(this.signedTxRequest, this.privateCall); + } +} + +/** + * Input to the private kernel circuit - Inner call. + */ +export class PrivateKernelInputsInner { + constructor( /** * The previous kernel data (dummy if this is the first kernel). */ @@ -109,7 +129,7 @@ export class PrivateKernelInputs { * @returns The buffer. */ toBuffer() { - return serializeToBuffer(this.signedTxRequest, this.previousKernel, this.privateCall); + return serializeToBuffer(this.previousKernel, this.privateCall); } } diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index b1909a789680..353d37c06117 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -24,7 +24,8 @@ import { PrivateCallData, PrivateCircuitPublicInputs, PrivateHistoricTreeRoots, - PrivateKernelInputs, + PrivateKernelInputsInit, + PrivateKernelInputsInner, PublicCallData, PublicCircuitPublicInputs, PublicDataRead, @@ -392,15 +393,26 @@ export function makeProof(seed = 1) { } /** - * Makes arbitrary private kernel inputs. + * Makes arbitrary private kernel inputs - initial call. * @param seed - The seed to use for generating the private kernel inputs. * @returns Private kernel inputs. */ -export function makePrivateKernelInputs(seed = 1): PrivateKernelInputs { - return new PrivateKernelInputs( +export function makePrivateKernelInputsInit(seed = 1): PrivateKernelInputsInit { + return new PrivateKernelInputsInit( makeSignedTxRequest(seed), - makePreviousKernelData(seed + 0x1000), - makePrivateCallData(seed + 0x2000), + makePrivateCallData(seed + 0x1000), + ); +} + +/** + * Makes arbitrary private kernel inputs - inner call. + * @param seed - The seed to use for generating the private kernel inputs. + * @returns Private kernel inputs. + */ +export function makePrivateKernelInputsInner(seed = 1): PrivateKernelInputsInner { + return new PrivateKernelInputsInner( + makePreviousKernelData(seed), + makePrivateCallData(seed + 0x1000), ); } From 0b5dc0e70ce3cca3ed34bae34aca76b836d99ab0 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 19 May 2023 11:18:35 +0000 Subject: [PATCH 15/36] wip - format typescript --- yarn-project/circuits.js/src/tests/factories.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/yarn-project/circuits.js/src/tests/factories.ts b/yarn-project/circuits.js/src/tests/factories.ts index 353d37c06117..3ea5a710f8fa 100644 --- a/yarn-project/circuits.js/src/tests/factories.ts +++ b/yarn-project/circuits.js/src/tests/factories.ts @@ -398,10 +398,7 @@ export function makeProof(seed = 1) { * @returns Private kernel inputs. */ export function makePrivateKernelInputsInit(seed = 1): PrivateKernelInputsInit { - return new PrivateKernelInputsInit( - makeSignedTxRequest(seed), - makePrivateCallData(seed + 0x1000), - ); + return new PrivateKernelInputsInit(makeSignedTxRequest(seed), makePrivateCallData(seed + 0x1000)); } /** @@ -410,10 +407,7 @@ export function makePrivateKernelInputsInit(seed = 1): PrivateKernelInputsInit { * @returns Private kernel inputs. */ export function makePrivateKernelInputsInner(seed = 1): PrivateKernelInputsInner { - return new PrivateKernelInputsInner( - makePreviousKernelData(seed), - makePrivateCallData(seed + 0x1000), - ); + return new PrivateKernelInputsInner(makePreviousKernelData(seed), makePrivateCallData(seed + 0x1000)); } /** From 7df14002a800385c2de095390fa18492dcbeb8ad Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 19 May 2023 12:19:05 +0000 Subject: [PATCH 16/36] wip - replace CONSTRUCTOR_ARGS by FUNCTION_ARGS --- circuits/cpp/src/aztec3/constants.hpp | 3 +- .../src/abis/__snapshots__/abis.test.ts.snap | 156 +++++++----------- .../circuits.js/src/structs/generators.ts | 2 +- 3 files changed, 60 insertions(+), 101 deletions(-) diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index e1379d30710e..2b2d6ff9057f 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -72,7 +72,7 @@ enum GeneratorIndex { FUNCTION_LEAF, CONTRACT_DEPLOYMENT_DATA, CONSTRUCTOR, - CONSTRUCTOR_ARGS, + FUNCTION_ARGS, CONTRACT_ADDRESS, CONTRACT_LEAF, CALL_CONTEXT, @@ -87,7 +87,6 @@ enum GeneratorIndex { PUBLIC_DATA_LEAF, SIGNED_TX_REQUEST, L1_TO_L2_MESSAGE_SECRET, - FUNCTION_ARGS, }; enum StorageSlotGeneratorIndex { diff --git a/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap b/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap index f1940738b366..0bfb2e1906ec 100644 --- a/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap +++ b/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap @@ -75,38 +75,38 @@ Fr { exports[`abis wasm bindings hash constructor info (max args) 1`] = ` { "data": [ - 17, - 65, - 239, - 79, - 136, - 212, - 189, - 51, - 170, - 242, - 156, + 6, + 127, + 250, + 108, 115, - 132, - 149, - 107, - 201, - 106, - 251, - 197, - 32, - 17, - 83, - 157, + 140, + 194, + 58, + 155, + 126, + 77, + 172, + 138, + 33, + 56, + 45, 60, + 49, + 53, + 1, + 132, + 78, + 225, + 189, + 96, + 36, 20, - 193, - 76, - 148, - 91, - 0, - 240, - 107, + 194, + 195, + 179, + 254, + 239, ], "type": "Buffer", } @@ -115,78 +115,38 @@ exports[`abis wasm bindings hash constructor info (max args) 1`] = ` exports[`abis wasm bindings hash constructor info 2 args 1`] = ` { "data": [ - 6, - 68, - 51, - 2, - 184, - 173, - 157, - 181, - 176, - 237, - 231, - 126, - 239, - 178, - 163, - 129, - 192, - 31, - 3, - 224, - 40, + 8, + 32, 166, - 132, - 231, - 115, - 188, - 48, - 223, - 230, - 76, - 176, - 44, - ], - "type": "Buffer", -} -`; - -exports[`abis wasm bindings hashes VK 1`] = ` -Object { - "data": Array [ - 3, - 215, - 112, - 230, - 112, + 70, + 82, + 251, + 130, + 41, + 118, + 69, + 174, + 93, 168, - 8, - 190, - 95, - 206, - 52, - 172, - 46, - 85, - 55, + 126, + 225, + 80, + 199, + 219, + 105, + 158, + 51, + 11, + 131, + 193, + 242, + 88, + 148, + 45, + 101, + 116, 190, - 134, - 187, - 169, - 57, - 109, - 253, - 250, - 109, - 224, - 150, - 49, - 156, - 32, - 17, - 205, - 37, + 202, ], "type": "Buffer", } diff --git a/yarn-project/circuits.js/src/structs/generators.ts b/yarn-project/circuits.js/src/structs/generators.ts index b827ee3b7345..3a1f3fa66069 100644 --- a/yarn-project/circuits.js/src/structs/generators.ts +++ b/yarn-project/circuits.js/src/structs/generators.ts @@ -17,7 +17,7 @@ export enum GeneratorIndex { FUNCTION_LEAF, CONTRACT_DEPLOYMENT_DATA, CONSTRUCTOR, - CONSTRUCTOR_ARGS, + FUNCTION_ARGS, CONTRACT_ADDRESS, CONTRACT_LEAF, CALL_CONTEXT, From f0ae6630f34334b63255132dfd1f4239b98c2bfa Mon Sep 17 00:00:00 2001 From: jeanmon Date: Fri, 19 May 2023 15:12:56 +0000 Subject: [PATCH 17/36] wip - add nullifier and l1-l2-message tree roots in initial private kernel circuit --- .../kernel/private/native_private_kernel_circuit_initial.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index b5c08203bf74..3e982c2b266b 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -49,7 +49,9 @@ void initialise_end_values(PrivateKernelInputsInit const& private_inputs, .private_historic_tree_roots = PrivateHistoricTreeRoots{ .private_data_tree_root = private_call_public_inputs.historic_private_data_tree_root, + .nullifier_tree_root = private_call_public_inputs.historic_nullifier_tree_root, .contract_tree_root = private_call_public_inputs.historic_contract_tree_root, + .l1_to_l2_messages_tree_root = private_call_public_inputs.historic_l1_to_l2_messages_tree_root, }, }, .tx_context = private_inputs.signed_tx_request.tx_request.tx_context, From 9bbef1c64183e772ef2ce421d710239614ac124c Mon Sep 17 00:00:00 2001 From: jeanmon Date: Mon, 22 May 2023 13:09:10 +0000 Subject: [PATCH 18/36] wip - post merge fix --- .../aztec3/circuits/kernel/private/.test.cpp | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index d365e0289e1b..e9542e187779 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -688,23 +688,4 @@ TEST(private_kernel_tests, cbind_private_kernel__dummy_previous_kernel) EXPECT_EQ(actual_ss.str(), expected_ss.str()); } -/** - * @brief Test error is registered when `new_nullifiers` are not empty in first iteration - */ -TEST(private_kernel_tests, native_registers_error_when_no_space_for_nullifier) -{ - NT::fr const& amount = 5; - NT::fr const& asset_id = 1; - NT::fr const& memo = 999; - - auto private_inputs = do_private_call_get_kernel_inputs(false, deposit, { amount, asset_id, memo }); - array_push(private_inputs.previous_kernel.public_inputs.end.new_nullifiers, NT::fr::random_element()); - - DummyComposer composer = DummyComposer("private_kernel_tests__native_registers_error_when_no_space_for_nullifier"); - native_private_kernel_circuit(composer, private_inputs, true); - - ASSERT_EQ(composer.get_first_failure().code, - CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_IN_FIRST_ITERATION); -} - } // namespace aztec3::circuits::kernel::private_kernel From e71af787d65bf62dc48198432a4fd2244680df9b Mon Sep 17 00:00:00 2001 From: jeanmon Date: Mon, 22 May 2023 16:52:30 +0000 Subject: [PATCH 19/36] Migrate common.hpp functions into non-templated ones --- .../aztec3/circuits/kernel/private/common.cpp | 109 ++++++++++++++++ .../aztec3/circuits/kernel/private/common.hpp | 119 ++---------------- .../private/native_private_kernel_circuit.cpp | 4 +- .../native_private_kernel_circuit_initial.cpp | 9 +- 4 files changed, 126 insertions(+), 115 deletions(-) create mode 100644 circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp new file mode 100644 index 000000000000..01a458798d0e --- /dev/null +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp @@ -0,0 +1,109 @@ +#include "init.hpp" + +#include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" +#include "aztec3/circuits/abis/new_contract_data.hpp" +#include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" +#include "aztec3/circuits/hash.hpp" +#include "aztec3/constants.hpp" +#include "aztec3/utils/array.hpp" +#include "aztec3/utils/dummy_composer.hpp" + +using DummyComposer = aztec3::utils::DummyComposer; + +using aztec3::circuits::abis::ContractLeafPreimage; +using aztec3::circuits::abis::KernelCircuitPublicInputs; + +using aztec3::utils::is_array_empty; +using aztec3::utils::push_array_to_array; +using DummyComposer = aztec3::utils::DummyComposer; +using CircuitErrorCode = aztec3::utils::CircuitErrorCode; +using aztec3::circuits::abis::private_kernel::PrivateCallData; + +namespace aztec3::circuits::kernel::private_kernel { + +void common_validate_call_stack(DummyComposer& composer, PrivateCallData const& private_call) +{ + const auto& stack = private_call.call_stack_item.public_inputs.private_call_stack; + const auto& preimages = private_call.private_call_stack_preimages; + for (size_t i = 0; i < stack.size(); ++i) { + const auto& hash = stack[i]; + const auto& preimage = preimages[i]; + + // Note: this assumes it's computationally infeasible to have `0` as a valid call_stack_item_hash. + // Assumes `hash == 0` means "this stack item is empty". + const auto calculated_hash = hash == 0 ? 0 : preimage.hash(); + composer.do_assert(hash == calculated_hash, + format("private_call_stack[", i, "] = ", hash, "; does not reconcile"), + CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_ITEM_HASH_MISMATCH); + } +} + +void common_update_end_values(DummyComposer& composer, + PrivateCallData const& private_call, + KernelCircuitPublicInputs& public_inputs) +{ + const auto private_call_public_inputs = private_call.call_stack_item.public_inputs; + + const auto& new_commitments = private_call_public_inputs.new_commitments; + const auto& new_nullifiers = private_call_public_inputs.new_nullifiers; + + const auto& is_static_call = private_call_public_inputs.call_context.is_static_call; + + if (is_static_call) { + // No state changes are allowed for static calls: + composer.do_assert(is_array_empty(new_commitments) == true, + "new_commitments must be empty for static calls", + CircuitErrorCode::PRIVATE_KERNEL__NEW_COMMITMENTS_NOT_EMPTY_FOR_STATIC_CALL); + composer.do_assert(is_array_empty(new_nullifiers) == true, + "new_nullifiers must be empty for static calls", + CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_FOR_STATIC_CALL); + } + + const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; + + // Enhance commitments and nullifiers with domain separation whereby domain is the contract. + { // commitments & nullifiers + std::array siloed_new_commitments; + for (size_t i = 0; i < new_commitments.size(); ++i) { + siloed_new_commitments[i] = new_commitments[i] == 0 ? 0 + : add_contract_address_to_commitment( + storage_contract_address, new_commitments[i]); + } + + std::array siloed_new_nullifiers; + for (size_t i = 0; i < new_nullifiers.size(); ++i) { + siloed_new_nullifiers[i] = new_nullifiers[i] == 0 ? 0 + : add_contract_address_to_nullifier( + storage_contract_address, new_nullifiers[i]); + } + + push_array_to_array(siloed_new_commitments, public_inputs.end.new_commitments); + push_array_to_array(siloed_new_nullifiers, public_inputs.end.new_nullifiers); + } + + { // call stacks + const auto& this_private_call_stack = private_call_public_inputs.private_call_stack; + push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); + } + + { // new l2 to l1 messages + const auto& portal_contract_address = private_call.portal_contract_address; + const auto& new_l2_to_l1_msgs = private_call_public_inputs.new_l2_to_l1_msgs; + std::array new_l2_to_l1_msgs_to_insert; + for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) { + if (!new_l2_to_l1_msgs[i].is_zero()) { + // @todo @LHerskind chain-ids and rollup version id should be added here. Right now, just hard coded. + // @todo @LHerskind chain-id is hardcoded for foundry + const auto chain_id = fr(31337); + new_l2_to_l1_msgs_to_insert[i] = compute_l2_to_l1_hash(storage_contract_address, + fr(1), // rollup version id + portal_contract_address, + chain_id, + new_l2_to_l1_msgs[i]); + } + } + push_array_to_array(new_l2_to_l1_msgs_to_insert, public_inputs.end.new_l2_to_l1_msgs); + } +} + +} // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp index 2d9eec0d9292..12351e2fd673 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -3,122 +3,19 @@ #include "init.hpp" #include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" -#include "aztec3/circuits/abis/new_contract_data.hpp" -#include "aztec3/circuits/hash.hpp" -#include "aztec3/constants.hpp" -#include "aztec3/utils/array.hpp" +#include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include "aztec3/utils/dummy_composer.hpp" -using DummyComposer = aztec3::utils::DummyComposer; - -using aztec3::circuits::abis::ContractLeafPreimage; -using aztec3::circuits::abis::KernelCircuitPublicInputs; - -using aztec3::utils::is_array_empty; -using aztec3::utils::push_array_to_array; -using DummyComposer = aztec3::utils::DummyComposer; -using CircuitErrorCode = aztec3::utils::CircuitErrorCode; - - namespace aztec3::circuits::kernel::private_kernel { -template -void common_validate_call_stack(DummyComposer& composer, KernelPrivateInput const& private_inputs) -{ - const auto& stack = private_inputs.private_call.call_stack_item.public_inputs.private_call_stack; - const auto& preimages = private_inputs.private_call.private_call_stack_preimages; - for (size_t i = 0; i < stack.size(); ++i) { - const auto& hash = stack[i]; - const auto& preimage = preimages[i]; - - // Note: this assumes it's computationally infeasible to have `0` as a valid call_stack_item_hash. - // Assumes `hash == 0` means "this stack item is empty". - const auto calculated_hash = hash == 0 ? 0 : preimage.hash(); - composer.do_assert(hash == calculated_hash, - format("private_call_stack[", i, "] = ", hash, "; does not reconcile"), - CircuitErrorCode::PRIVATE_KERNEL__PRIVATE_CALL_STACK_ITEM_HASH_MISMATCH); - } -} - -/** - * @brief Validates the kernel execution of the current iteration - * @tparam The type of kernel input - * @param composer The circuit composer - * @param public_kernel_inputs The inputs to this iteration of the kernel circuit - */ -template -void common_validate_kernel_execution(DummyComposer& composer, KernelInput const& private_inputs) -{ - common_validate_call_context(composer, private_inputs); - common_validate_call_stack(composer, private_inputs); -}; - -template void common_update_end_values(DummyComposer& composer, - KernelPrivateInput const& private_inputs, - KernelCircuitPublicInputs& public_inputs) -{ - const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; - - const auto& new_commitments = private_call_public_inputs.new_commitments; - const auto& new_nullifiers = private_call_public_inputs.new_nullifiers; - - const auto& is_static_call = private_call_public_inputs.call_context.is_static_call; - - if (is_static_call) { - // No state changes are allowed for static calls: - composer.do_assert(is_array_empty(new_commitments) == true, - "new_commitments must be empty for static calls", - CircuitErrorCode::PRIVATE_KERNEL__NEW_COMMITMENTS_NOT_EMPTY_FOR_STATIC_CALL); - composer.do_assert(is_array_empty(new_nullifiers) == true, - "new_nullifiers must be empty for static calls", - CircuitErrorCode::PRIVATE_KERNEL__NEW_NULLIFIERS_NOT_EMPTY_FOR_STATIC_CALL); - } - - const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - - // Enhance commitments and nullifiers with domain separation whereby domain is the contract. - { // commitments & nullifiers - std::array siloed_new_commitments; - for (size_t i = 0; i < new_commitments.size(); ++i) { - siloed_new_commitments[i] = new_commitments[i] == 0 ? 0 - : add_contract_address_to_commitment( - storage_contract_address, new_commitments[i]); - } - - std::array siloed_new_nullifiers; - for (size_t i = 0; i < new_nullifiers.size(); ++i) { - siloed_new_nullifiers[i] = new_nullifiers[i] == 0 ? 0 - : add_contract_address_to_nullifier( - storage_contract_address, new_nullifiers[i]); - } - - push_array_to_array(siloed_new_commitments, public_inputs.end.new_commitments); - push_array_to_array(siloed_new_nullifiers, public_inputs.end.new_nullifiers); - } +using DummyComposer = aztec3::utils::DummyComposer; +using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::private_kernel::PrivateCallData; - { // call stacks - const auto& this_private_call_stack = private_call_public_inputs.private_call_stack; - push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); - } +void common_validate_call_stack(DummyComposer& composer, PrivateCallData const& private_call); - { // new l2 to l1 messages - const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; - const auto& new_l2_to_l1_msgs = private_call_public_inputs.new_l2_to_l1_msgs; - std::array new_l2_to_l1_msgs_to_insert; - for (size_t i = 0; i < new_l2_to_l1_msgs.size(); ++i) { - if (!new_l2_to_l1_msgs[i].is_zero()) { - // @todo @LHerskind chain-ids and rollup version id should be added here. Right now, just hard coded. - // @todo @LHerskind chain-id is hardcoded for foundry - const auto chain_id = fr(31337); - new_l2_to_l1_msgs_to_insert[i] = compute_l2_to_l1_hash(storage_contract_address, - fr(1), // rollup version id - portal_contract_address, - chain_id, - new_l2_to_l1_msgs[i]); - } - } - push_array_to_array(new_l2_to_l1_msgs_to_insert, public_inputs.end.new_l2_to_l1_msgs); - } -} +void common_update_end_values(DummyComposer& composer, + PrivateCallData const& private_call, + KernelCircuitPublicInputs& public_inputs); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 92056724023f..7cb070277dfd 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -257,9 +257,9 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo // Noir doesn't have hash index so it can't hash private call stack item correctly // validate_this_private_call_stack(composer, private_inputs); // TODO(dbanks12): may need to comment out hash check in here according to TODO above - common_validate_call_stack(composer, private_inputs); + common_validate_call_stack(composer, private_inputs.private_call); - common_update_end_values(composer, private_inputs, public_inputs); + common_update_end_values(composer, private_inputs.private_call, public_inputs); contract_logic(composer, private_inputs, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index 3e982c2b266b..e65bf111eeee 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -5,7 +5,10 @@ #include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/abis/private_historic_tree_roots.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" +#include "aztec3/circuits/hash.hpp" #include "aztec3/circuits/kernel/private/init.hpp" +#include "aztec3/constants.hpp" +#include "aztec3/utils/array.hpp" using aztec3::circuits::abis::CombinedConstantData; using aztec3::circuits::abis::CombinedHistoricTreeRoots; @@ -13,6 +16,8 @@ using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; using aztec3::utils::array_push; +using aztec3::utils::is_array_empty; +using CircuitErrorCode = aztec3::utils::CircuitErrorCode; namespace aztec3::circuits::kernel::private_kernel { @@ -256,11 +261,11 @@ KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyCompose validate_this_private_call_against_tx_request(composer, private_inputs); - common_validate_call_stack>(composer, private_inputs); + common_validate_call_stack(composer, private_inputs.private_call); update_end_values(private_inputs, public_inputs); - common_update_end_values>(composer, private_inputs, public_inputs); + common_update_end_values(composer, private_inputs.private_call, public_inputs); contract_logic(composer, private_inputs, public_inputs); From 886363bdb5765a679d2844553c89ff16025ebf45 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Mon, 22 May 2023 06:17:09 -0700 Subject: [PATCH 20/36] refactor(sol): use Hash.sha256ToField library where required (#637) * refactor(sol): use Hash.sha256ToField library where required * fmt :) * feat: expose bytes32 hash directly * fmt: https://i.pinimg.com/originals/81/23/a1/8123a132c007eab782d6ca9bed517eb3.jpg --------- Co-authored-by: Maddiaa0 --- l1-contracts/src/core/Decoder.sol | 10 ++++---- l1-contracts/src/core/libraries/Hash.sol | 10 ++++++++ l1-contracts/test/Decoder.t.sol | 29 +++++++----------------- 3 files changed, 22 insertions(+), 27 deletions(-) diff --git a/l1-contracts/src/core/Decoder.sol b/l1-contracts/src/core/Decoder.sol index aa87a1c4220d..1d49a2428d71 100644 --- a/l1-contracts/src/core/Decoder.sol +++ b/l1-contracts/src/core/Decoder.sol @@ -2,6 +2,8 @@ // Copyright 2023 Aztec Labs. pragma solidity >=0.8.18; +import {Hash} from "@aztec/core/libraries/Hash.sol"; + /** * @title Decoder * @author Aztec Labs @@ -108,10 +110,6 @@ contract Decoder { uint256 internal constant CONTRACTS_PER_KERNEL = 1; uint256 internal constant L1_TO_L2_MSGS_PER_ROLLUP = 16; - // Prime field order - uint256 internal constant P = - 21888242871839275222246405745257275088548364400416034343698204186575808495617; - /** * @notice Decodes the inputs and computes values to check state against * @param _l2Block - The L2 block calldata. @@ -167,7 +165,7 @@ contract Decoder { mstore(add(temp, add(0x20, endOfTreesData)), _diffRoot) mstore(add(temp, add(0x40, endOfTreesData)), _l1ToL2MsgsHash) } - return bytes32(uint256(sha256(temp)) % P); + return Hash.sha256ToField(temp); } /** @@ -504,7 +502,7 @@ contract Decoder { // Compute current iteration's logs hash and truncate the hash to field // See: https://discourse.aztec.network/t/proposal-forcing-the-sequencer-to-actually-submit-data-to-l1/426/2 - logsHash = bytes32(uint256(sha256(temp)) % P); + logsHash = Hash.sha256ToField(temp); } return (logsHash, offset); diff --git a/l1-contracts/src/core/libraries/Hash.sol b/l1-contracts/src/core/libraries/Hash.sol index 4f3be42a996b..fa56fb1b83ad 100644 --- a/l1-contracts/src/core/libraries/Hash.sol +++ b/l1-contracts/src/core/libraries/Hash.sol @@ -47,4 +47,14 @@ library Hash { function sha256ToField(bytes memory _data) internal pure returns (bytes32) { return bytes32(uint256(sha256(_data)) % Constants.P); } + + /** + * @notice Computes the sha256 hash of the provided data and converts it to a field element + * @dev Using modulo to convert the hash to a field element. + * @param _data - A bytes32 value to hash + * @return The hash of the provided data as a field element + */ + function sha256ToField(bytes32 _data) internal pure returns (bytes32) { + return sha256ToField(abi.encodePacked(_data)); + } } diff --git a/l1-contracts/test/Decoder.t.sol b/l1-contracts/test/Decoder.t.sol index bf6b00b6a9a1..142fde9e87cd 100644 --- a/l1-contracts/test/Decoder.t.sol +++ b/l1-contracts/test/Decoder.t.sol @@ -5,7 +5,7 @@ pragma solidity >=0.8.18; import {Test} from "forge-std/Test.sol"; import {Decoder} from "@aztec/core/Decoder.sol"; -import {Constants} from "@aztec/core/libraries/Constants.sol"; +import {Hash} from "@aztec/core/libraries/Hash.sol"; import {DecoderHelper} from "./DecoderHelper.sol"; /** @@ -144,12 +144,9 @@ contract DecoderTest is Test { // Note: First 32 bytes are 0 because those correspond to the hash of previous iteration and there was no previous // iteration. - bytes32 referenceLogsHash = bytes32( - uint256( - sha256( - hex"0000000000000000000000000000000000000000000000000000000000000000aafdc7aa93e78a70" - ) - ) % Constants.P + + bytes32 referenceLogsHash = Hash.sha256ToField( + hex"0000000000000000000000000000000000000000000000000000000000000000aafdc7aa93e78a70" ); assertEq(bytesAdvanced, emptyKernelData.length, "Advanced by an incorrect number of bytes"); @@ -167,22 +164,12 @@ contract DecoderTest is Test { hex"0000002400000008aafdc7aa93e78a700000001497aee30906a86173c86c6d3f108eefc36e7fb014"; (bytes32 logsHash, uint256 bytesAdvanced) = helper.computeKernelLogsHash(emptyKernelData); - bytes32 referenceLogsHashFromIteration1 = bytes32( - uint256( - sha256( - hex"0000000000000000000000000000000000000000000000000000000000000000aafdc7aa93e78a70" - ) - ) % Constants.P + bytes32 referenceLogsHashFromIteration1 = Hash.sha256ToField( + hex"0000000000000000000000000000000000000000000000000000000000000000aafdc7aa93e78a70" ); - bytes32 referenceLogsHashFromIteration2 = bytes32( - uint256( - sha256( - bytes.concat( - referenceLogsHashFromIteration1, hex"97aee30906a86173c86c6d3f108eefc36e7fb014" - ) - ) - ) % Constants.P + bytes32 referenceLogsHashFromIteration2 = Hash.sha256ToField( + bytes.concat(referenceLogsHashFromIteration1, hex"97aee30906a86173c86c6d3f108eefc36e7fb014") ); assertEq(bytesAdvanced, emptyKernelData.length, "Advanced by an incorrect number of bytes"); From 3cd529328b499c193118c932e69585a7142b7136 Mon Sep 17 00:00:00 2001 From: Lasse Herskind <16536249+LHerskind@users.noreply.github.com> Date: Mon, 22 May 2023 16:07:12 +0100 Subject: [PATCH 21/36] fix: Add checks for arg-type (#638) * fix: Add checks for arg-type * fix: support arg of 'number' type * fix: correct wrapped fr in acir sim * no need to force encode in some e2e tests! --------- Co-authored-by: Maddiaa0 Co-authored-by: Rahul Kothari --- .../acir-simulator/src/abi_coder/encoder.ts | 12 ++++++++- .../src/client/private_execution.test.ts | 11 +++----- .../src/e2e_nested_contract.test.ts | 26 +++++-------------- .../e2e_rollup_native_asset_contract.test.ts | 6 +---- 4 files changed, 22 insertions(+), 33 deletions(-) diff --git a/yarn-project/acir-simulator/src/abi_coder/encoder.ts b/yarn-project/acir-simulator/src/abi_coder/encoder.ts index 3d38a06de68b..4c294aa69f87 100644 --- a/yarn-project/acir-simulator/src/abi_coder/encoder.ts +++ b/yarn-project/acir-simulator/src/abi_coder/encoder.ts @@ -19,7 +19,17 @@ class ArgumentEncoder { private encodeArgument(abiType: ABIType, arg: any) { switch (abiType.kind) { case 'field': - this.flattened.push(new Fr(arg)); + if (typeof arg === 'number') { + this.flattened.push(new Fr(BigInt(arg))); + } else if (typeof arg === 'bigint') { + this.flattened.push(new Fr(arg)); + } else if (typeof arg === 'object') { + if (typeof arg.toField === 'function') { + this.flattened.push(arg.toField()); + } else { + this.flattened.push(arg); + } + } break; case 'boolean': this.flattened.push(new Fr(arg ? 1n : 0n)); diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 99d724fcb48b..171308993ffc 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -329,7 +329,7 @@ describe('Private Execution test suite', () => { AztecAddress.random(), AztecAddress.ZERO, new FunctionData(Buffer.alloc(4), true, false), - encodeArguments(parentAbi, [Fr.fromBuffer(childAddress.toBuffer()).value, Fr.fromBuffer(childSelector).value]), + encodeArguments(parentAbi, [Fr.fromBuffer(childAddress.toBuffer()), Fr.fromBuffer(childSelector)]), Fr.random(), txContext, Fr.ZERO, @@ -427,8 +427,7 @@ describe('Private Execution test suite', () => { AztecAddress.random(), contractAddress, new FunctionData(Buffer.alloc(4), true, true), - // BUG: placing a fr in args will result in a fr wrapped in an fr: https://github.com/AztecProtocol/aztec-packages/issues/611 - encodeArguments(abi, [bridgedAmount, recipient, messageKey.value, secret.value]), + encodeArguments(abi, [bridgedAmount, recipient, messageKey, secret]), Fr.random(), txContext, Fr.ZERO, @@ -459,11 +458,7 @@ describe('Private Execution test suite', () => { AztecAddress.random(), parentAddress, new FunctionData(Buffer.alloc(4), true, false), - encodeArguments(parentAbi, [ - Fr.fromBuffer(childAddress.toBuffer()).value, - Fr.fromBuffer(childSelector).value, - 42n, - ]), + encodeArguments(parentAbi, [Fr.fromBuffer(childAddress.toBuffer()), Fr.fromBuffer(childSelector), 42n]), Fr.random(), txContext, Fr.ZERO, diff --git a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts index eb72e65147c6..26cbc79b2560 100644 --- a/yarn-project/end-to-end/src/e2e_nested_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_nested_contract.test.ts @@ -57,10 +57,6 @@ describe('e2e_nested_contract', () => { return contract; }; - const addressToField = (address: AztecAddress): bigint => { - return Fr.fromBuffer(address.toBuffer()).value; - }; - const getChildStoredValue = (child: { address: AztecAddress }) => node.getStorageAt(child.address, 1n).then(x => toBigInt(x!)); @@ -69,7 +65,7 @@ describe('e2e_nested_contract', () => { */ it('should mine transactions that perform nested calls', async () => { const tx = parentContract.methods - .entryPoint(addressToField(childContract.address), Fr.fromBuffer(childContract.methods.value.selector).value) + .entryPoint(childContract.address, Fr.fromBuffer(childContract.methods.value.selector)) .send({ from: accounts[0] }); await tx.isMined(0, 0.1); @@ -80,11 +76,7 @@ describe('e2e_nested_contract', () => { it('should mine transactions that perform public nested calls', async () => { const tx = parentContract.methods - .pubEntryPoint( - addressToField(childContract.address), - Fr.fromBuffer(childContract.methods.pubValue.selector).value, - 42n, - ) + .pubEntryPoint(childContract.address, Fr.fromBuffer(childContract.methods.pubValue.selector), 42n) .send({ from: accounts[0] }); await tx.isMined(0, 0.1); @@ -95,11 +87,7 @@ describe('e2e_nested_contract', () => { it('should mine transactions that enqueue public calls', async () => { const tx = parentContract.methods - .enqueueCallToChild( - addressToField(childContract.address), - Fr.fromBuffer(childContract.methods.pubStoreValue.selector).value, - 42n, - ) + .enqueueCallToChild(childContract.address, Fr.fromBuffer(childContract.methods.pubStoreValue.selector), 42n) .send({ from: accounts[0] }); await tx.isMined(0, 0.1); @@ -112,8 +100,8 @@ describe('e2e_nested_contract', () => { it('should mine transactions that enqueue a public call with nested public calls', async () => { const tx = parentContract.methods .enqueueCallToPubEntryPoint( - addressToField(childContract.address), - Fr.fromBuffer(childContract.methods.pubStoreValue.selector).value, + childContract.address, + Fr.fromBuffer(childContract.methods.pubStoreValue.selector), 42n, ) .send({ from: accounts[0] }); @@ -128,8 +116,8 @@ describe('e2e_nested_contract', () => { it.skip('should mine transactions that enqueue multiple public calls with nested public calls', async () => { const tx = parentContract.methods .enqueueCallsToPubEntryPoint( - addressToField(childContract.address), - Fr.fromBuffer(childContract.methods.pubStoreValue.selector).value, + childContract.address, + Fr.fromBuffer(childContract.methods.pubStoreValue.selector), 42n, ) .send({ from: accounts[0] }); diff --git a/yarn-project/end-to-end/src/e2e_rollup_native_asset_contract.test.ts b/yarn-project/end-to-end/src/e2e_rollup_native_asset_contract.test.ts index 9bbd6a00f9ed..847759fd3658 100644 --- a/yarn-project/end-to-end/src/e2e_rollup_native_asset_contract.test.ts +++ b/yarn-project/end-to-end/src/e2e_rollup_native_asset_contract.test.ts @@ -158,11 +158,7 @@ describe('e2e_rollup_native_asset_contract', () => { const ethOutAddress = EthAddress.fromString('0x000000000000000000000000000000000000dead'); const tx = contract.methods - .withdraw( - withdrawAmount, - pointToPublicKey(await aztecRpcServer.getAccountPublicKey(owner)), - ethOutAddress.toField().value, - ) + .withdraw(withdrawAmount, pointToPublicKey(await aztecRpcServer.getAccountPublicKey(owner)), ethOutAddress) .send({ from: accounts[0] }); await tx.isMined(0, 0.1); From 3ecd3bcfb0689354f780cdaf05d28c1a2f6be786 Mon Sep 17 00:00:00 2001 From: Maddiaa <47148561+Maddiaa0@users.noreply.github.com> Date: Mon, 22 May 2023 10:20:22 -0700 Subject: [PATCH 22/36] fix: naming consistency in messaging (messageHash -> message) (#641) * fix: contentHash -> content * fix: update content in nr * fix: update incorrect message hash naming --------- Co-authored-by: Maddiaa0 --- .../acir-simulator/src/client/db_oracle.ts | 2 +- .../src/client/private_execution.test.ts | 8 +- .../src/contracts/noir-aztec3/src/context.nr | 4 +- .../src/messaging/l1_to_l2_message.nr | 148 +++++++++--------- yarn-project/types/src/l1_to_l2_message.ts | 8 +- 5 files changed, 85 insertions(+), 85 deletions(-) diff --git a/yarn-project/acir-simulator/src/client/db_oracle.ts b/yarn-project/acir-simulator/src/client/db_oracle.ts index de5430e6575a..b2ae9c980c19 100644 --- a/yarn-project/acir-simulator/src/client/db_oracle.ts +++ b/yarn-project/acir-simulator/src/client/db_oracle.ts @@ -27,7 +27,7 @@ export interface NoteLoadOracleInputs { export interface MessageLoadOracleInputs { /** * An collapsed array of fields containing all of the l1 to l2 message components. - * `l1ToL2Message.toFieldArray()` -\> [sender, chainId, recipient, version, contentHash, secretHash, deadline, fee] + * `l1ToL2Message.toFieldArray()` -\> [sender, chainId, recipient, version, content, secretHash, deadline, fee] */ message: Fr[]; /** diff --git a/yarn-project/acir-simulator/src/client/private_execution.test.ts b/yarn-project/acir-simulator/src/client/private_execution.test.ts index 171308993ffc..d3332db227b6 100644 --- a/yarn-project/acir-simulator/src/client/private_execution.test.ts +++ b/yarn-project/acir-simulator/src/client/private_execution.test.ts @@ -357,16 +357,16 @@ describe('Private Execution test suite', () => { let recipientPk: Buffer; let recipient: NoirPoint; - const buildL1ToL2Message = async (content: Fr[], targetContract: AztecAddress, secret: Fr) => { + const buildL1ToL2Message = async (contentPreimage: Fr[], targetContract: AztecAddress, secret: Fr) => { const wasm = await CircuitsWasm.get(); // Function selector: 0x1801fbe5 keccak256('mint(uint256,bytes32)') const contentBuf = Buffer.concat([ Buffer.from([0x18, 0x01, 0xfb, 0xe5]), - ...content.map(field => field.toBuffer()), + ...contentPreimage.map(field => field.toBuffer()), ]); const temp = toBigIntBE(sha256(contentBuf)); - const contentHash = Fr.fromBuffer(toBufferBE(temp % Fr.MODULUS, 32)); + const content = Fr.fromBuffer(toBufferBE(temp % Fr.MODULUS, 32)); const secretHash = computeSecretMessageHash(wasm, secret); @@ -375,7 +375,7 @@ describe('Private Execution test suite', () => { return new L1ToL2Message( new L1Actor(EthAddress.random(), 1), new L2Actor(targetContract, 1), - contentHash, + content, secretHash, 0, 0, diff --git a/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/context.nr b/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/context.nr index d807cf61827a..331f04002bbd 100644 --- a/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/context.nr +++ b/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/context.nr @@ -79,7 +79,7 @@ impl PrivateFunctionContext { // Inputs must be temporarily passed in to prevent too many unknowns // Note this returns self to get around an issue where mutable structs do not maintain mutations unless reassigned - fn consume_l1_to_l2_message(mut self: Self, inputs: abi::Inputs, msg_key: Field, content_hash: Field, secret: Field) -> PrivateFunctionContext { + fn consume_l1_to_l2_message(mut self: Self, inputs: abi::Inputs, msg_key: Field, content: Field, secret: Field) -> PrivateFunctionContext { let returned_message = get_l1_to_l2_message_call(msg_key); let l1_to_l2_message_data = make_l1_to_l2_message_getter_data(returned_message, 0, secret); @@ -90,7 +90,7 @@ impl PrivateFunctionContext { constrain l1_to_l2_message_data.message.recipient == inputs.call_context.storage_contract_address; // Validate the message hash is correct - constrain l1_to_l2_message_data.message.content_hash == content_hash; + constrain l1_to_l2_message_data.message.content == content; // Validate the message secret is correct l1_to_l2_message_data.message.validate_message_secret(); diff --git a/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/messaging/l1_to_l2_message.nr b/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/messaging/l1_to_l2_message.nr index 8ddc74c59957..7547e5224903 100644 --- a/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/messaging/l1_to_l2_message.nr +++ b/yarn-project/noir-contracts/src/contracts/noir-aztec3/src/messaging/l1_to_l2_message.nr @@ -14,7 +14,7 @@ struct L1ToL2Message { chainId: Field, recipient: Field, version: Field, - content_hash: Field, + content: Field, secret: Field, secret_hash: Field, deadline: u32, @@ -29,7 +29,7 @@ impl L1ToL2Message { chainId: 0, recipient: 0, version: 0, - content_hash: 0, + content: 0, secret: 0, secret_hash: 0, deadline: 0 as u32, @@ -49,7 +49,7 @@ impl L1ToL2Message { chainId: fields[1], recipient: fields[2], version: fields[3], - content_hash: fields[4], + content: fields[4], secret: secret, secret_hash: fields[5], deadline: fields[6] as u32, @@ -70,7 +70,7 @@ impl L1ToL2Message { let chainId_bytes = self.chainId.to_be_bytes(32); let recipient_bytes = self.recipient.to_be_bytes(32); let version_bytes = self.version.to_be_bytes(32); - let content_hash_bytes = self.content_hash.to_be_bytes(32); + let content_bytes = self.content.to_be_bytes(32); let secret_hash_bytes = self.secret_hash.to_be_bytes(32); let deadline_bytes = (self.deadline as Field).to_be_bytes(32); let fee_bytes = (self.fee as Field).to_be_bytes(32); @@ -213,38 +213,38 @@ impl L1ToL2Message { hash_bytes[30 + 96] = version_bytes[30]; hash_bytes[31 + 96] = version_bytes[31]; - hash_bytes[0 + 128] = content_hash_bytes[0]; - hash_bytes[1 + 128] = content_hash_bytes[1]; - hash_bytes[2 + 128] = content_hash_bytes[2]; - hash_bytes[3 + 128] = content_hash_bytes[3]; - hash_bytes[4 + 128] = content_hash_bytes[4]; - hash_bytes[5 + 128] = content_hash_bytes[5]; - hash_bytes[6 + 128] = content_hash_bytes[6]; - hash_bytes[7 + 128] = content_hash_bytes[7]; - hash_bytes[8 + 128] = content_hash_bytes[8]; - hash_bytes[9 + 128] = content_hash_bytes[9]; - hash_bytes[10 + 128] = content_hash_bytes[10]; - hash_bytes[11 + 128] = content_hash_bytes[11]; - hash_bytes[12 + 128] = content_hash_bytes[12]; - hash_bytes[13 + 128] = content_hash_bytes[13]; - hash_bytes[14 + 128] = content_hash_bytes[14]; - hash_bytes[15 + 128] = content_hash_bytes[15]; - hash_bytes[16 + 128] = content_hash_bytes[16]; - hash_bytes[17 + 128] = content_hash_bytes[17]; - hash_bytes[18 + 128] = content_hash_bytes[18]; - hash_bytes[19 + 128] = content_hash_bytes[19]; - hash_bytes[20 + 128] = content_hash_bytes[20]; - hash_bytes[21 + 128] = content_hash_bytes[21]; - hash_bytes[22 + 128] = content_hash_bytes[22]; - hash_bytes[23 + 128] = content_hash_bytes[23]; - hash_bytes[24 + 128] = content_hash_bytes[24]; - hash_bytes[25 + 128] = content_hash_bytes[25]; - hash_bytes[26 + 128] = content_hash_bytes[26]; - hash_bytes[27 + 128] = content_hash_bytes[27]; - hash_bytes[28 + 128] = content_hash_bytes[28]; - hash_bytes[29 + 128] = content_hash_bytes[29]; - hash_bytes[30 + 128] = content_hash_bytes[30]; - hash_bytes[31 + 128] = content_hash_bytes[31]; + hash_bytes[0 + 128] = content_bytes[0]; + hash_bytes[1 + 128] = content_bytes[1]; + hash_bytes[2 + 128] = content_bytes[2]; + hash_bytes[3 + 128] = content_bytes[3]; + hash_bytes[4 + 128] = content_bytes[4]; + hash_bytes[5 + 128] = content_bytes[5]; + hash_bytes[6 + 128] = content_bytes[6]; + hash_bytes[7 + 128] = content_bytes[7]; + hash_bytes[8 + 128] = content_bytes[8]; + hash_bytes[9 + 128] = content_bytes[9]; + hash_bytes[10 + 128] = content_bytes[10]; + hash_bytes[11 + 128] = content_bytes[11]; + hash_bytes[12 + 128] = content_bytes[12]; + hash_bytes[13 + 128] = content_bytes[13]; + hash_bytes[14 + 128] = content_bytes[14]; + hash_bytes[15 + 128] = content_bytes[15]; + hash_bytes[16 + 128] = content_bytes[16]; + hash_bytes[17 + 128] = content_bytes[17]; + hash_bytes[18 + 128] = content_bytes[18]; + hash_bytes[19 + 128] = content_bytes[19]; + hash_bytes[20 + 128] = content_bytes[20]; + hash_bytes[21 + 128] = content_bytes[21]; + hash_bytes[22 + 128] = content_bytes[22]; + hash_bytes[23 + 128] = content_bytes[23]; + hash_bytes[24 + 128] = content_bytes[24]; + hash_bytes[25 + 128] = content_bytes[25]; + hash_bytes[26 + 128] = content_bytes[26]; + hash_bytes[27 + 128] = content_bytes[27]; + hash_bytes[28 + 128] = content_bytes[28]; + hash_bytes[29 + 128] = content_bytes[29]; + hash_bytes[30 + 128] = content_bytes[30]; + hash_bytes[31 + 128] = content_bytes[31]; hash_bytes[0 + 160] = secret_hash_bytes[0]; hash_bytes[1 + 160] = secret_hash_bytes[1]; @@ -345,69 +345,69 @@ impl L1ToL2Message { hash_bytes[30 + 224] = fee_bytes[30]; hash_bytes[31 + 224] = fee_bytes[31]; - let content_sha256 = dep::std::hash::sha256(hash_bytes); + let message_sha256 = dep::std::hash::sha256(hash_bytes); - // // Convert the content_sha256 to a field element + // // Convert the message_sha256 to a field element let mut v = 1; let mut high = 0 as Field; let mut low = 0 as Field; // Unroll loops because otherwise takes forever to compile // for i in [15 - i for i in range(16)]: - // print('high = high + (content_sha256[{0}] as Field) * v;'.format(i)) - // print('low = low + (content_sha256[16 + {0}] as Field) * v;'.format(i)) + // print('high = high + (message_sha256[{0}] as Field) * v;'.format(i)) + // print('low = low + (message_sha256[16 + {0}] as Field) * v;'.format(i)) // print('v = v * 256;'); - high = high + (content_sha256[15] as Field) * v; - low = low + (content_sha256[16 + 15] as Field) * v; + high = high + (message_sha256[15] as Field) * v; + low = low + (message_sha256[16 + 15] as Field) * v; v = v * 256; - high = high + (content_sha256[14] as Field) * v; - low = low + (content_sha256[16 + 14] as Field) * v; + high = high + (message_sha256[14] as Field) * v; + low = low + (message_sha256[16 + 14] as Field) * v; v = v * 256; - high = high + (content_sha256[13] as Field) * v; - low = low + (content_sha256[16 + 13] as Field) * v; + high = high + (message_sha256[13] as Field) * v; + low = low + (message_sha256[16 + 13] as Field) * v; v = v * 256; - high = high + (content_sha256[12] as Field) * v; - low = low + (content_sha256[16 + 12] as Field) * v; + high = high + (message_sha256[12] as Field) * v; + low = low + (message_sha256[16 + 12] as Field) * v; v = v * 256; - high = high + (content_sha256[11] as Field) * v; - low = low + (content_sha256[16 + 11] as Field) * v; + high = high + (message_sha256[11] as Field) * v; + low = low + (message_sha256[16 + 11] as Field) * v; v = v * 256; - high = high + (content_sha256[10] as Field) * v; - low = low + (content_sha256[16 + 10] as Field) * v; + high = high + (message_sha256[10] as Field) * v; + low = low + (message_sha256[16 + 10] as Field) * v; v = v * 256; - high = high + (content_sha256[9] as Field) * v; - low = low + (content_sha256[16 + 9] as Field) * v; + high = high + (message_sha256[9] as Field) * v; + low = low + (message_sha256[16 + 9] as Field) * v; v = v * 256; - high = high + (content_sha256[8] as Field) * v; - low = low + (content_sha256[16 + 8] as Field) * v; + high = high + (message_sha256[8] as Field) * v; + low = low + (message_sha256[16 + 8] as Field) * v; v = v * 256; - high = high + (content_sha256[7] as Field) * v; - low = low + (content_sha256[16 + 7] as Field) * v; + high = high + (message_sha256[7] as Field) * v; + low = low + (message_sha256[16 + 7] as Field) * v; v = v * 256; - high = high + (content_sha256[6] as Field) * v; - low = low + (content_sha256[16 + 6] as Field) * v; + high = high + (message_sha256[6] as Field) * v; + low = low + (message_sha256[16 + 6] as Field) * v; v = v * 256; - high = high + (content_sha256[5] as Field) * v; - low = low + (content_sha256[16 + 5] as Field) * v; + high = high + (message_sha256[5] as Field) * v; + low = low + (message_sha256[16 + 5] as Field) * v; v = v * 256; - high = high + (content_sha256[4] as Field) * v; - low = low + (content_sha256[16 + 4] as Field) * v; + high = high + (message_sha256[4] as Field) * v; + low = low + (message_sha256[16 + 4] as Field) * v; v = v * 256; - high = high + (content_sha256[3] as Field) * v; - low = low + (content_sha256[16 + 3] as Field) * v; + high = high + (message_sha256[3] as Field) * v; + low = low + (message_sha256[16 + 3] as Field) * v; v = v * 256; - high = high + (content_sha256[2] as Field) * v; - low = low + (content_sha256[16 + 2] as Field) * v; + high = high + (message_sha256[2] as Field) * v; + low = low + (message_sha256[16 + 2] as Field) * v; v = v * 256; - high = high + (content_sha256[1] as Field) * v; - low = low + (content_sha256[16 + 1] as Field) * v; + high = high + (message_sha256[1] as Field) * v; + low = low + (message_sha256[16 + 1] as Field) * v; v = v * 256; - high = high + (content_sha256[0] as Field) * v; - low = low + (content_sha256[16 + 0] as Field) * v; + high = high + (message_sha256[0] as Field) * v; + low = low + (message_sha256[16 + 0] as Field) * v; v = v * 256; - let content_hash = low + high * v; - content_hash + let message_hash = low + high * v; + message_hash } // The nullifier of a l1 to l2 message is the hash of the message salted with the secret and tree index diff --git a/yarn-project/types/src/l1_to_l2_message.ts b/yarn-project/types/src/l1_to_l2_message.ts index 1ab857227e43..2943b68ba02c 100644 --- a/yarn-project/types/src/l1_to_l2_message.ts +++ b/yarn-project/types/src/l1_to_l2_message.ts @@ -19,9 +19,9 @@ export class L1ToL2Message { */ public readonly recipient: L2Actor, /** - * The hash of the message content. + * The message content. */ - public readonly contentHash: Fr, + public readonly content: Fr, /** * The hash of the spending secret. */ @@ -51,7 +51,7 @@ export class L1ToL2Message { return [ ...this.sender.toFieldArray(), ...this.recipient.toFieldArray(), - this.contentHash, + this.content, this.secretHash, new Fr(BigInt(this.deadline)), new Fr(BigInt(this.fee)), @@ -59,7 +59,7 @@ export class L1ToL2Message { } toBuffer(): Buffer { - return serializeToBuffer(this.sender, this.recipient, this.contentHash, this.secretHash, this.deadline, this.fee); + return serializeToBuffer(this.sender, this.recipient, this.content, this.secretHash, this.deadline, this.fee); } static empty(): L1ToL2Message { From 9cabcff36faa20496b9c43b8720dcb7a425fac09 Mon Sep 17 00:00:00 2001 From: Santiago Palladino Date: Mon, 22 May 2023 15:41:39 -0300 Subject: [PATCH 23/36] chore: remove unknown casts in archiver test (#648) Removes intermediate casts to unknown from archiver test, which hide type errors in the args of the mocked event. --- yarn-project/archiver/src/archiver/archiver.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/yarn-project/archiver/src/archiver/archiver.test.ts b/yarn-project/archiver/src/archiver/archiver.test.ts index ac98fb362af4..e3742e82705d 100644 --- a/yarn-project/archiver/src/archiver/archiver.test.ts +++ b/yarn-project/archiver/src/archiver/archiver.test.ts @@ -81,7 +81,7 @@ function makeL2BlockProcessedEvent(l1BlockNum: bigint, l2BlockNum: bigint) { blockNumber: l1BlockNum, args: { blockNum: l2BlockNum }, transactionHash: `0x${l2BlockNum}`, - } as unknown as Log; + } as Log; } /** @@ -95,11 +95,11 @@ function makeUnverifiedDataEvent(l1BlockNum: bigint, l2BlockNum: bigint) { blockNumber: l1BlockNum, args: { l2BlockNum, - sender: EthAddress.random(), + sender: EthAddress.random().toString(), data: '0x' + createRandomUnverifiedData(16).toString('hex'), }, transactionHash: `0x${l2BlockNum}`, - } as unknown as Log; + } as Log; } /** @@ -126,7 +126,7 @@ function makeContractDeployedEvent(l1BlockNum: bigint, l2BlockNum: bigint) { acir: '0x' + acir, }, transactionHash: `0x${l2BlockNum}`, - } as unknown as Log; + } as Log; } /** From e58cf6d5c2a052884906ed5292c616477fc1c7a2 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 23 May 2023 07:30:01 +0000 Subject: [PATCH 24/36] Consolidation code for contract_logic --- .../aztec3/circuits/kernel/private/common.cpp | 102 +++++++++++++ .../aztec3/circuits/kernel/private/common.hpp | 10 ++ .../private/native_private_kernel_circuit.cpp | 138 +++--------------- .../native_private_kernel_circuit_initial.cpp | 107 +------------- 4 files changed, 139 insertions(+), 218 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp index 01a458798d0e..5bbbb04acfa8 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp @@ -1,5 +1,7 @@ #include "init.hpp" +#include "aztec3/circuits/abis/contract_deployment_data.hpp" +#include "aztec3/circuits/abis/function_data.hpp" #include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" #include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" @@ -10,9 +12,13 @@ using DummyComposer = aztec3::utils::DummyComposer; +using aztec3::circuits::abis::ContractDeploymentData; using aztec3::circuits::abis::ContractLeafPreimage; +using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::KernelCircuitPublicInputs; +using aztec3::circuits::abis::NewContractData; +using aztec3::utils::array_push; using aztec3::utils::is_array_empty; using aztec3::utils::push_array_to_array; using DummyComposer = aztec3::utils::DummyComposer; @@ -106,4 +112,100 @@ void common_update_end_values(DummyComposer& composer, } } +void common_contract_logic(DummyComposer& composer, + PrivateCallData const& private_call, + KernelCircuitPublicInputs& public_inputs, + ContractDeploymentData const& contract_dep_data, + FunctionData const& function_data) +{ + const auto private_call_public_inputs = private_call.call_stack_item.public_inputs; + const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; + const auto& portal_contract_address = private_call.portal_contract_address; + const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; + // contract deployment + + // input storage contract address must be 0 if its a constructor call and non-zero otherwise + auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; + + auto private_call_vk_hash = + stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK); + + auto constructor_hash = + compute_constructor_hash(function_data, private_call_public_inputs.args, private_call_vk_hash); + + if (is_contract_deployment) { + composer.do_assert(contract_dep_data.constructor_vk_hash == private_call_vk_hash, + "constructor_vk_hash doesn't match private_call_vk_hash", + CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONSTRUCTOR_VK_HASH); + } + + auto const new_contract_address = compute_contract_address(deployer_address, + contract_dep_data.contract_address_salt, + contract_dep_data.function_tree_root, + constructor_hash); + + if (is_contract_deployment) { + // must imply == derived address + composer.do_assert(storage_contract_address == new_contract_address, + "contract address supplied doesn't match derived address", + CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); + } else { + // non-contract deployments must specify contract address being interacted with + composer.do_assert(storage_contract_address != 0, + "contract address can't be 0 for non-contract deployment related transactions", + CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); + } + + // compute contract address nullifier + auto const blake_input = new_contract_address.to_field().to_buffer(); + auto const new_contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); + + // push the contract address nullifier to nullifier vector + if (is_contract_deployment) { + array_push(public_inputs.end.new_nullifiers, new_contract_address_nullifier); + } + + // Add new contract data if its a contract deployment function + NewContractData const native_new_contract_data{ new_contract_address, + portal_contract_address, + contract_dep_data.function_tree_root }; + + array_push, KERNEL_NEW_CONTRACTS_LENGTH>(public_inputs.end.new_contracts, + native_new_contract_data); + + /* We need to compute the root of the contract tree, starting from the function's VK: + * - Compute the vk_hash (done above) + * - Compute the function_leaf: hash(function_selector, is_private, vk_hash, acir_hash) + * - Hash the function_leaf with the function_leaf's sibling_path to get the function_tree_root + * - Compute the contract_leaf: hash(contract_address, portal_contract_address, function_tree_root) + * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root + */ + + // The logic below ensures that the contract exists in the contracts tree + if (!is_contract_deployment) { + auto const& computed_function_tree_root = + function_tree_root_from_siblings(private_call.call_stack_item.function_data.function_selector, + true, // is_private + private_call_vk_hash, + private_call.acir_hash, + private_call.function_leaf_membership_witness.leaf_index, + private_call.function_leaf_membership_witness.sibling_path); + + auto const& computed_contract_tree_root = + contract_tree_root_from_siblings(computed_function_tree_root, + storage_contract_address, + portal_contract_address, + private_call.contract_leaf_membership_witness.leaf_index, + private_call.contract_leaf_membership_witness.sibling_path); + + auto const& purported_contract_tree_root = + private_call.call_stack_item.public_inputs.historic_contract_tree_root; + + composer.do_assert( + computed_contract_tree_root == purported_contract_tree_root, + "computed_contract_tree_root doesn't match purported_contract_tree_root", + CircuitErrorCode::PRIVATE_KERNEL__COMPUTED_CONTRACT_TREE_ROOT_AND_PURPORTED_CONTRACT_TREE_ROOT_MISMATCH); + } +} + } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp index 12351e2fd673..ab238b154b57 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -2,20 +2,30 @@ #include "init.hpp" +#include "aztec3/circuits/abis/contract_deployment_data.hpp" +#include "aztec3/circuits/abis/function_data.hpp" #include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" #include "aztec3/circuits/abis/private_kernel/private_call_data.hpp" #include "aztec3/utils/dummy_composer.hpp" namespace aztec3::circuits::kernel::private_kernel { +using aztec3::circuits::abis::ContractDeploymentData; using DummyComposer = aztec3::utils::DummyComposer; +using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::private_kernel::PrivateCallData; + void common_validate_call_stack(DummyComposer& composer, PrivateCallData const& private_call); void common_update_end_values(DummyComposer& composer, PrivateCallData const& private_call, KernelCircuitPublicInputs& public_inputs); +void common_contract_logic(DummyComposer& composer, + PrivateCallData const& private_call, + KernelCircuitPublicInputs& public_inputs, + ContractDeploymentData const& contract_dep_data, + FunctionData const& function_data); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 7cb070277dfd..7e7e970e9e76 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -4,7 +4,6 @@ #include "aztec3/circuits/abis/kernel_circuit_public_inputs.hpp" #include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_inner.hpp" -#include "aztec3/circuits/hash.hpp" #include "aztec3/constants.hpp" #include "aztec3/utils/array.hpp" #include "aztec3/utils/dummy_composer.hpp" @@ -13,20 +12,13 @@ namespace aztec3::circuits::kernel::private_kernel { using aztec3::circuits::abis::ContractLeafPreimage; using aztec3::circuits::abis::KernelCircuitPublicInputs; -using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using aztec3::utils::array_length; using aztec3::utils::array_pop; -using aztec3::utils::array_push; using DummyComposer = aztec3::utils::DummyComposer; using CircuitErrorCode = aztec3::utils::CircuitErrorCode; -using aztec3::circuits::compute_constructor_hash; -using aztec3::circuits::compute_contract_address; -using aztec3::circuits::contract_tree_root_from_siblings; -using aztec3::circuits::function_tree_root_from_siblings; - // using plonk::stdlib::merkle_tree:: // // TODO: NEED TO RECONCILE THE `proof`'s public inputs (which are uint8's) with the @@ -69,113 +61,6 @@ void initialise_end_values(PrivateKernelInputsInner const& private_inputs, end.optionally_revealed_data = start.optionally_revealed_data; } -void contract_logic(DummyComposer& composer, - PrivateKernelInputsInner const& private_inputs, - KernelCircuitPublicInputs& public_inputs) -{ - const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; - const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; - const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; - const auto& contract_deployment_data = private_call_public_inputs.contract_deployment_data; - - // contract deployment - - // In general and long term, we probably need to support contract deployment in the inner kernel calls. - - // input storage contract address must be 0 if its a constructor call and non-zero otherwise - auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; - - auto private_call_vk_hash = stdlib::recursion::verification_key::compress_native( - private_inputs.private_call.vk, GeneratorIndex::VK); - - auto constructor_hash = compute_constructor_hash(private_inputs.private_call.call_stack_item.function_data, - private_call_public_inputs.args, - private_call_vk_hash); - - if (is_contract_deployment) { - composer.do_assert(contract_deployment_data.constructor_vk_hash == private_call_vk_hash, - "constructor_vk_hash doesn't match private_call_vk_hash", - CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONSTRUCTOR_VK_HASH); - } - - auto const new_contract_address = compute_contract_address(deployer_address, - contract_deployment_data.contract_address_salt, - contract_deployment_data.function_tree_root, - constructor_hash); - - if (is_contract_deployment) { - // must imply == derived address - composer.do_assert(storage_contract_address == new_contract_address, - "contract address supplied doesn't match derived address", - CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); - } else { - // non-contract deployments must specify contract address being interacted with - composer.do_assert(storage_contract_address != 0, - "contract address can't be 0 for non-contract deployment related transactions", - CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); - } - - // compute contract address nullifier - auto const blake_input = new_contract_address.to_field().to_buffer(); - auto const new_contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); - - // push the contract address nullifier to nullifier vector - if (is_contract_deployment) { - array_push(public_inputs.end.new_nullifiers, new_contract_address_nullifier); - } - - // Add new contract data if its a contract deployment function - NewContractData const native_new_contract_data{ new_contract_address, - portal_contract_address, - contract_deployment_data.function_tree_root }; - - array_push, KERNEL_NEW_CONTRACTS_LENGTH>(public_inputs.end.new_contracts, - native_new_contract_data); - - /* We need to compute the root of the contract tree, starting from the function's VK: - * - Compute the vk_hash (done above) - * - Compute the function_leaf: hash(function_selector, is_private, vk_hash, acir_hash) - * - Hash the function_leaf with the function_leaf's sibling_path to get the function_tree_root - * - Compute the contract_leaf: hash(contract_address, portal_contract_address, function_tree_root) - * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root - */ - - // ensure that historic/purported contract tree root matches the one in previous kernel - auto const& purported_contract_tree_root = - private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; - auto const& previous_kernel_contract_tree_root = - private_inputs.previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots - .contract_tree_root; - composer.do_assert( - purported_contract_tree_root == previous_kernel_contract_tree_root, - "purported_contract_tree_root doesn't match previous_kernel_contract_tree_root", - CircuitErrorCode::PRIVATE_KERNEL__PURPORTED_CONTRACT_TREE_ROOT_AND_PREVIOUS_KERNEL_CONTRACT_TREE_ROOT_MISMATCH); - - // The logic below ensures that the contract exists in the contracts tree - if (!is_contract_deployment) { - auto const& computed_function_tree_root = function_tree_root_from_siblings( - private_inputs.private_call.call_stack_item.function_data.function_selector, - true, // is_private - private_call_vk_hash, - private_inputs.private_call.acir_hash, - private_inputs.private_call.function_leaf_membership_witness.leaf_index, - private_inputs.private_call.function_leaf_membership_witness.sibling_path); - - auto const& computed_contract_tree_root = contract_tree_root_from_siblings( - computed_function_tree_root, - storage_contract_address, - portal_contract_address, - private_inputs.private_call.contract_leaf_membership_witness.leaf_index, - private_inputs.private_call.contract_leaf_membership_witness.sibling_path); - - composer.do_assert( - computed_contract_tree_root == purported_contract_tree_root, - "computed_contract_tree_root doesn't match purported_contract_tree_root", - CircuitErrorCode::PRIVATE_KERNEL__COMPUTED_CONTRACT_TREE_ROOT_AND_PURPORTED_CONTRACT_TREE_ROOT_MISMATCH); - } -} - void validate_this_private_call_hash(DummyComposer& composer, PrivateKernelInputsInner const& private_inputs, KernelCircuitPublicInputs& public_inputs) @@ -208,6 +93,19 @@ void validate_this_private_call_stack(DummyComposer& composer, PrivateKernelInpu } }; +void validate_contract_tree_root(DummyComposer& composer, PrivateKernelInputsInner const& private_inputs) +{ + auto const& purported_contract_tree_root = + private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; + auto const& previous_kernel_contract_tree_root = + private_inputs.previous_kernel.public_inputs.constants.historic_tree_roots.private_historic_tree_roots + .contract_tree_root; + composer.do_assert( + purported_contract_tree_root == previous_kernel_contract_tree_root, + "purported_contract_tree_root doesn't match previous_kernel_contract_tree_root", + CircuitErrorCode::PRIVATE_KERNEL__PURPORTED_CONTRACT_TREE_ROOT_AND_PREVIOUS_KERNEL_CONTRACT_TREE_ROOT_MISMATCH); +} + void validate_inputs(DummyComposer& composer, PrivateKernelInputsInner const& private_inputs) { const auto& this_call_stack_item = private_inputs.private_call.call_stack_item; @@ -261,7 +159,15 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo common_update_end_values(composer, private_inputs.private_call, public_inputs); - contract_logic(composer, private_inputs, public_inputs); + // ensure that historic/purported contract tree root matches the one in previous kernel + validate_contract_tree_root(composer, private_inputs); + + const auto private_call_stack_item = private_inputs.private_call.call_stack_item; + common_contract_logic(composer, + private_inputs.private_call, + public_inputs, + private_call_stack_item.public_inputs.contract_deployment_data, + private_call_stack_item.function_data); // We'll skip any verification in this native implementation, because for a Local Developer Testnet, there won't // _be_ a valid proof to verify!!! auto aggregation_object = verify_proofs(composer, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index e65bf111eeee..3e9c8684949e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -2,17 +2,14 @@ #include "aztec3/circuits/abis/combined_constant_data.hpp" #include "aztec3/circuits/abis/combined_historic_tree_roots.hpp" -#include "aztec3/circuits/abis/new_contract_data.hpp" #include "aztec3/circuits/abis/private_historic_tree_roots.hpp" #include "aztec3/circuits/abis/private_kernel/private_kernel_inputs_init.hpp" -#include "aztec3/circuits/hash.hpp" #include "aztec3/circuits/kernel/private/init.hpp" #include "aztec3/constants.hpp" #include "aztec3/utils/array.hpp" using aztec3::circuits::abis::CombinedConstantData; using aztec3::circuits::abis::CombinedHistoricTreeRoots; -using aztec3::circuits::abis::NewContractData; using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; using aztec3::utils::array_push; @@ -66,104 +63,6 @@ void initialise_end_values(PrivateKernelInputsInit const& private_inputs, public_inputs.constants = constants; } -void contract_logic(DummyComposer& composer, - PrivateKernelInputsInit const& private_inputs, - KernelCircuitPublicInputs& public_inputs) -{ - const auto private_call_public_inputs = private_inputs.private_call.call_stack_item.public_inputs; - const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; - const auto& portal_contract_address = private_inputs.private_call.portal_contract_address; - const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; - const auto& contract_deployment_data = - private_inputs.signed_tx_request.tx_request.tx_context.contract_deployment_data; - - // contract deployment - - // input storage contract address must be 0 if its a constructor call and non-zero otherwise - auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; - - auto private_call_vk_hash = stdlib::recursion::verification_key::compress_native( - private_inputs.private_call.vk, GeneratorIndex::VK); - - auto constructor_hash = compute_constructor_hash(private_inputs.signed_tx_request.tx_request.function_data, - private_call_public_inputs.args, - private_call_vk_hash); - - if (is_contract_deployment) { - composer.do_assert(contract_deployment_data.constructor_vk_hash == private_call_vk_hash, - "constructor_vk_hash doesn't match private_call_vk_hash", - CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONSTRUCTOR_VK_HASH); - } - - auto const new_contract_address = compute_contract_address(deployer_address, - contract_deployment_data.contract_address_salt, - contract_deployment_data.function_tree_root, - constructor_hash); - - if (is_contract_deployment) { - // must imply == derived address - composer.do_assert(storage_contract_address == new_contract_address, - "contract address supplied doesn't match derived address", - CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); - } else { - // non-contract deployments must specify contract address being interacted with - composer.do_assert(storage_contract_address != 0, - "contract address can't be 0 for non-contract deployment related transactions", - CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); - } - - // compute contract address nullifier - auto const blake_input = new_contract_address.to_field().to_buffer(); - auto const new_contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); - - // push the contract address nullifier to nullifier vector - if (is_contract_deployment) { - array_push(public_inputs.end.new_nullifiers, new_contract_address_nullifier); - } - - // Add new contract data if its a contract deployment function - NewContractData const native_new_contract_data{ new_contract_address, - portal_contract_address, - contract_deployment_data.function_tree_root }; - - array_push, KERNEL_NEW_CONTRACTS_LENGTH>(public_inputs.end.new_contracts, - native_new_contract_data); - - /* We need to compute the root of the contract tree, starting from the function's VK: - * - Compute the vk_hash (done above) - * - Compute the function_leaf: hash(function_selector, is_private, vk_hash, acir_hash) - * - Hash the function_leaf with the function_leaf's sibling_path to get the function_tree_root - * - Compute the contract_leaf: hash(contract_address, portal_contract_address, function_tree_root) - * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root - */ - - // The logic below ensures that the contract exists in the contracts tree - if (!is_contract_deployment) { - auto const& computed_function_tree_root = function_tree_root_from_siblings( - private_inputs.private_call.call_stack_item.function_data.function_selector, - true, // is_private - private_call_vk_hash, - private_inputs.private_call.acir_hash, - private_inputs.private_call.function_leaf_membership_witness.leaf_index, - private_inputs.private_call.function_leaf_membership_witness.sibling_path); - - auto const& computed_contract_tree_root = contract_tree_root_from_siblings( - computed_function_tree_root, - storage_contract_address, - portal_contract_address, - private_inputs.private_call.contract_leaf_membership_witness.leaf_index, - private_inputs.private_call.contract_leaf_membership_witness.sibling_path); - - auto const& purported_contract_tree_root = - private_inputs.private_call.call_stack_item.public_inputs.historic_contract_tree_root; - - composer.do_assert( - computed_contract_tree_root == purported_contract_tree_root, - "computed_contract_tree_root doesn't match purported_contract_tree_root", - CircuitErrorCode::PRIVATE_KERNEL__COMPUTED_CONTRACT_TREE_ROOT_AND_PURPORTED_CONTRACT_TREE_ROOT_MISMATCH); - } -} - void validate_this_private_call_against_tx_request(DummyComposer& composer, PrivateKernelInputsInit const& private_inputs) { @@ -267,7 +166,11 @@ KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyCompose common_update_end_values(composer, private_inputs.private_call, public_inputs); - contract_logic(composer, private_inputs, public_inputs); + common_contract_logic(composer, + private_inputs.private_call, + public_inputs, + private_inputs.signed_tx_request.tx_request.tx_context.contract_deployment_data, + private_inputs.signed_tx_request.tx_request.function_data); // We'll skip any verification in this native implementation, because for a Local Developer Testnet, there won't // _be_ a valid proof to verify!!! auto aggregation_object = verify_proofs(composer, From 49246dfa92cbb50f329bb735428814ff13c0855c Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 23 May 2023 14:45:17 +0000 Subject: [PATCH 25/36] e2e fixing: Initialise public and private call stack and comment out some checks --- .../kernel/private/native_private_kernel_circuit.cpp | 2 +- .../private/native_private_kernel_circuit_initial.cpp | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 7e7e970e9e76..83eb362bff06 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -155,7 +155,7 @@ KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& compo // Noir doesn't have hash index so it can't hash private call stack item correctly // validate_this_private_call_stack(composer, private_inputs); // TODO(dbanks12): may need to comment out hash check in here according to TODO above - common_validate_call_stack(composer, private_inputs.private_call); + // common_validate_call_stack(composer, private_inputs.private_call); common_update_end_values(composer, private_inputs.private_call, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp index 3e9c8684949e..85d2ba6891dc 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp @@ -14,6 +14,7 @@ using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; using aztec3::utils::array_push; using aztec3::utils::is_array_empty; +using aztec3::utils::push_array_to_array; using CircuitErrorCode = aztec3::utils::CircuitErrorCode; namespace aztec3::circuits::kernel::private_kernel { @@ -61,6 +62,9 @@ void initialise_end_values(PrivateKernelInputsInit const& private_inputs, // Set the constants in public_inputs. public_inputs.constants = constants; + + push_array_to_array(private_call_public_inputs.private_call_stack, public_inputs.end.private_call_stack); + push_array_to_array(private_call_public_inputs.public_call_stack, public_inputs.end.public_call_stack); } void validate_this_private_call_against_tx_request(DummyComposer& composer, @@ -158,9 +162,9 @@ KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyCompose validate_inputs(composer, private_inputs); - validate_this_private_call_against_tx_request(composer, private_inputs); + // validate_this_private_call_against_tx_request(composer, private_inputs); - common_validate_call_stack(composer, private_inputs.private_call); + // common_validate_call_stack(composer, private_inputs.private_call); update_end_values(private_inputs, public_inputs); From c416a338c3e04c3a2f2ca4958ed149c58c329746 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 23 May 2023 15:25:33 +0000 Subject: [PATCH 26/36] Renaming file native_private_kernel_initial.XPP into native_private_kernel_init.XPP --- circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp | 2 +- ...rcuit_initial.cpp => native_private_kernel_circuit_init.cpp} | 0 ...rcuit_initial.hpp => native_private_kernel_circuit_init.hpp} | 0 3 files changed, 1 insertion(+), 1 deletion(-) rename circuits/cpp/src/aztec3/circuits/kernel/private/{native_private_kernel_circuit_initial.cpp => native_private_kernel_circuit_init.cpp} (100%) rename circuits/cpp/src/aztec3/circuits/kernel/private/{native_private_kernel_circuit_initial.hpp => native_private_kernel_circuit_init.hpp} (100%) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp index 2270dac947ea..5682d8470a4e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp @@ -1,4 +1,4 @@ #include "init.hpp" #include "native_private_kernel_circuit.hpp" -#include "native_private_kernel_circuit_initial.hpp" +#include "native_private_kernel_circuit_init.hpp" #include "private_kernel_circuit.hpp" \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp similarity index 100% rename from circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.cpp rename to circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.hpp similarity index 100% rename from circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_initial.hpp rename to circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.hpp From c8df3b48a3b9f46ef9a813ae2b9fc41ee3a651e2 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 23 May 2023 15:31:10 +0000 Subject: [PATCH 27/36] Rename native_private_kernel_circuit into native_private_kernel_circuit_inner --- circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp | 4 ++-- circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp | 2 +- ...el_circuit.cpp => native_private_kernel_circuit_inner.cpp} | 4 ++-- ...el_circuit.hpp => native_private_kernel_circuit_inner.hpp} | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) rename circuits/cpp/src/aztec3/circuits/kernel/private/{native_private_kernel_circuit.cpp => native_private_kernel_circuit_inner.cpp} (97%) rename circuits/cpp/src/aztec3/circuits/kernel/private/{native_private_kernel_circuit.hpp => native_private_kernel_circuit_inner.hpp} (72%) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index 0280e4655d3e..822c0a1ae74d 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -19,8 +19,8 @@ using aztec3::circuits::abis::SignedTxRequest; using aztec3::circuits::abis::private_kernel::PrivateCallData; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; -using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit_initial; +using aztec3::circuits::kernel::private_kernel::native_private_kernel_circuit_inner; using aztec3::circuits::kernel::private_kernel::private_kernel_circuit; using aztec3::circuits::kernel::private_kernel::utils::dummy_previous_kernel; @@ -100,7 +100,7 @@ WASM_EXPORT uint8_t* private_kernel__sim(uint8_t const* signed_tx_request_buf, .private_call = private_call_data, }; - public_inputs = native_private_kernel_circuit(composer, private_inputs); + public_inputs = native_private_kernel_circuit_inner(composer, private_inputs); } // serialize public inputs to bytes vec diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp index 5682d8470a4e..7195cb64ed0e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/index.hpp @@ -1,4 +1,4 @@ #include "init.hpp" -#include "native_private_kernel_circuit.hpp" #include "native_private_kernel_circuit_init.hpp" +#include "native_private_kernel_circuit_inner.hpp" #include "private_kernel_circuit.hpp" \ No newline at end of file diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp similarity index 97% rename from circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp rename to circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp index 83eb362bff06..1f21db4b18e6 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp @@ -138,8 +138,8 @@ void validate_inputs(DummyComposer& composer, PrivateKernelInputsInner const // TODO: decide what to return. // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. -KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, - PrivateKernelInputsInner const& private_inputs) +KernelCircuitPublicInputs native_private_kernel_circuit_inner(DummyComposer& composer, + PrivateKernelInputsInner const& private_inputs) { // We'll be pushing data to this during execution of this circuit. KernelCircuitPublicInputs public_inputs{}; diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.hpp similarity index 72% rename from circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp rename to circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.hpp index e7afa9e7c1d4..d1e332132aa6 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.hpp @@ -13,7 +13,7 @@ using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using DummyComposer = aztec3::utils::DummyComposer; // TODO: decide what to return. -KernelCircuitPublicInputs native_private_kernel_circuit(DummyComposer& composer, - PrivateKernelInputsInner const& _private_inputs); +KernelCircuitPublicInputs native_private_kernel_circuit_inner(DummyComposer& composer, + PrivateKernelInputsInner const& _private_inputs); } // namespace aztec3::circuits::kernel::private_kernel \ No newline at end of file From 7f8c1441e547411d368943586c40a37bb6bb1600 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Tue, 23 May 2023 17:10:29 +0000 Subject: [PATCH 28/36] Simplify if/else clause on deployment contract boolean in contract logic --- .../aztec3/circuits/kernel/private/common.cpp | 66 +++++++++---------- 1 file changed, 30 insertions(+), 36 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp index 5bbbb04acfa8..66b944525c99 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp @@ -122,10 +122,6 @@ void common_contract_logic(DummyComposer& composer, const auto& storage_contract_address = private_call_public_inputs.call_context.storage_contract_address; const auto& portal_contract_address = private_call.portal_contract_address; const auto& deployer_address = private_call_public_inputs.call_context.msg_sender; - // contract deployment - - // input storage contract address must be 0 if its a constructor call and non-zero otherwise - auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; auto private_call_vk_hash = stdlib::recursion::verification_key::compress_native(private_call.vk, GeneratorIndex::VK); @@ -133,56 +129,54 @@ void common_contract_logic(DummyComposer& composer, auto constructor_hash = compute_constructor_hash(function_data, private_call_public_inputs.args, private_call_vk_hash); - if (is_contract_deployment) { - composer.do_assert(contract_dep_data.constructor_vk_hash == private_call_vk_hash, - "constructor_vk_hash doesn't match private_call_vk_hash", - CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONSTRUCTOR_VK_HASH); - } - auto const new_contract_address = compute_contract_address(deployer_address, contract_dep_data.contract_address_salt, contract_dep_data.function_tree_root, constructor_hash); + // Add new contract data if its a contract deployment function + NewContractData const native_new_contract_data{ new_contract_address, + portal_contract_address, + contract_dep_data.function_tree_root }; + + array_push, KERNEL_NEW_CONTRACTS_LENGTH>(public_inputs.end.new_contracts, + native_new_contract_data); + + auto is_contract_deployment = public_inputs.constants.tx_context.is_contract_deployment_tx; + + // input storage contract address must be 0 if its a constructor call and non-zero otherwise if (is_contract_deployment) { + composer.do_assert(contract_dep_data.constructor_vk_hash == private_call_vk_hash, + "constructor_vk_hash doesn't match private_call_vk_hash", + CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONSTRUCTOR_VK_HASH); + // must imply == derived address composer.do_assert(storage_contract_address == new_contract_address, "contract address supplied doesn't match derived address", CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); + + // compute contract address nullifier + auto const blake_input = new_contract_address.to_field().to_buffer(); + auto const new_contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); + + // push the contract address nullifier to nullifier vector + array_push(public_inputs.end.new_nullifiers, new_contract_address_nullifier); } else { // non-contract deployments must specify contract address being interacted with composer.do_assert(storage_contract_address != 0, "contract address can't be 0 for non-contract deployment related transactions", CircuitErrorCode::PRIVATE_KERNEL__INVALID_CONTRACT_ADDRESS); - } - - // compute contract address nullifier - auto const blake_input = new_contract_address.to_field().to_buffer(); - auto const new_contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); - - // push the contract address nullifier to nullifier vector - if (is_contract_deployment) { - array_push(public_inputs.end.new_nullifiers, new_contract_address_nullifier); - } - - // Add new contract data if its a contract deployment function - NewContractData const native_new_contract_data{ new_contract_address, - portal_contract_address, - contract_dep_data.function_tree_root }; - array_push, KERNEL_NEW_CONTRACTS_LENGTH>(public_inputs.end.new_contracts, - native_new_contract_data); + /* We need to compute the root of the contract tree, starting from the function's VK: + * - Compute the vk_hash (done above) + * - Compute the function_leaf: hash(function_selector, is_private, vk_hash, acir_hash) + * - Hash the function_leaf with the function_leaf's sibling_path to get the function_tree_root + * - Compute the contract_leaf: hash(contract_address, portal_contract_address, function_tree_root) + * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root + */ - /* We need to compute the root of the contract tree, starting from the function's VK: - * - Compute the vk_hash (done above) - * - Compute the function_leaf: hash(function_selector, is_private, vk_hash, acir_hash) - * - Hash the function_leaf with the function_leaf's sibling_path to get the function_tree_root - * - Compute the contract_leaf: hash(contract_address, portal_contract_address, function_tree_root) - * - Hash the contract_leaf with the contract_leaf's sibling_path to get the contract_tree_root - */ + // The logic below ensures that the contract exists in the contracts tree - // The logic below ensures that the contract exists in the contracts tree - if (!is_contract_deployment) { auto const& computed_function_tree_root = function_tree_root_from_siblings(private_call.call_stack_item.function_data.function_selector, true, // is_private From bb55316a43ddf22d7c56013118a5f8181c9706fb Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 09:37:51 +0000 Subject: [PATCH 29/36] abis test snapshot - restore from master for vk hash --- .../src/abis/__snapshots__/abis.test.ts.snap | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap b/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap index 0bfb2e1906ec..3eb2b4dadc87 100644 --- a/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap +++ b/yarn-project/circuits.js/src/abis/__snapshots__/abis.test.ts.snap @@ -152,6 +152,46 @@ exports[`abis wasm bindings hash constructor info 2 args 1`] = ` } `; +exports[`abis wasm bindings hashes VK 1`] = ` +Object { + "data": Array [ + 3, + 215, + 112, + 230, + 112, + 168, + 8, + 190, + 95, + 206, + 52, + 172, + 46, + 85, + 55, + 190, + 134, + 187, + 169, + 57, + 109, + 253, + 250, + 109, + 224, + 150, + 49, + 156, + 32, + 17, + 205, + 37, + ], + "type": "Buffer", +} +`; + exports[`abis wasm bindings hashes a tx request 1`] = ` { "data": [ From 58fa0336f7bda813ef0c0bfed4424c3c9649d9ff Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 09:38:41 +0000 Subject: [PATCH 30/36] Remove old TODO comments --- .../kernel/private/native_private_kernel_circuit_init.cpp | 2 -- .../kernel/private/native_private_kernel_circuit_init.hpp | 1 - .../kernel/private/native_private_kernel_circuit_inner.cpp | 1 - .../kernel/private/native_private_kernel_circuit_inner.hpp | 1 - 4 files changed, 5 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp index 85d2ba6891dc..2bbdbb43597e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp @@ -146,9 +146,7 @@ void update_end_values(PrivateKernelInputsInit const& private_inputs, Kernel array_push(public_inputs.end.new_nullifiers, private_inputs.signed_tx_request.tx_request.nonce); } - // NOTE: THIS IS A VERY UNFINISHED WORK IN PROGRESS. -// TODO: decide what to return. // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyComposer& composer, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.hpp index cf3735d44de8..c9d86e0a397e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.hpp @@ -13,7 +13,6 @@ using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; // using abis::private_kernel::PublicInputs; using DummyComposer = aztec3::utils::DummyComposer; -// TODO: decide what to return. KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyComposer& composer, PrivateKernelInputsInit const& private_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp index 1f21db4b18e6..665b847720f7 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp @@ -135,7 +135,6 @@ void validate_inputs(DummyComposer& composer, PrivateKernelInputsInner const } // NOTE: THIS IS A VERY UNFINISHED WORK IN PROGRESS. -// TODO: decide what to return. // TODO: is there a way to identify whether an input has not been used by ths circuit? This would help us more-safely // ensure we're constraining everything. KernelCircuitPublicInputs native_private_kernel_circuit_inner(DummyComposer& composer, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.hpp index d1e332132aa6..3aff96134508 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.hpp @@ -12,7 +12,6 @@ using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInner; using DummyComposer = aztec3::utils::DummyComposer; -// TODO: decide what to return. KernelCircuitPublicInputs native_private_kernel_circuit_inner(DummyComposer& composer, PrivateKernelInputsInner const& _private_inputs); From ab006b0232f44f93342da2265d115371c1ecfff5 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 09:47:58 +0000 Subject: [PATCH 31/36] Fork FUNCTION_ARGS into FUNCTION/CONSTRUCTOR_ARGS generator indices --- circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp | 2 +- circuits/cpp/src/aztec3/circuits/hash.hpp | 2 +- circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp | 2 +- circuits/cpp/src/aztec3/constants.hpp | 3 ++- yarn-project/circuits.js/src/structs/generators.ts | 6 +++++- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp b/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp index 67f9b698637c..590c88a0f540 100644 --- a/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp @@ -274,7 +274,7 @@ TEST(abi_tests, hash_constructor) // Calculate the expected hash in-test NT::fr const expected_hash = NT::compress( - { func_data.hash(), NT::compress(args, aztec3::GeneratorIndex::FUNCTION_ARGS), constructor_vk_hash }, + { func_data.hash(), NT::compress(args, aztec3::GeneratorIndex::CONSTRUCTOR_ARGS), constructor_vk_hash }, aztec3::GeneratorIndex::CONSTRUCTOR); // Confirm cbind output == expected hash diff --git a/circuits/cpp/src/aztec3/circuits/hash.hpp b/circuits/cpp/src/aztec3/circuits/hash.hpp index 578596625594..0156e8771e72 100644 --- a/circuits/cpp/src/aztec3/circuits/hash.hpp +++ b/circuits/cpp/src/aztec3/circuits/hash.hpp @@ -18,7 +18,7 @@ using aztec3::circuits::abis::FunctionLeafPreimage; template typename NCT::fr compute_args_hash(std::array args) { - return NCT::compress(args, FUNCTION_ARGS); + return NCT::compress(args, CONSTRUCTOR_ARGS); } template typename NCT::fr compute_constructor_hash(FunctionData function_data, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index e9542e187779..a0f668c97758 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -484,7 +484,7 @@ void validate_deployed_contract_address(PrivateKernelInputsInit const& priva auto private_circuit_vk_hash = stdlib::recursion::verification_key::compress_native( private_inputs.private_call.vk, GeneratorIndex::VK); auto expected_constructor_hash = NT::compress({ private_inputs.private_call.call_stack_item.function_data.hash(), - NT::compress(tx_request.args, FUNCTION_ARGS), + NT::compress(tx_request.args, CONSTRUCTOR_ARGS), private_circuit_vk_hash }, CONSTRUCTOR); NT::fr const expected_contract_address = diff --git a/circuits/cpp/src/aztec3/constants.hpp b/circuits/cpp/src/aztec3/constants.hpp index 2b2d6ff9057f..e1379d30710e 100644 --- a/circuits/cpp/src/aztec3/constants.hpp +++ b/circuits/cpp/src/aztec3/constants.hpp @@ -72,7 +72,7 @@ enum GeneratorIndex { FUNCTION_LEAF, CONTRACT_DEPLOYMENT_DATA, CONSTRUCTOR, - FUNCTION_ARGS, + CONSTRUCTOR_ARGS, CONTRACT_ADDRESS, CONTRACT_LEAF, CALL_CONTEXT, @@ -87,6 +87,7 @@ enum GeneratorIndex { PUBLIC_DATA_LEAF, SIGNED_TX_REQUEST, L1_TO_L2_MESSAGE_SECRET, + FUNCTION_ARGS, }; enum StorageSlotGeneratorIndex { diff --git a/yarn-project/circuits.js/src/structs/generators.ts b/yarn-project/circuits.js/src/structs/generators.ts index 3a1f3fa66069..15da8d99a242 100644 --- a/yarn-project/circuits.js/src/structs/generators.ts +++ b/yarn-project/circuits.js/src/structs/generators.ts @@ -17,7 +17,7 @@ export enum GeneratorIndex { FUNCTION_LEAF, CONTRACT_DEPLOYMENT_DATA, CONSTRUCTOR, - FUNCTION_ARGS, + CONSTRUCTOR_ARGS, CONTRACT_ADDRESS, CONTRACT_LEAF, CALL_CONTEXT, @@ -29,4 +29,8 @@ export enum GeneratorIndex { TX_CONTEXT, TX_REQUEST, PUBLIC_LEAF_INDEX, + PUBLIC_DATA_LEAF, + SIGNED_TX_REQUEST, + L1_TO_L2_MESSAGE_SECRET, + FUNCTION_ARGS, } From b7c56b8122b1b2a8fbbf5e8d331e705a9387fdf4 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 10:19:48 +0000 Subject: [PATCH 32/36] Move code copying public/private_call_stack in PKC init --- circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp | 3 +++ .../kernel/private/native_private_kernel_circuit_init.cpp | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp index 66b944525c99..0306a6476e56 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp @@ -90,6 +90,9 @@ void common_update_end_values(DummyComposer& composer, { // call stacks const auto& this_private_call_stack = private_call_public_inputs.private_call_stack; push_array_to_array(this_private_call_stack, public_inputs.end.private_call_stack); + + const auto& this_public_call_stack = private_call_public_inputs.public_call_stack; + push_array_to_array(this_public_call_stack, public_inputs.end.public_call_stack); } { // new l2 to l1 messages diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp index 2bbdbb43597e..6673a16bfd69 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp @@ -62,9 +62,6 @@ void initialise_end_values(PrivateKernelInputsInit const& private_inputs, // Set the constants in public_inputs. public_inputs.constants = constants; - - push_array_to_array(private_call_public_inputs.private_call_stack, public_inputs.end.private_call_stack); - push_array_to_array(private_call_public_inputs.public_call_stack, public_inputs.end.public_call_stack); } void validate_this_private_call_against_tx_request(DummyComposer& composer, From 8f00d8be59558a1c73b3718badd3a58cca7f7a02 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 11:07:37 +0000 Subject: [PATCH 33/36] Clang tidy fix --- .../kernel/private/native_private_kernel_circuit_init.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp index 6673a16bfd69..c4e32dfa3a95 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp @@ -14,7 +14,6 @@ using aztec3::circuits::abis::PrivateHistoricTreeRoots; using aztec3::circuits::abis::private_kernel::PrivateKernelInputsInit; using aztec3::utils::array_push; using aztec3::utils::is_array_empty; -using aztec3::utils::push_array_to_array; using CircuitErrorCode = aztec3::utils::CircuitErrorCode; namespace aztec3::circuits::kernel::private_kernel { From 61e3a7bc645ab37222a9791dcb593685dacfc21b Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 11:47:30 +0000 Subject: [PATCH 34/36] Add clarifications into a comment --- circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp index 822c0a1ae74d..51b467872c45 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/c_bind.cpp @@ -114,7 +114,9 @@ WASM_EXPORT uint8_t* private_kernel__sim(uint8_t const* signed_tx_request_buf, return composer.alloc_and_serialize_first_failure(); } -// jeanmon: only support inner variant +// TODO(jeanmon): We currently only support inner variant because the circuit version +// was not splitted into inner/init counterparts. Once this is done, we have to modify +// the below method to dispatch over the two variants based on first_iteration boolean. // returns size of proof data WASM_EXPORT size_t private_kernel__prove(uint8_t const* signed_tx_request_buf, uint8_t const* previous_kernel_buf, From 332762f0f5017eaefa69cccd77596249af2247a7 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 12:07:25 +0000 Subject: [PATCH 35/36] Added comments --- circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp | 2 +- .../kernel/private/native_private_kernel_circuit_init.cpp | 5 +++++ .../kernel/private/native_private_kernel_circuit_inner.cpp | 2 ++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp index ab238b154b57..502929e134e3 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/common.hpp @@ -16,7 +16,7 @@ using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::KernelCircuitPublicInputs; using aztec3::circuits::abis::private_kernel::PrivateCallData; - +// TODO(suyash): Add comments to these as well as other functions in PKC-init. void common_validate_call_stack(DummyComposer& composer, PrivateCallData const& private_call); void common_update_end_values(DummyComposer& composer, diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp index c4e32dfa3a95..2a1e6ef5bf1e 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_init.cpp @@ -156,8 +156,13 @@ KernelCircuitPublicInputs native_private_kernel_circuit_initial(DummyCompose validate_inputs(composer, private_inputs); + // TODO(rahul) FIXME - https://github.com/AztecProtocol/aztec-packages/issues/499 + // Noir doesn't have hash index so it can't hash private call stack item correctly + // TODO(jeanmon) FIXME - https://github.com/AztecProtocol/aztec-packages/issues/672 // validate_this_private_call_against_tx_request(composer, private_inputs); + // TODO(dbanks12): may need to comment out hash check in here according to TODO above + // TODO(jeanmon) FIXME - https://github.com/AztecProtocol/aztec-packages/issues/671 // common_validate_call_stack(composer, private_inputs.private_call); update_end_values(private_inputs, public_inputs); diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp index 665b847720f7..9ffa1974ee4c 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit_inner.cpp @@ -153,7 +153,9 @@ KernelCircuitPublicInputs native_private_kernel_circuit_inner(DummyComposer& // TODO(rahul) FIXME - https://github.com/AztecProtocol/aztec-packages/issues/499 // Noir doesn't have hash index so it can't hash private call stack item correctly // validate_this_private_call_stack(composer, private_inputs); + // TODO(dbanks12): may need to comment out hash check in here according to TODO above + // TODO(jeanmon) FIXME - https://github.com/AztecProtocol/aztec-packages/issues/671 // common_validate_call_stack(composer, private_inputs.private_call); common_update_end_values(composer, private_inputs.private_call, public_inputs); From 58864f3f1eabd3da313fa2dc98effb7d8c500c89 Mon Sep 17 00:00:00 2001 From: jeanmon Date: Thu, 25 May 2023 12:59:34 +0000 Subject: [PATCH 36/36] remove empty lines --- circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp index a0f668c97758..8677ed2f34df 100644 --- a/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/circuits/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -385,7 +385,6 @@ PrivateKernelInputsInit do_private_call_get_kernel_inputs_init(bool const is //*************************************************************************** PrivateKernelInputsInit kernel_private_inputs = PrivateKernelInputsInit{ .signed_tx_request = signed_tx_request, - .private_call = private_call_data, }; @@ -460,7 +459,6 @@ PrivateKernelInputsInner do_private_call_get_kernel_inputs_inner(bool const //*************************************************************************** PrivateKernelInputsInner kernel_private_inputs = PrivateKernelInputsInner{ .previous_kernel = mock_previous_kernel, - .private_call = private_call_data, };