Пример #1
0
bool bitcoin_from_base58(bool *test_net,
			 struct bitcoin_address *addr,
			 const char *base58, size_t base58_len)
{
	u8 buf[1 + sizeof(addr->addr) + 4];
	BIGNUM bn;
	size_t len;
	u8 csum[4];

	BN_init(&bn);
	if (!raw_decode_base58(&bn, base58, base58_len))
		return false;

	len = BN_num_bytes(&bn);
	if (len > sizeof(buf))
		return false;

	memset(buf, 0, sizeof(buf));
	BN_bn2bin(&bn, buf + sizeof(buf) - len);
	BN_free(&bn);

	if (buf[0] == 111)
		*test_net = true;
	else if (buf[0] == 0)
		*test_net = false;
	else
		return false;

	base58_get_checksum(csum, buf, 1 + sizeof(addr->addr));
	if (memcmp(csum, buf + 1 + sizeof(addr->addr), sizeof(csum)) != 0)
		return false;

	memcpy(&addr->addr, buf+1, sizeof(addr->addr));
	return true;
}
Пример #2
0
static bool from_base58(u8 *version,
			struct ripemd160 *rmd,
			const char *base58, size_t base58_len)
{
	u8 buf[1 + sizeof(*rmd) + 4];
	BIGNUM bn;
	size_t len;
	u8 csum[4];

	BN_init(&bn);
	if (!raw_decode_base58(&bn, base58, base58_len))
		return false;

	len = BN_num_bytes(&bn);
	if (len > sizeof(buf))
		return false;

	memset(buf, 0, sizeof(buf));
	BN_bn2bin(&bn, buf + sizeof(buf) - len);
	BN_free(&bn);

	*version = buf[0];

	base58_get_checksum(csum, buf, 1 + sizeof(*rmd));
	if (memcmp(csum, buf + 1 + sizeof(*rmd), sizeof(csum)) != 0)
		return false;

	memcpy(rmd, buf+1, sizeof(*rmd));
	return true;
}
Пример #3
0
bool key_from_base58(secp256k1_context *secpctx,
		     const char *base58, size_t base58_len,
		     bool *test_net, struct privkey *priv, struct pubkey *key)
{
	u8 keybuf[1 + 32 + 1 + 4];
	u8 csum[4];
	BIGNUM bn;
	bool compressed;
	size_t keylen;
	
	BN_init(&bn);
	if (!raw_decode_base58(&bn, base58, base58_len))
		return false;

	keylen = BN_num_bytes(&bn);
	if (keylen == 1 + 32 + 4)
		compressed = false;
	else if (keylen == 1 + 32 + 1 + 4)
		compressed = true;
	else
		goto fail_free_bn;
	BN_bn2bin(&bn, keybuf);

	base58_get_checksum(csum, keybuf, keylen - sizeof(csum));
	if (memcmp(csum, keybuf + keylen - sizeof(csum), sizeof(csum)) != 0)
		goto fail_free_bn;

	/* Byte after key should be 1 to represent a compressed key. */
	if (compressed && keybuf[1 + 32] != 1)
		goto fail_free_bn;

	if (keybuf[0] == 128)
		*test_net = false;
	else if (keybuf[0] == 239)
		*test_net = true;
	else
		goto fail_free_bn;

	/* Copy out secret. */
	memcpy(priv->secret, keybuf + 1, sizeof(priv->secret));

	if (!secp256k1_ec_seckey_verify(secpctx, priv->secret))
		goto fail_free_bn;

	/* Get public key, too, since we know if it's compressed. */
	if (!pubkey_from_privkey(secpctx, priv, key,
				 compressed ? SECP256K1_EC_COMPRESSED : 0))
		goto fail_free_bn;

	BN_free(&bn);
	return true;

fail_free_bn:
	BN_free(&bn);
	return false;
}
Пример #4
0
bool ripemd_from_base58(u8 *version,
			struct ripemd160 *ripemd160,
			const char *base58)
{
	u8 buf[1 + sizeof(*ripemd160) + 4];
	u8 csum[4];
	BIGNUM bn;
	size_t len;

	/* Too long?  Check here before doing arithmetic. */
	if (strlen(base58) > BASE58_ADDR_MAX_LEN - 1)
		return false;

	BN_init(&bn);
	/* Fails if it contains invalid characters. */
	if (!raw_decode_base58(&bn, base58, strlen(base58)))
		return false;

	/* Too big? */
	len = BN_num_bytes(&bn);
	if (len > sizeof(buf)) {
		BN_free(&bn);
		return false;
	}

	/* Fill start with zeroes. */
	memset(buf, 0, sizeof(buf) - len);
	BN_bn2bin(&bn, buf + sizeof(buf) - len);
	BN_free(&bn);

	/* Check checksum is correct. */
	base58_get_checksum(csum, buf, sizeof(buf));
	if (memcmp(csum, buf + 1 + sizeof(*ripemd160), 4) != 0)
		return false;

	*version = buf[0];
	memcpy(ripemd160, buf + 1, sizeof(*ripemd160));
	return true;
}
Пример #5
0
bool key_from_base58(const char *base58, size_t base58_len,
		     bool *test_net, struct privkey *priv, struct pubkey *key)
{
	u8 keybuf[1 + 32 + 1 + 4];
	u8 csum[4];
	BIGNUM bn;
	bool compressed;
	secp256k1_context_t *secpctx;
	int keylen;
	
	BN_init(&bn);
	if (!raw_decode_base58(&bn, base58, base58_len))
		return false;

	keylen = BN_num_bytes(&bn);
	if (keylen == 1 + 32 + 4)
		compressed = false;
	else if (keylen == 1 + 32 + 1 + 4)
		compressed = true;
	else
		goto fail_free_bn;
	BN_bn2bin(&bn, keybuf);

	base58_get_checksum(csum, keybuf, keylen - sizeof(csum));
	if (memcmp(csum, keybuf + keylen - sizeof(csum), sizeof(csum)) != 0)
		goto fail_free_bn;

	/* Byte after key should be 1 to represent a compressed key. */
	if (compressed && keybuf[1 + 32] != 1)
		goto fail_free_bn;

	if (keybuf[0] == 128)
		*test_net = false;
	else if (keybuf[0] == 239)
		*test_net = true;
	else
		goto fail_free_bn;

	/* Copy out secret. */
	memcpy(priv->secret, keybuf + 1, sizeof(priv->secret));

	secpctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
	if (!secp256k1_ec_seckey_verify(secpctx, priv->secret))
		goto fail_free_secpctx;

	/* Get public key, too. */
	if (!secp256k1_ec_pubkey_create(secpctx, key->key, &keylen,
					priv->secret, compressed))
		goto fail_free_secpctx;
	assert(keylen == pubkey_len(key));

	BN_free(&bn);
	secp256k1_context_destroy(secpctx);
	return true;

fail_free_secpctx:
	secp256k1_context_destroy(secpctx);
fail_free_bn:
	BN_free(&bn);
	return false;
}