Oblivious Pseudorandom Functions (OPRFs) using Prime-Order Groups
draft-irtf-cfrg-voprf-07
This document is an Internet-Draft (I-D) that has been submitted to the Internet Research Task Force (IRTF) stream.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
The information below is for an old version of the document.
| Document | Type |
This is an older version of an Internet-Draft that was ultimately published as RFC 9497.
|
|
|---|---|---|---|
| Authors | Alex Davidson , Armando Faz-Hernandez , Nick Sullivan , Christopher A. Wood | ||
| Last updated | 2021-07-06 | ||
| Replaces | draft-sullivan-cfrg-voprf | ||
| RFC stream | Internet Research Task Force (IRTF) | ||
| Formats | |||
| IETF conflict review | conflict-review-irtf-cfrg-voprf, conflict-review-irtf-cfrg-voprf, conflict-review-irtf-cfrg-voprf, conflict-review-irtf-cfrg-voprf, conflict-review-irtf-cfrg-voprf, conflict-review-irtf-cfrg-voprf | ||
| Additional resources | Mailing list discussion | ||
| Stream | IRTF state | Active RG Document | |
| Consensus boilerplate | Unknown | ||
| Document shepherd | (None) | ||
| IESG | IESG state | Became RFC 9497 (Informational) | |
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-irtf-cfrg-voprf-07
Network Working Group A. Davidson
Internet-Draft Brave Software
Intended status: Informational A. Faz-Hernandez
Expires: 7 January 2022 N. Sullivan
C.A. Wood
Cloudflare
6 July 2021
Oblivious Pseudorandom Functions (OPRFs) using Prime-Order Groups
draft-irtf-cfrg-voprf-07
Abstract
An Oblivious Pseudorandom Function (OPRF) is a two-party protocol for
computing the output of a PRF. One party (the server) holds the PRF
secret key, and the other (the client) holds the PRF input. The
'obliviousness' property ensures that the server does not learn
anything about the client's input during the evaluation. The client
should also not learn anything about the server's secret PRF key.
Optionally, OPRFs can also satisfy a notion 'verifiability' (VOPRF).
In this setting, the client can verify that the server's output is
indeed the result of evaluating the underlying PRF with just a public
key. This document specifies OPRF and VOPRF constructions
instantiated within prime-order groups, including elliptic curves.
Discussion Venues
This note is to be removed before publishing as an RFC.
Source for this draft and an issue tracker can be found at
https://github.com/cfrg/draft-irtf-cfrg-voprf.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
Davidson, et al. Expires 7 January 2022 [Page 1]
Internet-Draft OPRFs July 2021
This Internet-Draft will expire on 7 January 2022.
Copyright Notice
Copyright (c) 2021 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. Code Components
extracted from this document must include Simplified BSD License text
as described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Simplified BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3
1.1. Change log . . . . . . . . . . . . . . . . . . . . . . . 4
1.2. Requirements . . . . . . . . . . . . . . . . . . . . . . 6
2. Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . 6
2.1. Prime-Order Group Dependency . . . . . . . . . . . . . . 7
2.2. Conventions and Terminology . . . . . . . . . . . . . . . 8
3. (V)OPRF Protocol . . . . . . . . . . . . . . . . . . . . . . 9
3.1. Overview . . . . . . . . . . . . . . . . . . . . . . . . 10
3.2. Context Setup . . . . . . . . . . . . . . . . . . . . . . 10
3.3. Context APIs . . . . . . . . . . . . . . . . . . . . . . 11
3.3.1. Server Context . . . . . . . . . . . . . . . . . . . 12
3.3.2. VerifiableServerContext . . . . . . . . . . . . . . . 14
3.3.3. Client Context . . . . . . . . . . . . . . . . . . . 18
3.3.4. VerifiableClientContext . . . . . . . . . . . . . . . 20
4. Ciphersuites . . . . . . . . . . . . . . . . . . . . . . . . 25
4.1. OPRF(ristretto255, SHA-512) . . . . . . . . . . . . . . . 25
4.2. OPRF(decaf448, SHAKE-256) . . . . . . . . . . . . . . . . 26
4.3. OPRF(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 26
4.4. OPRF(P-384, SHA-512) . . . . . . . . . . . . . . . . . . 27
4.5. OPRF(P-521, SHA-512) . . . . . . . . . . . . . . . . . . 27
5. API Considerations . . . . . . . . . . . . . . . . . . . . . 28
6. Security Considerations . . . . . . . . . . . . . . . . . . . 28
6.1. Security Properties . . . . . . . . . . . . . . . . . . . 28
6.2. Cryptographic Security . . . . . . . . . . . . . . . . . 29
6.2.1. Computational Hardness Assumptions . . . . . . . . . 29
6.2.2. Protocol Security . . . . . . . . . . . . . . . . . . 30
6.2.3. Q-Strong-DH Oracle . . . . . . . . . . . . . . . . . 31
6.2.4. Implications for Ciphersuite Choices . . . . . . . . 32
6.3. Domain Separation . . . . . . . . . . . . . . . . . . . . 32
6.4. Element and Scalar Validation . . . . . . . . . . . . . . 32
Davidson, et al. Expires 7 January 2022 [Page 2]
Internet-Draft OPRFs July 2021
6.5. Hashing to Group . . . . . . . . . . . . . . . . . . . . 33
6.6. Blinding Considerations . . . . . . . . . . . . . . . . . 33
6.7. Timing Leaks . . . . . . . . . . . . . . . . . . . . . . 34
6.8. Key Rotation . . . . . . . . . . . . . . . . . . . . . . 34
6.8.1. Parameter Commitments . . . . . . . . . . . . . . . . 34
7. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 35
8. References . . . . . . . . . . . . . . . . . . . . . . . . . 35
8.1. Normative References . . . . . . . . . . . . . . . . . . 35
8.2. Informative References . . . . . . . . . . . . . . . . . 37
Appendix A. Test Vectors . . . . . . . . . . . . . . . . . . . . 37
A.1. OPRF(ristretto255, SHA-512) . . . . . . . . . . . . . . . 38
A.1.1. Base Mode . . . . . . . . . . . . . . . . . . . . . . 38
A.1.2. Verifiable Mode . . . . . . . . . . . . . . . . . . . 39
A.2. OPRF(decaf448, SHAKE-256) . . . . . . . . . . . . . . . . 40
A.2.1. Base Mode . . . . . . . . . . . . . . . . . . . . . . 40
A.2.2. Verifiable Mode . . . . . . . . . . . . . . . . . . . 41
A.3. OPRF(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 43
A.3.1. Base Mode . . . . . . . . . . . . . . . . . . . . . . 43
A.3.2. Verifiable Mode . . . . . . . . . . . . . . . . . . . 44
A.4. OPRF(P-384, SHA-512) . . . . . . . . . . . . . . . . . . 45
A.4.1. Base Mode . . . . . . . . . . . . . . . . . . . . . . 45
A.4.2. Verifiable Mode . . . . . . . . . . . . . . . . . . . 46
A.5. OPRF(P-521, SHA-512) . . . . . . . . . . . . . . . . . . 48
A.5.1. Base Mode . . . . . . . . . . . . . . . . . . . . . . 48
A.5.2. Verifiable Mode . . . . . . . . . . . . . . . . . . . 49
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 51
1. Introduction
A pseudorandom function (PRF) F(k, x) is an efficiently computable
function taking a private key k and a value x as input. This
function is pseudorandom if the keyed function K(_) = F(K, _) is
indistinguishable from a randomly sampled function acting on the same
domain and range as K(). An oblivious PRF (OPRF) is a two-party
protocol between a server and a client, where the server holds a PRF
key k and the client holds some input x. The protocol allows both
parties to cooperate in computing F(k, x) such that: the client
learns F(k, x) without learning anything about k; and the server does
not learn anything about x or F(k, x). A Verifiable OPRF (VOPRF) is
an OPRF wherein the server can prove to the client that F(k, x) was
computed using the key k.
The usage of OPRFs has been demonstrated in constructing a number of
applications: password-protected secret sharing schemes [JKKX16];
privacy-preserving password stores [SJKS17]; and password-
authenticated key exchange or PAKE [I-D.irtf-cfrg-opaque]. A VOPRF
is necessary in some applications, e.g., the Privacy Pass protocol
[I-D.davidson-pp-protocol], wherein this VOPRF is used to generate
Davidson, et al. Expires 7 January 2022 [Page 3]
Internet-Draft OPRFs July 2021
one-time authentication tokens to bypass CAPTCHA challenges. VOPRFs
have also been used for password-protected secret sharing schemes
e.g. [JKK14].
This document introduces an OPRF protocol built in prime-order
groups, applying to finite fields of prime-order and also elliptic
curve (EC) groups. The protocol has the option of being extended to
a VOPRF with the addition of a NIZK proof for proving discrete log
equality relations. This proof demonstrates correctness of the
computation, using a known public key that serves as a commitment to
the server's secret key. The document describes the protocol, the
public-facing API, and its security properties.
1.1. Change log
draft-07 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-07):
* Bind blinding mechanism to mode (additive for verifiable mode and
multiplicative for base mode).
* Add explicit errors for deserialization.
* Document explicit errors and API considerations.
* Adopt SHAKE-256 for decaf448 ciphersuite.
* Normalize HashToScalar functionality for all ciphersuites.
* Refactor and generalize DLEQ proof functionality and domain
separation tags for use in other protocols.
* Update test vectors.
* Apply various editorial changes.
draft-06 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-06):
* Specify of group element and scalar serialization.
* Remove info parameter from the protocol API and update domain
separation guidance.
* Fold Unblind function into Finalize.
* Optimize ComputeComposites for servers (using knowledge of the
private key).
* Specify deterministic key generation method.
Davidson, et al. Expires 7 January 2022 [Page 4]
Internet-Draft OPRFs July 2021
* Update test vectors.
* Apply various editorial changes.
draft-05 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-05):
* Move to ristretto255 and decaf448 ciphersuites.
* Clean up ciphersuite definitions.
* Pin domain separation tag construction to draft version.
* Move key generation outside of context construction functions.
* Editorial changes.
draft-04 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-04):
* Introduce Client and Server contexts for controlling verifiability
and required functionality.
* Condense API.
* Remove batching from standard functionality (included as an
extension)
* Add Curve25519 and P-256 ciphersuites for applications that
prevent strong-DH oracle attacks.
* Provide explicit prime-order group API and instantiation advice
for each ciphersuite.
* Proof-of-concept implementation in sage.
* Remove privacy considerations advice as this depends on
applications.
draft-03 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-03):
* Certify public key during VerifiableFinalize.
* Remove protocol integration advice.
* Add text discussing how to perform domain separation.
* Drop OPRF_/VOPRF_ prefix from algorithm names.
* Make prime-order group assumption explicit.
Davidson, et al. Expires 7 January 2022 [Page 5]
Internet-Draft OPRFs July 2021
* Changes to algorithms accepting batched inputs.
* Changes to construction of batched DLEQ proofs.
* Updated ciphersuites to be consistent with hash-to-curve and added
OPRF specific ciphersuites.
draft-02 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-02):
* Added section discussing cryptographic security and static DH
oracles.
* Updated batched proof algorithms.
draft-01 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-01):
* Updated ciphersuites to be in line with
https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-04.
* Made some necessary modular reductions more explicit.
1.2. Requirements
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.
2. Preliminaries
The (V)OPRF protocol in this document has two primary dependencies:
* "GG": A prime-order group implementing the API described below in
Section 2.1, with base point defined in the corresponding
reference for each group. (See Section 4 for these base points.)
* "Hash": A cryptographic hash function that is indifferentiable
from a Random Oracle, whose output length is Nh bytes long.
Section 4 specifies ciphersuites as combinations of "GG" and "Hash".
Davidson, et al. Expires 7 January 2022 [Page 6]
Internet-Draft OPRFs July 2021
2.1. Prime-Order Group Dependency
In this document, we assume the construction of an additive, prime-
order group "GG" for performing all mathematical operations. Such
groups are uniquely determined by the choice of the prime "p" that
defines the order of the group. We use "GF(p)" to represent the
finite field of order "p". For the purpose of understanding and
implementing this document, we take "GF(p)" to be equal to the set of
integers defined by "{0, 1, ..., p-1}".
The fundamental group operation is addition "+" with identity element
"I". For any elements "A" and "B" of the group "GG", "A + B = B + A"
is also a member of "GG". Also, for any "A" in "GG", there exists an
element "-A" such that "A + (-A) = (-A) + A = I". Scalar
multiplication is equivalent to the repeated application of the group
operation on an element A with itself "r-1" times, this is denoted as
"r*A = A + ... + A". For any element "A", "p*A=I". We denote "G" as
the fixed generator of the group. Scalar base multiplication is
equivalent to the repeated application of the group operation "G"
with itself "r-1" times, this is denoted as "ScalarBaseMult(r)". The
set of scalars corresponds to "GF(p)". This document uses types
"Element" and "Scalar" to denote elements of the group "GG" and its
set of scalars, respectively.
We now detail a number of member functions that can be invoked on a
prime-order group "GG".
* Order(): Outputs the order of "GG" (i.e. "p").
* Identity(): Outputs the identity element of the group (i.e. "I").
* HashToGroup(x): A member function of "GG" that deterministically
maps an array of bytes "x" to an element of "GG". The map must
ensure that, for any adversary receiving "R = HashToGroup(x)", it
is computationally difficult to reverse the mapping. This
function is optionally parameterized by a domain separation tag
(DST); see Section 4.
* HashToScalar(x): A member function of "GG" that deterministically
maps an array of bytes "x" to an element in GF(p). This function
is optionally parameterized by a DST; see Section 4.
* RandomScalar(): A member function of "GG" that chooses at random a
non-zero element in GF(p).
* SerializeElement(A): A member function of "GG" that maps a group
element "A" to a unique byte array "buf" of fixed length "Ne".
The output type of this function is "SerializedElement".
Davidson, et al. Expires 7 January 2022 [Page 7]
Internet-Draft OPRFs July 2021
* DeserializeElement(buf): A member function of "GG" that maps a
byte array "buf" to a group element "A", or fails if the input is
not a valid byte representation of an element. This function can
raise a DeserializeError if deserialization fails or "A" is the
identity element of the group; see Section 6.4.
* SerializeScalar(s): A member function of "GG" that maps a scalar
element "s" to a unique byte array "buf" of fixed length "Ns".
The output type of this function is "SerializedScalar".
* DeserializeScalar(buf): A member function of "GG" that maps a byte
array "buf" to a scalar "s", or fails if the input is not a valid
byte representation of a scalar. This function can raise a
DeserializeError if deserialization fails; see Section 6.4.
Two functions can be used for generating a (V)OPRF key pair ("skS",
"pkS") where "skS" is a non-zero integer less than "p" and "pkS =
ScalarBaseMult(skS)": "GenerateKeyPair" and "DeriveKeyPair".
"GenerateKeyPair" is a randomized function that outputs a fresh key
pair ("skS", "pkS") upon ever invocation. "DeriveKeyPair" is a
deterministic function that generates private key "skS" from a random
byte string "seed", which SHOULD have at least "Ns" bytes of entropy,
and then computes "pkS = ScalarBaseMult(skS)".
It is convenient in cryptographic applications to instantiate such
prime-order groups using elliptic curves, such as those detailed in
[SEC2]. For some choices of elliptic curves (e.g. those detailed in
[RFC7748], which require accounting for cofactors) there are some
implementation issues that introduce inherent discrepancies between
standard prime-order groups and the elliptic curve instantiation. In
this document, all algorithms that we detail assume that the group is
a prime-order group, and this MUST be upheld by any implementation.
That is, any curve instantiation should be written such that any
discrepancies with a prime-order group instantiation are removed.
See Section 4 for advice corresponding to the implementation of this
interface for specific definitions of elliptic curves.
2.2. Conventions and Terminology
The following conventions are used throughout the document.
* For any object "x", we write "len(x)" to denote its length in
bytes.
* For two byte arrays "x" and "y", write "x || y" to denote their
concatenation.
Davidson, et al. Expires 7 January 2022 [Page 8]
Internet-Draft OPRFs July 2021
* I2OSP and OS2IP: Convert a byte array to and from a non-negative
integer as described in [RFC8017]. Note that these functions
operate on byte arrays in big-endian byte order.
Data structure descriptions use TLS notation [RFC8446], Section 3.
All algorithm descriptions are written in a Python-like pseudocode.
We also use the "CT_EQUAL(a, b)" function to represent constant-time
byte-wise equality between byte arrays "a" and "b". This function
returns "true" if "a" and "b" are equal, and "false" otherwise.
The following terms are used throughout this document.
* PRF: Pseudorandom Function.
* OPRF: Oblivious Pseudorandom Function.
* VOPRF: Verifiable Oblivious Pseudorandom Function.
* Client: Protocol initiator. Learns pseudorandom function
evaluation as the output of the protocol.
* Server: Computes the pseudorandom function over a secret key.
Learns nothing about the client's input.
* NIZK: Non-interactive zero knowledge.
* DLEQ: Discrete Logarithm Equality.
3. (V)OPRF Protocol
In this section, we define two OPRF variants: a base mode and
verifiable mode. In the base mode, a client and server interact to
compute y = F(skS, x), where x is the client's input, skS is the
server's private key, and y is the OPRF output. The client learns y
and the server learns nothing. In the verifiable mode, the client
also gets proof that the server used skS in computing the function.
To achieve verifiability, as in the original work of [JKK14], we
provide a zero-knowledge proof that the key provided as input by the
server in the "Evaluate" function is the same key as it used to
produce their public key. As an example of the nature of attacks
that this prevents, this ensures that the server uses the same
private key for computing the VOPRF output and does not attempt to
"tag" individual servers with select keys. This proof must not
reveal the server's long-term private key to the client.
The following one-byte values distinguish between these two modes:
Davidson, et al. Expires 7 January 2022 [Page 9]
Internet-Draft OPRFs July 2021
+================+=======+
| Mode | Value |
+================+=======+
| modeBase | 0x00 |
+----------------+-------+
| modeVerifiable | 0x01 |
+----------------+-------+
Table 1
3.1. Overview
Both participants agree on the mode and a choice of ciphersuite that
is used before the protocol exchange. Once established, the base
mode of the protocol runs to compute "output = F(skS, input)" as
follows:
Client(input) Server(skS)
----------------------------------------------------------
blind, blindedElement = Blind(input)
blindedElement
---------->
evaluatedElement, proof = Evaluate(skS, blindedElement)
evaluatedElement
<----------
output = Finalize(input, blind, evaluatedElement, blindedElement)
In "Blind" the client generates a token and blinding data. The
server computes the (V)OPRF evaluation in "Evaluation" over the
client's blinded token. In "Finalize" the client unblinds the server
response and produces a byte array corresponding to the output of the
OPRF protocol.
In the verifiable mode of the protocol, the server additionally
computes a proof in Evaluate. The client verifies this proof using
the server's expected public key before completing the protocol and
producing the protocol output.
3.2. Context Setup
Both modes of the OPRF involve an offline setup phase. In this
phase, both the client and server create a context used for executing
the online phase of the protocol. The key pair ("skS", "pkS") should
be generated by calling either "GenerateKeyPair" or "DeriveKeyPair".
Davidson, et al. Expires 7 January 2022 [Page 10]
Internet-Draft OPRFs July 2021
The base mode setup functions for creating client and server contexts
are below:
def SetupBaseServer(suite, skS):
contextString =
"VOPRF07-" || I2OSP(modeBase, 1) || I2OSP(suite.ID, 2)
return ServerContext(contextString, skS)
def SetupBaseClient(suite):
contextString =
"VOPRF07-" || I2OSP(modeBase, 1) || I2OSP(suite.ID, 2)
return ClientContext(contextString)
The verifiable mode setup functions for creating client and server
contexts are below:
def SetupVerifiableServer(suite, skS, pkS):
contextString =
"VOPRF07-" || I2OSP(modeVerifiable, 1) || I2OSP(suite.ID, 2)
return VerifiableServerContext(contextString, skS)
def SetupVerifiableClient(suite, pkS):
contextString =
"VOPRF07-" || I2OSP(modeVerifiable, 1) || I2OSP(suite.ID, 2)
return VerifiableClientContext(contextString, pkS)
Each setup function takes a ciphersuite from the list defined in
Section 4. Each ciphersuite has a two-byte field ID used to identify
the suite.
[[RFC editor: please change "VOPRF07" to "RFCXXXX", where XXXX is the
final number, here and elsewhere before publication.]]
3.3. Context APIs
In this section, we detail the APIs available on the client and
server (V)OPRF contexts. Each API has the following implicit
parameters:
* GG, a prime-order group implementing the API described in
Section 2.1.
* contextString, a domain separation tag taken from the client or
server context.
The data type "ClientInput" is an opaque byte string of arbitrary
length no larger than 2^13 octets. "Proof" is a concatenated
sequence of two "SerializedScalar" values, as shown below.
Davidson, et al. Expires 7 January 2022 [Page 11]
Internet-Draft OPRFs July 2021
SerializedScalar Proof[2*Ns];
3.3.1. Server Context
The ServerContext encapsulates the context string constructed during
setup and the (V)OPRF key pair. It has three functions, "Evaluate",
"FullEvaluate" and "VerifyFinalize" described below. "Evaluate"
takes serialized representations of blinded group elements from the
client as inputs.
"FullEvaluate" takes ClientInput values, and it is useful for
applications that need to compute the whole OPRF protocol on the
server side only.
"VerifyFinalize" takes ClientInput values and their corresponding
output digests from "Finalize" as input, and returns true if the
inputs match the outputs.
Note that "VerifyFinalize" and "FullEvaluate" are not used in the
main OPRF protocol. They are exposed as an API for building higher-
level protocols.
3.3.1.1. Evaluate
Input:
Scalar skS
SerializedElement blindedElement
Output:
SerializedElement evaluatedElement
Errors: DeserializeError
def Evaluate(skS, blindedElement):
R = GG.DeserializeElement(blindedElement)
Z = skS * R
evaluatedElement = GG.SerializeElement(Z)
return evaluatedElement
3.3.1.2. FullEvaluate
Davidson, et al. Expires 7 January 2022 [Page 12]
Internet-Draft OPRFs July 2021
Input:
Scalar skS
ClientInput input
Output:
opaque output[Nh]
def FullEvaluate(skS, input):
P = GG.HashToGroup(input)
T = skS * P
issuedElement = GG.SerializeElement(T)
finalizeDST = "Finalize-" || contextString
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(issuedElement), 2) || issuedElement ||
I2OSP(len(finalizeDST), 2) || finalizeDST
return Hash(hashInput)
3.3.1.3. VerifyFinalize
Input:
Scalar skS
ClientInput input
opaque output[Nh]
Output:
boolean valid
def VerifyFinalize(skS, input, output):
T = GG.HashToGroup(input)
element = GG.SerializeElement(T)
issuedElement = Evaluate(skS, [element])
E = GG.SerializeElement(issuedElement)
finalizeDST = "Finalize-" || contextString
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(E), 2) || E ||
I2OSP(len(finalizeDST), 2) || finalizeDST
digest = Hash(hashInput)
return CT_EQUAL(digest, output)
Davidson, et al. Expires 7 January 2022 [Page 13]
Internet-Draft OPRFs July 2021
3.3.2. VerifiableServerContext
The VerifiableServerContext extends the base ServerContext with an
augmented "Evaluate()" function. This function produces a proof that
"skS" was used in computing the result. It makes use of the helper
functions "GenerateProof" and "ComputeComposites", described below.
3.3.2.1. Evaluate
Input:
Scalar skS
Element pkS
SerializedElement blindedElement
Output:
SerializedElement evaluatedElement
Proof proof
Errors: DeserializeError
def Evaluate(skS, pkS, blindedElement):
R = GG.DeserializeElement(blindedElement)
Z = skS * R
evaluatedElement = GG.SerializeElement(Z)
proof = GenerateProof(skS, G, pkS, R, Z)
return evaluatedElement, proof
The helper functions "GenerateProof" and "ComputeComposites" are
defined below.
3.3.2.2. GenerateProof
Davidson, et al. Expires 7 January 2022 [Page 14]
Internet-Draft OPRFs July 2021
Input:
Scalar k
Element A
Element B
Element C
Element D
Output:
Proof proof
def GenerateProof(k, A, B, C, D)
Cs = [C]
Ds = [D]
a = ComputeCompositesFast(k, B, Cs, Ds)
r = GG.RandomScalar()
M = a[0]
Z = a[1]
t2 = r * A
t3 = r * M
Bm = GG.SerializeElement(B)
a0 = GG.SerializeElement(M)
a1 = GG.SerializeElement(Z)
a2 = GG.SerializeElement(t2)
a3 = GG.SerializeElement(t3)
challengeDST = "Challenge-" || contextString
h2Input = I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(a0), 2) || a0 ||
I2OSP(len(a1), 2) || a1 ||
I2OSP(len(a2), 2) || a2 ||
I2OSP(len(a3), 2) || a3 ||
I2OSP(len(challengeDST), 2) || challengeDST
c = GG.HashToScalar(h2Input)
s = (r - c * k) mod p
proof = [GG.SerializeScalar(c), GG.SerializeScalar(s)]
return proof
Davidson, et al. Expires 7 January 2022 [Page 15]
Internet-Draft OPRFs July 2021
3.3.2.2.1. Batching inputs
Unlike other functions, "ComputeComposites" takes lists of inputs,
rather than a single input. Applications can take advantage of this
functionality by invoking "GenerateProof" on batches of inputs to
produce a combined, constant-size proof. (In the pseudocode above,
the single inputs "blindedElement" and "evaluatedElement" are passed
as one-item lists to "ComputeComposites".)
In particular, servers can produce a single, constant-sized proof for
N client inputs sent in a single request, rather than one proof per
client input. This optimization benefits clients and servers since
it amortizes the cost of proof generation and bandwidth across
multiple requests.
3.3.2.2.2. Fresh Randomness
We note here that it is essential that a different "r" value is used
for every invocation. If this is not done, then this may leak "skS"
as is possible in Schnorr or (EC)DSA scenarios where fresh randomness
is not used.
3.3.2.3. ComputeComposites
The definition of "ComputeComposites" is given below. This function
is used both on generation and verification of the proof.
Davidson, et al. Expires 7 January 2022 [Page 16]
Internet-Draft OPRFs July 2021
Input:
Element B
Element Cs[m]
Element Ds[m]
Output:
Element composites[2]
def ComputeComposites(B, Cs, Ds):
Bm = GG.SerializeElement(B)
seedDST = "Seed-" || contextString
compositeDST = "Composite-" || contextString
h1Input = I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(seedDST), 2) || seedDST
seed = Hash(h1Input)
M = GG.Identity()
Z = GG.Identity()
for i = 0 to m-1:
Ci = GG.SerializeElement(Cs[i])
Di = GG.SerializeElement(Ds[i])
h2Input = I2OSP(len(seed), 2) || seed || I2OSP(i, 2) ||
I2OSP(len(Ci), 2) || Ci ||
I2OSP(len(Di), 2) || Di ||
I2OSP(len(compositeDST), 2) || compositeDST
di = GG.HashToScalar(h2Input)
M = di * Cs[i] + M
Z = di * Ds[i] + Z
return [M, Z]
If the private key is known, as is the case for the server, this
function can be optimized as shown in "ComputeCompositesFast" below.
Davidson, et al. Expires 7 January 2022 [Page 17]
Internet-Draft OPRFs July 2021
Input:
Scalar k
Element B
Element Cs[m]
Element Ds[m]
Output:
Element composites[2]
def ComputeCompositesFast(k, B, Cs, Ds):
Bm = GG.SerializeElement(B)
seedDST = "Seed-" || contextString
compositeDST = "Composite-" || contextString
h1Input = I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(seedDST), 2) || seedDST
seed = Hash(h1Input)
M = GG.Identity()
for i = 0 to m-1:
Ci = GG.SerializeElement(Cs[i])
Di = GG.SerializeElement(Ds[i])
h2Input = I2OSP(len(seed), 2) || seed || I2OSP(i, 2) ||
I2OSP(len(Ci), 2) || Ci ||
I2OSP(len(Di), 2) || Di ||
I2OSP(len(compositeDST), 2) || compositeDST
di = GG.HashToScalar(h2Input)
M = di * Cs[i] + M
Z = k * M
return [M, Z]
3.3.3. Client Context
The ClientContext encapsulates the context string constructed during
setup. It has two functions, "Blind()" and "Finalize()", as
described below. It also has an internal function, "Unblind()",
which is used by "Finalize". The implementation of these functions
varies depending on the mode.
Davidson, et al. Expires 7 January 2022 [Page 18]
Internet-Draft OPRFs July 2021
3.3.3.1. Blind
In this mode, blinding is done multiplicatively. Under certain
application circumstances, the more optimal additive blinding
mechanism described in Section 3.3.4.2 can be used. See Section 6.6
for more details.
"Blind" is implemented as follows.
Input:
ClientInput input
Output:
Scalar blind
SerializedElement blindedElement
def Blind(input):
blind = GG.RandomScalar()
P = GG.HashToGroup(input)
blindedElement = GG.SerializeElement(blind * P)
return blind, blindedElement
The inverse "Unblind" is implemented as follows.
Input:
Scalar blind
SerializedElement evaluatedElement
Output:
SerializedElement unblindedElement
Errors: DeserializeError
def Unblind(blind, evaluatedElement, ...):
Z = GG.DeserializeElement(evaluatedElement)
N = (blind^(-1)) * Z
unblindedElement = GG.SerializeElement(N)
return unblindedElement
Davidson, et al. Expires 7 January 2022 [Page 19]
Internet-Draft OPRFs July 2021
3.3.3.2. Finalize
"Finalize" depends on the internal "Unblind" function. In this mode,
"Finalize" and does not include all inputs listed in Section 3.1.
These additional inputs are only useful for the verifiable mode,
described in Section 3.3.4.3.
Input:
ClientInput input
Scalar blind
SerializedElement evaluatedElement
Output:
opaque output[Nh]
def Finalize(input, blind, evaluatedElement):
unblindedElement = Unblind(blind, evaluatedElement)
finalizeDST = "Finalize-" || contextString
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(unblindedElement), 2) || unblindedElement ||
I2OSP(len(finalizeDST), 2) || finalizeDST
return Hash(hashInput)
3.3.4. VerifiableClientContext
The VerifiableClientContext extends the base ClientContext with the
desired server public key "pkS" with an augmented "Unblind()"
function. This function verifies an evaluation proof using "pkS".
It makes use of the helper function "ComputeComposites" described
above. It has one helper function, "VerifyProof()", defined below.
3.3.4.1. VerifyProof
This algorithm outputs a boolean "verified" which indicates whether
the proof inside of the evaluation verifies correctly, or not.
Davidson, et al. Expires 7 January 2022 [Page 20]
Internet-Draft OPRFs July 2021
Input:
Element A
Element B
Element C
Element D
Proof proof
Output:
boolean verified
def VerifyProof(A, B, C, D, proof):
Cs = [C]
Ds = [D]
a = ComputeComposites(B, Cs, Ds)
c = GG.DeserializeScalar(proof[0])
s = GG.DeserializeScalar(proof[1])
M = a[0]
Z = a[1]
t2 = ((s * A) + (c * B))
t3 = ((s * M) + (c * Z))
Bm = GG.SerializeElement(B)
a0 = GG.SerializeElement(M)
a1 = GG.SerializeElement(Z)
a2 = GG.SerializeElement(t2)
a3 = GG.SerializeElement(t3)
challengeDST = "Challenge-" || contextString
h2Input = I2OSP(len(Bm), 2) || Bm ||
I2OSP(len(a0), 2) || a0 ||
I2OSP(len(a1), 2) || a1 ||
I2OSP(len(a2), 2) || a2 ||
I2OSP(len(a3), 2) || a3 ||
I2OSP(len(challengeDST), 2) || challengeDST
expectedC = GG.HashToScalar(h2Input)
return CT_EQUAL(expectedC, c)
Davidson, et al. Expires 7 January 2022 [Page 21]
Internet-Draft OPRFs July 2021
3.3.4.2. Verifiable Blind
In this mode, where the server public key is available for proof
verification, blinding is done additively. This variant is named
"VerifiableBlind" and "VerifiableUnblind". It takes two inputs: the
client input and a blinded version of the group generator. The
latter is computed using a function called "VerifiablePreprocess",
also described below.
"VerifiableBlind" is implemented as follows.
Input:
ClientInput input
Element blindedGenerator
Output:
SerializedElement blindedElement
def VerifiableBlind(input, blindedGenerator):
P = GG.HashToGroup(input)
blindedElement = GG.SerializeElement(P + blindedGenerator)
return blindedElement
The inverse "VerifiableUnblind" is implemented as follows. This
function can raise an exception if element deserialization or proof
verification fails.
Davidson, et al. Expires 7 January 2022 [Page 22]
Internet-Draft OPRFs July 2021
Input:
Element blindedPublicKey
SerializedElement evaluatedElement
SerializedElement blindedElement
Element pkS
Scalar proof
Output:
SerializedElement unblindedElement
Errors: DeserializeError, VerifyError
def VerifiableUnblind(blindedPublicKey, evaluatedElement,
blindedElement, pkS, proof):
Z = GG.DeserializeElement(evaluatedElement)
R = GG.DeserializeElement(blindedElement)
if VerifyProof(G, pkS, R, Z, proof) == false:
raise VerifyError
N := Z - blindedPublicKey
unblindedElement = GG.SerializeElement(N)
return unblindedElement
The internal "VerifiablePreprocess" function computes a blind and
uses it to compute a corresponding blinded version of the group
generator and server public key. This function can be used to pre-
compute tables of values for future invocations of the protocol, or
it can be computed only when needed for a single invocation of the
protocol.
Davidson, et al. Expires 7 January 2022 [Page 23]
Internet-Draft OPRFs July 2021
Input:
Element pkS
Output:
Element blindedGenerator
Element blindedPublicKey
Scalar blind
def Preprocess(pkS):
blind = GG.RandomScalar()
blindedGenerator = ScalarBaseMult(blind)
blindedPublicKey = pkS * blind
return blindedGenerator, blindedPublicKey, blind
3.3.4.3. Verifiable Finalize
Input:
ClientInput input
Element blindedPublicKey
SerializedElement evaluatedElement
SerializedElement blindedElement
Element pkS
Scalar proof
Output:
opaque output[Nh]
def Finalize(input, blindedPublicKey, evaluatedElement,
blindedElement, pkS, proof):
unblindedElement =
VerifiableUnblind(blindedPublicKey, evaluatedElement,
blindedElement, pkS, proof)
finalizeDST = "Finalize-" || contextString
hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(unblindedElement), 2) || unblindedElement ||
I2OSP(len(finalizeDST), 2) || finalizeDST
return Hash(hashInput)
Davidson, et al. Expires 7 January 2022 [Page 24]
Internet-Draft OPRFs July 2021
4. Ciphersuites
A ciphersuite (also referred to as 'suite' in this document) for the
protocol wraps the functionality required for the protocol to take
place. This ciphersuite should be available to both the client and
server, and agreement on the specific instantiation is assumed
throughout. A ciphersuite contains instantiations of the following
functionalities:
* "GG": A prime-order group exposing the API detailed in
Section 2.1, with base point defined in the corresponding
reference for each group. Each group also specifies HashToGroup,
HashToScalar, and serialization functionalities. For HashToGroup,
the domain separation tag (DST) is constructed in accordance with
the recommendations in [I-D.irtf-cfrg-hash-to-curve], Section 3.1.
For HashToScalar, each group specifies an integer order that is
used in reducing integer values to a member of the corresponding
scalar field.
* "Hash": A cryptographic hash function that is indifferentiable
from a Random Oracle, whose output length is Nh bytes long.
This section specifies ciphersuites with supported groups and hash
functions. For each ciphersuite, contextString is that which is
computed in the Setup functions.
Applications should take caution in using ciphersuites targeting
P-256 and ristretto255. See Section 6.2 for related discussion.
4.1. OPRF(ristretto255, SHA-512)
* Group: ristretto255 [RISTRETTO]
- HashToGroup(): Use hash_to_ristretto255
[I-D.irtf-cfrg-hash-to-curve] with DST = "HashToGroup-" ||
contextString, and "expand_message" = "expand_message_xmd"
using SHA-512.
- HashToScalar(): Compute "uniform_bytes" using "expand_message"
= "expand_message_xmd", DST = "HashToScalar-" || contextString,
and output length 64, interpret "uniform_bytes" as a 512-bit
integer in little-endian order, and reduce the integer modulo
"Order()".
- Serialization: Both group elements and scalars are encoded in
Ne = Ns = 32 bytes. For group elements, use the 'Encode' and
'Decode' functions from [RISTRETTO]. For scalars, ensure they
are fully reduced modulo "Order()" and in little-endian order.
Davidson, et al. Expires 7 January 2022 [Page 25]
Internet-Draft OPRFs July 2021
* Hash: SHA-512, and Nh = 64.
* ID: 0x0001
4.2. OPRF(decaf448, SHAKE-256)
* Group: decaf448 [RISTRETTO]
- HashToGroup(): Use hash_to_decaf448
[I-D.irtf-cfrg-hash-to-curve] with DST = "HashToGroup-" ||
contextString, and "expand_message" = "expand_message_xof"
using SHAKE-256.
- HashToScalar(): Compute "uniform_bytes" using "expand_message"
= "expand_message_xof", DST = "HashToScalar-" || contextString,
and output length 64, interpret "uniform_bytes" as a 512-bit
integer in little-endian order, and reduce the integer modulo
"Order()".
- Serialization: Both group elements and scalars are encoded in
Ne = Ns = 56 bytes. For group elements, use the 'Encode' and
'Decode' functions from [RISTRETTO]. For scalars, ensure they
are fully reduced modulo "Order()" and in little-endian order.
* Hash: SHAKE-256, and Nh = 64.
* ID: 0x0002
4.3. OPRF(P-256, SHA-256)
* Group: P-256 (secp256r1) [x9.62]
- HashToGroup(): Use hash_to_curve with suite P256_XMD:SHA-
256_SSWU_RO_ [I-D.irtf-cfrg-hash-to-curve] and DST =
"HashToGroup-" || contextString.
- HashToScalar(): Use hash_to_field from
[I-D.irtf-cfrg-hash-to-curve] using L = 48,
"expand_message_xmd" with SHA-256, DST = "HashToScalar-" ||
contextString, and prime modulus equal to "Order()".
- Serialization: Elements are serialized as Ne = 33 byte strings
using compressed point encoding for the curve [SEC1]. Scalars
are serialized as Ns = 32 byte strings by fully reducing the
value modulo "Order()" and in big-endian order.
* Hash: SHA-256, and Nh = 32.
Davidson, et al. Expires 7 January 2022 [Page 26]
Internet-Draft OPRFs July 2021
* ID: 0x0003
4.4. OPRF(P-384, SHA-512)
* Group: P-384 (secp384r1) [x9.62]
- HashToGroup(): Use hash_to_curve with suite P384_XMD:SHA-
512_SSWU_RO_ [I-D.irtf-cfrg-hash-to-curve] and DST =
"HashToGroup-" || contextString.
- HashToScalar(): Use hash_to_field from
[I-D.irtf-cfrg-hash-to-curve] using L = 72,
"expand_message_xmd" with SHA-512, DST = "HashToScalar-" ||
contextString, and prime modulus equal to "Order()".
- Serialization: Elements are serialized as Ne = 49 byte strings
using compressed point encoding for the curve [SEC1]. Scalars
are serialized as Ns = 48 byte strings by fully reducing the
value modulo "Order()" and in big-endian order.
* Hash: SHA-512, and Nh = 64.
* ID: 0x0004
4.5. OPRF(P-521, SHA-512)
* Group: P-521 (secp521r1) [x9.62]
- HashToGroup(): Use hash_to_curve with suite P521_XMD:SHA-
512_SSWU_RO_ [I-D.irtf-cfrg-hash-to-curve] and DST =
"HashToGroup-" || contextString.
- HashToScalar(): Use hash_to_field from
[I-D.irtf-cfrg-hash-to-curve] using L = 98,
"expand_message_xmd" with SHA-512, DST = "HashToScalar-" ||
contextString, and prime modulus equal to "Order()".
- Serialization: Elements are serialized as Ne = 67 byte strings
using compressed point encoding for the curve [SEC1]. Scalars
are serialized as Ns = 66 byte strings by fully reducing the
value modulo "Order()" and in big-endian order.
* Hash: SHA-512, and Nh = 64.
* ID: 0x0005
Davidson, et al. Expires 7 January 2022 [Page 27]
Internet-Draft OPRFs July 2021
5. API Considerations
Some VOPRF APIs specified in this document are fallible. For
example, "Finalize" and "Evaluate" can fail if any element received
from the peer fails deserialization. The explicit errors generated
throughout this specification, along with the conditions that lead to
each error, are as follows:
* "VerifyError": VOPRF proof verification failed; Section 3.3.4.2.
* "DeserializeError": Group element or scalar deserialization
failure; Section 2.1.
The errors in this document are meant as a guide to implementors.
They are not an exhaustive list of all the errors an implementation
might emit. For example, implementations might run out of memory and
return a corresponding error.
6. Security Considerations
This section discusses the cryptographic security of our protocol,
along with some suggestions and trade-offs that arise from the
implementation of an OPRF.
6.1. Security Properties
The security properties of an OPRF protocol with functionality y =
F(k, x) include those of a standard PRF. Specifically:
* Pseudorandomness: F is pseudorandom if the output y = F(k,x) on
any input x is indistinguishable from uniformly sampling any
element in F's range, for a random sampling of k.
In other words, consider an adversary that picks inputs x from the
domain of F and evaluates F on (k,x) (without knowledge of randomly
sampled k). Then the output distribution F(k,x) is indistinguishable
from the output distribution of a randomly chosen function with the
same domain and range.
A consequence of showing that a function is pseudorandom, is that it
is necessarily non-malleable (i.e. we cannot compute a new evaluation
of F from an existing evaluation). A genuinely random function will
be non-malleable with high probability, and so a pseudorandom
function must be non-malleable to maintain indistinguishability.
An OPRF protocol must also satisfy the following property:
Davidson, et al. Expires 7 January 2022 [Page 28]
Internet-Draft OPRFs July 2021
* Oblivious: The server must learn nothing about the client's input
or the output of the function. In addition, the client must learn
nothing about the server's private key.
Essentially, obliviousness tells us that, even if the server learns
the client's input x at some point in the future, then the server
will not be able to link any particular OPRF evaluation to x. This
property is also known as unlinkability [DGSTV18].
Optionally, for any protocol that satisfies the above properties,
there is an additional security property:
* Verifiable: The client must only complete execution of the
protocol if it can successfully assert that the OPRF output it
computes is correct. This is taken with respect to the OPRF key
held by the server.
Any OPRF that satisfies the 'verifiable' security property is known
as a verifiable OPRF, or VOPRF for short. In practice, the notion of
verifiability requires that the server commits to the key before the
actual protocol execution takes place. Then the client verifies that
the server has used the key in the protocol using this commitment.
In the following, we may also refer to this commitment as a public
key.
6.2. Cryptographic Security
Below, we discuss the cryptographic security of the (V)OPRF protocol
from Section 3, relative to the necessary cryptographic assumptions
that need to be made.
6.2.1. Computational Hardness Assumptions
Each assumption states that the problems specified below are
computationally difficult to solve in relation to a particular choice
of security parameter "sp".
Let GG = GG(sp) be a group with prime-order p, and let GF(p) be a
finite field of order p.
6.2.1.1. Discrete-log (DL) Problem
Given G, a generator of GG, and H = hG for some h in GF(p); output h.
6.2.1.2. Decisional Diffie-Hellman (DDH) Problem
Sample uniformly at random d in {0,1}. Given (G, aG, bG, C), where
Davidson, et al. Expires 7 January 2022 [Page 29]
Internet-Draft OPRFs July 2021
* G is a generator of GG;
* a,b are elements of GF(p);
* if d == 0: C = abG; else: C is sampled uniformly at random from
GG.
Output d' == d.
6.2.2. Protocol Security
Our OPRF construction is based on the VOPRF construction known as
2HashDH-NIZK given by [JKK14]; essentially without providing zero-
knowledge proofs that verify that the output is correct. Our VOPRF
construction is identical to the [JKK14] construction, except that we
can optionally perform multiple VOPRF evaluations in one go, whilst
only constructing one NIZK proof object. This is enabled using an
established batching technique.
Consequently, the cryptographic security of our construction is based
on the assumption that the One-More Gap DH is computationally
difficult to solve.
The (N,Q)-One-More Gap DH (OMDH) problem asks the following.
Given:
- G, k * G, and (G_1, ... , G_N), all elements of GG;
- oracle access to an OPRF functionality using the key k;
- oracle access to DDH solvers.
Find Q+1 pairs of the form below:
(G_{j_s}, k * G_{j_s})
where the following conditions hold:
- s is a number between 1 and Q+1;
- j_s is a number between 1 and N for each s;
- Q is the number of allowed queries.
The original paper [JKK14] gives a security proof that the 2HashDH-
NIZK construction satisfies the security guarantees of a VOPRF
protocol Section 6.1 under the OMDH assumption in the universal
composability (UC) security model.
Davidson, et al. Expires 7 January 2022 [Page 30]
Internet-Draft OPRFs July 2021
6.2.3. Q-Strong-DH Oracle
A side-effect of our OPRF design is that it allows instantiation of a
oracle for constructing Q-strong-DH (Q-sDH) samples. The Q-Strong-DH
problem asks the following.
Given G1, G2, h*G2, (h^2)*G2, ..., (h^Q)*G2; for G1 and G2
generators of GG.
Output ( (1/(k+c))*G1, c ) where c is an element of GF(p)
The assumption that this problem is hard was first introduced in
[BB04]. Since then, there have been a number of cryptanalytic
studies that have reduced the security of the assumption below that
implied by the group instantiation (for example, [BG04] and
[Cheon06]). In summary, the attacks reduce the security of the group
instantiation by log_2(Q)/2 bits. Note that the attacks only work in
situations where Q divides p-1 or p+1, where p is the order of the
prime-order group used to instantiate the OPRF.
As an example, suppose that a group instantiation is used that
provides 128 bits of security against discrete log cryptanalysis.
Then an adversary with access to a Q-sDH oracle and makes Q=2^20
queries can reduce the security of the instantiation by log_2(2^20)/2
= 10 bits. Launching an attack would require 2^(p/2-log_2(Q)/2) bits
of memory.
Notice that it is easy to instantiate a Q-sDH oracle using the OPRF
functionality that we provide. A client can just submit sequential
queries of the form (G, k * G, (k^2)G, ..., (k^(Q-1))G), where each
query is the output of the previous interaction. This means that any
client that submits Q queries to the OPRF can use the aforementioned
attacks to reduce the security of the group instantiation by
(log_2(Q)/2) bits.
Recall that from a malicious client's perspective, the adversary wins
if they can distinguish the OPRF interaction from a protocol that
computes the ideal functionality provided by the PRF.
Davidson, et al. Expires 7 January 2022 [Page 31]
Internet-Draft OPRFs July 2021
6.2.4. Implications for Ciphersuite Choices
The OPRF instantiations that we recommend in this document are
informed by the cryptanalytic discussion above. In particular,
choosing elliptic curves configurations that describe 128-bit group
instantiations would appear to in fact instantiate an OPRF with
128-(log_2(Q)/2) bits of security. Moreover, such attacks are only
possible for those certain applications where the adversary can query
the OPRF directly. In applications where such an oracle is not made
available this security loss does not apply.
In most cases, it would require an informed and persistent attacker
to launch a highly expensive attack to reduce security to anything
much below 100 bits of security. We see this possibility as
something that may result in problems in the future. For
applications that admit the aforementioned oracle functionality, and
that cannot tolerate discrete logarithm security of lower than 128
bits, we recommend only implementing ciphersuites with IDs 0x0002,
0x0004, and 0x0005.
6.3. Domain Separation
Applications SHOULD construct input to the protocol to provide domain
separation. Any system which has multiple (V)OPRF applications
should distinguish client inputs to ensure the OPRF results are
separate. Guidance for constructing info can be found in
[I-D.irtf-cfrg-hash-to-curve]; Section 3.1.
6.4. Element and Scalar Validation
The DeserializeElement function recovers a group element from an
arbitrary byte array. This function validates that the element is a
proper member of the group and is not the identity element, and
returns an error if either condition is not met.
For P-256, P-384, and P-521 ciphersuites, this function performs
partial public-key validation as defined in Section 5.6.2.3.4 of
[keyagreement]. This includes checking that the coordinates are in
the correct range, that the point is on the curve, and that the point
is not the point at infinity. If these checks fail, deserialization
returns an error.
For ristretto255 and decaf448, elements are deserialized by invoking
the Decode function from [RISTRETTO], Section 4.3.1 and [RISTRETTO],
Section 5.3.1, respectively, which returns false if the element is
invalid. If this function returns false, deserialization returns an
error.
Davidson, et al. Expires 7 January 2022 [Page 32]
Internet-Draft OPRFs July 2021
The DeserializeScalar function recovers a scalar field element from
an arbitrary byte array. Like DeserializeElement, this function
validates that the element is a member of the scalar field and
returns an error if this condition is not met.
For P-256, P-384, and P-521 ciphersuites, this function ensures that
the input, when treated as a big-endian integer, is a value between 0
and "Order()". For ristretto255 and decaf448, this function ensures
that the input, when treated as a little-endian integer, is a valud
between 0 and "Order()".
6.5. Hashing to Group
A critical requirement of implementing the prime-order group using
elliptic curves is a method to instantiate the function
"GG.HashToGroup", that maps inputs to group elements. In the
elliptic curve setting, this deterministically maps inputs x (as byte
arrays) to uniformly chosen points on the curve.
In the security proof of the construction Hash is modeled as a random
oracle. This implies that any instantiation of "GG.HashToGroup" must
be pre-image and collision resistant. In Section 4 we give
instantiations of this functionality based on the functions described
in [I-D.irtf-cfrg-hash-to-curve]. Consequently, any OPRF
implementation must adhere to the implementation and security
considerations discussed in [I-D.irtf-cfrg-hash-to-curve] when
instantiating the function.
6.6. Blinding Considerations
This document makes use of two types of blinding variants:
multiplicative and additive. The advantage of additive blinding is
that it allows the client to pre-process tables of blinded scalar
multiplications for the group generator and server public key. This
can provide a computational efficiency advantage (due to the fact
that a fixed-base multiplication can be calculated faster than a
variable-base multiplication). Pre-processing also reduces the
amount of computation that needs to be done in the online exchange.
However, the choice of blinding mechanism has security implications.
[JKX21] analyze the security properties of both blinding mechanisms
used in this document. The results can be summarized as follows:
* Multiplicative blinding is safe for all applications.
* Additive blinding is possibly unsafe, unless one of the following
conditions are met:
Davidson, et al. Expires 7 January 2022 [Page 33]
Internet-Draft OPRFs July 2021
- The client has a certified copy of the server public key (as is
the case in the verifiable mode);
- The client input has high entropy; and
- The client mixes the public key into the OPRF evaluation.
To avoid security issues with the base mode, where some of the above
conditions may not be met, this specification RECOMMENDS use of
multiplicative blinding. This is because it is not known if the
server public key is available or if the client input has high
entropy. Applications wherein either of these conditions are true
MAY use additive blinding.
The verifiable mode always makes use of the more efficient additive
blinding variant, as the public key is always available for verifying
the proof.
6.7. Timing Leaks
To ensure no information is leaked during protocol execution, all
operations that use secret data MUST run in constant time.
Operations that SHOULD run in constant time include all prime-order
group operations and proof-specific operations ("GenerateProof()" and
"VerifyProof()").
6.8. Key Rotation
Since the server's key is critical to security, the longer it is
exposed by performing (V)OPRF operations on client inputs, the longer
it is possible that the key can be compromised. For example, if the
key is kept in circulation for a long period of time, then it also
allows the clients to make enough queries to launch more powerful
variants of the Q-sDH attacks from Section 6.2.3.
To combat attacks of this nature, regular key rotation should be
employed on the server-side. A suitable key-cycle for a key used to
compute (V)OPRF evaluations would be between one week and six months.
6.8.1. Parameter Commitments
For some applications, it may be desirable for the server to bind
tokens to certain parameters, e.g., protocol versions, ciphersuites,
etc. To accomplish this, the server should use a distinct scalar for
each parameter combination. Upon redemption of a token T from the
client, the server can later verify that T was generated using the
scalar associated with the corresponding parameters.
Davidson, et al. Expires 7 January 2022 [Page 34]
Internet-Draft OPRFs July 2021
7. Acknowledgements
This document resulted from the work of the Privacy Pass team
[PrivacyPass]. The authors would also like to acknowledge helpful
conversations with Hugo Krawczyk. Eli-Shaoul Khedouri provided
additional review and comments on key consistency. Daniel Bourdrez,
Tatiana Bradley, Sofia Celi, Frank Denis, and Bas Westerbaan also
provided helpful input and contributions to the document.
8. References
8.1. Normative References
[BB04] "Short Signatures Without Random Oracles",
<http://ai.stanford.edu/~xb/eurocrypt04a/bbsigs.pdf>.
[BG04] "The Static Diffie-Hellman Problem",
<https://eprint.iacr.org/2004/306>.
[Cheon06] "Security Analysis of the Strong Diffie-Hellman Problem",
<https://www.iacr.org/archive/
eurocrypt2006/40040001/40040001.pdf>.
[DGSTV18] "Privacy Pass, Bypassing Internet Challenges Anonymously",
<https://www.degruyter.com/view/j/popets.2018.2018.issue-
3/popets-2018-0026/popets-2018-0026.xml>.
[I-D.davidson-pp-protocol]
Davidson, A., "Privacy Pass: The Protocol", Work in
Progress, Internet-Draft, draft-davidson-pp-protocol-01,
13 July 2020, <https://datatracker.ietf.org/doc/html/
draft-davidson-pp-protocol-01>.
[I-D.irtf-cfrg-hash-to-curve]
Faz-Hernandez, A., Scott, S., Sullivan, N., Wahby, R. S.,
and C. A. Wood, "Hashing to Elliptic Curves", Work in
Progress, Internet-Draft, draft-irtf-cfrg-hash-to-curve-
11, 13 April 2021, <https://datatracker.ietf.org/doc/html/
draft-irtf-cfrg-hash-to-curve-11>.
[I-D.irtf-cfrg-opaque]
Krawczyk, H., Bourdrez, D., Lewi, K., and C. A. Wood, "The
OPAQUE Asymmetric PAKE Protocol", Work in Progress,
Internet-Draft, draft-irtf-cfrg-opaque-05, 7 June 2021,
<https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-
opaque-05>.
Davidson, et al. Expires 7 January 2022 [Page 35]
Internet-Draft OPRFs July 2021
[JKK14] "Round-Optimal Password-Protected Secret Sharing and
T-PAKE in the Password-Only model",
<https://eprint.iacr.org/2014/650>.
[JKKX16] "Highly-Efficient and Composable Password-Protected Secret
Sharing (Or, How to Protect Your Bitcoin Wallet Online)",
<https://eprint.iacr.org/2016/144>.
[PrivacyPass]
"Privacy Pass",
<https://github.com/privacypass/challenge-bypass-server>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/rfc/rfc2119>.
[RFC7748] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves
for Security", RFC 7748, DOI 10.17487/RFC7748, January
2016, <https://www.rfc-editor.org/rfc/rfc7748>.
[RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch,
"PKCS #1: RSA Cryptography Specifications Version 2.2",
RFC 8017, DOI 10.17487/RFC8017, November 2016,
<https://www.rfc-editor.org/rfc/rfc8017>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.
[RISTRETTO]
Valence, H. D., Grigg, J., Tankersley, G., Valsorda, F.,
Lovecruft, I., and M. Hamburg, "The ristretto255 and
decaf448 Groups", Work in Progress, Internet-Draft, draft-
irtf-cfrg-ristretto255-decaf448-00, 5 October 2020,
<https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-
ristretto255-decaf448-00>.
[SEC1] Standards for Efficient Cryptography Group (SECG), ., "SEC
1: Elliptic Curve Cryptography",
<https://www.secg.org/sec1-v2.pdf>.
[SEC2] Standards for Efficient Cryptography Group (SECG), ., "SEC
2: Recommended Elliptic Curve Domain Parameters",
<http://www.secg.org/sec2-v2.pdf>.
[SJKS17] "SPHINX, A Password Store that Perfectly Hides from
Itself", <https://eprint.iacr.org/2018/695>.
Davidson, et al. Expires 7 January 2022 [Page 36]
Internet-Draft OPRFs July 2021
[x9.62] ANSI, "Public Key Cryptography for the Financial Services
Industry: the Elliptic Curve Digital Signature Algorithm
(ECDSA)", ANSI X9.62-1998, September 1998.
8.2. Informative References
[JKX21] Jarecki, S., Krawczyk, H., and J. Xu, "On the (In)Security
of the Diffie-Hellman Oblivious PRF with Multiplicative
Blinding", PKC'21 , March 2021,
<https://eprint.iacr.org/2021/273>.
[keyagreement]
Barker, E., Chen, L., Roginsky, A., Vassilev, A., and R.
Davis, "Recommendation for pair-wise key-establishment
schemes using discrete logarithm cryptography", National
Institute of Standards and Technology report,
DOI 10.6028/nist.sp.800-56ar3, April 2018,
<https://doi.org/10.6028/nist.sp.800-56ar3>.
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
<https://www.rfc-editor.org/rfc/rfc8446>.
Appendix A. Test Vectors
This section includes test vectors for the (V)OPRF protocol specified
in this document. For each ciphersuite specified in Section 4, there
is a set of test vectors for the protocol when run in the base mode
and verifiable mode. Each test vector lists the batch size for the
evaluation. Each test vector value is encoded as a hexadecimal byte
string. The label for each test vector value is described below.
* "Input": The client input, an opaque byte string.
* "Blind": The blind value output by "Blind()", a serialized
"Scalar" of "Ns" bytes long.
* "BlindedElement": The blinded value output by "Blind()", a
serialized "Element" of "Ne" bytes long.
* "EvaluatedElement": The evaluated element output by "Evaluate()",
a serialized "Element" of "Ne" bytes long.
* "EvaluationProofC": The "c" component of the Evaluation proof
(only listed for verifiable mode test vectors), a serialized
"Scalar" of "Ns" bytes long.
Davidson, et al. Expires 7 January 2022 [Page 37]
Internet-Draft OPRFs July 2021
* "EvaluationProofS": The "s" component of the Evaluation proof
(only listed for verifiable mode test vectors), a serialized
"Scalar" of "Ns" bytes long.
* "Output": The OPRF output, a byte string of length "Nh" bytes.
Test vectors with batch size B > 1 have inputs separated by a comma
",". Applicable test vectors will have B different values for the
"Input", "Blind", "BlindedElement", "EvaluationElement", and "Output"
fields.
Base mode uses multiplicative blinding while verifiable mode uses
additive blinding, as described in Section 3.3.3 and Section 3.3.4,
respectively.
The server key material, "pkSm" and "skSm", are listed under the mode
for each ciphersuite. Both "pkSm" and "skSm" are the serialized
values of "pkS" and "skS", respectively, as used in the protocol.
Each key pair is derived from a "seed", which is listed as well,
using the following implementation of "DeriveKeyPair":
def DeriveKeyPair(mode, suite, seed):
skS = GG.HashToScalar(seed, DST = "HashToScalar-" || contextString)
pkS = ScalarBaseMult(skS)
return skS, pkS
A.1. OPRF(ristretto255, SHA-512)
A.1.1. Base Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
skSm = caeff69352df4905a9121a4997704ca8cee1524a110819eb87deba1a39ec1
701
A.1.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = c604c785ada70d77a5256ae21767de8c3304115237d262134f5e46e512cf
8e03
BlindedElement = fc20e03aff3a9de9b37e8d35886ade11ec7d85c2a1fb5bb0b16
86c64e07ac467
EvaluationElement = 7c72cc293cd7d44c0b57c273f27befd598b132edc665694b
dc9c42a4d3083c0a
Output = e3a209dce2d3ea3d84fcddb282818caebb756a341e08a310d9904314f53
92085d13c3f76339d745db0f46974a6049c3ea9546305af55d37760b2136d9b3f013
4
Davidson, et al. Expires 7 January 2022 [Page 38]
Internet-Draft OPRFs July 2021
A.1.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 5ed895206bfc53316d307b23e46ecc6623afb3086da74189a416012be037
e50b
BlindedElement = 483d4f39de5ff77fa0f9a0ad2334dd5bf87f2cda868539d21de
67ce49e7d1536
EvaluationElement = 026f2758fc62f02a7ff95f35ec6f20186aa57c0274361655
543ea235d7b2aa34
Output = 2c17dc3e9398dadb44bb2d3360c446302e99f1fe0ec40f0b1ad25c9cf00
2be1e4b41b4900ef056537fe8c14532ccea4d796f5feab9541af48057d83c0db86fe
9
A.1.2. Verifiable Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
skSm = ac37d5850510299406ea8eb8fa226a7bfc2467a4b070d6c7bf667948b9600
b00
pkSm = 0c0254e22063cae3e1bae02fb6fa20882664a117c0278eda6bda3372c0dd9
860
A.1.2.1. Test Vector 1, Batch Size 1
Input = 00
Blind = ed8366feb6b1d05d1f46acb727061e43aadfafe9c10e5a64e7518d63e326
3503
BlindedElement = 66a2835d9da73ecf1ea433bca7ae2b887995cf4b1ffc14f77de
0a417e880a534
EvaluationElement = 8ac09f2a720b3ff03373776edaff052ac4cbe685737df20b
82f6ae1829b21f25
EvaluationProofC = a82634a5381954a31a2f537f76a6765ed6965ed5a48599b41
064d213b06e4b0f
EvaluationProofS = 4b8e4ce683fdc433965db51efb9573a669e83ed5982b05a48
3b71fa181179e0c
Output = e694146179b874ff64f0c9ec59c292031e7d3386703d0ed129cfee98eec
eeb184c0335c7c28be75f7298a33a48c05b2acbd36169a075e495f710c490b404ce3
0
A.1.2.2. Test Vector 2, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 39]
Internet-Draft OPRFs July 2021
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = e6d0f1d89ad552e383d6c6f4e8598cc3037d6e274d22da3089e7afbd4171
ea02
BlindedElement = 122d4446e76662865ff48a7f1117eab928cfdaafca237e3b424
7cb9c6761fd0f
EvaluationElement = 6438480e8cbff8afbcd23f8655910388a9251874b008e1aa
9ff36f3f89c0e02a
EvaluationProofC = c7a18f8d95aceb7f5948cb3c8747b3d33900a6f3d7ccb9236
5860da919ebd705
EvaluationProofS = 67e02e92883fa976ca171b87807450af9ac638581311bd5bc
cc9efa8ddae020a
Output = aa5475f7d60613eab56bf317ea10340ed26be9cbea9685f2617f5a68d55
09a485a15d4db1b41c3ef0f68dd54cc3a4a53d92813797babb0683b71263f5e63b3f
6
A.1.2.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 80513e77795feeec6d2c450589b0e1b178febd5c193a9fcba0d27f0a06e0
d50f,533c2e6d91c934f919ac218973be55ba0d7b234160a0d4cf3bddafbda99e2e0
c
BlindedElement = 025529520d154b88dde799ad81b4bad43c10d2d983c866304b3
65de3062d5c16,68b7ead5133c421ac2052e384421b7d306fe698245e0bebe4d0058
bb7daf1b69
EvaluationElement = e27c872c0f0e04aa86927c28b42fb3181c312741296d6dc6
247b3152ea7bb81f,f07381baa4420ed5cf1bb4e52f3e1a32a9372b17161e11086d1
18b424f87a104
EvaluationProofC = fa1af76c86aaa73a4abb577f5a30ff9b8aced055120ae0390
b73f51d173c620a
EvaluationProofS = 51ccd568a3494f627eee67660a44133706d67d88a9652aee1
02f999553214e06
Output = e694146179b874ff64f0c9ec59c292031e7d3386703d0ed129cfee98eec
eeb184c0335c7c28be75f7298a33a48c05b2acbd36169a075e495f710c490b404ce3
0,aa5475f7d60613eab56bf317ea10340ed26be9cbea9685f2617f5a68d5509a485a
15d4db1b41c3ef0f68dd54cc3a4a53d92813797babb0683b71263f5e63b3f6
A.2. OPRF(decaf448, SHAKE-256)
A.2.1. Base Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
skSm = 78f2622804104209f7e015370ff98f4a3cbf311e6784e9f4944f8a252dc08
e916d9ab1a60dc905f0e56631903ecd4ae6e15291776d61460b
A.2.1.1. Test Vector 1, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 40]
Internet-Draft OPRFs July 2021
Input = 00
Blind = d1080372f0fcf8c5eace50914e7127f576725f215cc7c111673c635ce668
bbbb9b50601ad89b358ab8c23ed0b6c9d040365ec9d060868714
BlindedElement = 984e0a443ee194090737df4afb402253f216b77650c91d252b6
638e1179723d51a4154b88eae396f1320f5df3c4b17f779516c456e364bd1
EvaluationElement = ec07794d109d5dd976bac4f23a4d041f4abd17017af78add
5dd87c66db44590131e23dd3e30310f43284b9e0b874041105eb8201ad584830
Output = e2d48872c64bd0e62cd6165c0a75399bbf6cecf39b85230c2748ccf7ebf
376d28394ac0b9518e1adb070c6952b5ab897e1cbce5f9d78ec8935de59f58210321
a
A.2.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = aed1ffa44fd8f0ed16373606a3cf7df589cca86d8ea1abbf5768771dbef3
d401c74ae55ba1e28b9565e1e4018eb261a14134a4ce60c1c718
BlindedElement = 4aa751f84b2634b73efa364b03e60b92b84f457576e6b369eea
b76140e3859d10d2e98174f13f5a2c70670529ccf093d5f1aaf355b4f830b
EvaluationElement = 429e9d382354f8079cc1e353ef431243cdfca5ec35eb662f
2214b96483e5e6392f15734dd56d65c0c1600d7fd685315831d11f3c33e7230d
Output = b57a408fa6dafe00091e6f6b3d0086bc21ae9c4ead173987672e92f7116
2fea3970341cd63bc33ca442302474bbf95db41cd2b9fa0f2a607b6b4f57443a2f4b
5
A.2.2. Verifiable Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
skSm = 9eb722f7fee9f61f24ad31bc42309f73648cf4393929e8f5f333fe10c6975
c827a1eba4e03ae2fa8735db2f63f6c98c7af6010e64c81f535
pkSm = b6e2751176d57836fe1dfbdbbdc78a1b5c5a52f831226c9d8dfdf5daf8f46
6e310e80978e9b81c387f5bc85cc7ef5567f4dd3ba7674579a2
A.2.2.1. Test Vector 1, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 41]
Internet-Draft OPRFs July 2021
Input = 00
Blind = 4c936db1779a621b6c71475ac3111fd5703a59b713929f36dfd1e892a7fe
814479c93d8b4b6e11d1f6fe5351e51457b665fa7b76074e531f
BlindedElement = c0c9b0d321c4e7c8c13b910428196af3f36d5dae4796e2577fb
51493d3204cc1ee7732d81e0429195e4ad9226b84797feb261bfb2dbe48e9
EvaluationElement = a8f7614c46fb27a49f22fd3d3795d4f96667dfa075d967d7
3e32e9eb0e6705055dfc4446b20c8600cb1a6e636b9066217690c9ee9cd509c0
EvaluationProofC = 199a534bc888fb31dc08a1a1374c669ae61578ba7d51c0d40
f5169e35f95eda58fa7801d30593206b4df72de0680956dff2d8ded5b56e324
EvaluationProofS = 91370471e63326a97f0b2830c4caf95129ac603fd504496fc
cb559c9109e079c49a504acbef4dd6e64ef2f429286f40ff00f4c6a7a57a107
Output = 31c251b66b1fafa46519252c9fc018dd117f219697f45e38bda7253d9cd
02d5a631600387c4863139ea79b3c036c706e70040d2148c43fa2fd47ea3d1d6f42e
5
A.2.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 15b3355179392f40c3d5a15f0d5ffc354e340454ec779f575e4573a3886a
b5e57e4da2985cea9e32f6d95539ce2c7189e1bd7462e8c5483a
BlindedElement = 3c05e826c9d885fd29bf537acc3bcc279c0821bd65cf21d9dcc
99a15af2474df8b3903f220cce9a9f7966a3991c37ae69a73deca4925ab58
EvaluationElement = ac1821113a6748a66c75ac71bedf2784402b60cbf9df16c3
cfc0ba1a240edfaa5ea5f35a5d5fa8221d60deeceb9dd14a6c4ed0ef01f2f2b4
EvaluationProofC = 2129b555a89ee00a826ae0080a71874a2b7612dfa3357c32f
3c1421cb0f93168eee21d72e0d279e772fed4724397463c4972ec8b09f50a2f
EvaluationProofS = a1ec1562977cb52a458e26736e350ac02e09f709b81788f6b
944022c2313a1217134b9cc6232ac86d6b758d2b906ac5d9158a13e7221ec32
Output = e7956cc9410d6a906a0293172e816750cfc099d04db7af8a8970b3bb20d
73cbec56d61a969ff1db724b1701cbf63ad570b591a1fde2c7f409dee29457a6c5d8
c
A.2.2.3. Test Vector 3, Batch Size 2
Davidson, et al. Expires 7 January 2022 [Page 42]
Internet-Draft OPRFs July 2021
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 614bb578f29cc677ea9e7aea3e4839413997e020f9377b63c13584156a09
a46dd2a425c41eac0e313a47e99d05df72c6e1d58e6592577a0d,4c115060bca87db
7d73e00cbb8559f84cb7a221b235b0950a0ab553f03f10e1386abe954011b7da62bb
6599418ef90b5d4ea98cc28aff517
BlindedElement = e2f4aa0e9d09c39cc6f9f58fa4e99af814977f3033cfe613d7c
e525ebf62b93970e4e32b99c1f8090b55d55fb9cb6180c864b5ea29342f98,6ec406
36ebae90b96df53d451c47a26231c7975ab0b3f2af61f8b6d6455662a08cdeb92ccb
6bc08d6c0a6662435f693f55c043bd4d366b01
EvaluationElement = 32f832dcf7d7d493c1c23c3cd94546aef8ffbc455ac16ebe
c2d892d9e731581b41790879e735cb825574552af397a787b47593f095f5a40f,ea5
eee6f8206ceaa109b2c0fcf7807d3b585c751e1476ab140515972eac3a9a847b4858
871e4d92c69a7c8e32bcbaa2aa59d876f02b083b8
EvaluationProofC = 170d265464be75ee7e820f4b90b4f6ded3c379607b103eeb9
e04026f07eb89ae233169af78b32d79dfa40a7bbce0d16c6a3562345e44471f
EvaluationProofS = ec007985eb27fa7931793801f3e060b272ac12610419ca411
52b24e7fab94e639cd85d95b9f6fa16ec32715fd4028f6441d4c5e06a0e2c3c
Output = 31c251b66b1fafa46519252c9fc018dd117f219697f45e38bda7253d9cd
02d5a631600387c4863139ea79b3c036c706e70040d2148c43fa2fd47ea3d1d6f42e
5,e7956cc9410d6a906a0293172e816750cfc099d04db7af8a8970b3bb20d73cbec5
6d61a969ff1db724b1701cbf63ad570b591a1fde2c7f409dee29457a6c5d8c
A.3. OPRF(P-256, SHA-256)
A.3.1. Base Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
skSm = a1b2355828f2c76de6749af9d093bd9fe0f2cada3ec653cd9a6d3126a7a78
27b
A.3.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 5d9e7f6efd3093c32ecceabd57fb03cf760c926d2a7bfa265babf29ec98a
f0d0
BlindedElement = 03e3c379698da853d9844098fa0ac676970d5ec24167b598714
cd2ee188604ddd2
EvaluationElement = 03ea54e8d095332d1a601a3f8a5013188aea036bf9b56323
6f7fd3b046908b42fd
Output = 464e3e51e4086a824d9a2f939524d7069ae4072a788bc9d5daa0762b258
26437
A.3.1.2. Test Vector 2, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 43]
Internet-Draft OPRFs July 2021
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 825155ab61f17605af2ae2e935c78d857c9407bcd45128d57d338f1671b5
fcbe
BlindedElement = 030b40be181ffbb3c3ae4a4911287c43261f5e4034781def69c
51608f372a02102
EvaluationElement = 03115ad70ea55dbb4006da0ee3589a3582f31ef9cd143996
d1e31a25ad3abdcf6f
Output = b597d58c843d0f9d2712121b0a3e2912ebee1c829eed3089eade9af4359
ab275
A.3.2. Verifiable Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
skSm = 4e7804245a743c59d624457677294e04a8bc4bdcd94f0d3bd54f568067489
d34
pkSm = 03b51a0af95c819b09ee80c2056cf0ab0551a5355266d3a0aaff90c3fe915
ed892
A.3.2.1. Test Vector 1, Batch Size 1
Input = 00
Blind = cee64d86fd20ab4caa264a26c0e3d42fb773b3173ba76f9588c9b14779bd
8d91
BlindedElement = 03a734663e3eb29474c79996fe1d0662071594ed7a27832e214
9bad364e44784c5
EvaluationElement = 022ca51b981dd6bd5e08ad7f16ed0e08e67270fe2fc0df76
0be8f95019ffba50c6
EvaluationProofC = d7403f40351dc210d55b78ee34671b2f239faf264b5af8aec
a3101ada4ff8643
EvaluationProofS = 6d7cb0e2697bf197578e6dde7abf09d31cf782260e471c930
e79acc6949df83e
Output = 63e261480afa379117f23016997d6c8558262407d54c588881b74650a7c
cdfd1
A.3.2.2. Test Vector 2, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 44]
Internet-Draft OPRFs July 2021
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 5c4b401063eff0bf242b4cd534a79bacfc2e715b2db1e7a3ad4ff8af1b24
daa2
BlindedElement = 03b6bc0a56d6ed8461a06605c1b293e768d418dc9c42b8851c1
a49292456dd1dad
EvaluationElement = 0349529dc853a564345aa04a9512a088ad69c5064b1108f8
edfe914c5b74e03f58
EvaluationProofC = 88185c7c3a5fdebf24fc37c39925d745b4a286ec9234f32a3
dbf36c5b5261230
EvaluationProofS = aac945f48e297e4d70ed819688176030ffe370bfe2292a12c
4570b83ba7912a0
Output = 1232618e21b6c287ac80fcbe3fbc5013d6ec858a1529abf628514c0c19c
16570
A.3.2.3. Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = f0c7822ba317fb5e86028c44b92bd3aedcf6744d388ca013ef33edd36930
4eda,3b9631be9f8b274d9aaf671bfb6a775229bf435021b89c683259773bc686956
b
BlindedElement = 02fbfb72be2e5df24abb1791489e3a77f9d30b28bafea7ba7c0
f2c31bbf3deb851,0357f017a6cb76f545233c96b806165b52fb7ab700708f817cf3
501b789f8d57fb
EvaluationElement = 0350f7984730eb0a6fa95e795b68a13b3d461bf0c9bfa6e4
a33709b08f65ae528b,026061aa05c776aa08fd96c7eb284051f8a1303d989a1c8b5
e9a478e5c9f37207f
EvaluationProofC = a6e08a019deaf2eba7f40162be527bb574db98679662bb97e
0db02d58638d0dc
EvaluationProofS = 65dc2e6b64e172d8b7f6dac088737f4612a1ea455801eed6d
140554bed0903dd
Output = 63e261480afa379117f23016997d6c8558262407d54c588881b74650a7c
cdfd1,1232618e21b6c287ac80fcbe3fbc5013d6ec858a1529abf628514c0c19c165
70
A.4. OPRF(P-384, SHA-512)
A.4.1. Base Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
skSm = ef1b52c12cdf43dc260bf5425a30cde7d708ec34b38dcfbdc2946d7baf525
361e797f6a98f1ebd80f64865f21cde1c6d
A.4.1.1. Test Vector 1, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 45]
Internet-Draft OPRFs July 2021
Input = 00
Blind = 359073c015b92d15450f7fb395bf52c6ea98384c491fe4e4d423b59de7b0
df382902c13bdc9993d3717bda68fc080b99
BlindedElement = 02fa3115c21ffcacc09ca470729b725781f84333e217cfeec2b
8ba6a54ce492ede7ead3714c5b177427ef853effb1b5c24
EvaluationElement = 020407d59b1497e23f6ff1af68631657dd31c418a8f5e3e9
4878e842ace8b72514f90f95909284069ca88b7728ba5fcdc8
Output = a1a1e468268164ad307b7bb5a92add28ed42117f5ca4dfd6e6534c56183
4ac65f394d0eb25489a22420d52c605931745a6683638b648d230b7599c7c78cb0b1
5
A.4.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 21ece4f9b6ffd01ce82082545413bd9bb5e8f3c63b86ae88d9ce0530b01c
b1c23382c7ec9bdd6e75898e4877d8e2bc17
BlindedElement = 025fddc89a832089a59120df742acb34dba82b26afcae977961
57df238b5905c494a23c56b1f485cbbff78d31df7fa1492
EvaluationElement = 03ab50834f953a0b27afdad59cb18c6ffa3d95dfc265467b
d7dfe96935b6cef735daa39f7a08853092f47323371695153d
Output = b5ef8dbe81d0fd8bbcd104d5f729aaa1d8b7378ab0c6da84c1a13152891
ac71a069bc9654f7f6c3f9dfc6b9e5d47996e81d7679992300216afe9a759f737741
e
A.4.2. Verifiable Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3
skSm = 67ee1c9e67566d87bfcca9e5dac4bfdb8bdd727c031133fac2aa9ba6c41e6
1e5f8fd401b5d76c7d54b15b15932797479
pkSm = 029b51b2ce9c499f2056e65e0f41d60960f9c4795c0cf94af273ce840c20b
e4cdf87690b6b121b37d399b49afcc2ec9ac3
A.4.2.1. Test Vector 1, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 46]
Internet-Draft OPRFs July 2021
Input = 00
Blind = 102f6338df84c9602bfa9e7d690b1f7a173d07e6d54a419db4a6308f8b09
589e4283efb9cd1ee4061c6bf884e60a8774
BlindedElement = 03dacf29b7369164ab41eb0388a8258def9ff09933b3a2abed4
a400327810b0b5d940a4d4710473f61266a6d2b20e6786d
EvaluationElement = 020b0ee924fc9a6f9b51894b3db9df3f2e1f29eb46f41a59
7aaa81942e1f6673f38c47db05924d08867cc7b45ffd5bfba0
EvaluationProofC = 79fe0dbfc6fd433b155f98fd4a019de4d7ffeef4bd6eb10a8
bf5a03602f20ef99ac2e05ca497f6276338b6f523bcf4b2
EvaluationProofS = 4ad2a121801039a9368f3aeb7011b553d18e7f4406c63ddfb
5799a9f53e3fc11c939b591ebc670a7297c66624d62ff49
Output = 8cf810d1e5750dffe92ad14749c007bbcfea47153eb49007edafd30201d
deca63730db8acdec0ca7fd8db2a96775e3f17c7d41db40d469c1054ac0d3f709cf2
b
A.4.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 8aec1d0c3d16afd032da7ba961449a56cec6fb918e932b06d5778ac7f67b
ecfb3e3869237f74106241777f230582e84a
BlindedElement = 027c6fc6f8ddf937b6c44183a39246ab26d0caf5ad7dd13e556
acbb997cd66295e66511a78df5e216a4d354bc7e909e027
EvaluationElement = 025b559f59b4e3417bf26956af2675c9e3f3cd5d97e1c507
8dc880e8bfb0858a34fb9ba9744b7d9d66effc3e8faf02371a
EvaluationProofC = 144948b5d60dbf8b3cb15a5808e6cd35715db57e0c5e4e237
1a0d7b18bdea59e9e0e53dd9e618010544c5e33a52c6565
EvaluationProofS = f237c5f04902be869bd21b94118c58fe2d1aacb182bab2271
ea107afc9da3a97aadaac27022b46980ffd5ab828c54df5
Output = 2c7f0e808bd75781c1673bfa14de23347a0ef3a4c413312bc4368387ae3
bd6da250f726f1b5dcade0187f0ac378e54fdd3792e3a66ce9482c42631909e9de1d
8
A.4.2.3. Test Vector 3, Batch Size 2
Davidson, et al. Expires 7 January 2022 [Page 47]
Internet-Draft OPRFs July 2021
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 41fabd4722d92472d858051ce9ad1a533176a862c697b2c392aff2aeb77e
b20c2ae6ba52fe31e13e03bf1d9f39878b23,51171628f1d28bb7402ca4aea6465e2
67b7f977a1fb71593281099ef2625644aee0b6c5f5e6e01a2b052b3bd4caf539b
BlindedElement = 030117571255e98fe43636c07b1d6a2e793563bf50644946144
7295678c707c4e9214d9805fcc3df35acfb29b775fab1f0,039e9c4a303efc469e20
00965c7a023dabc43f88caea4e8b47e3b737ee8fc30ba93480d29b9e1e3e59cedfa2
a5f4aeb9dd
EvaluationElement = 032a382fdef3f63c6bd4fbdc26448773356880a1d7e16ec4
0f35374714e49cc725ea84e33b69e188f68fb782c558263ce0,02f88eaba928531d8
357e808cb7148c0de204d5d589a6bba770c4cfa448876a029aea214c3e0bb6a693a7
d88b001dbc098
EvaluationProofC = 0bc83100bf6b3ac8d8ad46f3973c107441edfa551f5622286
751698617f809713e749492e1310241bd0f66c657d74f8b
EvaluationProofS = 09b2fc47495de88f2dbde5ea6f0abc24d750861b6a25adca3
a36e65ac1e0913a2f988e0684e520fd3b63be47e57914b4
Output = 8cf810d1e5750dffe92ad14749c007bbcfea47153eb49007edafd30201d
deca63730db8acdec0ca7fd8db2a96775e3f17c7d41db40d469c1054ac0d3f709cf2
b,2c7f0e808bd75781c1673bfa14de23347a0ef3a4c413312bc4368387ae3bd6da25
0f726f1b5dcade0187f0ac378e54fdd3792e3a66ce9482c42631909e9de1d8
A.5. OPRF(P-521, SHA-512)
A.5.1. Base Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
skSm = 016ee706f30ce7e15e4ffa3114c7d59a7b6f302d531ca60419be39d1cd43e
e13b1fc8398b7f63a900cdc49c6e99f65a74403db2fa739927a2ee288cff857d9d84
ecf
A.5.1.1. Test Vector 1, Batch Size 1
Input = 00
Blind = 01b983705fcc9a39607288b935b0797ac6b3c4b2e848823ac9ae16b3a3b5
816be03432370deb7c3c17d9fc7cb4e0ce646e04e42d638e0fa7a434ed340772a8b5
d626
BlindedElement = 0301f0a8c68e58f5571bd39fe3b0b2aa055a8c34e3d68ba0d2e
d177db0bc7575d477ed8f557596feb5ac568fe738eee8cff7dcb56dc78f52bf381c0
912e0e84b5a3f5b
EvaluationElement = 0200babff80ca9060825acc2e53da599016aa4685f3c3f38
ad71dafe4200b26a588cd040fb56947c78929fc1bc56075bedbb363f28bcf65e33c6
fe7f938783a2dfa97e
Output = da67996ac63b34db17ae15c98edd21565286d7549970f260c2f1360c62e
418c3695fa61e50c39df59be2e14376abb6732c07a627a7b49ac4615544e95b47afa
c
Davidson, et al. Expires 7 January 2022 [Page 48]
Internet-Draft OPRFs July 2021
A.5.1.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 01a03b1096b0316bc8567c89bd70267d35c8ddcb2be2cdc867089a2eb5cf
471b1e6eb4b043b9644c8539857abe3a2022e9c9fd6a1695bbabe8add48bcd149ff3
b841
BlindedElement = 030099c35342a43221c6e03debfb17bad71b62e04c9242aa6e9
f2f915163ef4f5b8b7fe1740a4d636c36bd5c73ca39c69992dc7f6dff8f232125efc
22af4df8352fea2
EvaluationElement = 03017c756b73ddbaa80c2ee4ad61e431ac2494f80c258065
23c6be5cff2f544540d74263a4c93fb4e43e8411fc145448013c376d7ddb73f001cb
c9c5529b693b0e1aa8
Output = 3d8405a1f73a8c2fb87bb1136499991fe0c4708b64767531385dc6db106
f09d47868860fbb47bc1ac6a466673bb52ef304cba124580109ea41b2734eb3cd14c
5
A.5.2. Verifiable Mode
seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3
skSm = 0017674057e06c5e3e8a331f2dc3558540701c9cd0f4c19126d5972af6a01
447b312d05a06dab3e9e07c891d749444c27ede0897ad42aea03b887eb5db93e3f29
a86
pkSm = 0201ee4e2eaa74728f577f4bb282c5440cd454fdee1d79b15a36d34b5e5a1
25e3ccc0f99e32cc0a6a15b5652a0c8a424860c6753f685d0e1e150ceba24ca3386f
29216
A.5.2.1. Test Vector 1, Batch Size 1
Davidson, et al. Expires 7 January 2022 [Page 49]
Internet-Draft OPRFs July 2021
Input = 00
Blind = 00bbb82117c88bbd91b8954e16c0b9ceed3ce992b198be1ebfba9ba970db
d75beefbfc6d056b7f7ba1ef79f4facbf2d912c26ce2ecc5bb8d66419b379952e96b
d6f5
BlindedElement = 03017f6448132acb88e7b3c4324f9d9608e27a95dc9ac643915
a9e85618ed09b7072729237646da9a0d37a1169c148cb13041817ccf6e2eb37b512f
f89d1850718ec50
EvaluationElement = 0300db733bf9d6441b04d9f650b3a572252200f84dc15d67
e75d6417479db3dc5c1f29cefc0e3578858ad3ec6037d3ea2f03b2d60ba5fe9f6aa4
b408ee128204bbb334
EvaluationProofC = 002097435da1befb7ad15ad2d25ad3e56b0eccbec5087d773
94039c2871a020dcf30deb4d95b5050f5febe1ebda4547870d46b1d3cef4dd04f793
e6016a23d180285
EvaluationProofS = 01976fbe0ce1922c14eef7ad402cb463d6f11ba2ae402a19e
4bc514c814b42d226175f76353c2b0bad26f98985e5f3b96a8e5557d78b7bc13eb8c
44cafb9f441772c
Output = 64b90ccb524dc125290bda4f6102871a8580d9cb0dfe1c0e46ae87d70a1
690ddf7ed5d970ac3b51e959a8769fd8e5ee5a92ebf4e74db6104fc4334258b128d5
0
A.5.2.2. Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 009055c99bf9591cb0eab2a72d044c05ca2cc2ef9b609a38546f74b6d688
f70cf205f782fa11a0d61b2f5a8a2a1143368327f3077c68a1545e9aafbba6a90dc0
d40a
BlindedElement = 0201a8d0747e840cedd4586ca5382ef51031c9fb7074fcf6c9b
7acd6c74ee80dd33efa01f91cd3f50c9685fdea84c8a779cf8a3a6caedeb8050a782
241f8469d641d1a
EvaluationElement = 0200470a42df4d40ddaebb7e4a3e308c09396e4f0217fb62
ffd1aad6f35449c41e655a0b073a82003b192685dc5567096a2ad690128dfdd62693
c97cd54e536b044ad5
EvaluationProofC = 01c01a155fd0c0e690f44cd2e4771b9c4cbc95d84e517f103
79b5e59e643c4c28b480b2a582e8dc03f1fb1f9dd26b73a7fbc9443c5cf543d288d4
3d078fe9db1f3a1
EvaluationProofS = 01bb2e45130b23cf6af1ac7777ac1c6189d0b3740c6fb1130
69bed943fd19d4093c6c1ffd872964189a02f5948d7f06d2090321510a46beabe6b6
19d84d4c23065f5
Output = 93d48a50859a56aabe4d19f4517eff37494959536381b8c072f7d968335
dae63d62b98b448160be9559c680a4bb2aee54acd8f26fd2ce6d6e7f714124a5c56b
5
A.5.2.3. Test Vector 3, Batch Size 2
Davidson, et al. Expires 7 January 2022 [Page 50]
Internet-Draft OPRFs July 2021
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a
Blind = 01c6cf092d80c7cf2cb55388d899515238094c800bdd9c65f71780ba85f5
ae9b4703e17e559ca3ccd1944f9a70536c175f11a827452672b60d4e9f89eba28104
6e29,00cba1ba1a337759061965a423d9d3d6e1e1006dc8984ad28a4c93ecfc36fc2
171046b3c4284855cfa2434ed98db9e68a597db2c14728fade716a6a82d600444b26
e
BlindedElement = 020043edd4cc7f6131931455923f988620f03077d89cfc51c65
bb2f026312352dd9ccb8df17184cf8e5b3a08cfd12e12beaecbabc82b2a8c3ecf16b
e13ff4996b48e47,0300c958264a3308f411c69561ad13a61581c4d4ffecc3feff4c
0b5041b86a4a2b1b40b36a9d71ad5f0bde53514b06484fb0536dd601e42380580514
d9b7399249b406
EvaluationElement = 020011583e8c7d713ed23d2f6c2261923ef30a7534593b10
26511914b97f91a590cf50599901af6a86892abcd433b5073d869d7b330b9f4273d5
b0c614275cf0bf0c4e,02003ab9ffa4f5331b53a208999d1200b870683a53a065b3d
e57bad18a02f206968854c1d5bb94e3a7f946e3f3a6313ef2b6a9327ab160d7d2637
8dd3a880a1f002f6f
EvaluationProofC = 01dff218da0d67f76a979a4c3677a67d59a174e8e122f3d13
c0494611fe1c766d2ea08fee354ef3c7db3a6b3a3d7d75ea6a1f7e1deff35bccf27a
43ddf33ab1bf4aa
EvaluationProofS = 00434d173267092e93912d2d2714a357bb570f3105fae0191
e33e19a5eb9bb1656f361c533770fc90dc7ecaec88d0e6855c525118a1f857e7abbf
46d6b159dc4f271
Output = 64b90ccb524dc125290bda4f6102871a8580d9cb0dfe1c0e46ae87d70a1
690ddf7ed5d970ac3b51e959a8769fd8e5ee5a92ebf4e74db6104fc4334258b128d5
0,93d48a50859a56aabe4d19f4517eff37494959536381b8c072f7d968335dae63d6
2b98b448160be9559c680a4bb2aee54acd8f26fd2ce6d6e7f714124a5c56b5
Authors' Addresses
Alex Davidson
Brave Software
Email: alex.davidson92@gmail.com
Armando Faz-Hernandez
Cloudflare
101 Townsend St
San Francisco,
United States of America
Email: armfazh@cloudflare.com
Davidson, et al. Expires 7 January 2022 [Page 51]
Internet-Draft OPRFs July 2021
Nick Sullivan
Cloudflare
101 Townsend St
San Francisco,
United States of America
Email: nick@cloudflare.com
Christopher A. Wood
Cloudflare
101 Townsend St
San Francisco,
United States of America
Email: caw@heapingbits.net
Davidson, et al. Expires 7 January 2022 [Page 52]