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)
{
    ossl_ec_point *ec_point;
    EC_POINT *point = NULL;
    VALUE arg1, arg2;
    VALUE group_v = Qnil;
    const EC_GROUP *group = NULL;

    Data_Get_Struct(self, ossl_ec_point, ec_point);
    if (ec_point->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_iv_get(arg1, "@group");
            SafeRequire_EC_GROUP(group_v, group);
            SafeRequire_EC_POINT(arg1, arg_point);

            point = EC_POINT_dup(arg_point, group);
        } else if (rb_obj_is_kind_of(arg1, cEC_GROUP)) {
            group_v = arg1;
            SafeRequire_EC_GROUP(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;
        SafeRequire_EC_GROUP(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)");

    ec_point->point = point;

    rb_iv_set(self, "@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_iv_get(a, "@group");
    VALUE group_v2 = rb_iv_get(b, "@group");
    const EC_GROUP *group;

    if (ossl_ec_group_eql(group_v1, group_v2) == Qfalse)
        return Qfalse;

    Require_EC_POINT(a, point1);
    SafeRequire_EC_POINT(b, point2);
    SafeRequire_EC_GROUP(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;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, 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;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, 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;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

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

    return self;
}
mul(bn) → point click to toggle source
mul(bn, bn) → point
mul([bn], [point]) → point
mul([bn], [point], bn) → point
static VALUE ossl_ec_point_mul(int argc, VALUE *argv, VALUE self)
{
    EC_POINT *point1, *point2;
    const EC_GROUP *group;
    VALUE group_v = rb_iv_get(self, "@group");
    VALUE bn_v1, bn_v2, r, points_v;
    BIGNUM *bn1 = NULL, *bn2 = NULL;

    Require_EC_POINT(self, point1);
    SafeRequire_EC_GROUP(group_v, group);

    r = rb_obj_alloc(cEC_POINT);
    ossl_ec_point_initialize(1, &group_v, r);
    Require_EC_POINT(r, point2);

    argc = rb_scan_args(argc, argv, "12", &bn_v1, &points_v, &bn_v2);

    if (rb_obj_is_kind_of(bn_v1, cBN)) {
        bn1 = GetBNPtr(bn_v1);
        if (argc >= 2) {
            bn2 = GetBNPtr(points_v);
        }
        if (EC_POINT_mul(group, point2, bn2, point1, bn1, ossl_bn_ctx) != 1)
            ossl_raise(eEC_POINT, "Multiplication failed");
    } else {
        size_t i, points_len, bignums_len;
        const EC_POINT **points;
        const BIGNUM **bignums;

        Check_Type(bn_v1, T_ARRAY);
        bignums_len = RARRAY_LEN(bn_v1);
        bignums = (const BIGNUM **)OPENSSL_malloc(bignums_len * (int)sizeof(BIGNUM *));

        for (i = 0; i < bignums_len; ++i) {
            bignums[i] = GetBNPtr(rb_ary_entry(bn_v1, i));
        }

        if (!rb_obj_is_kind_of(points_v, rb_cArray)) {
            OPENSSL_free((void *)bignums);
            rb_raise(rb_eTypeError, "Argument2 must be an array");
        }

        rb_ary_unshift(points_v, self);
        points_len = RARRAY_LEN(points_v);
        points = (const EC_POINT **)OPENSSL_malloc(points_len * (int)sizeof(EC_POINT *));

        for (i = 0; i < points_len; ++i) {
            Get_EC_POINT(rb_ary_entry(points_v, i), points[i]);
        }

        if (argc >= 3) {
            bn2 = GetBNPtr(bn_v2);
        }
        if (EC_POINTs_mul(group, point2, bn2, points_len, points, bignums, ossl_bn_ctx) != 1) {
            OPENSSL_free((void *)bignums);
            OPENSSL_free((void *)points);
            ossl_raise(eEC_POINT, "Multiplication failed");
        }
        OPENSSL_free((void *)bignums);
        OPENSSL_free((void *)points);
    }

    return r;
}
on_curve? → true | false click to toggle source
static VALUE ossl_ec_point_is_on_curve(VALUE self)
{
    EC_POINT *point;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, 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;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

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

    return self;
}
to_bn → OpenSSL::BN click to toggle source

See the OpenSSL documentation for EC_POINT_point2bn()

static VALUE ossl_ec_point_to_bn(VALUE self)
{
    EC_POINT *point;
    VALUE bn_obj;
    VALUE group_v = rb_iv_get(self, "@group");
    const EC_GROUP *group;
    point_conversion_form_t form;
    BIGNUM *bn;

    Require_EC_POINT(self, point);
    SafeRequire_EC_GROUP(group_v, group);

    form = EC_GROUP_get_point_conversion_form(group);

    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;
}