13#include "gmock/gmock.h"
16#include <gtest/gtest.h>
21using ::testing::ElementsAreArray;
23using ::testing::Property;
28template <
typename G1>
class TestAffineElement :
public testing::Test {
29 using element =
typename G1::element;
33 static void test_read_write_buffer()
41 std::vector<uint8_t> v(65);
42 uint8_t* ptr = v.data();
62 std::vector<uint8_t> v(64);
63 uint8_t* ptr = v.data();
72 static void test_read_and_write()
79 std::vector<uint8_t> v(
sizeof(R));
80 uint8_t* ptr = v.data();
87 const uint8_t* read_ptr = v.data();
95 static void test_msgpack_serialization()
102 msgpack::sbuffer sbuf;
103 msgpack::pack(sbuf, P);
106 msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size());
107 msgpack::object deserialized = oh.get();
110 deserialized.convert(R);
122 msgpack::sbuffer sbuf;
123 msgpack::pack(sbuf, P);
126 msgpack::object_handle oh = msgpack::unpack(sbuf.data(), sbuf.size());
127 msgpack::object deserialized = oh.get();
130 deserialized.convert(R);
137 static void test_point_compression()
139 for (
size_t i = 0; i < 10; i++) {
147 static void test_point_compression_unsafe()
149 for (
size_t i = 0; i < 100; i++) {
156 EXPECT_EQ(P, Q_points[0]);
163 static void test_infinity_regression()
168 ASSERT_FALSE(P == R);
172 static void test_infinity_ordering_regression()
178 EXPECT_NE(P < Q, Q < P);
185 static void test_batch_endomorphism_by_minus_one()
187 constexpr size_t num_points = 2;
193 for (
size_t i = 0; i < num_points; i++) {
194 EXPECT_EQ(affine_points[i], -result[i]);
202 static void test_fixed_point_at_infinity()
215using TestTypes = testing::Types<bb::g1, grumpkin::g1, secp256k1::g1, secp256r1::g1>;
222 TestFixture::test_read_and_write();
227 TestFixture::test_read_write_buffer();
228 TestFixture::test_msgpack_serialization();
233 if constexpr (TypeParam::Fq::modulus.data[3] >= 0x4000000000000000ULL) {
236 TestFixture::test_point_compression();
242 if constexpr (TypeParam::Fq::modulus.data[3] >= 0x4000000000000000ULL) {
245 TestFixture::test_fixed_point_at_infinity();
251 if constexpr (TypeParam::Fq::modulus.data[3] >= 0x4000000000000000ULL) {
252 TestFixture::test_point_compression_unsafe();
260 TestFixture::test_infinity_ordering_regression();
269 template <
typename Element,
typename Scalar>
274 template <
typename Element,
typename Scalar>
283TYPED_TEST(TestAffineElement, MulWithEndomorphismMatchesMulWithoutEndomorphism)
285 for (
int i = 0; i < 100; i++) {
294TEST(AffineElementFromPublicInputs, Bn254FromPublicInputs)
301 AffineElement point = AffineElement::random_element();
306 std::vector<Fr> public_inputs;
309 auto limb = x.
slice(index, index + bb::stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION);
310 public_inputs.emplace_back(
Fr(limb));
311 index += bb::stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION;
315 auto limb = y.
slice(index, index + bb::stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION);
316 public_inputs.emplace_back(
Fr(limb));
317 index += bb::stdlib::NUM_LIMB_BITS_IN_FIELD_SIMULATION;
322 auto reconstructed = AffineElement::reconstruct_from_public(limbs);
324 EXPECT_EQ(reconstructed, point);
327TEST(AffineElementFromPublicInputs, GrumpkinFromPublicInputs)
333 AffineElement point = AffineElement::random_element();
340 auto reconstructed = AffineElement::reconstruct_from_public(limbs);
342 EXPECT_EQ(reconstructed, point);
347TEST(AffineElement, InfinityMulByScalarIsInfinity)
350 EXPECT_TRUE(result.is_point_at_infinity());
354TEST(AffineElement, BatchMulMatchesNonBatchMul)
356 constexpr size_t num_points = 512;
359 affine_points.push_back(grumpkin::g1::affine_element::infinity());
362 std::transform(affine_points.begin(),
365 [exponent](
const auto& el) { return el * exponent; });
368 grumpkin::g1::element::batch_mul_with_endomorphism(affine_points, exponent);
370 EXPECT_THAT(result, ElementsAreArray(expected));
374TEST(AffineElement, InfinityBatchMulByScalarIsInfinity)
376 constexpr size_t num_points = 1024;
382 EXPECT_THAT(result, Each(Property(&grumpkin::g1::affine_element::is_point_at_infinity, Eq(
true))));
387 if constexpr (TypeParam::USE_ENDOMORPHISM) {
388 TestFixture::test_batch_endomorphism_by_minus_one();
394TEST(AffineElement, HashToCurve)
399 fr(
uint256_t(
"24c4cb9c1206ab5470592f237f1698abe684dadf0ab4d7a132c32b2134e2c12e")),
400 fr(
uint256_t(
"0668b8d61a317fb34ccad55c930b3554f1828a0e5530479ecab4defe6bbc0b2e"))));
404 fr(
uint256_t(
"107f1b633c6113f3222f39f6256f0546b41a4880918c86864b06471afb410454")),
405 fr(
uint256_t(
"050cd3823d0c01590b6a50adcc85d2ee4098668fd28805578aa05a423ea938c6"))));
408 test_vectors.emplace_back(std::vector<uint8_t>{ 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x77, 0x6f, 0x72, 0x6c, 0x64 },
410 fr(
uint256_t(
"037c5c229ae495f6e8d1b4bf7723fafb2b198b51e27602feb8a4d1053d685093")),
411 fr(
uint256_t(
"10cf9596c5b2515692d930efa2cf3817607e4796856a79f6af40c949b066969f"))));
414 auto result = grumpkin::g1::affine_element::hash_to_curve(
std::get<0>(test_case), 0);
testing::Types< TestType< stdlib::bn254< bb::UltraCircuitBuilder >, UseBigfield::Yes >, TestType< stdlib::bn254< bb::MegaCircuitBuilder >, UseBigfield::No > > TestTypes
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)
static constexpr std::array< affine_element, 2 > from_compressed_unsafe(const uint256_t &compressed) noexcept
Reconstruct a point in affine coordinates from compressed form.
constexpr bool is_point_at_infinity() const noexcept
static affine_element infinity()
constexpr uint256_t compress() const noexcept
static affine_element serialize_from_buffer(const uint8_t *buffer, bool write_x_first=false)
Restore point from a buffer.
constexpr void self_set_infinity() noexcept
static constexpr affine_element from_compressed(const uint256_t &compressed) noexcept
Reconstruct a point in affine coordinates from compressed form.
constexpr bool on_curve() const noexcept
static constexpr affine_element one() noexcept
static void serialize_to_buffer(const affine_element &value, uint8_t *buffer, bool write_x_first=false)
Serialize the point to the given buffer.
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 uint256_t slice(uint64_t start, uint64_t end) const
test_vector test_vectors[]
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(ShpleminiTest, TestSettings)
TEST(MegaCircuitBuilder, CopyConstructor)
field< Bn254FrParams > fr
void write(B &buf, field2< base_field, Params > const &value)
TYPED_TEST(ShpleminiTest, CorrectnessOfMultivariateClaimBatching)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static constexpr size_t PUBLIC_INPUTS_SIZE
static field random_element(numeric::RNG *engine=nullptr) noexcept
static constexpr field zero()