#include "../key_derive.c" #include #include #include static bool print_superverbose; #define SUPERVERBOSE(...) \ do { if (print_superverbose) printf(__VA_ARGS__); } while(0) #define PRINT_ACTUAL_FEE #include "../commit_tx.c" #include "../htlc_tx.c" #include #include #include #include #include #include #include /* Turn this on to brute-force fee values */ /*#define DEBUG */ static struct sha256 sha256_from_hex(const char *hex) { struct sha256 sha256; if (strstarts(hex, "0x")) hex += 2; if (!hex_decode(hex, strlen(hex), &sha256, sizeof(sha256))) abort(); return sha256; } /* bitcoind loves its backwards txids! */ static struct sha256_double txid_from_hex(const char *hex) { struct sha256_double sha256; struct sha256 rev = sha256_from_hex(hex); size_t i; for (i = 0; i < sizeof(rev); i++) sha256.sha.u.u8[sizeof(sha256) - 1 - i] = rev.u.u8[i]; return sha256; } static struct privkey privkey_from_hex(const char *hex) { struct privkey pk; size_t len; if (strstarts(hex, "0x")) hex += 2; len = strlen(hex); /* BOLT #3: * * private keys are displayed as 32 bytes plus a trailing 1 (bitcoin's * convention for "compressed" private keys, i.e. keys for which the * public key is compressed) */ if (len == 66 && strends(hex, "01")) len -= 2; if (!hex_decode(hex, len, &pk, sizeof(pk))) abort(); return pk; } static void tx_must_be_eq(const struct bitcoin_tx *a, const struct bitcoin_tx *b) { tal_t *tmpctx = tal_tmpctx(NULL); u8 *lina, *linb; size_t i, len; lina = linearize_tx(tmpctx, a); linb = linearize_tx(tmpctx, b); len = tal_len(lina); if (tal_len(linb) < len) len = tal_len(linb); for (i = 0; i < tal_len(lina); i++) { if (i >= tal_len(linb)) errx(1, "Second tx is truncated:\n" "%s\n" "%s", tal_hex(tmpctx, lina), tal_hex(tmpctx, linb)); if (lina[i] != linb[i]) errx(1, "tx differ at offset %zu:\n" "%s\n" "%s", i, tal_hex(tmpctx, lina), tal_hex(tmpctx, linb)); } if (i != tal_len(linb)) errx(1, "First tx is truncated:\n" "%s\n" "%s", tal_hex(tmpctx, lina), tal_hex(tmpctx, linb)); tal_free(tmpctx); } /* BOLT #3: * * htlc 0 direction: remote->local * htlc 0 amount_msat: 1000000 * htlc 0 expiry: 500 * htlc 0 payment_preimage: 0000000000000000000000000000000000000000000000000000000000000000 * htlc 1 direction: remote->local * htlc 1 amount_msat: 2000000 * htlc 1 expiry: 501 * htlc 1 payment_preimage: 0101010101010101010101010101010101010101010101010101010101010101 * htlc 2 direction: local->remote * htlc 2 amount_msat: 2000000 * htlc 2 expiry: 502 * htlc 2 payment_preimage: 0202020202020202020202020202020202020202020202020202020202020202 * htlc 3 direction: local->remote * htlc 3 amount_msat: 3000000 * htlc 3 expiry: 503 * htlc 3 payment_preimage: 0303030303030303030303030303030303030303030303030303030303030303 * htlc 4 direction: remote->local * htlc 4 amount_msat: 4000000 * htlc 4 expiry: 504 * htlc 4 payment_preimage: 0404040404040404040404040404040404040404040404040404040404040404 */ static const struct htlc **setup_htlcs(const tal_t *ctx) { const struct htlc **htlcs = tal_arr(ctx, const struct htlc *, 5); int i; for (i = 0; i < 5; i++) { struct htlc *htlc = tal(htlcs, struct htlc); htlc->id = i; switch (i) { case 0: htlc->state = RCVD_ADD_ACK_REVOCATION; htlc->msatoshi = 1000000; break; case 1: htlc->state = RCVD_ADD_ACK_REVOCATION; htlc->msatoshi = 2000000; break; case 2: htlc->state = SENT_ADD_ACK_REVOCATION; htlc->msatoshi = 2000000; break; case 3: htlc->state = SENT_ADD_ACK_REVOCATION; htlc->msatoshi = 3000000; break; case 4: htlc->state = RCVD_ADD_ACK_REVOCATION; htlc->msatoshi = 4000000; break; } if (i == 0 || i == 1 || i == 4) { /* direction: remote->local */ } else { /* direction: local->remote */ htlc->state = SENT_ADD_ACK_REVOCATION; } htlc->expiry.locktime = 500 + i; htlc->r = tal(htlc, struct preimage); memset(htlc->r, i, sizeof(*htlc->r)); sha256(&htlc->rhash, htlc->r, sizeof(*htlc->r)); htlcs[i] = htlc; } return htlcs; } #if 0 static struct pubkey pubkey_from_hex(const char *hex) { struct pubkey pubkey; if (strstarts(hex, "0x")) hex += 2; if (!pubkey_from_hexstr(hex, strlen(hex), &pubkey)) abort(); return pubkey; } #endif static void report_htlcs(const struct bitcoin_tx *tx, const struct htlc **htlc_map, u16 to_self_delay, const struct privkey *local_secretkey, const struct pubkey *localkey, const struct pubkey *local_delayedkey, const struct privkey *x_remote_secretkey, const struct pubkey *remotekey, const struct pubkey *local_revocation_key, u64 feerate_per_kw) { tal_t *tmpctx = tal_tmpctx(NULL); size_t i, n; struct sha256_double txid; struct bitcoin_tx **htlc_tx; secp256k1_ecdsa_signature *remotesig; u8 **wscript; htlc_tx = tal_arrz(tmpctx, struct bitcoin_tx *, tal_count(htlc_map)); remotesig = tal_arr(tmpctx, secp256k1_ecdsa_signature, tal_count(htlc_map)); wscript = tal_arr(tmpctx, u8 *, tal_count(htlc_map)); bitcoin_txid(tx, &txid); /* First report remote signatures, in order we would receive them. */ n = 0; for (i = 0; i < tal_count(htlc_map); i++) n += (htlc_map[i] != NULL); printf("num_htlcs: %zu\n", n); for (i = 0; i < tal_count(htlc_map); i++) { const struct htlc *htlc = htlc_map[i]; if (!htlc) continue; if (htlc_owner(htlc) == LOCAL) { htlc_tx[i] = htlc_timeout_tx(htlc_tx, &txid, i, htlc, to_self_delay, local_revocation_key, local_delayedkey, feerate_per_kw); wscript[i] = bitcoin_wscript_htlc_offer(tmpctx, localkey, remotekey, &htlc->rhash, local_revocation_key); } else { htlc_tx[i] = htlc_success_tx(htlc_tx, &txid, i, htlc, to_self_delay, local_revocation_key, local_delayedkey, feerate_per_kw); wscript[i] = bitcoin_wscript_htlc_receive(tmpctx, &htlc->expiry, localkey, remotekey, &htlc->rhash, local_revocation_key); } sign_tx_input(htlc_tx[i], 0, NULL, wscript[i], x_remote_secretkey, remotekey, &remotesig[i]); printf("# signature for output %zi (htlc %zu)\n", i, htlc->id); printf("remote_htlc_signature = %s\n", type_to_string(tmpctx, secp256k1_ecdsa_signature, &remotesig[i])); } /* For any HTLC outputs, produce htlc_tx */ for (i = 0; i < tal_count(htlc_map); i++) { secp256k1_ecdsa_signature localsig; const struct htlc *htlc = htlc_map[i]; if (!htlc) continue; sign_tx_input(htlc_tx[i], 0, NULL, wscript[i], local_secretkey, localkey, &localsig); printf("# local_signature = %s\n", type_to_string(tmpctx, secp256k1_ecdsa_signature, &localsig)); if (htlc_owner(htlc) == LOCAL) { htlc_timeout_tx_add_witness(htlc_tx[i], localkey, remotekey, &htlc->rhash, local_revocation_key, &localsig, &remotesig[i]); } else { htlc_success_tx_add_witness(htlc_tx[i], &htlc->expiry, localkey, remotekey, &localsig, &remotesig[i], htlc->r, local_revocation_key); } printf("output htlc_%s_tx %"PRIu64": %s\n", htlc_owner(htlc) == LOCAL ? "timeout" : "success", htlc->id, tal_hex(tmpctx, linearize_tx(tmpctx, htlc_tx[i]))); } tal_free(tmpctx); } static void report(struct bitcoin_tx *tx, const u8 *wscript, const struct privkey *x_remote_funding_privkey, const struct pubkey *remote_funding_pubkey, const struct privkey *local_funding_privkey, const struct pubkey *local_funding_pubkey, u16 to_self_delay, const struct privkey *local_secretkey, const struct pubkey *localkey, const struct pubkey *local_delayedkey, const struct privkey *x_remote_secretkey, const struct pubkey *remotekey, const struct pubkey *local_revocation_key, u64 feerate_per_kw, const struct htlc **htlc_map) { tal_t *tmpctx = tal_tmpctx(NULL); char *txhex; secp256k1_ecdsa_signature localsig, remotesig; sign_tx_input(tx, 0, NULL, wscript, x_remote_funding_privkey, remote_funding_pubkey, &remotesig); printf("remote_signature = %s\n", type_to_string(tmpctx, secp256k1_ecdsa_signature, &remotesig)); sign_tx_input(tx, 0, NULL, wscript, local_funding_privkey, local_funding_pubkey, &localsig); printf("# local_signature = %s\n", type_to_string(tmpctx, secp256k1_ecdsa_signature, &localsig)); tx->input[0].witness = bitcoin_witness_2of2(tx->input, &localsig, &remotesig, local_funding_pubkey, remote_funding_pubkey); txhex = tal_hex(tmpctx, linearize_tx(tx, tx)); printf("output commit_tx: %s\n", txhex); report_htlcs(tx, htlc_map, to_self_delay, local_secretkey, localkey, local_delayedkey, x_remote_secretkey, remotekey, local_revocation_key, feerate_per_kw); tal_free(tmpctx); } #ifdef DEBUG static u64 calc_fee(const struct bitcoin_tx *tx, u64 input_satoshi) { size_t i; u64 output_satoshi = 0; for (i = 0; i < tal_count(tx->output); i++) output_satoshi += tx->output[i].amount; return input_satoshi - output_satoshi; } /* For debugging, we do brute-force increase to find thresholds */ static u64 increase(u64 feerate_per_kw) { return feerate_per_kw + 1; } #else static u64 increase(u64 feerate_per_kw) { /* BOLT #3: * * local_feerate_per_kw: 0 * ... * local_feerate_per_kw: 648 * ... * local_feerate_per_kw: 2070 * ... * local_feerate_per_kw: 2195 * ... * local_feerate_per_kw: 3703 * ... * local_feerate_per_kw: 4915 * ... * local_feerate_per_kw: 9651181 */ const u64 rates[] = { 0, 648, 2070, 2195, 3703, 4915, 9651181 }; size_t i; for (i = 0; i < ARRAY_SIZE(rates); i++) if (rates[i] == feerate_per_kw) return rates[i+1]; abort(); } #endif /* HTLCs as seen from other side. */ static const struct htlc **invert_htlcs(const struct htlc **htlcs) { size_t i, n = tal_count(htlcs); const struct htlc **inv = tal_arr(htlcs, const struct htlc *, n); for (i = 0; i < n; i++) { struct htlc *htlc; inv[i] = htlc = tal_dup(inv, struct htlc, htlcs[i]); if (inv[i]->state == RCVD_ADD_ACK_REVOCATION) htlc->state = SENT_ADD_ACK_REVOCATION; else { assert(inv[i]->state == SENT_ADD_ACK_REVOCATION); htlc->state = RCVD_ADD_ACK_REVOCATION; } } return inv; } int main(void) { tal_t *tmpctx = tal_tmpctx(NULL); struct sha256_double funding_txid; u64 funding_amount_satoshi, dust_limit_satoshi, feerate_per_kw; u16 to_self_delay; /* x_ prefix means internal vars we used to derive spec */ struct privkey local_funding_privkey, x_remote_funding_privkey; struct privkey x_local_payment_basepoint_secret, x_remote_payment_basepoint_secret; struct privkey x_local_per_commitment_secret; struct privkey x_local_delayed_payment_basepoint_secret; struct privkey x_local_revocation_basepoint_secret; struct privkey local_secretkey, x_remote_secretkey; struct privkey x_local_delayed_secretkey; struct pubkey local_funding_pubkey, remote_funding_pubkey; struct pubkey local_payment_basepoint, remote_payment_basepoint; struct pubkey x_local_delayed_payment_basepoint; struct pubkey x_local_revocation_basepoint; struct pubkey x_local_per_commitment_point; struct pubkey localkey, remotekey, tmpkey; struct pubkey local_delayedkey; struct pubkey local_revocation_key; struct bitcoin_tx *tx, *tx2; u8 *wscript; unsigned int funding_output_index; u64 commitment_number, cn_obscurer, to_local_msat, to_remote_msat; const struct htlc **htlcs = setup_htlcs(tmpctx), **htlc_map, **htlc_map2, **inv_htlcs = invert_htlcs(htlcs); secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN); /* BOLT #3: * * # Appendix C: Commitment and HTLC Transaction Test Vectors * * In the following: * - we consider *local* transactions, which implies that all payments * to *local* are delayed * - we assume that *local* is the funder * - private keys are displayed as 32 bytes plus a trailing 1 * (bitcoin's convention for "compressed" private keys, i.e. keys * for which the public key is compressed) * * - transaction signatures are all deterministic, using * RFC6979 (using HMAC-SHA256) * * We start by defining common basic parameters for each test vector: * the HTLCs are not used for the first "simple commitment tx with no * HTLCs" test. * * funding_tx_id: 8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be * funding_output_index: 0 * funding_amount_satoshi: 10000000 * commitment_number: 42 * local_delay: 144 * local_dust_limit_satoshi: 546 */ funding_txid = txid_from_hex("8984484a580b825b9972d7adb15050b3ab624ccd731946b3eeddb92f4e7ef6be"); funding_output_index = 0; funding_amount_satoshi = 10000000; commitment_number = 42; to_self_delay = 144; dust_limit_satoshi = 546; #ifdef DEBUG print_superverbose = true; #endif /* BOLT #3: * *