Skip to content
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
2 changes: 2 additions & 0 deletions barretenberg/cpp/pil/avm/constants_gen.pil
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ namespace constants;
pol START_EMIT_NULLIFIER_WRITE_OFFSET = 207;
pol START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET = 223;
pol START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET = 225;
pol GRUMPKIN_ONE_X = 1;
pol GRUMPKIN_ONE_Y = 17631683881184975370165255887551781615748388533673675138860;
pol GENERATOR_INDEX__NOTE_HASH_NONCE = 2;
pol GENERATOR_INDEX__UNIQUE_NOTE_HASH = 3;
pol GENERATOR_INDEX__SILOED_NOTE_HASH = 4;
Expand Down
143 changes: 143 additions & 0 deletions barretenberg/cpp/pil/vm2/address_derivation.pil
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
include "constants_gen.pil";
include "ecc.pil";
include "poseidon2_hash.pil";
include "precomputed.pil";
include "scalar_mul.pil";

namespace address_derivation;

pol commit sel;
sel * (1 - sel) = 0;

#[skippable_if]
sel = 0;

// Address preimage components
pol commit salt;
pol commit deployer_addr;
pol commit class_id;
pol commit init_hash;
pol commit nullifier_key_x;
pol commit nullifier_key_y;
pol commit incoming_viewing_key_x;
pol commit incoming_viewing_key_y;
pol commit outgoing_viewing_key_x;
pol commit outgoing_viewing_key_y;
pol commit tagging_key_x;
pol commit tagging_key_y;

// Expected derived address
pol commit address;


// Computation of salted initialization hash

pol commit salted_init_hash;

// It's reused between the partial address and salted initialization hash. Weird.
// TODO: We need this temporarily while we dont allow for aliases in the lookup tuple
pol commit partial_address_domain_separator;
sel * (partial_address_domain_separator - constants.GENERATOR_INDEX__PARTIAL_ADDRESS) = 0;

#[SALTED_INITIALIZATION_HASH_POSEIDON2_0]
sel { partial_address_domain_separator, salt, init_hash, salted_init_hash }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, we do not support a constant nor alias in a lookup tuple?
Because otherwise, we could inline constants.GENERATOR_INDEX__PARTIAL_ADDRESS in the tuple and get rid of
the above relation.
I suggest to write a TODO so that we can simplify once we support constants in lookups.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll write a todo, unfortunately we can't, on lookups we need to use real columns ):

in poseidon2_hash.start { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };

#[SALTED_INITIALIZATION_HASH_POSEIDON2_1]
sel { deployer_addr, precomputed.zero, precomputed.zero, salted_init_hash}
in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Poseidon2 was changed to propagate the final output on the whole run. It's however still incomplete, I talked with Ilyas about it because we need to lookup also the iteration index. This hash run in poseidon looks like this:


+----------------------------------+---------+-----------+------------------+-------+-----+-----+
|             input_0              | input_1 |  input_2  |      output      | start | end | sel |
+----------------------------------+---------+-----------+------------------+-------+-----+-----+
| 0                                | 0       | 0         | 0                |     0 |   0 |   0 |
| partial_address_domain_separator | salt    | init_hash | salted_init_hash |     1 |   0 |   1 |
| deployer_addr                    | 0       | 0         | salted_init_hash |     0 |   1 |   1 |
| 0                                | 0       | 0         | 0                |     0 |   0 |   0 |
+----------------------------------+---------+-----------+------------------+-------+-----+-----+

In order for it to be safe I need to assert that start is on on the first one and end is on in the second one. However, a malicious prover could still insert more rounds between the two rows, that's why poseidon will need to be improved to include a round_index column, so I can lookup with 0 on start and 1 on end so I can be safe that a malicious prover hasn't inserted more rounds

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please file an issue to fix poseidon if there's not already one (and to update all callers), assign to ilyas, and add it to this doc since this seems quite important.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done



// Computation of partial address

pol commit partial_address;

#[PARTIAL_ADDRESS_POSEIDON2]
sel { partial_address_domain_separator, class_id, salted_init_hash, partial_address }
in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };


// Hash the public keys

pol commit public_keys_hash;

// TODO: We need this temporarily while we dont allow for aliases in the lookup tuple
pol commit public_keys_hash_domain_separator;
sel * (public_keys_hash_domain_separator - constants.GENERATOR_INDEX__PUBLIC_KEYS_HASH) = 0;

// Remove all the 0s for is_infinite when removed from public_keys.nr
// https://github.com/AztecProtocol/aztec-packages/issues/7529
#[PUBLIC_KEYS_HASH_POSEIDON2_0]
sel { public_keys_hash_domain_separator, nullifier_key_x, nullifier_key_y, public_keys_hash }
in poseidon2_hash.start { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };

#[PUBLIC_KEYS_HASH_POSEIDON2_1]
sel { precomputed.zero, incoming_viewing_key_x, incoming_viewing_key_y, public_keys_hash }
in poseidon2_hash.sel { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };

#[PUBLIC_KEYS_HASH_POSEIDON2_2]
sel { precomputed.zero, outgoing_viewing_key_x, outgoing_viewing_key_y, public_keys_hash }
in poseidon2_hash.sel { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };

#[PUBLIC_KEYS_HASH_POSEIDON2_3]
sel { precomputed.zero, tagging_key_x, tagging_key_y, public_keys_hash }
in poseidon2_hash.sel { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };

#[PUBLIC_KEYS_HASH_POSEIDON2_4]
sel { precomputed.zero, precomputed.zero, precomputed.zero, public_keys_hash }
in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };


// Compute the preaddress

pol commit preaddress;

// TODO: We need this temporarily while we dont allow for aliases in the lookup tuple
pol commit preaddress_domain_separator;
sel * (preaddress_domain_separator - constants.GENERATOR_INDEX__CONTRACT_ADDRESS_V1) = 0;

#[PREADDRESS_POSEIDON2]
sel { preaddress_domain_separator, public_keys_hash, partial_address, preaddress }
in poseidon2_hash.end { poseidon2_hash.input_0, poseidon2_hash.input_1, poseidon2_hash.input_2, poseidon2_hash.output };


// Derive preaddress public key

pol commit preaddress_public_key_x;
pol commit preaddress_public_key_y;

// TODO: We need this temporarily while we dont allow for aliases in the lookup tuple
pol commit g1_x;
sel * (g1_x - constants.GRUMPKIN_ONE_X) = 0;

pol commit g1_y;
sel * (g1_y - constants.GRUMPKIN_ONE_Y) = 0;

#[PREADDRESS_SCALAR_MUL]
sel {
preaddress,
g1_x, g1_y, precomputed.zero,
preaddress_public_key_x, preaddress_public_key_y, precomputed.zero
} in scalar_mul.start {
scalar_mul.scalar,
scalar_mul.point_x, scalar_mul.point_y, scalar_mul.point_inf,
scalar_mul.res_x, scalar_mul.res_y, scalar_mul.res_inf
};


// Finally, the address must be the x coordinate of preaddress_public_key + incoming_viewing_key

pol commit address_y;

#[ADDRESS_ECADD]
sel {
preaddress_public_key_x, preaddress_public_key_y, precomputed.zero,
incoming_viewing_key_x, incoming_viewing_key_y, precomputed.zero,
address, address_y, precomputed.zero
} in ecc.sel {
ecc.p_x, ecc.p_y, ecc.p_is_inf,
ecc.q_x, ecc.q_y, ecc.q_is_inf,
ecc.r_x, ecc.r_y, ecc.r_is_inf
};


2 changes: 2 additions & 0 deletions barretenberg/cpp/pil/vm2/constants_gen.pil
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ namespace constants;
pol START_EMIT_NULLIFIER_WRITE_OFFSET = 207;
pol START_EMIT_L2_TO_L1_MSG_WRITE_OFFSET = 223;
pol START_EMIT_UNENCRYPTED_LOG_WRITE_OFFSET = 225;
pol GRUMPKIN_ONE_X = 1;
pol GRUMPKIN_ONE_Y = 17631683881184975370165255887551781615748388533673675138860;
pol GENERATOR_INDEX__NOTE_HASH_NONCE = 2;
pol GENERATOR_INDEX__UNIQUE_NOTE_HASH = 3;
pol GENERATOR_INDEX__SILOED_NOTE_HASH = 4;
Expand Down
1 change: 1 addition & 0 deletions barretenberg/cpp/pil/vm2/execution.pil
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include "alu.pil";
include "addressing.pil";
include "address_derivation.pil";
include "bc_decomposition.pil";
include "bc_hashing.pil";
include "bc_retrieval.pil";
Expand Down
5 changes: 4 additions & 1 deletion barretenberg/cpp/src/barretenberg/vm2/common/aztec_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,18 @@ struct PublicKeys {
return { nullifier_key.x, nullifier_key.y, incoming_viewing_key.x, incoming_viewing_key.y,
outgoing_viewing_key.x, outgoing_viewing_key.y, tagging_key.x, tagging_key.y };
}

bool operator==(const PublicKeys& other) const = default;
};

struct ContractInstance {
AztecAddress address;
FF salt;
AztecAddress deployer_addr;
ContractClassId contract_class_id;
FF initialisation_hash;
PublicKeys public_keys;

bool operator==(const ContractInstance& other) const = default;
};

struct ContractClass {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <cstdint>
#include <ostream>

namespace bb::avm2 {

Expand Down Expand Up @@ -51,15 +52,27 @@ template <typename AffinePoint> class StandardAffinePoint {

constexpr const BaseField& y() const noexcept { return point.is_point_at_infinity() ? zero : point.y; }

static StandardAffinePoint& infinity()
static const StandardAffinePoint& infinity()
{
static auto infinity = StandardAffinePoint(AffinePoint::infinity());
return infinity;
}

static const StandardAffinePoint& one()
{
static auto one = StandardAffinePoint(AffinePoint::one());
return one;
}

private:
AffinePoint point;
static constexpr const auto zero = BaseField::zero();
};

template <typename T> std::ostream& operator<<(std::ostream& os, const StandardAffinePoint<T>& point)
{
os << "StandardAffinePoint(" << point.x() << ", " << point.y() << ", " << point.is_infinity() << ")";
return os;
}

} // namespace bb::avm2
Loading