Skip to content

Commit

Permalink
3738 - add positive unit tests for addition with type u8, u16, u32, u64
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanmon committed Jan 11, 2024
1 parent 8e4f299 commit 0a65b54
Showing 1 changed file with 239 additions and 17 deletions.
256 changes: 239 additions & 17 deletions barretenberg/cpp/src/barretenberg/vm/tests/AvmMini_arithmetic.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,13 +91,42 @@ Row common_validate_sub(std::vector<Row> const& trace,

common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag);

// Check that addition selector is set.
// Check that subtraction selector is set.
EXPECT_EQ(row->avmMini_sel_op_sub, FF(1));
EXPECT_EQ(alu_row->aluChip_alu_op_sub, FF(1));

return *alu_row;
}

Row common_validate_mul(std::vector<Row> const& trace,
FF const& a,
FF const& b,
FF const& c,
FF const& addr_a,
FF const& addr_b,
FF const& addr_c,
avm_trace::AvmMemoryTag const tag)
{
// Find the first row enabling the multiplication selector
auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avmMini_sel_op_mul == FF(1); });

// Find the corresponding Alu trace row
auto clk = row->avmMini_clk;
auto alu_row = std::ranges::find_if(trace.begin(), trace.end(), [clk](Row r) { return r.aluChip_alu_clk == clk; });

// Check that both rows were found
EXPECT_TRUE(row != trace.end());
EXPECT_TRUE(alu_row != trace.end());

common_validate_arithmetic_op(*row, *alu_row, a, b, c, addr_a, addr_b, addr_c, tag);

// Check that multiplication selector is set.
EXPECT_EQ(row->avmMini_sel_op_mul, FF(1));
EXPECT_EQ(alu_row->aluChip_alu_op_mul, FF(1));

return *alu_row;
}

} // anonymous namespace

namespace tests_avm {
Expand Down Expand Up @@ -202,15 +231,11 @@ TEST_F(AvmMiniArithmeticTestsFF, multiplication)
trace_builder.return_op(0, 3);
auto trace = trace_builder.finalize();

// Find the first row enabling the multiplication selector
auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avmMini_sel_op_mul == FF(1); });
auto alu_row = common_validate_mul(trace, FF(20), FF(5), FF(100), FF(2), FF(0), FF(1), AvmMemoryTag::ff);

// Check that the correct result is stored at the expected memory location.
EXPECT_TRUE(row != trace.end());
EXPECT_EQ(row->avmMini_ic, FF(100));
EXPECT_EQ(row->avmMini_mem_idx_c, FF(1));
EXPECT_EQ(row->avmMini_mem_op_c, FF(1));
EXPECT_EQ(row->avmMini_rwc, FF(1));
EXPECT_EQ(alu_row.aluChip_alu_ff_tag, FF(1));
EXPECT_EQ(alu_row.aluChip_alu_cf, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(0));

validate_trace_proof(std::move(trace));
}
Expand All @@ -225,15 +250,11 @@ TEST_F(AvmMiniArithmeticTestsFF, multiplicationByZero)
trace_builder.return_op(0, 3);
auto trace = trace_builder.finalize();

// Find the first row enabling the multiplication selector
auto row = std::ranges::find_if(trace.begin(), trace.end(), [](Row r) { return r.avmMini_sel_op_mul == FF(1); });
auto alu_row = common_validate_mul(trace, FF(127), FF(0), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::ff);

// Check that the correct result is stored at the expected memory location.
EXPECT_TRUE(row != trace.end());
EXPECT_EQ(row->avmMini_ic, FF(0));
EXPECT_EQ(row->avmMini_mem_idx_c, FF(2));
EXPECT_EQ(row->avmMini_mem_op_c, FF(1));
EXPECT_EQ(row->avmMini_rwc, FF(1));
EXPECT_EQ(alu_row.aluChip_alu_ff_tag, FF(1));
EXPECT_EQ(alu_row.aluChip_alu_cf, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(0));

validate_trace_proof(std::move(trace));
}
Expand Down Expand Up @@ -446,6 +467,51 @@ TEST_F(AvmMiniArithmeticTestsU8, subtractionCarry)
validate_trace_proof(std::move(trace));
}

// Test on basic multiplication over u8 type.
TEST_F(AvmMiniArithmeticTestsU8, multiplication)
{
// trace_builder
trace_builder.set(13, 0, AvmMemoryTag::u8);
trace_builder.set(15, 1, AvmMemoryTag::u8);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u8);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row = common_validate_mul(trace, FF(13), FF(15), FF(195), FF(0), FF(1), FF(2), AvmMemoryTag::u8);

EXPECT_EQ(alu_row.aluChip_alu_u8_tag, FF(1));

// Decomposition of integer multiplication in 8-bit registers
EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(195));
EXPECT_EQ(alu_row.aluChip_alu_u8_r1, FF(0));

validate_trace_proof(std::move(trace));
}

// Test on multiplication over u8 type with overflow.
TEST_F(AvmMiniArithmeticTestsU8, multiplicationOverflow)
{
// trace_builder
trace_builder.set(200, 0, AvmMemoryTag::u8);
trace_builder.set(170, 1, AvmMemoryTag::u8);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u8);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row = common_validate_mul(trace, FF(200), FF(170), FF(208), FF(0), FF(1), FF(2), AvmMemoryTag::u8);

EXPECT_EQ(alu_row.aluChip_alu_u8_tag, FF(1));

// Decomposition of integer multiplication in 8-bit registers
// 34'000 = 208 + 132 * 256
EXPECT_EQ(alu_row.aluChip_alu_u8_r0, FF(208));
EXPECT_EQ(alu_row.aluChip_alu_u8_r1, FF(132));

validate_trace_proof(std::move(trace));
}

/******************************************************************************
* Positive Tests - U16
******************************************************************************/
Expand Down Expand Up @@ -535,6 +601,51 @@ TEST_F(AvmMiniArithmeticTestsU16, subtractionCarry)
validate_trace_proof(std::move(trace));
}

// Test on basic multiplication over u16 type.
TEST_F(AvmMiniArithmeticTestsU16, multiplication)
{
// trace_builder
trace_builder.set(200, 0, AvmMemoryTag::u16);
trace_builder.set(245, 1, AvmMemoryTag::u16);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u16);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row = common_validate_mul(trace, FF(200), FF(245), FF(49000), FF(0), FF(1), FF(2), AvmMemoryTag::u16);

EXPECT_EQ(alu_row.aluChip_alu_u16_tag, FF(1));

// Decomposition of integer multiplication in 16-bit registers
EXPECT_EQ(alu_row.aluChip_alu_u16_r0, FF(49000));
EXPECT_EQ(alu_row.aluChip_alu_u16_r1, FF(0));

validate_trace_proof(std::move(trace));
}

// Test on multiplication over u16 type with overflow.
TEST_F(AvmMiniArithmeticTestsU16, multiplicationOverflow)
{
// trace_builder
trace_builder.set(512, 0, AvmMemoryTag::u16);
trace_builder.set(1024, 1, AvmMemoryTag::u16);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u16);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row = common_validate_mul(trace, FF(512), FF(1024), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::u16);

EXPECT_EQ(alu_row.aluChip_alu_u16_tag, FF(1));

// Decomposition of integer multiplication in 16-bit registers
// 512 * 1024 = 0 + 8 * 2^16
EXPECT_EQ(alu_row.aluChip_alu_u16_r0, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u16_r1, FF(8));

validate_trace_proof(std::move(trace));
}

/******************************************************************************
* Positive Tests - U32
******************************************************************************/
Expand Down Expand Up @@ -632,6 +743,58 @@ TEST_F(AvmMiniArithmeticTestsU32, subtractionCarry)
validate_trace_proof(std::move(trace));
}

// Test on basic multiplication over u32 type.
TEST_F(AvmMiniArithmeticTestsU32, multiplication)
{
// trace_builder
trace_builder.set(11111, 0, AvmMemoryTag::u32);
trace_builder.set(11111, 1, AvmMemoryTag::u32);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u32);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row =
common_validate_mul(trace, FF(11111), FF(11111), FF(123454321), FF(0), FF(1), FF(2), AvmMemoryTag::u32);

EXPECT_EQ(alu_row.aluChip_alu_u32_tag, FF(1));

// Decomposition of integer multiplication in 16-bit registers
// 123454321 = 50033 + 1883 * 2^16
EXPECT_EQ(alu_row.aluChip_alu_u16_r0, FF(50033));
EXPECT_EQ(alu_row.aluChip_alu_u16_r1, FF(1883));
EXPECT_EQ(alu_row.aluChip_alu_u16_r2, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u16_r3, FF(0));

validate_trace_proof(std::move(trace));
}

// Test on multiplication over u32 type with overflow.
TEST_F(AvmMiniArithmeticTestsU32, multiplicationOverflow)
{
// trace_builder
trace_builder.set(11 << 25, 0, AvmMemoryTag::u32);
trace_builder.set(13 << 22, 1, AvmMemoryTag::u32);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u32);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row =
common_validate_mul(trace, FF(11 << 25), FF(13 << 22), FF(0), FF(0), FF(1), FF(2), AvmMemoryTag::u32);

EXPECT_EQ(alu_row.aluChip_alu_u32_tag, FF(1));

// Decomposition of integer multiplication in 16-bit registers
// 143 * 2^47 = 0 + 0 * 2^16 + 2^15 * 2^32 + 71 * 2^48
EXPECT_EQ(alu_row.aluChip_alu_u16_r0, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u16_r1, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u16_r2, FF(32768)); // 2^15
EXPECT_EQ(alu_row.aluChip_alu_u16_r3, FF(71));

validate_trace_proof(std::move(trace));
}

/******************************************************************************
* Positive Tests - U64
******************************************************************************/
Expand Down Expand Up @@ -749,6 +912,65 @@ TEST_F(AvmMiniArithmeticTestsU64, subtractionCarry)
validate_trace_proof(std::move(trace));
}

// Test on basic multiplication over u64 type.
TEST_F(AvmMiniArithmeticTestsU64, multiplication)
{
// trace_builder
trace_builder.set(999888777, 0, AvmMemoryTag::u64);
trace_builder.set(555444333, 1, AvmMemoryTag::u64);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u64);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row = common_validate_mul(
trace, FF(999888777), FF(555444333), FF(555382554814950741LLU), FF(0), FF(1), FF(2), AvmMemoryTag::u64);

EXPECT_EQ(alu_row.aluChip_alu_u64_tag, FF(1));

// Decomposition of integer multiplication in 16-bit registers
// 555,382,554,814,950,741 = 44,373 + 46,641 * 2^16 + 7,549 * 2^32 + 1,973 * 2^48
EXPECT_EQ(alu_row.aluChip_alu_u16_r0, FF(44373));
EXPECT_EQ(alu_row.aluChip_alu_u16_r1, FF(46641));
EXPECT_EQ(alu_row.aluChip_alu_u16_r2, FF(7549));
EXPECT_EQ(alu_row.aluChip_alu_u16_r3, FF(1973));

validate_trace_proof(std::move(trace));
}

// Test on multiplication over u64 type with overflow.
TEST_F(AvmMiniArithmeticTestsU64, multiplicationOverflow)
{
uint64_t const a = UINT64_MAX;
uint64_t const b = UINT64_MAX;
// (2^64 - 1)^2 = 2^128 - 2^65 + 1 (mod. 2^64) = 1

// trace_builder
trace_builder.set(a, 0, AvmMemoryTag::u64);
trace_builder.set(b, 1, AvmMemoryTag::u64);

trace_builder.mul(0, 1, 2, AvmMemoryTag::u64);
trace_builder.return_op(2, 1);
auto trace = trace_builder.finalize();

auto alu_row = common_validate_mul(trace, FF(a), FF(b), FF(1), FF(0), FF(1), FF(2), AvmMemoryTag::u64);

EXPECT_EQ(alu_row.aluChip_alu_u64_tag, FF(1));

// Decomposition of integer multiplication in 16-bit registers
// 2^128 - 2^65 + 1
EXPECT_EQ(alu_row.aluChip_alu_u16_r0, FF(1));
EXPECT_EQ(alu_row.aluChip_alu_u16_r1, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u16_r2, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u16_r3, FF(0));
EXPECT_EQ(alu_row.aluChip_alu_u16_r4, FF(UINT16_MAX - 1));
EXPECT_EQ(alu_row.aluChip_alu_u16_r5, FF(UINT16_MAX));
EXPECT_EQ(alu_row.aluChip_alu_u16_r6, FF(UINT16_MAX));
EXPECT_EQ(alu_row.aluChip_alu_u16_r7, FF(UINT16_MAX));

validate_trace_proof(std::move(trace));
}

/******************************************************************************
* Positive Tests - U128
******************************************************************************/
Expand Down

0 comments on commit 0a65b54

Please sign in to comment.