<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Hi<br class=""><br class="">The overhauled version of the former BIP151 has fundamental differences and deserves (requires?) a new BIP.</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Calling it „v2 peer-to-peer message transport protocol“ is more accurate since it is no longer only about encryption.</div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""></div><div dir="auto" style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">The formatted draft proposal can be found here:&nbsp;<a href="https://gist.github.com/jonasschnelli/c530ea8421b8d0e80c51486325587c52" class="">https://gist.github.com/jonasschnelli/c530ea8421b8d0e80c51486325587c52</a><br class=""><br class="">Significant changes compared to the current available BIP151<br class="">* A optimised AEAD construct is now proposed (ChaCha20Poly1305@Bitcoin), reducing the required ChaCha20 rounds (compared to the openSSH version).<br class="">* introduce NODE_P2P_V2<br class="">* 32bytes-per-side „pseudorandom" key exchange<br class="">* the multi message envelope has been removed<br class="">* the length of a packet uses now a 3-byte integer with 23 available bits<br class="">* introduction of short-command-ID (ex.: uint8_t 13 == INV, etc.) which result in<br class="">&nbsp;some v2 messages require less bandwidth then v1<br class="">*&nbsp;the key derivation and what communication direction uses what key is now more<br class="">&nbsp;specific<div class=""><br class=""></div><div class="">First benchmarks of the used primitives</div><div class=""><a href="https://github.com/bitcoin/bitcoin/pull/15519#issuecomment-469705289" class="">https://github.com/bitcoin/bitcoin/pull/15519#issuecomment-469705289</a></div><div class=""><br class=""></div><div class="">Benchmark of the AEAD compared to the HASH (double SHA256)</div><div class="">(Indicates that v2 messages may be more performant):</div><div class=""><a href="https://github.com/bitcoin/bitcoin/pull/15649#issuecomment-475782376" class="">https://github.com/bitcoin/bitcoin/pull/15649#issuecomment-475782376</a></div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">Proposal:</div><div class=""><br class=""></div><div class=""><div class="">&lt;pre&gt;</div><div class="">&nbsp; BIP: ???</div><div class="">&nbsp; Layer: Peer Services</div><div class="">&nbsp; Title: Version 2 Peer-to-Peer Message Transport Protocol</div><div class="">&nbsp; Author: Jonas Schnelli &lt;dev@jonasschnelli.ch&gt;</div><div class="">&nbsp; Status: Draft</div><div class="">&nbsp; Type: Standards Track</div><div class="">&nbsp; Created: 2019-03-08</div><div class="">&nbsp; License: PD</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">== Abstract ==</div><div class=""><br class=""></div><div class="">This BIP describes a new Bitcoin peer to peer transport protocol with&nbsp;</div><div class="">opportunistic encryption.</div><div class=""><br class=""></div><div class="">== Motivation ==</div><div class=""><br class=""></div><div class="">The current peer-to-peer protocol is partially inefficient and in plaintext.</div><div class=""><br class=""></div><div class="">With the current unencrypted message transport, BGP hijack, block delay attacks&nbsp;</div><div class="">and message tempering are inexpensive and can be executed in a covert way&nbsp;</div><div class="">(undetectable MITM)&lt;ref&gt;[https://btc-hijack.ethz.ch/files/btc_hijack.pdf&nbsp;</div><div class="">Hijacking Bitcoin: Routing Attacks on Cryptocurrencies - M. Apostolaki, A.&nbsp;</div><div class="">Zohar, L.Vanbever]&lt;/ref&gt;.</div><div class=""><br class=""></div><div class="">Adding opportunistic encryption introduces a high risk for attackers of being&nbsp;</div><div class="">detected. Peer operators can compare encryption session IDs or use other form&nbsp;</div><div class="">of authentication schemes &lt;ref&nbsp;</div><div class="">name="bip150"&gt;[https://github.com/bitcoin/bips/blob/master/bip-0150.mediawiki&nbsp;</div><div class="">BIP150]&lt;/ref&gt; to identify an attack.</div><div class=""><br class=""></div><div class="">Each current version 1 Bitcoin peer-to-peer message uses a double-SHA256&nbsp;</div><div class="">checksum truncated to 4 bytes. Roughly the same amount of computation power&nbsp;</div><div class="">would be required for encrypting and authenticating a peer-to-peer message with&nbsp;</div><div class="">ChaCha20 &amp; Poly1305.</div><div class=""><br class=""></div><div class="">Additionally, this BIP describes a way how data manipulation (blocking or&nbsp;</div><div class="">tempering commands by an intercepting TCP/IP node) would be identifiable by the&nbsp;</div><div class="">communicating peers.</div><div class=""><br class=""></div><div class="">Encrypting traffic between peers is already possible with VPN, tor, stunnel,&nbsp;</div><div class="">curveCP or any other encryption mechanism on a deeper OSI level, however, most&nbsp;</div><div class="">of those solutions require significant knowhow in how to setup such a secure&nbsp;</div><div class="">channel and are therefore not widely deployed.</div><div class=""><br class=""></div><div class="">== Specification ==</div><div class=""><br class=""></div><div class="">&lt;blockquote&gt;</div><div class="">The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",</div><div class="">"SHOULD NOT", "RECOMMENDED", &nbsp;"MAY", and "OPTIONAL" in this document are to be</div><div class="">interpreted as described in RFC 2119&lt;ref&gt;[https://tools.ietf.org/html/rfc2119&nbsp;</div><div class="">RFC 2119]&lt;/ref&gt;.</div><div class="">&lt;/blockquote&gt;</div><div class=""><br class=""></div><div class="">A peer that supports the message transport protocol as defined in this proposal&nbsp;</div><div class="">MUST accept encryption requests from all peers.</div><div class=""><br class=""></div><div class="">Both communication direction share the same shared-secret but have different&nbsp;</div><div class="">symmetric cipher keys.</div><div class=""><br class=""></div><div class="">The encryption handshake MUST happen before sending any other messages to the&nbsp;</div><div class="">responding peer.</div><div class=""><br class=""></div><div class="">If the responding peer closes the connection after sending the handshake&nbsp;</div><div class="">request, the initiating peer MAY try to connect again with the v1 peer-to-peer&nbsp;</div><div class="">transport protocol. Such reconnects allow an attacker to "downgrade" the&nbsp;</div><div class="">encryption to plaintext communication and thus, accepting v1 connections MUST&nbsp;</div><div class="">not be done when the Bitcoin peer-to-peer network uses almost only v2&nbsp;</div><div class="">communication.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">=== NODE_P2P_V2 ===</div><div class=""><br class=""></div><div class="">Peers supporting the transport protocol after this proposal MUST signal&nbsp;</div><div class="">&lt;code&gt;NODE_P2P_V2&lt;/code&gt;</div><div class="">&lt;pre&gt;</div><div class="">NODE_P2P_V2 = (1 &lt;&lt; 11)</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">A peer usually learns an address along with the expected service flags which&nbsp;</div><div class="">MAY be used to filter possible outbound peers.</div><div class=""><br class=""></div><div class="">A peer signaling &lt;code&gt;NODE_P2P_V2&lt;/code&gt; MUST accept encrypted communication&nbsp;</div><div class="">specified in this proposal.</div><div class=""><br class=""></div><div class="">Peers MAY only make outbound connections to peers supporting&nbsp;</div><div class="">&lt;code&gt;NODE_P2P_V2&lt;/code&gt;.</div><div class=""><br class=""></div><div class="">=== Handshake ===</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">&nbsp;----------------------------------------------------------------------------------------</div><div class="">&nbsp;| Initiator &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Responder &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| x, X &nbsp; &nbsp; &nbsp; &nbsp; := SECP256k1_KEYGEN() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="">&nbsp;| CLIENT_HDATA := X &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --- CLIENT_HDATA ---&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; y, Y &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; := SECP256k1_KEYGEN() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ECDH_KEY &nbsp; &nbsp; &nbsp; := SECP256k1_ECDH(X,y) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SERVER_HDATA &nbsp; := Y &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;-- SERVER_HDATA ---- &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| ECDH_KEY &nbsp; &nbsp; := SECP256k1_ECDH(x,Y) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;----------------------------------------------------------------------------------------</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">To request encrypted communication (only possible if yet no other messages have&nbsp;</div><div class="">been sent or received), the initiating peer generates an EC secp256k1 ephemeral&nbsp;</div><div class="">key and sends the corresponding 32-byte public key to the responding peer and&nbsp;</div><div class="">waits for the remote 32-byte public key from the counterparty.</div><div class=""><br class=""></div><div class="">ODD secp256k1 public keys MUST be used (public keys starting with 0x02). If the&nbsp;</div><div class="">public key from the generated ephemeral key is an EVEN public key (starting&nbsp;</div><div class="">with 0x03), negating the key and recalculating its public key SHOULD be done.</div><div class="">Only using ODD public makes it more complex to identify the handshake based on&nbsp;</div><div class="">analyzing the traffic.</div><div class=""><br class=""></div><div class="">The handshake request and response message are raw 32byte payloads containing&nbsp;</div><div class="">no header, length or checksum (the pure 32byte payload) and MUST be sent before&nbsp;</div><div class="">anything else.</div><div class=""><br class=""></div><div class="">Public keys starting with the 4-byte network magic are forbidden and MUST lead&nbsp;</div><div class="">to locally re-generate an ephemeral-key.</div><div class=""><br class=""></div><div class="">Pseudocode for the ephemeral-key generation</div><div class="">&lt;pre&gt;</div><div class="">do {</div><div class="">&nbsp; &nbsp; ecdh_key.MakeNewKey();</div><div class="">&nbsp; &nbsp; if (ecdh_key.GetPubKey()[0] == 3) {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; ecdh_key.Negate();</div><div class="">&nbsp; &nbsp; }</div><div class="">} while (m_ecdh_key.GetPubKey()[0..3] == NETWORK_MAGIC);</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">Once a peer has received the public key from its counterparty, the shared&nbsp;</div><div class="">secret MUST be calculated by using secp256k1 ECDH.</div><div class=""><br class=""></div><div class="">Private keys will never be transmitted. The shared secret can only be&nbsp;</div><div class="">calculated if an attacker knows at least one private key and the counterparties&nbsp;</div><div class="">public key. This key-exchange is based on the discrete log problem and thus not&nbsp;</div><div class="">sufficiently strong against known forms of possible quantum computer&nbsp;</div><div class="">algorithms. Adding an additional quantum resistant key exchange like NewHope is&nbsp;</div><div class="">possible but out of scope for this proposal.</div><div class=""><br class=""></div><div class="">After a successful handshake, the messages format MUST use the "v2 messages&nbsp;</div><div class="">structure". Non-encrypted v1 messages from the initiating peer MUST lead to an&nbsp;</div><div class="">immediate connection termination.</div><div class=""><br class=""></div><div class="">After a successful handshake, both peers MUST cleanse the ephemeral-session-key&nbsp;</div><div class="">from memory and/or persistence storage.</div><div class=""><br class=""></div><div class="">A peer not supporting this proposal will not perform the described handshake&nbsp;</div><div class="">and thus send a v1 version message.</div><div class="">Peers supporting this BIP MAY optionally allow unencrypted v1 communication by&nbsp;</div><div class="">detecting a v1 version message by the initial 11-byte sequence of &lt;code&gt;4byte&nbsp;</div><div class="">net magic || "version"&lt;/code&gt;.</div><div class=""><br class=""></div><div class="">=== Symmetric Encryption Cipher Keys ===</div><div class=""><br class=""></div><div class="">Once the ECDH secret (&lt;code&gt;ECDH_KEY&lt;/code&gt;) is calculated on each side, the&nbsp;</div><div class="">symmetric encryption cipher keys MUST be derived with HKDF&nbsp;</div><div class="">&lt;ref&gt;[https://tools.ietf.org/html/rfc5869 HKDF (RFC 5869)]&lt;/ref&gt; after the&nbsp;</div><div class="">following specification:</div><div class=""><br class=""></div><div class="">1. HKDF extraction</div><div class="">&lt;code&gt;PRK = HKDF_EXTRACT(hash=SHA256, salt="BitcoinSharedSecret||INITIATOR_32BYTES_PUBKEY||RESPONDER_32BYTES_PUBKEY", ikm=ECDH_KEY)&lt;/code&gt;.</div><div class=""><br class=""></div><div class="">2. Derive Key_1_A (K_1 communication direction A)</div><div class="">&lt;code&gt;K1A = HKDF_EXPAND(prk=PRK, hash=SHA256, info="BitcoinK_1_A", L=32)&lt;/code&gt;</div><div class=""><br class=""></div><div class="">2. Derive Key_2_A (K_2 communication direction A)</div><div class="">&lt;code&gt;K1B = HKDF_EXPAND(prk=PRK, hash=SHA256, info="BitcoinK_2_A", L=32)&lt;/code&gt;</div><div class=""><br class=""></div><div class="">3. Derive Key_1_B (K_1 communication direction B)</div><div class="">&lt;code&gt;K2 = HKDF_EXPAND(prk=PRK, hash=SHA256, info="BitcoinK_1_B", L=32)&lt;/code&gt;</div><div class=""><br class=""></div><div class="">3. Derive Key_2_B (K_2 communication direction B)</div><div class="">&lt;code&gt;K2 = HKDF_EXPAND(prk=PRK, hash=SHA256, info="BitcoinK_2_B", L=32)&lt;/code&gt;</div><div class=""><br class=""></div><div class="">=== Session ID ===</div><div class=""><br class=""></div><div class="">Both parties MUST also calculate the 256bit session-id using &lt;code&gt;SID =&nbsp;</div><div class="">HKDF_EXPAND(prk=PRK, hash=SHA256, info="BitcoinSessionID", L=32)&lt;/code&gt;. The&nbsp;</div><div class="">session-id can be used for authenticating the encryption-session (identity&nbsp;</div><div class="">check).</div><div class=""><br class=""></div><div class="">The session-id MUST be presented to the user on request.</div><div class=""><br class=""></div><div class="">=== ChaCha20-Poly1305@Bitcoin Cipher Suite ===</div><div class=""><br class=""></div><div class="">==== Background ====</div><div class=""><br class=""></div><div class="">ChaCha20 is a stream cipher designed by Daniel Bernstein and described in&nbsp;</div><div class="">&lt;ref&gt;[http://cr.yp.to/chacha/chacha-20080128.pdf ChaCha20]&lt;/ref&gt;. It operates&nbsp;</div><div class="">by permuting 128 fixed bits, 128 or 256 bits of key, a 64 bit nonce and a 64&nbsp;</div><div class="">bit counter into 64 bytes of output. This output is used as a keystream, with&nbsp;</div><div class="">any unused bytes simply discarded.</div><div class=""><br class=""></div><div class="">Poly1305 &lt;ref&gt;[http://cr.yp.to/mac/poly1305-20050329.pdf Poly1305]&lt;/ref&gt;, also&nbsp;</div><div class="">by Daniel Bernstein, is a one-time Carter-Wegman MAC that computes a 128 bit&nbsp;</div><div class="">integrity tag given a message and a single-use 256 bit secret key.</div><div class=""><br class=""></div><div class="">The chacha20-poly1305@bitcoin combines these two primitives into an&nbsp;</div><div class="">authenticated encryption mode. The construction used is based on that proposed&nbsp;</div><div class="">for TLS by Adam Langley in&nbsp;</div><div class="">&lt;ref&gt;[http://tools.ietf.org/html/draft-agl-tls-chacha20poly1305-03 "ChaCha20&nbsp;</div><div class="">and Poly1305 based Cipher Suites for TLS", Adam Langley]&lt;/ref&gt;, but differs in&nbsp;</div><div class="">the layout of data passed to the MAC and in the addition of encryption of the&nbsp;</div><div class="">packet lengths.</div><div class=""><br class=""></div><div class="">==== Detailed Construction ====</div><div class=""><br class=""></div><div class="">The chacha20-poly1305@bitcoin cipher requires two 256 bits of key material as&nbsp;</div><div class="">output from the key exchange. Each key (K_1 and K_2) are used by two separate&nbsp;</div><div class="">instances of chacha20.</div><div class=""><br class=""></div><div class="">The instance keyed by K_1 is a stream cipher that is used only to encrypt the 3&nbsp;</div><div class="">byte packet length field and has its own sequence number. The second instance,&nbsp;</div><div class="">keyed by K_2, is used in conjunction with poly1305 to build an AEAD&nbsp;</div><div class="">(Authenticated Encryption with Associated Data) that is used to encrypt and&nbsp;</div><div class="">authenticate the entire packet.</div><div class=""><br class=""></div><div class="">Two separate cipher instances are used here so as to keep the packet lengths&nbsp;</div><div class="">confidential but not create an oracle for the packet payload cipher by&nbsp;</div><div class="">decrypting and using the packet length prior to checking the MAC. By using an&nbsp;</div><div class="">independently-keyed cipher instance to encrypt the length, an active attacker&nbsp;</div><div class="">seeking to exploit the packet input handling as a decryption oracle can learn&nbsp;</div><div class="">nothing about the payload contents or its MAC (assuming key derivation,&nbsp;</div><div class="">ChaCha20 and Poly1305 are secure).</div><div class=""><br class=""></div><div class="">The AEAD is constructed as follows: for each packet, generate a Poly1305 key by&nbsp;</div><div class="">taking the first 256 bits of ChaCha20 stream output generated using K_2, an IV&nbsp;</div><div class="">consisting of the packet sequence number encoded as an LE uint64 and a ChaCha20&nbsp;</div><div class="">block counter of zero. The K_2 ChaCha20 block counter is then set to the&nbsp;</div><div class="">little-endian encoding of 1 (i.e. {1, 0, 0, 0, 0, 0, 0, 0}) and this instance&nbsp;</div><div class="">is used for encryption of the packet payload.</div><div class=""><br class=""></div><div class="">==== Packet Handling ====</div><div class=""><br class=""></div><div class="">When receiving a packet, the length must be decrypted first. When 3 bytes of&nbsp;</div><div class="">ciphertext length have been received, they may be decrypted.</div><div class=""><br class=""></div><div class="">A ChaCha20 round always calculates 64bytes which is sufficient to crypt 21&nbsp;</div><div class="">times a 3 bytes length field (21*3 = 63). The length field sequence number can&nbsp;</div><div class="">thus be used 21 times (keystream caching).</div><div class=""><br class=""></div><div class="">The length field must be enc-/decrypted with the ChaCha20 keystream keyed with&nbsp;</div><div class="">K_1 defined by block counter 0, the length field sequence number in little&nbsp;</div><div class="">endian and a keystream position from 0 to 60.</div><div class=""><br class=""></div><div class="">Pseudo code example:</div><div class="">&lt;pre&gt;</div><div class="">// init</div><div class="">sequence_nr_payload = 0; //payload sequence number</div><div class="">sequence_nr_length_field = 0; //length field sequence number (will be reused)</div><div class="">aad_length_field_pos = 0; //position in the length field cipher instance keystream chunk</div><div class=""><br class=""></div><div class="">...</div><div class=""><br class=""></div><div class="">// actual encryption</div><div class="">if cache_length_field_sequence_number != sequence_nr_length_field {</div><div class="">&nbsp; cache_keystream_64_bytes = ChaCha20(key=K_1, iv=little_endian(sequence_nr_length_field), counter=0);</div><div class="">&nbsp; cache_length_field_sequence_number = sequence_nr_length_field</div><div class="">}</div><div class="">packet_length = XOR_TO_LE(cache_length_field_sequence_number[aad_length_field_pos - aad_length_field_pos+3], ciphertext[0-3])</div><div class=""><br class=""></div><div class="">sequence_nr_payload++;</div><div class="">aad_length_field_pos += 3; //skip 3 bytes in keystream</div><div class="">if (aad_length_field_pos + 3 &gt; 64) { //if we are outside of the 64byte keystream...</div><div class="">&nbsp; aad_length_field_pos = 0; // reset at position 0</div><div class="">&nbsp; sequence_nr_length_field++; // increase length field sequence number</div><div class="">}</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">Once the entire packet has been received, the MAC MUST be checked before&nbsp;</div><div class="">decryption. A per-packet Poly1305 key is generated as described above and the&nbsp;</div><div class="">MAC tag calculated using Poly1305 with this key over the ciphertext of the&nbsp;</div><div class="">packet length and the payload together. The calculated MAC is then compared in&nbsp;</div><div class="">constant time with the one appended to the packet and the packet decrypted&nbsp;</div><div class="">using ChaCha20 as described above (with K_2, the packet sequence number as&nbsp;</div><div class="">nonce and a starting block counter of 1).</div><div class=""><br class=""></div><div class="">Detection of an invalid MAC MUST lead to immediate connection termination.</div><div class=""><br class=""></div><div class="">To send a packet, first encode the 3 byte length and encrypt it using K_1 as&nbsp;</div><div class="">described above. Encrypt the packet payload (using K_2) and append it to the&nbsp;</div><div class="">encrypted length. Finally, calculate a MAC tag and append it.</div><div class=""><br class=""></div><div class="">The initiating peer MUST use &lt;code&gt;K_1_A, K_2_A&lt;/code&gt; to encrypt messages on&nbsp;</div><div class="">the send channel, &lt;code&gt;K_1_B, K_2_B&lt;/code&gt; MUST be used to decrypt messages on&nbsp;</div><div class="">the receive channel.</div><div class=""><br class=""></div><div class="">The responding peer MUST use &lt;code&gt;K_1_A, K_2_A&lt;/code&gt; to decrypt messages on&nbsp;</div><div class="">the receive channel, &lt;code&gt;K_1_B, K_2_B&lt;/code&gt; MUST be used to encrypt messages&nbsp;</div><div class="">on the send channel.</div><div class=""><br class=""></div><div class="">Optimized implementations of ChaCha20-Poly1305@bitcoin are relatively fast in&nbsp;</div><div class="">general, therefore it is very likely that encrypted messages require not more&nbsp;</div><div class="">CPU cycles per bytes then the current unencrypted p2p message format&nbsp;</div><div class="">(ChaCha20/Poly1305 versus double SHA256).</div><div class=""><br class=""></div><div class="">The initial packet sequence numbers are 0.</div><div class=""><br class=""></div><div class="">K_2 ChaCha20 cipher instance (payload) must never reuse a {key, nonce} for&nbsp;</div><div class="">encryption nor may it be used to encrypt more than 2^70 bytes under the same&nbsp;</div><div class="">{key, nonce}.</div><div class=""><br class=""></div><div class="">K_1 ChaCha20 cipher instance (length field/AAD) must never reuse a {key, nonce,&nbsp;</div><div class="">position-in-keystream} for encryption nor may it be used to encrypt more than&nbsp;</div><div class="">2^70 bytes under the same {key, nonce}.</div><div class=""><br class=""></div><div class="">We use message sequence numbers for both communication directions.</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">&nbsp;------------------------------------------------------------------------------------------</div><div class="">&nbsp;| Initiator &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Responder &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| AEAD() = ChaCha20Poly1305Bitcoin() &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; |</div><div class="">&nbsp;| MSG_A_CIPH = AEAD(k=K_1_A, K_2_A, payload_nonce=0, aad_nonce=0, aad_pos=0, msg) &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --- MSG_CIPH ---&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;msg &nbsp; := AEAD(k=K_1_A,K_2_A, n=0, ..., MSG_A_CIPH) &nbsp;|</div><div class="">&nbsp;| &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;|</div><div class="">&nbsp;------------------------------------------------------------------------------------------</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">==== Test Vectors ====</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">message &nbsp; 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</div><div class="">k1 (DATA) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</div><div class="">k2 (AAD) &nbsp;00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</div><div class=""><br class=""></div><div class="">AAD keystream</div><div class="">76 b8 e0 ad a0 f1 3d 90 40 5d 6a e5 53 86 bd 28 bd d2 19 b8 a0 8d ed 1a a8 36 ef cc 8b 77 0d c7 da 41 59 7c 51 57 48 8d 77 24 e0 3f b8 d8 4a 37 6a 43 b8 f4 15 18 a1 1c c3 87 b6 69 b2 ee 65 86</div><div class=""><br class=""></div><div class="">ciphertext</div><div class="">76 b8 e0 9f 07 e7 be 55 51 38 7a 98 ba 97 7c 73 2d 08 0d cb 0f 29 a0 48 e3 65 69 12 c6 53 3e 32</div><div class=""><br class=""></div><div class="">MAC</div><div class="">d2 fc 11 82 9c 1b 6c 1d f1 f5 51 cd 61 31 ff 08</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">message &nbsp; 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</div><div class="">k1 (DATA) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</div><div class="">k2 (AAD) &nbsp;00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00</div><div class=""><br class=""></div><div class="">AAD keystream</div><div class="">76 b8 e0 ad a0 f1 3d 90 40 5d 6a e5 53 86 bd 28 bd d2 19 b8 a0 8d ed 1a a8 36 ef cc 8b 77 0d c7 da 41 59 7c 51 57 48 8d 77 24 e0 3f b8 d8 4a 37 6a 43 b8 f4 15 18 a1 1c c3 87 b6 69 b2 ee 65 86</div><div class=""><br class=""></div><div class="">ciphertext</div><div class="">77 b8 e0 9f 07 e7 be 55 51 38 7a 98 ba 97 7c 73 2d 08 0d cb 0f 29 a0 48 e3 65 69 12 c6 53 3e 32</div><div class=""><br class=""></div><div class="">MAC</div><div class="">ba f0 c8 5b 6d ff 86 02 b0 6c f5 2a 6a ef c6 2e</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">message</div><div class="">ff 00 00 f1 95 e6 69 82 10 5f fb 64 0b b7 75 7f 57 9d a3 16 02 fc 93 ec 01 ac 56 f8 5a c3 c1 34 a4 54 7b 73 3b 46 41 30 42 c9 44 00 49 17 69 05 d3 be 59 ea 1c 53 f1 59 16 15 5c 2b e8 24 1a 38 00 8b 9a 26 bc 35 94 1e 24 44 17 7c 8a de 66 89 de 95 26 49 86 d9 58 89 fb 60 e8 46 29 c9 bd 9a 5a cb 1c c1 18 be 56 3e b9 b3 a4 a4 72 f8 2e 09 a7 e7 78 49 2b 56 2e f7 13 0e 88 df e0 31 c7 9d b9 d4 f7 c7 a8 99 15 1b 9a 47 50 32 b6 3f c3 85 24 5f e0 54 e3 dd 5a 97 a5 f5 76 fe 06 40 25 d3 ce 04 2c 56 6a b2 c5 07 b1 38 db 85 3e 3d 69 59 66 09 96 54 6c c9 c4 a6 ea fd c7 77 c0 40 d7 0e af 46 f7 6d ad 39 79 e5 c5 36 0c 33 17 16 6a 1c 89 4c 94 a3 71 87 6a 94 df 76 28 fe 4e aa f2 cc b2 7d 5a aa e0 ad 7a d0 f9 d4 b6 ad 3b 54 09 87 46 d4 52 4d 38 40 7a 6d eb 3a b7 8f ab 78 c9</div><div class=""><br class=""></div><div class="">k1 (DATA) 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f</div><div class="">k2 (AAD) &nbsp;ff 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f</div><div class=""><br class=""></div><div class="">AAD keystream</div><div class="">c6 40 c1 71 1e 3e e9 04 ac 35 c5 7a b9 79 1c 8a 1c 40 86 03 a9 0b 77 a8 3b 54 f6 c8 44 cb 4b 06 d9 4e 7f c6 c8 00 e1 65 ac d6 61 47 e8 0e c4 5a 56 7f 6c e6 6d 05 ec 0c ae 67 9d ce eb 89 00 17</div><div class=""><br class=""></div><div class="">ciphertext</div><div class="">39 40 c1 e9 2d a4 58 2f f6 f9 2a 77 6a eb 14 d0 14 d3 84 ee b3 0f 66 0d ac f7 0a 14 a2 3f d3 1e 91 21 27 01 33 4e 2c e1 ac f5 19 9d c8 4f 4d 61 dd be 65 71 bc a5 af 87 4b 4c 92 26 c2 6e 65 09 95 d1 57 64 4e 18 48 b9 6e d6 c2 10 2d 54 89 a0 50 e7 1d 29 a5 a6 6e ce 11 de 5f b5 c9 55 8d 54 da 28 fe 45 b0 bc 4d b4 e5 b8 80 30 bf c4 a3 52 b4 b7 06 8e cc f6 56 ba e7 ad 6a 35 61 53 15 fc 7c 49 d4 20 03 88 d5 ec a6 7c 2e 82 2e 06 93 36 c6 9b 40 db 67 e0 f3 c8 12 09 c5 0f 32 16 a4 b8 9f b3 ae 1b 98 4b 78 51 a2 ec 6f 68 ab 12 b1 01 ab 12 0e 1e a7 31 3b b9 3b 5a 0f 71 18 5c 7f ea 01 7d db 92 76 98 61 c2 9d ba 4f bc 43 22 80 d5 df f2 1b 36 d1 c4 c7 90 12 8b 22 69 99 50 bb 18 bf 74 c4 48 cd fe 54 7d 8e d4 f6 57 d8 00 5f dc 0c d7 a0 50 c2 d4 60 50 a4 4c 43 76 35 58 58&nbsp;</div><div class=""><br class=""></div><div class="">MAC</div><div class="">98 1f be 8b 18 42 88 27 6e 7a 93 ea bc 89 9c 4a</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">=== v2 Messages Structure ===</div><div class=""><br class=""></div><div class="">{|class="wikitable"</div><div class="">! Field Size !! Description !! Data type !! Comments</div><div class="">|-</div><div class="">| 3 || length &amp; flag || 23 + 1 bits || Encrypted length of ciphertext payload (not counting the MAC tag) in number of bytes (only 2^23 is usable, most significant bit is the rekey-flag)</div><div class="">|-</div><div class="">| 1-13 || encrypted command || variable || ASCII command (or one byte short command ID)</div><div class="">|-</div><div class="">| ? || encrypted payload || ? || The actual data</div><div class="">|-</div><div class="">| 16 || MAC tag || ? || 128bit MAC-tag</div><div class="">|}</div><div class=""><br class=""></div><div class="">Encrypted messages do not have the 4byte network magic.</div><div class=""><br class=""></div><div class="">The maximum message size is 2^23 (8’388’608) bytes. Future communication MAY&nbsp;</div><div class="">exceed this limit and thus MUST be split into different messages.</div><div class=""><br class=""></div><div class="">Decrypting and processing the message before the authentication succeeds (MAC&nbsp;</div><div class="">verified) MUST not be done.</div><div class=""><br class=""></div><div class="">The 4byte sha256 checksum is no longer required because the AEAD (MAC).</div><div class=""><br class=""></div><div class="">Both peers MUST keep track of the message sequence number (uint32) of sent and&nbsp;</div><div class="">received messages for building a 64-bit symmetric cipher IV.</div><div class=""><br class=""></div><div class="">The command field MUST start with a byte that defines the length of the ASCII&nbsp;</div><div class="">command string up to 12 chars (1 to 12) or a short command ID (see below).</div><div class=""><br class=""></div><div class="">==== Short Command ID ====</div><div class=""><br class=""></div><div class="">To save valuable bandwidth, the v2 message format supports message command&nbsp;</div><div class="">short IDs for message types with high frequency. The ID/string mapping is a&nbsp;</div><div class="">peer to peer arrangement and MAY be negotiated between the initiating and&nbsp;</div><div class="">responding peer. A peer conforming to this proposal MUST support short IDs&nbsp;</div><div class="">based on the table below and SHOULD use short command IDs for outgoing messages.</div><div class=""><br class=""></div><div class="">{|class="wikitable"</div><div class="">! Number !! Command</div><div class="">|-</div><div class="">| 13 || INV</div><div class="">|-</div><div class="">| 14 || HEADERS</div><div class="">|-</div><div class="">| 15 || PING</div><div class="">|-</div><div class="">| 16 || PONG</div><div class="">|-</div><div class="">|}</div><div class=""><br class=""></div><div class="">==== Length comparisons between v1 and v2 messages ====</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">v1 in: 4(Magic)+12(Command)+4(MessageSize)+4(Checksum)+36(Payload) == 60</div><div class="">v2 inv: 3(MessageSize&amp;Flag)+1(Command)+36(Payload)+16(MAC) == 56</div><div class="">(93.33%)</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">v1 ping: 4(Magic)+12(Command)+4(MessageSize)+4(Checksum)+8(Payload) == 32</div><div class="">v2 pong: 3(MessageSize&amp;Flag)+1(Command)+8(Payload)+16(MAC) == 28</div><div class="">(87.5%)</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">&lt;pre&gt;</div><div class="">v1 block: 4(Magic)+12(Command)+4(MessageSize)+4(Checksum)+1’048’576(Payload) = 1’048’600</div><div class="">v2 block: 3(MessageSize&amp;Flag)+6(CommandStr)+8(Payload)+16(MAC) == 28 = 1’048’601</div><div class="">(100.000095%)</div><div class="">&lt;/pre&gt;</div><div class=""><br class=""></div><div class="">=== Re-Keying ===</div><div class=""><br class=""></div><div class="">Re-keying can be signaled by setting the most significant bit in the length&nbsp;</div><div class="">field before encryption. A peer signaling a rekey MUST use the next key for&nbsp;</div><div class="">encryption messages AFTER the message where the signaling has been done.</div><div class=""><br class=""></div><div class="">A peer identifying a rekey by checking the most significant bit in the envelope&nbsp;</div><div class="">length must use the next key for decrypt messages AFTER the message where the&nbsp;</div><div class="">signaling has been detected.</div><div class=""><br class=""></div><div class="">The next symmetric cipher key MUST be calculated by &lt;code&gt;SHA256(SHA256(session&nbsp;</div><div class="">ID || old_symmetric_cipher_key))&lt;/code&gt; and the packet sequence number of the&nbsp;</div><div class="">according encryption direction must be set to 0.</div><div class=""><br class=""></div><div class="">Re-Keying interval is a peer policy with a minimum timespan of 10 seconds.</div><div class=""><br class=""></div><div class="">The Re-Keying must be done after every 1GB of data sent (recommended by RFC4253&nbsp;</div><div class="">SSH Transport) or if the last rekey was more than an hour ago.</div><div class=""><br class=""></div><div class="">Peers calculate the counterparty limits and MUST disconnect immediately if a&nbsp;</div><div class="">violation of the limits has been detected.</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">=== Risks ===</div><div class=""><br class=""></div><div class="">The encryption does not include an authentication scheme. This BIP does not&nbsp;</div><div class="">cover a proposal to avoid MITM attacks during the encryption initialization.&nbsp;</div><div class="">However, peers MUST show the session-id to the user on request which allows to&nbsp;</div><div class="">identify a MITM by a manual verification on a secure channel.</div><div class=""><br class=""></div><div class="">Optional authentication schemes may be covered by other proposals &lt;ref&nbsp;</div><div class="">name="bip150"&gt;[https://github.com/bitcoin/bips/blob/master/bip-0150.mediawiki&nbsp;</div><div class="">BIP150]&lt;/ref&gt;.</div><div class=""><br class=""></div><div class="">An attacker could delay or halt v2 protocol enforcement by providing a&nbsp;</div><div class="">reasonable amount of peers not supporting the v2 protocol.</div><div class=""><br class=""></div><div class="">== Compatibility ==</div><div class=""><br class=""></div><div class="">This proposal is backward compatible (as long as not enforced). Non-supporting&nbsp;</div><div class="">peers can still use unencrypted communications.</div><div class=""><br class=""></div><div class="">== Reference implementation ==</div><div class="">* Complete Bitcoin Core implementation: https://github.com/bitcoin/bitcoin/pull/14032</div><div class="">* Reference implementation of the AEAD in C: https://github.com/jonasschnelli/chacha20poly1305</div><div class=""><br class=""></div><div class="">== References ==</div><div class=""><br class=""></div><div class="">&lt;references/&gt;</div><div class=""><br class=""></div><div class="">== Acknowledgements ==</div><div class="">* Pieter Wuille and Gregory Maxwell for most of the ideas in this BIP.</div><div class="">* Tim Ruffing for the review and the hint for the enhancement of the symmetric&nbsp;</div><div class="">key derivation</div><div class=""><br class=""></div><div class=""><br class=""></div><div class="">== Copyright ==</div><div class="">This work is placed in the public domain.</div><div class=""><br class=""></div></div></div></body></html>