diff --git a/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp b/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp index 8591e02d73a2..586199aea53e 100644 --- a/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp +++ b/barretenberg/cpp/src/barretenberg/benchmark/basics_bench/basics.bench.cpp @@ -24,6 +24,7 @@ #include "barretenberg/common/op_count.hpp" #include "barretenberg/common/thread.hpp" #include "barretenberg/ecc/curves/bn254/bn254.hpp" +#include "barretenberg/numeric/random/engine.hpp" #include "barretenberg/polynomials/polynomial.hpp" #include "barretenberg/srs/global_crs.hpp" #include @@ -466,6 +467,19 @@ void pippenger(State& state) benchmark::DoNotOptimize(ck->commit(pol)); } } + +void bn254fr_random(State& state) +{ + numeric::RNG& engine = numeric::get_randomness(); + for (auto _ : state) { + state.PauseTiming(); + size_t num_cycles = 1UL << static_cast(state.range(0)); + state.ResumeTiming(); + for (size_t i = 0; i < num_cycles; i++) { + benchmark::DoNotOptimize(fr::random_element(&engine)); + } + } +} } // namespace BENCHMARK(parallel_for_field_element_addition)->Unit(kMicrosecond)->DenseRange(0, MAX_REPETITION_LOG); @@ -485,4 +499,5 @@ BENCHMARK(sequential_copy)->Unit(kMicrosecond)->DenseRange(20, 25); BENCHMARK(uint_multiplication)->Unit(kMicrosecond)->DenseRange(12, 27); BENCHMARK(uint_extended_multiplication)->Unit(kMicrosecond)->DenseRange(12, 27); BENCHMARK(pippenger)->Unit(kMicrosecond)->DenseRange(16, 20)->Setup(DoPippengerSetup)->Iterations(5); +BENCHMARK(bn254fr_random)->Unit(kMicrosecond)->DenseRange(10, 20); BENCHMARK_MAIN(); \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp index 343156b5c18a..7281257356df 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fq.test.cpp @@ -1,4 +1,6 @@ #include "fq.hpp" +#include "barretenberg/numeric/random/engine.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" #include "barretenberg/serialize/test_helper.hpp" #include @@ -526,4 +528,17 @@ TEST(fq, NegAndSelfNeg0CmpRegression) a_neg = 0; a_neg.self_neg(); EXPECT_EQ((a == a_neg), true); +} + +// This test shows that ((lo|hi)% modulus) in uint512_t is equivalent to (lo + 2^256 * hi) in field elements so we +// don't have to use the slow API (uint512_t' modulo operation) +TEST(fq, EquivalentRandomness) +{ + auto& engine = numeric::get_debug_randomness(); + uint512_t random_uint512 = engine.get_random_uint512(); + auto random_lo = fq(random_uint512.lo); + auto random_hi = fq(random_uint512.hi); + uint512_t q(fq::modulus); + constexpr auto pow_2_256 = fq(uint256_t(1) << 128).sqr(); + EXPECT_EQ(random_lo + pow_2_256 * random_hi, fq((random_uint512 % q).lo)); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp index 7d2d89edd043..9e49512c501f 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp +++ b/barretenberg/cpp/src/barretenberg/ecc/curves/bn254/fr.test.cpp @@ -378,4 +378,16 @@ TEST(fr, Uint256Conversions) static_assert(a == c); EXPECT_EQ(a, c); +} +// This test shows that ((lo|hi)% modulus) in uint512_t is equivalent to (lo + 2^256 * hi) in field elements so we +// don't have to use the slow API (uint512_t's modulo operation) +TEST(fr, EquivalentRandomness) +{ + auto& engine = numeric::get_debug_randomness(); + uint512_t random_uint512 = engine.get_random_uint512(); + auto random_lo = fr(random_uint512.lo); + auto random_hi = fr(random_uint512.hi); + uint512_t r(fr::modulus); + constexpr auto pow_2_256 = fr(uint256_t(1) << 128).sqr(); + EXPECT_EQ(random_lo + pow_2_256 * random_hi, fr((random_uint512 % r).lo)); } \ No newline at end of file diff --git a/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp b/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp index 4ab221fc7193..17f034e40d78 100644 --- a/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp +++ b/barretenberg/cpp/src/barretenberg/ecc/fields/field_impl.hpp @@ -10,6 +10,7 @@ #include #include "./field_declarations.hpp" +#include "barretenberg/numeric/uint256/uint256.hpp" namespace bb { @@ -687,11 +688,18 @@ template field field::random_element(numeric::RNG* engine) noexc if (engine == nullptr) { engine = &numeric::get_randomness(); } - - uint512_t source = engine->get_random_uint512(); - uint512_t q(modulus); - uint512_t reduced = source % q; - return field(reduced.lo); + constexpr field pow_2_256 = field(uint256_t(1) << 128).sqr(); + field lo; + field hi; + *(uint256_t*)lo.data = engine->get_random_uint256(); + *(uint256_t*)hi.data = engine->get_random_uint256(); + lo.self_reduce_once(); + lo.self_reduce_once(); + lo.self_reduce_once(); + hi.self_reduce_once(); + hi.self_reduce_once(); + hi.self_reduce_once(); + return lo + (pow_2_256 * hi); } template constexpr size_t field::primitive_root_log_size() noexcept