Skip to content

Commit

Permalink
pkey/ec: remove deprecated PKey::EC::Point#mul(ary, ary [, bn]) form
Browse files Browse the repository at this point in the history
The method has two forms, each corresponding to EC_POINT_mul() and
EC_POINTs_mul(). The latter form does not work with any OpenSSL or
LibreSSL versions that are still supported by upstream.

The latter form has an extremely confusing behavior, too, and using it
would print a deprecation warning since commit 812de42 in 2020,
which went to 3.0.0. Let's remove it.
  • Loading branch information
rhenium committed Jan 22, 2025
1 parent a1012fc commit 7343d3c
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 84 deletions.
74 changes: 12 additions & 62 deletions ext/openssl/ossl_pkey_ec.c
Original file line number Diff line number Diff line change
Expand Up @@ -1478,19 +1478,16 @@ static VALUE ossl_ec_point_add(VALUE self, VALUE other)
/*
* call-seq:
* point.mul(bn1 [, bn2]) => point
* point.mul(bns, points [, bn2]) => point
*
* Performs elliptic curve point multiplication.
*
* The first form calculates <tt>bn1 * point + bn2 * G</tt>, where +G+ is the
* generator of the group of _point_. _bn2_ may be omitted, and in that case,
* the result is just <tt>bn1 * point</tt>.
*
* The second form calculates <tt>bns[0] * point + bns[1] * points[0] + ...
* + bns[-1] * points[-1] + bn2 * G</tt>. _bn2_ may be omitted. _bns_ must be
* an array of OpenSSL::BN. _points_ must be an array of
* OpenSSL::PKey::EC::Point. Please note that <tt>points[0]</tt> is not
* multiplied by <tt>bns[0]</tt>, but <tt>bns[1]</tt>.
* Before version 4.0.0, and when compiled with OpenSSL 1.1.1 or older, this
* method allowed another form:
* point.mul(bns, points [, bn2]) => point
*/
static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
{
Expand All @@ -1508,62 +1505,15 @@ static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
GetECPoint(result, point_result);

rb_scan_args(argc, argv, "12", &arg1, &arg2, &arg3);
if (!RB_TYPE_P(arg1, T_ARRAY)) {
BIGNUM *bn = GetBNPtr(arg1);

if (!NIL_P(arg2))
bn_g = GetBNPtr(arg2);
if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1)
ossl_raise(eEC_POINT, NULL);
} else {
#if (defined(OPENSSL_VERSION_MAJOR) && OPENSSL_VERSION_MAJOR >= 3) || defined(LIBRESSL_VERSION_NUMBER)
rb_raise(rb_eNotImpError, "calling #mul with arrays is not" \
"supported by this OpenSSL version");
#else
/*
* bignums | arg1[0] | arg1[1] | arg1[2] | ...
* points | self | arg2[0] | arg2[1] | ...
*/
long i, num;
VALUE bns_tmp, tmp_p, tmp_b;
const EC_POINT **points;
const BIGNUM **bignums;

Check_Type(arg1, T_ARRAY);
Check_Type(arg2, T_ARRAY);
if (RARRAY_LEN(arg1) != RARRAY_LEN(arg2) + 1) /* arg2 must be 1 larger */
ossl_raise(rb_eArgError, "bns must be 1 longer than points; see the documentation");

rb_warning("OpenSSL::PKey::EC::Point#mul(ary, ary) is deprecated; " \
"use #mul(bn) form instead");

num = RARRAY_LEN(arg1);
bns_tmp = rb_ary_tmp_new(num);
bignums = ALLOCV_N(const BIGNUM *, tmp_b, num);
for (i = 0; i < num; i++) {
VALUE item = RARRAY_AREF(arg1, i);
bignums[i] = GetBNPtr(item);
rb_ary_push(bns_tmp, item);
}

points = ALLOCV_N(const EC_POINT *, tmp_p, num);
points[0] = point_self; /* self */
for (i = 0; i < num - 1; i++)
GetECPoint(RARRAY_AREF(arg2, i), points[i + 1]);

if (!NIL_P(arg3))
bn_g = GetBNPtr(arg3);

if (EC_POINTs_mul(group, point_result, bn_g, num, points, bignums, ossl_bn_ctx) != 1) {
ALLOCV_END(tmp_b);
ALLOCV_END(tmp_p);
ossl_raise(eEC_POINT, NULL);
}

ALLOCV_END(tmp_b);
ALLOCV_END(tmp_p);
#endif
}
if (RB_TYPE_P(arg1, T_ARRAY) || argc > 2)
rb_raise(rb_eNotImpError, "OpenSSL::PKey::EC::Point#mul with arrays " \
"is no longer supported");

BIGNUM *bn = GetBNPtr(arg1);
if (!NIL_P(arg2))
bn_g = GetBNPtr(arg2);
if (EC_POINT_mul(group, point_result, bn_g, point_self, bn, ossl_bn_ctx) != 1)
ossl_raise(eEC_POINT, NULL);

return result;
}
Expand Down
25 changes: 3 additions & 22 deletions test/openssl/test_pkey_ec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -425,28 +425,6 @@ def test_ec_point_mul
# 3 * (6, 3) + 3 * (5, 1) = (7, 6)
result_a2 = point_a.mul(3, 3)
assert_equal B(%w{ 04 07 06 }), result_a2.to_octet_string(:uncompressed)
EnvUtil.suppress_warning do # Point#mul(ary, ary [, bn]) is deprecated
begin
result_b1 = point_a.mul([3], [])
rescue NotImplementedError
# LibreSSL and OpenSSL 3.0 do no longer support this form of calling
next
end

# 3 * point_a = 3 * (6, 3) = (16, 13)
result_b1 = point_a.mul([3], [])
assert_equal B(%w{ 04 10 0D }), result_b1.to_octet_string(:uncompressed)
# 3 * point_a + 2 * point_a = 3 * (6, 3) + 2 * (6, 3) = (7, 11)
result_b1 = point_a.mul([3, 2], [point_a])
assert_equal B(%w{ 04 07 0B }), result_b1.to_octet_string(:uncompressed)
# 3 * point_a + 5 * point_a.group.generator = 3 * (6, 3) + 5 * (5, 1) = (13, 10)
result_b1 = point_a.mul([3], [], 5)
assert_equal B(%w{ 04 0D 0A }), result_b1.to_octet_string(:uncompressed)

assert_raise(ArgumentError) { point_a.mul([1], [point_a]) }
assert_raise(TypeError) { point_a.mul([1], nil) }
assert_raise(TypeError) { point_a.mul([nil], []) }
end
rescue OpenSSL::PKey::EC::Group::Error
# CentOS patches OpenSSL to reject curves defined over Fp where p < 256 bits
raise if $!.message !~ /unsupported field/
Expand All @@ -459,6 +437,9 @@ def test_ec_point_mul
# invalid argument
point = p256_key.public_key
assert_raise(TypeError) { point.mul(nil) }

# mul with arrays was removed in version 4.0.0
assert_raise(NotImplementedError) { point.mul([1], []) }
end

# test Group: asn1_flag, point_conversion
Expand Down

0 comments on commit 7343d3c

Please sign in to comment.