diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt index a90789f9c6..d199134cb6 100644 --- a/cpp/src/CMakeLists.txt +++ b/cpp/src/CMakeLists.txt @@ -90,6 +90,7 @@ if(WASM) $ $ $ + $ $ $ $ @@ -192,6 +193,7 @@ if(WASM) $ $ $ + $ $ $ $ @@ -227,6 +229,7 @@ else() $ $ $ + $ $ $ $ diff --git a/cpp/src/barretenberg/ecc/groups/affine_element.hpp b/cpp/src/barretenberg/ecc/groups/affine_element.hpp index 81e6099030..293ba2bd53 100644 --- a/cpp/src/barretenberg/ecc/groups/affine_element.hpp +++ b/cpp/src/barretenberg/ecc/groups/affine_element.hpp @@ -49,6 +49,13 @@ template class alignas(64) affine_el constexpr bool on_curve() const noexcept; + /** + * @brief Samples a random point on the curve. + * + * @return A randomly chosen point on the curve + */ + static affine_element random_element(numeric::random::Engine* engine = nullptr) noexcept; + /** * @brief Hash a seed value to curve. * diff --git a/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp b/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp index 691f03f942..356f2719c4 100644 --- a/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp +++ b/cpp/src/barretenberg/ecc/groups/affine_element_impl.hpp @@ -202,5 +202,34 @@ affine_element affine_element::hash_to_curve(const uint64_ return affine_element(x_out, y_out_); } + +template +affine_element affine_element::random_element(numeric::random::Engine* engine) noexcept +{ + bool found_one = false; + Fq yy; + Fq x; + Fq y; + while (!found_one) { + // Sample a random x-coordinate and check if it satisfies curve equation. + x = Fq::random_element(engine); + yy = x.sqr() * x + T::b; + if constexpr (T::has_a) { + yy += (x * T::a); + } + auto [found_root, y1] = yy.sqrt(); + y = y1; + + // Negate the y-coordinate based on a randomly sampled bit. + bool random_bit = (engine->get_random_uint8() & 1); + if (random_bit) { + y = -y; + } + + found_one = found_root; + } + return affine_element(x, y); +} + } // namespace group_elements } // namespace barretenberg diff --git a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp index 002fce1df1..b87bf158c4 100644 --- a/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp +++ b/cpp/src/barretenberg/stdlib/primitives/bigfield/bigfield.hpp @@ -160,7 +160,7 @@ template class bigfield { field_t lo = binary_basis_limbs[0].element + (binary_basis_limbs[1].element * shift_1); field_t hi = binary_basis_limbs[2].element + (binary_basis_limbs[3].element * shift_1); // n.b. this only works if NUM_LIMB_BITS * 2 is divisible by 8 - ASSERT((NUM_LIMB_BITS / 8) * 8 == NUM_LIMB_BITS); + ASSERT((NUM_LIMB_BITS * 2 / 8) * 8 == NUM_LIMB_BITS * 2); result.write(byte_array(hi, 32 - (NUM_LIMB_BITS / 4))); result.write(byte_array(lo, (NUM_LIMB_BITS / 4))); return result;