class OpenSSL::PKey::EC::Point
Attributes
Public Class Methods
Creates a new instance of OpenSSL::PKey::EC::Point
. If the only argument is an instance of EC::Point
, a copy is returned. Otherwise, creates a point that belongs to group.
encoded_point is the octet string representation of the point. This must be either a String or an OpenSSL::BN
.
static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self) { EC_POINT *point; VALUE group_v, arg2; const EC_GROUP *group; TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point); if (point) rb_raise(eEC_POINT, "EC_POINT already initialized"); rb_scan_args(argc, argv, "11", &group_v, &arg2); if (rb_obj_is_kind_of(group_v, cEC_POINT)) { if (argc != 1) rb_raise(rb_eArgError, "invalid second argument"); return ossl_ec_point_initialize_copy(self, group_v); } GetECGroup(group_v, group); if (argc == 1) { point = EC_POINT_new(group); if (!point) ossl_raise(eEC_POINT, "EC_POINT_new"); } else { if (rb_obj_is_kind_of(arg2, cBN)) { point = EC_POINT_bn2point(group, GetBNPtr(arg2), NULL, ossl_bn_ctx); if (!point) ossl_raise(eEC_POINT, "EC_POINT_bn2point"); } else { StringValue(arg2); point = EC_POINT_new(group); if (!point) ossl_raise(eEC_POINT, "EC_POINT_new"); if (!EC_POINT_oct2point(group, point, (unsigned char *)RSTRING_PTR(arg2), RSTRING_LEN(arg2), ossl_bn_ctx)) { EC_POINT_free(point); ossl_raise(eEC_POINT, "EC_POINT_oct2point"); } } } RTYPEDDATA_DATA(self) = point; rb_ivar_set(self, id_i_group, group_v); return self; }
Public Instance Methods
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; }
static VALUE ossl_ec_point_eql(VALUE a, VALUE b) { EC_POINT *point1, *point2; VALUE group_v1 = rb_attr_get(a, id_i_group); VALUE group_v2 = rb_attr_get(b, id_i_group); const EC_GROUP *group; if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse) return Qfalse; GetECPoint(a, point1); GetECPoint(b, point2); GetECGroup(group_v1, group); switch (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx)) { case 0: return Qtrue; case 1: return Qfalse; default: ossl_raise(eEC_POINT, "EC_POINT_cmp"); } UNREACHABLE; }
static VALUE ossl_ec_point_is_at_infinity(VALUE self) { EC_POINT *point; const EC_GROUP *group; GetECPoint(self, point); GetECPointGroup(self, group); switch (EC_POINT_is_at_infinity(group, point)) { case 1: return Qtrue; case 0: return Qfalse; default: ossl_raise(eEC_POINT, "EC_POINT_is_at_infinity"); } UNREACHABLE; }
static VALUE ossl_ec_point_initialize_copy(VALUE self, VALUE other) { EC_POINT *point, *point_new; EC_GROUP *group; VALUE group_v; TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point_new); if (point_new) ossl_raise(eEC_POINT, "EC::Point already initialized"); GetECPoint(other, point); group_v = rb_obj_dup(rb_attr_get(other, id_i_group)); GetECGroup(group_v, group); point_new = EC_POINT_dup(point, group); if (!point_new) ossl_raise(eEC_POINT, "EC_POINT_dup"); RTYPEDDATA_DATA(self) = point_new; rb_ivar_set(self, id_i_group, group_v); return self; }
static VALUE ossl_ec_point_invert(VALUE self) { EC_POINT *point; const EC_GROUP *group; GetECPoint(self, point); GetECPointGroup(self, group); if (EC_POINT_invert(group, point, ossl_bn_ctx) != 1) ossl_raise(eEC_POINT, "EC_POINT_invert"); return self; }
This method is deprecated and should not be used. This is a no-op.
static VALUE ossl_ec_point_make_affine(VALUE self) { EC_POINT *point; const EC_GROUP *group; GetECPoint(self, point); GetECPointGroup(self, group); rb_warn("OpenSSL::PKey::EC::Point#make_affine! is deprecated"); #if !OSSL_OPENSSL_PREREQ(3, 0, 0) if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1) ossl_raise(eEC_POINT, "EC_POINT_make_affine"); #endif return self; }
Performs elliptic curve point multiplication.
The first form calculates bn1 * point + bn2 * G
, where G
is the generator of the group of point. bn2 may be omitted, and in that case, the result is just bn1 * point
.
The second form calculates bns[0] * point + bns[1] * points[0] + ... + bns[-1] * points[-1] + bn2 * G
. 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 points[0]
is not multiplied by bns[0]
, but bns[1]
.
static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self) { EC_POINT *point_self, *point_result; const EC_GROUP *group; VALUE group_v = rb_attr_get(self, id_i_group); VALUE arg1, arg2, arg3, result; const BIGNUM *bn_g = NULL; GetECPoint(self, point_self); GetECGroup(group_v, group); result = rb_obj_alloc(cEC_POINT); ossl_ec_point_initialize(1, &group_v, result); 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 } return result; }
static VALUE ossl_ec_point_is_on_curve(VALUE self) { EC_POINT *point; const EC_GROUP *group; GetECPoint(self, point); GetECPointGroup(self, group); switch (EC_POINT_is_on_curve(group, point, ossl_bn_ctx)) { case 1: return Qtrue; case 0: return Qfalse; default: ossl_raise(eEC_POINT, "EC_POINT_is_on_curve"); } UNREACHABLE; }
static VALUE ossl_ec_point_set_to_infinity(VALUE self) { EC_POINT *point; const EC_GROUP *group; GetECPoint(self, point); GetECPointGroup(self, group); if (EC_POINT_set_to_infinity(group, point) != 1) ossl_raise(eEC_POINT, "EC_POINT_set_to_infinity"); return self; }
Returns the octet string representation of the EC
point as an instance of OpenSSL::BN
.
If conversion_form is not given, the point_conversion_form attribute set to the group is used.
See to_octet_string
for more information.
# File openssl/lib/openssl/pkey.rb, line 307 def to_bn(conversion_form = group.point_conversion_form) OpenSSL::BN.new(to_octet_string(conversion_form), 2) end
Returns the octet string representation of the elliptic curve point.
conversion_form specifies how the point is converted. Possible values are:
-
:compressed
-
:uncompressed
-
:hybrid
static VALUE ossl_ec_point_to_octet_string(VALUE self, VALUE conversion_form) { EC_POINT *point; const EC_GROUP *group; point_conversion_form_t form; VALUE str; size_t len; GetECPoint(self, point); GetECPointGroup(self, group); form = parse_point_conversion_form_symbol(conversion_form); len = EC_POINT_point2oct(group, point, form, NULL, 0, ossl_bn_ctx); if (!len) ossl_raise(eEC_POINT, "EC_POINT_point2oct"); str = rb_str_new(NULL, (long)len); if (!EC_POINT_point2oct(group, point, form, (unsigned char *)RSTRING_PTR(str), len, ossl_bn_ctx)) ossl_raise(eEC_POINT, "EC_POINT_point2oct"); return str; }