From 99e416d42c239bda81be52c126293425801ab82d Mon Sep 17 00:00:00 2001 From: suyash67 Date: Thu, 24 Jul 2025 13:58:12 +0000 Subject: [PATCH 1/2] first pass at removing logic from uint. --- .../stdlib/primitives/uint/logic.cpp | 365 --------- .../stdlib/primitives/uint/uint.hpp | 40 - .../stdlib/primitives/uint/uint.test.cpp | 720 ------------------ 3 files changed, 1125 deletions(-) delete mode 100644 barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp deleted file mode 100644 index 9d6ef527eb02..000000000000 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/logic.cpp +++ /dev/null @@ -1,365 +0,0 @@ -// === AUDIT STATUS === -// internal: { status: not started, auditors: [], date: YYYY-MM-DD } -// external_1: { status: not started, auditors: [], date: YYYY-MM-DD } -// external_2: { status: not started, auditors: [], date: YYYY-MM-DD } -// ===================== - -#include "../circuit_builders/circuit_builders.hpp" -#include "barretenberg/common/assert.hpp" -#include "uint.hpp" - -using namespace bb; - -namespace bb::stdlib { - -using namespace bb::plookup; - -template -uint uint::operator&(const uint& other) const -{ - return logic_operator(other, LogicOp::AND); -} - -template -uint uint::operator^(const uint& other) const -{ - return logic_operator(other, LogicOp::XOR); -} - -template -uint uint::operator|(const uint& other) const -{ - return (*this + other) - (*this & other); -} - -template uint uint::operator~() const -{ - return uint(context, MASK) - *this; -} - -template -uint uint::operator>>(const size_t shift) const -{ - if (shift >= width) { - return uint(context, 0); - } - if (is_constant()) { - return uint(context, (additive_constant >> shift) & MASK); - } - - if (witness_status != WitnessStatus::OK) { - normalize(); - } - - if (shift == 0) { - return *this; - } - - uint64_t bits_per_hi_limb; - // last limb will not likely bit `bits_per_limb`. Need to be careful with our range check - if (shift >= ((width / bits_per_limb) * bits_per_limb)) { - bits_per_hi_limb = width % bits_per_limb; - } else { - bits_per_hi_limb = bits_per_limb; - } - const uint64_t slice_bit_position = shift % bits_per_limb; - const size_t accumulator_index = shift / bits_per_limb; - const uint32_t slice_index = accumulators[accumulator_index]; - const uint64_t slice_value = uint256_t(context->get_variable(slice_index)).data[0]; - - const uint64_t slice_lo = slice_value % (1ULL << slice_bit_position); - const uint64_t slice_hi = slice_value >> slice_bit_position; - const uint32_t slice_lo_idx = slice_bit_position ? context->add_variable(slice_lo) : context->zero_idx; - const uint32_t slice_hi_idx = - (slice_bit_position != bits_per_limb) ? context->add_variable(slice_hi) : context->zero_idx; - - context->create_big_add_gate( - { slice_index, slice_lo_idx, context->zero_idx, slice_hi_idx, -1, 1, 0, (1 << slice_bit_position), 0 }); - - if (slice_bit_position != 0) { - context->create_new_range_constraint(slice_lo_idx, (1ULL << slice_bit_position) - 1); - } - context->create_new_range_constraint(slice_hi_idx, (1ULL << (bits_per_hi_limb - slice_bit_position)) - 1); - std::vector> sublimbs; - sublimbs.emplace_back(field_t::from_witness_index(context, slice_hi_idx)); - - const size_t start = accumulator_index + 1; - field_t coefficient(context, uint64_t(1ULL << (start * bits_per_limb - shift))); - field_t shifter(context, uint64_t(1ULL << bits_per_limb)); - for (size_t i = accumulator_index + 1; i < num_accumulators(); ++i) { - sublimbs.emplace_back(field_t::from_witness_index(context, accumulators[i]) * - field_t(coefficient)); - coefficient *= shifter; - } - - uint32_t result_index = field_t::accumulate(sublimbs).get_witness_index(); - uint result(context); - result.witness_index = result_index; - result.witness_status = WitnessStatus::WEAK_NORMALIZED; - return result; -} - -template -uint uint::operator<<(const size_t shift) const -{ - if (shift >= width) { - return uint(context, 0); - } - if (is_constant()) { - return uint(context, (additive_constant << shift) & MASK); - } - - if (witness_status != WitnessStatus::OK) { - normalize(); - } - - if (shift == 0) { - return *this; - } - - uint64_t slice_bit_position; - size_t accumulator_index; - size_t bits_per_hi_limb; - // most significant limb is only 2 bits long (for u32), need to be careful about which slice we index, - // and how large the range check is on our hi limb - if (shift < (width - ((width / bits_per_limb) * bits_per_limb))) { - bits_per_hi_limb = width % bits_per_limb; - slice_bit_position = bits_per_hi_limb - (shift % bits_per_hi_limb); - accumulator_index = num_accumulators() - 1; - } else { - const size_t offset = width % bits_per_limb; - slice_bit_position = bits_per_limb - ((shift - offset) % bits_per_limb); - accumulator_index = num_accumulators() - 2 - ((shift - offset) / bits_per_limb); - bits_per_hi_limb = bits_per_limb; - } - - const uint32_t slice_index = accumulators[accumulator_index]; - const uint64_t slice_value = uint256_t(context->get_variable(slice_index)).data[0]; - - const uint64_t slice_lo = slice_value % (1ULL << slice_bit_position); - const uint64_t slice_hi = slice_value >> slice_bit_position; - const uint32_t slice_lo_idx = slice_bit_position ? context->add_variable(slice_lo) : context->zero_idx; - const uint32_t slice_hi_idx = - (slice_bit_position != bits_per_hi_limb) ? context->add_variable(slice_hi) : context->zero_idx; - - context->create_big_add_gate( - { slice_index, slice_lo_idx, context->zero_idx, slice_hi_idx, -1, 1, 0, (1 << slice_bit_position), 0 }); - - context->create_new_range_constraint(slice_lo_idx, (1ULL << slice_bit_position) - 1); - - if (slice_bit_position != bits_per_limb) { - context->create_new_range_constraint(slice_hi_idx, (1ULL << (bits_per_hi_limb - slice_bit_position)) - 1); - } - - std::vector> sublimbs; - sublimbs.emplace_back(field_t::from_witness_index(context, slice_lo_idx) * - field_t(context, 1ULL << ((accumulator_index)*bits_per_limb + shift))); - - field_t coefficient(context, uint64_t(1ULL << shift)); - field_t shifter(context, uint64_t(1ULL << bits_per_limb)); - for (size_t i = 0; i < accumulator_index; ++i) { - sublimbs.emplace_back(field_t::from_witness_index(context, accumulators[i]) * - field_t(coefficient)); - coefficient *= shifter; - } - - uint32_t result_index = field_t::accumulate(sublimbs).get_witness_index(); - uint result(context); - result.witness_index = result_index; - result.witness_status = WitnessStatus::WEAK_NORMALIZED; - return result; -} - -template -uint uint::ror(const size_t target_rotation) const -{ - const size_t rotation = target_rotation & (width - 1); - - const auto rotate = [](const uint256_t input, const uint64_t rot) { - uint256_t r0 = (input >> rot); - uint256_t r1 = (input << (width - rot)) & MASK; - return (rot > 0) ? (r0 + r1) : input; - }; - - if (is_constant()) { - return uint(context, rotate(additive_constant, rotation)); - } - - if (witness_status != WitnessStatus::OK) { - normalize(); - } - - if (rotation == 0) { - return *this; - } - - const size_t shift = rotation; - uint64_t bits_per_hi_limb; - // last limb will not likely bit `bits_per_limb`. Need to be careful with our range check - if (shift >= ((width / bits_per_limb) * bits_per_limb)) { - bits_per_hi_limb = width % bits_per_limb; - } else { - bits_per_hi_limb = bits_per_limb; - } - const uint64_t slice_bit_position = shift % bits_per_limb; - const size_t accumulator_index = shift / bits_per_limb; - const uint32_t slice_index = accumulators[accumulator_index]; - const uint64_t slice_value = uint256_t(context->get_variable(slice_index)).data[0]; - - const uint64_t slice_lo = slice_value % (1ULL << slice_bit_position); - const uint64_t slice_hi = slice_value >> slice_bit_position; - const uint32_t slice_lo_idx = slice_bit_position ? context->add_variable(slice_lo) : context->zero_idx; - const uint32_t slice_hi_idx = - (slice_bit_position != bits_per_limb) ? context->add_variable(slice_hi) : context->zero_idx; - - context->create_big_add_gate( - { slice_index, slice_lo_idx, context->zero_idx, slice_hi_idx, -1, 1, 0, (1 << slice_bit_position), 0 }); - - if (slice_bit_position != 0) { - context->create_new_range_constraint(slice_lo_idx, (1ULL << slice_bit_position) - 1); - } - context->create_new_range_constraint(slice_hi_idx, (1ULL << (bits_per_hi_limb - slice_bit_position)) - 1); - std::vector> sublimbs; - sublimbs.emplace_back(field_t::from_witness_index(context, slice_hi_idx)); - - const size_t start = accumulator_index + 1; - field_t coefficient(context, uint64_t(1ULL << (start * bits_per_limb - shift))); - field_t shifter(context, uint64_t(1ULL << bits_per_limb)); - for (size_t i = accumulator_index + 1; i < num_accumulators(); ++i) { - sublimbs.emplace_back(field_t::from_witness_index(context, accumulators[i]) * - field_t(coefficient)); - coefficient *= shifter; - } - - coefficient = field_t(context, uint64_t(1ULL << (width - shift))); - for (size_t i = 0; i < accumulator_index; ++i) { - sublimbs.emplace_back(field_t::from_witness_index(context, accumulators[i]) * - field_t(coefficient)); - coefficient *= shifter; - } - sublimbs.emplace_back(field_t::from_witness_index(context, slice_lo_idx) * field_t(coefficient)); - - uint32_t result_index = field_t::accumulate(sublimbs).get_witness_index(); - uint result(context); - result.witness_index = result_index; - result.witness_status = WitnessStatus::WEAK_NORMALIZED; - return result; -} - -template -uint uint::rol(const size_t target_rotation) const -{ - return ror(width - (target_rotation & (width - 1))); -} - -template -uint uint::logic_operator(const uint& other, const LogicOp op_type) const -{ - Builder* ctx = (context == nullptr) ? other.context : context; - - // we need to ensure that we can decompose our integers into (width / 2) quads - // we don't need to completely normalize, however, as our quaternary decomposition will do that by default - const uint256_t lhs = get_value(); - const uint256_t rhs = other.get_value(); - uint256_t out = 0; - - switch (op_type) { - case AND: { - out = lhs & rhs; - break; - } - case XOR: { - out = lhs ^ rhs; - break; - } - default: { - } - } - - if (is_constant() && other.is_constant()) { - return uint(ctx, out); - } - - // We need to decide which lookup table to use based on the native type and operation type. - MultiTableId multi_table_id; - if constexpr (std::is_same_v) { - multi_table_id = (op_type == XOR) ? MultiTableId::UINT64_XOR : MultiTableId::UINT64_AND; - } else if constexpr (std::is_same_v) { - multi_table_id = (op_type == XOR) ? MultiTableId::UINT32_XOR : MultiTableId::UINT32_AND; - } else if constexpr (std::is_same_v) { - multi_table_id = (op_type == XOR) ? MultiTableId::UINT16_XOR : MultiTableId::UINT16_AND; - } else if constexpr (std::is_same_v) { - multi_table_id = (op_type == XOR) ? MultiTableId::UINT8_XOR : MultiTableId::UINT8_AND; - } else { - throw_or_abort("unsupported native type for stdlib uint operation."); - } - - // We allow the uint types to contain unbounded values (for example, uint32_t can hold values > 2^32). - // When looking them up in the lookup tables though, we don't need to range-constrain them because the lookup - // operation itself acts as an implicit range-check. If the inputs are out of range, the lookup constraint will - // fail, i.e., the values in lookup gates don't match the values in the actual lookup table. - // Construct the lookup keys from the uints. - field_t key_left = field_t::from_witness_index(context, witness_index); - key_left.additive_constant = is_constant() ? fr(additive_constant) : fr::zero(); - field_t key_right = field_t::from_witness_index(context, other.witness_index); - key_right.additive_constant = other.is_constant() ? fr(other.additive_constant) : fr::zero(); - - // Perform the lookup to get the accumulators. - ReadData> lookup = - plookup_read::get_lookup_accumulators(multi_table_id, key_left, key_right, true); - - uint result(ctx); - // result.accumulators.resize(num_accumulators()); - field_t scaling_factor(context, bb::fr(1ULL << bits_per_limb)); - - // N.B. THIS LOOP ONLY WORKS IF THE LOGIC TABLE SLICE SIZE IS HALF THAT OF `bits_per_limb` - ASSERT(num_accumulators() == (lookup[ColumnIdx::C3].size() + 1) / 2, - "uint::logic num of accumulators must be half of num of lookups."); - - for (size_t i = 0; i < num_accumulators(); ++i) { - - /** - * we can extract a slice value, by taking the relative difference between accumulating sums. - * each table row sums a 6-bit slice into an accumulator, we need to take the difference between slices in jumps - *of 2, to get a 12-bit slice - * - * If our output limbs are b0, b1, b2, b3, b4, b5, our lookup[ColumnIdx::C3] values represent: - * (where X = 2^6) - * | c0 | b0 + X.b1 + X.X.b2 + X.X.X.b3 + X.X.X.X.b4 + X.X.X.X.X.b5 - * | c1 | b1 + X.b2 + X.X.b3 + X.X.X.b4 + X.X.X.X.b5 - * | c2 | b2 + X. b3 + X.X.b4 + X.X.X.b5 - * | c3 | b3 + X.b4 + X.X.b5 - * | c4 | b4 + X.b5 - * | c5 | b5 - * - * - * We want in our accumulators: - * - * | acc[0] | c0 - X.X.c2 | - * | acc[1] | c2 - X.X.c4 | - * | acc[2] | c4 | - **/ - - if (i != (num_accumulators() - 1)) { - result.accumulators.emplace_back( - (lookup[ColumnIdx::C3][2 * i] - (lookup[ColumnIdx::C3][2 * (i + 1)] * scaling_factor)).witness_index); - } else { - result.accumulators.emplace_back(lookup[ColumnIdx::C3][2 * (num_accumulators() - 1)].witness_index); - } - } - - result.witness_index = lookup[ColumnIdx::C3][0].get_witness_index(); - result.witness_status = WitnessStatus::OK; - return result; -} - -template class uint; -template class uint; -template class uint; -template class uint; -template class uint; -template class uint; -template class uint; -template class uint; - -} // namespace bb::stdlib diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.hpp index 7c68f3de436a..699059fbe574 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.hpp @@ -50,19 +50,6 @@ template class uint { uint operator/(const uint& other) const; uint operator%(const uint& other) const; - uint operator&(const uint& other) const; - uint operator^(const uint& other) const; - uint operator|(const uint& other) const; - uint operator~() const; - - uint operator>>(const size_t shift) const; - uint operator<<(const size_t shift) const; - - uint ror(const size_t target_rotation) const; - uint rol(const size_t target_rotation) const; - uint ror(const uint256_t target_rotation) const { return ror(static_cast(target_rotation.data[0])); } - uint rol(const uint256_t target_rotation) const { return rol(static_cast(target_rotation.data[0])); } - bool_t operator>(const uint& other) const; bool_t operator<(const uint& other) const; bool_t operator>=(const uint& other) const; @@ -97,33 +84,6 @@ template class uint { return *this; } - uint operator&=(const uint& other) - { - *this = operator&(other); - return *this; - } - uint operator^=(const uint& other) - { - *this = operator^(other); - return *this; - } - uint operator|=(const uint& other) - { - *this = operator|(other); - return *this; - } - - uint operator>>=(const size_t shift) - { - *this = operator>>(shift); - return *this; - } - uint operator<<=(const size_t shift) - { - *this = operator<<(shift); - return *this; - } - uint normalize() const; uint256_t get_value() const; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp index 6b4d591035e8..f0c3bf764ccd 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.test.cpp @@ -373,190 +373,6 @@ template class stdlib_uint : public testing::Test { EXPECT_EQ(result, true); } - static void test_xor_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = c_expected ^ a_expected; - } - - Builder builder = Builder(); - - witness_ct first_input(&builder, static_cast(0x10000000a3b10422)); - witness_ct second_input(&builder, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c ^ a; - } - uint_native a_result = static_cast(a.get_value()); - - EXPECT_EQ(a_result, a_expected); - - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } - - static void test_xor_constants() - { - Builder builder = Builder(); - - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - - uint_ct const_a(&builder, static_cast(0x10000000a3b10422)); - uint_ct const_b(&builder, static_cast(0xfafab007eac21343)); - uint_ct c = const_a ^ const_b; - c.get_witness_index(); - - EXPECT_EQ(c.get_additive_constant(), uint256_t(c_expected)); - } - - static void test_xor_more_constants() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < 1; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = (a_expected + b_expected) ^ - (static_cast(0x10000000a3b10422) ^ static_cast(0xfafab007eac21343)); - } - - Builder builder = Builder(); - - witness_ct first_input(&builder, static_cast(0x10000000a3b10422)); - witness_ct second_input(&builder, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < 1; ++i) { - uint_ct const_a = static_cast(0x10000000a3b10422); - uint_ct const_b = static_cast(0xfafab007eac21343); - b = a; - a = c; - c = (a + b) ^ (const_a ^ const_b); - } - uint_native c_result = static_cast(c.get_value()); - EXPECT_EQ(c_result, c_expected); - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } - - static void test_and_constants() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected & b_expected; - for (size_t i = 0; i < 1; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = (~a_expected & static_cast(0x10000000a3b10422)) + - (b_expected & static_cast(0xfafab007eac21343)); - // c_expected = (a_expected + b_expected) & (static_cast(0x10000000a3b10422) & - // static_cast(0xfafab007eac21343)); - } - - Builder builder = Builder(); - - witness_ct first_input(&builder, static_cast(0x10000000a3b10422)); - witness_ct second_input(&builder, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a & b; - for (size_t i = 0; i < 1; ++i) { - uint_ct const_a = static_cast(0x10000000a3b10422); - uint_ct const_b = static_cast(0xfafab007eac21343); - b = a; - a = c; - c = (~a & const_a) + (b & const_b); - } - uint_native c_result = static_cast(c.get_value()); - EXPECT_EQ(c_result, c_expected); - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } - - static void test_and_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected + b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = c_expected & a_expected; - } - - Builder builder = Builder(); - - witness_ct first_input(&builder, static_cast(0x10000000a3b10422)); - witness_ct second_input(&builder, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a + b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c & a; - } - uint_native a_result = static_cast(a.get_value()); - EXPECT_EQ(a_result, a_expected); - - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } - - static void test_or_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = c_expected | a_expected; - } - - Builder builder = Builder(); - - witness_ct first_input(&builder, static_cast(0x10000000a3b10422)); - witness_ct second_input(&builder, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c | a; - } - uint_native a_result = static_cast(a.get_value()); - EXPECT_EQ(a_result, a_expected); - - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } - static void test_gt_special() { const auto run_test = [](bool lhs_constant, bool rhs_constant, int type = 0) { @@ -624,192 +440,6 @@ template class stdlib_uint : public testing::Test { run_test(true, true, 2); } - static uint_native rotate(uint_native value, size_t rotation) - { - return rotation ? static_cast(value >> rotation) + - static_cast(value << (uint_native_width - rotation)) - : value; - } - - static void test_ror_special() - { - uint_native a_expected = static_cast(0x10000000a3b10422); - uint_native b_expected = static_cast(0xfafab007eac21343); - uint_native c_expected = a_expected ^ b_expected; - for (size_t i = 0; i < uint_native_width; ++i) { - b_expected = a_expected; - a_expected = c_expected; - c_expected = a_expected + b_expected; - a_expected = rotate(c_expected, i % 31) + rotate(a_expected, (i + 1) % 31); - } - - Builder builder = Builder(); - - witness_ct first_input(&builder, static_cast(0x10000000a3b10422)); - witness_ct second_input(&builder, static_cast(0xfafab007eac21343)); - - uint_ct a = first_input; - uint_ct b = second_input; - uint_ct c = a ^ b; - for (size_t i = 0; i < uint_native_width; ++i) { - b = a; - a = c; - c = a + b; - a = c.ror(static_cast(i % 31)) + a.ror(static_cast((i + 1) % 31)); - } - uint_native a_result = static_cast(a.get_value()); - EXPECT_EQ(a_result, a_expected); - - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } - - /** - * @brief If uint_native_width == 32, test part of SHA256. Otherwise, do something similar. - * - * @details Notes that the static casts have to be there becuase of -Wc++11-narrowing flag. - * - * StandardPLONK: 210363 gates - */ - static void test_hash_rounds() - { - std::vector k_constants(64); - std::vector round_values(8); - if (uint_native_width == 32) { - k_constants = { static_cast(0x428a2f98), static_cast(0x71374491), - static_cast(0xb5c0fbcf), static_cast(0xe9b5dba5), - static_cast(0x3956c25b), static_cast(0x59f111f1), - static_cast(0x923f82a4), static_cast(0xab1c5ed5), - static_cast(0xd807aa98), static_cast(0x12835b01), - static_cast(0x243185be), static_cast(0x550c7dc3), - static_cast(0x72be5d74), static_cast(0x80deb1fe), - static_cast(0x9bdc06a7), static_cast(0xc19bf174), - static_cast(0xe49b69c1), static_cast(0xefbe4786), - static_cast(0x0fc19dc6), static_cast(0x240ca1cc), - static_cast(0x2de92c6f), static_cast(0x4a7484aa), - static_cast(0x5cb0a9dc), static_cast(0x76f988da), - static_cast(0x983e5152), static_cast(0xa831c66d), - static_cast(0xb00327c8), static_cast(0xbf597fc7), - static_cast(0xc6e00bf3), static_cast(0xd5a79147), - static_cast(0x06ca6351), static_cast(0x14292967), - static_cast(0x27b70a85), static_cast(0x2e1b2138), - static_cast(0x4d2c6dfc), static_cast(0x53380d13), - static_cast(0x650a7354), static_cast(0x766a0abb), - static_cast(0x81c2c92e), static_cast(0x92722c85), - static_cast(0xa2bfe8a1), static_cast(0xa81a664b), - static_cast(0xc24b8b70), static_cast(0xc76c51a3), - static_cast(0xd192e819), static_cast(0xd6990624), - static_cast(0xf40e3585), static_cast(0x106aa070), - static_cast(0x19a4c116), static_cast(0x1e376c08), - static_cast(0x2748774c), static_cast(0x34b0bcb5), - static_cast(0x391c0cb3), static_cast(0x4ed8aa4a), - static_cast(0x5b9cca4f), static_cast(0x682e6ff3), - static_cast(0x748f82ee), static_cast(0x78a5636f), - static_cast(0x84c87814), static_cast(0x8cc70208), - static_cast(0x90befffa), static_cast(0xa4506ceb), - static_cast(0xbef9a3f7), static_cast(0xc67178f2) }; - - round_values = { static_cast(0x01020304), static_cast(0x0a0b0c0d), - static_cast(0x1a2b3e4d), static_cast(0x03951bd3), - static_cast(0x0e0fa3fe), static_cast(0x01000000), - static_cast(0x0f0eeea1), static_cast(0x12345678) }; - } else { - k_constants = get_several_random(64); - round_values = get_several_random(8); - }; - - std::vector w_alt = get_several_random(64); - - uint_native a_alt = round_values[0]; - uint_native b_alt = round_values[1]; - uint_native c_alt = round_values[2]; - uint_native d_alt = round_values[3]; - uint_native e_alt = round_values[4]; - uint_native f_alt = round_values[5]; - uint_native g_alt = round_values[6]; - uint_native h_alt = round_values[7]; - for (size_t i = 0; i < 64; ++i) { - uint_native S1_alt = rotate(e_alt, 7 % uint_native_width) ^ rotate(e_alt, 11 % uint_native_width) ^ - rotate(e_alt, 25 % uint_native_width); - uint_native ch_alt = (e_alt & f_alt) ^ ((~e_alt) & g_alt); - uint_native temp1_alt = h_alt + S1_alt + ch_alt + k_constants[i % 64] + w_alt[i]; - - uint_native S0_alt = rotate(a_alt, 2 % uint_native_width) ^ rotate(a_alt, 13 % uint_native_width) ^ - rotate(a_alt, 22 % uint_native_width); - uint_native maj_alt = (a_alt & b_alt) ^ (a_alt & c_alt) ^ (b_alt & c_alt); - uint_native temp2_alt = S0_alt + maj_alt; - - h_alt = g_alt; - g_alt = f_alt; - f_alt = e_alt; - e_alt = d_alt + temp1_alt; - d_alt = c_alt; - c_alt = b_alt; - b_alt = a_alt; - a_alt = temp1_alt + temp2_alt; - } - Builder builder = Builder(); - - std::vector w; - std::vector k; - for (size_t i = 0; i < 64; ++i) { - w.emplace_back(uint_ct(witness_ct(&builder, w_alt[i]))); - k.emplace_back(uint_ct(&builder, k_constants[i % 64])); - } - uint_ct a = witness_ct(&builder, round_values[0]); - uint_ct b = witness_ct(&builder, round_values[1]); - uint_ct c = witness_ct(&builder, round_values[2]); - uint_ct d = witness_ct(&builder, round_values[3]); - uint_ct e = witness_ct(&builder, round_values[4]); - uint_ct f = witness_ct(&builder, round_values[5]); - uint_ct g = witness_ct(&builder, round_values[6]); - uint_ct h = witness_ct(&builder, round_values[7]); - for (size_t i = 0; i < 64; ++i) { - uint_ct S1 = - e.ror(7U % uint_native_width) ^ e.ror(11U % uint_native_width) ^ e.ror(25U % uint_native_width); - uint_ct ch = (e & f) + ((~e) & g); - uint_ct temp1 = h + S1 + ch + k[i] + w[i]; - - uint_ct S0 = - a.ror(2U % uint_native_width) ^ a.ror(13U % uint_native_width) ^ a.ror(22U % uint_native_width); - uint_ct T0 = (b & c); - uint_ct T1 = (b - T0) + (c - T0); - uint_ct T2 = a & T1; - uint_ct maj = T2 + T0; - uint_ct temp2 = S0 + maj; - - h = g; - g = f; - f = e; - e = d + temp1; - d = c; - c = b; - b = a; - a = temp1 + temp2; - } - - uint_native a_result = static_cast(a.get_value()); // PROBLEM - uint_native b_result = static_cast(b.get_value()); - uint_native c_result = static_cast(c.get_value()); - uint_native d_result = static_cast(d.get_value()); - uint_native e_result = static_cast(e.get_value()); - uint_native f_result = static_cast(f.get_value()); - uint_native g_result = static_cast(g.get_value()); - uint_native h_result = static_cast(h.get_value()); - - EXPECT_EQ(a_result, a_alt); - EXPECT_EQ(b_result, b_alt); - EXPECT_EQ(c_result, c_alt); - EXPECT_EQ(d_result, d_alt); - EXPECT_EQ(e_result, e_alt); - EXPECT_EQ(f_result, f_alt); - EXPECT_EQ(g_result, g_alt); - EXPECT_EQ(h_result, h_alt); - - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } - // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO /** @@ -1174,172 +804,6 @@ template class stdlib_uint : public testing::Test { EXPECT_EQ(result, false); } - static void check_accumulator_correctness(Builder& builder, const uint_ct& result_uint, uint_native expected_result) - { - uint_native val = expected_result; - const auto accumulators = result_uint.get_accumulators(); - for (size_t i = 0; i < uint_ct::num_accumulators(); ++i) { - const uint64_t result = uint256_t(builder.get_variable(accumulators[i])).data[0]; - const uint64_t expected = val & ((1ULL << uint_ct::bits_per_limb) - 1); - val = val >> uint_ct::bits_per_limb; - EXPECT_EQ(result, expected); - } - } - - static void test_and() - { - Builder builder = Builder(); - - const auto and_integers = [&builder](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native expected = (a_val + const_a) & (b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct b = rhs_constant ? uint_ct(&builder, b_val) : witness_ct(&builder, b_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct b_shift = uint_ct(&builder, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c & d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - EXPECT_EQ(result, expected); - - // Check accumulators constructed from lookup tables. This needs to be checked only if - // either of the inputs in a witness. - if (!lhs_constant || !rhs_constant) { - check_accumulator_correctness(builder, e, expected); - } - }; - - and_integers(false, false); - and_integers(false, true); - and_integers(true, false); - and_integers(true, true); - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - - static void test_xor() - { - Builder builder = Builder(); - - const auto xor_integers = [&builder](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native expected = (a_val + const_a) ^ (b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct b = rhs_constant ? uint_ct(&builder, b_val) : witness_ct(&builder, b_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct b_shift = uint_ct(&builder, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c ^ d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - EXPECT_EQ(result, expected); - - // Check accumulators constructed from lookup tables. This needs to be checked only if - // either of the inputs in a witness. - if (!lhs_constant || !rhs_constant) { - check_accumulator_correctness(builder, e, expected); - } - }; - - xor_integers(false, false); - xor_integers(false, true); - xor_integers(true, false); - xor_integers(true, true); - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - - static void test_or() - { - Builder builder = Builder(); - - const auto or_integers = [&builder](bool lhs_constant = false, bool rhs_constant = false) { - uint_native a_val = get_random(); - uint_native b_val = get_random(); - uint_native const_a = get_random(); - uint_native const_b = get_random(); - uint_native expected = (a_val + const_a) | (b_val + const_b); - uint_ct a = lhs_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct b = rhs_constant ? uint_ct(&builder, b_val) : witness_ct(&builder, b_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct b_shift = uint_ct(&builder, const_b); - uint_ct c = a + a_shift; - uint_ct d = b + b_shift; - uint_ct e = c | d; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - EXPECT_EQ(result, expected); - - // Check accumulators constructed from lookup tables. This needs to be checked only if - // either of the inputs in a witness. - if (!lhs_constant || !rhs_constant) { - check_accumulator_correctness(builder, e, expected); - } - }; - - or_integers(false, false); - or_integers(false, false); - or_integers(false, false); - or_integers(false, false); - or_integers(false, false); - or_integers(false, true); - or_integers(true, false); - or_integers(true, true); - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - - static void test_not() - { - Builder builder = Builder(); - - const auto not_integers = [&builder](bool lhs_constant = false, bool = false) { - uint_native a_val = get_random(); - uint_native const_a = get_random(); - uint_native expected = ~(a_val + const_a); - uint_ct a = lhs_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct c = a + a_shift; - uint_ct e = ~c; - e = e.normalize(); - - uint_native result = uint_native(e.get_value()); - - EXPECT_EQ(result, expected); - }; - - not_integers(false, false); - not_integers(false, true); - not_integers(true, false); - not_integers(true, true); - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - static void test_gt() { Builder builder = Builder(); @@ -1611,126 +1075,6 @@ template class stdlib_uint : public testing::Test { EXPECT_EQ(proof_result, true); } - static void test_right_shift() - { - Builder builder = Builder(); - - const auto shift_integer = [&builder](const bool is_constant, const uint_native shift) { - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast(a_val + const_a) >> shift; - uint_ct a = is_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct c = a + a_shift; - uint_ct d = c >> shift; - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - shift_integer(false, i); - shift_integer(true, i); - } - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - - static void test_left_shift() - { - Builder builder = Builder(); - - const auto shift_integer = [&builder](const bool is_constant, const uint_native shift) { - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast((a_val + const_a) << shift); - uint_ct a = is_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct c = a + a_shift; - uint_ct d = c << shift; - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - shift_integer(true, i); - shift_integer(false, i); - } - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - - static void test_ror() - { - Builder builder = Builder(); - - const auto ror_integer = [&builder](const bool is_constant, const uint_native rotation) { - const auto ror = [](const uint_native in, const uint_native rval) { - return rval ? (in >> rval) | (in << (uint_native_width - rval)) : in; - }; - - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast(ror(static_cast(const_a + a_val), rotation)); - uint_ct a = is_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct c = a + a_shift; - uint_ct d = c.ror(rotation); - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - ror_integer(true, i); - ror_integer(false, i); - } - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - - static void test_rol() - { - Builder builder = Builder(); - - const auto rol_integer = [&builder](const bool is_constant, const uint_native rotation) { - const auto rol = [](const uint_native in, const uint_native rval) { - return rval ? (in << rval) | (in >> (uint_native_width - rval)) : in; - }; - - uint_native const_a = get_random(); - uint_native a_val = get_random(); - uint_native expected = static_cast(rol(static_cast(const_a + a_val), rotation)); - uint_ct a = is_constant ? uint_ct(&builder, a_val) : witness_ct(&builder, a_val); - uint_ct a_shift = uint_ct(&builder, const_a); - uint_ct c = a + a_shift; - uint_ct d = c.rol(rotation); - uint_native result = uint_native(d.get_value()); - - EXPECT_EQ(result, expected); - }; - - for (uint_native i = 0; i < uint_native_width; ++i) { - rol_integer(true, i); - rol_integer(false, i); - } - - printf("builder gates = %zu\n", builder.get_estimated_num_finalized_gates()); - - bool proof_result = CircuitChecker::check(builder); - EXPECT_EQ(proof_result, true); - } - /** * @brief Test the function uint_ct::at used to extract bits. */ @@ -1809,42 +1153,10 @@ TYPED_TEST(stdlib_uint, test_mul_big) { TestFixture::test_mul_big(); } -TYPED_TEST(stdlib_uint, test_xor_special) -{ - TestFixture::test_xor_special(); -} -TYPED_TEST(stdlib_uint, test_xor_constants) -{ - TestFixture::test_xor_constants(); -} -TYPED_TEST(stdlib_uint, test_xor_more_constants) -{ - TestFixture::test_xor_more_constants(); -} -TYPED_TEST(stdlib_uint, test_and_constants) -{ - TestFixture::test_and_constants(); -} -TYPED_TEST(stdlib_uint, test_and_special) -{ - TestFixture::test_and_special(); -} -TYPED_TEST(stdlib_uint, test_or_special) -{ - TestFixture::test_or_special(); -} TYPED_TEST(stdlib_uint, test_gt_special) { TestFixture::test_gt_special(); } -TYPED_TEST(stdlib_uint, test_ror_special) -{ - TestFixture::test_ror_special(); -} -TYPED_TEST(stdlib_uint, test_hash_rounds) -{ - TestFixture::test_hash_rounds(); -} // BELOW HERE ARE TESTS FORMERLY MARKED AS TURBO TYPED_TEST(stdlib_uint, test_add) { @@ -1878,22 +1190,6 @@ TYPED_TEST(stdlib_uint, div_remainder_constraint) { TestFixture::div_remainder_constraint(); } -TYPED_TEST(stdlib_uint, test_and) -{ - TestFixture::test_and(); -} -TYPED_TEST(stdlib_uint, test_xor) -{ - TestFixture::test_xor(); -} -TYPED_TEST(stdlib_uint, test_or) -{ - TestFixture::test_or(); -} -TYPED_TEST(stdlib_uint, test_not) -{ - TestFixture::test_not(); -} TYPED_TEST(stdlib_uint, test_gt) { TestFixture::test_gt(); @@ -1922,22 +1218,6 @@ TYPED_TEST(stdlib_uint, test_logical_not) { TestFixture::test_logical_not(); } -TYPED_TEST(stdlib_uint, test_right_shift) -{ - TestFixture::test_right_shift(); -} -TYPED_TEST(stdlib_uint, test_left_shift) -{ - TestFixture::test_left_shift(); -} -TYPED_TEST(stdlib_uint, test_ror) -{ - TestFixture::test_ror(); -} -TYPED_TEST(stdlib_uint, test_rol) -{ - TestFixture::test_rol(); -} TYPED_TEST(stdlib_uint, test_at) { TestFixture::test_at(); From da4914f7e87df029043b1be08126023c4dac6b81 Mon Sep 17 00:00:00 2001 From: suyash67 Date: Fri, 25 Jul 2025 07:47:03 +0000 Subject: [PATCH 2/2] remove ops from fuzzer. --- .../stdlib/primitives/uint/uint.fuzzer.hpp | 496 +----------------- 1 file changed, 7 insertions(+), 489 deletions(-) diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.fuzzer.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.fuzzer.hpp index fd3e3fbee49e..859bd7b35ee2 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.fuzzer.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/uint/uint.fuzzer.hpp @@ -59,26 +59,7 @@ template class UintFuzzBase { */ class Instruction { public: - enum OPCODE { - CONSTANT, - ADD, - SUBTRACT, - MULTIPLY, - DIVIDE, - MODULO, - AND, - OR, - XOR, - GET_BIT, - SHL, - SHR, - ROL, - ROR, - NOT, - SET, - RANDOMSEED, - _LAST - }; + enum OPCODE { CONSTANT, ADD, SUBTRACT, MULTIPLY, DIVIDE, MODULO, GET_BIT, SET, RANDOMSEED, _LAST }; struct TwoArgs { uint8_t in; @@ -119,7 +100,6 @@ template class UintFuzzBase { // Choose which instruction we are going to generate OPCODE instruction_opcode = static_cast(rng.next() % (OPCODE::_LAST)); uint8_t in1, in2, out; - uint8_t bit; // Depending on instruction switch (instruction_opcode) { case OPCODE::CONSTANT: @@ -130,9 +110,6 @@ template class UintFuzzBase { case OPCODE::MULTIPLY: case OPCODE::DIVIDE: case OPCODE::MODULO: - case OPCODE::AND: - case OPCODE::OR: - case OPCODE::XOR: // For two-input-one-output instructions we just randomly pick each argument and generate an instruction // accordingly in1 = static_cast(rng.next() & 0xff); @@ -141,15 +118,6 @@ template class UintFuzzBase { return { .id = instruction_opcode, .arguments.threeArgs = { .in1 = in1, .in2 = in2, .out = out } }; break; case OPCODE::GET_BIT: - case OPCODE::SHL: - case OPCODE::SHR: - case OPCODE::ROL: - case OPCODE::ROR: - in1 = static_cast(rng.next() & 0xff); - out = static_cast(rng.next() & 0xff); - bit = static_cast(rng.next() & 0xff); - return { .id = instruction_opcode, .arguments.bitArgs = { .in = in1, .out = out, .bit = bit } }; - case OPCODE::NOT: case OPCODE::SET: in1 = static_cast(rng.next() & 0xff); out = static_cast(rng.next() & 0xff); @@ -196,23 +164,7 @@ template class UintFuzzBase { case OPCODE::MULTIPLY: case OPCODE::DIVIDE: case OPCODE::MODULO: - case OPCODE::AND: - case OPCODE::OR: - case OPCODE::XOR: - // Randomly sample each of the arguments with 50% probability - PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in1) - PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.in2) - PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.threeArgs.out) - break; case OPCODE::GET_BIT: - case OPCODE::SHL: - case OPCODE::SHR: - case OPCODE::ROL: - case OPCODE::ROR: - PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.bitArgs.in) - PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.bitArgs.out) - PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.bitArgs.bit) - case OPCODE::NOT: case OPCODE::SET: PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.in) PUT_RANDOM_BYTE_IF_LUCKY(instruction.arguments.twoArgs.out) @@ -238,15 +190,7 @@ template class UintFuzzBase { static constexpr size_t MULTIPLY = 3; static constexpr size_t DIVIDE = 3; static constexpr size_t MODULO = 3; - static constexpr size_t AND = 3; - static constexpr size_t OR = 3; - static constexpr size_t XOR = 3; static constexpr size_t GET_BIT = 10; - static constexpr size_t SHL = 10; - static constexpr size_t SHR = 10; - static constexpr size_t ROL = 10; - static constexpr size_t ROR = 10; - static constexpr size_t NOT = 2; static constexpr size_t SET = 2; static constexpr size_t RANDOMSEED = sizeof(uint32_t); }; @@ -271,18 +215,15 @@ template class UintFuzzBase { } if constexpr (opcode == Instruction::OPCODE::ADD || opcode == Instruction::OPCODE::SUBTRACT || opcode == Instruction::OPCODE::MULTIPLY || opcode == Instruction::OPCODE::DIVIDE || - opcode == Instruction::OPCODE::MODULO || opcode == Instruction::OPCODE::AND || - opcode == Instruction::OPCODE::OR || opcode == Instruction::OPCODE::XOR) { + opcode == Instruction::OPCODE::MODULO) { return { .id = static_cast(opcode), .arguments.threeArgs = { .in1 = *Data, .in2 = *(Data + 1), .out = *(Data + 2) } }; } - if constexpr (opcode == Instruction::OPCODE::GET_BIT || opcode == Instruction::OPCODE::SHL || - opcode == Instruction::OPCODE::SHR || opcode == Instruction::OPCODE::ROL || - opcode == Instruction::OPCODE::ROR) { + if constexpr (opcode == Instruction::OPCODE::GET_BIT) { return Instruction{ .id = static_cast(opcode), .arguments.bitArgs = { .in = *Data, .out = *(Data + 1), .bit = *(Data + 2) } }; } - if constexpr (opcode == Instruction::OPCODE::NOT || opcode == Instruction::OPCODE::SET) { + if constexpr (opcode == Instruction::OPCODE::SET) { return { .id = static_cast(opcode), .arguments.twoArgs = { .in = *Data, .out = *(Data + 1) } }; } @@ -311,27 +252,19 @@ template class UintFuzzBase { instruction_opcode == Instruction::OPCODE::SUBTRACT || instruction_opcode == Instruction::OPCODE::MULTIPLY || instruction_opcode == Instruction::OPCODE::DIVIDE || - instruction_opcode == Instruction::OPCODE::MODULO || - instruction_opcode == Instruction::OPCODE::AND || - instruction_opcode == Instruction::OPCODE::OR || - instruction_opcode == Instruction::OPCODE::XOR) { + instruction_opcode == Instruction::OPCODE::MODULO) { *Data = instruction.id; *(Data + 1) = instruction.arguments.threeArgs.in1; *(Data + 2) = instruction.arguments.threeArgs.in2; *(Data + 3) = instruction.arguments.threeArgs.out; } - if constexpr (instruction_opcode == Instruction::OPCODE::GET_BIT || - instruction_opcode == Instruction::OPCODE::SHL || - instruction_opcode == Instruction::OPCODE::SHR || - instruction_opcode == Instruction::OPCODE::ROL || - instruction_opcode == Instruction::OPCODE::ROR) { + if constexpr (instruction_opcode == Instruction::OPCODE::GET_BIT) { *Data = instruction.id; *(Data + 1) = instruction.arguments.bitArgs.in; *(Data + 2) = instruction.arguments.bitArgs.out; *(Data + 3) = instruction.arguments.bitArgs.bit; } - if constexpr (instruction_opcode == Instruction::OPCODE::NOT || - instruction_opcode == Instruction::OPCODE::SET) { + if constexpr (instruction_opcode == Instruction::OPCODE::SET) { *Data = instruction.id; *(Data + 1) = instruction.arguments.twoArgs.in; *(Data + 2) = instruction.arguments.twoArgs.out; @@ -668,99 +601,6 @@ template class UintFuzzBase { abort(); } } - ExecutionHandler operator&(const ExecutionHandler& other) const - { - const Reference ref_result(this->ref.v8 & other.ref.v8, - this->ref.v16 & other.ref.v16, - this->ref.v32 & other.ref.v32, - this->ref.v64 & other.ref.v64); - - switch (VarianceRNG.next() % 2) { - case 0: - /* & operator */ - return ExecutionHandler(ref_result, - Uint(this->uint.v8 & other.uint.v8, - this->uint.v16 & other.uint.v16, - this->uint.v32 & other.uint.v32, - this->uint.v64 & other.uint.v64)); - case 1: - /* &= operator */ - { - Uint u = uint; - - u.v8 &= other.uint.v8; - u.v16 &= other.uint.v16; - u.v32 &= other.uint.v32; - u.v64 &= other.uint.v64; - - return ExecutionHandler(ref_result, u); - } - default: - abort(); - } - } - ExecutionHandler operator|(const ExecutionHandler& other) const - { - const Reference ref_result(this->ref.v8 | other.ref.v8, - this->ref.v16 | other.ref.v16, - this->ref.v32 | other.ref.v32, - this->ref.v64 | other.ref.v64); - - switch (VarianceRNG.next() % 2) { - case 0: - /* | operator */ - return ExecutionHandler(ref_result, - Uint(this->uint.v8 | other.uint.v8, - this->uint.v16 | other.uint.v16, - this->uint.v32 | other.uint.v32, - this->uint.v64 | other.uint.v64)); - case 1: - /* |= operator */ - { - Uint u = uint; - - u.v8 |= other.uint.v8; - u.v16 |= other.uint.v16; - u.v32 |= other.uint.v32; - u.v64 |= other.uint.v64; - - return ExecutionHandler(ref_result, u); - } - default: - abort(); - } - } - ExecutionHandler operator^(const ExecutionHandler& other) const - { - const Reference ref_result(this->ref.v8 ^ other.ref.v8, - this->ref.v16 ^ other.ref.v16, - this->ref.v32 ^ other.ref.v32, - this->ref.v64 ^ other.ref.v64); - - switch (VarianceRNG.next() % 2) { - case 0: - /* ^ operator */ - return ExecutionHandler(ref_result, - Uint(this->uint.v8 ^ other.uint.v8, - this->uint.v16 ^ other.uint.v16, - this->uint.v32 ^ other.uint.v32, - this->uint.v64 ^ other.uint.v64)); - case 1: - /* ^= operator */ - { - Uint u = uint; - - u.v8 ^= other.uint.v8; - u.v16 ^= other.uint.v16; - u.v32 ^= other.uint.v32; - u.v64 ^= other.uint.v64; - - return ExecutionHandler(ref_result, u); - } - default: - abort(); - } - } ExecutionHandler get_bit(Builder* builder, const size_t bit) const { return ExecutionHandler(Reference(this->get_bit(this->ref.v8, bit), @@ -772,93 +612,6 @@ template class UintFuzzBase { this->get_bit(builder, this->uint.v32, bit), this->get_bit(builder, this->uint.v64, bit))); } - ExecutionHandler shl(const size_t bits) const - { - const Reference ref_result(shl(this->ref.v8, bits), - shl(this->ref.v16, bits), - shl(this->ref.v32, bits), - shl(this->ref.v64, bits)); - - switch (VarianceRNG.next() % 2) { - case 0: - /* << operator */ - return ExecutionHandler( - ref_result, - Uint( - this->uint.v8 << bits, this->uint.v16 << bits, this->uint.v32 << bits, this->uint.v64 << bits)); - case 1: - /* <<= operator */ - { - Uint u = uint; - - u.v8 <<= bits; - u.v16 <<= bits; - u.v32 <<= bits; - u.v64 <<= bits; - - return ExecutionHandler(ref_result, u); - } - default: - abort(); - } - } - ExecutionHandler shr(const size_t bits) const - { - const Reference ref_result(shr(this->ref.v8, bits), - shr(this->ref.v16, bits), - shr(this->ref.v32, bits), - shr(this->ref.v64, bits)); - - switch (VarianceRNG.next() % 2) { - case 0: - /* >> operator */ - return ExecutionHandler( - ref_result, - Uint( - this->uint.v8 >> bits, this->uint.v16 >> bits, this->uint.v32 >> bits, this->uint.v64 >> bits)); - case 1: - /* >>= operator */ - { - Uint u = uint; - - u.v8 >>= bits; - u.v16 >>= bits; - u.v32 >>= bits; - u.v64 >>= bits; - - return ExecutionHandler(ref_result, u); - } - default: - abort(); - } - } - ExecutionHandler rol(const size_t bits) const - { - return ExecutionHandler(Reference(std::rotl(this->ref.v8, static_cast(bits % 8)), - std::rotl(this->ref.v16, static_cast(bits % 16)), - std::rotl(this->ref.v32, static_cast(bits % 32)), - std::rotl(this->ref.v64, static_cast(bits % 64))), - Uint(this->uint.v8.rol(bits), - this->uint.v16.rol(bits), - this->uint.v32.rol(bits), - this->uint.v64.rol(bits))); - } - ExecutionHandler ror(const size_t bits) const - { - return ExecutionHandler(Reference(std::rotr(this->ref.v8, static_cast(bits % 8)), - std::rotr(this->ref.v16, static_cast(bits % 16)), - std::rotr(this->ref.v32, static_cast(bits % 32)), - std::rotr(this->ref.v64, static_cast(bits % 64))), - Uint(this->uint.v8.ror(bits), - this->uint.v16.ror(bits), - this->uint.v32.ror(bits), - this->uint.v64.ror(bits))); - } - ExecutionHandler not_() const - { - return ExecutionHandler(Reference(~this->ref.v8, ~this->ref.v16, ~this->ref.v32, ~this->ref.v64), - Uint(~this->uint.v8, ~this->uint.v16, ~this->uint.v32, ~this->uint.v64)); - } /* Explicit re-instantiation using the various constructors */ ExecutionHandler set(Builder* builder) const { @@ -1074,96 +827,6 @@ template class UintFuzzBase { } return 0; }; - /** - * @brief Execute the and operator instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_AND(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.threeArgs.in1 % stack.size(); - size_t second_index = instruction.arguments.threeArgs.in2 % stack.size(); - size_t output_index = instruction.arguments.threeArgs.out; - - ExecutionHandler result; - result = stack[first_index] & stack[second_index]; - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; - /** - * @brief Execute the or operator instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_OR(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.threeArgs.in1 % stack.size(); - size_t second_index = instruction.arguments.threeArgs.in2 % stack.size(); - size_t output_index = instruction.arguments.threeArgs.out; - - ExecutionHandler result; - result = stack[first_index] | stack[second_index]; - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; - /** - * @brief Execute the xor operator instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_XOR(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.threeArgs.in1 % stack.size(); - size_t second_index = instruction.arguments.threeArgs.in2 % stack.size(); - size_t output_index = instruction.arguments.threeArgs.out; - - ExecutionHandler result; - result = stack[first_index] ^ stack[second_index]; - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; /** * @brief Execute the GET_BIT instruction * @@ -1192,151 +855,6 @@ template class UintFuzzBase { } return 0; }; - /** - * @brief Execute the left-shift operator instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_SHL(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.bitArgs.in % stack.size(); - size_t output_index = instruction.arguments.bitArgs.out; - const uint8_t bit = instruction.arguments.bitArgs.bit; - ExecutionHandler result; - result = stack[first_index].shl(bit); - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; - /** - * @brief Execute the right-shift operator instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_SHR(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.bitArgs.in % stack.size(); - size_t output_index = instruction.arguments.bitArgs.out; - const uint8_t bit = instruction.arguments.bitArgs.bit; - ExecutionHandler result; - result = stack[first_index].shr(bit); - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; - /** - * @brief Execute the left-rotate operator instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_ROL(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.bitArgs.in % stack.size(); - size_t output_index = instruction.arguments.bitArgs.out; - const uint8_t bit = instruction.arguments.bitArgs.bit; - ExecutionHandler result; - result = stack[first_index].rol(bit); - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; - /** - * @brief Execute the right-rotate operator instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_ROR(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.bitArgs.in % stack.size(); - size_t output_index = instruction.arguments.bitArgs.out; - const uint8_t bit = instruction.arguments.bitArgs.bit; - ExecutionHandler result; - result = stack[first_index].ror(bit); - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; - /** - * @brief Execute the NOT instruction - * - * @param builder - * @param stack - * @param instruction - * @return if everything is ok, 1 if we should stop execution, since an expected error was encountered - */ - static inline size_t execute_NOT(Builder* builder, - std::vector& stack, - Instruction& instruction) - { - (void)builder; - if (stack.size() == 0) { - return 1; - } - size_t first_index = instruction.arguments.twoArgs.in % stack.size(); - size_t output_index = instruction.arguments.twoArgs.out; - - ExecutionHandler result; - result = stack[first_index].not_(); - // If the output index is larger than the number of elements in stack, append - if (output_index >= stack.size()) { - stack.push_back(result); - } else { - stack[output_index] = result; - } - return 0; - }; /** * @brief Execute the SET instruction *