<?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.6.13 (Ruby 3.1.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-opaque-09" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.13.0 -->
  <front>
    <title abbrev="OPAQUE">The OPAQUE Asymmetric PAKE Protocol</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-opaque-09"/>
    <author initials="D." surname="Bourdrez" fullname="Daniel Bourdrez">
      <organization/>
      <address>
        <email>d@bytema.re</email>
      </address>
    </author>
    <author initials="H." surname="Krawczyk" fullname="Hugo Krawczyk">
      <organization>Algorand Foundation</organization>
      <address>
        <email>hugokraw@gmail.com</email>
      </address>
    </author>
    <author initials="K." surname="Lewi" fullname="Kevin Lewi">
      <organization>Novi Research</organization>
      <address>
        <email>lewi.kevin.k@gmail.com</email>
      </address>
    </author>
    <author initials="C. A." surname="Wood" fullname="Christopher A. Wood">
      <organization>Cloudflare, Inc.</organization>
      <address>
        <email>caw@heapingbits.net</email>
      </address>
    </author>
    <date year="2022" month="July" day="06"/>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <t>This document describes the OPAQUE protocol, a secure 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.</t>
    </abstract>
    <note removeInRFC="true">
      <name>Discussion Venues</name>
      <t>Source for this draft and an issue tracker can be found at
  <eref target="https://github.com/cfrg/draft-irtf-cfrg-opaque"/>.</t>
    </note>
  </front>
  <middle>
    <section anchor="intro">
      <name>Introduction</name>
      <t>Password authentication is ubiquitous in many applications. In a common
implementation, a client authenticates to a server by sending its client
ID and password to the server over a secure connection. This makes
the password vulnerable to server mishandling, including accidentally
logging the password or storing it in plaintext in a database. Server
compromise resulting in access to these plaintext passwords is not an
uncommon security incident, even among security-conscious organizations.
Moreover, plaintext password authentication over secure channels such as
TLS is also vulnerable to cases where TLS may fail, including PKI
attacks, certificate mishandling, termination outside the security
perimeter, visibility to TLS-terminating intermediaries, and more.</t>
      <t>Asymmetric (or Augmented) Password Authenticated Key Exchange (aPAKE)
protocols are designed to provide password authentication and
mutually authenticated key exchange in a client-server setting without
relying on PKI (except during client registration) and without
disclosing passwords to servers or other entities other than the client
machine. A secure aPAKE should provide the best possible security for a
password protocol. Indeed, some attacks are inevitable, such as
online impersonation attempts with guessed client passwords and offline
dictionary attacks upon the compromise of a server and leakage of its
credential file. In the latter case, the attacker learns a mapping of
a client's password under a one-way function and uses such a mapping to
validate potential guesses for the password. Crucially important is
for the password protocol to use an unpredictable one-way mapping.
Otherwise, the attacker can pre-compute a deterministic list of mapped
passwords leading to almost instantaneous leakage of passwords upon
server compromise.</t>
      <t>This document describes OPAQUE, a PKI-free secure aPAKE that is secure
against pre-computation attacks. OPAQUE provides forward secrecy with
respect to password leakage while also hiding the password from the
server, even during password registration. OPAQUE allows applications
to increase the difficulty of offline dictionary attacks via iterated
hashing or other key stretching schemes. OPAQUE is also extensible, allowing
clients to safely store and retrieve arbitrary application data on servers
using only their password.</t>
      <t>OPAQUE is defined and proven as the composition of three functionalities:
an oblivious pseudorandom function (OPRF), a key recovery mechanism,
and an authenticated key exchange (AKE) protocol. It can be seen
as a "compiler" for transforming any suitable AKE protocol into a secure
aPAKE protocol. (See <xref target="security-considerations"/> for requirements of the
OPRF and AKE protocols.) This document specifies one OPAQUE instantiation
based on <xref target="_3DH"/>. Other instantiations are possible, as discussed in
<xref target="alternate-akes"/>, but their details are out of scope for this document.
In general, the modularity of OPAQUE's design makes it easy to integrate
with additional AKE protocols, e.g., TLS or HMQV, and with future ones such
as those based on post-quantum techniques.</t>
      <t>OPAQUE consists of two stages: registration and authenticated key exchange.
In the first stage, a client registers its password with the server and stores
information used to recover authentication credentials on the server. Recovering these
credentials can only be done with knowledge of the client password. In the second
stage, a client uses its password to recover those credentials and subsequently
uses them as input to an AKE protocol. This stage has additional mechanisms to
prevent an active attacker from interacting with the server to guess or confirm
clients registered via the first phase. Servers can use this mechanism to safeguard
registered clients against this type of enumeration attack; see
<xref target="preventing-client-enumeration"/> for more discussion.</t>
      <t>The name OPAQUE is a homonym of O-PAKE where O is for Oblivious. The name
OPAKE was taken.</t>
      <t>This draft complies with the requirements for PAKE protocols set forth in
<xref target="RFC8125"/>.</t>
      <section anchor="requirements-notation">
        <name>Requirements Notation</name>
        <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 BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only when, they
appear in all capitals, as shown here.</t>
      </section>
      <section anchor="notation">
        <name>Notation</name>
        <t>The following functions are used throughout this document:</t>
        <ul spacing="normal">
          <li>I2OSP and OS2IP: Convert a byte string to and from a non-negative integer as
described in Section 4 of <xref target="RFC8017"/>. Note that these functions operate on
byte strings in big-endian byte order.</li>
          <li>concat(x0, ..., xN): Concatenate byte strings. For example,
<tt>concat(0x01, 0x0203, 0x040506) = 0x010203040506</tt>.</li>
          <li>random(n): Generate a cryptographically secure pseudorandom byte string of length <tt>n</tt> bytes.</li>
          <li>xor(a,b): Apply XOR to byte strings. For example, <tt>xor(0xF0F0, 0x1234) = 0xE2C4</tt>.
It is an error to call this function with arguments of unequal length.</li>
          <li>ct_equal(a, b): Return <tt>true</tt> if <tt>a</tt> is equal to <tt>b</tt>, and false otherwise.
The implementation of this function must be constant-time in the length of <tt>a</tt>
and <tt>b</tt>, which are assumed to be of equal length, irrespective of the values <tt>a</tt>
or <tt>b</tt>.</li>
        </ul>
        <t>Except if said otherwise, random choices in this specification refer to
drawing with uniform distribution from a given set (i.e., "random" is short
for "uniformly random"). Random choices can be replaced with fresh outputs from
a cryptographically strong pseudorandom generator, according to the requirements
in <xref target="RFC4086"/>, or pseudorandom function. For convenience, we define <tt>nil</tt> as a
lack of value.</t>
        <t>All protocol messages and structures defined in this document use the syntax from
<xref section="3" sectionFormat="comma" target="RFC8446"/>.</t>
      </section>
    </section>
    <section anchor="dependencies">
      <name>Cryptographic Dependencies</name>
      <t>OPAQUE depends on the following cryptographic protocols and primitives:</t>
      <ul spacing="normal">
        <li>Oblivious Pseudorandom Function (OPRF); <xref target="deps-oprf"/></li>
        <li>Key Derivation Function (KDF); <xref target="deps-symmetric"/></li>
        <li>Message Authentication Code (MAC); <xref target="deps-symmetric"/></li>
        <li>Cryptographic Hash Function; <xref target="deps-hash"/></li>
        <li>Key Stretching Function (KSF); <xref target="deps-hash"/></li>
      </ul>
      <t>This section describes these protocols and primitives in more detail. Unless said
otherwise, all random nonces and seeds used in these dependencies and the rest of
the OPAQUE protocol are of length <tt>Nn</tt> and <tt>Nseed</tt> bytes, respectively, where
<tt>Nn</tt> = <tt>Nseed</tt> = 32.</t>
      <section anchor="deps-oprf">
        <name>Oblivious Pseudorandom Function</name>
        <t>An Oblivious Pseudorandom Function (OPRF) is a two-party protocol between client and
server for computing a PRF such that the client learns the PRF output and neither party learns
the input of the other. This specification depends on the prime-order OPRF construction specified
in <xref target="OPRF"/>, draft version -10, using the OPRF mode (0x00) from <xref section="3.1" sectionFormat="comma" target="OPRF"/>.</t>
        <t>The following OPRF client APIs are used:</t>
        <ul spacing="normal">
          <li>Blind(element): Create and output (<tt>blind</tt>, <tt>blinded_element</tt>), consisting of a blinded
representation of input <tt>element</tt>, denoted <tt>blinded_element</tt>, along with a value to revert
the blinding process, denoted <tt>blind</tt>.</li>
          <li>Finalize(element, blind, evaluated_element): Finalize the OPRF evaluation using input <tt>element</tt>,
random inverter <tt>blind</tt>, and evaluation output <tt>evaluated_element</tt>, yielding output <tt>oprf_output</tt>.</li>
        </ul>
        <t>Moreover, the following OPRF server APIs are used:</t>
        <ul spacing="normal">
          <li>Evaluate(k, blinded_element): Evaluate blinded input element <tt>blinded_element</tt> using
input key <tt>k</tt>, yielding output element <tt>evaluated_element</tt>. This is equivalent to
the Evaluate function described in <xref section="3.3.1" sectionFormat="comma" target="OPRF"/>, where <tt>k</tt> is the private key parameter.</li>
          <li>DeriveKeyPair(seed, info): Derive a private and public key pair deterministically
from a seed and info parameter, as described in <xref section="3.2" sectionFormat="comma" target="OPRF"/>.</li>
        </ul>
        <t>Finally, this specification makes use of the following shared APIs and parameters:</t>
        <ul spacing="normal">
          <li>SerializeElement(element): Map input <tt>element</tt> to a fixed-length byte array <tt>buf</tt>.</li>
          <li>DeserializeElement(buf): Attempt to map input byte array <tt>buf</tt> to an OPRF group element.
This function can raise a DeserializeError upon failure; see <xref section="2.1" sectionFormat="comma" target="OPRF"/>
for more details.</li>
          <li>Noe: The size of a serialized OPRF group element output from SerializeElement.</li>
          <li>Nok: The size of an OPRF private key as output from DeriveKeyPair.</li>
        </ul>
      </section>
      <section anchor="deps-symmetric">
        <name>Key Derivation Function and Message Authentication Code</name>
        <t>A Key Derivation Function (KDF) is a function that takes some source of initial
keying material and uses it to derive one or more cryptographically strong keys.
This specification uses a KDF with the following API and parameters:</t>
        <ul spacing="normal">
          <li>Extract(salt, ikm): Extract a pseudorandom key of fixed length <tt>Nx</tt> bytes from
input keying material <tt>ikm</tt> and an optional byte string <tt>salt</tt>.</li>
          <li>Expand(prk, info, L): Expand a pseudorandom key <tt>prk</tt> using the optional string <tt>info</tt>
into <tt>L</tt> bytes of output keying material.</li>
          <li>Nx: The output size of the <tt>Extract()</tt> function in bytes.</li>
        </ul>
        <t>This specification also makes use of a collision-resistant Message Authentication Code
(MAC) with the following API and parameters:</t>
        <ul spacing="normal">
          <li>MAC(key, msg): Compute a message authentication code over input <tt>msg</tt> with key
<tt>key</tt>, producing a fixed-length output of <tt>Nm</tt> bytes.</li>
          <li>Nm: The output size of the <tt>MAC()</tt> function in bytes.</li>
        </ul>
      </section>
      <section anchor="deps-hash">
        <name>Hash Functions</name>
        <t>This specification makes use of a collision-resistant hash function with the following
API and parameters:</t>
        <ul spacing="normal">
          <li>Hash(msg): Apply a cryptographic hash function to input <tt>msg</tt>, producing a
fixed-length digest of size <tt>Nh</tt> bytes.</li>
          <li>Nh: The output size of the <tt>Hash()</tt> function in bytes.</li>
        </ul>
        <t>This specification makes use of a Key Stretching Function (KSF), which is a slow
and expensive cryptographic hash function with the following API:</t>
        <ul spacing="normal">
          <li>Stretch(msg, params): Apply a key stretching function with parameters
<tt>params</tt> to stretch the input <tt>msg</tt> and harden it against offline
dictionary attacks. This function also needs to satisfy collision resistance.</li>
        </ul>
      </section>
    </section>
    <section anchor="protocol-overview">
      <name>Protocol Overview</name>
      <t>OPAQUE consists of two stages: registration and authenticated key exchange.
In the first stage, a client registers its password with the server and stores
its credential file on the server. In the second stage (also called the
"login" stage), the client recovers its authentication material and uses it to
perform a mutually authenticated key exchange.</t>
      <section anchor="setup">
        <name>Setup</name>
        <t>Prior to both stages, the client and server agree on a configuration that
fully specifies the cryptographic algorithm dependencies necessary to run the
protocol; see <xref target="configurations"/> for details.
The server chooses a pair of keys (<tt>server_private_key</tt> and <tt>server_public_key</tt>)
for the AKE, and chooses a seed (<tt>oprf_seed</tt>) of <tt>Nh</tt> bytes for the OPRF.
The server can use this single pair of keys with multiple
clients and can opt to use multiple seeds (so long as they are kept consistent for
each client).</t>
      </section>
      <section anchor="offline-registration">
        <name>Offline Registration</name>
        <t>Registration is the only stage in OPAQUE that requires a server-authenticated
and confidential channel: either physical, out-of-band, PKI-based, etc.</t>
        <t>The client inputs its credentials, which include its password and user
identifier, and the server inputs its parameters, which include its private key
and other information.</t>
        <t>The client output of this stage is a single value <tt>export_key</tt> that the client
may use for application-specific purposes, e.g., to encrypt additional
information for storage on the server. The server does not have access to this
<tt>export_key</tt>.</t>
        <t>The server output of this stage is a record corresponding to the client's
registration that it stores in a credential file alongside other clients
registrations as needed.</t>
        <t>The registration flow is shown below:</t>
        <artwork><![CDATA[
    creds                                   parameters
      |                                         |
      v                                         v
    Client                                    Server
    ------------------------------------------------
                registration request
             ------------------------->
                registration response
             <-------------------------
                      record
             ------------------------->
   ------------------------------------------------
      |                                         |
      v                                         v
  export_key                                 record
]]></artwork>
        <t>These messages are named <tt>RegistrationRequest</tt>, <tt>RegistrationResponse</tt>, and
<tt>RegistrationRecord</tt>, respectively. Their contents and wire format are defined in
<xref target="registration-messages"/>.</t>
      </section>
      <section anchor="online-authenticated-key-exchange">
        <name>Online Authenticated Key Exchange</name>
        <t>In this second stage, a client obtains credentials previously registered
with the server, recovers private key material using the password, and
subsequently uses them as input to the AKE protocol. As in the registration
phase, the client inputs its credentials, including its password and user
identifier, and the server inputs its parameters and the credential file record
corresponding to the client. The client outputs two values, an <tt>export_key</tt>
(matching that from registration) and a <tt>session_key</tt>, the latter of which
is the primary AKE output. The server outputs a single value <tt>session_key</tt>
that matches that of the client. Upon completion, clients and servers can
use these values as needed.</t>
        <t>The authenticated key exchange flow is shown below:</t>
        <artwork><![CDATA[
    creds                             (parameters, record)
      |                                         |
      v                                         v
    Client                                    Server
    ------------------------------------------------
                   AKE message 1
             ------------------------->
                   AKE message 2
             <-------------------------
                   AKE message 3
             ------------------------->
   ------------------------------------------------
      |                                         |
      v                                         v
(export_key, session_key)                  session_key
]]></artwork>
        <t>These messages are named <tt>KE1</tt>, <tt>KE2</tt>, and <tt>KE3</tt>, respectively. They carry the
messages of the concurrent execution of the key recovery process (OPRF) and the
authenticated key exchange (AKE), and their corresponding wire formats are
specified in <xref target="ake-messages"/>.</t>
        <t>The rest of this document describes the details of these stages in detail.
<xref target="client-material"/> describes how client credential information is
generated, encoded, and stored on the server during registration, and recovered during
login. <xref target="offline-phase"/> describes the first registration stage of the protocol,
and <xref target="online-phase"/> describes the second authentication stage of the protocol.
<xref target="configurations"/> describes how to instantiate OPAQUE using different
cryptographic dependencies and parameters.</t>
      </section>
    </section>
    <section anchor="client-material">
      <name>Client Credential Storage and Key Recovery</name>
      <t>OPAQUE makes use of a structure called <tt>Envelope</tt> to manage client credentials.
The client creates its <tt>Envelope</tt> on registration and sends it to the server for
storage. On every login, the server sends this <tt>Envelope</tt> to the client so it can
recover its key material for use in the AKE.</t>
      <t>Future variants of OPAQUE may use different key recovery mechanisms. See <xref target="key-recovery"/> for details.</t>
      <t>Applications may pin key material to identities if desired. If no identity is given
for a party, its value MUST default to its public key. The following types of
application credential information are considered:</t>
      <ul spacing="normal">
        <li>client_private_key: The encoded client private key for the AKE protocol.</li>
        <li>client_public_key: The encoded client public key for the AKE protocol.</li>
        <li>server_public_key: The encoded server public key for the AKE protocol.</li>
        <li>client_identity: The client identity. This is an application-specific value,
e.g., an e-mail address or an account name. If not specified, it defaults
to the client's public key.</li>
        <li>server_identity: The server identity. This is typically a domain name, e.g., example.com.
If not specified, it defaults to the server's public key. See <xref target="identities"/> for
information about this identity.</li>
      </ul>
      <t>These credential values are used in the <tt>CleartextCredentials</tt> structure as follows:</t>
      <artwork><![CDATA[
struct {
  uint8 server_public_key[Npk];
  uint8 server_identity<1..2^16-1>;
  uint8 client_identity<1..2^16-1>;
} CleartextCredentials;
]]></artwork>
      <t>The function CreateCleartextCredentials constructs a <tt>CleartextCredentials</tt> structure given
application credential information.</t>
      <artwork><![CDATA[
CreateCleartextCredentials

Input:
- server_public_key, the encoded server public key for the AKE protocol.
- client_public_key, the encoded client public key for the AKE protocol.
- server_identity, the optional encoded server identity.
- client_identity, the optional encoded client identity.

Output:
- cleartext_credentials, a CleartextCredentials structure.

def CreateCleartextCredentials(server_public_key, client_public_key,
                               server_identity, client_identity):
  # Set identities as public keys if no application-layer identity is provided
  if server_identity == nil
    server_identity = server_public_key
  if client_identity == nil
    client_identity = client_public_key

  Create CleartextCredentials cleartext_credentials with
    (server_public_key, server_identity, client_identity)
  return cleartext_credentials
]]></artwork>
      <section anchor="key-recovery">
        <name>Key Recovery</name>
        <t>This specification defines a key recovery mechanism that uses the stretched OPRF
output as a seed to directly derive the private and public keys using the
<tt>DeriveAuthKeyPair()</tt> function defined in <xref target="key-creation"/>.</t>
        <section anchor="envelope-structure">
          <name>Envelope Structure</name>
          <t>The key recovery mechanism defines its <tt>Envelope</tt> as follows:</t>
          <artwork><![CDATA[
struct {
  uint8 nonce[Nn];
  uint8 auth_tag[Nm];
} Envelope;
]]></artwork>
          <t>nonce: A unique nonce of length <tt>Nn</tt>, used to protect this <tt>Envelope</tt>.</t>
          <t>auth_tag: An authentication tag protecting the contents of the envelope, covering
the envelope nonce and <tt>CleartextCredentials</tt>.</t>
        </section>
        <section anchor="envelope-creation">
          <name>Envelope Creation</name>
          <t>Clients create an <tt>Envelope</tt> at registration with the function <tt>Store</tt> defined
below. Note that <tt>DeriveAuthKeyPair</tt> in this function can fail with negligible
probability. If this occurs, servers should re-run the function, sampling a
new <tt>envelope_nonce</tt>, to completion.</t>
          <artwork><![CDATA[
Store

Input:
- randomized_pwd, a randomized password.
- server_public_key, the encoded server public key for
  the AKE protocol.
- server_identity, the optional encoded server identity.
- client_identity, the optional encoded client identity.

Output:
- envelope, the client's Envelope structure.
- client_public_key, the client's AKE public key.
- masking_key, an encryption key used by the server with the sole purpose
  of defending against client enumeration attacks.
- export_key, an additional client key.

def Store(randomized_pwd, server_public_key, server_identity, client_identity):
  envelope_nonce = random(Nn)
  masking_key = Expand(randomized_pwd, "MaskingKey", Nh)
  auth_key = Expand(randomized_pwd, concat(envelope_nonce, "AuthKey"), Nh)
  export_key = Expand(randomized_pwd, concat(envelope_nonce, "ExportKey"), Nh)
  seed = Expand(randomized_pwd, concat(envelope_nonce, "PrivateKey"), Nseed)
  (_, client_public_key) = DeriveAuthKeyPair(seed)

  cleartext_creds =
    CreateCleartextCredentials(server_public_key, client_public_key,
                               server_identity, client_identity)
  auth_tag = MAC(auth_key, concat(envelope_nonce, cleartext_creds))

  Create Envelope envelope with (envelope_nonce, auth_tag)
  return (envelope, client_public_key, masking_key, export_key)
]]></artwork>
        </section>
        <section anchor="envelope-recovery">
          <name>Envelope Recovery</name>
          <t>Clients recover their <tt>Envelope</tt> during login with the <tt>Recover</tt> function
defined below.</t>
          <artwork><![CDATA[
Recover

Input:
- randomized_pwd, a randomized password.
- server_public_key, the encoded server public key for the AKE protocol.
- envelope, the client's Envelope structure.
- server_identity, the optional encoded server identity.
- client_identity, the optional encoded client identity.

Output:
- client_private_key, the encoded client private key for the AKE protocol.
- export_key, an additional client key.

Exceptions:
- EnvelopeRecoveryError, the envelope fails to be recovered.

def Recover(randomized_pwd, server_public_key, envelope,
            server_identity, client_identity):
  auth_key = Expand(randomized_pwd, concat(envelope.nonce, "AuthKey"), Nh)
  export_key = Expand(randomized_pwd, concat(envelope.nonce, "ExportKey", Nh)
  seed = Expand(randomized_pwd, concat(envelope.nonce, "PrivateKey"), Nseed)
  (client_private_key, client_public_key) = DeriveAuthKeyPair(seed)

  cleartext_creds = CreateCleartextCredentials(server_public_key,
                      client_public_key, server_identity, client_identity)
  expected_tag = MAC(auth_key, concat(envelope.nonce, cleartext_creds))
  If !ct_equal(envelope.auth_tag, expected_tag)
    raise EnvelopeRecoveryError
  return (client_private_key, export_key)
]]></artwork>
        </section>
      </section>
    </section>
    <section anchor="offline-phase">
      <name>Offline Registration</name>
      <t>The registration process proceeds as follows. The client inputs
the following values:</t>
      <ul spacing="normal">
        <li>password: The client's password.</li>
        <li>creds: The client credentials, as described in <xref target="client-material"/>.</li>
      </ul>
      <t>The server inputs the following values:</t>
      <ul spacing="normal">
        <li>server_private_key: The server private key for the AKE protocol.</li>
        <li>server_public_key: The server public key for the AKE protocol.</li>
        <li>credential_identifier: A unique identifier for the client's
credential, generated by the server.</li>
        <li>client_identity: The optional client identity as described in <xref target="client-material"/>.</li>
        <li>oprf_seed: A seed used to derive per-client OPRF keys.</li>
      </ul>
      <t>The registration protocol then runs as shown below:</t>
      <artwork><![CDATA[
  Client                                         Server
 ------------------------------------------------------
 (request, blind) = CreateRegistrationRequest(password)

                        request
              ------------------------->

 response = CreateRegistrationResponse(request,
                                       server_public_key,
                                       credential_identifier,
                                       oprf_seed)

                        response
              <-------------------------

 (record, export_key) = FinalizeRegistrationRequest(response,
                                                    server_identity,
                                                    client_identity)

                        record
              ------------------------->
]]></artwork>
      <t><xref target="registration-messages"/> describes the formats for the above messages, and
<xref target="registration-functions"/> describes details of the functions and the
corresponding parameters referenced above.</t>
      <t>At the end of this interaction, the server stores the <tt>record</tt> object as the
credential file for each client along with the associated <tt>credential_identifier</tt>
and <tt>client_identity</tt> (if different). Note that the values <tt>oprf_seed</tt> and
<tt>server_private_key</tt> from the server's setup phase must also be persisted.
The <tt>oprf_seed</tt> value SHOULD be used for all clients; see <xref target="preventing-client-enumeration"/>.
The <tt>server_private_key</tt> may be unique for each client.</t>
      <t>Both client and server MUST validate the other party's public key before use.
See <xref target="validation"/> for more details. Upon completion, the server stores
the client's credentials for later use. Moreover, the client MAY use the output
<tt>export_key</tt> for further application-specific purposes; see <xref target="export-key-usage"/>.</t>
      <section anchor="registration-messages">
        <name>Registration Messages</name>
        <t>This section contains definitions of the <tt>RegistrationRequest</tt>,
<tt>RegistrationResponse</tt>, and <tt>RegistrationRecord</tt> messages exchanged between
client and server during registration.</t>
        <artwork><![CDATA[
struct {
  uint8 blinded_message[Noe];
} RegistrationRequest;
]]></artwork>
        <t>blinded_message: A serialized OPRF group element.</t>
        <artwork><![CDATA[
struct {
  uint8 evaluated_message[Noe];
  uint8 server_public_key[Npk];
} RegistrationResponse;
]]></artwork>
        <t>evaluated_message: A serialized OPRF group element.</t>
        <t>server_public_key: The server's encoded public key that will be used for
the online AKE stage.</t>
        <artwork><![CDATA[
struct {
  uint8 client_public_key[Npk];
  uint8 masking_key[Nh];
  Envelope envelope;
} RegistrationRecord;
]]></artwork>
        <t>client_public_key: The client's encoded public key, corresponding to
the private key <tt>client_private_key</tt>.</t>
        <t>masking_key: An encryption key used by the server to preserve
confidentiality of the envelope during login to defend against
client enumeration attacks.</t>
        <t>envelope: The client's <tt>Envelope</tt> structure.</t>
      </section>
      <section anchor="registration-functions">
        <name>Registration Functions</name>
        <t>This section contains definitions of the functions used by client and server
during registration, including <tt>CreateRegistrationRequest</tt>, <tt>CreateRegistrationResponse</tt>,
and <tt>FinalizeRegistrationRequest</tt>.</t>
        <section anchor="createregistrationrequest">
          <name>CreateRegistrationRequest</name>
          <t>To begin the registration flow, the client executes the following function. This function
can fail with a InvalidInputError error with negligibile probability. A different input
password is necessary in the event of this error.</t>
          <artwork><![CDATA[
CreateRegistrationRequest

Input:
- password, an opaque byte string containing the client's password.

Output:
- request, a RegistrationRequest structure.
- blind, an OPRF scalar value.

Exceptions:
- InvalidInputError, when Blind fails

def CreateRegistrationRequest(password):
  (blind, blinded_element) = Blind(password)
  blinded_message = SerializeElement(blinded_element)
  Create RegistrationRequest request with blinded_message
  return (request, blind)
]]></artwork>
        </section>
        <section anchor="create-reg-response">
          <name>CreateRegistrationResponse</name>
          <t>To process the client's registration request, the server executes
the following function. This function can fail with a <tt>DeriveKeyPairError</tt>
error with negligible probability. In this case, application can
choose a new <tt>credential_identifier</tt> for this registration record
and re-run this function.</t>
          <artwork><![CDATA[
CreateRegistrationResponse

Input:
- request, a RegistrationRequest structure.
- server_public_key, the server's public key.
- credential_identifier, an identifier that uniquely represents the credential.
- oprf_seed, the seed of Nh bytes used by the server to generate an oprf_key.

Output:
- response, a RegistrationResponse structure.

Exceptions:
- DeserializeError, when OPRF element deserialization fails.
- DeriveKeyPairError, when OPRF key derivation fails.

def CreateRegistrationResponse(request, server_public_key,
                               credential_identifier, oprf_seed):
  seed = Expand(oprf_seed, concat(credential_identifier, "OprfKey"), Nok)
  (oprf_key, _) = DeriveKeyPair(seed, "OPAQUE-DeriveKeyPair")

  blinded_element = DeserializeElement(request.blinded_message)
  evaluated_element = Evaluate(oprf_key, blinded_element)
  evaluated_message = SerializeElement(evaluated_element)

  Create RegistrationResponse response with (evaluated_message, server_public_key)
  return response
]]></artwork>
        </section>
        <section anchor="finalize-request">
          <name>FinalizeRegistrationRequest</name>
          <t>To create the user record used for subsequent authentication and complete the
registration flow, the client executes the following function.</t>
          <artwork><![CDATA[
FinalizeRegistrationRequest

Input:
- password, an opaque byte string containing the client's password.
- blind, an OPRF scalar value.
- response, a RegistrationResponse structure.
- server_identity, the optional encoded server identity.
- client_identity, the optional encoded client identity.

Output:
- record, a RegistrationRecord structure.
- export_key, an additional client key.

Exceptions:
- DeserializeError, when OPRF element deserialization fails.

def FinalizeRegistrationRequest(password, blind, response, server_identity, client_identity):
  evaluated_element = DeserializeElement(response.evaluated_message)
  oprf_output = Finalize(password, blind, evaluated_element)

  stretched_oprf_output = Stretch(oprf_output, params)
  randomized_pwd = Extract("", concat(oprf_output, stretched_oprf_output))

  (envelope, client_public_key, masking_key, export_key) =
    Store(randomized_pwd, response.server_public_key,
          server_identity, client_identity)
  Create RegistrationRecord record with (client_public_key, masking_key, envelope)
  return (record, export_key)
]]></artwork>
          <t>See <xref target="online-phase"/> for details about the output <tt>export_key</tt> usage.</t>
        </section>
      </section>
    </section>
    <section anchor="online-phase">
      <name>Online Authenticated Key Exchange</name>
      <t>The generic outline of OPAQUE with a 3-message AKE protocol includes three messages:
<tt>KE1</tt>, <tt>KE2</tt>, and <tt>KE3</tt>, where <tt>KE1</tt> and <tt>KE2</tt> include key exchange shares, e.g., DH values, sent
by the client and server, respectively, and <tt>KE3</tt> provides explicit client authentication and
full forward security (without it, forward secrecy is only achieved against eavesdroppers,
which is insufficient for OPAQUE security).</t>
      <t>This section describes the online authenticated key exchange protocol flow,
message encoding, and helper functions. This stage is composed of a concurrent
OPRF and key exchange flow. The key exchange protocol is authenticated using the
client and server credentials established during registration; see <xref target="offline-phase"/>.
In the end, the client proves its knowledge of the password, and both client and
server agree on (1) a mutually authenticated shared secret key and (2) any optional
application information exchange during the handshake.</t>
      <t>In this stage, the client inputs the following values:</t>
      <ul spacing="normal">
        <li>password: The client's password.</li>
        <li>client_identity: The client identity, as described in <xref target="client-material"/>.</li>
      </ul>
      <t>The server inputs the following values:</t>
      <ul spacing="normal">
        <li>server_private_key: The server's private key for the AKE protocol.</li>
        <li>server_public_key: The server's public key for the AKE protocol.</li>
        <li>server_identity: The server identity, as described in <xref target="client-material"/>.</li>
        <li>record: The <tt>RegistrationRecord</tt> object corresponding to the client's registration.</li>
        <li>credential_identifier: An identifier that uniquely represents the credential.</li>
        <li>oprf_seed: The seed used to derive per-client OPRF keys.</li>
      </ul>
      <t>The client receives two outputs: a session secret and an export key. The export
key is only available to the client and may be used for additional
application-specific purposes, as outlined in <xref target="export-key-usage"/>. The output
<tt>export_key</tt> MUST NOT be used in any way before the protocol completes
successfully. See <xref target="alternate-key-recovery"/> for more details about this
requirement. The server receives a single output: a session secret matching the
client's.</t>
      <t>The protocol runs as shown below:</t>
      <artwork><![CDATA[
  Client                                         Server
 ------------------------------------------------------
  ke1 = ClientInit(password)

                         ke1
              ------------------------->

  ke2 = ServerInit(server_identity, server_private_key,
                    server_public_key, record,
                    credential_identifier, oprf_seed, ke1)

                         ke2
              <-------------------------

    (ke3,
    session_key,
    export_key) = ClientFinish(client_identity,
                               server_identity, ke2)

                         ke3
              ------------------------->

                       session_key = ServerFinish(ke3)
]]></artwork>
      <t>Both client and server may use implicit internal state objects to keep necessary
material for the OPRF and AKE, <tt>client_state</tt> and <tt>server_state</tt>, respectively.</t>
      <t>The client state <tt>ClientState</tt> may have the following fields:</t>
      <ul spacing="normal">
        <li>password: The client's password.</li>
        <li>blind: The random blinding inverter returned by <tt>Blind()</tt>.</li>
        <li>client_ake_state: The <tt>ClientAkeState</tt> defined in <xref target="ake-protocol"/>.</li>
      </ul>
      <t>The server state <tt>ServerState</tt> may have the following fields:</t>
      <ul spacing="normal">
        <li>server_ake_state: The <tt>ServerAkeState</tt> defined in <xref target="ake-protocol"/>.</li>
      </ul>
      <t>The rest of this section describes these authenticated key exchange messages
and their parameters in more detail. <xref target="ake-messages"/> defines the structure of the
messages passed between client and server in the above setup. <xref target="ake-functions"/>
describes details of the functions and corresponding parameters mentioned above.
<xref target="cred-retrieval"/> discusses internal functions used for retrieving client
credentials, and <xref target="ake-protocol"/> discusses how these functions are used to execute
the authenticated key exchange protocol.</t>
      <section anchor="ake-messages">
        <name>AKE Messages</name>
        <t>In this section, we define the <tt>KE1</tt>, <tt>KE2</tt>, and <tt>KE3</tt> structs that make up
the AKE messages used in the protocol. <tt>KE1</tt> is composed of a <tt>CredentialRequest</tt>
and <tt>AuthRequest</tt>, and <tt>KE2</tt> is composed of a <tt>CredentialResponse</tt>
and <tt>AuthResponse</tt>.</t>
        <artwork><![CDATA[
struct {
  uint8 client_nonce[Nn];
  uint8 client_keyshare[Npk];
} AuthRequest;
]]></artwork>
        <t>client_nonce: A fresh randomly generated nonce of length <tt>Nn</tt>.</t>
        <t>client_keyshare: A serialized client ephemeral key share of fixed size <tt>Npk</tt>.</t>
        <artwork><![CDATA[
struct {
  CredentialRequest credential_request;
  AuthRequest auth_request;
} KE1;
]]></artwork>
        <t>credential_request: A <tt>CredentialRequest</tt> structure.</t>
        <t>auth_request: An <tt>AuthRequest</tt> structure.</t>
        <artwork><![CDATA[
struct {
  uint8 server_nonce[Nn];
  uint8 server_keyshare[Npk];
  uint8 server_mac[Nm];
} AuthResponse;
]]></artwork>
        <t>server_nonce: A fresh randomly generated nonce of length <tt>Nn</tt>.</t>
        <t>server_keyshare: Server ephemeral key share of fixed size <tt>Npk</tt>, where <tt>Npk</tt>
depends on the corresponding prime order group.</t>
        <t>server_mac: An authentication tag computed over the handshake transcript
computed using <tt>Km2</tt>, defined below.</t>
        <artwork><![CDATA[
struct {
  CredentialResponse credential_response;
  AuthResponse auth_response;
} KE2;
]]></artwork>
        <t>credential_response: A <tt>CredentialResponse</tt> structure.</t>
        <t>auth_response: An <tt>AuthResponse</tt> structure.</t>
        <artwork><![CDATA[
struct {
  uint8 client_mac[Nm];
} KE3;
]]></artwork>
        <t>client_mac: An authentication tag computed over the handshake transcript
of fixed size <tt>Nm</tt>, computed using <tt>Km2</tt>, defined below.</t>
      </section>
      <section anchor="ake-functions">
        <name>AKE Functions</name>
        <t>In this section, we define the main functions used to produce the AKE messages
in the protocol. Note that this section relies on definitions of subroutines defined
in later sections:</t>
        <ul spacing="normal">
          <li>
            <tt>CreateCredentialRequest</tt>, <tt>CreateCredentialResponse</tt>, <tt>RecoverCredentials</tt>
defined in <xref target="cred-retrieval"/></li>
          <li>
            <tt>AuthClientStart</tt>, <tt>AuthServerRespond</tt>, <tt>AuthClientFinalize</tt>, and <tt>AuthServerFinalize</tt>
defined in <xref target="ake-client"/> and <xref target="ake-server"/></li>
        </ul>
        <section anchor="clientinit">
          <name>ClientInit</name>
          <t>The <tt>ClientInit</tt> function begins the AKE protocol and produces the client's <tt>KE1</tt>
output for the server.</t>
          <artwork><![CDATA[
ClientInit

State:
- state, a ClientState structure.

Input:
- password, an opaque byte string containing the client's password.

Output:
- ke1, a KE1 message structure.

def ClientInit(password):
  credential_request, blind = CreateCredentialRequest(password)
  state.password = password
  state.blind = blind
  ke1 = AuthClientStart(request)
  return ke1
]]></artwork>
        </section>
        <section anchor="serverinit">
          <name>ServerInit</name>
          <t>The <tt>ServerInit</tt> function continues the AKE protocol by processing the client's <tt>KE1</tt> message
and producing the server's <tt>KE2</tt> output.</t>
          <artwork><![CDATA[
ServerInit

State:
- state, a ServerState structure.

Input:
- server_identity, the optional encoded server identity, which is set to
  server_public_key if nil.
- server_private_key, the server's private key.
- server_public_key, the server's public key.
- record, the client's RegistrationRecord structure.
- credential_identifier, an identifier that uniquely represents the credential.
- oprf_seed, the server-side seed of Nh bytes used to generate an oprf_key.
- ke1, a KE1 message structure.
- client_identity, the encoded client identity.

Output:
- ke2, a KE2 structure.

def ServerInit(server_identity, server_private_key, server_public_key,
               record, credential_identifier, oprf_seed, ke1, client_identity):
  credential_response = CreateCredentialResponse(ke1.request, server_public_key, record,
    credential_identifier, oprf_seed)
  auth_response = AuthServerRespond(server_identity, server_private_key,
    client_identity, record.client_public_key, ke1, credential_response)
  Create KE2 ke2 with (credential_response, auth_response)
]]></artwork>
        </section>
        <section anchor="clientfinish">
          <name>ClientFinish</name>
          <t>The <tt>ClientFinish</tt> function completes the AKE protocol for the client and
produces the client's <tt>KE3</tt> output for the server, as well as the <tt>session_key</tt>
and <tt>export_key</tt> outputs from the AKE.</t>
          <artwork><![CDATA[
ClientFinish

State:
- state, a ClientState structure.

Input:
- client_identity, the optional encoded client identity, which is set
  to client_public_key if not specified.
- server_identity, the optional encoded server identity, which is set
  to server_public_key if not specified.
- ke2, a KE2 message structure.

Output:
- ke3, a KE3 message structure.
- session_key, the session's shared secret.
- export_key, an additional client key.

def ClientFinish(client_identity, server_identity, ke2):
  (client_private_key, server_public_key, export_key) =
    RecoverCredentials(state.password, state.blind, ke2.credential_response,
                       server_identity, client_identity)
  (ke3, session_key) =
    AuthClientFinalize(client_identity, client_private_key, server_identity,
                       server_public_key, ke2)
  return (ke3, session_key, export_key)
]]></artwork>
        </section>
        <section anchor="serverfinish">
          <name>ServerFinish</name>
          <t>The <tt>ServerFinish</tt> function completes the AKE protocol for the server, yielding the <tt>session_key</tt>.
Since the OPRF is a two-message protocol, <tt>KE3</tt> has no element of the OPRF, and it, therefore,
invokes the AKE's <tt>AuthServerFinalize</tt> directly. The <tt>AuthServerFinalize</tt> function
takes <tt>KE3</tt> as input and MUST verify the client authentication material it contains
before the <tt>session_key</tt> value can be used. This verification is necessary to ensure
forward secrecy against active attackers.</t>
          <artwork><![CDATA[
ServerFinish

State:
- state, a ServerState structure.

Input:
- ke3, a KE3 structure.

Output:
- session_key, the shared session secret if and only if ke3 is valid.

def ServerFinish(ke3):
  return AuthServerFinalize(ke3)
]]></artwork>
          <t>This function MUST NOT return the <tt>session_key</tt> value if the client authentication
material is invalid, and may instead return an appropriate error message such as
ClientAuthenticationError, invoked from <tt>AuthServerFinalize</tt>.</t>
        </section>
      </section>
      <section anchor="cred-retrieval">
        <name>Credential Retrieval</name>
        <t>This section describes the sub-protocol run during authentication to retrieve and
recover the client credentials.</t>
        <section anchor="credential-retrieval-messages">
          <name>Credential Retrieval Messages</name>
          <t>This section describes the <tt>CredentialRequest</tt> and <tt>CredentialResponse</tt> messages exchanged
between client and server to perform credential retrieval.</t>
          <artwork><![CDATA[
struct {
  uint8 blinded_message[Noe];
} CredentialRequest;
]]></artwork>
          <t>blinded_message: A serialized OPRF group element.</t>
          <artwork><![CDATA[
struct {
  uint8 evaluated_message[Noe];
  uint8 masking_nonce[Nn];
  uint8 masked_response[Npk + Ne];
} CredentialResponse;
]]></artwork>
          <t>evaluated_message: A serialized OPRF group element.</t>
          <t>masking_nonce: A nonce used for the confidentiality of the
<tt>masked_response</tt> field.</t>
          <t>masked_response: An encrypted form of the server's public key and the
client's <tt>Envelope</tt> structure.</t>
        </section>
        <section anchor="credential-retrieval-functions">
          <name>Credential Retrieval Functions</name>
          <t>This section describes the <tt>CreateCredentialRequest</tt>, <tt>CreateCredentialResponse</tt>,
and <tt>RecoverCredentials</tt> functions used for credential retrieval.</t>
          <section anchor="create-credential-request">
            <name>CreateCredentialRequest</name>
            <t>The <tt>CreateCredentialRequest</tt> is used by the client to initiate the credential
retrieval process, and it produces a <tt>CredentialRequest</tt> message and OPRF state.
Like <tt>CreateRegistrationRequest</tt>, this function can fail with a InvalidInputError
error with negligibile probability. However, this should not occur since
registration (via <tt>CreateRegistrationRequest</tt>) will fail when provided the same
password input.</t>
            <artwork><![CDATA[
CreateCredentialRequest

Input:
- password, an opaque byte string containing the client's password.

Output:
- request, a CredentialRequest structure.
- blind, an OPRF scalar value.

Exceptions:
- InvalidInputError, when Blind fails

def CreateCredentialRequest(password):
  (blind, blinded_element) = Blind(password)
  blinded_message = SerializeElement(blinded_element)
  Create CredentialRequest request with blinded_message
  return (request, blind)
]]></artwork>
          </section>
          <section anchor="create-credential-response">
            <name>CreateCredentialResponse</name>
            <t>The <tt>CreateCredentialResponse</tt> function is used by the server to process the client's
<tt>CredentialRequest</tt> message and complete the credential retrieval process, producing
a <tt>CredentialResponse</tt>.</t>
            <t>There are two scenarios to handle for the construction of a <tt>CredentialResponse</tt>
object: either the record for the client exists (corresponding to a properly
registered client), or it was never created (corresponding to a client that has
yet to register).</t>
            <t>In the case of an existing record with the corresponding identifier
<tt>credential_identifier</tt>, the server invokes the following function to
produce a <tt>CredentialResponse</tt>:</t>
            <artwork><![CDATA[
CreateCredentialResponse

Input:
- request, a CredentialRequest structure.
- server_public_key, the public key of the server.
- record, an instance of RegistrationRecord which is the server's
  output from registration.
- credential_identifier, an identifier that uniquely represents the credential.
- oprf_seed, the server-side seed of Nh bytes used to generate an oprf_key.

Output:
- response, a CredentialResponse structure.

Exceptions:
- DeserializeError, when OPRF element deserialization fails.

def CreateCredentialResponse(request, server_public_key, record,
                             credential_identifier, oprf_seed):
  seed = Expand(oprf_seed, concat(credential_identifier, "OprfKey"), Nok)
  (oprf_key, _) = DeriveKeyPair(seed, "OPAQUE-DeriveKeyPair")

  blinded_element = DeserializeElement(request.blinded_message)
  evaluated_element = Evaluate(oprf_key, blinded_element)
  evaluated_message = SerializeElement(evaluated_element)

  masking_nonce = random(Nn)
  credential_response_pad = Expand(record.masking_key,
                                   concat(masking_nonce, "CredentialResponsePad"),
                                   Npk + Ne)
  masked_response = xor(credential_response_pad,
                        concat(server_public_key, record.envelope))
  Create CredentialResponse response with (evaluated_message, masking_nonce, masked_response)
  return response
]]></artwork>
            <t>In the case of a record that does not exist and if client enumeration prevention is desired,
the server MUST respond to the credential request to fake the existence of the record.
The server SHOULD invoke the <tt>CreateCredentialResponse</tt> function with a fake client record
argument that is configured so that:</t>
            <ul spacing="normal">
              <li>
                <tt>record.client_public_key</tt> is set to a randomly generated public key of length <tt>Npk</tt></li>
              <li>
                <tt>record.masking_key</tt> is set to a random byte string of length <tt>Nh</tt></li>
              <li>
                <tt>record.envelope</tt> is set to the byte string consisting only of zeros of length <tt>Ne</tt></li>
            </ul>
            <t>It is RECOMMENDED that a fake client record is created once (e.g. as the first user record
of the application) and stored alongside legitimate client records. This allows servers to locate
the record in a time comparable to that of a legitimate client record.</t>
            <t>Note that the responses output by either scenario are indistinguishable to an adversary
that is unable to guess the registered password for the client corresponding to <tt>credential_identifier</tt>.</t>
          </section>
          <section anchor="recover-credentials">
            <name>RecoverCredentials</name>
            <t>The <tt>RecoverCredentials</tt> function is used by the client to process the server's
<tt>CredentialResponse</tt> message and produce the client's private key, server public
key, and the <tt>export_key</tt>.</t>
            <artwork><![CDATA[
RecoverCredentials

Input:
- password, an opaque byte string containing the client's password.
- blind, an OPRF scalar value.
- response, a CredentialResponse structure.
- server_identity, The optional encoded server identity.
- client_identity, The encoded client identity.

Output:
- client_private_key, the client's private key for the AKE protocol.
- server_public_key, the public key of the server.
- export_key, an additional client key.

Exceptions:
- DeserializeError, when OPRF element deserialization fails.

def RecoverCredentials(password, blind, response,
                       server_identity, client_identity):
  evaluated_element = DeserializeElement(response.evaluated_message)

  oprf_output = Finalize(password, blind, evaluated_element)
  stretched_oprf_output = Stretch(oprf_output, params)
  randomized_pwd = Extract("", concat(oprf_output, stretched_oprf_output))

  masking_key = Expand(randomized_pwd, "MaskingKey", Nh)
  credential_response_pad = Expand(masking_key,
                                   concat(response.masking_nonce, "CredentialResponsePad"),
                                   Npk + Ne)
  concat(server_public_key, envelope) = xor(credential_response_pad,
                                              response.masked_response)
  (client_private_key, export_key) =
    Recover(randomized_pwd, server_public_key, envelope,
            server_identity, client_identity)

  return (client_private_key, server_public_key, export_key)
]]></artwork>
          </section>
        </section>
      </section>
      <section anchor="ake-protocol">
        <name>AKE Protocol</name>
        <t>This section describes the authenticated key exchange protocol for OPAQUE using
3DH, a 3-message AKE which satisfies the forward secrecy and KCI properties
discussed in <xref target="security-considerations"/>.</t>
        <t>The client AKE state <tt>ClientAkeState</tt> mentioned in <xref target="online-phase"/> has the
following fields:</t>
        <ul spacing="normal">
          <li>client_secret: An opaque byte string of length <tt>Nsk</tt>.</li>
          <li>ke1: A value of type <tt>KE1</tt>.</li>
        </ul>
        <t>The server AKE state <tt>ServerAkeState</tt> mentioned in <xref target="online-phase"/> has the
following fields:
- expected_client_mac: An opaque byte string of length <tt>Nm</tt>.
- session_key: An opaque byte string of length <tt>Nx</tt>.</t>
        <t><xref target="ake-client"/> and <xref target="ake-server"/> specify the inner workings of client and
server functions, respectively.</t>
        <section anchor="key-creation">
          <name>Key Creation</name>
          <t>We assume the following functions to exist for all candidate groups in this
setting:</t>
          <ul spacing="normal">
            <li>DeriveAuthKeyPair(seed): Derive a private and public authentication key pair
deterministically from the input <tt>seed</tt>. This function is implemented as
DeriveKeyPair(seed, "OPAQUE-DeriveAuthKeyPair"), where DeriveKeyPair is
as specified in <xref section="3.2" sectionFormat="comma" target="OPRF"/>.</li>
            <li>GenerateAuthKeyPair(): Return a randomly generated private and public key
pair. This can be implemented by invoking DeriveAuthKeyPair with <tt>Nseed</tt>
random bytes as input.</li>
            <li>SerializeElement(element): A member function of the underlying group that
maps <tt>element</tt> to a unique byte array, mirrored from the definition of the
similarly-named function of the OPRF group described in
<xref section="2.1" sectionFormat="comma" target="OPRF"/>.</li>
          </ul>
        </section>
        <section anchor="key-schedule-functions">
          <name>Key Schedule Functions</name>
          <t>This section contains functions used for the AKE key schedule.</t>
          <section anchor="transcript-functions">
            <name>Transcript Functions</name>
            <t>The OPAQUE-3DH key derivation procedures make use of the functions below,
re-purposed from TLS 1.3 <xref target="RFC8446"/>.</t>
            <artwork><![CDATA[
Expand-Label(Secret, Label, Context, Length) =
    Expand(Secret, CustomLabel, Length)
]]></artwork>
            <t>Where CustomLabel is specified as:</t>
            <artwork><![CDATA[
struct {
  uint16 length = Length;
  opaque label<8..255> = "OPAQUE-" + Label;
  uint8 context<0..255> = Context;
} CustomLabel;

Derive-Secret(Secret, Label, Transcript-Hash) =
    Expand-Label(Secret, Label, Transcript-Hash, Nx)
]]></artwork>
            <t>Note that the <tt>Label</tt> parameter is not a NULL-terminated string.</t>
            <t>OPAQUE-3DH can optionally include shared <tt>context</tt> information in the
transcript, such as configuration parameters or application-specific info, e.g.
"appXYZ-v1.2.3".</t>
            <t>The OPAQUE-3DH key schedule requires a preamble, which is computed as follows.</t>
            <artwork><![CDATA[
Preamble

Parameters:
- context, optional shared context information.

Input:
- client_identity, the optional encoded client identity, which is set
  to client_public_key if not specified.
- ke1, a KE1 message structure.
- server_identity, the optional encoded server identity, which is set
  to server_public_key if not specified.
- credential_response, the corresponding field on the KE2 structure.
- server_nonce, the corresponding field on the AuthResponse structure.
- server_keyshare, the corresponding field on the AuthResponse structure.

Output:
- preamble, the protocol transcript with identities and messages.

def Preamble(client_identity, ke1, server_identity, ke2):
  preamble = concat("RFCXXXX",
                     I2OSP(len(context), 2), context,
                     I2OSP(len(client_identity), 2), client_identity,
                     ke1,
                     I2OSP(len(server_identity), 2), server_identity,
                     credential_response,
                     server_nonce,
                     server_keyshare)
  return preamble
]]></artwork>
          </section>
          <section anchor="shared-secret-derivation">
            <name>Shared Secret Derivation</name>
            <t>The OPAQUE-3DH shared secret derived during the key exchange protocol is
computed using the following helper function.</t>
            <artwork><![CDATA[
DeriveKeys

Input:
- ikm, input key material.
- preamble, the protocol transcript with identities and messages.

Output:
- Km2, a MAC authentication key.
- Km3, a MAC authentication key.
- session_key, the shared session secret.

def DeriveKeys(ikm, preamble):
  prk = Extract("", ikm)
  handshake_secret = Derive-Secret(prk, "HandshakeSecret", Hash(preamble))
  session_key = Derive-Secret(prk, "SessionKey", Hash(preamble))
  Km2 = Derive-Secret(handshake_secret, "ServerMAC", "")
  Km3 = Derive-Secret(handshake_secret, "ClientMAC", "")
  return (Km2, Km3, session_key)
]]></artwork>
          </section>
        </section>
        <section anchor="ake-client">
          <name>3DH Client Functions</name>
          <t>The <tt>AuthClientStart</tt> function is used by the client to create a
<tt>KE1</tt> structure.</t>
          <artwork><![CDATA[
AuthClientStart

Parameters:
- Nn, the nonce length.

State:
- state, a ClientAkeState structure.

Input:
- credential_request, a CredentialRequest structure.

Output:
- ke1, a KE1 structure.

def AuthClientStart(credential_request):
  client_nonce = random(Nn)
  (client_secret, client_keyshare) = GenerateAuthKeyPair()
  Create AuthRequest auth_request with (client_nonce, client_keyshare)
  Create KE1 ke1 with (credential_request, auth_request)
  state.client_secret = client_secret
  state.ke1 = ke1
  return ke1
]]></artwork>
          <t>The <tt>AuthClientFinalize</tt> function is used by the client to create a <tt>KE3</tt>
message and output <tt>session_key</tt> using the server's <tt>KE2</tt> message and
recovered credential information.</t>
          <artwork><![CDATA[
AuthClientFinalize

State:
- state, a ClientAkeState structure.

Input:
- client_identity, the optional encoded client identity, which is
  set to client_public_key if not specified.
- client_private_key, the client's private key.
- server_identity, the optional encoded server identity, which is
  set to server_public_key if not specified.
- server_public_key, the server's public key.
- ke2, a KE2 message structure.

Output:
- ke3, a KE3 structure.
- session_key, the shared session secret.

Exceptions:
- ServerAuthenticationError, the handshake fails.

def AuthClientFinalize(client_identity, client_private_key, server_identity,
                       server_public_key, ke2):

  dh1 = SerializeElement(state.client_secret * ke2.auth_response.server_keyshare)
  dh2 = SerializeElement(state.client_secret * server_public_key)
  dh3 = SerializeElement(client_private_key  * ke2.auth_response.server_keyshare)
  ikm = concat(dh1, dh2, dh3)

  preamble = Preamble(client_identity,
                      state.ke1,
                      server_identity,
                      ke2.credential_response,
                      ke2.auth_response.server_nonce,
                      ke2.auth_response.server_keyshare)
  Km2, Km3, session_key = DeriveKeys(ikm, preamble)
  expected_server_mac = MAC(Km2, Hash(preamble))
  if !ct_equal(ke2.server_mac, expected_server_mac),
    raise ServerAuthenticationError
  client_mac = MAC(Km3, Hash(concat(preamble, expected_server_mac))
  Create KE3 ke3 with client_mac
  return (ke3, session_key)
]]></artwork>
        </section>
        <section anchor="ake-server">
          <name>3DH Server Functions</name>
          <t>The <tt>AuthServerRespond</tt> function is used by the server to process the client's
<tt>KE1</tt> message and public credential information to create a <tt>KE2</tt> message.</t>
          <artwork><![CDATA[
AuthServerRespond

Parameters:
- Nn, the nonce length.

State:
- state, a ServerAkeState structure.

Input:
- server_identity, the optional encoded server identity, which is set to
  server_public_key if not specified.
- server_private_key, the server's private key.
- client_identity, the optional encoded client identity, which is set to
  client_public_key if not specified.
- client_public_key, the client's public key.
- ke1, a KE1 message structure.

Output:
- auth_response, an AuthResponse structure.

def AuthServerRespond(server_identity, server_private_key, client_identity,
                      client_public_key, ke1, credential_response):
  server_nonce = random(Nn)
  (server_private_keyshare, server_keyshare) = GenerateAuthKeyPair()
  preamble = Preamble(client_identity,
                      ke1,
                      server_identity,
                      credential_response,
                      server_nonce,
                      server_keyshare)

  dh1 = SerializeElement(server_private_keyshare * ke1.auth_request.client_keyshare)
  dh2 = SerializeElement(server_private_key * ke1.auth_request.client_keyshare)
  dh3 = SerializeElement(server_private_keyshare * client_public_key)
  ikm = concat(dh1, dh2, dh3)

  Km2, Km3, session_key = DeriveKeys(ikm, preamble)
  server_mac = MAC(Km2, Hash(preamble))
  expected_client_mac = MAC(Km3, Hash(concat(preamble, server_mac))

  state.expected_client_mac = MAC(Km3, Hash(concat(preamble, server_mac))
  state.session_key = session_key
  Create AuthResponse auth_response with (server_nonce, server_keyshare, server_mac)
  return auth_response
]]></artwork>
          <t>The <tt>AuthServerFinalize</tt> function is used by the server to process the client's
<tt>KE3</tt> message and output the final <tt>session_key</tt>.</t>
          <artwork><![CDATA[
AuthServerFinalize

State:
- state, a ServerAkeState structure.

Input:
- ke3, a KE3 structure.

Output:
- session_key, the shared session secret if and only if ke3 is valid.

Exceptions:
- ClientAuthenticationError, the handshake fails.

def AuthServerFinalize(ke3):
  if !ct_equal(ke3.client_mac, state.expected_client_mac):
    raise ClientAuthenticationError
  return state.session_key
]]></artwork>
        </section>
      </section>
    </section>
    <section anchor="configurations">
      <name>Configurations</name>
      <t>An OPAQUE-3DH configuration is a tuple (OPRF, KDF, MAC, Hash, KSF, Group, Context)
such that the following conditions are met:</t>
      <ul spacing="normal">
        <li>The OPRF protocol uses the "base mode" variant of <xref target="OPRF"/> and implements
the interface in <xref target="dependencies"/>. Examples include OPRF(ristretto255, SHA-512) and
OPRF(P-256, SHA-256).</li>
        <li>The KDF, MAC, and Hash functions implement the interfaces in <xref target="dependencies"/>.
Examples include HKDF <xref target="RFC5869"/> for the KDF, HMAC <xref target="RFC2104"/> for the MAC,
and SHA-256 and SHA-512 for the Hash functions. If an extensible output function
such as SHAKE128 <xref target="FIPS202"/> is used then the output length <tt>Nh</tt> MUST be chosen
to align with the target security level of the OPAQUE configuration. For example,
if the target security parameter for the configuration is 128-bits, then <tt>Nh</tt> SHOULD be at least 32 bytes.</li>
        <li>The KSF has fixed parameters, chosen by the application, and implements the
interface in <xref target="dependencies"/>. Examples include Argon2 <xref target="ARGON2"/>,
scrypt <xref target="SCRYPT"/>, and PBKDF2 <xref target="PBKDF2"/> with fixed parameter choices.</li>
        <li>The Group mode identifies the group used in the OPAQUE-3DH AKE. This SHOULD
match that of the OPRF. For example, if the OPRF is OPRF(ristretto255, SHA-512),
then Group SHOULD be ristretto255.</li>
      </ul>
      <t>Context is the shared parameter used to construct the preamble in <xref target="transcript-functions"/>.
This parameter SHOULD include any application-specific configuration information or
parameters that are needed to prevent cross-protocol or downgrade attacks.</t>
      <t>Absent an application-specific profile, the following configurations are RECOMMENDED:</t>
      <ul spacing="normal">
        <li>OPRF(ristretto255, SHA-512), HKDF-SHA-512, HMAC-SHA-512, SHA-512, Scrypt(32768,8,1), internal, ristretto255</li>
        <li>OPRF(P-256, SHA-256), HKDF-SHA-256, HMAC-SHA-256, SHA-256, Scrypt(32768,8,1), internal, P-256</li>
      </ul>
      <t>Future configurations may specify different combinations of dependent algorithms,
with the following considerations:</t>
      <ol spacing="normal" type="1"><li>The size of AKE public and private keys -- <tt>Npk</tt> and <tt>Nsk</tt>, respectively -- must adhere
to the output length limitations of the KDF Expand function. If HKDF is used, this means
Npk, Nsk &lt;= 255 * Nx, where Nx is the output size of the underlying hash function.
See <xref target="RFC5869"/> for details.</li>
        <li>The output size of the Hash function SHOULD be long enough to produce a key for
MAC of suitable length. For example, if MAC is HMAC-SHA256, then <tt>Nh</tt> could be
32 bytes.</li>
      </ol>
    </section>
    <section anchor="app-considerations">
      <name>Application Considerations</name>
      <t>Beyond choosing an appropriate configuration, there are several parameters which
applications can use to control OPAQUE:</t>
      <ul spacing="normal">
        <li>Credential identifier: As described in <xref target="offline-phase"/>, this is a unique
handle to the client's credential being stored. In applications where there are alternate
client identities that accompany an account, such as a username or email address, this
identifier can be set to those alternate values. For simplicity, applications may choose
to set <tt>credential_identifier</tt> to be equal to <tt>client_identity</tt>. Applications
MUST NOT use the same credential identifier for multiple clients.</li>
        <li>Context information: As described in <xref target="configurations"/>, applications may include
a shared context string that is authenticated as part of the handshake. This parameter
SHOULD include any configuration information or parameters that are needed to prevent
cross-protocol or downgrade attacks. This context information is not sent over the
wire in any key exchange messages. However, applications may choose to send it alongside
key exchange messages if needed for their use case.</li>
        <li>Client and server identities: As described in <xref target="client-material"/>, clients
and servers are identified with their public keys by default. However, applications
may choose alternate identities that are pinned to these public keys. For example,
servers may use a domain name instead of a public key as their identifier. Absent
alternate notions of identity, applications SHOULD set these identities to nil
and rely solely on public key information.</li>
        <li>Enumeration prevention: As described in <xref target="create-credential-response"/>, if servers
receive a credential request for a non-existent client, they SHOULD respond with a
"fake" response to prevent active client enumeration attacks. Servers that
implement this mitigation SHOULD use the same configuration information (such as
the oprf_seed) for all clients; see <xref target="preventing-client-enumeration"/>. In settings
where this attack is not a concern, servers may choose to not support this functionality.</li>
      </ul>
    </section>
    <section anchor="implementation-considerations">
      <name>Implementation Considerations</name>
      <t>This section documents considerations for OPAQUE implementations. This includes
implementation safeguards and error handling considerations.</t>
      <section anchor="implementation-safeguards">
        <name>Implementation Safeguards</name>
        <t>Certain information created, exchanged, and processed in OPAQUE is sensitive.
Specifically, all private key material and intermediate values, along with the
outputs of the key exchange phase, are all secret. Implementations should not
retain these values in memory when no longer needed. Moreover, all operations,
particularly the cryptographic and group arithmetic operations, should be
constant-time and independent of the bits of any secrets. This includes any
conditional branching during the creation of the credential response, as needed
to mitigate client enumeration attacks.</t>
        <t>As specified in <xref target="offline-phase"/> and <xref target="online-phase"/>, OPAQUE only requires
the client password as input to the OPRF for registration and authentication.
However, implementations can incorporate the client identity alongside the
password as input to the OPRF. This provides additional client-side entropy
which can supplement the entropy that should be introduced by the server during
an honest execution of the protocol. This also provides domain separation
between different clients that might otherwise share the same password.</t>
        <t>Finally, note that online guessing attacks (against any aPAKE) can be done from
both the client side and the server side. In particular, a malicious server can
attempt to simulate honest responses to learn the client's password.
Implementations and deployments of OPAQUE SHOULD consider additional checks to
mitigate this type of attack: for instance, by ensuring that there is a
server-authenticated channel over which OPAQUE registration and login are run.</t>
      </section>
      <section anchor="error-considerations">
        <name>Error Considerations</name>
        <t>Some functions included in this specification are fallible. For example, the
authenticated key exchange protocol may fail because the client's password was
incorrect or the authentication check failed, yielding an error. The explicit
errors generated throughout this specification, along with conditions that lead
to each error, are as follows:</t>
        <ul spacing="normal">
          <li>EnvelopeRecoveryError: The envelope Recover function failed to produce any
authentication key material; <xref target="envelope-recovery"/>.</li>
          <li>ServerAuthenticationError: The client failed to complete the authenticated
key exchange protocol with the server; <xref target="ake-client"/>.</li>
          <li>ClientAuthenticationError: The server failed to complete the authenticated
key exchange protocol with the client; <xref target="ake-server"/>.</li>
        </ul>
        <t>Beyond these explicit errors, OPAQUE implementations can produce implicit errors.
For example, if protocol messages sent between client and server do not match
their expected size, an implementation should produce an error. More generally,
if any protocol message received from the peer is invalid, perhaps because the
message contains an invalid public key (indicated by the AKE DeserializeElement
function failing) or an invalid OPRF element (indicated by the OPRF DeserializeElement),
then an implementation should produce an error.</t>
        <t>The errors in this document are meant as a guide for implementors. They are not an
exhaustive list of all the errors an implementation might emit. For example, an
implementation might run out of memory.</t>
        <!--
TODO(caw): As part of https://github.com/cfrg/draft-irtf-cfrg-opaque/issues/312, address
the failure case that occurs when Blind fails, noting that this is an exceptional case that
happens with negligible probability
-->

</section>
    </section>
    <section anchor="security-considerations">
      <name>Security Considerations</name>
      <t>OPAQUE is defined as the composition of two functionalities: an OPRF and
an AKE protocol. It can be seen as a "compiler" for transforming any AKE
protocol (with KCI security and forward secrecy; see below)
into a secure aPAKE protocol. In OPAQUE, the client stores a secret private key at the
server during password registration and retrieves this key each time
it needs to authenticate to the server. The OPRF security properties
ensure that only the correct password can unlock the private key
while at the same time avoiding potential offline guessing attacks.
This general composability property provides great flexibility and
enables a variety of OPAQUE instantiations, from optimized
performance to integration with existing authenticated key exchange
protocols such as TLS.</t>
      <section anchor="notable-design-differences">
        <name>Notable Design Differences</name>
        <t>[[RFC EDITOR: Please delete this section before publication.]]</t>
        <t>The specification as written here differs from the original cryptographic design in <xref target="JKX18"/>
and the corresponding CFRG document <xref target="I-D.krawczyk-cfrg-opaque-03"/>, both of which were used
as input to the CFRG PAKE competition. This section describes these differences, including
their motivation and explanation as to why they preserve the provable security of OPAQUE based
on <xref target="JKX18"/>.</t>
        <t>The following list enumerates important functional differences that were made
as part of the protocol specification process to address application or
implementation considerations.</t>
        <ul spacing="normal">
          <li>Clients construct envelope contents without revealing the password to the
server, as described in <xref target="offline-phase"/>, whereas the servers construct
envelopes in <xref target="JKX18"/>. This change adds to the security of the protocol.
<xref target="JKX18"/> considered the case where the envelope was constructed by the
server for reasons of compatibility with previous UC modeling. An upcoming
paper analyzes the registration phase as specified in this document. This
change was made to support registration flows where the client chooses the
password and wishes to keep it secret from the server, and it is compatible
with the variant in <xref target="JKX18"/> that was originally analyzed.</li>
          <li>Envelopes do not contain encrypted credentials. Instead, envelopes contain
information used to derive client private key material for the AKE. This
variant is also analyzed in the new paper referred to in the previous item.
This change improves the assumption behind the protocol by getting rid of
equivocality and random key robustness for the encryption function. The
latter property is only required for authentication and achieved by a
collision-resistant MAC. This change was made for two reasons. First, it
reduces the number of bytes stored in envelopes, which is a helpful
improvement for large applications of OPAQUE with many registered users.
Second, it removes the need for client applications to generate authentication
keys during registration. Instead, this responsibility is handled by OPAQUE,
thereby simplifying the client interface to the protocol.</li>
          <li>Envelopes are masked with a per-user masking key as a way of preventing
client enumeration attacks. See <xref target="preventing-client-enumeration"/> for more
details. This extension is not needed for the security of OPAQUE as an aPAKE
but only used to provide a defense against enumeration attacks. In the
analysis, the masking key can be simulated as a (pseudo) random key. This
change was made to support real-world use cases where client or user
enumeration is a security (or privacy) risk.</li>
          <li>Per-user OPRF keys are derived from a client identity and cross-user PRF seed
as a mitigation against client enumeration attacks. See
<xref target="preventing-client-enumeration"/> for more details. The analysis of OPAQUE
assumes OPRF keys of different users are independently random or
pseudorandom. Deriving these keys via a single PRF (i.e., with a single
cross-user key) applied to users' identities satisfies this assumption.
This change was made to support real-world use cases where client or user
enumeration is a security (or privacy) risk.</li>
          <li>The protocol outputs an export key for the client in addition to a shared
session key that can be used for application-specific purposes. This key
is a pseudorandom value independent of other values in the protocol and
has no influence on the security analysis (it can be simulated with a
random output). This change was made to support more application use cases
for OPAQUE, such as the use of OPAQUE for end-to-end encrypted backups;
see <xref target="WhatsAppE2E"/>.</li>
          <li>The protocol admits optional application-layer client and server identities.
In the absence of these identities, the client and server are authenticated
against their public keys. Binding authentication to identities is part
of the AKE part of OPAQUE. The type of identities and their semantics
are application dependent and independent of the protocol analysis. This
change was made to simplify client and server interfaces to the protocol
by removing the need to specify additional identities alongside their
corresponding public authentication keys when not needed.</li>
          <li>The protocol admits application-specific context information configured
out-of-band in the AKE transcript. This allows domain separation between
different application uses of OPAQUE. This is a mechanism for the AKE
component and is best practice for domain separation between different
applications of the protocol. This change was made to allow different
applications to use OPAQUE without the risk of cross-protocol attacks.</li>
          <li>Servers use a separate identifier for computing OPRF evaluations and
indexing into the password file storage, called the credential_identifier.
This allows clients to change their application-layer identity
(client_identity) without inducing server-side changes, e.g., by changing
an email address associated with a given account. This mechanism is part
of the derivation of OPRF keys via a single PRF. As long as the derivation
of different OPRF keys from a single OPRF has different PRF inputs, the
protocol is secure. The choice of such inputs is up to the application.</li>
        </ul>
        <t>The following list enumerates notable differences and refinements from the original
cryptographic design in <xref target="JKX18"/> and the corresponding CFRG document
<xref target="I-D.krawczyk-cfrg-opaque-03"/> that were made to make this specification
suitable for interoperable implementations.</t>
        <ul spacing="normal">
          <li>
            <xref target="JKX18"/> used a generic prime-order group for the DH-OPRF and HMQV operations,
and includes necessary prime-order subgroup checks when receiving attacker-controlled
values over the wire. This specification instantiates the prime-order group used for
3DH using prime-order groups based on elliptic curves, as described in
<xref section="2.1" sectionFormat="comma" target="I-D.irtf-cfrg-voprf"/>. This specification also delegates OPRF group
choice and operations to <xref target="I-D.irtf-cfrg-voprf"/>. As such, the prime-order group as used
in the OPRF and 3DH as specified in this document both adhere to the requirements as
<xref target="JKX18"/>.</li>
          <li>
            <xref target="JKX18"/> specified DH-OPRF (see Appendix B) to instantiate
the OPRF functionality in the protocol. A critical part of DH-OPRF is the
hash-to-group operation, which was not instantiated in the original analysis.
However, the requirements for this operation were included. This specification
instantiates the OPRF functionality based on the <xref target="I-D.irtf-cfrg-voprf"/>, which
is identical to the DH-OPRF functionality in <xref target="JKX18"/> and, concretely, uses
the hash-to-curve functions in <xref target="I-D.irtf-cfrg-hash-to-curve"/>. All hash-to-curve
methods in <xref target="I-D.irtf-cfrg-hash-to-curve"/> are compliant with the requirement
in <xref target="JKX18"/>, namely, that the output be a member of the prime-order group.</li>
          <li>
            <xref target="JKX18"/> and <xref target="I-D.krawczyk-cfrg-opaque-03"/> both used HMQV as the AKE
for the protocol. However, this document fully specifies 3DH instead of HMQV
(though a sketch for how to instantiate OPAQUE using HMQV is included in <xref target="hmqv-sketch"/>).
Since 3DH satisfies the essential requirements for the AKE as described in <xref target="JKX18"/>
and <xref target="I-D.krawczyk-cfrg-opaque-03"/>, as recalled in <xref target="security-analysis"/>, this change
preserves the overall security of the protocol. 3DH was chosen for its
simplicity and ease of implementation.</li>
          <li>The DH-OPRF and HMQV instantiation of OPAQUE in <xref target="JKX18"/>, Figure 12 uses
a different transcript than that which is described in this specification. In particular,
the key exchange transcript specified in <xref target="ake-protocol"/> is a superset of the transcript
as defined in <xref target="JKX18"/>. This was done to align with best practices, such as is
done for key exchange protocols like TLS 1.3 <xref target="RFC8446"/>.</li>
          <li>Neither <xref target="JKX18"/> nor <xref target="I-D.krawczyk-cfrg-opaque-03"/> included wire format details for the
protocol, which is essential for interoperability. This specification fills this
gap by including such wire format details and corresponding test vectors; see <xref target="test-vectors"/>.</li>
        </ul>
      </section>
      <section anchor="security-analysis">
        <name>Security Analysis</name>
        <t>Jarecki et al. <xref target="JKX18"/> proved the security of OPAQUE
in a strong aPAKE model that ensures security against pre-computation attacks
and is formulated in the Universal Composability (UC) framework <xref target="Canetti01"/>
under the random oracle model. This assumes security of the OPRF
function and the underlying key exchange protocol. In turn, the
security of the OPRF protocol from <xref target="OPRF"/> is proven
in the random oracle model under the One-More Diffie-Hellman assumption <xref target="JKKX16"/>.</t>
        <t>OPAQUE's design builds on a line of work initiated in the seminal
paper of Ford and Kaliski <xref target="FK00"/> and is based on the HPAKE protocol
of Xavier Boyen <xref target="Boyen09"/> and the (1,1)-PPSS protocol from Jarecki
et al. <xref target="JKKX16"/>. None of these papers considered security against
pre-computation attacks or presented a proof of aPAKE security
(not even in a weak model).</t>
        <t>The KCI property required from AKE protocols for use with OPAQUE
states that knowledge of a party's private key does not allow an attacker
to impersonate others to that party. This is an important security
property achieved by most public-key based AKE protocols, including
protocols that use signatures or public key encryption for
authentication. It is also a property of many implicitly
authenticated protocols, e.g., HMQV, but not all of them. We also note that
key exchange protocols based on shared keys do not satisfy the KCI
requirement, hence they are not considered in the OPAQUE setting.
We note that KCI is needed to ensure a crucial property of OPAQUE: even upon
compromise of the server, the attacker cannot impersonate the client to the
server without first running an exhaustive dictionary attack.
Another essential requirement from AKE protocols for use in OPAQUE is to
provide forward secrecy (against active attackers).</t>
      </section>
      <section anchor="related-protocols">
        <name>Related Protocols</name>
        <t>Despite the existence of multiple designs for (PKI-free) aPAKE protocols,
none of these protocols are secure against pre-computation attacks.
This includes protocols that have recent analyses in the UC model such
as AuCPace <xref target="AuCPace"/> and SPAKE2+ <xref target="SPAKE2plus"/>. In particular, none
of these protocols can use the standard technique against pre-computation
that combines secret random values ("salt") into the one-way password mappings.
Either these protocols do not use a salt at all or, if they do, they
transmit the salt from server to client in the clear, hence losing the
secrecy of the salt and its defense against pre-computation.</t>
        <t>We note that as shown in <xref target="JKX18"/>, these protocols, and any aPAKE
in the model from <xref target="GMR06"/>, can be converted into an aPAKE secure against
pre-computation attacks at the expense of an additional OPRF execution.</t>
        <t>Beyond AuCPace and SPAKE2+, the most widely deployed PKI-free aPAKE is SRP <xref target="RFC2945"/>,
which is vulnerable to pre-computation attacks, lacks proof of security, and is
less efficient than OPAQUE. Moreover, SRP requires a ring as it mixes addition and
multiplication operations, and thus does not work over standard elliptic curves.
OPAQUE is therefore a suitable replacement for applications that use SRP.</t>
      </section>
      <section anchor="identities">
        <name>Identities</name>
        <t>AKE protocols generate keys that need to be uniquely and verifiably bound to a pair
of identities. In the case of OPAQUE, those identities correspond to client_identity and server_identity.
Thus, it is essential for the parties to agree on such identities, including an
agreed bit representation of these identities as needed.</t>
        <t>Applications may have different policies about how and when identities are
determined. A natural approach is to tie client_identity to the identity the server uses
to fetch the envelope (hence determined during password registration) and to tie server_identity
to the server identity used by the client to initiate an offline password
registration or online authenticated key exchange session. server_identity and client_identity can also
be part of the envelope or be tied to the parties' public keys. In principle, identities
may change across different sessions as long as there is a policy that
can establish if the identity is acceptable or not to the peer. However, we note
that the public keys of both the server and the client must always be those defined
at the time of password registration.</t>
        <t>The client identity (client_identity) and server identity (server_identity) are
optional parameters that are left to the application to designate as aliases for
the client and server. If the application layer does not supply values for these
parameters, then they will be omitted from the creation of the envelope
during the registration stage. Furthermore, they will be substituted with
client_identity = client_public_key and server_identity = server_public_key during
the authenticated key exchange stage.</t>
        <t>The advantage of supplying a custom client_identity and server_identity (instead of simply relying
on a fallback to client_public_key and server_public_key) is that the client can then ensure that any
mappings between client_identity and client_public_key (and server_identity and server_public_key)
are protected by the authentication from the envelope. Then, the client can verify that the
client_identity and server_identity contained in its envelope match the client_identity
and server_identity supplied by the server.</t>
        <t>However, if this extra layer of verification is unnecessary for the application, then simply
leaving client_identity and server_identity unspecified (and using client_public_key and
server_public_key instead) is acceptable.</t>
      </section>
      <section anchor="export-key-usage">
        <name>Export Key Usage</name>
        <t>The export key can be used (separately from the OPAQUE protocol) to provide
confidentiality and integrity to other data which only the client should be
able to process. For instance, if the server is expected to maintain any
client-side secrets which require a password to access, then this export key
can be used to encrypt these secrets so that they remain hidden from the
server.</t>
      </section>
      <section anchor="static-diffie-hellman-oracles">
        <name>Static Diffie-Hellman Oracles</name>
        <t>While one can expect the practical security of the OPRF function (namely,
the hardness of computing the function without knowing the key) to be in the
order of computing discrete logarithms or solving Diffie-Hellman, Brown and
Gallant <xref target="BG04"/> and Cheon <xref target="Cheon06"/> show an attack that slightly improves
on generic attacks. For typical curves, the attack requires an infeasible
number of calls to the OPRF or results in insignificant security loss;
see <xref target="OPRF"/> for more information. For OPAQUE, these attacks
are particularly impractical as they translate into an infeasible number of
failed authentication attempts directed at individual users.</t>
      </section>
      <section anchor="validation">
        <name>Input Validation</name>
        <t>Both client and server MUST validate the other party's public key(s) used
for the execution of OPAQUE. This includes the keys shared during the
offline registration phase, as well as any keys shared during the online
key agreement phase. The validation procedure varies depending on the
type of key. For example, for OPAQUE instantiations
using 3DH with P-256, P-384, or P-521 as the underlying group, validation
is as specified in Section 5.6.2.3.4 of <xref target="keyagreement"/>. This includes
checking that the coordinates are in the correct range, that the point
is on the curve, and that the point is not the point at infinity.
Additionally, validation MUST ensure the Diffie-Hellman shared secret is
not the point at infinity.</t>
      </section>
      <section anchor="oprf-key-stretching">
        <name>OPRF Key Stretching</name>
        <t>Applying a key stretching function to the output of the OPRF greatly increases the cost of an offline
attack upon the compromise of the credential file at the server. Applications
SHOULD select parameters that balance cost and complexity. Note that in
OPAQUE, the key stretching function is executed by the client, as opposed to
the server. This means that applications must consider a tradeoff between the
performance of the protocol on clients (specifically low-end devices) and
protection against offline attacks after a server compromise.</t>
      </section>
      <section anchor="preventing-client-enumeration">
        <name>Client Enumeration</name>
        <t>Client enumeration refers to attacks where the attacker tries to learn
extra information about the behavior of clients that have registered with
the server. There are two types of attacks we consider:</t>
        <t>1) An attacker tries to learn whether a given client identity is registered
with a server, and
2) An attacker tries to learn whether a given client identity has recently
completed registration, re-registered (e.g. after a password change), or
changed its identity.</t>
        <t>OPAQUE prevents these attacks during the authentication flow. The first is
prevented by requiring servers to act with unregistered client identities in a
way that is indistinguishable from their behavior with existing registered clients.
Servers do this by simulating a fake CredentialResponse as specified in
<xref target="create-credential-response"/> for unregistered users, and also encrypting both
CredentialResponse using a masking key. In this way, real and fake CredentialResponse
messages are indistinguishable from one another.
Implementations must also take care to avoid side-channel leakage (e.g., timing
attacks) from helping differentiate these operations from a regular server
response. Note that this may introduce possible abuse vectors since the
server's cost of generating a CredentialResponse is less than that of the
client's cost of generating a CredentialRequest. Server implementations
may choose to forego the construction of a simulated credential response
message for an unregistered client if these client enumeration attacks can
be mitigated through other application-specific means or are otherwise not
applicable for their threat model.</t>
        <t>Preventing the second type of attack requires the server to supply a
credential_identifier value for a given client identity, consistently between
the registration response and credential response; see <xref target="create-reg-response"/>
and <xref target="create-credential-response"/>. Note that credential_identifier can be set
to client_identity for simplicity.</t>
        <t>In the event of a server compromise that results in a re-registration of
credentials for all compromised clients, the oprf_seed value MUST be resampled,
resulting in a change in the oprf_key value for each client. Although this
change can be detected by an adversary, it is only leaked upon password rotation
after the exposure of the credential files, and equally affects all registered
clients.</t>
        <t>Finally, applications must use the same key recovery mechanism when using this
prevention throughout their lifecycle. The envelope size may vary between
mechanisms, so a switch could then be detected.</t>
        <t>OPAQUE does not prevent either type of attack during the registration flow.
Servers necessarily react differently during the registration flow between
registered and unregistered clients. This allows an attacker to use the server's
response during registration as an oracle for whether a given client identity is
registered. Applications should mitigate against this type of attack by rate
limiting or otherwise restricting the registration flow.</t>
      </section>
      <section anchor="protecting-the-registration-masking-key">
        <name>Protecting the Registration Masking Key</name>
        <t>The user enumeration prevention method described in this documents uses a symmetric
encryption key generated by the client on registration that is sent to the server over
an authenticated channel, such as one provided by TLS <xref target="RFC8446"/>. In the event that this
channel is compromised, this encryption key could be leaked to an attacker.</t>
        <t>One mitigation against this threat is to additionally encrypt the <tt>RegistrationRecord</tt>
sent from client to server at the application layer using public key encryption, e.g.,
with HPKE <xref target="RFC9180"/>.
However, the details of this mechanism are out of scope
of this document.</t>
      </section>
      <section anchor="password-salt-and-storage-implications">
        <name>Password Salt and Storage Implications</name>
        <t>In OPAQUE, the OPRF key acts as the secret salt value that ensures the infeasibility
of pre-computation attacks. No extra salt value is needed. Also, clients never
disclose their passwords to the server, even during registration. Note that a corrupted
server can run an exhaustive offline dictionary attack to validate guesses for the client's
password; this is inevitable in any aPAKE protocol. (OPAQUE enables defense against such
offline dictionary attacks by distributing the server so that an offline attack is only
possible if all - or a minimal number of - servers are compromised <xref target="JKX18"/>.) Furthermore,
if the server does not sample this OPRF key with sufficiently high entropy, or if it is not
kept hidden from an adversary, then any derivatives from the client's password may also be
susceptible to an offline dictionary attack to recover the original password.</t>
        <t>Some applications may require learning the client's password for enforcing password
rules. Doing so invalidates this important security property of OPAQUE and is
NOT RECOMMENDED. Applications should move such checks to the client. Note that
limited checks at the server are possible to implement, e.g., detecting repeated
passwords.</t>
      </section>
      <section anchor="ake-private-key-storage">
        <name>AKE Private Key Storage</name>
        <t>Server implementations of OPAQUE do not need access to the raw AKE private key. They only require
the ability to compute shared secrets as specified in <xref target="key-schedule-functions"/>. Thus, applications
may store the server AKE private key in a Hardware Security Module (HSM) or
similar. Upon compromise of the OPRF seed and client envelopes, this would prevent an
attacker from using this data to mount a server spoofing attack. Supporting implementations
need to consider allowing separate AKE and OPRF algorithms in cases where the HSM is
incompatible with the OPRF algorithm.</t>
      </section>
    </section>
    <section anchor="iana-considerations">
      <name>IANA Considerations</name>
      <t>This document makes no IANA requests.</t>
    </section>
  </middle>
  <back>
    <references>
      <name>References</name>
      <references>
        <name>Normative References</name>
        <reference anchor="RFC2119">
          <front>
            <title>Key words for use in RFCs to Indicate Requirement Levels</title>
            <author fullname="S. Bradner" initials="S." surname="Bradner">
              <organization/>
            </author>
            <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">
              <organization/>
            </author>
            <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="RFC4086">
          <front>
            <title>Randomness Requirements for Security</title>
            <author fullname="D. Eastlake 3rd" initials="D." surname="Eastlake 3rd">
              <organization/>
            </author>
            <author fullname="J. Schiller" initials="J." surname="Schiller">
              <organization/>
            </author>
            <author fullname="S. Crocker" initials="S." surname="Crocker">
              <organization/>
            </author>
            <date month="June" year="2005"/>
            <abstract>
              <t>Security systems are built on strong cryptographic algorithms that foil pattern analysis attempts.  However, the security of these systems is dependent on generating secret quantities for passwords, cryptographic keys, and similar quantities.  The use of pseudo-random processes to generate secret quantities can result in pseudo-security. A sophisticated attacker may find it easier to reproduce the environment that produced the secret quantities and to search the resulting small set of possibilities than to locate the quantities in the whole of the potential number space.</t>
              <t>Choosing random quantities to foil a resourceful and motivated adversary is surprisingly difficult.  This document points out many pitfalls in using poor entropy sources or traditional pseudo-random number generation techniques for generating such quantities.  It recommends the use of truly random hardware techniques and shows that the existing hardware on many systems can be used for this purpose. It provides suggestions to ameliorate the problem when a hardware solution is not available, and it gives examples of how large such quantities need to be for some applications.  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="106"/>
          <seriesInfo name="RFC" value="4086"/>
          <seriesInfo name="DOI" value="10.17487/RFC4086"/>
        </reference>
        <reference anchor="OPRF">
          <front>
            <title>Oblivious Pseudorandom Functions (OPRFs) using Prime-Order Groups</title>
            <author fullname="Alex Davidson">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Armando Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Nick Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Christopher A. Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="6" month="July" year="2022"/>
            <abstract>
              <t>   An Oblivious Pseudorandom Function (OPRF) is a two-party protocol
   between client and server for computing the output of a Pseudorandom
   Function (PRF).  The server provides the PRF secret key, and the
   client provides the PRF input.  At the end of the protocol, the
   client learns the PRF output without learning anything about the PRF
   secret key, and the server learns neither the PRF input nor output.
   An OPRF can also satisfy a notion of 'verifiability', called a VOPRF.
   A VOPRF ensures clients can verify that the server used a specific
   private key during the execution of the protocol.  A VOPRF can also
   be partially-oblivious, called a POPRF.  A POPRF allows clients and
   servers to provide public input to the PRF computation.  This
   document specifies an OPRF, VOPRF, and POPRF instantiated within
   standard prime-order groups, including elliptic curves.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-voprf-11"/>
        </reference>
        <reference anchor="RFC2104">
          <front>
            <title>HMAC: Keyed-Hashing for Message Authentication</title>
            <author fullname="H. Krawczyk" initials="H." surname="Krawczyk">
              <organization/>
            </author>
            <author fullname="M. Bellare" initials="M." surname="Bellare">
              <organization/>
            </author>
            <author fullname="R. Canetti" initials="R." surname="Canetti">
              <organization/>
            </author>
            <date month="February" year="1997"/>
            <abstract>
              <t>This document describes HMAC, a mechanism for message authentication using cryptographic hash functions. HMAC can be used with any iterative cryptographic hash function, e.g., MD5, SHA-1, in combination with a secret shared key.  The cryptographic strength of HMAC depends on the properties of the underlying hash function.  This memo provides information for the Internet community.  This memo does not specify an Internet standard of any kind</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2104"/>
          <seriesInfo name="DOI" value="10.17487/RFC2104"/>
        </reference>
        <reference anchor="I-D.irtf-cfrg-voprf">
          <front>
            <title>Oblivious Pseudorandom Functions (OPRFs) using Prime-Order Groups</title>
            <author fullname="Alex Davidson">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Armando Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Nick Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Christopher A. Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="6" month="July" year="2022"/>
            <abstract>
              <t>   An Oblivious Pseudorandom Function (OPRF) is a two-party protocol
   between client and server for computing the output of a Pseudorandom
   Function (PRF).  The server provides the PRF secret key, and the
   client provides the PRF input.  At the end of the protocol, the
   client learns the PRF output without learning anything about the PRF
   secret key, and the server learns neither the PRF input nor output.
   An OPRF can also satisfy a notion of 'verifiability', called a VOPRF.
   A VOPRF ensures clients can verify that the server used a specific
   private key during the execution of the protocol.  A VOPRF can also
   be partially-oblivious, called a POPRF.  A POPRF allows clients and
   servers to provide public input to the PRF computation.  This
   document specifies an OPRF, VOPRF, and POPRF instantiated within
   standard prime-order groups, including elliptic curves.

              </t>
            </abstract>
          </front>
          <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-voprf-11"/>
        </reference>
      </references>
      <references>
        <name>Informative References</name>
        <reference anchor="I-D.krawczyk-cfrg-opaque-03" target="https://datatracker.ietf.org/doc/html/draft-krawczyk-cfrg-opaque-03">
          <front>
            <title>The OPAQUE Asymmetric PAKE Protocol</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="PAKE-Selection" target="https://github.com/cfrg/pake-selection">
          <front>
            <title>CFRG PAKE selection process repository</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="Boyen09">
          <front>
            <title>HPAKE: Password Authentication Secure against Cross-Site User Impersonation</title>
            <author initials="X." surname="Boyen" fullname="Xavier Boyen">
              <organization/>
            </author>
            <date year="2009"/>
          </front>
          <seriesInfo name="Cryptology and Network Security (CANS)" value=""/>
        </reference>
        <reference anchor="BG04">
          <front>
            <title>The static Diffie-Hellman problem</title>
            <author initials="D." surname="Brown" fullname="Daniel R. L. Brown">
              <organization/>
            </author>
            <author initials="R." surname="Galant" fullname="Robert P. Galant">
              <organization/>
            </author>
            <date year="2004"/>
          </front>
          <seriesInfo name="http://eprint.iacr.org/2004/306" value=""/>
        </reference>
        <reference anchor="Canetti01">
          <front>
            <title>Universally composable security: A new paradigm for cryptographic protocols</title>
            <author initials="R." surname="Canetti" fullname="Ran Canetti">
              <organization/>
            </author>
            <date year="2001"/>
          </front>
          <seriesInfo name="IEEE Symposium on Foundations of Computer Science (FOCS)" value=""/>
        </reference>
        <reference anchor="Cheon06">
          <front>
            <title>Security analysis of the strong Diffie-Hellman problem</title>
            <author initials="J. H." surname="Cheon" fullname="Jung Hee Cheon">
              <organization/>
            </author>
            <date year="2006"/>
          </front>
          <seriesInfo name="Euroctypt 2006" value=""/>
        </reference>
        <reference anchor="FK00">
          <front>
            <title>Server-assisted generation of a strong secret from a password</title>
            <author initials="W." surname="Ford" fullname="Warwick Ford">
              <organization/>
            </author>
            <author initials="B. S." surname="Kaliski, Jr" fullname="Burton S. Kaliski, Jr">
              <organization/>
            </author>
            <date year="2000"/>
          </front>
          <seriesInfo name="WETICE" value=""/>
        </reference>
        <reference anchor="FIPS202" target="https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.202.pdf">
          <front>
            <title>SHA-3 Standard: Permutation-Based Hash and Extendable-Output Functions</title>
            <author>
              <organization>National Institute of Standards and Technology (NIST)</organization>
            </author>
            <date year="2015" month="August"/>
          </front>
        </reference>
        <reference anchor="GMR06">
          <front>
            <title>A method for making password-based key exchange resilient to server compromise</title>
            <author initials="C." surname="Gentry" fullname="Craig Gentry">
              <organization/>
            </author>
            <author initials="P." surname="MacKenzie" fullname="Phil MacKenzie">
              <organization/>
            </author>
            <author initials="" surname="Z, Ramzan" fullname="Zulfikar Ramzan">
              <organization/>
            </author>
            <date year="2006"/>
          </front>
          <seriesInfo name="CRYPTO" value=""/>
        </reference>
        <reference anchor="AuCPace">
          <front>
            <title>AuCPace: Efficient verifier-based PAKE protocol tailored for the IIoT</title>
            <author initials="B." surname="Haase" fullname="Bjorn Haase">
              <organization/>
            </author>
            <author initials="B." surname="Labrique" fullname="Benoit Labrique">
              <organization/>
            </author>
            <date year="2018"/>
          </front>
          <seriesInfo name="http://eprint.iacr.org/2018/286" value=""/>
        </reference>
        <reference anchor="keyagreement">
          <front>
            <title>Recommendation for pair-wise key-establishment schemes using discrete logarithm cryptography</title>
            <author fullname="Elaine Barker" initials="E." surname="Barker">
              <organization/>
            </author>
            <author fullname="Lily Chen" initials="L." surname="Chen">
              <organization/>
            </author>
            <author fullname="Allen Roginsky" initials="A." surname="Roginsky">
              <organization/>
            </author>
            <author fullname="Apostol Vassilev" initials="A." surname="Vassilev">
              <organization/>
            </author>
            <author fullname="Richard Davis" initials="R." surname="Davis">
              <organization/>
            </author>
            <date month="April" year="2018"/>
          </front>
          <seriesInfo name="National Institute of Standards and Technology" value="report"/>
          <seriesInfo name="DOI" value="10.6028/nist.sp.800-56ar3"/>
        </reference>
        <reference anchor="JKX18">
          <front>
            <title>OPAQUE: An Asymmetric PAKE Protocol Secure Against Pre-Computation Attacks</title>
            <author initials="S." surname="Jarecki" fullname="Stanislaw Jarecki">
              <organization/>
            </author>
            <author initials="H." surname="Krawczyk" fullname="Hugo Krawczyk">
              <organization/>
            </author>
            <author initials="J." surname="Xu" fullname="Jiayu Xu">
              <organization/>
            </author>
            <date year="2018"/>
          </front>
          <seriesInfo name="Eurocrypt" value=""/>
        </reference>
        <reference anchor="JKKX16">
          <front>
            <title>Highly-efficient and composable password-protected secret sharing (or: how to protect your bitcoin wallet online)</title>
            <author initials="S." surname="Jarecki" fullname="Stanislaw Jarecki">
              <organization/>
            </author>
            <author initials="A." surname="Kiayias" fullname="Aggelos Kiayias">
              <organization/>
            </author>
            <author initials="H." surname="Krawczyk" fullname="Hugo Krawczyk">
              <organization/>
            </author>
            <author initials="J." surname="Xu" fullname="Jiayu Xu">
              <organization/>
            </author>
            <date year="2016"/>
          </front>
          <seriesInfo name="IEEE European Symposium on Security and Privacy" value=""/>
        </reference>
        <reference anchor="LGR20" target="https://eprint.iacr.org/2020/1491.pdf">
          <front>
            <title>Partitioning Oracle Attacks</title>
            <author initials="J." surname="Len" fullname="Julia Len">
              <organization/>
            </author>
            <author initials="P." surname="Grubbs" fullname="Paul Grubbs">
              <organization/>
            </author>
            <author initials="T." surname="Ristenpart" fullname="Thomas Ristenpart">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="HMQV">
          <front>
            <title>HMQV: A high-performance secure Diffie-Hellman protocol</title>
            <author initials="H." surname="Krawczyk" fullname="Hugo Krawczyk">
              <organization/>
            </author>
            <date year="2005"/>
          </front>
          <seriesInfo name="CRYPTO" value=""/>
        </reference>
        <reference anchor="SPAKE2plus">
          <front>
            <title>Security Analysis of SPAKE2+</title>
            <author initials="V." surname="Shoup" fullname="Victor Shoup">
              <organization/>
            </author>
            <date year="2020"/>
          </front>
          <seriesInfo name="http://eprint.iacr.org/2020/313" value=""/>
        </reference>
        <reference anchor="_3DH">
          <front>
            <title>Simplifying OTR deniability</title>
            <author>
              <organization/>
            </author>
            <date year="2016"/>
          </front>
          <seriesInfo name="https://signal.org/blog/simplifying-otr-deniability" value=""/>
        </reference>
        <reference anchor="WhatsAppE2E" target="https://www.whatsapp.com/security/WhatsApp_Security_Encrypted_Backups_Whitepaper.pdf">
          <front>
            <title>Security of End-to-End Encrypted Backups</title>
            <author>
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="RFC2945">
          <front>
            <title>The SRP Authentication and Key Exchange System</title>
            <author fullname="T. Wu" initials="T." surname="Wu">
              <organization/>
            </author>
            <date month="September" year="2000"/>
            <abstract>
              <t>This document describes a cryptographically strong network authentication mechanism known as the Secure Remote Password (SRP) protocol.  [STANDARDS-TRACK]</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2945"/>
          <seriesInfo name="DOI" value="10.17487/RFC2945"/>
        </reference>
        <reference anchor="RFC5869">
          <front>
            <title>HMAC-based Extract-and-Expand Key Derivation Function (HKDF)</title>
            <author fullname="H. Krawczyk" initials="H." surname="Krawczyk">
              <organization/>
            </author>
            <author fullname="P. Eronen" initials="P." surname="Eronen">
              <organization/>
            </author>
            <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="RFC8125">
          <front>
            <title>Requirements for Password-Authenticated Key Agreement (PAKE) Schemes</title>
            <author fullname="J. Schmidt" initials="J." surname="Schmidt">
              <organization/>
            </author>
            <date month="April" year="2017"/>
            <abstract>
              <t>Password-Authenticated Key Agreement (PAKE) schemes are interactive protocols that allow the participants to authenticate each other and derive shared cryptographic keys using a (weaker) shared password. This document reviews different types of PAKE schemes.  Furthermore, it presents requirements and gives recommendations to designers of new schemes.  It is a product of the Crypto Forum Research Group (CFRG).</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8125"/>
          <seriesInfo name="DOI" value="10.17487/RFC8125"/>
        </reference>
        <reference anchor="RFC8446">
          <front>
            <title>The Transport Layer Security (TLS) Protocol Version 1.3</title>
            <author fullname="E. Rescorla" initials="E." surname="Rescorla">
              <organization/>
            </author>
            <date month="August" year="2018"/>
            <abstract>
              <t>This document specifies version 1.3 of the Transport Layer Security (TLS) protocol.  TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.</t>
              <t>This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961.  This document also specifies new requirements for TLS 1.2 implementations.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="8446"/>
          <seriesInfo name="DOI" value="10.17487/RFC8446"/>
        </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">
              <organization/>
            </author>
            <author fullname="B. Kaliski" initials="B." surname="Kaliski">
              <organization/>
            </author>
            <author fullname="J. Jonsson" initials="J." surname="Jonsson">
              <organization/>
            </author>
            <author fullname="A. Rusch" initials="A." surname="Rusch">
              <organization/>
            </author>
            <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="ARGON2">
          <front>
            <title>Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications</title>
            <author fullname="A. Biryukov" initials="A." surname="Biryukov">
              <organization/>
            </author>
            <author fullname="D. Dinu" initials="D." surname="Dinu">
              <organization/>
            </author>
            <author fullname="D. Khovratovich" initials="D." surname="Khovratovich">
              <organization/>
            </author>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson">
              <organization/>
            </author>
            <date month="September" year="2021"/>
            <abstract>
              <t>This document describes the Argon2 memory-hard function for password hashing and proof-of-work applications.  We provide an implementer-oriented description with test vectors.  The purpose is to simplify adoption of Argon2 for Internet protocols.  This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9106"/>
          <seriesInfo name="DOI" value="10.17487/RFC9106"/>
        </reference>
        <reference anchor="SCRYPT">
          <front>
            <title>The scrypt Password-Based Key Derivation Function</title>
            <author fullname="C. Percival" initials="C." surname="Percival">
              <organization/>
            </author>
            <author fullname="S. Josefsson" initials="S." surname="Josefsson">
              <organization/>
            </author>
            <date month="August" year="2016"/>
            <abstract>
              <t>This document specifies the password-based key derivation function scrypt.  The function derives one or more secret keys from a secret string.  It is based on memory-hard functions, which offer added protection against attacks using custom hardware.  The document also provides an ASN.1 schema.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7914"/>
          <seriesInfo name="DOI" value="10.17487/RFC7914"/>
        </reference>
        <reference anchor="PBKDF2">
          <front>
            <title>PKCS #5: Password-Based Cryptography Specification Version 2.0</title>
            <author fullname="B. Kaliski" initials="B." surname="Kaliski">
              <organization/>
            </author>
            <date month="September" year="2000"/>
            <abstract>
              <t>This document provides recommendations for the implementation of password-based cryptography, covering key derivation functions, encryption schemes, message-authentication schemes, and ASN.1 syntax identifying the techniques.  This memo provides information for the Internet community.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="2898"/>
          <seriesInfo name="DOI" value="10.17487/RFC2898"/>
        </reference>
        <reference anchor="I-D.irtf-cfrg-hash-to-curve">
          <front>
            <title>Hashing to Elliptic Curves</title>
            <author fullname="Armando Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Sam Scott">
              <organization>Cornell Tech</organization>
            </author>
            <author fullname="Nick Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Riad S. Wahby">
              <organization>Stanford University</organization>
            </author>
            <author fullname="Christopher A. Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="15" month="June" year="2022"/>
            <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="Internet-Draft" value="draft-irtf-cfrg-hash-to-curve-16"/>
        </reference>
        <reference anchor="RFC9180">
          <front>
            <title>Hybrid Public Key Encryption</title>
            <author fullname="R. Barnes" initials="R." surname="Barnes">
              <organization/>
            </author>
            <author fullname="K. Bhargavan" initials="K." surname="Bhargavan">
              <organization/>
            </author>
            <author fullname="B. Lipp" initials="B." surname="Lipp">
              <organization/>
            </author>
            <author fullname="C. Wood" initials="C." surname="Wood">
              <organization/>
            </author>
            <date month="February" year="2022"/>
            <abstract>
              <t>This document describes a scheme for hybrid public key encryption (HPKE). This scheme provides a variant of public key encryption of arbitrary-sized plaintexts for a recipient public key. It also includes three authenticated variants, including one that authenticates possession of a pre-shared key and two optional ones that authenticate possession of a key encapsulation mechanism (KEM) private key. HPKE works for any combination of an asymmetric KEM, key derivation function (KDF), and authenticated encryption with additional data (AEAD) encryption function. Some authenticated variants may not be supported by all KEMs. We provide instantiations of the scheme using widely used and efficient primitives, such as Elliptic Curve Diffie-Hellman (ECDH) key agreement, HMAC-based key derivation function (HKDF), and SHA2.</t>
              <t>This document is a product of the Crypto Forum Research Group (CFRG) in the IRTF.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="9180"/>
          <seriesInfo name="DOI" value="10.17487/RFC9180"/>
        </reference>
      </references>
    </references>
    <section anchor="acknowledgments">
      <name>Acknowledgments</name>
      <t>The OPAQUE protocol and its analysis is the joint work of the author with Stanislaw
Jarecki and Jiayu Xu. We are indebted to the OPAQUE reviewers during CFRG's
aPAKE selection process, particularly Julia Hesse and Bjorn Tackmann.
This draft has benefited from comments by multiple people. Special thanks
to Richard Barnes, Dan Brown, Eric Crockett, Paul Grubbs, Fredrik Kuivinen,
Payman Mohassel, Jason Resch, Greg Rubin, and Nick Sullivan.</t>
    </section>
    <section anchor="alternate-key-recovery">
      <name>Alternate Key Recovery Mechanisms</name>
      <t>Client authentication material can be stored and retrieved using different key
recovery mechanisms. Any key recovery mechanism that encrypts data
in the envelope MUST use an authenticated encryption scheme with random
key-robustness (or key-committing). Deviating from the key-robustness
requirement may open the protocol to attacks, e.g., <xref target="LGR20"/>.
This specification enforces this property by using a MAC over the envelope
contents.</t>
      <t>We remark that export_key for authentication or encryption requires
no special properties from the authentication or encryption schemes
as long as export_key is used only after authentication material is successfully
recovered, i.e., after the MAC in RecoverCredentials passes verification.</t>
    </section>
    <section anchor="alternate-akes">
      <name>Alternate AKE Instantiations</name>
      <t>It is possible to instantiate OPAQUE with other AKEs, such as HMQV <xref target="HMQV"/> and SIGMA-I.
HMQV is similar to 3DH but varies in its key schedule. SIGMA-I uses digital signatures
rather than static DH keys for authentication. Specification of these instantiations is
left to future documents. A sketch of how these instantiations might change is included
in the next subsection for posterity.</t>
      <t>OPAQUE may also be instantiated with any post-quantum (PQ) AKE protocol that has the message
flow above and security properties (KCI resistance and forward secrecy) outlined
in <xref target="security-considerations"/>. Note that such an instantiation is not quantum-safe unless
the OPRF is quantum-safe. However, an OPAQUE instantiation where the AKE is quantum-safe,
but the OPRF is not, would still ensure the confidentiality of application data encrypted
under session_key (or a key derived from it) with a quantum-safe encryption function.</t>
      <section anchor="hmqv-sketch">
        <name>HMQV Instantiation Sketch</name>
        <t>An HMQV instantiation would work similar to OPAQUE-3DH, differing primarily in the key
schedule <xref target="HMQV"/>. First, the key schedule <tt>preamble</tt> value would use a different constant prefix
-- "HMQV" instead of "3DH" -- as shown below.</t>
        <artwork><![CDATA[
preamble = concat("HMQV",
                  I2OSP(len(client_identity), 2), client_identity,
                  KE1,
                  I2OSP(len(server_identity), 2), server_identity,
                  KE2.credential_response,
                  KE2.auth_response.server_nonce,
                  KE2.auth_response.server_keyshare)
]]></artwork>
        <t>Second, the IKM derivation would change. Assuming HMQV is instantiated with a cyclic
group of prime order p with bit length L, clients would compute <tt>IKM</tt> as follows:</t>
        <artwork><![CDATA[
u' = (eskU + u \* skU) mod p
IKM = (epkS \* pkS^s)^u'
]]></artwork>
        <t>Likewise, servers would compute <tt>IKM</tt> as follows:</t>
        <artwork><![CDATA[
s' = (eskS + s \* skS) mod p
IKM = (epkU \* pkU^u)^s'
]]></artwork>
        <t>In both cases, <tt>u</tt> would be computed as follows:</t>
        <artwork><![CDATA[
hashInput = concat(I2OSP(len(epkU), 2), epkU,
                   I2OSP(len(info), 2), info,
                   I2OSP(len("client"), 2), "client")
u = Hash(hashInput) mod L
]]></artwork>
        <t>Likewise, <tt>s</tt> would be computed as follows:</t>
        <artwork><![CDATA[
hashInput = concat(I2OSP(len(epkS), 2), epkS,
                   I2OSP(len(info), 2), info,
                   I2OSP(len("server"), 2), "server")
s = Hash(hashInput) mod L
]]></artwork>
        <t>Hash is the same hash function used in the main OPAQUE protocol for key derivation.
Its output length (in bits) must be at least L.</t>
      </section>
      <section anchor="sigma-i-instantiation-sketch">
        <name>SIGMA-I Instantiation Sketch</name>
        <t>A SIGMA-I instantiation differs more drastically from OPAQUE-3DH since authentication
uses digital signatures instead of Diffie Hellman. In particular, both KE2 and KE3
would carry a digital signature, computed using the server and client private keys
established during registration, respectively, as well as a MAC, where the MAC is
computed as in OPAQUE-3DH.</t>
        <t>The key schedule would also change. Specifically, the key schedule <tt>preamble</tt> value would
use a different constant prefix -- "SIGMA-I" instead of "3DH" -- and the <tt>IKM</tt> computation
would use only the ephemeral key shares exchanged between client and server.</t>
      </section>
    </section>
    <section anchor="test-vectors">
      <name>Test Vectors</name>
      <t>This section contains real and fake test vectors for the OPAQUE-3DH specification.
Each real test vector in <xref target="real-vectors"/> specifies the configuration information,
protocol inputs, intermediate values computed during registration and authentication,
and protocol outputs.</t>
      <t>Similarly, each fake test vector in <xref target="fake-vectors"/> specifies
the configuration information, protocol inputs, and protocol
outputs computed during the authentication of an unknown or unregistered user. Note that <tt>masking_key</tt>,
<tt>client_private_key</tt>, and <tt>client_public_key</tt> are used as additional inputs as described in
<xref target="create-credential-response"/>. <tt>client_public_key</tt> is used as the fake record's public key, and
<tt>masking_key</tt> for the fake record's masking key parameter.</t>
      <t>All values are encoded in hexadecimal strings. The configuration information
includes the (OPRF, Hash, KSF, KDF, MAC, Group, Context) tuple, where the Group
matches that which is used in the OPRF. These test vectors were generated using
draft-10 of <xref target="OPRF"/>.</t>
      <section anchor="real-vectors">
        <name>Real Test Vectors</name>
        <section anchor="opaque-3dh-real-test-vector-1">
          <name>OPAQUE-3DH Real Test Vector 1</name>
          <section anchor="configuration">
            <name>Configuration</name>
            <artwork><![CDATA[
OPRF: 0001
Hash: SHA512
KSF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: ristretto255
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values">
            <name>Input Values</name>
            <artwork><![CDATA[
oprf_seed: f433d0227b0b9dd54f7c4422b600e764e47fb503f1f9a0f0a47c6606b0
54a7fdc65347f1a08f277e22358bbabe26f823fca82c7848e9a75661f4ec5d5c1989e
f
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d2
3ba7a38dfec
masking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80
f612fdfc6d
server_private_key: 47451a85372f8b3537e249d7b54188091fb18edde78094b43
e2ba42b5eb89f0d
server_public_key: b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a
382c9b79df1a78
server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e
138e3d4a1
client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb38
0cae6a6cc
server_keyshare: c8c39f573135474c51660b02425bca633e339cec4e1acc69c94d
d48497fe4028
client_keyshare: 0c3a00c961fead8a16f818929cc976f0475e4f723519318b96f4
947a7a5f9663
server_private_keyshare: 2e842960258a95e28bcfef489cffd19d8ec99cc1375d
840f96936da7dbb0b40d
client_private_keyshare: 22c919134c9bdd9dc0c5ef3450f18b54820f43f646a9
5223bf4a85b2018c2001
blind_registration: 76cfbfe758db884bebb33582331ba9f159720ca8784a2a070
a265d9c2d6abe01
blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4
b0790308
]]></artwork>
          </section>
          <section anchor="intermediate-values">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 8e5e5c04b2154336fa52ac691eb6df5f59ec7315b8467b0bba
1ed4f413043b44
auth_key: e1ff65c196e1c4b4bf46361798eec479b318831329680f33b4f77ad49d8
c6e6ef49d87082d654d21f2e36454582353fefc23c07637bd8ca4aa88a4461ea96d6c
randomized_pwd: 4386bf4b83db06f47672fd60b4cface554558da7be3c616c56b2e
d29b544d1b50bc45893b1c05d8d6866a9bbe91395e4704740be58728e8872352f56d5
319f8f
envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a3
8dfec8e8bde8d4eb9e171240b3d2dfb43ef93efe5cd15412614b3df11ecb58890047e
2fa31c283e7c58c40495226cfa0ed7756e493431b85c464aad7fdaaf1ab41ac7
handshake_secret: 885a0a7bd8e704d8fc26f62b8657f8c5d01ffb35b27ad538493
968dcf6dba7a2d42d404d6ed6a87805a030ffafe791fb69fd044c1ac152ee0ee78853
cebb0700
server_mac_key: d29e33eb506fbf199c818d1300e7253404a7d5de9c660a90f79af
e4cc15da2ae31e511c6eb1c4df95f47c9759606732781a3d1884a4d53cba690bdb9e9
ac4d7c
client_mac_key: 4d4d4c4b8b35501876ed01d07f5718357ff720163b84813b1bde4
f3b6ca3e1de744a267e3d145e6095a0e5b1617714e10af7e10093d0ba8dd115e6bdb1
f5ccd9
oprf_key: 6c246eaa55e47d0490ffa8a6f784e803eed9384a250458def36a2acebf1
5c905
]]></artwork>
          </section>
          <section anchor="output-values">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 62235332ae15911d69812e9eeb6ac8fe4fa0ffc7590831d
5c5e1631e01049276
registration_response: 6268d13fea98ebc8e6b88d0b3cc8a78d2ac8fa8efc741c
d2e966940c52c31c71b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a3
82c9b79df1a78
registration_upload: 8e5e5c04b2154336fa52ac691eb6df5f59ec7315b8467b0b
ba1ed4f413043b449afea0ddedbbce5c083c5d5d02aa5218bcc7100f541d841bb5974
f084f7aa0b929399feb39efd17e13ce1035cbb23251da3b5126a574b239c7b73519d8
847e2fac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfe
c8e8bde8d4eb9e171240b3d2dfb43ef93efe5cd15412614b3df11ecb58890047e2fa3
1c283e7c58c40495226cfa0ed7756e493431b85c464aad7fdaaf1ab41ac7
KE1: 1670c409ebb699a6012629451d218d42a34eddba1d2978536c45e199c60a0b4e
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc0c3a0
0c961fead8a16f818929cc976f0475e4f723519318b96f4947a7a5f9663
KE2: 36b4d06f413b72004392d7359cd6a998c667533203d6a671afe81ca09a282f72
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d378cc
6b0113bf0b6afd9e0728e62ba793d5d25bb97794c154d036bf09c98c472368bffc4e3
5b7dc48f5a32dd3fede3b9e563f7a170d0e082d02c0a105cdf1ee0ea1928202076ff3
7ce174f2c669d52d8adc424e925a3bc9a4ca5ce16d9b7a1791ff7e47a0d2fa42424e5
476f8cfa7bb20b2796ad877295a996ffcb049313f4e971cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a1c8c39f573135474c51660b02425bca
633e339cec4e1acc69c94dd48497fe402848f3b062916ea7666973222944dabe1027e
5bea84b1b5d46dab64b1c6eda3170d4c9adba8afa61eb4153061d528b39102f32ecda
7d7625dbc229e6630a607e03
KE3: 4e23f0f84a5261918a7fc23bf1978a935cf4e320d56984079f8c7f4a54847b9e
979f519928c5898927cf6aa8d51ac42dc2d0f5840956caa3a34dbc55ce74415f
export_key: 403a270110164ae0de7ea77c6824343211e8c1663ccaedde908dc9acf
661039a379c8ac7e4b0cb23a8d1375ae94a772f91536de131d9d86633cb9445f773df
ac
session_key: d2dea308255aa3cecf72bcd6ac96ff7ab2e8bad0494b90180ad340b7
d8942a36ee358e76c372790d4a5c1ac900997ea2abbf35f2d65510f8dfd668e593b8e
1fe
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-real-test-vector-2">
          <name>OPAQUE-3DH Real Test Vector 2</name>
          <section anchor="configuration-1">
            <name>Configuration</name>
            <artwork><![CDATA[
OPRF: 0001
Hash: SHA512
KSF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: ristretto255
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-1">
            <name>Input Values</name>
            <artwork><![CDATA[
client_identity: 616c696365
server_identity: 626f62
oprf_seed: f433d0227b0b9dd54f7c4422b600e764e47fb503f1f9a0f0a47c6606b0
54a7fdc65347f1a08f277e22358bbabe26f823fca82c7848e9a75661f4ec5d5c1989e
f
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d2
3ba7a38dfec
masking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80
f612fdfc6d
server_private_key: 47451a85372f8b3537e249d7b54188091fb18edde78094b43
e2ba42b5eb89f0d
server_public_key: b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a
382c9b79df1a78
server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e
138e3d4a1
client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb38
0cae6a6cc
server_keyshare: c8c39f573135474c51660b02425bca633e339cec4e1acc69c94d
d48497fe4028
client_keyshare: 0c3a00c961fead8a16f818929cc976f0475e4f723519318b96f4
947a7a5f9663
server_private_keyshare: 2e842960258a95e28bcfef489cffd19d8ec99cc1375d
840f96936da7dbb0b40d
client_private_keyshare: 22c919134c9bdd9dc0c5ef3450f18b54820f43f646a9
5223bf4a85b2018c2001
blind_registration: 76cfbfe758db884bebb33582331ba9f159720ca8784a2a070
a265d9c2d6abe01
blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4
b0790308
]]></artwork>
          </section>
          <section anchor="intermediate-values-1">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 8e5e5c04b2154336fa52ac691eb6df5f59ec7315b8467b0bba
1ed4f413043b44
auth_key: e1ff65c196e1c4b4bf46361798eec479b318831329680f33b4f77ad49d8
c6e6ef49d87082d654d21f2e36454582353fefc23c07637bd8ca4aa88a4461ea96d6c
randomized_pwd: 4386bf4b83db06f47672fd60b4cface554558da7be3c616c56b2e
d29b544d1b50bc45893b1c05d8d6866a9bbe91395e4704740be58728e8872352f56d5
319f8f
envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a3
8dfec43084457c1ffa561c8f37fbad1b8de6c41e6df200e6ebe15d5ce4243fa973ef3
e480644e56a6de865cc4d3d9e20e0510e63474e2b11f4b4c8f665cc439cc2d7d
handshake_secret: 19d0d9f286f44f573dd61435690b0359c3a70e5c363ba4819ac
fa113b0ddeab603f322185812ddcdd2abbfba77933cd5c3430ea6591e99c30a19884a
80d25dab
server_mac_key: 5096c1f1b295521bc8c5aeba462fc11e123eb710899f164dab737
45f55f42b27a31f810efb06fc56890f3635a18f3f8c9ef7881f32a251a5f5a7354c82
70f257
client_mac_key: 1c284c2a22bfb415a5091c94726dd02ae9adb12d28db5207a87be
0c3f75c1c37df549315f51e0dd2053271a477a45bf0adbc246f7f7e47e201785b6429
e93a84
oprf_key: 6c246eaa55e47d0490ffa8a6f784e803eed9384a250458def36a2acebf1
5c905
]]></artwork>
          </section>
          <section anchor="output-values-1">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 62235332ae15911d69812e9eeb6ac8fe4fa0ffc7590831d
5c5e1631e01049276
registration_response: 6268d13fea98ebc8e6b88d0b3cc8a78d2ac8fa8efc741c
d2e966940c52c31c71b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a3
82c9b79df1a78
registration_upload: 8e5e5c04b2154336fa52ac691eb6df5f59ec7315b8467b0b
ba1ed4f413043b449afea0ddedbbce5c083c5d5d02aa5218bcc7100f541d841bb5974
f084f7aa0b929399feb39efd17e13ce1035cbb23251da3b5126a574b239c7b73519d8
847e2fac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfe
c43084457c1ffa561c8f37fbad1b8de6c41e6df200e6ebe15d5ce4243fa973ef3e480
644e56a6de865cc4d3d9e20e0510e63474e2b11f4b4c8f665cc439cc2d7d
KE1: 1670c409ebb699a6012629451d218d42a34eddba1d2978536c45e199c60a0b4e
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc0c3a0
0c961fead8a16f818929cc976f0475e4f723519318b96f4947a7a5f9663
KE2: 36b4d06f413b72004392d7359cd6a998c667533203d6a671afe81ca09a282f72
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d378cc
6b0113bf0b6afd9e0728e62ba793d5d25bb97794c154d036bf09c98c472368bffc4e3
5b7dc48f5a32dd3fede3b9e563f7a170d0e082d02c0a105cdf1ee0279ab2faaf30bb2
722ef0dbb4c66632703c736dc6aeb163c467a60e0abb09bf4d4d49c1c65f522667cb4
b6da94faa9d7835ad67e8e3198afb4e64d6fb06bc35371cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a1c8c39f573135474c51660b02425bca
633e339cec4e1acc69c94dd48497fe4028dfe19d6cf6d292ae99a497f9ba41702a194
5f5d9f3ab60ea801b5a691098c7af74956a5e1324322877b6d399583670e54dc90752
5235fd47c8e396fab340beed
KE3: 824fe89731cd47062819165662cd1c42c4b2d2321bd062e637fdd0361b0dad03
02bd5e9a9d02c72452dc65298bf330071e061b8bb4e1c8762a350d99c8c003ac
export_key: 403a270110164ae0de7ea77c6824343211e8c1663ccaedde908dc9acf
661039a379c8ac7e4b0cb23a8d1375ae94a772f91536de131d9d86633cb9445f773df
ac
session_key: 5ea9a76f5f5cc59ba7871012836947c946f8c303cc94e048cdc83ada
c89db7187cf5c718ffdd7cb6d8c3005dc0f77814d5f26011b584f9622c649a357cb17
a4c
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-real-test-vector-3">
          <name>OPAQUE-3DH Real Test Vector 3</name>
          <section anchor="configuration-2">
            <name>Configuration</name>
            <artwork><![CDATA[
OPRF: 0003
Hash: SHA256
KSF: Identity
KDF: HKDF-SHA256
MAC: HMAC-SHA256
Group: P256_XMD:SHA-256_SSWU_RO_
Context: 4f50415155452d504f43
Nh: 32
Npk: 33
Nsk: 32
Nm: 32
Nx: 32
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-2">
            <name>Input Values</name>
            <artwork><![CDATA[
oprf_seed: 62f60b286d20ce4fd1d64809b0021dad6ed5d52a2c8cf27ae6582543a0
a8dce2
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebd
cf65670e51f
masking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80
f612fdfc6d
server_private_key: c36139381df63bfc91c850db0b9cfbec7a62e86d80040a41a
a7725bf0e79d5e5
server_public_key: 035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd9
f2092d6067784874
server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e
138e3d4a1
client_nonce: ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f
91fdaeeb1
server_keyshare: 020e67941e94deba835214421d2d8c90de9b0f7f925d11e2032c
e19b1832ae8e0f
client_keyshare: 03493f36ca12467d1f5eaaabea67ca31377c4869c1e9a62346b6
f01a991624b95d
server_private_keyshare: 9addab838c920fa7044f3a46b91ecaea24b0e7203992
8ee7d4c37a5b9bc17349
client_private_keyshare: 89d5a7e18567f255748a86beac13913df755a5adf776
d69e143147b545d22134
blind_registration: 411bf1a62d119afe30df682b91a0a33d777972d4f2daa4b34
ca527d597078153
blind_login: c497fddf6056d241e6cf9fb7ac37c384f49b357a221eb0a802c989b9
942256c1
]]></artwork>
          </section>
          <section anchor="intermediate-values-2">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 03763748cc2dfe4f6f80f8e4f3087b2d2222a7c9ba7d3c3aa8
e89c4975eed0999f
auth_key: 1fa6020180e18dde869f4f8363fc1b6841dbbc9fc9d258ece830af7efc2
5abdb
randomized_pwd: 4138e29dc8398d8c83b89129cb29ee5dc962fcb5fb2dca25981cb
351b83e0546
envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6567
0e51fc82109537121d7c39d96f3e04732e1f0b8cc55d98bb4e5968ace317de1d42c3d
handshake_secret: 21c9ee3561e6924110d86f99a624fe2fdc1aeea03f1b17c279f
b94da851e3686
server_mac_key: 87cab7092d3219b613459ea1ec2973be054367b331937d6973181
2f418425082
client_mac_key: 9dffe56b53981e86b37553beedb5d2226465a02d75d577bacef82
9775494bd93
oprf_key: 59984c44639e303cd46912ce722fc7d042023f25e264a3775667ea63c30
add69
]]></artwork>
          </section>
          <section anchor="output-values-2">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 0271e8fd723a873d16ddbda1d3700b9a42eca179ba09a8f
c2a2e40a8142fa35fe0
registration_response: 03c6fe2c086fa5333a15c5718ddda1f15a61e9ea9a0c4a
36f5f0dfe4f090250a70035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd
9f2092d6067784874
registration_upload: 03763748cc2dfe4f6f80f8e4f3087b2d2222a7c9ba7d3c3a
a8e89c4975eed0999f5b042a53415b5db1161dacf9f9ef0c30ed6b0179038e5e8e5a0
aa087c8bc0753a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6
5670e51fc82109537121d7c39d96f3e04732e1f0b8cc55d98bb4e5968ace317de1d42
c3d
KE1: 036514cf26a2578f1a45ea8faf540e52b237236ee97dc54948eca7b7f71ba9e1
29ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1034
93f36ca12467d1f5eaaabea67ca31377c4869c1e9a62346b6f01a991624b95d
KE2: 036ebcb79716cf2ecd0b3e5f3141709f72feb7369d2de41c61e0fa5695e78385
3e38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d286
5751562662eea8de000fdfd4cd1bf506b137d12f28bffaf11a0d720c6ddfe532b2aff
31acb0a8fbb89de1e29cc5a93a33f2e259cf59ad6c88a473d5f056aeb2b6b5eb03a0e
21e32a309373ed45506c3f58bf3d9978925cbf35b337e8ae220be71cd9960ecef2fe0
d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1020e67941e94deba83521
4421d2d8c90de9b0f7f925d11e2032ce19b1832ae8e0fb6eda25f9a67e3930e862860
02b8dd8b6339ddfdbaebaefe205fe474fb66884d
KE3: 4fd2178c39492f816796db05aa2400204944d6bc5ed4a1e4d7b8b24b9f1894bc
export_key: 00e1f2a1613c78183ec5127f805d320f31ce5dfef70d78f64d327d6c6
e325ae1
session_key: e39ed0c2a0b551bad5e9e8bb7017c66918d514b6412a4e30d4cac7a7
08d35646
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-real-test-vector-4">
          <name>OPAQUE-3DH Real Test Vector 4</name>
          <section anchor="configuration-3">
            <name>Configuration</name>
            <artwork><![CDATA[
OPRF: 0003
Hash: SHA256
KSF: Identity
KDF: HKDF-SHA256
MAC: HMAC-SHA256
Group: P256_XMD:SHA-256_SSWU_RO_
Context: 4f50415155452d504f43
Nh: 32
Npk: 33
Nsk: 32
Nm: 32
Nx: 32
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-3">
            <name>Input Values</name>
            <artwork><![CDATA[
client_identity: 616c696365
server_identity: 626f62
oprf_seed: 62f60b286d20ce4fd1d64809b0021dad6ed5d52a2c8cf27ae6582543a0
a8dce2
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebd
cf65670e51f
masking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80
f612fdfc6d
server_private_key: c36139381df63bfc91c850db0b9cfbec7a62e86d80040a41a
a7725bf0e79d5e5
server_public_key: 035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd9
f2092d6067784874
server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e
138e3d4a1
client_nonce: ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f
91fdaeeb1
server_keyshare: 020e67941e94deba835214421d2d8c90de9b0f7f925d11e2032c
e19b1832ae8e0f
client_keyshare: 03493f36ca12467d1f5eaaabea67ca31377c4869c1e9a62346b6
f01a991624b95d
server_private_keyshare: 9addab838c920fa7044f3a46b91ecaea24b0e7203992
8ee7d4c37a5b9bc17349
client_private_keyshare: 89d5a7e18567f255748a86beac13913df755a5adf776
d69e143147b545d22134
blind_registration: 411bf1a62d119afe30df682b91a0a33d777972d4f2daa4b34
ca527d597078153
blind_login: c497fddf6056d241e6cf9fb7ac37c384f49b357a221eb0a802c989b9
942256c1
]]></artwork>
          </section>
          <section anchor="intermediate-values-3">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 03763748cc2dfe4f6f80f8e4f3087b2d2222a7c9ba7d3c3aa8
e89c4975eed0999f
auth_key: 1fa6020180e18dde869f4f8363fc1b6841dbbc9fc9d258ece830af7efc2
5abdb
randomized_pwd: 4138e29dc8398d8c83b89129cb29ee5dc962fcb5fb2dca25981cb
351b83e0546
envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6567
0e51f6f7b04d6f92795c9bdb72da5ebe7745b8a6c38fc64c391b1be60b4f49ff2ce67
handshake_secret: 2bbe0da5102418c041884e9d42e62c946255138d74ea3d69acd
013bf2240c849
server_mac_key: 2b23b08101bbecc22352f1580cd73c1678affdca160ec8cfccbe0
e808029d192
client_mac_key: e279a0b44ae7c1ffb57e7cf179369c6282a18e38e6d1d070eee81
a44062d59e5
oprf_key: 59984c44639e303cd46912ce722fc7d042023f25e264a3775667ea63c30
add69
]]></artwork>
          </section>
          <section anchor="output-values-3">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 0271e8fd723a873d16ddbda1d3700b9a42eca179ba09a8f
c2a2e40a8142fa35fe0
registration_response: 03c6fe2c086fa5333a15c5718ddda1f15a61e9ea9a0c4a
36f5f0dfe4f090250a70035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd
9f2092d6067784874
registration_upload: 03763748cc2dfe4f6f80f8e4f3087b2d2222a7c9ba7d3c3a
a8e89c4975eed0999f5b042a53415b5db1161dacf9f9ef0c30ed6b0179038e5e8e5a0
aa087c8bc0753a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6
5670e51f6f7b04d6f92795c9bdb72da5ebe7745b8a6c38fc64c391b1be60b4f49ff2c
e67
KE1: 036514cf26a2578f1a45ea8faf540e52b237236ee97dc54948eca7b7f71ba9e1
29ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1034
93f36ca12467d1f5eaaabea67ca31377c4869c1e9a62346b6f01a991624b95d
KE2: 036ebcb79716cf2ecd0b3e5f3141709f72feb7369d2de41c61e0fa5695e78385
3e38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d286
5751562662eea8de000fdfd4cd1bf506b137d12f28bffaf11a0d720c6ddfe532b2aff
31acb0a8fbb89de1e29cc5a93a33f2e259cf59ad6c88a473d5f056aeb211efe68628e
45c388328e97b78809368c72b9efc78fe51ecc7f5b6f7f4c4c2e471cd9960ecef2fe0
d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1020e67941e94deba83521
4421d2d8c90de9b0f7f925d11e2032ce19b1832ae8e0f182fa038ada128f4440131f9
8adc14cfbdf9045d95b6a55db9b38ffd0aa539f7
KE3: a9a61a2442845e83b86c22d56ff038893208fcb0e2026d65e2a04f87497e873f
export_key: 00e1f2a1613c78183ec5127f805d320f31ce5dfef70d78f64d327d6c6
e325ae1
session_key: 9d15a7020c089b7c7ab7d6341e34a16260279b59dda8d63cabd3da0b
a14da32c
]]></artwork>
          </section>
        </section>
      </section>
      <section anchor="fake-vectors">
        <name>Fake Test Vectors</name>
        <section anchor="opaque-3dh-fake-test-vector-1">
          <name>OPAQUE-3DH Fake Test Vector 1</name>
          <section anchor="configuration-4">
            <name>Configuration</name>
            <artwork><![CDATA[
OPRF: 0001
Hash: SHA512
KSF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: ristretto255
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-4">
            <name>Input Values</name>
            <artwork><![CDATA[
client_identity: 616c696365
server_identity: 626f62
oprf_seed: 743fc168d1f826ad43738933e5adb23da6fb95f95a1b069f0daa0522d0
a78b617f701fc6aa46d3e7981e70de7765dfcd6b1e13e3369a582eb8dc456b10aa53b
0
credential_identifier: 31323334
masking_nonce: 9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c61
9e27b6e5a6
client_private_key: 2b98980aa95ab53a0f39f0291903d2fdf04b00c167f081416
9922df873002409
client_public_key: 84f43f9492e19c22d8bdaa4447cc3d4db1cdb5427a9f852c47
07921212c36251
server_private_key: c788585ae8b5ba2942b693b849be0c0426384e41977c18d2e
81fbe30fd7c9f06
server_public_key: 825f832667480f08b0c9069da5083ac4d0e9ee31b49c4e0310
031fea04d52966
server_nonce: 1e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813
055ae2d12
server_keyshare: 5236e2e06d49f0b496db2a786f6ee1016f15b4fd6c0dbd95d6b1
17055d914157
server_private_keyshare: 6d8fba9741a357584770f85294430bce2252fe212a8a
372152a73c7ffe414503
masking_key: 39ebd51f0e39a07a1c2d2431995b0399bca9996c5d10014d6ebab445
3dc10ce5cef38ed3df6e56bfff40c2d8dd4671c2b4cf63c3d54860f31fe40220d690b
b71
KE1: 20098d3321812eab08e9f3ccd5640d26194cb5cf73f4c5d551f9fea8f5a5765f
42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0a0e4ed
8bcc15f3dd01a30365c97c0c0de0a3dd3fbf5d3cbec55fb6ac1d3bf740f
]]></artwork>
          </section>
          <section anchor="output-values-4">
            <name>Output Values</name>
            <artwork><![CDATA[
KE2: e891a2527f657f5a72d723c735e9c3ae9179275f8e74f89a81418561b1db5670
9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a632b5a
b1bff96636144faa4f9f9afaac75dd88ea99cf5175902ae3f3b2195693f165f11929b
a510a5978e64dcdabecbd7ee1e4380ce270e58fea58e6462d92964a1aaef72698bca1
c673baeb04cc2bf7de5f3c2f5553464552d3a0f7698a9ca7f9c5e70c6cb1f706b2f17
5ab9d04bbd13926e816b6811a50b4aafa9799d5ed7971e10f6eeab2a7a420bf09da9b
27a4639645622c46358de9cf7ae813055ae2d125236e2e06d49f0b496db2a786f6ee1
016f15b4fd6c0dbd95d6b117055d9141571ef6a1ac9c84f21e6914ecb5d2020fe50c2
5b3c026b9f7a877c7526c13309cc4dd4d33050932c627813a67ceb1d3a8e0065fd55a
054296ef3097c6a8a04ac33c
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-fake-test-vector-2">
          <name>OPAQUE-3DH Fake Test Vector 2</name>
          <section anchor="configuration-5">
            <name>Configuration</name>
            <artwork><![CDATA[
OPRF: 0003
Hash: SHA256
KSF: Identity
KDF: HKDF-SHA256
MAC: HMAC-SHA256
Group: P256_XMD:SHA-256_SSWU_RO_
Context: 4f50415155452d504f43
Nh: 32
Npk: 33
Nsk: 32
Nm: 32
Nx: 32
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-5">
            <name>Input Values</name>
            <artwork><![CDATA[
client_identity: 616c696365
server_identity: 626f62
oprf_seed: bb1cd59e16ac09bc0cb6d528541695d7eba2239b1613a3db3ade77b362
80f725
credential_identifier: 31323334
masking_nonce: 9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c61
9e27b6e5a6
client_private_key: d423b87899fc61d014fc8330a4e26190fcfa470a3afe59243
24294af7dbbc1dd
client_public_key: 03b81708eae026a9370616c22e1e8542fe9dbebd36ce8a2661
b708e9628f4a57fc
server_private_key: 34fbe7e830be1fe8d2187c97414e3826040cbe49b893b6422
9bab5e85a5888c7
server_public_key: 0221e034c0e202fe883dcfc96802a7624166fed4cfcab4ae30
cf5f3290d01c88bf
server_nonce: 1e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813
055ae2d12
server_keyshare: 03f42965d5bcba2a590a49eb2418061effe40b5c29a34b8e5163
e0ef32044b2e4c
server_private_keyshare: 1a2a0ff27f3ca75221378a2a21fe5222ce0b439452f8
70475857a34197ba8f6d
masking_key: caecc6ccb4cae27cb54d8f3a1af1bac52a3d53107ce08497cdd362b1
992e4e5e
KE1: 0223afb7e2362271bdf2e20c62e25819e65d379308dfa4d9911f2fc7ada2296f
7f42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0a039
94d4f1221bfd205063469e92ea4d492f7cc76a327223633ab74590c30cf7285
]]></artwork>
          </section>
          <section anchor="output-values-5">
            <name>Output Values</name>
            <artwork><![CDATA[
KE2: 029c5324a734851923b27ea573dce1c2ed10c497ee222c5500763c96c5209db0
cd9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a6fac
da65ce0a97b9085e7af07f61fd3fdd046d257cbf2183ce8766090b8041a8bf28d79dd
4c9031ddc75bb6ddb4c291e639937840e3d39fc0d5a3d6e7723c09f7945df485bcf9a
efe3fe82d149e84049e259bb5b33d6a2ff3b25e4bfb7eff0962821e10f6eeab2a7a42
0bf09da9b27a4639645622c46358de9cf7ae813055ae2d1203f42965d5bcba2a590a4
9eb2418061effe40b5c29a34b8e5163e0ef32044b2e4c1bf93ad07640bc9ed22e2a33
8734d55d0d22f5cc16d179e5aa4cce845b9a04a8
]]></artwork>
          </section>
        </section>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+y96Xrb6Jkg+h9XgVb9KGmaZHGTRKlS3aOS7bLLm2K5knTn
dFsg8FFEiwQYgJSseJxrmWuZKzvv9q0AKdmVpec8R3lSlkjgW9997Xa70Tpf
L9Rp/H6u4rcXZ7/95Wl8Vt8vl2pd5Wl8cfbyaXxRlesyLRdRMp1W6vZUnouy
Mi2SJbybVcls3c2r9aybzqrrbrlK/rRR3f5JlCVrdRql8N/rsro/jfNiVkZR
vqpO43W1qdfDfv+kP4xu1P1dWWWn8YtirapCrbtPcMgoqtdJkX1IFmUB09yr
Olrlp/EfYTWduC6rdaVmNfx2v8Rf/iOKks16XlanUdyNYvjJi/o0ftKLfyw3
VVapP9OHvOQnSZGrhf+NWib5AnbzP6f3a/i9VylvoOe9+GWV3KV/vr9xBnq+
uS79z8vqGgb/c7LOy+I0PlvAzmET8bNyU2T0oTvZHF6/gbf/5zX+3UvLpTfn
y178St3lznwv1W1e2A/9yd6Ut3n8TtUqqdK5O80Cnu/d4Ku9my1Tnffis178
+7LMnNnO51Ver8vVXFXet/6054tyk80WSaU6cINpz505hb3NVbLKi+tpvq57
cLkAAAAG1RLevgXogKdfdJ/0buQMfRAandJgXwCk9HhSXas1nO56vapPv/sO
zj1ZV0l6o6pertazHqz/OwDf7+br5eI7Bt8t8+PycILupVqolPbrruj82buf
eAG1/j5eVWWq6jqu1Kqs8zUAfuuirvP1fDPFe/gOp/xuldyorhkF5/2xvFdF
/8SbcO85znYaXyR1jTgTnwHMq2Kdp3QZ8aVKN5WKk+sEbnUdn1dlXXcv87WK
f6nhEl8sV6qqy4Ie3qOBDdLQT1f+Faj4Q49XYT5luPhDcpvDaPwVfQeD56rG
i4VDqe5X63JRXt/HCPlv1BpWesNLy9f38f752ZvLA3qNCESMZIA2/FN/3Lhw
oAGwu/hJPpvlqvtcLRbLhA55ulDLh3eA+F+Vd+EOhAC8AwTzHwhehwd+ShZJ
sQ7ef1dOVbWOL8zXjVPAe4ZrVqsqL9a9PEkrAjvY6/i7Uf/I3/4Y3z9PADvW
eX/g3/gvBeBJVSeLxX0M0AJAlcDWYS4+TqAxcaHu4lVSJVl+vYwBt+KUruC6
SlbzPI1Wghz1I24cNizrCHcMp66/aWz2xdOnT+PLe1xcvlnGAIiW3tVxOYvP
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

-->

</rfc>
