diff options
Diffstat (limited to 'ext/openssl/ossl_bn.c')
-rw-r--r-- | ext/openssl/ossl_bn.c | 186 |
1 files changed, 72 insertions, 114 deletions
diff --git a/ext/openssl/ossl_bn.c b/ext/openssl/ossl_bn.c index 8d0f63a9..56fa0ec3 100644 --- a/ext/openssl/ossl_bn.c +++ b/ext/openssl/ossl_bn.c @@ -792,78 +792,64 @@ BIGNUM_SELF_SHIFT(lshift) */ BIGNUM_SELF_SHIFT(rshift) -#define BIGNUM_RAND(func) \ - static VALUE \ - ossl_bn_s_##func(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, NULL); \ - } \ - if (BN_##func(result, b, top, bottom) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ - } - -/* - * Document-method: OpenSSL::BN.rand - * BN.rand(bits [, fill [, odd]]) -> aBN - */ -BIGNUM_RAND(rand) - /* - * Document-method: OpenSSL::BN.pseudo_rand - * BN.pseudo_rand(bits [, fill [, odd]]) -> aBN - */ -BIGNUM_RAND(pseudo_rand) - -#define BIGNUM_RAND_RANGE(func) \ - static VALUE \ - ossl_bn_s_##func##_range(VALUE klass, VALUE range) \ - { \ - BIGNUM *bn = GetBNPtr(range), *result; \ - VALUE obj = NewBN(klass); \ - if (!(result = BN_new())) { \ - ossl_raise(eBNError, NULL); \ - } \ - if (BN_##func##_range(result, bn) <= 0) { \ - BN_free(result); \ - ossl_raise(eBNError, NULL); \ - } \ - SetBN(obj, result); \ - return obj; \ - } - -/* - * Document-method: OpenSSL::BN.rand_range * call-seq: - * BN.rand_range(range) -> aBN + * BN.rand(bits [, fill [, odd]]) -> aBN + * + * Generates a cryptographically strong pseudo-random number of +bits+. * + * See also the man page BN_rand(3). */ -BIGNUM_RAND_RANGE(rand) +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; +} /* - * Document-method: OpenSSL::BN.pseudo_rand_range * call-seq: - * BN.pseudo_rand_range(range) -> aBN + * BN.rand_range(range) -> aBN * + * Generates a cryptographically strong pseudo-random number in the range + * 0...+range+. + * + * See also the man page BN_rand_range(3). */ -BIGNUM_RAND_RANGE(pseudo_rand) +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; +} /* * call-seq: @@ -1118,34 +1104,29 @@ ossl_bn_hash(VALUE self) * bn.prime? => true | false * bn.prime?(checks) => true | false * - * Performs a Miller-Rabin probabilistic primality test with _checks_ - * iterations. If _checks_ is not specified, a number of iterations is used - * that yields a false positive rate of at most 2^-80 for random input. + * Performs a Miller-Rabin probabilistic primality test for +bn+. * - * === Parameters - * * _checks_ - integer + * <b>+checks+ parameter is deprecated in version 3.0.</b> It has no effect. */ static VALUE ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) { BIGNUM *bn; - VALUE vchecks; - int checks = BN_prime_checks; + int ret; - if (rb_scan_args(argc, argv, "01", &vchecks) == 1) { - checks = NUM2INT(vchecks); - } + rb_check_arity(argc, 0, 1); GetBN(self, bn); - switch (BN_is_prime_ex(bn, checks, ossl_bn_ctx, NULL)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ - return Qnil; + +#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; } /* @@ -1154,40 +1135,17 @@ ossl_bn_is_prime(int argc, VALUE *argv, VALUE self) * bn.prime_fasttest?(checks) => true | false * bn.prime_fasttest?(checks, trial_div) => true | false * - * Performs a Miller-Rabin primality test. This is same as #prime? except this - * first attempts trial divisions with some small primes. + * Performs a Miller-Rabin probabilistic primality test for +bn+. * - * === Parameters - * * _checks_ - integer - * * _trial_div_ - boolean + * <b>Deprecated in version 3.0.</b> 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) { - BIGNUM *bn; - VALUE vchecks, vtrivdiv; - int checks = BN_prime_checks, do_trial_division = 1; - - rb_scan_args(argc, argv, "02", &vchecks, &vtrivdiv); - - if (!NIL_P(vchecks)) { - checks = NUM2INT(vchecks); - } - GetBN(self, bn); - /* handle true/false */ - if (vtrivdiv == Qfalse) { - do_trial_division = 0; - } - switch (BN_is_prime_fasttest_ex(bn, checks, ossl_bn_ctx, do_trial_division, NULL)) { - case 1: - return Qtrue; - case 0: - return Qfalse; - default: - ossl_raise(eBNError, NULL); - } - /* not reachable */ - return Qnil; + rb_check_arity(argc, 0, 2); + return ossl_bn_is_prime(0, argv, self); } /* @@ -1306,9 +1264,9 @@ Init_ossl_bn(void) * get_word */ rb_define_singleton_method(cBN, "rand", ossl_bn_s_rand, -1); - rb_define_singleton_method(cBN, "pseudo_rand", ossl_bn_s_pseudo_rand, -1); rb_define_singleton_method(cBN, "rand_range", ossl_bn_s_rand_range, 1); - rb_define_singleton_method(cBN, "pseudo_rand_range", ossl_bn_s_pseudo_rand_range, 1); + rb_define_alias(rb_singleton_class(cBN), "pseudo_rand", "rand"); + rb_define_alias(rb_singleton_class(cBN), "pseudo_rand_range", "rand_range"); rb_define_singleton_method(cBN, "generate_prime", ossl_bn_s_generate_prime, -1); rb_define_method(cBN, "prime?", ossl_bn_is_prime, -1); |