aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRick Mark <rick.mark@coinbase.com>2021-04-01 12:29:21 -0700
committerRick Mark <rick.mark@coinbase.com>2021-04-01 12:29:21 -0700
commit0321b1e945f89d08ab3632fe8bb3b7726086e9bb (patch)
treed3b22086f46eb438e1893ea28b3269dabf4ad902
parent69f89d4ae967f87e355dbbe05fbc039a083b6792 (diff)
downloadruby-openssl-0321b1e945f89d08ab3632fe8bb3b7726086e9bb.tar.gz
BN.abs and BN uplus
Adds standard math abs fuction and revises uplus to return a duplicated object due to BN mutability
-rw-r--r--ext/openssl/ossl_bn.c31
-rw-r--r--test/openssl/test_bn.rb21
2 files changed, 51 insertions, 1 deletions
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c
index 1d43e457..ac3f8382 100644
--- a/ext/openssl/ossl_bn.c
+++ b/ext/openssl/ossl_bn.c
@@ -936,7 +936,17 @@ ossl_bn_copy(VALUE self, VALUE other)
static VALUE
ossl_bn_uplus(VALUE self)
{
- return 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;
}
/*
@@ -960,6 +970,24 @@ ossl_bn_uminus(VALUE self)
return obj;
}
+/*
+ * call-seq:
+ * bn.abs -> aBN
+ */
+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);
+ }
+}
+
#define BIGNUM_CMP(func) \
static VALUE \
ossl_bn_##func(VALUE self, VALUE other) \
@@ -1176,6 +1204,7 @@ Init_ossl_bn(void)
rb_define_method(cBN, "+@", ossl_bn_uplus, 0);
rb_define_method(cBN, "-@", ossl_bn_uminus, 0);
+ rb_define_method(cBN, "abs", ossl_bn_abs, 0);
rb_define_method(cBN, "+", ossl_bn_add, 1);
rb_define_method(cBN, "-", ossl_bn_sub, 1);
diff --git a/test/openssl/test_bn.rb b/test/openssl/test_bn.rb
index 547d334c..1ed4bbee 100644
--- a/test/openssl/test_bn.rb
+++ b/test/openssl/test_bn.rb
@@ -131,6 +131,27 @@ class OpenSSL::TestBN < OpenSSL::TestCase
assert_equal(-999, +@e2)
assert_equal(-999, -@e1)
assert_equal(+999, -@e2)
+
+ # These methods create new BN instances due to BN mutability
+ # Ensure that the instance isn't the same
+ e1_plus = +@e1
+ e1_minus = -@e1
+ assert_equal(false, @e1.equal?(e1_plus))
+ assert_equal(true, @e1 == e1_plus)
+ assert_equal(false, @e1.equal?(e1_minus))
+ end
+
+ def test_abs
+ assert_equal(@e1, @e2.abs)
+ assert_equal(@e3, @e4.abs)
+ assert_not_equal(@e2, @e2.abs)
+ assert_not_equal(@e4, @e4.abs)
+ assert_equal(false, @e2.abs.negative?)
+ assert_equal(false, @e4.abs.negative?)
+ assert_equal(true, (-@e1.abs).negative?)
+ assert_equal(true, (-@e2.abs).negative?)
+ assert_equal(true, (-@e3.abs).negative?)
+ assert_equal(true, (-@e4.abs).negative?)
end
def test_mod