Do a better job testing EC_POINT_cmp. If EC_POINT_cmp always returns points are equal, our tests barely notice. Change-Id: I1a78d95af2fad3d97c2db013468d34159807ff21 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/40664 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/ec/ec_test.cc b/crypto/fipsmodule/ec/ec_test.cc index 95b3db0..586b0b3 100644 --- a/crypto/fipsmodule/ec/ec_test.cc +++ b/crypto/fipsmodule/ec/ec_test.cc
@@ -554,6 +554,60 @@ EXPECT_TRUE(EC_POINT_is_on_curve(group(), p.get(), nullptr)); } +TEST_P(ECCurveTest, Compare) { + bssl::UniquePtr<EC_KEY> key1(EC_KEY_new_by_curve_name(GetParam().nid)); + ASSERT_TRUE(key1); + ASSERT_TRUE(EC_KEY_generate_key(key1.get())); + const EC_POINT *pub1 = EC_KEY_get0_public_key(key1.get()); + + bssl::UniquePtr<EC_KEY> key2(EC_KEY_new_by_curve_name(GetParam().nid)); + ASSERT_TRUE(key2); + ASSERT_TRUE(EC_KEY_generate_key(key2.get())); + const EC_POINT *pub2 = EC_KEY_get0_public_key(key2.get()); + + // Two different points should not compare as equal. + EXPECT_EQ(1, EC_POINT_cmp(group(), pub1, pub2, nullptr)); + + // Serialize |pub1| and parse it back out. This gives a point in affine + // coordinates. + std::vector<uint8_t> serialized; + ASSERT_TRUE( + EncodeECPoint(&serialized, group(), pub1, POINT_CONVERSION_UNCOMPRESSED)); + bssl::UniquePtr<EC_POINT> p(EC_POINT_new(group())); + ASSERT_TRUE(p); + ASSERT_TRUE(EC_POINT_oct2point(group(), p.get(), serialized.data(), + serialized.size(), nullptr)); + + // The points should be equal. + EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), pub1, nullptr)); + + // Add something to the point. It no longer compares as equal. + ASSERT_TRUE(EC_POINT_add(group(), p.get(), p.get(), pub2, nullptr)); + EXPECT_EQ(1, EC_POINT_cmp(group(), p.get(), pub1, nullptr)); + + // Negate |pub2|. It should no longer compare as equal. This tests that we + // check both x and y coordinate. + bssl::UniquePtr<EC_POINT> q(EC_POINT_new(group())); + ASSERT_TRUE(q); + ASSERT_TRUE(EC_POINT_copy(q.get(), pub2)); + ASSERT_TRUE(EC_POINT_invert(group(), q.get(), nullptr)); + EXPECT_EQ(1, EC_POINT_cmp(group(), q.get(), pub2, nullptr)); + + // Return |p| to the original value. It should be equal to |pub1| again. + ASSERT_TRUE(EC_POINT_add(group(), p.get(), p.get(), q.get(), nullptr)); + EXPECT_EQ(0, EC_POINT_cmp(group(), p.get(), pub1, nullptr)); + + // Infinity compares as equal to itself, but not other points. + bssl::UniquePtr<EC_POINT> inf1(EC_POINT_new(group())), + inf2(EC_POINT_new(group())); + ASSERT_TRUE(inf1); + ASSERT_TRUE(EC_POINT_set_to_infinity(group(), inf1.get())); + // |q| is currently -|pub2|. + ASSERT_TRUE(EC_POINT_add(group(), inf2.get(), pub2, q.get(), nullptr)); + EXPECT_EQ(0, EC_POINT_cmp(group(), inf1.get(), inf2.get(), nullptr)); + EXPECT_EQ(1, EC_POINT_cmp(group(), inf1.get(), p.get(), nullptr)); +} + TEST_P(ECCurveTest, GenerateFIPS) { // Generate an EC_KEY. bssl::UniquePtr<EC_KEY> key(EC_KEY_new_by_curve_name(GetParam().nid));