Пример #1
0
/* Is a < b? (If equal we don't care) */
static bool key_less(const struct pubkey *a, const struct pubkey *b)
{
	/* Shorter one wins. */
	if (pubkey_len(a) != pubkey_len(b))
		return pubkey_len(a) < pubkey_len(b);

	return memcmp(a->key, b->key, pubkey_len(a)) < 0;
}
Пример #2
0
void bitcoin_address(const struct pubkey *key, struct bitcoin_address *addr)
{
	struct sha256 h;

	sha256(&h, key->key, pubkey_len(key));
	ripemd160(&addr->addr, h.u.u8, sizeof(h));
}
Пример #3
0
BitcoinPubkey *pubkey_to_proto(const tal_t *ctx, const struct pubkey *key)
{
    BitcoinPubkey *p = tal(ctx, BitcoinPubkey);

    bitcoin_pubkey__init(p);
    p->key.len = pubkey_len(key);
    p->key.data = tal_dup_arr(p, u8, key->key, p->key.len, 0);

    assert(pubkey_valid(p->key.data, p->key.len));
    return p;
}
Пример #4
0
static void dump_tx(const char *msg,
		    const struct bitcoin_tx *tx, size_t inputnum,
		    const u8 *script, size_t script_len,
		    const struct pubkey *key,
		    const struct sha256_double *h)
{
	size_t i, j;
	warnx("%s tx version %u locktime %#x:",
	      msg, tx->version, tx->lock_time);
	for (i = 0; i < tx->input_count; i++) {
		warnx("input[%zu].txid = "SHA_FMT, i,
		      SHA_VALS(tx->input[i].txid.sha.u.u8));
		warnx("input[%zu].index = %u", i, tx->input[i].index);
	}
	for (i = 0; i < tx->output_count; i++) {
		warnx("output[%zu].amount = %llu",
		      i, (long long)tx->output[i].amount);
		warnx("output[%zu].script = %llu",
		      i, (long long)tx->output[i].script_length);
		for (j = 0; j < tx->output[i].script_length; j++)
			fprintf(stderr, "%02x", tx->output[i].script[j]);
		fprintf(stderr, "\n");
	}
	warnx("input[%zu].script = %zu", inputnum, script_len);
	for (i = 0; i < script_len; i++)
		fprintf(stderr, "%02x", script[i]);
	if (key) {
		fprintf(stderr, "\nPubkey: ");
		for (i = 0; i < pubkey_len(key); i++)
			fprintf(stderr, "%02x", key->key[i]);
		fprintf(stderr, "\n");
	}
	if (h) {
		fprintf(stderr, "\nHash: ");
		for (i = 0; i < sizeof(h->sha.u.u8); i++)
			fprintf(stderr, "%02x", h->sha.u.u8[i]);
		fprintf(stderr, "\n");
	}
}
Пример #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;
}
Пример #6
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct sha256 seed, revocation_hash, their_rhash;
	OpenChannel *o1, *o2;
	Update *update;
	struct bitcoin_tx *anchor, *commit;
	struct sha256_double anchor_txid;
	struct pkt *pkt;
	struct bitcoin_signature sig;
	EC_KEY *privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	int64_t delta;
	size_t i, p2sh_out;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<seed> <anchor-tx> <open-channel-file1> <open-channel-file2> <commit-privkey> <update-protobuf> [previous-updates]\n"
			   "Accept a new update message",
			   "Print this message.");

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 6)
		opt_usage_exit_fail("Expected 5+ arguments");

	if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed)))
		errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]);
	
	anchor = bitcoin_tx_from_file(ctx, argv[2]);
	bitcoin_txid(anchor, &anchor_txid);
	o1 = pkt_from_file(argv[3], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[4], PKT__PKT_OPEN)->open;

	privkey = key_from_base58(argv[5], strlen(argv[5]), &testnet, &pubkey1);
	if (!privkey)
		errx(1, "Invalid private key '%s'", argv[5]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[5]);

	update = pkt_from_file(argv[6], PKT__PKT_UPDATE)->update;
	
	/* Figure out cumulative delta since anchor. */
	delta = update->delta;
	for (i = 7; i < argc; i++) {
		Update *u = pkt_from_file(argv[i], PKT__PKT_UPDATE)->update;
		delta += u->delta;
	}

	/* Get next revocation hash. */
	shachain_from_seed(&seed, argc - 6, &revocation_hash);
	sha256(&revocation_hash,
	       revocation_hash.u.u8, sizeof(revocation_hash.u.u8));
	
	/* Get pubkeys */
	if (!proto_to_pubkey(o1->anchor->pubkey, &pubkey2))
		errx(1, "Invalid o1 commit pubkey");
	if (pubkey_len(&pubkey1) != pubkey_len(&pubkey2)
	    || memcmp(pubkey1.key, pubkey2.key, pubkey_len(&pubkey2)) != 0)
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->anchor->pubkey, &pubkey2))
		errx(1, "Invalid o2 final pubkey");

	/* This is what the anchor pays to; figure out whick output. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);
	p2sh_out = find_p2sh_out(anchor, redeemscript);

	/* Now create THEIR new commitment tx to spend 2/2 output of anchor. */
	proto_to_sha256(update->revocation_hash, &their_rhash);
	commit = create_commit_tx(ctx, o2, o1, &their_rhash, delta,
				  &anchor_txid, p2sh_out);

	/* If contributions don't exceed fees, this fails. */
	if (!commit)
		errx(1, "Delta too large");

	/* Sign it for them. */
	sign_tx_input(ctx, commit, 0, redeemscript, tal_count(redeemscript),
		      privkey, &pubkey1, &sig.sig);

	pkt = update_accept_pkt(ctx, &sig.sig, &revocation_hash);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
Пример #7
0
static void add_push_key(u8 **scriptp, const struct pubkey *key)
{
	add_push_bytes(scriptp, key->key, pubkey_len(key));
}
Пример #8
0
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *close_tx;
	struct pkt *pkt;
	struct signature sig;
	struct privkey privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	char *close_file = NULL;
	u64 close_fee = 10000;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	opt_register_arg("--complete=<close-msg-file>",
			 opt_set_charp, NULL, &close_file,
			 "Create a close_transaction_complete msg instead");
	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<open-channel-file1> <open-channel-file2> <anchor-file> <commit-privkey> [{+/-}update-protobuf]...\n"
			   "Create the signature needed for the close transaction",
			   "Print this message.");
	opt_register_arg("--close-fee=<bits>",
			 opt_set_bits, opt_show_bits, &close_fee,
			 "100's of satoshi to pay for close tx");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 5)
		opt_usage_exit_fail("Expected 4+ arguments");

	o1 = pkt_from_file(argv[1], PKT__PKT_OPEN)->open;
	o2 = pkt_from_file(argv[2], PKT__PKT_OPEN)->open;
	a = pkt_from_file(argv[3], PKT__PKT_OPEN_ANCHOR)->open_anchor;

	if (!key_from_base58(argv[4], strlen(argv[4]), &testnet, &privkey, &pubkey1))
		errx(1, "Invalid private key '%s'", argv[4]);
	if (!testnet)
		errx(1, "Private key '%s' not on testnet!", argv[4]);

	if (close_file) {
		CloseChannel *c;
		c = pkt_from_file(close_file, PKT__PKT_CLOSE)->close;
		close_fee = c->close_fee;
	}
	
	cstate = gather_updates(ctx, o1, o2, a, close_fee, argv + 5, NULL,
		       NULL, NULL, NULL);

	/* Get pubkeys */
	if (!proto_to_pubkey(o1->commit_key, &pubkey2))
		errx(1, "Invalid o1 commit pubkey");
	if (pubkey_len(&pubkey1) != pubkey_len(&pubkey2)
	    || memcmp(pubkey1.key, pubkey2.key, pubkey_len(&pubkey2)) != 0)
		errx(1, "o1 pubkey != this privkey");
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid o2 commit pubkey");

	/* This is what the anchor pays to. */
	redeemscript = bitcoin_redeem_2of2(ctx, &pubkey1, &pubkey2);

	close_tx = create_close_tx(ctx, o1, o2, a, cstate->a.pay, cstate->b.pay);

	/* Sign it for them. */
	sign_tx_input(ctx, close_tx, 0, redeemscript, tal_count(redeemscript),
		      &privkey, &pubkey1, &sig);

	if (close_file)
		pkt = close_channel_complete_pkt(ctx, &sig);
	else
		pkt = close_channel_pkt(ctx, close_fee, &sig);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}