<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE rfc [
  <!ENTITY nbsp    "&#160;">
  <!ENTITY zwsp   "&#8203;">
  <!ENTITY nbhy   "&#8209;">
  <!ENTITY wj     "&#8288;">
]>
<?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
<!-- generated by https://github.com/cabo/kramdown-rfc version 1.7.4 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-denis-dprive-dnscrypt-02" category="info" submissionType="independent" version="3">
  <!-- xml2rfc v2v3 conversion 3.19.0 -->
  <front>
    <title abbrev="DNSCrypt">The DNSCrypt protocol</title>
    <seriesInfo name="Internet-Draft" value="draft-denis-dprive-dnscrypt-02"/>
    <author fullname="Frank Denis">
      <organization>Individual Contributor</organization>
      <address>
        <email>fde@00f.net</email>
      </address>
    </author>
    <date year="2024" month="January" day="14"/>
    <keyword>dns</keyword>
    <keyword>encryption</keyword>
    <keyword>privacy</keyword>
    <abstract>
      <?line 29?>

<t>The DNSCrypt protocol is designed to encrypt and authenticate DNS traffic between clients and resolvers. This document specifies the protocol and its implementation.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-denis-dprive-dnscrypt/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/DNSCrypt/dnscrypt-protocol"/>.</t>
    </note>
  </front>
  <middle>
    <?line 33?>

<section anchor="introduction">
      <name>Introduction</name>
      <t>The document defines a specific protocol, DNSCrypt, that encrypts and authenticates DNS <xref target="RFC1035"/> queries and responses, improving confidentiality, integrity, and resistance to attacks affecting the original DNS protocol.</t>
      <t>The protocol is designed to be lightweight, extensible, and simple to implement securely on top of an existing DNS client, server or proxy.</t>
      <t>DNS packets don't need to be parsed nor rewritten. DNSCrypt simply wraps them in a secure, encrypted container. Encrypted packets are then exchanged the same way as regular packets, using the standard DNS transport mechanisms. Queries and responses are sent over UDP, falling back to TCP for large responses only if necessary.</t>
      <t>DNSCrypt is stateless. Every query can be processed independently from other queries. There are no session identifiers. In order to better defend against fingerprinting, clients can replace their keys whenever they want, without extra interactions with servers.</t>
      <t>DNSCrypt packets can securely be proxied without having to be decrypted, allowing client IP addresses to be hidden from resolvers ("Anonymized DNSCrypt").</t>
      <t>A recursive DNS server can accept DNSCrypt queries on the same IP address and port as regular DNS. Similarly, DNSCrypt and DoH can also share the same IP address and TCP port.</t>
      <t>Finally, DNSCrypt addresses two security issues inherent to regular DNS over UDP: amplification and fragment attacks.</t>
    </section>
    <section anchor="conventions-and-definitions">
      <name>Conventions And Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

<t>Definitions for client queries:</t>
      <ul spacing="normal">
        <li>
          <t><tt>&lt;dnscrypt-query&gt;</tt>:  <tt>&lt;client-magic&gt;</tt> <tt>&lt;client-pk&gt;</tt> <tt>&lt;client-nonce&gt;</tt> <tt>&lt;encrypted-query&gt;</tt></t>
        </li>
        <li>
          <t><tt>&lt;client-magic&gt;</tt>: a 8 byte identifier for the resolver certificate
chosen by the client.</t>
        </li>
        <li>
          <t><tt>&lt;client-pk&gt;</tt>: the client's public key, whose length depends on the encryption algorithm defined in the chosen certificate.</t>
        </li>
        <li>
          <t><tt>&lt;client-sk&gt;</tt>: the client's secret key.</t>
        </li>
        <li>
          <t><tt>&lt;resolver-pk&gt;</tt>: the resolver's public key.</t>
        </li>
        <li>
          <t><tt>&lt;client-nonce&gt;</tt>: a unique query identifier for a given (<tt>&lt;client-sk&gt;</tt>, <tt>&lt;resolver-pk&gt;</tt>) tuple. The same query sent twice for the same (<tt>&lt;client-sk&gt;</tt>, <tt>&lt;resolver-pk&gt;</tt>) tuple must use two distinct <tt>&lt;client-nonce&gt;</tt> values. The length of <tt>&lt;client-nonce&gt;</tt> depends on the chosen encryption algorithm.</t>
        </li>
        <li>
          <t><tt>AE</tt>: the authenticated encryption function.</t>
        </li>
        <li>
          <t><tt>&lt;encrypted-query&gt;</tt>: <tt>AE(&lt;shared-key&gt; &lt;client-nonce&gt; &lt;client-nonce-pad&gt;, &lt;client-query&gt; &lt;client-query-pad&gt;)</tt></t>
        </li>
        <li>
          <t><tt>&lt;shared-key&gt;</tt>: the shared key derived from <tt>&lt;resolver-pk&gt;</tt> and <tt>&lt;client-sk&gt;</tt>, using the key exchange algorithm defined in the chosen certificate.
-<tt>&lt;client-query&gt;</tt>: the unencrypted client query. The query is not modified; in particular, the query flags are not altered and the query length must be kept in queries prepared to be sent over TCP.</t>
        </li>
        <li>
          <t><tt>&lt;client-nonce-pad&gt;</tt>: <tt>&lt;client-nonce&gt;</tt> length is half the nonce length required by the encryption algorithm. In client queries, the other half, <tt>&lt;client-nonce-pad&gt;</tt> is filled with NUL bytes.</t>
        </li>
        <li>
          <t><tt>&lt;client-query-pad&gt;</tt>: the variable-length padding.</t>
        </li>
      </ul>
      <t>Definitions for server responses:</t>
      <ul spacing="normal">
        <li>
          <t><tt>&lt;dnscrypt-response&gt;</tt>: <tt>&lt;resolver-magic&gt;</tt> <tt>&lt;nonce&gt;</tt> <tt>&lt;encrypted-response&gt;</tt></t>
        </li>
        <li>
          <t><tt>&lt;resolver-magic&gt;</tt>: the <tt>0x72 0x36 0x66 0x6e 0x76 0x57 0x6a 0x38</tt> byte sequence</t>
        </li>
        <li>
          <t><tt>&lt;nonce&gt;</tt>: <tt>&lt;client-nonce&gt;</tt> <tt>&lt;resolver-nonce&gt;</tt></t>
        </li>
        <li>
          <t><tt>&lt;client-nonce&gt;</tt>: the nonce sent by the client in the related query.</t>
        </li>
        <li>
          <t><tt>&lt;client-pk&gt;</tt>: the client's public key.</t>
        </li>
        <li>
          <t><tt>&lt;resolver-sk&gt;</tt>: the resolver's secret key.</t>
        </li>
        <li>
          <t><tt>&lt;resolver-nonce&gt;</tt>: a unique response identifier for a given <tt>(&lt;client-pk&gt;, &lt;resolver-sk&gt;)</tt> tuple. The length of <tt>&lt;resolver-nonce&gt;</tt> depends on the chosen encryption algorithm.</t>
        </li>
        <li>
          <t><tt>DE</tt>: the authenticated decryption function.</t>
        </li>
        <li>
          <t><tt>&lt;encrypted-response&gt;</tt>: <tt>DE(&lt;shared-key&gt;, &lt;nonce&gt;, &lt;resolver-response&gt; &lt;resolver-response-pad&gt;)</tt></t>
        </li>
        <li>
          <t><tt>&lt;shared-key&gt;</tt>: the shared key derived from <tt>&lt;resolver-sk&gt;</tt> and <tt>&lt;client-pk&gt;</tt>, using the key exchange algorithm defined in the chosen certificate.</t>
        </li>
        <li>
          <t><tt>&lt;resolver-response&gt;</tt>: the unencrypted resolver response. The response is not modified; in particular, the query flags are not altered and the response length must be kept in responses prepared to be sent over TCP.</t>
        </li>
        <li>
          <t><tt>&lt;resolver-response-pad&gt;</tt>: the variable-length padding.</t>
        </li>
      </ul>
    </section>
    <section anchor="protocol-overview">
      <name>Protocol Overview</name>
      <t>The protocol operates as follows:</t>
      <ol spacing="normal" type="1"><li>
          <t>The DNSCrypt client sends a DNS query to a DNSCrypt server to retrieve the server's public keys.</t>
        </li>
        <li>
          <t>The client generates its own key pair.</t>
        </li>
        <li>
          <t>The client encrypts unmodified DNS queries using a server's public key, padding them as necessary, and concatenates them to a nonce and a copy of the client's public key. The resulting output is sent using standard DNS transport mechanisms.</t>
        </li>
        <li>
          <t>Encrypted queries are decrypted by the server using the attached client public key and the server's own secret key. The output is a regular DNS packet that doesn't require any special processing.</t>
        </li>
        <li>
          <t>To send an encrypted response, the server adds padding to the unmodified response, encrypts the result using the client's public key and the client's nonce, and truncates the response if necessary. The resulting packet, truncated or not, is sent to the client using standard DNS mechanisms.</t>
        </li>
        <li>
          <t>The client authenticates and decrypts the response using its secret key, the server's public key, the attached nonce, and its own nonce. If the response was truncated, the client may adjust internal parameters and retry over TCP. If not, the output is a regular DNS response that can be directly forwarded to applications and stub resolvers.</t>
        </li>
      </ol>
    </section>
    <section anchor="key-management">
      <name>Key Management</name>
      <t>Both the client and the resolver initially generate a short-term key pair for each supported encryption system.</t>
      <t>The client generates a key pair for each resolver it communicates with, and the resolver generates a key pair for each client it communicates with. The resolver also generates a public key for each supported encryption system.</t>
    </section>
    <section anchor="session-establishment">
      <name>Session Establishment</name>
      <t>From a client perspective, a DNSCrypt session begins with the client sending a non-authenticated DNS query to a DNSCrypt-enabled resolver. This DNS query encodes the certificate versions supported by the client, as well as a public identifier of the provider requested by the client.</t>
      <t>The resolver responds with a public set of signed certificates that must be verified by the client using a previously distributed public key, known as the provider public key. Each certificate includes a validity period, a serial number, a version that defines a key exchange mechanism, an authenticated encryption algorithm and its parameters, as well as a short-term public key, known as the resolver public key.</t>
      <t>A resolver can support multiple algorithms and advertise multiple resolver public keys simultaneously. The client picks the one with the highest serial number among the currently valid ones that match a supported protocol version.</t>
      <t>Each certificate includes a magic number that the client must prefix its queries with, in order for the resolver to know what certificate was chosen by the client to construct a given query.</t>
      <t>The encryption algorithm, resolver public key, and client magic number from the chosen certificate are then used by the client to send encrypted queries. These queries include the client public key.</t>
      <t>Using this client public key, and knowing which certificate was chosen by the client as well as the relevant secret key, the resolver verifies and decrypts the query and encrypts the response using the same parameters.</t>
    </section>
    <section anchor="transport">
      <name>Transport</name>
      <t>The DNSCrypt protocol can use the UDP and TCP transport protocols.
DNSCrypt Clients and resolvers should support the protocol over UDP and must support it over TCP.</t>
      <t>The default port for this protocol should be 443, both for TCP and UDP.</t>
    </section>
    <section anchor="padding-for-client-queries-over-udp">
      <name>Padding For Client Queries Over UDP</name>
      <t>Prior to encryption, queries are padded using the ISO/IEC 7816-4 format. The padding starts with a byte valued 0x80 followed by a variable number of NUL bytes.</t>
      <t><tt>&lt;client-query&gt;</tt> <tt>&lt;client-query-pad&gt;</tt> must be at least <tt>&lt;min-query-len&gt;</tt> bytes. If the length of the client query is less than <tt>&lt;min-query-len&gt;</tt>, the padding length must be adjusted in order to satisfy this requirement.</t>
      <t><tt>&lt;min-query-len&gt;</tt> is a variable length, initially set to 256 bytes, and must be a multiple of 64 bytes.</t>
    </section>
    <section anchor="client-queries-over-udp">
      <name>Client Queries Over UDP</name>
      <t>Client queries sent using UDP must be padded as described in section 3.</t>
      <t>A UDP packet can contain a single query, whose entire content is the <tt>&lt;dnscrypt-query&gt;</tt> construction documented in section 2.</t>
      <t>UDP packets using the DNSCrypt protocol can be fragmented into multiple IP packets and can use a single source port.</t>
      <t>After having received a query, the resolver can either ignore the query or reply with a DNSCrypt-encapsulated response.</t>
      <t>The client must verify and decrypt the response using the resolver's public key, the shared secret and the received nonce. If the response cannot be verified, the response must be discarded.</t>
      <t>If the response has the TC flag set, the client must:</t>
      <ol spacing="normal" type="1"><li>
          <t>send the query again using TCP</t>
        </li>
        <li>
          <t>set the new minimum query length as:</t>
        </li>
      </ol>
      <t><tt>&lt;min-query-len&gt; ::= min(&lt;min-query-len&gt; + 64, &lt;max-query-len&gt;)</tt></t>
      <t><tt>&lt;min-query-len&gt;</tt> must be capped so that the full length of a DNSCrypt packet doesn't exceed the maximum size required by the transport layer.</t>
      <t>The client may decrease <tt>&lt;min-query-len&gt;</tt>, but the length must remain a multiple of 64 bytes.</t>
    </section>
    <section anchor="padding-for-client-queries-over-tcp">
      <name>Padding For Client Queries Over TCP</name>
      <t>Prior to encryption, queries are padded using the ISO/IEC 7816-4 format. The padding starts with a byte valued 0x80 followed by a
variable number of NUL bytes.</t>
      <t>The length of <tt>&lt;client-query-pad&gt;</tt> is randomly chosen between 1 and 256 bytes (including the leading 0x80), but the total length of <tt>&lt;client-query&gt;</tt> <tt>&lt;client-query-pad&gt;</tt> must be a multiple of 64 bytes.</t>
      <t>For example, an originally unpadded 56-bytes DNS query can be padded as:</t>
      <t><tt>&lt;56-bytes-query&gt; 0x80 0x00 0x00 0x00 0x00 0x00 0x00 0x00</tt></t>
      <t>or</t>
      <t><tt>&lt;56-bytes-query&gt; 0x80 (0x00 * 71)</tt></t>
      <t>or</t>
      <t><tt>&lt;56-bytes-query&gt; 0x80 (0x00 * 135)</tt></t>
      <t>or</t>
      <t><tt>&lt;56-bytes-query&gt; 0x80 (0x00 * 199)</tt></t>
    </section>
    <section anchor="client-queries-over-tcp">
      <name>Client Queries Over TCP</name>
      <t>Encrypted client queries over TCP only differ from queries sent over UDP by the padding length computation and by the fact that they are prefixed with their length, encoded as two big-endian bytes.</t>
      <t>Cleartext DNS query payloads are not prefixed by their length, even when sent over TCP.</t>
      <t>Unlike UDP queries, a query sent over TCP can be shorter than the response.</t>
      <t>After having received a response from the resolver, the client and the resolver must close the TCP connection. Multiple transactions over the same TCP connections are not allowed by this revision of the protocol.</t>
    </section>
    <section anchor="authenticated-encryption-and-key-exchange-algorithm">
      <name>Authenticated Encryption And Key Exchange Algorithm</name>
      <t>The <tt>Box-XChaChaPoly</tt> construction, and the way to use it described in this section, must be referenced in certificates as version <tt>2</tt> of the public-key authenticated encryption system.</t>
      <t>The construction, originally implemented in the libsodium cryptographic library and exposed under the name "crypto_box_curve25519xchacha20poly1305", uses the Curve25119 elliptic curve in Montgomery form and the <tt>hchacha20</tt> hash function for key exchange, the <tt>XChaCha20</tt> stream cipher, and <tt>Poly1305</tt> for message authentication.</t>
      <t>The public and secret keys are 32 bytes long in storage. The MAC is 16 bytes long, and is prepended to the ciphertext.</t>
      <t>When using <tt>Box-XChaChaPoly</tt>, this construction requires a 24 bytes nonce, that must not be reused for a given shared secret.</t>
      <t>With a 24 bytes nonce, a question sent by a DNSCrypt client must be encrypted using the shared secret, and a nonce constructed as follows: 12 bytes chosen by the client followed by 12 NUL (<tt>0x00</tt>) bytes.</t>
      <t>A response to this question must be encrypted using the shared secret, and a nonce constructed as follows: the bytes originally chosen by the client, followed by bytes chosen by the resolver.</t>
      <t>The resolver's half of the nonce should be randomly chosen.</t>
      <t>The client's half of the nonce can include a timestamp in addition to a counter or to random bytes, so that when a response is received, the client can use this timestamp to immediately discard responses to queries that have been sent too long ago, or dated in the future.</t>
    </section>
    <section anchor="certificates">
      <name>Certificates</name>
      <t>The client begins a DNSCrypt session by sending a regular unencrypted TXT DNS query to the resolver IP address, on the DNSCrypt port, first over UDP, then, in case of failure, timeout or truncation, over TCP.</t>
      <t>Resolvers are not required to serve certificates both on UDP and TCP.</t>
      <t>The name in the question (<tt>&lt;provider name</tt>) must follow this scheme:</t>
      <t><tt>&lt;protocol-major-version&gt; . dnscrypt-cert . &lt;zone&gt;</tt></t>
      <t>A major protocol version has only one certificate format.</t>
      <t>A DNSCrypt client implementing the second version of the protocol must send a query with the TXT type and a name of the form:</t>
      <t><tt>2.dnscrypt-cert.example.com</tt></t>
      <t>The zone must be a valid DNS name, but may not be registered in the DNS hierarchy.</t>
      <t>A single provider name can be shared by multiple resolvers operated by the same entity, and a resolver can respond to multiple provider
names, especially to support multiple protocol versions simultaneously.</t>
      <t>In order to use a DNSCrypt-enabled resolver, a client must know the following information:</t>
      <ul spacing="normal">
        <li>
          <t>The resolver IP address and port</t>
        </li>
        <li>
          <t>The provider name</t>
        </li>
        <li>
          <t>The provider public key</t>
        </li>
      </ul>
      <t>The provider public key is a long-term key whose sole purpose is to verify the certificates. It is never used to encrypt or verify DNS queries. A unique provider public key can be used to sign multiple certificates.</t>
      <t>For example, an organization operating multiple resolvers can use a unique provider name and provider public key across all resolvers,
and just provide a list of IP addresses and ports. Each resolver may have its unique set of certificates that can be signed with the
same key.</t>
      <t>Certificates should be signed on dedicated hardware and not on the resolvers. Resolvers must serve the certificates, provided that they
have already been signed.</t>
      <t>A successful response to certificate request contains one or more <tt>TXT</tt> records, each record containing a certificate encoded as follows:</t>
      <ul spacing="normal">
        <li>
          <t><tt>&lt;cert&gt;</tt>: <tt>&lt;cert-magic&gt; &lt;es-version&gt; &lt;protocol-minor-version&gt; &lt;signature&gt; &lt;resolver-pk&gt; &lt;client-magic&gt; &lt;serial&gt; &lt;ts-start&gt; &lt;ts-end&gt; &lt;extensions&gt;</tt></t>
        </li>
        <li>
          <t><tt>&lt;cert-magic&gt;</tt>: <tt>0x44 0x4e 0x53 0x43</tt></t>
        </li>
        <li>
          <t><tt>&lt;es-version&gt;</tt>: the cryptographic construction to use with this certificate.</t>
        </li>
      </ul>
      <t>For <tt>Box-XChaChaPoly</tt>, <tt>&lt;es-version&gt;</tt> must be <tt>0x00 0x02</tt>.</t>
      <ul spacing="normal">
        <li>
          <t><tt>&lt;protocol-minor-version&gt;</tt>: <tt>0x00 0x00</tt></t>
        </li>
        <li>
          <t><tt>&lt;signature&gt;</tt>: a 64-byte signature of <tt>(&lt;resolver-pk&gt; &lt;client-magic&gt; &lt;serial&gt; &lt;ts-start&gt; &lt;ts-end&gt; &lt;extensions&gt;)</tt> using the Ed25519 algorithm and the provider secret key. Ed25519 must be used in this version of the protocol.</t>
        </li>
        <li>
          <t><tt>&lt;resolver-pk&gt;</tt>: the resolver short-term public key, which is 32 bytes when
using X25519.</t>
        </li>
        <li>
          <t><tt>&lt;client-magic&gt;</tt>: the first 8 bytes of a client query that was built using the information from this certificate. It may be a truncated public key. Two valid certificates cannot share the same <tt>&lt;client-magic&gt;</tt>.</t>
        </li>
        <li>
          <t><tt>&lt;client-magic&gt;</tt> must not start with <tt>0x00 0x00 0x00 0x00 0x00 0x00 0x00</tt>
(seven all-zero bytes) in order to avoid a confusion with the QUIC protocol.</t>
        </li>
        <li>
          <t><tt>&lt;serial&gt;</tt>: a 4 byte serial number in big-endian format. If more than one certificates are valid, the client must prefer the certificate
with a higher serial number.</t>
        </li>
        <li>
          <t><tt>&lt;ts-start&gt;</tt>: the date the certificate is valid from, as a big-endian
4-byte unsigned Unix timestamp.</t>
        </li>
        <li>
          <t><tt>&lt;ts-end&gt;</tt>: the date the certificate is valid until (inclusive), as a
big-endian 4-byte unsigned Unix timestamp.</t>
        </li>
        <li>
          <t><tt>&lt;extensions&gt;</tt>: empty in the current protocol version, but may contain additional data in future revisions, including minor versions. The computation and the verification of the signature must include the extensions. An implementation not supporting these extensions must ignore them.</t>
        </li>
      </ul>
      <t>Certificates made of these information, without extensions, are 116 bytes long. With the addition of the cert-magic, es-version and
protocol-minor-version, the record is 124 bytes long.</t>
      <t>After having received a set of certificates, the client checks their validity based on the current date, filters out the ones designed for encryption systems that are not supported by the client, and chooses the certificate with the higher serial number.</t>
      <t>DNSCrypt queries sent by the client must use the <tt>&lt;client-magic&gt;</tt> header of the chosen certificate, as well as the specified encryption
system and public key.</t>
      <t>The client must check for new certificates every hour, and switch to a new certificate if:</t>
      <ul spacing="normal">
        <li>
          <t>the current certificate is not present or not valid any more</t>
        </li>
      </ul>
      <t>or</t>
      <ul spacing="normal">
        <li>
          <t>a certificate with a higher serial number than the current one is available.</t>
        </li>
      </ul>
    </section>
    <section anchor="implementation-status">
      <name>Implementation Status</name>
      <t><em>This note is to be removed before publishing as an RFC.</em></t>
      <t>Multiple implementations of the protocol described in this document have been developed and verified for interoperability.</t>
      <t>A comprehensive list of known implementations can be found at <eref target="https://dnscrypt.info/implementations"/>.</t>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>DNSCrypt does not protect against attacks on DNS infrastructure.</t>
    </section>
    <section anchor="operational-considerations">
      <name>Operational Considerations</name>
      <t>Special attention should be paid to the uniqueness of the generated secret keys.</t>
      <t>Client public keys can be used by resolvers to authenticate clients, link queries to customer accounts, and unlock business-specific
features such as redirecting specific domain names to a sinkhole.</t>
      <t>Resolvers accessible from any client IP address can also opt for only responding to a set of whitelisted public keys.</t>
      <t>Resolvers accepting queries from any client must accept any client public key. In particular, an anonymous client can generate a new key pair for every session, or even for every query.</t>
      <t>This mitigates the ability for a resolver to group queries by client public keys, and discover the set of IP addresses a user might have been operating.</t>
      <t>Resolvers must rotate the short-term key pair every 24 hours at most, and must throw away the previous secret key.</t>
      <t>After a key rotation, a resolver must still accept all the previous keys that haven't expired.</t>
      <t>Provider public keys may be published as a DNSSEC-signed TXT records, in the same zone as the provider name.</t>
      <t>For example, a query for the TXT type on the name <tt>"2.pubkey.example.com"</tt> may return a signed record containing a hexadecimal-encoded provider public key for the provider name <tt>"2.dnscrypt-cert.example.com"</tt>.</t>
      <t>As a client is likely to reuse the same key pair many times, servers are encouraged to cache shared keys instead of performing the X25519 operation for each query. This makes the computational overhead of DNSCrypt negligible compared to plain DNS.</t>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </section>
    <section anchor="appendix-1-the-box-xchachapoly-algorithm">
      <name>Appendix 1: The Box-XChaChaPoly Algorithm</name>
      <t>The <tt>Box-XChaChaPoly</tt> algorithm combines the <tt>X25519</tt> <xref target="RFC7748"/> key exchange mechanism with a variant of the ChaCha20-Poly1305 constrution defined in <xref target="RFC8439"/>.</t>
      <section anchor="hchacha20">
        <name>HChaCha20</name>
        <t><tt>HChaCha20</tt> is an intermediary step based on the construction and security proof used to create XSalsa20, an extended-nonce Salsa20 variant.</t>
        <t><tt>HChaCha20</tt> is initialized the same way as the <tt>ChaCha20</tt> cipher defined in <xref target="RFC8439"/>, except
that <tt>HChaCha20</tt> uses a 128-bit nonce and has no counter. Instead, the block counter is replaced by the first 32 bits of the nonce.</t>
        <t>Consider the two figures below, where each non-whitespace character
represents one nibble of information about the ChaCha states (all
numbers little-endian):</t>
        <artwork><![CDATA[
                  cccccccc  cccccccc  cccccccc  cccccccc
                  kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
                  kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
                  bbbbbbbb  nnnnnnnn  nnnnnnnn  nnnnnnnn

           ChaCha20 State: c=constant k=key b=blockcount n=nonce


                  cccccccc  cccccccc  cccccccc  cccccccc
                  kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
                  kkkkkkkk  kkkkkkkk  kkkkkkkk  kkkkkkkk
                  nnnnnnnn  nnnnnnnn  nnnnnnnn  nnnnnnnn

                 HChaCha20 State: c=constant k=key n=nonce
]]></artwork>
        <t>After initialization, proceed through the ChaCha rounds as usual.</t>
        <t>Once the 20 ChaCha rounds have been completed, the first 128 bits and last 128 bits of the ChaCha state (both little-endian) are concatenated, and this 256-bit subkey is returned.</t>
      </section>
      <section anchor="test-vector-for-the-hchacha20-block-function">
        <name>Test Vector For The HChaCha20 Block Function</name>
        <artwork><![CDATA[
   o  Key = 00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:
      14:15:16:17:18:19:1a:1b:1c:1d:1e:1f.  The key is a sequence of
      octets with no particular structure before we copy it into the
      HChaCha state.

   o  Nonce = (00:00:00:09:00:00:00:4a:00:00:00:00:31:41:59:27)

   After setting up the HChaCha state, it looks like this:

                    61707865 3320646e 79622d32 6b206574
                    03020100 07060504 0b0a0908 0f0e0d0c
                    13121110 17161514 1b1a1918 1f1e1d1c
                    09000000 4a000000 00000000 27594131

                     ChaCha state with the key setup.

   After running 20 rounds (10 column rounds interleaved with 10
   "diagonal rounds"), the HChaCha state looks like this:

                    423b4182 fe7bb227 50420ed3 737d878a
                    0aa76448 7954cdf3 846acd37 7b3c58ad
                    77e35583 83e77c12 e0076a2d bc6cd0e5
                    d5e4f9a0 53a8748a 13c42ec1 dcecd326

                       HChaCha state after 20 rounds

   HChaCha20 will then return only the first and last rows, in little
   endian, resulting in the following 256-bit key:

                    82413b42 27b27bfe d30e4250 8a877d73
                    a0f9e4d5 8a74a853 c12ec413 26d3ecdc

                        Resultant HChaCha20 subkey
]]></artwork>
      </section>
      <section anchor="chacha20djb">
        <name>ChaCha20_DJB</name>
        <t>ChaCha20 was originally designed to have a 8 byte nonce.</t>
        <t>For the needs of TLS, <xref target="RFC8439"/> changed this to set <tt>N_MIN</tt> and <tt>N_MAX</tt> to <tt>12</tt>, at the expense of a smaller internal counter.</t>
        <t>DNSCrypt uses ChaCha20 as originally specified, with <tt>N_MIN = N_MAX = 8</tt>.</t>
        <t>We refer to this variant as <tt>ChaCha20_DJB</tt>.</t>
        <t>Common implementations may just refer to it as <tt>ChaCha20</tt> and the IETF version as <tt>ChaCha20-IETF</tt>.</t>
        <t>The internal counter in <tt>ChaCha20_DJB</tt> is 4 bytes larger than <tt>ChaCha20</tt>. There are no other differences between <tt>ChaCha20_DJB</tt> and <tt>ChaCha20</tt>.</t>
      </section>
      <section anchor="xchacha20djb">
        <name>XChaCha20_DJB</name>
        <t>XChaCha20_DJB can be constructed from ChaCha20 implementation and HChaCha20.</t>
        <t>All one needs to do is:</t>
        <ol spacing="normal" type="1"><li>
            <t>Pass the key and the first 16 bytes of the 24-byte nonce to <tt>HChaCha20</tt> to obtain the subkey.</t>
          </li>
          <li>
            <t>Use the subkey and remaining 8 byte nonce with <tt>ChaCha20_DJB</tt>.</t>
          </li>
        </ol>
      </section>
      <section anchor="xchacha20djb-poly1305">
        <name>XChaCha20_DJB-Poly1305</name>
        <t>XChaCha20 is a stream cipher and offers no integrity guarantees without being combined with a MAC algorithm (e.g. Poly1305).</t>
        <t><tt>XChaCha20_DJB-Poly1305</tt> adds an authentication tag to ciphertext encrypted with <tt>XChaCha20_DJB</tt>.</t>
        <t>The Poly1305 key is computed as in <xref target="RFC8439"/>, by encrypting an empty block.</t>
        <t>Finally, the output of the Poly1305 function is prepended to the ciphertext:</t>
        <ul spacing="normal">
          <li>
            <t><tt>&lt;k&gt;</tt>: encryption key</t>
          </li>
          <li>
            <t><tt>&lt;m&gt;</tt>: message to encrypt</t>
          </li>
          <li>
            <t><tt>&lt;ct&gt;</tt>: <tt>XChaCha20_DJB(&lt;k&gt;, &lt;m&gt;)</tt></t>
          </li>
          <li>
            <t><tt>XChaCha20_DJB-Poly1305(&lt;k&gt;, &lt;m&gt;)</tt>: <tt>Poly1305(&lt;ct&gt;) || &lt;ct&gt;</tt></t>
          </li>
        </ul>
      </section>
      <section anchor="the-box-xchachapoly-algorithm">
        <name>The Box-XChaChaPoly Algorithm</name>
        <t>The Box-XChaChaPoly algorithm combines the key exchange mechanism X25519 defined <xref target="RFC7748"/> with the <tt>XChaCha20_DJB-Poly1305</tt> authenticated encryption algorithm.</t>
        <ul spacing="normal">
          <li>
            <t><tt>&lt;k&gt;</tt>: encryption key</t>
          </li>
          <li>
            <t><tt>&lt;m&gt;</tt>: message to encrypt</t>
          </li>
          <li>
            <t><tt>&lt;pk&gt;</tt>: recipent's public key</t>
          </li>
          <li>
            <t><tt>&lt;sk&gt;</tt>: sender's secret key</t>
          </li>
          <li>
            <t><tt>&lt;sk'&gt;</tt>: <tt>HChaCha20(X25519(&lt;pk&gt;, &lt;sk&gt;))</tt></t>
          </li>
          <li>
            <t><tt>Box-XChaChaPoly(pk, sk, m)</tt>: <tt>XChaCha20_DJB-Poly1305(&lt;sk'&gt;, &lt;m&gt;)</tt></t>
          </li>
        </ul>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-normative-references">
      <name>Normative References</name>
      <reference anchor="RFC1035" target="https://www.rfc-editor.org/info/rfc1035" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.1035.xml">
        <front>
          <title>Domain names - implementation and specification</title>
          <author fullname="P. Mockapetris" initials="P." surname="Mockapetris"/>
          <date month="November" year="1987"/>
          <abstract>
            <t>This RFC is the revised specification of the protocol and format used in the implementation of the Domain Name System. It obsoletes RFC-883. This memo documents the details of the domain name client - server communication.</t>
          </abstract>
        </front>
        <seriesInfo name="STD" value="13"/>
        <seriesInfo name="RFC" value="1035"/>
        <seriesInfo name="DOI" value="10.17487/RFC1035"/>
      </reference>
      <reference anchor="RFC2119" target="https://www.rfc-editor.org/info/rfc2119" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml">
        <front>
          <title>Key words for use in RFCs to Indicate Requirement Levels</title>
          <author fullname="S. Bradner" initials="S." surname="Bradner"/>
          <date month="March" year="1997"/>
          <abstract>
            <t>In many standards track documents several words are used to signify the requirements in the specification. These words are often capitalized. This document defines these words as they should be interpreted in IETF documents. This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="2119"/>
        <seriesInfo name="DOI" value="10.17487/RFC2119"/>
      </reference>
      <reference anchor="RFC8174" target="https://www.rfc-editor.org/info/rfc8174" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml">
        <front>
          <title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
          <author fullname="B. Leiba" initials="B." surname="Leiba"/>
          <date month="May" year="2017"/>
          <abstract>
            <t>RFC 2119 specifies common key words that may be used in protocol specifications. This document aims to reduce the ambiguity by clarifying that only UPPERCASE usage of the key words have the defined special meanings.</t>
          </abstract>
        </front>
        <seriesInfo name="BCP" value="14"/>
        <seriesInfo name="RFC" value="8174"/>
        <seriesInfo name="DOI" value="10.17487/RFC8174"/>
      </reference>
      <reference anchor="RFC7748" target="https://www.rfc-editor.org/info/rfc7748" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.7748.xml">
        <front>
          <title>Elliptic Curves for Security</title>
          <author fullname="A. Langley" initials="A." surname="Langley"/>
          <author fullname="M. Hamburg" initials="M." surname="Hamburg"/>
          <author fullname="S. Turner" initials="S." surname="Turner"/>
          <date month="January" year="2016"/>
          <abstract>
            <t>This memo specifies two elliptic curves over prime fields that offer a high level of practical security in cryptographic applications, including Transport Layer Security (TLS). These curves are intended to operate at the ~128-bit and ~224-bit security level, respectively, and are generated deterministically based on a list of required properties.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="7748"/>
        <seriesInfo name="DOI" value="10.17487/RFC7748"/>
      </reference>
      <reference anchor="RFC8439" target="https://www.rfc-editor.org/info/rfc8439" xml:base="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8439.xml">
        <front>
          <title>ChaCha20 and Poly1305 for IETF Protocols</title>
          <author fullname="Y. Nir" initials="Y." surname="Nir"/>
          <author fullname="A. Langley" initials="A." surname="Langley"/>
          <date month="June" year="2018"/>
          <abstract>
            <t>This document defines the ChaCha20 stream cipher as well as the use of the Poly1305 authenticator, both as stand-alone algorithms and as a "combined mode", or Authenticated Encryption with Associated Data (AEAD) algorithm.</t>
            <t>RFC 7539, the predecessor of this document, was meant to serve as a stable reference and an implementation guide. It was a product of the Crypto Forum Research Group (CFRG). This document merges the errata filed against RFC 7539 and adds a little text to the Security Considerations section.</t>
          </abstract>
        </front>
        <seriesInfo name="RFC" value="8439"/>
        <seriesInfo name="DOI" value="10.17487/RFC8439"/>
      </reference>
    </references>
  </back>
  <!-- ##markdown-source:
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
XwAA

-->

</rfc>
