<?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.25 (Ruby 3.1.3) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-opaque-10" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.16.0 -->
  <front>
    <title abbrev="OPAQUE">The OPAQUE Asymmetric PAKE Protocol</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-opaque-10"/>
    <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="2023" month="March" day="13"/>
    <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 -20, 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>BlindEvaluate(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 BlindEvaluate 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 = BlindEvaluate(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 public key 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: A server ephemeral public key 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):
  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 not specified.
- 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 optional encoded client identity, which is set to
  client_public_key if not specified.

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.credential_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)
  return ke2
]]></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 + Nn + Nm];
} 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 = BlindEvaluate(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 + Nn + Nm)
  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>Nn + Nm</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 + Nn + Nm)
  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:</t>
        <ul spacing="normal">
          <li>expected_client_mac: An opaque byte string of length <tt>Nm</tt>.</li>
          <li>session_key: An opaque byte string of length <tt>Nx</tt>.</li>
        </ul>
        <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 ristretto255-SHA512 and
P256-SHA256.</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 Argon2id <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 ristretto255-SHA512,
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>ristretto255-SHA512, HKDF-SHA-512, HMAC-SHA-512, SHA-512,
  Argon2id(t=1, p=4, m=2^21), ristretto255</li>
        <li>P256-SHA256, HKDF-SHA-256, HMAC-SHA-256, SHA-256, Argon2id(t=1, p=4, m=2^21), 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
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" initials="A." surname="Davidson">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Armando Faz-Hernandez" initials="A." surname="Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Nick Sullivan" initials="N." surname="Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="21" month="February" year="2023"/>
            <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 private 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
   private 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.  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-voprf-21"/>
        </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" initials="A." surname="Davidson">
              <organization>Brave Software</organization>
            </author>
            <author fullname="Armando Faz-Hernandez" initials="A." surname="Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Nick Sullivan" initials="N." surname="Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="Wood">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <date day="21" month="February" year="2023"/>
            <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 private 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
   private 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.  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-voprf-21"/>
        </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" initials="A." surname="Faz-Hernandez">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Sam Scott" initials="S." surname="Scott">
              <organization>Cornell Tech</organization>
            </author>
            <author fullname="Nick Sullivan" initials="N." surname="Sullivan">
              <organization>Cloudflare, Inc.</organization>
            </author>
            <author fullname="Riad S. Wahby" initials="R. S." surname="Wahby">
              <organization>Stanford University</organization>
            </author>
            <author fullname="Christopher A. Wood" initials="C. A." surname="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 public keys 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: ristretto255-SHA512
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: 2ec892bdbf9b3e2ea834be9eb11f5d187e64ba661ec041c0a3
b66db8b7d6cc30
auth_key: 6cd32316f18d72a9a927a83199fa030663a38ce0c11fbaef82aa9003773
0494fc555c4d49506284516edd1628c27965b7555a4ebfed2223199f6c67966dde822
randomized_pwd: aac48c25ab036e30750839d31d6e73007344cb1155289fb7d329b
eb932e9adeea73d5d5c22a0ce1952f8aba6d66007615cd1698d4ac85ef1fcf150031d
1435d9
envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a3
8dfecb9dbe7d48cf714fc3533becab6faf60b783c94d258477eb74ecc453413bf61c5
3fd58f0fb3c1175410b674c02e1b59b2d729a865b709db3dc4ee2bb45703d5a8
handshake_secret: 562564da0d4efdc73cb6efbb454388dabfa5052d4e7e83f4d02
40c5afd8352881e762755c2f1a9110e36b05fe770f0f48658489c9730dcd365e6c2d4
049c8fe3
server_mac_key: 59473632c53a647f9f4ab4d6c3b81e241dd9cb19ca05f0eabed7e
593f0407ff57e7f060621e5e48d5291be600a1959fbecbc26d4a7157bd227a993c37b
645f73
client_mac_key: f2d019bad603b45b2ac50376279a0a37d097723b5405aa4fb20a5
9f60cdbdd52ec043372cedcdbbdb634c54483e1be51a88d13a5798180acb84c10b129
7069fd
oprf_key: 5d4c6a8b7c7138182afb4345d1fae6a9f18a1744afbcc3854f8f5a2b4b4
c6d05
]]></artwork>
          </section>
          <section anchor="output-values">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 5059ff249eb1551b7ce4991f3336205bde44a105a032e74
7d21bf382e75f7a71
registration_response: 7408a268083e03abc7097fc05b587834539065e86fb0c7
b6342fcf5e01e5b019b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a3
82c9b79df1a78
registration_upload: 2ec892bdbf9b3e2ea834be9eb11f5d187e64ba661ec041c0
a3b66db8b7d6cc301ac5844383c7708077dea41cbefe2fa15724f449e535dd7dd562e
66f5ecfb95864eadddec9db5874959905117dad40a4524111849799281fefe3c51fa8
2785c5ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfe
cb9dbe7d48cf714fc3533becab6faf60b783c94d258477eb74ecc453413bf61c53fd5
8f0fb3c1175410b674c02e1b59b2d729a865b709db3dc4ee2bb45703d5a8
KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44d
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc0c3a0
0c961fead8a16f818929cc976f0475e4f723519318b96f4947a7a5f9663
KE2: 7e308140890bcde30cbcea28b01ea1ecfbd077cff62c4def8efa075aabcbb471
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dd6ec6
0bcdb26dc455ddf3e718f1020490c192d70dfc7e403981179d8073d1146a4f9aa1ced
4e4cd984c657eb3b54ced3848326f70331953d91b02535af44d9fe0610f003be80cb2
098357928c8ea17bb065af33095f39d4e0b53b1687f02d522d96bad4ca354293d5c40
1177ccbd302cf565b96c327f71bc9eaf2890675d2fbb71cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a1c8c39f573135474c51660b02425bca
633e339cec4e1acc69c94dd48497fe40287f33611c2cf0eef57adbf48942737d9421e
6b20e4b9d6e391d4168bf4bf96ea57aa42ad41c977605e027a9ef706a349f4b2919fe
3562c8e86c4eeecf2f9457d4
KE3: df9a13cd256091f90f0fcb2ef6b3411e4aebff07bb0813299c0ec7f5dedd33a7
681231a001a82f1dece1777921f42abfeee551ee34392e1c9743c5cc1dc1ef8c
export_key: 1ef15b4fa99e8a852412450ab78713aad30d21fa6966c9b8c9fb3262a
970dc62950d4dd4ed62598229b1b72794fc0335199d9f7fcc6eaedde92cc04870e63f
16
session_key: 8a0f9f4928fc0c3b5bb261c4b7b3997600405424a8128632e85a5667
b4b742484ed791933971be6d3fcf2b23c56b8e8f7e7edcae19a03b8fd87f5999fce12
9d2
]]></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: ristretto255-SHA512
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: 2ec892bdbf9b3e2ea834be9eb11f5d187e64ba661ec041c0a3
b66db8b7d6cc30
auth_key: 6cd32316f18d72a9a927a83199fa030663a38ce0c11fbaef82aa9003773
0494fc555c4d49506284516edd1628c27965b7555a4ebfed2223199f6c67966dde822
randomized_pwd: aac48c25ab036e30750839d31d6e73007344cb1155289fb7d329b
eb932e9adeea73d5d5c22a0ce1952f8aba6d66007615cd1698d4ac85ef1fcf150031d
1435d9
envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a3
8dfec1ac902dc5589e9a5f0de56ad685ea8486210ef41449cd4d8712828913c5d2b68
0b2b3af4a26c765cff329bfb66d38ecf1d6cfa9e7a73c222c6efe0d9520f7d7c
handshake_secret: bc2abaa979af9cbb6859856b7d5d201a038fbdfa7e10f11d131
d3f8f6fc3b263bde4db6d2d9207d4648ff80415a276d5f157f9d37a3eade559db2e5f
3fa026b2
server_mac_key: 2420461c589866700b08c8818cbf390c872629a14cf32a264dad3
375f85f33188c8f04bdb71880b2d4613187a0e416808ab62b45858b88319882602371
ef5f75
client_mac_key: 156e4ab0b9f71ef994bbbb73928e6d14d7335cf9561f113d61ac6
b41fab35f9c72fe827d3c4d7dd91d8398ee619810e4f9286e6b32f329eb6b1476ce18
fa8500
oprf_key: 5d4c6a8b7c7138182afb4345d1fae6a9f18a1744afbcc3854f8f5a2b4b4
c6d05
]]></artwork>
          </section>
          <section anchor="output-values-1">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 5059ff249eb1551b7ce4991f3336205bde44a105a032e74
7d21bf382e75f7a71
registration_response: 7408a268083e03abc7097fc05b587834539065e86fb0c7
b6342fcf5e01e5b019b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a3
82c9b79df1a78
registration_upload: 2ec892bdbf9b3e2ea834be9eb11f5d187e64ba661ec041c0
a3b66db8b7d6cc301ac5844383c7708077dea41cbefe2fa15724f449e535dd7dd562e
66f5ecfb95864eadddec9db5874959905117dad40a4524111849799281fefe3c51fa8
2785c5ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfe
c1ac902dc5589e9a5f0de56ad685ea8486210ef41449cd4d8712828913c5d2b680b2b
3af4a26c765cff329bfb66d38ecf1d6cfa9e7a73c222c6efe0d9520f7d7c
KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44d
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc0c3a0
0c961fead8a16f818929cc976f0475e4f723519318b96f4947a7a5f9663
KE2: 7e308140890bcde30cbcea28b01ea1ecfbd077cff62c4def8efa075aabcbb471
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dd6ec6
0bcdb26dc455ddf3e718f1020490c192d70dfc7e403981179d8073d1146a4f9aa1ced
4e4cd984c657eb3b54ced3848326f70331953d91b02535af44d9fea502150b67fe367
95dd8914f164e49f81c7688a38928372134b7dccd50e09f8fed9518b7b2f94835b3c4
fe4c8475e7513f20eb97ff0568a39caee3fd6251876f71cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a1c8c39f573135474c51660b02425bca
633e339cec4e1acc69c94dd48497fe4028c463164503598ea84fab9005b9cd51b7bb3
206fb22a412e8a86b9cb6ffca18f5ea6b4c24fdc94865e8bf74248e6be15b85b16041
40ffad2175f9518452d381af
KE3: a86ece659d90525e2476aa1756d313b067581cb7b0643b97be6b8ab8d0f10843
57e514ecfaff9dc18f6cca37da630545f0048393f16bc175eb819653ebc45b60
export_key: 1ef15b4fa99e8a852412450ab78713aad30d21fa6966c9b8c9fb3262a
970dc62950d4dd4ed62598229b1b72794fc0335199d9f7fcc6eaedde92cc04870e63f
16
session_key: 0968e91efeb702d6aa09023a9a79803332d8bd3442a79b8ad09490b9
267161013bf475bed945238a5e976ef7d7de7ff41ae30439fe2fc39758fb3e56f2683
e60
]]></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: P256-SHA256
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: 02dc91b178ba2c4bbf9b9403fca25457b906a7f507e59b6e70
3031e09114ba2be0
auth_key: 5bd4be1602516092dc5078f8d699f5721dc1720a49fb80d8e5c16377abd
0987b
randomized_pwd: 06be0a1a51d56557a3adad57ba29c5510565dcd8b5078fa319151
b9382258fb0
envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6567
0e51fe155412cb432898eda63529c3b2633521f770cccbd25d7548a4e20665a45e65a
handshake_secret: c59197dd9269abfdb3037ea1c203a97627e2c0aa142000d1c3f
06a2c8713077d
server_mac_key: a431a5c1d3cb5772cbc66af0c2851e23dd9ad153a0c8b99081c7d
0d543173fde
client_mac_key: 7329ffd54df21db5532fce8794fca78b505fef9397aad28a424f6
ea3f97c51ca
oprf_key: 2dfb5cb9aa1476093be74ca0d43e5b02862a05f5d6972614d7433acdc66
f7f31
]]></artwork>
          </section>
          <section anchor="output-values-2">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 029e949a29cfa0bf7c1287333d2fb3dc586c41aa652f507
0d26a5315a1b50229f8
registration_response: 0350d3694c00978f00a5ce7cd08a00547e4ab5fb5fc2b2
f6717cdaa6c89136efef035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd
9f2092d6067784874
registration_upload: 02dc91b178ba2c4bbf9b9403fca25457b906a7f507e59b6e
703031e09114ba2be07f0ed53532d3ae8e505ecc70d42d2b814b6b0e48156def71ea0
29148b2803aafa921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6
5670e51fe155412cb432898eda63529c3b2633521f770cccbd25d7548a4e20665a45e
65a
KE1: 037342f0bcb3ecea754c1e67576c86aa90c1de3875f390ad599a26686cdfee6e
07ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1034
93f36ca12467d1f5eaaabea67ca31377c4869c1e9a62346b6f01a991624b95d
KE2: 0246da9fe4d41d5ba69faa6c509a1d5bafd49a48615a47a8dd4b0823cc147648
1138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d2f0
c547f70deaeca54d878c14c1aa5e1ab405dec833777132eea905c2fbb12504a67dcbe
0e66740c76b62c13b04a38a77926e19072953319ec65e41f9bfd2ae2687bd3348bfe3
3cb0bb9864fdb3b307f7dd68a17f3f150074a0bfc830ab889717d71cd9960ecef2fe0
d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1020e67941e94deba83521
4421d2d8c90de9b0f7f925d11e2032ce19b1832ae8e0fb5166145361a2c344d9737dd
5c826fede3bbfafa418ad379ce4fa65fbb15db6e
KE3: 272d04758b2b436bf0239ba7b9bd0a1686a9b6542ceaaf08732054beda956498
export_key: c3c9a1b0e33ac84dd83d0b7e8af6794e17e7a3caadff289fbd9dc769a
853c64b
session_key: a224790a010afc0a3f37e23c1b7a5cb7f9e73e3d9a924116510d97d8
0e2a1e0c
]]></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: P256-SHA256
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: 02dc91b178ba2c4bbf9b9403fca25457b906a7f507e59b6e70
3031e09114ba2be0
auth_key: 5bd4be1602516092dc5078f8d699f5721dc1720a49fb80d8e5c16377abd
0987b
randomized_pwd: 06be0a1a51d56557a3adad57ba29c5510565dcd8b5078fa319151
b9382258fb0
envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6567
0e51f4d7773a36a208a866301dbb2858e40dc5638017527cf91aef32d3848eebe0971
handshake_secret: 0ee4a82c4a34992f72bfbcb5d2ce64044477dfe200b9d8c92bf
1759b219b3485
server_mac_key: 77ebd7511216a51e9c2f3368ce6c1e40513f24b6f42085ef18e7f
737b427aab5
client_mac_key: e48e2064cf570dbd18eb42550d4459c58ac4ae4e28881d1aefbab
d668f7f1df9
oprf_key: 2dfb5cb9aa1476093be74ca0d43e5b02862a05f5d6972614d7433acdc66
f7f31
]]></artwork>
          </section>
          <section anchor="output-values-3">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 029e949a29cfa0bf7c1287333d2fb3dc586c41aa652f507
0d26a5315a1b50229f8
registration_response: 0350d3694c00978f00a5ce7cd08a00547e4ab5fb5fc2b2
f6717cdaa6c89136efef035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd
9f2092d6067784874
registration_upload: 02dc91b178ba2c4bbf9b9403fca25457b906a7f507e59b6e
703031e09114ba2be07f0ed53532d3ae8e505ecc70d42d2b814b6b0e48156def71ea0
29148b2803aafa921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6
5670e51f4d7773a36a208a866301dbb2858e40dc5638017527cf91aef32d3848eebe0
971
KE1: 037342f0bcb3ecea754c1e67576c86aa90c1de3875f390ad599a26686cdfee6e
07ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1034
93f36ca12467d1f5eaaabea67ca31377c4869c1e9a62346b6f01a991624b95d
KE2: 0246da9fe4d41d5ba69faa6c509a1d5bafd49a48615a47a8dd4b0823cc147648
1138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d2f0
c547f70deaeca54d878c14c1aa5e1ab405dec833777132eea905c2fbb12504a67dcbe
0e66740c76b62c13b04a38a77926e19072953319ec65e41f9bfd2ae268d7f10604202
1c80300e4c6f585980cf39fc51a4a6bba41b0729f9b240c729e5671cd9960ecef2fe0
d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1020e67941e94deba83521
4421d2d8c90de9b0f7f925d11e2032ce19b1832ae8e0fdca637d2a5390f4c809a67b4
6977c536fe9f643f703178a17a413d14e4bb523c
KE3: 298cd0077d018f122bc95d706e5fef06537814c567f08d5e40b0c0ae918f9287
export_key: c3c9a1b0e33ac84dd83d0b7e8af6794e17e7a3caadff289fbd9dc769a
853c64b
session_key: 0c59872e9bcdde274f4f52f6ba0fd1acca211d6eb7db98677b457a73
9ef1f0d8
]]></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: ristretto255-SHA512
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: b0a26dcaca2230b8f5e4b1bcab9c84b586140221bb8b2848486874b0be448905
42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0a0e4ed
8bcc15f3dd01a30365c97c0c0de0a3dd3fbf5d3cbec55fb6ac1d3bf740f
]]></artwork>
          </section>
          <section anchor="output-values-4">
            <name>Output Values</name>
            <artwork><![CDATA[
KE2: 928f79ad8df21963e91411b9f55165ba833dea918f441db967cdc09521d22925
9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a632b5a
b1bff96636144faa4f9f9afaac75dd88ea99cf5175902ae3f3b2195693f165f11929b
a510a5978e64dcdabecbd7ee1e4380ce270e58fea58e6462d92964a1aaef72698bca1
c673baeb04cc2bf7de5f3c2f5553464552d3a0f7698a9ca7f9c5e70c6cb1f706b2f17
5ab9d04bbd13926e816b6811a50b4aafa9799d5ed7971e10f6eeab2a7a420bf09da9b
27a4639645622c46358de9cf7ae813055ae2d125236e2e06d49f0b496db2a786f6ee1
016f15b4fd6c0dbd95d6b117055d914157cb5e11625c701e642293ad32bfcf88da653
c9b6e71efc8a89607fd46ed5e7b9bf7cc7dbb997a4fd41194a04bcd0c5d88052e080a
2f02c68d8d9e9c0ce15c92ff
]]></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: P256-SHA256
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: 0396875da2b4f7749bba411513aea02dc514a48d169d8a9531bd61d3af3fa9ba
ae42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0a039
94d4f1221bfd205063469e92ea4d492f7cc76a327223633ab74590c30cf7285
]]></artwork>
          </section>
          <section anchor="output-values-5">
            <name>Output Values</name>
            <artwork><![CDATA[
KE2: 0201198dcd13f9792eb75dcfa815f61b049abfe2e3e9456d4bbbceec5f442efd
049c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a6fac
da65ce0a97b9085e7af07f61fd3fdd046d257cbf2183ce8766090b8041a8bf28d79dd
4c9031ddc75bb6ddb4c291e639937840e3d39fc0d5a3d6e7723c09f7945df485bcf9a
efe3fe82d149e84049e259bb5b33d6a2ff3b25e4bfb7eff0962821e10f6eeab2a7a42
0bf09da9b27a4639645622c46358de9cf7ae813055ae2d1203f42965d5bcba2a590a4
9eb2418061effe40b5c29a34b8e5163e0ef32044b2e4c196137813ed8ec48627f0b0d
90d9427f4ec137f8360769df167c25836eae5d91
]]></artwork>
          </section>
        </section>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
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

-->

</rfc>
