<?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.21 (Ruby 3.3.6) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-hybrid-kems-00" category="info" submissionType="IRTF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.25.0 -->
  <front>
    <title abbrev="hybrid-kems">Hybrid PQ/T Key Encapsulation Mechanisms</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-hybrid-kems-00"/>
    <author fullname="Deirdre Connolly">
      <organization>SandboxAQ</organization>
      <address>
        <email>durumcrustulum@gmail.com</email>
      </address>
    </author>
    <date year="2025" month="January" day="08"/>
    <workgroup>Crypto Forum</workgroup>
    <abstract>
      <?line 129?>

<t>This document defines generic techniques to achive hybrid
post-quantum/traditional (PQ/T) key encapsulation mechanisms (KEMs) from
post-quantum and traditional component algorithms that meet specified
security properties. It then uses those generic techniques to construct
several concrete instances of hybrid KEMs.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Discussion of this document takes place on the
    Crypto Forum Research Group mailing list (cfrg@ietf.org),
    which is archived at <eref target="https://mailarchive.ietf.org/arch/browse/cfrg"/>.</t>
      <t>Source for this draft and an issue tracker can be found at
    <eref target="https://github.com/cfrg/draft-irtf-cfrg-pq1"/>.</t>
    </note>
  </front>
  <middle>
    <?line 137?>

<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 this document is provide a small set of techniques for
constructing hybrid KEMs designed to achieve specific security properties
given conforming component algorithms, that should be suitable for the vast
majority of use cases.</t>
      </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="notation">
      <name>Notation</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:</t>
      <ul spacing="normal">
        <li>
          <t><tt>random(n)</tt>: return a pseudorandom byte string of length <tt>n</tt> bytes produced
by a cryptographically-secure random number generator.</t>
        </li>
        <li>
          <t><tt>concat(x0, ..., xN)</tt>: Concatenation of byte strings.  <tt>concat(0x01,
0x0203, 0x040506) = 0x010203040506</tt>.</t>
        </li>
        <li>
          <t><tt>I2OSP(n, w)</tt>: Convert non-negative integer <tt>n</tt> to a <tt>w</tt>-length, big-endian
byte string, as described in <xref target="RFC8017"/>.</t>
        </li>
        <li>
          <t><tt>OS2IP(x)</tt>: Convert byte string <tt>x</tt> to a non-negative integer, as described
in <xref target="RFC8017"/>, assuming big-endian byte order.</t>
        </li>
      </ul>
      <section anchor="kems">
        <name>Key encapsulation mechanisms</name>
        <t>Key encapsulation mechanisms (KEMs) are cryptographic schemes that consist of
three algorithms:</t>
        <ul spacing="normal">
          <li>
            <t><tt>KeyGen() -&gt; (pk, sk)</tt>: A probabilistic key generation algorithm, which
generates a public encapsulation key <tt>pk</tt> and a secret decapsulation key
<tt>sk</tt>.</t>
          </li>
          <li>
            <t><tt>Encaps(pk) -&gt; (ct, shared_secret)</tt>: A probabilistic encapsulation
algorithm, which takes as input a public encapsulation key <tt>pk</tt> and outputs
a ciphertext <tt>ct</tt> and shared secret <tt>shared_secret</tt>.</t>
          </li>
          <li>
            <t><tt>Decaps(sk, ct) -&gt; shared_secret</tt>: A decapsulation algorithm, which takes
as input a secret decapsulation key <tt>sk</tt> and ciphertext <tt>ct</tt> and outputs a
shared secret <tt>shared_secret</tt>.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="hybrid-kem-security-properties">
      <name>Hybrid KEM Security Properties</name>
      <t>Hybrid KEM constructions aim to provide security by combining two or more
schemes so that security is preserved if all but one schemes are replaced by
an arbitrarily bad scheme.</t>
      <section anchor="hybrid-security">
        <name>Hybrid Security</name>
        <t>Informally, hybrid KEMs are secure if the <tt>KDF</tt> is secure, and if any one of
the components KEMs is secure: this is the 'hybrid' property.</t>
      </section>
      <section anchor="ind-cca-security">
        <name>IND-CCA security</name>
        <t>Also known as IND-CCA2 security for general public key encryption, for KEMs
that encapsulate a new random 'message' each time.</t>
        <t>The notion of INDistinguishability against Chosen-Ciphertext Attacks
(IND-CCA) [RS92] is now widely accepted as the standard security notion for
asymmetric encryption schemes. IND-CCA security requires that no efficient
adversary can recognize which of two messages is encrypted in a given
ciphertext, even if the two candidate messages are chosen by the adversary
himself.</t>
      </section>
      <section anchor="ciphertext-second-preimage-resistant-c2pri-security-ciphertext-collision-resistance-ccr">
        <name>Ciphertext second preimage resistant (C2PRI) security / ciphertext collision resistance (CCR)</name>
        <t>The notion where, even if a KEM has broken IND-CCA security (either due to
construction, implementation, or other), its internal structure, based on the
Fujisaki-Okamoto transform, guarantees that it is impossible to find a second
ciphertext that decapsulates to the same shared secret <tt>K</tt>: this notion is
known as ciphertext second preimage resistance (C2SPI) for KEMs
<xref target="XWING"/>. The same notion has also been described as chosen ciphertext
resistance elsewhere <xref target="CDM23"/>.</t>
      </section>
      <section anchor="binding-properties">
        <name>Binding properties</name>
        <section anchor="x-bind-k-pk-security">
          <name>X-BIND-K-PK security</name>
        </section>
        <section anchor="x-bind-k-ct-security">
          <name>X-BIND-K-CT security</name>
          <t>Ciphertext second preimage resistance for KEMs ([C2PRI]<xref target="XWING"/>). Related to
the ciphertext collision-freeness of the underlying PKE scheme of a
FO-transform KEM. Also called ciphertext collision resistance.</t>
        </section>
      </section>
    </section>
    <section anchor="cryptographic-deps">
      <name>Cryptographic Dependencies</name>
      <t>The generic hybrid PQ/T KEM constructions we define depend on the the
following cryptographic primitives:</t>
      <ul spacing="normal">
        <li>
          <t>Extendable Output Function <xref target="xof"/></t>
        </li>
        <li>
          <t>Key Derivation Function <xref target="kdf"/></t>
        </li>
        <li>
          <t>Post-Quantum-secure KEM <xref target="pq-kem"/></t>
        </li>
        <li>
          <t>Nominal Diffie-Hellman Group <xref target="group"/></t>
        </li>
      </ul>
      <section anchor="xof">
        <name><tt>XOF</tt></name>
        <t>Extendable-output function (XOF). A function on bit strings in which the
output can be extended to any desired length. Ought to satisfy the following
properties as long as the specified output length is sufficiently long to
prevent trivial attacks:</t>
        <ol spacing="normal" type="1"><li>
            <t>(One-way) It is computationally infeasible to find any input that maps to
any new pre-specified output.</t>
          </li>
          <li>
            <t>(Collision-resistant) It is computationally infeasible to find any two
distinct inputs that map to the same output.</t>
          </li>
        </ol>
        <t><bcp14>MUST</bcp14> provide the bit-security required to source input randomness for PQ/T
components from a seed that is expanded to a output length, of which a subset
is passed to the component key generation algorithms.</t>
      </section>
      <section anchor="kdf">
        <name>Key Derivation Function <tt>KDF</tt></name>
        <t>A secure key derivation function (KDF) that is modeled as a secure
pseudorandom function (PRF) in the standard model <xref target="GHP2018"/> and independent
random oracle in the random oracle model (ROM).</t>
      </section>
      <section anchor="pq-kem">
        <name>Post-Quantum KEM</name>
        <t>An IND-CCA KEM that is resilient against post-quantum attacks. It fulfills
the scheme API in {kems}.</t>
        <section anchor="post-quantum-kem-ciphertext-pqct">
          <name>Post-quantum KEM ciphertext <tt>pq_CT</tt></name>
          <t>The ciphertext produced from one encapsulation from the post-quantum
component KEM.</t>
        </section>
        <section anchor="post-quantum-kem-public-encapsulation-key-pqpk">
          <name>Post-quantum KEM public encapsulation key <tt>pq_PK</tt></name>
          <t>The public encapsulation key produced by one key generation from the
post-quantum component KEM.</t>
        </section>
        <section anchor="post-quantum-kem-shared-secret-pqss">
          <name>Post-quantum KEM shared secret <tt>pq_SS</tt></name>
          <t>The shared secret produced from one encapsulation/decapsulation from the
post-quantum component KEM.</t>
        </section>
        <section anchor="traditional-kem-ciphertext-tradct">
          <name>Traditional KEM ciphertext <tt>trad_CT</tt></name>
          <t>The ciphertext (or equivalent) produced from one encapsulation from the
traditional component KEM. For the constructions in this document, this is a
Diffie-Hellman group element.</t>
        </section>
        <section anchor="traditional-kem-public-encapsulation-key-tradpk">
          <name>Traditional KEM public encapsulation key <tt>trad_PK</tt></name>
          <t>The public encapsulation key produced by one key generation from the
traditional component KEM. For the constructions in this document, this is a
Diffie-Hellman group element.</t>
        </section>
        <section anchor="traditional-kem-shared-secret-tradss">
          <name>Traditional KEM shared secret <tt>trad_SS</tt></name>
          <t>The shared secret produced from one encapsulation/decapsulation from the
traditional component KEM. For the constructions in this document, this is a
Diffie-Hellman group element.</t>
        </section>
      </section>
      <section anchor="group">
        <name>Nominal Diffie-Hellman Group</name>
        <t>The traditional DH-KEM construction depends on an abelian group of order
<tt>order</tt>. We represent this group as the object <tt>G</tt> that additionally defines
helper functions described below. The group operation for <tt>G</tt> is addition <tt>+</tt>
with identity element <tt>I</tt>. For any elements <tt>A</tt> and <tt>B</tt> of the group <tt>G</tt>,
<tt>A + B = B + A</tt> is also a member of <tt>G</tt>. Also, for any <tt>A</tt> in <tt>G</tt>, there
exists an element <tt>-A</tt> such that <tt>A + (-A) = (-A) + A = I</tt>. For convenience,
we use <tt>-</tt> to denote subtraction, e.g., <tt>A - B = A + (-B)</tt>.  Integers, taken
modulo the group order <tt>order</tt>, are called scalars; arithmetic operations on
scalars are implicitly performed modulo <tt>order</tt>. Scalar multiplication is
equivalent to the repeated application of the group operation on an element
<tt>A</tt> with itself <tt>r-1</tt> times, denoted as <tt>ScalarMult(A, r)</tt>. We denote the
sum, difference, and product of two scalars using the <tt>+</tt>, <tt>-</tt>, and <tt>*</tt>
operators, respectively. (Note that this means <tt>+</tt> may refer to group element
addition or scalar addition, depending on the type of the operands.) For any
element <tt>A</tt>, <tt>ScalarMult(A, order) = I</tt>.  We denote <tt>B</tt> as a fixed generator
of the group. Scalar base multiplication is equivalent to the repeated
application of the group operation on <tt>B</tt> with itself <tt>r-1</tt> times, this is
denoted as <tt>ScalarBaseMult(r)</tt>. The set of scalars corresponds to
<tt>GF(order)</tt>, which we refer to as the scalar field. It is assumed that group
element addition, negation, and equality comparison can be efficiently
computed for arbitrary group elements.</t>
        <t>This document uses types <tt>Element</tt> and <tt>Scalar</tt> to denote elements of the
group <tt>G</tt> and its set of scalars, respectively. We denote <tt>Scalar(x)</tt> as the
conversion of integer input <tt>x</tt> to the corresponding <tt>Scalar</tt> value with the
same numeric value. For example, <tt>Scalar(1)</tt> yields a <tt>Scalar</tt> representing
the value 1.  We denote equality comparison of these types as <tt>==</tt> and
assignment of values by <tt>=</tt>. When comparing Scalar values, e.g., for the
purposes of sorting lists of Scalar values, the least nonnegative
representation mod <tt>order</tt> is used.</t>
        <t>We now detail a number of member functions that can be invoked on <tt>G</tt>.</t>
        <ul spacing="normal">
          <li>
            <t>Order(): Outputs the order of <tt>G</tt> (i.e., <tt>order</tt>).</t>
          </li>
          <li>
            <t>Identity(): Outputs the identity <tt>Element</tt> of the group (i.e., <tt>I</tt>).</t>
          </li>
          <li>
            <t>RandomScalar(): Outputs a random <tt>Scalar</tt> element in GF(order), i.e., a
random scalar in [0, order - 1].</t>
          </li>
          <li>
            <t>ScalarMult(A, k): Outputs the scalar multiplication between Element <tt>A</tt> and
Scalar <tt>k</tt>.</t>
          </li>
          <li>
            <t>ScalarBaseMult(k): Outputs the scalar multiplication between Scalar <tt>k</tt> and
the group generator <tt>B</tt>.</t>
          </li>
          <li>
            <t>SerializeElement(A): Maps an <tt>Element</tt> <tt>A</tt> to a canonical byte array <tt>buf</tt>
of fixed length <tt>Ne</tt>. This function raises an error if <tt>A</tt> is the identity
element of the group.</t>
          </li>
          <li>
            <t>DeserializeElement(buf): Attempts to map a byte array <tt>buf</tt> to an <tt>Element</tt>
              <tt>A</tt>, and fails if the input is not the valid canonical byte representation
of an element of the group. This function raises an error if
deserialization fails or if <tt>A</tt> is the identity element of the group.</t>
          </li>
          <li>
            <t>SerializeScalar(s): Maps a Scalar <tt>s</tt> to a canonical byte array <tt>buf</tt> of
fixed length <tt>Ns</tt>.</t>
          </li>
          <li>
            <t>DeserializeScalar(buf): Attempts to map a byte array <tt>buf</tt> to a <tt>Scalar</tt>
              <tt>s</tt>.  This function raises an error if deserialization fails.</t>
          </li>
        </ul>
      </section>
    </section>
    <section anchor="other">
      <name>Other</name>
      <section anchor="label">
        <name><tt>label</tt></name>
        <t>ASCII-encoded bytes that provide oracle cloning <xref target="BDG2020"/> in the security
game via domain separation. The IND-CCA security of hybrid KEMs often
relies on the KDF function <tt>KDF</tt> to behave as an independent
random oracle, which the inclusion of the <tt>label</tt> achieves via domain
separation <xref target="GHP2018"/>.</t>
        <t>By design, the calls to <tt>KDF</tt> in these constructions and usage anywhere else
in higher level protoocl use separate input domains unless intentionally
duplicating the 'label' per concrete instance with fixed paramters. This
justifies modeling them as independent functions even if instantiated by the
same KDF. This domain separation is achieved by using prefix-free sets of
<tt>label</tt> values. Recall that a set is prefix-free if no element is a prefix of
another within the set.</t>
        <t>Length diffentiation is sometimes used to achieve domain separation but as a
technique it is [brittle and prone to misuse]<xref target="BDG2020"/> in practice so we
favor the use of an explicit post-fix label.</t>
      </section>
    </section>
    <section anchor="hybrid-kem-generic-constructions">
      <name>Hybrid KEM Generic Constructions</name>
      <section anchor="common-security-requirements">
        <name>Common security requirements</name>
        <section anchor="kdf-as-a-secure-prf">
          <name>KDF as a secure PRF</name>
          <t>A key derivation function (KDF) that is modeled as a secure pseudorandom
function (PRF) in the standard model <xref target="GHP2018"/> and independent random oracle
in the random oracle model (ROM).</t>
        </section>
        <section anchor="ind-cca-secure-post-quantum-kem">
          <name>IND-CCA-secure Post-Quantum KEM</name>
          <t>A component post-quantum KEM that has IND-CCA security.</t>
        </section>
        <section anchor="ind-cca-secure-traditional-kem">
          <name>IND-CCA-secure traditional KEM</name>
          <t>A component traditional KEM that has IND-CCA security.</t>
        </section>
        <section anchor="fixed-lengths">
          <name>Fixed lengths</name>
          <t>Every instantiation in concrete parameters of the generic constructions is
for fixed parameter sizes, KDF choice, and label, allowing the lengths to not
also be encoded into the generic construction. The label/KDF/component
algorithm parameter sets <bcp14>MUST</bcp14> be disjoint and non-colliding.</t>
          <t>This document assumes and requires that the length of each public key,
ciphertext, and shared secret is fixed once the algorithm is fixed in the
concrete instantiations. This is the case for all concrete instantiations in
this document.</t>
        </section>
      </section>
      <section anchor="keygen">
        <name>Key Generation</name>
        <t>We specify a common generic key generation scheme for all generic
constructions. This requires the component key generation algorithns to
accept the sufficient random seed, possibly according to their parameter set.</t>
        <!-- TODO: make keygen generic -->
<t>### Key derivation {#derive-key-pair}</t>
        <!-- TODO: make key derivation generic -->

</section>
      <section anchor="kitchen-sink-construction">
        <name>'Kitchen Sink' construction:</name>
        <t>As indicated by the name, the <tt>KitchenSink</tt> construction puts 'the whole
transcript' through the KDF. This relies on the minimum security properties
of its component algorithms at the cost of more bytes needing to be processed
by the KDF.</t>
        <artwork><![CDATA[
def KitchenSink-KEM.SharedSecret(pq_SS, trad_SS, pq_CT, pq_PK, trad_CT, trad_PK):
    return KDF(concat(pq_SS, trad_SS, pq_CT, pq_PK, trad_CT, trad_PK, label))
]]></artwork>
        <section anchor="security-properties">
          <name>Security properties</name>
          <t>Because the entire hybrid KEM ciphertext and encapsulation key material are
included in the KDF preimage, the <tt>KitchenSink</tt> construction is resilient
against implementation errors in the component algorithms. <!-- TODO: cite
that thing -->
          </t>
          <!-- ## 'CtKDF' construction {#ctkdf} ? -->

<!-- https://eprint.iacr.org/2023/972.pdf -->

<!-- A key derivation function (KDF) is a function on four arguments (s, r,
c, ℓ), -->
<t><!-- where s is the input key material, r is salt, c is arbitrary
information (a.k.a. --> <!-- “info”) associated with the output key material,
and ℓ is the desired output key --> <!-- material length. -->
          </t>
          <!-- ~~~ -->
<t><!-- def ctKDF-KEM.SharedSecret(pq_SS, trad_SS, trad_CT, pq_CT,
trad_PK, pq_PK): --> <!-- secret = concat(pq_SS, trad_SS) --> <!-- v' =
f(context, concat(pq_PK, trad_PK), concat(pq_CT, trad_CT)) --> <!-- return
KDF(secret, label, v', length) --> <!-- ~~~ -->
          </t>
          <!-- ### Security properties -->

<!-- - IND-CCA in the Random Oracle Model, as long as at least one KEM is
correct -->
<t><!-- and OW-CCA secure. In this setting, the KDF is modeled as a
random oracle. -->
          </t>
        </section>
      </section>
      <section anchor="QSF">
        <name>'QSF' construction</name>
        <t>Inspired by the generic QSF (Quantum Superiority Fighter) framework in <xref target="XWING"/>,
which leverages the security properties of a KEM like ML-KEM and an inlined instance
of DH-KEM, to elide other public data like the PQ ciphertext and encapsulation key from
the KDF input:</t>
        <artwork><![CDATA[
def QSF-KEM.SharedSecret(pq_SS, trad_SS, trad_CT, trad_PK):
    return KDF(concat(pq_SS, trad_SS, trad_CT, trad_PK, label))
]]></artwork>
        <section anchor="requirements">
          <name>Requirements</name>
          <section anchor="nominal-diffie-hellman-group-with-strong-diffie-hellman-security">
            <name>Nominal Diffie-Hellman Group with strong Diffie-Hellman security</name>
            <t>A cryptographic group modelable as a nominal group where the strong
Diffie-Hellman assumption holds {XWING}. Specically regarding a nominal
group, this means that especially the QSF construction's security is
based on a computational-Diffie-Hellman-like problem, but no assumption is
made about the format of the generated group element - no assumption is made
that the shared group element is indistinguishable from random bytes.</t>
            <t>The concrete instantiations in this document use elliptic curve groups that
have been modeled as nominal groups in the literature.</t>
          </section>
          <section anchor="post-quantum-ind-cca-kem-with-ciphertext-second-preimage-resistance">
            <name>Post-quantum IND-CCA KEM with ciphertext second preimage resistance</name>
            <t>The QSF relies the post-quantum KEM component having IND-CCA security against
a post-quantum attacker, and ciphertext second preimage resistance (C2SPI,
also known as chosen ciphertext resistance, CCR). C2SPI/CCR is <xref target="CDM23">equivalent to
LEAK-BIND-K,PK-CT security</xref></t>
          </section>
          <section anchor="kdf-is-a-secure-post-quantum-prf-modelable-as-a-random-oracle">
            <name>KDF is a secure (post-quantum) PRF, modelable as a random oracle</name>
            <t>Indistinguishability of the final shared secret from a random key is
established by modeling the key-derivation function as a random
oracle <xref target="XWING"/>.</t>
          </section>
        </section>
      </section>
    </section>
    <section anchor="concrete-hybrid-kem-instances">
      <name>Concrete Hybrid KEM Instances</name>
      <section anchor="qsf-sha3-256-ml-kem-768-p-256-todo-include-the-xof-">
        <name><tt>QSF-SHA3-256-ML-KEM-768-P-256</tt> <!-- TODO: include the XOF?? -->
        </name>
        <t>Also known as <xref target="XWING"/> but with P-256 instead of X25519.</t>
        <ul spacing="normal">
          <li>
            <t><tt>label</tt>: <tt>QSF-SHA3-256-ML-KEM-768-P-256</tt></t>
          </li>
          <li>
            <t><tt>XOF</tt>: [SHAKE-256][FIPS202]</t>
          </li>
          <li>
            <t><tt>KDF</tt>: [SHA3-256][FIPS202]</t>
          </li>
          <li>
            <t>PQ KEM: <xref target="FIPS203">ML-KEM-768</xref></t>
          </li>
          <li>
            <t>Group: [P-256]<xref target="FIPS186"/> (secp256r1) <xref target="ANSIX9.62"/>, where Ne = 33 and Ns = 32.</t>
          </li>
        </ul>
        <t>This instantiation uses P-256 for the Group.</t>
        <!-- TODO: this is the FROST style, which uses 33 bytes for the serialized
group element. It doesn't match the existing HPKE KEM style, which uses 65
bytes for the serialized element. The 33-byte version is compressed, which
may have implications for binding properties, but is compressed vs not
sufficiently distinct to matter, when the sign is encoded. Align? Don't?

If we pick the smaller, we may figure out how to get the label size down to
fit the whole preimage into the Keccak block input size, which would be nice
for performance. But that might be trying to hard to over-engineer this. -->

<ul spacing="normal">
          <li>
            <t>Group: P-256
            </t>
            <ul spacing="normal">
              <li>
                <t>Order(): Return
0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551.</t>
              </li>
              <li>
                <t>Identity(): As defined in <xref target="ANSIX9.62"/>.</t>
              </li>
              <li>
                <t>RandomScalar(): Implemented by returning a uniformly random Scalar in the
range [0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for
implementation guidance.</t>
              </li>
              <li>
                <t>SerializeElement(A): Implemented using the compressed
Elliptic-Curve-Point-to-Octet-String method according to <xref target="SEC1"/>,
yielding a 33-byte output. Additionally, this function validates that the
input element is not the group identity element.</t>
              </li>
              <li>
                <t>DeserializeElement(buf): Implemented by attempting to deserialize a
33-byte input string to a public key using the compressed
Octet-String-to-Elliptic-Curve-Point method according to <xref target="SEC1"/>, and
then performs public-key validation as defined in section 3.2.2.1 of
<xref target="SEC1"/>.  This includes checking that the coordinates of the resulting
point are in the correct range, that the point is on the curve, and that
the point is not the point at infinity. (As noted in the specification,
validation of the point order is not required since the cofactor is 1.)
If any of these checks fail, deserialization returns an error.</t>
              </li>
              <li>
                <t>SerializeScalar(s): Implemented using the Field-Element-to-Octet-String
conversion according to <xref target="SEC1"/>.</t>
              </li>
              <li>
                <t>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar
from a 32-byte string using Octet-String-to-Field-Element from
<xref target="SEC1"/>. This function can fail if the input does not represent a Scalar
in the range [0, <tt>G.Order()</tt> - 1].</t>
              </li>
            </ul>
          </li>
        </ul>
        <section anchor="key-generation">
          <name>Key generation</name>
          <t>A keypair (decapsulation key, encapsulation key) is generated as follows.</t>
          <!-- TODO: include the label in keygen? Concat with seed? -->

<artwork><![CDATA[
def expandDecapsulationKey(sk):
  expanded = SHAKE256(sk, 96)
  (pk_M, sk_M) = ML-KEM-768.KeyGen_internal(expanded[0:32], expanded[32:64])
  sk_G = Scalar(expanded[64:96])
  pk_G = ScalarMultBase(sk_G)
  return (sk_M, sk_G, pk_M, pk_G)

def GenerateKeyPair():
  sk = random(32)
  (sk_M, sk_G, pk_M, pk_G) = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_G)
]]></artwork>
          <t><tt>GenerateKeyPair()</tt> returns the 32 byte secret decapsulation key <tt>sk</tt> and the
1217 byte encapsulation key <tt>pk</tt>.</t>
          <t>For testing, it is convenient to have a deterministic version of key
generation. An implementation <bcp14>MAY</bcp14> provide the following derandomized variant
of key generation.</t>
          <artwork><![CDATA[
def GenerateKeyPairDerand(sk):
  sk_M, sk_G, pk_M, pk_G = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_X)
]]></artwork>
          <t><tt>sk</tt> <bcp14>MUST</bcp14> be 32 bytes.</t>
          <t><tt>GenerateKeyPairDerand()</tt> returns the 32 byte secret decapsulation key <tt>sk</tt>
and the 1217 byte encapsulation key <tt>pk</tt>.</t>
        </section>
      </section>
      <section anchor="shared-secret">
        <name>Shared secret</name>
        <t>Given 32-byte strings <tt>ss_M</tt>, <tt>ss_G</tt>, and the 33-byte strings <tt>ct_G</tt>, <tt>pk_G</tt>,
representing the ML-KEM-768 shared secret, P-256 shared secret, P-256
ciphertext (ephemeral public key) and P-256 public key respectively, the 32
byte combined shared secret is given by:</t>
        <artwork><![CDATA[
def SharedSecret(ss_M, ss_G, ct_G, pk_G):
  return SHA3-256(concat(
    ss_M,
    ss_X,
    ct_G,
    pk_G,
    `label`
  ))
]]></artwork>
        <t>where <tt>label</tt> is the instance <tt>label</tt>. In hex <tt>label</tt> is given by <tt>TODO</tt>.</t>
      </section>
      <section anchor="encapsulation">
        <name>Encapsulation</name>
        <t>Given an encapsulation key <tt>pk</tt>, encapsulation proceeds as follows.</t>
        <artwork><![CDATA[
def Encapsulate(pk):
  pk_M = pk[0:1184]
  pk_G = pk[1184:1217]
  ek_G = RandomScalar()
  ct_G = ScalarMultBase(ek_G)
  ss_G = ScalarMult(ek_G, pk_G)
  (ss_M, ct_M) = ML-KEM-768.Encaps(pk_M)
  ss = SharedSecret(ss_M, ss_G, ct_G, pk_G)
  ct = concat(ct_M, ct_G)
  return (ss, ct)
]]></artwork>
        <t><tt>pk</tt> is a 1217 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 1121 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="FIPS203"/> §7.2.</t>
        <section anchor="derandomized">
          <name>Derandomized</name>
          <t>For testing, it is convenient to have a deterministic version of
encapsulation. An implementation <bcp14>MAY</bcp14> provide the following derandomized
function.</t>
          <artwork><![CDATA[
def EncapsulateDerand(pk, eseed):
  pk_M = pk[0:1184]
  pk_G = pk[1184:1217]
  ek_G = eseed[32:65]
  ct_G = ScalarMultBase(ek_G)
  ss_G = ScalarMult(ek_G, pk_G)

  (ss_M, ct_M) = ML-KEM-768.EncapsDerand(pk_M, eseed[0:32])
  ss = SharedSecret(ss_M, ss_G, ct_G, pk_G)
  ct = concat(ct_M, ct_G)
  return (ss, ct)
]]></artwork>
          <t><tt>pk</tt> is a 1217 byte X-Wing encapsulation key resulting from
<tt>GeneratePublicKey()</tt> <tt>eseed</tt> <bcp14>MUST</bcp14> be 65 bytes.</t>
          <t><tt>EncapsulateDerand()</tt> returns the 32 byte shared secret <tt>ss</tt> and the 1121
byte ciphertext <tt>ct</tt>.</t>
        </section>
      </section>
      <section anchor="decapsulation">
        <name>Decapsulation</name>
        <artwork><![CDATA[
def Decapsulate(ct, sk):
  (sk_M, sk_G, pk_M, pk_G) = expandDecapsulationKey(sk)
  ct_M = ct[0:1088]
  ct_G = ct[1088:1121]
  ss_M = ML-KEM-768.Decapsulate(ct_M, sk_M)
  ss_G = ScalarMult(sk_G, ct_G)
  return SharedSecret(ss_M, ss_G, ct_G, pk_G)
]]></artwork>
        <t><tt>ct</tt> is the 1121 byte ciphertext resulting from <tt>Encapsulate()</tt> <tt>sk</tt> is a 32
byte decapsulation key resulting from <tt>GenerateKeyPair()</tt></t>
        <t><tt>Decapsulate()</tt> returns the 32 byte shared secret.</t>
        <section anchor="security-properties-1">
          <name>Security properties</name>
          <section anchor="binding">
            <name>Binding</name>
            <t>The inlined DH-KEM is instantiated over the elliptic curve group P-256: as
shown in <xref target="CDM23"/>, this gives the traditional KEM maximum binding
properties (MAL-BIND-K-CT, MAL-BIND-K-PK).</t>
            <t>ML-KEM-768 as standardized in <xref target="FIPS203"/>, when using the 64-byte seed key
format as is here, provides MAL-BIND-K-CT security and LEAK-BIND-K-PK
security, as demonstrated in <xref target="SCHMIEG2024"/>.</t>
            <t>Therefore this concrete instance provides MAL-BIND-K-PK and MAL-BIND-K-CT
security. <!-- TODO: update XWING paper to show this -->
            </t>
            <t>This implies via <xref target="KSMW2024"/> that this instance 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>
          </section>
        </section>
      </section>
      <section anchor="kitchensink-hkdf-sha-256-ml-kem-768-x25519-todo-include-the-xof-">
        <name><tt>KitchenSink-HKDF-SHA-256-ML-KEM-768-X25519</tt> <!-- TODO: include the XOF?? -->
        </name>
        <ul spacing="normal">
          <li>
            <t><tt>label</tt>: <tt>KitchenSink-HKDF-SHA-256-ML-KEM-768-X25519</tt></t>
          </li>
          <li>
            <t><tt>XOF</tt>: [SHAKE-256][FIPS202]</t>
          </li>
          <li>
            <t><tt>KDF</tt>: <xref target="HKDF">HKDF-SHA-256</xref></t>
          </li>
        </ul>
        <t>HKDF is comprised of <tt>HKDF-Extract</tt> and <tt>HKDF-Expand</tt>. We compose them as one
function here:</t>
        <!-- TODO: double check on whether the public context should go in `*_info`
or if -->
<t><!-- all concatted is fine; i think a separate label is ok? HKDF as
a split PRF seems extra?-->
        </t>
        <artwork><![CDATA[
def LabeledExtract(salt, label, ikm):
  labeled_ikm = concat("Hybrid", suite_id, label, ikm)
  return HDKF-Extract(salt, labeled_ikm)

def LabeledExpand(prk, label, info, L):
  labeled_info = concat(I2OSP(L, 2), "Hybrid", suite_id,
                        label, info)
  return HKDF-Expand(prk, labeled_info, L)


def HKDF(preimage):
  prk = LabeledExtract("", "hybrid_prk", preimage)
  shared_secret = LabeledExpand(prk, "shared_secret", "", 32)
  return shared_secret
]]></artwork>
        <ul spacing="normal">
          <li>
            <t>PQ KEM: ML-KEM-768 <xref target="FIPS203"/></t>
          </li>
          <li>
            <t>Group: X25519 <xref target="X25519"/></t>
          </li>
        </ul>
        <t>This instantiation uses X25519 for the Group.</t>
        <ul spacing="normal">
          <li>
            <t>Group: Curve25519 <xref target="X25519"/>, where Ne = 32 and Ns = 32.
            </t>
            <ul spacing="normal">
              <li>
                <t>Order(): Return 2^252 + 0x14def9dea2f79cd65812631a5cf5d3ed (see
  <xref target="RFC7748"/>).</t>
              </li>
              <li>
                <t>Identity(): As defined in <xref target="RFC7748"/>.</t>
              </li>
              <li>
                <t>RandomScalar(): Implemented by returning a uniformly random Scalar in the
range [0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for
implementation guidance.</t>
              </li>
              <li>
                <t>SerializeElement(A): Implemented as specified in <xref target="RFC7748"/>.</t>
              </li>
              <li>
                <t>DeserializeElement(buf): Implemented as specified in <xref target="RFC7748"/>.</t>
              </li>
              <li>
                <t>SerializeScalar(s): Implemented by outputting the little-endian 32-byte
encoding of the Scalar value with the top three bits set to zero. <!--
TODO: check -->
                </t>
              </li>
              <li>
                <t>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar
from a little-endian 32-byte string. This function can fail if the input
does not represent a Scalar in the range [0, <tt>G.Order()</tt> - 1]. Note
that this means the top three bits of the input <bcp14>MUST</bcp14> be zero. <!-- TODO:
check -->
                </t>
              </li>
            </ul>
          </li>
        </ul>
        <section anchor="key-generation-1">
          <name>Key generation</name>
          <t>A keypair (decapsulation key, encapsulation key) is generated as follows.</t>
          <!-- TODO: include the label in keygen? Concat with seed? -->

<artwork><![CDATA[
def expandDecapsulationKey(sk):
  expanded = SHAKE256(sk, 96)
  (pk_M, sk_M) = ML-KEM-768.KeyGen_internal(expanded[0:32], expanded[32:64])
  sk_G = Scalar(expanded[64:96])
  pk_G = ScalarMultBase(sk_G)
  return (sk_M, sk_G, pk_M, pk_G)

def GenerateKeyPair():
  sk = random(32)
  (sk_M, sk_G, pk_M, pk_G) = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_G)
]]></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>For testing, it is convenient to have a deterministic version of key
generation. An implementation <bcp14>MAY</bcp14> provide the following derandomized variant
of key generation.</t>
          <artwork><![CDATA[
def GenerateKeyPairDerand(sk):
  sk_M, sk_G, pk_M, pk_G = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_X)
]]></artwork>
          <t><tt>sk</tt> <bcp14>MUST</bcp14> 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="shared-secret-1">
        <name>Shared secret</name>
        <t>Given 32-byte strings <tt>ss_M</tt>, <tt>ss_G</tt>, <tt>ct_G</tt>, <tt>pk_G</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 SharedSecret(ss_M, ss_G, ct_G, pk_G):
  return HKDF(concat(
    ss_M,
    ss_X,
    ct_G,
    pk_G,
    `label`
  ))
]]></artwork>
        <t>where <tt>label</tt> is the instance <tt>label</tt>. In hex <tt>label</tt> is given by <tt>TODO</tt>.</t>
      </section>
      <section anchor="encapsulation-1">
        <name>Encapsulation</name>
        <t>Given an encapsulation key <tt>pk</tt>, encapsulation proceeds as follows.</t>
        <artwork><![CDATA[
def Encapsulate(pk):
  pk_M = pk[0:1184]
  pk_G = pk[1184:1216]
  ek_G = RandomScalar()
  ct_G = ScalarMultBase(ek_G)
  ss_G = ScalarMult(ek_G, pk_G)
  (ss_M, ct_M) = ML-KEM-768.Encaps(pk_M)
  ss = SharedSecret(ss_M, ss_G, ct_G, pk_G)
  ct = concat(ct_M, ct_G)
  return (ss, ct)
]]></artwork>
        <t><tt>pk</tt> is a 1216 byte 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="FIPS203"/> §7.2.</t>
        <section anchor="derandomized-1">
          <name>Derandomized</name>
          <t>For testing, it is convenient to have a deterministic version of
encapsulation. An implementation <bcp14>MAY</bcp14> provide the following derandomized
function.</t>
          <artwork><![CDATA[
def EncapsulateDerand(pk, eseed):
  pk_M = pk[0:1184]
  pk_G = pk[1184:1216]
  ek_G = eseed[32:64]
  ct_G = ScalarMultBase(ek_G)
  ss_G = ScalarMult(ek_G, pk_G)

  (ss_M, ct_M) = ML-KEM-768.EncapsDerand(pk_M, eseed[0:32])
  ss = SharedSecret(ss_M, ss_G, ct_G, pk_G)
  ct = concat(ct_M, ct_G)
  return (ss, ct)
]]></artwork>
          <t><tt>pk</tt> is a 1217 byte X-Wing encapsulation key resulting from
<tt>GeneratePublicKey()</tt> <tt>eseed</tt> <bcp14>MUST</bcp14> be 65 bytes.</t>
          <t><tt>EncapsulateDerand()</tt> returns the 32 byte shared secret <tt>ss</tt> and the 1121
byte ciphertext <tt>ct</tt>.</t>
        </section>
      </section>
      <section anchor="decapsulation-1">
        <name>Decapsulation</name>
        <artwork><![CDATA[
def Decapsulate(ct, sk):
  (sk_M, sk_G, pk_M, pk_G) = expandDecapsulationKey(sk)
  ct_M = ct[0:1088]
  ct_G = ct[1088:1120]
  ss_M = ML-KEM-768.Decapsulate(ct_M, sk_M)
  ss_G = ScalarMult(sk_G, ct_G)
  return SharedSecret(ss_M, ss_G, ct_G, pk_G)
]]></artwork>
        <t><tt>ct</tt> is the 1120 byte ciphertext resulting from <tt>Encapsulate()</tt> <tt>sk</tt> is a 32
byte decapsulation key resulting from <tt>GenerateKeyPair()</tt></t>
        <t><tt>Decapsulate()</tt> returns the 32 byte shared secret.</t>
        <section anchor="security-properties-2">
          <name>Security properties</name>
          <!-- TODO: say something about HKDF as a KDF -->

<section anchor="binding-1">
            <name>Binding</name>
            <t>The inlined DH-KEM instantiated over the elliptic curve group X25519: as
shown in <xref target="CDM23"/>, this gives the traditional KEM maximum binding
properties (MAL-BIND-K-CT, MAL-BIND-K-PK).</t>
            <t>ML-KEM-768 as standardized in <xref target="FIPS203"/>, when using the 64-byte seed key
format as is here, provides MAL-BIND-K-CT security and LEAK-BIND-K-PK
security, as demonstrated in <xref target="SCHMIEG2024"/>. Further, the ML-KEM ciphertext
and encapsulation key are included in the KDF preimage, giving
straightforward CT and PK binding for the entire bytes of the hybrid KEM
ciphertext and encapsulation key. Therefore this concrete instance provides
MAL-BIND-K-PK and MAL-BIND-K-CT security.</t>
            <t>This implies via <xref target="KSMW2024"/> that this instance 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>
          </section>
        </section>
      </section>
      <section anchor="qsf-sha3-256-ml-kem-1024-p-384-todo-include-the-xof-">
        <name><tt>QSF-SHA3-256-ML-KEM-1024-P-384</tt> <!-- TODO: include the XOF?? -->
        </name>
        <ul spacing="normal">
          <li>
            <t><tt>label</tt>: <tt>QSF-SHA3-256-ML-KEM-768-P-256</tt></t>
          </li>
          <li>
            <t><tt>XOF</tt>: [SHAKE-256][FIPS202]</t>
          </li>
          <li>
            <t><tt>KDF</tt>: [SHA3-256][FIPS202]</t>
          </li>
          <li>
            <t>PQ KEM: <xref target="FIPS203">ML-KEM-1024</xref></t>
          </li>
          <li>
            <t>Group: [P-384]<xref target="FIPS186"/> (secp256r1) <xref target="ANSIX9.62"/>, where Ne = 33 and Ns = 32.</t>
          </li>
        </ul>
        <t>This instantiation uses P-384 for the Group.</t>
        <!-- TODO: this is the FROST style, which uses 33 bytes for the serialized
group element. It doesn't match the existing HPKE KEM style, which uses 65
bytes for the serialized element. The 33-byte version is compressed, which
may have implications for binding properties, but is compressed vs not
sufficiently distinct to matter, when the sign is encoded. Align? Don't?

If we pick the smaller, we may figure out how to get the label size down to
fit the whole preimage into the Keccak block input size, which would be nice
for performance. But that might be trying to hard to over-engineer this. -->

<ul spacing="normal">
          <li>
            <t>Group: P-384
            </t>
            <ul spacing="normal">
              <li>
                <t>Order(): Return
0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf
581a0db248b0a77aecec196accc52973</t>
              </li>
              <li>
                <t>Identity(): As defined in <xref target="ANSIX9.62"/>.</t>
              </li>
              <li>
                <t>RandomScalar(): Implemented by returning a uniformly random Scalar in the
range [0, <tt>G.Order()</tt> - 1]. Refer to <xref target="random-scalar"/> for
implementation guidance.</t>
              </li>
              <li>
                <t>SerializeElement(A): Implemented using the compressed
Elliptic-Curve-Point-to-Octet-String method according to <xref target="SEC1"/>,
yielding a 61-byte output. Additionally, this function validates that the
input element is not the group identity element.</t>
              </li>
              <li>
                <t>DeserializeElement(buf): Implemented by attempting to deserialize a
61-byte input string to a public key using the compressed
Octet-String-to-Elliptic-Curve-Point method according to <xref target="SEC1"/>, and
then performs public-key validation as defined in section 3.2.2.1 of
<xref target="SEC1"/>.  This includes checking that the coordinates of the resulting
point are in the correct range, that the point is on the curve, and that
the point is not the point at infinity. (As noted in the specification,
validation of the point order is not required since the cofactor is 1.)
If any of these checks fail, deserialization returns an error.</t>
              </li>
              <li>
                <t>SerializeScalar(s): Implemented using the Field-Element-to-Octet-String
conversion according to <xref target="SEC1"/>.</t>
              </li>
              <li>
                <t>DeserializeScalar(buf): Implemented by attempting to deserialize a Scalar
from a 48-byte string using Octet-String-to-Field-Element from
<xref target="SEC1"/>. This function can fail if the input does not represent a Scalar
in the range [0, <tt>G.Order()</tt> - 1].</t>
              </li>
            </ul>
          </li>
        </ul>
        <section anchor="key-generation-2">
          <name>Key generation</name>
          <t>A keypair (decapsulation key, encapsulation key) is generated as follows.</t>
          <!-- TODO: include the label in keygen? Concat with seed? -->

<artwork><![CDATA[
def expandDecapsulationKey(sk):
  expanded = SHAKE256(sk, 112)
  (pk_M, sk_M) = ML-KEM-1024.KeyGen_internal(expanded[0:32], expanded[32:64])
  sk_G = Scalar(expanded[64:112])
  pk_G = ScalarMultBase(sk_G)
  return (sk_M, sk_G, pk_M, pk_G)

def GenerateKeyPair():
  sk = random(32)
  (sk_M, sk_G, pk_M, pk_G) = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_G)
]]></artwork>
          <t><tt>GenerateKeyPair()</tt> returns the 32 byte secret decapsulation key <tt>sk</tt> and the
1629 byte encapsulation key <tt>pk</tt>.</t>
          <t>For testing, it is convenient to have a deterministic version of key
generation. An implementation <bcp14>MAY</bcp14> provide the following derandomized variant
of key generation.</t>
          <artwork><![CDATA[
def GenerateKeyPairDerand(sk):
  sk_M, sk_G, pk_M, pk_G = expandDecapsulationKey(sk)
  return sk, concat(pk_M, pk_X)
]]></artwork>
          <t><tt>sk</tt> <bcp14>MUST</bcp14> be 32 bytes.</t>
          <t><tt>GenerateKeyPairDerand()</tt> returns the 32 byte secret decapsulation key <tt>sk</tt>
and the 1629 byte encapsulation key <tt>pk</tt>.</t>
        </section>
      </section>
      <section anchor="shared-secret-2">
        <name>Shared secret</name>
        <t>Given 32-byte string <tt>ss_M</tt>, the 61-byte strings <tt>ss_G</tt>, <tt>ct_G</tt>, <tt>pk_G</tt>,
representing the ML-KEM-1024 shared secret, P-384 shared secret, P-384
ciphertext (ephemeral public key) and P-384 public key respectively, the 32
byte combined shared secret is given by:</t>
        <artwork><![CDATA[
def SharedSecret(ss_M, ss_G, ct_G, pk_G):
  return SHA3-256(concat(
    ss_M,
    ss_X,
    ct_G,
    pk_G,
    `label`
  ))
]]></artwork>
        <t>where <tt>label</tt> is the instance <tt>label</tt>. In hex <tt>label</tt> is given by <tt>TODO</tt>.</t>
      </section>
      <section anchor="encapsulation-2">
        <name>Encapsulation</name>
        <t>Given an encapsulation key <tt>pk</tt>, encapsulation proceeds as follows.</t>
        <artwork><![CDATA[
def Encapsulate(pk):
  pk_M = pk[0:1568]
  pk_G = pk[1568:1629]
  ek_G = RandomScalar()
  ct_G = ScalarMultBase(ek_G)
  ss_G = ScalarMult(ek_G, pk_G)
  (ss_M, ct_M) = ML-KEM-1024.Encaps(pk_M)
  ss = SharedSecret(ss_M, ss_G, ct_G, pk_G)
  ct = concat(ct_M, ct_G)
  return (ss, ct)
]]></artwork>
        <t><tt>pk</tt> is a 1629 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 1629 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="FIPS203"/> §7.2.</t>
        <section anchor="derandomized-2">
          <name>Derandomized</name>
          <t>For testing, it is convenient to have a deterministic version of
encapsulation. An implementation <bcp14>MAY</bcp14> provide the following derandomized
function.</t>
          <artwork><![CDATA[
def EncapsulateDerand(pk, eseed):
  pk_M = pk[0:1568]
  pk_G = pk[1568:1629]
  ek_G = eseed[32:80]
  ct_G = ScalarMultBase(ek_G)
  ss_G = ScalarMult(ek_G, pk_G)

  (ss_M, ct_M) = ML-KEM-768.EncapsDerand(pk_M, eseed[0:32])
  ss = SharedSecret(ss_M, ss_G, ct_G, pk_G)
  ct = concat(ct_M, ct_G)
  return (ss, ct)
]]></artwork>
          <t><tt>pk</tt> is a 1629 byte X-Wing encapsulation key resulting from
<tt>GeneratePublicKey()</tt> <tt>eseed</tt> <bcp14>MUST</bcp14> be 80 bytes.</t>
          <t><tt>EncapsulateDerand()</tt> returns the 32 byte shared secret <tt>ss</tt> and the 1629
byte ciphertext <tt>ct</tt>.</t>
        </section>
      </section>
      <section anchor="decapsulation-2">
        <name>Decapsulation</name>
        <artwork><![CDATA[
def Decapsulate(ct, sk):
  (sk_M, sk_G, pk_M, pk_G) = expandDecapsulationKey(sk)
  ct_M = ct[0:1568]
  ct_G = ct[1568:1629]
  ss_M = ML-KEM-1024.Decapsulate(ct_M, sk_M)
  ss_G = ScalarMult(sk_G, ct_G)
  return SharedSecret(ss_M, ss_G, ct_G, pk_G)
]]></artwork>
        <t><tt>ct</tt> is the 1629 byte ciphertext resulting from <tt>Encapsulate()</tt> <tt>sk</tt> is a 32
byte decapsulation key resulting from <tt>GenerateKeyPair()</tt></t>
        <t><tt>Decapsulate()</tt> returns the 32 byte shared secret.</t>
        <section anchor="security-properties-3">
          <name>Security properties</name>
          <section anchor="binding-2">
            <name>Binding</name>
            <t>The inlined DH-KEM is instantiated over the elliptic curve group P-384: as
shown in <xref target="CDM23"/>, this gives the traditional KEM maximum binding
properties (MAL-BIND-K-CT, MAL-BIND-K-PK).</t>
            <t>ML-KEM-1024 as standardized in <xref target="FIPS203"/>, when using the 64-byte seed key
format as is here, provides MAL-BIND-K-CT security and LEAK-BIND-K-PK
security, as demonstrated in <xref target="SCHMIEG2024"/>.</t>
            <t>Therefore this concrete instance provides MAL-BIND-K-PK and MAL-BIND-K-CT
security. <!-- TODO: update XWING paper to show this -->
            </t>
            <t>This implies via <xref target="KSMW2024"/> that this instance 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>
          </section>
        </section>
      </section>
    </section>
    <section anchor="random-scalar">
      <name>Random Scalar Generation</name>
      <t>Two popular algorithms for generating a random integer uniformly distributed in
the range [0, G.Order() -1] are as follows:</t>
      <section anchor="rejection-sampling">
        <name>Rejection Sampling</name>
        <t>Generate a random byte array with <tt>Ns</tt> bytes, and attempt to map to a Scalar
by calling <tt>DeserializeScalar</tt> in constant time. If it succeeds, return the
result. If it fails, try again with another random byte array, until the
procedure succeeds. Failure to implement <tt>DeserializeScalar</tt> in constant time
can leak information about the underlying corresponding Scalar.</t>
        <t>As an optimization, if the group order is very close to a power of
2, it is acceptable to omit the rejection test completely.  In
particular, if the group order is p, and there is an integer b
such that |p - 2<sup>b</sup>| is less than 2<sup>(b/2)</sup>, then
<tt>RandomScalar</tt> can simply return a uniformly random integer of at
most b bits.</t>
      </section>
      <section anchor="wide-reduction">
        <name>Wide Reduction</name>
        <t>Generate a random byte array with <tt>l = ceil(((3 * ceil(log2(G.Order()))) / 2) / 8)</tt>
bytes, and interpret it as an integer; reduce the integer modulo <tt>G.Order()</tt> and return the
result. See <xref section="5" sectionFormat="of" target="HASH-TO-CURVE"/> for the underlying derivation of <tt>l</tt>.</t>
      </section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>Informally, these hybrid KEMs are secure if the <tt>KDF</tt> is secure, and either
the elliptic curve is secure, or the post-quantum KEM is secure: this is the
'hybrid' property.</t>
      <t>More precisely for the concrete instantiations in this document, if SHA3-256,
SHA3-512, and SHAKE-256 may be modelled as a random oracle, then the IND-CCA
security of <tt>QSF</tt> constructions is bounded by the IND-CCA security of ML-KEM,
and the gap-CDH security of secp256n1, see <xref target="XWING"/>.</t>
      <section anchor="fixed-length">
        <name>Fixed-length</name>
        <t>Variable-length secrets are generally dangerous. In particular, using key
material of variable length and processing it using hash functions may result
in a timing side channel. In broad terms, when the secret is longer, the hash
function may need to process more blocks internally. In some unfortunate
circumstances, this has led to timing attacks, e.g. the Lucky Thirteen
<xref target="LUCKY13"/> and Raccoon <xref target="RACCOON"/> attacks.</t>
        <t>Furthermore, <xref target="AVIRAM"/> identified a risk of using variable-length secrets when
the hash function used in the key derivation function is no longer
collision-resistant.</t>
        <t>If concatenation were to be used with values that are not fixed-length, a
length prefix or other unambiguous encoding would need to be used to ensure
that the composition of the two values is injective and requires a mechanism
different from that specified in this document.</t>
        <t>Therefore, this specification <bcp14>MUST</bcp14> only be used with algorithms which have
fixed-length shared secrets (after the variant has been fixed by the
algorithm identifier in the NamedGroup negotiation in Section 3.1).</t>
      </section>
    </section>
    <section anchor="out-of-scope">
      <name>Out of Scope</name>
      <t>Considerations that were considered and not included in these designs:</t>
      <section anchor="more-than-two-component-kems">
        <name>More than two component KEMs</name>
        <t>Design team decided to restrict the space to only two components, a
traditional and a post-quantum KEM.</t>
      </section>
      <section anchor="parameterized-output-length">
        <name>Parameterized output length</name>
        <t>Not analyzed as part of any security proofs in the literature, and a
complicatation deemed unnecessary.</t>
      </section>
      <section anchor="protocol-specific-labels-info">
        <name>Protocol-specific labels / info</name>
        <t>The concrete instantiations have specific labels, protocol-specific
information is out of scope.</t>
      </section>
      <section anchor="other-component-primitives">
        <name>Other Component Primitives</name>
        <t>There is demand for other hybrid variants that either use different
primitives (RSA, NTRU, Classic McEliece, FrodoKEM), parameters, or that use a
combiner optimized for a specific use case. Other use cases could be covered
in subsequent documents and not included here.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <section anchor="hpke">
        <name>HPKE</name>
        <t>TODO</t>
      </section>
    </section>
  </middle>
  <back>
    <references anchor="sec-combined-references">
      <name>References</name>
      <references anchor="sec-normative-references">
        <name>Normative References</name>
        <reference anchor="FIPS203">
          <front>
            <title>Module-lattice-based key-encapsulation mechanism standard</title>
            <author>
              <organization/>
            </author>
            <date month="August" year="2024"/>
          </front>
          <seriesInfo name="DOI" value="10.6028/nist.fips.203"/>
          <refcontent>National Institute of Standards and Technology (U.S.)</refcontent>
        </reference>
        <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="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="RFC8017">
          <front>
            <title>PKCS #1: RSA Cryptography Specifications Version 2.2</title>
            <author fullname="K. Moriarty" initials="K." role="editor" surname="Moriarty"/>
            <author fullname="B. Kaliski" initials="B." surname="Kaliski"/>
            <author fullname="J. Jonsson" initials="J." surname="Jonsson"/>
            <author fullname="A. Rusch" initials="A." surname="Rusch"/>
            <date month="November" year="2016"/>
            <abstract>
              <t>This document provides recommendations for the implementation of public-key cryptography based on the RSA algorithm, covering cryptographic primitives, encryption schemes, signature schemes with appendix, and ASN.1 syntax for representing keys and for identifying the schemes.</t>
              <t>This document represents a republication of PKCS #1 v2.2 from RSA Laboratories' Public-Key Cryptography Standards (PKCS) series. By publishing this RFC, change control is transferred to the IETF.</t>
              <t>This document also obsoletes RFC 3447.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8017"/>
          <seriesInfo name="DOI" value="10.17487/RFC8017"/>
        </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="HASH-TO-CURVE">
          <front>
            <title>Hashing to Elliptic Curves</title>
            <author fullname="A. Faz-Hernandez" initials="A." surname="Faz-Hernandez"/>
            <author fullname="S. Scott" initials="S." surname="Scott"/>
            <author fullname="N. Sullivan" initials="N." surname="Sullivan"/>
            <author fullname="R. S. Wahby" initials="R. S." surname="Wahby"/>
            <author fullname="C. A. Wood" initials="C. A." surname="Wood"/>
            <date month="August" year="2023"/>
            <abstract>
              <t>This document specifies a number of algorithms for encoding or hashing an arbitrary string to a point on an elliptic curve. This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9380"/>
          <seriesInfo name="DOI" value="10.17487/RFC9380"/>
        </reference>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="ANSIX9.62">
          <front>
            <title>Public Key Cryptography for the Financial Services Industry: the Elliptic Curve Digital Signature Algorithm (ECDSA)</title>
            <author>
              <organization>ANS</organization>
            </author>
            <date year="2005" month="November"/>
          </front>
          <seriesInfo name="ANS" value="X9.62-2005"/>
        </reference>
        <reference anchor="AVIRAM" target="https://mailarchive.ietf.org/arch/msg/tls/F4SVeL2xbGPaPB2GW_GkBbD_a5M/">
          <front>
            <title>[TLS] Combining Secrets in Hybrid Key Exchange in TLS 1.3</title>
            <author initials="" surname="Nimrod Aviram">
              <organization/>
            </author>
            <author initials="" surname="Benjamin Dowling">
              <organization/>
            </author>
            <author initials="" surname="Ilan Komargodski">
              <organization/>
            </author>
            <author initials="" surname="Kenny Paterson">
              <organization/>
            </author>
            <author initials="" surname="Eyal Ronen">
              <organization/>
            </author>
            <author initials="" surname="Eylon Yogev">
              <organization/>
            </author>
            <date year="2021" month="September" day="01"/>
          </front>
        </reference>
        <reference anchor="BDG2020" target="https://eprint.iacr.org/2020/241.pdf">
          <front>
            <title>Separate Your Domains: NIST PQC KEMs, Oracle Cloning and Read-Only Indifferentiability</title>
            <author>
              <organization/>
            </author>
            <date year="2020"/>
          </front>
        </reference>
        <reference anchor="CDM23" target="https://eprint.iacr.org/2023/1933.pdf">
          <front>
            <title>Keeping Up with the KEMs: Stronger Security Notions for KEMs and automated analysis of KEM-based protocols</title>
            <author initials="C." surname="Cremers" fullname="Cas Cremers">
              <organization>CISPA Helmholtz Center for Information Security</organization>
            </author>
            <author initials="A." surname="Dax" fullname="Alexander Dax">
              <organization>CISPA Helmholtz Center for Information Security</organization>
            </author>
            <author initials="N." surname="Medinger" fullname="Niklas Medinger">
              <organization>CISPA Helmholtz Center for Information Security</organization>
            </author>
            <date year="2023"/>
          </front>
        </reference>
        <reference anchor="FIPS186">
          <front>
            <title>Digital Signature Standard (DSS)</title>
            <author>
              <organization/>
            </author>
            <date month="February" year="2023"/>
          </front>
          <seriesInfo name="DOI" value="10.6028/nist.fips.186-5"/>
          <refcontent>National Institute of Standards and Technology (U.S.)</refcontent>
        </reference>
        <reference anchor="GHP2018" target="https://eprint.iacr.org/2018/024.pdf">
          <front>
            <title>KEM Combiners</title>
            <author>
              <organization/>
            </author>
            <date year="2018"/>
          </front>
        </reference>
        <reference anchor="I-D.driscoll-pqt-hybrid-terminology">
          <front>
            <title>Terminology for Post-Quantum Traditional Hybrid Schemes</title>
            <author fullname="Florence 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="KSMW2024" 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="LUCKY13" target="https://ieeexplore.ieee.org/iel7/6547086/6547088/06547131.pdf">
          <front>
            <title>Lucky Thirteen: Breaking the TLS and DTLS record protocols</title>
            <author initials="N. J." surname="Al Fardan">
              <organization/>
            </author>
            <author initials="K. G." surname="Paterson">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="RACCOON" target="https://raccoon-attack.com/">
          <front>
            <title>Raccoon Attack: Finding and Exploiting Most-Significant-Bit-Oracles in TLS-DH(E)</title>
            <author initials="R." surname="Merget">
              <organization/>
            </author>
            <author initials="M." surname="Brinkmann">
              <organization/>
            </author>
            <author initials="N." surname="Aviram">
              <organization/>
            </author>
            <author initials="J." surname="Somorovsky">
              <organization/>
            </author>
            <author initials="J." surname="Mittmann">
              <organization/>
            </author>
            <author initials="J." surname="Schwenk">
              <organization/>
            </author>
            <date year="2020" month="September"/>
          </front>
        </reference>
        <reference anchor="HKDF">
          <front>
            <title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</title>
            <author fullname="H. Krawczyk" initials="H." surname="Krawczyk"/>
            <author fullname="P. Eronen" initials="P." surname="Eronen"/>
            <date month="May" year="2010"/>
            <abstract>
              <t>This document specifies a simple Hashed Message Authentication Code (HMAC)-based key derivation function (HKDF), which can be used as a building block in various protocols and applications. The key derivation function (KDF) is intended to support a wide range of applications and requirements, and is conservative in its use of cryptographic hash functions. This document is not an Internet Standards Track specification; it is published for informational purposes.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="5869"/>
          <seriesInfo name="DOI" value="10.17487/RFC5869"/>
        </reference>
        <reference anchor="SCHMIEG2024" target="https://eprint.iacr.org/2024/523.pdf">
          <front>
            <title>Unbindable Kemmy Schmidt: ML-KEM is neither MAL-BIND-K-CT nor MAL-BIND-K-PK</title>
            <author initials="S." surname="Schmieg" fullname="Sophie Schmieg">
              <organization/>
            </author>
            <date year="2024"/>
          </front>
        </reference>
        <reference anchor="SEC1" target="https://secg.org/sec1-v2.pdf">
          <front>
            <title>Elliptic Curve Cryptography, Standards for Efficient Cryptography Group, ver. 2</title>
            <author>
              <organization/>
            </author>
            <date year="2009"/>
          </front>
        </reference>
        <reference anchor="X25519">
          <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="XWING" target="https://eprint.iacr.org/2024/039.pdf">
          <front>
            <title>X-Wing: The Hybrid KEM You’ve Been Looking For</title>
            <author>
              <organization/>
            </author>
            <date year="2024"/>
          </front>
        </reference>
      </references>
    </references>
    <?line 1252?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>TODO acknowledge.</t>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+192XbjRpbgO74iKvMhqSqCEqkllaqyPUxqbaUWi+ntZGmS
IBCkYIEADYCSaHXWqYf5g3mac2bOmbf5j/6U+pK5WwABkLLkpW1XV2a3SxIQ
iLhx4+73RoTruk4e5pHeUc8O58M0DNT556tv1bGeq73Y96bZLPLyMInVifav
vDjMJtkzxxsOU32zo67oC/daTzLH93I9TtL5jgrjUeI4QeLH3gT6DVJvlLth
mo9cf5SOXesjd23NyWbDSZhlMEQ+n0Lzo4u3+46fxJmOs1m2o0ZelGkHBlt3
bpP0epwmsykA20vn0zxR+0k6mzxzHG+WXyXpjqNcR8G/0SyKePRdHaZBqlUv
ieMkiub0OknHMJXvaWI7qu/FwTC5635O7/TECyOAegYd++ksy2fRbPLfxvi0
5ScTx4mTdAJf3ugdar9/dN7vrK3DSGdHrfZaa2uts716etR/28I3LXjlOIgR
66Puaf/o61etrQ73YPB/PhtGoU+o59mNU296NVfwrcqvtNoPYy/2Qy9SfZ3e
hL7O1FEcAISIdGywF0XhNIcuerP0RqvdcBzm2Docx14+AyR0I1ihML+aqMZe
b7ffXXlGAASwdDvqNLlpqs7a2iY9y3Qa6gwBZyCVegZgP9tRBLhbtCsQT/9c
+Uko3sGJ4nS/PLronshcvXSsc6CcPJ9mO6uriFYv9a8AM61Q56MWfLeKD1Yn
2Xg1j7LV/Y3+l/pN5254cO6dv+4cfPX+4Pr1cPe9t3myWkHfu7dv+pewzpNh
GIfxGJDkpzrPgByVUDYR9R2S8VjjY/hAtVvrNhI6a522u/bKXWv/4OzCGCjz
NJykSaC6N2HqTZY3ea3jb70JDLWb3EYA1PJWR5EXq+NkArhJguw6XN7qWMfx
XJ0DmGmWxMvb7M1hvS+SWD/4PgJW/iYZ6xt48Xr3AOa7VqXCvp56KQwCrWYp
wA0rRJMFigbR0FPHeydZU52lnh8BV0F3iGvgIHWhvcA9i6M5UmU4GulUx3no
DcMozOfPlq6+nqZhnLdCz09p4RGa1c5GuzUNRtVFWYM/e7snnfUqsMdaT3H8
L6bqFuiauAABBKbO0wSWOUUymAHNz4G+kd0zYidsQ0DDAsMMcw2/xV40z8JM
JSN87Q69DJ5O0yRP/CTKnjyB9dX2q/X1xRmsP05QvRYwvp7A+hbPWYj1vGzh
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
+Dsw501LGO3/A7uuzLKwqAAA

-->

</rfc>
