14#include "gmock/gmock.h"
17#include <gtest/gtest.h>
22using ::testing::ElementsAreArray;
24using ::testing::Property;
29template <
typename G1>
class TestAffineElement :
public testing::Test {
30 using element =
typename G1::element;
31 using affine_element =
typename G1::affine_element;
34 static void test_read_write_buffer()
38 affine_element P = affine_element(element::random_element());
42 std::vector<uint8_t> v(65);
43 uint8_t* ptr = v.data();
44 affine_element::serialize_to_buffer(P, ptr);
47 Q = affine_element::serialize_from_buffer(ptr + 1);
48 ASSERT_FALSE(Q.on_curve() && !Q.is_point_at_infinity());
52 R = affine_element::serialize_from_buffer(ptr);
53 ASSERT_TRUE(R.on_curve());
59 affine_element P = affine_element(element::random_element());
60 P.self_set_infinity();
63 std::vector<uint8_t> v(64);
64 uint8_t* ptr = v.data();
65 affine_element::serialize_to_buffer(P, ptr);
67 R = affine_element::serialize_from_buffer(ptr);
68 ASSERT_TRUE(R.is_point_at_infinity());
73 static void test_read_and_write()
77 affine_element P = affine_element(element::random_element());
78 [[maybe_unused]] affine_element R;
80 std::vector<uint8_t> v(
sizeof(R));
81 uint8_t* ptr = v.data();
83 ASSERT_TRUE(P.on_curve());
88 const uint8_t* read_ptr = v.data();
91 ASSERT_TRUE(R.on_curve());
96 static void test_msgpack_serialization()
100 affine_element P = affine_element(element::random_element());
103 msgpack::sbuffer sbuf;
104 msgpack::pack(sbuf, P);
107 msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size());
108 msgpack::object deserialized = oh.get();
111 deserialized.convert(R);
113 ASSERT_TRUE(R.on_curve() && !R.is_point_at_infinity());
119 affine_element P = affine_element(element::random_element());
120 P.self_set_infinity();
123 msgpack::sbuffer sbuf;
124 msgpack::pack(sbuf, P);
127 msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size());
128 msgpack::object deserialized = oh.get();
131 deserialized.convert(R);
133 ASSERT_TRUE(R.is_point_at_infinity());
138 static void test_point_compression()
140 for (
size_t i = 0; i < 10; i++) {
141 affine_element P = affine_element(element::random_element());
144 compressed.
data[3] |= group_elements::UINT256_TOP_LIMB_MSB;
146 affine_element Q = affine_element::from_compressed(compressed);
151 static void test_point_compression_unsafe()
153 for (
size_t i = 0; i < 100; i++) {
154 affine_element P = affine_element(element::random_element());
160 EXPECT_EQ(P, Q_points[0]);
167 static void test_infinity_regression()
170 P.self_set_infinity();
171 affine_element R(0, P.y);
172 ASSERT_FALSE(P == R);
174 static void test_infinity_ordering_regression()
176 affine_element P(0, 1);
177 affine_element Q(0, 1);
179 P.self_set_infinity();
180 EXPECT_NE(P < Q, Q < P);
187 static void test_batch_endomorphism_by_minus_one()
193 element::batch_mul_with_endomorphism(affine_points, -affine_element::Fr::one());
196 EXPECT_EQ(affine_points[i], -result[i]);
204 static void test_fixed_point_at_infinity()
206 using Fq = affine_element::Fq;
207 affine_element P = affine_element::infinity();
210 affine_element R = affine_element(element::random_element());
217using TestTypes = testing::Types<bb::g1, grumpkin::g1, secp256k1::g1, secp256r1::g1>;
224 TestFixture::test_read_and_write();
229 TestFixture::test_read_write_buffer();
230 TestFixture::test_msgpack_serialization();
235 if constexpr (TypeParam::Fq::modulus.data[3] >= MODULUS_TOP_LIMB_LARGE_THRESHOLD) {
238 TestFixture::test_point_compression();
244 if constexpr (TypeParam::Fq::modulus.data[3] >= MODULUS_TOP_LIMB_LARGE_THRESHOLD) {
247 TestFixture::test_fixed_point_at_infinity();
253 if constexpr (TypeParam::Fq::modulus.data[3] >= MODULUS_TOP_LIMB_LARGE_THRESHOLD) {
254 TestFixture::test_point_compression_unsafe();
262 TestFixture::test_infinity_ordering_regression();
271 template <
typename Element,
typename Scalar>
276 template <
typename Element,
typename Scalar>
285TYPED_TEST(TestAffineElement, MulWithEndomorphismMatchesMulWithoutEndomorphism)
287 for (
int i = 0; i < 100; i++) {
296TEST(AffineElementFromPublicInputs, Bn254FromPublicInputs)
302 AffineElement point = AffineElement::random_element();
309 auto reconstructed = FrCodec::deserialize_from_fields<AffineElement>(limbs);
311 EXPECT_EQ(reconstructed, point);
314TEST(AffineElementFromPublicInputs, GrumpkinFromPublicInputs)
320 AffineElement point = AffineElement::random_element();
327 auto reconstructed = FrCodec::deserialize_from_fields<AffineElement>(limbs);
329 EXPECT_EQ(reconstructed, point);
334TEST(AffineElement, InfinityMulByScalarIsInfinity)
337 EXPECT_TRUE(result.is_point_at_infinity());
341TEST(AffineElement, BatchMulMatchesNonBatchMul)
343 constexpr size_t num_points = 512;
346 affine_points.push_back(grumpkin::g1::affine_element::infinity());
349 std::transform(affine_points.begin(),
352 [exponent](
const auto& el) { return el * exponent; });
355 grumpkin::g1::element::batch_mul_with_endomorphism(affine_points, exponent);
357 EXPECT_THAT(result, ElementsAreArray(expected));
361TEST(AffineElement, InfinityBatchMulByScalarIsInfinity)
363 constexpr size_t num_points = 1024;
369 EXPECT_THAT(result, Each(Property(&grumpkin::g1::affine_element::is_point_at_infinity, Eq(
true))));
374 if constexpr (TypeParam::USE_ENDOMORPHISM) {
375 TestFixture::test_batch_endomorphism_by_minus_one();
381TEST(AffineElement, HashToCurve)
386 fr(
uint256_t(
"24c4cb9c1206ab5470592f237f1698abe684dadf0ab4d7a132c32b2134e2c12e")),
387 fr(
uint256_t(
"0668b8d61a317fb34ccad55c930b3554f1828a0e5530479ecab4defe6bbc0b2e"))));
391 fr(
uint256_t(
"107f1b633c6113f3222f39f6256f0546b41a4880918c86864b06471afb410454")),
392 fr(
uint256_t(
"050cd3823d0c01590b6a50adcc85d2ee4098668fd28805578aa05a423ea938c6"))));
395 test_vectors.emplace_back(std::vector<uint8_t>{ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 },
397 fr(
uint256_t(
"037c5c229ae495f6e8d1b4bf7723fafb2b198b51e27602feb8a4d1053d685093")),
398 fr(
uint256_t(
"10cf9596c5b2515692d930efa2cf3817607e4796856a79f6af40c949b066969f"))));
401 auto result = grumpkin::g1::affine_element::hash_to_curve(
std::get<0>(test_case), 0);
static std::vector< fr > serialize_to_fields(const T &val)
Conversion from transcript values to bb::frs.
typename Group::affine_element AffineElement
static Element mul_without_endomorphism(const Element &element, const Scalar &scalar)
static Element mul_with_endomorphism(const Element &element, const Scalar &scalar)
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
element mul_with_endomorphism(const Fr &scalar) const noexcept
element mul_without_endomorphism(const Fr &scalar) const noexcept
group_elements::affine_element< Fq, Fr, Params > affine_element
constexpr bool get_bit(uint64_t bit_index) const
test_vector test_vectors[]
bb::curve::BN254::Element Element
std::conditional_t< IsGoblinBigGroup< C, Fq, Fr, G >, element_goblin::goblin_element< C, goblin_field< C >, Fr, G >, element_default::element< C, Fq, Fr, G > > element
element wraps either element_default::element or element_goblin::goblin_element depending on parametr...
Entry point for Barretenberg command-line interface.
void read(B &it, field2< base_field, Params > &value)
TYPED_TEST_SUITE(CommitmentKeyTest, Curves)
field< Bn254FrParams > fr
void write(B &buf, field2< base_field, Params > const &value)
TYPED_TEST(CommitmentKeyTest, CommitToZeroPoly)
TEST(BoomerangMegaCircuitBuilder, BasicCircuit)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
testing::Types< VKTestParams< UltraFlavor, stdlib::recursion::honk::DefaultIO< UltraCircuitBuilder > >, VKTestParams< UltraFlavor, stdlib::recursion::honk::RollupIO >, VKTestParams< UltraKeccakFlavor, stdlib::recursion::honk::DefaultIO< UltraCircuitBuilder > >, VKTestParams< MegaFlavor, stdlib::recursion::honk::DefaultIO< MegaCircuitBuilder > > > TestTypes
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()