diff --git a/cpp/barretenberg b/cpp/barretenberg index 9a56aa33..6c101be1 160000 --- a/cpp/barretenberg +++ b/cpp/barretenberg @@ -1 +1 @@ -Subproject commit 9a56aa3370306d5f9b7e9b6324220f8c713674ef +Subproject commit 6c101be134bbea01deed88a5085ebd35e6f62796 diff --git a/cpp/src/aztec3/circuits/abis/c_bind.cpp b/cpp/src/aztec3/circuits/abis/c_bind.cpp index 1a462456..7ddea1cc 100644 --- a/cpp/src/aztec3/circuits/abis/c_bind.cpp +++ b/cpp/src/aztec3/circuits/abis/c_bind.cpp @@ -15,6 +15,7 @@ #include "private_kernel/private_inputs.hpp" #include "private_kernel/public_inputs.hpp" +#include #include #include @@ -25,6 +26,8 @@ namespace { +using aztec3::circuits::compute_constructor_hash; +using aztec3::circuits::compute_contract_address; using aztec3::circuits::abis::FunctionData; using aztec3::circuits::abis::FunctionLeafPreimage; using aztec3::circuits::abis::TxContext; @@ -296,16 +299,8 @@ WASM_EXPORT void abis__hash_constructor(uint8_t const* function_data_buf, read(args_buf, args); read(constructor_vk_hash_buf, constructor_vk_hash); - NT::fr function_data_hash = function_data.hash(); - NT::fr args_hash = NT::compress(args, aztec3::CONSTRUCTOR_ARGS); + NT::fr constructor_hash = compute_constructor_hash(function_data, args, constructor_vk_hash); - std::vector inputs = { - function_data_hash, - args_hash, - constructor_vk_hash, - }; - - NT::fr constructor_hash = NT::compress(inputs, aztec3::GeneratorIndex::CONSTRUCTOR); NT::fr::serialize_to_buffer(constructor_hash, output); } @@ -341,14 +336,9 @@ WASM_EXPORT void abis__compute_contract_address(uint8_t const* deployer_address_ read(function_tree_root_buf, function_tree_root); read(constructor_hash_buf, constructor_hash); - std::vector inputs = { - deployer_address, - contract_address_salt, - function_tree_root, - constructor_hash, - }; + NT::address contract_address = + compute_contract_address(deployer_address, contract_address_salt, function_tree_root, constructor_hash); - NT::address contract_address = NT::fr(NT::compress(inputs, aztec3::GeneratorIndex::CONTRACT_ADDRESS)); NT::fr::serialize_to_buffer(contract_address, output); } diff --git a/cpp/src/aztec3/circuits/abis/c_bind.test.cpp b/cpp/src/aztec3/circuits/abis/c_bind.test.cpp index a3f7c761..364c92ba 100644 --- a/cpp/src/aztec3/circuits/abis/c_bind.test.cpp +++ b/cpp/src/aztec3/circuits/abis/c_bind.test.cpp @@ -110,7 +110,7 @@ TEST(abi_tests, hash_vk) // Initialize some random VK data NT::VKData vk_data; vk_data.composer_type = engine.get_random_uint32(); - vk_data.circuit_size = engine.get_random_uint32(); + vk_data.circuit_size = uint32_t(1) << (engine.get_random_uint8() >> 3); // must be a power of two vk_data.num_public_inputs = engine.get_random_uint32(); vk_data.commitments["test1"] = g1::element::random_element(); vk_data.commitments["test2"] = g1::element::random_element(); diff --git a/cpp/src/aztec3/circuits/hash.hpp b/cpp/src/aztec3/circuits/hash.hpp new file mode 100644 index 00000000..25361f13 --- /dev/null +++ b/cpp/src/aztec3/circuits/hash.hpp @@ -0,0 +1,77 @@ +#include +#include + +namespace aztec3::circuits { + +using abis::FunctionData; + +template typename NCT::fr compute_args_hash(std::array args) +{ + return NCT::compress(args, CONSTRUCTOR_ARGS); +} + +template +typename NCT::fr compute_constructor_hash(FunctionData function_data, + std::array args, + typename NCT::fr constructor_vk_hash) +{ + using fr = typename NCT::fr; + + fr function_data_hash = function_data.hash(); + fr args_hash = compute_args_hash(args); + + std::vector inputs = { + function_data_hash, + args_hash, + constructor_vk_hash, + }; + + return NCT::compress(inputs, aztec3::GeneratorIndex::CONSTRUCTOR); +} + +template +typename NCT::address compute_contract_address(typename NCT::address deployer_address, + typename NCT::fr contract_address_salt, + typename NCT::fr function_tree_root, + typename NCT::fr constructor_hash) +{ + using fr = typename NCT::fr; + using address = typename NCT::address; + + std::vector inputs = { + deployer_address.to_field(), + contract_address_salt, + function_tree_root, + constructor_hash, + }; + + return address(NCT::compress(inputs, aztec3::GeneratorIndex::CONTRACT_ADDRESS)); +} + +template +typename NCT::fr add_contract_address_to_commitment(typename NCT::address contract_address, typename NCT::fr commitment) +{ + using fr = typename NCT::fr; + + std::vector inputs = { + contract_address.to_field(), + commitment, + }; + + return NCT::compress(inputs, aztec3::GeneratorIndex::OUTER_COMMITMENT); +} + +template +typename NCT::fr add_contract_address_to_nullifier(typename NCT::address contract_address, typename NCT::fr nullifier) +{ + using fr = typename NCT::fr; + + std::vector inputs = { + contract_address.to_field(), + nullifier, + }; + + return NCT::compress(inputs, aztec3::GeneratorIndex::OUTER_NULLIFIER); +} + +} // namespace aztec3::circuits \ No newline at end of file diff --git a/cpp/src/aztec3/circuits/kernel/private/.test.cpp b/cpp/src/aztec3/circuits/kernel/private/.test.cpp index 90da6cde..27c2980c 100644 --- a/cpp/src/aztec3/circuits/kernel/private/.test.cpp +++ b/cpp/src/aztec3/circuits/kernel/private/.test.cpp @@ -530,7 +530,8 @@ TEST(private_kernel_tests, test_basic_contract_deployment) // Now we can derive the vk: std::shared_ptr constructor_vk = dummy_constructor_composer.compute_verification_key(); - auto constructor_vk_hash = stdlib::recursion::verification_key::compress_native(constructor_vk); + auto constructor_vk_hash = + stdlib::recursion::verification_key::compress_native(constructor_vk, GeneratorIndex::VK); // Now, we can proceed with the proper (non-dummy) invokation of our constructor circuit: @@ -768,7 +769,8 @@ TEST(private_kernel_tests, test_native_basic_contract_deployment) // Now we can derive the vk: std::shared_ptr constructor_vk = dummy_constructor_composer.compute_verification_key(); - auto constructor_vk_hash = stdlib::recursion::verification_key::compress_native(constructor_vk); + auto constructor_vk_hash = + stdlib::recursion::verification_key::compress_native(constructor_vk, GeneratorIndex::VK); // Now, we can proceed with the proper (non-dummy) invokation of our constructor circuit: diff --git a/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp b/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp index 32801811..5ea41dd4 100644 --- a/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp +++ b/cpp/src/aztec3/circuits/kernel/private/native_private_kernel_circuit.cpp @@ -1,3 +1,4 @@ +#include "aztec3/constants.hpp" #include "init.hpp" #include @@ -5,6 +6,7 @@ #include #include +#include namespace aztec3::circuits::kernel::private_kernel { @@ -18,6 +20,9 @@ using aztec3::utils::array_push; using aztec3::utils::is_array_empty; using aztec3::utils::push_array_to_array; +using aztec3::circuits::compute_constructor_hash; +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, @@ -88,27 +93,24 @@ void update_end_values(PrivateInputs const& private_inputs, PublicInputs ASSERT(storage_contract_address != 0); } - auto private_call_vk_hash = - stdlib::recursion::verification_key::compress_native(private_inputs.private_call.vk); - auto constructor_hash = - NT::compress({ private_inputs.signed_tx_request.tx_request.function_data.hash(), - NT::compress(private_call_public_inputs.args, CONSTRUCTOR_ARGS), - private_call_vk_hash }, - CONSTRUCTOR); + 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) { ASSERT(contract_deployment_data.constructor_vk_hash == private_call_vk_hash); } - // compute the contract address - auto contract_address = NT::compress({ deployer_address.to_field(), - contract_deployment_data.contract_address_salt, - contract_deployment_data.function_tree_root, - constructor_hash }, - CONTRACT_ADDRESS); + auto contract_address = compute_contract_address(deployer_address, + contract_deployment_data.contract_address_salt, + contract_deployment_data.function_tree_root, + constructor_hash); // compute contract address nullifier - auto blake_input = contract_address.to_buffer(); + auto blake_input = contract_address.to_field().to_buffer(); auto contract_address_nullifier = NT::fr::serialize_from_buffer(NT::blake3s(blake_input).data()); // push the contract address nullifier to nullifier vector @@ -136,18 +138,18 @@ void update_end_values(PrivateInputs const& private_inputs, PublicInputs { // 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 - : NT::compress({ storage_contract_address.to_field(), new_commitments[i] }, - GeneratorIndex::OUTER_COMMITMENT); + 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 - : NT::compress({ storage_contract_address.to_field(), new_nullifiers[i] }, - GeneratorIndex::OUTER_NULLIFIER); + 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); diff --git a/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp b/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp index ad018071..3d851736 100644 --- a/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp +++ b/cpp/src/aztec3/circuits/kernel/private/private_kernel_circuit.cpp @@ -1,3 +1,4 @@ +#include "aztec3/constants.hpp" #include "init.hpp" #include @@ -6,6 +7,8 @@ #include #include +#include + namespace aztec3::circuits::kernel::private_kernel { using aztec3::circuits::abis::private_kernel::NewContractData; @@ -18,6 +21,11 @@ using plonk::stdlib::array_push; using plonk::stdlib::is_array_empty; using plonk::stdlib::push_array_to_array; +using aztec3::circuits::add_contract_address_to_commitment; +using aztec3::circuits::add_contract_address_to_nullifier; +using aztec3::circuits::compute_constructor_hash; +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, @@ -112,25 +120,22 @@ void update_end_values(PrivateInputs const& private_inputs, PublicInputs .must_imply(storage_contract_address != CT::fr(0), "storage_contract_address is zero for a private function"); - auto private_call_vk_hash = private_inputs.private_call.vk->compress(); - auto constructor_hash = - CT::compress({ private_inputs.signed_tx_request.tx_request.function_data.hash(), - CT::compress(private_call_public_inputs.args, CONSTRUCTOR_ARGS), - private_call_vk_hash }, - CONSTRUCTOR); + 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, + private_call_public_inputs.args, + private_call_vk_hash); is_contract_deployment.must_imply(contract_deployment_data.constructor_vk_hash == private_call_vk_hash, "constructor_vk_hash does not match private call vk hash"); // compute the contract address - auto contract_address = CT::compress({ deployer_address.to_field(), - contract_deployment_data.contract_address_salt, - contract_deployment_data.function_tree_root, - constructor_hash }, - CONTRACT_ADDRESS); + auto contract_address = compute_contract_address(deployer_address, + contract_deployment_data.contract_address_salt, + contract_deployment_data.function_tree_root, + constructor_hash); // compute contract address nullifier - auto blake_input = CT::byte_array(contract_address); + auto blake_input = CT::byte_array(contract_address.to_field()); auto contract_address_nullifier = CT::fr(CT::blake3s(blake_input)); // push the contract address nullifier to nullifier vector @@ -152,19 +157,17 @@ void update_end_values(PrivateInputs const& private_inputs, PublicInputs { // commitments, nullifiers, and contracts std::array siloed_new_commitments; for (size_t i = 0; i < new_commitments.size(); ++i) { - siloed_new_commitments[i] = - CT::fr::conditional_assign(new_commitments[i] == 0, - 0, - CT::compress({ storage_contract_address.to_field(), new_commitments[i] }, - GeneratorIndex::OUTER_COMMITMENT)); + siloed_new_commitments[i] = CT::fr::conditional_assign( + 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] = - CT::fr::conditional_assign(new_nullifiers[i] == 0, - 0, - CT::compress({ storage_contract_address.to_field(), new_nullifiers[i] }, - GeneratorIndex::OUTER_NULLIFIER)); + siloed_new_nullifiers[i] = CT::fr::conditional_assign( + new_nullifiers[i] == 0, + 0, + add_contract_address_to_nullifier(storage_contract_address, new_nullifiers[i])); } // Add new commitments/etc to AggregatedData