Skip to content

Commit 42286b7

Browse files
committed
fix: Enforce recipients of l2l1msgs having 20 bytes at most
1 parent 42fd086 commit 42286b7

File tree

26 files changed

+234
-44
lines changed

26 files changed

+234
-44
lines changed

barretenberg/cpp/pil/vm2/constants_gen.pil

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// GENERATED FILE - DO NOT EDIT, RUN yarn remake-constants in yarn-project/constants
22
namespace constants;
3+
pol MAX_ETH_ADDRESS_VALUE = 1461501637330902918203684832716283019655932542975;
34
pol NOTE_HASH_TREE_HEIGHT = 42;
45
pol PUBLIC_DATA_TREE_HEIGHT = 40;
56
pol NULLIFIER_TREE_HEIGHT = 42;

barretenberg/cpp/pil/vm2/opcodes/send_l2_to_l1_msg.pil

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,26 @@ namespace execution; // this is a virtual gadget that shares rows with the execu
3939
#[MAX_WRITES_REACHED]
4040
sel_execute_send_l2_to_l1_msg * (REMAINING_L2_TO_L1_MSG_WRITES * (sel_l2_to_l1_msg_limit_error * (1 - remaining_l2_to_l1_msgs_inv) + remaining_l2_to_l1_msgs_inv) - 1 + sel_l2_to_l1_msg_limit_error) = 0;
4141

42-
// The opcode errors if we have reached the limit or if we are in a static context
42+
// TODO: We need this temporarily while we do not allow for aliases in the lookup tuple
43+
pol commit max_eth_address_value;
44+
sel_execute_send_l2_to_l1_msg * (constants.MAX_ETH_ADDRESS_VALUE - max_eth_address_value) = 0;
45+
46+
pol commit too_large_recipient_error;
47+
48+
#[RECIPIENT_CHECK]
49+
sel_execute_send_l2_to_l1_msg {
50+
register[0], // recipient
51+
max_eth_address_value,
52+
too_large_recipient_error
53+
} in ff_gt.sel_gt {
54+
ff_gt.a,
55+
ff_gt.b,
56+
ff_gt.result
57+
};
58+
59+
// The opcode errors if we have reached the limit, if we are in a static context, or if the recipient is too large.
4360
#[OPCODE_ERROR]
44-
sel_execute_send_l2_to_l1_msg * ((1 - sel_l2_to_l1_msg_limit_error) * (1 - is_static) - (1 - sel_opcode_error)) = 0;
61+
sel_execute_send_l2_to_l1_msg * ((1 - sel_l2_to_l1_msg_limit_error) * (1 - is_static) * (1 - too_large_recipient_error) - (1 - sel_opcode_error)) = 0;
4562

4663
// =========== LOOKUP PI ===========
4764
pol commit sel_write_l2_to_l1_msg;

barretenberg/cpp/src/barretenberg/avm_fuzzer/fuzz_lib/simulator.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -194,16 +194,6 @@ bool compare_simulator_results(SimulatorResult& result1, SimulatorResult& result
194194
result2.output.resize(MAX_RETURN_DATA_SIZE_IN_FIELDS);
195195
}
196196

197-
// TODO(avm):
198-
// https://linear.app/aztec-labs/issue/AVM-209/l2l1msgs-possible-completeness-issue-with-recipient-20-bytes
199-
for (auto& l2_to_l1_msg : result1.public_tx_effect.l2_to_l1_msgs) {
200-
l2_to_l1_msg.message.recipient = FF(static_cast<uint256_t>(l2_to_l1_msg.message.recipient).slice(0, 20));
201-
}
202-
203-
for (auto& l2_to_l1_msg : result2.public_tx_effect.l2_to_l1_msgs) {
204-
l2_to_l1_msg.message.recipient = FF(static_cast<uint256_t>(l2_to_l1_msg.message.recipient).slice(0, 20));
205-
}
206-
207197
return result1.reverted == result2.reverted && result1.output == result2.output &&
208198
result1.end_tree_snapshots == result2.end_tree_snapshots &&
209199
result1.public_tx_effect == result2.public_tx_effect;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include "barretenberg/avm_fuzzer/mutations/basic_types/eth_address.hpp"
2+
3+
#include "barretenberg/avm_fuzzer/mutations/basic_types/field.hpp"
4+
#include "barretenberg/vm2/common/aztec_types.hpp"
5+
6+
using bb::avm2::EthAddress;
7+
using bb::avm2::FF;
8+
9+
namespace {
10+
11+
EthAddress ff_to_eth_address(FF ff)
12+
{
13+
return EthAddress(static_cast<uint256_t>(ff).slice(0, 20));
14+
}
15+
16+
} // namespace
17+
18+
EthAddress generate_random_eth_address(std::mt19937_64& rng)
19+
{
20+
return ff_to_eth_address(generate_random_field(rng));
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <random>
4+
5+
#include "barretenberg/vm2/common/aztec_types.hpp"
6+
7+
bb::avm2::EthAddress generate_random_eth_address(std::mt19937_64& rng);

barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/basic_types/field.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <random>
44

55
#include "barretenberg/avm_fuzzer/mutations/configuration.hpp"
6+
#include "barretenberg/vm2/common/aztec_types.hpp"
67
#include "barretenberg/vm2/common/field.hpp"
78

89
bb::avm2::FF generate_random_field(std::mt19937_64& rng);

barretenberg/cpp/src/barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "barretenberg/avm_fuzzer/mutations/tx_types/accumulated_data.hpp"
22

33
#include "barretenberg/avm_fuzzer/fuzz_lib/constants.hpp"
4+
#include "barretenberg/avm_fuzzer/mutations/basic_types/eth_address.hpp"
45
#include "barretenberg/avm_fuzzer/mutations/basic_types/field.hpp"
56
#include "barretenberg/avm_fuzzer/mutations/basic_types/vector.hpp"
67
#include "barretenberg/avm_fuzzer/mutations/configuration.hpp"
@@ -45,7 +46,8 @@ void mutate_nullifier(FF& nullifier, std::mt19937_64& rng)
4546
ScopedL2ToL1Message generate_l2_to_l1_message(std::mt19937_64& rng)
4647
{
4748
return ScopedL2ToL1Message{
48-
.message = L2ToL1Message{ .recipient = generate_random_field(rng), .content = generate_random_field(rng) },
49+
.message =
50+
L2ToL1Message{ .recipient = generate_random_eth_address(rng), .content = generate_random_field(rng) },
4951
.contract_address = generate_random_field(rng),
5052
};
5153
}
@@ -57,7 +59,7 @@ void mutate_l2_to_l1_msg(ScopedL2ToL1Message& msg, std::mt19937_64& rng)
5759
switch (choice) {
5860
case 0:
5961
// Mutate recipient
60-
msg.message.recipient = generate_random_field(rng);
62+
msg.message.recipient = generate_random_eth_address(rng);
6163
break;
6264
case 1:
6365
// Mutate content

barretenberg/cpp/src/barretenberg/vm2/common/aztec_constants.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// GENERATED FILE - DO NOT EDIT, RUN yarn remake-constants in yarn-project/constants
22
#pragma once
33

4+
#define MAX_ETH_ADDRESS_VALUE "0x000000000000000000000000ffffffffffffffffffffffffffffffffffffffff"
45
#define ARCHIVE_HEIGHT 30
56
#define NOTE_HASH_TREE_HEIGHT 42
67
#define PUBLIC_DATA_TREE_HEIGHT 40

barretenberg/cpp/src/barretenberg/vm2/constraining/relations/send_l2_to_l1_msg.test.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,30 @@
77
#include "barretenberg/vm2/constraining/flavor_settings.hpp"
88
#include "barretenberg/vm2/constraining/testing/check_relation.hpp"
99
#include "barretenberg/vm2/generated/relations/execution.hpp"
10+
#include "barretenberg/vm2/simulation/gadgets/field_gt.hpp"
11+
#include "barretenberg/vm2/simulation/testing/mock_range_check.hpp"
1012
#include "barretenberg/vm2/testing/macros.hpp"
1113
#include "barretenberg/vm2/testing/public_inputs_builder.hpp"
1214
#include "barretenberg/vm2/tracegen/execution_trace.hpp"
15+
#include "barretenberg/vm2/tracegen/field_gt_trace.hpp"
1316
#include "barretenberg/vm2/tracegen/precomputed_trace.hpp"
1417
#include "barretenberg/vm2/tracegen/public_inputs_trace.hpp"
1518
#include "barretenberg/vm2/tracegen/test_trace_container.hpp"
1619

1720
namespace bb::avm2::constraining {
1821
namespace {
1922

23+
using simulation::EventEmitter;
24+
using simulation::FieldGreaterThan;
25+
using simulation::FieldGreaterThanEvent;
26+
using simulation::MockRangeCheck;
27+
2028
using tracegen::ExecutionTraceBuilder;
2129
using tracegen::PublicInputsTraceBuilder;
2230
using tracegen::TestTraceContainer;
2331

2432
using testing::PublicInputsBuilder;
33+
using tracegen::FieldGreaterThanTraceBuilder;
2534

2635
using FF = AvmFlavorSettings::FF;
2736
using C = Column;
@@ -32,6 +41,7 @@ TEST(SendL2ToL1MsgConstrainingTest, Positive)
3241
uint64_t prev_num_l2_to_l1_msgs = MAX_L2_TO_L1_MSGS_PER_TX - 1;
3342
TestTraceContainer trace({ {
3443
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
44+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
3545
{ C::execution_register_0_, /*recipient=*/42 },
3646
{ C::execution_register_1_, /*content=*/27 },
3747
{ C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
@@ -54,6 +64,7 @@ TEST(SendL2ToL1MsgConstrainingTest, LimitReached)
5464
uint64_t prev_num_l2_to_l1_msgs = MAX_L2_TO_L1_MSGS_PER_TX;
5565
TestTraceContainer trace({ {
5666
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
67+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
5768
{ C::execution_register_0_, /*recipient=*/42 },
5869
{ C::execution_register_1_, /*content=*/27 },
5970
{ C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
@@ -88,6 +99,7 @@ TEST(SendL2ToL1MsgConstrainingTest, Discard)
8899
uint64_t prev_num_l2_to_l1_msgs = 0;
89100
TestTraceContainer trace({ {
90101
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
102+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
91103
{ C::execution_register_0_, /*recipient=*/42 },
92104
{ C::execution_register_1_, /*content=*/27 },
93105
{ C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
@@ -119,6 +131,12 @@ TEST(SendL2ToL1MsgConstrainingTest, Interactions)
119131
AztecAddress address = 0xdeadbeef;
120132
AvmAccumulatedData accumulated_data = {};
121133

134+
MockRangeCheck mock_range_check;
135+
EventEmitter<FieldGreaterThanEvent> ff_gt_event_emitter;
136+
FieldGreaterThan field_gt(mock_range_check, ff_gt_event_emitter);
137+
138+
ASSERT_FALSE(field_gt.ff_gt(recipient, FF(MAX_ETH_ADDRESS_VALUE)));
139+
122140
accumulated_data.l2_to_l1_msgs[0] = {
123141
.message =
124142
L2ToL1Message{
@@ -135,6 +153,7 @@ TEST(SendL2ToL1MsgConstrainingTest, Interactions)
135153

136154
TestTraceContainer trace({ {
137155
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
156+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
138157
{ C::execution_register_0_, recipient },
139158
{ C::execution_register_1_, content },
140159
{ C::execution_mem_tag_reg_0_, static_cast<uint8_t>(MemoryTag::FF) },
@@ -150,6 +169,9 @@ TEST(SendL2ToL1MsgConstrainingTest, Interactions)
150169
{ C::execution_subtrace_operation_id, AVM_EXEC_OP_ID_SENDL2TOL1MSG },
151170
} });
152171

172+
FieldGreaterThanTraceBuilder field_gt_builder;
173+
field_gt_builder.process(ff_gt_event_emitter.dump_events(), trace);
174+
153175
PublicInputsTraceBuilder public_inputs_builder;
154176
public_inputs_builder.process_public_inputs(trace, public_inputs);
155177
public_inputs_builder.process_public_inputs_aux_precomputed(trace);
@@ -158,13 +180,34 @@ TEST(SendL2ToL1MsgConstrainingTest, Interactions)
158180
precomputed_builder.process_misc(trace, trace.get_num_rows());
159181

160182
check_relation<send_l2_to_l1_msg>(trace);
161-
check_interaction<ExecutionTraceBuilder, lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_settings>(trace);
183+
check_interaction<ExecutionTraceBuilder,
184+
lookup_send_l2_to_l1_msg_write_l2_to_l1_msg_settings,
185+
lookup_send_l2_to_l1_msg_recipient_check_settings>(trace);
186+
}
187+
188+
TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldErrorIfRecipientTooLarge)
189+
{
190+
TestTraceContainer trace({ {
191+
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
192+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
193+
{ C::execution_too_large_recipient_error, 1 },
194+
{ C::execution_sel_l2_to_l1_msg_limit_error, 0 },
195+
{ C::execution_is_static, 0 },
196+
{ C::execution_sel_opcode_error, 1 },
197+
} });
198+
check_relation<send_l2_to_l1_msg>(trace, send_l2_to_l1_msg::SR_OPCODE_ERROR);
199+
200+
// Negative test: sel_opcode_error must be on
201+
trace.set(C::execution_sel_opcode_error, 0, 0);
202+
EXPECT_THROW_WITH_MESSAGE(check_relation<send_l2_to_l1_msg>(trace, send_l2_to_l1_msg::SR_OPCODE_ERROR),
203+
"OPCODE_ERROR");
162204
}
163205

164206
TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldErrorIfStatic)
165207
{
166208
TestTraceContainer trace({ {
167209
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
210+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
168211
{ C::execution_sel_l2_to_l1_msg_limit_error, 0 },
169212
{ C::execution_is_static, 1 },
170213
{ C::execution_sel_opcode_error, 1 },
@@ -182,6 +225,7 @@ TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldNotWriteIfDiscard)
182225
{
183226
TestTraceContainer trace({ {
184227
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
228+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
185229
{ C::execution_sel_opcode_error, 0 },
186230
{ C::execution_discard, 1 },
187231
{ C::execution_sel_write_l2_to_l1_msg, 0 },
@@ -199,6 +243,7 @@ TEST(SendL2ToL1MsgConstrainingTest, NegativeShouldNumL2ToL1MessagesIncrease)
199243
{
200244
TestTraceContainer trace({ {
201245
{ C::execution_sel_execute_send_l2_to_l1_msg, 1 },
246+
{ C::execution_max_eth_address_value, FF(MAX_ETH_ADDRESS_VALUE) },
202247
{ C::execution_sel_opcode_error, 0 },
203248
{ C::execution_prev_num_l2_to_l1_messages, 0 },
204249
{ C::execution_num_l2_to_l1_messages, 1 },

barretenberg/cpp/src/barretenberg/vm2/generated/columns.hpp

Lines changed: 7 additions & 7 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)