class OpenSSL::BN - RDoc Documentation

# class OpenSSL::BN

### Constants

CONSTTIME
MALLOCED
STATIC_DATA

### Public Class Methods

generate_prime(bits, [, safe [, add [, rem]]]) → bn click to toggle source

Generates a random prime number of bit length bits. If safe is set to `true`, generates a safe prime. If add is specified, generates a prime that fulfills condition `p % add = rem`.

### Parameters¶ ↑

- bits - integer

- safe - boolean

- add - `BN`

- rem - `BN`

    static VALUE
    ossl_bn_s_generate_prime(int argc, VALUE *argv, VALUE klass)
    {
        BIGNUM *add = NULL, *rem = NULL, *result;
        int safe = 1, num;
        VALUE vnum, vsafe, vadd, vrem, obj;

        rb_scan_args(argc, argv, "13", &vnum, &vsafe, &vadd, &vrem);

        num = NUM2INT(vnum);

        if (vsafe == Qfalse) {
            safe = 0;
        }
        if (!NIL_P(vadd)) {
            add = GetBNPtr(vadd);
            rem = NIL_P(vrem) ? NULL : GetBNPtr(vrem);
        }
        obj = NewBN(klass);
        if (!(result = BN_new())) {
            ossl_raise(eBNError, NULL);
        }
        if (!BN_generate_prime_ex(result, num, safe, add, rem, NULL)) {
            BN_free(result);
            ossl_raise(eBNError, NULL);
        }
        SetBN(obj, result);

        return obj;
    }

OpenSSL::BN.new(bn) → aBN click to toggle source
OpenSSL::BN.new(integer) → aBN
OpenSSL::BN.new(string, base = 10) → aBN

Construct a new OpenSSL BIGNUM object.

If `bn` is an `Integer` or `OpenSSL::BN`, a new instance of `OpenSSL::BN` representing the same value is returned. See also `Integer#to_bn` for the short-hand.

If a `String` is given, the content will be parsed according to `base`.

`string`

  The string to be parsed.

`base`

  The format. Must be one of the following:

  - `0` - MPI format. See the man page BN_mpi2bn(3) for details.

  - `2` - Variable-length and big-endian binary encoding of a positive number.

  - `10` - Decimal number representation, with a leading ‘-’ for a negative number.

  - `16` - Hexadeciaml number representation, with a leading ‘-’ for a negative number.

    static VALUE
    ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
    {
        BIGNUM *bn;
        VALUE str, bs;
        int base = 10;
        char *ptr;

        if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
            base = NUM2INT(bs);
        }

        if (NIL_P(str)) {
            ossl_raise(rb_eArgError, "invalid argument");
        }

        if (RB_INTEGER_TYPE_P(str)) {
            GetBN(self, bn);
            integer_to_bnptr(str, bn);

            return self;
        }

        if (RTEST(rb_obj_is_kind_of(str, cBN))) {
            BIGNUM *other;

            GetBN(self, bn);
            GetBN(str, other); /* Safe - we checked kind_of? above */
            if (!BN_copy(bn, other)) {
                ossl_raise(eBNError, NULL);
            }
            return self;
        }

        GetBN(self, bn);
        switch (base) {
        case 0:
            ptr = StringValuePtr(str);
            if (!BN_mpi2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
                ossl_raise(eBNError, NULL);
            }
            break;
        case 2:
            ptr = StringValuePtr(str);
            if (!BN_bin2bn((unsigned char *)ptr, RSTRING_LENINT(str), bn)) {
                ossl_raise(eBNError, NULL);
            }
            break;
        case 10:
            if (!BN_dec2bn(&bn, StringValueCStr(str))) {
                ossl_raise(eBNError, NULL);
            }
            break;
        case 16:
            if (!BN_hex2bn(&bn, StringValueCStr(str))) {
                ossl_raise(eBNError, NULL);
            }
            break;
        default:
            ossl_raise(rb_eArgError, "invalid radix %d", base);
        }
        return self;
    }

rand(bits [, fill [, odd]]) → aBN click to toggle source

Generates a cryptographically strong pseudo-random number of `bits`.

See also the man page BN_rand(3).

    static VALUE
    ossl_bn_s_rand(int argc, VALUE *argv, VALUE klass)
    {
        BIGNUM *result;
        int bottom = 0, top = 0, b;
        VALUE bits, fill, odd, obj;

        switch (rb_scan_args(argc, argv, "12", &bits, &fill, &odd)) {
          case 3:
            bottom = (odd == Qtrue) ? 1 : 0;
            /* FALLTHROUGH */
          case 2:
            top = NUM2INT(fill);
        }
        b = NUM2INT(bits);
        obj = NewBN(klass);
        if (!(result = BN_new())) {
            ossl_raise(eBNError, "BN_new");
        }
        if (BN_rand(result, b, top, bottom) <= 0) {
            BN_free(result);
            ossl_raise(eBNError, "BN_rand");
        }
        SetBN(obj, result);
        return obj;
    }

rand_range(range) → aBN click to toggle source

Generates a cryptographically strong pseudo-random number in the range 0…`range`.

See also the man page BN_rand_range(3).

    static VALUE
    ossl_bn_s_rand_range(VALUE klass, VALUE range)
    {
        BIGNUM *bn = GetBNPtr(range), *result;
        VALUE obj = NewBN(klass);
        if (!(result = BN_new()))
            ossl_raise(eBNError, "BN_new");
        if (BN_rand_range(result, bn) <= 0) {
            BN_free(result);
            ossl_raise(eBNError, "BN_rand_range");
        }
        SetBN(obj, result);
        return obj;
    }

### Public Instance Methods

bn % bn2 → aBN
bn * bn2 → aBN
bn ** bn2 → aBN
bn + bn2 → aBN
+bn → aBN click to toggle source

    static VALUE
    ossl_bn_uplus(VALUE self)
    {
        VALUE obj;
        BIGNUM *bn1, *bn2;

        GetBN(self, bn1);
        obj = NewBN(cBN);
        bn2 = BN_dup(bn1);
        if (!bn2)
            ossl_raise(eBNError, "BN_dup");
        SetBN(obj, bn2);

        return obj;
    }

bn - bn2 → aBN
-bn → aBN click to toggle source

    static VALUE
    ossl_bn_uminus(VALUE self)
    {
        VALUE obj;
        BIGNUM *bn1, *bn2;

        GetBN(self, bn1);
        obj = NewBN(cBN);
        bn2 = BN_dup(bn1);
        if (!bn2)
            ossl_raise(eBNError, "BN_dup");
        SetBN(obj, bn2);
        BN_set_negative(bn2, !BN_is_negative(bn2));

        return obj;
    }

bn1 / bn2 → [result, remainder] click to toggle source

Division of `OpenSSL::BN` instances

    static VALUE
    ossl_bn_div(VALUE self, VALUE other)
    {
        BIGNUM *bn1, *bn2 = GetBNPtr(other), *r1, *r2;
        VALUE klass, obj1, obj2;

        GetBN(self, bn1);

        klass = rb_obj_class(self);
        obj1 = NewBN(klass);
        obj2 = NewBN(klass);
        if (!(r1 = BN_new())) {
            ossl_raise(eBNError, NULL);
        }
        if (!(r2 = BN_new())) {
            BN_free(r1);
            ossl_raise(eBNError, NULL);
        }
        if (!BN_div(r1, r2, bn1, bn2, ossl_bn_ctx)) {
            BN_free(r1);
            BN_free(r2);
            ossl_raise(eBNError, NULL);
        }
        SetBN(obj1, r1);
        SetBN(obj2, r2);

        return rb_ary_new3(2, obj1, obj2);
    }

bn << bits → aBN
<=>(p1)
Alias for: cmp
bn == obj → true or false click to toggle source

Returns `true` only if obj has the same value as bn. Contrast this with `OpenSSL::BN#eql?`, which requires obj to be `OpenSSL::BN`.

    static VALUE
    ossl_bn_eq(VALUE self, VALUE other)
    {
        BIGNUM *bn1, *bn2;

        GetBN(self, bn1);
        other = try_convert_to_bn(other);
        if (NIL_P(other))
            return Qfalse;
        GetBN(other, bn2);

        if (!BN_cmp(bn1, bn2)) {
            return Qtrue;
        }
        return Qfalse;
    }

Also aliased as: ===
===(p1)

Returns `true` only if obj has the same value as bn. Contrast this with `OpenSSL::BN#eql?`, which requires obj to be `OpenSSL::BN`.

Alias for: ==
bn >> bits → aBN
abs → aBN click to toggle source

    static VALUE
    ossl_bn_abs(VALUE self)
    {
        BIGNUM *bn1;

        GetBN(self, bn1);
        if (BN_is_negative(bn1)) {
            return ossl_bn_uminus(self);
        }
        else {
            return ossl_bn_uplus(self);
        }
    }

bit_set?(bit) → true | false click to toggle source

Tests bit bit in bn and returns `true` if set, `false` if not set.

    static VALUE
    ossl_bn_is_bit_set(VALUE self, VALUE bit)
    {
        int b;
        BIGNUM *bn;

        b = NUM2INT(bit);
        GetBN(self, bn);
        if (BN_is_bit_set(bn, b)) {
            return Qtrue;
        }
        return Qfalse;
    }

clear_bit!(bit) → self
cmp(bn2) → integer
Also aliased as: <=>
coerce(p1) click to toggle source

    static VALUE
    ossl_bn_coerce(VALUE self, VALUE other)
    {
        switch(TYPE(other)) {
        case T_STRING:
            self = ossl_bn_to_s(0, NULL, self);
            break;
        case T_FIXNUM:
        case T_BIGNUM:
            self = ossl_bn_to_i(self);
            break;
        default:
            if (!RTEST(rb_obj_is_kind_of(other, cBN))) {
                ossl_raise(rb_eTypeError, "Don't know how to coerce");
            }
        }
        return rb_assoc_new(other, self);
    }

copy(p1)
Alias for: initialize_copy
eql?(obj) → true or false click to toggle source

Returns `true` only if obj is a `OpenSSL::BN` with the same value as bn. Contrast this with `OpenSSL::BN#==`, which performs type conversions.

    static VALUE
    ossl_bn_eql(VALUE self, VALUE other)
    {
        BIGNUM *bn1, *bn2;

        if (!rb_obj_is_kind_of(other, cBN))
            return Qfalse;
        GetBN(self, bn1);
        GetBN(other, bn2);

        return BN_cmp(bn1, bn2) ? Qfalse : Qtrue;
    }

gcd(bn2) → aBN
get_flags(flags) → flags click to toggle source

Returns the flags on the `BN` object. The argument is used as a bit mask.

### Parameters¶ ↑

- flags - integer

    static VALUE
    ossl_bn_get_flags(VALUE self, VALUE arg)
    {
        BIGNUM *bn;
        GetBN(self, bn);

        return INT2NUM(BN_get_flags(bn, NUM2INT(arg)));
    }

hash → Integer click to toggle source

Returns a hash code for this object.

See also `Object#hash`.

    static VALUE
    ossl_bn_hash(VALUE self)
    {
        BIGNUM *bn;
        VALUE tmp, hash;
        unsigned char *buf;
        int len;

        GetBN(self, bn);
        len = BN_num_bytes(bn);
        buf = ALLOCV(tmp, len);
        if (BN_bn2bin(bn, buf) != len) {
            ALLOCV_END(tmp);
            ossl_raise(eBNError, "BN_bn2bin");
        }

        hash = ST2FIX(rb_memhash(buf, len));
        ALLOCV_END(tmp);

        return hash;
    }

initialize_copy(p1) click to toggle source

    static VALUE
    ossl_bn_copy(VALUE self, VALUE other)
    {
        BIGNUM *bn1, *bn2;

        rb_check_frozen(self);

        if (self == other) return self;

        GetBN(self, bn1);
        bn2 = GetBNPtr(other);

        if (!BN_copy(bn1, bn2)) {
            ossl_raise(eBNError, NULL);
        }
        return self;
    }

Also aliased as: copy
lshift!(bits) → self
mod_add(bn1, bn2) → aBN
mod_exp(bn1, bn2) → aBN
mod_inverse(bn2) → aBN click to toggle source

    static VALUE
    ossl_bn_mod_inverse(VALUE self, VALUE other)
    {
        BIGNUM *bn1, *bn2 = GetBNPtr(other), *result;
        VALUE obj;
        GetBN(self, bn1);
        obj = NewBN(rb_obj_class(self));
        if (!(result = BN_mod_inverse(NULL, bn1, bn2, ossl_bn_ctx)))
            ossl_raise(eBNError, "BN_mod_inverse");
        SetBN(obj, result);
        return obj;
    }

mod_mul(bn1, bn2) → aBN
mod_sqr(bn2) → aBN
mod_sub(bn1, bn2) → aBN
negative? → true | false click to toggle source

    static VALUE
    ossl_bn_is_negative(VALUE self)
    {
        BIGNUM *bn;

        GetBN(self, bn);
        if (BN_is_zero(bn))
            return Qfalse;
        return BN_is_negative(bn) ? Qtrue : Qfalse;
    }

num_bits → integer
num_bytes → integer
odd? → true | false
one? → true | false
pretty_print(q) click to toggle source

    # File ext/openssl/lib/openssl/bn.rb, line 20
    def pretty_print(q)
      q.object_group(self) {
        q.text ' '
        q.text to_i.to_s
      }
    end

prime? → true | false click to toggle source
prime?(checks) → true | false

Performs a Miller-Rabin probabilistic primality test for `bn`.

`checks` parameter is deprecated in version 3.0. It has no effect.

    static VALUE
    ossl_bn_is_prime(int argc, VALUE *argv, VALUE self)
    {
        BIGNUM *bn;
        int ret;

        rb_check_arity(argc, 0, 1);
        GetBN(self, bn);

    #ifdef HAVE_BN_CHECK_PRIME
        ret = BN_check_prime(bn, ossl_bn_ctx, NULL);
        if (ret < 0)
            ossl_raise(eBNError, "BN_check_prime");
    #else
        ret = BN_is_prime_fasttest_ex(bn, BN_prime_checks, ossl_bn_ctx, 1, NULL);
        if (ret < 0)
            ossl_raise(eBNError, "BN_is_prime_fasttest_ex");
    #endif
        return ret ? Qtrue : Qfalse;
    }

prime_fasttest? → true | false click to toggle source
prime_fasttest?(checks) → true | false
prime_fasttest?(checks, trial_div) → true | false

Performs a Miller-Rabin probabilistic primality test for `bn`.

Deprecated in version 3.0. Use `prime?` instead.

`checks` and `trial_div` parameters no longer have any effect.

    static VALUE
    ossl_bn_is_prime_fasttest(int argc, VALUE *argv, VALUE self)
    {
        rb_check_arity(argc, 0, 2);
        return ossl_bn_is_prime(0, argv, self);
    }

rshift!(bits) → self
set_bit!(bit) → self
set_flags(flags) → nil click to toggle source

Enables the flags on the `BN` object. Currently, the flags argument can contain zero of `OpenSSL::BN::CONSTTIME`.

    static VALUE
    ossl_bn_set_flags(VALUE self, VALUE arg)
    {
        BIGNUM *bn;
        GetBN(self, bn);

        BN_set_flags(bn, NUM2INT(arg));
        return Qnil;
    }

sqr → aBN
to_bn() click to toggle source

    static VALUE
    ossl_bn_to_bn(VALUE self)
    {
        return self;
    }

to_i → integer click to toggle source

    static VALUE
    ossl_bn_to_i(VALUE self)
    {
        BIGNUM *bn;
        char *txt;
        VALUE num;

        GetBN(self, bn);

        if (!(txt = BN_bn2hex(bn))) {
            ossl_raise(eBNError, NULL);
        }
        num = rb_cstr_to_inum(txt, 16, Qtrue);
        OPENSSL_free(txt);

        return num;
    }

Also aliased as: to_int
to_int()
Alias for: to_i
to_s(base = 10) → string click to toggle source

Returns the string representation of the bignum.

`BN.new` can parse the encoded string to convert back into an `OpenSSL::BN`.

`base`

  The format. Must be one of the following:

  - `0` - MPI format. See the man page BN_bn2mpi(3) for details.

  - `2` - Variable-length and big-endian binary encoding. The sign of the bignum is ignored.

  - `10` - Decimal number representation, with a leading ‘-’ for a negative bignum.

  - `16` - Hexadeciaml number representation, with a leading ‘-’ for a negative bignum.

    static VALUE
    ossl_bn_to_s(int argc, VALUE *argv, VALUE self)
    {
        BIGNUM *bn;
        VALUE str, bs;
        int base = 10, len;
        char *buf;

        if (rb_scan_args(argc, argv, "01", &bs) == 1) {
            base = NUM2INT(bs);
        }
        GetBN(self, bn);
        switch (base) {
        case 0:
            len = BN_bn2mpi(bn, NULL);
            str = rb_str_new(0, len);
            if (BN_bn2mpi(bn, (unsigned char *)RSTRING_PTR(str)) != len)
                ossl_raise(eBNError, NULL);
            break;
        case 2:
            len = BN_num_bytes(bn);
            str = rb_str_new(0, len);
            if (BN_bn2bin(bn, (unsigned char *)RSTRING_PTR(str)) != len)
                ossl_raise(eBNError, NULL);
            break;
        case 10:
            if (!(buf = BN_bn2dec(bn))) ossl_raise(eBNError, NULL);
            str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
            break;
        case 16:
            if (!(buf = BN_bn2hex(bn))) ossl_raise(eBNError, NULL);
            str = ossl_buf2str(buf, rb_long2int(strlen(buf)));
            break;
        default:
            ossl_raise(rb_eArgError, "invalid radix %d", base);
        }

        return str;
    }

ucmp(bn2) → integer
zero? → true | false