Exemple #1
0
/* Save and check signature. */
static Pkt *check_and_save_commit_sig(struct peer *peer,
				      struct commit_info *ci,
				      const Signature *pb)
{
	struct bitcoin_signature *sig = tal(ci, struct bitcoin_signature);

	assert(!ci->sig);
	sig->stype = SIGHASH_ALL;
	if (!proto_to_signature(peer->dstate->secpctx, pb, &sig->sig))
		return pkt_err(peer, "Malformed signature");

	log_debug(peer->log, "Checking sig for %u/%u msatoshis, %zu/%zu htlcs",
		  ci->cstate->side[OURS].pay_msat,
		  ci->cstate->side[THEIRS].pay_msat,
		  tal_count(ci->cstate->side[OURS].htlcs),
		  tal_count(ci->cstate->side[THEIRS].htlcs));

	/* Their sig should sign our commit tx. */
	if (!check_tx_sig(peer->dstate->secpctx,
			  ci->tx, 0,
			  NULL, 0,
			  peer->anchor.witnessscript,
			  &peer->remote.commitkey,
			  sig))
		return pkt_err(peer, "Bad signature");

	ci->sig = sig;
	return NULL;
}
Exemple #2
0
/* Save and check signature. */
static Pkt *check_and_save_commit_sig(struct peer *peer,
				      struct commit_info *ci,
				      const Signature *pb)
{
	assert(!ci->sig);
	ci->sig = tal(ci, struct bitcoin_signature);
	ci->sig->stype = SIGHASH_ALL;
	if (!proto_to_signature(pb, &ci->sig->sig))
		return pkt_err(peer, "Malformed signature");

	/* Their sig should sign our commit tx. */
	if (!check_tx_sig(peer->dstate->secpctx,
			  ci->tx, 0,
			  NULL, 0,
			  peer->anchor.witnessscript,
			  &peer->them.commitkey,
			  ci->sig))
		return pkt_err(peer, "Bad signature");

	return NULL;
}
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct sha256 seed, preimage, our_rhash, their_rhash;
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct bitcoin_tx *commit;
	struct pkt *pkt;
	struct bitcoin_signature sig;
	struct privkey privkey;
	bool testnet;
	struct pubkey pubkey1, pubkey2;
	u8 *redeemscript;
	size_t num_updates;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<seed> <open-channel-file1> <open-channel-file2> <open-anchor-file> <commit-privkey> <all-previous-updates>...\n"
			   "Create a new update-channel-signature message",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

	if (argc < 8)
		opt_usage_exit_fail("Expected 7+ arguments");

	if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed)))
		errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]);

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

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

	sig.stype = SIGHASH_ALL;

	/* Figure out cumulative delta since anchor. */
	cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 6,
				&num_updates,
				&our_rhash, &their_rhash, &sig.sig);
	if (num_updates < 1)
		errx(1, "Expected at least one update!");

	/* Give up revocation preimage for old tx. */
	shachain_from_seed(&seed, num_updates - 1, &preimage);
	
	/* Get pubkeys */
	if (!proto_to_pubkey(o1->commit_key, &pubkey2))
		errx(1, "Invalid o1 commit pubkey");
	if (!pubkey_eq(&pubkey1, &pubkey2))
		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);

	/* Check our new commit is signed correctly by them. */
	commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, cstate);
	if (!commit)
		errx(1, "Invalid packets");

	/* Check their signature signs this input correctly. */
	if (!check_tx_sig(commit, 0, redeemscript, tal_count(redeemscript),
			  &pubkey2, &sig))
		errx(1, "Invalid signature.");

	/* Now create THEIR new commitment tx to spend 2/2 output of anchor. */
	invert_cstate(cstate);
	commit = create_commit_tx(ctx, o2, o1, a, &their_rhash, cstate);
	if (!commit)
		errx(1, "Invalid packets");

	/* Their pubkey must be valid */
	if (!proto_to_pubkey(o2->commit_key, &pubkey2))
		errx(1, "Invalid public open-channel-file2");

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

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

	tal_free(ctx);
	return 0;
}
int main(int argc, char *argv[])
{
	const tal_t *ctx = tal_arr(NULL, char, 0);
	struct sha256 seed, our_rhash, their_rhash, preimage;
	OpenChannel *o1, *o2;
	OpenAnchor *a;
	struct pkt *pkt;
	struct bitcoin_tx *commit;
	struct pubkey pubkey1, pubkey2;
	size_t num_updates;
	struct bitcoin_signature sig;
	u8 *redeemscript;
	struct channel_state *cstate;

	err_set_progname(argv[0]);

	opt_register_noarg("--help|-h", opt_usage_and_exit,
			   "<seed> <open-channel-file1> <open-channel-file2> <open-anchor-file> <all-previous-updates>\n"
			   "Create a new update-complete message",
			   "Print this message.");
	opt_register_version();

 	opt_parse(&argc, argv, opt_log_stderr_exit);

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

	if (!hex_decode(argv[1], strlen(argv[1]), &seed, sizeof(seed)))
		errx(1, "Invalid seed '%s' - need 256 hex bits", argv[1]);

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

	sig.stype = SIGHASH_ALL;

	/* This also checks that preimage is correct! */
	cstate = gather_updates(ctx, o1, o2, a, commit_fee(o1, o2), argv + 5,
				&num_updates,
				&our_rhash, &their_rhash, &sig.sig);
	if (num_updates < 1)
		errx(1, "Expected at least one update!");

	/* Get pubkeys */
	if (!proto_to_pubkey(o1->commit_key, &pubkey1))
		errx(1, "Invalid o1 commit pubkey");
	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);

	/* Check their signature signs our new commit tx correctly. */
	commit = create_commit_tx(ctx, o1, o2, a, &our_rhash, cstate);
	if (!commit)
		errx(1, "Delta too large");

	if (!check_tx_sig(commit, 0, redeemscript, tal_count(redeemscript),
			  &pubkey2, &sig))
		errx(1, "Invalid signature.");
	
	/* Hand over our preimage for previous tx. */
	shachain_from_seed(&seed, num_updates - 1, &preimage);
	pkt = update_complete_pkt(ctx, &preimage);
	if (!write_all(STDOUT_FILENO, pkt, pkt_totlen(pkt)))
		err(1, "Writing out packet");

	tal_free(ctx);
	return 0;
}
Exemple #5
0
Pkt *accept_pkt_close_sig(struct peer *peer, const Pkt *pkt, bool *acked,
			  bool *we_agree)
{
	const CloseSignature *c = pkt->close_signature;
	struct bitcoin_tx *close_tx;
	struct bitcoin_signature theirsig;

	log_info(peer->log, "accept_pkt_close_sig: they offered close fee %"
		 PRIu64, c->close_fee);
	*acked = *we_agree = false;

	/* BOLT #2:
	 *
	 * The sender MUST set `close_fee` lower than or equal to the fee of the
	 * final commitment transaction, and MUST set `close_fee` to an even
	 * number of satoshis.
	 */
	if ((c->close_fee & 1)
	    || c->close_fee > commit_tx_fee(peer->them.commit->tx,
					    peer->anchor.satoshis)) {
		return pkt_err(peer, "Invalid close fee");
	}

	/* FIXME: Don't accept tiny fee at all? */

	/* BOLT #2:
	   ... otherwise it SHOULD propose a
	   value strictly between the received `close_fee` and its
	   previously-sent `close_fee`.
	*/
	if (peer->closing.their_sig) {
		/* We want more, they should give more. */
		if (peer->closing.our_fee > peer->closing.their_fee) {
			if (c->close_fee <= peer->closing.their_fee)
				return pkt_err(peer, "Didn't increase close fee");
		} else {
			if (c->close_fee >= peer->closing.their_fee)
				return pkt_err(peer, "Didn't decrease close fee");
		}
	}

	/* BOLT #2:
	 *
	 * The receiver MUST check `sig` is valid for the close
	 * transaction, and MUST fail the connection if it is not. */
	theirsig.stype = SIGHASH_ALL;
	if (!proto_to_signature(c->sig, &theirsig.sig))
		return pkt_err(peer, "Invalid signature format");

	close_tx = peer_create_close_tx(peer, c->close_fee);
	if (!check_tx_sig(peer->dstate->secpctx, close_tx, 0,
			  NULL, 0,
			  peer->anchor.witnessscript,
			  &peer->them.commitkey, &theirsig))
		return pkt_err(peer, "Invalid signature");

	tal_free(peer->closing.their_sig);
	peer->closing.their_sig = tal_dup(peer,
					  struct bitcoin_signature, &theirsig);
	peer->closing.their_fee = c->close_fee;

	if (peer->closing.our_fee == peer->closing.their_fee) {
		log_info(peer->log, "accept_pkt_close_sig: That's an ack");
		*acked = true;
	} else {
		/* Adjust our fee to close on their fee. */
		u64 sum;

		/* Beware overflow! */
		sum = (u64)peer->closing.our_fee + peer->closing.their_fee;

		peer->closing.our_fee = sum / 2;
		if (peer->closing.our_fee & 1)
			peer->closing.our_fee++;

		log_info(peer->log, "accept_pkt_close_sig: we change to %"PRIu64,
			 peer->closing.our_fee);

		/* Corner case: we may now agree with them. */
		if (peer->closing.our_fee == peer->closing.their_fee)
			*we_agree = true;
	}

	/* FIXME: Dynamic fee! */
	return NULL;
}