Skip to content

Commit

Permalink
Merge pull request #843 from rhenium/ky/pkey-ec-point-remove-mul-multi
Browse files Browse the repository at this point in the history
pkey/ec: remove deprecated PKey::EC::Point#mul(ary, ary [, bn]) form
  • Loading branch information
rhenium authored Feb 3, 2025
2 parents e9a8700 + 7343d3c commit 1c270b8
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 1c270b8

Please sign in to comment.