method
new
v2_1_10 -
Show latest stable
- Class:
OpenSSL::BN
new(p1, p2 = v2)public
No documentation available.
static VALUE
ossl_bn_initialize(int argc, VALUE *argv, VALUE self)
{
BIGNUM *bn;
VALUE str, bs;
int base = 10;
if (rb_scan_args(argc, argv, "11", &str, &bs) == 2) {
base = NUM2INT(bs);
}
if (RB_TYPE_P(str, T_FIXNUM)) {
long i;
unsigned char bin[sizeof(long)];
long n = FIX2LONG(str);
unsigned long un = labs(n);
for (i = sizeof(long) - 1; 0 <= i; i--) {
bin[i] = un&0xff;
un >>= 8;
}
GetBN(self, bn);
if (!BN_bin2bn(bin, sizeof(bin), bn)) {
ossl_raise(eBNError, NULL);
}
if (n < 0) BN_set_negative(bn, 1);
return self;
}
else if (RB_TYPE_P(str, T_BIGNUM)) {
int i, j, len = RBIGNUM_LENINT(str);
BDIGIT *ds = RBIGNUM_DIGITS(str);
VALUE buf;
unsigned char *bin = (unsigned char*)ALLOCV_N(BDIGIT, buf, len);
for (i = 0; len > i; i++) {
BDIGIT v = ds[i];
for (j = SIZEOF_BDIGITS - 1; 0 <= j; j--) {
bin[(len-1-i)*SIZEOF_BDIGITS+j] = v&0xff;
v >>= 8;
}
}
GetBN(self, bn);
if (!BN_bin2bn(bin, (int)SIZEOF_BDIGITS*len, bn)) {
ALLOCV_END(buf);
ossl_raise(eBNError, NULL);
}
ALLOCV_END(buf);
if (!RBIGNUM_SIGN(str)) BN_set_negative(bn, 1);
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;
}
StringValue(str);
GetBN(self, bn);
switch (base) {
case 0:
if (!BN_mpi2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
ossl_raise(eBNError, NULL);
}
break;
case 2:
if (!BN_bin2bn((unsigned char *)RSTRING_PTR(str), RSTRING_LENINT(str), bn)) {
ossl_raise(eBNError, NULL);
}
break;
case 10:
if (!BN_dec2bn(&bn, RSTRING_PTR(str))) {
ossl_raise(eBNError, NULL);
}
break;
case 16:
if (!BN_hex2bn(&bn, RSTRING_PTR(str))) {
ossl_raise(eBNError, NULL);
}
break;
default:
ossl_raise(rb_eArgError, "invalid radix %d", base);
}
return self;
}