Example #1
0
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;
}
Example #2
0
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;
}
Example #3
0
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;
}