VALUE asn1integer_to_num(ASN1_INTEGER *ai) { BIGNUM *bn; #if DO_IT_VIA_RUBY char *txt; #endif VALUE num; if (!ai) { ossl_raise(rb_eTypeError, "ASN1_INTEGER is NULL!"); } if (!(bn = ASN1_INTEGER_to_BN(ai, NULL))) { ossl_raise(eOSSLError, NULL); } #if DO_IT_VIA_RUBY if (!(txt = BN_bn2dec(bn))) { BN_free(bn); ossl_raise(eOSSLError, NULL); } num = rb_cstr_to_inum(txt, 10, Qtrue); OPENSSL_free(txt); #else num = ossl_bn_new(bn); #endif BN_free(bn); return num; }
static VALUE str2num(char *s) { if (strchr(s, '/')) return rb_cstr_to_rat(s, 0); if (strpbrk(s, ".eE")) return DBL2NUM(rb_cstr_to_dbl(s, 0)); return rb_cstr_to_inum(s, 10, 0); }
/* * call-seq: * bn.to_i => integer */ static VALUE ossl_bn_to_i(VALUE self) { BIGNUM *bn; char *txt; VALUE num; GetBN(self, bn); if (!(txt = BN_bn2dec(bn))) { ossl_raise(eBNError, NULL); } num = rb_cstr_to_inum(txt, 10, Qtrue); OPENSSL_free(txt); return num; }
static VALUE string_spec_rb_cstr_to_inum(VALUE self, VALUE str, VALUE inum, VALUE badcheck) { int num = FIX2INT(inum); return rb_cstr_to_inum(RSTRING_PTR(str), num, RTEST(badcheck)); }
static VALUE bert_buf_tobignum(struct bert_buf *buf, uint8_t sign, uint32_t bin_digits) { #ifdef BERT_FAST_BIGNUM uint32_t *bin_buf = NULL; VALUE rb_num; uint32_t round_size; bert_buf_ensure(buf, bin_digits); /* Hack: ensure that we have at least a full word * of extra padding for the actual string, so Ruby * cannot guess the sign of the bigint from the MSB */ round_size = 4 + ((bin_digits + 3) & ~3); bin_buf = xmalloc(round_size); memcpy(bin_buf, buf->data, bin_digits); memset((char *)bin_buf + bin_digits, 0x0, round_size - bin_digits); /* Make Ruby unpack the string internally. * this is significantly faster than adding * the bytes one by one */ rb_num = rb_big_unpack(bin_buf, round_size / 4); /* Enfore sign. So fast! */ RBIGNUM_SET_SIGN(rb_num, !sign); free(bin_buf); return rb_num; #else /** * Slower bignum serialization; convert to a base16 * string and then let ruby parse it internally. * * We're shipping with this by default because * `rb_big_unpack` is not trustworthy */ static const char to_hex[] = "0123456789abcdef"; char *num_str = NULL, *ptr; VALUE rb_num; int32_t i; bert_buf_ensure(buf, bin_digits); /* 2 digits per byte + sign + trailing null */ num_str = ptr = xmalloc((bin_digits * 2) + 2); *ptr++ = sign ? '-' : '+'; for (i = (int32_t)bin_digits - 1; i >= 0; --i) { uint8_t val = buf->data[i]; *ptr++ = to_hex[val >> 4]; *ptr++ = to_hex[val & 0xf]; } *ptr = 0; buf->data += bin_digits; rb_num = rb_cstr_to_inum(num_str, 16, 1); free(num_str); return rb_num; #endif }