| RFC 9807 | OPAQUE | July 2025 |
| Bourdrez, et al. | Informational | [Page] |
This document describes the OPAQUE protocol, an Augmented (or Asymmetric)Password-Authenticated Key Exchange (aPAKE) protocol that supports mutualauthentication in a client-server setting without reliance on PKI andwith security against pre-computation attacks upon server compromise.In addition, the protocol provides forward secrecy and the ability tohide the password from the server, even during password registration.This document specifies the core OPAQUE protocol and one instantiationbased on 3DH. This document is a product of the Crypto Forum ResearchGroup (CFRG) in the IRTF.¶
This document is not an Internet Standards Track specification; it is published for informational purposes.¶
This document is a product of the Internet Research Task Force (IRTF). The IRTF publishes the results of Internet-related research and development activities. These results might not be suitable for deployment. This RFC represents the consensus of the Crypto Forum Research Group of the Internet Research Task Force (IRTF). Documents approved for publication by the IRSG are not candidates for any level of Internet Standard; see Section 2 of RFC 7841.¶
Information about the current status of this document, any errata, and how to provide feedback on it may be obtained athttps://www.rfc-editor.org/info/rfc9807.¶
Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document.¶
Password authentication is ubiquitous in many applications. In a commonimplementation, a client authenticates to a server by sending its clientID and password to the server over a secure connection. This makesthe password vulnerable to server mishandling, including accidentallylogging the password or storing it in plaintext in a database. Servercompromise resulting in access to these plaintext passwords is not anuncommon security incident, even among security-conscious organizations. Moreover, plaintext password authentication over secure channels such asTLS is also vulnerable in cases where TLS may fail, including PKIattacks, certificate mishandling, termination outside the securityperimeter, visibility to TLS-terminating intermediaries, and more.¶
Augmented (or Asymmetric) Password Authenticated Key Exchange (aPAKE)protocols are designed to provide password authentication andmutually authenticated key exchange in a client-server setting withoutrelying on PKI (except during client registration) and withoutdisclosing passwords to servers or other entities other than the clientmachine. A secure aPAKE should provide the best possible security for apassword protocol. Indeed, some attacks are inevitable, such asonline impersonation attempts with guessed client passwords and offlinedictionary attacks upon the compromise of a server and leakage of itscredential file. In the latter case, the attacker learns a mapping ofa client's password under a one-way function and uses such a mapping tovalidate potential guesses for the password. It is crucially important for the password protocol to use an unpredictable one-way mapping.Otherwise, the attacker can pre-compute a deterministic list of mappedpasswords leading to almost instantaneous leakage of passwords uponserver compromise.¶
This document describes OPAQUE, an aPAKE protocol that is secure againstpre-computation attacks (as defined in[JKX18]). OPAQUE provides forwardsecrecy with respect to password leakage while also hiding the password fromthe server, even during password registration. OPAQUE allows applicationsto increase the difficulty of offline dictionary attacks via iteratedhashing or other key-stretching schemes. OPAQUE is also extensible, allowingclients to safely store and retrieve arbitrary application data on serversusing only their password.¶
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 seenas a "compiler" for transforming any suitable AKE protocol into a secureaPAKE protocol. (SeeSection 10 for requirements of theOPRF and AKE protocols.) This document specifies one OPAQUE instantiationbased on[TripleDH]. Other instantiations are possible, as discussed inAppendix B, but their details are out of scope for this document.In general, the modularity of OPAQUE's design makes it easy to integrate withadditional AKE protocols, e.g., TLS or HMQV (Hashed Menezes-Qu-Vanstone), andwith future AKE protocols such as those based on post-quantum techniques.¶
OPAQUE consists of two stages: registration and authenticated key exchange.In the first stage, a client registers its password with the server and storesinformation used to recover authentication credentials on the server. Recovering thesecredentials can only be done with knowledge of the client password. In the secondstage, a client uses its password to recover those credentials and subsequentlyuses them as input to an AKE protocol. This stage has additional mechanisms toprevent an active attacker from interacting with the server to guess or confirmclients registered via the first phase. Servers can use this mechanism to safeguardregistered clients against this type of enumeration attack; seeSection 10.9 for more discussion.¶
The name "OPAQUE" is a homonym of O-PAKE, where O is for Oblivious. The name"OPAKE" was taken.¶
This document complies with the requirements for PAKE protocols set forth in[RFC8125]. This document represents the consensus of the Crypto ForumResearch Group (CFRG). It is not an IETF product and is not a standard.¶
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[RFC2119][RFC8174] when, and only when, they appear in all capitals, as shown here.¶
The following functions are used throughout this document:¶
concat(0x01, 0x0203, 0x040506) = 0x010203040506.¶n bytes.¶n bytes all equal to 0 (zero).¶xor(0xF0F0, 0x1234) = 0xE2C4. It is an error to call this function with arguments of unequal length.¶true ifa is equal tob, and false otherwise. The implementation of this function must be constant-time in the length ofa andb, which are assumed to be of equal length, irrespective of the valuesa orb.¶Except if said otherwise, random choices in this specification refer todrawing with uniform distribution from a given set (i.e., "random" is shortfor "uniformly random"). Random choices can be replaced with fresh outputs froma cryptographically strong pseudorandom generator, according to the requirementsin[RFC4086], or a pseudorandom function. For convenience, we definenil as alack of value.¶
All protocol messages and structures defined in this document use the syntax fromSection 3 of [RFC8446].¶
OPAQUE depends on the following cryptographic protocols and primitives:¶
Oblivious Pseudorandom Function (OPRF);Section 2.1¶
Key Derivation Function (KDF);Section 2.2¶
Message Authentication Code (MAC);Section 2.2¶
Cryptographic Hash Function;Section 2.3¶
Key Stretching Function (KSF);Section 2.3¶
This section describes these protocols and primitives in more detail. Unless saidotherwise, all random nonces andseeds used in these dependencies and the rest ofthe OPAQUE protocol are of lengthNn andNseed bytes, respectively, whereNn =Nseed = 32.¶
An Oblivious Pseudorandom Function (OPRF) is a two-party protocol betweenclient and server for computing a Pseudorandom Function (PRF), where the PRF key is held by the serverand the input to the function is provided by the client. The client does notlearn anything about the PRF other than the obtained output, and the serverlearns nothing about the client's input or the function output.This specification depends on the prime-order OPRF construction specifiedasmodeOPRF (0x00) fromSection 3.1 of [RFC9497].¶
The following OPRF client APIs are used:¶
blind,blinded_element), consisting of a blinded representation of inputelement, denotedblinded_element, along with a value to revert the blinding process, denotedblind. This is equivalent to the Blind function described inSection 3.3.1 of [RFC9497].¶element, random inverterblind, and evaluation outputevaluated_element, yielding outputoprf_output. This is equivalent to the Finalize function described inSection 3.3.1 of [RFC9497].¶Moreover, the following OPRF server APIs are used:¶
blinded_element using input keyk, yielding output elementevaluated_element. This is equivalent to the BlindEvaluate function described inSection 3.3.1 of [RFC9497], wherek is the private key parameter.¶sk,pk), consisting of a private and public key derived deterministically from an inputseed and inputinfo parameter, as described inSection 3.2 of [RFC9497].¶Finally, this specification makes use of the following shared APIs and parameters:¶
element to a fixed-length byte array.¶buf to an OPRF group element. This function can raise a DeserializeError upon failure; seeSection 2.1 of [RFC9497] for more details.¶A Key Derivation Function (KDF) is a function that takes some source of initialkeying material and uses it to derive one or more cryptographically strong keys.This specification uses a KDF with the following API and parameters:¶
Nx bytes from input keying materialikm and an optional byte stringsalt.¶prk, using the stringinfo, intoL bytes of output keying material.¶Nx:Extract() function in bytes.¶This specification also makes use of a random-key robust Message Authentication Code(MAC). SeeSection 10.6 for more details on this property. The API and parameters forthe random-key robust MAC are as follows:¶
This specification makes use of a collision-resistant hash function with the followingAPI and parameters:¶
msg, producing a fixed-length digest of sizeNh bytes.¶Nh:Hash() function in bytes.¶This specification makes use of a Key Stretching Function (KSF), which is a slowand expensive cryptographic hash function with the following API:¶
msg and harden it against offline dictionary attacks. This function also needs to satisfy collision resistance.¶OPAQUE consists of two stages: registration and authenticated key exchange (AKE).In the first stage, a client registers its password with the server and storesits credential file on the server. In the second stage (also called the"login" or "online" stage), the client recovers its authentication material and uses it toperform a mutually authenticated key exchange.¶
Prior to both stages, the client and server agree on a configuration thatfully specifies the cryptographic algorithm dependencies necessary to run theprotocol; seeSection 7 for details.The server chooses a pair of keys (server_private_key andserver_public_key)for the AKE protocol and chooses aseed (oprf_seed) ofNh bytes for the OPRF.The server can useserver_private_key andserver_public_key with multipleclients. The server can also opt to use a differentseed for each client(i.e., each client can be assigned a singleseed), so long as they are maintainedacross the registration and online AKE stages and kept consistent for eachclient (since an inconsistent mapping of clients toseeds could leak informationas described inSection 10.9).¶
Registration is the only stage in OPAQUE that requires a server-authenticatedchannel with confidentiality and integrity: either physical, out-of-band, PKI-based, etc.¶
The client inputs its credentials, which include its password and useridentifier, and the server inputs its parameters, which include its private keyand other information.¶
The client output of this stage is a single valueexport_key that the clientmay use for application-specific purposes, e.g., as a symmetric key used to encryptadditional information for storage on the server. The server does not have access to thisexport_key.¶
The server output of this stage is arecord corresponding to the client'sregistration that it stores in a credential file alongside other clientsregistrations as needed.¶
The registration flow is shown inFigure 1, and the process is described in more detail inSection 5:¶
credentials parameters | | v v Client Server ------------------------------------------------ registration request -------------------------> registration response <------------------------- record -------------------------> ------------------------------------------------ | | v v export_key record
These messages are namedRegistrationRequest,RegistrationResponse, andRegistrationRecord, respectively. Their contents and wire format are defined inSection 5.1.¶
In this second stage, a client obtains credentials previously registeredwith the server, recovers private key material using the password, andsubsequently uses them as input to the AKE protocol. As in the registrationphase, the client inputs its credentials, including its password and useridentifier, and the server inputs its parameters and the credential filerecordcorresponding to the client. The client outputs two values, anexport_key(matching that from registration) and asession_key, the latter of whichis the primary AKE protocol output. The server outputs a single valuesession_keythat matches that of the client. Upon completion, clients and servers canuse these values as needed.¶
The authenticated key exchange flow is shown inFigure 2:¶
credentials (parameters, record) | | v v Client Server ------------------------------------------------ AKE message 1 -------------------------> AKE message 2 <------------------------- AKE message 3 -------------------------> ------------------------------------------------ | | v v(export_key, session_key) session_key
These messages are namedKE1,KE2, andKE3, respectively. They carry themessages of the concurrent execution of the key recovery process (OPRF) and theauthenticated key exchange (AKE). Their corresponding wire formats arespecified inSection 6.1.¶
The rest of this document describes the specifics of these stages in detail.Section 4 describes how client credential information isgenerated, encoded, and stored on the server during registration and recovered duringlogin.Section 5 describes the first registration stage of the protocol,andSection 6 describes the second authentication stage of the protocol.Section 7 describes how to instantiate OPAQUE using differentcryptographic dependencies and parameters.¶
OPAQUE makes use of a structure calledEnvelope to manage client credentials.The client creates itsEnvelope on registration and sends it to the server forstorage. On every login, the server sends thisEnvelope to the client so it canrecover its key material for use in the AKE.¶
Applications may pin key material to identities if desired. If no identity is givenfor a party, its valueMUST default to its public key. The following types ofapplication credential information are considered:¶
client_private_key:client_public_key:server_public_key:client_identity:server_identity:A subset of these credential values are used in theCleartextCredentials structure as follows:¶
struct { uint8 server_public_key[Npk]; uint8 server_identity<1..2^16-1>; uint8 client_identity<1..2^16-1>;} CleartextCredentials;¶The function CreateCleartextCredentials constructs aCleartextCredentials structure givenapplication credential information.¶
CreateCleartextCredentialsInput:- 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 cleartext_credentials = CleartextCredentials { server_public_key, server_identity, client_identity } return cleartext_credentials¶This specification defines a key recovery mechanism that uses the stretched OPRFoutput as aseed to directly derive the private and public keys using theDeriveDiffieHellmanKeyPair() function defined inSection 6.4.1.¶
The key recovery mechanism defines itsEnvelope as follows:¶
struct { uint8 envelope_nonce[Nn]; uint8 auth_tag[Nm];} Envelope;¶Clients create anEnvelope at registration with the functionStore definedbelow. Note thatDeriveDiffieHellmanKeyPair in this function can fail with negligibleprobability. If this occurs, servers should re-run the function, sampling anewenvelope_nonce, to completion.¶
StoreInput:- 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, server_public_key, I2OSP(len(cleartext_credentials.server_identity), 2), cleartext_credentials.server_identity, I2OSP(len(cleartext_credentials.client_identity), 2), cleartext_credentials.client_identity )) envelope = Envelope { envelope_nonce, auth_tag } return (envelope, client_public_key, masking_key, export_key)¶Clients recover theirEnvelope during login with theRecover functiondefined below.¶
RecoverInput:- 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)¶
In the case ofEnvelopeRecoveryError being raised, all previously computedintermediary values in this functionMUST be deleted.¶
The registration process proceeds as follows. The client inputsthe following values:¶
The server inputs the following values:¶
server_public_key:credential_identifier:client_identity:oprf_seed:seed used to derive per-client OPRF keys.¶The registration protocol then runs as shown below:¶
Client Server ------------------------------------------------------ (request, blind) = CreateRegistrationRequest(password) request -------------------------> response = CreateRegistrationResponse(request, server_public_key, credential_identifier, oprf_seed) response <------------------------- (record, export_key) = FinalizeRegistrationRequest(password, blind, response, server_identity, client_identity) record ------------------------->¶
Section 5.1 describes the formats for the above messages, andSection 5.2 describes details of the functions and thecorresponding parameters referenced above.¶
At the end of this interaction, the server stores therecord object as thecredential file for each client along with the associatedcredential_identifierandclient_identity (if different). Note that the valuesoprf_seed andserver_private_key from the server's setup phase must also be persisted.Theoprf_seed valueSHOULD be used for all clients; seeSection 10.9for the justification behind this, along with a description of the exception in whichapplications may choose to avoid the use of a globaloprf_seed value across clientsand instead sample OPRF keys uniquely for each client. Theserver_private_key maybe unique for each client.¶
Both client and serverMUST validate the other party's public key before use.SeeSection 10.7 for more details. Upon completion, the server storesthe client's credentials for later use. Moreover, the clientMAY use the outputexport_key for further application-specific purposes; seeSection 10.4.¶
This section contains definitions of theRegistrationRequest,RegistrationResponse, andRegistrationRecord messages exchanged betweenclient and server during registration.¶
struct { uint8 blinded_message[Noe];} RegistrationRequest;¶struct { uint8 evaluated_message[Noe]; uint8 server_public_key[Npk];} RegistrationResponse;¶server_public_key:struct { uint8 client_public_key[Npk]; uint8 masking_key[Nh]; Envelope envelope;} RegistrationRecord;¶This section contains definitions of the functions used by client and serverduring registration, includingCreateRegistrationRequest,CreateRegistrationResponse,andFinalizeRegistrationRequest.¶
To begin the registration flow, the client executes the following function. This functioncan fail with anInvalidInputError error with negligible probability. A different inputpassword is necessary in the event of this error.¶
CreateRegistrationRequestInput:- password, an opaque byte string containing the client's password.Output:- request, a RegistrationRequest structure.- blind, an OPRF scalar value.Exceptions:- InvalidInputError, when Blind failsdef CreateRegistrationRequest(password): (blind, blinded_element) = Blind(password) blinded_message = SerializeElement(blinded_element) request = RegistrationRequest { blinded_message } return (request, blind)¶To process the client's registration request, the server executesthe following function. This function can fail with aDeriveKeyPairErrorerror with negligible probability. In this case, applications canchoose a newcredential_identifier for this registrationrecordand rerun this function.¶
CreateRegistrationResponseInput:- 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) response = RegistrationResponse { evaluated_message, server_public_key } return response¶To create the userrecord used for subsequent authentication and complete theregistration flow, the client executes the following function.¶
FinalizeRegistrationRequestInput:- 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) record = RegistrationRecord { client_public_key, masking_key, envelope } return (record, export_key)¶The generic outline of OPAQUE with a 3-message AKE protocol includes threemessages:KE1,KE2, andKE3.KE1 andKE2 include key exchange shares (e.g., DHvalues) sent by the client and server, respectively.KE3 provides explicitclient authentication and full forward security (without it, forward secrecyis only achieved against eavesdroppers, which is insufficient for OPAQUEsecurity).¶
This section describes the online authenticated key exchange protocol flow,message encoding, and helper functions. This stage is composed of a concurrentOPRF and key exchange flow. The key exchange protocol is authenticated using theclient and server credentials established during registration; seeSection 5.In the end, the client proves its knowledge of the password, and both client andserver agree on (1) a mutually authenticated shared secret key and (2) any optionalapplication information exchange during the handshake.¶
In this stage, the client inputs the following values:¶
The server inputs the following values:¶
server_private_key:server_public_key:server_identity:record:RegistrationRecord object corresponding to the client's registration.¶credential_identifier:oprf_seed:seed used to derive per-client OPRF keys.¶The client receives two outputs: a session secret and an export key. The exportkey is only available to the client and may be used for additionalapplication-specific purposes, as outlined inSection 10.4.ClientsMUST NOT use the outputexport_key beforeauthenticating the peer in the authenticated key exchange protocol.SeeAppendix A for more details about thisrequirement. The server receives a single output: a session secret matching theclient's.¶
The protocol runs as shown below:¶
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)¶
Both client and server may use implicit internal state objects to keep necessarymaterial for the OPRF and AKE,client_state, andserver_state, respectively.¶
The client stateClientState may have the following fields:¶
blind:Blind().¶ClientAkeState as defined inSection 6.4.¶The server stateServerState may have the following fields:¶
ServerAkeState as defined inSection 6.4.¶Both of these states are ephemeral and should be erased after the protocol completes.¶
The rest of this section describes these authenticated key exchange messagesand their parameters in more detail.Section 6.1 defines the structure of themessages passed between client and server in the above setup.Section 6.2describes details of the functions and corresponding parameters mentioned above.Section 6.3 discusses internal functions used for retrieving clientcredentials, andSection 6.4 discusses how these functions are used to executethe authenticated key exchange protocol.¶
In this section, we define theKE1,KE2, andKE3 structs that make upthe AKE messages used in the protocol.KE1 is composed of aCredentialRequestandAuthRequest, andKE2 is composed of aCredentialResponseandAuthResponse.¶
struct { uint8 client_nonce[Nn]; uint8 client_public_keyshare[Npk];} AuthRequest;¶Nn.¶Npk.¶struct { CredentialRequest credential_request; AuthRequest auth_request;} KE1;¶struct { uint8 server_nonce[Nn]; uint8 server_public_keyshare[Npk]; uint8 server_mac[Nm];} AuthResponse;¶Nn.¶server_public_keyshare:Npk, whereNpk depends on the corresponding prime order group.¶Km2, which is defined below.¶struct { CredentialResponse credential_response; AuthResponse auth_response;} KE2;¶struct { uint8 client_mac[Nm];} KE3;¶Nm, computed usingKm2, defined below.¶In this section, we define the main functions used to produce the AKE messagesin the protocol. Note that this section relies on definitions of subroutines definedin later sections:¶
CreateCredentialRequest,CreateCredentialResponse, andRecoverCredentials are defined inSection 6.3.¶
AuthClientStart,AuthServerRespond,AuthClientFinalize, andAuthServerFinalize aredefined in Sections6.4.3 and6.4.4.¶
TheGenerateKE1 function begins the AKE protocol and produces the client'sKE1output for the server.¶
GenerateKE1State:- 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¶
TheGenerateKE2 function continues the AKE protocol by processing the client'sKE1 messageand producing the server'sKE2 output.¶
GenerateKE2State:- 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) ke2 = KE2 { credential_response, auth_response } return ke2¶TheGenerateKE3 function completes the AKE protocol for the client andproduces the client'sKE3 output for the server, as well as thesession_keyandexport_key outputs from the AKE.¶
GenerateKE3State:- 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, 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)¶
TheServerFinish function completes the AKE protocol for the server, yielding thesession_key.Since the OPRF is a two-message protocol,KE3 has no element of the OPRF. Therefore,KE3invokes the AKE'sAuthServerFinalize directly. TheAuthServerFinalize functiontakesKE3 as input andMUST verify the client authentication material it containsbefore thesession_key value can be used. This verification is necessary to ensureforward secrecy against active attackers.¶
ServerFinishState:- 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)¶
This functionMUST NOT return thesession_key value if the client authenticationmaterial is invalid and may instead return an appropriate error message, such asClientAuthenticationError, which is invoked fromAuthServerFinalize.¶
This section describes the sub-protocol run during authentication to retrieve andrecover the client credentials.¶
This section describes theCredentialRequest andCredentialResponse messages exchangedbetween client and server to perform credential retrieval.¶
struct { uint8 blinded_message[Noe];} CredentialRequest;¶struct { uint8 evaluated_message[Noe]; uint8 masking_nonce[Nn]; uint8 masked_response[Npk + Nn + Nm];} CredentialResponse;¶This section describes theCreateCredentialRequest,CreateCredentialResponse,andRecoverCredentials functions used for credential retrieval.¶
TheCreateCredentialRequest is used by the client to initiate the credentialretrieval process, and it produces aCredentialRequest message and OPRF state.LikeCreateRegistrationRequest, this function can fail with anInvalidInputErrorerror with negligible probability. However, this should not occur sinceregistration (viaCreateRegistrationRequest) will fail when provided the samepassword input.¶
CreateCredentialRequestInput:- password, an opaque byte string containing the client's password.Output:- request, a CredentialRequest structure.- blind, an OPRF scalar value.Exceptions:- InvalidInputError, when Blind failsdef CreateCredentialRequest(password): (blind, blinded_element) = Blind(password) blinded_message = SerializeElement(blinded_element) request = CredentialRequest { blinded_message } return (request, blind)¶TheCreateCredentialResponse function is used by the server to process the client'sCredentialRequest message and complete the credential retrieval process, producingaCredentialResponse.¶
There are two scenarios to handle for the construction of aCredentialResponseobject: either therecord for the client exists (corresponding to a properlyregistered client) or it was never created (corresponding to an unregisteredclient identity, possibly the result of an enumeration attack attempt).¶
In the case of an existingrecord with the corresponding identifiercredential_identifier, the server invokes the following function toproduce aCredentialResponse:¶
CreateCredentialResponseInput:- 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)) response = CredentialResponse { evaluated_message, masking_nonce, masked_response } return response¶In the case of arecord that does not exist and if client enumeration prevention is desired,the serverMUST respond to the credential request to fake the existence of therecord.The serverSHOULD invoke theCreateCredentialResponse function with a fake clientrecordargument that is configured so that:¶
record.client_public_key is set to a randomly generated public key of lengthNpk¶
record.masking_key is set to a random byte string of lengthNh¶
record.envelope is set to the byte string consisting only of zeros of lengthNn + Nm¶
It isRECOMMENDED that a fake clientrecord is created once (e.g., as the first userrecordof the application) and then stored alongside legitimate clientrecords to servesubsequent client requests. This allows servers to retrieve therecord in a time comparableto that of a legitimate clientrecord.¶
Note that the responses output by either scenario are indistinguishable to an adversarythat is unable to guess the registered password for the client corresponding tocredential_identifier.¶
TheRecoverCredentials function is used by the client to process the server'sCredentialResponse message and produce the client's private key, server publickey, and theexport_key.¶
RecoverCredentialsInput:- 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.- 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, export_key)¶This section describes the authenticated key exchange protocol for OPAQUE using3DH, a 3-message AKE that satisfies the forward secrecy and KCI propertiesdiscussed inSection 10.¶
The client AKE stateClientAkeState mentioned inSection 6 has thefollowing fields:¶
The server AKE stateServerAkeState mentioned inSection 6 has thefollowing fields:¶
Nm.¶session_key:Nx.¶Sections6.4.3 and6.4.4 specify the inner workings of client andserver functions, respectively.¶
We assume the following functions exist for all Diffie-Hellman key exchangevariants:¶
seed. The type of the private key depends on the implementation, whereas the type of the public key is a byte string ofNpk bytes.¶k and public inputB. The output of this function is a unique, fixed-length byte string.¶It isRECOMMENDED to use Elliptic Curve Diffie-Hellman for this key exchange protocol.Implementations for recommended groups inSection 7, as well as groupscovered by test vectors inAppendix C, are described in the following sections.¶
This section describes the implementation of the Diffie-Hellman key exchange functions based on ristretto255as defined in[RFC9496].¶
B from its encoded input using the Decode function inSection 4.3.1 of [RFC9496]. The output is then encoded using the SerializeElement function of the OPRF group described inSection 2.1 of [RFC9497].¶This section describes the implementation of the Diffie-Hellman key exchange functions based on NIST P-256as defined in[NISTCurves].¶
B from its encoded input using the compressed Octet-String-to-Elliptic-Curve-Point method according to[NISTCurves]. The output is then encoded using the SerializeElement function of the OPRF group described inSection 2.1 of [RFC9497].¶This section describes the implementation of the Diffie-Hellman key exchange functions based on Curve25519as defined in[RFC7748].¶
k based onseed (of lengthNseed = 32 bytes) as described inSection 5 of [RFC7748], as well as the result of DiffieHellman(k, B), where B is the base point of Curve25519.¶This section contains functions used for the AKE key schedule.¶
The OPAQUE-3DH key derivation procedures make use of the functions below that are repurposed from TLS 1.3[RFC8446].¶
Expand-Label(Secret, Label, Context, Length) = Expand(Secret, CustomLabel, Length)¶
Where CustomLabel is specified and encoded (followingSection 3.4 of [RFC8446]) as:¶
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)¶Note that theLabel parameter is not a NULL-terminated string.¶
OPAQUE-3DH can optionally include application-specific, sharedcontext information in thetranscript, such as configuration parameters or application-specific information, e.g.,"appXYZ-v1.2.3".¶
The OPAQUE-3DH key schedule requires apreamble, which is computed as follows.¶
PreambleParameters:- 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, credential_response, server_nonce, server_public_keyshare): preamble = concat("OPAQUEv1-", 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¶The OPAQUE-3DH shared secret derived during the key exchange protocol iscomputed using the following helper function.¶
DeriveKeysInput:- 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)¶TheAuthClientStart function is used by the client to create aKE1 structure.¶
AuthClientStartParameters:- 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) auth_request = AuthRequest { client_nonce, client_public_keyshare } ke1 = KE1 { credential_request, auth_request } state.client_secret = client_secret state.ke1 = ke1 return ke1¶TheAuthClientFinalize function is used by the client to create aKE3message and outputsession_key using the server'sKE2 message andrecovered credential information.¶
AuthClientFinalizeState:- 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.auth_response.server_mac, expected_server_mac), raise ServerAuthenticationError client_mac = MAC(Km3, Hash(concat(preamble, expected_server_mac))) ke3 = KE3 { client_mac } return (ke3, session_key)¶TheAuthServerRespond function is used by the server to process the client'sKE1 message and public credential information to create aKE2 message.¶
AuthServerRespondParameters:- 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)) state.expected_client_mac = MAC(Km3, Hash(concat(preamble, server_mac))) state.session_key = session_key auth_response = AuthResponse { server_nonce, server_public_keyshare, server_mac } return auth_response¶TheAuthServerFinalize function is used by the server to process the client'sKE3 message and output the finalsession_key.¶
AuthServerFinalizeState:- 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¶
An OPAQUE-3DH configuration is a tuple (OPRF, KDF, MAC, Hash, KSF, Group, Context)such that the following conditions are met:¶
The OPRF protocol uses themodeOPRF configuration inSection 3.1 of [RFC9497] andimplements the interface inSection 2. Examples include ristretto255-SHA512and P256-SHA256.¶
The KDF, MAC, and Hash functions implement the interfaces inSection 2.Examples include HKDF[RFC5869] for the KDF, HMAC[RFC2104] for the MAC,and SHA-256 and SHA-512 for the Hash functions. If an extensible output functionsuch as SHAKE128[FIPS202] is used, then the output lengthNhMUST be chosento align with the target security level of the OPAQUE configuration. For example,if the target security parameter for the configuration is 128 bits, thenNhSHOULDbe at least 32 bytes.¶
The KSF is determined by the application and implements the interface inSection 2. As noted, collision resistance is required. Examples for KSFinclude Argon2id[RFC9106], scrypt[RFC7914], and PBKDF2[RFC8018] with fixed parameter choices. SeeSection 8for more information about this choice of function.¶
The Group mode identifies the group used in the OPAQUE-3DH AKE. ThisSHOULDmatch that of the OPRF. For example, if the OPRF is ristretto255-SHA512,then GroupSHOULD be ristretto255.¶
Context is the shared parameter used to construct thepreamble inSection 6.4.2.1.This parameterSHOULD include any application-specific configuration information orparameters that are needed to prevent cross-protocol or downgrade attacks.¶
Absent an application-specific profile, the following configurations areRECOMMENDED:¶
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¶
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¶
P256-SHA256, HKDF-SHA-256, HMAC-SHA-256, SHA-256, scrypt(S = zeroes(16), N = 32768, r = 8, p = 1, dkLen = 32), P-256¶
The above recommended configurations target 128-bit security.¶
Future configurations may specify different combinations of dependent algorithmswith the following considerations:¶
The size of AKE public and private keys --Npk andNsk, respectively -- must adhereto the output length limitations of the KDF Expand function. If HKDF is used, this meansNpk,Nsk <= 255 *Nx, whereNx is the output size of the underlying hash function.See[RFC5869] for details.¶
The output size of the Hash functionSHOULD be long enough to produce a key forMAC of suitable length. For example, if MAC is HMAC-SHA256, thenNh could be32 bytes.¶
Beyond choosing an appropriate configuration, there are several parameters that applications can use to control OPAQUE:¶
Credential identifier: As described inSection 5, this is a uniquehandle to the client's credential being stored. In applications where there are alternateclient identities that accompany an account, such as a username or email address, thisidentifier can be set to those alternate values. For simplicity, applications may chooseto setcredential_identifier to be equal toclient_identity. ApplicationsMUST NOT use the same credential identifier for multiple clients.¶
Context information: As described inSection 7, applications may includea sharedcontext string that is authenticated as part of the handshake. This parameterSHOULD include any configuration information or parameters that are needed to preventcross-protocol or downgrade attacks. Thiscontext information is not sent over thewire in any key exchange messages. However, applications may choose to send it alongsidekey exchange messages if needed for their use case.¶
Client and server identities: As described inSection 4, clientsand servers are identified with their public keys by default. However, applicationsmay 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. Absentalternate notions of identity, applicationsSHOULD set these identities to niland rely solely on public key information.¶
Configuration and envelope updates: Applications may wish to update or change theirconfiguration or other parameters that affect the client'sRegistrationRecord overtime. 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 iscryptographically bound to theRegistrationRecord, such as the server's public key(server_public_key). Any such change will require users to reregister to create anewRegistrationRecord. Supporting these types of updates can be helpful for applicationsthat anticipate such changes in their deployment setting.¶
Password hardening parameters: Key stretching is done to help prevent password disclosurein the event of server compromise; seeSection 10.8. There is no ideal or defaultset of parameters, though relevant specifications for KSFs give some reasonabledefaults.¶
Enumeration prevention: If serversreceive a credential request for a non-existent client, theySHOULD respond with a"fake" response to prevent active client enumeration attacks as described inSection 6.3.2.2. Servers thatimplement this mitigationSHOULD use the same configuration information (such astheoprf_seed) for all clients; seeSection 10.9. In settingswhere this attack is not a concern, servers may choose to not support this functionality.¶
Handling password changes: In the event of a password change, the client andserver can run the registration phase using the new password as afresh instance (ensuring to resample all random values). The resultingregistrationrecord can then replace the previousrecord corresponding tothe client's old password registration.¶
This section documents considerations for OPAQUE implementations. This includesimplementation safeguards and error handling considerations.¶
Certain information created, exchanged, and processed in OPAQUE is sensitive.Specifically, all private key material and intermediate values, along with theoutputs of the key exchange phase, are all secret. Implementations should notretain these values in memory when no longer needed. Moreover, all operations,particularly the cryptographic and group arithmetic operations, should beconstant-time and independent of the bits of any secrets. This includes anyconditional branching during the creation of the credential response as neededto mitigate client enumeration attacks.¶
As specified inSection 5 andSection 6, OPAQUE only requiresthe client password as input to the OPRF for registration and authentication.However, ifclient_identity can be bound to the client's registrationrecord(i.e., the identity will not change during the lifetime of therecord),then an implementationSHOULD incorporateclient_identity alongside thepassword as input to the OPRF. Furthermore, it isRECOMMENDED to incorporateserver_identity alongside the password as input to the OPRF. Theseadditions provide domain separation for clients and servers; seeSection 10.2.¶
Online guessing attacks (against any aPAKE) can be done fromboth the client side and the server side. In particular, a malicious server canattempt to simulate honest responses to learn the client's password.While this constitutes an exhaustive online attack (as expensive as a guessingattack from the client side), it can be mitigated when the channel betweenclient and server is authenticated, e.g., using server-authenticated TLS. Insuch cases, these online attacks are limited to clients and the authenticatedserver itself. Moreover, such a channel provides privacy of user information,including identity and envelope values.¶
Additionally, note that a client participating in the online login stagewill learn whether or not authentication is successful after receiving theKE2 message. This means that the server should treat any client which fails tosend a subsequentKE3 message as an authentication failure. This can be handledin applications that wish to track authentication failures by, for example,assuming by default that any client authentication attempt is a failure unless aKE3message is received by the server and passesServerFinish without error.¶
Some functions included in this specification are fallible. For example, theauthenticated key exchange protocol may fail because the client's password wasincorrect or the authentication check failed, yielding an error. The expliciterrors generated throughout this specification, along with conditions that leadto each error, are as follows:¶
EnvelopeRecoveryError: TheEnvelopeRecover function failed to produce anyauthentication key material;Section 4.1.3.¶
ServerAuthenticationError: The client failed to complete the authenticatedkey exchange protocol with the server;Section 6.4.3.¶
ClientAuthenticationError: The server failed to complete the authenticatedkey exchange protocol with the client;Section 6.4.4.¶
Beyond these explicit errors, OPAQUE implementations can produce implicit errors.For example, if protocol messages sent between client and server do not matchtheir expected size, an implementation should produce an error. More generally,if any protocol message received from the peer is invalid, perhaps because themessage contains an invalid public key (indicated by the AKE DeserializeElementfunction failing) or an invalid OPRF element (indicated by the OPRF DeserializeElement),then an implementation should produce an error.¶
The errors in this document are meant as a guide for implementors. They are not anexhaustive list of all the errors an implementation might emit. For example, animplementation might run out of memory.¶
OPAQUE is defined as the composition of two functionalities: an OPRF andan AKE protocol. It can be seen as a "compiler" for transforming any AKEprotocol (with Key Compromise Impersonation (KCI) security and forward secrecy; seeSection 10.2)into a secure aPAKE protocol. In OPAQUE, the client derives a private keyduring password registration and retrieves this key each timeit needs to authenticate to the server. The OPRF security propertiesensure that only the correct password can unlock the private keywhile at the same time avoiding potential offline guessing attacks.This general composability property provides great flexibility andenables a variety of OPAQUE instantiations, from optimizedperformance to integration with existing authenticated key exchangeprotocols such as TLS.¶
The specification as written here differs from the original cryptographic design in[JKX18]and the corresponding CFRG document[Krawczyk20], both of which were usedas input to the CFRG PAKE competition. This section describes these differences, includingtheir motivation and explanation as to why they preserve the provable security of OPAQUE basedon[JKX18].¶
The following list enumerates important functional differences that were madeas part of the protocol specification process to address application orimplementation considerations.¶
Clients construct envelope contents without revealing the password to theserver, as described inSection 5, whereas the servers constructenvelopes in[JKX18]. This change adds to the security of the protocol.[JKX18] considered the case where the envelope was constructed by theserver for reasons of compatibility with previous Universal Composability (UC) security modeling.[HJKW23]analyzes the registration phase as specified in this document. Thischange was made to support registration flows where the client chooses thepassword and wishes to keep it secret from the server, and it is compatiblewith the variant in[JKX18] that was originally analyzed.¶
Envelopes do not contain encrypted credentials. Instead, envelopes containinformation used to derive client private key material for the AKE.This change improves the assumption behind the protocol by getting rid ofequivocality and random key robustness for the encryption function.The random-key robustness property defined inSection 2.2 is onlyneeded for the MAC function. This change was made for two reasons. First, itreduces the number of bytes stored in envelopes, which is a helpfulimprovement for large applications of OPAQUE with many registered users.Second, it removes the need for client applications to generate privatekeys during registration. Instead, this responsibility is handled by OPAQUE,thereby simplifying the client interface to the protocol.¶
Envelopes are masked with a per-user masking key as a way of preventingclient enumeration attacks. SeeSection 10.9 for moredetails. This extension is not needed for the security of OPAQUE as an aPAKE protocol,but is only used to provide a defense against enumeration attacks. In theanalysis, the masking key can be simulated as a (pseudo) random key. Thischange was made to support real-world use cases where client or userenumeration is a security (or privacy) risk.¶
Per-user OPRF keys are derived from a client identity and cross-user PRFseedas a mitigation against client enumeration attacks. SeeSection 10.9 for more details. The analysis of OPAQUEassumes OPRF keys of different users are independently random orpseudorandom. Deriving these keys via a single PRF (i.e., with a singlecross-user key) applied to users' identities satisfies this assumption.This change was made to support real-world use cases where client or userenumeration is a security (or privacy) risk. Note that the derivation of theOPRF key via a PRF keyed byoprf_seed and applied to the uniquecredential_identifier ensures the critical requirement of the per-user OPRF keysbeing unique per client.¶
The protocol outputs an export key for the client in addition to a sharedsession key that can be used for application-specific purposes. This keyis a pseudorandom value derived from the client password (among other values) andhas no influence on the security analysis (it can be simulated with arandom output). This change was made to support more application use casesfor OPAQUE, such as the use of OPAQUE for end-to-end encrypted backups;see[WhatsAppE2E].¶
The AKE protocol describes a 3-message protocol where the third message includes clientauthentication material that the server is required to verify. This change(from the original 2-message protocol) was made to provide explicit clientauthentication and full forward security. The 3-message protocol is analyzedin[JKX18].¶
The protocol admits optional application-layer client and server identities.In the absence of these identities, the client and server are authenticatedagainst their public keys. Binding authentication to identities is partof the AKE part of OPAQUE. The type of identities and their semanticsare application-dependent and independent of the protocol analysis. Thischange was made to simplify client and server interfaces to the protocolby removing the need to specify additional identities alongside theircorresponding public authentication keys when not needed.¶
The protocol admits application-specificcontext information configuredout-of-band in the AKE transcript. This allows domain separation betweendifferent application uses of OPAQUE. This is a mechanism for the AKEcomponent and is best practice for domain separation between differentapplications of the protocol. This change was made to allow differentapplications to use OPAQUE without the risk of cross-protocol attacks.¶
Servers use a separate identifier for computing OPRF evaluations andindexing into the registrationrecord storage called thecredential_identifier.This allows clients to change their application-layer identity(client_identity) without inducing server-side changes, e.g., by changingan email address associated with a given account. This mechanism is partof the derivation of OPRF keys via a single PRF. As long as the derivationof different OPRF keys from a single PRF has different PRF inputs, theprotocol is secure. The choice of such inputs is up to the application.¶
[JKX18] comments on a defense against offlinedictionary attacks upon server compromise or honest-but-curious servers. The authors suggest implementing the OPRF phase as a threshold OPRF[TOPPSS], effectively forcing an attacker to act online or control at least t key shares (of the total n), where t is the threshold number of shares necessary to recombine the secret OPRF key. Only then would an attacker 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 dictionary attack without access to the clientrecord database. However, this mechanism is out of scope for this document.¶
The following list enumerates notable differences and refinements from the originalcryptographic design in[JKX18] and the corresponding CFRG document[Krawczyk20] that were made to make this specificationsuitable for interoperable implementations.¶
[JKX18] used a generic prime-order group for the DH-OPRF and HMQV operations,and includes necessary prime-order subgroup checks when receiving attacker-controlledvalues over the wire. This specification instantiates the prime-order group used for3DH using prime-order groups based on elliptic curves as described inSection 2.1 of [RFC9497]. This specification also delegates OPRF groupchoice and operations toSection 4 of [RFC9497]. As such, the prime-order group as usedin the OPRF and 3DH as specified in this document both adhere to the requirements in[JKX18].¶
Appendix B of[JKX18] specified DH-OPRF to instantiatethe OPRF functionality in the protocol. A critical part of DH-OPRF is thehash-to-group operation, which was not instantiated in the original analysis.However, the requirements for this operation were included. This specificationinstantiates the OPRF functionality based onSection 3.3.1 of [RFC9497], whichis identical to the DH-OPRF functionality in[JKX18] and, concretely, usesthe hash-to-curve functions in[RFC9380]. All hash-to-curvemethods in[RFC9380] are compliant with the requirementin[JKX18], namely, that the output be a member of the prime-order group.¶
[JKX18] and[Krawczyk20] both used HMQV as the AKEfor the protocol. However, this document fully specifies 3DH instead of HMQV(though a sketch for how to instantiate OPAQUE using HMQV is included inAppendix B.1).Since 3DH satisfies the essential requirements for the AKE protocol as described in[JKX18]and[Krawczyk20], as recalled inSection 10.2, this changepreserves the overall security of the protocol. 3DH was chosen for itssimplicity and ease of implementation.¶
The DH-OPRF and HMQV instantiation of OPAQUE as shown in Figure 12[JKX18] usesa different transcript than that which is described in this specification. In particular,the key exchange transcript specified inSection 6.4 is a superset of the transcriptas defined in[JKX18]. This was done to align with best practices, like what is done for key exchange protocols like TLS 1.3[RFC8446].¶
Neither[JKX18] nor[Krawczyk20] included wire format details for theprotocol, which is essential for interoperability. This specification fills thisgap by including such wire format details and corresponding test vectors; seeAppendix C.¶
Jarecki et al. [JKX18] proved the security of OPAQUE (modulo thedesign differences outlined inSection 10.1)in a strong aPAKE model that ensures security against precomputation attacksand is formulated in the UC framework[Canetti01]under the random oracle model. This assumes security of the OPRFfunction and the underlying key exchange protocol.¶
OPAQUE's design builds on a line of work initiated in the seminalpaper of Ford and Kaliski[FK00] and is based on the HPAKE protocolof Xavier Boyen[Boyen09] and the (1,1)-PPSS protocol from Jareckiet al. [JKKX16]. None of these papers considered security againstprecomputation attacks or presented a proof of aPAKE security(not even in a weak model).¶
The KCI property required from AKE protocols for use with OPAQUEstates that knowledge of a party's private key does not allow an attackerto impersonate others to that party. This is an important securityproperty achieved by most public-key-based AKE protocols, includingprotocols that use signatures or public key encryption forauthentication. It is also a property of many implicitlyauthenticated protocols, e.g., HMQV, but not all of them. We also note thatkey exchange protocols based on shared keys do not satisfy the KCIrequirement, hence they are not considered in the OPAQUE setting.We note that KCI is needed to ensure a crucial property of OPAQUE. Even uponcompromise of the server, the attacker cannot impersonate the client to theserver without first running an exhaustive dictionary attack.Another essential requirement from AKE protocols for use in OPAQUE is toprovide forward secrecy (against active attackers).¶
In[JKX18], security is proven for one instance (i.e., onekey) of the OPAQUE protocol, and without batching. There is currently nosecurity analysis available for the OPAQUE protocol described in thisdocument in a setting with multiple server keys or batching.¶
As stated inSection 9.1, incorporatingclient_identityadds domain separation, particularly against servers that choose the sameOPRF key for multiple clients. Theclient_identity as input to the OPRFalso acts as a key identifier that would be required for a proof of theprotocol in the multi-key setting; the OPAQUE analysis in[JKX18] assumessingle server-key instances. Addingserver_identity to the OPRF inputprovides domain separation for clients that reuse the sameclient_identityacross different server instantiations.¶
AKE protocols generate keys that need to be uniquely and verifiably bound to a pairof identities. In the case of OPAQUE, those identities correspond toclient_identity andserver_identity.Thus, it is essential for the parties to agree on such identities, including anagreed bit representation of these identities as needed.¶
Note that the method of transmission ofclient_identity from client to server is outsidethe scope of this protocol and it is up to an application to choose how this identityshould be delivered (for instance, alongside the first OPAQUE message or agreed upon beforethe OPAQUE protocol begins).¶
Applications may have different policies about how and when identities aredetermined. A natural approach is to tieclient_identity to the identity the server usesto fetch the envelope (determined during password registration) and tieserver_identityto the server identity used by the client to initiate an offline passwordregistration or online authenticated key exchange session.server_identity andclient_identity can alsobe part of the envelope or tied to the parties' public keys. In principle, identitiesmay change across different sessions as long as there is a policy thatcan establish if the identity is acceptable or not to the peer. However, we notethat the public keys of both the server and the client must always be those definedat the time of password registration.¶
The client identity (client_identity) and server identity (server_identity) areoptional parameters that are left to the application to designate as aliases forthe client and server. If the application layer does not supply values for theseparameters, then they will be omitted from the creation of the envelopeduring the registration stage. Furthermore, they will be substituted withclient_identity =client_public_key andserver_identity =server_public_key duringthe authenticated key exchange stage.¶
The advantage of supplying a customclient_identity andserver_identity (instead of simply relyingon a fallback toclient_public_key andserver_public_key) is that the client can then ensure that anymappings betweenclient_identity andclient_public_key (andserver_identity andserver_public_key)are protected by the authentication from the envelope. Then, the client can verify that theclient_identity andserver_identity contained in its envelope match theclient_identityandserver_identity supplied by the server.¶
However, if this extra layer of verification is unnecessary for the application, then simplyleavingclient_identity andserver_identity unspecified (and usingclient_public_key andserver_public_key instead) is acceptable.¶
The export key can be used (separately from the OPAQUE protocol) to provideconfidentiality and integrity to other data that only the client should beable to process. For instance, if the client wishes to store secrets with athird party, then this export key can be used by the client to encrypt thesesecrets so that they remain hidden from a passive adversary that does not haveaccess to the server's secret keys or the client's password.¶
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 theorder of computing discrete logarithms or solving Diffie-Hellman, Brown andGallant[BG04] and Cheon[Cheon06] show an attack that slightly improveson generic attacks. For typical curves, the attack requires an infeasiblenumber of calls to the OPRF or results in insignificant security loss;seeSection 7.2.3 of [RFC9497] for more information. For OPAQUE, these attacksare particularly impractical as they translate into an infeasible number offailed authentication attempts directed at individual users.¶
The random-key robustness property for a MAC statesthat, given two random keys k1 and k2, it is infeasible to find a message msuch that MAC(k1, m) = MAC(k2, m). Note that in general, not every MAC functionis key-robust. In particular, GMAC (which underlies GCM) does not satisfykey-robustness, whereas HMAC with a collision-resistant hash function doessatisfy key-robustness.¶
An application can choose to use a non-key-robust MAC within the AKE portion ofthe protocol described inSection 6.4, but itMUST use a key-robust MACfor the creation of theauth_tag parameter inSection 4.1.2.¶
Both client and serverMUST validate the other party's public key(s) usedfor the execution of OPAQUE. This includes the keys shared during theregistration phase, as well as any keys shared during the onlinekey agreement phase. The validation procedure varies depending on thetype of key. For example, for OPAQUE instantiationsusing 3DH with P-256, P-384, or P-521 as the underlying group, validationis as specified in Section 5.6.2.3.4 of[keyagreement]. This includeschecking that the coordinates are in the correct range, that the pointis on the curve, and that the point is not the point at infinity.Additionally, validationMUST ensure the Diffie-Hellman shared secret isnot the point at infinity.¶
Applying a key stretching function to the output of the OPRF greatly increases the cost of an offlineattack upon the compromise of the credential file on the server. ApplicationsSHOULD select parameters for the KSF that balance cost and complexity acrossdifferent client implementations and deployments. Note that in OPAQUE, thekey stretching function is executed by the client as opposed to the server incommon password hashing scenarios. This means that applications must considera tradeoff between the performance of the protocol on clients (specifically low-enddevices) and protection against offline attacks after a server compromise.¶
Client enumeration refers to attacks where the attacker tries to learn whethera given user identity is registered with a server or whether a reregistrationor change of password was performed for that user. OPAQUE counters theseattacks by requiring servers to act with unregistered client identities in away that is indistinguishable from their behavior with existing registered clients.Servers do this by simulating a fakeCredentialResponse as specified inSection 6.3.2.2 for unregistered users and encryptingCredentialResponse using a masking key. In this way, real and fakeCredentialResponsemessages are indistinguishable from one another.Implementations must also take care to avoid side-channel leakage (e.g., timingattacks) from helping differentiate these operations from a regular serverresponse. Note that this may introduce possible abuse vectors since theserver's cost of generating aCredentialResponse is less than that of theclient's cost of generating aCredentialRequest. Server implementationsmay choose to forego the construction of a simulated credential responsemessage for an unregistered client if these client enumeration attacks canbe mitigated through other application-specific means or are otherwise notapplicable for their threat model.¶
OPAQUE does not prevent this type of attack during the registration flow.Servers necessarily react differently during the registration flow betweenregistered and unregistered clients. This allows an attacker to use the server'sresponse during registration as an oracle for whether a given client identity isregistered. Applications should mitigate against this type of attack by ratelimiting or otherwise restricting the registration flow.¶
Finally, applications that do not require protection againstclient enumeration attacks can choose to derive independent OPRF keys for differentclients. The advantage to using independently-derived OPRF keys is that the serveravoids keeping theoprf_seed value across different clients, which, if leaked, wouldcompromise the security for all clients reliant onoprf_seed as noted in[DL24].¶
The user enumeration prevention method described in this document uses asymmetric encryption key,masking_key, generated and sent to the serverby the client during registration. This requires a confidential channelbetween client and server during registration, e.g., using TLS[RFC8446].If the channel is only authenticated (this is a requirement for correctidentification of the parties), a confidential channel can be establishedusing public-key encryption, e.g., with HPKE[RFC9180]. However, the detailsof this mechanism are out of scope for this document.¶
In OPAQUE, the OPRF key acts as the secretsalt value that ensures the infeasibilityof precomputation attacks. No extrasalt value is needed. Also, clients neverdisclose their passwords to the server, even during registration. Note that a corruptedserver can run an exhaustive offline dictionary attack to validate guesses for the client'spassword; this is inevitable in any (single-server) aPAKE protocol. It can be avoided inthe case of OPAQUE by resorting to a multi-server threshold OPRF implementation,e.g.,[TOPPSS]. Furthermore, if the server does notsample the PRFseed with sufficiently high entropy, or if it is not kept hidden from anadversary, then any derivatives from the client's password may also be susceptible to anoffline dictionary attack to recover the original password.¶
Some applications may require learning the client's password to enforce passwordrules. Doing so invalidates this important security property of OPAQUE and isNOT RECOMMENDED unless it is not possible for applications to move such checksto the client. Note that limited checks at the server are possible to implement, e.g.,detecting repeated passwords upon reregistrations or password change.¶
In general, passwords should be selected with sufficient entropy to avoid being susceptibleto recovery through dictionary attacks, both online and offline.¶
Server implementations of OPAQUE do not need access to the raw AKE private key. They only requirethe ability to compute shared secrets as specified inSection 6.4.2. Thus, applicationsmay store the server AKE private key in a Hardware Security Module (HSM) orsimilar. Upon compromise ofoprf_seed and client envelopes, this would prevent anattacker from using this data to mount a server spoofing attack. Supporting implementationsneed to consider allowing separate AKE and OPRF algorithms in cases where the HSM isincompatible with the OPRF algorithm.¶
For scenarios in which the client has access to private state that can be persisted acrossregistration and login, the client can back up therandomized_password variable (ascomputed inSection 5.2.3) so that upon a future login attempt, the client canauthenticate to the server usingrandomized_password instead of the original password.This can be achieved by supplying an arbitrary password as input toCreateCredentialRequest in the login phase, and then usingrandomized_password fromthe backup inRecoverCredentials (invoked byGenerateKE3) rather than computing it fromthe password.¶
This provides an advantage over the regular authentication flow for loginin that ifrandomized_password is compromised, an adversary cannot use this value tosuccessfully impersonate the server to the client during login. The drawback is that it isonly applicable to settings whererandomized_password can be treated as a credentialthat can be stored securely after registration and retrieved upon login.¶
This document has no IANA actions.¶
Client authentication material can be stored and retrieved using different keyrecovery mechanisms. Any key recovery mechanism that encrypts datain the envelopeMUST use an authenticated encryption scheme with randomkey-robustness (or key-committing). Deviating from the key-robustnessrequirement may open the protocol to attacks, e.g.,[LGR20].This specification enforces this property by using a MAC over the envelopecontents.¶
We remark thatexport_key for authentication or encryption requiresno special properties from the authentication or encryption schemesas long asexport_key is used only after authentication material is successfullyrecovered, i.e., after the MAC inRecoverCredentials passes verification.¶
It is possible to instantiate OPAQUE with other AKEs, such as HMQV[HMQV] and SIGMA-I[SIGMA-I].HMQV is similar to 3DH but varies in its key schedule. SIGMA-I uses digital signaturesrather than static DH keys for authentication. Specification of these instantiations isleft to future documents. A sketch of how these instantiations might change is includedin the next subsection for posterity.¶
OPAQUE may also be instantiated with any post-quantum (PQ) AKE protocol that has the messageflow above and security properties (KCI resistance and forward secrecy) outlinedinSection 10. Note that such an instantiation is not quantum-safe unlessthe OPRF is quantum-safe. However, an OPAQUE instantiation where the AKE protocol is quantum-safe,but the OPRF is not, would still ensure the confidentiality and integrity of application data encryptedundersession_key (or a key derived from it) with a quantum-safe encryption function.However, the only effect of a break of the OPRF by a future quantum attacker would bethe ability of this attacker to run at that time an exhaustive dictionaryattack against the old user's password and only for users whose envelopes wereharvested while in use (in the case of OPAQUE run over a TLS channel with theserver, harvesting such envelopes requires targeted active attacks).¶
An HMQV instantiation would work similarly to OPAQUE-3DH, differing primarily in the keyschedule[HMQV]. First, the key schedulepreamble value would use a different constant prefix-- "HMQV" instead of "3DH" -- as shown below.¶
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)¶Second, theIKM derivation would change. Assuming HMQV is instantiated with a cyclicgroup of prime order p with bit length L, clients would computeIKM as follows:¶
u' = (eskU + u \* skU) mod pIKM = (epkS \* pkS^s)^u'¶
Likewise, servers would computeIKM as follows:¶
s' = (eskS + s \* skS) mod pIKM = (epkU \* pkU^u)^s'¶
In both cases,u would be computed as follows:¶
hashInput = concat(I2OSP(len(epkU), 2), epkU, I2OSP(len(info), 2), info, I2OSP(len("client"), 2), "client")u = Hash(hashInput) mod L¶Likewise,s would be computed as follows:¶
hashInput = concat(I2OSP(len(epkS), 2), epkS, I2OSP(len(info), 2), info, I2OSP(len("server"), 2), "server")s = Hash(hashInput) mod L¶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.¶
Both parties should perform validation (as inSection 10.7) on each other'spublic keys before computing the above parameters.¶
A SIGMA-I[SIGMA-I] instantiation differs more drastically from OPAQUE-3DH since authenticationuses digital signatures instead of Diffie-Hellman. In particular, bothKE2 andKE3would carry a digital signature, computed using the server and client private keysestablished during registration, respectively, as well as a MAC, where the MAC iscomputed as in OPAQUE-3DH but it also covers the identity of the sender.¶
The key schedule would also change. Specifically, the key schedulepreamble value woulduse a different constant prefix -- "SIGMA-I" instead of "3DH" -- and theIKM computationwould use only the ephemeral public keys exchanged between client and server.¶
This section contains real and fake test vectors for the OPAQUE-3DH specification.Each real test vector inAppendix C.1 specifies the configuration information,protocol inputs, intermediate values computed during registration and authentication,and protocol outputs.¶
Similarly, each fake test vector inAppendix C.2 specifiesthe configuration information, protocol inputs, and protocoloutputs computed during the authentication of an unknown or unregistered user. Note thatmasking_key,client_private_key, andclient_public_key are used as additional inputs as described inSection 6.3.2.2.client_public_key is used as the fakerecord's public key, andmasking_key is used for the fakerecord's masking key parameter.¶
All values are encoded in hexadecimal strings. The configuration informationincludes the (OPRF, Hash, KSF, KDF, MAC, Group, Context) tuple, where the Groupmatches that which is used in the OPRF. The KSF used for each test vector is theidentity function (denoted Identity), which returns as output the input messagesupplied to the function without any modification, i.e.,msg = Stretch(msg).¶
OPRF: ristretto255-SHA512Hash: SHA512KSF: IdentityKDF: HKDF-SHA512MAC: HMAC-SHA512Group: ristretto255Context: 4f50415155452d504f43Nh: 64Npk: 32Nsk: 32Nm: 64Nx: 64Nok: 32¶
oprf_seed: f433d0227b0b9dd54f7c4422b600e764e47fb503f1f9a0f0a47c6606b054a7fdc65347f1a08f277e22358bbabe26f823fca82c7848e9a75661f4ec5d5c1989efcredential_identifier: 31323334password: 436f7272656374486f72736542617474657279537461706c65envelope_nonce: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfecmasking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dserver_private_key: 47451a85372f8b3537e249d7b54188091fb18edde78094b43e2ba42b5eb89f0dserver_public_key: b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a382c9b79df1a78server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6ccclient_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf1091933541936304bserver_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a1e85ff80da12f982fblind_registration: 76cfbfe758db884bebb33582331ba9f159720ca8784a2a070a265d9c2d6abe01blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4b0790308¶
client_public_key: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccbaccafb57ac5c3675auth_key: 6cd32316f18d72a9a927a83199fa030663a38ce0c11fbaef82aa90037730494fc555c4d49506284516edd1628c27965b7555a4ebfed2223199f6c67966dde822randomized_password: aac48c25ab036e30750839d31d6e73007344cb1155289fb7d329beb932e9adeea73d5d5c22a0ce1952f8aba6d66007615cd1698d4ac85ef1fcf150031d1435d9envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfec634b0f5b96109c198a8027da51854c35bee90d1e1c781806d07d49b76de6a28b8d9e9b6c93b9f8b64d16dddd9c5bfb5fea48ee8fd2f75012a8b308605cdd8ba5handshake_secret: 81263cb85a0cfa12450f0f388de4e92291ec4c7c7a0878b624550ff528726332f1298fc6cc822a432c89504347c7a2ccd70316ae3da6a15e0399e6db3f7c1b12server_mac_key: 0d36b26cfe38f51f804f0a9361818f32ee1ce2a4e5578653b527184af058d3b2d8075c296fd84d24677913d1baa109290cd81a13ed383f9091a3804e65298dfcclient_mac_key: 91750adbac54a5e8e53b4c233cc8d369fe83b0de1b6a3cd85575eeb0bb01a6a90a086a2cf5fe75fff2a9379c30ba9049510a33b5b0b1444a88800fc3eee2260doprf_key: 5d4c6a8b7c7138182afb4345d1fae6a9f18a1744afbcc3854f8f5a2b4b4c6d05¶
registration_request: 5059ff249eb1551b7ce4991f3336205bde44a105a032e747d21bf382e75f7a71registration_response: 7408a268083e03abc7097fc05b587834539065e86fb0c7b6342fcf5e01e5b019b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a382c9b79df1a78registration_upload: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccbaccafb57ac5c36751ac5844383c7708077dea41cbefe2fa15724f449e535dd7dd562e66f5ecfb95864eadddec9db5874959905117dad40a4524111849799281fefe3c51fa82785c5ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfec634b0f5b96109c198a8027da51854c35bee90d1e1c781806d07d49b76de6a28b8d9e9b6c93b9f8b64d16dddd9c5bfb5fea48ee8fd2f75012a8b308605cdd8ba5KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44dda7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc6e29bee50701498605b2c085d7b241ca15ba5c32027dd21ba420b94ce60da326KE2: 7e308140890bcde30cbcea28b01ea1ecfbd077cff62c4def8efa075aabcbb47138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dd6ec60bcdb26dc455ddf3e718f1020490c192d70dfc7e403981179d8073d1146a4f9aa1ced4e4cd984c657eb3b54ced3848326f70331953d91b02535af44d9fedc80188ca46743c52786e0382f95ad85c08f6afcd1ccfbff95e2bdeb015b166c6b20b92f832cc6df01e0b86a7efd92c1c804ff865781fa93f2f20b446c8371b671cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1c4f62198a9d6fa9170c42c3c71f1971b29eb1d5d0bd733e40816c91f7912cc4a660c48dae03e57aaa38f3d0cffcfc21852ebc8b405d15bd6744945ba1a93438a162b6111699d98a16bb55b7bdddfe0fc5608b23da246e7bd73b47369169c5c90KE3: 4455df4f810ac31a6748835888564b536e6da5d9944dfea9e34defb9575fe5e2661ef61d2ae3929bcf57e53d464113d364365eb7d1a57b629707ca48da18e442export_key: 1ef15b4fa99e8a852412450ab78713aad30d21fa6966c9b8c9fb3262a970dc62950d4dd4ed62598229b1b72794fc0335199d9f7fcc6eaedde92cc04870e63f16session_key: 42afde6f5aca0cfa5c163763fbad55e73a41db6b41bc87b8e7b62214a8eedc6731fa3cb857d657ab9b3764b89a84e91ebcb4785166fbb02cedfcbdfda215b96f¶
OPRF: ristretto255-SHA512Hash: SHA512KSF: IdentityKDF: HKDF-SHA512MAC: HMAC-SHA512Group: ristretto255Context: 4f50415155452d504f43Nh: 64Npk: 32Nsk: 32Nm: 64Nx: 64Nok: 32¶
client_identity: 616c696365server_identity: 626f62oprf_seed: f433d0227b0b9dd54f7c4422b600e764e47fb503f1f9a0f0a47c6606b054a7fdc65347f1a08f277e22358bbabe26f823fca82c7848e9a75661f4ec5d5c1989efcredential_identifier: 31323334password: 436f7272656374486f72736542617474657279537461706c65envelope_nonce: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfecmasking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dserver_private_key: 47451a85372f8b3537e249d7b54188091fb18edde78094b43e2ba42b5eb89f0dserver_public_key: b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a382c9b79df1a78server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6ccclient_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf1091933541936304bserver_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a1e85ff80da12f982fblind_registration: 76cfbfe758db884bebb33582331ba9f159720ca8784a2a070a265d9c2d6abe01blind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4b0790308¶
client_public_key: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccbaccafb57ac5c3675auth_key: 6cd32316f18d72a9a927a83199fa030663a38ce0c11fbaef82aa90037730494fc555c4d49506284516edd1628c27965b7555a4ebfed2223199f6c67966dde822randomized_password: aac48c25ab036e30750839d31d6e73007344cb1155289fb7d329beb932e9adeea73d5d5c22a0ce1952f8aba6d66007615cd1698d4ac85ef1fcf150031d1435d9envelope: ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfec1ac902dc5589e9a5f0de56ad685ea8486210ef41449cd4d8712828913c5d2b680b2b3af4a26c765cff329bfb66d38ecf1d6cfa9e7a73c222c6efe0d9520f7d7chandshake_secret: 5e723bed1e5276de2503419eba9da61ead573109c401226832398c7e08155b885bfe7bc93451f9d887a0c1d0c19233e40a8e47b347a9ac3907f94032a4cff64fserver_mac_key: dad66bb9251073d17a13f8e5500f36e5998e3cde520ca0738e7085af62fd97812eb79a745c94d0bf8a6ac17f980cf435504cf64041eeb6bb237796d2c7f81e9aclient_mac_key: f816fe2914f7c5b29852385615d7c7f31ac122adf202d7ccd497606d7aabd48930323d1d02b1cc9ecd456c4de6f46c7950becb18bffd921dd5876381b5486ffeoprf_key: 5d4c6a8b7c7138182afb4345d1fae6a9f18a1744afbcc3854f8f5a2b4b4c6d05¶
registration_request: 5059ff249eb1551b7ce4991f3336205bde44a105a032e747d21bf382e75f7a71registration_response: 7408a268083e03abc7097fc05b587834539065e86fb0c7b6342fcf5e01e5b019b2fe7af9f48cc502d016729d2fe25cdd433f2c4bc904660b2a382c9b79df1a78registration_upload: 76a845464c68a5d2f7e442436bb1424953b17d3e2e289ccbaccafb57ac5c36751ac5844383c7708077dea41cbefe2fa15724f449e535dd7dd562e66f5ecfb95864eadddec9db5874959905117dad40a4524111849799281fefe3c51fa82785c5ac13171b2f17bc2c74997f0fce1e1f35bec6b91fe2e12dbd323d23ba7a38dfec1ac902dc5589e9a5f0de56ad685ea8486210ef41449cd4d8712828913c5d2b680b2b3af4a26c765cff329bfb66d38ecf1d6cfa9e7a73c222c6efe0d9520f7d7cKE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44dda7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc6e29bee50701498605b2c085d7b241ca15ba5c32027dd21ba420b94ce60da326KE2: 7e308140890bcde30cbcea28b01ea1ecfbd077cff62c4def8efa075aabcbb47138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dd6ec60bcdb26dc455ddf3e718f1020490c192d70dfc7e403981179d8073d1146a4f9aa1ced4e4cd984c657eb3b54ced3848326f70331953d91b02535af44d9fea502150b67fe36795dd8914f164e49f81c7688a38928372134b7dccd50e09f8fed9518b7b2f94835b3c4fe4c8475e7513f20eb97ff0568a39caee3fd6251876f71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1c4f62198a9d6fa9170c42c3c71f1971b29eb1d5d0bd733e40816c91f7912cc4a292371e7809a9031743e943fb3b56f51de903552fc91fba4e7419029951c3970b2e2f0a9dea218d22e9e4e0000855bb6421aa3610d6fc0f4033a6517030d4341KE3: 7a026de1d6126905736c3f6d92463a08d209833eb793e46d0f7f15b3e0f62c7643763c02bbc6b8d3d15b63250cae98171e9260f1ffa789750f534ac11a0176d5export_key: 1ef15b4fa99e8a852412450ab78713aad30d21fa6966c9b8c9fb3262a970dc62950d4dd4ed62598229b1b72794fc0335199d9f7fcc6eaedde92cc04870e63f16session_key: ae7951123ab5befc27e62e63f52cf472d6236cb386c968cc47b7e34f866aa4bc7638356a73cfce92becf39d6a7d32a1861f12130e824241fe6cab34fbd471a57¶
OPRF: ristretto255-SHA512Hash: SHA512KSF: IdentityKDF: HKDF-SHA512MAC: HMAC-SHA512Group: curve25519Context: 4f50415155452d504f43Nh: 64Npk: 32Nsk: 32Nm: 64Nx: 64Nok: 32¶
oprf_seed: a78342ab84d3d30f08d5a9630c79bf311c31ed7f85d9d4959bf492ec67a0eec8a67dfbf4497248eebd49e878aab173e5e4ff76354288fdd53e949a5f7c9f7f1bcredential_identifier: 31323334password: 436f7272656374486f72736542617474657279537461706c65envelope_nonce: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0bmasking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dserver_private_key: c06139381df63bfc91c850db0b9cfbec7a62e86d80040a41aa7725bf0e79d564server_public_key: a41e28269b4e97a66468cc00c5a57753e192e152766989770688aa90486ef031server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6ccclient_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf1091933541936304bserver_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a1e85ff80da12f982fblind_registration: c575731ffe1cb0ca5ba63b42c4699767b8b9ab78ba39316ee04baddb2034a70ablind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4b0790308¶
client_public_key: 0936ea94ab030ec332e29050d266c520e916731a052d05ced7e0cfe751142b48auth_key: 7e880ab484f750e80e6f839d975aff476070ce65066d85ea62523d1d5764739d91307fac47186a4ab935e6a5c7f70cb47faa9473311947502c022cc67ae9440crandomized_password: 3a602c295a9c323d9362fe286f104567ed6862b25dbe30fada844f19e41cf40047424b7118e15dc2c1a815a70fea5c8de6c30aa61440cd4b4b5e8f3963fbb2e1envelope: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0b20c1e81fef28e92e897ca8287d49a55075b47c3988ff0fff367d79a3e350ccac150b4a3ff48b4770c8e84e437b3d4e68d2b95833f7788f7eb93fa6a8afb85ecbhandshake_secret: 178c8c15e025252380c3edb1c6ad8ac52573b38d536099e2f865786f5e31c642608550c0c6f281c37ce259667dd72768af31630e0eb36f1096a2e6421c2aa163server_mac_key: f3c6a8e069c54bb0d8905139f723c9e22f5c662dc08848243a6654c8223800019b9823523d84da2ef67ca1c14277630aace464c113be8a0a658c39e181a8bb71client_mac_key: b1ee7ce52dbd0ab72872924ff11596cb196bbabfc319e74aca78ade54a0f74dd15dcf5621f6d2e79161b0c9b701381d494836dedbb86e584a65b34267a370e01oprf_key: 62ef7f7d9506a14600c34f642aaf6ef8019cc82a6755db4fded5248ea146030a¶
registration_request: 26f3dbfd76b8e5f85b4da604f42889a7d4b1bc919f655381a67de02c59fd5436registration_response: 506e8f1b89c098fb89b5b6210a05f7898cafdaea221761e8d5272fc39e0f9f08a41e28269b4e97a66468cc00c5a57753e192e152766989770688aa90486ef031registration_upload: 0936ea94ab030ec332e29050d266c520e916731a052d05ced7e0cfe751142b486d23c6ed818882f9bdfdcf91389fcbc0b7a3faf92bd0bd6be4a1e7730277b694fc7c6ba327fbe786af18487688e0f7c148bbd54dc2fc80c28e7a976d9ef53c3540d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0b20c1e81fef28e92e897ca8287d49a55075b47c3988ff0fff367d79a3e350ccac150b4a3ff48b4770c8e84e437b3d4e68d2b95833f7788f7eb93fa6a8afb85ecbKE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44dda7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc10a83b9117d3798cb2957fbdb0268a0d63dbf9d66bde5c00c78affd80026c911KE2: 9a0e5a1514f62e005ea098b0d8cf6750e358c4389e6add1c52aed9500fa19d0038fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d22cc31127d6f0096755be3c3d2dd6287795c317aeea10c9485bf4f419a786642c19a8f151ceb5e8767d175248c62c017de94057398d28bf0ed00d1b50ee4f812fd9afddf98af8cd58067ca43b0633b6cadd0e9d987f89623fed4d3583bdf6910c425600e90dab3c6b3513188a465461a67f6bbc47aeba808f7f7e2c6d66f5c3271cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a141f55f0bef355cfb34ccd468fdacad75865ee7efef95f4cb6c25d477f720502676f06a3b806da262139bf3fa76a1090b94dac78bc3bc6f8747d5b35acf94eff3ec2ebe7d49b8cf16be64120b279fe92664e47be5da7e60f08f12e91192652f79KE3: 550e923829a544496d8316c490da2b979b78c730dd75be3a17f237a26432c19fbba54b6a0467b1c22ecbd6794bc5fa5b04215ba1ef974c6b090baa42c5bb984fexport_key: 9dec51d6d0f6ce7e4345f10961053713b07310cc2e45872f57bbd2fe5070fdf0fb5b77c7ddaa2f3dc5c35132df7417ad7fefe0f690ad266e5a54a21d045c9c38session_key: fd2fdd07c1bcc88e81c1b1d1de5ad62dfdef1c0b8209ff9d671e1fac55ce9c34d381c1fb2703ff53a797f77daccbe33047ccc167b8105171e10ec962eea203aa¶
OPRF: ristretto255-SHA512Hash: SHA512KSF: IdentityKDF: HKDF-SHA512MAC: HMAC-SHA512Group: curve25519Context: 4f50415155452d504f43Nh: 64Npk: 32Nsk: 32Nm: 64Nx: 64Nok: 32¶
client_identity: 616c696365server_identity: 626f62oprf_seed: a78342ab84d3d30f08d5a9630c79bf311c31ed7f85d9d4959bf492ec67a0eec8a67dfbf4497248eebd49e878aab173e5e4ff76354288fdd53e949a5f7c9f7f1bcredential_identifier: 31323334password: 436f7272656374486f72736542617474657279537461706c65envelope_nonce: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0bmasking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dserver_private_key: c06139381df63bfc91c850db0b9cfbec7a62e86d80040a41aa7725bf0e79d564server_public_key: a41e28269b4e97a66468cc00c5a57753e192e152766989770688aa90486ef031server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1client_nonce: da7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6ccclient_keyshare_seed: 82850a697b42a505f5b68fcdafce8c31f0af2b581f063cf1091933541936304bserver_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a1e85ff80da12f982fblind_registration: c575731ffe1cb0ca5ba63b42c4699767b8b9ab78ba39316ee04baddb2034a70ablind_login: 6ecc102d2e7a7cf49617aad7bbe188556792d4acd60a1a8a8d2b65d4b0790308¶
client_public_key: 0936ea94ab030ec332e29050d266c520e916731a052d05ced7e0cfe751142b48auth_key: 7e880ab484f750e80e6f839d975aff476070ce65066d85ea62523d1d5764739d91307fac47186a4ab935e6a5c7f70cb47faa9473311947502c022cc67ae9440crandomized_password: 3a602c295a9c323d9362fe286f104567ed6862b25dbe30fada844f19e41cf40047424b7118e15dc2c1a815a70fea5c8de6c30aa61440cd4b4b5e8f3963fbb2e1envelope: 40d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0bb4c0eab6143959a650c5f6b32acf162b1fbe95bb36c5c4f99df53865c4d3537d69061d80522d772cd0efdbe91f817f6bf7259a56e20b4eb9cbe9443702f4b759handshake_secret: 13e7dc6afa5334b9dfffe26bee3caf744ef4add176caee464cdeb3d37303b90de35a8bf095df84471ac77d705f12fe232f1571de1d6a001d3e80899873a142dcserver_mac_key: a58135acfb2bde92d506cf59119729a6404ad94eba294e4b52a63baf58cfe03f21bcf735222c7f2c27a60bd958be7f6aed50dc03a78f64e7ae4ac1ff071b95aaclient_mac_key: 1e1a8ba156aadc4a302f707d2193c9dab477b355f430d450dd407ce40dc75613f76ec33dec494f8a6bfdcf951eb060dac33e6572c693954fe92e33730c9ab0a2oprf_key: 62ef7f7d9506a14600c34f642aaf6ef8019cc82a6755db4fded5248ea146030a¶
registration_request: 26f3dbfd76b8e5f85b4da604f42889a7d4b1bc919f655381a67de02c59fd5436registration_response: 506e8f1b89c098fb89b5b6210a05f7898cafdaea221761e8d5272fc39e0f9f08a41e28269b4e97a66468cc00c5a57753e192e152766989770688aa90486ef031registration_upload: 0936ea94ab030ec332e29050d266c520e916731a052d05ced7e0cfe751142b486d23c6ed818882f9bdfdcf91389fcbc0b7a3faf92bd0bd6be4a1e7730277b694fc7c6ba327fbe786af18487688e0f7c148bbd54dc2fc80c28e7a976d9ef53c3540d6b67fdd7da7c49894750754514dbd2070a407166bd2a5237cca9bf44d6e0bb4c0eab6143959a650c5f6b32acf162b1fbe95bb36c5c4f99df53865c4d3537d69061d80522d772cd0efdbe91f817f6bf7259a56e20b4eb9cbe9443702f4b759KE1: c4dedb0ba6ed5d965d6f250fbe554cd45cba5dfcce3ce836e4aee778aa3cd44dda7e07376d6d6f034cfa9bb537d11b8c6b4238c334333d1f0aebb380cae6a6cc10a83b9117d3798cb2957fbdb0268a0d63dbf9d66bde5c00c78affd80026c911KE2: 9a0e5a1514f62e005ea098b0d8cf6750e358c4389e6add1c52aed9500fa19d0038fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d22cc31127d6f0096755be3c3d2dd6287795c317aeea10c9485bf4f419a786642c19a8f151ceb5e8767d175248c62c017de94057398d28bf0ed00d1b50ee4f812699bff7663be3c5d59de94d8e7e58817c7da005b39c25d25555c929e1c5cf6c1b82837b1367c839aab56a422c0d97719426a79a16f9869cf852100597b23b5a071cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a141f55f0bef355cfb34ccd468fdacad75865ee7efef95f4cb6c25d477f72050267cc22c87edbf3ecaca64cb33bc60dc3bfc551e365f0d46a7fed0e09d96f9afbb48868f5bb3c3e05a86ed8c9476fc22c58306c5a291be34388e09548ba9d70f39KE3: d16344e791c3f18594d22ba068984fa18ec1e9bead662b75f66826ffd627932fcd1ec40cd01dcf5f63f4055ebe45c7717a57a833aad360256cf1e1c20c0eae1cexport_key: 9dec51d6d0f6ce7e4345f10961053713b07310cc2e45872f57bbd2fe5070fdf0fb5b77c7ddaa2f3dc5c35132df7417ad7fefe0f690ad266e5a54a21d045c9c38session_key: f6116d3aa0e4089a179713bad4d98ed5cb57e5443cae8d36ef78996fa60f3dc6e9fcdd63c001596b06dbc1285d80211035cc0e485506b3f7a650cbf78c5bffc9¶
OPRF: P256-SHA256Hash: SHA256KSF: IdentityKDF: HKDF-SHA256MAC: HMAC-SHA256Group: P256_XMD:SHA-256_SSWU_RO_Context: 4f50415155452d504f43Nh: 32Npk: 33Nsk: 32Nm: 32Nx: 32Nok: 32¶
oprf_seed: 62f60b286d20ce4fd1d64809b0021dad6ed5d52a2c8cf27ae6582543a0a8dce2credential_identifier: 31323334password: 436f7272656374486f72736542617474657279537461706c65envelope_nonce: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf65670e51fmasking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dserver_private_key: c36139381df63bfc91c850db0b9cfbec7a62e86d80040a41aa7725bf0e79d5e5server_public_key: 035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd9f2092d6067784874server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1client_nonce: ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1client_keyshare_seed: 633b875d74d1556d2a2789309972b06db21dfcc4f5ad51d7e74d783b7cfab8dcserver_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a1e85ff80da12f982fblind_registration: 411bf1a62d119afe30df682b91a0a33d777972d4f2daa4b34ca527d597078153blind_login: c497fddf6056d241e6cf9fb7ac37c384f49b357a221eb0a802c989b9942256c1¶
client_public_key: 03b218507d978c3db570ca994aaf36695a731ddb2db272c817f79746fc37ae5214auth_key: 5bd4be1602516092dc5078f8d699f5721dc1720a49fb80d8e5c16377abd0987brandomized_password: 06be0a1a51d56557a3adad57ba29c5510565dcd8b5078fa319151b9382258fb0envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf65670e51fad30bbcfc1f8eda0211553ab9aaf26345ad59a128e80188f035fe4924fad67b8handshake_secret: 83a932431a8f25bad042f008efa2b07c6cd0faa8285f335b6363546a9f9b235fserver_mac_key: 13e928581febfad28855e3e7f03306d61bd69489686f621535d44a1365b73b0dclient_mac_key: afdc53910c25183b08b930e6953c35b3466276736d9de2e9c5efaf150f4082c5oprf_key: 2dfb5cb9aa1476093be74ca0d43e5b02862a05f5d6972614d7433acdc66f7f31¶
registration_request: 029e949a29cfa0bf7c1287333d2fb3dc586c41aa652f5070d26a5315a1b50229f8registration_response: 0350d3694c00978f00a5ce7cd08a00547e4ab5fb5fc2b2f6717cdaa6c89136efef035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd9f2092d6067784874registration_upload: 03b218507d978c3db570ca994aaf36695a731ddb2db272c817f79746fc37ae52147f0ed53532d3ae8e505ecc70d42d2b814b6b0e48156def71ea029148b2803aafa921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf65670e51fad30bbcfc1f8eda0211553ab9aaf26345ad59a128e80188f035fe4924fad67b8KE1: 037342f0bcb3ecea754c1e67576c86aa90c1de3875f390ad599a26686cdfee6e07ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1022ed3f32f318f81bab80da321fecab3cd9b6eea11a95666dfa6beeaab321280b6KE2: 0246da9fe4d41d5ba69faa6c509a1d5bafd49a48615a47a8dd4b0823cc1476481138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d2f0c547f70deaeca54d878c14c1aa5e1ab405dec833777132eea905c2fbb12504a67dcbe0e66740c76b62c13b04a38a77926e19072953319ec65e41f9bfd2ae26837b6ce688bf9af2542f04eec9ab96a1b9328812dc2f5c89182ed47fead61f09f71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a103c1701353219b53acf337bf6456a83cefed8f563f1040b65afbf3b65d3bc9a19b50a73b145bc87a157e8c58c0342e2047ee22ae37b63db17e0a82a30fcc4ecf7bKE3: e97cab4433aa39d598e76f13e768bba61c682947bdcf9936035e8a3a3ebfb66eexport_key: c3c9a1b0e33ac84dd83d0b7e8af6794e17e7a3caadff289fbd9dc769a853c64bsession_key: 484ad345715ccce138ca49e4ea362c6183f0949aaaa1125dc3bc3f80876e7cd1¶
OPRF: P256-SHA256Hash: SHA256KSF: IdentityKDF: HKDF-SHA256MAC: HMAC-SHA256Group: P256_XMD:SHA-256_SSWU_RO_Context: 4f50415155452d504f43Nh: 32Npk: 33Nsk: 32Nm: 32Nx: 32Nok: 32¶
client_identity: 616c696365server_identity: 626f62oprf_seed: 62f60b286d20ce4fd1d64809b0021dad6ed5d52a2c8cf27ae6582543a0a8dce2credential_identifier: 31323334password: 436f7272656374486f72736542617474657279537461706c65envelope_nonce: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf65670e51fmasking_nonce: 38fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6dserver_private_key: c36139381df63bfc91c850db0b9cfbec7a62e86d80040a41aa7725bf0e79d5e5server_public_key: 035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd9f2092d6067784874server_nonce: 71cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a1client_nonce: ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1client_keyshare_seed: 633b875d74d1556d2a2789309972b06db21dfcc4f5ad51d7e74d783b7cfab8dcserver_keyshare_seed: 05a4f54206eef1ba2f615bc0aa285cb22f26d1153b5b40a1e85ff80da12f982fblind_registration: 411bf1a62d119afe30df682b91a0a33d777972d4f2daa4b34ca527d597078153blind_login: c497fddf6056d241e6cf9fb7ac37c384f49b357a221eb0a802c989b9942256c1¶
client_public_key: 03b218507d978c3db570ca994aaf36695a731ddb2db272c817f79746fc37ae5214auth_key: 5bd4be1602516092dc5078f8d699f5721dc1720a49fb80d8e5c16377abd0987brandomized_password: 06be0a1a51d56557a3adad57ba29c5510565dcd8b5078fa319151b9382258fb0envelope: a921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf65670e51f4d7773a36a208a866301dbb2858e40dc5638017527cf91aef32d3848eebe0971handshake_secret: 80bdcc498f22de492e90ee8101fcc7c101e158dd49c77f7c283816ae329ed62fserver_mac_key: 0f82432fbdb5b90daf27a91a3acc42299a9590dba1b77932c2207b4cb3d4a157client_mac_key: 7f629eb0b1b69979b07ca1f564b3e92ed22f07569fd1d11725d93e46731fbe71oprf_key: 2dfb5cb9aa1476093be74ca0d43e5b02862a05f5d6972614d7433acdc66f7f31¶
registration_request: 029e949a29cfa0bf7c1287333d2fb3dc586c41aa652f5070d26a5315a1b50229f8registration_response: 0350d3694c00978f00a5ce7cd08a00547e4ab5fb5fc2b2f6717cdaa6c89136efef035f40ff9cf88aa1f5cd4fe5fd3da9ea65a4923a5594f84fd9f2092d6067784874registration_upload: 03b218507d978c3db570ca994aaf36695a731ddb2db272c817f79746fc37ae52147f0ed53532d3ae8e505ecc70d42d2b814b6b0e48156def71ea029148b2803aafa921f2a014513bd8a90e477a629794e89fec12d12206dde662ebdcf65670e51f4d7773a36a208a866301dbb2858e40dc5638017527cf91aef32d3848eebe0971KE1: 037342f0bcb3ecea754c1e67576c86aa90c1de3875f390ad599a26686cdfee6e07ab3d33bde0e93eda72392346a7a73051110674bbf6b1b7ffab8be4f91fdaeeb1022ed3f32f318f81bab80da321fecab3cd9b6eea11a95666dfa6beeaab321280b6KE2: 0246da9fe4d41d5ba69faa6c509a1d5bafd49a48615a47a8dd4b0823cc1476481138fe59af0df2c79f57b8780278f5ae47355fe1f817119041951c80f612fdfc6d2f0c547f70deaeca54d878c14c1aa5e1ab405dec833777132eea905c2fbb12504a67dcbe0e66740c76b62c13b04a38a77926e19072953319ec65e41f9bfd2ae268d7f106042021c80300e4c6f585980cf39fc51a4a6bba41b0729f9b240c729e5671cd9960ecef2fe0d0f7494986fa3d8b2bb01963537e60efb13981e138e3d4a103c1701353219b53acf337bf6456a83cefed8f563f1040b65afbf3b65d3bc9a19b84922c7e5d074838a8f278592c53f61fb59f031e85ad480c0c71086b871e1b24KE3: 46833578cee137775f6be3f01b80748daac5a694101ad0e9e7025480552da56aexport_key: c3c9a1b0e33ac84dd83d0b7e8af6794e17e7a3caadff289fbd9dc769a853c64bsession_key: 27766fabd8dd88ff37fbd0ef1a491e601d10d9f016c2b28c4bd1b0fb7511a3c3¶
OPRF: ristretto255-SHA512Hash: SHA512KSF: IdentityKDF: HKDF-SHA512MAC: HMAC-SHA512Group: ristretto255Context: 4f50415155452d504f43Nh: 64Npk: 32Nsk: 32Nm: 64Nx: 64Nok: 32¶
client_identity: 616c696365server_identity: 626f62oprf_seed: 743fc168d1f826ad43738933e5adb23da6fb95f95a1b069f0daa0522d0a78b617f701fc6aa46d3e7981e70de7765dfcd6b1e13e3369a582eb8dc456b10aa53b0credential_identifier: 31323334masking_nonce: 9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a6client_private_key: 2b98980aa95ab53a0f39f0291903d2fdf04b00c167f0814169922df873002409client_public_key: 84f43f9492e19c22d8bdaa4447cc3d4db1cdb5427a9f852c4707921212c36251server_private_key: c788585ae8b5ba2942b693b849be0c0426384e41977c18d2e81fbe30fd7c9f06server_public_key: 825f832667480f08b0c9069da5083ac4d0e9ee31b49c4e0310031fea04d52966server_nonce: 1e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813055ae2d12client_keyshare_seed: a270dc715dc2b4612bc7864312a05c3e9788ee1bad1f276d1e15bdeb4c355e94server_keyshare_seed: 360b0937f47d45f6123a4d8f0d0c0814b6120d840ebb8bc5b4f6b62df07f78c2masking_key: 39ebd51f0e39a07a1c2d2431995b0399bca9996c5d10014d6ebab4453dc10ce5cef38ed3df6e56bfff40c2d8dd4671c2b4cf63c3d54860f31fe40220d690bb71KE1: b0a26dcaca2230b8f5e4b1bcab9c84b586140221bb8b2848486874b0be44890542d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0ab641d7f20a245a09f1d4dbb6e301661af7f352beb0791d055e48d3645232f77f¶
KE2: 928f79ad8df21963e91411b9f55165ba833dea918f441db967cdc09521d229259c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a632b5ab1bff96636144faa4f9f9afaac75dd88ea99cf5175902ae3f3b2195693f165f11929ba510a5978e64dcdabecbd7ee1e4380ce270e58fea58e6462d92964a1aaef72698bca1c673baeb04cc2bf7de5f3c2f5553464552d3a0f7698a9ca7f9c5e70c6cb1f706b2f175ab9d04bbd13926e816b6811a50b4aafa9799d5ed7971e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813055ae2d1298251c5ba55f6b0b2d58d9ff0c88fe4176484be62a96db6e2a8c4d431bd1bf27fe6c1d0537603835217d42ebf7b2581982732e74892fd28211b31ed33863f0beaf75ba6f59474c0aaf9d78a60a9b2f4cd24d7ab54131b3c8efa192df6b72db4c¶
OPRF: ristretto255-SHA512Hash: SHA512KSF: IdentityKDF: HKDF-SHA512MAC: HMAC-SHA512Group: curve25519Context: 4f50415155452d504f43Nh: 64Npk: 32Nsk: 32Nm: 64Nx: 64Nok: 32¶
client_identity: 616c696365server_identity: 626f62oprf_seed: 66e650652a8266b2205f31fdd68adeb739a05b5e650b19e7edc75e734a1296d6088188ca46c31ae8ccbd42a52ed338c06e53645387a7efbc94b6a0449526155ecredential_identifier: 31323334masking_nonce: 9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a6client_private_key: 288bf63470199221847bb035d99f96531adf8badd14cb1571b48f7a506649660client_public_key: 3c64a3153854cc9f0c23aab3c1a19106ec8bab4730736d1d003880a1d5a59005server_private_key: 30fbe7e830be1fe8d2187c97414e3826040cbe49b893b64229bab5e85a588846server_public_key: 78b3040047ff26572a7619617601a61b9c81899bee92f00cfcaa5eed96863555server_nonce: 1e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813055ae2d12client_keyshare_seed: a270dc715dc2b4612bc7864312a05c3e9788ee1bad1f276d1e15bdeb4c355e94server_keyshare_seed: 360b0937f47d45f6123a4d8f0d0c0814b6120d840ebb8bc5b4f6b62df07f78c2masking_key: 79ad2621b0757a447dff7108a8ae20a068ce67872095620f415ea611c9dcc04972fa359538cd2fd6528775ca775487b2b56db642049b8a90526b975a38484c6aKE1: b0a26dcaca2230b8f5e4b1bcab9c84b586140221bb8b2848486874b0be44890542d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0ac059b7ba2aec863933ae48816360c7a9022e83d822704f3b0b86c0502a66e574¶
KE2: 6606b6fedbb33f19a81a1feb5149c600fe77252f58acd3080d7504d3dad4922f9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a67db398c0f65d8c298eac430abdae4c80e82b552fb940c00f0cbcea853c0f96c1c15099f3d4b0e83ecc249613116d605b8d77bb68bdf76994c2bc507e2dcae4176f00afed68ad25cf3040a0e991acece31ca532117f5c12816997372ff031ad04ebcdce06c501da24e7b4db95343456e2ed260895ec362694230a1fa20e24a9c71e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813055ae2d122d9055eb8f83e1b497370adad5cc2a417bf9be436a792def0c7b7ccb92b9e275d7c663104ea4655bd70570d975c05351655d55fbfb392286edb55600a23b55ce18f8c60e0d1960c960412dd08eabc81ba7ca8ae2b04aad65462321f51c298010¶
OPRF: P256-SHA256Hash: SHA256KSF: IdentityKDF: HKDF-SHA256MAC: HMAC-SHA256Group: P256_XMD:SHA-256_SSWU_RO_Context: 4f50415155452d504f43Nh: 32Npk: 33Nsk: 32Nm: 32Nx: 32Nok: 32¶
client_identity: 616c696365server_identity: 626f62oprf_seed: bb1cd59e16ac09bc0cb6d528541695d7eba2239b1613a3db3ade77b36280f725credential_identifier: 31323334masking_nonce: 9c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a6client_private_key: d423b87899fc61d014fc8330a4e26190fcfa470a3afe5924324294af7dbbc1ddclient_public_key: 03b81708eae026a9370616c22e1e8542fe9dbebd36ce8a2661b708e9628f4a57fcserver_private_key: 34fbe7e830be1fe8d2187c97414e3826040cbe49b893b64229bab5e85a5888c7server_public_key: 0221e034c0e202fe883dcfc96802a7624166fed4cfcab4ae30cf5f3290d01c88bfserver_nonce: 1e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813055ae2d12client_keyshare_seed: a270dc715dc2b4612bc7864312a05c3e9788ee1bad1f276d1e15bdeb4c355e94server_keyshare_seed: 360b0937f47d45f6123a4d8f0d0c0814b6120d840ebb8bc5b4f6b62df07f78c2masking_key: caecc6ccb4cae27cb54d8f3a1af1bac52a3d53107ce08497cdd362b1992e4e5eKE1: 0396875da2b4f7749bba411513aea02dc514a48d169d8a9531bd61d3af3fa9baae42d4e61ed3f8d64cdd3b9d153343eca15b9b0d5e388232793c6376bd2d9cfd0a02147a6583983cc9973b5082db5f5070890cb373d70f7ac1b41ed2305361009784¶
KE2: 0201198dcd13f9792eb75dcfa815f61b049abfe2e3e9456d4bbbceec5f442efd049c035896a043e70f897d87180c543e7a063b83c1bb728fbd189c619e27b6e5a6facda65ce0a97b9085e7af07f61fd3fdd046d257cbf2183ce8766090b8041a8bf28d79dd4c9031ddc75bb6ddb4c291e639937840e3d39fc0d5a3d6e7723c09f7945df485bcf9aefe3fe82d149e84049e259bb5b33d6a2ff3b25e4bfb7eff0962821e10f6eeab2a7a420bf09da9b27a4639645622c46358de9cf7ae813055ae2d12023f82bbb24e75b8683fd13b843cd566efae996cd0016cffdcc24ee2bc937d026f80144878749a69565b433c1040aff67e94f79345de888a877422b9bbe21ec329¶
We are indebted to the OPAQUE reviewers during CFRG's aPAKE selection process, particularlyJulia Hesse andBjorn Tackmann. This document has benefited from comments by multiple people. Special thanks toRichard Barnes,Dan Brown,Matt Campagna,Eric Crockett,Paul Grubbs,Fredrik Kuivinen,Stefan Marsiske,Payman Mohassel,Marta Mularczyk,Jason Resch,Greg Rubin, andNick Sullivan.Hugo Krawczyk wishes to thank his OPAQUE co-authorsStas Jarecki andJiayu Xu, without whom this work would have not been possible.¶