diff --git a/channeld/full_channel.c b/channeld/full_channel.c
index 59c9f00e7..a0ba3da53 100644
--- a/channeld/full_channel.c
+++ b/channeld/full_channel.c
@@ -242,6 +242,8 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx,
 	if (!derive_keyset(per_commitment_point,
 			   &channel->basepoints[side].payment,
 			   &channel->basepoints[!side].payment,
+			   &channel->basepoints[side].htlc,
+			   &channel->basepoints[!side].htlc,
 			   &channel->basepoints[side].delayed_payment,
 			   &channel->basepoints[!side].revocation,
 			   &keyset))
diff --git a/common/derive_basepoints.c b/common/derive_basepoints.c
index 6db8b2d43..964b03f7f 100644
--- a/common/derive_basepoints.c
+++ b/common/derive_basepoints.c
@@ -22,6 +22,8 @@ bool derive_basepoints(const struct privkey *seed,
 		secrets->funding_privkey = keys.f;
 		secrets->revocation_basepoint_secret = keys.r.secret;
 		secrets->payment_basepoint_secret = keys.p.secret;
+		/* We currently make htlc_basepoint_secret the same */
+		secrets->htlc_basepoint_secret = keys.p.secret;
 		secrets->delayed_payment_basepoint_secret = keys.d.secret;
 	}
 
@@ -32,6 +34,7 @@ bool derive_basepoints(const struct privkey *seed,
 
 	if (basepoints) {
 		if (!pubkey_from_privkey(&keys.r, &basepoints->revocation)
+		    || !pubkey_from_privkey(&keys.p, &basepoints->htlc)
 		    || !pubkey_from_privkey(&keys.p, &basepoints->payment)
 		    || !pubkey_from_privkey(&keys.d, &basepoints->delayed_payment))
 			return false;
diff --git a/common/derive_basepoints.h b/common/derive_basepoints.h
index e36548965..70c1e9863 100644
--- a/common/derive_basepoints.h
+++ b/common/derive_basepoints.h
@@ -12,6 +12,7 @@ struct sha256;
 struct basepoints {
 	struct pubkey revocation;
 	struct pubkey payment;
+	struct pubkey htlc;
 	struct pubkey delayed_payment;
 };
 
@@ -19,6 +20,7 @@ struct secrets {
 	struct privkey funding_privkey;
 	struct secret revocation_basepoint_secret;
 	struct secret payment_basepoint_secret;
+	struct secret htlc_basepoint_secret;
 	struct secret delayed_payment_basepoint_secret;
 };
 
diff --git a/common/initial_channel.c b/common/initial_channel.c
index c4c47b696..1b8660cc0 100644
--- a/common/initial_channel.c
+++ b/common/initial_channel.c
@@ -75,6 +75,8 @@ struct bitcoin_tx *initial_channel_tx(const tal_t *ctx,
 	if (!derive_keyset(per_commitment_point,
 			   &channel->basepoints[side].payment,
 			   &channel->basepoints[!side].payment,
+			   &channel->basepoints[side].htlc,
+			   &channel->basepoints[!side].htlc,
 			   &channel->basepoints[side].delayed_payment,
 			   &channel->basepoints[!side].revocation,
 			   &keyset))
diff --git a/common/key_derive.c b/common/key_derive.c
index 46a9bbf94..052512a9b 100644
--- a/common/key_derive.c
+++ b/common/key_derive.c
@@ -7,7 +7,7 @@
 
 /* BOLT #3:
  *
- * ### `localkey`, `remotekey`, `local_delayedkey` and `remote_delayedkey` Derivation
+ * ### `localkey`, `remotekey`, `local_htlckey`, `remote_htlckey`, `local_delayedkey` and `remote_delayedkey` Derivation
  *
  * These keys are simply generated by addition from their base points:
  *
@@ -15,9 +15,9 @@
  *
  * The `localkey` uses the local node's `payment_basepoint`, `remotekey`
  * uses the remote node's `payment_basepoint`, the `local_delayedkey`
- * uses the local node's `delayed_payment_basepoint`, and the
- * `remote_delayedkey` uses the remote node's
- * `delayed_payment_basepoint`.
+ * uses the local node's `delayed_payment_basepoint`, the `local_htlckey`
+ * uses the local node's `htlc_basepoint` and the `remote_delayedkey` uses
+ * the remote node's `delayed_payment_basepoint`.
  */
 bool derive_simple_key(const struct pubkey *basepoint,
 		    const struct pubkey *per_commitment_point,
@@ -54,7 +54,8 @@ bool derive_simple_key(const struct pubkey *basepoint,
 /* BOLT #3:
  *
  * The corresponding private keys can be derived similarly if the basepoint
- * secrets are known (i.e., `localkey` and `local_delayedkey` only):
+ * secrets are known (i.e., `localkey`, `local_htlckey` and `local_delayedkey`
+ * only):
  *
  *     secretkey = basepoint_secret + SHA256(per_commitment_point || basepoint)
  */
diff --git a/common/keyset.c b/common/keyset.c
index 2e4d2b862..b293e953e 100644
--- a/common/keyset.c
+++ b/common/keyset.c
@@ -4,14 +4,16 @@
 bool derive_keyset(const struct pubkey *per_commitment_point,
 		   const struct pubkey *self_payment_basepoint,
 		   const struct pubkey *other_payment_basepoint,
+		   const struct pubkey *self_htlc_basepoint,
+		   const struct pubkey *other_htlc_basepoint,
 		   const struct pubkey *self_delayed_basepoint,
 		   const struct pubkey *other_revocation_basepoint,
 		   struct keyset *keyset)
 {
 	/* BOLT #3:
 	 *
-	 * ### `localkey`, `remotekey`, `local_delayedkey` and
-         *     `remote_delayedkey` Derivation
+	 * ### `localkey`, `remotekey`, `local_htlckey`, `remote_htlckey`,
+	 *     `local_delayedkey` and `remote_delayedkey` Derivation
 	 *
 	 * These keys are simply generated by addition from their base points:
 	 *
@@ -20,7 +22,8 @@ bool derive_keyset(const struct pubkey *per_commitment_point,
 	 * The `localkey` uses the local node's `payment_basepoint`,
 	 * `remotekey` uses the remote node's `payment_basepoint`, the
 	 * `local_delayedkey` uses the local node's
-	 * `delayed_payment_basepoint`, and the `remote_delayedkey` uses the
+	 * `delayed_payment_basepoint`, the `local_htlckey` uses the local
+	 * node's `htlc_basepoint` and the `remote_delayedkey` uses the
 	 * remote node's `delayed_payment_basepoint`.
 	 */
 	if (!derive_simple_key(self_payment_basepoint,
@@ -33,6 +36,16 @@ bool derive_keyset(const struct pubkey *per_commitment_point,
 			       &keyset->other_payment_key))
 		return false;
 
+	if (!derive_simple_key(self_htlc_basepoint,
+			       per_commitment_point,
+			       &keyset->self_htlc_key))
+		return false;
+
+	if (!derive_simple_key(other_htlc_basepoint,
+			       per_commitment_point,
+			       &keyset->other_htlc_key))
+		return false;
+
 	if (!derive_simple_key(self_delayed_basepoint,
 			       per_commitment_point,
 			       &keyset->self_delayed_payment_key))
diff --git a/common/keyset.h b/common/keyset.h
index 3ddeb8312..7859876da 100644
--- a/common/keyset.h
+++ b/common/keyset.h
@@ -7,6 +7,7 @@
 /* Keys needed to derive a particular commitment tx. */
 struct keyset {
 	struct pubkey self_revocation_key;
+	struct pubkey self_htlc_key, other_htlc_key;
 	struct pubkey self_delayed_payment_key;
 	struct pubkey self_payment_key, other_payment_key;
 };
@@ -14,6 +15,8 @@ struct keyset {
 bool derive_keyset(const struct pubkey *per_commitment_point,
 		   const struct pubkey *self_payment_basepoint,
 		   const struct pubkey *other_payment_basepoint,
+		   const struct pubkey *self_htlc_basepoint,
+		   const struct pubkey *other_htlc_basepoint,
 		   const struct pubkey *self_delayed_basepoint,
 		   const struct pubkey *other_revocation_basepoint,
 		   struct keyset *keyset);
diff --git a/lightningd/test/run-channel.c b/lightningd/test/run-channel.c
index a6cdf16e6..b436cfb57 100644
--- a/lightningd/test/run-channel.c
+++ b/lightningd/test/run-channel.c
@@ -388,6 +388,10 @@ int main(void)
 	localbase.payment = pubkey_from_hex("034f355bdcb7cc0af728ef3cceb9615d90684bb5b2ca5f859ab0f0b704075871aa");
 	remotebase.payment = pubkey_from_hex("032c0b7cf95324a07d05398b240174dc0c2be444d96b159aa6c7f7b1e668680991");
 
+	/* FIXME: Update bolt */
+	localbase.htlc = localbase.payment;
+	remotebase.htlc = remotebase.payment;
+
 	/* We put unknown in for some things; valgrind will warn if used. */
 	localbase.revocation = *unknown;
 	remotebase.delayed_payment = *unknown;
@@ -452,6 +456,10 @@ int main(void)
 	keyset.self_delayed_payment_key = pubkey_from_hex("03fd5960528dc152014952efdb702a88f71e3c1653b2314431701ec77e57fde83c");
 	keyset.self_revocation_key = pubkey_from_hex("0212a140cd0c6539d07cd08dfe09984dec3251ea808b892efeac3ede9402bf2b19");
 
+	/* FIXME: Update bolt */
+	keyset.self_htlc_key = keyset.self_payment_key;
+	keyset.other_htlc_key = keyset.other_payment_key;
+
 	raw_tx = commit_tx(tmpctx, &funding_txid, funding_output_index,
 			   funding_amount_satoshi,
 			   LOCAL, remote_config->to_self_delay,
diff --git a/onchaind/onchain.c b/onchaind/onchain.c
index 89277cd33..84d23e28f 100644
--- a/onchaind/onchain.c
+++ b/onchaind/onchain.c
@@ -1140,6 +1140,8 @@ static void handle_our_unilateral(const struct bitcoin_tx *tx,
 				  const struct pubkey *remote_revocation_basepoint,
 				  const struct pubkey *remote_payment_basepoint,
 				  const struct pubkey *local_payment_basepoint,
+				  const struct pubkey *remote_htlc_basepoint,
+				  const struct pubkey *local_htlc_basepoint,
 				  const struct pubkey *local_delayed_payment_basepoint,
 				  u64 commit_num,
 				  const struct htlc_stub *htlcs,
@@ -1180,6 +1182,8 @@ static void handle_our_unilateral(const struct bitcoin_tx *tx,
 	if (!derive_keyset(&local_per_commitment_point,
 			   local_payment_basepoint,
 			   remote_payment_basepoint,
+			   local_htlc_basepoint,
+			   remote_htlc_basepoint,
 			   local_delayed_payment_basepoint,
 			   remote_revocation_basepoint,
 			   ks))
@@ -1191,7 +1195,9 @@ static void handle_our_unilateral(const struct bitcoin_tx *tx,
 		     " self_revocation_key: %s"
 		     " self_delayed_payment_key: %s"
 		     " self_payment_key: %s"
-		     " other_payment_key: %s",
+		     " other_payment_key: %s"
+		     " self_htlc_key: %s"
+		     " other_htlc_key: %s",
 		     commit_num,
 		     type_to_string(trc, struct pubkey,
 				    &keyset->self_revocation_key),
@@ -1200,7 +1206,11 @@ static void handle_our_unilateral(const struct bitcoin_tx *tx,
 		     type_to_string(trc, struct pubkey,
 				    &keyset->self_payment_key),
 		     type_to_string(trc, struct pubkey,
-				    &keyset->other_payment_key));
+				    &keyset->other_payment_key),
+		     type_to_string(trc, struct pubkey,
+				    &keyset->self_htlc_key),
+		     type_to_string(trc, struct pubkey,
+				    &keyset->other_htlc_key));
 
 	if (!derive_simple_privkey(&secrets->delayed_payment_basepoint_secret,
 				   local_delayed_payment_basepoint,
@@ -1422,6 +1432,8 @@ static void handle_their_cheat(const struct bitcoin_tx *tx,
 			       const struct pubkey *local_revocation_basepoint,
 			       const struct pubkey *local_payment_basepoint,
 			       const struct pubkey *remote_payment_basepoint,
+			       const struct pubkey *remote_htlc_basepoint,
+			       const struct pubkey *local_htlc_basepoint,
 			       const struct pubkey *remote_delayed_payment_basepoint,
 			       u64 commit_num,
 			       const struct htlc_stub *htlcs,
@@ -1468,6 +1480,8 @@ static void handle_their_cheat(const struct bitcoin_tx *tx,
 		     ": per_commit_point=%s"
 		     " self_payment_basepoint=%s"
 		     " other_payment_basepoint=%s"
+		     " self_htlc_basepoint=%s"
+		     " other_htlc_basepoint=%s"
 		     " self_delayed_basepoint=%s"
 		     " other_revocation_basepoint=%s",
 		     commit_num,
@@ -1477,6 +1491,10 @@ static void handle_their_cheat(const struct bitcoin_tx *tx,
 				    remote_payment_basepoint),
 		     type_to_string(trc, struct pubkey,
 				    local_payment_basepoint),
+		     type_to_string(trc, struct pubkey,
+				    remote_htlc_basepoint),
+		     type_to_string(trc, struct pubkey,
+				    local_htlc_basepoint),
 		     type_to_string(trc, struct pubkey,
 				    remote_delayed_payment_basepoint),
 		     type_to_string(trc, struct pubkey,
@@ -1487,6 +1505,8 @@ static void handle_their_cheat(const struct bitcoin_tx *tx,
 	if (!derive_keyset(&per_commitment_point,
 			   remote_payment_basepoint,
 			   local_payment_basepoint,
+			   local_htlc_basepoint,
+			   remote_htlc_basepoint,
 			   remote_delayed_payment_basepoint,
 			   local_revocation_basepoint,
 			   ks))
@@ -1498,7 +1518,9 @@ static void handle_their_cheat(const struct bitcoin_tx *tx,
 		     " self_revocation_key: %s"
 		     " self_delayed_payment_key: %s"
 		     " self_payment_key: %s"
-		     " other_payment_key: %s",
+		     " other_payment_key: %s"
+		     " self_htlc_key: %s"
+		     " other_htlc_key: %s",
 		     commit_num,
 		     type_to_string(trc, struct pubkey,
 				    &keyset->self_revocation_key),
@@ -1507,7 +1529,11 @@ static void handle_their_cheat(const struct bitcoin_tx *tx,
 		     type_to_string(trc, struct pubkey,
 				    &keyset->self_payment_key),
 		     type_to_string(trc, struct pubkey,
-				    &keyset->other_payment_key));
+				    &keyset->other_payment_key),
+		     type_to_string(trc, struct pubkey,
+				    &keyset->self_htlc_key),
+		     type_to_string(trc, struct pubkey,
+				    &keyset->other_htlc_key));
 
 	revocation_privkey = tal(tx, struct privkey);
 	if (!derive_revocation_privkey(&secrets->revocation_basepoint_secret,
@@ -1670,6 +1696,8 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
 				    const struct pubkey *local_revocation_basepoint,
 				    const struct pubkey *local_payment_basepoint,
 				    const struct pubkey *remote_payment_basepoint,
+				    const struct pubkey *remote_htlc_basepoint,
+				    const struct pubkey *local_htlc_basepoint,
 				    const struct pubkey *remote_delayed_payment_basepoint,
 				    u64 commit_num,
 				    const struct htlc_stub *htlcs,
@@ -1701,6 +1729,8 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
 		     ": per_commit_point=%s"
 		     " self_payment_basepoint=%s"
 		     " other_payment_basepoint=%s"
+		     " self_htlc_basepoint=%s"
+		     " other_htlc_basepoint=%s"
 		     " self_delayed_basepoint=%s"
 		     " other_revocation_basepoint=%s",
 		     commit_num,
@@ -1710,6 +1740,10 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
 				    remote_payment_basepoint),
 		     type_to_string(trc, struct pubkey,
 				    local_payment_basepoint),
+		     type_to_string(trc, struct pubkey,
+				    remote_htlc_basepoint),
+		     type_to_string(trc, struct pubkey,
+				    local_htlc_basepoint),
 		     type_to_string(trc, struct pubkey,
 				    remote_delayed_payment_basepoint),
 		     type_to_string(trc, struct pubkey,
@@ -1720,6 +1754,8 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
 	if (!derive_keyset(remote_per_commitment_point,
 			   remote_payment_basepoint,
 			   local_payment_basepoint,
+			   remote_htlc_basepoint,
+			   local_htlc_basepoint,
 			   remote_delayed_payment_basepoint,
 			   local_revocation_basepoint,
 			   ks))
@@ -1731,7 +1767,9 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
 		     " self_revocation_key: %s"
 		     " self_delayed_payment_key: %s"
 		     " self_payment_key: %s"
-		     " other_payment_key: %s",
+		     " other_payment_key: %s"
+		     " self_htlc_key: %s"
+		     " other_htlc_key: %s",
 		     commit_num,
 		     type_to_string(trc, struct pubkey,
 				    &keyset->self_revocation_key),
@@ -1740,7 +1778,11 @@ static void handle_their_unilateral(const struct bitcoin_tx *tx,
 		     type_to_string(trc, struct pubkey,
 				    &keyset->self_payment_key),
 		     type_to_string(trc, struct pubkey,
-				    &keyset->other_payment_key));
+				    &keyset->other_payment_key),
+		     type_to_string(trc, struct pubkey,
+				    &keyset->self_htlc_key),
+		     type_to_string(trc, struct pubkey,
+				    &keyset->other_htlc_key));
 
 	if (!derive_simple_privkey(&secrets->payment_basepoint_secret,
 				   local_payment_basepoint,
@@ -1865,7 +1907,7 @@ int main(int argc, char *argv[])
 	const tal_t *ctx = tal_tmpctx(NULL);
 	u8 *msg;
 	struct privkey seed;
-	struct pubkey remote_payment_basepoint,
+	struct pubkey remote_payment_basepoint, remote_htlc_basepoint,
 		remote_per_commit_point, old_remote_per_commit_point,
 		remote_revocation_basepoint, remote_delayed_payment_basepoint;
 	enum side funder;
@@ -1924,6 +1966,7 @@ int main(int argc, char *argv[])
 				   &num_htlcs)) {
 		master_badmsg(WIRE_ONCHAIN_INIT, msg);
 	}
+	remote_htlc_basepoint = remote_payment_basepoint;
 	derive_basepoints(&seed, NULL, &basepoints, &secrets, &shaseed);
 	bitcoin_txid(tx, &txid);
 
@@ -1994,6 +2037,8 @@ int main(int argc, char *argv[])
 					      &remote_revocation_basepoint,
 					      &remote_payment_basepoint,
 					      &basepoints.payment,
+					      &remote_htlc_basepoint,
+					      &basepoints.htlc,
 					      &basepoints.delayed_payment,
 					      commit_num,
 					      htlcs,
@@ -2017,6 +2062,8 @@ int main(int argc, char *argv[])
 					   &basepoints.revocation,
 					   &basepoints.payment,
 					   &remote_payment_basepoint,
+					   &basepoints.htlc,
+					   &remote_htlc_basepoint,
 					   &remote_delayed_payment_basepoint,
 					   commit_num,
 					   htlcs,
@@ -2039,6 +2086,8 @@ int main(int argc, char *argv[])
 						&basepoints.revocation,
 						&basepoints.payment,
 						&remote_payment_basepoint,
+						&basepoints.htlc,
+						&remote_htlc_basepoint,
 						&remote_delayed_payment_basepoint,
 						commit_num,
 						htlcs,
@@ -2053,6 +2102,8 @@ int main(int argc, char *argv[])
 						&basepoints.revocation,
 						&basepoints.payment,
 						&remote_payment_basepoint,
+						&basepoints.htlc,
+						&remote_htlc_basepoint,
 						&remote_delayed_payment_basepoint,
 						commit_num,
 						htlcs,