Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
update_check.test.cpp
Go to the documentation of this file.
1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
3
4#include <cmath>
5#include <cstdint>
6
18
19namespace bb::avm2::constraining {
20namespace {
21
22using ::testing::TestWithParam;
23
25using simulation::UpdateCheckEvent;
26
27using tracegen::TestTraceContainer;
28using tracegen::UpdateCheckTraceBuilder;
29
31using C = Column;
33
34using update_check_relation = bb::avm2::update_check<FF>;
35
36TEST(UpdateCheckConstrainingTest, EmptyRow)
37{
38 check_relation<update_check_relation>(testing::empty_trace());
39}
40
41UpdateCheckEvent never_written = {
42 .address = 0xdeadbeef,
43 .current_class_id = 1,
44 .original_class_id = 1,
45 .current_timestamp = 100,
46};
47
48UpdateCheckEvent never_updated = {
49 .address = 0xdeadbeef,
50 .current_class_id = 1,
51 .original_class_id = 1,
52 .current_timestamp = 100,
53 .update_hash = 27,
54};
55
56UpdateCheckEvent update_from_original_next_timestamp = {
57 .address = 0xdeadbeef,
58 .current_class_id = 1,
59 .original_class_id = 1,
60 .current_timestamp = 100,
61 .update_hash = 27,
62 .update_preimage_metadata = FF(static_cast<uint64_t>(1234) << 32) + 101,
63 .update_preimage_pre_class_id = 0,
64 .update_preimage_post_class_id = 2,
65};
66
67UpdateCheckEvent update_next_timestamp = {
68 .address = 0xdeadbeef,
69 .current_class_id = 2,
70 .original_class_id = 1,
71 .current_timestamp = 100,
72 .update_hash = 27,
73 .update_preimage_metadata = FF(static_cast<uint64_t>(1234) << 32) + 101,
74 .update_preimage_pre_class_id = 2,
75 .update_preimage_post_class_id = 3,
76};
77
78UpdateCheckEvent update_previous_timestamp = {
79 .address = 0xdeadbeef,
80 .current_class_id = 3,
81 .original_class_id = 1,
82 .current_timestamp = 100,
83 .update_hash = 27,
84 .update_preimage_metadata = FF(static_cast<uint64_t>(1234) << 32) + 99,
85 .update_preimage_pre_class_id = 2,
86 .update_preimage_post_class_id = 3,
87};
88
89UpdateCheckEvent update_current_timestamp = {
90 .address = 0xdeadbeef,
91 .current_class_id = 3,
92 .original_class_id = 1,
93 .current_timestamp = 100,
94 .update_hash = 27,
95 .update_preimage_metadata = FF(static_cast<uint64_t>(1234) << 32) + 100,
96 .update_preimage_pre_class_id = 2,
97 .update_preimage_post_class_id = 3,
98};
99
100std::vector<UpdateCheckEvent> positive_tests = {
101 never_written,
102 never_updated,
103 update_from_original_next_timestamp,
104 update_next_timestamp,
105 update_previous_timestamp,
106 update_current_timestamp,
107};
108
109class UpdateCheckPositiveConstrainingTest : public TestWithParam<UpdateCheckEvent> {};
110
111TEST_P(UpdateCheckPositiveConstrainingTest, PositiveTest)
112{
113 const auto& event = GetParam();
114 TestTraceContainer trace({ { { C::precomputed_first_row, 1 } } });
115 UpdateCheckTraceBuilder update_check_builder;
116 update_check_builder.process({ event }, trace);
117 check_relation<update_check_relation>(trace);
118}
119
120INSTANTIATE_TEST_SUITE_P(UpdateCheckConstrainingTest,
121 UpdateCheckPositiveConstrainingTest,
122 ::testing::ValuesIn(positive_tests));
123
124TEST(UpdateCheckConstrainingTest, HashIsZeroCheck)
125{
126 // sel * (update_hash * ((1 - hash_not_zero) * (1 - update_hash_inv) + update_hash_inv) - 1 + (1 - hash_not_zero))
127 TestTraceContainer trace({
128 {
129 { C::precomputed_first_row, 1 },
130 { C::update_check_sel, 1 },
131 { C::update_check_update_hash, 27 },
132 { C::update_check_hash_not_zero, 1 },
133 { C::update_check_update_hash_inv, FF(27).invert() },
134 },
135 });
136
137 check_relation<update_check_relation>(trace, update_check_relation::SR_HASH_IS_ZERO_CHECK);
138
139 // Negative test - disable not zero
140 trace.set(C::update_check_hash_not_zero, 0, 0);
141
143 check_relation<update_check_relation>(trace, update_check_relation::SR_HASH_IS_ZERO_CHECK),
144 "HASH_IS_ZERO_CHECK");
145}
146
147TEST(UpdateCheckConstrainingTest, NeverUpdatedCheck)
148{
149 // (1 - hash_not_zero) * (current_class_id - original_class_id)
150 TestTraceContainer trace({
151 {
152 { C::precomputed_first_row, 1 },
153 { C::update_check_hash_not_zero, 0 },
154 { C::update_check_current_class_id, 1 },
155 { C::update_check_original_class_id, 1 },
156 },
157 });
158
159 check_relation<update_check_relation>(trace, update_check_relation::SR_NEVER_UPDATED_CHECK);
160
161 // Negative test - different class id
162 trace.set(C::update_check_current_class_id, 0, 2);
163
165 check_relation<update_check_relation>(trace, update_check_relation::SR_NEVER_UPDATED_CHECK),
166 "NEVER_UPDATED_CHECK");
167}
168
169TEST(UpdateCheckConstrainingTest, UpdateMetadataDecomposition)
170{
171 // update_hi_metadata * TWO_POW_32 + timestamp_of_change - update_preimage_metadata
172 TestTraceContainer trace({
173 {
174 { C::precomputed_first_row, 1 },
175 { C::update_check_hash_not_zero, 1 },
176 { C::update_check_update_hi_metadata, 1234 },
177 { C::update_check_timestamp_of_change, 101 },
178 { C::update_check_update_preimage_metadata, FF(static_cast<uint64_t>(1234) << 32) + 101 },
179 },
180 });
181
182 check_relation<update_check_relation>(trace, update_check_relation::SR_UPDATE_METADATA_DECOMPOSITION);
183
184 // Negative test - manipulate timestamp of change
185 trace.set(C::update_check_timestamp_of_change, 0, 102);
186
188 check_relation<update_check_relation>(trace, update_check_relation::SR_UPDATE_METADATA_DECOMPOSITION),
189 "UPDATE_METADATA_DECOMPOSITION");
190}
191
192TEST(UpdateCheckConstrainingTest, UpdatePreClassIsZero)
193{
194 // hash_not_zero * (update_preimage_pre_class_id * (update_pre_class_id_is_zero * (1 - update_pre_class_inv) +
195 // update_pre_class_inv) - 1 + update_pre_class_id_is_zero)
196 TestTraceContainer trace({
197 {
198 { C::precomputed_first_row, 1 },
199 { C::update_check_hash_not_zero, 1 },
200 { C::update_check_update_preimage_pre_class_id, 27 },
201 { C::update_check_update_pre_class_id_is_zero, 0 },
202 { C::update_check_update_pre_class_inv, FF(27).invert() },
203 },
204 });
205
206 check_relation<update_check_relation>(trace, update_check_relation::SR_UPDATE_PRE_CLASS_IS_ZERO);
207
208 // Negative test - Lie about it being zero
209 trace.set(C::update_check_update_pre_class_id_is_zero, 0, 1);
210
212 check_relation<update_check_relation>(trace, update_check_relation::SR_UPDATE_PRE_CLASS_IS_ZERO),
213 "UPDATE_PRE_CLASS_IS_ZERO");
214}
215
216TEST(UpdateCheckConstrainingTest, UpdatePostClassIsZero)
217{
218 // hash_not_zero * (update_preimage_post_class_id * (update_post_class_id_is_zero * (1 - update_post_class_inv) +
219 // update_post_class_inv) - 1 + update_post_class_id_is_zero)
220 TestTraceContainer trace({
221 {
222 { C::precomputed_first_row, 1 },
223 { C::update_check_hash_not_zero, 1 },
224 { C::update_check_update_preimage_post_class_id, 27 },
225 { C::update_check_update_post_class_id_is_zero, 0 },
226 { C::update_check_update_post_class_inv, FF(27).invert() },
227 },
228 });
229
230 check_relation<update_check_relation>(trace, update_check_relation::SR_UPDATE_POST_CLASS_IS_ZERO);
231
232 // Negative test - Lie about it being zero
233 trace.set(C::update_check_update_post_class_id_is_zero, 0, 1);
234
236 check_relation<update_check_relation>(trace, update_check_relation::SR_UPDATE_POST_CLASS_IS_ZERO),
237 "UPDATE_POST_CLASS_IS_ZERO");
238}
239
240TEST(UpdateCheckConstrainingTest, FutureUpdateClassIdAssignment)
241{
242 // hash_not_zero * timestamp_is_lt_timestamp_of_change * (original_class_id * update_pre_class_id_is_zero +
243 // update_preimage_pre_class_id - current_class_id)
244 TestTraceContainer trace({
245 {
246 { C::precomputed_first_row, 1 },
247 { C::update_check_hash_not_zero, 1 },
248 { C::update_check_timestamp_is_lt_timestamp_of_change, 1 },
249 { C::update_check_original_class_id, 42 },
250 { C::update_check_update_preimage_pre_class_id, 27 },
251 { C::update_check_update_pre_class_id_is_zero, 0 },
252 { C::update_check_current_class_id, 27 },
253 },
254 });
255
256 check_relation<update_check_relation>(trace, update_check_relation::SR_FUTURE_UPDATE_CLASS_ID_ASSIGNMENT);
257
258 // Negative test - should use original class id
259 trace.set(C::update_check_update_pre_class_id_is_zero, 0, 1);
260 trace.set(C::update_check_update_preimage_pre_class_id, 0, 0);
261
263 check_relation<update_check_relation>(trace, update_check_relation::SR_FUTURE_UPDATE_CLASS_ID_ASSIGNMENT),
264 "FUTURE_UPDATE_CLASS_ID_ASSIGNMENT");
265
266 // Fix - should use original class id
267 trace.set(C::update_check_current_class_id, 0, 42);
268 check_relation<update_check_relation>(trace, update_check_relation::SR_FUTURE_UPDATE_CLASS_ID_ASSIGNMENT);
269}
270
271TEST(UpdateCheckConstrainingTest, PastUpdateClassIdAssignment)
272{
273 // hash_not_zero * (1 - timestamp_is_lt_timestamp_of_change) * (original_class_id * update_post_class_id_is_zero +
274 // update_preimage_post_class_id - current_class_id)
275
276 TestTraceContainer trace({
277 {
278 { C::precomputed_first_row, 1 },
279 { C::update_check_hash_not_zero, 1 },
280 { C::update_check_timestamp_is_lt_timestamp_of_change, 0 },
281 { C::update_check_original_class_id, 42 },
282 { C::update_check_update_preimage_post_class_id, 27 },
283 { C::update_check_update_post_class_id_is_zero, 0 },
284 { C::update_check_current_class_id, 27 },
285 },
286 });
287
288 check_relation<update_check_relation>(trace, update_check_relation::SR_PAST_UPDATE_CLASS_ID_ASSIGNMENT);
289
290 // Negative test - should use original class id
291 trace.set(C::update_check_update_post_class_id_is_zero, 0, 1);
292 trace.set(C::update_check_update_preimage_post_class_id, 0, 0);
293
295 check_relation<update_check_relation>(trace, update_check_relation::SR_PAST_UPDATE_CLASS_ID_ASSIGNMENT),
296 "PAST_UPDATE_CLASS_ID_ASSIGNMENT");
297
298 // Fix - should use original class id
299 trace.set(C::update_check_current_class_id, 0, 42);
300 check_relation<update_check_relation>(trace, update_check_relation::SR_PAST_UPDATE_CLASS_ID_ASSIGNMENT);
301}
302
303} // namespace
304} // namespace bb::avm2::constraining
INSTANTIATE_TEST_SUITE_P(AcirTests, AcirIntegrationSingleTest, testing::Values("a_1327_concrete_in_generic", "a_1_mul", "a_2_div", "a_3_add", "a_4_sub", "a_5_over", "a_6", "a_6_array", "a_7", "a_7_function", "aes128_encrypt", "arithmetic_binary_operations", "array_dynamic", "array_dynamic_blackbox_input", "array_dynamic_main_output", "array_dynamic_nested_blackbox_input", "array_eq", "array_if_cond_simple", "array_len", "array_neq", "array_sort", "array_to_slice", "array_to_slice_constant_length", "assert", "assert_statement", "assign_ex", "bigint", "bit_and", "bit_not", "bit_shifts_comptime", "bit_shifts_runtime", "blake3", "bool_not", "bool_or", "break_and_continue", "brillig_acir_as_brillig", "brillig_array_eq", "brillig_array_to_slice", "brillig_arrays", "brillig_assert", "brillig_bit_shifts_runtime", "brillig_blake2s", "brillig_blake3", "brillig_calls", "brillig_calls_array", "brillig_calls_conditionals", "brillig_conditional", "brillig_cow", "brillig_cow_assign", "brillig_cow_regression", "brillig_ecdsa_secp256k1", "brillig_ecdsa_secp256r1", "brillig_embedded_curve", "brillig_fns_as_values", "brillig_hash_to_field", "brillig_identity_function", "brillig_keccak", "brillig_loop", "brillig_nested_arrays", "brillig_not", "brillig_oracle", "brillig_pedersen", "brillig_recursion", "brillig_references", "brillig_schnorr", "brillig_sha256", "brillig_signed_cmp", "brillig_signed_div", "brillig_slices", "brillig_to_be_bytes", "brillig_to_bits", "brillig_to_bytes_integration", "brillig_to_le_bytes", "brillig_top_level", "brillig_uninitialized_arrays", "brillig_wrapping", "cast_bool", "closures_mut_ref", "conditional_1", "conditional_2", "conditional_regression_421", "conditional_regression_547", "conditional_regression_661", "conditional_regression_short_circuit", "conditional_regression_underflow", "custom_entry", "databus", "debug_logs", "diamond_deps_0", "double_verify_nested_proof", "double_verify_proof", "ecdsa_secp256k1", "ecdsa_secp256r1", "ecdsa_secp256r1_3x", "eddsa", "embedded_curve_ops", "field_attribute", "generics", "global_consts", "hash_to_field", "hashmap", "higher_order_functions", "if_else_chain", "import", "inline_never_basic", "integer_array_indexing", "keccak256", "main_bool_arg", "main_return", "merkle_insert", "missing_closure_env", "modules", "modules_more", "modulus", "nested_array_dynamic", "nested_array_dynamic_simple", "nested_array_in_slice", "nested_arrays_from_brillig", "no_predicates_basic", "no_predicates_brillig", "no_predicates_numeric_generic_poseidon", "operator_overloading", "pedersen_check", "pedersen_commitment", "pedersen_hash", "poseidon_bn254_hash", "poseidonsponge_x5_254", "pred_eq", "prelude", "references", "regression", "regression_2660", "regression_3051", "regression_3394", "regression_3607", "regression_3889", "regression_4088", "regression_4124", "regression_4202", "regression_4449", "regression_4709", "regression_5045", "regression_capacity_tracker", "regression_mem_op_predicate", "regression_method_cannot_be_found", "regression_struct_array_conditional", "schnorr", "sha256", "sha2_byte", "side_effects_constrain_array", "signed_arithmetic", "signed_comparison", "signed_division", "simple_2d_array", "simple_add_and_ret_arr", "simple_array_param", "simple_bitwise", "simple_comparison", "simple_mut", "simple_not", "simple_print", "simple_program_addition", "simple_radix", "simple_shield", "simple_shift_left_right", "slice_coercion", "slice_dynamic_index", "slice_loop", "slices", "strings", "struct", "struct_array_inputs", "struct_fields_ordering", "struct_inputs", "submodules", "to_be_bytes", "to_bytes_consistent", "to_bytes_integration", "to_le_bytes", "trait_as_return_type", "trait_impl_base_type", "traits_in_crates_1", "traits_in_crates_2", "tuple_inputs", "tuples", "type_aliases", "u128", "u16_support", "unconstrained_empty", "unit_value", "unsafe_range_constraint", "witness_compression", "xor"))
TEST_P(AcirIntegrationSingleTest, DISABLED_ProveAndVerifyProgram)
void set(Column col, uint32_t row, const FF &value)
TestTraceContainer trace
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessage)
Definition macros.hpp:7
AvmFlavorSettings::FF FF
TEST(TxExecutionConstrainingTest, WriteTreeValue)
Definition tx.test.cpp:508
IndexedLeaf< PublicDataLeafValue > PublicDataTreeLeafPreimage
TestTraceContainer empty_trace()
Definition fixtures.cpp:153
typename Flavor::FF FF
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13