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);
34 EXPECT_EQ(seventeen, -
b);
37TEST(grumpkin, SubgroupGenerator)
42 EXPECT_NE(subgroup_generator.
pow(3),
fq::one());
43 EXPECT_NE(subgroup_generator.
pow(29),
fq::one());
44 EXPECT_EQ(subgroup_generator.
pow(87),
fq::one());
45 EXPECT_EQ(subgroup_generator * subgroup_generator_inverse,
fq::one());
48TEST(grumpkin, OneYIsCorrect)
53 EXPECT_EQ(one_y, -expected);
60TEST(grumpkin, RandomElement)
66TEST(grumpkin, RandomAffineElement)
77 EXPECT_EQ(
a ==
b,
true);
78 EXPECT_EQ(
a ==
a,
true);
80 b.self_set_infinity();
82 EXPECT_EQ(
a ==
b,
false);
85 EXPECT_EQ(
a == c,
false);
87 a.self_set_infinity();
89 EXPECT_EQ(
a ==
b,
true);
92TEST(grumpkin, CheckGroupModulus)
103TEST(grumpkin, AddExceptionTestInfinity)
119 result = lhs + rhs_b;
121 EXPECT_EQ(lhs == result,
true);
126 EXPECT_EQ(rhs == result,
true);
129TEST(grumpkin, AddExceptionTestDbl)
139 expected = lhs.
dbl();
141 EXPECT_EQ(result == expected,
true);
144TEST(grumpkin, AddDblConsistency)
159 dbl_result =
a.dbl();
161 EXPECT_EQ(add_result == dbl_result,
true);
164TEST(grumpkin, AddDblConsistencyRepeated)
184 EXPECT_EQ(result == expected,
true);
187TEST(grumpkin, MixedAddExceptionTestInfinity)
204 EXPECT_EQ(rhs_c == result,
true);
207TEST(grumpkin, MixedAddExceptionTestDbl)
217 expected = lhs.
dbl();
219 EXPECT_EQ(result == expected,
true);
222TEST(grumpkin, AddMixedAddConsistencyCheck)
231 add_result = lhs + rhs_b;
232 mixed_add_result = lhs + rhs;
234 EXPECT_EQ(add_result == mixed_add_result,
true);
239 for (
size_t i = 0; i < 100; ++i) {
243 EXPECT_EQ(affine_test.
on_curve(),
true);
248 size_t num_points = 2;
251 for (
size_t i = 0; i < num_points; ++i) {
255 normalized[i] = points[i];
257 grumpkin::g1::element::batch_normalize(&normalized[0], num_points);
259 for (
size_t i = 0; i < num_points; ++i) {
264 zz = points[i].z.
sqr();
265 zzz = points[i].z * zz;
266 result_x = normalized[i].x * zz;
267 result_y = normalized[i].y * zzz;
269 EXPECT_EQ((result_x == points[i].x),
true);
270 EXPECT_EQ((result_y == points[i].y),
true);
274TEST(grumpkin, GroupExponentiationZeroAndOne)
285TEST(grumpkin, GroupExponentiationConsistencyCheck)
299 EXPECT_EQ(result == expected,
true);
302TEST(grumpkin, DeriveGenerators)
304 constexpr size_t num_generators = 128;
307 for (
size_t i = 0; i < result.size(); ++i) {
308 if ((i != j) && result[i] == y) {
315 for (
size_t k = 0; k < num_generators; ++k) {
316 EXPECT_EQ(is_unique(result[k], k),
true);
317 EXPECT_EQ(result[k].on_curve(),
true);
323 constexpr size_t num_points = 1024;
326 for (
size_t i = 0; i < num_points; ++i) {
327 points.emplace_back(grumpkin::g1::element::random_element());
329 grumpkin::g1::element::batch_normalize(&points[0], num_points);
332 for (
size_t i = 0; i < num_points; ++i) {
333 affine_points.emplace_back(points[i]);
337 std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
340 expected.reserve(num_points);
341 for (
const auto& point : points) {
342 expected.emplace_back((point * exponent).normalize());
345 std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();
346 std::chrono::milliseconds diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
349 start = std::chrono::steady_clock::now();
351 const auto result = grumpkin::g1::element::batch_mul_with_endomorphism(affine_points, exponent);
352 end = std::chrono::steady_clock::now();
353 diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
356 for (
size_t i = 0; i < num_points; ++i) {
357 EXPECT_EQ(result[i].x, expected[i].x);
358 EXPECT_EQ(result[i].y, expected[i].y);
366 auto beta_sqr = beta * beta;
369 for (
size_t i = 0; i < 256; i++) {
371 if (val == beta || val == beta_sqr) {
379TEST(grumpkin, CheckPrecomputedGenerators)
381 ASSERT_TRUE((bb::check_precomputed_generators<grumpkin::g1, "pedersen_hash_length", 1UL>()));
382 ASSERT_TRUE((bb::check_precomputed_generators<grumpkin::g1, "DEFAULT_DOMAIN_SEPARATOR", 8UL>()));
388TEST(grumpkin, ScalarMulNegativeK2Regression)
393 {{ 0x71922da036dca5f4, 0xd970a56127fb8227, 0x59e26bcea0d48bac, 0x0 },
"m=1"},
394 {{ 0xe3245b406db94be8, 0xb2e14ac24ff7044e, 0xb3c4d79d41a91759, 0x0 },
"m=2"},
395 {{ 0x54b688e0a495f1dc, 0x8c51f02377f28676, 0x0da7436be27da306, 0x1 },
"m=3"},
399 for (
const auto& tc : boundary_cases) {
400 grumpkin::fr base_scalar{ tc.limbs[0], tc.limbs[1], tc.limbs[2], tc.limbs[3] };
406 EXPECT_EQ(naive_result.
on_curve(),
true) << tc.tag;
407 EXPECT_EQ(endo_result.
on_curve(),
true) << tc.tag;
408 EXPECT_EQ(endo_result, naive_result) << tc.tag;
411 for (
size_t i = 0; i < 100; ++i) {
419 EXPECT_EQ(naive_res.
on_curve(),
true) << tc.tag <<
" offset " << i;
420 EXPECT_EQ(endo_res.
on_curve(),
true) << tc.tag <<
" offset " << i;
421 EXPECT_EQ(endo_res, naive_res) << tc.tag <<
" offset " << i;
static constexpr ScalarField subgroup_generator_inverse
static constexpr ScalarField subgroup_generator
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()
BB_INLINE constexpr field pow(const uint256_t &exponent) const noexcept
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()
static constexpr bb::fr one_y
static constexpr bb::fr b