diff options
-rw-r--r-- | ext/openssl/ossl_pkey_ec.c | 29 | ||||
-rw-r--r-- | test/test_pkey_ec.rb | 16 |
2 files changed, 45 insertions, 0 deletions
diff --git a/ext/openssl/ossl_pkey_ec.c b/ext/openssl/ossl_pkey_ec.c index 8bb61124..fc2bc6c8 100644 --- a/ext/openssl/ossl_pkey_ec.c +++ b/ext/openssl/ossl_pkey_ec.c @@ -1564,6 +1564,34 @@ ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form) /* * call-seq: + * point.add(point) => point + * + * Performs elliptic curve point addition. + */ +static VALUE ossl_ec_point_add(VALUE self, VALUE other) +{ + EC_POINT *point_self, *point_other, *point_result; + const EC_GROUP *group; + VALUE group_v = rb_attr_get(self, id_i_group); + VALUE result; + + GetECPoint(self, point_self); + GetECPoint(other, point_other); + GetECGroup(group_v, group); + + result = rb_obj_alloc(cEC_POINT); + ossl_ec_point_initialize(1, &group_v, result); + GetECPoint(result, point_result); + + if (EC_POINT_add(group, point_result, point_self, point_other, ossl_bn_ctx) != 1) { + ossl_raise(eEC_POINT, "EC_POINT_add"); + } + + return result; +} + +/* + * call-seq: * point.mul(bn1 [, bn2]) => point * point.mul(bns, points [, bn2]) => point * @@ -1786,6 +1814,7 @@ void Init_ossl_ec(void) /* all the other methods */ rb_define_method(cEC_POINT, "to_octet_string", ossl_ec_point_to_octet_string, 1); + rb_define_method(cEC_POINT, "add", ossl_ec_point_add, 1); rb_define_method(cEC_POINT, "mul", ossl_ec_point_mul, -1); id_i_group = rb_intern("@group"); diff --git a/test/test_pkey_ec.rb b/test/test_pkey_ec.rb index 95b5a642..c4eb2ead 100644 --- a/test/test_pkey_ec.rb +++ b/test/test_pkey_ec.rb @@ -289,6 +289,22 @@ class OpenSSL::TestEC < OpenSSL::PKeyTestCase assert_equal true, point.on_curve? end + def test_ec_point_add + group = OpenSSL::PKey::EC::Group.new(:GFp, 17, 2, 2) + group.point_conversion_form = :uncompressed + gen = OpenSSL::PKey::EC::Point.new(group, B(%w{ 04 05 01 })) + group.set_generator(gen, 19, 1) + + point_a = OpenSSL::PKey::EC::Point.new(group, B(%w{ 04 06 03 })) + point_b = OpenSSL::PKey::EC::Point.new(group, B(%w{ 04 10 0D })) + + result = point_a.add(point_b) + assert_equal B(%w{ 04 0D 07 }), result.to_octet_string(:uncompressed) + + assert_raise(TypeError) { point_a.add(nil) } + assert_raise(ArgumentError) { point_a.add } + end + def test_ec_point_mul begin # y^2 = x^3 + 2x + 2 over F_17 |