Esempio n. 1
0
static void test_extended_key()
{
	printf("TEST: test_extended_key\n");

	// Check we get sensible results when parsing some test vector data

	struct hd_extended_key pub;
	assert(hd_extended_key_init(&pub));
	{
		cstring *tv1data = base58_decode(s_tv1_m_xpub);
		assert(hd_extended_key_deser(&pub, tv1data->str, tv1data->len));
		cstr_free(tv1data, true);
	}

	struct hd_extended_key priv;
	assert(hd_extended_key_init(&priv));
	{
		cstring *tv1data = base58_decode(s_tv1_m_xprv);
		assert(hd_extended_key_deser(&priv, tv1data->str, tv1data->len));
		cstr_free(tv1data, true);
	}

	printf("PUB:\n");
	print_ek_public(&pub);

	printf("PRV:\n");
	print_ek_public(&priv);

	// Check we get the same codechains

	assert(0 == memcmp(pub.chaincode.data, priv.chaincode.data, 32));

	hd_extended_key_free(&priv);
	hd_extended_key_free(&pub);
}
Esempio n. 2
0
static void wallet_free_hdkey(void *p)
{
	struct hd_extended_key *hdkey = p;

	if (!hdkey)
		return;

	hd_extended_key_free(hdkey);
	memset(hdkey, 0, sizeof(*hdkey));
	free(hdkey);
}
Esempio n. 3
0
cstring *wallet_new_address(struct wallet *wlt)
{
	struct hd_path_seg hdpath[] = {
		{ 44, true },	// BIP 44
		{ 0, true },	// chain: BTC
		{ 0, true },	// acct#
		{ 0, false },	// change?
		{ 0, false },	// key index
	};

	struct wallet_account *acct = account_byname(wlt, wlt->def_acct->str);
	if (!acct)
		return NULL;

	// patch HD path based on account settings
	hdpath[2].index = acct->acct_idx;
	hdpath[4].index = acct->next_key_idx;

	assert(wlt->hdmaster && (wlt->hdmaster->len > 0));
	struct hd_extended_key *master = parr_idx(wlt->hdmaster, 0);
	assert(master != NULL);

	struct hd_extended_key child;
	hd_extended_key_init(&child);

	if (!hd_derive(&child, master, hdpath, ARRAY_SIZE(hdpath))) {
		hd_extended_key_free(&child);
		return NULL;
	}

	acct->next_key_idx++;

	cstring *rs = bp_pubkey_get_address(&child.key,wlt->chain->addr_pubkey);

	hd_extended_key_free(&child);

	return rs;
}
Esempio n. 4
0
static void test_vector_2()
{
	struct hd_extended_key_serialized tv2_m_xpub;
	read_ek_ser_from_base58(s_tv2_m_xpub, &tv2_m_xpub);
	struct hd_extended_key_serialized tv2_m_xprv;
	read_ek_ser_from_base58(s_tv2_m_xprv, &tv2_m_xprv);
	struct hd_extended_key_serialized tv2_m_0_xpub;
	read_ek_ser_from_base58(s_tv2_m_0_xpub, &tv2_m_0_xpub);
	struct hd_extended_key_serialized tv2_m_0_xprv;
	read_ek_ser_from_base58(s_tv2_m_0_xprv, &tv2_m_0_xprv);
	struct hd_extended_key_serialized tv2_m_0_2147483647H_xpub;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_xpub,
				&tv2_m_0_2147483647H_xpub);
	struct hd_extended_key_serialized tv2_m_0_2147483647H_xprv;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_xprv,
				&tv2_m_0_2147483647H_xprv);
	struct hd_extended_key_serialized tv2_m_0_2147483647H_1_xpub;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_1_xpub,
				&tv2_m_0_2147483647H_1_xpub);
	struct hd_extended_key_serialized tv2_m_0_2147483647H_1_xprv;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_1_xprv,
				&tv2_m_0_2147483647H_1_xprv);
	struct hd_extended_key_serialized
		tv2_m_0_2147483647H_1_2147483646H_xpub;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_1_2147483646H_xpub,
				&tv2_m_0_2147483647H_1_2147483646H_xpub);
	struct hd_extended_key_serialized
		tv2_m_0_2147483647H_1_2147483646H_xprv;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_1_2147483646H_xprv,
				&tv2_m_0_2147483647H_1_2147483646H_xprv);
	struct hd_extended_key_serialized
		tv2_m_0_2147483647H_1_2147483646H_2_xpub;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_1_2147483646H_2_xpub,
				&tv2_m_0_2147483647H_1_2147483646H_2_xpub);
	struct hd_extended_key_serialized
		tv2_m_0_2147483647H_1_2147483646H_2_xprv;
	read_ek_ser_from_base58(s_tv2_m_0_2147483647H_1_2147483646H_2_xprv,
				&tv2_m_0_2147483647H_1_2147483646H_2_xprv);

	printf("TEST: test_vector_2\n");

	// Chain m

	struct hd_extended_key m;
	assert(hd_extended_key_init(&m));
	assert(hd_extended_key_generate_master(&m, s_tv2_seed,
					       sizeof(s_tv2_seed)));
	assert(compare_serialized_pub(&m, &tv2_m_xpub));
	assert(compare_serialized_prv(&m, &tv2_m_xprv));

	// Chain m/0

	struct hd_extended_key m_0;
	assert(hd_extended_key_init(&m_0));
	assert(hd_extended_key_generate_child(&m, 0x0, &m_0));
	assert(compare_serialized_pub(&m_0, &tv2_m_0_xpub));
	assert(compare_serialized_prv(&m_0, &tv2_m_0_xprv));

	// Chain m/0/2147483647H

	struct hd_extended_key m_0_2147483647H;
	assert(hd_extended_key_init(&m_0_2147483647H));
	assert(hd_extended_key_generate_child(&m_0, 0x80000000 | 2147483647,
					      &m_0_2147483647H));
	assert(compare_serialized_pub(&m_0_2147483647H,
				      &tv2_m_0_2147483647H_xpub));
	assert(compare_serialized_prv(&m_0_2147483647H,
				      &tv2_m_0_2147483647H_xprv));

	// Chain m/0/2147483647H/1

	struct hd_extended_key m_0_2147483647H_1;
	assert(hd_extended_key_init(&m_0_2147483647H_1));
	assert(hd_extended_key_generate_child(&m_0_2147483647H, 1,
					      &m_0_2147483647H_1));
	assert(compare_serialized_pub(&m_0_2147483647H_1,
				      &tv2_m_0_2147483647H_1_xpub));
	assert(compare_serialized_prv(&m_0_2147483647H_1,
				      &tv2_m_0_2147483647H_1_xprv));

	// Chain m/0/2147483647H/1/2147483646H

	struct hd_extended_key m_0_2147483647H_1_2147483646H;
	assert(hd_extended_key_init(&m_0_2147483647H_1_2147483646H));
	assert(hd_extended_key_generate_child(&m_0_2147483647H_1,
					      0x80000000 | 2147483646,
					      &m_0_2147483647H_1_2147483646H));
	assert(compare_serialized_pub(&m_0_2147483647H_1_2147483646H,
				      &tv2_m_0_2147483647H_1_2147483646H_xpub));
	assert(compare_serialized_prv(&m_0_2147483647H_1_2147483646H,
				      &tv2_m_0_2147483647H_1_2147483646H_xprv));

	// Chain m/0/2147483647H/1/2147483646H/2

	struct hd_extended_key m_0_2147483647H_1_2147483646H_2;
	assert(hd_extended_key_init(&m_0_2147483647H_1_2147483646H_2));
	assert(hd_extended_key_generate_child(&m_0_2147483647H_1_2147483646H, 2,
					      &m_0_2147483647H_1_2147483646H_2));
	assert(compare_serialized_pub(&m_0_2147483647H_1_2147483646H_2,
				      &tv2_m_0_2147483647H_1_2147483646H_2_xpub));
	assert(compare_serialized_prv(&m_0_2147483647H_1_2147483646H_2,
				      &tv2_m_0_2147483647H_1_2147483646H_2_xprv));

	hd_extended_key_free(&m_0_2147483647H_1_2147483646H_2);
	hd_extended_key_free(&m_0_2147483647H_1_2147483646H);
	hd_extended_key_free(&m_0_2147483647H_1);
	hd_extended_key_free(&m_0_2147483647H);
	hd_extended_key_free(&m_0);
	hd_extended_key_free(&m);
}
Esempio n. 5
0
static void test_vector_1()
{
	struct hd_extended_key_serialized tv1_m_xpub;
	read_ek_ser_from_base58(s_tv1_m_xpub, &tv1_m_xpub);
	struct hd_extended_key_serialized tv1_m_xprv;
	read_ek_ser_from_base58(s_tv1_m_xprv, &tv1_m_xprv);
	struct hd_extended_key_serialized tv1_m_0H_xpub;
	read_ek_ser_from_base58(s_tv1_m_0H_xpub, &tv1_m_0H_xpub);
	struct hd_extended_key_serialized tv1_m_0H_xprv;
	read_ek_ser_from_base58(s_tv1_m_0H_xprv, &tv1_m_0H_xprv);
	struct hd_extended_key_serialized tv1_m_0H_1_xpub;
	read_ek_ser_from_base58(s_tv1_m_0H_1_xpub, &tv1_m_0H_1_xpub);
	struct hd_extended_key_serialized tv1_m_0H_1_xprv;
	read_ek_ser_from_base58(s_tv1_m_0H_1_xprv, &tv1_m_0H_1_xprv);
	struct hd_extended_key_serialized tv1_m_0H_1_2H_xpub;
	read_ek_ser_from_base58(s_tv1_m_0H_1_2H_xpub, &tv1_m_0H_1_2H_xpub);
	struct hd_extended_key_serialized tv1_m_0H_1_2H_xprv;
	read_ek_ser_from_base58(s_tv1_m_0H_1_2H_xprv, &tv1_m_0H_1_2H_xprv);
	struct hd_extended_key_serialized tv1_m_0H_1_2H_2_xpub;
	read_ek_ser_from_base58(s_tv1_m_0H_1_2H_2_xpub, &tv1_m_0H_1_2H_2_xpub);
	struct hd_extended_key_serialized tv1_m_0H_1_2H_2_xprv;
	read_ek_ser_from_base58(s_tv1_m_0H_1_2H_2_xprv, &tv1_m_0H_1_2H_2_xprv);
	struct hd_extended_key_serialized tv1_m_0H_1_2H_2_1000000000_xpub;
	read_ek_ser_from_base58(s_tv1_m_0H_1_2H_2_1000000000_xpub,
				&tv1_m_0H_1_2H_2_1000000000_xpub);
	struct hd_extended_key_serialized tv1_m_0H_1_2H_2_1000000000_xprv;
	read_ek_ser_from_base58(s_tv1_m_0H_1_2H_2_1000000000_xprv,
				&tv1_m_0H_1_2H_2_1000000000_xprv);

	printf("TEST: test_vector_1\n");

	// Chain m

	struct hd_extended_key m;
	assert(hd_extended_key_init(&m));
	assert(hd_extended_key_generate_master(&m, s_tv1_seed,
					       sizeof(s_tv1_seed)));
	assert(compare_serialized_pub(&m, &tv1_m_xpub));
	assert(compare_serialized_prv(&m, &tv1_m_xprv));

	// Chain m/0H

	struct hd_extended_key m_0H;
	assert(hd_extended_key_init(&m_0H));
	assert(hd_extended_key_generate_child(&m, 0x80000000, &m_0H));
	assert(compare_serialized_pub(&m_0H, &tv1_m_0H_xpub));
	assert(compare_serialized_prv(&m_0H, &tv1_m_0H_xprv));

	// Chain m/0H/1

	struct hd_extended_key m_0H_1;
	assert(hd_extended_key_init(&m_0H_1));
	assert(hd_extended_key_generate_child(&m_0H, 0x00000001, &m_0H_1));
	assert(compare_serialized_pub(&m_0H_1, &tv1_m_0H_1_xpub));
	assert(compare_serialized_prv(&m_0H_1, &tv1_m_0H_1_xprv));

	// Chain m/0H/1/2H

	struct hd_extended_key m_0H_1_2H;
	assert(hd_extended_key_init(&m_0H_1_2H));
	assert(hd_extended_key_generate_child(&m_0H_1, 0x80000002, &m_0H_1_2H));
	assert(compare_serialized_pub(&m_0H_1_2H, &tv1_m_0H_1_2H_xpub));
	assert(compare_serialized_prv(&m_0H_1_2H, &tv1_m_0H_1_2H_xprv));

	// Chain m/0H/1/2H/2

	struct hd_extended_key m_0H_1_2H_2;
	assert(hd_extended_key_init(&m_0H_1_2H_2));
	assert(hd_extended_key_generate_child(&m_0H_1_2H, 0x00000002,
					      &m_0H_1_2H_2));
	assert(compare_serialized_pub(&m_0H_1_2H_2, &tv1_m_0H_1_2H_2_xpub));
	assert(compare_serialized_prv(&m_0H_1_2H_2, &tv1_m_0H_1_2H_2_xprv));

	// Chain m/0H/1/2H/2/1000000000

	struct hd_extended_key m_0H_1_2H_2_1000000000;
	assert(hd_extended_key_init(&m_0H_1_2H_2_1000000000));
	assert(hd_extended_key_generate_child(&m_0H_1_2H_2, 1000000000,
					      &m_0H_1_2H_2_1000000000));
	assert(compare_serialized_pub(&m_0H_1_2H_2_1000000000,
				      &tv1_m_0H_1_2H_2_1000000000_xpub));
	assert(compare_serialized_prv(&m_0H_1_2H_2_1000000000,
				      &tv1_m_0H_1_2H_2_1000000000_xprv));

	hd_extended_key_free(&m_0H_1_2H_2_1000000000);
	hd_extended_key_free(&m_0H_1_2H_2);
	hd_extended_key_free(&m_0H_1_2H);
	hd_extended_key_free(&m_0H_1);
	hd_extended_key_free(&m_0H);
	hd_extended_key_free(&m);
}
Esempio n. 6
0
static void test_serialize()
{
	printf("TEST: test_serialize\n");

	const char seed[] = "picocoin test seed";

	struct hd_extended_key m;
	struct hd_extended_key_serialized m_xpub;
	struct hd_extended_key_serialized m_xprv;

	{
		assert(hd_extended_key_init(&m));
		assert(hd_extended_key_generate_master(&m, seed, sizeof(seed)));
		assert(0 == m.depth);
		assert(0 == m.index);
		assert(write_ek_ser_pub(&m_xpub, &m));
		assert(write_ek_ser_prv(&m_xprv, &m));
	}

	// Check that there are no gaps in serialized data

	{
		struct hd_extended_key_serialized m_xpub_A;
		struct hd_extended_key_serialized m_xpub_B;

		memset(m_xpub_A.data, 0xff, sizeof(m_xpub_A.data));
		assert(write_ek_ser_pub(&m_xpub_A, &m));
		memset(m_xpub_B.data, 0x00, sizeof(m_xpub_B.data));
		assert(write_ek_ser_pub(&m_xpub_B, &m));
		assert(0 == memcmp(m_xpub_A.data, m_xpub_B.data, sizeof(m_xpub_B.data)));
	}

	{
		struct hd_extended_key_serialized m_xprv_A;
		struct hd_extended_key_serialized m_xprv_B;

		memset(m_xprv_A.data, 0xff, sizeof(m_xprv_A.data));
		assert(write_ek_ser_prv(&m_xprv_A, &m));
		memset(m_xprv_B.data, 0x00, sizeof(m_xprv_B.data));
		assert(write_ek_ser_prv(&m_xprv_B, &m));
		assert(0 == memcmp(m_xprv_A.data, m_xprv_B.data, sizeof(m_xprv_B.data)));
	}

	// generate child keys 1 and 2H, keep serialized version for
	// comparison

	struct hd_extended_key m_1;
	struct hd_extended_key_serialized m_1_xpub;
	struct hd_extended_key_serialized m_1_xprv;

	struct hd_extended_key m_2H;
	struct hd_extended_key_serialized m_2H_xpub;
	struct hd_extended_key_serialized m_2H_xprv;

	{
		assert(hd_extended_key_init(&m_1));
		assert(hd_extended_key_generate_child(&m, 1, &m_1));
		assert(write_ek_ser_pub(&m_1_xpub, &m_1));
		assert(write_ek_ser_prv(&m_1_xprv, &m_1));

		assert(hd_extended_key_init(&m_2H));
		assert(hd_extended_key_generate_child(&m, 0x80000002, &m_2H));
		assert(write_ek_ser_pub(&m_2H_xpub, &m_2H));
		assert(write_ek_ser_prv(&m_2H_xprv, &m_2H));
	}

	// read back in, re-serialize and check the memory

	{
		struct hd_extended_key m_1_;
		struct hd_extended_key_serialized m_1_xpub_;
		struct hd_extended_key_serialized m_1_xprv_;
		assert(hd_extended_key_init(&m_1_));
		assert(hd_extended_key_deser(&m_1_, m_1_xprv.data, sizeof(m_1_xprv)));
		assert(write_ek_ser_pub(&m_1_xpub_, &m_1_));
		assert(write_ek_ser_prv(&m_1_xprv_, &m_1_));

		assert(0 == memcmp(&m_1_xpub, &m_1_xpub_, sizeof(m_1_xpub_)));
		assert(0 == memcmp(&m_1_xprv, &m_1_xprv_, sizeof(m_1_xprv_)));

		hd_extended_key_free(&m_1_);
	}

	{
		struct hd_extended_key m_2H_;
		struct hd_extended_key_serialized m_2H_xpub_;
		struct hd_extended_key_serialized m_2H_xprv_;
		assert(hd_extended_key_init(&m_2H_));
		assert(hd_extended_key_deser(&m_2H_, m_2H_xprv.data, sizeof(m_2H_xprv)));
		assert(write_ek_ser_pub(&m_2H_xpub_, &m_2H_));
		assert(write_ek_ser_prv(&m_2H_xprv_, &m_2H_));

		assert(0 == memcmp(&m_2H_xpub, &m_2H_xpub_, sizeof(m_2H_xpub_)));
		assert(0 == memcmp(&m_2H_xprv, &m_2H_xprv_, sizeof(m_2H_xprv_)));

		hd_extended_key_free(&m_2H_);
	}

	// read back master, generate child, check prv and pub

	{
		struct hd_extended_key m_;
		struct hd_extended_key m_1_;
		struct hd_extended_key m_2H_;

		assert(hd_extended_key_init(&m_));
		assert(hd_extended_key_deser(&m_, m_xprv.data, sizeof(m_xprv)));

		assert(hd_extended_key_init(&m_1_));
		assert(hd_extended_key_generate_child(&m_, 1, &m_1_));
		assert(check_keys_match(&m_1, &m_1_));

		assert(hd_extended_key_init(&m_2H_));
		assert(hd_extended_key_generate_child(&m_, 0x80000002, &m_2H_));
		assert(check_keys_match(&m_2H, &m_2H_));

		hd_extended_key_free(&m_2H_);
		hd_extended_key_free(&m_1_);
		hd_extended_key_free(&m_);
	}

	// read back master from xpub and generate child.  ensure prv keys
	// can't be retrieved but public keys match.

	{
		struct hd_extended_key m_;
		struct hd_extended_key m_1_;
		uint8_t priv[32];

		assert(hd_extended_key_init(&m_));
		assert(hd_extended_key_deser(&m_, m_xpub.data, sizeof(m_xpub)));
		assert(!bp_key_secret_get(&priv[0], sizeof(priv), &m_.key));

		assert(hd_extended_key_init(&m_1_));
		assert(hd_extended_key_generate_child(&m_, 1, &m_1_));
		assert(!bp_key_secret_get(&priv[0], sizeof(priv), &m_1_.key));

		assert(check_keys_match(&m_1, &m_1_));

		hd_extended_key_free(&m_1_);
		hd_extended_key_free(&m_);
	}

	// read back child from xpub.  ensure no hardened children can be
	// generated.

	{
		struct hd_extended_key m_2H_;
		struct hd_extended_key m_2H_3H_;
		assert(hd_extended_key_init(&m_2H_));
		assert(hd_extended_key_deser(&m_2H_, m_2H_xpub.data, sizeof(m_2H_xpub)));

		assert(hd_extended_key_init(&m_2H_3H_));
		assert(!hd_extended_key_generate_child(&m_2H_, 0x80000003, &m_2H_));

		hd_extended_key_free(&m_2H_3H_);
		hd_extended_key_free(&m_2H_);
	}

	hd_extended_key_free(&m_2H);
	hd_extended_key_free(&m_1);
	hd_extended_key_free(&m);
}