1#include <gmock/gmock.h>
2#include <gtest/gtest.h>
25#include "barretenberg/aztec/aztec_constants.hpp"
45using ::testing::Return;
46using ::testing::StrictMock;
48using tracegen::BitwiseTraceBuilder;
49using tracegen::ExecutionTraceBuilder;
50using tracegen::KeccakF1600TraceBuilder;
51using tracegen::PrecomputedTraceBuilder;
52using tracegen::Sha256TraceBuilder;
53using tracegen::TestTraceContainer;
55using simulation::Bitwise;
56using simulation::BitwiseEvent;
57using simulation::EventEmitter;
58using simulation::FieldGreaterThan;
59using simulation::FieldGreaterThanEvent;
60using simulation::GreaterThan;
61using simulation::GreaterThanEvent;
62using simulation::MemoryStore;
63using simulation::MockExecutionIdManager;
64using simulation::RangeCheck;
65using simulation::RangeCheckEvent;
66using simulation::Sha256;
67using simulation::Sha256CompressionEvent;
75TEST(BitwiseConstrainingTest, EmptyRow)
81TEST(BitwiseConstrainingTest, AndWithTracegen)
83 TestTraceContainer
trace;
91 .a = MemoryValue::from<uint8_t>(85),
92 .b = MemoryValue::from<uint8_t>(175),
95 .a = MemoryValue::from<uint16_t>(5323),
96 .b = MemoryValue::from<uint16_t>(321),
99 .a = MemoryValue::from<uint32_t>(13793),
100 .b = MemoryValue::from<uint32_t>(10590617),
103 .a = MemoryValue::from<uint64_t>(0x7bff744e3cdf79LLU),
104 .b = MemoryValue::from<uint64_t>(0x14ccccccccb6LLU),
105 .res = 0x14444c0ccc30LLU },
107 .a = MemoryValue::from<uint128_t>((
uint128_t{ 0xb900000000000001 } << 64)),
108 .b = MemoryValue::from<uint128_t>((
uint128_t{ 0x1006021301080000 } << 64) +
109 uint128_t{ 0x000000000000001080876844827 }),
110 .res =
uint128_t{ 0x1000000000000000 } << 64 }
116 check_relation<bitwise>(trace);
120TEST(BitwiseConstrainingTest, OrWithTracegen)
122 TestTraceContainer
trace;
130 .a = MemoryValue::from<uint8_t>(128),
131 .b = MemoryValue::from<uint8_t>(127),
134 .a = MemoryValue::from<uint16_t>(5323),
135 .b = MemoryValue::from<uint16_t>(321),
138 .a = MemoryValue::from<uint32_t>(13793),
139 .b = MemoryValue::from<uint32_t>(10590617),
142 .a = MemoryValue::from<uint64_t>(0x7bff744e3cdf79LLU),
143 .b = MemoryValue::from<uint64_t>(0x14ccccccccb6LLU),
144 .res = 0x7bfffccefcdfffLLU },
146 .a = MemoryValue::from<uint128_t>((
uint128_t{ 0xb900000000000000 } << 64)),
147 .b = MemoryValue::from<uint128_t>((
uint128_t{ 0x1006021301080000 } << 64) +
148 uint128_t{ 0x000000000000001080876844827 }),
155 check_relation<bitwise>(trace);
159TEST(BitwiseConstrainingTest, XorWithTracegen)
161 TestTraceContainer
trace;
170 .a = MemoryValue::from<uint8_t>(85),
171 .b = MemoryValue::from<uint8_t>(175),
174 .a = MemoryValue::from<uint16_t>(5323),
175 .b = MemoryValue::from<uint16_t>(321),
178 .a = MemoryValue::from<uint32_t>(13793),
179 .b = MemoryValue::from<uint32_t>(10590617),
182 .a = MemoryValue::from<uint64_t>(0x7bff744e3cdf79LLU),
183 .b = MemoryValue::from<uint64_t>(0x14ccccccccb6LLU),
184 .res = 0x7bebb882f013cfLLU },
186 .a = MemoryValue::from<uint128_t>((
uint128_t{ 0xb900000000000001 } << 64)),
187 .b = MemoryValue::from<uint128_t>((
uint128_t{ 0x1006021301080000 } << 64) +
188 uint128_t{ 0x000000000000001080876844827 }),
195 check_relation<bitwise>(trace);
198TEST(BitwiseConstrainingTest, MixedOperationsWithTracegen)
200 TestTraceContainer
trace;
208 .a = MemoryValue::from<uint32_t>(13793),
209 .b = MemoryValue::from<uint32_t>(10590617),
212 .a = MemoryValue::from<uint16_t>(5323),
213 .b = MemoryValue::from<uint16_t>(321),
216 .a = MemoryValue::from<uint32_t>(13793),
217 .b = MemoryValue::from<uint32_t>(10590617),
220 .a = MemoryValue::from<uint8_t>(85),
221 .b = MemoryValue::from<uint8_t>(175),
224 .a = MemoryValue::from<uint8_t>(85),
225 .b = MemoryValue::from<uint8_t>(175),
232 check_relation<bitwise>(trace);
237TEST(BitwiseConstrainingTest, Simd64WithTracegen)
239 TestTraceContainer
trace;
242 const uint64_t a1 = 0xAAAAAAAAAAAAAAAAULL;
243 const uint64_t b1 = 0x5555555555555555ULL;
244 const uint64_t a2 = 0x123456789ABCDEF0ULL;
245 const uint64_t b2 = 0x0F0F0F0F0F0F0F0FULL;
251 .a = MemoryValue::from<uint128_t>(A),
252 .b = MemoryValue::from<uint128_t>(B),
256 .a = MemoryValue::from<uint128_t>(A),
257 .b = MemoryValue::from<uint128_t>(B),
263 check_relation<bitwise>(trace);
266 EXPECT_EQ(
trace.
get(C::bitwise_sel_simd_64, 0), 1);
267 EXPECT_EQ(
trace.
get(C::bitwise_ia, 0),
FF(a1));
268 EXPECT_EQ(
trace.
get(C::bitwise_ia_simd, 0),
FF(a2));
269 EXPECT_EQ(
trace.
get(C::bitwise_ib, 0),
FF(b1));
270 EXPECT_EQ(
trace.
get(C::bitwise_ib_simd, 0),
FF(b2));
271 EXPECT_EQ(
trace.
get(C::bitwise_ic, 0),
FF(
static_cast<uint64_t
>(a1 ^ b1)));
272 EXPECT_EQ(
trace.
get(C::bitwise_ic_simd, 0),
FF(
static_cast<uint64_t
>(a2 ^ b2)));
276TEST(BitwiseConstrainingTest, NegativeSimd64OnlyOnU128)
278 TestTraceContainer
trace({
280 { C::bitwise_sel, 1 },
281 { C::bitwise_sel_keccak, 1 },
282 { C::bitwise_sel_simd_64, 1 },
283 { C::bitwise_sel_u128, 1 },
289 trace.
set(C::bitwise_sel_u128, 0, 0);
296TEST(BitwiseConstrainingTest, NegativeRecomposition)
300 TestTraceContainer
trace({
302 { C::bitwise_sel, 1 },
303 { C::bitwise_sel_compute, 1 },
304 { C::bitwise_sel_u16, 1 },
305 { C::bitwise_sel_and, 1 },
306 { C::bitwise_ia, 0x1234 },
307 { C::bitwise_ib, 0x1234 },
308 { C::bitwise_ic, 0x1234 },
309 { C::bitwise_ia_byte_0_, 0x34 },
310 { C::bitwise_ia_byte_1_, 0x12 },
311 { C::bitwise_ib_byte_0_, 0x34 },
312 { C::bitwise_ib_byte_1_, 0x12 },
313 { C::bitwise_output_and_0_, 0x34 },
314 { C::bitwise_output_and_1_, 0x12 },
320 trace.
set(C::bitwise_ia, 0, 0x1235);
321 trace.
set(C::bitwise_ib, 0, 0x1334);
322 trace.
set(C::bitwise_ic, 0, 0x0234);
334TEST(BitwiseConstrainingTest, InactiveLimbDoesNotAffectRecomposition)
337 TestTraceContainer
trace({
339 { C::bitwise_sel, 1 },
340 { C::bitwise_sel_compute, 1 },
341 { C::bitwise_ia, 0x34 },
342 { C::bitwise_ia_byte_0_, 0x34 },
343 { C::bitwise_ia_byte_1_, 0xFF },
352TEST(BitwiseConstrainingTest, NegativeTagLenDecomposition)
355 TestTraceContainer
trace({
357 { C::bitwise_sel, 1 },
358 { C::bitwise_sel_compute, 1 },
359 { C::bitwise_sel_u16, 1 },
360 { C::bitwise_tag_byte_len, 2 },
366 trace.
set(C::bitwise_tag_byte_len, 0, 3);
372TEST(BitwiseConstrainingTest, NegativeInputTagCannotBeFF)
374 TestTraceContainer
trace;
387 trace.
set(C::bitwise_sel_tag_ff_err, 0, 0);
395TEST(BitwiseConstrainingTest, NegativeInputTagsShouldMatch)
397 TestTraceContainer
trace;
409 trace.
set(C::bitwise_sel_tag_mismatch_err, 0, 0);
417TEST(BitwiseConstrainingTest, NegativeResTagShouldMatchInput)
419 TestTraceContainer
trace;
423 .a = MemoryValue::from<uint8_t>(85),
424 .b = MemoryValue::from<uint8_t>(175),
438TEST(BitwiseConstrainingTest, MixedOperationsInteractions)
440 TestTraceContainer
trace;
449 .a = MemoryValue::from<uint32_t>(13793),
450 .b = MemoryValue::from<uint32_t>(10590617),
453 .a = MemoryValue::from<uint16_t>(5323),
454 .b = MemoryValue::from<uint16_t>(321),
457 .a = MemoryValue::from<uint32_t>(13793),
458 .b = MemoryValue::from<uint32_t>(10590617),
461 .a = MemoryValue::from<uint8_t>(85),
462 .b = MemoryValue::from<uint8_t>(175),
465 .a = MemoryValue::from<uint8_t>(85),
466 .b = MemoryValue::from<uint8_t>(175),
477 check_all_interactions<BitwiseTraceBuilder>(trace);
478 check_relation<bitwise>(trace);
481TEST(BitwiseConstrainingTest, BitwiseExecInteraction)
483 TestTraceContainer
trace({ {
485 { C::bitwise_sel, 1 },
486 { C::bitwise_err, 1 },
489 { C::bitwise_ia, 0x01 },
491 { C::bitwise_ib, 0x01 },
492 { C::bitwise_ic, 0x00 },
494 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
MemoryTag::FF) },
495 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
MemoryTag::U8) },
497 { C::execution_mem_tag_reg_2_,
static_cast<uint8_t
>(
MemoryTag::U8) },
498 { C::execution_register_0_, 0x01 },
499 { C::execution_register_1_, 0x01 },
500 { C::execution_register_2_, 0x00 },
501 { C::execution_sel_exec_dispatch_bitwise, 1 },
502 { C::execution_sel_opcode_error, 1 },
506 check_interaction<ExecutionTraceBuilder, lookup_execution_dispatch_to_bitwise_settings>(trace);
509TEST(BitwiseConstrainingTest, InvalidBitwiseExecInteraction)
511 TestTraceContainer
trace({ {
513 { C::bitwise_sel, 1 },
514 { C::bitwise_ib, 0x01 },
515 { C::bitwise_ia, 0x01 },
518 { C::bitwise_ic, 0x00 },
523 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
MemoryTag::U8) },
524 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
MemoryTag::U16) },
525 { C::execution_mem_tag_reg_2_,
static_cast<uint8_t
>(
MemoryTag::U8) },
526 { C::execution_register_0_, 0x01 },
527 { C::execution_register_1_, 0x01 },
528 { C::execution_register_2_, 0x00 },
529 { C::execution_sel_exec_dispatch_bitwise, 1 },
534 (check_interaction<ExecutionTraceBuilder, lookup_execution_dispatch_to_bitwise_settings>(trace)),
535 "Failed.*EXECUTION_DISPATCH_TO_BITWISE. Could not find tuple in destination.");
538TEST(BitwiseConstrainingTest, ErrorHandlingInputFF)
540 TestTraceContainer
trace;
554 check_relation<bitwise>(trace);
557TEST(BitwiseConstrainingTest, ErrorHandlingInputTagMismatch)
559 TestTraceContainer
trace;
570 check_relation<bitwise>(trace);
571 check_all_interactions<BitwiseTraceBuilder>(trace);
574TEST(BitwiseConstrainingTest, ErrorHandlingMultiple)
576 TestTraceContainer
trace;
587 check_relation<bitwise>(trace);
590TEST(BitwiseConstrainingTest, ExecBitwiseDispatchOnErrorMismatch)
596 TestTraceContainer
trace({ {
598 { C::execution_sel_exec_dispatch_bitwise, 1 },
600 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
a.get_tag()) },
601 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
b.get_tag()) },
602 { C::execution_register_0_,
a.as_ff() },
603 { C::execution_register_1_,
b.as_ff() },
606 { C::execution_mem_tag_reg_2_,
static_cast<uint8_t
>(
MemoryTag::FF) },
607 { C::execution_register_2_, 0x00 },
608 { C::execution_sel_opcode_error, 1 },
616 check_relation<bitwise>(trace);
617 check_interaction<ExecutionTraceBuilder, lookup_execution_dispatch_to_bitwise_settings>(trace);
620TEST(BitwiseConstrainingTest, ExecBitwiseDispatchOnErrorFF)
627 TestTraceContainer
trace({ {
629 { C::execution_sel_exec_dispatch_bitwise, 1 },
631 { C::execution_mem_tag_reg_0_,
static_cast<uint8_t
>(
a.get_tag()) },
632 { C::execution_mem_tag_reg_1_,
static_cast<uint8_t
>(
b.get_tag()) },
633 { C::execution_register_0_,
a.as_ff() },
634 { C::execution_register_1_,
b.as_ff() },
637 { C::execution_mem_tag_reg_2_,
static_cast<uint8_t
>(
MemoryTag::FF) },
638 { C::execution_register_2_, 0x00 },
639 { C::execution_sel_opcode_error, 1 },
647 check_relation<bitwise>(trace);
648 check_interaction<ExecutionTraceBuilder, lookup_execution_dispatch_to_bitwise_settings>(trace);
657TEST(BitwiseConstrainingTest, VulnerabilityKeccakOnError)
659 TestTraceContainer
trace({
661 { C::bitwise_sel, 1 },
662 { C::bitwise_sel_keccak, 1 },
663 { C::bitwise_err, 1 },
672TEST(BitwiseConstrainingTest, VulnerabilitySha256OnError)
674 TestTraceContainer
trace({
676 { C::bitwise_sel, 1 },
677 { C::bitwise_sel_sha256, 1 },
678 { C::bitwise_err, 1 },
691TEST(BitwiseConstrainingTest, VulnerabilityFakeKeccakXorOutput)
693 TestTraceContainer
trace;
698 check_relation<keccakf1600>(trace);
699 check_relation<bitwise>(trace);
701 uint32_t keccak_start_row = 0;
703 if (
trace.
get(C::keccakf1600_start, i) ==
FF(1)) {
704 keccak_start_row = i;
708 ASSERT_EQ(
trace.
get(C::keccakf1600_start, keccak_start_row),
FF(1));
709 ASSERT_EQ(
trace.
get(C::keccakf1600_sel_no_error, keccak_start_row),
FF(1));
713 FF real_state_in_40 =
trace.
get(C::keccakf1600_state_in_40, keccak_start_row);
714 FF real_state_in_41 =
trace.
get(C::keccakf1600_state_in_41, keccak_start_row);
715 FF real_theta_xor_41 =
trace.
get(C::keccakf1600_theta_xor_41, keccak_start_row);
718 FF fake_theta_xor_41 =
FF(0xFA0E0BAD0DEADULL);
719 ASSERT_NE(fake_theta_xor_41, real_theta_xor_41);
720 trace.
set(C::keccakf1600_theta_xor_41, keccak_start_row, fake_theta_xor_41);
727 { C::bitwise_sel, 1 },
728 { C::bitwise_sel_keccak, 1 },
729 { C::bitwise_op_id,
FF(AVM_BITWISE_XOR_OP_ID) },
730 { C::bitwise_ia, real_state_in_40 },
731 { C::bitwise_ib, real_state_in_41 },
732 { C::bitwise_ic, fake_theta_xor_41 },
733 { C::bitwise_tag_a,
FF(MEM_TAG_U64) },
734 { C::bitwise_tag_b,
FF(MEM_TAG_U32) },
735 { C::bitwise_tag_c, 0 },
739 check_relation<keccakf1600>(trace);
743 (check_interaction<KeccakF1600TraceBuilder, lookup_keccakf1600_theta_xor_41_settings>(trace)),
744 "Failed.*LOOKUP_KECCAKF1600_THETA_XOR_41. Could not find tuple in destination.");
748TEST(BitwiseConstrainingTest, VulnerabilityFakeSha256XorOutput)
764 EventEmitter<Sha256CompressionEvent> sha256_event_emitter;
767 std::array<uint32_t, 8> state = { 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
768 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 };
770 for (uint32_t i = 0; i < 8; ++i) {
771 mem.
set(state_addr + i, MemoryValue::from<uint32_t>(state[i]));
774 std::array<uint32_t, 16> input = { 0x61626380, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x18 };
776 for (uint32_t i = 0; i < 16; ++i) {
777 mem.
set(input_addr + i, MemoryValue::from<uint32_t>(input[i]));
781 sha256_gadget.compression(
mem, state_addr, input_addr, output_addr);
783 TestTraceContainer
trace;
784 trace.
set(C::precomputed_first_row, 0, 1);
786 Sha256TraceBuilder sha256_builder;
787 sha256_builder.process(sha256_event_emitter.get_events(), trace);
789 BitwiseTraceBuilder bitwise_builder;
792 check_relation<sha256_relation>(trace);
793 check_relation<bitwise>(trace);
795 uint32_t sha256_row = 0;
798 if (
trace.
get(C::sha256_sel_compute_w, i) ==
FF(1)) {
804 ASSERT_TRUE(found) <<
"Could not find sha256 row with sel_compute_w=1";
806 FF real_w_15_rotr_7 =
trace.
get(C::sha256_w_15_rotr_7, sha256_row);
807 FF real_w_15_rotr_18 =
trace.
get(C::sha256_w_15_rotr_18, sha256_row);
808 FF real_xor_output =
trace.
get(C::sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_row);
810 FF fake_xor_output =
FF(0xDEADBEEF);
811 ASSERT_NE(fake_xor_output, real_xor_output);
812 trace.
set(C::sha256_w_15_rotr_7_xor_w_15_rotr_18, sha256_row, fake_xor_output);
818 { C::bitwise_sel, 1 },
819 { C::bitwise_sel_sha256, 1 },
820 { C::bitwise_op_id,
FF(AVM_BITWISE_XOR_OP_ID) },
821 { C::bitwise_ia, real_w_15_rotr_7 },
822 { C::bitwise_ib, real_w_15_rotr_18 },
823 { C::bitwise_ic, fake_xor_output },
824 { C::bitwise_tag_a,
FF(MEM_TAG_U32) },
825 { C::bitwise_tag_b,
FF(MEM_TAG_U8) },
826 { C::bitwise_sel_tag_mismatch_err, 1 },
827 { C::bitwise_sel_tag_ff_err, 0 },
828 { C::bitwise_err, 1 },
829 { C::bitwise_tag_a_inv,
FF(MEM_TAG_U32).
invert() },
830 { C::bitwise_tag_ab_diff_inv,
FF(MEM_TAG_U32 - MEM_TAG_U8).
invert() },
831 { C::bitwise_tag_c, 0 },
835 check_relation<sha256_relation>(trace);
841 tracegen::SharedIndexCache cache;
842 tracegen::LookupIntoDynamicTableGeneric<lookup_sha256_w_s_0_xor_0_settings> lookup(cache, C::bitwise_sel);
844 "Failed.*LOOKUP_SHA256_W_S_0_XOR_0. Could not find tuple in destination.");
#define EXPECT_THROW_WITH_MESSAGE(code, expectedMessageRegex)
FieldGreaterThan field_gt
static TaggedValue from(T value)
static TaggedValue from_tag(ValueTag tag, FF value)
static constexpr size_t SR_BITW_SIMD_ONLY_ON_U128
static constexpr size_t SR_BITW_TAG_LEN_DECOMPOSITION
static constexpr size_t SR_BITW_RECOMP_A
static constexpr size_t SR_INPUT_TAG_CANNOT_BE_FF
static constexpr size_t SR_BITW_RECOMP_B
static constexpr size_t SR_BITW_RECOMP_C
static constexpr size_t SR_RES_TAG_SHOULD_MATCH_INPUT
static constexpr size_t SR_BITW_NO_EXTERNAL_ON_ERROR
static std::string get_subrelation_label(size_t index)
static constexpr size_t SR_INPUT_TAGS_SHOULD_MATCH
void set(MemoryAddress index, MemoryValue value) override
void process(const simulation::EventEmitterInterface< simulation::AluEvent >::Container &events, TraceContainer &trace)
Process the ALU events and populate the ALU relevant columns in the trace.
void process_misc(TraceContainer &trace, const uint32_t num_rows=PRECOMPUTED_TRACE_SIZE)
Populate miscellaneous precomputed columns: first_row selector and idx (row index).
void process_bitwise(TraceContainer &trace)
Populate the 8-bit bitwise lookup table (AND, OR, XOR).
void process_sel_range_16(TraceContainer &trace)
Generate a selector column that activates the first 2^16 (65536) rows.
void process_tag_parameters(TraceContainer &trace)
Populate the memory tag parameters table (byte length, max bits, max value per tag).
const FF & get(Column col, uint32_t row) const
uint32_t get_num_rows() const
void set(Column col, uint32_t row, const FF &value, bool use_atomic_limbs=false)
PrecomputedTraceBuilder precomputed_builder
EventEmitter< GreaterThanEvent > gt_event_emitter
ExecutionIdManager execution_id_manager
EventEmitter< RangeCheckEvent > range_check_event_emitter
TEST(AvmFixedVKTests, FixedVKCommitments)
Test that the fixed VK commitments agree with the ones computed from precomputed columns.
void generate_keccak_trace(TestTraceContainer &trace, const std::vector< MemoryAddress > &dst_addresses, const std::vector< MemoryAddress > &src_addresses, uint16_t space_id)
TestTraceContainer empty_trace()
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
simulation::PublicDataTreeReadWriteEvent event
unsigned __int128 uint128_t
NoopEventEmitter< FieldGreaterThanEvent > field_gt_event_emitter
NoopEventEmitter< BitwiseEvent > bitwise_event_emitter
constexpr field invert() const noexcept