<?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.34 (Ruby 3.2.2) -->
<rfc xmlns:xi="http://www.w3.org/2001/XInclude" ipr="trust200902" docName="draft-irtf-cfrg-opaque-11" category="info" tocInclude="true" sortRefs="true" symRefs="true" version="3">
  <!-- xml2rfc v2v3 conversion 3.17.3 -->
  <front>
    <title abbrev="OPAQUE">The OPAQUE Asymmetric PAKE Protocol</title>
    <seriesInfo name="Internet-Draft" value="draft-irtf-cfrg-opaque-11"/>
    <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="June" day="08"/>
    <keyword>Internet-Draft</keyword>
    <abstract>
      <?line 242?>

<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>
    <?line 253?>

<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.
<?line -6?>
        </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>zeroes(n): Generate a string of <tt>n</tt> bytes all equal to 0 (zero).</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 -21, 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): Apply a key stretching function 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
channel with confidentiality and integrity: 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>DeriveDiffieHellmanKeyPair()</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>DeriveDiffieHellmanKeyPair</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_password, 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_password, server_public_key, server_identity, client_identity):
  envelope_nonce = random(Nn)
  masking_key = Expand(randomized_password, "MaskingKey", Nh)
  auth_key = Expand(randomized_password, concat(envelope_nonce, "AuthKey"), Nh)
  export_key = Expand(randomized_password, concat(envelope_nonce, "ExportKey"), Nh)
  seed = Expand(randomized_password, concat(envelope_nonce, "PrivateKey"), Nseed)
  (_, client_public_key) = DeriveDiffieHellmanKeyPair(seed)

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

  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_password, 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.
- cleartext_credentials, a CleartextCredentials structure.
- export_key, an additional client key.

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

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

  cleartext_credentials = CreateCleartextCredentials(server_public_key,
                      client_public_key, server_identity, client_identity)
  expected_tag = MAC(auth_key, concat(envelope.nonce, cleartext_credentials))
  If !ct_equal(envelope.auth_tag, expected_tag)
    raise EnvelopeRecoveryError
  return (client_private_key, cleartext_credentials, 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_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)
  randomized_password = Extract("", concat(oprf_output, stretched_oprf_output))

  (envelope, client_public_key, masking_key, export_key) =
    Store(randomized_password, 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 = GenerateKE1(password)

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

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

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

    (ke3,
    session_key,
    export_key) = GenerateKE3(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="protocol-3dh"/>.</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="protocol-3dh"/>.</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="protocol-3dh"/> 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_public_keyshare[Npk];
} AuthRequest;
]]></artwork>
        <t>client_nonce: A fresh randomly generated nonce of length <tt>Nn</tt>.</t>
        <t>client_public_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_public_keyshare[Npk];
  uint8 server_mac[Nm];
} AuthResponse;
]]></artwork>
        <t>server_nonce: A fresh randomly generated nonce of length <tt>Nn</tt>.</t>
        <t>server_public_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="generateke1">
          <name>GenerateKE1</name>
          <t>The <tt>GenerateKE1</tt> function begins the AKE protocol and produces the client's <tt>KE1</tt>
output for the server.</t>
          <artwork><![CDATA[
GenerateKE1

State:
- state, a ClientState structure.

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

Output:
- ke1, a KE1 message structure.

def GenerateKE1(password):
  request, blind = CreateCredentialRequest(password)
  state.password = password
  state.blind = blind
  ke1 = AuthClientStart(request)
  return ke1
]]></artwork>
        </section>
        <section anchor="generateke2">
          <name>GenerateKE2</name>
          <t>The <tt>GenerateKE2</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[
GenerateKE2

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 GenerateKE2(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)
  cleartext_credentials = CreateCleartextCredentials(server_public_key,
                      record.client_public_key, server_identity, client_identity)
  auth_response = AuthServerRespond(cleartext_credentials, server_private_key,
                      record.client_public_key, ke1, credential_response)
  Create KE2 ke2 with (credential_response, auth_response)
  return ke2
]]></artwork>
        </section>
        <section anchor="generateke3">
          <name>GenerateKE3</name>
          <t>The <tt>GenerateKE3</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[
GenerateKE3

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 GenerateKE3(client_identity, server_identity, ke2):
  (client_private_key, cleartext_credentials, server_public_key, export_key) =
    RecoverCredentials(state.password, state.blind, ke2.credential_response,
                       server_identity, client_identity)
  (ke3, session_key) =
    AuthClientFinalize(cleartext_credentials, client_private_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 encoded client private key for the AKE protocol.
- cleartext_credentials, a CleartextCredentials structure.
- 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)
  randomized_password = Extract("", concat(oprf_output, stretched_oprf_output))

  masking_key = Expand(randomized_password, "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, cleartext_credentials, export_key) =
    Recover(randomized_password, server_public_key, envelope,
            server_identity, client_identity)

  return (client_private_key, cleartext_credentials, server_public_key, export_key)
]]></artwork>
          </section>
        </section>
      </section>
      <section anchor="protocol-3dh">
        <name>3DH 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>3DH Key Exchange Functions</name>
          <t>We assume the following functions to exist for all Diffie-Hellman key exchange
variants:</t>
          <ul spacing="normal">
            <li>DeriveDiffieHellmanKeyPair(seed): Derive a private and public Diffie-Hellman
key pair deterministically from the input <tt>seed</tt>. The type of the private key
depends on the implementation, whereas the type of the public key is a
byte string of <tt>Npk</tt> bytes.</li>
            <li>DiffieHellman(k, B): A function that performs the Diffie-Hellman operation
between the private input <tt>k</tt> and public input <tt>B</tt>.
The output of this function is a unique, fixed-length byte string.</li>
          </ul>
          <t>Implementations for recommended groups in <xref target="configurations"/>, as well as groups
covered by test vectors in <xref target="test-vectors"/>, are described in the following sections.</t>
          <section anchor="dh-ristretto255">
            <name>3DH ristretto255</name>
            <t>This section describes the implementation of the Diffie-Hellman key exchange functions based on ristretto255,
as defined in <xref target="RISTRETTO"/>.</t>
            <ul spacing="normal">
              <li>DeriveDiffieHellmanKeyPair(seed): This function is implemented as
DeriveKeyPair(seed, "OPAQUE-DeriveDiffieHellmanKeyPair"), where DeriveKeyPair is
as specified in <xref section="3.2" sectionFormat="comma" target="OPRF"/>. The public value from DeriveKeyPair
is encoded using SerializeElement from <xref section="2.1" sectionFormat="of" target="OPRF"/>.</li>
              <li>DiffieHellman(k, B): Implemented as scalar multiplication as described in
<xref section="4" sectionFormat="of" target="RISTRETTO"/> after decoding <tt>B</tt> from its encoded input using
the Decode function in <xref section="4.3.1" sectionFormat="of" target="RISTRETTO"/>. The output is then
encoded using the SerializeElement function of the OPRF group described in
<xref section="2.1" sectionFormat="comma" target="OPRF"/>.</li>
            </ul>
          </section>
          <section anchor="dh-p-256">
            <name>3DH P-256</name>
            <t>This section describes the implementation of the Diffie-Hellman key exchange functions based on NIST P-256,
as defined in <xref target="NISTCurves"/>.</t>
            <ul spacing="normal">
              <li>DeriveDiffieHellmanKeyPair(seed): This function is implemented as
DeriveKeyPair(seed, "OPAQUE-DeriveDiffieHellmanKeyPair"), where DeriveKeyPair is
as specified in <xref section="3.2" sectionFormat="comma" target="OPRF"/>. The public value from DeriveKeyPair
is encoded using SerializeElement from <xref section="2.1" sectionFormat="of" target="OPRF"/>.</li>
              <li>DiffieHellman(k, B): Implemented as scalar multiplication as described in
<xref target="NISTCurves"/>, after decoding <tt>B</tt> from its encoded input using
the compressed Octet-String-to-Elliptic-Curve-Point method according to <xref target="NISTCurves"/>.
The output is then encoded using the SerializeElement function of the OPRF
group described in <xref section="2.1" sectionFormat="comma" target="OPRF"/>.</li>
            </ul>
          </section>
          <section anchor="dh-curve25519">
            <name>3DH Curve25519</name>
            <t>This section describes the implementation of the Diffie-Hellman key exchange functions based on Curve25519,
as defined in <xref target="Curve25519"/>.</t>
            <ul spacing="normal">
              <li>DeriveDiffieHellmanKeyPair(seed): This function is implemented by returning the private
key <tt>k</tt> based on seed (of length <tt>Nseed = 32</tt> bytes), as described in <xref section="5" sectionFormat="of" target="Curve25519"/>,
as well as the result of DiffieHellman(k, B), where B is the base point of Curve25519.</li>
              <li>DiffieHellman(k, B): Implemented using the X25519 function in <xref section="5" sectionFormat="of" target="Curve25519"/>.
The output is then used raw, with no processing.</li>
            </ul>
          </section>
        </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_public_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_public_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_keyshare_seed = random(Nseed)
  (client_secret, client_public_keyshare) = DeriveDiffieHellmanKeyPair(client_keyshare_seed)
  Create AuthRequest auth_request with (client_nonce, client_public_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:
- cleartext_credentials, a CleartextCredentials structure.
- client_private_key, the client's private key.
- ke2, a KE2 message structure.

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

Exceptions:
- ServerAuthenticationError, the handshake fails.

def AuthClientFinalize(cleartext_credentials, client_private_key, ke2):

  dh1 = DiffieHellman(state.client_secret, ke2.auth_response.server_public_keyshare)
  dh2 = DiffieHellman(state.client_secret, cleartext_credentials.server_public_key)
  dh3 = DiffieHellman(client_private_key, ke2.auth_response.server_public_keyshare)
  ikm = concat(dh1, dh2, dh3)

  preamble = Preamble(cleartext_credentials.client_identity,
                      state.ke1,
                      cleartext_credentials.server_identity,
                      ke2.credential_response,
                      ke2.auth_response.server_nonce,
                      ke2.auth_response.server_public_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:
- cleartext_credentials, a CleartextCredentials structure.
- server_private_key, the server's private key.
- client_public_key, the client's public key.
- ke1, a KE1 message structure.

Output:
- auth_response, an AuthResponse structure.

def AuthServerRespond(cleartext_credentials, server_private_key, client_public_key, ke1, credential_response):
  server_nonce = random(Nn)
  server_keyshare_seed = random(Nseed)
  (server_private_keyshare, server_public_keyshare) = DeriveDiffieHellmanKeyPair(server_keyshare_seed)
  preamble = Preamble(cleartext_credentials.client_identity,
                      ke1,
                      cleartext_credentials.server_identity,
                      credential_response,
                      server_nonce,
                      server_public_keyshare)

  dh1 = DiffieHellman(server_private_keyshare, ke1.auth_request.client_public_keyshare)
  dh2 = DiffieHellman(server_private_key, ke1.auth_request.client_public_keyshare)
  dh3 = DiffieHellman(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_public_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 is determined by the application and implements the interface in
<xref target="dependencies"/>. As noted, collision resistance is required. Examples for KSF
include Argon2id <xref target="ARGON2"/>, scrypt <xref target="SCRYPT"/>, and PBKDF2
<xref target="PBKDF2"/> with fixed parameter choices. See <xref target="app-considerations"/>
for more information about this choice of function.</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(S = zeroes(16), p = 4, T = Nh, m = 2^21, t = 1, v = 0x13, K = nil, X = nil, y = 2), ristretto255</li>
        <li>P256-SHA256, HKDF-SHA-256, HMAC-SHA-256, SHA-256,
  Argon2id(S = zeroes(16), p = 4, T = Nh, m = 2^21, t = 1, v = 0x13, K = nil, X = nil, y = 2), P-256</li>
        <li>P256-SHA256, HKDF-SHA-256, HMAC-SHA-256, SHA-256, scrypt(N = 32768, r = 8, p = 1), 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>Configuration and envelope updates: Applications may wish to update or change their
configuration or other parameters which affect the client's RegistrationRecord over
time. Some reasons for changing these are to use different cryptographic algorithms,
e.g., a different KSF with improved parameters, or to update key material that is
cryptographically bound to the RegistrationRecord, such as the server's public key
(server_public_key). Any such change will require users to re-register to create a
new RegistrationRecord. Supporting these types of updates can be helpful for applications
which anticipate such changes in their deployment setting.</li>
        <li>Password hardening parameters: Key stretching is done to help prevent password disclosure
in the event of server compromise; see <xref target="key-stretch"/>. There is no ideal or default
set of parameters, though relevant specifications for KSFs give some reasonable
defaults.</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><strong>RFC editor: remove this section before publication.</strong></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>
          <li>
            <xref target="JKX18"/> comments on a defense against offline
dictionary attacks upon server compromise or honest-but-curious servers.
The authors suggest implementing the OPRF phase as a threshold OPRF <xref target="TOPPSS"/>,
effectively forcing an attacker to act online or to control at least t key
shares (among the total n), where t is the threshold number of shares necessary
to recombine the secret OPRF key, and only then be able to run an offline dictionary
attack. This implementation only affects the server and changes nothing for the client.
Furthermore, if the threshold OPRF servers holding these keys are separate from
the authentication server, then recovering all n shares would still not suffice
to run an offline dictionnary attack without access to the client record database.
However, this mechanism is out of scope for this document.</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="protocol-3dh"/> 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="key-stretch">
        <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 for the KSF that balance cost and complexity across
all possible client implementations and deployments. Note that in OPAQUE, the
key stretching function is executed by the client, as opposed to the server in
traditional password hashing scenarios. 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. 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 initials="" surname="WhatsApp" fullname="WhatsApp">
              <organization/>
            </author>
            <date>n.d.</date>
          </front>
        </reference>
        <reference anchor="TOPPSS">
          <front>
            <title>TOPPSS: Cost-minimal Password-Protected Secret Sharing based on Threshold OPRF</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="2017"/>
          </front>
          <seriesInfo name="Applied Cryptology and Network Security - ACNS 2017" value=""/>
        </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="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="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="RISTRETTO">
          <front>
            <title>The ristretto255 and decaf448 Groups</title>
            <author fullname="Henry de Valence" initials="H." surname="de Valence">
         </author>
            <author fullname="Jack Grigg" initials="J." surname="Grigg">
         </author>
            <author fullname="Mike Hamburg" initials="M." surname="Hamburg">
         </author>
            <author fullname="Isis Lovecruft" initials="I." surname="Lovecruft">
         </author>
            <author fullname="George Tankersley" initials="G." surname="Tankersley">
         </author>
            <author fullname="Filippo Valsorda" initials="F." surname="Valsorda">
         </author>
            <date day="3" month="April" year="2023"/>
            <abstract>
              <t>   This memo specifies two prime-order groups, ristretto255 and
   decaf448, suitable for safely implementing higher-level and complex
   cryptographic protocols.  The ristretto255 group can be implemented
   using Curve25519, allowing existing Curve25519 implementations to be
   reused and extended to provide a prime-order group.  Likewise, the
   decaf448 group can be implemented using edwards448.

   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-ristretto255-decaf448-07"/>
        </reference>
        <reference anchor="NISTCurves">
          <front>
            <title>Digital Signature Standard (DSS)</title>
            <author>
              <organization/>
            </author>
            <date month="July" year="2013"/>
          </front>
          <seriesInfo name="National Institute of Standards and Technology" value="report"/>
          <seriesInfo name="DOI" value="10.6028/nist.fips.186-4"/>
        </reference>
        <reference anchor="Curve25519">
          <front>
            <title>Elliptic Curves for Security</title>
            <author fullname="A. Langley" initials="A." surname="Langley">
              <organization/>
            </author>
            <author fullname="M. Hamburg" initials="M." surname="Hamburg">
              <organization/>
            </author>
            <author fullname="S. Turner" initials="S." surname="Turner">
              <organization/>
            </author>
            <date month="January" year="2016"/>
            <abstract>
              <t>This memo specifies two elliptic curves over prime fields that offer a high level of practical security in cryptographic applications, including Transport Layer Security (TLS).  These curves are intended to operate at the ~128-bit and ~224-bit security level, respectively, and are generated deterministically based on a list of required properties.</t>
            </abstract>
          </front>
          <seriesInfo name="RFC" value="7748"/>
          <seriesInfo name="DOI" value="10.17487/RFC7748"/>
        </reference>
        <reference anchor="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="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="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>
    <?line 2238?>

<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 and integrity 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_public_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-21 of <xref target="OPRF"/>. The KSF used for each test vector is the identity function
(denoted Identity), which returns as output the input message supplied to the function
without any modification, i.e., msg = Stretch(msg).</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
client_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf
1091933541936304b
server_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a
1e85ff80da12f982f
blind_registration: 76cfbfe758db884bebb33582331ba9f159720ca8784a2a070
a265d9c2d6abe01
blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4
b0790308
]]></artwork>
          </section>
          <section anchor="intermediate-values">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccbac
cafb57ac5c3675
auth_key: 6cd32316f18d72a9a927a83199fa030663a38ce0c11fbaef82aa9003773
0494fc555c4d49506284516edd1628c27965b7555a4ebfed2223199f6c67966dde822
randomized_password: aac48c25ab036e30750839d31d6e73007344cb1155289fb7
d329beb932e9adeea73d5d5c22a0ce1952f8aba6d66007615cd1698d4ac85ef1fcf15
0031d1435d9
envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a3
8dfec634b0f5b96109c198a8027da51854c35bee90d1e1c781806d07d49b76de6a28b
8d9e9b6c93b9f8b64d16dddd9c5bfb5fea48ee8fd2f75012a8b308605cdd8ba5
handshake_secret: 7032215dfe771d18168271a8dd8c220098f6cfa6e63ccec7770
61f6e6b74acee646d655454ee28e1a089c2bcdf0659999d2b60782290b2a5a067d663
09ea1e46
server_mac_key: 4d9c9d82092b7a932d8ab42a9acfc7e08ce84c94eaa309c32321d
f90c5f93b093bdd8df15f573ec4d8952a1616d15127e270d97f9c638a6613187966e2
fa031a
client_mac_key: 7ee640a0a860b1751d67f5994a3db290a0afd928434d65c166f34
c73a245a7ab75d8ba15683f0701034f87d5c047f5082e138880fb37bec387c4863ba9
1c9750
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: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccb
accafb57ac5c36751ac5844383c7708077dea41cbefe2fa15724f449e535dd7dd562e
66f5ecfb95864eadddec9db5874959905117dad40a4524111849799281fefe3c51fa8
2785c5ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfe
c634b0f5b96109c198a8027da51854c35bee90d1e1c781806d07d49b76de6a28b8d9e
9b6c93b9f8b64d16dddd9c5bfb5fea48ee8fd2f75012a8b308605cdd8ba5
KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44d
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc6e29b
ee50701498605b2c085d7b241ca15ba5c32027dd21ba420b94ce60da326
KE2: 7e308140890bcde30cbcea28b01ea1ecfbd077cff62c4def8efa075aabcbb471
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dd6ec6
0bcdb26dc455ddf3e718f1020490c192d70dfc7e403981179d8073d1146a4f9aa1ced
4e4cd984c657eb3b54ced3848326f70331953d91b02535af44d9fedc80188ca46743c
52786e0382f95ad85c08f6afcd1ccfbff95e2bdeb015b166c6b20b92f832cc6df01e0
b86a7efd92c1c804ff865781fa93f2f20b446c8371b671cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a1c4f62198a9d6fa9170c42c3c71f197
1b29eb1d5d0bd733e40816c91f7912cc4aa47faa9314446793501f622f63a84db1bf5
b346d13f48d2f1a93902475e625fac1d0dea3ad473c0db2de94098b7142c5099758f8
568c98495d409b5a601b3e59
KE3: 2a5e2036d390f4c79e6d5a15ffa8ede52b8da7ff07b9a016a201f22f3420aaa3
3326ba6fe19b947f23cfbb8a2534b488cca31e35a2521e1ab7a49e299c82a07b
export_key: 1ef15b4fa99e8a852412450ab78713aad30d21fa6966c9b8c9fb3262a
970dc62950d4dd4ed62598229b1b72794fc0335199d9f7fcc6eaedde92cc04870e63f
16
session_key: db06b9d5d2c6034db948f58da84a6c5bdeaab7037adc338d7fada357
3c5dbcfe649c4f172615f97f63da944bee601abb69121203f0bf56cb7742efdd1afbb
21a
]]></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
client_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf
1091933541936304b
server_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a
1e85ff80da12f982f
blind_registration: 76cfbfe758db884bebb33582331ba9f159720ca8784a2a070
a265d9c2d6abe01
blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4
b0790308
]]></artwork>
          </section>
          <section anchor="intermediate-values-1">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccbac
cafb57ac5c3675
auth_key: 6cd32316f18d72a9a927a83199fa030663a38ce0c11fbaef82aa9003773
0494fc555c4d49506284516edd1628c27965b7555a4ebfed2223199f6c67966dde822
randomized_password: aac48c25ab036e30750839d31d6e73007344cb1155289fb7
d329beb932e9adeea73d5d5c22a0ce1952f8aba6d66007615cd1698d4ac85ef1fcf15
0031d1435d9
envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a3
8dfec1ac902dc5589e9a5f0de56ad685ea8486210ef41449cd4d8712828913c5d2b68
0b2b3af4a26c765cff329bfb66d38ecf1d6cfa9e7a73c222c6efe0d9520f7d7c
handshake_secret: ce0bce1d698443e07b85551d38654ddf2d9fa3791cab39c0ceb
84a87408d3189da191d5f28d994178c794a363c8b2431d66de8e6d048bf1afc09588a
1790017d
server_mac_key: 87212e945d15bd1ff230240795a0b09e1e1d42d7ce8b78fbe4bf5
6a60288ed64d8cd9e13a27537d3d06323fee990d994653809466a47b0786885f933c6
9f1c68
client_mac_key: c0f37b7c91f2d16b5466e55d27dbdf1f6727c2ee830b1bcd03cf4
7c4fc3b5520a166a0a21e9f12a4880555272153c77b97b3e534c327aea1b60e8b5d18
a14b9a
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: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccb
accafb57ac5c36751ac5844383c7708077dea41cbefe2fa15724f449e535dd7dd562e
66f5ecfb95864eadddec9db5874959905117dad40a4524111849799281fefe3c51fa8
2785c5ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfe
c1ac902dc5589e9a5f0de56ad685ea8486210ef41449cd4d8712828913c5d2b680b2b
3af4a26c765cff329bfb66d38ecf1d6cfa9e7a73c222c6efe0d9520f7d7c
KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44d
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc6e29b
ee50701498605b2c085d7b241ca15ba5c32027dd21ba420b94ce60da326
KE2: 7e308140890bcde30cbcea28b01ea1ecfbd077cff62c4def8efa075aabcbb471
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dd6ec6
0bcdb26dc455ddf3e718f1020490c192d70dfc7e403981179d8073d1146a4f9aa1ced
4e4cd984c657eb3b54ced3848326f70331953d91b02535af44d9fea502150b67fe367
95dd8914f164e49f81c7688a38928372134b7dccd50e09f8fed9518b7b2f94835b3c4
fe4c8475e7513f20eb97ff0568a39caee3fd6251876f71cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a1c4f62198a9d6fa9170c42c3c71f197
1b29eb1d5d0bd733e40816c91f7912cc4a376718206a20e4941b5423a1fb1603b8452
d3a2071b37132c9f9324b1cf160e10d40469f54d5f1c4a25f1ed1bb74dd5b87b27ae3
9a8b53e22382f2e45f156d74
KE3: d015536b2ecafb1a87f6ed057982cf73e75ec56a774549f672d59c0c4b7e3762
e0c6d8a2382ae855c8ef5240bbe1e404b8c455c03dc1a716d459f67828f0574f
export_key: 1ef15b4fa99e8a852412450ab78713aad30d21fa6966c9b8c9fb3262a
970dc62950d4dd4ed62598229b1b72794fc0335199d9f7fcc6eaedde92cc04870e63f
16
session_key: 494a13c9d02c5af791ce743e8c08abd0be287e4ddd32a1dcc93072a6
3b4109d67ae53fa3ae2d1333501a40dfbab630235688f3b000828f7084e5f4a6b3a10
48d
]]></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: ristretto255-SHA512
Hash: SHA512
KSF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: curve25519
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-2">
            <name>Input Values</name>
            <artwork><![CDATA[
oprf_seed: a78342ab84d3d30f08d5a9630c79bf311c31ed7f85d9d4959bf492ec67
a0eec8a67dfbf4497248eebd49e878aab173e5e4ff76354288fdd53e949a5f7c9f7f1
b
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cc
a9bf44d6e0b
masking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80
f612fdfc6d
server_private_key: c06139381df63bfc91c850db0b9cfbec7a62e86d80040a41a
a7725bf0e79d564
server_public_key: a41e28269b4e97a66468cc00c5a57753e192e1527669897706
88aa90486ef031
server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e
138e3d4a1
client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb38
0cae6a6cc
client_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf
1091933541936304b
server_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a
1e85ff80da12f982f
blind_registration: c575731ffe1cb0ca5ba63b42c4699767b8b9ab78ba39316ee
04baddb2034a70a
blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4
b0790308
]]></artwork>
          </section>
          <section anchor="intermediate-values-2">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 0936ea94ab030ec332e29050d266c520e916731a052d05ced7
e0cfe751142b48
auth_key: 7e880ab484f750e80e6f839d975aff476070ce65066d85ea62523d1d576
4739d91307fac47186a4ab935e6a5c7f70cb47faa9473311947502c022cc67ae9440c
randomized_password: 3a602c295a9c323d9362fe286f104567ed6862b25dbe30fa
da844f19e41cf40047424b7118e15dc2c1a815a70fea5c8de6c30aa61440cd4b4b5e8
f3963fbb2e1
envelope: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44
d6e0b20c1e81fef28e92e897ca8287d49a55075b47c3988ff0fff367d79a3e350ccac
150b4a3ff48b4770c8e84e437b3d4e68d2b95833f7788f7eb93fa6a8afb85ecb
handshake_secret: 6936d2b78f13d865997dd37c42c741dfe4c0297199e55d7f889
1fa4771ed2357e990b44faec69733c607b7541442b5f27ea01513b4f0b84545e0ff75
81ea7764
server_mac_key: 62a11be878ecfcbd7c8875e86a0f479befcb4b1742480c9ac2d2a
5fa8d9e96c3bf60edb953ba15e32dc3e2cba60029c0c61481fdc7a80946f596b77fff
6b18ee
client_mac_key: e646055bf0a395c6c7c61078dabe0f0026ec6ba079ddb70f11ec9
ba41e5ff70e37a87d8fbeca11d7dc22e2aacf2828de6e1d776b451fa1bd4419b0a6b5
9cc353
oprf_key: 62ef7f7d9506a14600c34f642aaf6ef8019cc82a6755db4fded5248ea14
6030a
]]></artwork>
          </section>
          <section anchor="output-values-2">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 26f3dbfd76b8e5f85b4da604f42889a7d4b1bc919f65538
1a67de02c59fd5436
registration_response: 506e8f1b89c098fb89b5b6210a05f7898cafdaea221761
e8d5272fc39e0f9f08a41e28269b4e97a66468cc00c5a57753e192e15276698977068
8aa90486ef031
registration_upload: 0936ea94ab030ec332e29050d266c520e916731a052d05ce
d7e0cfe751142b486d23c6ed818882f9bdfdcf91389fcbc0b7a3faf92bd0bd6be4a1e
7730277b694fc7c6ba327fbe786af18487688e0f7c148bbd54dc2fc80c28e7a976d9e
f53c3540d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0
b20c1e81fef28e92e897ca8287d49a55075b47c3988ff0fff367d79a3e350ccac150b
4a3ff48b4770c8e84e437b3d4e68d2b95833f7788f7eb93fa6a8afb85ecb
KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44d
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc10a83
b9117d3798cb2957fbdb0268a0d63dbf9d66bde5c00c78affd80026c911
KE2: 9a0e5a1514f62e005ea098b0d8cf6750e358c4389e6add1c52aed9500fa19d00
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d22cc3
1127d6f0096755be3c3d2dd6287795c317aeea10c9485bf4f419a786642c19a8f151c
eb5e8767d175248c62c017de94057398d28bf0ed00d1b50ee4f812fd9afddf98af8cd
58067ca43b0633b6cadd0e9d987f89623fed4d3583bdf6910c425600e90dab3c6b351
3188a465461a67f6bbc47aeba808f7f7e2c6d66f5c3271cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a141f55f0bef355cfb34ccd468fdacad
75865ee7efef95f4cb6c25d477f720502601bd116f3cb70f03d9cbc25d5606b8c5764
a1b9b11b28f2cbbd5630a836f9dbb2e7e8914639bca0fb9c99d58d42dfe3057cfe881
491b1d0812948aa4a7a7c7f7
KE3: 93a3c0da12392ad5336962e340b7c44ed445a67d61dae7bc5e2ccf891f6e9fac
6596f93350d3d559f7bbb182376a07ec7377e7966b7cc549fb8d0b6fb575f157
export_key: 9dec51d6d0f6ce7e4345f10961053713b07310cc2e45872f57bbd2fe5
070fdf0fb5b77c7ddaa2f3dc5c35132df7417ad7fefe0f690ad266e5a54a21d045c9c
38
session_key: a30c5ad775d0bc9aeb47757cc68a9332cb3acb7fc332ca07ba96d707
1847e492c8de3541997f97a605eb9b60cde6feb8dc57322e60ec42ae78c87a2e215e2
77f
]]></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: ristretto255-SHA512
Hash: SHA512
KSF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: curve25519
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-3">
            <name>Input Values</name>
            <artwork><![CDATA[
client_identity: 616c696365
server_identity: 626f62
oprf_seed: a78342ab84d3d30f08d5a9630c79bf311c31ed7f85d9d4959bf492ec67
a0eec8a67dfbf4497248eebd49e878aab173e5e4ff76354288fdd53e949a5f7c9f7f1
b
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cc
a9bf44d6e0b
masking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80
f612fdfc6d
server_private_key: c06139381df63bfc91c850db0b9cfbec7a62e86d80040a41a
a7725bf0e79d564
server_public_key: a41e28269b4e97a66468cc00c5a57753e192e1527669897706
88aa90486ef031
server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e
138e3d4a1
client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb38
0cae6a6cc
client_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf
1091933541936304b
server_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a
1e85ff80da12f982f
blind_registration: c575731ffe1cb0ca5ba63b42c4699767b8b9ab78ba39316ee
04baddb2034a70a
blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4
b0790308
]]></artwork>
          </section>
          <section anchor="intermediate-values-3">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 0936ea94ab030ec332e29050d266c520e916731a052d05ced7
e0cfe751142b48
auth_key: 7e880ab484f750e80e6f839d975aff476070ce65066d85ea62523d1d576
4739d91307fac47186a4ab935e6a5c7f70cb47faa9473311947502c022cc67ae9440c
randomized_password: 3a602c295a9c323d9362fe286f104567ed6862b25dbe30fa
da844f19e41cf40047424b7118e15dc2c1a815a70fea5c8de6c30aa61440cd4b4b5e8
f3963fbb2e1
envelope: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44
d6e0bb4c0eab6143959a650c5f6b32acf162b1fbe95bb36c5c4f99df53865c4d3537d
69061d80522d772cd0efdbe91f817f6bf7259a56e20b4eb9cbe9443702f4b759
handshake_secret: f5b8fa77a67e638114899eca80c3549aa2c8e277a3412bccbe0
a7e3943a5798d1e5ede2a847144759b17eb253f2f65efcccf82fe7b5f26e17175713d
be845786
server_mac_key: a8cdc5647342743be8ae6fc51e7105651b16bcb5fe4913834e7c2
139dbc06d84c75215e7e84e1785f431c925844eb8c9c0d14959239422368166f41485
e7847a
client_mac_key: b326230809ee373101e8b387aa33a865f7afa375f8c3e5a8fb592
b2e89e3117ccae85b0440421c75eb38a4ca4bde9355a549179b84748e21a3e378a3eb
538e37
oprf_key: 62ef7f7d9506a14600c34f642aaf6ef8019cc82a6755db4fded5248ea14
6030a
]]></artwork>
          </section>
          <section anchor="output-values-3">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 26f3dbfd76b8e5f85b4da604f42889a7d4b1bc919f65538
1a67de02c59fd5436
registration_response: 506e8f1b89c098fb89b5b6210a05f7898cafdaea221761
e8d5272fc39e0f9f08a41e28269b4e97a66468cc00c5a57753e192e15276698977068
8aa90486ef031
registration_upload: 0936ea94ab030ec332e29050d266c520e916731a052d05ce
d7e0cfe751142b486d23c6ed818882f9bdfdcf91389fcbc0b7a3faf92bd0bd6be4a1e
7730277b694fc7c6ba327fbe786af18487688e0f7c148bbd54dc2fc80c28e7a976d9e
f53c3540d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0
bb4c0eab6143959a650c5f6b32acf162b1fbe95bb36c5c4f99df53865c4d3537d6906
1d80522d772cd0efdbe91f817f6bf7259a56e20b4eb9cbe9443702f4b759
KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44d
da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc10a83
b9117d3798cb2957fbdb0268a0d63dbf9d66bde5c00c78affd80026c911
KE2: 9a0e5a1514f62e005ea098b0d8cf6750e358c4389e6add1c52aed9500fa19d00
38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d22cc3
1127d6f0096755be3c3d2dd6287795c317aeea10c9485bf4f419a786642c19a8f151c
eb5e8767d175248c62c017de94057398d28bf0ed00d1b50ee4f812699bff7663be3c5
d59de94d8e7e58817c7da005b39c25d25555c929e1c5cf6c1b82837b1367c839aab56
a422c0d97719426a79a16f9869cf852100597b23b5a071cd9960ecef2fe0d0f749498
6fa3d8b2bb01963537e60efb13981e138e3d4a141f55f0bef355cfb34ccd468fdacad
75865ee7efef95f4cb6c25d477f7205026816ce1eb529f8f3c6cec676d8c08f5ca760
c4322016850f329c4a2fb07364768a11a5380564d4cbceae511c873627c22c9ee9f05
488278de0fcf646f0825efdd
KE3: f6325cf6a7bd808fca69d54546ef61f2b5ec62fe8b96ca3c9b3e054841ab35ae
552bc5d8eea5ec840f56578be2cd2c30b52fa03266a2f4518cf764d9ced467ec
export_key: 9dec51d6d0f6ce7e4345f10961053713b07310cc2e45872f57bbd2fe5
070fdf0fb5b77c7ddaa2f3dc5c35132df7417ad7fefe0f690ad266e5a54a21d045c9c
38
session_key: 867930cba2b9988acfbe8289bffff728f7c799153be737c8a915ed98
647a7bc7a7f5f9c03deb797d36eda54de6015683a60e08f34e746e37514c4714d0644
99f
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-real-test-vector-5">
          <name>OPAQUE-3DH Real Test Vector 5</name>
          <section anchor="configuration-4">
            <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-4">
            <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
client_keyshare_seed: 633b875d74d1556d2a2789309972b06db21dfcc4f5ad51d
7e74d783b7cfab8dc
server_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a
1e85ff80da12f982f
blind_registration: 411bf1a62d119afe30df682b91a0a33d777972d4f2daa4b34
ca527d597078153
blind_login: c497fddf6056d241e6cf9fb7ac37c384f49b357a221eb0a802c989b9
942256c1
]]></artwork>
          </section>
          <section anchor="intermediate-values-4">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 03b218507d978c3db570ca994aaf36695a731ddb2db272c817
f79746fc37ae5214
auth_key: 5bd4be1602516092dc5078f8d699f5721dc1720a49fb80d8e5c16377abd
0987b
randomized_password: 06be0a1a51d56557a3adad57ba29c5510565dcd8b5078fa3
19151b9382258fb0
envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6567
0e51fad30bbcfc1f8eda0211553ab9aaf26345ad59a128e80188f035fe4924fad67b8
handshake_secret: 12f661f08a195208b2558d6c4c9fff5527a6af971087ce9eca8
00a77ca9c277a
server_mac_key: e07959284f64abd523651d0619d67cd5e026081671400af6282ff
bff85949d93
client_mac_key: d6672fd556c0811391bb48177255341979bfd0418c15169a62cb4
f18a40a37d6
oprf_key: 2dfb5cb9aa1476093be74ca0d43e5b02862a05f5d6972614d7433acdc66
f7f31
]]></artwork>
          </section>
          <section anchor="output-values-4">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 029e949a29cfa0bf7c1287333d2fb3dc586c41aa652f507
0d26a5315a1b50229f8
registration_response: 0350d3694c00978f00a5ce7cd08a00547e4ab5fb5fc2b2
f6717cdaa6c89136efef035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd
9f2092d6067784874
registration_upload: 03b218507d978c3db570ca994aaf36695a731ddb2db272c8
17f79746fc37ae52147f0ed53532d3ae8e505ecc70d42d2b814b6b0e48156def71ea0
29148b2803aafa921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6
5670e51fad30bbcfc1f8eda0211553ab9aaf26345ad59a128e80188f035fe4924fad6
7b8
KE1: 037342f0bcb3ecea754c1e67576c86aa90c1de3875f390ad599a26686cdfee6e
07ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1022
ed3f32f318f81bab80da321fecab3cd9b6eea11a95666dfa6beeaab321280b6
KE2: 0246da9fe4d41d5ba69faa6c509a1d5bafd49a48615a47a8dd4b0823cc147648
1138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d2f0
c547f70deaeca54d878c14c1aa5e1ab405dec833777132eea905c2fbb12504a67dcbe
0e66740c76b62c13b04a38a77926e19072953319ec65e41f9bfd2ae26837b6ce688bf
9af2542f04eec9ab96a1b9328812dc2f5c89182ed47fead61f09f71cd9960ecef2fe0
d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a103c1701353219b53acf33
7bf6456a83cefed8f563f1040b65afbf3b65d3bc9a19b037d9b23fea94aa69aff597a
63f2e8109064925589923667840390535d331279
KE3: c1252b9a0af176f5878b8f9b55934c2463ee7226d2b7d97cadfb901ca4a55b8f
export_key: c3c9a1b0e33ac84dd83d0b7e8af6794e17e7a3caadff289fbd9dc769a
853c64b
session_key: 1fc4d7b0d75bb02c36a9b10b563671967e27283c9fe0082fa16cfa94
a12151b2
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-real-test-vector-6">
          <name>OPAQUE-3DH Real Test Vector 6</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: 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
client_keyshare_seed: 633b875d74d1556d2a2789309972b06db21dfcc4f5ad51d
7e74d783b7cfab8dc
server_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a
1e85ff80da12f982f
blind_registration: 411bf1a62d119afe30df682b91a0a33d777972d4f2daa4b34
ca527d597078153
blind_login: c497fddf6056d241e6cf9fb7ac37c384f49b357a221eb0a802c989b9
942256c1
]]></artwork>
          </section>
          <section anchor="intermediate-values-5">
            <name>Intermediate Values</name>
            <artwork><![CDATA[
client_public_key: 03b218507d978c3db570ca994aaf36695a731ddb2db272c817
f79746fc37ae5214
auth_key: 5bd4be1602516092dc5078f8d699f5721dc1720a49fb80d8e5c16377abd
0987b
randomized_password: 06be0a1a51d56557a3adad57ba29c5510565dcd8b5078fa3
19151b9382258fb0
envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6567
0e51f4d7773a36a208a866301dbb2858e40dc5638017527cf91aef32d3848eebe0971
handshake_secret: 1546f3fb57232805f5d44afd97ade62d104f976261f631b5734
04b80fcac744f
server_mac_key: 04142fcb444d419a62fcdb5624dc3e31888146bcf4ab980f77445
cf43d4e61ae
client_mac_key: a93654bfe439ea07a85a944d650148cd0794d76341a74c8409f9c
01e7a91c2d3
oprf_key: 2dfb5cb9aa1476093be74ca0d43e5b02862a05f5d6972614d7433acdc66
f7f31
]]></artwork>
          </section>
          <section anchor="output-values-5">
            <name>Output Values</name>
            <artwork><![CDATA[
registration_request: 029e949a29cfa0bf7c1287333d2fb3dc586c41aa652f507
0d26a5315a1b50229f8
registration_response: 0350d3694c00978f00a5ce7cd08a00547e4ab5fb5fc2b2
f6717cdaa6c89136efef035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd
9f2092d6067784874
registration_upload: 03b218507d978c3db570ca994aaf36695a731ddb2db272c8
17f79746fc37ae52147f0ed53532d3ae8e505ecc70d42d2b814b6b0e48156def71ea0
29148b2803aafa921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf6
5670e51f4d7773a36a208a866301dbb2858e40dc5638017527cf91aef32d3848eebe0
971
KE1: 037342f0bcb3ecea754c1e67576c86aa90c1de3875f390ad599a26686cdfee6e
07ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1022
ed3f32f318f81bab80da321fecab3cd9b6eea11a95666dfa6beeaab321280b6
KE2: 0246da9fe4d41d5ba69faa6c509a1d5bafd49a48615a47a8dd4b0823cc147648
1138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d2f0
c547f70deaeca54d878c14c1aa5e1ab405dec833777132eea905c2fbb12504a67dcbe
0e66740c76b62c13b04a38a77926e19072953319ec65e41f9bfd2ae268d7f10604202
1c80300e4c6f585980cf39fc51a4a6bba41b0729f9b240c729e5671cd9960ecef2fe0
d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a103c1701353219b53acf33
7bf6456a83cefed8f563f1040b65afbf3b65d3bc9a19b606ebbf63c85a49acaa94b61
b9c5ad3d1c8368f5e73635df42c386d9dcb77c77
KE3: 690ab24fe2cb5889bc42426cce3445ee425fbd2f368c95aac23dfbee9729c788
export_key: c3c9a1b0e33ac84dd83d0b7e8af6794e17e7a3caadff289fbd9dc769a
853c64b
session_key: a2f482abd58500c560d0f4dbd6c6e55d573cfb350ade0a016f079dfe
e5f42657
]]></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-6">
            <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-6">
            <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
client_keyshare_seed: a270dc715dc2b4612bc7864312a05c3e9788ee1bad1f276
d1e15bdeb4c355e94
server_keyshare_seed: 360b0937f47d45f6123a4d8f0d0c0814b6120d840ebb8bc
5b4f6b62df07f78c2
masking_key: 39ebd51f0e39a07a1c2d2431995b0399bca9996c5d10014d6ebab445
3dc10ce5cef38ed3df6e56bfff40c2d8dd4671c2b4cf63c3d54860f31fe40220d690b
b71
KE1: b0a26dcaca2230b8f5e4b1bcab9c84b586140221bb8b2848486874b0be448905
42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0ab641d
7f20a245a09f1d4dbb6e301661af7f352beb0791d055e48d3645232f77f
]]></artwork>
          </section>
          <section anchor="output-values-6">
            <name>Output Values</name>
            <artwork><![CDATA[
KE2: 928f79ad8df21963e91411b9f55165ba833dea918f441db967cdc09521d22925
9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a632b5a
b1bff96636144faa4f9f9afaac75dd88ea99cf5175902ae3f3b2195693f165f11929b
a510a5978e64dcdabecbd7ee1e4380ce270e58fea58e6462d92964a1aaef72698bca1
c673baeb04cc2bf7de5f3c2f5553464552d3a0f7698a9ca7f9c5e70c6cb1f706b2f17
5ab9d04bbd13926e816b6811a50b4aafa9799d5ed7971e10f6eeab2a7a420bf09da9b
27a4639645622c46358de9cf7ae813055ae2d1298251c5ba55f6b0b2d58d9ff0c88fe
4176484be62a96db6e2a8c4d431bd1bf27e077203e6dc290083d0769a2e8d3c8755c8
5974c32294c6f9fa0adbb34b977472a794b9fb2bdacd6347c8f9d1e0a50b6e763f384
f32b42c8bc40ad608ba6135e
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-fake-test-vector-2">
          <name>OPAQUE-3DH Fake Test Vector 2</name>
          <section anchor="configuration-7">
            <name>Configuration</name>
            <artwork><![CDATA[
OPRF: ristretto255-SHA512
Hash: SHA512
KSF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: curve25519
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
]]></artwork>
          </section>
          <section anchor="input-values-7">
            <name>Input Values</name>
            <artwork><![CDATA[
client_identity: 616c696365
server_identity: 626f62
oprf_seed: 66e650652a8266b2205f31fdd68adeb739a05b5e650b19e7edc75e734a
1296d6088188ca46c31ae8ccbd42a52ed338c06e53645387a7efbc94b6a0449526155
e
credential_identifier: 31323334
masking_nonce: 9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c61
9e27b6e5a6
client_private_key: 288bf63470199221847bb035d99f96531adf8badd14cb1571
b48f7a506649660
client_public_key: 3c64a3153854cc9f0c23aab3c1a19106ec8bab4730736d1d00
3880a1d5a59005
server_private_key: 30fbe7e830be1fe8d2187c97414e3826040cbe49b893b6422
9bab5e85a588846
server_public_key: 78b3040047ff26572a7619617601a61b9c81899bee92f00cfc
aa5eed96863555
server_nonce: 1e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813
055ae2d12
client_keyshare_seed: a270dc715dc2b4612bc7864312a05c3e9788ee1bad1f276
d1e15bdeb4c355e94
server_keyshare_seed: 360b0937f47d45f6123a4d8f0d0c0814b6120d840ebb8bc
5b4f6b62df07f78c2
masking_key: 79ad2621b0757a447dff7108a8ae20a068ce67872095620f415ea611
c9dcc04972fa359538cd2fd6528775ca775487b2b56db642049b8a90526b975a38484
c6a
KE1: b0a26dcaca2230b8f5e4b1bcab9c84b586140221bb8b2848486874b0be448905
42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0ac059b
7ba2aec863933ae48816360c7a9022e83d822704f3b0b86c0502a66e574
]]></artwork>
          </section>
          <section anchor="output-values-7">
            <name>Output Values</name>
            <artwork><![CDATA[
KE2: 6606b6fedbb33f19a81a1feb5149c600fe77252f58acd3080d7504d3dad4922f
9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a67db39
8c0f65d8c298eac430abdae4c80e82b552fb940c00f0cbcea853c0f96c1c15099f3d4
b0e83ecc249613116d605b8d77bb68bdf76994c2bc507e2dcae4176f00afed68ad25c
f3040a0e991acece31ca532117f5c12816997372ff031ad04ebcdce06c501da24e7b4
db95343456e2ed260895ec362694230a1fa20e24a9c71e10f6eeab2a7a420bf09da9b
27a4639645622c46358de9cf7ae813055ae2d122d9055eb8f83e1b497370adad5cc2a
417bf9be436a792def0c7b7ccb92b9e27513c6a0d5d96e939563ad168990ed0156b8d
8fb82888ce111f217b1103b4c6d67ee9738777033dd0d85e39776993b5f1f7fa4252b
13a9c37c0fdd06204ca315c6
]]></artwork>
          </section>
        </section>
        <section anchor="opaque-3dh-fake-test-vector-3">
          <name>OPAQUE-3DH Fake Test Vector 3</name>
          <section anchor="configuration-8">
            <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-8">
            <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
client_keyshare_seed: a270dc715dc2b4612bc7864312a05c3e9788ee1bad1f276
d1e15bdeb4c355e94
server_keyshare_seed: 360b0937f47d45f6123a4d8f0d0c0814b6120d840ebb8bc
5b4f6b62df07f78c2
masking_key: caecc6ccb4cae27cb54d8f3a1af1bac52a3d53107ce08497cdd362b1
992e4e5e
KE1: 0396875da2b4f7749bba411513aea02dc514a48d169d8a9531bd61d3af3fa9ba
ae42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0a021
47a6583983cc9973b5082db5f5070890cb373d70f7ac1b41ed2305361009784
]]></artwork>
          </section>
          <section anchor="output-values-8">
            <name>Output Values</name>
            <artwork><![CDATA[
KE2: 0201198dcd13f9792eb75dcfa815f61b049abfe2e3e9456d4bbbceec5f442efd
049c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a6fac
da65ce0a97b9085e7af07f61fd3fdd046d257cbf2183ce8766090b8041a8bf28d79dd
4c9031ddc75bb6ddb4c291e639937840e3d39fc0d5a3d6e7723c09f7945df485bcf9a
efe3fe82d149e84049e259bb5b33d6a2ff3b25e4bfb7eff0962821e10f6eeab2a7a42
0bf09da9b27a4639645622c46358de9cf7ae813055ae2d12023f82bbb24e75b8683fd
13b843cd566efae996cd0016cffdcc24ee2bc937d026f459621ce1b4126bc75fb6114
1194c77ea9dc92d11aa1993f35336ccdbbcf13fc
]]></artwork>
          </section>
        </section>
      </section>
    </section>
  </back>
  <!-- ##markdown-source:
H4sIAAAAAAAAA+y9WXob2Zko+B6rCDMfDLoAJAkOopTO8qUoKqVUSmKJSjur
3GUxABwQUQQi4AiAFM2Wv95Db6DX0kvplfQ/nikCIKXMtOt2Xz2IJBBxxn8e
e71essyXM/MkfT816duz43/78TQ9rm/nc7Os8lF6dvzqND2rymU5KmdJNhxW
5vqJPJeMy1GRzeHdcZVNlr28Wk56o0l12SsX2V9Xpre7m4yzpXmSjOD/y7K6
fZLmxaRMknxRPUmX1apeDnZ2Hu8Mkitze1NW4yfpy2JpqsIse89wyCSpl1kx
/pDNygKmuTV1ssifpH+G1XTTuqyWlZnU8NvtHH/5zyTJVstpWT1J0l6Swr+8
qJ+kz/rp03JVjSvzN/qQl/wsK3IzC78x8yyfwW7+x/B2Cb/3KxMM9KKfvqqy
m9Hfbq+8gV6sLsvw87K6hMH/li3zsniSHs9g57CJ9Hm5Ksb0oT/ZFF6/grf/
xyX+3R+V82DOV/30B3OTe/O9Mtd54T4MJ3tTXufpO1ObrBpN/Wlm8Hz/Cl/t
X62Z6qSfHvfTP5Xl2JvtZFrl9bJcTE0VfBtOezIrV+PJLKtMF25w1PdnHsHe
piZb5MXlMF/WfbhcAAAAg2oOb18DdKTpy96z/pUcYQBBO3tPaKzPgFF6PKsu
zRIOd7lc1E++/hqOPVtW2ejKVP3cLCd9WP7XAL1fT5fz2dcMvWvmT2BAnKB3
bmZmRNv1V3Ty/N13vIBav08XVTkydZ1WZlHW+RLgvnVRl/lyuhriNXyNU369
yK5Mz46C8z4tb02x8ziYcOsFzvYkPcvqGlEmPQaQN8UyH9FdpOdmtKpMml1m
cKnL9KQq67p3ni9N+mMNd/hyvjBVXRb08BYNbHGG/vXkpwDFT31ehf2UweKn
7DqH0fgr+g4Gz02N9wqHUt0uluWsvLxNEfDfmCWs9IqXli9v087J8ZvzbXqN
6EOKVIA2/N3OfuPCgQTA7tJn+WSSm94LM5vNMzrk4czM798Bon9V3sQ7EPx/
B/gVPhC9Dg98l82yYhm9/64cmmqZntmvG6eA9wzXbBZVXiz7eTaqCOxgr/tf
7+0chtvfx/dPMkCOZb6zG974jwWgSVVns9ltCtACQJXB1mEuPk4gMWlhbtJF
VmXj/HKeAmqlI7qCyypbTPNRshDkqB9w47BhWUe8Yzh1/aax2Zenp6fp+S0u
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
AtPL8K9HWvwfUw1aGv0EAgA=

-->

</rfc>
