static bool CastToBigNum(mpz_t vo, const struct buffer *buf, bool fRequireMinimal, const size_t nMaxNumSize) { if (buf->len > nMaxNumSize) return false; const unsigned char *vch = buf->p; if (fRequireMinimal && buf->len > 0) { // Check that the number is encoded with the minimum possible // number of bytes. // // If the most-significant-byte - excluding the sign bit - is zero // then we're not minimal. Note how this test also rejects the // negative-zero encoding, 0x80. if ((vch[buf->len - 1] & 0x7f) == 0) { // One exception: if there's more than one byte and the most // significant bit of the second-most-significant-byte is set // it would conflict with the sign bit. An example of this case // is +-255, which encode to 0xff00 and 0xff80 respectively. // (big-endian). if (buf->len <= 1 || (vch[buf->len - 2] & 0x80) == 0) { return false; } } } bn_setvch(vo, buf->p, buf->len); return true; }
static bool CastToBigNum(BIGNUM *vo, const struct buffer *buf) { if (buf->len > nMaxNumSize) return false; // Get rid of extra leading zeros: // buf -> bn -> buf -> bn BIGNUM bn; BN_init(&bn); bn_setvch(&bn, buf->p, buf->len); GString *bn_s = bn_getvch(&bn); bn_setvch(vo, bn_s->str, bn_s->len); g_string_free(bn_s, TRUE); BN_clear_free(&bn); return true; }
cstring *base58_encode(const void *data_, size_t data_len) { const unsigned char *data = data_; BIGNUM bn58, bn0, bn, dv, rem; BN_CTX *ctx; ctx = BN_CTX_new(); BN_init(&bn58); BN_init(&bn0); BN_init(&bn); BN_init(&dv); BN_init(&rem); BN_set_word(&bn58, 58); BN_set_word(&bn0, 0); unsigned char swapbuf[data_len + 1]; bu_reverse_copy(swapbuf, data, data_len); swapbuf[data_len] = 0; bn_setvch(&bn, swapbuf, sizeof(swapbuf)); cstring *rs = cstr_new_sz(data_len * 138 / 100 + 1); while (BN_cmp(&bn, &bn0) > 0) { if (!BN_div(&dv, &rem, &bn, &bn58, ctx)) goto err_out; BN_copy(&bn, &dv); unsigned int c = (int32_t)BN_get_word(&rem); cstr_append_c(rs, base58_chars[c]); } unsigned int i; for (i = 0; i < data_len; i++) { if (data[i] == 0) cstr_append_c(rs, base58_chars[0]); else break; } cstring *rs_swap = cstr_new_sz(rs->len); cstr_resize(rs_swap, rs->len); bu_reverse_copy((unsigned char *) rs_swap->str, (unsigned char *) rs->str, rs->len); cstr_free(rs, true); rs = rs_swap; out: BN_clear_free(&bn58); BN_clear_free(&bn0); BN_clear_free(&bn); BN_clear_free(&dv); BN_clear_free(&rem); BN_CTX_free(ctx); return rs; err_out: cstr_free(rs, true); rs = NULL; goto out; }