<?xml version="1.0" encoding="UTF-8"?>
  <?xml-stylesheet type="text/xsl" href="rfc2629.xslt" ?>
  <!-- generated by https://github.com/cabo/kramdown-rfc2629 version 1.2.9 -->

<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
]>

<?rfc toc="yes"?>
<?rfc sortrefs="yes"?>
<?rfc symrefs="yes"?>

<rfc ipr="trust200902" docName="draft-barnes-cfrg-hpke-01" category="info">

  <front>
    <title abbrev="HPKE">Hybrid Public Key Encryption</title>

    <author initials="R.L." surname="Barnes" fullname="Richard L. Barnes">
      <organization>Cisco</organization>
      <address>
        <email>rlb@ipv.sx</email>
      </address>
    </author>
    <author initials="K." surname="Bhargavan" fullname="Karthik Bhargavan">
      <organization>Inria</organization>
      <address>
        <email>karthikeyan.bhargavan@inria.fr</email>
      </address>
    </author>

    <date year="2019" month="March" day="11"/>

    
    
    <keyword>Internet-Draft</keyword>

    <abstract>


<t>This document describes a scheme for hybrid public-key encryption (HPKE).  This scheme provides authenticated public key
encryption of arbitrary-sized plaintexts for a recipient public key. HPKE works
for any Diffie-Hellman group and has a strong security proof. We provide instantiations
of the scheme using standard and efficient primitives.</t>



    </abstract>


  </front>

  <middle>


<section anchor="introduction" title="Introduction">

<t>Hybrid public-key encryption (HPKE) is a substantially more
efficient solution than traditional public key encryption techniques
such as those based on RSA or ElGamal.  Encrypted messages convey a
single ciphertext and authentication tag alongside a short public
key, which may be further compressed. The key size and computational
complexity of elliptic curve cryptographic primitives for
authenticated encryption therefore make it compelling for a variety
of use case. This type of public key encryption has many
applications in practice, for example, in PGP <xref target="RFC6637"/> and in
the developing Messaging Layer Security protocol
<xref target="I-D.ietf-mls-protocol"/>.</t>

<t>Currently, there are numerous competing and non-interoperable
standards and variants for hybrid encryption, including ANSI X9.63
<xref target="ANSI"/>, IEEE 1363a <xref target="IEEE"/>, ISO/IEC 18033-2 <xref target="ISO"/>, and SECG SEC
1 <xref target="SECG"/>. Lack of a single standard makes selection and deployment
of a compatible, cross-platform and ecosystem solution difficult to
define.  This document defines an HPKE scheme that provides a subset
of the functions provided by the collection of schemes above, but
specified with sufficient clarity that they can be interoperably
implemented and formally verified.</t>

</section>
<section anchor="requirements-notation" title="Requirements Notation">

<t>The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”,
“SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “NOT RECOMMENDED”, “MAY”, and
“OPTIONAL” in this document are to be interpreted as described in
BCP14 <xref target="RFC2119"/> <xref target="RFC8174"/>  when, and only when, they appear in
all capitals, as shown here.</t>

</section>
<section anchor="security-properties" title="Security Properties">

<t>As a hybrid authentication encryption algorithm, we desire security
against (adaptive) chosen ciphertext attacks (IND-CCA2 secure). The
HPKE variants described in this document achieve this property under
the Random Oracle model assuming the gap Computational Diffie
Hellman (CDH) problem is hard <xref target="S01"/>.</t>

</section>
<section anchor="notation" title="Notation">

<t>The following terms are used throughout this document to describe the
operations, roles, and behaviors of HPKE:</t>

<t><list style="symbols">
  <t>Initiator (I): Sender of an encrypted message.</t>
  <t>Responder (R): Receiver of an encrypted message.</t>
  <t>Ephemeral (E): A fresh random value meant for one-time use.</t>
  <t><spanx style="verb">(skX, pkX)</spanx>: A KEM key pair used in role X; <spanx style="verb">skX</spanx> is the private
key and <spanx style="verb">pkX</spanx> is the public key</t>
  <t><spanx style="verb">pk(sk)</spanx>: The public key corresponding to a private key</t>
  <t><spanx style="verb">len(x)</spanx>: The one-octet length of the octet string <spanx style="verb">x</spanx></t>
  <t><spanx style="verb">+</spanx>: Concatenation of octet strings; <spanx style="verb">0x01 + 0x02 = 0x0102</spanx></t>
  <t><spanx style="verb">*</spanx>: Repetition of an octet string; <spanx style="verb">0x01 * 4 = 0x01010101</spanx></t>
  <t><spanx style="verb">^</spanx>: XOR of octet strings; <spanx style="verb">0xF0F0 ^ 0x1234 = 0xE2C4</spanx></t>
</list></t>

</section>
<section anchor="cryptographic-dependencies" title="Cryptographic Dependencies">

<t>HPKE variants rely on the following primitives:</t>

<t><list style="symbols">
  <t>A Key Encapsulation Mechanism (KEM):
  <list style="symbols">
      <t>GenerateKeyPair(): Generate a key pair (sk, pk)</t>
      <t>Marshal(pk): Produce a fixed-length octet string encoding the
public key <spanx style="verb">pk</spanx></t>
      <t>Unmarshal(enc): Parse a fixed-length octet string to recover a
public key</t>
      <t>Encap(pk): Generate an ephemeral symmetric key and a
fixed-length encapsulation of that key that can be decapsulated
by the holder of the private key corresponding to pk</t>
      <t>Decap(enc, sk): Use the private key <spanx style="verb">sk</spanx> to recover the ephemeral
symmetric key from its encapsulated representation <spanx style="verb">enc</spanx></t>
      <t>AuthEncap(pkR, skI) (optional): Same as Encap(), but the outputs
encode an assurance that the ephemeral shared key is known only
to the holder of the private key <spanx style="verb">skI</spanx></t>
      <t>AuthDecap(skI, pkR) (optional): Same as Decap(), but the holder
of the private key <spanx style="verb">skI</spanx> is assured that the ephemeral shared
key is known only to the holder of the private key corresponding
to <spanx style="verb">pkI</spanx></t>
    </list></t>
  <t>A Key Derivation Function:
  <list style="symbols">
      <t>Extract(salt, IKM): Extract a pseudorandom key of fixed length
from input keying material <spanx style="verb">IKM</spanx> and an optional octet string
<spanx style="verb">salt</spanx></t>
      <t>Expand(PRK, info, L): Expand a pseudorandom key <spanx style="verb">PRK</spanx> using
optional string <spanx style="verb">info</spanx> into <spanx style="verb">L</spanx> bytes of output keying material</t>
      <t>Nh: The output size of the Extract function</t>
    </list></t>
  <t>An AEAD encryption algorithm <xref target="RFC5116"/>:
  <list style="symbols">
      <t>Seal(key, nonce, aad, pt): Encrypt and authenticate plaintext
<spanx style="verb">pt</spanx> with associated data <spanx style="verb">aad</spanx> using secret key <spanx style="verb">key</spanx> and nonce
<spanx style="verb">nonce</spanx>, yielding ciphertext and tag <spanx style="verb">ct</spanx></t>
      <t>Open(key, nonce, aad, ct): Decrypt ciphertext <spanx style="verb">ct</spanx> using
associated data <spanx style="verb">aad</spanx> with secret key <spanx style="verb">key</spanx> and nonce <spanx style="verb">nonce</spanx>,
returning plaintext message <spanx style="verb">pt</spanx> or the error value <spanx style="verb">OpenError</spanx></t>
      <t>Nk: The length in octets of a key for this algorithm</t>
      <t>Nn: The length in octets of a nonce for this algorithm</t>
    </list></t>
</list></t>

<t>A set of concrete instantiations of these primitives is provided in
<xref target="ciphersuites"/>.  Ciphersuite values are two octets long.</t>

<section anchor="dh-based-kem" title="DH-Based KEM">

<t>Suppose we are given a Diffie-Hellman group that provides the
following operations:</t>

<t><list style="symbols">
  <t>GenerateKeyPair(): Generate an ephemeral key pair <spanx style="verb">(sk, pk)</spanx>
for the DH group in use</t>
  <t>DH(sk, pk): Perform a non-interactive DH exchange using the
private key sk and public key pk to produce a shared secret</t>
  <t>Marshal(pk): Produce a fixed-length octet string encoding the
public key <spanx style="verb">pk</spanx></t>
</list></t>

<t>Then we can construct a KEM (which we’ll call “DHKEM”) in the
following way:</t>

<figure><artwork><![CDATA[
def Encap(pkR):
  skE, pkE = GenerateKeyPair()
  zz = DH(skE, pkR)
  enc = Marshal(pkE)
  return zz, enc

def Decap(enc, skR):
  pkE = Unmarshal(enc)
  return DH(skR, pkE)

def AuthEncap(pkR, skI):
  skE, pkE = GenerateKeyPair()
  zz = DH(skE, pkR) + DH(skI, pkR)
  enc = Marshal(pkE)
  return zz, enc

def AuthDecap(enc, skR, pkI):
  pkE = Unmarshal(enc)
  return DH(skR, pkE) + DH(skR, pkI)
]]></artwork></figure>

<t>The Marshal and GenerateKeyPair functions are the same as for the
underlying DH group.</t>

</section>
</section>
<section anchor="hybrid-public-key-encryption" title="Hybrid Public Key Encryption">

<t>In this section, we define a few HPKE variants.  All cases take a
plaintext <spanx style="verb">pt</spanx> and a recipient public key <spanx style="verb">pkR</spanx> and produce an
ciphertext <spanx style="verb">ct</spanx> and an encapsulated key <spanx style="verb">enc</spanx>.  These outputs are
constructed so that only the holder of the private key corresponding
to <spanx style="verb">pkR</spanx> can decapsulate the key from <spanx style="verb">enc</spanx> and decrypt the
ciphertext.  All of the algorithms also take an <spanx style="verb">info</spanx> parameter
that can be used to influence the generation of keys (e.g., to fold
in identity information) and an <spanx style="verb">aad</spanx> parameter that provides
Additional Authenticated Data to the AEAD algorithm in use.</t>

<t>In addition to the base case of encrypting to a public key, we
include two authenticated variants, one of which authenticates
possession of a pre-shared key, and one of which authenticates
possession of a KEM private key.  The following one-octet values
will be used to distinguish between modes:</t>

<texttable>
      <ttcol align='left'>Mode</ttcol>
      <ttcol align='left'>Value</ttcol>
      <c>mode_base</c>
      <c>0x00</c>
      <c>mode_psk</c>
      <c>0x01</c>
      <c>mode_auth</c>
      <c>0x02</c>
</texttable>

<t>All of these cases follow the same basic two-step pattern:</t>

<t><list style="numbers">
  <t>Set up an encryption context that is shared between the sender
and the recipient</t>
  <t>Use that context to encrypt or decrypt content</t>
</list></t>

<t>A “context” encodes the AEAD algorithm and key in use, and manages
the nonces used so that the same nonce is not used with multiple
plaintexts.</t>

<t>The procedures described in this session are laid out in a
Python-like pseudocode.  The ciphersuite in use is left implicit.</t>

<section anchor="encryption-to-a-public-key" title="Encryption to a Public Key">

<t>The most basic function of an HPKE scheme is to enable encryption
for the holder of a given KEM private key.  The <spanx style="verb">SetupBaseI()</spanx> and
<spanx style="verb">SetupBaseR()</spanx> procedures establish contexts that can be used to
encrypt and decrypt, respectively, for a given private key.</t>

<t>The the shared secret produced by the KEM is combined via the KDF
with information describing the key exchange, as well as the
explicit <spanx style="verb">info</spanx> parameter provided by the caller.</t>

<t>Note that the <spanx style="verb">SetupCore()</spanx> method is also used by the other HPKE
variants describe below.  The value <spanx style="verb">0*Nh</spanx> in the <spanx style="verb">SetupBase()</spanx>
procedure represents an all-zero octet string of length <spanx style="verb">Nh</spanx>.</t>

<figure><artwork><![CDATA[
def SetupCore(mode, secret, kemContext, info):
  context = ciphersuite + mode +
            len(kemContext) + kemContext +
            len(info) + info
  key = Expand(secret, "hpke key" + context, Nk)
  nonce = Expand(secret, "hpke nonce" + context, Nn)
  return Context(key, nonce)

def SetupBase(pkR, zz, enc, info):
  kemContext = enc + pkR
  secret = Extract(0\*Nh, zz)
  return SetupCore(mode_base, secret, kemContext, info)

def SetupBaseI(pkR, info):
  zz, enc = Encap(pkR)
  return SetupBase(pkR, zz, enc, info)

def SetupBaseR(enc, skR, info):
  zz = Decap(enc, skR)
  return SetupBase(pk(skR), zz, enc, info)
]]></artwork></figure>

<t>Note that the context construction in the SetupCore procedure is
equivalent to serializing a structure of the following form in the
TLS presentation syntax:</t>

<figure><artwork><![CDATA[
struct {
    uint16 ciphersuite;
    uint8 mode;
    opaque kemContext<0..255>;
    opaque info<0..255>;
} HPKEContext;
]]></artwork></figure>

</section>
<section anchor="authentication-using-a-pre-shared-key" title="Authentication using a Pre-Shared Key">

<t>This variant extends the base mechansism by allowing the recipient
to authenticate that the sender possessed a given pre-shared key
(PSK).  We assume that both parties have been provisioned with both
the PSK value <spanx style="verb">psk</spanx> and another octet string <spanx style="verb">pskID</spanx> that is used to
identify which PSK should be used.</t>

<t>The primary differences from the base case are:</t>

<t><list style="symbols">
  <t>The PSK is used as the <spanx style="verb">salt</spanx> input to the KDF (instead of 0)</t>
  <t>The PSK ID is added to the context string used as the <spanx style="verb">info</spanx> input
to the KDF</t>
</list></t>

<t>This mechanism is not suitable for use with a low-entropy password
as the PSK.  A malicious recipient that does not possess the PSK can
use decryption of a plaintext as an oracle for performing offline
dictionary attacks.</t>

<figure><artwork><![CDATA[
def SetupPSK(pkR, psk, pskID, zz, enc, info):
  kemContext = enc + pkR + pskID
  secret = Extract(psk, zz)
  return SetupCore(mode_psk, secret, kemContext, info)

def SetupPSKI(pkR, psk, pskID, info):
  zz, enc = Encap(pkR)
  return SetupPSK(pkR, psk, pskID, zz, enc, info)

def SetupPSKR(enc, skR, psk, pskID, info):
  zz = Decap(enc, skR)
  return SetupPSK(pk(skR), psk, pskID, zz, enc, info)
]]></artwork></figure>

</section>
<section anchor="authentication-using-an-asymmetric-key" title="Authentication using an Asymmetric Key">

<t>This variant extends the base mechansism by allowing the recipient
to authenticate that the sender possessed a given KEM private key.
This assurance is based on the assumption that
<spanx style="verb">AuthDecap(enc, skR, pkI)</spanx> produces the correct shared secret
only if the encapsulated value <spanx style="verb">enc</spanx> was produced by
<spanx style="verb">AuthEncap(pkR, skI)</spanx>, where <spanx style="verb">skI</spanx> is the private key corresponding
to <spanx style="verb">pkI</spanx>.  In other words, only two people could have produced this
secret, so if the recipient is one, then the sender must be the
other.</t>

<t>The primary differences from the base case are:</t>

<t><list style="symbols">
  <t>The calls to <spanx style="verb">Encap</spanx> and <spanx style="verb">Decap</spanx> are replaced with calls to
<spanx style="verb">AuthEncap</spanx> and <spanx style="verb">AuthDecap</spanx>.</t>
  <t>The initiator public key is added to the context string used as
the <spanx style="verb">info</spanx> input to the KDF</t>
</list></t>

<t>Obviously, this variant can only be used with a KEM that provides
<spanx style="verb">AuthEncap()</spanx> and <spanx style="verb">AuthDecap()</spanx> procuedures.</t>

<t>This mechanism authenticates only the key pair of the initiator, not
any other identity.  If an application wishes to authenticate some
other identity for the sender (e.g., an email address or domain
name), then this identity should be included in the <spanx style="verb">info</spanx> parameter
to avoid unknown key share attacks.</t>

<figure><artwork><![CDATA[
def SetupAuth(pkR, pkI, zz, enc, info):
  kemContext = enc + pkR + pkI
  secret = Extract(0*Nh, zz)
  return SetupCore(mode_auth, secret, kemContext, info)

def SetupAuthI(pkR, skI, info):
  zz, enc = AuthEncap(pkR, skI)
  return SetupAuth(pkR, pk(skI), zz, enc, info)

def SetupAuthR(enc, skR, pkI, info):
  zz = AuthDecap(enc, skR, pkI)
  return SetupAuth(pk(skR), pkI, zz, enc, info)
]]></artwork></figure>

</section>
<section anchor="encryption-and-decryption" title="Encryption and Decryption">

<t>HPKE allows multiple encryption operations to be done based on a
given setup transaction.  Since the public-key operations involved
in setup are typically more expensive than symmetric encryption or
decryption, this allows applications to “amortize” the cost of the
public-key operations, reducing the overall overhead.</t>

<t>In order to avoid nonce reuse, however, this decryption must be
stateful.  Each of the setup procedures above produces a context
object that stores the required state:</t>

<t><list style="symbols">
  <t>The AEAD algorithm in use</t>
  <t>The key to be used with the AEAD algorithm</t>
  <t>A base nonce value</t>
  <t>A sequence number (initially 0)</t>
</list></t>

<t>All of these fields except the sequence number are constant.  The
sequence number is used to provide nonce uniqueness: The nonce used
for each encryption or decryption operation is the result of XORing
the base nonce with the current sequence number, encoded as a
big-endian integer of the same length as the nonce.  Implementations
MAY use a sequence number that is shorter than the nonce (padding on
the left with zero), but MUST return an error if the sequence number
overflows.</t>

<t>Each encryption or decryption operation increments the sequence
number for the context in use.  A given context SHOULD be used either
only for encryption or only for decryption.</t>

<t>It is up to the application to ensure that encryptions and
decryptions are done in the proper sequence, so that the nonce
values used for encryption and decryption line up.</t>

<figure><artwork><![CDATA[
def Context.Nonce(seq):
  encSeq = encode\_big\_endian(seq, len(self.nonce))
  return self.nonce ^ encSeq

def Context.Seal(aad, pt):
  ct = Seal(self.key, self.Nonce(self.seq), aad, pt)
  self.seq += 1
  return ct

def Context.Open(aad, ct):
  pt = Open(self.key, self.Nonce(self.seq), aad, pt)
  if pt == OpenError:
    return OpenError
  self.seq += 1
  return pt
]]></artwork></figure>

</section>
</section>
<section anchor="ciphersuites" title="Ciphersuites">

<t>The HPKE variants as presented will function correctly for any
combination of primitives that provides the functions described
above. In this section, we provide specific instantiations of these
primitives for standard groups, including: Curve25519, Curve448
<xref target="RFC7748"/>, and the NIST curves P-256 and P-512.</t>

<texttable>
      <ttcol align='left'>Value</ttcol>
      <ttcol align='left'>KEM</ttcol>
      <ttcol align='left'>KDF</ttcol>
      <ttcol align='left'>AEAD</ttcol>
      <c>0x0001</c>
      <c>DHKEM(P-256)</c>
      <c>HKDF-SHA256</c>
      <c>AES-GCM-128</c>
      <c>0x0002</c>
      <c>DHKEM(P-256)</c>
      <c>HKDF-SHA256</c>
      <c>ChaCha20Poly1305</c>
      <c>0x0002</c>
      <c>DHKEM(Curve25519)</c>
      <c>HKDF-SHA256</c>
      <c>AES-GCM-128</c>
      <c>0x0002</c>
      <c>DHKEM(Curve25519)</c>
      <c>HKDF-SHA256</c>
      <c>ChaCha20Poly1305</c>
      <c>0x0001</c>
      <c>DHKEM(P-521)</c>
      <c>HKDF-SHA512</c>
      <c>AES-GCM-256</c>
      <c>0x0002</c>
      <c>DHKEM(P-521)</c>
      <c>HKDF-SHA512</c>
      <c>ChaCha20Poly1305</c>
      <c>0x0002</c>
      <c>DHKEM(Curve448)</c>
      <c>HKDF-SHA512</c>
      <c>AES-GCM-256</c>
      <c>0x0002</c>
      <c>DHKEM(Curve448)</c>
      <c>HKDF-SHA512</c>
      <c>ChaCha20Poly1305</c>
</texttable>

<t>For the NIST curves P-256 and P-521, the Marshal function of the DH
scheme produces the normal (non-compressed) representation of the
public key, according to <xref target="SECG"/>.  When these curves are used, the
recipient of an HPKE ciphertext MUST validate that the ephemeral public
key <spanx style="verb">pkE</spanx> is on the curve.  The relevant validation procedures are
defined in <xref target="keyagreement"/></t>

<t>For the CFRG curves Curve25519 and Curve448, the Marshal function is
the identity function, since these curves already use fixed-length
octet strings for public keys.</t>

<t>The values <spanx style="verb">Nk</spanx> and <spanx style="verb">Nn</spanx> for the AEAD algorithms referenced above
are as follows:</t>

<texttable>
      <ttcol align='left'>AEAD</ttcol>
      <ttcol align='left'>Nk</ttcol>
      <ttcol align='left'>Nn</ttcol>
      <c>AES-GCM-128</c>
      <c>16</c>
      <c>12</c>
      <c>AES-GCM-256</c>
      <c>32</c>
      <c>12</c>
      <c>ChaCha20Poly1305</c>
      <c>32</c>
      <c>12</c>
</texttable>

</section>
<section anchor="security-considerations" title="Security Considerations">

<t>[[ TODO ]]</t>

</section>
<section anchor="iana-considerations" title="IANA Considerations">

<t>[[ OPEN ISSUE: Should the above table be in an IANA registry? ]]</t>

</section>


  </middle>

  <back>

    <references title='Normative References'>

<reference anchor="S01" target="http://www.shoup.net/papers/iso-2_1.pdf">
  <front>
    <title>A Proposal for an ISO Standard for Public Key Encryption (verison 2.1)</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="ANSI" >
  <front>
    <title>Public Key Cryptography for the Financial Services Industry -- Key Agreement and Key Transport Using Elliptic Curve Cryptography</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="IEEE" >
  <front>
    <title>IEEE 1363a, Standard Specifications for Public Key Cryptography - Amendment 1 -- Additional Techniques</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="ISO" >
  <front>
    <title>ISO/IEC 18033-2, Information Technology - Security Techniques - Encryption Algorithms - Part 2 -- Asymmetric Ciphers</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="SECG" target="http://www.secg.org/download/aid-780/sec1-v2.pdf">
  <front>
    <title>Elliptic Curve Cryptography, Standards for Efficient Cryptography Group, ver. 2</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>
<reference anchor="MAEA10" target="http://sceweb.sce.uhcl.edu/yang/teaching/csci5234WebSecurityFall2011/Chaum-blind-signatures.PDF">
  <front>
    <title>A Comparison of the Standardized Versions of ECIES</title>
    <author >
      <organization></organization>
    </author>
    <date year="n.d."/>
  </front>
</reference>


<reference anchor="keyagreement" >
  <front>
    <title>Recommendation for Pair-Wise Key Establishment Schemes Using Discrete Logarithm Cryptography</title>
    <author initials="E." surname="Barker" fullname="Elaine Barker">
      <organization></organization>
    </author>
    <author initials="L." surname="Chen" fullname="Lily Chen">
      <organization></organization>
    </author>
    <author initials="A." surname="Roginsky" fullname="Allen Roginsky">
      <organization></organization>
    </author>
    <author initials="M." surname="Smid" fullname="Miles Smid">
      <organization></organization>
    </author>
    <date year="2013" month="May"/>
  </front>
  <seriesInfo name="National Institute of Standards and Technology" value="report"/>
  <seriesInfo name="DOI" value="10.6028/nist.sp.800-56ar2"/>
</reference>



<reference  anchor="RFC2119" target='https://www.rfc-editor.org/info/rfc2119'>
<front>
<title>Key words for use in RFCs to Indicate Requirement Levels</title>
<author initials='S.' surname='Bradner' fullname='S. Bradner'><organization /></author>
<date year='1997' month='March' />
<abstract><t>In many standards track documents several words are used to signify the requirements in the specification.  These words are often capitalized. This document defines these words as they should be interpreted in IETF documents.  This document specifies an Internet Best Current Practices for the Internet Community, and requests discussion and suggestions for improvements.</t></abstract>
</front>
<seriesInfo name='BCP' value='14'/>
<seriesInfo name='RFC' value='2119'/>
<seriesInfo name='DOI' value='10.17487/RFC2119'/>
</reference>



<reference  anchor="RFC8174" target='https://www.rfc-editor.org/info/rfc8174'>
<front>
<title>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</title>
<author initials='B.' surname='Leiba' fullname='B. Leiba'><organization /></author>
<date year='2017' month='May' />
<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="RFC5116" target='https://www.rfc-editor.org/info/rfc5116'>
<front>
<title>An Interface and Algorithms for Authenticated Encryption</title>
<author initials='D.' surname='McGrew' fullname='D. McGrew'><organization /></author>
<date year='2008' month='January' />
<abstract><t>This document defines algorithms for Authenticated Encryption with Associated Data (AEAD), and defines a uniform interface and a registry for such algorithms.  The interface and registry can be used as an application-independent set of cryptoalgorithm suites.  This approach provides advantages in efficiency and security, and promotes the reuse of crypto implementations.  [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='5116'/>
<seriesInfo name='DOI' value='10.17487/RFC5116'/>
</reference>



<reference  anchor="RFC7748" target='https://www.rfc-editor.org/info/rfc7748'>
<front>
<title>Elliptic Curves for Security</title>
<author initials='A.' surname='Langley' fullname='A. Langley'><organization /></author>
<author initials='M.' surname='Hamburg' fullname='M. Hamburg'><organization /></author>
<author initials='S.' surname='Turner' fullname='S. Turner'><organization /></author>
<date year='2016' month='January' />
<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>




    </references>

    <references title='Informative References'>





<reference  anchor="RFC6637" target='https://www.rfc-editor.org/info/rfc6637'>
<front>
<title>Elliptic Curve Cryptography (ECC) in OpenPGP</title>
<author initials='A.' surname='Jivsov' fullname='A. Jivsov'><organization /></author>
<date year='2012' month='June' />
<abstract><t>This document defines an Elliptic Curve Cryptography extension to the OpenPGP public key format and specifies three Elliptic Curves that enjoy broad support by other standards, including standards published by the US National Institute of Standards and Technology.  The document specifies the conventions for interoperability between compliant OpenPGP implementations that make use of this extension and these Elliptic Curves.   [STANDARDS-TRACK]</t></abstract>
</front>
<seriesInfo name='RFC' value='6637'/>
<seriesInfo name='DOI' value='10.17487/RFC6637'/>
</reference>



<reference anchor="I-D.ietf-mls-protocol">
<front>
<title>The Messaging Layer Security (MLS) Protocol</title>

<author initials='R' surname='Barnes' fullname='Richard Barnes'>
    <organization />
</author>

<author initials='J' surname='Millican' fullname='Jon Millican'>
    <organization />
</author>

<author initials='E' surname='Omara' fullname='Emad Omara'>
    <organization />
</author>

<author initials='K' surname='Cohn-Gordon' fullname='Katriel Cohn-Gordon'>
    <organization />
</author>

<author initials='R' surname='Robert' fullname='Raphael Robert'>
    <organization />
</author>

<date month='January' day='11' year='2019' />

<abstract><t>Messaging applications are increasingly making use of end-to-end security mechanisms to ensure that messages are only accessible to the communicating endpoints, and not to any servers involved in delivering messages.  Establishing keys to provide such protections is challenging for group chat settings, in which more than two participants need to agree on a key but may not be online at the same time.  In this document, we specify a key establishment protocol that provides efficient asynchronous group key establishment with forward secrecy and post-compromise security for groups in size ranging from two to thousands.</t></abstract>

</front>

<seriesInfo name='Internet-Draft' value='draft-ietf-mls-protocol-03' />
<format type='TXT'
        target='http://www.ietf.org/internet-drafts/draft-ietf-mls-protocol-03.txt' />
</reference>




    </references>


<section anchor="possible-todos" title="Possible TODOs">

<t>The following extensions might be worth specifying:</t>

<t><list style="symbols">
  <t>Multiple recipients - It might be possible to add some
simplifications / assurances for the case where the same value is
being encrypted to multiple recipients.</t>
  <t>Test vectors - Obviously, we can provide decryption test vectors
in this document.  In order to provide known-answer tests, we
would have to introduce a non-secure deterministic mode where the
ephemeral key pair is derived from the inputs.  And to do that
safely, we would need to augment the decrypt function to detect
the deterministic mode and fail.</t>
  <t>A reference implementation in hacspec or similar</t>
</list></t>

</section>


  </back>

<!-- ##markdown-source:
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
qzAiK6LsAVaQpGEZ/Df4LDrUbEgAAA==

-->

</rfc>

