<?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.39 (Ruby 3.4.9) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-kemeleon-02" category="info" submissionType="IRTF" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.34.0 -->
  <front>
    <title abbrev="Kemeleon">Kemeleon Encodings</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-kemeleon-02"/>
    <author fullname="Felix Günther">
      <organization>IBM Research Europe - Zurich</organization>
      <address>
        <email>mail@felixguenther.info</email>
      </address>
    </author>
    <author fullname="Douglas Stebila">
      <organization>University of Waterloo</organization>
      <address>
        <email>dstebila@uwaterloo.ca</email>
      </address>
    </author>
    <author fullname="Shannon Veitch">
      <organization>ETH Zurich</organization>
      <address>
        <email>shannon.veitch@inf.ethz.ch</email>
      </address>
    </author>
    <date year="2026" month="July" day="03"/>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 80?>

<t>This document specifies Kemeleon encoding algorithms for encoding ML-KEM encapsulation keys and ciphertexts as random bytestrings.
Kemeleon encodings provide obfuscation of encapsulation keys and ciphertexts, relying on module LWE assumptions.</t>
    </abstract>
    <note removeInRFC="true">
      <name>About This Document</name>
      <t>
        The latest revision of this draft can be found at <eref target="https://ssveitch.github.io/draft-kemeleon/draft-irtf-cfrg-kemeleon.html"/>.
        Status information for this document may be found at <eref target="https://datatracker.ietf.org/doc/draft-irtf-cfrg-kemeleon/"/>.
      </t>
      <t>Source for this draft and an issue tracker can be found at
        <eref target="https://github.com/ssveitch/draft-kemeleon"/>.</t>
    </note>
  </front>
  <middle>
    <?line 85?>

<section anchor="intro">
      <name>Introduction</name>
      <t>ML-KEM <xref target="FIPS203"/> is a post-quantum key-encapsulation mechanism (KEM) recently standardized by NIST,
Many applications are transitioning from classical Diffie-Hellman (DH) based solutions to constructions based on ML-KEM.
The use of Elligator and related Hash-to-Curve <xref target="RFC9380"/> algorithms are ubiquitous in DH-based protocols where DH shares are required to be encoded as, and look indistinguishable from, random bytestrings.
For example, applications using Elligator include protocols used for censorship circumvention in Tor <xref target="OBFS4"/>, password-authenticated key exchange (PAKE) protocols <xref target="CPACE"/> <xref target="OPAQUE"/>, and private set intersection (PSI) <xref target="ECDH-PSI"/>.</t>
      <t>For the post-quantum transition, an analogous encoding for (ML-)KEM encapsulation keys and ciphertexts to random bytestrings is required.
This document specifies such an encoding, Kemeleon, for ML-KEM encapsulation keys and ciphertexts.
Kemeleon was introduced in <xref target="GSV24"/> for building an (post-quantum) "obfuscated" KEM whose encapsulation keys and ciphertexts are indistinguishable from random.
This document specifies a version of the Kemeleon encoding that avoids any failure probability, as well as an alternate version that trades some failure probability for smaller encoding size.</t>
    </section>
    <section anchor="conventions">
      <name>Conventions and Definitions</name>
      <t>The key words "<bcp14>MUST</bcp14>", "<bcp14>MUST NOT</bcp14>", "<bcp14>REQUIRED</bcp14>", "<bcp14>SHALL</bcp14>", "<bcp14>SHALL
NOT</bcp14>", "<bcp14>SHOULD</bcp14>", "<bcp14>SHOULD NOT</bcp14>", "<bcp14>RECOMMENDED</bcp14>", "<bcp14>NOT RECOMMENDED</bcp14>",
"<bcp14>MAY</bcp14>", and "<bcp14>OPTIONAL</bcp14>" in this document are to be interpreted as
described in BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      <?line -18?>

</section>
    <section anchor="notation">
      <name>Notation / ML-KEM Background</name>
      <t>A KEM consists of three algorithms:</t>
      <ul spacing="normal">
        <li>
          <t><tt>KeyGen() -&gt; (ek, dk)</tt>: A probabilistic key generation algorithm that, with no input, generates an encapsulation key <tt>ek</tt> and a decapsulation key <tt>dk</tt>.</t>
        </li>
        <li>
          <t><tt>Encaps(ek) -&gt; (c, K)</tt>: A probabilistic encapsulation algorithm that takes as input an encapsulation key <tt>ek</tt>, and outputs a ciphertext <tt>ct</tt> and shared secret <tt>K</tt>.</t>
        </li>
        <li>
          <t><tt>Decaps(dk, c) -&gt; K</tt>: A decapsulation algorithm that takes as input a decapsulation key <tt>dk</tt> and ciphertext <tt>c</tt>, and outputs a shared secret <tt>K</tt>.</t>
        </li>
      </ul>
      <t>The following variables and functions are adopted from <xref target="FIPS203"/>:</t>
      <ul spacing="normal">
        <li>
          <t><tt>q = 3329</tt>, <tt>n = 256</tt></t>
        </li>
        <li>
          <t><tt>Compress_d : x -&gt; round((2^d/q)*x) mod 2^d</tt> (Equation 4.7 <xref target="FIPS203"/>)</t>
        </li>
        <li>
          <t><tt>Decompress_d : y -&gt; round((q/2^d)*y)</tt> (Equation 4.8 <xref target="FIPS203"/>)</t>
        </li>
        <li>
          <t><tt>k = 2</tt> for ML-KEM-512, <tt>k = 3</tt> for ML-KEM-768, <tt>k = 4</tt> for ML-KEM-1024</t>
        </li>
        <li>
          <t>remaining parameters <tt>d_u</tt>, <tt>d_v</tt>, etc. are defined by the respective ML-KEM parameter set (Table 2 <xref target="FIPS203"/>) -- this document writes <tt>du</tt> and <tt>dv</tt> in place of <tt>d_u</tt>, <tt>d_v</tt> in pseudocode</t>
        </li>
      </ul>
      <t><tt>ML-KEM.KeyGen()</tt> (Section 7.1 <xref target="FIPS203"/>) produces an encapsulation key, <tt>ek</tt> and a decapsulation key, <tt>dk</tt>.
Encapsulation keys consist of byte-encoded vectors of coefficients in Z_q, where each coefficient is encoded in 12 bits, together with a 32-byte seed for generating the matrix <tt>A</tt>.
<tt>ML-KEM.Encaps(ek)</tt> (Section 7.2 <xref target="FIPS203"/>) produces ciphertexts consisting of byte-encoded compressed vectors of cofficients, where each coefficient in Z_q is compressed by a certain number of bits (depending on the ML-KEM parameter set).</t>
      <t>The following terms and notation are used throughout this document:</t>
      <ul spacing="normal">
        <li>
          <t><tt>a[i]</tt> denotes the <tt>i</tt>th position of a vector <tt>a</tt> of coefficients</t>
        </li>
        <li>
          <t><tt>concat(x0, ..., xN)</tt>: returns the concatenation of bytestrings.</t>
        </li>
      </ul>
    </section>
    <section anchor="kemeleon">
      <name>Kemeleon Encoding</name>
      <t>At a high level, the constructions in this document instantiate the following functions:</t>
      <ul spacing="normal">
        <li>
          <t><tt>EncodeEk(ek) -&gt; eek</tt> is the (possibly randomized) encoding algorithm that on input an encapsulation key, outputs an obfuscated encapsulation key or an error.</t>
        </li>
        <li>
          <t><tt>DecodeEk(eek) -&gt; ek</tt> is the deterministic decoding algorithm that on input an obfuscated encapsulation key, outputs an encapsulation key.</t>
        </li>
        <li>
          <t><tt>EncodeCtxt(c) -&gt; ec</tt> is the (possibly randomized) encoding algorithm that on input a ciphertext, outputs an obfuscated ciphertext or an error.</t>
        </li>
        <li>
          <t><tt>DecodeCtxt(ec) -&gt; c</tt> is the deterministic decoding algorithm that on input an obfuscated ciphertext, outputs a ciphertext.</t>
        </li>
      </ul>
      <section anchor="common-func">
        <name>Common Functions</name>
        <t>The following function <tt>VectorEncode</tt> maps a vector of length <tt>n</tt> of coefficients modulo <tt>q</tt> to a large integer <tt>r</tt> such that <tt>r</tt> is byte-aligned and (statistically close to) uniformly distributed.
<tt>VectorEncode</tt> first accumulates the coefficients into a large integer <tt>r</tt> and then, applying the technique from <xref target="ELL2"/>, adds <tt>m * q^n</tt>,
where <tt>m</tt> is chosen at random from <tt>[0,floor((2^3072-r)/(q^n))]</tt>.
This results in an encoded output value byte-aligned to <tt>384</tt> bytes (the same size as the standard ML-KEM vector encoding)
whose statistical distance from uniform is at most <tt>2^-76</tt>.</t>
        <artwork><![CDATA[
VectorEncode(a):
   r = 0
   t = 76   # stat. distance from uniform and byte-aligned
   b = 2996 # ceil(n*log2(q))
   for i from 1 to n:
      r += q^(i-1)*a[i]
   m <--$ [0,...,floor((2^(b+t)-r)/(q^(n)))]
   r = r + m*q^n
   return r
]]></artwork>
        <t>The following function <tt>VectorDecode</tt> inverts the above mapping.</t>
        <artwork><![CDATA[
VectorDecode(r):
   r = r % q^n
   for i from 1 to n:
      a[i] = r % q
      r = r // q
   return a
]]></artwork>
        <t>The following algorithm <tt>SamplePreimage</tt> samples an uncompressed pre-image of a coefficient <tt>c</tt> at random, where <tt>u</tt> is the decompressed value of <tt>c</tt>.
It must take as input values of <tt>u</tt> that are output from <tt>Decompress_d</tt>.
The mapping is based on the <tt>Compress_d</tt>, <tt>Decompress_d</tt> algorithms from (Section 4.2.1 <xref target="FIPS203"/>).</t>
        <artwork><![CDATA[
SamplePreimage(d,u,c):
   if d == 10:
      if Compress_d(u + 2) == c:
         rand <--$ [-1,0,1,2]
      else if Compress_d(u - 2) == c:
         rand <--$ [-2,-1,0,1]
      else:
         rand <--$ [-1,0,1]
      return u + rand
   if d == 11:
      if Compress_d(u + 1) == c:
         rand <--$ [0,1]
      else if Compress_d(u - 1) == c:
         rand <--$ [-1,0]
      else:
         rand = 0
      return u + rand
   if d == 5:
      if u == 0:
         rand <--$ [-52,...,52]
      else if u <= 1560:
         rand <--$ [-51,...,52]
      else:
         rand <--$ [-52,...,51]
      return u + rand
   if d == 4:
      if u == 0:
         rand <--$ [-104,...,104]
      else if u <= 1456:
         rand <--$ [-103,...,104]
      else:
         rand <--$ [-104,...,103]
      return u + rand
   else:
      return err
]]></artwork>
      </section>
      <section anchor="pk-encoding">
        <name>Encoding Encapsulation Keys</name>
        <t>The following algorithms encode ML-KEM encapsulation keys as random bytestrings.
<tt>rho</tt> is the public seed used to generate the public matrix <tt>A</tt> <xref target="FIPS203"/>.
This is already a random 32-byte string, so it is returned alongside the encoded value of <tt>t</tt>.
<tt>t</tt> is a vector of <tt>k</tt> polynomials with <tt>n</tt> coefficients.
We treat each polynomial in <tt>t</tt> as a vector of <tt>n</tt> coefficient, for which we apply <tt>VectorEncode</tt>.
From this, we obtain <tt>k</tt> values that are then concatenated.</t>
        <artwork><![CDATA[
Kemeleon.EncodeEk(ek = (t, rho)):
   for i in range(k):
      r_i = VectorEncode(t[i])
   r = concat(r_1,...,r_k)
   return concat(r,rho)
]]></artwork>
        <artwork><![CDATA[
Kemeleon.DecodeEk(eek):
   r_1,..,r_k,rho = eek # rho and each r_i is fixed length
   t = []
   for i in range(k):
      t_i = VectorDecode(r_i)
      t.append(t_i)
   return (t, rho)
]]></artwork>
      </section>
      <section anchor="ctxt-encoding">
        <name>Encoding Ciphertexts</name>
        <t>ML-KEM ciphertexts consist of two components: <tt>c_1</tt>, a vector of <tt>k</tt> polynomials with <tt>n</tt> coefficients mod <tt>2^du</tt>, and <tt>c_2</tt>, a polynomial with <tt>n</tt> coefficients mod <tt>2^dv</tt>.
The coefficients of these polynomials are not uniformly distributed, as a result of the compression step in encapsulation.
The following encoding function decompresses and recovers a random preimage of this compression step in order to recover the uniform distribution of coefficients.
Then, the same vector encoding step used for encapsulation keys can be applied.</t>
        <artwork><![CDATA[
Kemeleon.EncodeCtxt(c = (c_1,c_2)):
   u = Decompress_du(c_1)
   for i from 1 to k*n:
      u[i] = SamplePreimage(du,u[i],c_1[i])
   v = Decompress_dv(c_2)
   for i from 1 to n:
      v[i] = SamplePreimage(dv,v[i],c_2[i])
   for i in range(k)
      r_i = VectorEncode(u[i])
   r_(k+1) = VectorEncode(v)
   r = concat(r_0,...,r_(k+1))
   return r
]]></artwork>
        <artwork><![CDATA[
Kemeleon.DecodeCtxt(r):
   r_0,...,r_(k+1) = r # each r_i is fixed length
   for i in range(k):
      u[i] = VectorDecode(r_i)
   v = VectorDecode(r_(k+1))
   c_1 = Compress_du(u)
   c_2 = Compress_dv(v)
   return (c_1,c_2)
]]></artwork>
      </section>
      <section anchor="properties">
        <name>Summary of Properties</name>
        <table anchor="summary-encoding">
          <name>Summary of Kemeleon Properties</name>
          <thead>
            <tr>
              <th align="left">Algorithm / Parameter</th>
              <th align="right">Output size (bytes)</th>
              <th align="right">Success probability</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">Kemeleon - ML-KEM-512</td>
              <td align="right">ek: 800, ctxt: 1152</td>
              <td align="right">ek: 1.00, ctxt: 1.00</td>
            </tr>
            <tr>
              <td align="left">Kemeleon - ML-KEM-768</td>
              <td align="right">ek: 1184, ctxt: 1536</td>
              <td align="right">ek: 1.00, ctxt: 1.00</td>
            </tr>
            <tr>
              <td align="left">Kemeleon - ML-KEM-1024</td>
              <td align="right">ek: 1568, ctxt: 1920</td>
              <td align="right">ek: 1.00, ctxt: 1.00</td>
            </tr>
          </tbody>
        </table>
      </section>
    </section>
    <section anchor="considerations">
      <name>Additional Considerations for Applications</name>
      <t>This section contains additional considerations and comments related to using Kemeleon encodings in different applications.</t>
      <section anchor="rejection-sampling">
        <name>Smaller Outputs from Rejection Sampling</name>
        <t>In applications willing to incur some probability of failure in encoding, the following variant of the encoding algorithms that result in smaller output sizes for encapsulation keys and ciphertexts can be used.
The following algorithms make use of helper functions in <xref target="helper-rejection"/>.
The encoding algorithms for encapsulation keys should handle errors accordingly, returning an error if <tt>VectorEncodeR</tt> returns an error.</t>
        <artwork><![CDATA[
Kemeleon.EncodeEkR(ek = (t, rho)):
   r = VectorEncodeR(t)
   return concat(r,rho)
]]></artwork>
        <artwork><![CDATA[
Kemeleon.DecodeEkR(eek):
   r,rho = eek # rho and each r_i is fixed length
   t = VectorDecodeR(r)
   return (t, rho)
]]></artwork>
        <t>For ciphertexts, the second ciphertext component need not be decompressed, and rejection sampling can be used to retain uniformity instead.</t>
        <artwork><![CDATA[
Kemeleon.EncodeCtxtR(c = (c_1,c_2)):
   u = Decompress_du(c_1)
   for i from 1 to k*n:
      u[i] = SamplePreimage(du,u[i],c_1[i])
   r = VectorEncodeR(u)
   if r == err:
      return err
   for i from 1 to n:
      if c_2[i] == 0:
         return err with prob. 1/ceil(q/(2^dv))
   return concat(r,c_2)
]]></artwork>
        <artwork><![CDATA[
Kemeleon.DecodeCtxtR(ec):
   r,c_2 = ec              # c_2 is fixed length
   u = VectorDecodeR(r)
   c_1 = Compress_du(u)
   return (c_1,c_2)
]]></artwork>
        <t>This is a byte-aligned variant of the encoding as described in the original work <xref target="GSV24"/>, and has the following properties.</t>
        <table anchor="summary-alternate">
          <name>Summary of Alternate Encoding Properties</name>
          <thead>
            <tr>
              <th align="left">Algorithm / Parameter</th>
              <th align="right">Output size (bytes)</th>
              <th align="right">Success probability</th>
              <th align="right">Additional considerations</th>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td align="left">Kemeleon - ML-KEM-512</td>
              <td align="right">ek: 781, ctxt: 877</td>
              <td align="right">ek: 0.56, ctxt: 0.51</td>
              <td align="right">Large int (750B) arithmetic</td>
            </tr>
            <tr>
              <td align="left">Kemeleon - ML-KEM-768</td>
              <td align="right">ek: 1156, ctxt: 1252</td>
              <td align="right">ek: 0.83, ctxt: 0.77</td>
              <td align="right">Large int (1150B) arithmetic</td>
            </tr>
            <tr>
              <td align="left">Kemeleon - ML-KEM-1024</td>
              <td align="right">ek: 1530, ctxt: 1658</td>
              <td align="right">ek: 0.62, ctxt: 0.57</td>
              <td align="right">Large int (1500B) arithmetic</td>
            </tr>
          </tbody>
        </table>
        <section anchor="helper-rejection">
          <name>Helper Functions</name>
          <t>The following algorithms <tt>VectorEncodeR</tt> and <tt>VectorDecodeR</tt> are used for vector encoding.</t>
          <t>Encoding in this case accumulates all <tt>k</tt> polynomials into one large integer <tt>r</tt> and rejects if the most significant bit <tt>msb(r)</tt> is <tt>1</tt>.
The unused top bits of <tt>r</tt> (when represented in network byte order) are randomized to ensure a fully byte-aligned random output.
In this variant, it is no longer feasible to parallelize the encoding of the <tt>k</tt> polynomials; these must be treated as a single vector of <tt>k*n</tt> coefficients in order to achieve a reasonable rate of rejection.
Therefore, this approach also requires arithmetic over larger integers (up to <tt>ceil(log2(q^(4n))) = 11,982</tt> bit integers for ML-KEM-1024, where <tt>k = 4</tt>).</t>
          <artwork><![CDATA[
VectorEncodeR(a,k):
   r = 0
   for i from 1 to k*n:
      r += q^(i-1)*a[i]
   if msb(r) == 1:
      return err
   r = IntegerRandomizeUnused(r,k)
   return r
]]></artwork>
          <artwork><![CDATA[
VectorDecodeR(r,k):
   r = IntegerClearUnused(r,k)
   for i from 1 to k*n:
      a[i] = r % q
      r = r // q
   return a
]]></artwork>
          <t>The following helper functions randomize resp. clear the unused bits of the top byte of an integer <tt>r</tt> (represented in network byte order) produced in <tt>VectorEncodeR</tt>.</t>
          <artwork><![CDATA[
IntegerRandomizeUnused(r,k):
   b = floor(log2(q^(k*n)))    # bit size of r, without msb(r) = 0
         # b=5990 if k=2, b=8986 if k=3, b=11981 if k=4
   x = 8 - (b % 8)             # number of unused bits
   r_bytes = to_bytes(r)       # network byte order
   mask = 0xFF << (8 - x) & 0xFF
   rand = random_byte(1)       # sample 1 byte uniformly random
   r_bytes[0] = r_bytes[0] | (rand & mask)
   r = from_bytes(r_bytes)
   return r
]]></artwork>
          <artwork><![CDATA[
IntegerClearUnused(r,k):
   b = floor(log2(q^(k*n)))    # bit size of target integer, without msb(r) = 0
         # b=5990 if k=2, b=8986 if k=3, b=11981 if k=4
   x = 8 - (b % 8)             # number of randomized bits
   r_bytes = to_bytes(r)       # network byte order
   mask = 0xFF >> x
   r_bytes[0] = r_bytes[0] & mask
   r = from_bytes(r_bytes)
   return r
]]></artwork>
        </section>
        <section anchor="compressing-encapsulation-keys-without-rejection-sampling">
          <name>Compressing Encapsulation Keys without Rejection Sampling</name>
          <t>Applications merely interested in compressing encapsulation keys may use <tt>EncodeEkR</tt> and <tt>DecodeEkR</tt> without rejection and random padding in <tt>VectorEncodeR</tt>.
The resulting encoded encapsulation keys will NOT be uniformly random, but have smaller output size as in <xref target="summary-alternate"/>.</t>
        </section>
      </section>
      <section anchor="deterministic">
        <name>Deterministic Encoding</name>
        <t>The randomness used in <tt>Kemeleon</tt> ciphertext encodings <bcp14>MAY</bcp14> be derived in a deterministic manner.
To do so, following a call to <tt>Encap</tt> which returns a KEM key <tt>K</tt> and a ciphertext <tt>c</tt>, the following steps can be taken:</t>
        <ul spacing="normal">
          <li>
            <t>Using a key derivation function (KDF), derive from the key <tt>K</tt> a new key <tt>K'</tt> and a seed for randomness <tt>rnd</tt>.</t>
          </li>
          <li>
            <t>The seed <tt>rnd</tt> can be used to generate the randomness required when encoding the ciphertext <tt>c</tt>.</t>
          </li>
          <li>
            <t>Use <tt>K'</tt> in place of <tt>K</tt> wherever applicable in the remainder of the protocol/system.</t>
          </li>
          <li>
            <t>Upon any call to <tt>Decap</tt>, apply the same KDF to derive the new key <tt>K'</tt>, as required.</t>
          </li>
        </ul>
        <t>Deriving a new KEM key for use in the remainder of a system is crucial in order to ensure key separation (i.e., the implementation <bcp14>MUST NOT</bcp14> use the original key <tt>K</tt> to derive randomness and for other purposes).</t>
        <t>The randomness used to encode an encapsulation key <bcp14>MAY</bcp14> be stored alongside the corresponding decapsulation key, if it is subsequently needed.
See <xref target="randomness-security"/> for relevant discussion on keeping this randomness secret.</t>
      </section>
      <section anchor="hash-to-curve">
        <name>Relation to Hash-to-Curve</name>
        <t>While the functionality of Kemeleon is similar to hash-to-curve <xref target="RFC9380"/> (mapping arbitrary byte strings to encapsulation keys/ciphertexts), the applications where hash-to-curve is used do not immediately follow in the KEM-based setting because having such an encapsulation key (without <tt>dk</tt>) or ciphertext (without <tt>dk</tt> or <tt>ek</tt>) does not appear to provide the same functionality, since it is not clear how to continue working with the element in the same way that can be done with an elliptic curve point.</t>
      </section>
      <section anchor="direct-generation">
        <name>Modifying ML-KEM Algorithms</name>
        <t>In applications that <em>only</em> require Kemeleon-encoded values <em>and</em> where the underlying ML-KEM implementation can be modified, the ciphertext encoding algorithm (and ML-KEM encapsulation/decapsulation algorithms) <bcp14>MAY</bcp14> be adapted as follows for improved efficiency.
In particular, the compression step in the ML-KEM encapsulation algorithm can be omitted, and therefore, the decompression step in the Kemeleon algorithm can be omitted.
In the implementation of ML-KEM, the compression step (lines 22-23 of Algorithm 14 <xref target="FIPS203"/>) and corresponding decompression step (lines 3-4 of Algorithm 15 <xref target="FIPS203"/>) can be omitted from the encapsulation/decapsulation algorithms in ML-KEM.
In this case, the Kemeleon encoding algorithm for ciphertexts would omit the <tt>Decompress</tt> and <tt>SamplePreimage</tt> steps and immediately apply <tt>VectorEncode</tt>:</t>
        <artwork><![CDATA[
Kemeleon.EncodeCtxt(c = (c_1,c_2)):
   w = [c_1,c_2] # treat c_1,c_2 as a singular vector of (k+1)*n coefficients
   r = VectorEncode(w,k+1)
   return r
]]></artwork>
        <t>Decoding is adapted analogously.</t>
        <artwork><![CDATA[
Kemeleon.DecodeCtxt(ec):
   w = VectorDecode(r,k+1)
   c_1,c_2 = w # c_1, c_2 are fixed length
   return (c_1,c_2)
]]></artwork>
      </section>
    </section>
    <section anchor="security">
      <name>Security Considerations</name>
      <t>This section contains additional security considerations about the Kemeleon encodings described in this document.</t>
      <section anchor="assumptions">
        <name>Computational Assumptions</name>
        <t>In general, the obfuscation properties of the Kemeleon encodings depend on module LWE assumptions similar to those underlying the IND-CCA security of ML-KEM; see <xref target="GSV24"/> for the detailed security analysis of the original Kemeleon encoding.
In particular, the notions of public/encapsulation key and ciphertext uniformity capture the indistinguishability of Kemeleon-encoded encapsulation keys and ciphertexts from random bitstrings, respectively.
Both require the module LWE assumption to hold in order for Kemeleon to maintain its uniformity properties.
Furthermore, distinguishing a pair of a Kemeleon-encoded encapsulation key and a Kemeleon-encoded ciphertext from uniformly random bitstrings also reduces to a module LWE assumption.</t>
      </section>
      <section anchor="randomness-security">
        <name>Randomness Sampling</name>
        <t>Both encapsulation key and ciphertext encodings in the Kemeleon encoding are randomized.
The randomness (or seed used to generate randomness) used in Kemeleon encodings <bcp14>MUST</bcp14> be kept secret.
In particular, public randomness enables distinguishing a Kemeleon-encoded value from a random bytestring:
Decoding the value in question and re-encoding it with the public randomness will yield the original value if it was Kemeleon-encoded.</t>
      </section>
      <section anchor="timing-security">
        <name>Timing Side-Channels</name>
        <t>Beyond timing side-channel considerations for ML-KEM itself, care should be taken when using Kemeleon encodings.
Algorithms required to perform large integer arithmetic may leak information via timing.
Additionally, rejecting and re-generating encapsulation keys or ciphertexts may leak information about the use of Kemeleon encodings, as might the overhead of the encoding itself.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document has no IANA actions.</t>
    </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="RFC9380">
          <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>
        <reference anchor="ELL2" target="https://eprint.iacr.org/2014/043">
          <front>
            <title>Elligator Squared: Uniform Points on Elliptic Curves of Prime Order as Uniform Random Strings</title>
            <author initials="M." surname="Tibouchi" fullname="Mehdi Tibouchi">
              <organization/>
            </author>
            <date year="2014"/>
          </front>
        </reference>
        <reference anchor="GSV24" target="https://eprint.iacr.org/2024/1086">
          <front>
            <title>Obfuscated Key Exchange</title>
            <author initials="F." surname="Günther" fullname="Felix Günther">
              <organization/>
            </author>
            <author initials="D." surname="Stebila" fullname="Douglas Stebila">
              <organization/>
            </author>
            <author initials="S." surname="Veitch" fullname="Shannon Veitch">
              <organization/>
            </author>
            <date year="2024"/>
          </front>
        </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>
      </references>
      <references anchor="sec-informative-references">
        <name>Informative References</name>
        <reference anchor="OBFS4" target="https://gitlab.torproject.org/tpo/anti-censorship/pluggable-transports/lyrebird/-/blob/HEAD/doc/obfs4-spec.txt">
          <front>
            <title>obfs4 (The obfourscator)</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="CPACE">
          <front>
            <title>CPace, a balanced composable PAKE</title>
            <author fullname="Michel Abdalla" initials="M." surname="Abdalla">
              <organization>Alloc Init Labs - New York</organization>
            </author>
            <author fullname="Björn Haase" initials="B." surname="Haase">
              <organization>Endress + Hauser Liquid Analysis - Gerlingen</organization>
            </author>
            <author fullname="Julia Hesse" initials="J." surname="Hesse">
              <organization>IBM Research Europe - Zurich</organization>
            </author>
            <date day="22" month="April" year="2026"/>
            <abstract>
              <t>   This document describes CPace which is a protocol that allows two
   parties that share a low-entropy secret (password) to derive a strong
   shared key without disclosing the secret to offline dictionary
   attacks.  The CPace protocol was tailored for constrained devices and
   can be used on groups of prime- and non-prime order.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-cpace-21"/>
        </reference>
        <reference anchor="OPAQUE">
          <front>
            <title>The OPAQUE Augmented PAKE Protocol</title>
            <author fullname="Daniel Bourdrez" initials="D." surname="Bourdrez">
         </author>
            <author fullname="Hugo Krawczyk" initials="H." surname="Krawczyk">
              <organization>AWS</organization>
            </author>
            <author fullname="Kevin Lewi" initials="K." surname="Lewi">
              <organization>Meta</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="21" month="November" year="2024"/>
            <abstract>
              <t>   This document describes the OPAQUE protocol, an augmented (or
   asymmetric) password-authenticated key exchange (aPAKE) that supports
   mutual authentication in a client-server setting without reliance on
   PKI and with security against pre-computation attacks upon server
   compromise.  In addition, the protocol provides forward secrecy and
   the ability to hide the password from the server, even during
   password registration.  This document specifies the core OPAQUE
   protocol and one instantiation based on 3DH.  This document is a
   product of the Crypto Forum Research Group (CFRG) in the IRTF.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-opaque-18"/>
        </reference>
        <reference anchor="ECDH-PSI">
          <front>
            <title>PSI based on ECDH</title>
            <author fullname="Yuchen Wang" initials="Y." surname="Wang">
              <organization>Ant Group</organization>
            </author>
            <author fullname="ChangWenting" initials="" surname="ChangWenting">
              <organization>Ant Group</organization>
            </author>
            <author fullname="Yufei Lu" initials="Y." surname="Lu">
              <organization>Ant Group</organization>
            </author>
            <author fullname="Cheng Hong" initials="C." surname="Hong">
              <organization>Ant Group</organization>
            </author>
            <author fullname="Jin Peng" initials="J." surname="Peng">
              <organization>Ant Group</organization>
            </author>
            <date day="21" month="October" year="2024"/>
            <abstract>
              <t>   This document describes Elliptic Curve Diffie-Hellman Private Set
   Intersection (ECDH-PSI).  It instantiates the classical Meadows
   match-making protocol with standard elliptic curves and hash-to-curve
   methods.  In ECDH-PSI, data items are encoded to points on an
   elliptic curve, and masked by the private keys of both parties.
   After collecting the mutually masked datasets from both parties, a
   participant computes their intersection and outputs the corresponding
   original data items as result.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-ecdh-psi-00"/>
        </reference>
      </references>
    </references>
    <?line 485?>

<?line 487?>

<section numbered="false" anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>Thanks to
<contact fullname="Michael Rosenberg"/>,
<contact fullname="John Mattsson"/>, and
<contact fullname="Stanislaw Jarecki"/>
for contributions to this document and helpful discussions.</t>
    </section>
  </back>
  <!-- ##markdown-source:
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
uNrvYtC5uQziWR4YMTQW87/J5UZt9VAAAA==

-->

</rfc>
