aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortrevnoise <noise@trevp.net>2016-10-07 19:38:34 -0700
committertrevnoise <noise@trevp.net>2016-10-07 19:38:34 -0700
commitddffc62f68b18147a74351c7fdafb58de3ce9dab (patch)
tree7f51dea3c33900fd1609c36d918411a3ff1eca35
parentUpdate metadata (diff)
downloadnoise-31.tar.xz
noise-31.zip
Adding outputv31
-rw-r--r--output/noise.html1026
-rw-r--r--output/noise.pdfbin333431 -> 327990 bytes
2 files changed, 1026 insertions, 0 deletions
diff --git a/output/noise.html b/output/noise.html
new file mode 100644
index 0000000..81d53e7
--- /dev/null
+++ b/output/noise.html
@@ -0,0 +1,1026 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Style-Type" content="text/css" />
+ <meta name="generator" content="pandoc" />
+ <meta name="author" content="Trevor Perrin (noise@trevp.net)" />
+ <meta name="date" content="2016-10-07" />
+ <title>The Noise Protocol Framework</title>
+ <style type="text/css">code{white-space: pre;}</style>
+ <link rel="stylesheet" href="spec_markdown.css" type="text/css" />
+</head>
+<body>
+<div id="header">
+<h1 class="title">The Noise Protocol Framework</h1>
+<b>Author:</b> Trevor Perrin (noise@trevp.net)<br/>
+<b>Revision:</b> 31<br/>
+<b>Date:</b> 2016-10-07<br/>
+</div>
+<div id="TOC">
+<h2 class="toc">Table of Contents</h2>
+<ul>
+<li><a href="#introduction">1. Introduction</a></li>
+<li><a href="#overview">2. Overview</a><ul>
+<li><a href="#terminology">2.1. Terminology</a></li>
+<li><a href="#overview-of-handshake-state-machine">2.2. Overview of handshake state machine</a></li>
+</ul></li>
+<li><a href="#message-format">3. Message format</a></li>
+<li><a href="#crypto-functions">4. Crypto functions</a><ul>
+<li><a href="#dh-functions">4.1. DH functions</a></li>
+<li><a href="#cipher-functions">4.2. Cipher functions</a></li>
+<li><a href="#hash-functions">4.3. Hash functions</a></li>
+</ul></li>
+<li><a href="#processing-rules">5. Processing rules</a><ul>
+<li><a href="#the-cipherstate-object">5.1 The <code>CipherState</code> object</a></li>
+<li><a href="#the-symmetricstate-object">5.2. The <code>SymmetricState</code> object</a></li>
+<li><a href="#the-handshakestate-object">5.3. The <code>HandshakeState</code> object</a></li>
+</ul></li>
+<li><a href="#prologue">6. Prologue</a></li>
+<li><a href="#pre-shared-symmetric-keys">7. Pre-shared symmetric keys</a></li>
+<li><a href="#handshake-patterns">8. Handshake patterns</a><ul>
+<li><a href="#pattern-validity">8.1. Pattern validity</a></li>
+<li><a href="#one-way-patterns">8.2. One-way patterns</a></li>
+<li><a href="#interactive-patterns">8.3. Interactive patterns</a></li>
+<li><a href="#payload-security-properties">8.4. Payload security properties</a></li>
+<li><a href="#identity-hiding">8.5. Identity hiding</a></li>
+<li><a href="#more-patterns">8.6. More patterns</a></li>
+</ul></li>
+<li><a href="#advanced-uses">9. Advanced uses</a><ul>
+<li><a href="#dummy-static-public-keys">9.1. Dummy static public keys</a></li>
+<li><a href="#compound-protocols-and-noise-pipes">9.2. Compound protocols and &quot;Noise Pipes&quot;</a></li>
+<li><a href="#protocol-indistinguishability">9.3. Protocol indistinguishability</a></li>
+<li><a href="#channel-binding">9.4. Channel binding</a></li>
+</ul></li>
+<li><a href="#dh-functions-cipher-functions-and-hash-functions">10. DH functions, cipher functions, and hash functions</a><ul>
+<li><a href="#the-25519-dh-functions">10.1. The <code>25519</code> DH functions</a></li>
+<li><a href="#the-448-dh-functions">10.2. The <code>448</code> DH functions</a></li>
+<li><a href="#the-chachapoly-cipher-functions">10.3. The <code>ChaChaPoly</code> cipher functions</a></li>
+<li><a href="#the-aesgcm-cipher-functions">10.4. The <code>AESGCM</code> cipher functions</a></li>
+<li><a href="#the-sha256-hash-function">10.5. The <code>SHA256</code> hash function</a></li>
+<li><a href="#the-sha512-hash-function">10.6. The <code>SHA512</code> hash function</a></li>
+<li><a href="#the-blake2s-hash-function">10.7. The <code>BLAKE2s</code> hash function</a></li>
+<li><a href="#the-blake2b-hash-function">10.8. The <code>BLAKE2b</code> hash function</a></li>
+</ul></li>
+<li><a href="#protocol-names">11. Protocol names</a></li>
+<li><a href="#application-responsibilities">12. Application responsibilities</a></li>
+<li><a href="#security-considerations">13. Security considerations</a></li>
+<li><a href="#rationale">14. Rationale</a></li>
+<li><a href="#ipr">15. IPR</a></li>
+<li><a href="#acknowledgements">16. Acknowledgements</a></li>
+<li><a href="#references">17. References</a></li>
+</ul>
+</div>
+<h1 id="introduction">1. Introduction</h1>
+<p>Noise is a framework for crypto protocols based on Diffie-Hellman key agreement. Noise can describe protocols that consist of a single message as well as interactive protocols.</p>
+<h1 id="overview">2. Overview</h1>
+<h2 id="terminology">2.1. Terminology</h2>
+<p>A Noise protocol begins with two parties exchanging <strong>handshake messages</strong>. During this <strong>handshake phase</strong> the parties exchange DH public keys and perform a sequence of DH operations, hashing the DH results into a shared secret key. After the handshake phase each party can use this shared key to send encrypted <strong>transport messages</strong>.</p>
+<p>The Noise framework supports handshakes where each party has a long-term <strong>static key pair</strong> and/or an <strong>ephemeral key pair</strong>. A Noise handshake is described by a simple language. This language consists of <strong>tokens</strong> which are arranged into <strong>message patterns</strong>. Message patterns are arranged into <strong>handshake patterns</strong>.</p>
+<p>A <strong>message pattern</strong> is a sequence of tokens that specifies the DH public keys that comprise a handshake message, and the DH operations that are performed when sending or receiving that message. A <strong>handshake pattern</strong> specifies the sequential exchange of messages that comprise a handshake.</p>
+<p>A handshake pattern can be instantiated by <strong>DH functions</strong>, <strong>cipher functions</strong>, and a <strong>hash function</strong> to give a concrete <strong>Noise protocol</strong>.</p>
+<h2 id="overview-of-handshake-state-machine">2.2. Overview of handshake state machine</h2>
+<p>The core of Noise is a set of variables maintained by each party during a handshake, and rules for sending and receiving handshake messages by sequentially processing the tokens from a message pattern.</p>
+<p>Each party maintains the following variables:</p>
+<ul>
+<li><p><strong><code>s, e</code></strong>: The local party's static and ephemeral key pairs (which may be empty).</p></li>
+<li><p><strong><code>rs, re</code></strong>: The remote party's static and ephemeral public keys (which may be empty).</p></li>
+<li><p><strong><code>h</code></strong>: A <strong>handshake hash</strong> value that hashes all the handshake data that's been sent and received.</p></li>
+<li><p><strong><code>ck</code></strong>: A <strong>chaining key</strong> that hashes all previous DH outputs. Once the handshake completes, the chaining key will be used to derive the encryption keys for transport messages.</p></li>
+<li><p><strong><code>k, n</code></strong>: An encryption key <code>k</code> (which may be empty) and a counter-based nonce <code>n</code>. Whenever a new DH output causes a new <code>ck</code> to be calculated, a new <code>k</code> is also calculated. The key <code>k</code> and nonce <code>n</code> are used to encrypt static public keys and handshake payloads. Encryption with <code>k</code> uses some <strong>AEAD</strong> cipher mode (in the sense of Rogaway <span class="citation">[<a href="#ref-Rogaway:2002">1</a>]</span>) and includes the current <code>h</code> value as &quot;associated data&quot; which is covered by the AEAD authentication. Encryption of static public keys and payloads provides some confidentiality and key confirmation during the handshake phase.</p></li>
+</ul>
+<p>A handshake message consists of some DH public keys followed by a <strong>payload</strong>. The payload may contain certificates or other data chosen by the application. To send a handshake message, the sender specifies the payload and sequentially processes each token from a message pattern. The possible tokens are:</p>
+<ul>
+<li><p><strong><code>&quot;e&quot;</code></strong>: The sender generates a new ephemeral key pair and stores it in the <code>e</code> variable, writes the ephemeral public key as cleartext into the message buffer, and hashes the public key along with the old <code>h</code> to derive a new <code>h</code>.</p></li>
+<li><p><strong><code>&quot;s&quot;</code></strong>: The sender writes its static public key from the <code>s</code> variable into the message buffer, encrypting it if <code>k</code> is non-empty, and hashes the output along with the old <code>h</code> to derive a new <code>h</code>.</p></li>
+<li><p><strong><code>&quot;ee&quot;, &quot;se&quot;, &quot;es&quot;, &quot;ss&quot;</code></strong>: A DH is performed between the initiator's key pair (whether static or ephemeral is determined by the first letter) and the responder's key pair (whether static or ephemeral is determined by the second letter). The result is hashed along with the old <code>ck</code> to derive a new <code>ck</code> and <code>k</code>, and <code>n</code> is set to zero.</p></li>
+</ul>
+<p>After processing the final token in a handshake message, the sender then writes the payload into the message buffer, encrypting it if <code>k</code> is non-empty, and hashes the output along with the old <code>h</code> to derive a new <code>h</code>.</p>
+<p>As a simple example, an unauthenticated DH handshake is described by the handshake pattern:</p>
+<pre><code> -&gt; e
+ &lt;- e, ee</code></pre>
+<p>The <strong>initiator</strong> sends the first message, which is simply an ephemeral public key. The <strong>responder</strong> sends back its own ephemeral public key. Then a DH is performed and the output is hashed into a shared secret key.</p>
+<p>Note that a cleartext payload is sent in the first message, after the cleartext ephemeral public key, and an encrypted payload is sent in the response message, after the cleartext ephemeral public key. The application may send whatever payloads it wants.</p>
+<p>The responder can send its static public key (under encryption) and authenticate itself via a slightly different pattern:</p>
+<pre><code> -&gt; e
+ &lt;- e, ee, s, es</code></pre>
+<p>In this case, the final <code>ck</code> and <code>k</code> values are a hash of both DH results. Since the <code>es</code> token indicates a DH between the initiator's ephemeral key and the responder's static key, successful decryption by the initiator of the second message's payload serves to authenticate the responder to the initiator.</p>
+<p>Note that the second message's payload may contain a zero-length plaintext, but the payload ciphertext will still contain authentication data (such as an authentication tag or &quot;synthetic IV&quot;), since encryption is with an AEAD mode. The second message's payload can also be used to deliver certificates for the responder's static public key.</p>
+<p>The initiator can send <em>its</em> static public key (under encryption), and authenticate itself, using a handshake pattern with one additional message:</p>
+<pre><code> -&gt; e
+ &lt;- e, ee, s, es
+ -&gt; s, se</code></pre>
+<p>The following sections flesh out the details, and add some complications. However, the core of Noise is this simple system of variables, tokens, and processing rules, which allow concise expression of a range of protocols.</p>
+<h1 id="message-format">3. Message format</h1>
+<p>All Noise messages are less than or equal to 65535 bytes in length. Restricting message size has several advantages:</p>
+<ul>
+<li><p>Simpler testing, since it's easy to test the maximum sizes.</p></li>
+<li><p>Reduces the likelihood of errors in memory handling, or integer overflow.</p></li>
+<li><p>Enables support for streaming decryption and random-access decryption of large data streams.</p></li>
+<li><p>Enables higher-level protocols that encapsulate Noise messages to use an efficient standard length field of 16 bits.</p></li>
+</ul>
+<p>All Noise messages can be processed without parsing, since there are no type or length fields. Of course, Noise messages might be encapsulated within a higher-level protocol that contains type and length information. Noise messages might encapsulate payloads that require parsing of some sort, but payloads are handled by the application, not by Noise.</p>
+<p>A Noise <strong>transport message</strong> is simply an AEAD ciphertext that is less than or equal to 65535 bytes in length, and that consists of an encrypted payload plus 16 bytes of authentication data. The details depend on the AEAD cipher function, e.g. AES256-GCM, or ChaCha20-Poly1305, but typically the authentication data is either a 16-byte authentication tag appended to the ciphertext, or a 16-byte synthetic IV prepended to the ciphertext.</p>
+<p>A Noise <strong>handshake message</strong> is also less than or equal to 65535 bytes. It begins with a sequence of one or more DH public keys, as determined by its message pattern. Following the public keys will be a single payload which can be used to convey certificates or other handshake data, but can also contain a zero-length plaintext.</p>
+<p>Static public keys and payloads will be in cleartext if they are sent in a handshake prior to a DH operation, and will be AEAD ciphertexts if they occur after a DH operation. (If Noise is being used with pre-shared symmetric keys, this rule is different: <em>all</em> static public keys and payloads will be encrypted; see <a href="#pre-shared-symmetric-keys">Section 7</a>). Like transport messages, AEAD ciphertexts will expand each encrypted field (whether static public key or payload) by 16 bytes.</p>
+<p></p>
+<p>For an example, consider the handshake pattern:</p>
+<pre><code> -&gt; e
+ &lt;- e, ee, s, es
+ -&gt; s, se</code></pre>
+<p>The first message consists of a cleartext public key (<code>&quot;e&quot;</code>) followed by a cleartext payload (remember that a payload is implicit at the end of each message pattern). The second message consists of a cleartext public key (<code>&quot;e&quot;</code>) followed by an encrypted public key (<code>&quot;s&quot;</code>) followed by an encrypted payload. The third message consists of an encrypted public key (<code>&quot;s&quot;</code>) followed by an encrypted payload.</p>
+<p>Assuming each payload contains a zero-length plaintext, and DH public keys are 56 bytes, the message sizes will be:</p>
+<ol style="list-style-type: decimal">
+<li>56 bytes (one cleartext public key and a cleartext payload)</li>
+<li>144 bytes (two public keys, the second encrypted, and encrypted payload)</li>
+<li>88 bytes (one encrypted public key and encrypted payload)</li>
+</ol>
+<p>If pre-shared symmetric keys are used, the first message grows in size to 72 bytes, since the first payload becomes encrypted.</p>
+<h1 id="crypto-functions">4. Crypto functions</h1>
+<p>A Noise protocol is instantiated with a concrete set of <strong>DH functions</strong>, <strong>cipher functions</strong>, and a <strong>hash function</strong>. The signature for these functions is defined below. Some concrete functions are defined in <a href="#dh-functions-cipher-functions-and-hash-functions">Section 10</a>.</p>
+<p>The following notation will be used in algorithm pseudocode:</p>
+<ul>
+<li>The <code>||</code> operator concatenates byte sequences.</li>
+<li>The <code>byte()</code> function constructs a single byte.</li>
+</ul>
+<h2 id="dh-functions">4.1. DH functions</h2>
+<p>Noise depends on the following <strong>DH functions</strong> (and an associated constant):</p>
+<ul>
+<li><p><strong><code>GENERATE_KEYPAIR()</code></strong>: Generates a new DH key pair. A DH key pair consists of <code>public_key</code> and <code>private_key</code> elements. A <code>public_key</code> represents an encoding of a DH public key into a byte sequence of length <code>DHLEN</code>. The <code>public_key</code> encoding details are specific to each set of DH functions.</p></li>
+<li><p><strong><code>DH(key_pair, public_key)</code></strong>: Performs a DH calculation between the private key in <code>key_pair</code> and <code>public_key</code> and returns an output sequence of bytes of length <code>DHLEN</code>. If the function detects an invalid <code>public_key</code>, the output may be all zeros or any other value that doesn't leak information about the private key. For reasons discussed in <a href="#dummy-static-public-keys">Section 9.1</a> it is recommended for the function to have a <strong>null public key value</strong> that always yields the same output, regardless of private key. For example, the DH functions in <a href="#dh-functions-cipher-functions-and-hash-functions">Section 10</a> always map a DH public key of all zeros to an output of all zeros.</p></li>
+<li><p><strong><code>DHLEN</code></strong> = A constant specifying the size in bytes of public keys and DH outputs. For security reasons, <code>DHLEN</code> must be 32 or greater.</p></li>
+</ul>
+<h2 id="cipher-functions">4.2. Cipher functions</h2>
+<p>Noise depends on the following <strong>cipher functions</strong>:</p>
+<ul>
+<li><p><strong><code>ENCRYPT(k, n, ad, plaintext)</code></strong>: Encrypts <code>plaintext</code> using the cipher key <code>k</code> of 32 bytes and an 8-byte unsigned integer nonce <code>n</code> which must be unique for the key <code>k</code>. Returns the ciphertext. Encryption must be done with an &quot;AEAD&quot; encryption mode with the associated data <code>ad</code> (using the terminology from <span class="citation">[<a href="#ref-Rogaway:2002">1</a>]</span>) and returns a ciphertext that is the same size as the plaintext plus 16 bytes for authentication data. The entire ciphertext must be indistinguishable from random if the key is secret.</p></li>
+<li><p><strong><code>DECRYPT(k, n, ad, ciphertext)</code></strong>: Decrypts <code>ciphertext</code> using a cipher key <code>k</code> of 32 bytes, an 8-byte unsigned integer nonce <code>n</code>, and associated data <code>ad</code>. Returns the plaintext, unless authentication fails, in which case an error is signaled to the caller.</p></li>
+</ul>
+<h2 id="hash-functions">4.3. Hash functions</h2>
+<p>Noise depends on the following <strong>hash function</strong> (and associated constants):</p>
+<ul>
+<li><p><strong><code>HASH(data)</code></strong>: Hashes some arbitrary-length data with a collision-resistant cryptographic hash function and returns an output of <code>HASHLEN</code> bytes.</p></li>
+<li><p><strong><code>HASHLEN</code></strong> = A constant specifying the size in bytes of the hash output. Must be 32 or 64.</p></li>
+<li><p><strong><code>BLOCKLEN</code></strong> = A constant specifying the size in bytes that the hash function uses internally to divide its input for iterative processing. This is needed to use the hash function with HMAC (<code>BLOCKLEN</code> is <code>B</code> in <span class="citation">[<a href="#ref-rfc2104">2</a>]</span>).</p></li>
+</ul>
+<p>Noise defines additional functions based on the above <code>HASH()</code> function:</p>
+<ul>
+<li><p><strong><code>HMAC-HASH(key, data)</code></strong>: Applies <code>HMAC</code> from <span class="citation">[<a href="#ref-rfc2104">2</a>]</span> using the <code>HASH()</code> function. This function is only called as part of <code>HKDF()</code>, below.</p></li>
+<li><strong><code>HKDF(chaining_key, input_key_material)</code></strong>: Takes a <code>chaining_key</code> byte sequence of length <code>HASHLEN</code>, and an <code>input_key_material</code> byte sequence with length either zero bytes, 32 bytes, or <code>DHLEN</code> bytes. Returns two byte sequences of length <code>HASHLEN</code>, as follows:
+<ul>
+<li>Sets <code>temp_key = HMAC-HASH(chaining_key, input_key_material)</code>.</li>
+<li>Sets <code>output1 = HMAC-HASH(temp_key, byte(0x01))</code>.</li>
+<li>Sets <code>output2 = HMAC-HASH(temp_key, output1 || byte(0x02))</code>.</li>
+<li>Returns the pair <code>(output1, output2)</code>.</li>
+</ul></li>
+</ul>
+<p>Note that <code>temp_key</code>, <code>output1</code>, and <code>output2</code> are all <code>HASHLEN</code> bytes in length. Also note that the <code>HKDF()</code> function is simply <code>HKDF</code> from <span class="citation">[<a href="#ref-rfc5869">3</a>]</span> with the <code>chaining_key</code> as HKDF <code>salt</code>, and zero-length HKDF <code>info</code>.</p>
+<h1 id="processing-rules">5. Processing rules</h1>
+<p>To precisely define the processing rules we adopt an object-oriented terminology, and present three &quot;objects&quot; which encapsulate state variables and provide &quot;methods&quot; which implement processing logic. These three objects are presented as a hierarchy: each higher-layer object includes one instance of the object beneath it. From lowest-layer to highest, the objects are:</p>
+<ul>
+<li><p>A <strong><code>CipherState</code></strong> object contains <code>k</code> and <code>n</code> variables, which it uses to encrypt and decrypt ciphertexts. During the handshake phase each party has a single <code>CipherState</code>, but during the transport phase each party has two <code>CipherState</code> objects: one for sending, and one for receiving.</p></li>
+<li><p>A <strong><code>SymmetricState</code></strong> object contains a <code>CipherState</code> plus <code>ck</code> and <code>h</code> variables. It is so-named because it encapsulates all the &quot;symmetric crypto&quot; used by Noise. During the handshake phase each party has a single <code>SymmetricState</code>, which can be deleted once the handshake is finished.</p></li>
+<li><p>A <strong><code>HandshakeState</code></strong> object contains a <code>SymmetricState</code> plus DH variables <code>(s, e, rs, re)</code> and a variable representing the handshake pattern. During the handshake phase each party has a single <code>HandshakeState</code>, which can be deleted once the handshake is finished.</p></li>
+</ul>
+<p>To execute a Noise protocol you <code>Initialize()</code> a <code>HandshakeState</code>. During initialization you specify the handshake pattern, any local key pairs, and any public keys for the remote party you have knowledge of. After <code>Initialize()</code> you call <code>WriteMessage()</code> and <code>ReadMessage()</code> on the <code>HandshakeState</code> to process each handshake message. If a decryption error occurs the handshake has failed and the <code>HandshakeState</code> is deleted without sending further messages.</p>
+<p>Processing the final handshake message returns two <code>CipherState</code> objects, the first for encrypting transport messages from initiator to responder, and the second for messages in the other direction. At that point the <code>HandshakeState</code> may be deleted. Transport messages are then encrypted and decrypted by calling <code>EncryptWithAd()</code> and <code>DecryptWithAd()</code> on the relevant <code>CipherState</code> with zero-length associated data.</p>
+<p>The below sections describe these objects in detail.</p>
+<h2 id="the-cipherstate-object">5.1 The <code>CipherState</code> object</h2>
+<p>A <code>CipherState</code> can encrypt and decrypt data based on its <code>k</code> and <code>n</code> variables:</p>
+<ul>
+<li><p><strong><code>k</code></strong>: A cipher key of 32 bytes (which may be <code>empty</code>). <code>Empty</code> is a special value which indicates <code>k</code> has not yet been initialized.</p></li>
+<li><p><strong><code>n</code></strong>: An 8-byte (64-bit) unsigned integer nonce.</p></li>
+</ul>
+<p>A <code>CipherState</code> responds to the following methods. The <code>++</code> post-increment operator applied to <code>n</code> means &quot;use the current <code>n</code> value, then increment it&quot;. The maximum <code>n</code> value (2^64-1) is reserved for future use and must not be used. If incrementing <code>n</code> results in 2^64-1 (the maximum value), then any further <code>EncryptWithAd()</code> or <code>DecryptWithAd()</code> calls will signal an error to the caller.</p>
+<ul>
+<li><p><strong><code>InitializeKey(key)</code></strong>: Sets <code>k = key</code>. Sets <code>n = 0</code>.</p></li>
+<li><p><strong><code>HasKey()</code></strong>: Returns true if <code>k</code> is non-empty, false otherwise.</p></li>
+<li><p><strong><code>EncryptWithAd(ad, plaintext)</code></strong>: If <code>k</code> is non-empty returns <code>ENCRYPT(k, n++, ad, plaintext)</code>. Otherwise returns <code>plaintext</code>.</p></li>
+<li><p><strong><code>DecryptWithAd(ad, ciphertext)</code></strong>: If <code>k</code> is non-empty returns <code>DECRYPT(k, n++, ad, ciphertext)</code>. Otherwise returns <code>ciphertext</code>. If an authentication failure occurs in <code>DECRYPT()</code> the error is signaled to the caller.</p></li>
+</ul>
+<h2 id="the-symmetricstate-object">5.2. The <code>SymmetricState</code> object</h2>
+<p>A <code>SymmetricState</code> object contains a <code>CipherState</code> plus the following variables:</p>
+<ul>
+<li><strong><code>ck</code></strong>: A chaining key of <code>HASHLEN</code> bytes.</li>
+<li><strong><code>h</code></strong>: A hash output of <code>HASHLEN</code> bytes.</li>
+</ul>
+<p>A <code>SymmetricState</code> responds to the following methods:</p>
+<ul>
+<li><p><strong><code>InitializeSymmetric(protocol_name)</code></strong>: Takes an arbitrary-length <code>protocol_name</code> byte sequence (see <a href="#protocol-names">Section 11</a>). Executes the following steps:</p>
+<ul>
+<li><p>If <code>protocol_name</code> is less than or equal to <code>HASHLEN</code> bytes in length, sets <code>h</code> equal to <code>protocol_name</code> with zero bytes appended to make <code>HASHLEN</code> bytes. Otherwise sets <code>h = HASH(protocol_name)</code>.</p></li>
+<li><p>Sets <code>ck = h</code>.</p></li>
+<li><p>Calls <code>InitializeKey(empty)</code>.</p></li>
+</ul></li>
+<li><p><strong><code>MixKey(input_key_material)</code></strong>: Sets <code>ck, temp_k = HKDF(ck, input_key_material)</code>. If <code>HASHLEN</code> is 64, then truncates <code>temp_k</code> to 32 bytes. Calls <code>InitializeKey(temp_k)</code>.</p></li>
+<li><p><strong><code>MixHash(data)</code></strong>: Sets <code>h = HASH(h || data)</code>.</p></li>
+<li><p><strong><code>EncryptAndHash(plaintext)</code></strong>: Sets <code>ciphertext = EncryptWithAd(h, plaintext)</code>, calls <code>MixHash(ciphertext)</code>, and returns <code>ciphertext</code>. Note that if <code>k</code> is <code>empty</code>, the <code>EncryptWithAd()</code> call will set <code>ciphertext</code> equal to <code>plaintext</code>.</p></li>
+<li><p><strong><code>DecryptAndHash(ciphertext)</code></strong>: Sets <code>plaintext = DecryptWithAd(h, ciphertext)</code>, calls <code>MixHash(ciphertext)</code>, and returns <code>plaintext</code>. Note that if <code>k</code> is <code>empty</code>, the <code>DecryptWithAd()</code> call will set <code>plaintext</code> equal to <code>ciphertext</code>.</p></li>
+<li><strong><code>Split()</code></strong>: Returns a pair of <code>CipherState</code> objects for encrypting transport messages. Executes the following steps, where <code>zerolen</code> is a zero-length byte sequence:
+<ul>
+<li>Sets <code>temp_k1, temp_k2 = HKDF(ck, zerolen)</code>.</li>
+<li>If <code>HASHLEN</code> is 64, then truncates <code>temp_k1</code> and <code>temp_k2</code> to 32 bytes.</li>
+<li>Creates two new <code>CipherState</code> objects <code>c1</code> and <code>c2</code>.</li>
+<li>Calls <code>c1.InitializeKey(temp_k1)</code> and <code>c2.InitializeKey(temp_k2)</code>.</li>
+<li>Returns the pair <code>(c1, c2)</code>.</li>
+</ul></li>
+</ul>
+<h2 id="the-handshakestate-object">5.3. The <code>HandshakeState</code> object</h2>
+<p>A <code>HandshakeState</code> object contains a <code>SymmetricState</code> plus the following variables, any of which may be <code>empty</code>. <code>Empty</code> is a special value which indicates the variable has not yet been initialized.</p>
+<ul>
+<li><strong><code>s</code></strong>: The local static key pair</li>
+<li><strong><code>e</code></strong>: The local ephemeral key pair</li>
+<li><strong><code>rs</code></strong>: The remote party's static public key</li>
+<li><strong><code>re</code></strong>: The remote party's ephemeral public key</li>
+</ul>
+<p>A <code>HandshakeState</code> also has variables to track its role, and the remaining portion of the handshake pattern:</p>
+<ul>
+<li><p><strong><code>initiator</code></strong>: A boolean indicating the initiator or responder role.</p></li>
+<li><p><strong><code>message_patterns</code></strong>: A sequence of message patterns. Each message pattern is a sequence of tokens from the set <code>(&quot;s&quot;, &quot;e&quot;, &quot;ee&quot;, &quot;es&quot;, &quot;se&quot;, &quot;ss&quot;)</code>.</p></li>
+</ul>
+<p>A <code>HandshakeState</code> responds to the following methods:</p>
+<ul>
+<li><p><strong><code>Initialize(handshake_pattern, initiator, prologue, s, e, rs, re)</code></strong>: Takes a valid <code>handshake_pattern</code> (see <a href="#handshake-patterns">Section 8</a>) and an <code>initiator</code> boolean specifying this party's role as either initiator or responder.</p>
+<p>Takes a <code>prologue</code> byte sequence which may be zero-length, or which may contain context information that both parties want to confirm is identical (see <a href="#prologue">Section 6</a>).</p>
+<p>Takes a set of DH key pairs <code>(s, e)</code> and public keys <code>(rs, re)</code> for initializing local variables, any of which may be empty. Public keys are only passed in if the <code>handshake_pattern</code> uses pre-messages (see <a href="#handshake-patterns">Section 8</a>). The ephemeral values <code>(e, re)</code> are typically left empty, since they are created and exchanged during the handshake; but there are exceptions (see <a href="compound-protocols-and-noise-pipes">Section 9.2</a>).</p>
+<ul>
+<li><p>Derives a <code>protocol_name</code> byte sequence by combining the names for the handshake pattern and crypto functions, as specified in <a href="#protocol-names">Section 11</a>. Calls <code>InitializeSymmetric(protocol_name)</code>.</p></li>
+<li><p>Calls <code>MixHash(prologue)</code>.</p></li>
+<li><p>Sets the <code>initiator</code>, <code>s</code>, <code>e</code>, <code>rs</code>, and <code>re</code> variables to the corresponding arguments.</p></li>
+<li><p>Calls <code>MixHash()</code> once for each public key listed in the pre-messages from <code>handshake_pattern</code>, with the specified public key as input (see <a href="#handshake-patterns">Section 8</a> for an explanation of pre-messages). If both initiator and responder have pre-messages, the initiator's public keys are hashed first.</p></li>
+<li><p>Sets <code>message_patterns</code> to the message patterns from <code>handshake_pattern</code>.</p></li>
+</ul></li>
+<li><p><strong><code>WriteMessage(payload, message_buffer)</code></strong>: Takes a <code>payload</code> byte sequence which may be zero-length, and a <code>message_buffer</code> to write the output into.</p>
+<ul>
+<li><p>Fetches and deletes the next message pattern from <code>message_patterns</code>, then sequentially processes each token from the message pattern:</p>
+<ul>
+<li><p>For <code>&quot;e&quot;</code>: Sets <code>e = GENERATE_KEYPAIR()</code>, overwriting any previous value for <code>e</code>. Appends <code>e.public_key</code> to the buffer. Calls <code>MixHash(e.public_key)</code>.</p></li>
+<li><p>For <code>&quot;s&quot;</code>: Appends <code>EncryptAndHash(s.public_key)</code> to the buffer.</p></li>
+<li><p>For <code>&quot;xy&quot;</code>: Calls <code>MixKey(DH(x, ry))</code> if <code>initiator</code>, otherwise <code>MixKey(DH(y, rx))</code>.</p></li>
+</ul></li>
+<li><p>Appends <code>EncryptAndHash(payload)</code> to the buffer.</p></li>
+<li><p>If there are no more message patterns returns two new <code>CipherState</code> objects by calling <code>Split()</code>.</p></li>
+</ul></li>
+<li><p><strong><code>ReadMessage(message, payload_buffer)</code></strong>: Takes a byte sequence containing a Noise handshake message, and a <code>payload_buffer</code> to write the message's plaintext payload into.</p>
+<ul>
+<li><p>Fetches and deletes the next message pattern from <code>message_patterns</code>, then sequentially processes each token from the message pattern:</p>
+<ul>
+<li><p>For <code>&quot;e&quot;</code>: Sets <code>re</code> to the next <code>DHLEN</code> bytes from the message, overwriting any previous value for <code>re</code>. Calls <code>MixHash(re.public_key)</code>.</p></li>
+<li><p>For <code>&quot;s&quot;</code>: Sets <code>temp</code> to the next <code>DHLEN + 16</code> bytes of the message if <code>HasKey() == True</code>, or to the next <code>DHLEN</code> bytes otherwise. Sets <code>rs</code> to <code>DecryptAndHash(temp)</code>.</p></li>
+<li><p>For <code>&quot;xy&quot;</code>: Calls <code>MixKey(DH(x, ry))</code> if <code>initiator</code>, otherwise <code>MixKey(DH(y, rx))</code>.</p></li>
+</ul></li>
+<li><p>Calls <code>DecryptAndHash()</code> on the remaining bytes of the message and stores the output into <code>payload_buffer</code>.</p></li>
+<li><p>If there are no more message patterns returns two new <code>CipherState</code> objects by calling <code>Split()</code>.</p></li>
+</ul></li>
+</ul>
+<h1 id="prologue">6. Prologue</h1>
+<p>Noise protocols have a <strong>prologue</strong> input which allows arbitrary data to be hashed into the <code>h</code> variable. If both parties do not provide identical prologue data, the handshake will fail due to a decryption error. This is useful when the parties engaged in negotiation prior to the handshake and want to ensure they share identical views of that negotiation.</p>
+<p>For example, suppose Bob communicates to Alice a list of Noise protocols that he is willing to support. Alice will then choose and execute a single protocol. To ensure that a &quot;man-in-the-middle&quot; did not edit Bob's list to remove options, Alice and Bob could include the list as prologue data.</p>
+<p>Note that while the parties confirm their prologues are identical, they don't mix prologue data into encryption keys. If an input contains secret data that's intended to strengthen the encryption, a &quot;PSK&quot; handshake should be used instead (see next section).</p>
+<h1 id="pre-shared-symmetric-keys">7. Pre-shared symmetric keys</h1>
+<p>Noise provides an optional <strong>pre-shared symmetric key</strong> or <strong>PSK</strong> mode to support protocols where both parties already have a shared secret key. When using pre-shared symmetric keys, the following changes are made:</p>
+<ul>
+<li><p>Protocol names (<a href="#protocol-names">Section 11</a>) use the prefix <code>&quot;NoisePSK_&quot;</code> instead of <code>&quot;Noise_&quot;</code>.</p></li>
+<li><p><code>Initialize()</code> takes an additional <code>psk</code> argument, which is a sequence of 32 bytes. Immediately after <code>MixHash(prologue)</code> it sets <code>ck, temp = HKDF(ck, psk)</code>, then calls <code>MixHash(temp)</code>. This mixes the pre-shared key into the chaining key, and also mixes a one-way function of the pre-shared key into the <code>h</code> value to ensure that <code>h</code> is a function of all handshake inputs.</p></li>
+<li><p><code>WriteMessage()</code> and <code>ReadMessage()</code> are modified when processing the <code>&quot;e&quot;</code> token to call <code>MixKey(e.public_key)</code> as the final step. Because the initial messages in a handshake pattern are required to start with <code>&quot;e&quot;</code> (<a href="#pattern-validity">Section 8.1</a>), this ensures <code>k</code> is initialized from the pre-shared key. This also uses the ephemeral public key's value as a random nonce to prevent re-using the same <code>k</code> and <code>n</code> for different messages.</p></li>
+<li><p><code>Initialize()</code> is modified when processing an <code>&quot;e&quot;</code> pre-message token in a &quot;dependent&quot; handshake pattern (see <a href="#pattern-validity">Section 8.1</a>) to call <code>MixKey()</code> on the ephemeral public key immediately after calling <code>MixHash()</code> on it. This accomplishes the same randomization as the previous bullet, but needs to be applied to pre-messages for dependent patterns.</p></li>
+</ul>
+<h1 id="handshake-patterns">8. Handshake patterns</h1>
+<p>A <strong>message pattern</strong> is some sequence of tokens from the set <code>(&quot;e&quot;, &quot;s&quot;, &quot;ee&quot;, &quot;es&quot;, &quot;se&quot;, &quot;ss&quot;)</code>.</p>
+<p>A <strong>handshake pattern</strong> consists of:</p>
+<ul>
+<li>A pattern for the initiator's <strong>pre-message</strong> that is either:
+<ul>
+<li><code>&quot;e&quot;</code></li>
+<li><code>&quot;s&quot;</code></li>
+<li><code>&quot;e, s&quot;</code></li>
+<li>empty</li>
+</ul></li>
+<li><p>A pattern for the responder's pre-message that takes the same range of values as the initiator's pre-message.</p></li>
+<li><p>A sequence of message patterns for the actual handshake messages</p></li>
+</ul>
+<p>The pre-messages represent an exchange of public keys that was somehow performed prior to the handshake, so these public keys must be inputs to <code>Initialize()</code> for the &quot;recipient&quot; of the pre-message.</p>
+<p>The first actual handshake message is sent from the initiator to the responder, the next is sent by the responder, the next from the initiator, and so on in alternating fashion.</p>
+<p>The following handshake pattern describes an unauthenticated DH handshake:</p>
+<pre><code>Noise_NN():
+ -&gt; e
+ &lt;- e, ee</code></pre>
+<p>The handshake pattern name is <code>Noise_NN</code>. This naming convention will be explained in <a href="#interactive-patterns">Section 8.3</a>. The empty parentheses indicate that neither party is initialized with any key pairs. The tokens <code>&quot;s&quot;</code> and/or <code>&quot;e&quot;</code> inside the parentheses would indicate that the initiator is initialized with static and/or ephemeral key pairs. The tokens <code>&quot;rs&quot;</code> and/or <code>&quot;re&quot;</code> would indicate the same thing for the responder.</p>
+<p>Pre-messages are shown as patterns prior to the delimiter &quot;...&quot;, with a right-pointing arrow for the initiator's pre-message, and a left-pointing arrow for the responder's pre-message. If both parties have a pre-message, the initiator's is listed first (and hashed first). During <code>Initialize()</code>, <code>MixHash()</code> is called on any pre-message public keys, as described in <a href="#the-handshakestate-object">Section 5.3</a>.</p>
+<p>The following pattern describes a handshake where the initiator has pre-knowledge of the responder's static public key, and performs a DH with the responder's static public key as well as the responder's ephemeral public key. This pre-knowledge allows an encrypted payload to be sent in the first message, although full forward secrecy and replay protection is only achieved with the second message.</p>
+<pre><code>Noise_NK(rs):
+ &lt;- s
+ ...
+ -&gt; e, es
+ &lt;- e, ee</code></pre>
+<h2 id="pattern-validity">8.1. Pattern validity</h2>
+<p>Handshake patterns must be <strong>valid</strong> in the following senses:</p>
+<ol style="list-style-type: decimal">
+<li><p>Parties can only send a static public key if they were initialized with a static key pair, and can only perform DH between private keys and public keys they possess.</p></li>
+<li><p>Parties must not send their static public key, or an ephemeral public key, more than once per handshake (i.e. ignoring the pre-messages, there must be no more than one occurrence of &quot;e&quot;, and one occurrence of &quot;s&quot;, in the messages sent by any party).</p></li>
+<li><p>Parties must send an ephemeral public key at the start of the first message they send (i.e. the first token of the first message pattern in each direction must be <code>&quot;e&quot;</code>). To support &quot;compound protocols&quot; (see <a href="#compound-protocols-and-noise-pipes">Section 9.2</a>) an exception is allowed if the party's ephemeral public key was used as a &quot;pre-message&quot;. A handshake pattern that relies on this exception is a <strong>dependent pattern</strong>, and can only be used according to the rules in <a href="#compound-protocols-and-noise-pipes">Section 9.2</a>.</p></li>
+<li><p>After performing a DH between a remote public key and any local private key that is not an ephemeral private key, the local party must not send any encrypted data unless they have also performed a DH between an ephemeral private key and the remote public key.</p></li>
+</ol>
+<p>Patterns failing the first check are obviously nonsense.</p>
+<p>The second check outlaws redundant transmission of values to simplify implementation and testing.</p>
+<p>The third and fourth checks are necessary because Noise uses DH outputs involving ephemeral keys to randomize the shared secret keys. Noise also uses ephemeral public keys to randomize PSK-based encryption. Patterns failing these checks could result in subtle but catastrophic security flaws.</p>
+<p>Users are recommended to only use the handshake patterns listed below, or other patterns that have been vetted by experts to satisfy the above checks.</p>
+<h2 id="one-way-patterns">8.2. One-way patterns</h2>
+<p>The following example handshake patterns represent &quot;one-way&quot; handshakes supporting a one-way stream of data from a sender to a recipient. These patterns could be used to encrypt files, database records, or other non-interactive data streams.</p>
+<p>Following a one-way handshake the sender can send a stream of transport messages, encrypting them using the first <code>CipherState</code> returned by <code>Split()</code>. The second <code>CipherState</code> from <code>Split()</code> is discarded - the recipient must not send any messages using it (as this would violate the rules in <a href="#pattern-validity">Section 8.1</a>).</p>
+<p>One-way patterns are named with a single character, which indicates the status of the sender's static key:</p>
+<ul>
+<li><strong><code>N</code></strong> = <strong><code>N</code></strong>o static key for sender</li>
+<li><strong><code>K</code></strong> = Static key for sender <strong><code>K</code></strong>nown to recipient</li>
+<li><strong><code>X</code></strong> = Static key for sender <strong><code>X</code></strong>mitted (&quot;transmitted&quot;) to recipient</li>
+</ul>
+<table style="width:36%;">
+<colgroup>
+<col width="36%" />
+</colgroup>
+<tbody>
+<tr class="odd">
+<td><pre><code>Noise_N(rs):
+ &lt;- s
+ ...
+ -&gt; e, es</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_K(s, rs):
+ -&gt; s
+ &lt;- s
+ ...
+ -&gt; e, es, ss</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_X(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, es, s, ss</code></pre></td>
+</tr>
+</tbody>
+</table>
+<p><code>Noise_N</code> is a conventional DH-based public-key encryption. The other patterns add sender authentication, where the sender's public key is either known to the recipient beforehand (<code>Noise_K</code>) or transmitted under encryption (<code>Noise_X</code>).</p>
+<h2 id="interactive-patterns">8.3. Interactive patterns</h2>
+<p>The following example handshake patterns represent interactive protocols.</p>
+<p>Interactive patterns are named with two characters, which indicate the status of the initator and responder's static keys:</p>
+<p>The first character refers to the initiator's static key:</p>
+<ul>
+<li><strong><code>N</code></strong> = <strong><code>N</code></strong>o static key for initiator</li>
+<li><strong><code>K</code></strong> = Static key for initiator <strong><code>K</code></strong>nown to responder</li>
+<li><strong><code>X</code></strong> = Static key for initiator <strong><code>X</code></strong>mitted (&quot;transmitted&quot;) to responder</li>
+<li><strong><code>I</code></strong> = Static key for initiator <strong><code>I</code></strong>mmediately transmitted to responder, despite reduced or absent identity hiding</li>
+</ul>
+<p>The second character refers to the responder's static key:</p>
+<ul>
+<li><strong><code>N</code></strong> = <strong><code>N</code></strong>o static key for responder</li>
+<li><strong><code>K</code></strong> = Static key for responder <strong><code>K</code></strong>nown to responder</li>
+<li><strong><code>X</code></strong> = Static key for responder <strong><code>X</code></strong>mitted (&quot;transmitted&quot;) to initiator</li>
+</ul>
+<table style="width:85%;">
+<colgroup>
+<col width="38%" />
+<col width="45%" />
+</colgroup>
+<tbody>
+<tr class="odd">
+<td><pre><code>Noise_NN():
+ -&gt; e
+ &lt;- e, ee</code></pre></td>
+<td><pre><code> Noise_KN(s):
+ -&gt; s
+ ...
+ -&gt; e
+ &lt;- e, ee, se</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_NK(rs):
+ &lt;- s
+ ...
+ -&gt; e, es
+ &lt;- e, ee</code></pre></td>
+<td><pre><code> Noise_KK(s, rs):
+ -&gt; s
+ &lt;- s
+ ...
+ -&gt; e, es, ss
+ &lt;- e, ee, se</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code> Noise_NX(rs):
+ -&gt; e
+ &lt;- e, ee, s, es</code></pre></td>
+<td><pre><code> Noise_KX(s, rs):
+ -&gt; s
+ ...
+ -&gt; e
+ &lt;- e, ee, se, s, es</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code> Noise_XN(s):
+ -&gt; e
+ &lt;- e, ee
+ -&gt; s, se</code></pre></td>
+<td><pre><code> Noise_IN(s):
+ -&gt; e, s
+ &lt;- e, ee, se</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code> Noise_XK(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, es
+ &lt;- e, ee
+ -&gt; s, se</code></pre></td>
+<td><pre><code> Noise_IK(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, es, s, ss
+ &lt;- e, ee, se</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code> Noise_XX(s, rs):
+ -&gt; e
+ &lt;- e, ee, s, es
+ -&gt; s, se</code></pre></td>
+<td><pre><code> Noise_IX(s, rs):
+ -&gt; e, s
+ &lt;- e, ee, se, s, es</code></pre></td>
+</tr>
+</tbody>
+</table>
+<p>The <code>Noise_XX</code> pattern is the most generically useful, since it is efficient and supports mutual authentication and transmission of static public keys.</p>
+<p>All interactive patterns allow some encryption of handshake payloads:</p>
+<ul>
+<li><p>Patterns where the initiator has pre-knowledge of the responder's static public key (i.e. patterns ending in <code>&quot;K&quot;</code>) allow &quot;zero-RTT&quot; encryption, meaning the initiator can encrypt the first handshake payload.</p></li>
+<li><p>All interactive patterns allow &quot;half-RTT&quot; encryption of the first response payload, but the encryption only targets an initiator static public key in patterns starting with &quot;K&quot; or &quot;I&quot;.</p></li>
+</ul>
+<p>The security properties for handshake payloads are usually weaker than the final security properties achieved by transport payloads, so these early encryptions must be used with caution.</p>
+<p>In some patterns the security properties of transport payloads can also vary. In particular: patterns starting with &quot;K&quot; or &quot;I&quot; have the caveat that the responder is only guaranteed &quot;weak&quot; forward secrecy for the transport messages it sends until it receives a transport message from the initiator. After receiving a transport message from the initiator, the responder becomes assured of &quot;strong&quot; forward secrecy.</p>
+<p>The next section provides more analysis of these payload security properties.</p>
+<h2 id="payload-security-properties">8.4. Payload security properties</h2>
+<p>The following table lists the security properties for Noise handshake and transport payloads for all the named patterns in <a href="#one-way-patterns">Section 8.2</a> and <a href="#interactive-patterns">Section 8.3</a>. Each payload is assigned an &quot;authentication&quot; property regarding the degree of authentication of the sender provided to the recipient, and a &quot;confidentiality&quot; property regarding the degree of confidentiality provided to the sender.</p>
+<p>The authentication properties are:</p>
+<ol start="0" style="list-style-type: decimal">
+<li><p><strong>No authentication.</strong> This payload may have been sent by any party, including an active attacker.</p></li>
+<li><p><strong>Sender authentication <em>vulnerable</em> to key-compromise impersonation (KCI)</strong>. The sender authentication is based on a static-static DH (<code>&quot;ss&quot;</code>) involving both parties' static key pairs. If the recipient's long-term private key has been compromised, this authentication can be forged. Note that a future version of Noise might include signatures, which could improve this security property, but brings other trade-offs.</p></li>
+<li><p><strong>Sender authentication <em>resistant</em> to key-compromise impersonation (KCI)</strong>. The sender authentication is based on an ephemeral-static DH (<code>&quot;es&quot;</code> or <code>&quot;se&quot;</code>) between the sender's static key pair and the recipient's ephemeral key pair. Assuming the corresponding private keys are secure, this authentication cannot be forged.</p></li>
+</ol>
+<p>The confidentiality properties are:</p>
+<ol start="0" style="list-style-type: decimal">
+<li><p><strong>No confidentiality.</strong> This payload is sent in cleartext.</p></li>
+<li><p><strong>Encryption to an ephemeral recipient.</strong> This payload has forward secrecy, since encryption involves an ephemeral-ephemeral DH (<code>&quot;ee&quot;</code>). However, the sender has not authenticated the recipient, so this payload might be sent to any party, including an active attacker.</p></li>
+<li><p><strong>Encryption to a known recipient, forward secrecy for sender compromise only, vulnerable to replay.</strong> This payload is encrypted based only on DHs involving the recipient's static key pair. If the recipient's static private key is compromised, even at a later date, this payload can be decrypted. This message can also be replayed, since there's no ephemeral contribution from the recipient.</p></li>
+<li><p><strong>Encryption to a known recipient, weak forward secrecy.</strong> This payload is encrypted based on an ephemeral-ephemeral DH and also an ephemeral-static DH involving the recipient's static key pair. However, the binding between the recipient's alleged ephemeral public key and the recipient's static public key hasn't been verified by the sender, so the recipient's alleged ephemeral public key may have been forged by an active attacker. In this case, the attacker could later compromise the recipient's static private key to decrypt the payload. Note that a future version of Noise might include signatures, which could improve this security property, but brings other trade-offs.</p></li>
+<li><p><strong>Encryption to a known recipient, weak forward secrecy if the sender's private key has been compromised.</strong> This payload is encrypted based on an ephemeral-ephemeral DH, and also based on an ephemeral-static DH involving the recipient's static key pair. However, the binding between the recipient's alleged ephemeral public and the recipient's static public key has only been verified based on DHs involving both those public keys and the sender's static private key. Thus, if the sender's static private key was previously compromised, the recipient's alleged ephemeral public key may have been forged by an active attacker. In this case, the attacker could later compromise the intended recipient's static private key to decrypt the payload (this is a variant of a &quot;KCI&quot; attack enabling a &quot;weak forward secrecy&quot; attack). Note that a future version of Noise might include signatures, which could improve this security property, but brings other trade-offs.</p></li>
+<li><p><strong>Encryption to a known recipient, strong forward secrecy.</strong> This payload is encrypted based on an ephemeral-ephemeral DH as well as an ephemeral-static DH with the recipient's static key pair. Assuming the ephemeral private keys are secure, and the recipient is not being actively impersonated by an attacker that has stolen its static private key, this payload cannot be decrypted.</p></li>
+</ol>
+<p>For one-way handshakes, the below-listed security properties apply to the handshake payload as well as transport payloads.</p>
+<p>For interactive handshakes, security properties are listed for each handshake payload. Transport payloads are listed as arrows without a pattern. Transport payloads are only listed if they have different security properties than the previous handshake payload sent from the same party. If two transport payloads are listed, the security properties for the second only apply if the first was received.</p>
+<table style="width:88%;">
+<colgroup>
+<col width="87%" />
+</colgroup>
+<tbody>
+<tr class="odd">
+<td><pre><code> Authentication Confidentiality</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_N 0 2</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_K 1 2</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_X 1 2</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_NN
+ -&gt; e 0 0
+ &lt;- e, ee 0 1
+ -&gt; 0 1</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_NK
+ &lt;- s
+ ...
+ -&gt; e, es 0 2
+ &lt;- e, ee 2 1
+ -&gt; 0 5</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_NX
+ -&gt; e 0 0
+ &lt;- e, ee, s, es 2 1
+ -&gt; 0 5</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_XN
+ -&gt; e 0 0
+ &lt;- e, ee 0 1
+ -&gt; s, se 2 1
+ &lt;- 0 5</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_XK
+ &lt;- s
+ ...
+ -&gt; e, es 0 2
+ &lt;- e, ee 2 1
+ -&gt; s, se 2 5
+ &lt;- 2 5</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_XX
+ -&gt; e 0 0
+ &lt;- e, ee, s, es 2 1
+ -&gt; s, se 2 5
+ &lt;- 2 5</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_KN
+ -&gt; s
+ ...
+ -&gt; e 0 0
+ &lt;- e, ee, se 0 3
+ -&gt; 2 1
+ &lt;- 0 5</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_KK
+ -&gt; s
+ &lt;- s
+ ...
+ -&gt; e, es, ss 1 2
+ &lt;- e, ee, se 2 4
+ -&gt; 2 5
+ &lt;- 2 5</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_KX
+ -&gt; s
+ ...
+ -&gt; e 0 0
+ &lt;- e, ee, se, s, es 2 3
+ -&gt; 2 5
+ &lt;- 2 5</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_IN
+ -&gt; e, s 0 0
+ &lt;- e, ee, se 0 3
+ -&gt; 2 1
+ &lt;- 0 5</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_IK
+ &lt;- s
+ ...
+ -&gt; e, es, s, ss 1 2
+ &lt;- e, ee, se 2 4
+ -&gt; 2 5
+ &lt;- 2 5</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_IX
+ -&gt; e, s 0 0
+ &lt;- e, ee, se, s, es 2 3
+ -&gt; 2 5
+ &lt;- 2 5</code></pre></td>
+</tr>
+</tbody>
+</table>
+<h2 id="identity-hiding">8.5. Identity hiding</h2>
+<p>The following table lists the identity hiding properties for all the named patterns in <a href="#one-way-patterns">Section 8.2</a> and <a href="#interactive-patterns">Section 8.3</a>. Each pattern is assigned properties describing the confidentiality supplied to the initiator's static public key, and to the responder's static public key. The underlying assumptions are that ephemeral private keys are secure, and that parties abort the handshake if they receive a static public key from the other party which they don't trust.</p>
+<p>This section only considers identity leakage through static public key fields in handshakes. Of course, the identities of Noise participants might be exposed through other means, including payload fields, traffic analysis, or metadata such as IP addresses.</p>
+<p>The properties for the relevant public key are:</p>
+<ol start="0" style="list-style-type: decimal">
+<li><p>Transmitted in clear.</p></li>
+<li><p>Encrypted with forward secrecy, but can be probed by an anonymous initiator.</p></li>
+<li><p>Encrypted with forward secrecy, but sent to an anonymous responder.</p></li>
+<li><p>Not transmitted, but a passive attacker can check candidates for the responder's private key and determine whether the candidate is correct.</p></li>
+<li><p>Encrypted to responder's static public key, without forward secrecy. If an attacker learns the responder's private key they can decrypt the initiator's public key.</p></li>
+<li><p>Not transmitted, but a passive attacker can check candidates for the responder's private key and initiator's public key and determine if both candidates are correct.</p></li>
+<li><p>Encrypted but with weak forward secrecy. An active attacker who pretends to be the initiator without the initiator's static private key, then later learns the initiator private key, can then decrypt the responder's public key.</p></li>
+<li><p>Not transmitted, but an active attacker who pretends to be the initator without the initiator's static private key, then later learns a candidate for the initiator private key, can then check whether the candidate is correct.</p></li>
+<li><p>Encrypted with forward secrecy to an authenticated party.</p></li>
+</ol>
+<!-- end of list - necesary to trick Markdown into seeing the following -->
+<table style="width:60%;">
+<colgroup>
+<col width="59%" />
+</colgroup>
+<tbody>
+<tr class="odd">
+<td><pre><code> Initiator Responder</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_N - 3</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_K 5 5</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_X 4 3</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_NN - -</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_NK - 3</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_NX - 1</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_XN 2 -</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_XK 8 3</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_XX 8 1</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_KN 7 -</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_KK 5 5</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_KX 7 6</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_IN 0 -</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_IK 4 3</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_IX 0 6</code></pre></td>
+</tr>
+</tbody>
+</table>
+<h2 id="more-patterns">8.6. More patterns</h2>
+<p>The patterns in the previous sections are the best option for most scenarios.</p>
+<p>However, to construct new patterns we can apply some <strong>transformation</strong> to an existing pattern, and name the resulting pattern by appending the transformation name to the existing pattern's name.</p>
+<p>For example, if you don't care about identity hiding, you could apply a &quot;noidh&quot; transformation which moves static public keys earlier in messages, so they are sent in cleartext where possible. This transforms the patterns from the left column to the right column:</p>
+<table style="width:89%;">
+<colgroup>
+<col width="44%" />
+<col width="44%" />
+</colgroup>
+<tbody>
+<tr class="odd">
+<td><pre><code>Noise_X(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, es, s, ss</code></pre></td>
+<td><pre><code> Noise_Xnoidh(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, s, es, ss</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_NX(rs):
+ -&gt; e
+ &lt;- e, ee, s, es</code></pre></td>
+<td><pre><code> Noise_NXnoidh(rs):
+ -&gt; e
+ &lt;- e, s, ee, es</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_XX(s, rs):
+ -&gt; e
+ &lt;- e, ee, s, es
+ -&gt; s, se</code></pre></td>
+<td><pre><code> Noise_XXnoidh(s, rs):
+ -&gt; e
+ &lt;- e, s, ee, es
+ -&gt; s, se</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_KX(s, rs):
+ -&gt; s
+ ...
+ -&gt; e
+ &lt;- e, ee, se, s, es</code></pre></td>
+<td><pre><code> Noise_KXnoidh(s, rs):
+ -&gt; s
+ ...
+ -&gt; e
+ &lt;- e, s, ee, se, es</code></pre></td>
+</tr>
+<tr class="odd">
+<td><pre><code>Noise_IK(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, es, s, ss
+ &lt;- e, ee, se</code></pre></td>
+<td><pre><code> Noise_IKnoidh(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, s, es, ss
+ &lt;- e, ee, se</code></pre></td>
+</tr>
+<tr class="even">
+<td><pre><code>Noise_IX(s, rs):
+ -&gt; e, s
+ &lt;- e, ee, se, s, es</code></pre></td>
+<td><pre><code> Noise_IXnoidh(s, rs):
+ -&gt; e, s
+ &lt;- e, s, ee, se, es</code></pre></td>
+</tr>
+</tbody>
+</table>
+<p>Other tranformations might add or remove <code>&quot;ss&quot;</code> operations, or defer DH operations until later.</p>
+<h1 id="advanced-uses">9. Advanced uses</h1>
+<h2 id="dummy-static-public-keys">9.1. Dummy static public keys</h2>
+<p>Consider a protocol where an initiator will authenticate herself if the responder requests it. This could be viewed as the initiator choosing between patterns like <code>Noise_NX</code> and <code>Noise_XX</code> based on some value inside the responder's first handshake payload.</p>
+<p>Noise doesn't directly support this. Instead, this could be simulated by always executing <code>Noise_XX</code>. The initiator can simulate the <code>Noise_NX</code> case by sending a <strong>dummy static public key</strong> if authentication is not requested. The value of the dummy public key doesn't matter. For efficiency, the initiator can send a null public key value per <a href="#crypto-functions">Section 4</a> (e.g. an all-zeros <code>25519</code> value that is guaranteed to produce an all-zeros output).</p>
+<p>This technique is simple, since it allows use of a single handshake pattern. It also doesn't reveal which option was chosen from message sizes. It could be extended to allow a <code>Noise_XX</code> pattern to support any permutation of authentications (initiator only, responder only, both, or none).</p>
+<h2 id="compound-protocols-and-noise-pipes">9.2. Compound protocols and &quot;Noise Pipes&quot;</h2>
+<p>Consider a protocol where the initiator can attempt zero-RTT encryption based on the responder's static public key. If the responder has changed his static public key, the parties will need to switch to a &quot;fallback&quot; handshake where the responder transmits the new static public key and the initiator resends the zero-RTT data.</p>
+<p>This can be handled by both parties re-initializing their <code>HandshakeState</code> and executing a different handshake. Using handshake re-initialization to switch from one &quot;simple&quot; Noise protocol to another results in a <strong>compound protocol</strong>.</p>
+<p>Public keys that were exchanged in the first handshake can be represented as pre-messages in the second handshake. If an ephemeral public key was sent in the first handshake and used as a pre-message in the second handshake, that party can avoid sending a new ephemeral by using a &quot;dependent&quot; pattern (see <a href="pattern-validity">Section 8.1</a>).</p>
+<p>Re-initializing with a dependent pattern is only allowed if the new handshake and old handshake have different protocol names (see <a href="#protocol-names">Section 11</a>) and the rules for handling PSKs are followed (see <a href="#pre-shared-symmetric-keys">Section 7</a>).</p>
+<p>If any negotiation occurred in the first handshake, the first handshake's <code>h</code> variable should be provided as prologue to the second handshake.</p>
+<p>By way of example, this section defines the <strong>Noise Pipe</strong> compound protocol. This protocol uses three handshake patterns - two defined in the previous section, and a new one:</p>
+<ul>
+<li><p><code>Noise_XX</code> is used for an initial <strong>full handshake</strong> if the parties haven't communicated before, after which the initiator can cache the responder's static public key.</p></li>
+<li><p><code>Noise_IK</code> is used for a zero-RTT <strong>abbreviated handshake</strong>.</p></li>
+<li><p>If the responder fails to decrypt the first <code>Noise_IK</code> message (perhaps due to changing his static key), the responder will initiate a new <strong>fallback handshake</strong> using the <code>Noise_XXfallback</code> pattern which is identical to <code>Noise_XX</code> except re-using the ephemeral public key from the first <code>Noise_IK</code> message as a pre-message public key (thus is a &quot;dependent&quot; pattern).</p></li>
+</ul>
+<p>Below are the three patterns used for Noise Pipes:</p>
+<pre><code>Noise_XX(s, rs):
+ -&gt; e
+ &lt;- e, ee, s, es
+ -&gt; s, se
+
+Noise_IK(s, rs):
+ &lt;- s
+ ...
+ -&gt; e, es, s, ss
+ &lt;- e, ee, se
+
+Noise_XXfallback(s, rs, re):
+ &lt;- e
+ ...
+ -&gt; e, ee, s, se
+ &lt;- s, es</code></pre>
+<p>Note that in the fallback case, the initiator and responder roles are switched: If Alice initiates a <code>Noise_IK</code> handshake with Bob, Bob might initiate a <code>Noise_XXfallback</code> handshake.</p>
+<p>There needs to be some way for the recipient of a message to distinguish whether it's the next message in the current handshake pattern, or requires re-initialization for a new pattern. For example, each handshake message could be preceded by a <code>type</code> byte (see <a href="#application-responsibilities">Section 12</a>). This byte is not part of the Noise message proper, but simply signals when re-initialization is needed. It could have the following meanings:</p>
+<ul>
+<li><p>If <code>type == 0</code> in the initiator's first message then the initiator is performing a <code>Noise_XX</code> handshake <em>(full handshake)</em>.</p></li>
+<li><p>If <code>type == 1</code> in the initiator's first message then the initiator is performing a <code>Noise_IK</code> handshake <em>(attempted abbreviated handshake)</em>.</p></li>
+<li><p>If <code>type == 0</code> in the responder's first <code>Noise_IK</code> response then the responder accepted the <code>Noise_IK</code> message <em>(successful abbreviated handshake)</em>.</p></li>
+<li><p>If <code>type == 1</code> in the responder's first <code>Noise_IK</code> response then the responder failed to authenticate the initiator's <code>Noise_IK</code> message and is performing a <code>Noise_XXfallback</code> handshake, using the initiator's ephemeral public key as a pre-message <em>(fallback handshake)</em>.</p></li>
+</ul>
+<p>Note that the <code>type</code> byte doesn't need to be explicitly authenticated (as prologue, or additional AEAD data), since it's implicitly authenticated if the message is processed succesfully.</p>
+<h2 id="protocol-indistinguishability">9.3. Protocol indistinguishability</h2>
+<p>Parties may wish to hide what protocol they are executing from an eavesdropper. For example, suppose parties are using Noise Pipes, and want to hide whether they are performing a full handshake, abbreviated handshake, or fallback handshake.</p>
+<p>This is fairly easy:</p>
+<ul>
+<li><p>The first three messages can have their payloads padded with random bytes to a constant size, regardless of which handshake is executed.</p></li>
+<li><p>Instead of a <code>type</code> byte, the responder can use trial decryption to differentiate between an initial message using <code>Noise_XX</code> or <code>Noise_IK</code>.</p></li>
+<li><p>Instead of a <code>type</code> byte, an initiator who sent a <code>Noise_IK</code> initial message can use trial decryption to differentiate between a response using <code>Noise_IK</code> or <code>Noise_XXfallback</code>.</p></li>
+</ul>
+<p>This leaves the Noise ephemerals in the clear, so an eavesdropper might suspect the parties are using Noise, even if it can't distinguish the handshakes. To make the ephemerals indistinguishable from random, techniques like Elligator <span class="citation">[<a href="#ref-elligator">4</a>]</span> could be used.</p>
+<h2 id="channel-binding">9.4. Channel binding</h2>
+<p>Parties may wish to execute a Noise protocol, then perform authentication at the application layer using signatures, passwords, or something else.</p>
+<p>To support this, Noise libraries should expose the final value of <code>h</code> to the application as a <strong>handshake hash</strong> which uniquely identifies the Noise session.</p>
+<p>Parties can then sign the handshake hash, or hash it along with their password, to get an authentication token which has a &quot;channel binding&quot; property: the token can't be used by the receiving party with a different sesssion.</p>
+<h1 id="dh-functions-cipher-functions-and-hash-functions">10. DH functions, cipher functions, and hash functions</h1>
+<h2 id="the-25519-dh-functions">10.1. The <code>25519</code> DH functions</h2>
+<ul>
+<li><p><strong><code>GENERATE_KEYPAIR()</code></strong>: Returns a new Curve25519 key pair.</p></li>
+<li><p><strong><code>DH(keypair, public_key)</code></strong>: Executes the Curve25519 DH function (aka &quot;X25519&quot; in <span class="citation">[<a href="#ref-rfc7748">5</a>]</span>. The null public key value is all zeros, which will always produce an output of all zeros. Other invalid public key values will also produce an output of all zeros.</p></li>
+<li><p><strong><code>DHLEN</code></strong> = 32</p></li>
+</ul>
+<h2 id="the-448-dh-functions">10.2. The <code>448</code> DH functions</h2>
+<ul>
+<li><p><strong><code>GENERATE_KEYPAIR()</code></strong>: Returns a new Curve448 key pair.</p></li>
+<li><p><strong><code>DH(keypair, public_key)</code></strong>: Executes the Curve448 DH function (aka &quot;X448&quot; in <span class="citation">[<a href="#ref-rfc7748">5</a>]</span>. The null public key value is all zeros, which will always produce an output of all zeros. Other invalid public key values will also produce an output of all zeros.</p></li>
+<li><p><strong><code>DHLEN</code></strong> = 56</p></li>
+</ul>
+<h2 id="the-chachapoly-cipher-functions">10.3. The <code>ChaChaPoly</code> cipher functions</h2>
+<ul>
+<li><strong><code>ENCRYPT(k, n, ad, plaintext)</code> / <code>DECRYPT(k, n, ad, ciphertext)</code></strong>: <code>AEAD_CHACHA20_POLY1305</code> from <span class="citation">[<a href="#ref-rfc7539">6</a>]</span>. The 96-bit nonce is formed by encoding 32 bits of zeros followed by little-endian encoding of <code>n</code>. (Earlier implementations of ChaCha20 used a 64-bit nonce; with these implementations it's compatible to encode <code>n</code> directly into the ChaCha20 nonce without the 32-bit zero prefix).</li>
+</ul>
+<h2 id="the-aesgcm-cipher-functions">10.4. The <code>AESGCM</code> cipher functions</h2>
+<ul>
+<li><strong><code>ENCRYPT(k, n, ad, plaintext)</code> / <code>DECRYPT(k, n, ad, ciphertext)</code></strong>: AES256 with GCM from <span class="citation">[<a href="#ref-nistgcm">7</a>]</span> with a 128-bit tag appended to the ciphertext. The 96-bit nonce is formed by encoding 32 bits of zeros followed by big-endian encoding of <code>n</code>.</li>
+</ul>
+<h2 id="the-sha256-hash-function">10.5. The <code>SHA256</code> hash function</h2>
+<ul>
+<li><strong><code>HASH(input)</code></strong>: <code>SHA-256</code> from <span class="citation">[<a href="#ref-nistsha2">8</a>]</span>.</li>
+<li><strong><code>HASHLEN</code></strong> = 32</li>
+<li><strong><code>BLOCKLEN</code></strong> = 64</li>
+</ul>
+<h2 id="the-sha512-hash-function">10.6. The <code>SHA512</code> hash function</h2>
+<ul>
+<li><strong><code>HASH(input)</code></strong>: <code>SHA-512</code> from <span class="citation">[<a href="#ref-nistsha2">8</a>]</span>.</li>
+<li><strong><code>HASHLEN</code></strong> = 64</li>
+<li><strong><code>BLOCKLEN</code></strong> = 128</li>
+</ul>
+<h2 id="the-blake2s-hash-function">10.7. The <code>BLAKE2s</code> hash function</h2>
+<ul>
+<li><strong><code>HASH(input)</code></strong>: <code>BLAKE2s</code> from <span class="citation">[<a href="#ref-rfc7693">9</a>]</span> with digest length 32.</li>
+<li><strong><code>HASHLEN</code></strong> = 32</li>
+<li><strong><code>BLOCKLEN</code></strong> = 64</li>
+</ul>
+<h2 id="the-blake2b-hash-function">10.8. The <code>BLAKE2b</code> hash function</h2>
+<ul>
+<li><strong><code>HASH(input)</code></strong>: <code>BLAKE2b</code> from <span class="citation">[<a href="#ref-rfc7693">9</a>]</span> with digest length 64.</li>
+<li><strong><code>HASHLEN</code></strong> = 64</li>
+<li><strong><code>BLOCKLEN</code></strong> = 128</li>
+</ul>
+<h1 id="protocol-names">11. Protocol names</h1>
+<p>To produce a <strong>Noise protocol name</strong> for <code>Initialize()</code> you concatenate the ASCII names for the handshake pattern, the DH functions, the cipher functions, and the hash function, with underscore separators. For example:</p>
+<ul>
+<li><code>Noise_XX_25519_AESGCM_SHA256</code></li>
+<li><code>Noise_N_25519_ChaChaPoly_BLAKE2s</code></li>
+<li><code>Noise_XXfallback_448_AESGCM_SHA512</code></li>
+<li><code>Noise_IK_448_ChaChaPoly_BLAKE2b</code></li>
+</ul>
+<p>If a pre-shared symmetric key is in use, then the prefix <code>&quot;NoisePSK_&quot;</code> is used instead of <code>&quot;Noise_&quot;</code>:</p>
+<ul>
+<li><code>NoisePSK_XX_25519_AESGCM_SHA256</code></li>
+<li><code>NoisePSK_N_25519_ChaChaPoly_BLAKE2s</code></li>
+<li><code>NoisePSK_XXfallback_448_AESGCM_SHA512</code></li>
+<li><code>NoisePSK_IK_448_ChaChaPoly_BLAKE2b</code></li>
+</ul>
+<h1 id="application-responsibilities">12. Application responsibilities</h1>
+<p>An application built on Noise must consider several issues:</p>
+<ul>
+<li><p><strong>Choosing crypto functions</strong>: The <code>25519</code> DH functions are recommended for typical uses, though the <code>448</code> DH functions might offer some extra security in case a cryptanalytic attack is developed against elliptic curve cryptography. The <code>448</code> DH functions should be used with a 512-bit hash like <code>SHA512</code> or <code>BLAKE2b</code>. The <code>25519</code> DH functions may be used with a 256-bit hash like <code>SHA256</code> or <code>BLAKE2s</code>, though a 512-bit hash might offer some extra security in case a cryptanalytic attack is developed against the smaller hash functions.</p></li>
+<li><p><strong>Extensibility</strong>: Applications are recommended to use an extensible data format for the payloads of all messages (e.g. JSON, Protocol Buffers). This ensures that fields can be added in the future which are ignored by older implementations.</p></li>
+<li><p><strong>Padding</strong>: Applications are recommended to use a data format for the payloads of all encrypted messages that allows padding. This allows implementations to avoid leaking information about message sizes. Using an extensible data format, per the previous bullet, will typically suffice.</p></li>
+<li><p><strong>Session termination</strong>: Applications must consider that a sequence of Noise transport messages could be truncated by an attacker. Applications should include explicit length fields or termination signals inside of transport payloads to signal the end of an interactive session, or the end of a one-way stream of transport messages.</p></li>
+<li><p><strong>Length fields</strong>: Applications must handle any framing or additional length fields for Noise messages, considering that a Noise message may be up to 65535 bytes in length. If an explicit length field is needed, applications are recommended to add a 16-bit big-endian length field prior to each message.</p></li>
+<li><p><strong>Type fields</strong>: Applications are recommended to include a single-byte type field prior to each Noise handshake message (and prior to the length field, if one is included). A recommended idiom is for the value zero to indicate no change from the current Noise protocol, and for applications to reject messages with an unknown value. This allows future protocol versions to specify handshake re-initialization or any other compatibility-breaking change (protocol extensions that don't break compatibility can be handled within Noise payloads).</p></li>
+</ul>
+<h1 id="security-considerations">13. Security considerations</h1>
+<p>This section collects various security considerations:</p>
+<ul>
+<li><p><strong>Session termination</strong>: Preventing attackers from truncating a stream of transport messages is an application responsibility. See previous section.</p></li>
+<li><p><strong>Rollback</strong>: If parties decide on a Noise protocol based on some previous negotiation that is not included as prologue, then a rollback attack might be possible. This is a particular risk with handshake re-initialization, and requires careful attention if a Noise handshake is preceded by communication between the parties.</p></li>
+<li><p><strong>Misusing public keys as secrets</strong>: It might be tempting to use a pattern with a pre-message public key and assume that a successful handshake implies the other party's knowledge of the public key. Unfortunately, this is not the case, since setting public keys to invalid values might cause predictable DH output. For example, a <code>Noise_NK_25519</code> initiator might send an invalid ephemeral public key to cause a known DH output of all zeros, despite not knowing the responder's static public key. If the parties want to authenticate with a shared secret, it must be passed in as a PSK.</p></li>
+<li><p><strong>Channel binding</strong>: Depending on the DH functions, it might be possible for a malicious party to engage in multiple sessions that derive the same shared secret key by setting public keys to invalid values that cause predictable DH output (as in previous bullet). This is why a higher-level protocol should use the handshake hash (<code>h</code>) for a unique channel binding, instead of <code>ck</code>, as explained in <a href="#channel-binding">Section 9.4</a>.</p></li>
+<li><p><strong>Incrementing nonces</strong>: Reusing a nonce value for <code>n</code> with the same key <code>k</code> for encryption would be catastrophic. Implementations must carefully follow the rules for nonces. Nonces are not allowed to wrap back to zero due to integer overflow, and the maximum nonce value is reserved for future use. This means parties are not allowed to send more than 2^64-1 transport messages.</p></li>
+<li><p><strong>Fresh ephemerals</strong>: Every party in a Noise protocol should send a new ephemeral public key and perform a DH with it prior to sending any encrypted data. Otherwise replay of a handshake message could trigger catastrophic key reuse. This is one rationale behind the patterns in <a href="#handshake-patterns">Section 8</a>, and the validity rules in <a href="#pattern-validity">Section 8.1</a>. It's also the reason why one-way handshakes only allow transport messages from the sender, not the recipient.</p></li>
+<li><p><strong>Protocol names</strong>: The protocol name used with <code>Initialize()</code> must uniquely identify the combination of handshake pattern and crypto functions for every key it's used with (whether ephemeral key pair, static key pair, or PSK). If the same secret key was reused with the same protocol name but a different set of cryptographic operations then bad interactions could occur.</p></li>
+<li><p><strong>Pre-shared symmetric keys</strong>: Pre-shared symmetric keys must be secret values with 256 bits of entropy.</p></li>
+<li><p><strong>Data volumes</strong>: The <code>AESGCM</code> cipher functions suffer a gradual reduction in security as the volume of data encrypted under a single key increases. Due to this, parties should not send more than 2^56 bytes (roughly 72 petabytes) encrypted by a single key. If sending such large volumes of data is a possibility, different cipher functions should be chosen.</p></li>
+<li><p><strong>Hash collisions</strong>: If an attacker can find hash collisions on prologue data or the handshake hash, they may be able to perform &quot;transcript collision&quot; attacks that trick the parties into having different views of handshake data. It is important to use Noise with collision-resistant hash functions, and replace the hash function at any sign of weakness.</p></li>
+<li><p><strong>Implementation fingerprinting</strong>: If this protocol is used in settings with anonymous parties, care should be taken that implementations behave identically in all cases. This may require mandating exact behavior for handling of invalid DH public keys.</p></li>
+</ul>
+<h1 id="rationale">14. Rationale</h1>
+<p>This section collects various design rationale:</p>
+<p>Nonces are 64 bits in length because:</p>
+<ul>
+<li>Some ciphers only have 64 bit nonces (e.g. Salsa20).</li>
+<li>64 bit nonces were used in the initial specification and implementations of ChaCha20, so Noise nonces can be used with these implementations.</li>
+<li>64 bits makes it easy for the entire nonce to be treated as an integer and incremented.</li>
+<li>96 bits nonces (e.g. in RFC 7539) are a confusing size where it's unclear if random nonces are acceptable.</li>
+</ul>
+<p>The recommended hash function families are SHA2 and BLAKE2 because:</p>
+<ul>
+<li>SHA2 is widely available.</li>
+<li>SHA2 is often used alongside AES.</li>
+<li>BLAKE2 is fast and similar to ChaCha20.</li>
+</ul>
+<p>Hash output lengths of both 256 bits and 512 bits are supported because:</p>
+<ul>
+<li>SHA-256 and BLAKE2s have sufficient collision-resistance at the 128-bit security level.</li>
+<li>SHA-256 and BLAKE2s require less RAM, and less calculation when processing smaller inputs (due to smaller block size), than their larger brethren (SHA-512 and BLAKE2b).</li>
+<li>SHA-256 and BLAKE2s are faster on 32-bit processors than their larger brethren.</li>
+</ul>
+<p>Cipher keys and pre-shared symmetric keys are 256 bits because:</p>
+<ul>
+<li>256 bits is a conservative length for cipher keys when considering cryptanalytic safety margins, time/memory tradeoffs, multi-key attacks, and quantum attacks.</li>
+<li>Pre-shared key length is fixed to simplify testing and implementation, and to deter users from mistakenly using low-entropy passwords as pre-shared keys.</li>
+</ul>
+<p>The authentication data in a ciphertext is 128 bits because:</p>
+<ul>
+<li>Some algorithms (e.g. GCM) lose more security than an ideal MAC when truncated.</li>
+<li>Noise may be used in a wide variety of contexts, including where attackers can receive rapid feedback on whether MAC guesses are correct.</li>
+<li>A single fixed length is simpler than supporting variable-length tags.</li>
+</ul>
+<p>The GCM security limit is 2^56 bytes because:</p>
+<ul>
+<li>This is 2^52 AES blocks (each block is 16 bytes). The limit is based on the risk of birthday collisions being used to rule out plaintext guesses. The probability an attacker could rule out a random guess on a 2^56 byte plaintext is less than 1 in 1 million (roughly (2^52 * 2^52) / 2^128).</li>
+</ul>
+<p>Big-endian length fields are recommended because:</p>
+<ul>
+<li>Length fields are likely to be handled by parsing code where big-endian &quot;network byte order&quot; is traditional.</li>
+<li>Some ciphers use big-endian internally (e.g. GCM, SHA2).</li>
+<li>While it's true that Curve25519, Curve448, and ChaCha20/Poly1305 use little-endian, these will likely be handled by specialized libraries, so there's not a strong argument for aligning with them.</li>
+</ul>
+<p>Cipher nonces are big-endian for AES-GCM, and little-endian for ChaCha20, because:</p>
+<ul>
+<li>ChaCha20 uses a little-endian block counter internally.</li>
+<li>AES-GCM uses a big-endian block counter internally.</li>
+<li>It makes sense to use consistent endianness in the cipher code.</li>
+</ul>
+<p>The <code>MixKey()</code> design uses <code>HKDF</code> because:</p>
+<ul>
+<li>HKDF applies multiple layers of hashing between each <code>MixKey()</code> input. This &quot;extra&quot; hashing might mitigate the impact of hash function weakness.</li>
+<li>HKDF is well-known and is used in similar ways in other protocols (e.g. Signal, IPsec).</li>
+<li>HKDF and HMAC are widely-used constructions. If some weakness is found in a hash function, cryptanalysts will likely analyze that weakness in the context of HKDF and HMAC.</li>
+</ul>
+<p><code>MixHash()</code> is used instead of sending all inputs through <code>MixKey()</code> because:</p>
+<ul>
+<li><code>MixHash()</code> is more efficient than <code>MixKey()</code>.</li>
+<li><code>MixHash()</code> avoids any IPR concerns regarding mixing identity data into session keys (see KEA+).</li>
+<li><code>MixHash()</code> produces a non-secret <code>h</code> value that might be useful to higher-level protocols, e.g. for channel-binding.</li>
+</ul>
+<p>The <code>h</code> value hashes handshake ciphertext instead of plaintext because:</p>
+<ul>
+<li>This ensures <code>h</code> is a non-secret value that can be used for channel-binding or other purposes without leaking secret information.</li>
+<li>This provides stronger guarantees against ciphertext malleability.</li>
+</ul>
+<p>Session termination is left to the application because:</p>
+<ul>
+<li>Providing a termination signal in Noise doesn't help the application much, since the application still has to use the signal correctly.</li>
+<li>For an application with its own termination signal, having a second termination signal in Noise is likely to be confusing rather than helpful.</li>
+</ul>
+<p>Explicit random nonces (like TLS &quot;Random&quot; fields) are not used because:</p>
+<ul>
+<li>One-time ephemeral public keys make explicit nonces unnecessary.</li>
+<li>Explicit nonces allow reuse of ephemeral public keys. However reusing ephemerals (with periodic replacement) is more complicated, requires a secure time source, is less secure in case of ephemeral compromise, and only provides a small optimization, since key generation can be done for a fraction of the cost of a DH operation.</li>
+<li>Explicit nonces increase message size.</li>
+<li>Explicit nonces make it easier to &quot;backdoor&quot; crypto implementations, e.g. by modifying the RNG so that key recovery data is leaked through the nonce fields.</li>
+</ul>
+<h1 id="ipr">15. IPR</h1>
+<p>The Noise specification (this document) is hereby placed in the public domain.</p>
+<h1 id="acknowledgements">16. Acknowledgements</h1>
+<p>Noise is inspired by:</p>
+<ul>
+<li>The NaCl and CurveCP protocols from Dan Bernstein et al <span class="citation">[<a href="#ref-nacl">10</a>], [<a href="#ref-curvecp">11</a>]</span>.</li>
+<li>The SIGMA and HOMQV protocols from Hugo Krawczyk <span class="citation">[<a href="#ref-sigma">12</a>], [<a href="#ref-homqv">13</a>]</span>.</li>
+<li>The Ntor protocol from Ian Goldberg et al <span class="citation">[<a href="#ref-ntor">14</a>]</span>.</li>
+<li>The analysis of OTR by Mario Di Raimondo et al <span class="citation">[<a href="#ref-otr">15</a>]</span>.</li>
+<li>The analysis by Caroline Kudla and Kenny Paterson of &quot;Protocol 4&quot; by Simon Blake-Wilson et al <span class="citation">[<a href="#ref-kudla2005">16</a>], [<a href="#ref-blakewilson1997">17</a>]</span>.</li>
+</ul>
+<p>General feedback on the spec and design came from: Moxie Marlinspike, Jason Donenfeld, Rhys Weatherley, Tiffany Bennett, Jonathan Rudenberg, Stephen Touset, Tony Arcieri, and Alex Wied.</p>
+<p>Thanks to Tom Ritter, Karthikeyan Bhargavan, David Wong, and Klaus Hartke for editorial feedback.</p>
+<p>Moxie Marlinspike, Hugo Krawczyk, Samuel Neves, Christian Winnerlein, J.P. Aumasson, and Jason Donenfeld provided helpful input and feedback on the key derivation design.</p>
+<p>The BLAKE2 team (in particular J.P. Aumasson, Samuel Neves, and Zooko) provided helpful discussion on using BLAKE2 with Noise.</p>
+<p>Jeremy Clark, Thomas Ristenpart, and Joe Bonneau gave feedback on much earlier versions.</p>
+<h1 id="references" class="unnumbered">17. References</h1>
+<div id="refs" class="references">
+<div id="ref-Rogaway:2002">
+<p>[1] P. Rogaway, “Authenticated-encryption with Associated-data,” in Proceedings of the 9th ACM Conference on Computer and Communications Security, 2002. <a href="http://web.cs.ucdavis.edu/~rogaway/papers/ad.pdf" class="uri">http://web.cs.ucdavis.edu/~rogaway/papers/ad.pdf</a></p>
+</div>
+<div id="ref-rfc2104">
+<p>[2] H. Krawczyk, M. Bellare, and R. Canetti, “HMAC: Keyed-Hashing for Message Authentication.” Internet Engineering Task Force; RFC 2104 (Informational); IETF, Feb-1997. <a href="http://www.ietf.org/rfc/rfc2104.txt" class="uri">http://www.ietf.org/rfc/rfc2104.txt</a></p>
+</div>
+<div id="ref-rfc5869">
+<p>[3] H. Krawczyk and P. Eronen, “HMAC-based Extract-and-Expand Key Derivation Function (HKDF).” Internet Engineering Task Force; RFC 5869 (Informational); IETF, May-2010. <a href="http://www.ietf.org/rfc/rfc5869.txt" class="uri">http://www.ietf.org/rfc/rfc5869.txt</a></p>
+</div>
+<div id="ref-elligator">
+<p>[4] D. J. Bernstein, M. Hamburg, A. Krasnova, and T. Lange, “Elligator: Elliptic-curve points indistinguishable from uniform random strings.” Cryptology ePrint Archive, Report 2013/325, 2013. <a href="http://eprint.iacr.org/2013/325" class="uri">http://eprint.iacr.org/2013/325</a></p>
+</div>
+<div id="ref-rfc7748">
+<p>[5] A. Langley, M. Hamburg, and S. Turner, “Elliptic Curves for Security.” Internet Engineering Task Force; RFC 7748 (Informational); IETF, Jan-2016. <a href="http://www.ietf.org/rfc/rfc7748.txt" class="uri">http://www.ietf.org/rfc/rfc7748.txt</a></p>
+</div>
+<div id="ref-rfc7539">
+<p>[6] Y. Nir and A. Langley, “ChaCha20 and Poly1305 for IETF Protocols.” Internet Engineering Task Force; RFC 7539 (Informational); IETF, May-2015. <a href="http://www.ietf.org/rfc/rfc7539.txt" class="uri">http://www.ietf.org/rfc/rfc7539.txt</a></p>
+</div>
+<div id="ref-nistgcm">
+<p>[7] M. J. Dworkin, “SP 800-38D. Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC,” National Institute of Standards &amp; Technology, Gaithersburg, MD, United States, 2007. <a href="http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf" class="uri">http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf</a></p>
+</div>
+<div id="ref-nistsha2">
+<p>[8] NIST, “FIPS 180-4. Secure Hash Standard (SHS),” National Institute of Standards &amp; Technology, Gaithersburg, MD, United States, 2012. <a href="http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf" class="uri">http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf</a></p>
+</div>
+<div id="ref-rfc7693">
+<p>[9] M.-J. Saarinen and J.-P. Aumasson, “The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC).” Internet Engineering Task Force; RFC 7693 (Informational); IETF, Nov-2015. <a href="http://www.ietf.org/rfc/rfc7693.txt" class="uri">http://www.ietf.org/rfc/rfc7693.txt</a></p>
+</div>
+<div id="ref-nacl">
+<p>[10] D. J. Bernstein, T. Lange, and P. Schwabe, “NaCl: Networking and Cryptography Library.”. <a href="https://nacl.cr.yp.to/" class="uri">https://nacl.cr.yp.to/</a></p>
+</div>
+<div id="ref-curvecp">
+<p>[11] D. J. Bernstein, “CurveCP: Usable security for the Internet.”. <a href="https://curvecp.org" class="uri">https://curvecp.org</a></p>
+</div>
+<div id="ref-sigma">
+<p>[12] H. Krawczyk, “SIGMA: The ‘SIGn-and-MAc’ Approach to Authenticated Diffie-Hellman and Its Use in the IKE Protocols,” in Advances in Cryptology - CRYPTO 2003, 2003. <a href="http://webee.technion.ac.il/~hugo/sigma.html" class="uri">http://webee.technion.ac.il/~hugo/sigma.html</a></p>
+</div>
+<div id="ref-homqv">
+<p>[13] S. Halevi and H. Krawczyk, “One-Pass HMQV and Asymmetric Key-Wrapping.” Cryptology ePrint Archive, Report 2010/638, 2010. <a href="http://eprint.iacr.org/2010/638" class="uri">http://eprint.iacr.org/2010/638</a></p>
+</div>
+<div id="ref-ntor">
+<p>[14] I. Goldberg, D. Stebila, and B. Ustaoglu, “Anonymity and One-way Authentication in Key Exchange Protocols,” Design, Codes, and Cryptography, vol. 67, no. 2, May 2013. <a href="http://cacr.uwaterloo.ca/techreports/2011/cacr2011-11.pdf" class="uri">http://cacr.uwaterloo.ca/techreports/2011/cacr2011-11.pdf</a></p>
+</div>
+<div id="ref-otr">
+<p>[15] M. Di Raimondo, R. Gennaro, and H. Krawczyk, “Secure Off-the-record Messaging,” in Proceedings of the 2005 ACM Workshop on Privacy in the Electronic Society, 2005. <a href="http://www.dmi.unict.it/diraimondo/web/wp-content/uploads/papers/otr.pdf" class="uri">http://www.dmi.unict.it/diraimondo/web/wp-content/uploads/papers/otr.pdf</a></p>
+</div>
+<div id="ref-kudla2005">
+<p>[16] C. Kudla and K. G. Paterson, “Modular Security Proofs for Key Agreement Protocols,” in Advances in Cryptology - ASIACRYPT 2005: 11th International Conference on the Theory and Application of Cryptology and Information Security, 2005. <a href="http://www.isg.rhul.ac.uk/~kp/ModularProofs.pdf" class="uri">http://www.isg.rhul.ac.uk/~kp/ModularProofs.pdf</a></p>
+</div>
+<div id="ref-blakewilson1997">
+<p>[17] S. Blake-Wilson, D. Johnson, and A. Menezes, “Key agreement protocols and their security analysis,” in Crytography and Coding: 6th IMA International Conference Cirencester, UK, December 17–19, 1997 Proceedings, 1997. <a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.25.387" class="uri">http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.25.387</a></p>
+</div>
+</div>
+</body>
+</html>
diff --git a/output/noise.pdf b/output/noise.pdf
index f30b178..f5f73cf 100644
--- a/output/noise.pdf
+++ b/output/noise.pdf
Binary files differ