<?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.29 (Ruby 3.3.8) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-connolly-cfrg-xwing-kem-07" category="info" consensus="true" submissionType="IRTF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.28.1 -->
  <front>
    <title abbrev="xwing">X-Wing: general-purpose hybrid post-quantum KEM</title>
    <seriesInfo name="Internet-Draft" value="draft-connolly-cfrg-xwing-kem-07"/>
    <author fullname="Deirdre Connolly">
      <organization>SandboxAQ</organization>
      <address>
        <email>durumcrustulum@gmail.com</email>
      </address>
    </author>
    <author fullname="Peter Schwabe">
      <organization>MPI-SP &amp; Radboud University</organization>
      <address>
        <email>peter@cryptojedi.org</email>
      </address>
    </author>
    <author initials="B. E." surname="Westerbaan" fullname="Bas Westerbaan">
      <organization>Cloudflare</organization>
      <address>
        <email>bas@cloudflare.com</email>
      </address>
    </author>
    <date year="2025" month="May" day="03"/>
    <area>IRTF</area>
    <workgroup>Crypto Forum</workgroup>
    <keyword>post quantum</keyword>
    <keyword>kem</keyword>
    <keyword>PQ/T hybrid</keyword>
    <abstract>
      <?line 114?>

<t>This memo defines X-Wing, a general-purpose post-quantum/traditional
hybrid key encapsulation mechanism (PQ/T KEM) built on X25519 and
ML-KEM-768.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://dconnolly.github.io/draft-connolly-cfrg-xwing-kem/draft-connolly-cfrg-xwing-kem.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-connolly-cfrg-xwing-kem/"/>.
      </t>
      <t>
        Discussion of this document takes place on the
        Crypto Forum Research Group mailing list (<eref target="mailto:cfrg@ietf.org"/>),
        which is archived at <eref target="https://mailarchive.ietf.org/arch/search/?email_list=cfrg"/>.
        Subscribe at <eref target="https://www.ietf.org/mailman/listinfo/cfrg/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/dconnolly/draft-connolly-cfrg-xwing-kem"/>.</t>
    </note>
  </front>
  <middle>
    <?line 120?>

<section anchor="intro">
      <name>Introduction</name>
      <section anchor="motivation">
        <name>Motivation</name>
        <t>There are many choices that can be made when specifying a hybrid KEM:
the constituent KEMs; their security levels; the combiner; and the hash
within, to name but a few. Having too many similar options are a burden
to the ecosystem.</t>
        <t>The aim of X-Wing is to provide a concrete, simple choice for
post-quantum hybrid KEM, that should be suitable for the vast majority
of use cases.</t>
      </section>
      <section anchor="goals">
        <name>Design goals</name>
        <t>By making concrete choices, we can simplify and improve many aspects of
X-Wing.</t>
        <ul spacing="normal">
          <li>
            <t>Simplicity of definition. Because all shared secrets and cipher texts
are fixed length, we do not need to encode the length. Using SHA3-256,
we do not need HMAC-based construction. For the concrete choice of
ML-KEM-768, we do not need to mix in its ciphertext, see <xref target="secc"/>.</t>
          </li>
          <li>
            <t>Security analysis. Because ML-KEM-768 already assumes the Quantum Random
Oracle Model (QROM), we do not need to complicate the analysis
of X-Wing by considering stronger models.</t>
          </li>
          <li>
            <t>Performance. Not having to mix in the ML-KEM-768 ciphertext is a nice
performance benefit. Furthermore, by using SHA3-256 in the combiner,
which matches the hashing in ML-KEM-768, this hash can be computed in
one go on platforms where two-way Keccak is available.</t>
          </li>
        </ul>
        <t>We aim for "128 bits" security (NIST PQC level 1). Although at the
moment there is no peer-reviewed evidence that ML-KEM-512 does not reach
this level, we would like to hedge against future cryptanalytic
improvements, and feel ML-KEM-768 provides a comfortable margin.</t>
        <t>We aim for X-Wing to be usable for most applications, including
specifically HPKE <xref target="RFC9180"/>.</t>
      </section>
      <section anchor="not-an-interactive-key-agreement">
        <name>Not an interactive key-agreement</name>
        <t>Traditionally most protocols use a Diffie-Hellman (DH) style
non-interactive key-agreement.  In many cases, a DH key agreement can be
replaced by the interactive key-agreement afforded by a KEM without
change in the protocol flow.  One notable example is TLS <xref target="HYBRID"/>
          <xref target="XYBERTLS"/>.  However, not all uses of DH can be replaced in a
straight-forward manner by a plain KEM.</t>
      </section>
      <section anchor="auth">
        <name>Not an authenticated KEM</name>
        <t>In particular, X-Wing is not, borrowing the language of <xref target="RFC9180"/>, an
<em>authenticated</em> KEM.</t>
      </section>
      <section anchor="comparisons">
        <name>Comparisons</name>
        <section anchor="with-hpke-x25519kyber768draft00">
          <name>With HPKE X25519Kyber768Draft00</name>
          <t>X-Wing is most similar to HPKE's X25519Kyber768Draft00
<xref target="XYBERHPKE"/>. The key differences are:</t>
          <ul spacing="normal">
            <li>
              <t>X-Wing uses the final version of ML-KEM-768.</t>
            </li>
            <li>
              <t>X-Wing hashes the shared secrets, to be usable outside of HPKE.</t>
            </li>
            <li>
              <t>X-Wing has a simpler combiner by flattening DHKEM(X25519) into the
final hash.</t>
            </li>
            <li>
              <t>X-Wing does not hash in the ML-KEM-768 ciphertext.</t>
            </li>
          </ul>
          <t>There is also a different KEM called X25519Kyber768Draft00 <xref target="XYBERTLS"/>
which is used in TLS. This one should not be used outside of TLS, as it
assumes the presence of the TLS transcript to ensure non malleability.</t>
        </section>
        <section anchor="with-generic-combiner">
          <name>With generic combiner</name>
          <t>The generic combiner of <xref target="I-D.ounsworth-cfrg-kem-combiners"/> can be
instantiated with ML-KEM-768 and DHKEM(X25519). That achieves similar
security, but:</t>
          <ul spacing="normal">
            <li>
              <t>X-Wing is more performant, not hashing in the ML-KEM-768 ciphertext,
and flattening the DHKEM construction, with the same level of
security.</t>
            </li>
            <li>
              <t>X-Wing has a fixed 32 byte shared secret, instead of a variable shared
secret.</t>
            </li>
            <li>
              <t>X-Wing does not accept the optional counter and fixedInfo arguments.</t>
            </li>
          </ul>
        </section>
      </section>
    </section>
    <section anchor="requirements-notation">
      <name>Requirements Notation</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?>

</section>
    <section anchor="conventions-and-definitions">
      <name>Conventions and Definitions</name>
      <t>This document is consistent with all terminology defined in
<xref target="I-D.driscoll-pqt-hybrid-terminology"/>.</t>
      <t>The following terms are used throughout this document to describe these operations:</t>
      <ul spacing="normal">
        <li>
          <t><tt>concat(x0, ..., xN)</tt>: returns the concatenation of byte
strings. <tt>concat(0x01, 0x0203, 0x040506) = 0x010203040506</tt>.</t>
        </li>
        <li>
          <t><tt>random(n)</tt>: returns a byte string of length <tt>n</tt> bytes produced by
a cryptographically-secure pseudorandom number generator.</t>
        </li>
      </ul>
    </section>
    <section anchor="base-crypto">
      <name>Cryptographic Dependencies</name>
      <t>X-Wing relies on the following primitives:</t>
      <ul spacing="normal">
        <li>
          <t>ML-KEM-768 post-quantum key-encapsulation mechanism (KEM) <xref target="MLKEM"/>:  </t>
          <ul spacing="normal">
            <li>
              <t><tt>ML-KEM-768.KeyGen_internal(d, z)</tt>: Deterministic algorithm to generate an
ML-KEM-768 key pair <tt>(pk_M, sk_M)</tt> of an encapsulation key <tt>pk_M</tt>
and decapsulation key <tt>sk_M</tt>.
It is the derandomized version of <tt>ML-KEM-768.KeyGen</tt>.
Note that <tt>ML-KEM-768.KeyGen_internal()</tt> returns the keys in reverse
order of <tt>GenerateKeyPair()</tt> defined below.
<tt>d</tt> and <tt>z</tt> are both 32 byte strings.</t>
            </li>
            <li>
              <t><tt>ML-KEM-768.Encaps(pk_M)</tt>: Randomized algorithm to generate <tt>(ss_M,
ct_M)</tt>, an ephemeral 32 byte shared key <tt>ss_M</tt>, and a fixed-length
encapsulation (ciphertext) of that key <tt>ct_M</tt> for encapsulation key <tt>pk_M</tt>.      </t>
              <t><tt>ML-KEM-768.Encaps(pk_M)</tt> <bcp14>MUST</bcp14> perform the encapsulation key check
of <xref target="MLKEM"/> §7.2 and raise an error if it fails.</t>
            </li>
            <li>
              <t><tt>ML-KEM-768.Decap(ct_M, sk_M)</tt>: Deterministic algorithm using the
decapsulation key <tt>sk_M</tt> to recover the shared key from <tt>ct_M</tt>.      </t>
              <t><tt>ML-KEM-768.Decap(ct_M, sk_M)</tt> is NOT required  to perform the
decapsulation key check of <xref target="MLKEM"/> §7.3.</t>
            </li>
          </ul>
          <t>
To generate deterministic test vectors, we also use  </t>
          <ul spacing="normal">
            <li>
              <t><tt>ML-KEM-768.Encaps_internal(pk_M, m)</tt>: Algorithm to generate <tt>(ss_M, ct_M)</tt>,
an ephemeral 32 byte shared key <tt>ss_M</tt>, and a fixed-length
encapsulation (ciphertext) of that key <tt>ct_M</tt> for encapsulation key
<tt>pk_M</tt>. <tt>m</tt> is a 32 byte string.      </t>
              <t><tt>ML-KEM-768.Encaps_internal(pk_M)</tt> <bcp14>MUST</bcp14> perform the encapsulation key check
of <xref target="MLKEM"/> §7.2 and raise an error if it fails.</t>
            </li>
          </ul>
        </li>
        <li>
          <t>X25519 elliptic curve Diffie-Hellman key-exchange defined in <xref section="5" sectionFormat="of" target="RFC7748"/>:  </t>
          <ul spacing="normal">
            <li>
              <t><tt>X25519(k, u)</tt>: takes 32 byte strings k and u representing a
Curve25519 scalar and the u-coordinate of a point respectively, and returns
the 32 byte string representing the u-coordinate of their scalar multiplication.</t>
            </li>
            <li>
              <t><tt>X25519_BASE</tt>: the 32 byte string representing the standard base point
of Curve25519. In hexadecimal,
it is given by <tt>0900000000000000000000000000000000000000000000000000000000000000</tt>.</t>
            </li>
          </ul>
        </li>
      </ul>
      <t>Note that 9 is the standard basepoint for X25519, cf <xref section="6.1" sectionFormat="of" target="RFC7748"/>.</t>
      <ul spacing="normal">
        <li>
          <t>Symmetric cryptography.  </t>
          <ul spacing="normal">
            <li>
              <t><tt>SHAKE256(message, outlen)</tt>: The extendable-output function (XOF)
with that name defined in Section 6.2 of <xref target="FIPS202"/>. Note that
outlen counts bits.</t>
            </li>
            <li>
              <t><tt>SHA3-256(message)</tt>: The hash with that name
defined in Section 6.1 of <xref target="FIPS202"/>.</t>
            </li>
          </ul>
        </li>
      </ul>
    </section>
    <section anchor="x-wing-construction">
      <name>X-Wing Construction</name>
      <section anchor="encoding">
        <name>Encoding and sizes</name>
        <t>X-Wing encapsulation key, decapsulation key, ciphertexts and shared secrets are all
fixed-length byte strings.</t>
        <dl>
          <dt>Decapsulation key (private):</dt>
          <dd>
            <t>32 bytes</t>
          </dd>
          <dt>Encapsulation key (public):</dt>
          <dd>
            <t>1216 bytes</t>
          </dd>
          <dt>Ciphertext:</dt>
          <dd>
            <t>1120 bytes</t>
          </dd>
          <dt>Shared secret:</dt>
          <dd>
            <t>32 bytes</t>
          </dd>
        </dl>
      </section>
      <section anchor="key-generation">
        <name>Key generation</name>
        <t>An X-Wing keypair (decapsulation key, encapsulation key) is generated as
follows.</t>
        <artwork><![CDATA[
def expandDecapsulationKey(sk):
  expanded = SHAKE256(sk, 96*8) # expand sk to 96 bytes using SHAKE256
  (pk_M, sk_M) = ML-KEM-768.KeyGen_internal(expanded[0:32], expanded[32:64])
  sk_X = expanded[64:96]
  pk_X = X25519(sk_X, X25519_BASE)
  return (sk_M, sk_X, pk_M, pk_X)

def GenerateKeyPair():
  sk = random(32)
  (sk_M, sk_X, pk_M, pk_X) = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_X)
]]></artwork>
        <t><tt>GenerateKeyPair()</tt> returns the 32 byte secret decapsulation key <tt>sk</tt>
and the 1216 byte encapsulation key <tt>pk</tt>.</t>
        <t>Here and in the balance of the document for clarity we use
the <tt>M</tt> and <tt>X</tt> subscripts for ML-KEM-768 and X25519 components respectively.</t>
        <section anchor="derive-key-pair">
          <name>Key derivation</name>
          <t>For testing, it is convenient to have a deterministic version
of key generation. An X-Wing implementation <bcp14>MAY</bcp14> provide the following
derandomized variant of key generation.</t>
          <artwork><![CDATA[
def GenerateKeyPairDerand(sk):
  sk_M, sk_X, pk_M, pk_X = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_X)
]]></artwork>
          <t><tt>sk</tt> must be 32 bytes.</t>
          <t><tt>GenerateKeyPairDerand()</tt> returns the 32 byte secret encapsulation key
<tt>sk</tt> and the 1216 byte decapsulation key <tt>pk</tt>.</t>
        </section>
      </section>
      <section anchor="combiner">
        <name>Combiner</name>
        <t>Given 32 byte strings <tt>ss_M</tt>, <tt>ss_X</tt>, <tt>ct_X</tt>, <tt>pk_X</tt>, representing the
ML-KEM-768 shared secret, X25519 shared secret, X25519 ciphertext
(ephemeral public key) and X25519 public key respectively, the 32 byte
combined shared secret is given by:</t>
        <artwork><![CDATA[
def Combiner(ss_M, ss_X, ct_X, pk_X):
  return SHA3-256(concat(
    ss_M,
    ss_X,
    ct_X,
    pk_X,
    XWingLabel
  ))
]]></artwork>
        <t>where XWingLabel is the following 6 byte ASCII string</t>
        <artwork><![CDATA[
XWingLabel = concat(
    "\./",
    "/^\",
)
]]></artwork>
        <t>In hexadecimal, XWingLabel is given by <tt>5c2e2f2f5e5c</tt>.</t>
      </section>
      <section anchor="encaps">
        <name>Encapsulation</name>
        <t>Given an X-Wing encapsulation key <tt>pk</tt>, encapsulation proceeds as follows.</t>
        <artwork><![CDATA[
def Encapsulate(pk):
  pk_M = pk[0:1184]
  pk_X = pk[1184:1216]
  ek_X = random(32)
  ct_X = X25519(ek_X, X25519_BASE)
  ss_X = X25519(ek_X, pk_X)
  (ss_M, ct_M) = ML-KEM-768.Encaps(pk_M)
  ss = Combiner(ss_M, ss_X, ct_X, pk_X)
  ct = concat(ct_M, ct_X)
  return (ss, ct)
]]></artwork>
        <t><tt>pk</tt> is a 1216 byte X-Wing encapsulation key resulting from <tt>GeneratePublicKey()</tt></t>
        <t><tt>Encapsulate()</tt> returns the 32 byte shared secret <tt>ss</tt> and the 1120 byte
ciphertext <tt>ct</tt>.</t>
        <t>Note that <tt>Encapsulate()</tt> may raise an error if the ML-KEM encapsulation
does not pass the check of <xref target="MLKEM"/> §7.2.</t>
        <section anchor="derandomized">
          <name>Derandomized</name>
          <t>For testing, it is convenient to have a deterministic version
of encapsulation. An X-Wing implementation <bcp14>MAY</bcp14> provide
the following derandomized function.</t>
          <artwork><![CDATA[
def EncapsulateDerand(pk, eseed):
  pk_M = pk[0:1184]
  pk_X = pk[1184:1216]
  ek_X = eseed[32:64]
  ct_X = X25519(ek_X, X25519_BASE)
  ss_X = X25519(ek_X, pk_X)
  (ss_M, ct_M) = ML-KEM-768.EncapsDerand(pk_M, eseed[0:32])
  ss = Combiner(ss_M, ss_X, ct_X, pk_X)
  ct = concat(ct_M, ct_X)
  return (ss, ct)
]]></artwork>
          <t><tt>pk</tt> is a 1216 byte X-Wing encapsulation key resulting from <tt>GeneratePublicKey()</tt>
            <tt>eseed</tt> <bcp14>MUST</bcp14> be 64 bytes.</t>
          <t><tt>EncapsulateDerand()</tt> returns the 32 byte shared secret <tt>ss</tt> and the 1120 byte
ciphertext <tt>ct</tt>.</t>
        </section>
      </section>
      <section anchor="decaps">
        <name>Decapsulation</name>
        <artwork><![CDATA[
def Decapsulate(ct, sk):
  (sk_M, sk_X, pk_M, pk_X) = expandDecapsulationKey(sk)
  ct_M = ct[0:1088]
  ct_X = ct[1088:1120]
  ss_M = ML-KEM-768.Decapsulate(ct_M, sk_M)
  ss_X = X25519(sk_X, ct_X)
  return Combiner(ss_M, ss_X, ct_X, pk_X)
]]></artwork>
        <t><tt>ct</tt> is the 1120 byte ciphertext resulting from <tt>Encapsulate()</tt>
          <tt>sk</tt> is a 32 byte X-Wing decapsulation key resulting from <tt>GenerateKeyPair()</tt></t>
        <t><tt>Decapsulate()</tt> returns the 32 byte shared secret.</t>
        <section anchor="keeping-expanded-decapsulation-key-around">
          <name>Keeping expanded decapsulation key around</name>
          <t>For efficiency, an implementation <bcp14>MAY</bcp14> cache the result of <tt>expandDecapsulationKey</tt>.
This is useful in two cases:</t>
          <ol spacing="normal" type="1"><li>
              <t>If multiple ciphertexts for the same key are decapsulated.</t>
            </li>
            <li>
              <t>If a ciphertext is decapsulated for a key that has just been generated.
This happen on the client-side for TLS.</t>
            </li>
          </ol>
          <t>A typical API pattern to achieve this optimization is to have an
opaque decapsulation key object that hides the cached values.
For instance, such an API could have the following functions.</t>
          <ol spacing="normal" type="1"><li>
              <t><tt>GenerateKeyPair()</tt> returns an encapsulation key and an opaque
 object that contains the expanded decapsulation key.</t>
            </li>
            <li>
              <t><tt>Decapsulate(ct, esk)</tt> takes a ciphertext and an expanded decapsulation key.</t>
            </li>
            <li>
              <t><tt>PackDecapsulationKey(sk)</tt> takes an expanded decapsulation key,
 and returns the packed decapsulation key.</t>
            </li>
            <li>
              <t><tt>UnpackDecapsulationKey(sk)</tt> takes a packed decapsulation key, and returns
 the expanded decapsulation key. In the case of X-Wing this would
 be the same as a derandomized <tt>GenerateKeyPair()</tt>.</t>
            </li>
          </ol>
          <t>The expanded decapsulation key could cache even more computation,
such as the expanded matrix A in ML-KEM.</t>
          <t>Any such expanded decapsulation key <bcp14>MUST NOT</bcp14> be transmitted between
implementations, as this could break the security analysis of X-Wing.
In particular, the MAL-BIND-K-PK and MAL-BIND-K-CT binding
properties of X-Wing do not hold when transmitting the regular ML-KEM
decapsulation key.</t>
        </section>
      </section>
      <section anchor="use-in-hpke">
        <name>Use in HPKE</name>
        <t>X-Wing satisfies the HPKE KEM interface as follows.</t>
        <t>The <tt>SerializePublicKey</tt>, <tt>SerializePrivateKey</tt>,
and <tt>DeserializePrivateKey</tt> are the identity functions,
as X-Wing keys are fixed-length byte strings, see <xref target="encoding"/>.</t>
        <t><tt>DeriveKeyPair()</tt> is given by</t>
        <artwork><![CDATA[
def DeriveKeyPair(ikm):
  # Extract 32-byte seed from variable-length ikm using SHAKE.
  sk = SHAKE256(ikm, 32*8)
  return GenerateKeyPairDerand(sk)
]]></artwork>
        <t>where the HPKE private key and public key are the X-Wing decapsulation
key and encapsulation key respectively.</t>
        <t><tt>Encap()</tt> is <tt>Encapsulate()</tt> from <xref target="encaps"/>, where an
ML-KEM encapsulation key check failure causes an HPKE <tt>EncapError</tt>.</t>
        <t><tt>Decap()</tt> is <tt>Decapsulate()</tt> from <xref target="decaps"/>.</t>
        <t>X-Wing is not an authenticated KEM: it does not support <tt>AuthEncap()</tt>
and <tt>AuthDecap()</tt>, see <xref target="auth"/>.</t>
        <t>Nsecret, Nenc, Npk, and Nsk are defined in <xref target="iana"/>.</t>
      </section>
      <section anchor="use-in-tls-13">
        <name>Use in TLS 1.3</name>
        <t>For the client's share, the key_exchange value contains
the X-Wing encapsulation key.</t>
        <t>For the server's share, the key_exchange value contains
the X-Wing ciphertext.</t>
        <t>On ML-KEM encapsulation key check failure, the server <bcp14>MUST</bcp14>
abort with an illegal_parameter alert.</t>
      </section>
      <section anchor="use-in-x509-public-key-infrastructure">
        <name>Use in X.509 Public Key Infrastructure</name>
        <t>We use the OID 1.3.6.1.4.1.62253.25722 to identify X-Wing keys
as described below. In ASN.1 notation:</t>
        <artwork><![CDATA[
id-XWing OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
        dod(6) internet(1) private(4) enterprise(1) 62253 25722 }
]]></artwork>
        <section anchor="certificate">
          <name>Certificate</name>
          <t>In a X.509 certificate, the subjectPublicKeyInfo field
has the SubjectPublicKeyInfo type, which has the following ASN.1 syntax.</t>
          <artwork><![CDATA[
SubjectPublicKeyInfo  ::=  SEQUENCE  {
      algorithm         AlgorithmIdentifier,
      subjectPublicKey  BIT STRING
  }

AlgorithmIdentifier{ALGORITHM-TYPE, ALGORITHM-TYPE:AlgorithmSet} ::=
  SEQUENCE {
    algorithm   ALGORITHM-TYPE."&"id({AlgorithmSet}),
    parameters  ALGORITHM-TYPE.
                  "&"Params({AlgorithmSet}{@algorithm}) OPTIONAL
  }
]]></artwork>
          <t>An X-Wing encapsulation key <bcp14>MUST</bcp14> be encoded directly
using the ASN.1 type XWingPublicKey.</t>
          <artwork><![CDATA[
XWingPublicKey ::= OCTET STRING
]]></artwork>
          <t>The X-Wing encapsulation key is mapped to a subjectPublicKey (a
value of type BIT STRING) as follows: the most significant bit of
the OCTET STRING value becomes the most significant bit of the BIT
STRING value, and so on; the least significant bit of the OCTET
STRING becomes the least significant bit of the BIT STRING.</t>
          <t>The id-XWing identifier <bcp14>MUST</bcp14> be used as the algorithm field in
the SubjectPublicKeyInfo to identify an X-Wing encapsulation key.</t>
          <t>The contents of the parameters component <bcp14>MUST</bcp14> be absent.</t>
        </section>
        <section anchor="private-key">
          <name>Private key</name>
          <t>Below we replicate part of the definition of OneAsymmetricKey
from <xref target="RFC5958"/>.</t>
          <artwork><![CDATA[
OneAsymmetricKey ::= SEQUENCE {
  version                  Version,
  privateKeyAlgorithm      SEQUENCE {
  algorithm                PUBLIC-KEY.&id({PublicKeySet}),
  parameters               PUBLIC-KEY.&Params({PublicKeySet}
                             {@privateKeyAlgorithm.algorithm})
                                OPTIONAL}
  privateKey               OCTET STRING (CONTAINING
                             PUBLIC-KEY.&PrivateKey({PublicKeySet}
                               {@privateKeyAlgorithm.algorithm})),
  attributes           [0] Attributes OPTIONAL,
  ...,
  [[2: publicKey       [1] BIT STRING (CONTAINING
                             PUBLIC-KEY.&Params({PublicKeySet}
                               {@privateKeyAlgorithm.algorithm})
                               OPTIONAL,
  ...
}
]]></artwork>
          <t>When storing an X-Wing decapsulation key in a OneAsymmetricKey,
the privateKey OCTET STRING contains the raw octet string encoding
the X-Wing decapsulation key.</t>
          <t>The id-XWing identifier <bcp14>MUST</bcp14> be used as the algorithm field in
the OneAsymmetricKey to identify an X-Wing decapsulation key.</t>
          <t>The publicKey component <bcp14>MUST</bcp14> be absent.</t>
        </section>
      </section>
    </section>
    <section anchor="secc">
      <name>Security Considerations</name>
      <t>Informally, X-Wing is secure if SHA3 is secure, and either X25519 is
secure, or ML-KEM-768 is secure.</t>
      <t>More precisely, if SHA3-256, SHA3-512, and SHAKE-256 may be
modelled as a random oracle, then the IND-CCA security of X-Wing is
bounded by the IND-CCA security of ML-KEM-768, and the gap-CDH security
of Curve25519, see <xref target="PROOF"/>.</t>
      <t>The security of X-Wing relies crucially on the specifics of the
Fujisaki-Okamoto transformation used in ML-KEM-768: the X-Wing
combiner cannot be assumed to be secure, when used with different
KEMs. In particular it is not known to be safe to leave
out the post-quantum ciphertext from the combiner in the general case.</t>
      <section anchor="binding-properties">
        <name>Binding properties</name>
        <t>Some protocols rely on further properties of the KEM.
X-Wing satisfies the binding properties MAL-BIND-K-PK and MAL-BIND-K-CT
(TODO: reference to proof).
This implies <xref target="KSMW"/> X-Wing also satisfies</t>
        <ul spacing="normal">
          <li>
            <t>MAL-BIND-K,CT-PK</t>
          </li>
          <li>
            <t>MAL-BIND-K,PK-CT</t>
          </li>
          <li>
            <t>LEAK-BIND-K-PK</t>
          </li>
          <li>
            <t>LEAK-BIND-K-CT</t>
          </li>
          <li>
            <t>LEAK-BIND-K,CT-PK</t>
          </li>
          <li>
            <t>LEAK-BIND-K,PK-CT</t>
          </li>
          <li>
            <t>HON-BIND-K-PK</t>
          </li>
          <li>
            <t>HON-BIND-K-CT</t>
          </li>
          <li>
            <t>HON-BIND-K,CT-PK</t>
          </li>
          <li>
            <t>HON-BIND-K,PK-CT</t>
          </li>
        </ul>
        <t>In contrast, ML-KEM on its own does not achieve
MAL-BIND-K-PK, MAL-BIND-K-CT, nor MAL-BIND-K,PK-CT. <xref target="SCHMIEG"/></t>
      </section>
    </section>
    <section anchor="iana">
      <name>IANA Considerations</name>
      <t>This document requests/registers a new entry to the "HPKE KEM Identifiers"
registry.</t>
      <dl>
        <dt>Value:</dt>
        <dd>
          <t>25722 = 25519 + 203 = 0x647a (please)</t>
        </dd>
        <dt>KEM:</dt>
        <dd>
          <t>X-Wing</t>
        </dd>
        <dt>Nsecret:</dt>
        <dd>
          <t>32</t>
        </dd>
        <dt>Nenc:</dt>
        <dd>
          <t>1120</t>
        </dd>
        <dt>Npk:</dt>
        <dd>
          <t>1216</t>
        </dd>
        <dt>Nsk:</dt>
        <dd>
          <t>32</t>
        </dd>
        <dt>Auth:</dt>
        <dd>
          <t>no</t>
        </dd>
        <dt>Reference:</dt>
        <dd>
          <t>This document</t>
        </dd>
      </dl>
      <t>Furthermore, this document requests/registers a new entry to the TLS
Named Group (or Supported Group) registry, according to the procedures
in <xref section="6" sectionFormat="of" target="TLSIANA"/>.</t>
      <dl>
        <dt>Value:</dt>
        <dd>
          <t>25722 = 25519 + 203 = 0x647a (please)</t>
        </dd>
        <dt>Description:</dt>
        <dd>
          <t>X-Wing</t>
        </dd>
        <dt>DTLS-OK:</dt>
        <dd>
          <t>Y</t>
        </dd>
        <dt>Recommended:</dt>
        <dd>
          <t>N</t>
        </dd>
        <dt>Reference:</dt>
        <dd>
          <t>This document</t>
        </dd>
        <dt>Comment:</dt>
        <dd>
          <t>PQ/T hybrid of X25519 and ML-KEM-768</t>
        </dd>
      </dl>
      <t>Finally, for the ASN.1 module in {asn1}, IANA is requested to assign
an object identifier (OID) for the module identifier (TBD) with a
Description of "id-mod-XWing-kem-2024".</t>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="RFC2119">
          <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="X680" target="https://www.itu.int/rec/T-REC-X.680">
          <front>
            <title>Information Technology -- Abstract Syntax Notation One (ASN.1): Specification of basic notation</title>
            <author>
              <organization>ITU-T</organization>
            </author>
            <date year="2021" month="February"/>
          </front>
          <seriesInfo name="ITU-T Recommendation" value="X.680"/>
          <seriesInfo name="ISO/IEC" value="8824-1:2021"/>
        </reference>
        <reference anchor="RFC8174">
          <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="RFC5958">
          <front>
            <title>Asymmetric Key Packages</title>
            <author fullname="S. Turner" initials="S." surname="Turner"/>
            <date month="August" year="2010"/>
            <abstract>
              <t>This document defines the syntax for private-key information and a content type for it. Private-key information includes a private key for a specified public-key algorithm and a set of attributes. The Cryptographic Message Syntax (CMS), as defined in RFC 5652, can be used to digitally sign, digest, authenticate, or encrypt the asymmetric key format content type. This document obsoletes RFC 5208. [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5958"/>
          <seriesInfo name="DOI" value="10.17487/RFC5958"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="I-D.driscoll-pqt-hybrid-terminology">
          <front>
            <title>Terminology for Post-Quantum Traditional Hybrid Schemes</title>
            <author fullname="Flo D" initials="F." surname="D">
              <organization>UK National Cyber Security Centre</organization>
            </author>
            <date day="7" month="March" year="2023"/>
            <abstract>
              <t>   One aspect of the transition to post-quantum algorithms in
   cryptographic protocols is the development of hybrid schemes that
   incorporate both post-quantum and traditional asymmetric algorithms.
   This document defines terminology for such schemes.  It is intended
   to be used as a reference and, hopefully, to ensure consistency and
   clarity across different protocols, standards, and organisations.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-driscoll-pqt-hybrid-terminology-02"/>
        </reference>
        <reference anchor="I-D.ounsworth-cfrg-kem-combiners">
          <front>
            <title>Combiner function for hybrid key encapsulation mechanisms (Hybrid KEMs)</title>
            <author fullname="Mike Ounsworth" initials="M." surname="Ounsworth">
              <organization>Entrust Limited</organization>
            </author>
            <author fullname="Aron Wussler" initials="A." surname="Wussler">
              <organization>Proton AG</organization>
            </author>
            <author fullname="Stavros Kousidis" initials="S." surname="Kousidis">
              <organization>BSI</organization>
            </author>
            <date day="31" month="January" year="2024"/>
            <abstract>
              <t>   The migration to post-quantum cryptography often calls for performing
   multiple key encapsulations in parallel and then combining their
   outputs to derive a single shared secret.

   This document defines a comprehensible and easy to implement Keccak-
   based KEM combiner to join an arbitrary number of key shares, that is
   compatible with NIST SP 800-56Cr2 [SP800-56C] when viewed as a key
   derivation function.  The combiners defined here are practical split-
   key PRFs and are CCA-secure as long as at least one of the ingredient
   KEMs is.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ounsworth-cfrg-kem-combiners-05"/>
        </reference>
        <reference anchor="FIPS202" target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf">
          <front>
            <title>FIPS 202: SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions</title>
            <author initials="" surname="National Institute of Standards and Technology">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="MLKEM" target="https://nvlpubs.nist.gov/nistpubs/fips/nist.fips.203.pdf">
          <front>
            <title>FIPS 203: Module-Lattice-Based Key-Encapsulation Mechanism Standard</title>
            <author initials="" surname="National Institute of Standards and Technology">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="RFC9180">
          <front>
            <title>Hybrid Public Key Encryption</title>
            <author fullname="R. Barnes" initials="R." surname="Barnes"/>
            <author fullname="K. Bhargavan" initials="K." surname="Bhargavan"/>
            <author fullname="B. Lipp" initials="B." surname="Lipp"/>
            <author fullname="C. Wood" initials="C." surname="Wood"/>
            <date month="February" year="2022"/>
            <abstract>
              <t>This document describes a scheme for hybrid public key encryption (HPKE). This scheme provides a variant of public key encryption of arbitrary-sized plaintexts for a recipient public key. It also includes three authenticated variants, including one that authenticates possession of a pre-shared key and two optional ones that authenticate possession of a key encapsulation mechanism (KEM) private key. HPKE works for any combination of an asymmetric KEM, key derivation function (KDF), and authenticated encryption with additional data (AEAD) encryption function. Some authenticated variants may not be supported by all KEMs. We provide instantiations of the scheme using widely used and efficient primitives, such as Elliptic Curve Diffie-Hellman (ECDH) key agreement, HMAC-based key derivation function (HKDF), and SHA2.</t>
              <t>This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9180"/>
          <seriesInfo name="DOI" value="10.17487/RFC9180"/>
        </reference>
        <reference anchor="RFC7748">
          <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="HYBRID">
          <front>
            <title>Hybrid key exchange in TLS 1.3</title>
            <author fullname="Douglas Stebila" initials="D." surname="Stebila">
              <organization>University of Waterloo</organization>
            </author>
            <author fullname="Scott Fluhrer" initials="S." surname="Fluhrer">
              <organization>Cisco Systems</organization>
            </author>
            <author fullname="Shay Gueron" initials="S." surname="Gueron">
              <organization>University of Haifa and Amazon Web Services</organization>
            </author>
            <date day="12" month="February" year="2020"/>
            <abstract>
              <t>   Hybrid key exchange refers to using multiple key exchange algorithms
   simultaneously and combining the result with the goal of providing
   security even if all but one of the component algorithms is broken.
   It is motivated by transition to post-quantum cryptography.  This
   document provides a construction for hybrid key exchange in the
   Transport Layer Security (TLS) protocol version 1.3.

   Discussion of this work is encouraged to happen on the TLS IETF
   mailing list tls@ietf.org or on the GitHub repository which contains
   the draft: https://github.com/dstebila/draft-stebila-tls-hybrid-
   design.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-stebila-tls-hybrid-design-03"/>
        </reference>
        <reference anchor="XYBERHPKE">
          <front>
            <title>X25519Kyber768Draft00 hybrid post-quantum KEM for HPKE</title>
            <author fullname="Bas Westerbaan" initials="B." surname="Westerbaan">
              <organization>Cloudflare</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare</organization>
            </author>
            <date day="14" month="May" year="2024"/>
            <abstract>
              <t>   This memo defines X25519Kyber768Draft00, a hybrid post-quantum KEM,
   for HPKE (RFC9180).  This KEM does not support the authenticated
   modes of HPKE.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-westerbaan-cfrg-hpke-xyber768d00-03"/>
        </reference>
        <reference anchor="XYBERTLS">
          <front>
            <title>X25519Kyber768Draft00 hybrid post-quantum key agreement</title>
            <author fullname="Bas Westerbaan" initials="B." surname="Westerbaan">
              <organization>Cloudflare</organization>
            </author>
            <author fullname="Douglas Stebila" initials="D." surname="Stebila">
              <organization>University of Waterloo</organization>
            </author>
            <date day="24" month="September" year="2023"/>
            <abstract>
              <t>   This memo defines X25519Kyber768Draft00, a hybrid post-quantum key
   exchange for TLS 1.3.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-tls-westerbaan-xyber768d00-03"/>
        </reference>
        <reference anchor="TLSIANA">
          <front>
            <title>IANA Registry Updates for TLS and DTLS</title>
            <author fullname="Joseph A. Salowey" initials="J. A." surname="Salowey">
              <organization>Venafi</organization>
            </author>
            <author fullname="Sean Turner" initials="S." surname="Turner">
              <organization>sn3rd</organization>
            </author>
            <date day="11" month="April" year="2025"/>
            <abstract>
              <t>   This document updates the changes to TLS and DTLS IANA registries
   made in RFC 8447.  It adds a new value "D" for discouraged to the
   Recommended column of the selected TLS registries and adds a
   "Comments" column to all active registries that do not already have a
   "Comments" column.

   This document updates the following RFCs: 3749, 5077, 4680, 5246,
   5705, 5878, 6520, 7301, and 8447.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ietf-tls-rfc8447bis-12"/>
        </reference>
        <reference anchor="SCHMIEG" target="https://eprint.iacr.org/2024/523">
          <front>
            <title>Unbindable Kemmy Schmidt: ML-KEM is neither MAL-BIND-K-CT nor MAL-BIND-K-PK</title>
            <author initials="S." surname="Schmieg">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="KSMW" target="https://eprint.iacr.org/2024/1233">
          <front>
            <title>Binding Security of Implicitly-Rejecting KEMs and Application to BIKE and HQC</title>
            <author initials="J." surname="Kraemer">
              <organization/>
            </author>
            <author initials="P." surname="Struck">
              <organization/>
            </author>
            <author initials="M." surname="Weishaupl">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="PROOF" target="https://eprint.iacr.org/2024/039">
          <front>
            <title>X-Wing: The Hybrid KEM You’ve Been Looking For</title>
            <author initials="M." surname="Barbosa">
              <organization/>
            </author>
            <author initials="D." surname="Connolly">
              <organization/>
            </author>
            <author initials="J." surname="Duarte">
              <organization/>
            </author>
            <author initials="A." surname="Kaiser">
              <organization/>
            </author>
            <author initials="P." surname="Schwabe">
              <organization/>
            </author>
            <author initials="K." surname="Varner">
              <organization/>
            </author>
            <author initials="B. E." surname="Westerbraan">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
      </references>
    </references>
    <?line 708?>

<section anchor="implementations">
      <name>Implementations</name>
      <ul spacing="normal">
        <li>
          <t>Go  </t>
          <ul spacing="normal">
            <li>
              <t><eref target="https://github.com/cloudflare/circl/pull/471">CIRCL</eref></t>
            </li>
            <li>
              <t><eref target="https://github.com/FiloSottile/mlkem768">Filippo</eref></t>
            </li>
          </ul>
        </li>
        <li>
          <t>Rust  </t>
          <ul spacing="normal">
            <li>
              <t><eref target="https://github.com/rugo/xwing-kem.rs">xwing-kem.rs</eref>      </t>
              <t>
Note: implements the older <tt>-00</tt> version of this memo at the time of
writing.</t>
            </li>
            <li>
              <t><eref target="https://github.com/RustCrypto/KEMs/tree/master/x-wing">RustCrypto x-wing</eref></t>
            </li>
            <li>
              <t><eref target="https://github.com/orion-rs/orion">Orion</eref></t>
            </li>
          </ul>
        </li>
      </ul>
    </section>
    <section anchor="S-spec">
      <name>Machine-readable specification</name>
      <t>For the convenience of implementors, we provide a reference specification
in Python. This is a specification; not production ready code:
it should not be deployed as-is, as it leaks the private key by its runtime.</t>
      <section anchor="xwingpy">
        <name>xwing.py</name>
        <artwork><![CDATA[
# WARNING This is a specification of X-Wing; not a production-ready
# implementation. It is slow and does not run in constant time.

# Requires the CryptoDome for SHAKE, and pytest for testing. To install, run
#
#   pip install pycryptodome pytest

import binascii
import hashlib

import mlkem
import x25519

XWingLabel = br"""
                \./
                /^\
              """.replace(b'\n', b'').replace(b' ', b'')

assert len(XWingLabel) == 6
assert binascii.hexlify(XWingLabel) == b'5c2e2f2f5e5c'

def expandDecapsulationKey(seed):
    expanded = hashlib.shake_256(seed).digest(length=96)
    pkM, skM = mlkem.KeyGen(expanded[0:64], mlkem.params768)
    skX = expanded[64:96]
    pkX = x25519.X(skX, x25519.BASE)
    return skM, skX, pkM, pkX

def GenerateKeyPairDerand(seed):
    assert len(seed) == 32
    skM, skX, pkM, pkX = expandDecapsulationKey(seed)
    return seed, pkM + pkX

def Combiner(ssM, ssX, ctX, pkX):
    return hashlib.sha3_256(
        ssM +
        ssX +
        ctX +
        pkX +
        XWingLabel
    ).digest()

def EncapsulateDerand(pk, eseed):
    assert len(eseed) == 64
    assert len(pk) == 1216
    pkM = pk[0:1184]
    pkX = pk[1184:1216]
    ekX = eseed[32:64]
    ctX = x25519.X(ekX, x25519.BASE)
    ssX = x25519.X(ekX, pkX)
    ctM, ssM = mlkem.Enc(pkM, eseed[0:32], mlkem.params768)
    ss = Combiner(ssM, ssX, ctX, pkX)
    return ss, ctM + ctX

def Decapsulate(ct, sk):
    assert len(ct) == 1120
    assert len(sk) == 32
    ctM = ct[0:1088]
    ctX = ct[1088:1120]
    skM, skX, pkM, pkX = expandDecapsulationKey(sk)
    ssM = mlkem.Dec(skM, ctM, mlkem.params768)
    ssX = x25519.X(skX, ctX)
    return Combiner(ssM, ssX, ctX, pkX)
]]></artwork>
      </section>
      <section anchor="x25519py">
        <name>x25519.py</name>
        <artwork><![CDATA[
# WARNING This is a specification of X25519; not a production-ready
# implementation. It is slow and does not run in constant time.

p = 2**255 - 19
a24 = 121665

BASE = b'\x09' + b'\x00'*31

def decode(bs):
    return sum(bs[i] << 8*i for i in range(32)) % p

def decodeScalar(k):
    bs = list(k)
    bs[0] &= 248
    bs[31] &= 127
    bs[31] |= 64
    return decode(bs)

# See rfc7748 §5.
def X(k, u):
    assert len(k) == 32
    assert len(u) == 32

    k = decodeScalar(k)
    u = decode(u)
    x1, x2, x3, z2, z3, swap = u, 1, u, 0, 1, 0

    for t in range(255, -1, -1):
        kt = (k >> t) & 1
        swap ^= kt
        if swap == 1:
            x3, x2 = x2, x3
            z3, z2 = z2, z3
        swap = kt

        A = x2 + z2
        AA = (A*A) % p
        B = x2 - z2
        BB = (B*B) % p
        E = AA - BB
        C = x3 + z3
        D = x3 - z3
        DA = (D*A) % p
        CB = (C*B) % p
        x3 = DA + CB
        x3 = (x3 * x3) % p
        z3 = DA - CB
        z3 = (x1 * z3 * z3) % p
        x2 = (AA * BB) % p
        z2 = (E * (AA + (a24 * E) % p)) % p

    if swap == 1:
        x3, x2 = x2, x3
        z2, z3 = z3, z2

    ret = (x2 * pow(z2, p-2, p)) % p
    return bytes((ret >> 8*i) & 255 for i in range(32))
]]></artwork>
      </section>
      <section anchor="mlkempy">
        <name>mlkem.py</name>
        <artwork><![CDATA[
# WARNING This is a specification of Kyber; not a production ready
# implementation. It is slow and does not run in constant time.

# Requires the CryptoDome for SHAKE. To install, run
#
#   pip install pycryptodome pytest
from Crypto.Hash import SHAKE128, SHAKE256

import io
import hashlib
import functools
import collections

from math import floor

q = 3329
nBits = 8
zeta = 17
eta2 = 2

n = 2**nBits
inv2 = (q+1)//2 # inverse of 2

params = collections.namedtuple('params', ('k', 'du', 'dv', 'eta1'))

params512  = params(k = 2, du = 10, dv = 4, eta1 = 3)
params768  = params(k = 3, du = 10, dv = 4, eta1 = 2)
params1024 = params(k = 4, du = 11, dv = 5, eta1 = 2)

def smod(x):
    r = x % q
    if r > (q-1)//2:
        r -= q
    return r

# Rounds to nearest integer with ties going up
def Round(x):
    return int(floor(x + 0.5))

def Compress(x, d):
    return Round((2**d / q) * x) % (2**d)

def Decompress(y, d):
    assert 0 <= y and y <= 2**d
    return Round((q / 2**d) * y)

def BitsToWords(bs, w):
    assert len(bs) % w == 0
    return [sum(bs[i+j] * 2**j for j in range(w))
            for i in range(0, len(bs), w)]

def WordsToBits(bs, w):
    return sum([[(b >> i) % 2 for i in range(w)] for b in bs], [])

def Encode(a, w):
    return bytes(BitsToWords(WordsToBits(a, w), 8))

def Decode(a, w):
    return BitsToWords(WordsToBits(a, 8), w)

def brv(x):
    """ Reverses a 7-bit number """
    return int(''.join(reversed(bin(x)[2:].zfill(nBits-1))), 2)

class Poly:
    def __init__(self, cs=None):
        self.cs = (0,)*n if cs is None else tuple(cs)
        assert len(self.cs) == n

    def __add__(self, other):
        return Poly((a+b) % q for a,b in zip(self.cs, other.cs))

    def __neg__(self):
        return Poly(q-a for a in self.cs)
    def __sub__(self, other):
        return self + -other

    def __str__(self):
        return f"Poly({self.cs}"

    def __eq__(self, other):
        return self.cs == other.cs

    def NTT(self):
        cs = list(self.cs)
        layer = n // 2
        zi = 0
        while layer >= 2:
            for offset in range(0, n-layer, 2*layer):
                zi += 1
                z = pow(zeta, brv(zi), q)

                for j in range(offset, offset+layer):
                    t = (z * cs[j + layer]) % q
                    cs[j + layer] = (cs[j] - t) % q
                    cs[j] = (cs[j] + t) % q
            layer //= 2
        return Poly(cs)

    def RefNTT(self):
        # Slower, but simpler, version of the NTT.
        cs = [0]*n
        for i in range(0, n, 2):
            for j in range(n // 2):
                z = pow(zeta, (2*brv(i//2)+1)*j, q)
                cs[i] = (cs[i] + self.cs[2*j] * z) % q
                cs[i+1] = (cs[i+1] + self.cs[2*j+1] * z) % q
        return Poly(cs)

    def InvNTT(self):
        cs = list(self.cs)
        layer = 2
        zi = n//2
        while layer < n:
            for offset in range(0, n-layer, 2*layer):
                zi -= 1
                z = pow(zeta, brv(zi), q)

                for j in range(offset, offset+layer):
                    t = (cs[j+layer] - cs[j]) % q
                    cs[j] = (inv2*(cs[j] + cs[j+layer])) % q
                    cs[j+layer] = (inv2 * z * t) % q
            layer *= 2
        return Poly(cs)

    def MulNTT(self, other):
        """ Computes self o other, the multiplication of self and other
            in the NTT domain. """
        cs = [None]*n
        for i in range(0, n, 2):
            a1 = self.cs[i]
            a2 = self.cs[i+1]
            b1 = other.cs[i]
            b2 = other.cs[i+1]
            z = pow(zeta, 2*brv(i//2)+1, q)
            cs[i] = (a1 * b1 + z * a2 * b2) % q
            cs[i+1] = (a2 * b1 + a1 * b2) % q
        return Poly(cs)

    def Compress(self, d):
        return Poly(Compress(c, d) for c in self.cs)

    def Decompress(self, d):
        return Poly(Decompress(c, d) for c in self.cs)

    def Encode(self, d):
        return Encode(self.cs, d)

def sampleUniform(stream):
    cs = []
    while True:
        b = stream.read(3)
        d1 = b[0] + 256*(b[1] % 16)
        d2 = (b[1] >> 4) + 16*b[2]
        assert d1 + 2**12 * d2 == b[0] + 2**8 * b[1] + 2**16*b[2]
        for d in [d1, d2]:
            if d >= q:
                continue
            cs.append(d)
            if len(cs) == n:
                return Poly(cs)

def CBD(a, eta):
    assert len(a) == 64*eta
    b = WordsToBits(a, 8)
    cs = []
    for i in range(n):
        cs.append((sum(b[:eta]) - sum(b[eta:2*eta])) % q)
        b = b[2*eta:]
    return Poly(cs)

def XOF(seed, j, i):
    h = SHAKE128.new()
    h.update(seed + bytes([j, i]))
    return h

def PRF1(seed, nonce):
    assert len(seed) == 32
    h = SHAKE256.new()
    h.update(seed + bytes([nonce]))
    return h

def PRF2(seed, msg):
    assert len(seed) == 32
    h = SHAKE256.new()
    h.update(seed + msg)
    return h.read(32)

def G(seed):
    h = hashlib.sha3_512(seed).digest()
    return h[:32], h[32:]

def H(msg): return hashlib.sha3_256(msg).digest()

class Vec:
    def __init__(self, ps):
        self.ps = tuple(ps)

    def NTT(self):
        return Vec(p.NTT() for p in self.ps)

    def InvNTT(self):
        return Vec(p.InvNTT() for p in self.ps)

    def DotNTT(self, other):
        """ Computes the dot product <self, other> in NTT domain. """
        return sum((a.MulNTT(b) for a, b in zip(self.ps, other.ps)),
                   Poly())

    def __add__(self, other):
        return Vec(a+b for a,b in zip(self.ps, other.ps))

    def Compress(self, d):
        return Vec(p.Compress(d) for p in self.ps)

    def Decompress(self, d):
        return Vec(p.Decompress(d) for p in self.ps)

    def Encode(self, d):
        return Encode(sum((p.cs for p in self.ps), ()), d)

    def __eq__(self, other):
        return self.ps == other.ps

def EncodeVec(vec, w):
    return Encode(sum([p.cs for p in vec.ps], ()), w)
def DecodeVec(bs, k, w):
    cs = Decode(bs, w)
    return Vec(Poly(cs[n*i:n*(i+1)]) for i in range(k))
def DecodePoly(bs, w):
    return Poly(Decode(bs, w))

class Matrix:
    def __init__(self, cs):
        """ Samples the matrix uniformly from seed rho """
        self.cs = tuple(tuple(row) for row in cs)

    def MulNTT(self, vec):
        """ Computes matrix multiplication A*vec in the NTT domain. """
        return Vec(Vec(row).DotNTT(vec) for row in self.cs)

    def T(self):
        """ Returns transpose of matrix """
        k = len(self.cs)
        return Matrix((self.cs[j][i] for j in range(k))
                      for i in range(k))

def sampleMatrix(rho, k):
    return Matrix([[sampleUniform(XOF(rho, j, i))
            for j in range(k)] for i in range(k)])

def sampleNoise(sigma, eta, offset, k):
    return Vec(CBD(PRF1(sigma, i+offset).read(64*eta), eta)
               for i in range(k))

def constantTimeSelectOnEquality(a, b, ifEq, ifNeq):
    # WARNING! In production code this must be done in a
    # data-independent constant-time manner, which this implementation
    # is not. In fact, many more lines of code in this
    # file are not constant-time.
    return ifEq if a == b else ifNeq

def InnerKeyGen(seed, params):
    assert len(seed) == 32
    rho, sigma = G(seed + bytes([params.k]))
    A = sampleMatrix(rho, params.k)
    s = sampleNoise(sigma, params.eta1, 0, params.k)
    e = sampleNoise(sigma, params.eta1, params.k, params.k)
    sHat = s.NTT()
    eHat = e.NTT()
    tHat = A.MulNTT(sHat) + eHat
    pk = EncodeVec(tHat, 12) + rho
    sk = EncodeVec(sHat, 12)
    return (pk, sk)

def InnerEnc(pk, msg, seed, params):
    assert len(msg) == 32
    tHat = DecodeVec(pk[:-32], params.k, 12)
    if EncodeVec(tHat, 12) != pk[:-32]:
        raise Exception("ML-KEM public key not normalized")
    rho = pk[-32:]
    A = sampleMatrix(rho, params.k)
    r = sampleNoise(seed, params.eta1, 0, params.k)
    e1 = sampleNoise(seed, eta2, params.k, params.k)
    e2 = sampleNoise(seed, eta2, 2*params.k, 1).ps[0]
    rHat = r.NTT()
    u = A.T().MulNTT(rHat).InvNTT() + e1
    m = Poly(Decode(msg, 1)).Decompress(1)
    v = tHat.DotNTT(rHat).InvNTT() + e2 + m
    c1 = u.Compress(params.du).Encode(params.du)
    c2 = v.Compress(params.dv).Encode(params.dv)
    return c1 + c2

def InnerDec(sk, ct, params):
    split = params.du * params.k * n // 8
    c1, c2 = ct[:split], ct[split:]
    u = DecodeVec(c1, params.k, params.du).Decompress(params.du)
    v = DecodePoly(c2, params.dv).Decompress(params.dv)
    sHat = DecodeVec(sk, params.k, 12)
    return (v - sHat.DotNTT(u.NTT()).InvNTT()).Compress(1).Encode(1)

def KeyGen(seed, params):
    assert len(seed) == 64
    z = seed[32:]
    pk, sk2 = InnerKeyGen(seed[:32], params)
    h = H(pk)
    return (pk, sk2 + pk + h + z)

def Enc(pk, seed, params):
    assert len(seed) == 32

    K, r = G(seed + H(pk))
    ct = InnerEnc(pk, seed, r, params)
    return (ct, K)

def Dec(sk, ct, params):
    sk2 = sk[:12 * params.k * n//8]
    pk = sk[12 * params.k * n//8 : 24 * params.k * n//8 + 32]
    h = sk[24 * params.k * n//8 + 32 : 24 * params.k * n//8 + 64]
    z = sk[24 * params.k * n//8 + 64 : 24 * params.k * n//8 + 96]
    m2 = InnerDec(sk, ct, params)
    K2, r2 = G(m2 + h)
    ct2 = InnerEnc(pk, m2, r2, params)
    return constantTimeSelectOnEquality(
        ct2, ct,
        K2,                 # if ct == ct2
        PRF2(z, ct),        # if ct != ct2
    )
]]></artwork>
      </section>
    </section>
    <section anchor="test-vectors-todo-replace-with-test-vectors-that-re-use-ml-kem-x25519-values">
      <name>Test vectors # TODO: replace with test vectors that re-use ML-KEM, X25519 values</name>
      <artwork><![CDATA[
seed     7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26
sk     7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26
pk
  e2236b35a8c24b39b10aa1323a96a919a2ced88400633a7b07131713fc14b2b5b19cfc3d
  a5fa1a92c49f25513e0fd30d6b1611c9ab9635d7086727a4b7d21d34244e66969cf15b3b
  2a785329f61b096b277ea037383479a6b556de7231fe4b7fa9c9ac24c0699a0018a52534
  01bacfa905ca816573e56a2d2e067e9b7287533ba13a937dedb31fa44baced4076992361
  0034ae31e619a170245199b3c5c39864859fe1b4c9717a07c30495bdfb98a0a002ccf56c
  1286cef5041dede3c44cf16bf562c7448518026b3d8b9940680abd38a1575fd27b58da06
  3bfac32c39c30869374c05c1aeb1898b6b303cc68be455346ee0af699636224a148ca2ae
  a10463111c709f69b69c70ce8538746698c4c60a9aef0030c7924ceec42a5d36816f545e
  ae13293460b3acb37ea0e13d70e4aa78686da398a8397c08eaf96882113fe4f7bad4da40
  b0501e1c753efe73053c87014e8661c33099afe8bede414a5b1aa27d8392b3e131e9a70c
  1055878240cad0f40d5fe3cdf85236ead97e2a97448363b2808caafd516cd25052c5c362
  543c2517e4acd0e60ec07163009b6425fc32277acee71c24bab53ed9f29e74c66a0a3564
  955998d76b96a9a8b50d1635a4d7a67eb42df5644d330457293a8042f53cc7a69288f17e
  d55827e82b28e82665a86a14fbd96645eca8172c044f83bc0d8c0b4c8626985631ca87af
  829068f1358963cb333664ca482763ba3b3bb208577f9ba6ac62c25f76592743b64be519
  317714cb4102cb7b2f9a25b2b4f0615de31decd9ca55026d6da0b65111b16fe52feed8a4
  87e144462a6dba93728f500b6ffc49e515569ef25fed17aff520507368253525860f58be
  3be61c964604a6ac814e6935596402a520a4670b3d284318866593d15a4bb01c35e3e587
  ee0c67d2880d6f2407fb7a70712b838deb96c5d7bf2b44bcf6038ccbe33fbcf51a54a584
  fe90083c91c7a6d43d4fb15f48c60c2fd66e0a8aad4ad64e5c42bb8877c0ebec2b5e387c
  8a988fdc23beb9e16c8757781e0a1499c61e138c21f216c29d076979871caa6942bafc09
  0544bee99b54b16cb9a9a364d6246d9f42cce53c66b59c45c8f9ae9299a75d15180c3c95
  2151a91b7a10772429dc4cbae6fcc622fa8018c63439f890630b9928db6bb7f9438ae406
  5ed34d73d486f3f52f90f0807dc88dfdd8c728e954f1ac35c06c000ce41a0582580e3bb5
  7b672972890ac5e7988e7850657116f1b57d0809aaedec0bede1ae148148311c6f7e3173
  46e5189fb8cd635b986f8c0bdd27641c584b778b3a911a80be1c9692ab8e1bbb12839573
  cce19df183b45835bbb55052f9fc66a1678ef2a36dea78411e6c8d60501b4e60592d1369
  8a943b509185db912e2ea10be06171236b327c71716094c964a68b03377f513a05bcd99c
  1f346583bb052977a10a12adfc758034e5617da4c1276585e5774e1f3b9978b09d0e9c44
  d3bc86151c43aad185712717340223ac381d21150a04294e97bb13bbda21b5a182b6da96
  9e19a7fd072737fa8e880a53c2428e3d049b7d2197405296ddb361912a7bcf4827ced611
  d0c7a7da104dde4322095339f64a61d5bb108ff0bf4d780cae509fb22c256914193ff734
  9042581237d522828824ee3bdfd07fb03f1f942d2ea179fe722f06cc03de5b69859edb06
  eff389b27dce59844570216223593d4ba32d9abac8cd049040ef6534
eseed
  3cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e235b8cc87
  3c23dc62b8d260169afa2f75ab916a58d974918835d25e6a435085b2
ct
  b83aa828d4d62b9a83ceffe1d3d3bb1ef31264643c070c5798927e41fb07914a273f8f96
  e7826cd5375a283d7da885304c5de0516a0f0654243dc5b97f8bfeb831f68251219aabdd
  723bc6512041acbaef8af44265524942b902e68ffd23221cda70b1b55d776a92d1143ea3
  a0c475f63ee6890157c7116dae3f62bf72f60acd2bb8cc31ce2ba0de364f52b8ed38c79d
  719715963a5dd3842d8e8b43ab704e4759b5327bf027c63c8fa857c4908d5a8a7b88ac7f
  2be394d93c3706ddd4e698cc6ce370101f4d0213254238b4a2e8821b6e414a1cf20f6c12
  44b699046f5a01caa0a1a55516300b40d2048c77cc73afba79afeea9d2c0118bdf2adb88
  70dc328c5516cc45b1a2058141039e2c90a110a9e16b318dfb53bd49a126d6b73f215787
  517b8917cc01cabd107d06859854ee8b4f9861c226d3764c87339ab16c3667d2f49384e5
  5456dd40414b70a6af841585f4c90c68725d57704ee8ee7ce6e2f9be582dbee985e038ff
  c346ebfb4e22158b6c84374a9ab4a44e1f91de5aac5197f89bc5e5442f51f9a5937b102b
  a3beaebf6e1c58380a4a5fedce4a4e5026f88f528f59ffd2db41752b3a3d90efabe46389
  9b7d40870c530c8841e8712b733668ed033adbfafb2d49d37a44d4064e5863eb0af0a08d
  47b3cc888373bc05f7a33b841bc2587c57eb69554e8a3767b7506917b6b70498727f16ea
  c1a36ec8d8cfaf751549f2277db277e8a55a9a5106b23a0206b4721fa9b3048552c5bd5b
  594d6e247f38c18c591aea7f56249c72ce7b117afcc3a8621582f9cf71787e183dee0936
  7976e98409ad9217a497df888042384d7707a6b78f5f7fb8409e3b535175373461b77600
  2d799cbad62860be70573ecbe13b246e0da7e93a52168e0fb6a9756b895ef7f0147a0dc8
  1bfa644b088a9228160c0f9acf1379a2941cd28c06ebc80e44e17aa2f8177010afd78a97
  ce0868d1629ebb294c5151812c583daeb88685220f4da9118112e07041fcc24d5564a99f
  dbde28869fe0722387d7a9a4d16e1cc8555917e09944aa5ebaaaec2cf62693afad42a3f5
  18fce67d273cc6c9fb5472b380e8573ec7de06a3ba2fd5f931d725b493026cb0acbd3fe6
  2d00e4c790d965d7a03a3c0b4222ba8c2a9a16e2ac658f572ae0e746eafc4feba023576f
  08942278a041fb82a70a595d5bacbf297ce2029898a71e5c3b0d1c6228b485b1ade509b3
  5fbca7eca97b2132e7cb6bc465375146b7dceac969308ac0c2ac89e7863eb8943015b243
  14cafb9c7c0e85fe543d56658c213632599efabfc1ec49dd8c88547bb2cc40c9d38cbd30
  99b4547840560531d0188cd1e9c23a0ebee0a03d5577d66b1d2bcb4baaf21cc7fef1e038
  06ca96299df0dfbc56e1b2b43e4fc20c37f834c4af62127e7dae86c3c25a2f696ac8b589
  dec71d595bfbe94b5ed4bc07d800b330796fda89edb77be0294136139354eb8cd3759157
  8f9c600dd9be8ec6219fdd507adf3397ed4d68707b8d13b24ce4cd8fb22851bfe9d63240
  7f31ed6f7cb1600de56f17576740ce2a32fc5145030145cfb97e63e0e41d354274a079d3
  e6fb2e15
ss     d2df0522128f09dd8e2c92b1e905c793d8f57a54c3da25861f10bf4ca613e384

seed     badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea
sk     badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea
pk
  0333285fa253661508c9fb444852caa4061636cb060e69943b431400134ae1fbc0228724
  7cb38068bbb89e6714af10a3fcda6613acc4b5e4b0d6eb960c302a0253b1f507b596f088
  4d351da89b01c35543214c8e542390b2bc497967961ef10286879c34316e6483b644fc27
  e8019d73024ba1d1cc83650bb068a5431b33d1221b3d122dc1239010a55cb13782140893
  f30aca7c09380255a0c621602ffbb6a9db064c1406d12723ab3bbe2950a21fe521b160b3
  0b16724cc359754b4c88342651333ea9412d5137791cf75558ebc5c54c520dd6c622a059
  f6b332ccebb9f24103e59a297cd69e4a48a3bfe53a5958559e840db5c023f66c10ce2308
  1c2c8261d744799ba078285cfa71ac51f44708d0a6212c3993340724b3ac38f63e82a889
  a4fc581f6b8353cc6233ac8f5394b6cca292f892360570a3031c90c4da3f02a895677390
  e60c24684a405f69ccf1a7b95312a47c844a4f9c2c4a37696dc10072a87bf41a2717d45b
  2a99ce09a4898d5a3f6b67085f9a626646bcf369982d483972b9cd7d244c4f49970f766a
  22507925eca7df99a491d80c27723e84c7b49b633a46b46785a16a41e02c538251622117
  364615d9c2cdaa1687a860c18bfc9ce8690efb2a524cb97cdfd1a4ea661fa7d08817998a
  f838679b07c9db8455e2167a67c14d6a347522e89e8971270bec858364b1c1023b82c483
  cf8a8b76f040fe41c24dec2d49f6376170660605b80383391c4abad1136d874a77ef73b4
  40758b6e7059add20873192e6e372e069c22c5425188e5c240cb3a6e29197ad17e87ec41
  a813af68531f262a6db25bbdb8a15d2ed9c9f35b9f2063890bd26ef09426f225aa1e6008
  d31600a29bcdf3b10d0bc72788d35e25f4976b3ca6ac7cbf0b442ae399b225d9714d0638
  a864bda7018d3b7c793bd2ace6ac68f4284d10977cc029cf203c5698f15a06b162d6c8b4
  fd40c6af40824f9c6101bb94e9327869ab7efd835dfc805367160d6c8571e3643ac70cba
  d5b96a1ad99352793f5af71705f95126cb4787392e94d808491a2245064ba5a7a30c0663
  01392a6c315336e10dbc9c2177c7af382765b6c88eeab51588d01d6a95747f3652dc5b5c
  401a23863c7a0343737c737c99287a40a90896d4594730b552b910d23244684206f0eb84
  2fb9aa316ab182282a75fb72b6806cea4774b822169c386a58773c3edc8229d85905abb8
  7ac228f0f7a2ce9a497bb5325e17a6a82777a997c036c3b862d29c14682ad325a9600872
  f3913029a1588648ba590a7157809ff740b5138380015c40e9fb90f0311107946f28e596
  2e21666ad65092a3a60480cd16e61ff7fb5b44b70cf12201878428ef8067fceb1e1dcb49
  d66c773d312c7e53238cb620e126187009472d41036b702032411dc96cb750631df9d994
  52e495deb4300df660c8d35f32b424e98c7ed14b12d8ab11a289ac63c50a24d52925950e
  49ba6bf4c2c38953c92d60b6cd034e575c711ac41bfa66951f62b9392828d7b45aed377a
  c69c35f1c6b80f388f34e0bb9ce8167eb2bc630382825c396a407e905108081b444ac8a0
  7c2507376a750d18248ee0a81c4318d9a38fc44c3b41e8681f87c34138442659512c4127
  6e1cc8fc4eb66e12727bcb5a9e0e405cdea21538d6ea885ab169050e6b91e1b69f7ed34b
  cbb48fd4c562a576549f85b528c953926d96ea8a160b8843f1c89c62
eseed
  17cda7cfad765f5623474d368ccca8af0007cd9f5e4c849f167a580b14aabdefaee7eef4
  7cb0fca9767be1fda69419dfb927e9df07348b196691abaeb580b32d
ct
  c93beb22326705699bbc3d1d0aa6339be7a405debe61a7c337e1a91453c097a6f77c1306
  39d1aaeb193175f1a987aa1fd789a63c9cd487ebd6965f5d8389c8d7c8cfacbba4b44d2f
  be0ae84de9e96fb11215d9b76acd51887b752329c1a3e0468ccc49392c1e0f1aad61a73c
  10831e60a9798cb2e7ec07596b5803db3e243ecbb94166feade0c9197378700f8eb65a43
  502bbac4605992e2de2b906ab30ba401d7e1ff3c98f42cfc4b30b974d3316f331461ac05
  f43e0db7b41d3da702a4f567b6ee7295199c7be92f6b4a47e7307d34278e03c872fb4864
  7c446a64a3937dccd7c6d8de4d34b9dea45a0b065ef15b9e94d1b6df6dca7174d9bc9d14
  c6225e3a78a58785c3fe4e2fe6a0706f3365389e4258fbb61ecf1a1957715982b3f18444
  24e03acd83da7eee50573f6cd3ff396841e9a00ad679da92274129da277833d0524674fe
  ea09a98d25b888616f338412d8e65e151e65736c8c6fb448c9260fa20e7b2712148bcd3a
  0853865f50c1fc9e4f201aee3757120e034fd509d954b7a749ff776561382c4cb64cebcb
  b6aa82d04cd5c2b40395ecaf231bde8334ecfd955d09efa8c6e7935b1cb0298fb8b6740b
  e4593360eed5f129d59d98822a6cea37c57674e919e84d6b90f695fca58e7d29092bd70f
  7c97c6dfb021b9f87216a6271d8b144a364d03b6bf084f972dc59800b14a2c008bbd0992
  b5b82801020978f2bdddb3ca3367d876cffb3548dab695a29882cae2eb5ba7c847c3c71b
  d0150fa9c33aac8e6240e0c269b8e295ddb7b77e9c17bd310be65e28c0802136d086777b
  e5652d6f1ac879d3263e9c712d1af736eac048fe848a577d6afaea1428dc71db8c430edd
  7b584ae6e6aeaf7257aff0fd8fe25c30840e30ccfa1d95118ef0f6657367e9070f3d97a2
  e9a7bae19957bd707b00e31b6b0ebb9d7df4bd22e44c060830a194b5b8288353255b5295
  4ff5905ab2b126d9aa049e44599368c27d6cb033eae5182c2e1504ee4e3745f51488997b
  8f958f0209064f6f44a7e4de5226d5594d1ad9b42ac59a2d100a2f190df873a2e141552f
  33c923b4c927e8747c6f830c441a8bd3c5b371f6b3ab8103ebcfb18543aefc1beb6f776b
  bfd5344779f4aa23daaf395f69ec31dc046b491f0e5cc9c651dfc306bd8f2105be7bc7a4
  f4e21957f87278c771528a8740a92e2daefa76a3525f1fae17ec4362a2700988001d8600
  11d6ca3a95f79a0205bcf634cef373a8ea273ff0f4250eb8617d0fb92102a6aa09cf0c3e
  e2cad1ad96438c8e4dfd6ee0fcc85833c3103dd6c1600cd305bc2df4cda89b55ca237a3f
  9c3f82390074ff30825fc750130ebaf13d0cf7556d2c52a98a4bad39ca5d44aaadeaef77
  5c695e64d06e966acfcd552a14e2df6c63ae541f0fa88fc48263089685704506a21a0385
  6ce65d4f06d54f3157eeabd62491cb4ac7bf029e79f9fbd4c77e2a3588790c710e611da8
  b2040c76a61507a8020758dcc30894ad018fef98e401cc54106e20d94bd544a8f0e1fd05
  00342d123f618aa8c91bdf6e0e03200693c9651e469aee6f91c98bea4127ae66312f4ae3
  ea155b67
ss     f2e86241c64d60f6649fbc6c5b7d17180b780a3f34355e64a85749949c45f150

seed     ef58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c9
sk     ef58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c9
pk
  36244278824f77c621c660892c1c3886a9560caa52a97c461fd3958a598e749bbc8c7798
  ac8870bac7318ac2b863000ca3b0bdcbbc1ccfcb1a30875df9a76976763247083e646ccb
  2499a4e4f0c9f4125378ba3da1999538b86f99f2328332c177d1192b849413e655101289
  73f679d23253850bb6c347ba7ca81b5e6ac4c574565c731740b3cd8c9756caac39fba7ac
  422acc60c6c1a645b94e3b6d21485ebad9c4fe5bb4ea0853670c5246652bff65ce8381cb
  473c40c1a0cd06b54dcec11872b351397c0eaf995bebdb6573000cbe2496600ba76c8cb0
  23ec260f0571e3ec12a9c82d9db3c57b3a99e8701f78db4fabc1cc58b1bae02745073a81
  fc8045439ba3b885581a283a1ba64e103610aabb4ddfe9959e7241011b2638b56ba6a982
  ef610c514a57212555db9a98fb6bcf0e91660ec15dfa66a67408596e9ccb97489a09a073
  ffd1a0a7ebbe71aa5ff793cb91964160703b4b6c9c5390842c2c905d4a9f88111fed5787
  4ba9b03cf611e70486edf539767c7485189d5f1b08e32a274dc24a39c918fd2a4dfa946a
  8c897486f2c974031b2804aabc81749db430b85311372a3b8478868200b40e043f7bf4a1
  c3a08b0771b431e342ee277410bca034a0c77086c8f702b3aed2b4108bbd3af471633373
  a1ac74b128b148d1b9412aa66948cac6dc6614681fda02ca86675d2a756003c49c50f06e
  13c63ce4bc9f321c860b202ee931834930011f485c9af86b9f642f0c353ad305c66996b9
  a136b753973929495f0d8048db75529edcb4935904797ac66605490f66329c3bb36b8573
  a3e00f817b3082162ff106674d11b261baae0506cde7e69fdce93c6c7b59b9d4c759758a
  cf287c2e4c4bfab5170a9236daf21bdb6005e92464ee8863f845cf37978ef19969264a51
  6fe992c93b5f7ae7cb6718ac69257d630379e4aac6029cb906f98d91c92d118c36a6d161
  15d4c8f16066078badd161a65ba51e0252bc358c67cd2c4beab2537e42956e08a39cfccf
  0cd875b5499ee952c83a162c68084f6d35cf92f71ec66baec74ab87e2243160b64df54af
  b5a07f78ec0f5c5759e5a4322bca2643425748a1a97c62108510c44fd9089c5a7c14e57b
  1b77532800013027cff91922d7c935b4202bb507aa47598a6a5a030117210d4c49c17470
  0550ad6f82ad40e965598b86bc575448eb19d70380d465c1f870824c026d74a2522a799b
  7b122d06c83aa64c0974635897261433914fdfb14106c230425a83dc8467ad8234f086c7
  2a47418be9cfb582b1dcfa3d9aa45299b79fff265356d8286a1ca2f3c2184b2a70d15289
  e5b202d03b64c735a867b1154c55533ff61d6c296277011848143bc85a4b823040ae025a
  29293ab77747d85310078682e0ba0ac236548d905a79494324574d417c7a3457bd5fb525
  3c4876679034ae844d0d05010fec722db5621e3a67a2d58e2ff33b432269169b51f9dcc0
  95b8406dc1864cf0aeb6a2132661a38d641877594b3c51892b9364d25c63d637140a2018
  d10931b0daa5a2f2a405017688c991e586b522f94b1132bc7e87a63246475816c8be9c62
  b731691ab912eb656ce2619225663364701a014b7d0337212caa2ecc731f34438289e0ca
  4590a276802d980056b5d0d316cae2ecfea6d86696a9f161aa90ad47eaad8cadd31ae3cb
  c1c013747dfee80fb35b5299f555dcc2b787ea4f6f16ffdf66952461
eseed
  22a96188d032675c8ac850933c7aff1533b94c834adbb69c6115bad4692d8619f90b0cdf
  8a7b9c264029ac185b70b83f2801f2f4b3f70c593ea3aeeb613a7f1b
ct
  0d2e38cbf17a2e2e4e0c87a94ca1e7701ae1552e02509b3b00f9c82c39e3fd435b05b912
  75f47abc9f1021429a26a346598cd6cd9efdc8adc1dbc35036d0290bf89733c835309202
  232f9bf652ea82f3d49280d6e8a3bd3135fb883445ab5b074d949c5350c7c7d6ac59905b
  dbfce6639da8a9d4b390ecc1dd05522d2956f2d37a05593996e5cb3fd8d5a9eb52417732
  e1ebf545588713b4760227115aab7ada178dadbca583b26cfedba2888a0c95b950bf07f7
  50d7aa8103798aa3470a042c0105c6a037de2f9ebc396021b2ba2c16aba696fbac3454dc
  8e053b8fa55edd45215eeb57a1eab9106fb426b375a9b9e5c3419efc7610977e72640f9f
  d1b2ec337de33c35e5a7581b2aae4d8ee86d2e0ebf82a1350714de50d2d788687878a196
  44ae4e3175e8d59dc90171b3badeff65aeaf600e5e5483a3595fdeb40cbafcbd040c29a2
  f6900533ae999d24f54dfcef748c30313ca447cdddfa57ad78eaa890e90f3f7bf8d11696
  8a5713cc75fd0408f36364fa265c5617039304eaeac4cbee6fc49b9fe2276768cdbec2d7
  3a507b543cc028dc1b154b7c2b0412254c466a94a8d6ea3a47e1743469bd45c08f54cf96
  5884be3696e961741ede16e3b1bc4feb93faaef31d911dc0cb3fa90bcda991959a9d2cbc
  817a5564c5c01177a59e9577589ea344d60cf5b0aa39f31863febd54603ca87ad2363c76
  6642a3f52557bcd9e4c05a87665842ba336b83156a677030f0bad531a8387a1486a599ca
  a748fcea7bdc1eb63f3cdb97173551ab7c1c36b69acbbdb2ff7a1e7bc70439632ddc67b9
  7f3da1f59b3c1588515957cb8a2f86ab635ce0a78b7cdf24eac3445e8fc8b79ba04da9e9
  03f49a7d912c197a84b4cfabc779b97d24788419bcf58035db99717edb9fd1c1df8c4005
  f700eabba528ddfcbaeda6dd30754f795948a34c9319ab653524b19931c7900c4167988a
  f52292fe902e746b524d20ceffb4339e8f5535f41cf35f0f8ea8b4a7b949c5d2381116b1
  46e9b913a83a3fa1c65ff9468c835fe4114554a6c66a80e1c9a6bb064b380be3c95e5595
  ec979bf1c85aa938938e3f10e72b0c87811969e8ab0d83de0b0604c4016ac3a015e19514
  089271bdc6ebf2ec56fab6018e44de749b4c36cc235e370da8466dbdc253542a2d704eb3
  316fd70d5d238cb7eaaf05966d973f62c7ef43b9a806f4ed213ac8099ea15d61a9024441
  60883f6bf441a3e1469945c9b79489ea18390f1ebc83caca10bdb8f2429877b52bd44c94
  a228ef91c392ef5398c5c83982701318ccedab92f7a279c4fddebaa7fe5e986c48b7d813
  5b3fe4cd15be2004ce73ff86b1e55f8ecd6ba5b8114315f8e716ef3ab0a64564a4644651
  166ebd68b1f783e2e443dbccadfe189368647629f1a12215840b7f1d026de2f665c2eb02
  3ff51a6df160912811ee03444ae4227fb941dc9ec4f31b445006fd384de5e60e0a5061b5
  0cb1202f863090fc05eb814e2d42a03586c0b56f533847ac7b8184ce9690bc8dece32a88
  ca934f541d4cc520fa64de6b6e1c3c8e03db5971a445992227c825590688d203523f5271
  61137334
ss     953f7f4e8c5b5049bdc771d1dffada0dd961477d1a2ae0988baa7ea6898d893f

]]></artwork>
    </section>
    <section anchor="example-of-use-in-x509">
      <name>Example of use in X.509</name>
      <t>The following are the encodings of the X-Wing keypair with private key  <tt>0001…1f</tt>.</t>
      <artwork><![CDATA[
-----BEGIN PRIVATE KEY-----
MDQCAQAwDQYLKwYBBAGD5i2ByHoEIAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ
GhscHR4f
-----END PRIVATE KEY-----
]]></artwork>
      <artwork><![CDATA[
-----BEGIN PUBLIC KEY-----
MIIE1DANBgsrBgEEAYPmLYHIegOCBMEAb1QJigoOZBFGYUtpYLpg2GA9YvRH+atJ
m0e9aQbMQLBh2GNKPoiQbyhJWOdEHKbHJcu5cJW3ZxpGK2aByeZYC7yNYLFJ+mAm
EEOvu6UvIFpgKDhIUVlq3zcavqmNM0c4PSu2c0OPZ4NhK/hwFPe5Gol0AmU0XfZ5
NARz0cTBdohuXim48Fi7fHNTFmhs/1w764wmHLAJcKacGvzFS5TLhuHOY7pjbjlc
pFEB4hx70EwxPqGa8kFB79KtREFqJbpPZZEO99iAnDCT8EqvAOPNluNcSqPIAsGK
1vOdpLS42YyL15Atg6B7pFOWZ0pgJDyrk+gP2bHId3N2qcwNb6EV4mOTgLnGvnhI
vRNYjGRwOgU10ZoPgWM6l2oKEFtm7ihdD9JV6CwDMZJfQ4O278dh72CZI1oLmHJj
WKqdAbi4llGfkhR0u3wUuyIlK1wvENQSRsmyPnZEhJNn9UGhX2O8koo5u3vHPwe2
ZcSWu2VYyPRUiacuxLrNNOnFlMM4cbcj8DSV6ItDkasm5DBD3rYRezkZ5FxMGxar
KOR93XI2Y4VHZhkvwYBspwq7eGy9swky5oyKNwvPsHmDoBLDJmuT76YmV/S4ODdM
sLuV4OwGVBsHZdmc8VO8a5YTXKeApVs2R3ieMZFeRig8+ce7boRT+2aCEFFB8dwN
ANhe7XA7bGyWH3nIRSdrQkiUnAZ4LlE+spkbldlgQuOMvto1JEmytQhOvaUiamIG
QAeJEwowlkSYSLYp/upKLCp0PEoN3Jyz89Z2/FY3MbJsShpm3IRZFwBW1XaX8UQ7
gamjRBK7e/BfMydXWlkR3TAdYFOGfzwwgHEfG/EVh7C7KYQnayaF53ViEOSz+JVT
hCMeVYxvUQyR4PxWtdGIX/KUnpWka8G+4fpx9QJ+EMRDsOkdD9dED0Z6JyISEuiP
XGumQpbK4NIHv8YPiMfPtcRaoYOdGMs3xFhD5UJqSpDIArZCj5U8NZxKwGA0UvrA
tzYeL9NdzIhakhRdT8oBWPG31wtLzRGOSipBVEON8xDESpobmepBWQcmeoiwYkJB
V5wXIvRu1hwuPspUXJlwUXF1OZuADbJdo5WT0GSQ1xQsAOiNLbBH6YmL23rLftkH
9uMEFswN5UokLAohJjAvXVTIW8Zqwvg8eXlFtQZ8qkK9LgwZypdQblB6sKXJ9WM3
CEmcGfJK7FE705A6XXO27EmR98cuuZHBw3iJgFyx6jigzAIXayfFjWOM5aMmaEV8
+bm+AnygIUBXlxcl1UEC6JlnFusq2CNFO2BbhVNwsbIbOTLN7UFgqplzx+uuWsR2
TZTPfMlQbwd7rXMBLbtKyBQKOHRkEuszyVFFliBfcHY1hiIX2bYJGMYmjZNEkVuE
eiR2waJw8VSlyEI0FlrPyGk5hwLOqemgfnsOmeqb3LeEH+nA+iXIM4CSVho+3dxw
AfR4rWV4GmAkqtFl2baXmtrESKRGL1ZGhVJ/diQ0/ppCWoRDe0VzkuyoDJE1BhUe
OhMjnzQvynZVtuquhFoiHOs+Z/VjnGGT9v3u9X45m4CLfzqitXQKre2QFj3F13XJ
+vfx+9B12rNE6dfRRmRygfu6ezxWyv1YM7epMOxCBufDptd2T+gdeg==
-----END PUBLIC KEY-----
]]></artwork>
    </section>
    <section anchor="asn1">
      <name>ASN.1 Module</name>
      <t>This appendix includes the ASN.1 module <xref target="X680"/> for X-Wing.</t>
      <sourcecode markers="true"><![CDATA[
XWing-KEM-2024
   { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1)
     pkcs-9(9) smime(16) modules(0) id-mod-XWing-kem-2024(TBD) }

DEFINITIONS IMPLICIT TAGS ::= BEGIN

-- EXPORTS ALL;

IMPORTS

  KEM-ALGORITHM
    FROM KEMAlgorithmInformation-2023  -- [I-D.housley-lamps-cms-kemri]
       { iso(1) identified-organization(3) dod(6) internet(1)
         security(5) mechanisms(5) pkix(7) id-mod(0)
         id-mod-kemAlgorithmInformation-2023(109) }

  AlgorithmIdentifier{}, PUBLIC-KEY, SMIME-CAPS
    FROM AlgorithmInformation-2009  -- [RFC5912]
      { iso(1) identified-organization(3) dod(6) internet(1)
        security(5) mechanisms(5) pkix(7) id-mod(0)
        id-mod-algorithmInformation-02(58) } ;


-- XWing KEM Algorithm

id-XWing OBJECT IDENTIFIER ::= { iso(1) identified-organization(3)
           dod(6) internet(1) private(4) enterprise(1) 62253 25722 }

XWingPublicKey ::= OCTET STRING

kema-XWing KEM-ALGORITHM ::= {
   IDENTIFIER id-XWing
   PARAMS ARE absent
   PUBLIC-KEYS { pk-XWing }
   UKM ARE optional
   SMIME-CAPS { IDENTIFIED BY id-XWing } }

pk-XWing PUBLIC-KEY ::= {
  IDENTIFIER id-XWing
  -- KEY no ASN.1 wrapping --
  PARAMS ARE absent
  -- PRIVATE-KEY no ASN.1 wrapping --
  CERT-KEY-USAGE {keyEncipherment} }


-- Updates for the KEM-ALGORITHM Set from rfc5990bis

KeyEncapsulationMechanism ::=
   AlgorithmIdentifier { KEM-ALGORITHM, {KEMAlgorithms} }

KEMAlgorithms KEM-ALGORITHM ::= { kema-XWing, ... }


-- Updates for the SMIME-CAPS Set from RFC 5911

SMimeCapsSet SMIME-CAPS ::= {kema-XWing.&smimeCaps, ... }

END
]]></sourcecode>
    </section>
    <section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
    <section anchor="change-log">
      <name>Change log</name>
      <ul empty="true">
        <li>
          <t><strong>RFC Editor's Note:</strong> Please remove this section prior to publication of a
final version of this document.</t>
        </li>
      </ul>
      <section anchor="since-draft-connolly-cfrg-xwing-kem-06">
        <name>Since draft-connolly-cfrg-xwing-kem-06</name>
        <ul spacing="normal">
          <li>
            <t>Add asn.1 module.</t>
          </li>
          <li>
            <t>To match FIPS 202, we request number of bits from SHAKE-256 instead
of number of bytes. #27</t>
          </li>
          <li>
            <t>Update implementations section.</t>
          </li>
          <li>
            <t>Correct PEM header. #25</t>
          </li>
        </ul>
      </section>
      <section anchor="since-draft-connolly-cfrg-xwing-kem-05">
        <name>Since draft-connolly-cfrg-xwing-kem-05</name>
        <ul spacing="normal">
          <li>
            <t>Fix several typos.</t>
          </li>
          <li>
            <t>Change HPKE/TLS codepoint requests to the memorable 25519 + 203.</t>
          </li>
          <li>
            <t>Add instruction for use in X.509. #21</t>
          </li>
        </ul>
      </section>
      <section anchor="since-draft-connolly-cfrg-xwing-kem-04">
        <name>Since draft-connolly-cfrg-xwing-kem-04</name>
        <ul spacing="normal">
          <li>
            <t>Note that ML-KEM decapsulation key check is not required.</t>
          </li>
          <li>
            <t>Properly refer to FIPS 203 dependencies. #20</t>
          </li>
          <li>
            <t>Move label at the end. As everything fits within a single block of SHA3-256,
this does not make any difference.</t>
          </li>
          <li>
            <t>Use SHAKE-256 to stretch seed. This does not have any security or performance
effects: as we only squeeze 96 bytes, we perform a single Keccak permutation
whether SHAKE-128 or SHAKE-256 is used. The effective capacity of the sponge
in both cases is 832, which gives a security of 416 bits. It does require
less thought from anyone analysing X-Wing in a rush.</t>
          </li>
          <li>
            <t>Add HPKE codepoint.</t>
          </li>
          <li>
            <t>Don't mark TLS entry as recommended before it has been through the
IETF consensus process. (Obviously the authors recommend X-Wing.)</t>
          </li>
        </ul>
      </section>
      <section anchor="since-draft-connolly-cfrg-xwing-kem-03">
        <name>Since draft-connolly-cfrg-xwing-kem-03</name>
        <ul spacing="normal">
          <li>
            <t>Mandate ML-KEM encapsulation key check, and stipulate effect
on TLS and HPKE integration.</t>
          </li>
          <li>
            <t>Add provisional TLS codepoint. (Not assigned, yet.)</t>
          </li>
        </ul>
      </section>
      <section anchor="since-draft-connolly-cfrg-xwing-kem-02">
        <name>Since draft-connolly-cfrg-xwing-kem-02</name>
        <ul spacing="normal">
          <li>
            <t>Use seed as private key.</t>
          </li>
          <li>
            <t>Expand on caching decapsulation key values.</t>
          </li>
          <li>
            <t>Expand on binding properties.</t>
          </li>
        </ul>
      </section>
      <section anchor="since-draft-connolly-cfrg-xwing-kem-01">
        <name>Since draft-connolly-cfrg-xwing-kem-01</name>
        <ul spacing="normal">
          <li>
            <t>Add list of implementations.</t>
          </li>
          <li>
            <t>Miscellaneous editorial improvements.</t>
          </li>
          <li>
            <t>Add Python reference specification.</t>
          </li>
          <li>
            <t>Correct definition of <tt>ML-KEM-768.KeyGenDerand(seed)</tt>.</t>
          </li>
        </ul>
      </section>
      <section anchor="since-draft-connolly-cfrg-xwing-kem-00">
        <name>Since draft-connolly-cfrg-xwing-kem-00</name>
        <ul spacing="normal">
          <li>
            <t>A copy of the X25519 public key is now included in the X-Wing
decapsulation (private) key, so that decapsulation does not
require separate access to the X-Wing public key. See #2.</t>
          </li>
        </ul>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
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
aNoXhZQJ36i6PSx3J/4dobzZOBH2ct/s5sCqnKdqzNQI8oY+Fne02tWreWOh
9OY9vtn3jkzlmzjK176ltFFPq35xulxCqfltgSHisQailihxeGPeUCrmJ5Ha
8jaT2UXudtek/9ZPdAdZ7QzryzxVvtGQG2BjumjJJpwUlEEoapx1OvVneVug
20ln941f1R++mrDVWjwqmI4ePHhwi3v9tf341rXH//bXpWs82a6+PmMl/fmv
/Z/XrPTnn1cb16zqUku+igAIJS+rrszHX7V++cUK63v1YtoX+qt88dJyw/Tn
5lHEn1s/PDZfn5laODpfiac9vlCX+ldzhl7atfPOOVJdKXerfknC1eqwpjnP
IkdejByrM/LNo/Gh/3GtummqIGMTw+Th8eXdZ+OlW7lTKqP9doWGa/Wn+hBW
4zixmYI5EWMO9Ly982R8vTc2X3RD3OaqyM9zq5kt9/mDI0Ly7MKEuGAeJCnP
ZtM4yGPO8ZhjPKb/t9V0qqcb8veM+GcGxZPWo8ant41P9NX4JPOdf1o4RmtZ
M1VWbxD83om6BUHpmaRCf/ne8NLcMFisso3lk3i1ZpeP4slhvDvO4pXrahiC
vtMQRBTLjUSuVQ9G3nMLZb0rRquN03f3GejSgbxbmltQuzlzJ0rndutHx9AW
pJZNSqkJoF22ysumTUrfS2fQavksH0L7Gw34sl7tXEg0WjF9GPHdI5zbPsp0
FmTyQ9n9e7VbVffxN2Ys89B/XcYaCrR++JBRACGkBOX6VmncYdBqifFJZvj5
r1/t5Gd0bn6yf37oOaXqcy3ZfSUdL3r3eNrj2ofOR+tPf7Lihx2T6DrmnXPZ
ZZXD16vWf7OGzU5OzYuOK7XtpGKU8q3bK5Xe6M/+aP0z0/Xj+oLnmCuOGzWv
/D8zt62mM59lWdzS1qjI5JVB6z/+V9A2c3hbvit6y24XbLNxfVpfNzfkBMPS
Ksz16ew6D5grXx3xbP731qxv/PuNf8fXStQwXbO4yd+2+cEuuzYQYS45FLVm
rTvy/+zbnxlfjsquXFp//rOFn/2z5czjp/T9b7/QYnapU1QjIrh5F2ZynkzO
mLvMcOHeNzNh7pWzXhzA9D+7tGF6wFq+ufNrcnFl4+FGqff68mbZdL3ZdFMu
rmw+3FxsKoZIL+vcn13bksc9GWk+oe3y2vrCNTP69vLoW2akreWRvgrD5JFH
NFi8uMLfD/lxsf23qv16s/23sr1D+2+e+WtpENcIZINbm0vjGzGv7HBH7j+y
VsQpH1o7plXtOPdr8j4tlooTDRpVtmoPMfN0GWA4uF6RRsN1+Wt1PqnKjczh
55UVeQRDw63F1CRy3OHd87BXRdW/KeqZr8S6HfSs/3Mw/e+F46ZiWXbYNt8L
XiFu06njxmvzdzBrMN4ZLGP26qM54DUYdMf1BfnWm7JkAi03I/XUZDZE0R0M
Rq3WF/TpeW7S6m8KZ/rFilvf9ERJVI9a/GCKKa1Wvwz8phHc7srY3JdHzurj
x66FhPvmu0FEGTQuc6I5jj+bQVteQM4nUzSx8nPZAIi/8vMlf/+cT83fV/I3
Yzo/YxFVL/L9jYKNyq0jiZxYWy6R0iHw5Vf84INaeEgWstqa5eOlp7z7n3Lr
pxzbpLPGU379lFM9FTSfMqlg3BvkK1/rhCZ+hCN8qR1uZP0ZOa0bOc19bmSt
/1K1qZxlZMxM9g/MSeO+ViNhfHLaRb5YtHyPW8q/5wPzHXlDM7Z5YD542RXP
rBjlrnwlGtjtYHV1hrblTbvxylcWs/hM2dEKGs6tx9aXVQlb4tDmyuoMt9Ud
3Mw7qJKcbf3pF6s8EHcjP8pzdwzwhd5NlwxwU/UrJnU2eCPfEUbOXbOub6dV
UjGTuZbIZTd7/VAjh0efP9IjPX82Pvl5Hl2uVxc3CJeCD9ZQDSADfyxnZOZy
NpCJLcyoAVc+fFhJJax1ZGLucq/0ZC6lcikdg6Q/fJwTC8nv6lavZbhsCqM5
DdN+zYpXG8q4s5sfdBCbNZbPp6Ormd3AxolwxoElvEbrcvKi+lanmuM3bOvn
n9ufMcKV6vuA8hXALH19cJ98bH8rOt3uiokS2PwqA4qbZF158ep40L0pB5QJ
/PqrHGz49VeYYrcAAI9/ORz0dQOkyPV2JlEEJa0+7Is3ZSYDSENLd+UImwkn
2Xiu4gX6ajowyKvfagys8nw27kBK3I1Rq3XKXFdW1KNU1PulfAthzWjzW2dY
91w9LWOsNvvv6/Oq/3s6/rKuqhcbOv16nauNDsbT9PcmKDfx7nVzuzn4eDK6
d/DigRn+t2rI7w+aD+ovf2RMo5FfZgufd3B4drY8ajbD5AtrlD9ddaMlVvat
xwSEOeboWLWHy5/ri05XV23/TEx5csuTB0Ux1pMFd+6vmwewvIfmh9XFp6ph
Hv3SQL2z6xL8BdUQ4teMi3zrYMJfVlu3mi5FmXIea9V8Ht03sPwxAOob0Sob
f/iMCk3bj6uzpLH8Z6GZPCsXPoIeJz9+ptH20V1tS7E+fvxLQ/5NI83GDaM+
0cUdCoYcgaFE1vJ18NXXp64tVsi1WEZ70SZgZg/7s0u3I3JfwsZtZTfkXdrN
XapdUCHpS7TYIfmuglUefjbKvENanVpaHZFWZa4f3IcmrXy7W9DS+pEze1B+
XHhULtx6+F4J7/ev/j4XWvKePmu904H+ZPX/gf6z/n/Xf8SuH1UusV6a+x/w
BsGtD2c+0ehj9ccPP5o7n4G+aJX/7/Wph3/IpQ6m3VrhtyOupOSt8ovXx2Ws
H5RtyvPJi1/vJI5m2pgvHzUJoTmp6gwEg8F0eqoDAWpW7kuPlJz6NzulwcG1
xXc+Lt5zm/fwhYW7qTxZJ5HlR1N34ebys4tWtuDht9x75tpKmDWjPjKqU6LD
1L2twIZPl23kifJZ9w868gxll5rN78EAs2aZtCm/lmUBDsw6bODuH3fZaPi7
nVYw9N4OG/cN0qlJwNh8f/qrfkeOC60ANrTqVU+XhlTqqgw8Z6Pyt/FVahWD
MA+0hZgvnO0Xc0ilYPfIgus+XEnluOF/s5yw0cZQTnMD3O2v0tQJH6Yf3Ll1
VOAvF6XBBRzRoDw27/vhw1h0+cGpPi33IBIzZ58+5ML43I+LBg8EzQWJfLkd
muTwSqc/1Uvm1Dbvo+Yr+epyR6bMXaHT293dMi9jWpvbguOx+9sUSVX7Dw+5
26rFfYsA3FLUkp/3F3JPPfkVQ7M+PKFrwux6Wa/9wKcn7kNzzbjG6oKmEavc
e/Kxde9y3h7trpTbQuTlTjXyRf12l+PG7b6+Xim7vWhPh/Ir6cwDUlk2bOmD
PPhxdaG6flF2fnyy61S99wf9TN+W2PL21mxkLPD3Rzad3ju0Ww3dG5//wwaW
vhZGq9yoLkQ8bW7jXSxuWnq/Bo67uGe52NeHcsPnQraZKha8t2Jmf+8WnNxt
7JqVJO+1zu7leMPxMr0biiWWJG7YjE53IKFqFvS/MmzL/TK8DWfhbfj7aGqh
j6rJD7vZHkz+YI4uv2NrdpzB+lPjmT9L5/el30ZNYUW1K1CQrlaU01rknMMZ
52Saq2u3ogZ/jIst8tE/wHdFJLDdO4nu4qB/S6IrBT1rl/9Y1n8gzZUdNlr+
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
2T/b3Xz1Zvfr+fvW04txtnfiF+UoO4fbt8cwk7g1E/ObuhsT2d/fcbY3DjfP
x6PN852djXfHvRfv9vb1+dHW5sHORuq8fNY5Hxy939x9+u7VZPjuxfDcfbqR
vLs62XukJs9aPfK9epkevHyxeeE+PXx+POi8TG8unr05ynf2nqd7z7JpkD17
473/Onz63FWbN/r9u63o5vDdi91nj3obvdbOztHVNHx1tb87PH++fbH/6nX3
i/ctU1dfeocHhOjj0yn47Oj4vX948fzxxfXusQ6eDrr2Ru+V/bZ4H7QON06+
2dnZZj64mL7t9Px4txMVe4dnu72L8WPnOgr9697ei41n2XOVPb36tnsanL24
mO4dvYuGn9PP3aw13N3Z9C++RvbO9dfjL09VfLm7GSXPJyc7u1+epcPj9+93
jpKks9Hf3jqLd75cbRwdH3anh9npl+P9jfHT5y3n6igfvjj13Xc3L5xgY3Ie
bkbD3aM37+3h+bPtm9Hlo/NjN93bz71D90t2fZiGO6/93tHZ+Yv+06v+xX7r
6uTw3eenJ9dH568c+/3g+PzNQdh1B893die9qHORbyfPXodb19sH758VL/0j
F8B7Eblb7/edwYve3rPPrTfPv+Qbacfvdp8Wlxcn9tS7fjW92e8+d66vdg5f
np6MezfH/fc7F88O+8mrpxdv3aP4cjAIpt7V3vG1dlvvs9M3U/f1u5vjk1cd
lU2/vhgdHh71d7sHByCy7HO8ffo63J9sX6pxL9je3PZG7070t8v3we7Xg6df
1aj1/Ogk8d7uu+/813vvLy6vMOrx8PpLpJ/eJOPry5tgcPP88PrqeLzX2x5s
vth+1pueReG73uvHp/7Rdn7QGr+YvvaPrp++3hzvvc97Wfz6CNj47uztc70x
fD12T7yOPni/q0865/EjeT9jcHL2yFVbO7u7m3F+fdjaOLzQ0duNKH1682bP
6++fnOajl5edV/2N9/6L7s6j8fAy7ebd85fTo4OrycB5ttO7mby8OLpSrLi3
/7T1ckM/27keXHcvT9+dvng3fDwdPn+xNbSPdwaH3rObb3Hy3n28+847SJ+N
Ty+GPW//5P3u9eYb5616G796GbXOVe/zyebzSD/eLA5u8rdvupcn3tlG/m73
6Gnx7fr6fG+nePp45/VFtBU9f/eyr27UbuC97uwcnX579Oz1Weti60C/fvf1
6tXLmxP/+OubSf50/+3j56/6wzeXKn76yC+GX5OXzx7tHJxsj48usYt8Z9t+
Hz672T/dmXaOW2+fTnsvh+lz/3B/7yp+d9w5KI4n2YkavDvKnx6Mva+7F9vB
q2dfTofb+xuj91ufg1fx4fuvz6+fbtivrkYbrcm3d/pFcph/279QGFJ+Fg82
3xw/9ZzryYtvJ0+PTjvDzdc7R4fx1+2d0+Eg7enh5puXWU8POtfvLp9ttl4H
12/3r06mzsX19Hg8fPX2Wff61dtd5+j9dGM7fZYPgjdn9tPTl87Xl+ONo87h
i3RzDzN44XqjF8Xkcq+VTA92dsfXh8GrweWLjcHFs88bV29fn+2/id9/ub46
j/Xb7u7k5fv4y+Xz5MX59fubYf4y7W6G4+dvnyVvDrzW1k4ve1o8ex7t7kR2
sBG+fYvD7PROwAPT6fu9zWuv8+x89+Zr+Llz/m1j/626KXY/vzk6CNRBT+28
jluP0t6jjf7N+f6rzbfdr1nXebWzFT7r9nen4y/u1uHukbuZXrw+vB6n++nR
2YvD6NXu+Zdh99vXR9Ppm/GJ2zp7f3ZcHHRfptd5NHp7sPkinTy/2Xz5/Gjv
5HJnOv5283p3t9vZLLK9d85FZ/+tm7579vTgXe/z+8Ody9fTnZbunLjX6tl1
/Pq0e7Ozb+92R8c3Ty+Di+sXR1907/8r7Wqb08aB8Hf/Cs105goh0PCa0Lt2
hoAhJHEgQNK096XGlrEL2ETCJCST/367K9lASm/Su2+xkKV90+6iMM8z8ULZ
m/P7cfmSm2e5sJEL7rpWpTm89aNc2X18MBreoCK+3FY688b0ftmewfeGu/lS
mMOLQeey+K3j355/cIProw+LRfNLNGjxo9unabyOWudm8dS/4UbPt36ET9er
dfjtdhnfx347Cs56Mvftw+2PsNMZ1VfluH5Xqc4rzUvv6T5Y3l1fCF66bv8o
t4vlu3Mjt/Iec/XTYklcmdCyDAbzwXrixTX+9PhlvSp+tY75wuo9Nk9jr7VY
uqVRbuLyyadPWwXtValKarniTbYUzfHzO2JN1lTeCso4eIQC78xiV6NM7hAt
Pz/f1U6OXl4I2k+VdVWwjb+avZbJqEwOPysaVGJvRkJkaE7YMwtklClmkQx4
zEV+HLnrTCkLDUUGmrYsE9J2ZZCBHqZaqWfZYuqkqFr0kK9nYFjOgznPFGtZ
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
FYx/AILQEqBJ2gAA

-->

</rfc>
