Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
benesjan committed Aug 30, 2023
1 parent 8b43fdd commit 4376b77
Show file tree
Hide file tree
Showing 12 changed files with 124 additions and 101 deletions.
40 changes: 6 additions & 34 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,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/new_contract_data.hpp"
#include "aztec3/circuits/abis/packers.hpp"
#include "aztec3/circuits/abis/point.hpp"
Expand All @@ -30,10 +31,11 @@

namespace {

using aztec3::circuits::compute_complete_contract_address;
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 @@ -287,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_contract_address, aztec3::circuits::compute_complete_contract_address<NT>);

/**
* @brief Compute a contract address from deployer public key and partial address.
Expand Down Expand Up @@ -398,7 +370,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
6 changes: 1 addition & 5 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,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);
CBIND_DECL(abis__compute_complete_contract_address);

WASM_EXPORT void abis__compute_partial_address(uint8_t const* contract_address_salt_buf,
uint8_t const* function_tree_root_buf,
Expand Down
17 changes: 9 additions & 8 deletions circuits/cpp/src/aztec3/circuits/abis/c_bind.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,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 @@ -71,14 +72,14 @@ TEST(abi_tests, compute_partial_address)
EXPECT_EQ(actual, expected);
}

TEST(abi_tests, compute_contract_address)
TEST(abi_tests, compute_complete_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);
CompleteAddress<NT> const expected =
compute_complete_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;
Expand All @@ -89,11 +90,11 @@ TEST(abi_tests, compute_contract_address)
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());
abis__compute_complete_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());
Expand Down
70 changes: 70 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,70 @@
#pragma once
#include "aztec3/circuits/abis/coordinate.hpp"
#include "aztec3/circuits/abis/point.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::utils::types::CircuitTypes;
using aztec3::utils::types::NativeTypes;

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

fr 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();
}
};

} // namespace aztec3::circuits::abis
17 changes: 11 additions & 6 deletions circuits/cpp/src/aztec3/circuits/hash.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include "aztec3/circuits/abis/complete_address.hpp"
#include "aztec3/circuits/abis/function_data.hpp"
#include "aztec3/circuits/abis/function_leaf_preimage.hpp"
#include "aztec3/circuits/abis/function_selector.hpp"
Expand All @@ -16,6 +17,7 @@

namespace aztec3::circuits {

using abis::CompleteAddress;
using abis::FunctionData;
using abis::FunctionSelector;
using abis::Point;
Expand Down Expand Up @@ -72,17 +74,20 @@ 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)
template <typename NCT>
typename NCT::CompleteAddress compute_complete_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;
using CompleteAddress = typename NCT::CompleteAddress;

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);
const fr contract_address = compute_contract_address_from_partial(point, partial_address);
const CompleteAddress complete_address = { contract_address, point, partial_address };
return complete_address;
}

template <typename NCT> typename NCT::fr compute_commitment_nonce(typename NCT::fr const& first_nullifier,
Expand Down
9 changes: 5 additions & 4 deletions circuits/cpp/src/aztec3/circuits/kernel/private/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,10 +340,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 = compute_complete_contract_address(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
Expand Up @@ -20,8 +20,8 @@ using plonk::stdlib::array_push;
using plonk::stdlib::is_array_empty;
using plonk::stdlib::push_array_to_array;

using aztec3::circuits::compute_complete_contract_address;
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 contract_address = compute_complete_contract_address<CT>(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 @@ -225,10 +225,10 @@ 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>(
const auto complete_contract_address = compute_complete_contract_address<NT>(
msg_sender_pub_key, contract_address_salt, contract_deployment_data.function_tree_root, constructor_hash);
// update the contract address in the call context now that it is known
call_context.storage_contract_address = contract_address;
call_context.storage_contract_address = complete_contract_address.address;
} else {
const NT::fr& function_tree_root = function_tree_root_from_siblings<NT>(function_data.selector,
function_data.is_internal,
Expand Down Expand Up @@ -529,7 +529,7 @@ 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(
NT::fr const expected_contract_address = compute_complete_contract_address(
cdd.deployer_public_key, cdd.contract_address_salt, cdd.function_tree_root, expected_constructor_hash);

return (public_inputs.end.new_contracts[0].contract_address.to_field() == expected_contract_address);
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/aztec-rpc/src/contract_tree/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
isConstructor,
} from '@aztec/circuits.js';
import {
computeContractAddress,
computeCompleteContractAddress,
computeContractLeaf,
computeFunctionTreeRoot,
computePartialAddress,
Expand Down Expand Up @@ -98,7 +98,7 @@ export class ContractTree {
// TODO(benesjan) https://github.com/AztecProtocol/aztec-packages/issues/1873: create computeCompleteAddress
// function --> The following is wasteful as it computes partial address twice
const partialAddress = computePartialAddress(wasm, contractAddressSalt, root, constructorHash);
const address = computeContractAddress(wasm, from, contractAddressSalt, root, constructorHash);
const address = computeCompleteContractAddress(wasm, from, contractAddressSalt, root, constructorHash);
const completeAddress = await CompleteAddress.create(address, from, partialAddress);

const contractDao: ContractDao = {
Expand Down
4 changes: 2 additions & 2 deletions yarn-project/circuits.js/src/abis/abis.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { makeAztecAddress, makeEthAddress, makePoint, makeTxRequest, makeVerific
import { CircuitsWasm } from '../wasm/circuits_wasm.js';
import {
computeCommitmentNonce,
computeContractAddress,
computeCompleteContractAddress,
computeContractLeaf,
computeFunctionLeaf,
computeFunctionSelector,
Expand Down Expand Up @@ -67,7 +67,7 @@ describe('abis wasm bindings', () => {
const contractAddrSalt = new Fr(2n);
const treeRoot = new Fr(3n);
const constructorHash = new Fr(4n);
const res = computeContractAddress(wasm, deployerPubKey, contractAddrSalt, treeRoot, constructorHash);
const res = computeCompleteContractAddress(wasm, deployerPubKey, contractAddrSalt, treeRoot, constructorHash);
expect(res).toMatchSnapshot();
});

Expand Down
Loading

0 comments on commit 4376b77

Please sign in to comment.