[前][次][番号順一覧][スレッド一覧]

ruby-changes:28409

From: naruse <ko1@a...>
Date: Thu, 25 Apr 2013 16:03:26 +0900 (JST)
Subject: [ruby-changes:28409] naruse:r40461 (trunk): * ext/openssl/ossl_bn.c (ossl_bn_initialize): allow Fixnum and Bignum.

naruse	2013-04-25 16:02:31 +0900 (Thu, 25 Apr 2013)

  New Revision: 40461

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=40461

  Log:
    * ext/openssl/ossl_bn.c (ossl_bn_initialize): allow Fixnum and Bignum.
      [ruby-core:53986] [Feature #8217]

  Modified files:
    trunk/ChangeLog
    trunk/NEWS
    trunk/ext/openssl/lib/openssl/bn.rb
    trunk/ext/openssl/ossl_bn.c
    trunk/test/openssl/test_bn.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 40460)
+++ ChangeLog	(revision 40461)
@@ -1,3 +1,8 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Apr 25 14:35:01 2013  NARUSE, Yui  <naruse@r...>
+
+	* ext/openssl/ossl_bn.c (ossl_bn_initialize): allow Fixnum and Bignum.
+	  [ruby-core:53986] [Feature #8217]
+
 Thu Apr 25 14:26:32 2013  NARUSE, Yui  <naruse@r...>
 
 	* lib/uri/common.rb (URI.decode_www_form): follow current URL Standard.
Index: ext/openssl/lib/openssl/bn.rb
===================================================================
--- ext/openssl/lib/openssl/bn.rb	(revision 40460)
+++ ext/openssl/lib/openssl/bn.rb	(revision 40461)
@@ -29,7 +29,7 @@ end # OpenSSL https://github.com/ruby/ruby/blob/trunk/ext/openssl/lib/openssl/bn.rb#L29
 #
 class Integer
   def to_bn
-    OpenSSL::BN::new(self.to_s(16), 16)
+    OpenSSL::BN::new(self)
   end
 end # Integer
 
Index: ext/openssl/ossl_bn.c
===================================================================
--- ext/openssl/ossl_bn.c	(revision 40460)
+++ ext/openssl/ossl_bn.c	(revision 40461)
@@ -106,6 +106,7 @@ ossl_bn_alloc(VALUE klass) https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_bn.c#L106
  * call-seq:
  *    BN.new => aBN
  *    BN.new(bn) => aBN
+ *    BN.new(integer) => aBN
  *    BN.new(string) => aBN
  *    BN.new(string, 0 | 2 | 10 | 16) => aBN
  */
@@ -120,6 +121,44 @@ ossl_bn_initialize(int argc, VALUE *argv https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl_bn.c#L121
 	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;
 
Index: NEWS
===================================================================
--- NEWS	(revision 40460)
+++ NEWS	(revision 40461)
@@ -57,6 +57,10 @@ with all sufficient information, see the https://github.com/ruby/ruby/blob/trunk/NEWS#L57
     * Pathname#write
     * Pathname#binwrite
 
+* OpenSSL::BN
+  * extended methods:
+    * OpenSSL::BN.new allows Fixnum/Bignum argument.
+
 * open-uri
   * Support multiple fields with same field name (like Set-Cookie).
 
Index: test/openssl/test_bn.rb
===================================================================
--- test/openssl/test_bn.rb	(revision 40460)
+++ test/openssl/test_bn.rb	(revision 40461)
@@ -3,13 +3,38 @@ require_relative 'utils' https://github.com/ruby/ruby/blob/trunk/test/openssl/test_bn.rb#L3
 if defined?(OpenSSL)
 
 class OpenSSL::TestBN < Test::Unit::TestCase
-  def test_bn_to_bn
-    assert_equal(999.to_bn, OpenSSL::BN.new(999.to_bn))
+  def test_new_str
+    e1 = OpenSSL::BN.new(999.to_s(16), 16) # OpenSSL::BN.new(str, 16) must be most stable
+    e2 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
+    assert_equal(e1, OpenSSL::BN.new("999"))
+    assert_equal(e2, OpenSSL::BN.new((2**107-1).to_s))
+    assert_equal(e1, OpenSSL::BN.new("999", 10))
+    assert_equal(e2, OpenSSL::BN.new((2**107-1).to_s, 10))
+    assert_equal(e1, OpenSSL::BN.new("\x03\xE7", 2))
+    assert_equal(e2, OpenSSL::BN.new("\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 2))
+    assert_equal(e1, OpenSSL::BN.new("\x00\x00\x00\x02\x03\xE7", 0))
+    assert_equal(e2, OpenSSL::BN.new("\x00\x00\x00\x0E\a\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 0))
   end
 
-  def test_integer_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))
+  def test_new_bn
+    e1 = OpenSSL::BN.new(999.to_s(16), 16)
+    e2 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
+    assert_equal(e1, OpenSSL::BN.new(e1))
+    assert_equal(e2, OpenSSL::BN.new(e2))
+  end
+
+  def test_new_integer
+    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_to_bn
+    e1 = OpenSSL::BN.new(999.to_s(16), 16)
+    e2 = OpenSSL::BN.new((2**107-1).to_s(16), 16)
+    assert_equal(e1, 999.to_bn)
+    assert_equal(e2, (2**107-1).to_bn)
   end
 
   def test_prime_p

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]