32using Curves = ::testing::Types<curve::BN254, curve::Grumpkin>;
38 using Curve = TypeParam;
43 constexpr size_t num_points = 20;
44 AffineElement* points = (AffineElement*)(aligned_alloc(64,
sizeof(AffineElement) * (num_points)));
45 Fq* scratch_space = (
Fq*)(aligned_alloc(64,
sizeof(
Fq) * (num_points * 2)));
46 Fq* lambda = (
Fq*)(aligned_alloc(64,
sizeof(
Fq) * (num_points * 2)));
49 for (
size_t i = 0; i < num_points; ++i) {
50 points[i] = AffineElement(Element::random_element());
51 points_copy[i].x = points[i].x;
52 points_copy[i].y = points[i].y;
56 size_t count = num_points - 1;
57 for (
size_t i = num_points - 2; i < num_points; i -= 2) {
58 points_copy[count--] = points_copy[i] + points_copy[i + 1];
59 points_copy[count + 1] = points_copy[count + 1].normalize();
63 for (
size_t i = num_points - 1; i > num_points - 1 - (num_points / 2); --i) {
64 EXPECT_EQ((points[i].x == points_copy[i].x),
true);
65 EXPECT_EQ((points[i].y == points_copy[i].y),
true);
69 aligned_free(points_copy);
70 aligned_free(scratch_space);
75 using Curve = TypeParam;
84 Element expected = Group::one * scalar;
91 Element t1 = Group::affine_one * k1;
92 AffineElement generator = Group::affine_one;
94 generator.x = generator.x * beta;
95 generator.y = -generator.y;
99 EXPECT_EQ(result == expected,
true);
104 using Curve = TypeParam;
108 constexpr size_t target_degree = 1 << 8;
110 Fr* scalars = (
Fr*)(aligned_alloc(64,
sizeof(
Fr) * target_degree));
113 for (
size_t i = 0; i < target_degree; ++i) {
120 for (uint32_t i = 0; i < num_rounds; ++i) {
122 std::vector<uint64_t> scalar_slices(target_degree);
123 std::vector<uint64_t> sorted_scalar_slices(target_degree);
125 for (
size_t j = 0; j < target_degree; ++j) {
127 sorted_scalar_slices[j] = scalar_slices[j];
130 &sorted_scalar_slices[0], target_degree,
static_cast<uint32_t
>(bits_per_slice));
132 const auto find_entry = [scalar_slices, num_entries = target_degree](
auto x) {
133 for (
size_t k = 0; k < num_entries; ++k) {
134 if (scalar_slices[k] == x) {
140 for (
size_t j = 0; j < target_degree; ++j) {
141 EXPECT_EQ(find_entry(sorted_scalar_slices[j]),
true);
143 EXPECT_EQ((sorted_scalar_slices[j] & 0x7fffffffU) >= (sorted_scalar_slices[j - 1] & 0x7fffffffU),
true);
153 using Curve = TypeParam;
156 GTEST_SKIP() <<
"Skipping test for grumpkin";
165 size_t target_degree = 1200000;
168 Fr* scalars = (
Fr*)(aligned_alloc(64,
sizeof(
Fr) * target_degree));
171 Fr accumulator = source_scalar;
172 for (
size_t i = 0; i < target_degree; ++i) {
173 accumulator *= source_scalar;
177 Element first = scalar_multiplication::pippenger<Curve>({ 0, { scalars, target_degree } }, monomials);
178 first = first.normalize();
180 for (
size_t i = 0; i < target_degree; ++i) {
184 Element second = scalar_multiplication::pippenger<Curve>(
186 second = second.normalize();
188 EXPECT_EQ((first.z == second.z),
true);
189 EXPECT_EQ((first.z ==
Fq::one()),
true);
190 EXPECT_EQ((first.x == second.x),
true);
191 EXPECT_EQ((first.y == -second.y),
true);
193 aligned_free(scalars);
198 using Curve = TypeParam;
205 size_t num_points = 17;
207 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr) * num_points);
209 AffineElement* points = (AffineElement*)aligned_alloc(32,
sizeof(AffineElement) * (num_points * 2 + 1));
211 for (
size_t i = 0; i < num_points; ++i) {
213 points[i] = AffineElement(Element::random_element());
217 expected.self_set_infinity();
218 for (
size_t i = 0; i < num_points; ++i) {
219 Element temp = points[i] * scalars[i];
222 expected = expected.normalize();
224 Element result = scalar_multiplication::pippenger<Curve>({ 0, { scalars, num_points } },
225 { points, num_points * 2 });
226 result = result.normalize();
228 aligned_free(scalars);
229 aligned_free(points);
231 EXPECT_EQ(result == expected,
true);
236 using Curve = TypeParam;
241 constexpr size_t num_points = 8192;
243 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr) * num_points);
245 AffineElement* points = (AffineElement*)aligned_alloc(32,
sizeof(AffineElement) * (num_points * 2 + 1));
247 for (
size_t i = 0; i < num_points; ++i) {
249 points[i] = AffineElement(Element::random_element());
253 expected.self_set_infinity();
254 for (
size_t i = 0; i < num_points; ++i) {
255 Element temp = points[i] * scalars[i];
258 expected = expected.normalize();
260 Element result = scalar_multiplication::pippenger<Curve>({ 0, { scalars, num_points } },
261 { points, num_points });
262 result = result.normalize();
264 aligned_free(scalars);
265 aligned_free(points);
267 EXPECT_EQ(result == expected,
true);
272 using Curve = TypeParam;
277 constexpr size_t num_points = 128;
279 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr) * num_points);
281 AffineElement* points = (AffineElement*)aligned_alloc(32,
sizeof(AffineElement) * (num_points * 2 + 1));
283 AffineElement point = AffineElement(Element::random_element());
284 for (
size_t i = 0; i < num_points; ++i) {
290 expected.self_set_infinity();
291 for (
size_t i = 0; i < num_points; ++i) {
292 Element temp = points[i] * scalars[i];
295 if (!expected.is_point_at_infinity()) {
296 expected = expected.normalize();
298 Element result = scalar_multiplication::pippenger<Curve>({ 0, { scalars, num_points } },
299 { points, num_points * 2 });
300 result = result.normalize();
302 aligned_free(scalars);
303 aligned_free(points);
305 EXPECT_EQ(result == expected,
true);
310 using Curve = TypeParam;
315 constexpr size_t num_points = 8192;
317 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr) * num_points);
319 std::vector<AffineElement> points(num_points);
321 for (
size_t i = 0; i < num_points; ++i) {
322 points[i] = AffineElement(Element::random_element());
324 for (
size_t i = 0; i < (num_points / 4); ++i) {
330 scalars[i * 4 + 1].
data[0] = 0;
331 scalars[i * 4 + 1].
data[1] = 0;
332 scalars[i * 4 + 1].
data[2] = 0;
333 scalars[i * 4 + 1].
data[3] = 0;
337 scalars[i * 4 + 2].
data[2] = 0;
338 scalars[i * 4 + 2].
data[3] = 0;
341 scalars[i * 4 + 3].
data[1] = 0;
342 scalars[i * 4 + 3].
data[2] = 0;
343 scalars[i * 4 + 3].
data[3] = 0;
348 expected.self_set_infinity();
349 for (
size_t i = 0; i < num_points; ++i) {
350 Element temp = points[i] * scalars[i];
353 expected = expected.normalize();
355 Element result = scalar_multiplication::pippenger<Curve>({ 0, { scalars, num_points } }, points);
356 result = result.normalize();
358 aligned_free(scalars);
360 EXPECT_EQ(result == expected,
true);
365 using Curve = TypeParam;
370 constexpr size_t num_points = 8192;
372 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr) * num_points);
374 std::vector<AffineElement> points(num_points);
376 for (
size_t i = 0; i < num_points; ++i) {
378 points[i] = AffineElement(Element::random_element());
382 expected.self_set_infinity();
383 for (
size_t i = 0; i < num_points; ++i) {
384 Element temp = points[i] * scalars[i];
387 expected = expected.normalize();
388 Element result = scalar_multiplication::pippenger_unsafe<Curve>({ 0, { scalars, num_points } }, points);
389 result = result.normalize();
391 aligned_free(scalars);
393 EXPECT_EQ(result == expected,
true);
398 using Curve = TypeParam;
403 constexpr size_t num_points = 8192;
405 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr) * num_points);
407 AffineElement* points = (AffineElement*)aligned_alloc(32,
sizeof(AffineElement) * (num_points * 2 + 1));
409 for (
size_t i = 0; i < num_points; ++i) {
410 points[i] = AffineElement(Element::random_element());
412 for (
size_t i = 0; i < (num_points / 4); ++i) {
418 scalars[i * 4 + 1].
data[0] = 0;
419 scalars[i * 4 + 1].
data[1] = 0;
420 scalars[i * 4 + 1].
data[2] = 0;
421 scalars[i * 4 + 1].
data[3] = 0;
425 scalars[i * 4 + 2].
data[2] = 0;
426 scalars[i * 4 + 2].
data[3] = 0;
429 scalars[i * 4 + 3].
data[1] = 0;
430 scalars[i * 4 + 3].
data[2] = 0;
431 scalars[i * 4 + 3].
data[3] = 0;
436 expected.self_set_infinity();
437 for (
size_t i = 0; i < num_points; ++i) {
438 Element temp = points[i] * scalars[i];
441 expected = expected.normalize();
443 Element result = scalar_multiplication::pippenger_unsafe<Curve>({ 0, { scalars, num_points } },
444 { points, num_points * 2 + 1 });
445 result = result.normalize();
447 aligned_free(scalars);
448 aligned_free(points);
450 EXPECT_EQ(result == expected,
true);
455 using Curve = TypeParam;
460 size_t num_points = 1;
462 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr) * 1);
464 AffineElement* points = (AffineElement*)aligned_alloc(32,
sizeof(AffineElement) * (num_points * 2 + 1));
466 for (
size_t i = 0; i < num_points; ++i) {
468 points[i] = AffineElement(Element::random_element());
472 expected.self_set_infinity();
473 for (
size_t i = 0; i < num_points; ++i) {
474 Element temp = points[i] * scalars[i];
477 expected = expected.normalize();
479 Element result = scalar_multiplication::pippenger<Curve>({ 0, { scalars, num_points } },
480 { points, num_points * 2 });
481 result = result.normalize();
483 aligned_free(scalars);
484 aligned_free(points);
486 EXPECT_EQ(result == expected,
true);
491 using Curve = TypeParam;
496 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr));
498 AffineElement* points = (AffineElement*)aligned_alloc(32,
sizeof(AffineElement) * (2 + 1));
500 Element result = scalar_multiplication::pippenger<Curve>({ 0, { scalars, 0 } }, { points, 0 });
502 aligned_free(scalars);
503 aligned_free(points);
505 EXPECT_EQ(result.is_point_at_infinity(),
true);
510 using Curve = TypeParam;
516 Fr* scalars = (
Fr*)aligned_alloc(32,
sizeof(
Fr));
518 AffineElement* points = (AffineElement*)aligned_alloc(32,
sizeof(AffineElement) * (2 + 1));
521 points[0] = Group::affine_one;
522 Element result = scalar_multiplication::pippenger<Curve>({ 0, { scalars, 1 } }, { points, 2 });
524 aligned_free(scalars);
525 aligned_free(points);
527 EXPECT_EQ(result.is_point_at_infinity(),
true);
static void SetUpTestSuite()
typename Group::element Element
typename grumpkin::g1 Group
typename Group::affine_element AffineElement
virtual uint32_t get_random_uint32()=0
static uint32_t get_scalar_slice(const ScalarField &scalar, size_t round, size_t slice_size) noexcept
Extract c-bit slice from scalar for bucket index computation.
static void add_affine_points(AffineElement *points, const size_t num_points, typename Curve::BaseField *scratch_space) noexcept
Batch add n/2 independent point pairs using Montgomery's trick.
static uint32_t get_num_rounds(size_t num_points) noexcept
static uint32_t get_optimal_log_num_buckets(size_t num_points) noexcept
Compute optimal bits per slice by minimizing cost over c in [1, MAX_SLICE_BITS)
bb::curve::BN254::Element Element
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
size_t sort_point_schedule_and_count_zero_buckets(uint64_t *point_schedule, const size_t num_entries, const uint32_t bucket_index_bits) noexcept
Sort point schedule by bucket index and count zero-bucket entries.
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
::testing::Types< curve::BN254, curve::Grumpkin > Curves
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static constexpr field cube_root_of_unity()
static constexpr field one()
BB_INLINE constexpr field to_montgomery_form() const noexcept
static void split_into_endomorphism_scalars(const field &k, field &k1, field &k2)
Full-width endomorphism decomposition: k ≡ k1 - k2·λ (mod r). Modifies the field elements k1 and k2.
BB_INLINE constexpr void self_sqr() &noexcept
BB_INLINE constexpr void self_neg() &noexcept
static field random_element(numeric::RNG *engine=nullptr) noexcept
static BB_INLINE void __copy(const field &a, field &r) noexcept
static constexpr field zero()