Skip to content

Commit

Permalink
add support for EC_POINT_bn2point
Browse files Browse the repository at this point in the history
  • Loading branch information
samuel40791765 committed Jun 19, 2024
1 parent 6b26139 commit 76907cd
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 21 deletions.
41 changes: 41 additions & 0 deletions crypto/ec_extra/ec_asn1.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,3 +614,44 @@ BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, const EC_POINT *point,

return ret;
}

EC_POINT *EC_POINT_bn2point(const EC_GROUP *group,
const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) {
EC_POINT *ret = NULL;

// Allocate buffer and length.
size_t buf_len = BN_num_bytes(bn);
if (buf_len == 0) {
buf_len = 1;
}
uint8_t *buf = OPENSSL_malloc(buf_len);
if (buf == NULL) {
return NULL;
}

if (BN_bn2bin_padded(buf, buf_len,bn) < 0) {
goto end;
}

// Allocate new |EC_POINT| if |point| is NULL. Otherwise, use |point|.
if (point == NULL) {
ret = EC_POINT_new(group);
if (ret == NULL) {
goto end;
}
} else {
ret = point;
}

if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) {
if (ret != point) {
// Free the newly allocated |EC_POINT| on failure.
EC_POINT_free(ret);
}
goto end;
}

end:
OPENSSL_free(buf);
return ret;
}
71 changes: 51 additions & 20 deletions crypto/fipsmodule/ec/ec_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1034,27 +1034,58 @@ TEST(ECTest, ArbitraryCurve) {
ASSERT_TRUE(EC_GROUP_set_generator(group2.get(), generator2.get(),
order.get(), BN_value_one()));

EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group.get(), NULL));
EXPECT_EQ(0, EC_GROUP_cmp(group2.get(), group.get(), NULL));

bssl::UniquePtr<BIGNUM> converted_generator1(EC_POINT_point2bn(
group.get(), generator.get(), POINT_CONVERSION_UNCOMPRESSED, NULL, NULL));
ASSERT_TRUE(converted_generator1);

bssl::UniquePtr<BIGNUM> converted_generator2(EC_POINT_point2bn(
group2.get(), generator2.get(), POINT_CONVERSION_UNCOMPRESSED, NULL, NULL));
EXPECT_EQ(0, EC_GROUP_cmp(group.get(), group.get(), nullptr));
EXPECT_EQ(0, EC_GROUP_cmp(group2.get(), group.get(), nullptr));

// Convert |EC_POINT| to |BIGNUM| in uncompressed format with
// |EC_POINT_point2bn| and ensure results are the same.
bssl::UniquePtr<BIGNUM> converted_bignum(
EC_POINT_point2bn(group.get(), generator.get(),
POINT_CONVERSION_UNCOMPRESSED, nullptr, nullptr));
ASSERT_TRUE(converted_bignum);
bssl::UniquePtr<BIGNUM> converted_bignum2(
EC_POINT_point2bn(group2.get(), generator2.get(),
POINT_CONVERSION_UNCOMPRESSED, nullptr, nullptr));
ASSERT_TRUE(converted_bignum2);
EXPECT_EQ(0, BN_cmp(converted_bignum.get(), converted_bignum2.get()));

// Convert |BIGNUM| back to |EC_POINTS| with |EC_POINT_bn2point| and ensure
// output is identical to the original.
bssl::UniquePtr<EC_POINT> converted_generator(
EC_POINT_bn2point(group.get(), converted_bignum.get(), nullptr, nullptr));
ASSERT_TRUE(converted_generator);
EXPECT_EQ(0, EC_POINT_cmp(group.get(), generator.get(),
converted_generator.get(), nullptr));
bssl::UniquePtr<EC_POINT> converted_generator2(EC_POINT_bn2point(
group2.get(), converted_bignum2.get(), nullptr, nullptr));
ASSERT_TRUE(converted_generator2);
EXPECT_EQ(0, BN_cmp(converted_generator1.get(), converted_generator2.get()));

bssl::UniquePtr<BIGNUM> converted_generator3(EC_POINT_point2bn(
group.get(), generator.get(), POINT_CONVERSION_COMPRESSED, NULL, NULL));
ASSERT_TRUE(converted_generator3);

bssl::UniquePtr<BIGNUM> converted_generator4(EC_POINT_point2bn(
group2.get(), generator2.get(), POINT_CONVERSION_COMPRESSED, NULL, NULL));
ASSERT_TRUE(converted_generator4);
EXPECT_EQ(0, BN_cmp(converted_generator3.get(), converted_generator4.get()));

EXPECT_EQ(0, EC_POINT_cmp(group2.get(), generator2.get(),
converted_generator2.get(), nullptr));

// Convert |EC_POINT|s in compressed format with |EC_POINT_point2bn| and
// ensure results are the same.
converted_bignum.reset(EC_POINT_point2bn(group.get(), generator.get(),
POINT_CONVERSION_COMPRESSED, nullptr,
nullptr));
ASSERT_TRUE(converted_bignum);
converted_bignum2.reset(EC_POINT_point2bn(group2.get(), generator2.get(),
POINT_CONVERSION_COMPRESSED,
nullptr, nullptr));
ASSERT_TRUE(converted_bignum2);
EXPECT_EQ(0, BN_cmp(converted_bignum.get(), converted_bignum2.get()));

// Convert |BIGNUM| back to |EC_POINTS| with |EC_POINT_bn2point| and ensure
// output is identical to the original.
converted_generator.reset(
EC_POINT_bn2point(group.get(), converted_bignum.get(), nullptr, nullptr));
ASSERT_TRUE(converted_generator);
EXPECT_EQ(0, EC_POINT_cmp(group.get(), generator.get(),
converted_generator.get(), nullptr));
converted_generator2.reset(EC_POINT_bn2point(
group2.get(), converted_bignum2.get(), nullptr, nullptr));
ASSERT_TRUE(converted_generator2);
EXPECT_EQ(0, EC_POINT_cmp(group2.get(), generator2.get(),
converted_generator2.get(), nullptr));

// group3 uses the wrong generator.
bssl::UniquePtr<EC_GROUP> group3(
Expand Down
9 changes: 8 additions & 1 deletion include/openssl/ec.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,14 +393,21 @@ OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group,


// EC_POINT_point2bn converts an |EC_POINT| to a |BIGNUM| by serializing the
// point into the X9.62 form given by |form| then interpretting it as a BIGNUM.
// point into the X9.62 form given by |form| then interpreting it as a BIGNUM.
// On success, it returns the BIGNUM pointer supplied or, if |ret| is NULL,
// allocates and returns a fresh |BIGNUM|. On error, it returns NULL. The |ctx|
// argument may be used if not NULL.
OPENSSL_EXPORT OPENSSL_DEPRECATED BIGNUM *EC_POINT_point2bn(
const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form,
BIGNUM *ret, BN_CTX *ctx);

// EC_POINT_bn2point is like |EC_POINT_point2bn|, but converts a |BIGNUM| to an
// |EC_POINT| instead. On success, it returns the EC_POINT pointer supplied or,
// if |ret| is NULL, allocates and returns a fresh |EC_POINT|. On error, it
// returns NULL. The |ctx| argument may be used if not NULL.
OPENSSL_EXPORT OPENSSL_DEPRECATED EC_POINT *EC_POINT_bn2point(
const EC_GROUP *group, const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx);

// EC_GROUP_get_order sets |*order| to the order of |group|, if it's not
// NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use
// |EC_GROUP_get0_order| instead.
Expand Down

0 comments on commit 76907cd

Please sign in to comment.