diff --git a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp index 1d2729bc725d..fa41d4493c12 100644 --- a/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp +++ b/barretenberg/cpp/src/barretenberg/plonk_honk_shared/composer/composer_lib.test.cpp @@ -43,8 +43,9 @@ TEST_F(ComposerLibTests, LookupReadCounts) auto accumulators = plookup::get_lookup_accumulators(UINT32_XOR, left, right, /*is_2_to_1_lookup*/ true); builder.create_gates_from_plookup_accumulators(UINT32_XOR, accumulators, left_idx, right_idx); - EXPECT_EQ(builder.lookup_tables.size(), 1); // we only used a single table - EXPECT_EQ(builder.lookup_tables[0].size(), 4096); // table has size 64*64 (6 bit operands) + EXPECT_EQ(builder.lookup_tables.size(), 2); // we only used two tables, first for 6 bits, second for 2 bits + EXPECT_EQ(builder.lookup_tables[0].size(), 4096); // first table has size 64*64 (6 bit operands) + EXPECT_EQ(builder.lookup_tables[1].size(), 16); // first table has size 4*4 (2 bit operands) size_t circuit_size = 8192; @@ -59,15 +60,19 @@ TEST_F(ComposerLibTests, LookupReadCounts) // The uint32 XOR lookup table is constructed for 6 bit operands via double for loop that iterates through the left // operand externally (0 to 63) then the right operand internally (0 to 63). Computing (1 XOR 5) will thus result in - // 1 lookup from the (1*64 + 5)th index in the table and 5 lookups from the (0*64 + 0)th index (for the remaining 5 - // limbs that are all 0). The counts and tags at all other indices should be zero. + // 1 lookup from the (1*64 + 5)th index in the table and 4 lookups from the (0*64 + 0)th index (for the remaining 4 + // 6-bits limbs that are all 0) and one lookup from second table from the (64 * 64 + 0) index (for last 2 bits). + // The counts and tags at all other indices should be zero. for (auto [idx, count, tag] : zip_polys(read_counts, read_tags)) { if (idx == (0 + offset)) { - EXPECT_EQ(count, 5); + EXPECT_EQ(count, 4); EXPECT_EQ(tag, 1); } else if (idx == (69 + offset)) { EXPECT_EQ(count, 1); EXPECT_EQ(tag, 1); + } else if (idx == (64 * 64 + offset)) { + EXPECT_EQ(count, 1); + EXPECT_EQ(tag, 1); } else { EXPECT_EQ(count, 0); EXPECT_EQ(tag, 0); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/plookup_tables.cpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/plookup_tables.cpp index 0440eb17b9c5..3f7b3492bb72 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/plookup_tables.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/plookup_tables.cpp @@ -309,11 +309,17 @@ BasicTable create_basic_table(const BasicTableId id, const size_t index) case SHA256_BASE16_ROTATE2: { return sparse_tables::generate_sparse_table_with_rotation<16, 11, 2>(SHA256_BASE16_ROTATE2, index); } - case UINT_XOR_ROTATE0: { - return uint_tables::generate_xor_rotate_table<6, 0>(UINT_XOR_ROTATE0, index); + case UINT_XOR_SLICE_6_ROTATE_0: { + return uint_tables::generate_xor_rotate_table<6, 0>(UINT_XOR_SLICE_6_ROTATE_0, index); } - case UINT_AND_ROTATE0: { - return uint_tables::generate_and_rotate_table<6, 0>(UINT_AND_ROTATE0, index); + case UINT_AND_SLICE_6_ROTATE_0: { + return uint_tables::generate_and_rotate_table<6, 0>(UINT_AND_SLICE_6_ROTATE_0, index); + } + case UINT_XOR_SLICE_2_ROTATE_0: { + return uint_tables::generate_xor_rotate_table<2, 0>(UINT_XOR_SLICE_2_ROTATE_0, index); + } + case UINT_AND_SLICE_2_ROTATE_0: { + return uint_tables::generate_and_rotate_table<2, 0>(UINT_AND_SLICE_2_ROTATE_0, index); } case BN254_XLO_BASIC: { return ecc_generator_tables::ecc_generator_table::generate_xlo_table(BN254_XLO_BASIC, index); diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/types.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/types.hpp index 9ba18ab891f7..da5403489b52 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/types.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/types.hpp @@ -30,8 +30,10 @@ enum BasicTableId { SHA256_BASE16_ROTATE6, SHA256_BASE16_ROTATE7, SHA256_BASE16_ROTATE8, - UINT_XOR_ROTATE0, - UINT_AND_ROTATE0, + UINT_XOR_SLICE_6_ROTATE_0, + UINT_XOR_SLICE_2_ROTATE_0, + UINT_AND_SLICE_6_ROTATE_0, + UINT_AND_SLICE_2_ROTATE_0, BN254_XLO_BASIC, BN254_XHI_BASIC, BN254_YLO_BASIC, diff --git a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/uint.hpp b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/uint.hpp index 7ba5d03304a0..64059275abf3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/uint.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib_circuit_builders/plookup_tables/uint.hpp @@ -72,31 +72,49 @@ inline BasicTable generate_and_rotate_table(BasicTableId id, const size_t table_ inline MultiTable get_uint32_xor_table(const MultiTableId id = UINT32_XOR) { - const size_t num_entries = (32 + 5) / 6; - const uint64_t base = 1 << 6; + const size_t TABLE_BIT_SIZE = 6; + const size_t num_entries = 32 / TABLE_BIT_SIZE; + const uint64_t base = 1 << TABLE_BIT_SIZE; MultiTable table(base, base, base, num_entries); table.id = id; for (size_t i = 0; i < num_entries; ++i) { table.slice_sizes.emplace_back(base); - table.basic_table_ids.emplace_back(UINT_XOR_ROTATE0); + table.basic_table_ids.emplace_back(UINT_XOR_SLICE_6_ROTATE_0); table.get_table_values.emplace_back(&get_xor_rotate_values_from_key<6, 0>); } + + // 32 = 5 * 6 + 2 + // all remaining bits + const size_t LAST_BIT_SIZE = 32 - TABLE_BIT_SIZE * num_entries; + const size_t LAST_SLICE_SIZE = 1 << LAST_BIT_SIZE; + table.slice_sizes.emplace_back(base); + table.basic_table_ids.emplace_back(UINT_XOR_SLICE_2_ROTATE_0); + table.get_table_values.emplace_back(&get_xor_rotate_values_from_key); return table; } inline MultiTable get_uint32_and_table(const MultiTableId id = UINT32_AND) { - const size_t num_entries = (32 + 5) / 6; - const uint64_t base = 1 << 6; + const size_t TABLE_BIT_SIZE = 6; + const size_t num_entries = 32 / TABLE_BIT_SIZE; + const uint64_t base = 1 << TABLE_BIT_SIZE; MultiTable table(base, base, base, num_entries); table.id = id; for (size_t i = 0; i < num_entries; ++i) { table.slice_sizes.emplace_back(base); - table.basic_table_ids.emplace_back(UINT_AND_ROTATE0); - table.get_table_values.emplace_back(&get_and_rotate_values_from_key<6, 0>); + table.basic_table_ids.emplace_back(UINT_AND_SLICE_6_ROTATE_0); + table.get_table_values.emplace_back(&get_and_rotate_values_from_key); } + // 32 = 5 * 6 + 2 + // all remaining bits + const size_t LAST_TABLE_BIT_SIZE = 32 - TABLE_BIT_SIZE * num_entries; + const size_t LAST_SLICE_SIZE = 1 << LAST_TABLE_BIT_SIZE; + table.slice_sizes.emplace_back(LAST_SLICE_SIZE); + table.basic_table_ids.emplace_back(UINT_AND_SLICE_2_ROTATE_0); + table.get_table_values.emplace_back(&get_and_rotate_values_from_key); + return table; }