class OpenSSL::PKey::EC::Point

Attributes

group[R]

Public Class Methods

OpenSSL::PKey::EC::Point.new(point) click to toggle source
OpenSSL::PKey::EC::Point.new(group)
OpenSSL::PKey::EC::Point.new(group, bn)

See the OpenSSL documentation for EC_POINT_*

static VALUE ossl_ec_point_initialize(int argc, VALUE *argv, VALUE self)
{
    EC_POINT *point;
    VALUE arg1, arg2;
    VALUE group_v = Qnil;
    const EC_GROUP *group = NULL;

    TypedData_Get_Struct(self, EC_POINT, &ossl_ec_point_type, point);
    if (point)
        ossl_raise(eEC_POINT, "EC_POINT already initialized");

    switch (rb_scan_args(argc, argv, "11", &arg1, &arg2)) {
    case 1:
        if (rb_obj_is_kind_of(arg1, cEC_POINT)) {
            const EC_POINT *arg_point;

            group_v = rb_attr_get(arg1, id_i_group);
            SafeGetECGroup(group_v, group);
            SafeGetECPoint(arg1, arg_point);

            point = EC_POINT_dup(arg_point, group);
        } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
            group_v = arg1;
            SafeGetECGroup(group_v, group);

            point = EC_POINT_new(group);
        } else {
            ossl_raise(eEC_POINT, "wrong argument type: must be OpenSSL::PKey::EC::Point or OpenSSL::Pkey::EC::Group");
        }

        break;
     case 2:
        if (!rb_obj_is_kind_of(arg1, cEC_GROUP))
            ossl_raise(rb_eArgError, "1st argument must be OpenSSL::PKey::EC::Group");
        group_v = arg1;
        SafeGetECGroup(group_v, group);

        if (rb_obj_is_kind_of(arg2, cBN)) {
            const BIGNUM *bn = GetBNPtr(arg2);

            point = EC_POINT_bn2point(group, bn, NULL, ossl_bn_ctx);
        } else {
            BIO *in = ossl_obj2bio(&arg1);

/* BUG: finish me */

            BIO_free(in);

            if (point == NULL) {
                ossl_raise(eEC_POINT, "unknown type for 2nd arg");
            }
        }
        break;
    default:
        ossl_raise(rb_eArgError, "wrong number of arguments");
    }

    if (point == NULL)
        ossl_raise(eEC_POINT, NULL);

    if (NIL_P(group_v))
        ossl_raise(rb_eRuntimeError, "missing group (internal error)");

    RTYPEDDATA_DATA(self) = point;
    rb_ivar_set(self, id_i_group, group_v);

    return self;
}

Public Instance Methods

==(p1)
Alias for: eql?
eql?(point2) → true | false click to toggle source
point1 == point2 → true | false
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);
    SafeGetECPoint(b, point2);
    SafeGetECGroup(group_v1, group);

    if (EC_POINT_cmp(group, point1, point2, ossl_bn_ctx) == 1)
        return Qfalse;

    return Qtrue;
}
Also aliased as: ==
infinity? → true | false click to toggle source
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(cEC_POINT, "EC_POINT_is_at_infinity");
    }

    UNREACHABLE;
}
invert! → self click to toggle source
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(cEC_POINT, "EC_POINT_invert");

    return self;
}
make_affine! → self click to toggle source
static VALUE ossl_ec_point_make_affine(VALUE self)
{
    EC_POINT *point;
    const EC_GROUP *group;

    GetECPoint(self, point);
    GetECPointGroup(self, group);

    if (EC_POINT_make_affine(group, point, ossl_bn_ctx) != 1)
        ossl_raise(cEC_POINT, "EC_POINT_make_affine");

    return self;
}
mul(bn1 [, bn2]) → point click to toggle source
mul(bns, points [, bn2]) → point

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);
    SafeGetECGroup(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 {
        /*
         * 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");

        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++)
            SafeGetECPoint(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);
    }

    return result;
}
on_curve? → true | false click to toggle source
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(cEC_POINT, "EC_POINT_is_on_curve");
    }

    UNREACHABLE;
}
set_to_infinity! → self click to toggle source
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(cEC_POINT, "EC_POINT_set_to_infinity");

    return self;
}
to_bn(conversion_form = nil) → OpenSSL::BN click to toggle source

Convert the EC point into an octet string and store in an OpenSSL::BN. If conversion_form is given, the point data is converted using the specified form. If not given, the default form set in the EC::Group object is used.

See also EC::Point#point_conversion_form=.

static VALUE
ossl_ec_point_to_bn(int argc, VALUE *argv, VALUE self)
{
    EC_POINT *point;
    VALUE form_obj, bn_obj;
    const EC_GROUP *group;
    point_conversion_form_t form;
    BIGNUM *bn;

    GetECPoint(self, point);
    GetECPointGroup(self, group);
    rb_scan_args(argc, argv, "01", &form_obj);
    if (NIL_P(form_obj))
        form = EC_GROUP_get_point_conversion_form(group);
    else
        form = parse_point_conversion_form_symbol(form_obj);

    bn_obj = rb_obj_alloc(cBN);
    bn = GetBNPtr(bn_obj);

    if (EC_POINT_point2bn(group, point, form, bn, ossl_bn_ctx) == NULL)
        ossl_raise(eEC_POINT, "EC_POINT_point2bn");

    return bn_obj;
}