Esempio n. 1
0
bool bp_key_secret_set(struct bp_key *key, const void *privkey_, size_t pk_len)
{
	bp_key_free(key);

	if (!privkey_ || pk_len != 32)
		return false;

	const unsigned char *privkey = privkey_;
	BIGNUM *bn = BN_bin2bn(privkey, 32, BN_new());
	if (!bn)
		return false;

	key->k = EC_KEY_new_by_curve_name(NID_secp256k1);
	if (!key->k)
		goto err_out;
	
	if (!EC_KEY_regenerate_key(key->k, bn))
		goto err_out;
	if (!EC_KEY_check_key(key->k))
		return false;

	EC_KEY_set_conv_form(key->k, POINT_CONVERSION_COMPRESSED);

	BN_clear_free(bn);
	return true;

err_out:
	bp_key_free(key);
	BN_clear_free(bn);
	return false;
}
Esempio n. 2
0
static bool bp_checksig(const struct buffer *vchSigIn,
			const struct buffer *vchPubKey,
			const cstring *scriptCode,
			const struct bp_tx *txTo, unsigned int nIn)
{
	if (!vchSigIn || !vchPubKey || !scriptCode || !txTo ||
	    !vchSigIn->len || !vchPubKey->len || !scriptCode->len)
		return false;

	// Hash type is one byte tacked on to the end of the signature
	unsigned char *vch_back = vchSigIn->p + (vchSigIn->len - 1);
	int nHashType = *vch_back;
	struct buffer vchSig = { vchSigIn->p, vchSigIn->len - 1 };

	/* calculate signature hash of transaction */
	bu256_t sighash;
	bp_tx_sighash(&sighash, scriptCode, txTo, nIn, nHashType);

	/* verify signature hash */
	struct bp_key pubkey;
	bp_key_init(&pubkey);
	bool rc = false;
	if (!bp_pubkey_set(&pubkey, vchPubKey->p, vchPubKey->len))
		goto out;
	if (!bp_verify(&pubkey, &sighash, sizeof(sighash), vchSig.p, vchSig.len))
		goto out;

	rc = true;

out:
	bp_key_free(&pubkey);
	return rc;
}
Esempio n. 3
0
static void g_bp_key_free(gpointer data)
{
	struct bp_key *key = data;

	if (!key)
		return;

	bp_key_free(key);
	free(key);
}
Esempio n. 4
0
static void keytest()
{
	{
		struct bp_key k;
		bp_key_init(&k);
		bp_key_free(&k);
	}

	// Signature

	{
		const uint8_t test_secret[32] = { 0x1 };
		const uint8_t test_data[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
		bu256_t hash;
		SHA256(test_data, sizeof(test_data), (uint8_t *)&hash);

		void *pub = NULL;
		size_t publen = 0;
		void *sig = NULL;
		size_t siglen = 0;

		struct bp_key k;
		bp_key_init(&k);
		assert(bp_key_secret_set(&k, test_secret, sizeof(test_secret)));
		assert(bp_pubkey_get(&k, &pub, &publen));
		assert(NULL != pub);
		assert(0 != publen);

		assert(bp_sign(&k, (uint8_t *)&hash, sizeof(hash), &sig, &siglen));
		assert(NULL != sig);
		assert(0 != siglen);
		bp_key_free(&k);

		struct bp_key pubk;
		bp_key_init(&k);
		assert(bp_pubkey_set(&pubk, pub, publen));
		assert(bp_verify(&pubk, (uint8_t *)&hash, sizeof(hash), sig, siglen));

		bp_key_free(&k);
		free(pub);
		free(sig);
	}
}
Esempio n. 5
0
static void wallet_free_key(void *p)
{
	struct bp_key *key = p;

	if (!key)
		return;

	bp_key_free(key);
	memset(key, 0, sizeof(*key));
	free(key);
}
Esempio n. 6
0
static bool bp_checksig(const struct buffer *vchSigHT,
			const struct buffer *vchPubKey,
			const GString *scriptCode,
			const struct bp_tx *txTo, unsigned int nIn,
			int nHashType)
{
	if (!vchSigHT || !vchPubKey || !scriptCode || !txTo ||
	    !vchSigHT->len || !vchPubKey->len || !scriptCode->len)
		return false;

	/* examine hashtype at end of string, then remove it */
	unsigned char *vch_back = vchSigHT->p + (vchSigHT->len - 1);
	if (nHashType == 0)
		nHashType = *vch_back;
	else if (nHashType != *vch_back)
		return false;
	struct buffer vchSig = { vchSigHT->p, vchSigHT->len - 1 };

	/* calculate signature hash of transaction */
	bu256_t sighash;
	bp_tx_sighash(&sighash, scriptCode, txTo, nIn, nHashType);

	/* verify signature hash */
	struct bp_key key;
	bp_key_init(&key);

	bool rc = false;
	if (!bp_pubkey_set(&key, vchPubKey->p, vchPubKey->len))
		goto out;
	if (!bp_verify(&key, &sighash, sizeof(sighash), vchSig.p, vchSig.len))
		goto out;

	rc = true;

out:
	bp_key_free(&key);
	return rc;
}
Esempio n. 7
0
static bool sign1(const bu160_t *key_id, struct bp_keystore *ks,
		  const bu256_t *hash, int nHashType,
		  cstring *scriptSig)
{
	struct bp_key key;
	bool rc = false;

	bp_key_init(&key);

	/* find private key in keystore */
	if (!bkeys_key_get(ks, key_id, &key))
		goto out;

	void *sig = NULL;
	size_t siglen = 0;

	/* sign hash with private key */
	if (!bp_sign(&key, hash, sizeof(*hash), &sig, &siglen))
		goto out;

	/* append nHashType to signature */
	unsigned char ch = (unsigned char) nHashType;
	sig = realloc(sig, siglen + 1);
	memcpy(sig + siglen, &ch, 1);
	siglen++;

	/* append signature to scriptSig */
	bsp_push_data(scriptSig, sig, siglen);
	free(sig);

	rc = true;

out:
	bp_key_free(&key);
	return rc;
}
Esempio n. 8
0
static void runtest(const char *json_base_fn, const char *ser_in_fn,
		    const char *block_in_hash, const char *tx_in_hash)
{
	/* read wallet data */
	char *json_fn = test_filename(json_base_fn);
	json_t *wallet = read_json(json_fn);
	assert(wallet != NULL);

	/* read block data containing incoming payment */
	char *fn = test_filename(ser_in_fn);
	void *data;
	size_t data_len;
	assert(bu_read_file(fn, &data, &data_len, 1 * 1024 * 1024) == true);

	struct bp_block block_in;
	bp_block_init(&block_in);
	struct const_buffer buf = { data, data_len };

	assert(deser_bp_block(&block_in, &buf) == true);
	bp_block_calc_sha256(&block_in);

	/* verify block-in data matches expected block-in hash */
	bu256_t check_hash;
	assert(hex_bu256(&check_hash, block_in_hash) == true);

	assert(bu256_equal(&block_in.sha256, &check_hash) == true);

	/* load key that has received an incoming payment */
	struct bp_key key;
	assert(bp_key_init(&key) == true);

	load_json_key(wallet, &key);

	/* load key into keyset */
	struct bp_keyset ks;
	bpks_init(&ks);

	assert(bpks_add(&ks, &key) == true);

	/* find key matches in block */
	parr *matches;
	matches = bp_block_match(&block_in, &ks);
	assert(matches != NULL);
	assert(matches->len == 1);

	struct bp_block_match *match = parr_idx(matches, 0);
	assert(match->n == 1);			/* match 2nd tx, index 1 */

	/* get matching transaction */
	struct bp_tx *tx = parr_idx(block_in.vtx, match->n);
	bp_tx_calc_sha256(tx);

	/* verify txid matches expected */
	char tx_hexstr[BU256_STRSZ];
	bu256_hex(tx_hexstr, &tx->sha256);
	assert(strcmp(tx_hexstr, tx_in_hash) == 0);

	/* verify mask matches 2nd txout (1 << 1) */
	BIGNUM tmp_mask;
	BN_init(&tmp_mask);
	BN_one(&tmp_mask);
	BN_lshift(&tmp_mask, &tmp_mask, 1);
	assert(BN_cmp(&tmp_mask, &match->mask) == 0);

	/* build merkle tree, tx's branch */
	parr *mtree = bp_block_merkle_tree(&block_in);
	assert(mtree != NULL);
	parr *mbranch = bp_block_merkle_branch(&block_in, mtree, match->n);
	assert(mbranch != NULL);

	/* verify merkle branch for tx matches expected */
	bu256_t mrk_check;
	bp_check_merkle_branch(&mrk_check, &tx->sha256, mbranch, match->n);
	assert(bu256_equal(&mrk_check, &block_in.hashMerkleRoot) == true);

	/* release resources */
	parr_free(mtree, true);
	parr_free(mbranch, true);
	BN_clear_free(&tmp_mask);
	parr_free(matches, true);
	bpks_free(&ks);
	bp_key_free(&key);
	bp_block_free(&block_in);
	json_decref(wallet);
	free(data);
	free(fn);
	free(json_fn);
}
Esempio n. 9
0
static void runtest(void)
{
	unsigned int i;
	struct bp_key keys[4];

	/* generate keys */
	for (i = 0; i < ARRAY_SIZE(keys); i++) {
		struct bp_key *key = &keys[i];
		assert(bp_key_init(key) == true);
		assert(bp_key_generate(key) == true);
	}

	struct bp_keyset ks;

	bpks_init(&ks);

	/* add all but one to keyset */
	for (i = 0; i < (ARRAY_SIZE(keys) - 1); i++)
		assert(bpks_add(&ks, &keys[i]) == true);

	/* verify all-but-one are in keyset */
	for (i = 0; i < (ARRAY_SIZE(keys) - 1); i++) {
		unsigned char md160[RIPEMD160_DIGEST_LENGTH];
		void *pubkey;
		size_t pklen;

		assert(bp_pubkey_get(&keys[i], &pubkey, &pklen) == true);

		bu_Hash160(md160, pubkey, pklen);

		assert(bpks_lookup(&ks, pubkey, pklen, true) == false);
		assert(bpks_lookup(&ks, pubkey, pklen, false) == true);

		assert(bpks_lookup(&ks, md160, sizeof(md160), true) == true);
		assert(bpks_lookup(&ks, md160, sizeof(md160), false) == false);

		free(pubkey);
	}

	/* verify last key not in keyset */
	{
		unsigned char md160[RIPEMD160_DIGEST_LENGTH];
		void *pubkey;
		size_t pklen;

		struct bp_key *key = &keys[ARRAY_SIZE(keys) - 1];
		assert(bp_pubkey_get(key, &pubkey, &pklen) == true);

		bu_Hash160(md160, pubkey, pklen);

		assert(bpks_lookup(&ks, pubkey, pklen, true) == false);
		assert(bpks_lookup(&ks, pubkey, pklen, false) == false);

		assert(bpks_lookup(&ks, md160, sizeof(md160), true) == false);
		assert(bpks_lookup(&ks, md160, sizeof(md160), false) == false);

		free(pubkey);
	}

	bpks_free(&ks);

	for (i = 0; i < ARRAY_SIZE(keys); i++) {
		struct bp_key *key = &keys[i];
		bp_key_free(key);
	}
}