Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: computeContractAddress as computeCompleteAddress #1876

Merged
merged 10 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 5 additions & 67 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "rollup/root/root_rollup_public_inputs.hpp"

#include "aztec3/circuits/abis/combined_accumulated_data.hpp"
#include "aztec3/circuits/abis/complete_address.hpp"
#include "aztec3/circuits/abis/final_accumulated_data.hpp"
#include "aztec3/circuits/abis/new_contract_data.hpp"
#include "aztec3/circuits/abis/packers.hpp"
Expand All @@ -33,9 +34,8 @@
namespace {

using aztec3::circuits::compute_constructor_hash;
using aztec3::circuits::compute_contract_address;
using aztec3::circuits::compute_partial_address;
using aztec3::circuits::abis::CallStackItem;
using aztec3::circuits::abis::CompleteAddress;
using aztec3::circuits::abis::ConstantsPacker;
using aztec3::circuits::abis::FunctionData;
using aztec3::circuits::abis::FunctionLeafPreimage;
Expand Down Expand Up @@ -289,39 +289,9 @@ WASM_EXPORT void abis__hash_constructor(uint8_t const* function_data_buf,
}

/**
* @brief Compute a contract address
* This is a WASM-export that can be called from Typescript.
*
* @details Computes a contract address by hashing the deployers public key along with the previously computed partial
* address Return the serialized results in the `output` buffer.
*
* @param point_data_buf point data struct as a buffer of bytes
* @param contract_address_salt_buf salt value for the contract address
* @param function_tree_root_buf root value of the contract's function tree
* @param constructor_hash_buf the hash of the contract constructor's verification key
* @param output buffer that will contain the output. The serialized contract address.
* @brief Compute a complete address.
*/
WASM_EXPORT void abis__compute_contract_address(uint8_t const* point_data_buf,
uint8_t const* contract_address_salt_buf,
uint8_t const* function_tree_root_buf,
uint8_t const* constructor_hash_buf,
uint8_t* output)
{
Point<NT> deployer_public_key;
NT::fr contract_address_salt;
NT::fr function_tree_root;
NT::fr constructor_hash;

serialize::read(point_data_buf, deployer_public_key);
read(contract_address_salt_buf, contract_address_salt);
read(function_tree_root_buf, function_tree_root);
read(constructor_hash_buf, constructor_hash);

NT::fr const contract_address =
compute_contract_address(deployer_public_key, contract_address_salt, function_tree_root, constructor_hash);

NT::fr::serialize_to_buffer(contract_address, output);
}
CBIND(abis__compute_complete_address, aztec3::circuits::abis::CompleteAddress<NT>::compute);

/**
* @brief Compute a contract address from deployer public key and partial address.
Expand Down Expand Up @@ -350,38 +320,6 @@ WASM_EXPORT void abis__compute_contract_address_from_partial(uint8_t const* poin
NT::fr::serialize_to_buffer(contract_address, output);
}

/**
* @brief Compute a partial address
* This is a WASM-export that can be called from Typescript.
*
* @details Computes a partial address by hashing the salt, function tree root and constructor hash
* Return the serialized results in the `output` buffer.
*
* @param contract_address_salt_buf salt value for the contract address
* @param function_tree_root_buf root value of the contract's function tree
* @param constructor_hash_buf the hash of the contract constructor's verification key
* @param output buffer that will contain the output. The serialized contract address.
* See the link bellow for more details:
* https://github.com/AztecProtocol/aztec-packages/blob/master/docs/docs/concepts/foundation/accounts/keys.md#addresses-partial-addresses-and-public-keys
*/
WASM_EXPORT void abis__compute_partial_address(uint8_t const* contract_address_salt_buf,
uint8_t const* function_tree_root_buf,
uint8_t const* constructor_hash_buf,
uint8_t* output)
{
NT::fr contract_address_salt;
NT::fr function_tree_root;
NT::fr constructor_hash;

read(contract_address_salt_buf, contract_address_salt);
read(function_tree_root_buf, function_tree_root);
read(constructor_hash_buf, constructor_hash);
NT::fr const partial_address =
compute_partial_address<NT>(contract_address_salt, function_tree_root, constructor_hash);

NT::fr::serialize_to_buffer(partial_address, output);
}

/**
* @brief Hash args for a function call.
*
Expand All @@ -400,7 +338,7 @@ WASM_EXPORT void abis__compute_var_args_hash(uint8_t const* args_buf, uint8_t* o
* @brief Generates a function tree leaf from its preimage.
* This is a WASM-export that can be called from Typescript.
*
* @details given a `uint8_t const*` buffer representing a function leaf's prieimage,
* @details given a `uint8_t const*` buffer representing a function leaf's preimage,
* construct a NewContractData instance, hash, and return the serialized results
* in the `output` buffer.
*
Expand Down
11 changes: 1 addition & 10 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,7 @@ WASM_EXPORT void abis__hash_constructor(uint8_t const* func_data_buf,
uint8_t const* constructor_vk_hash_buf,
uint8_t* output);

WASM_EXPORT void abis__compute_contract_address(uint8_t const* point_data_buf,
uint8_t const* contract_address_salt_buf,
uint8_t const* function_tree_root_buf,
uint8_t const* constructor_hash_buf,
uint8_t* output);

WASM_EXPORT void abis__compute_partial_address(uint8_t const* contract_address_salt_buf,
uint8_t const* function_tree_root_buf,
uint8_t const* constructor_hash_buf,
uint8_t* output);
CBIND_DECL(abis__compute_complete_address);

CBIND_DECL(abis__compute_commitment_nonce);
CBIND_DECL(abis__compute_unique_commitment);
Expand Down
51 changes: 1 addition & 50 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "function_leaf_preimage.hpp"
#include "tx_request.hpp"

#include "aztec3/circuits/abis/complete_address.hpp"
#include "aztec3/circuits/abis/new_contract_data.hpp"
#include "aztec3/circuits/abis/tx_request.hpp"
#include "aztec3/circuits/hash.hpp"
Expand Down Expand Up @@ -50,56 +51,6 @@ template <size_t NUM_BYTES> std::string bytes_to_hex_str(std::array<uint8_t, NUM

namespace aztec3::circuits::abis {

TEST(abi_tests, compute_partial_address)
{
auto const contract_address_salt = NT::fr(3);
auto const function_tree_root = NT::fr(4);
auto const constructor_hash = NT::fr(5);
NT::fr const expected = compute_partial_address<NT>(contract_address_salt, function_tree_root, constructor_hash);

std::array<uint8_t, sizeof(NT::fr)> output = { 0 };
std::vector<uint8_t> salt_buf;
std::vector<uint8_t> function_tree_root_buf;
std::vector<uint8_t> constructor_hash_buf;
write(salt_buf, contract_address_salt);
write(function_tree_root_buf, function_tree_root);
write(constructor_hash_buf, constructor_hash);
abis__compute_partial_address(
salt_buf.data(), function_tree_root_buf.data(), constructor_hash_buf.data(), output.data());

// Convert buffer to `fr` for comparison to in-test calculated hash
NT::fr const actual = NT::fr::serialize_from_buffer(output.data());
EXPECT_EQ(actual, expected);
}

TEST(abi_tests, compute_contract_address)
{
Point<NT> const point = { .x = 1, .y = 3 };
auto const contract_address_salt = NT::fr(5);
auto const function_tree_root = NT::fr(6);
auto const constructor_hash = NT::fr(7);
NT::fr const expected =
compute_contract_address(point, contract_address_salt, function_tree_root, constructor_hash);

std::array<uint8_t, sizeof(NT::fr)> output = { 0 };
std::vector<uint8_t> contract_address_salt_buf;
std::vector<uint8_t> function_tree_root_buf;
std::vector<uint8_t> constructor_hash_buf;
std::vector<uint8_t> point_buf;
write(contract_address_salt_buf, contract_address_salt);
write(function_tree_root_buf, function_tree_root);
write(constructor_hash_buf, constructor_hash);
serialize::write(point_buf, point);
abis__compute_contract_address(point_buf.data(),
contract_address_salt_buf.data(),
function_tree_root_buf.data(),
constructor_hash_buf.data(),
output.data());

// Convert buffer to `fr` for comparison to in-test calculated hash
NT::fr const actual = NT::fr::serialize_from_buffer(output.data());
EXPECT_EQ(actual, expected);
}
TEST(abi_tests, hash_tx_request)
{
// Construct TxRequest with some randomized fields
Expand Down
90 changes: 90 additions & 0 deletions circuits/cpp/src/aztec3/circuits/abis/complete_address.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#pragma once
#include "aztec3/circuits/abis/coordinate.hpp"
#include "aztec3/circuits/abis/point.hpp"
#include "aztec3/circuits/hash.hpp"
#include "aztec3/utils/types/circuit_types.hpp"
#include "aztec3/utils/types/convert.hpp"
#include "aztec3/utils/types/native_types.hpp"

#include <barretenberg/barretenberg.hpp>

namespace aztec3::circuits::abis {

using aztec3::circuits::compute_partial_address;
using aztec3::utils::types::CircuitTypes;
using aztec3::utils::types::NativeTypes;

template <typename NCT> struct CompleteAddress {
using fr = typename NCT::fr;
using boolean = typename NCT::boolean;

typename NCT::address address;
Point<NCT> public_key;
fr partial_address;

// for serialization, update with new fields
MSGPACK_FIELDS(address, public_key, partial_address);
bool operator==(CompleteAddress<NCT> const&) const = default;

template <typename Builder> CompleteAddress<CircuitTypes<Builder>> to_circuit_type(Builder& builder) const
{
static_assert((std::is_same<NativeTypes, NCT>::value));

auto to_ct = [&](auto& e) { return aztec3::utils::types::to_ct(builder, e); };

CompleteAddress<CircuitTypes<Builder>> complete_address = { to_ct(address),
to_ct(public_key),
to_ct(partial_address) };

return complete_address;
};

template <typename Builder> CompleteAddress<NativeTypes> to_native_type() const
{
static_assert((std::is_same<CircuitTypes<Builder>, NCT>::value));

auto to_nt = [&](auto& e) { return aztec3::utils::types::to_nt<Builder>(e); };

CompleteAddress<NativeTypes> complete_address = { to_nt(address), to_nt(public_key), to_nt(partial_address) };

return complete_address;
};

void set_public()
{
static_assert(!(std::is_same<NativeTypes, NCT>::value));

address.set_public();
public_key.set_public();
partial_address.set_public();
}

void assert_is_zero()
{
static_assert(!(std::is_same<NativeTypes, NCT>::value));

address.assert_is_zero();
public_key.assert_is_zero();
partial_address.assert_is_zero();
}

static CompleteAddress<NCT> compute(Point<NCT> const& point,
typename NCT::fr const& contract_address_salt,
typename NCT::fr const& function_tree_root,
typename NCT::fr const& constructor_hash)
{
using fr = typename NCT::fr;

const fr partial_address =
compute_partial_address<NCT>(contract_address_salt, function_tree_root, constructor_hash);

CompleteAddress<NCT> complete_address;
complete_address.address = compute_contract_address_from_partial(point, partial_address);
complete_address.public_key = point;
complete_address.partial_address = partial_address;

return complete_address;
}
};

} // namespace aztec3::circuits::abis
13 changes: 0 additions & 13 deletions circuits/cpp/src/aztec3/circuits/hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,6 @@ typename NCT::address compute_contract_address_from_partial(Point<NCT> const& po
return { NCT::hash(inputs, aztec3::GeneratorIndex::CONTRACT_ADDRESS) };
}

template <typename NCT> typename NCT::address compute_contract_address(Point<NCT> const& point,
typename NCT::fr const& contract_address_salt,
typename NCT::fr const& function_tree_root,
typename NCT::fr const& constructor_hash)
{
using fr = typename NCT::fr;

const fr partial_address =
compute_partial_address<NCT>(contract_address_salt, function_tree_root, constructor_hash);

return compute_contract_address_from_partial(point, partial_address);
}

template <typename NCT> typename NCT::fr compute_commitment_nonce(typename NCT::fr const& first_nullifier,
typename NCT::fr const& commitment_index)
{
Expand Down
10 changes: 6 additions & 4 deletions circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "init.hpp"

#include "aztec3/circuits/abis/complete_address.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"
Expand Down Expand Up @@ -288,10 +289,11 @@ void common_contract_logic(DummyBuilder& builder,
auto constructor_hash =
compute_constructor_hash(function_data, private_call_public_inputs.args_hash, private_call_vk_hash);

auto const new_contract_address = compute_contract_address<NT>(contract_dep_data.deployer_public_key,
contract_dep_data.contract_address_salt,
contract_dep_data.function_tree_root,
constructor_hash);
auto const new_contract_address = abis::CompleteAddress<NT>::compute(contract_dep_data.deployer_public_key,
contract_dep_data.contract_address_salt,
contract_dep_data.function_tree_root,
constructor_hash)
.address;

// Add new contract data if its a contract deployment function
NewContractData<NT> const native_new_contract_data{ new_contract_address,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "init.hpp"

#include "aztec3/circuits/abis/complete_address.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"
Expand All @@ -21,7 +22,6 @@ using plonk::stdlib::is_array_empty;
using plonk::stdlib::push_array_to_array;

using aztec3::circuits::compute_constructor_hash;
using aztec3::circuits::compute_contract_address;
using aztec3::circuits::silo_commitment;
using aztec3::circuits::silo_nullifier;

Expand Down Expand Up @@ -113,10 +113,11 @@ void update_end_values(PrivateKernelInputsInner<CT> const& private_inputs, Kerne
"constructor_vk_hash does not match private call vk hash");

// compute the contract address (only valid if this is a contract deployment)
auto contract_address = compute_contract_address<CT>(contract_deployment_data.deployer_public_key,
contract_deployment_data.contract_address_salt,
contract_deployment_data.function_tree_root,
constructor_hash);
auto const contract_address = abis::CompleteAddress<CT>::compute(contract_deployment_data.deployer_public_key,
contract_deployment_data.contract_address_salt,
contract_deployment_data.function_tree_root,
constructor_hash)
.address;

// must imply == derived address
is_contract_deployment.must_imply(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#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/complete_address.hpp"
#include "aztec3/circuits/abis/contract_deployment_data.hpp"
#include "aztec3/circuits/abis/function_data.hpp"
#include "aztec3/circuits/abis/historic_block_data.hpp"
Expand Down Expand Up @@ -225,8 +226,11 @@ std::pair<PrivateCallData<NT>, ContractDeploymentData<NT>> create_private_call_d
auto constructor_hash = compute_constructor_hash<NT>(function_data, args_hash, private_circuit_vk_hash);

// Derive contract address so that it can be used inside the constructor itself
contract_address = compute_contract_address<NT>(
msg_sender_pub_key, contract_address_salt, contract_deployment_data.function_tree_root, constructor_hash);
contract_address = abis::CompleteAddress<NT>::compute(msg_sender_pub_key,
contract_address_salt,
contract_deployment_data.function_tree_root,
constructor_hash)
.address;
// update the contract address in the call context now that it is known
call_context.storage_contract_address = contract_address;
} else {
Expand Down Expand Up @@ -529,8 +533,10 @@ bool validate_deployed_contract_address(PrivateKernelInputsInit<NT> const& priva
auto expected_constructor_hash = compute_constructor_hash(
private_inputs.private_call.call_stack_item.function_data, tx_request.args_hash, private_circuit_vk_hash);

NT::fr const expected_contract_address = compute_contract_address(
cdd.deployer_public_key, cdd.contract_address_salt, cdd.function_tree_root, expected_constructor_hash);
NT::fr const expected_contract_address =
abis::CompleteAddress<NT>::compute(
cdd.deployer_public_key, cdd.contract_address_salt, cdd.function_tree_root, expected_constructor_hash)
.address;

return (public_inputs.end.new_contracts[0].contract_address.to_field() == expected_contract_address);
}
Expand Down
Loading