Ejemplo n.º 1
0
static void test_reverse_copy(void)
{
	size_t a_len = strlen(s_a);
	char buf[a_len + 1];

	bu_reverse_copy((unsigned char *)buf, (unsigned char *)s_a, a_len);
	buf[a_len] = 0;

	assert(!strcmp(s_b, buf));
}
Ejemplo n.º 2
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;
}
Ejemplo n.º 3
0
cstring *base58_decode(const char *s_in)
{
	BIGNUM bn58, bn, bnChar;
	BN_CTX *ctx;
	cstring *ret = NULL;

	ctx = BN_CTX_new();
	BN_init(&bn58);
	BN_init(&bn);
	BN_init(&bnChar);

	BN_set_word(&bn58, 58);
	BN_set_word(&bn, 0);

	while (isspace((int32_t)*s_in))
		s_in++;

	const char *p;
	for (p = s_in; *p; p++) {
		const char *p1 = strchr(base58_chars, *p);
		if (!p1) {
			while (isspace((int32_t)*p))
				p++;
			if (*p != '\0')
				goto out;
			break;
		}

		BN_set_word(&bnChar, p1 - base58_chars);

		if (!BN_mul(&bn, &bn, &bn58, ctx))
			goto out;

		if (!BN_add(&bn, &bn, &bnChar))
			goto out;
	}

	cstring *tmp = bn_getvch(&bn);

	if ((tmp->len >= 2) &&
	    (tmp->str[tmp->len - 1] == 0) &&
	    ((unsigned char)tmp->str[tmp->len - 2] >= 0x80))
		cstr_resize(tmp, tmp->len - 1);

	unsigned int leading_zero = 0;
	for (p = s_in; *p == base58_chars[0]; p++)
		leading_zero++;

	unsigned int be_sz = (uint32_t)tmp->len + (uint32_t)leading_zero;
	cstring *tmp_be = cstr_new_sz(be_sz);
	cstr_resize(tmp_be, be_sz);
	memset(tmp_be->str, 0, be_sz);

	bu_reverse_copy((unsigned char *)tmp_be->str + leading_zero,
			(unsigned char *)tmp->str, tmp->len);

	cstr_free(tmp, true);

	ret = tmp_be;

out:
	BN_clear_free(&bn58);
	BN_clear_free(&bn);
	BN_clear_free(&bnChar);
	BN_CTX_free(ctx);
	return ret;
}