类 OpenSSL::BN
常量
- CONSTTIME
- MALLOCED
- STATIC_DATA
公共类方法
生成一个位长为 bits 的随机素数。如果 safe 设置为 true
,则生成一个安全素数。如果指定了 add,则生成一个满足条件 p % add = rem
的素数。
参数¶ ↑
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 BIGNUM 对象。
如果 bn
是一个 Integer
或 OpenSSL::BN
,则返回一个表示相同值的 OpenSSL::BN
的新实例。另请参见 Integer#to_bn
以获取简写形式。
如果给定一个 String
,则内容将根据 base
进行解析。
string
-
要解析的字符串。
base
-
格式。必须是以下之一
-
0
- MPI 格式。有关详细信息,请参见手册页 BN_mpi2bn(3)。 -
2
- 正数的可变长度和大端二进制编码。 -
10
- 十进制数表示,负数前带有 ‘-’。 -
16
- 十六进制数表示,负数前带有 ‘-’。
-
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; }
生成一个 bits
位的密码学强伪随机数。
另请参见手册页 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; }
在 0…range
范围内生成一个密码学强伪随机数。
另请参见手册页 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; }
公共实例方法
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; }
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; }
OpenSSL::BN
实例的除法
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); }
仅当 obj 与 bn 的值相同,才返回 true
。将其与 OpenSSL::BN#eql?
进行对比,后者要求 obj 为 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; }
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); } }
测试 bn 中的位 bit,如果设置则返回 true
,否则返回 false
。
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; }
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); }
仅当 obj 是一个与 bn 值相同的 OpenSSL::BN
时,才返回 true
。将其与 OpenSSL::BN#==
进行对比,后者执行类型转换。
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; }
返回此对象的哈希码。
另请参见 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; }
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; }
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; }
# 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
对 bn
执行 Miller-Rabin 概率素数测试。
checks
参数在版本 3.0 中已弃用。 它没有效果。
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; }
对 bn
执行 Miller-Rabin 概率素数测试。
在版本 3.0 中已弃用。 改用 prime?
。
checks
和 trial_div
参数不再有任何效果。
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); }
启用 BN
对象上的标志。目前,flags 参数可以包含零个 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; }
static VALUE ossl_bn_to_bn(VALUE self) { return self; }
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; }
返回大数的字符串表示形式。
BN.new
可以解析编码后的字符串以转换回 OpenSSL::BN
。
base
-
格式。必须是以下之一
-
0
- MPI 格式。有关详细信息,请参见手册页 BN_bn2mpi(3)。 -
2
- 可变长度和大端二进制编码。大数的符号被忽略。 -
10
- 十进制数表示,负大数前带有 ‘-’。 -
16
- 十六进制数表示,负大数前带有 ‘-’。
-
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; }