Project

General

Profile

Actions

Feature #8217

closed

OpenSSL::BN.new with integers

Added by naruse (Yui NARUSE) about 11 years ago. Updated almost 11 years ago.

Status:
Closed
Target version:
[ruby-core:53986]

Description

Current OpenSSL::BN.new gets only strings, so users must do integer.to_s, it costs extra resource.
Therefore I propose OpenSSL::BN.new to allow Fixnu/Bignum.

diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index 1038135..1f1ebba 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -120,6 +120,44 @@ ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
base = NUM2INT(bs);
}

  • if (RB_TYPE_P(str, T_FIXNUM)) {
  • long i;
  • unsigned char bin = (unsigned char)ALLOC_N(long, 1);
  • long n = FIX2LONG(str);
  • unsigned long un = abs(n);
  • for (i = sizeof(VALUE) - 1; 0 <= i; i--) {
  •   bin[i] = un&0xff;
    
  •   un >>= 8;
    
  • }
  • GetBN(self, bn);
  • if (!BN_bin2bn(bin, sizeof(long), bn)) {
  •   ossl_raise(eBNError, NULL);
    
  • }
  • if (n < 0) BN_set_negative(bn, 1);
  • return self;
  • }
  • else if (RB_TYPE_P(str, T_BIGNUM)) {
  • long i, j;
  • BDIGIT *ds = RBIGNUM_DIGITS(str);
  • unsigned char bin = (unsigned char)ALLOC_N(BDIGIT, RBIGNUM_LEN(str));
  • for (i = 0; RBIGNUM_LEN(str) > i; i++) {
  •   BDIGIT v = ds[i];
    
  •   for (j = sizeof(BDIGIT) - 1; 0 <= j; j--) {
    
  •   bin[(RBIGNUM_LEN(str)-1-i)*sizeof(BDIGIT)+j] = v&0xff;
    
  •   v >>= 8;
    
  •   }
    
  • }
  • GetBN(self, bn);
  • if (!BN_bin2bn(bin, sizeof(BDIGIT)*RBIGNUM_LEN(str), bn)) {
  •   ossl_raise(eBNError, NULL);
    
  • }
  • if (!RBIGNUM_SIGN(str)) BN_set_negative(bn, 1);
  • return self;
  • }
    if (RTEST(rb_obj_is_kind_of(str, cBN))) {
    BIGNUM *other;

diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index af1c72c..758cc54 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -8,6 +8,13 @@ class OpenSSL::TestBN < Test::Unit::TestCase
end

def test_integer_to_bn

  • assert_equal(999.to_bn, OpenSSL::BN.new(999))
  • assert_equal((2 ** 107 - 1).to_bn, OpenSSL::BN.new(2 ** 107 - 1))
  • assert_equal(-999.to_bn, OpenSSL::BN.new(-999))
  • assert_equal((-(2 ** 107 - 1)).to_bn, OpenSSL::BN.new(-(2 ** 107 - 1)))
  • end
  • def test_integer_str_to_bn
    assert_equal(999.to_bn, OpenSSL::BN.new(999.to_s(16), 16))
    assert_equal((2 ** 107 - 1).to_bn, OpenSSL::BN.new((2 ** 107 - 1).to_s(16), 16))
    end
Actions

Also available in: Atom PDF

Like0
Like0