diff --git a/lightningd/cryptomsg.c b/lightningd/cryptomsg.c
index c68b4e739..0e6e3199b 100644
--- a/lightningd/cryptomsg.c
+++ b/lightningd/cryptomsg.c
@@ -122,22 +122,22 @@ u8 *cryptomsg_decrypt_body(const tal_t *ctx,
 }
 
 static struct io_plan *peer_decrypt_body(struct io_conn *conn,
-					 struct crypto_state *cs)
+					 struct peer_crypto_state *pcs)
 {
 	struct io_plan *plan;
 	u8 *in, *decrypted;
 
-	decrypted = cryptomsg_decrypt_body(cs->in, cs, cs->in);
+	decrypted = cryptomsg_decrypt_body(pcs->in, &pcs->cs, pcs->in);
 	if (!decrypted)
 		return io_close(conn);
 
 	/* Steal cs->in: we free it after, and decrypted too unless
 	 * they steal but be careful not to touch anything after
 	 * next_in (could free itself) */
-	in = tal_steal(NULL, cs->in);
-	cs->in = NULL;
+	in = tal_steal(NULL, pcs->in);
+	pcs->in = NULL;
 
-	plan = cs->next_in(conn, cs->peer, decrypted);
+	plan = pcs->next_in(conn, pcs->peer, decrypted);
 	tal_free(in);
 	return plan;
 }
@@ -174,31 +174,32 @@ bool cryptomsg_decrypt_header(struct crypto_state *cs, u8 hdr[18], u16 *lenp)
 }
 
 static struct io_plan *peer_decrypt_header(struct io_conn *conn,
-					   struct crypto_state *cs)
+					   struct peer_crypto_state *pcs)
 {
 	u16 len;
 
-	if (!cryptomsg_decrypt_header(cs, cs->in, &len))
+	if (!cryptomsg_decrypt_header(&pcs->cs, pcs->in, &len))
 		return io_close(conn);
 
-	tal_free(cs->in);
+	tal_free(pcs->in);
 
 	/* BOLT #8:
 	 *
 	 * * Read _exactly_ `l+16` bytes from the network buffer, let
 	 *   the bytes be known as `c`.
 	 */
-	cs->in = tal_arr(cs, u8, (u32)len + 16);
-	return io_read(conn, cs->in, tal_count(cs->in), peer_decrypt_body, cs);
+	pcs->in = tal_arr(conn, u8, (u32)len + 16);
+	return io_read(conn, pcs->in, tal_count(pcs->in), peer_decrypt_body,
+		       pcs);
 }
 
 struct io_plan *peer_read_message(struct io_conn *conn,
-				  struct crypto_state *cs,
+				  struct peer_crypto_state *pcs,
 				  struct io_plan *(*next)(struct io_conn *,
 							  struct peer *,
 							  u8 *msg))
 {
-	assert(!cs->in);
+	assert(!pcs->in);
 	/* BOLT #8:
 	 *
 	 * ### Decrypting Messages
@@ -208,16 +209,16 @@ struct io_plan *peer_read_message(struct io_conn *conn,
 	 *
 	 *  * Read _exactly_ `18-bytes` from the network buffer.
 	 */
-	cs->in = tal_arr(cs, u8, 18);
-	cs->next_in = next;
-	return io_read(conn, cs->in, 18, peer_decrypt_header, cs);
+	pcs->in = tal_arr(conn, u8, 18);
+	pcs->next_in = next;
+	return io_read(conn, pcs->in, 18, peer_decrypt_header, pcs);
 }
 
 static struct io_plan *peer_write_done(struct io_conn *conn,
-				       struct crypto_state *cs)
+				       struct peer_crypto_state *pcs)
 {
-	cs->out = tal_free(cs->out);
-	return cs->next_out(conn, cs->peer);
+	pcs->out = tal_free(pcs->out);
+	return pcs->next_out(conn, pcs->peer);
 }
 
 u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
@@ -230,7 +231,7 @@ u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
 	int ret;
 	u8 *out;
 
-	out = tal_arr(cs, u8, sizeof(l) + 16 + mlen + 16);
+	out = tal_arr(ctx, u8, sizeof(l) + 16 + mlen + 16);
 
 	/* BOLT #8:
 	 *
@@ -304,41 +305,27 @@ u8 *cryptomsg_encrypt_msg(const tal_t *ctx,
 }
 
 struct io_plan *peer_write_message(struct io_conn *conn,
-				   struct crypto_state *cs,
+				   struct peer_crypto_state *pcs,
 				   const u8 *msg,
 				   struct io_plan *(*next)(struct io_conn *,
 							   struct peer *))
 {
-	assert(!cs->out);
+	assert(!pcs->out);
 
-	cs->out = cryptomsg_encrypt_msg(cs, cs, msg);
-	cs->next_out = next;
+	pcs->out = cryptomsg_encrypt_msg(conn, &pcs->cs, msg);
+	pcs->next_out = next;
 
 	/* BOLT #8:
 	 *   * Send `lc || c` over the network buffer.
 	 */
-	return io_write(conn, cs->out, tal_count(cs->out), peer_write_done, cs);
+	return io_write(conn, pcs->out, tal_count(pcs->out),
+			peer_write_done, pcs);
 }
 
-struct crypto_state *crypto_state(struct peer *peer,
-				  const struct sha256 *sk,
-				  const struct sha256 *rk,
-				  const struct sha256 *rck,
-				  const struct sha256 *sck,
-				  u64 rn, u64 sn)
+void init_peer_crypto_state(struct peer *peer, struct peer_crypto_state *pcs)
 {
-	struct crypto_state *cs = tal(peer, struct crypto_state);
-
-	cs->rn = rn;
-	cs->sn = sn;
-	cs->sk = *sk;
-	cs->rk = *rk;
-	cs->s_ck = *sck;
-	cs->r_ck = *rck;
-	cs->peer = peer;
-	cs->out = cs->in = NULL;
-
-	return cs;
+	pcs->peer = peer;
+	pcs->out = pcs->in = NULL;
 }
 
 void towire_crypto_state(u8 **ptr, const struct crypto_state *cs)
diff --git a/lightningd/cryptomsg.h b/lightningd/cryptomsg.h
index d0e766463..64d212442 100644
--- a/lightningd/cryptomsg.h
+++ b/lightningd/cryptomsg.h
@@ -15,6 +15,10 @@ struct crypto_state {
 	struct sha256 sk, rk;
 	/* Chaining key for re-keying */
 	struct sha256 s_ck, r_ck;
+};
+
+struct peer_crypto_state {
+	struct crypto_state cs;
 
 	/* Peer who owns us: peer->crypto_state == this */
 	struct peer *peer;
@@ -25,24 +29,19 @@ struct crypto_state {
 	struct io_plan *(*next_out)(struct io_conn *, struct peer *);
 };
 
-/* Initializes peer->crypto_state */
-struct crypto_state *crypto_state(struct peer *peer,
-				  const struct sha256 *sk,
-				  const struct sha256 *rk,
-				  const struct sha256 *rck,
-				  const struct sha256 *sck,
-				  u64 rn, u64 sn);
+/* Initializes peer->cs (still need to read in cs->cs) */
+void init_peer_crypto_state(struct peer *peer, struct peer_crypto_state *pcs);
 
 /* Get decrypted message */
 struct io_plan *peer_read_message(struct io_conn *conn,
-				  struct crypto_state *cs,
+				  struct peer_crypto_state *cs,
 				  struct io_plan *(*next)(struct io_conn *,
 							  struct peer *,
 							  u8 *msg));
 
 /* Sends and frees message */
 struct io_plan *peer_write_message(struct io_conn *conn,
-				   struct crypto_state *cs,
+				   struct peer_crypto_state *cs,
 				   const u8 *msg,
 				   struct io_plan *(*next)(struct io_conn *,
 							   struct peer *));
diff --git a/lightningd/gossip/gossip.c b/lightningd/gossip/gossip.c
index 318c4d97e..1e9fe4de2 100644
--- a/lightningd/gossip/gossip.c
+++ b/lightningd/gossip/gossip.c
@@ -46,7 +46,7 @@ struct peer {
 	struct list_node list;
 
 	u64 unique_id;
-	struct crypto_state *cs;
+	struct peer_crypto_state pcs;
 
 	/* File descriptor corresponding to conn. */
 	int fd;
@@ -76,10 +76,11 @@ static void destroy_peer(struct peer *peer)
 static struct peer *setup_new_peer(struct daemon *daemon, const u8 *msg)
 {
 	struct peer *peer = tal(daemon, struct peer);
-	peer->cs = tal(peer, struct crypto_state);
-	if (!fromwire_gossipctl_new_peer(msg, NULL, &peer->unique_id, peer->cs))
+
+	init_peer_crypto_state(peer, &peer->pcs);
+	if (!fromwire_gossipctl_new_peer(msg, NULL, &peer->unique_id,
+					 &peer->pcs.cs))
 		return tal_free(peer);
-	peer->cs->peer = peer;
 	peer->daemon = daemon;
 	peer->error = NULL;
 	peer->msg_out = tal_arr(peer, u8*, 0);
@@ -102,15 +103,15 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
 
 	case WIRE_CHANNEL_ANNOUNCEMENT:
 		handle_channel_announcement(peer->daemon->rstate, msg, tal_count(msg));
-		return peer_read_message(conn, peer->cs, peer_msgin);
+		return peer_read_message(conn, &peer->pcs, peer_msgin);
 
 	case WIRE_NODE_ANNOUNCEMENT:
 		handle_node_announcement(peer->daemon->rstate, msg, tal_count(msg));
-		return peer_read_message(conn, peer->cs, peer_msgin);
+		return peer_read_message(conn, &peer->pcs, peer_msgin);
 
 	case WIRE_CHANNEL_UPDATE:
 		handle_channel_update(peer->daemon->rstate, msg, tal_count(msg));
-		return peer_read_message(conn, peer->cs, peer_msgin);
+		return peer_read_message(conn, &peer->pcs, peer_msgin);
 
 	case WIRE_INIT:
 		peer->error = "Duplicate INIT message received";
@@ -133,7 +134,7 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
 	case WIRE_REVOKE_AND_ACK:
 		/* Not our place to handle this, so we punt */
 		s = towire_gossipstatus_peer_nongossip(msg, peer->unique_id,
-						       peer->cs, msg);
+						       &peer->pcs.cs, msg);
 		status_send(s);
 		status_send_fd(io_conn_fd(conn));
 		return io_close(conn);
@@ -147,7 +148,7 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
 	if (t & 1) {
 		status_trace("Peer %"PRIu64" sent unknown packet %u, ignoring",
 			     peer->unique_id, t);
-		return peer_read_message(conn, peer->cs, peer_msgin);
+		return peer_read_message(conn, &peer->pcs, peer_msgin);
 	}
 	peer->error = tal_fmt(peer, "Unknown packet %u", t);
 	return io_close(conn);
@@ -183,7 +184,8 @@ static struct io_plan *peer_dump_gossip(struct io_conn *conn, struct peer *peer)
 		/* Going to wake up in pkt_out since we mix time based and message based wakeups */
 		return io_out_wait(conn, peer, pkt_out, peer);
 	} else {
-		return peer_write_message(conn, peer->cs, next->payload, peer_dump_gossip);
+		return peer_write_message(conn, &peer->pcs, next->payload,
+					  peer_dump_gossip);
 	}
 }
 
@@ -196,7 +198,7 @@ static struct io_plan *pkt_out(struct io_conn *conn, struct peer *peer)
 		out = peer->msg_out[0];
 		memmove(peer->msg_out, peer->msg_out + 1, (sizeof(*peer->msg_out)*(n-1)));
 		tal_resize(&peer->msg_out, n-1);
-		return peer_write_message(conn, peer->cs, out, pkt_out);
+		return peer_write_message(conn, &peer->pcs, out, pkt_out);
 	}
 
 	if (peer->gossip_sync){
@@ -259,13 +261,13 @@ static struct io_plan *peer_parse_init(struct io_conn *conn,
 	/* Need to go duplex here, otherwise backpressure would mean
 	 * we both wait indefinitely */
 	return io_duplex(conn,
-			 peer_read_message(conn, peer->cs, peer_msgin),
+			 peer_read_message(conn, &peer->pcs, peer_msgin),
 			 peer_dump_gossip(conn, peer));
 }
 
 static struct io_plan *peer_init_sent(struct io_conn *conn, struct peer *peer)
 {
-	return peer_read_message(conn, peer->cs, peer_parse_init);
+	return peer_read_message(conn, &peer->pcs, peer_parse_init);
 }
 
 static struct io_plan *peer_send_init(struct io_conn *conn, struct peer *peer)
@@ -278,7 +280,8 @@ static struct io_plan *peer_send_init(struct io_conn *conn, struct peer *peer)
 	 * SHOULD set feature bits corresponding to features it optionally
 	 * supports.
 	 */
-	return peer_write_message(conn, peer->cs, towire_init(peer, NULL, NULL),
+	return peer_write_message(conn, &peer->pcs,
+				  towire_init(peer, NULL, NULL),
 				  peer_init_sent);
 }
 
@@ -337,7 +340,7 @@ static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon,
 
 			out = towire_gossipctl_release_peer_response(msg,
 								     unique_id,
-								     peer->cs);
+								     &peer->pcs.cs);
 			return io_write_wire(conn, out, release_peer_fd, peer);
 		}
 	}
diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c
index 57bbbdc33..d24eb3118 100644
--- a/lightningd/gossip_control.c
+++ b/lightningd/gossip_control.c
@@ -46,17 +46,16 @@ static void peer_nongossip(struct subdaemon *gossip, const u8 *msg, int fd)
 	u64 unique_id;
 	struct peer *peer;
 	u8 *inner;
-	struct crypto_state *cs = tal(msg, struct crypto_state);
+	struct crypto_state cs;
 
 	if (!fromwire_gossipstatus_peer_nongossip(msg, msg, NULL,
-						  &unique_id, cs, &inner))
+						  &unique_id, &cs, &inner))
 		fatal("Gossip gave bad PEER_NONGOSSIP message %s",
 		      tal_hex(msg, msg));
 
 	peer = peer_by_unique_id(gossip->ld, unique_id);
 	if (!peer)
 		fatal("Gossip gave bad peerid %"PRIu64, unique_id);
-	cs->peer = peer;
 
 	log_debug(gossip->log, "Peer %s said %s",
 		  type_to_string(msg, struct pubkey, peer->id),
diff --git a/lightningd/handshake/handshake.c b/lightningd/handshake/handshake.c
index b351507b3..4e5abd8ba 100644
--- a/lightningd/handshake/handshake.c
+++ b/lightningd/handshake/handshake.c
@@ -972,7 +972,7 @@ int main(int argc, char *argv[])
 	struct pubkey my_id, their_id;
 	int hsmfd = 3, clientfd = 4;
 	struct secret ck, rk, sk;
-	struct crypto_state *cs;
+	struct crypto_state cs;
 
 	if (argc == 2 && streq(argv[1], "--version")) {
 		printf("%s\n", version());
@@ -994,17 +994,23 @@ int main(int argc, char *argv[])
 
 	if (fromwire_handshake_responder_req(msg, NULL, &my_id)) {
 		responder(clientfd, &my_id, &their_id, &ck, &sk, &rk);
-		cs = crypto_state(NULL, &sk.s, &rk.s, &ck.s, &ck.s, 0, 0);
+		cs.rn = cs.sn = 0;
+		cs.sk = sk.s;
+		cs.rk = rk.s;
+		cs.r_ck = cs.s_ck = ck.s;
 		wire_sync_write(REQ_FD,
 				towire_handshake_responder_resp(msg,
 								&their_id,
-								cs));
+								&cs));
 	} else if (fromwire_handshake_initiator_req(msg, NULL, &my_id,
 						    &their_id)) {
 		initiator(clientfd, &my_id, &their_id, &ck, &sk, &rk);
-		cs = crypto_state(NULL, &sk.s, &rk.s, &ck.s, &ck.s, 0, 0);
+		cs.rn = cs.sn = 0;
+		cs.sk = sk.s;
+		cs.rk = rk.s;
+		cs.r_ck = cs.s_ck = ck.s;
 		wire_sync_write(REQ_FD,
-				towire_handshake_initiator_resp(msg, cs));
+				towire_handshake_initiator_resp(msg, &cs));
 	} else
 		status_failed(WIRE_HANDSHAKE_BAD_COMMAND, "%i", fromwire_peektype(msg));
 
diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c
index 079fe4ff6..34b4cadf3 100644
--- a/lightningd/peer_control.c
+++ b/lightningd/peer_control.c
@@ -88,23 +88,22 @@ struct peer *peer_by_unique_id(struct lightningd *ld, u64 unique_id)
 static void handshake_succeeded(struct subdaemon *hs, const u8 *msg,
 				struct peer *peer)
 {
-	struct crypto_state *cs = tal(peer, struct crypto_state);
+	struct crypto_state cs;
 
 	if (!peer->id) {
 		struct pubkey id;
 
-		if (!fromwire_handshake_responder_resp(msg, NULL, &id, cs))
+		if (!fromwire_handshake_responder_resp(msg, NULL, &id, &cs))
 			goto err;
 		peer->id = tal_dup(peer, struct pubkey, &id);
 		log_info_struct(hs->log, "Peer in from %s",
 				struct pubkey, peer->id);
 	} else {
-		if (!fromwire_handshake_initiator_resp(msg, NULL, cs))
+		if (!fromwire_handshake_initiator_resp(msg, NULL, &cs))
 			goto err;
 		log_info_struct(hs->log, "Peer out to %s",
 				struct pubkey, peer->id);
 	}
-	cs->peer = peer;
 
 	/* FIXME: Look for peer duplicates! */
 
@@ -117,7 +116,7 @@ static void handshake_succeeded(struct subdaemon *hs, const u8 *msg,
 	peer_set_condition(peer, "Beginning gossip");
 
 	/* Tell gossip to handle it now. */
-	msg = towire_gossipctl_new_peer(msg, peer->unique_id, cs);
+	msg = towire_gossipctl_new_peer(msg, peer->unique_id, &cs);
 	subdaemon_req(peer->ld->gossip, msg, peer->fd, &peer->fd, NULL, NULL);
 
 	/* Peer struct longer owns fd. */
diff --git a/lightningd/test/run-cryptomsg.c b/lightningd/test/run-cryptomsg.c
index 2d6489bb9..afc41295b 100644
--- a/lightningd/test/run-cryptomsg.c
+++ b/lightningd/test/run-cryptomsg.c
@@ -67,7 +67,7 @@ static struct sha256 sha256_from_hex(const char *hex)
 int main(void)
 {
 	tal_t *tmpctx = tal_tmpctx(NULL);
-	struct crypto_state *cs_out, *cs_in;
+	struct peer_crypto_state cs_out, cs_in;
 	struct sha256 sk, rk, ck;
 	const void *msg = tal_dup_arr(tmpctx, char, "hello", 5, 0);
 	size_t i;
@@ -89,13 +89,17 @@ int main(void)
 	sk = sha256_from_hex("0x969ab31b4d288cedf6218839b27a3e2140827047f2c0f01bf5c04435d43511a9");
 	rk = sha256_from_hex("0xbb9020b8965f4df047e07f955f3c4b88418984aadc5cdb35096b9ea8fa5c3442");
 
-	cs_out = crypto_state(tmpctx, &sk, &rk, &ck, &ck, 0, 0);
-	cs_in = crypto_state(tmpctx, &rk, &sk, &ck, &ck, 0, 0);
+	cs_out.cs.sn = cs_out.cs.rn = cs_in.cs.sn = cs_in.cs.rn = 0;
+	cs_out.cs.sk = cs_in.cs.rk = sk;
+	cs_out.cs.rk = cs_in.cs.sk = rk;
+	cs_out.cs.s_ck = cs_out.cs.r_ck = cs_in.cs.s_ck = cs_in.cs.r_ck = ck;
+	init_peer_crypto_state(tmpctx, &cs_in);
+	init_peer_crypto_state(tmpctx, &cs_out);
 
 	for (i = 0; i < 1002; i++) {
 		write_buf = tal_arr(tmpctx, char, 0);
 
-		peer_write_message(NULL, cs_out, msg, check_msg_write);
+		peer_write_message(NULL, &cs_out, msg, check_msg_write);
 		if ((i % 500) < 2)
 			status_trace("output %zu: 0x%s", i,
 				     tal_hex(tmpctx, write_buf));
@@ -104,7 +108,7 @@ int main(void)
 		read_buf_len = tal_count(read_buf);
 		write_buf = tal_arr(tmpctx, char, 0);
 
-		peer_read_message(NULL, cs_in, check_msg_read);
+		peer_read_message(NULL, &cs_in, check_msg_read);
 		assert(read_buf_len == 0);
 	}
 	tal_free(tmpctx);