4#include <gtest/gtest.h>
10template <
typename Group,
typename Fr>
11typename Group::affine_element naive_scalar_mul(
const typename Group::element& base,
const Fr& scalar)
13 typename Group::element acc = Group::point_at_infinity;
14 typename Group::element runner = base;
16 for (
size_t i = 0; i < 256; ++i) {
17 if (bits.get_bit(i)) {
20 runner = runner.dbl();
22 return typename Group::affine_element(acc);
30 EXPECT_EQ(seventeen, -
b);
33TEST(grumpkin, RandomElement)
39TEST(grumpkin, RandomAffineElement)
50 EXPECT_EQ(
a ==
b,
true);
51 EXPECT_EQ(
a ==
a,
true);
53 b.self_set_infinity();
55 EXPECT_EQ(
a ==
b,
false);
58 EXPECT_EQ(
a == c,
false);
60 a.self_set_infinity();
62 EXPECT_EQ(
a ==
b,
true);
65TEST(grumpkin, CheckGroupModulus)
76TEST(grumpkin, AddExceptionTestInfinity)
94 EXPECT_EQ(lhs == result,
true);
99 EXPECT_EQ(rhs == result,
true);
102TEST(grumpkin, AddExceptionTestDbl)
112 expected = lhs.
dbl();
114 EXPECT_EQ(result == expected,
true);
117TEST(grumpkin, AddDblConsistency)
132 dbl_result =
a.dbl();
134 EXPECT_EQ(add_result == dbl_result,
true);
137TEST(grumpkin, AddDblConsistencyRepeated)
157 EXPECT_EQ(result == expected,
true);
160TEST(grumpkin, MixedAddExceptionTestInfinity)
177 EXPECT_EQ(rhs_c == result,
true);
180TEST(grumpkin, MixedAddExceptionTestDbl)
190 expected = lhs.
dbl();
192 EXPECT_EQ(result == expected,
true);
195TEST(grumpkin, AddMixedAddConsistencyCheck)
204 add_result = lhs + rhs_b;
205 mixed_add_result = lhs + rhs;
207 EXPECT_EQ(add_result == mixed_add_result,
true);
212 for (
size_t i = 0; i < 100; ++i) {
216 EXPECT_EQ(affine_test.
on_curve(),
true);
221 size_t num_points = 2;
224 for (
size_t i = 0; i < num_points; ++i) {
228 normalized[i] = points[i];
230 grumpkin::g1::element::batch_normalize(&normalized[0], num_points);
232 for (
size_t i = 0; i < num_points; ++i) {
237 zz = points[i].z.
sqr();
238 zzz = points[i].z * zz;
239 result_x = normalized[i].x * zz;
240 result_y = normalized[i].y * zzz;
242 EXPECT_EQ((result_x == points[i].x),
true);
243 EXPECT_EQ((result_y == points[i].y),
true);
247TEST(grumpkin, GroupExponentiationZeroAndOne)
258TEST(grumpkin, GroupExponentiationConsistencyCheck)
272 EXPECT_EQ(result == expected,
true);
275TEST(grumpkin, DeriveGenerators)
277 constexpr size_t num_generators = 128;
280 for (
size_t i = 0; i < result.size(); ++i) {
281 if ((i != j) && result[i] == y) {
288 for (
size_t k = 0; k < num_generators; ++k) {
289 EXPECT_EQ(is_unique(result[k], k),
true);
290 EXPECT_EQ(result[k].on_curve(),
true);
296 constexpr size_t num_points = 1024;
299 for (
size_t i = 0; i < num_points; ++i) {
300 points.emplace_back(grumpkin::g1::element::random_element());
302 grumpkin::g1::element::batch_normalize(&points[0], num_points);
305 for (
size_t i = 0; i < num_points; ++i) {
306 affine_points.emplace_back(points[i]);
310 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
313 expected.reserve(num_points);
314 for (
const auto& point : points) {
315 expected.emplace_back((point * exponent).normalize());
318 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
319 std::chrono::milliseconds diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
322 start = std::chrono::steady_clock::now();
324 const auto result = grumpkin::g1::element::batch_mul_with_endomorphism(affine_points, exponent);
325 end = std::chrono::steady_clock::now();
326 diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
329 for (
size_t i = 0; i < num_points; ++i) {
330 EXPECT_EQ(result[i].x, expected[i].x);
331 EXPECT_EQ(result[i].y, expected[i].y);
339 auto beta_sqr = beta * beta;
342 for (
size_t i = 0; i < 256; i++) {
344 if (val == beta || val == beta_sqr) {
352TEST(grumpkin, CheckPrecomputedGenerators)
354 ASSERT_TRUE((bb::check_precomputed_generators<grumpkin::g1, "pedersen_hash_length", 1UL>()));
355 ASSERT_TRUE((bb::check_precomputed_generators<grumpkin::g1, "DEFAULT_DOMAIN_SEPARATOR", 8UL>()));
361TEST(grumpkin, ScalarMulNegativeK2Regression)
366 {{ 0x71922da036dca5f4, 0xd970a56127fb8227, 0x59e26bcea0d48bac, 0x0 },
"m=1"},
367 {{ 0xe3245b406db94be8, 0xb2e14ac24ff7044e, 0xb3c4d79d41a91759, 0x0 },
"m=2"},
368 {{ 0x54b688e0a495f1dc, 0x8c51f02377f28676, 0x0da7436be27da306, 0x1 },
"m=3"},
372 for (
const auto& tc : boundary_cases) {
373 grumpkin::fr base_scalar{ tc.limbs[0], tc.limbs[1], tc.limbs[2], tc.limbs[3] };
379 EXPECT_EQ(naive_result.
on_curve(),
true) << tc.tag;
380 EXPECT_EQ(endo_result.
on_curve(),
true) << tc.tag;
381 EXPECT_EQ(endo_result, naive_result) << tc.tag;
384 for (
size_t i = 0; i < 100; ++i) {
392 EXPECT_EQ(naive_res.
on_curve(),
true) << tc.tag <<
" offset " << i;
393 EXPECT_EQ(endo_res.
on_curve(),
true) << tc.tag <<
" offset " << i;
394 EXPECT_EQ(endo_res, naive_res) << tc.tag <<
" offset " << i;
constexpr bool is_point_at_infinity() const noexcept
constexpr bool on_curve() const noexcept
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
constexpr element dbl() const noexcept
BB_INLINE constexpr bool on_curve() const noexcept
BB_INLINE constexpr void self_set_infinity() noexcept
BB_INLINE constexpr bool is_point_at_infinity() const noexcept
static constexpr element one
static constexpr affine_element affine_one
group_elements::element< Fq, Fr, Params > element
static constexpr Fq curve_b
static std::vector< affine_element > derive_generators(const std::vector< uint8_t > &domain_separator_bytes, const size_t num_generators, const size_t starting_index=0)
Derives generator points via hash-to-curve.
Entry point for Barretenberg command-line interface.
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static constexpr field cube_root_of_unity()
static constexpr field one()
static field random_element(numeric::RNG *engine=nullptr) noexcept
BB_INLINE constexpr field sqr() const noexcept
static BB_INLINE void __copy(const field &a, field &r) noexcept
BB_INLINE constexpr void self_to_montgomery_form() &noexcept
static constexpr field zero()