diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp index 7643afe8ad6..2fc3572cec3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp @@ -241,12 +241,6 @@ template class bigfield { bigfield conditional_negate(const bool_t& predicate) const; bigfield conditional_select(const bigfield& other, const bool_t& predicate) const; - static bigfield conditional_assign(const bool_t& predicate, const bigfield& lhs, const bigfield& rhs) - { - return rhs.conditional_select(lhs, predicate); - } - - bool_t operator==(const bigfield& other) const; void assert_is_in_field() const; void assert_less_than(const uint256_t upper_limit) const; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.test.cpp index 8ec46f817de..3aa7f6090ce 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.test.cpp @@ -841,45 +841,6 @@ template class stdlib_bigfield : public testing::Test { fq_ct ret = fq_ct::div_check_denominator_nonzero({}, a_ct); EXPECT_NE(ret.get_context(), nullptr); } - - static void test_assert_equal_not_equal() - { - auto builder = Builder(); - size_t num_repetitions = 10; - for (size_t i = 0; i < num_repetitions; ++i) { - fq inputs[4]{ fq::random_element(), fq::random_element(), fq::random_element(), fq::random_element() }; - - fq_ct a(witness_ct(&builder, fr(uint256_t(inputs[0]).slice(0, fq_ct::NUM_LIMB_BITS * 2))), - witness_ct(&builder, - fr(uint256_t(inputs[0]).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); - fq_ct b(witness_ct(&builder, fr(uint256_t(inputs[1]).slice(0, fq_ct::NUM_LIMB_BITS * 2))), - witness_ct(&builder, - fr(uint256_t(inputs[1]).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); - fq_ct c(witness_ct(&builder, fr(uint256_t(inputs[2]).slice(0, fq_ct::NUM_LIMB_BITS * 2))), - witness_ct(&builder, - fr(uint256_t(inputs[2]).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); - fq_ct d(witness_ct(&builder, fr(uint256_t(inputs[3]).slice(0, fq_ct::NUM_LIMB_BITS * 2))), - witness_ct(&builder, - fr(uint256_t(inputs[3]).slice(fq_ct::NUM_LIMB_BITS * 2, fq_ct::NUM_LIMB_BITS * 4)))); - - fq_ct two(witness_ct(&builder, fr(2)), - witness_ct(&builder, fr(0)), - witness_ct(&builder, fr(0)), - witness_ct(&builder, fr(0))); - fq_ct t0 = a + a; - fq_ct t1 = a * two; - - t0.assert_equal(t1); - t0.assert_is_not_equal(c); - t0.assert_is_not_equal(d); - stdlib::bool_t is_equal_a = t0 == t1; - stdlib::bool_t is_equal_b = t0 == c; - EXPECT_TRUE(is_equal_a.get_value()); - EXPECT_FALSE(is_equal_b.get_value()); - } - bool result = CircuitChecker::check(builder); - EXPECT_EQ(result, true); - } }; // Define types for which the above tests will be constructed. @@ -969,11 +930,6 @@ TYPED_TEST(stdlib_bigfield, division_context) TestFixture::test_division_context(); } -TYPED_TEST(stdlib_bigfield, assert_equal_not_equal) -{ - TestFixture::test_assert_equal_not_equal(); -} - // // This test was disabled before the refactor to use TYPED_TEST's/ // TEST(stdlib_bigfield, DISABLED_test_div_against_constants) // { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp index f8773225ad7..3e6fc79a994 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield_impl.hpp @@ -1562,57 +1562,6 @@ bigfield bigfield::conditional_select(const bigfield& ot return result; } -/** - * @brief Validate whether two bigfield elements are equal to each other - * @details To evaluate whether `(a == b)`, we use result boolean `r` to evaluate the following logic: - * (n.b all algebra involving bigfield elements is done in the bigfield) - * 1. If `r == 1` , `a - b == 0` - * 2. If `r == 0`, `a - b` posesses an inverse `I` i.e. `(a - b) * I - 1 == 0` - * We efficiently evaluate this logic by evaluating a single expression `(a - b)*X = Y` - * We use conditional assignment logic to define `X, Y` to be the following: - * If `r == 1` then `X = 1, Y = 0` - * If `r == 0` then `X = I, Y = 1` - * This allows us to evaluate `operator==` using only 1 bigfield multiplication operation. - * We can check the product equals 0 or 1 by directly evaluating the binary basis/prime basis limbs of Y. - * i.e. if `r == 1` then `(a - b)*X` should have 0 for all limb values - * if `r == 0` then `(a - b)*X` should have 1 in the least significant binary basis limb and 0 elsewhere - * @tparam Builder - * @tparam T - * @param other - * @return bool_t - */ -template bool_t bigfield::operator==(const bigfield& other) const -{ - Builder* ctx = context ? context : other.get_context(); - auto lhs = get_value() % modulus_u512; - auto rhs = other.get_value() % modulus_u512; - bool is_equal_raw = (lhs == rhs); - bool_t is_equal = witness_t(ctx, is_equal_raw); - - bigfield diff = (*this) - other; - - // TODO: get native values efficiently (i.e. if u512 value fits in a u256, subtract off modulus until u256 fits - // into finite field) - native diff_native = native((diff.get_value() % modulus_u512).lo); - native inverse_native = is_equal_raw ? 0 : diff_native.invert(); - - bigfield inverse = bigfield::from_witness(ctx, inverse_native); - - bigfield multiplicand = bigfield::conditional_assign(is_equal, one(), inverse); - - bigfield product = diff * multiplicand; - - field_t result = field_t::conditional_assign(is_equal, 0, 1); - - product.prime_basis_limb.assert_equal(result); - product.binary_basis_limbs[0].element.assert_equal(result); - product.binary_basis_limbs[1].element.assert_equal(0); - product.binary_basis_limbs[2].element.assert_equal(0); - product.binary_basis_limbs[3].element.assert_equal(0); - - return is_equal; -} - /** * REDUCTION CHECK * @@ -1798,7 +1747,6 @@ template void bigfield::assert_equal( std::cerr << "bigfield: calling assert equal on 2 CONSTANT bigfield elements...is this intended?" << std::endl; return; } else if (other.is_constant()) { - // TODO: wtf? // evaluate a strict equality - make sure *this is reduced first, or an honest prover // might not be able to satisfy these constraints. field_t t0 = (binary_basis_limbs[0].element - other.binary_basis_limbs[0].element); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp index 4cbe262e5d9..51cdb25c790 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.hpp @@ -21,8 +21,6 @@ namespace bb::stdlib { // ( ͡° ͜ʖ ͡°) template class element { public: - using bool_t = stdlib::bool_t; - struct secp256k1_wnaf { std::vector> wnaf; field_t positive_skew; @@ -40,23 +38,13 @@ template class element { element(const Fq& x, const Fq& y); element(const element& other); - element(element&& other) noexcept; + element(element&& other); static element from_witness(Builder* ctx, const typename NativeGroup::affine_element& input) { - element out; - if (input.is_point_at_infinity()) { - Fq x = Fq::from_witness(ctx, NativeGroup::affine_one.x); - Fq y = Fq::from_witness(ctx, NativeGroup::affine_one.y); - out.x = x; - out.y = y; - } else { - Fq x = Fq::from_witness(ctx, input.x); - Fq y = Fq::from_witness(ctx, input.y); - out.x = x; - out.y = y; - } - out.set_point_at_infinity(witness_t(ctx, input.is_point_at_infinity())); + Fq x = Fq::from_witness(ctx, input.x); + Fq y = Fq::from_witness(ctx, input.y); + element out(x, y); out.validate_on_curve(); return out; } @@ -64,17 +52,13 @@ template class element { void validate_on_curve() const { Fq b(get_context(), uint256_t(NativeGroup::curve_b)); - Fq _b = Fq::conditional_assign(is_point_at_infinity(), Fq::zero(), b); - Fq _x = Fq::conditional_assign(is_point_at_infinity(), Fq::zero(), x); - Fq _y = Fq::conditional_assign(is_point_at_infinity(), Fq::zero(), y); if constexpr (!NativeGroup::has_a) { // we validate y^2 = x^3 + b by setting "fix_remainder_zero = true" when calling mult_madd - Fq::mult_madd({ _x.sqr(), _y }, { _x, -_y }, { _b }, true); + Fq::mult_madd({ x.sqr(), y }, { x, -y }, { b }, true); } else { Fq a(get_context(), uint256_t(NativeGroup::curve_a)); - Fq _a = Fq::conditional_assign(is_point_at_infinity(), Fq::zero(), a); // we validate y^2 = x^3 + ax + b by setting "fix_remainder_zero = true" when calling mult_madd - Fq::mult_madd({ _x.sqr(), _x, _y }, { _x, _a, -_y }, { _b }, true); + Fq::mult_madd({ x.sqr(), x, y }, { x, a, -y }, { b }, true); } } @@ -88,7 +72,7 @@ template class element { } element& operator=(const element& other); - element& operator=(element&& other) noexcept; + element& operator=(element&& other); byte_array to_byte_array() const { @@ -98,9 +82,6 @@ template class element { return result; } - element checked_unconditional_add(const element& other) const; - element checked_unconditional_subtract(const element& other) const; - element operator+(const element& other) const; element operator-(const element& other) const; element operator-() const @@ -119,11 +100,11 @@ template class element { *this = *this - other; return *this; } - std::array checked_unconditional_add_sub(const element& other) const; + std::array add_sub(const element& other) const; element operator*(const Fr& other) const; - element conditional_negate(const bool_t& predicate) const + element conditional_negate(const bool_t& predicate) const { element result(*this); result.y = result.y.conditional_negate(predicate); @@ -195,13 +176,9 @@ template class element { typename NativeGroup::affine_element get_value() const { - uint512_t x_val = x.get_value() % Fq::modulus_u512; - uint512_t y_val = y.get_value() % Fq::modulus_u512; - auto result = typename NativeGroup::affine_element(x_val.lo, y_val.lo); - if (is_point_at_infinity().get_value()) { - result.self_set_infinity(); - } - return result; + uint512_t x_val = x.get_value(); + uint512_t y_val = y.get_value(); + return typename NativeGroup::affine_element(x_val.lo, y_val.lo); } // compute a multi-scalar-multiplication by creating a precomputed lookup table for each point, @@ -252,7 +229,7 @@ template class element { template ::value>> static element secp256k1_ecdsa_mul(const element& pubkey, const Fr& u1, const Fr& u2); - static std::vector compute_naf(const Fr& scalar, const size_t max_num_bits = 0); + static std::vector> compute_naf(const Fr& scalar, const size_t max_num_bits = 0); template static std::vector> compute_wnaf(const Fr& scalar); @@ -288,15 +265,10 @@ template class element { return nullptr; } - bool_t is_point_at_infinity() const { return _is_infinity; } - void set_point_at_infinity(const bool_t& is_infinity) { _is_infinity = is_infinity; } - Fq x; Fq y; private: - bool_t _is_infinity; - template >> static std::array, 5> create_group_element_rom_tables( const std::array& elements, std::array& limb_max); @@ -395,7 +367,7 @@ template class element { lookup_table_base(const lookup_table_base& other) = default; lookup_table_base& operator=(const lookup_table_base& other) = default; - element get(const std::array& bits) const; + element get(const std::array, length>& bits) const; element operator[](const size_t idx) const { return element_table[idx]; } @@ -425,7 +397,7 @@ template class element { lookup_table_plookup(const lookup_table_plookup& other) = default; lookup_table_plookup& operator=(const lookup_table_plookup& other) = default; - element get(const std::array& bits) const; + element get(const std::array, length>& bits) const; element operator[](const size_t idx) const { return element_table[idx]; } @@ -636,7 +608,7 @@ template class element { return chain_add_accumulator(add_accumulator[0]); } - element::chain_add_accumulator get_chain_add_accumulator(std::vector& naf_entries) const + element::chain_add_accumulator get_chain_add_accumulator(std::vector>& naf_entries) const { std::vector round_accumulator; for (size_t j = 0; j < num_sixes; ++j) { @@ -688,7 +660,7 @@ template class element { return (accumulator); } - element get(std::vector& naf_entries) const + element get(std::vector>& naf_entries) const { std::vector round_accumulator; for (size_t j = 0; j < num_sixes; ++j) { @@ -840,21 +812,21 @@ template class element { return chain_add_accumulator(add_accumulator[0]); } - element::chain_add_accumulator get_chain_add_accumulator(std::vector& naf_entries) const + element::chain_add_accumulator get_chain_add_accumulator(std::vector>& naf_entries) const { std::vector round_accumulator; for (size_t j = 0; j < num_quads; ++j) { - round_accumulator.push_back(quad_tables[j].get(std::array{ + round_accumulator.push_back(quad_tables[j].get(std::array, 4>{ naf_entries[4 * j], naf_entries[4 * j + 1], naf_entries[4 * j + 2], naf_entries[4 * j + 3] })); } if (has_triple) { - round_accumulator.push_back(triple_tables[0].get(std::array{ + round_accumulator.push_back(triple_tables[0].get(std::array, 3>{ naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1], naf_entries[num_quads * 4 + 2] })); } if (has_twin) { round_accumulator.push_back(twin_tables[0].get( - std::array{ naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1] })); + std::array, 2>{ naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1] })); } if (has_singleton) { round_accumulator.push_back(singletons[0].conditional_negate(naf_entries[num_points - 1])); @@ -877,7 +849,7 @@ template class element { return (accumulator); } - element get(std::vector& naf_entries) const + element get(std::vector>& naf_entries) const { std::vector round_accumulator; for (size_t j = 0; j < num_quads; ++j) { @@ -886,7 +858,7 @@ template class element { } if (has_triple) { - round_accumulator.push_back(triple_tables[0].get(std::array{ + round_accumulator.push_back(triple_tables[0].get(std::array, 3>{ naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1], naf_entries[num_quads * 4 + 2] })); } if (has_twin) { diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp index a8de2df775b..44201423b28 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup.test.cpp @@ -10,12 +10,12 @@ #include "barretenberg/stdlib/primitives/curves/secp256k1.hpp" #include "barretenberg/stdlib/primitives/curves/secp256r1.hpp" -using namespace bb; - namespace { auto& engine = numeric::get_debug_randomness(); } +using namespace bb; + // One can only define a TYPED_TEST with a single template paramter. // Our workaround is to pass parameters of the following type. template struct TestType { @@ -41,8 +41,6 @@ template class stdlib_biggroup : public testing::Test { using element = typename g1::element; using Builder = typename Curve::Builder; - using witness_ct = stdlib::witness_t; - using bool_ct = stdlib::bool_t; static constexpr auto EXPECT_CIRCUIT_CORRECTNESS = [](Builder& builder, bool expected_result = true) { info("num gates = ", builder.get_num_gates()); @@ -84,45 +82,6 @@ template class stdlib_biggroup : public testing::Test { EXPECT_CIRCUIT_CORRECTNESS(builder); } - static void test_add_points_at_infnity() - { - Builder builder; - size_t num_repetitions = 1; - for (size_t i = 0; i < num_repetitions; ++i) { - affine_element input_a(element::random_element()); - affine_element input_b(element::random_element()); - input_b.self_set_infinity(); - element_ct a = element_ct::from_witness(&builder, input_a); - // create copy of a with different witness - element_ct a_alternate = element_ct::from_witness(&builder, input_a); - element_ct a_negated = element_ct::from_witness(&builder, -input_a); - element_ct b = element_ct::from_witness(&builder, input_b); - - element_ct c = a + b; - element_ct d = b + a; - element_ct e = b + b; - element_ct f = a + a; - element_ct g = a + a_alternate; - element_ct h = a + a_negated; - - affine_element c_expected = affine_element(element(input_a) + element(input_b)); - affine_element d_expected = affine_element(element(input_b) + element(input_a)); - affine_element e_expected = affine_element(element(input_b) + element(input_b)); - affine_element f_expected = affine_element(element(input_a) + element(input_a)); - affine_element g_expected = affine_element(element(input_a) + element(input_a)); - affine_element h_expected = affine_element(element(input_a) + element(-input_a)); - - EXPECT_EQ(c.get_value(), c_expected); - EXPECT_EQ(d.get_value(), d_expected); - EXPECT_EQ(e.get_value(), e_expected); - EXPECT_EQ(f.get_value(), f_expected); - EXPECT_EQ(g.get_value(), g_expected); - EXPECT_EQ(h.get_value(), h_expected); - } - - EXPECT_CIRCUIT_CORRECTNESS(builder); - } - static void test_sub() { Builder builder; @@ -151,45 +110,6 @@ template class stdlib_biggroup : public testing::Test { EXPECT_CIRCUIT_CORRECTNESS(builder); } - static void test_sub_points_at_infnity() - { - Builder builder; - size_t num_repetitions = 1; - for (size_t i = 0; i < num_repetitions; ++i) { - affine_element input_a(element::random_element()); - affine_element input_b(element::random_element()); - input_b.self_set_infinity(); - element_ct a = element_ct::from_witness(&builder, input_a); - // create copy of a with different witness - element_ct a_alternate = element_ct::from_witness(&builder, input_a); - element_ct a_negated = element_ct::from_witness(&builder, -input_a); - element_ct b = element_ct::from_witness(&builder, input_b); - - element_ct c = a - b; - element_ct d = b - a; - element_ct e = b - b; - element_ct f = a - a; - element_ct g = a - a_alternate; - element_ct h = a - a_negated; - - affine_element c_expected = affine_element(element(input_a) - element(input_b)); - affine_element d_expected = affine_element(element(input_b) - element(input_a)); - affine_element e_expected = affine_element(element(input_b) - element(input_b)); - affine_element f_expected = affine_element(element(input_a) - element(input_a)); - affine_element g_expected = affine_element(element(input_a) - element(input_a)); - affine_element h_expected = affine_element(element(input_a) - element(-input_a)); - - EXPECT_EQ(c.get_value(), c_expected); - EXPECT_EQ(d.get_value(), d_expected); - EXPECT_EQ(e.get_value(), e_expected); - EXPECT_EQ(f.get_value(), f_expected); - EXPECT_EQ(g.get_value(), g_expected); - EXPECT_EQ(h.get_value(), h_expected); - } - - EXPECT_CIRCUIT_CORRECTNESS(builder); - } - static void test_dbl() { Builder builder; @@ -913,20 +833,10 @@ TYPED_TEST(stdlib_biggroup, add) TestFixture::test_add(); } -TYPED_TEST(stdlib_biggroup, add_points_at_infinity) -{ - - TestFixture::test_add_points_at_infnity(); -} TYPED_TEST(stdlib_biggroup, sub) { TestFixture::test_sub(); } -TYPED_TEST(stdlib_biggroup, sub_points_at_infinity) -{ - - TestFixture::test_sub_points_at_infnity(); -} TYPED_TEST(stdlib_biggroup, dbl) { TestFixture::test_dbl(); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp index 004538a3e5d..a10198286c3 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_batch_mul.hpp @@ -1,50 +1,21 @@ #pragma once -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" -#include namespace bb::stdlib { /** * only works for Plookup (otherwise falls back on batch_mul)! Multiscalar multiplication that utilizes 4-bit wNAF * lookup tables is more efficient than points-as-linear-combinations lookup tables, if the number of points is 3 or * fewer - * TODO: when we nuke standard and turbo plonk we should remove the fallback batch mul method! */ template template -element element::wnaf_batch_mul(const std::vector& _points, - const std::vector& _scalars) +element element::wnaf_batch_mul(const std::vector& points, + const std::vector& scalars) { constexpr size_t WNAF_SIZE = 4; - ASSERT(_points.size() == _scalars.size()); + ASSERT(points.size() == scalars.size()); if constexpr (!HasPlookup) { - return batch_mul(_points, _scalars, max_num_bits); - } - - // treat inputs for points at infinity. - // if a base point is at infinity, we substitute for element::one, and set the scalar multiplier to 0 - // this (partially) ensures the mul algorithm does not need to account for points at infinity - std::vector points; - std::vector scalars; - element one = element::one(nullptr); - for (size_t i = 0; i < points.size(); ++i) { - bool_t is_point_at_infinity = points[i].is_point_at_infinity(); - if (is_point_at_infinity.get_value() && static_cast(is_point_at_infinity.is_constant())) { - // if point is at infinity and a circuit constant we can just skip. - continue; - } - if (_scalars[i].get_value() == 0 && _scalars[i].is_constant()) { - // if scalar multiplier is 0 and also a constant, we can skip - continue; - } - element point(_points[i]); - point.x = Fq::conditional_assign(is_point_at_infinity, one.x, point.x); - point.y = Fq::conditional_assign(is_point_at_infinity, one.y, point.y); - Fr scalar = Fr::conditional_assign(is_point_at_infinity, 0, _scalars[i]); - points.push_back(point); - scalars.push_back(scalar); - - // TODO: if both point and scalar are constant, don't bother adding constraints + return batch_mul(points, scalars, max_num_bits); } std::vector> point_tables; @@ -78,8 +49,8 @@ element element::wnaf_batch_mul(const std::vector(wnaf_entries[i][num_rounds])); + Fq out_y = accumulator.y.conditional_select(skew.y, bool_t(wnaf_entries[i][num_rounds])); accumulator = element(out_x, out_y); } accumulator -= offset_generators.second; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_bn254.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_bn254.hpp index 0836b29bc87..5e03f8a58da 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_bn254.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_bn254.hpp @@ -7,8 +7,6 @@ * We use a special case algorithm to split bn254 scalar multipliers into endomorphism scalars * **/ -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" -#include "barretenberg/stdlib/primitives/circuit_builders/circuit_builders.hpp" namespace bb::stdlib { /** @@ -20,7 +18,6 @@ namespace bb::stdlib { * `small_scalars/small_points` : 128-bit scalar multipliers * `generator_scalar` : a 254-bit scalar multiplier over the bn254 generator point * - * TODO: this is plonk only. kill method when we deprecate standard/turbo plonk **/ template template @@ -57,9 +54,9 @@ element element::bn254_endo_batch_mul_with_generator auto& big_table = big_table_pair.first; auto& endo_table = big_table_pair.second; batch_lookup_table small_table(small_points); - std::vector> big_naf_entries; - std::vector> endo_naf_entries; - std::vector> small_naf_entries; + std::vector>> big_naf_entries; + std::vector>> endo_naf_entries; + std::vector>> small_naf_entries; const auto split_into_endomorphism_scalars = [ctx](const Fr& scalar) { bb::fr k = scalar.get_value(); @@ -102,9 +99,9 @@ element element::bn254_endo_batch_mul_with_generator element accumulator = element::chain_add_end(init_point); const auto get_point_to_add = [&](size_t naf_index) { - std::vector small_nafs; - std::vector big_nafs; - std::vector endo_nafs; + std::vector> small_nafs; + std::vector> big_nafs; + std::vector> endo_nafs; for (size_t i = 0; i < small_points.size(); ++i) { small_nafs.emplace_back(small_naf_entries[i][naf_index]); } @@ -181,14 +178,16 @@ element element::bn254_endo_batch_mul_with_generator } { element skew = accumulator - generator_table[128]; - Fq out_x = accumulator.x.conditional_select(skew.x, bool_t(generator_wnaf[generator_wnaf.size() - 1])); - Fq out_y = accumulator.y.conditional_select(skew.y, bool_t(generator_wnaf[generator_wnaf.size() - 1])); + Fq out_x = accumulator.x.conditional_select(skew.x, bool_t(generator_wnaf[generator_wnaf.size() - 1])); + Fq out_y = accumulator.y.conditional_select(skew.y, bool_t(generator_wnaf[generator_wnaf.size() - 1])); accumulator = element(out_x, out_y); } { element skew = accumulator - generator_endo_table[128]; - Fq out_x = accumulator.x.conditional_select(skew.x, bool_t(generator_endo_wnaf[generator_wnaf.size() - 1])); - Fq out_y = accumulator.y.conditional_select(skew.y, bool_t(generator_endo_wnaf[generator_wnaf.size() - 1])); + Fq out_x = + accumulator.x.conditional_select(skew.x, bool_t(generator_endo_wnaf[generator_wnaf.size() - 1])); + Fq out_y = + accumulator.y.conditional_select(skew.y, bool_t(generator_endo_wnaf[generator_wnaf.size() - 1])); accumulator = element(out_x, out_y); } @@ -214,7 +213,6 @@ element element::bn254_endo_batch_mul_with_generator * max_num_small_bits : MINIMUM value must be 128 bits * (we will be splitting `big_scalars` into two 128-bit scalars, we assume all scalars after this transformation are 128 *bits) - * TODO: this does not seem to be used anywhere except turbo plonk. delete once we deprecate turbo? **/ template template @@ -322,7 +320,7 @@ element element::bn254_endo_batch_mul(const std::vec **/ const size_t num_rounds = max_num_small_bits; const size_t num_points = points.size(); - std::vector> naf_entries; + std::vector>> naf_entries; for (size_t i = 0; i < num_points; ++i) { naf_entries.emplace_back(compute_naf(scalars[i], max_num_small_bits)); } @@ -356,7 +354,7 @@ element element::bn254_endo_batch_mul(const std::vec **/ for (size_t i = 1; i < num_rounds / 2; ++i) { // `nafs` tracks the naf value for each point for the current round - std::vector nafs; + std::vector> nafs; for (size_t j = 0; j < points.size(); ++j) { nafs.emplace_back(naf_entries[j][i * 2 - 1]); } @@ -385,7 +383,7 @@ element element::bn254_endo_batch_mul(const std::vec // we need to iterate 1 more time if the number of rounds is even if ((num_rounds & 0x01ULL) == 0x00ULL) { - std::vector nafs; + std::vector> nafs; for (size_t j = 0; j < points.size(); ++j) { nafs.emplace_back(naf_entries[j][num_rounds - 1]); } diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.hpp index 15d8a16c372..62404fc055e 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.hpp @@ -1,6 +1,5 @@ #pragma once -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" namespace bb::stdlib { /** diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.test.cpp index 6e6e38d9358..1ac09c4e69d 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_goblin.test.cpp @@ -10,12 +10,12 @@ #include "barretenberg/numeric/random/engine.hpp" #include -using namespace bb; - namespace { auto& engine = numeric::get_debug_randomness(); } +using namespace bb; + template class stdlib_biggroup_goblin : public testing::Test { using element_ct = typename Curve::Element; using scalar_ct = typename Curve::ScalarField; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp index d446cfa06a3..35b1c477d72 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_impl.hpp @@ -2,7 +2,8 @@ #include "../bit_array/bit_array.hpp" #include "../circuit_builders/circuit_builders.hpp" -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" + +using namespace bb; namespace bb::stdlib { @@ -10,181 +11,50 @@ template element::element() : x() , y() - , _is_infinity() {} template element::element(const typename G::affine_element& input) : x(nullptr, input.x) , y(nullptr, input.y) - , _is_infinity(nullptr, input.is_point_at_infinity()) {} template element::element(const Fq& x_in, const Fq& y_in) : x(x_in) , y(y_in) - , _is_infinity(x.get_context() ? x.get_context() : y.get_context(), false) {} template element::element(const element& other) : x(other.x) , y(other.y) - , _is_infinity(other.is_point_at_infinity()) {} template -element::element(element&& other) noexcept +element::element(element&& other) : x(other.x) , y(other.y) - , _is_infinity(other.is_point_at_infinity()) {} template element& element::operator=(const element& other) { - if (&other == this) { - return *this; - } x = other.x; y = other.y; - _is_infinity = other.is_point_at_infinity(); return *this; } template -element& element::operator=(element&& other) noexcept +element& element::operator=(element&& other) { - if (&other == this) { - return *this; - } x = other.x; y = other.y; - _is_infinity = other.is_point_at_infinity(); return *this; } template element element::operator+(const element& other) const -{ - // return checked_unconditional_add(other); - if constexpr (IsGoblinBuilder && std::same_as) { - // TODO(https://github.com/AztecProtocol/barretenberg/issues/707) Optimize - // Current gate count: 6398 - std::vector points{ *this, other }; - std::vector scalars{ 1, 1 }; - return goblin_batch_mul(points, scalars); - } - - // if x_coordinates match, lambda triggers a divide by zero error. - // Adding in `x_coordinates_match` ensures that lambda will always be well-formed - const bool_t x_coordinates_match = other.x == x; - const bool_t y_coordinates_match = (y == other.y); - const bool_t infinity_predicate = (x_coordinates_match && !y_coordinates_match); - const bool_t double_predicate = (x_coordinates_match && y_coordinates_match); - const bool_t lhs_infinity = is_point_at_infinity(); - const bool_t rhs_infinity = other.is_point_at_infinity(); - - // Compute the gradient `lambda`. If we add, `lambda = (y2 - y1)/(x2 - x1)`, else `lambda = 3x1*x1/2y1 - const Fq add_lambda_numerator = other.y - y; - const Fq xx = x * x; - const Fq dbl_lambda_numerator = xx + xx + xx; - const Fq lambda_numerator = Fq::conditional_assign(double_predicate, dbl_lambda_numerator, add_lambda_numerator); - - const Fq add_lambda_denominator = other.x - x; - const Fq dbl_lambda_denominator = y + y; - Fq lambda_denominator = Fq::conditional_assign(double_predicate, dbl_lambda_denominator, add_lambda_denominator); - // If either inputs are points at infinity, we set lambda_denominator to be 1. This ensures we never trigger a - // divide by zero error. - // (if either inputs are points at infinity we will not use the result of this computation) - Fq safe_edgecase_denominator = Fq(field_t(1), field_t(0), field_t(0), field_t(0)); - lambda_denominator = Fq::conditional_assign( - lhs_infinity || rhs_infinity || infinity_predicate, safe_edgecase_denominator, lambda_denominator); - const Fq lambda = Fq::div_without_denominator_check({ lambda_numerator }, lambda_denominator); - - const Fq x3 = lambda.sqradd({ -other.x, -x }); - const Fq y3 = lambda.madd(x - x3, { -y }); - - element result(x3, y3); - // if lhs infinity, return rhs - result.x = Fq::conditional_assign(lhs_infinity, other.x, result.x); - result.y = Fq::conditional_assign(lhs_infinity, other.y, result.y); - // if rhs infinity, return lhs - result.x = Fq::conditional_assign(rhs_infinity, x, result.x); - result.y = Fq::conditional_assign(rhs_infinity, y, result.y); - - // is result point at infinity? - // yes = infinity_predicate && !lhs_infinity && !rhs_infinity - // yes = lhs_infinity && rhs_infinity - // n.b. can likely optimize this - bool_t result_is_infinity = infinity_predicate && (!lhs_infinity && !rhs_infinity); - result_is_infinity = result_is_infinity || (lhs_infinity && rhs_infinity); - result.set_point_at_infinity(result_is_infinity); - return result; -} - -template -element element::operator-(const element& other) const -{ - // return checked_unconditional_add(other); - if constexpr (IsGoblinBuilder && std::same_as) { - // TODO(https://github.com/AztecProtocol/barretenberg/issues/707) Optimize - // Current gate count: 6398 - std::vector points{ *this, other }; - std::vector scalars{ 1, -Fr(1) }; - return goblin_batch_mul(points, scalars); - } - - // if x_coordinates match, lambda triggers a divide by zero error. - // Adding in `x_coordinates_match` ensures that lambda will always be well-formed - const bool_t x_coordinates_match = other.x == x; - const bool_t y_coordinates_match = (y == other.y); - const bool_t infinity_predicate = (x_coordinates_match && y_coordinates_match); - const bool_t double_predicate = (x_coordinates_match && !y_coordinates_match); - const bool_t lhs_infinity = is_point_at_infinity(); - const bool_t rhs_infinity = other.is_point_at_infinity(); - - // Compute the gradient `lambda`. If we add, `lambda = (y2 - y1)/(x2 - x1)`, else `lambda = 3x1*x1/2y1 - const Fq add_lambda_numerator = -other.y - y; - const Fq xx = x * x; - const Fq dbl_lambda_numerator = xx + xx + xx; - const Fq lambda_numerator = Fq::conditional_assign(double_predicate, dbl_lambda_numerator, add_lambda_numerator); - - const Fq add_lambda_denominator = other.x - x; - const Fq dbl_lambda_denominator = y + y; - Fq lambda_denominator = Fq::conditional_assign(double_predicate, dbl_lambda_denominator, add_lambda_denominator); - // If either inputs are points at infinity, we set lambda_denominator to be 1. This ensures we never trigger a - // divide by zero error. - // (if either inputs are points at infinity we will not use the result of this computation) - Fq safe_edgecase_denominator = Fq(field_t(1), field_t(0), field_t(0), field_t(0)); - lambda_denominator = Fq::conditional_assign( - lhs_infinity || rhs_infinity || infinity_predicate, safe_edgecase_denominator, lambda_denominator); - const Fq lambda = Fq::div_without_denominator_check({ lambda_numerator }, lambda_denominator); - - const Fq x3 = lambda.sqradd({ -other.x, -x }); - const Fq y3 = lambda.madd(x - x3, { -y }); - - element result(x3, y3); - // if lhs infinity, return rhs - result.x = Fq::conditional_assign(lhs_infinity, other.x, result.x); - result.y = Fq::conditional_assign(lhs_infinity, -other.y, result.y); - // if rhs infinity, return lhs - result.x = Fq::conditional_assign(rhs_infinity, x, result.x); - result.y = Fq::conditional_assign(rhs_infinity, y, result.y); - - // is result point at infinity? - // yes = infinity_predicate && !lhs_infinity && !rhs_infinity - // yes = lhs_infinity && rhs_infinity - // n.b. can likely optimize this - bool_t result_is_infinity = infinity_predicate && (!lhs_infinity && !rhs_infinity); - result_is_infinity = result_is_infinity || (lhs_infinity && rhs_infinity); - result.set_point_at_infinity(result_is_infinity); - return result; -} - -template -element element::checked_unconditional_add(const element& other) const { if constexpr (IsGoblinBuilder && std::same_as) { // TODO(https://github.com/AztecProtocol/barretenberg/issues/707) Optimize @@ -202,7 +72,7 @@ element element::checked_unconditional_add(const ele } template -element element::checked_unconditional_subtract(const element& other) const +element element::operator-(const element& other) const { if constexpr (IsGoblinBuilder && std::same_as) { // TODO(https://github.com/AztecProtocol/barretenberg/issues/707) Optimize @@ -235,7 +105,7 @@ element element::checked_unconditional_subtract(cons */ // TODO(https://github.com/AztecProtocol/barretenberg/issues/657): This function is untested template -std::array, 2> element::checked_unconditional_add_sub(const element& other) const +std::array, 2> element::add_sub(const element& other) const { if constexpr (IsGoblinBuilder && std::same_as) { return { *this + other, *this - other }; @@ -270,9 +140,7 @@ template element element Fq neg_lambda = Fq::msub_div({ x }, { (two_x + x) }, (y + y), {}); Fq x_3 = neg_lambda.sqradd({ -(two_x) }); Fq y_3 = neg_lambda.madd(x_3 - x, { -y }); - element result = element(x_3, y_3); - result.set_point_at_infinity(is_point_at_infinity()); - return result; + return element(x_3, y_3); } /** @@ -763,7 +631,7 @@ element element::batch_mul(const std::vector> naf_entries; + std::vector>> naf_entries; for (size_t i = 0; i < num_points; ++i) { naf_entries.emplace_back(compute_naf(scalars[i], max_num_bits)); } @@ -778,7 +646,7 @@ element element::batch_mul(const std::vector nafs(num_points); + std::vector> nafs(num_points); std::vector to_add; const size_t inner_num_rounds = (i != num_iterations - 1) ? num_rounds_per_iteration : num_rounds_per_final_iteration; @@ -841,14 +709,14 @@ element element::operator*(const Fr& scalar) const } else { constexpr uint64_t num_rounds = Fr::modulus.get_msb() + 1; - std::vector naf_entries = compute_naf(scalar); + std::vector> naf_entries = compute_naf(scalar); const auto offset_generators = compute_offset_generators(num_rounds); element accumulator = *this + offset_generators.first; for (size_t i = 1; i < num_rounds; ++i) { - bool_t predicate = naf_entries[i]; + bool_t predicate = naf_entries[i]; bigfield y_test = y.conditional_negate(predicate); element to_add(x, y_test); accumulator = accumulator.montgomery_ladder(to_add); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_nafs.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_nafs.hpp index f1dd10cd30e..32a8a3876c1 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_nafs.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_nafs.hpp @@ -1,6 +1,5 @@ #pragma once #include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp" -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" namespace bb::stdlib { @@ -482,17 +481,17 @@ std::vector> element::compute_naf(const Fr& scalar, cons uint256_t scalar_multiplier = scalar_multiplier_512.lo; const size_t num_rounds = (max_num_bits == 0) ? Fr::modulus.get_msb() + 1 : max_num_bits; - std::vector naf_entries(num_rounds + 1); + std::vector> naf_entries(num_rounds + 1); // if boolean is false => do NOT flip y // if boolean is true => DO flip y // first entry is skew. i.e. do we subtract one from the final result or not if (scalar_multiplier.get_bit(0) == false) { // add skew - naf_entries[num_rounds] = bool_t(witness_t(ctx, true)); + naf_entries[num_rounds] = bool_t(witness_t(ctx, true)); scalar_multiplier += uint256_t(1); } else { - naf_entries[num_rounds] = bool_t(witness_t(ctx, false)); + naf_entries[num_rounds] = bool_t(witness_t(ctx, false)); } for (size_t i = 0; i < num_rounds - 1; ++i) { bool next_entry = scalar_multiplier.get_bit(i + 1); @@ -500,7 +499,7 @@ std::vector> element::compute_naf(const Fr& scalar, cons // This is a VERY hacky workaround to ensure that UltraPlonkBuilder will apply a basic // range constraint per bool, and not a full 1-bit range gate if (next_entry == false) { - bool_t bit(ctx, true); + bool_t bit(ctx, true); bit.context = ctx; bit.witness_index = witness_t(ctx, true).witness_index; // flip sign bit.witness_bool = true; @@ -513,7 +512,7 @@ std::vector> element::compute_naf(const Fr& scalar, cons } naf_entries[num_rounds - i - 1] = bit; } else { - bool_t bit(ctx, false); + bool_t bit(ctx, false); bit.witness_index = witness_t(ctx, false).witness_index; // don't flip sign bit.witness_bool = false; if constexpr (HasPlookup) { @@ -526,7 +525,7 @@ std::vector> element::compute_naf(const Fr& scalar, cons naf_entries[num_rounds - i - 1] = bit; } } - naf_entries[0] = bool_t(ctx, false); // most significant entry is always true + naf_entries[0] = bool_t(ctx, false); // most significant entry is always true // validate correctness of NAF if constexpr (!Fr::is_composite) { @@ -543,7 +542,7 @@ std::vector> element::compute_naf(const Fr& scalar, cons Fr accumulator_result = Fr::accumulate(accumulators); scalar.assert_equal(accumulator_result); } else { - const auto reconstruct_half_naf = [](bool_t* nafs, const size_t half_round_length) { + const auto reconstruct_half_naf = [](bool_t* nafs, const size_t half_round_length) { // Q: need constraint to start from zero? field_t negative_accumulator(0); field_t positive_accumulator(0); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_secp256k1.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_secp256k1.hpp index b9b363ba8ea..6f898f6a217 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_secp256k1.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_secp256k1.hpp @@ -5,7 +5,6 @@ * TODO: we should try to genericize this, but this method is super fiddly and we need it to be efficient! * **/ -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" namespace bb::stdlib { template @@ -120,14 +119,14 @@ element element::secp256k1_ecdsa_mul(const element& const element& base_point, const field_t& positive_skew, const field_t& negative_skew) { - const bool_t positive_skew_bool(positive_skew); - const bool_t negative_skew_bool(negative_skew); + const bool_t positive_skew_bool(positive_skew); + const bool_t negative_skew_bool(negative_skew); auto to_add = base_point; to_add.y = to_add.y.conditional_negate(negative_skew_bool); element result = accumulator + to_add; // when computing the wNAF we have already validated that positive_skew and negative_skew cannot both be true - bool_t skew_combined = positive_skew_bool ^ negative_skew_bool; + bool_t skew_combined = positive_skew_bool ^ negative_skew_bool; result.x = accumulator.x.conditional_select(result.x, skew_combined); result.y = accumulator.y.conditional_select(result.y, skew_combined); return result; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_tables.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_tables.hpp index bdb6a9cd61f..78cc53e03b7 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_tables.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/biggroup/biggroup_tables.hpp @@ -1,6 +1,4 @@ #pragma once -#include "barretenberg/stdlib/primitives/biggroup/biggroup.hpp" -#include "barretenberg/stdlib/primitives/memory/twin_rom_table.hpp" #include "barretenberg/stdlib_circuit_builders/plookup_tables/types.hpp" namespace bb::stdlib { @@ -182,27 +180,27 @@ template element::lookup_table_plookup::lookup_table_plookup(const std::array& inputs) { if constexpr (length == 2) { - auto [A0, A1] = inputs[1].checked_unconditional_add_sub(inputs[0]); + auto [A0, A1] = inputs[1].add_sub(inputs[0]); element_table[0] = A0; element_table[1] = A1; } else if constexpr (length == 3) { - auto [R0, R1] = inputs[1].checked_unconditional_add_sub(inputs[0]); // B ± A + auto [R0, R1] = inputs[1].add_sub(inputs[0]); // B ± A - auto [T0, T1] = inputs[2].checked_unconditional_add_sub(R0); // C ± (B + A) - auto [T2, T3] = inputs[2].checked_unconditional_add_sub(R1); // C ± (B - A) + auto [T0, T1] = inputs[2].add_sub(R0); // C ± (B + A) + auto [T2, T3] = inputs[2].add_sub(R1); // C ± (B - A) element_table[0] = T0; element_table[1] = T2; element_table[2] = T3; element_table[3] = T1; } else if constexpr (length == 4) { - auto [T0, T1] = inputs[1].checked_unconditional_add_sub(inputs[0]); // B ± A - auto [T2, T3] = inputs[3].checked_unconditional_add_sub(inputs[2]); // D ± C + auto [T0, T1] = inputs[1].add_sub(inputs[0]); // B ± A + auto [T2, T3] = inputs[3].add_sub(inputs[2]); // D ± C - auto [F0, F3] = T2.checked_unconditional_add_sub(T0); // (D + C) ± (B + A) - auto [F1, F2] = T2.checked_unconditional_add_sub(T1); // (D + C) ± (B - A) - auto [F4, F7] = T3.checked_unconditional_add_sub(T0); // (D - C) ± (B + A) - auto [F5, F6] = T3.checked_unconditional_add_sub(T1); // (D - C) ± (B - A) + auto [F0, F3] = T2.add_sub(T0); // (D + C) ± (B + A) + auto [F1, F2] = T2.add_sub(T1); // (D + C) ± (B - A) + auto [F4, F7] = T3.add_sub(T0); // (D - C) ± (B + A) + auto [F5, F6] = T3.add_sub(T1); // (D - C) ± (B - A) element_table[0] = F0; element_table[1] = F1; @@ -213,20 +211,20 @@ element::lookup_table_plookup::lookup_table_plookup(con element_table[6] = F6; element_table[7] = F7; } else if constexpr (length == 5) { - auto [A0, A1] = inputs[1].checked_unconditional_add_sub(inputs[0]); // B ± A - auto [T2, T3] = inputs[3].checked_unconditional_add_sub(inputs[2]); // D ± C + auto [A0, A1] = inputs[1].add_sub(inputs[0]); // B ± A + auto [T2, T3] = inputs[3].add_sub(inputs[2]); // D ± C - auto [E0, E3] = inputs[4].checked_unconditional_add_sub(T2); // E ± (D + C) - auto [E1, E2] = inputs[4].checked_unconditional_add_sub(T3); // E ± (D - C) + auto [E0, E3] = inputs[4].add_sub(T2); // E ± (D + C) + auto [E1, E2] = inputs[4].add_sub(T3); // E ± (D - C) - auto [F0, F3] = E0.checked_unconditional_add_sub(A0); - auto [F1, F2] = E0.checked_unconditional_add_sub(A1); - auto [F4, F7] = E1.checked_unconditional_add_sub(A0); - auto [F5, F6] = E1.checked_unconditional_add_sub(A1); - auto [F8, F11] = E2.checked_unconditional_add_sub(A0); - auto [F9, F10] = E2.checked_unconditional_add_sub(A1); - auto [F12, F15] = E3.checked_unconditional_add_sub(A0); - auto [F13, F14] = E3.checked_unconditional_add_sub(A1); + auto [F0, F3] = E0.add_sub(A0); + auto [F1, F2] = E0.add_sub(A1); + auto [F4, F7] = E1.add_sub(A0); + auto [F5, F6] = E1.add_sub(A1); + auto [F8, F11] = E2.add_sub(A0); + auto [F9, F10] = E2.add_sub(A1); + auto [F12, F15] = E3.add_sub(A0); + auto [F13, F14] = E3.add_sub(A1); element_table[0] = F0; element_table[1] = F1; @@ -247,33 +245,33 @@ element::lookup_table_plookup::lookup_table_plookup(con } else if constexpr (length == 6) { // 44 adds! Only use this if it saves us adding another table to a multi-scalar-multiplication - auto [A0, A1] = inputs[1].checked_unconditional_add_sub(inputs[0]); - auto [E0, E1] = inputs[4].checked_unconditional_add_sub(inputs[3]); - auto [C0, C3] = inputs[2].checked_unconditional_add_sub(A0); - auto [C1, C2] = inputs[2].checked_unconditional_add_sub(A1); + auto [A0, A1] = inputs[1].add_sub(inputs[0]); + auto [E0, E1] = inputs[4].add_sub(inputs[3]); + auto [C0, C3] = inputs[2].add_sub(A0); + auto [C1, C2] = inputs[2].add_sub(A1); - auto [F0, F3] = inputs[5].checked_unconditional_add_sub(E0); - auto [F1, F2] = inputs[5].checked_unconditional_add_sub(E1); + auto [F0, F3] = inputs[5].add_sub(E0); + auto [F1, F2] = inputs[5].add_sub(E1); - auto [R0, R7] = F0.checked_unconditional_add_sub(C0); - auto [R1, R6] = F0.checked_unconditional_add_sub(C1); - auto [R2, R5] = F0.checked_unconditional_add_sub(C2); - auto [R3, R4] = F0.checked_unconditional_add_sub(C3); + auto [R0, R7] = F0.add_sub(C0); + auto [R1, R6] = F0.add_sub(C1); + auto [R2, R5] = F0.add_sub(C2); + auto [R3, R4] = F0.add_sub(C3); - auto [S0, S7] = F1.checked_unconditional_add_sub(C0); - auto [S1, S6] = F1.checked_unconditional_add_sub(C1); - auto [S2, S5] = F1.checked_unconditional_add_sub(C2); - auto [S3, S4] = F1.checked_unconditional_add_sub(C3); + auto [S0, S7] = F1.add_sub(C0); + auto [S1, S6] = F1.add_sub(C1); + auto [S2, S5] = F1.add_sub(C2); + auto [S3, S4] = F1.add_sub(C3); - auto [U0, U7] = F2.checked_unconditional_add_sub(C0); - auto [U1, U6] = F2.checked_unconditional_add_sub(C1); - auto [U2, U5] = F2.checked_unconditional_add_sub(C2); - auto [U3, U4] = F2.checked_unconditional_add_sub(C3); + auto [U0, U7] = F2.add_sub(C0); + auto [U1, U6] = F2.add_sub(C1); + auto [U2, U5] = F2.add_sub(C2); + auto [U3, U4] = F2.add_sub(C3); - auto [W0, W7] = F3.checked_unconditional_add_sub(C0); - auto [W1, W6] = F3.checked_unconditional_add_sub(C1); - auto [W2, W5] = F3.checked_unconditional_add_sub(C2); - auto [W3, W4] = F3.checked_unconditional_add_sub(C3); + auto [W0, W7] = F3.add_sub(C0); + auto [W1, W6] = F3.add_sub(C1); + auto [W2, W5] = F3.add_sub(C2); + auto [W3, W4] = F3.add_sub(C3); element_table[0] = R0; element_table[1] = R1; @@ -410,7 +408,7 @@ element::lookup_table_plookup::lookup_table_plookup(con template template element element::lookup_table_plookup::get( - const std::array& bits) const + const std::array, length>& bits) const { std::vector> accumulators; for (size_t i = 0; i < length; ++i) { @@ -560,20 +558,20 @@ element::lookup_table_base::lookup_table_base(const std::a template template element element::lookup_table_base::get( - const std::array& bits) const + const std::array, length>& bits) const { static_assert(length <= 4 && length >= 2); if constexpr (length == 2) { - bool_t table_selector = bits[0] ^ bits[1]; - bool_t sign_selector = bits[1]; + bool_t table_selector = bits[0] ^ bits[1]; + bool_t sign_selector = bits[1]; Fq to_add_x = twin0.x.conditional_select(twin1.x, table_selector); Fq to_add_y = twin0.y.conditional_select(twin1.y, table_selector); element to_add(to_add_x, to_add_y.conditional_negate(sign_selector)); return to_add; } else if constexpr (length == 3) { - bool_t t0 = bits[2] ^ bits[0]; - bool_t t1 = bits[2] ^ bits[1]; + bool_t t0 = bits[2] ^ bits[0]; + bool_t t1 = bits[2] ^ bits[1]; field_t x_b0 = field_t::select_from_two_bit_table(x_b0_table, t1, t0); field_t x_b1 = field_t::select_from_two_bit_table(x_b1_table, t1, t0); @@ -606,9 +604,9 @@ element element::lookup_table_base::get( return to_add; } else if constexpr (length == 4) { - bool_t t0 = bits[3] ^ bits[0]; - bool_t t1 = bits[3] ^ bits[1]; - bool_t t2 = bits[3] ^ bits[2]; + bool_t t0 = bits[3] ^ bits[0]; + bool_t t1 = bits[3] ^ bits[1]; + bool_t t2 = bits[3] ^ bits[2]; field_t x_b0 = field_t::select_from_three_bit_table(x_b0_table, t2, t1, t0); field_t x_b1 = field_t::select_from_three_bit_table(x_b1_table, t2, t1, t0); diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/secp256r1.hpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/secp256r1.hpp index 5b7a5106f3f..a6593e4f831 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/secp256r1.hpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/curves/secp256r1.hpp @@ -11,9 +11,9 @@ namespace bb::stdlib { template struct secp256r1 { static constexpr bb::CurveType type = bb::CurveType::SECP256R1; - typedef bb::secp256r1::fq fq; - typedef bb::secp256r1::fr fr; - typedef bb::secp256r1::g1 g1; + typedef ::secp256r1::fq fq; + typedef ::secp256r1::fr fr; + typedef ::secp256r1::g1 g1; typedef CircuitType Builder; typedef witness_t witness_ct; @@ -23,8 +23,8 @@ template struct secp256r1 { typedef bool_t bool_ct; typedef stdlib::uint32 uint32_ct; - typedef bigfield fq_ct; - typedef bigfield bigfr_ct; + typedef bigfield fq_ct; + typedef bigfield bigfr_ct; typedef element g1_ct; typedef element g1_bigfr_ct; }; diff --git a/barretenberg/cpp/src/barretenberg/stdlib/primitives/databus/databus.test.cpp b/barretenberg/cpp/src/barretenberg/stdlib/primitives/databus/databus.test.cpp index 5d8f05b50b3..e8daaa52170 100644 --- a/barretenberg/cpp/src/barretenberg/stdlib/primitives/databus/databus.test.cpp +++ b/barretenberg/cpp/src/barretenberg/stdlib/primitives/databus/databus.test.cpp @@ -6,8 +6,6 @@ #include "barretenberg/stdlib_circuit_builders/goblin_ultra_circuit_builder.hpp" #include "databus.hpp" -using namespace bb; - using Builder = GoblinUltraCircuitBuilder; using field_ct = stdlib::field_t; using witness_ct = stdlib::witness_t;