Movatterモバイル変換


[0]ホーム

URL:


RFC 9497OPRFsDecember 2023
Davidson, et al.Informational[Page]
Stream:
Internet Research Task Force (IRTF)
RFC:
9497
Category:
Informational
Published:
ISSN:
2070-1721
Authors:
A. Davidson
Brave Software
A. Faz-Hernandez
Cloudflare, Inc.
N. Sullivan
Cloudflare, Inc.
C. A. Wood
Cloudflare, Inc.

RFC 9497

Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order Groups

Abstract

An Oblivious Pseudorandom Function (OPRF) is a two-party protocol betweena client and a server for computing the output of a Pseudorandom Function (PRF).The server provides the PRF private key, and the client provides the PRFinput. At the end of the protocol, the client learns the PRF output withoutlearning anything about the PRF private key, and the server learns neitherthe PRF input nor output. An OPRF can also satisfy a notion of 'verifiability',called a VOPRF. A VOPRF ensures clients can verify that the server used aspecific private key during the execution of the protocol. A VOPRF can alsobe partially oblivious, called a POPRF. A POPRF allows clients and serversto provide public input to the PRF computation. This document specifies an OPRF,VOPRF, and POPRF instantiated within standard prime-order groups, includingelliptic curves. This document is a product of the Crypto Forum Research Group(CFRG) in the IRTF.

Status of This Memo

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/rfc9497.

Copyright Notice

Copyright (c) 2023 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.

Table of Contents

1.Introduction

A Pseudorandom Function (PRF) F(k, x) is an efficiently computablefunction taking a private key k and a value x as input. This function ispseudorandom if the keyed function K(_) = F(k, _) is indistinguishablefrom a randomly sampled function acting on the same domain and range asK(). An Oblivious PRF (OPRF) is a two-party protocol between a serverand a client, wherein the server holds a PRF key k and the client holdssome input x. The protocol allows both parties to cooperate in computingF(k, x), such that the client learns F(k, x) without learning anythingabout k and the server does not learn anything about x or F(k, x).A Verifiable OPRF (VOPRF) is an OPRF, wherein the server also provesto the client that F(k, x) was produced by the key k correspondingto the server's public key, which the client knows.A Partially Oblivious PRF (POPRF)is a variant of a VOPRF, where the client and server interact in computingF(k, x, y), for some PRF F with server-provided key k, client-providedinput x, and public input y, and the client receives proofthat F(k, x, y) was computed using k corresponding to the public keythat the client knows. A POPRF with fixed input y is functionallyequivalent to a VOPRF.

OPRFs have a variety of applications, including password-protected secretsharing schemes[JKKX16], privacy-preserving password stores[SJKS17], andpassword-authenticated key exchange (PAKE)[OPAQUE].Verifiable OPRFs are necessary in some applications, such as Privacy Pass[PRIVACY-PASS]. Verifiable OPRFs have also been used forpassword-protected secret sharing schemes, such as that of[JKK14].

This document specifies OPRF, VOPRF, and POPRF protocols built uponprime-order groups. The document describes each protocol variant,along with application considerations, and their security properties.

This document represents the consensus of the Crypto Forum ResearchGroup (CFRG). It is not an IETF product and is not a standard.

1.1.Requirements Language

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.

1.2.Notation and Terminology

The following functions and notation are used throughout the document.

  • For any objectx, we writelen(x) to denote its length in bytes.
  • For two-byte arraysx andy, writex || y to denote theirconcatenation.
  • I2OSP(x, xLen) converts a nonnegative integerx into a byte arrayof specified lengthxLen, as described in[RFC8017]. Note thatthis function returns a byte array in big-endian byte order.
  • The notationT U[N] refers to an array called U, containing N items of typeT. The typeopaque means one single byte of uninterpreted data. Items ofthe array are zero-indexed and referred to asU[j], such that 0 <= j < N.

All algorithms and procedures described in this document are laid outin a Python-like pseudocode. Each function takes a set of inputs and parametersand produces a set of output values. Parameters become constant values once theprotocol variant and the ciphersuite are fixed.

ThePrivateInput data type refers to inputs that are known only to the clientin the protocol, whereas thePublicInput data type refers to inputs that areknown to both the client and server in the protocol. BothPrivateInput andPublicInput are opaque byte strings of arbitrary length no larger than 216 - 1 bytes.This length restriction exists becausePublicInput andPrivateInput valuesare length-prefixed with two bytes before use throughout the protocol.

String values, such as "DeriveKeyPair", "Seed-", and "Finalize", are ASCII string literals.

The following terms are used throughout this document.

PRF:
Pseudorandom Function
OPRF:
Oblivious Pseudorandom Function
VOPRF:
Verifiable Oblivious Pseudorandom Function
POPRF:
Partially Oblivious Pseudorandom Function
Client:
Protocol initiator. Learns PRF evaluation asthe output of the protocol.
Server:
Computes the PRF using a private key. Learnsnothing about the client's input or output.

2.Preliminaries

The protocols in this document have two primary dependencies:

Group:
A prime-order group implementing the API described below inSection 2.1.SeeSection 4 for specific instances of groups.
Hash:
A cryptographic hash function whose output length isNh bytes.

Section 4 specifies ciphersuites as combinations ofGroup andHash.

2.1.Prime-Order Group

In this document, we assume the construction of an additive, prime-ordergroup, denotedGroup, for performing all mathematical operations. In prime-order groups,any element (other than the identity) can generate the other elements of thegroup. Usually, one elementis fixed and defined as the group generator. Such groups areuniquely determined by the choice of the primep that defines theorder of the group. (However, different representationsof the group for a singlep may exist.Section 4 lists specific groups that indicate both the order and representation.)

The fundamental group operation is addition+ with identity elementI. For any elementsA andB of the group,A + B = B + A isalso a member of the group. Also, for anyA in the group, there exists an element-A, such thatA + (-A) = (-A) + A = I. Scalar multiplication byr isequivalent to the repeated application of the group operation on anelementA with itselfr - 1 times; this is denoted asr * A = A + ... + A.For any elementA,p * A = I. The case when the scalar multiplication isperformed on the group generator is denoted asScalarMultGen(r).Given two elementsA andB, the discrete logarithm problem is to findan integer k, such that B = k * A. Thus, k is the discrete logarithm ofB with respect to the base A.The set of scalars corresponds toGF(p), a prime field of order p, and isrepresented as the set of integers defined by{0, 1, ..., p - 1}.This document uses typesElement andScalar to denote elements of the group and its set ofscalars, respectively.

We now detail a number of member functions that can be invoked on aprime-order group.

Order():
Outputs the order of the group (i.e.,p).
Identity():
Outputs the identity element of the group (i.e.,I).
Generator():
Outputs the generator element of the group.
HashToGroup(x):
Deterministically mapsan array of bytesx to an element ofGroup. The map must ensure that,for any adversary receivingR = HashToGroup(x), it iscomputationally difficult to reverse the mapping. This function is optionallyparameterized by a domain separation tag (DST); seeSection 4.Security properties of this function are describedin[RFC9380].
HashToScalar(x):
Deterministically mapsan array of bytesx to an element in GF(p). This function is optionallyparameterized by a DST; seeSection 4. Security properties of thisfunction are described in[RFC9380],Section 10.5.
RandomScalar():
Chooses at random a nonzero element in GF(p).
ScalarInverse(s):
Returns the inverse of input Scalars onGF(p).
SerializeElement(A):
Maps an ElementAto a canonical byte arraybuf of fixed-lengthNe.
DeserializeElement(buf):
Attempts to map a byte arraybuf toan ElementA and fails if the input is not the valid canonical byterepresentation of an element of the group. This function can raise aDeserializeError if deserialization fails orA is the identity element ofthe group; seeSection 4 for group-specific input validation steps.
SerializeScalar(s):
Maps Scalars to a canonicalbyte arraybuf of fixed-lengthNs.
DeserializeScalar(buf):
Attempts to map a byte arraybuf to Scalars.This function can raise a DeserializeError if deserialization fails; seeSection 4 for group-specific input validation steps.

Section 4 contains details for the implementation of this interfacefor different prime-order groups instantiated over elliptic curves. Inparticular, for some choices of elliptic curves, e.g., those detailed in[RFC7748], which require accounting for cofactors,Section 4describes required steps necessary to ensure the resulting group is ofprime order.

2.2.Discrete Logarithm Equivalence Proofs

A proof of knowledge allows a prover to convince a verifier that somestatement is true. If the prover can generate a proof without interactionwith the verifier, the proof is noninteractive. If the verifier learnsnothing other than whether the statement claimed by the prover is true orfalse, the proof is zero-knowledge.

This section describes a noninteractive, zero-knowledge proof for discretelogarithm equivalence (DLEQ), which is used in the construction of VOPRF andPOPRF. A DLEQ proof demonstrates that two pairs ofgroup elements have the same discrete logarithm without revealing thediscrete logarithm.

The DLEQ proof resembles the Chaum-Pedersen[ChaumPedersen] proof, whichis shown to be zero-knowledge by Jarecki, et al. [JKK14] and isnoninteractive after applying the Fiat-Shamir transform[FS00].Furthermore, Davidson, et al. [DGSTV18] showed a proof system forbatching DLEQ proofs that has constant-size proofs with respect to thenumber of inputs.The specific DLEQ proof system presented below follows this latterconstruction with two modifications: (1) the transcript used to generatethe seed includes more context information and (2) the individual challengesfor each element in the proof is derived from a seed-prefixed hash-to-scalarinvocation, rather than being sampled from a seeded Pseudorandom Number Generator (PRNG).The description is split intotwo subsections: one for generating the proof, which is done by serversin the verifiable protocols, and another for verifying the proof, which isdone by clients in the protocol.

2.2.1.Proof Generation

Generating a proof is done with theGenerateProof function, as defined below.Given Element values A and B, two non-empty lists of Element values C and D of lengthm, and Scalar k, this function produces a proof thatk * A == Bandk * C[i] == D[i] for eachi in[0, ..., m - 1].The output is a value of typeProof, which is a tuple of two Scalarvalues. We use the notationproof[0] andproof[1] to denotethe first and second elements in this tuple, respectively.

GenerateProof accepts lists of inputs to amortize the cost of proofgeneration. Applications can take advantage of this functionality toproduce a single, constant-sized proof form DLEQ inputs, ratherthanm proofs form DLEQ inputs.

Input:  Scalar k  Element A  Element B  Element C[m]  Element D[m]Output:  Proof proofParameters:  Group Gdef GenerateProof(k, A, B, C, D):  (M, Z) = ComputeCompositesFast(k, B, C, D)  r = G.RandomScalar()  t2 = r * A  t3 = r * M  Bm = G.SerializeElement(B)  a0 = G.SerializeElement(M)  a1 = G.SerializeElement(Z)  a2 = G.SerializeElement(t2)  a3 = G.SerializeElement(t3)  challengeTranscript =    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 ||    "Challenge"  c = G.HashToScalar(challengeTranscript)  s = r - c * k  return [c, s]

The helper functionComputeCompositesFast is as defined below and is anoptimization of theComputeComposites function for servers since they haveknowledge of the private key.

Input:  Scalar k  Element B  Element C[m]  Element D[m]Output:  Element M  Element ZParameters:  Group G  PublicInput contextStringdef ComputeCompositesFast(k, B, C, D):  Bm = G.SerializeElement(B)  seedDST = "Seed-" || contextString  seedTranscript =    I2OSP(len(Bm), 2) || Bm ||    I2OSP(len(seedDST), 2) || seedDST  seed = Hash(seedTranscript)  M = G.Identity()  for i in range(m):    Ci = G.SerializeElement(C[i])    Di = G.SerializeElement(D[i])    compositeTranscript =      I2OSP(len(seed), 2) || seed || I2OSP(i, 2) ||      I2OSP(len(Ci), 2) || Ci ||      I2OSP(len(Di), 2) || Di ||      "Composite"    di = G.HashToScalar(compositeTranscript)    M = di * C[i] + M  Z = k * M  return (M, Z)

When used in the protocol described inSection 3, the parametercontextString isas defined inSection 3.2.

2.2.2.Proof Verification

Verifying a proof is done with theVerifyProof function, as defined below.This function takes Element values A and B, two non-empty lists of Element values C and Dof lengthm, and aProof value output fromGenerateProof. It outputs asingle boolean value indicating whether or not the proof is valid for thegiven DLEQ inputs. Note this function can verify proofs on lists of inputswhenever the proof was generated as a batched DLEQ proof with the same inputs.

Input:  Element A  Element B  Element C[m]  Element D[m]  Proof proofOutput:  boolean verifiedParameters:  Group Gdef VerifyProof(A, B, C, D, proof):  (M, Z) = ComputeComposites(B, C, D)  c = proof[0]  s = proof[1]  t2 = ((s * A) + (c * B))  t3 = ((s * M) + (c * Z))  Bm = G.SerializeElement(B)  a0 = G.SerializeElement(M)  a1 = G.SerializeElement(Z)  a2 = G.SerializeElement(t2)  a3 = G.SerializeElement(t3)  challengeTranscript =    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 ||    "Challenge"  expectedC = G.HashToScalar(challengeTranscript)  verified = (expectedC == c)  return verified

The definition ofComputeComposites is given below.

Input:  Element B  Element C[m]  Element D[m]Output:  Element M  Element ZParameters:  Group G  PublicInput contextStringdef ComputeComposites(B, C, D):  Bm = G.SerializeElement(B)  seedDST = "Seed-" || contextString  seedTranscript =    I2OSP(len(Bm), 2) || Bm ||    I2OSP(len(seedDST), 2) || seedDST  seed = Hash(seedTranscript)  M = G.Identity()  Z = G.Identity()  for i in range(m):    Ci = G.SerializeElement(C[i])    Di = G.SerializeElement(D[i])    compositeTranscript =      I2OSP(len(seed), 2) || seed || I2OSP(i, 2) ||      I2OSP(len(Ci), 2) || Ci ||      I2OSP(len(Di), 2) || Di ||      "Composite"    di = G.HashToScalar(compositeTranscript)    M = di * C[i] + M    Z = di * D[i] + Z  return (M, Z)

When used in the protocol described inSection 3, the parametercontextString isas defined inSection 3.2.

3.Protocol

In this section, we define and describe three protocol variants referred to as theOPRF, VOPRF, and POPRF modes. Each of these variants involves two messages between theclient and server, but they differ slightly in terms of the security properties; seeSection 7.1 for more information. A high-level description of the functionality of each mode follows.

In the OPRF mode, a client and server interact to computeoutput = F(skS, input),whereinput is the client's private input,skS is the server's private key,andoutput is the OPRF output. After the execution of the protocol, theclient learns theoutput and the server learns nothing.This interaction is shown below.

    Client(input)                                        Server(skS)  -------------------------------------------------------------------  blind, blindedElement = Blind(input)                             blindedElement                               ---------->                evaluatedElement = BlindEvaluate(skS, blindedElement)                             evaluatedElement                               <----------  output = Finalize(input, blind, evaluatedElement)
Figure 1:OPRF Protocol Overview

In the VOPRF mode, the client additionally receives proof that the server usedskS in computing the function. To achieve verifiability, as in[JKK14], theserver provides a zero-knowledge proof that the key provided as input by the server intheBlindEvaluate function is the same key as is used to produce the server's public key,pkS,which the client receives as input to the protocol. This proof does not reveal the server'sprivate key to the client. This interaction is shown below.

    Client(input, pkS)       <---- pkS ------        Server(skS, pkS)  -------------------------------------------------------------------  blind, blindedElement = Blind(input)                             blindedElement                               ---------->              evaluatedElement, proof = BlindEvaluate(skS, pkS,                                                      blindedElement)                         evaluatedElement, proof                               <----------  output = Finalize(input, blind, evaluatedElement,                    blindedElement, pkS, proof)
Figure 2:VOPRF Protocol Overview with Additional Proof

The POPRF mode extends the VOPRF mode such that the client andserver can additionally provide the public inputinfo, which is used in computingthe PRF. That is, the client and server interact to computeoutput = F(skS, input, info), as is shown below.

    Client(input, pkS, info) <---- pkS ------  Server(skS, pkS, info)  -------------------------------------------------------------------  blind, blindedElement, tweakedKey = Blind(input, info, pkS)                             blindedElement                               ---------->         evaluatedElement, proof = BlindEvaluate(skS, blindedElement,                                                 info)                         evaluatedElement, proof                               <----------  output = Finalize(input, blind, evaluatedElement,                    blindedElement, proof, info, tweakedKey)
Figure 3:POPRF Protocol Overview with Additional Public Input

Each protocol consists of an offline setup phase and an online phase,as described in Sections3.2 and3.3, respectively. Configuration detailsfor the offline phase are described inSection 3.1.

3.1.Configuration

Each of the three protocol variants are identified with a one-byte value (in hexadecimal):

Table 1:Identifiers for Protocol Variants
ModeValue
modeOPRF0x00
modeVOPRF0x01
modePOPRF0x02

Additionally, each protocol variant is instantiated with a ciphersuiteor suite. Each ciphersuite is identified with an ASCII string identifier,referred to as identifier; seeSection 4 for the set of initialciphersuite values.

The mode and ciphersuite identifier values are combined to create a"context string" used throughout the protocol with the following function:

def CreateContextString(mode, identifier):  return "OPRFV1-" || I2OSP(mode, 1) || "-" || identifier

3.2.Key Generation and Context Setup

In the offline setup phase, the server generates a fresh, random keypair (skS,pkS). There are two ways to generate this key pair.The first of which is using theGenerateKeyPair function described below.

Input: NoneOutput:  Scalar skS  Element pkSParameters:  Group Gdef GenerateKeyPair():  skS = G.RandomScalar()  pkS = G.ScalarMultGen(skS)  return skS, pkS

The second way to generate the key pair is via the deterministic keygeneration functionDeriveKeyPair, as described inSection 3.2.1.Applications and implementations can use either method in practice.

Also during the offline setup phase, both the client and server create acontext used for executing the online phase of the protocol after agreeing on amode and ciphersuite identifier. The context, such asOPRFServerContext,is an implementation-specific data structure that stores a context string andthe relevant key material for each party.

The OPRF variant server and client contexts are created as follows:

def SetupOPRFServer(identifier, skS):  contextString = CreateContextString(modeOPRF, identifier)  return OPRFServerContext(contextString, skS)def SetupOPRFClient(identifier):  contextString = CreateContextString(modeOPRF, identifier)  return OPRFClientContext(contextString)

The VOPRF variant server and client contexts are created as follows:

def SetupVOPRFServer(identifier, skS):  contextString = CreateContextString(modeVOPRF, identifier)  return VOPRFServerContext(contextString, skS)def SetupVOPRFClient(identifier, pkS):  contextString = CreateContextString(modeVOPRF, identifier)  return VOPRFClientContext(contextString, pkS)

The POPRF variant server and client contexts are created as follows:

def SetupPOPRFServer(identifier, skS):  contextString = CreateContextString(modePOPRF, identifier)  return POPRFServerContext(contextString, skS)def SetupPOPRFClient(identifier, pkS):  contextString = CreateContextString(modePOPRF, identifier)  return POPRFClientContext(contextString, pkS)

3.2.1.Deterministic Key Generation

This section describes a deterministic key generation function,DeriveKeyPair.It accepts a seed of32 bytes generated from a cryptographically securerandom number generator and an optional (possibly empty)info string.Note that, by design, knowledge ofseed andinfois necessary to compute this function, which means that the secrecy of theoutput private key (skS) depends on the secrecy ofseed (since theinfostring is public).

Input:  opaque seed[32]  PublicInput infoOutput:  Scalar skS  Element pkSParameters:  Group G  PublicInput contextStringErrors: DeriveKeyPairErrordef DeriveKeyPair(seed, info):  deriveInput = seed || I2OSP(len(info), 2) || info  counter = 0  skS = 0  while skS == 0:    if counter > 255:      raise DeriveKeyPairError    skS = G.HashToScalar(deriveInput || I2OSP(counter, 1),                          DST = "DeriveKeyPair" || contextString)    counter = counter + 1  pkS = G.ScalarMultGen(skS)  return skS, pkS

3.3.Online Protocol

In the online phase, the client and server engage in a two-message protocolto compute the protocol output. This section describes the protocol detailsfor each protocol variant. Throughout each description, the following parametersare assumed to exist:

G:
a prime-order group implementing the API described inSection 2.1
contextString:
aPublicInput domain separation tag constructed during context setup, as created inSection 3.1
skS and pkS:
a Scalar and Element representing the private and public keys configured for the client and server inSection 3.2

Applications serialize protocol messages between the client and server fortransmission. Element values and Scalar values are serialized to byte arrays, and valuesof typeProof are serialized as the concatenation of two serialized Scalar values.Deserializing these values can fail; in which case, the applicationMUST abortthe protocol, raising aDeserializeError failure.

ApplicationsMUST check that input Element values received over the wireare not the group identity element. This check is handled after deserializingElement values; seeSection 4 for more information and requirementson input validation for each ciphersuite.

3.3.1.OPRF Protocol

The OPRF protocol begins with the client blinding its input, as describedby theBlind function below. Note that this function can fail with anInvalidInputError error for certain inputs that map to the group identityelement. Dealing with this failure is an application-specific decision;seeSection 5.3.

Input:  PrivateInput inputOutput:  Scalar blind  Element blindedElementParameters:  Group GErrors: InvalidInputErrordef Blind(input):  blind = G.RandomScalar()  inputElement = G.HashToGroup(input)  if inputElement == G.Identity():    raise InvalidInputError  blindedElement = blind * inputElement  return blind, blindedElement

Clients storeblind locally and sendblindedElement to the server for evaluation.Upon receipt, servers processblindedElement using theBlindEvaluate function describedbelow.

Input:  Scalar skS  Element blindedElementOutput:  Element evaluatedElementdef BlindEvaluate(skS, blindedElement):  evaluatedElement = skS * blindedElement  return evaluatedElement

Servers send the outputevaluatedElement to clients for processing.Recall that servers may process multiple client inputs by applying theBlindEvaluate function to eachblindedElement received and returning anarray with the correspondingevaluatedElement values.

Upon receipt ofevaluatedElement, clients process it to complete theOPRF evaluation with theFinalize function described below.

Input:  PrivateInput input  Scalar blind  Element evaluatedElementOutput:  opaque output[Nh]Parameters:  Group Gdef Finalize(input, blind, evaluatedElement):  N = G.ScalarInverse(blind) * evaluatedElement  unblindedElement = G.SerializeElement(N)  hashInput = I2OSP(len(input), 2) || input ||              I2OSP(len(unblindedElement), 2) || unblindedElement ||              "Finalize"  return Hash(hashInput)

An entity that knows both the private key and the input can compute the PRFresult using the followingEvaluate function.

Input:  Scalar skS  PrivateInput inputOutput:  opaque output[Nh]Parameters:  Group GErrors: InvalidInputErrordef Evaluate(skS, input):  inputElement = G.HashToGroup(input)  if inputElement == G.Identity():    raise InvalidInputError  evaluatedElement = skS * inputElement  issuedElement = G.SerializeElement(evaluatedElement)  hashInput = I2OSP(len(input), 2) || input ||              I2OSP(len(issuedElement), 2) || issuedElement ||              "Finalize"  return Hash(hashInput)

3.3.2.VOPRF Protocol

The VOPRF protocol begins with the client blinding its input, using the sameBlind function as inSection 3.3.1. Clients store the outputblind locallyand sendblindedElement to the server for evaluation. Upon receipt,servers processblindedElement to compute an evaluated element and a DLEQproof using the followingBlindEvaluate function.

Input:  Scalar skS  Element pkS  Element blindedElementOutput:  Element evaluatedElement  Proof proofParameters:  Group Gdef BlindEvaluate(skS, pkS, blindedElement):  evaluatedElement = skS * blindedElement  blindedElements = [blindedElement]     // list of length 1  evaluatedElements = [evaluatedElement] // list of length 1  proof = GenerateProof(skS, G.Generator(), pkS,                        blindedElements, evaluatedElements)  return evaluatedElement, proof

In the description above, inputs toGenerateProof are one-itemlists. Using larger lists allows servers to batch the evaluation of multipleelements while producing a single batched DLEQ proof for them.

The server sends bothevaluatedElement andproof back to the client.Upon receipt, the client processes both values to complete the VOPRF computationusing theFinalize function below.

Input:  PrivateInput input  Scalar blind  Element evaluatedElement  Element blindedElement  Element pkS  Proof proofOutput:  opaque output[Nh]Parameters:  Group GErrors: VerifyErrordef Finalize(input, blind, evaluatedElement,             blindedElement, pkS, proof):  blindedElements = [blindedElement]     // list of length 1  evaluatedElements = [evaluatedElement] // list of length 1  if VerifyProof(G.Generator(), pkS, blindedElements,                 evaluatedElements, proof) == false:    raise VerifyError  N = G.ScalarInverse(blind) * evaluatedElement  unblindedElement = G.SerializeElement(N)  hashInput = I2OSP(len(input), 2) || input ||              I2OSP(len(unblindedElement), 2) || unblindedElement ||              "Finalize"  return Hash(hashInput)

As inBlindEvaluate, inputs toVerifyProof are one-item lists. Clients canverify multiple inputs at once whenever the server produced a batched DLEQ prooffor them.

Finally, an entity that knows both the private key and the input can compute the PRFresult using theEvaluate function described inSection 3.3.1.

3.3.3.POPRF Protocol

The POPRF protocol begins with the client blinding its input, using thefollowing modifiedBlind function. In this step, the client also binds apublic info value, which produces an additionaltweakedKey to be used laterin the protocol. Note that this function can fail with anInvalidInputError error for certain private inputs that map to the groupidentity element, as well as certain public inputs that, if not detected atthis point, will cause server evaluation to fail. Dealing with either failureis an application-specific decision; seeSection 5.3.

Input:  PrivateInput input  PublicInput info  Element pkSOutput:  Scalar blind  Element blindedElement  Element tweakedKeyParameters:  Group GErrors: InvalidInputErrordef Blind(input, info, pkS):  framedInfo = "Info" || I2OSP(len(info), 2) || info  m = G.HashToScalar(framedInfo)  T = G.ScalarMultGen(m)  tweakedKey = T + pkS  if tweakedKey == G.Identity():    raise InvalidInputError  blind = G.RandomScalar()  inputElement = G.HashToGroup(input)  if inputElement == G.Identity():    raise InvalidInputError  blindedElement = blind * inputElement  return blind, blindedElement, tweakedKey

Clients store the outputsblind andtweakedKey locally and sendblindedElement tothe server for evaluation. Upon receipt, servers processblindedElement tocompute an evaluated element and a DLEQ proof using the followingBlindEvaluate function.

Input:  Scalar skS  Element blindedElement  PublicInput infoOutput:  Element evaluatedElement  Proof proofParameters:  Group GErrors: InverseErrordef BlindEvaluate(skS, blindedElement, info):  framedInfo = "Info" || I2OSP(len(info), 2) || info  m = G.HashToScalar(framedInfo)  t = skS + m  if t == 0:    raise InverseError  evaluatedElement = G.ScalarInverse(t) * blindedElement  tweakedKey = G.ScalarMultGen(t)  evaluatedElements = [evaluatedElement] // list of length 1  blindedElements = [blindedElement]     // list of length 1  proof = GenerateProof(t, G.Generator(), tweakedKey,                        evaluatedElements, blindedElements)  return evaluatedElement, proof

In the description above, inputs toGenerateProof are one-itemlists. Using larger lists allows servers to batch the evaluation of multipleelements while producing a single batched DLEQ proof for them.

BlindEvaluate triggersInverseError when the function is about tocalculate the inverse of a zero scalar, which does not exist and thereforeyields a failure in the protocol.This only occurs forinfo values that map to the private key of the server. Thus,clients that cause this error should be assumed to know the server private key. Hence,this error can be a signal for the server to replace its private key.

The server sends bothevaluatedElement andproof back to the client.Upon receipt, the client processes both values to complete the POPRF computationusing theFinalize function below.

Input:  PrivateInput input  Scalar blind  Element evaluatedElement  Element blindedElement  Proof proof  PublicInput info  Element tweakedKeyOutput:  opaque output[Nh]Parameters:  Group GErrors: VerifyErrordef Finalize(input, blind, evaluatedElement, blindedElement,             proof, info, tweakedKey):  evaluatedElements = [evaluatedElement] // list of length 1  blindedElements = [blindedElement]     // list of length 1  if VerifyProof(G.Generator(), tweakedKey, evaluatedElements,                 blindedElements, proof) == false:    raise VerifyError  N = G.ScalarInverse(blind) * evaluatedElement  unblindedElement = G.SerializeElement(N)  hashInput = I2OSP(len(input), 2) || input ||              I2OSP(len(info), 2) || info ||              I2OSP(len(unblindedElement), 2) || unblindedElement ||              "Finalize"  return Hash(hashInput)

As inBlindEvaluate, inputs toVerifyProof are one-item lists.Clients can verify multiple inputs at once whenever the server produced abatched DLEQ proof for them.

Finally, an entity that knows both the private key and the input can computethe PRF result using theEvaluate function described below.

Input:  Scalar skS  PrivateInput input  PublicInput infoOutput:  opaque output[Nh]Parameters:  Group GErrors: InvalidInputError, InverseErrordef Evaluate(skS, input, info):  inputElement = G.HashToGroup(input)  if inputElement == G.Identity():    raise InvalidInputError  framedInfo = "Info" || I2OSP(len(info), 2) || info  m = G.HashToScalar(framedInfo)  t = skS + m  if t == 0:    raise InverseError  evaluatedElement = G.ScalarInverse(t) * inputElement  issuedElement = G.SerializeElement(evaluatedElement)  hashInput = I2OSP(len(input), 2) || input ||              I2OSP(len(info), 2) || info ||              I2OSP(len(issuedElement), 2) || issuedElement ||              "Finalize"  return Hash(hashInput)

4.Ciphersuites

A ciphersuite (also referred to as 'suite' in this document) for the protocolwraps the functionality required for the protocol to take place. Theciphersuite should be available to both the client and server, and agreementon the specific instantiation is assumed throughout.

A ciphersuite contains instantiations of the following functionalities:

Group:
A prime-order group exposing the API detailed inSection 2.1, with thegenerator element defined in the corresponding reference for each group. Eachgroup also specifiesHashToGroup,HashToScalar, and serializationfunctionalities. ForHashToGroup, the domain separation tag (DST) is constructed in accordancewith the recommendations in[RFC9380],Section 3.1.ForHashToScalar, each group specifies an integer order that is used inreducing integer values to a member of the corresponding scalar field.
Hash:
A cryptographic hash function whose output length is Nh bytes long.

This section includes an initial set of ciphersuites with supported groupsand hash functions. It also includes implementation details for each ciphersuite,focusing on input validation. Future documents can specify additional ciphersuites as needed, provided they meet the requirements inSection 4.6.

For each ciphersuite,contextString is that which is computed in theSetup functions.Applications should take caution in using ciphersuites targeting P-256 and ristretto255.SeeSection 7.2 for related discussion.

4.1.OPRF(ristretto255, SHA-512)

This ciphersuite uses ristretto255[RFC9496] for the Group and SHA-512 for the hashfunction. The value of the ciphersuite identifier is "ristretto255-SHA512".

Group:

ristretto255[RFC9496]

Order():
Return 2252 + 27742317777372353535851937790883648493 (see[RFC9496]).
Identity():
As defined in[RFC9496].
Generator():
As defined in[RFC9496].
HashToGroup():
Use hash_to_ristretto255[RFC9380] with DST ="HashToGroup-" || contextString andexpand_message =expand_message_xmdusing SHA-512.
HashToScalar():
Computeuniform_bytes usingexpand_message =expand_message_xmd,DST = "HashToScalar-" || contextString, and an output length of 64 bytes, interpretuniform_bytes as a 512-bit integer in little-endian order, and reduce theinteger moduloGroup.Order().
ScalarInverse(s):
Returns the multiplicative inverse of input Scalars modGroup.Order().
RandomScalar():
Implemented by returning a uniformly random Scalar in the range[0,G.Order() - 1]. Refer toSection 4.7 for implementation guidance.
SerializeElement(A):
Implemented using theEncode function fromSection 4.3.2 of [RFC9496]; Ne = 32.
DeserializeElement(buf):
Implemented using theDecode function fromSection 4.3.1 of [RFC9496].Additionally, this function validates that the resulting element is not the groupidentity element. If these checks fail, deserialization returns an InputValidationError error.
SerializeScalar(s):
Implemented by outputting the little-endian, 32-byte encoding ofthe Scalar value with the top three bits set to zero; Ns = 32.
DeserializeScalar(buf):
Implemented by attempting to deserialize a Scalar from alittle-endian, 32-byte string. This function can fail if the input does notrepresent a Scalar in the range [0,G.Order() - 1]. Note that this means thetop three bits of the inputMUST be zero.
Hash:
SHA-512; Nh = 64.

4.2.OPRF(decaf448, SHAKE-256)

This ciphersuite uses decaf448[RFC9496] for the Group and SHAKE-256 for the hashfunction. The value of the ciphersuite identifier is "decaf448-SHAKE256".

Group:

decaf448[RFC9496]

Order():
Return 2446 - 13818066809895115352007386748515426880336692474882178609894547503885.
Identity():
As defined in[RFC9496].
Generator():
As defined in[RFC9496].
RandomScalar():
Implemented by returning a uniformly random Scalar in the range[0,G.Order() - 1]. Refer toSection 4.7 for implementation guidance.
HashToGroup():
Use hash_to_decaf448[RFC9380] with DST ="HashToGroup-" || contextString andexpand_message =expand_message_xofusing SHAKE-256.
HashToScalar():
Computeuniform_bytes usingexpand_message =expand_message_xof,DST = "HashToScalar-" || contextString, and output length 64, interpretuniform_bytes as a 512-bit integer in little-endian order, and reduce theinteger moduloGroup.Order().
ScalarInverse(s):
Returns the multiplicative inverse of input Scalars modGroup.Order().
SerializeElement(A):
Implemented using theEncode function fromSection 5.3.2 of [RFC9496]; Ne = 56.
DeserializeElement(buf):
Implemented using theDecode function fromSection 5.3.1 of [RFC9496].Additionally, this function validates that the resulting element is not the groupidentity element. If these checks fail, deserialization returns an InputValidationError error.
SerializeScalar(s):
Implemented by outputting the little-endian, 56-byte encoding ofthe Scalar value; Ns = 56.
DeserializeScalar(buf):
Implemented by attempting to deserialize a Scalar from alittle-endian, 56-byte string. This function can fail if the input does notrepresent a Scalar in the range [0,G.Order() - 1].
Hash:
SHAKE-256; Nh = 64.

4.3.OPRF(P-256, SHA-256)

This ciphersuite uses P-256[NISTCurves] for the Group and SHA-256 for the hashfunction. The value of the ciphersuite identifier is "P256-SHA256".

Group:

P-256 (secp256r1)[NISTCurves]

Order():
Return 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551.
Identity():
As defined in[NISTCurves].
Generator():
As defined in[NISTCurves].
RandomScalar():
Implemented by returning a uniformly random Scalar in the range[0,G.Order() - 1]. Refer toSection 4.7 for implementation guidance.
HashToGroup():
Use hash_to_curve with suite P256_XMD:SHA-256_SSWU_RO_[RFC9380] and DST ="HashToGroup-" || contextString.
HashToScalar():
Use hash_to_field from[RFC9380]using L = 48,expand_message_xmd with SHA-256,DST = "HashToScalar-" || contextString, and a prime modulus equal toGroup.Order().
ScalarInverse(s):
Returns the multiplicative inverse of input Scalars modGroup.Order().
SerializeElement(A):
Implemented using the compressed Elliptic-Curve-Point-to-Octet-String method according to[SEC1]; Ne = 33.
DeserializeElement(buf):
Implemented by attempting to deserialize a 33-byte input string toa public key using the compressed Octet-String-to-Elliptic-Curve-Point method according to[SEC1]and then performing partial public-key validation, as defined in Section 5.6.2.3.4 of[KEYAGREEMENT]. This includes checking that thecoordinates of the resulting point are in the correct range, that the point is onthe curve, and that the point is not the group identity element.If these checks fail, deserialization returns an InputValidationError error.
SerializeScalar(s):
Implemented using the Field-Element-to-Octet-String conversionaccording to[SEC1]; Ns = 32.
DeserializeScalar(buf):
Implemented by attempting to deserialize a Scalar from a 32-bytestring using Octet-String-to-Field-Element from[SEC1]. This function can fail if theinput does not represent a Scalar in the range [0,G.Order() - 1].
Hash:
SHA-256; Nh = 32.

4.4.OPRF(P-384, SHA-384)

This ciphersuite uses P-384[NISTCurves] for the Group and SHA-384 for the hashfunction. The value of the ciphersuite identifier is "P384-SHA384".

Group:

P-384 (secp384r1)[NISTCurves]

Order():
Return 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52973.
Identity():
As defined in[NISTCurves].
Generator():
As defined in[NISTCurves].
RandomScalar():
Implemented by returning a uniformly random Scalar in the range[0,G.Order() - 1]. Refer toSection 4.7 for implementation guidance.
HashToGroup():
Use hash_to_curve with suite P384_XMD:SHA-384_SSWU_RO_[RFC9380] and DST ="HashToGroup-" || contextString.
HashToScalar():
Use hash_to_field from[RFC9380]using L = 72,expand_message_xmd with SHA-384,DST = "HashToScalar-" || contextString, and aprime modulus equal toGroup.Order().
ScalarInverse(s):
Returns the multiplicative inverse of input Scalars modGroup.Order().
SerializeElement(A):
Implemented using the compressed Elliptic-Curve-Point-to-Octet-Stringmethod according to[SEC1]; Ne = 49.
DeserializeElement(buf):
Implemented by attempting to deserialize a 49-byte array toa public key using the compressed Octet-String-to-Elliptic-Curve-Point method according to[SEC1]and then performing partial public-key validation, as defined in Section 5.6.2.3.4 of[KEYAGREEMENT]. This includes checking that thecoordinates of the resulting point are in the correct range, that the point is onthe curve, and that the point is not the point at infinity. Additionally, this functionvalidates that the resulting element is not the group identity element.If these checks fail, deserialization returns an InputValidationError error.
SerializeScalar(s):
Implemented using the Field-Element-to-Octet-String conversionaccording to[SEC1]; Ns = 48.
DeserializeScalar(buf):
Implemented by attempting to deserialize a Scalar from a 48-bytestring using Octet-String-to-Field-Element from[SEC1]. This function can fail if theinput does not represent a Scalar in the range [0,G.Order() - 1].
Hash:
SHA-384; Nh = 48.

4.5.OPRF(P-521, SHA-512)

This ciphersuite uses P-521[NISTCurves] for the Group and SHA-512 for the hashfunction. The value of the ciphersuite identifier is "P521-SHA512".

Group:

P-521 (secp521r1)[NISTCurves]

Order():
Return 0x01fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409.
Identity():
As defined in[NISTCurves].
Generator():
As defined in[NISTCurves].
RandomScalar():
Implemented by returning a uniformly random Scalar in the range[0,G.Order() - 1]. Refer toSection 4.7 for implementation guidance.
HashToGroup():
Use hash_to_curve with suite P521_XMD:SHA-512_SSWU_RO_[RFC9380] and DST ="HashToGroup-" || contextString.
HashToScalar():
Use hash_to_field from[RFC9380]using L = 98,expand_message_xmd with SHA-512,DST = "HashToScalar-" || contextString, and aprime modulus equal toGroup.Order().
ScalarInverse(s):
Returns the multiplicative inverse of input Scalars modGroup.Order().
SerializeElement(A):
Implemented using the compressed Elliptic-Curve-Point-to-Octet-Stringmethod according to[SEC1]; Ne = 67.
DeserializeElement(buf):
Implemented by attempting to deserialize a 67-byte input string toa public key using the compressed Octet-String-to-Elliptic-Curve-Point method according to[SEC1]and then performing partial public-key validation, as defined in Section 5.6.2.3.4 of[KEYAGREEMENT]. This includes checking that thecoordinates of the resulting point are in the correct range, that the point is onthe curve, and that the point is not the point at infinity. Additionally, this functionvalidates that the resulting element is not the group identity element.If these checks fail, deserialization returns an InputValidationError error.
SerializeScalar(s):
Implemented using the Field-Element-to-Octet-String conversionaccording to[SEC1]; Ns = 66.
DeserializeScalar(buf):
Implemented by attempting to deserialize a Scalar from a 66-bytestring using Octet-String-to-Field-Element from[SEC1]. This function can fail if theinput does not represent a Scalar in the range [0,G.Order() - 1].
Hash:
SHA-512; Nh = 64.

4.6.Future Ciphersuites

A critical requirement of implementing the prime-order group usingelliptic curves is a method to instantiate the functionHashToGroup, which maps inputs to group elements. In the ellipticcurve setting, this deterministically maps inputs (as byte arrays) touniformly chosen points on the curve.

In the security proof of the construction, Hash is modeled as a randomoracle. This implies that any instantiation ofHashToGroup must bepre-image and collision resistant. InSection 4, we giveinstantiations of this functionality based on the functions described in[RFC9380]. Consequently, any OPRF implementationmust adhere to the implementation and security considerations discussedin[RFC9380] when instantiating the function.

TheDeserializeElement andDeserializeScalar functions instantiated for aparticular prime-order group corresponding to a ciphersuiteMUST adhere tothe description inSection 2.1. Future ciphersuitesMUST describe how inputvalidation is done forDeserializeElement andDeserializeScalar.

Additionally, future ciphersuites must take care when choosing thesecurity level of the group. SeeSection 7.2.3 for additional details.

4.7.Random Scalar Generation

Two popular algorithms for generating a random integer uniformly distributed inthe range [0, G.Order() - 1] are described in the following subsections.

4.7.1.Rejection Sampling

Generate a random byte array withNs bytes and attempt to map to a Scalarby callingDeserializeScalar in constant time. If it succeeds, return theresult. If it fails, try again with another random byte array until theprocedure succeeds. Failure to implementDeserializeScalar in constant timecan leak information about the underlying corresponding Scalar.

As an optimization, if the group order is very close to a power of2, it is acceptable to omit the rejection test completely. Inparticular, if the group order is p and there is an integer bsuch that |p - 2b| is less than 2(b/2), thenRandomScalar can simply return a uniformly random integer of atmost b bits.

4.7.2.Random Number Generation Using Extra Random Bits

Generate a random byte array withL = ceil(((3 * ceil(log2(G.Order()))) / 2) / 8)bytes, and interpret it as an integer; reduce the integer moduloG.Order(), and return theresult. See[RFC9380],Section 5 for the underlying derivation ofL.

5.Application Considerations

This section describes considerations for applications, including external interfacerecommendations, explicit error treatment, and public input representation for thePOPRF protocol variant.

5.1.Input Limits

Application inputs, expressed asPrivateInput orPublicInput values,MUST be smallerthan 216 - 1 bytes in length. Applications that require longer inputs can use a cryptographichash function to map these longer inputs to a fixed-length input that fits within thePublicInput orPrivateInput length bounds. Note that some cryptographic hash functionshave input length restrictions themselves, but these limits are often large enough tonot be a concern in practice. For example, SHA-256 has an input limit of 261 bytes.

5.2.External Interface Recommendations

InSection 3.3, the interface of the protocol functions allows that some inputs(and outputs) to be group Element and Scalar values. However, implementations caninstead operate over Element and Scalar values internally and only exposeinterfaces that operate with an application-specific format of messages.

5.3.Error Considerations

Some OPRF variants specified in this document have fallible operations. For example,FinalizeandBlindEvaluate can fail if any element received from the peer fails input validation.The explicit errors generated throughout this specification, along with theconditions that lead to each error, are as follows:

VerifyError:
Verifiable OPRF proof verification failed (Sections3.3.2 and3.3.3).
DeserializeError:
Group Element or Scalar deserialization failure (Sections2.1 and3.3).
InputValidationError:
Validation of byte array inputs failed (Section 4).

There are other explicit errors generated in this specification; however, they occur withnegligible probability in practice. We note them here for completeness.

InvalidInputError:
OPRF Blind input produces an invalid output element (Sections3.3.1 and3.3.3).
InverseError:
A tweaked private key is invalid, i.e., has no multiplicative inverse (Sections2.1 and3.3).

In general, 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.

5.4.POPRF Public Input

Functionally, the VOPRF and POPRF variants differ in that the POPRF variantadmits public input, whereas the VOPRF variant does not. Public input allowsclients and servers to cryptographically bind additional data to the POPRF output.A POPRF with fixed public input is functionally equivalent to a VOPRF. However, thereare differences in the underlying security assumptions made about each variant;seeSection 7.2 for more details.

This public input is known to both parties at the start of the protocol. It isRECOMMENDEDthat this public input be constructed with some type of higher-level domain separationto avoid cross protocol attacks or related issues. For example, protocols usingthis construction might ensure that the public input uses a unique, prefix-free encoding.See[RFC9380],Section 10.4 for further discussion onconstructing domain separation values.

Implementations of the POPRF may choose to not let applications controlinfo incases where this value is fixed or otherwise not useful to the application. In thiscase, the resulting protocol is functionally equivalent to the VOPRF, which does notadmit public input.

6.IANA Considerations

This document has no IANA actions.

7.Security Considerations

This section discusses the security of the protocols defined in this specification, alongwith some suggestions and trade-offs that arise from the implementationof the protocol variants in this document. Note that the syntax of the POPRFvariant is different from that of the OPRF and VOPRF variants since itadmits an additional public input, but the same security considerations apply.

7.1.Security Properties

The security properties of an OPRF protocol with functionality y = F(k, x)include those of a standard PRF. Specifically:

Pseudorandomness:
For a random sampling of k, F is pseudorandom if the outputy = F(k, x) on any input x is indistinguishable from uniformly sampling anyelement in F's range.

In other words, consider an adversary that picks inputs x from thedomain of F and evaluates F on (k, x) (without knowledge of randomlysampled k). Then, the output distribution F(k, x) is indistinguishablefrom the output distribution of a randomly chosen function with the samedomain and range.

A consequence of showing that a function is pseudorandom is that it isnecessarily nonmalleable (i.e., we cannot compute a new evaluation of Ffrom an existing evaluation). A genuinely random function will benonmalleable with high probability, so a pseudorandom function mustbe nonmalleable to maintain indistinguishability.

Unconditional input secrecy:
The server does not learn anything aboutthe client input x, even with unbounded computation.

In other words, an attacker with infinite computing power cannot recover anyinformation about the client's private input x from an invocation of theprotocol.

Essentially, input secrecy is the property that, even if the server learnsthe client's private input x at some point in the future, the server cannotlink any particular PRF evaluation to x. This property is also known as unlinkability[DGSTV18].

Beyond client input secrecy, in the OPRF protocol, the server learns nothing aboutthe output y of the function, nor does the client learn anything about theserver's private key k.

For the VOPRF and POPRF protocol variants, there is an additionalsecurity property:

Verifiable:
The client must only complete execution of the protocol ifit can successfully assert that the output it computes iscorrect. This is taken with respect to the private key held by theserver.

Any VOPRF or POPRF that satisfies the 'verifiable' security property is knownas 'verifiable'. In practice, the notion of verifiability requires thatthe server commits to the key before the actual protocol execution takesplace. Then, the client verifies that the server has used the key in theprotocol using this commitment. In the following, we may also refer to thiscommitment as a public key.

Finally, the POPRF variant also has the following security property:

Partial obliviousness:
The client and server must be able to perform thePRF on the client's private and public input. Both the client and server knowthe public input, but similar to the OPRF and VOPRF protocols, the serverlearns nothing about the client's private input or the output of the function,and the client learns nothing about the server's private key.

This property becomes useful when dealing with key management operations, such asthe rotation of the server's keys. Note that partial obliviousness only appliesto the POPRF variant because neither the OPRF nor VOPRF variants accept publicinput to the protocol.

Since the POPRF variant has a different syntax than the OPRF and VOPRF variants,i.e., y = F(k, x, info), the pseudorandomness property is generalized:

Pseudorandomness:
For a random sampling of k, F is pseudorandom if the outputy = F(k, x, info) on any input pairs (x, info) is indistinguishable from uniformlysampling any element in F's range.

7.2.Security Assumptions

Below, we discuss the cryptographic security of each protocol variantfromSection 3, relative to the necessary cryptographic assumptionsthat need to be made.

7.2.1.OPRF and VOPRF Assumptions

The OPRF and VOPRF protocol variants in this document are based on[JKK14].In particular, the VOPRF construction is similar to the[JKK14] constructionwith the following distinguishing properties:

  1. This document does not use session identifiers to differentiate different instances of the protocol.
  2. This document supports batching so that multiple evaluations can happen at once whilst only constructingone DLEQ proof object. This is enabled using an established batching technique[DGSTV18].

The pseudorandomness and input secrecy (and verifiability) of the OPRF (andVOPRF) protocols in[JKK14] are based on the One-More Gap ComputationalDiffie-Hellman assumption that is computationally difficult to solve in the corresponding prime-order group.In[JKK14], these properties are proven for one instance (i.e., one key) ofthe VOPRF protocol and without batching. There is currently no securityanalysis available for the VOPRF protocol described in this document ina setting with multiple server keys or batching.

7.2.2.POPRF Assumptions

The POPRF construction in this document is based on the construction knownas 3HashSDHI, given by[TCRSTW21]. The construction is identical to3HashSDHI, except that this design can optionally perform multiple POPRFevaluations in one batch, whilst only constructing one DLEQ proof object.This is enabled using an established batching technique[DGSTV18].

Pseudorandomness, input secrecy, verifiability, and partial obliviousness of the POPRF variant isbased on the assumption that the One-More Gap Strong Diffie-Hellman Inversion (SDHI)assumption from[TCRSTW21] is computationally difficult to solve in the correspondingprime-order group. Tyagi et al. [TCRSTW21] show that both the One-More Gap Computational Diffie-Hellman assumptionand the One-More Gap SDHI assumption reduce to the q-DL (Discrete Log) assumptionin the algebraic group model for some q number ofBlindEvaluate queries.(The One-More Gap Computational Diffie-Hellman assumption was the hardness assumption used toevaluate the OPRF and VOPRF designs based on[JKK14], which is a predecessorto the POPRF variant inSection 3.3.3.)

7.2.3.Static Diffie-Hellman Attack and Security Limits

A side effect of the OPRF protocol variants in this document is that they allowinstantiation of an oracle for constructing static Diffie-Hellman (DH) samples; see[BG04] and[Cheon06].These attacks are meant to recover (bits of) the server private key.Best-known attacks reduce the security of the prime-order group instantiation by log_2(Q) / 2bits, where Q is the number ofBlindEvaluate calls made by the attacker.

As a result of this class of attacks, choosing prime-order groups with a 128-bit securitylevel instantiates an OPRF with a reduced security level of 128 - (log_2(Q) / 2) bits of security.Moreover, such attacks are only possible for those certain applications where theadversary can query the OPRF directly. Applications can mitigate against this problemin a variety of ways, e.g., by rate-limiting client queries toBlindEvaluate or byrotating private keys. 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 tolaunch a highly expensive attack to reduce security to anything muchbelow 100 bits of security. Applications that admit the aforementionedoracle functionality and that cannot tolerate discrete logarithm securityof lower than 128 bits areRECOMMENDED to choose groups that target ahigher security level, such as decaf448 (used by ciphersuite decaf448-SHAKE256),P-384 (used by ciphersuite P384-SHA384), or P-521 (used by ciphersuite P521-SHA512).

7.3.Domain Separation

ApplicationsSHOULD construct input to the protocol to provide domainseparation. Any system that has multiple OPRF applications shoulddistinguish client inputs to ensure the OPRF results are separate.Guidance for constructing info can be found in[RFC9380],Section 3.1.

7.4.Timing Leaks

To ensure no information is leaked during protocol execution, alloperations that use secret dataMUST run in constant time. This includesall prime-order group operations and proof-specific operations thatoperate on secret data, includingGenerateProof andBlindEvaluate.

8.References

8.1.Normative References

[KEYAGREEMENT]
Barker, E.,Chen, L.,Roginsky, A.,Vassilev, A., andR. Davis,"Recommendation for pair-wise key-establishment schemes using discrete logarithm cryptography",NIST SP 800-56A (Rev. 3),DOI 10.6028/nist.sp.800-56ar3,,<https://doi.org/10.6028/nist.sp.800-56ar3>.
[RFC2119]
Bradner, S.,"Key words for use in RFCs to Indicate Requirement Levels",BCP 14,RFC 2119,DOI 10.17487/RFC2119,,<https://www.rfc-editor.org/info/rfc2119>.
[RFC8017]
Moriarty, K., Ed.,Kaliski, B.,Jonsson, J., andA. Rusch,"PKCS #1: RSA Cryptography Specifications Version 2.2",RFC 8017,DOI 10.17487/RFC8017,,<https://www.rfc-editor.org/info/rfc8017>.
[RFC8174]
Leiba, B.,"Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words",BCP 14,RFC 8174,DOI 10.17487/RFC8174,,<https://www.rfc-editor.org/info/rfc8174>.
[RFC9380]
Faz-Hernandez, A.,Scott, S.,Sullivan, N.,Wahby, R. S., andC. A. Wood,"Hashing to Elliptic Curves",RFC 9380,DOI 10.17487/RFC9380,,<https://www.rfc-editor.org/info/rfc9380>.
[RFC9496]
de Valence, H.,Grigg, J.,Hamburg, M.,Lovecruft, I.,Tankersley, G., andF. Valsorda,"The ristretto255 and decaf448 Groups",RFC 9496,DOI 10.17487/RFC9496,,<https://www.rfc-editor.org/info/rfc9496>.

8.2.Informative References

[BG04]
Brown, D. andR. Gallant,"The Static Diffie-Hellman Problem",,<https://eprint.iacr.org/2004/306>.
[ChaumPedersen]
Chaum, D. andT. Pedersen,"Wallet Databases with Observers",Advances in Cryptology - CRYPTO' 92, pp. 89-105,DOI 10.1007/3-540-48071-4_7,,<https://doi.org/10.1007/3-540-48071-4_7>.
[Cheon06]
Cheon, J.,"Security Analysis of the Strong Diffie-Hellman Problem",Advances in Cryptology - EUROCRYPT 2006, pp. 1-11,DOI 10.1007/11761679_1,,<https://doi.org/10.1007/11761679_1>.
[DGSTV18]
Davidson, A.,Goldberg, I.,Sullivan, N.,Tankersley, G., andF. Valsorda,"Privacy Pass: Bypassing Internet Challenges Anonymously",Proceedings on Privacy Enhancing Technologies, vol. 2018, no. 3, pp. 164-180,DOI 10.1515/popets-2018-0026,,<https://doi.org/10.1515/popets-2018-0026>.
[FS00]
Fiat, A. andA. Shamir,"How To Prove Yourself: Practical Solutions to Identification and Signature Problems",Advances in Cryptology - CRYPTO' 86, pp. 186-194,DOI 10.1007/3-540-47721-7_12,,<https://doi.org/10.1007/3-540-47721-7_12>.
[JKK14]
Jarecki, S.,Kiayias, A., andH. Krawczyk,"Round-Optimal Password-Protected Secret Sharing and T-PAKE in the Password-Only Model",Lecture Notes in Computer Science, pp. 233-253,DOI 10.1007/978-3-662-45608-8_13,,<https://doi.org/10.1007/978-3-662-45608-8_13>.
[JKKX16]
Jarecki, S.,Kiayias, A.,Krawczyk, H., andJ. Xu,"Highly-Efficient and Composable Password-Protected Secret Sharing (Or: How to Protect Your Bitcoin Wallet Online)",2016 IEEE European Symposium on Security and Privacy (EuroS&P),DOI 10.1109/eurosp.2016.30,,<https://doi.org/10.1109/eurosp.2016.30>.
[NISTCurves]
National Institute of Standards and Technology (NIST),"Digital Signature Standard (DSS)",FIPS PUB 186-5,DOI 10.6028/NIST.FIPS.186-5,,<https://doi.org/10.6028/NIST.FIPS.186-5>.
[OPAQUE]
Bourdrez, D.,Krawczyk, H.,Lewi, K., andC. A. Wood,"The OPAQUE Asymmetric PAKE Protocol",Work in Progress,Internet-Draft, draft-irtf-cfrg-opaque-13,,<https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-opaque-13>.
[PRIVACY-PASS]
Celi, S.,Davidson, A.,Valdez, S., andC. A. Wood,"Privacy Pass Issuance Protocol",Work in Progress,Internet-Draft, draft-ietf-privacypass-protocol-16,,<https://datatracker.ietf.org/doc/html/draft-ietf-privacypass-protocol-16>.
[PrivacyPass]
"Privacy Pass",commit 085380a,,<https://github.com/privacypass/team>.
[RFC7748]
Langley, A.,Hamburg, M., andS. Turner,"Elliptic Curves for Security",RFC 7748,DOI 10.17487/RFC7748,,<https://www.rfc-editor.org/info/rfc7748>.
[SEC1]
Standards for Efficient Cryptography Group (SECG),"SEC 1: Elliptic Curve Cryptography",,<https://www.secg.org/sec1-v2.pdf>.
[SJKS17]
Shirvanian, M.,Jarecki, S.,Krawczyk, H., andN. Saxena,"SPHINX: A Password Store that Perfectly Hides Passwords from Itself",2017 IEEE 37th International Conference on Distributed Computing Systems (ICDCS),DOI 10.1109/ICDCS.2017.64,,<https://doi.org/10.1109/ICDCS.2017.64>.
[TCRSTW21]
Tyagi, N.,Celi, S.,Ristenpart, T.,Sullivan, N.,Tessaro, S., andC. A. Wood,"A Fast and Simple Partially Oblivious PRF, with Applications",Advances in Cryptology - EUROCRYPT 2022 pp. 674-705,DOI 10.1007/978-3-031-07085-3_23,,<https://doi.org/10.1007/978-3-031-07085-3_23>.

Appendix A.Test Vectors

This section includes test vectors for the protocol variants specifiedin this document. For each ciphersuite specified inSection 4,there is a set of test vectors for the protocol when running the OPRF,VOPRF, and POPRF modes. Each test vector lists the batch size forthe evaluation. Each test vector value is encoded as a hexadecimalbyte string. The fields of each test vector are described below.

"Input":
The private client input, an opaque byte string.
"Info":
The public info, an opaque byte string. Only present for POPRF test vectors.
"Blind":
The blind value output byBlind(), a serialized ScalarofNs bytes long.
"BlindedElement":
The blinded value output byBlind(), a serializedElement ofNe bytes long.
"EvaluatedElement":
The evaluated element output byBlindEvaluate(),a serialized Element ofNe bytes long.
"Proof":
The serializedProof output fromGenerateProof() composed oftwo serialized Scalar values, eachNs bytes long. Only present forVOPRF and POPRF test vectors.
"ProofRandomScalar":
The random Scalarr computed inGenerateProof(), aserialized Scalar ofNs bytes long. Only present for VOPRF and POPRFtest vectors.
"Output":
The protocol output, an opaque byte string ofNh bytes long.

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.

The server key material,pkSm andskSm, are listed under the mode foreach ciphersuite. BothpkSm andskSm are the serialized values ofpkS andskS, respectively, as used in the protocol. Each key pairis derived from a seed, denotedSeed, and info string, denotedKeyInfo, which arelisted as well, using theDeriveKeyPair function fromSection 3.2.

A.1.ristretto255-SHA512

A.1.1.OPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 5ebcea5ee37023ccb9fc2d2019f9d7737be85591ae8652ffa9ef0f4d37063b0e
A.1.1.1.Test Vector 1, Batch Size 1
Input = 00Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706BlindedElement = 609a0ae68c15a3cf6903766461307e5c8bb2f95e7e6550e1ffa2dc99e412803cEvaluationElement = 7ec6578ae5120958eb2db1745758ff379e77cb64fe77b0b2d8cc917ea0869c7eOutput = 527759c3d9366f277d8c6020418d96bb393ba2afb20ff90df23fb7708264e2f3ab9135e3bd69955851de4b1f9fe8a0973396719b7912ba9ee8aa7d0b5e24bcf6
A.1.1.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706BlindedElement = da27ef466870f5f15296299850aa088629945a17d1f5b7f5ff043f76b3c06418EvaluationElement = b4cbf5a4f1eeda5a63ce7b77c7d23f461db3fcab0dd28e4e17cecb5c90d02c25Output = f4a74c9c592497375e796aa837e907b1a045d34306a749db9f34221f7e750cb4f2a6413a6bf6fa5e19ba6348eb673934a722a7ede2e7621306d18951e7cf2c73

A.1.2.VOPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = e6f73f344b79b379f1a0dd37e07ff62e38d9f71345ce62ae3a9bc60b04ccd909pkSm = c803e2cc6b05fc15064549b5920659ca4a77b2cca6f04f6b357009335476ad4e
A.1.2.1.Test Vector 1, Batch Size 1
Input = 00Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706BlindedElement = 863f330cc1a1259ed5a5998a23acfd37fb4351a793a5b3c090b642ddc439b945EvaluationElement = aa8fa048764d5623868679402ff6108d2521884fa138cd7f9c7669a9a014267eProof = ddef93772692e535d1a53903db24367355cc2cc78de93b3be5a8ffcc6985dd066d4346421d17bf5117a2a1ff0fcb2a759f58a539dfbe857a40bce4cf49ec600dProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0eOutput = b58cfbe118e0cb94d79b5fd6a6dafb98764dff49c14e1770b566e42402da1a7da4d8527693914139caee5bd03903af43a491351d23b430948dd50cde10d32b3c
A.1.2.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706BlindedElement = cc0b2a350101881d8a4cba4c80241d74fb7dcbfde4a61fde2f91443c2bf9ef0cEvaluationElement = 60a59a57208d48aca71e9e850d22674b611f752bed48b36f7a91b372bd7ad468Proof = 401a0da6264f8cf45bb2f5264bc31e109155600babb3cd4e5af7d181a2c9dc0a67154fabf031fd936051dec80b0b6ae29c9503493dde7393b722eafdf5a50b02ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0eOutput = 8a9a2f3c7f085b65933594309041fc1898d42d0858e59f90814ae90571a6df60356f4610bf816f27afdd84f47719e480906d27ecd994985890e5f539e7ea74b6
A.1.2.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706,222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0eBlindedElement = 863f330cc1a1259ed5a5998a23acfd37fb4351a793a5b3c090b642ddc439b945,90a0145ea9da29254c3a56be4fe185465ebb3bf2a1801f7124bbbadac751e654EvaluationElement = aa8fa048764d5623868679402ff6108d2521884fa138cd7f9c7669a9a014267e,cc5ac221950a49ceaa73c8db41b82c20372a4c8d63e5dded2db920b7eee36a2aProof = cc203910175d786927eeb44ea847328047892ddf8590e723c37205cb74600b0a5ab5337c8eb4ceae0494c2cf89529dcf94572ed267473d567aeed6ab873dee08ProofRandomScalar = 419c4f4f5052c53c45f3da494d2b67b220d02118e0857cdbcf037f9ea84bbe0cOutput = b58cfbe118e0cb94d79b5fd6a6dafb98764dff49c14e1770b566e42402da1a7da4d8527693914139caee5bd03903af43a491351d23b430948dd50cde10d32b3c,8a9a2f3c7f085b65933594309041fc1898d42d0858e59f90814ae90571a6df60356f4610bf816f27afdd84f47719e480906d27ecd994985890e5f539e7ea74b6

A.1.3.POPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 145c79c108538421ac164ecbe131942136d5570b16d8bf41a24d4337da981e07pkSm = c647bef38497bc6ec077c22af65b696efa43bff3b4a1975a3e8e0a1c5a79d631
A.1.3.1.Test Vector 1, Batch Size 1
Input = 00Info = 7465737420696e666fBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706BlindedElement = c8713aa89241d6989ac142f22dba30596db635c772cbf25021fdd8f3d461f715EvaluationElement = 1a4b860d808ff19624731e67b5eff20ceb2df3c3c03b906f5693e2078450d874Proof = 41ad1a291aa02c80b0915fbfbb0c0afa15a57e2970067a602ddb9e8fd6b7100de32e1ecff943a36f0b10e3dae6bd266cdeb8adf825d86ef27dbc6c0e30c52206ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0eOutput = ca688351e88afb1d841fde4401c79efebb2eb75e7998fa9737bd5a82a152406d38bd29f680504e54fd4587eddcf2f37a2617ac2fbd2993f7bdf45442ace7d221
A.1.3.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706BlindedElement = f0f0b209dd4d5f1844dac679acc7761b91a2e704879656cb7c201e82a99ab07dEvaluationElement = 8c3c9d064c334c6991e99f286ea2301d1bde170b54003fb9c44c6d7bd6fc1540Proof = 4c39992d55ffba38232cdac88fe583af8a85441fefd7d1d4a8d0394cd1de77018bf135c174f20281b3341ab1f453fe72b0293a7398703384bed822bfdeec8908ProofRandomScalar = 222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0eOutput = 7c6557b276a137922a0bcfc2aa2b35dd78322bd500235eb6d6b6f91bc5b56a52de2d65612d503236b321f5d0bebcbc52b64b92e426f29c9b8b69f52de98ae507
A.1.3.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec4c1f6706,222a5e897cf59db8145db8d16e597e8facb80ae7d4e26d9881aa6f61d645fc0eBlindedElement = c8713aa89241d6989ac142f22dba30596db635c772cbf25021fdd8f3d461f715,423a01c072e06eb1cce96d23acce06e1ea64a609d7ec9e9023f3049f2d64e50cEvaluationElement = 1a4b860d808ff19624731e67b5eff20ceb2df3c3c03b906f5693e2078450d874,aa1f16e903841036e38075da8a46655c94fc92341887eb5819f46312adfc0504Proof = 43fdb53be399cbd3561186ae480320caa2b9f36cca0e5b160c4a677b8bbf4301b28f12c36aa8e11e5a7ef551da0781e863a6dc8c0b2bf5a149c9e00621f02006ProofRandomScalar = 419c4f4f5052c53c45f3da494d2b67b220d02118e0857cdbcf037f9ea84bbe0cOutput = ca688351e88afb1d841fde4401c79efebb2eb75e7998fa9737bd5a82a152406d38bd29f680504e54fd4587eddcf2f37a2617ac2fbd2993f7bdf45442ace7d221,7c6557b276a137922a0bcfc2aa2b35dd78322bd500235eb6d6b6f91bc5b56a52de2d65612d503236b321f5d0bebcbc52b64b92e426f29c9b8b69f52de98ae507

A.2.decaf448-SHAKE256

A.2.1.OPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = e8b1375371fd11ebeb224f832dcc16d371b4188951c438f751425699ed29ecc80c6c13e558ccd67634fd82eac94aa8d1f0d7fee990695d1e
A.2.1.1.Test Vector 1, Batch Size 1
Input = 00Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112BlindedElement = e0ae01c4095f08e03b19baf47ffdc19cb7d98e583160522a3c7d6a0b2111cd93a126a46b7b41b730cd7fc943d4e28e590ed33ae475885f6cEvaluationElement = 50ce4e60eed006e22e7027454b5a4b8319eb2bc8ced609eb19eb3ad42fb19e06ba12d382cbe7ae342a0cad6ead0ef8f91f00bb7f0cd9c0a2Output = 37d3f7922d9388a15b561de5829bbf654c4089ede89c0ce0f3f85bcdba09e382ce0ab3507e021f9e79706a1798ffeac68ebd5cf62e5eb9838c7068351d97ae37
A.2.1.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112BlindedElement = 86a88dc5c6331ecfcb1d9aacb50a68213803c462e377577cacc00af28e15f0ddbc2e3d716f2f39ef95f3ec1314a2c64d940a9f295d8f13bbEvaluationElement = 162e9fa6e9d527c3cd734a31bf122a34dbd5bcb7bb23651f1768a7a9274cc116c03b58afa6f0dede3994a60066c76370e7328e7062fd5819Output = a2a652290055cb0f6f8637a249ee45e32ef4667db0b4c80c0a70d2a64164d01525cfdad5d870a694ec77972b9b6ec5d2596a5223e5336913f945101f0137f55e

A.2.2.VOPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = e3c01519a076a326a0eb566343e9b21c115fa18e6e85577ddbe890b33104fcc2835ddfb14a928dc3f5d79b936e17c76b99e0bf6a1680930epkSm = 945fc518c47695cf65217ace04b86ac5e4cbe26ca649d52854bb16c494ce09069d6add96b20d4b0ae311a87c9a73e3a146b525763ab2f955
A.2.2.1.Test Vector 1, Batch Size 1
Input = 00Blind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112BlindedElement = 7261bbc335c664ba788f1b1a1a4cd5190cc30e787ef277665ac1d314f8861e3ec11854ce3ddd42035d9e0f5cddde324c332d8c880abc00ebEvaluationElement = ca1491a526c28d880806cf0fb0122222392cf495657be6e4c9d203bceffa46c86406caf8217859d3fb259077af68e5d41b3699410781f467Proof = f84bbeee47aedf43558dae4b95b3853635a9fc1a9ea7eac9b454c64c66c4f49cd1c72711c7ac2e06c681e16ea693d5500bbd7b56455df52f69e00b76b4126961e1562fdbaaac40b7701065cbeece3febbfe09e00160f81775d36daed99d8a2a10be0759e01b7ee81217203416c9db208ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522bOutput = e2ac40b634f36cccd8262b285adff7c9dcc19cd308564a5f4e581d1a8535773b86fa4fc9f2203c370763695c5093aea4a7aedec4488b1340ba3bf663a23098c1
A.2.2.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112BlindedElement = 88287e553939090b888ddc15913e1807dc4757215555e1c3a79488ef311594729c7fa74c772a732b78440b7d66d0aa35f3bb316f1d93e1b2EvaluationElement = c00978c73e8e4ee1d447ab0d3ad1754055e72cc85c08e3a0db170909a9c61cbff1f1e7015f289e3038b0f341faea5d7780c130106065c231Proof = 7a2831a6b237e11ac1657d440df93bc5ce00f552e6020a99d5c956ffc4d07b5ade3e82ecdc257fd53d76239e733e0a1313e84ce16cc0d82734806092a693d7e8d3c420c2cb6ccd5d0ca32514fb78e9ad0973ebdcb52eba438fc73948d76339ee710121d83e2fe6f001cfdf551aff9f36ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522bOutput = 862952380e07ec840d9f6e6f909c5a25d16c3dacb586d89a181b4aa7380c959baa8c480fe8e6c64e089d68ea7aeeb5817bd524d7577905b5bab487690048c941
A.2.2.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112,b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522bBlindedElement = 7261bbc335c664ba788f1b1a1a4cd5190cc30e787ef277665ac1d314f8861e3ec11854ce3ddd42035d9e0f5cddde324c332d8c880abc00eb,2e15f393c035492a1573627a3606e528c6294c767c8d43b8c691ef70a52cc7dc7d1b53fe458350a270abb7c231b87ba58266f89164f714d9EvaluationElement = ca1491a526c28d880806cf0fb0122222392cf495657be6e4c9d203bceffa46c86406caf8217859d3fb259077af68e5d41b3699410781f467,8ec68e9871b296e81c55647ce64a04fe75d19932f1400544cd601468c60f998408bbb546601d4a636e8be279e558d70b95c8d4a4f61892beProof = 167d922f0a6ffa845eed07f8aa97b6ac746d902ecbeb18f49c009adc0521eab1e4d275b74a2dc266b7a194c854e85e7eb54a9a36376dfc04ec7f3bd55fc9618c3970cb548e064f8a2f06183a5702933dbc3e4c25a73438f2108ee1981c306181003c7ea92fce963ec7b4ba4f270e6d38ProofRandomScalar = 63798726803c9451ba405f00ef3acb633ddf0c420574a2ec6cbf28f840800e355c9fbaac10699686de2724ed22e797a00f3bd93d105a7f23Output = e2ac40b634f36cccd8262b285adff7c9dcc19cd308564a5f4e581d1a8535773b86fa4fc9f2203c370763695c5093aea4a7aedec4488b1340ba3bf663a23098c1,862952380e07ec840d9f6e6f909c5a25d16c3dacb586d89a181b4aa7380c959baa8c480fe8e6c64e089d68ea7aeeb5817bd524d7577905b5bab487690048c941

A.2.3.POPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 792a10dcbd3ba4a52a054f6f39186623208695301e7adb9634b74709ab22de402990eb143fd7c67ac66be75e0609705ecea800992aac8e19pkSm = 6c9d12723a5bbcf305522cc04b4a34d9ced2e12831826018ea7b5dcf5452647ad262113059bf0f6e4354319951b9d513c74f29cb0eec38c1
A.2.3.1.Test Vector 1, Batch Size 1
Input = 00Info = 7465737420696e666fBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112BlindedElement = 161183c13c6cb33b0e4f9b7365f8c5c12d13c72f8b62d276ca09368d093dce9b42198276b9e9d870ac392dda53efd28d1b7e6e8c060cdc42EvaluationElement = 06ec89dfde25bb2a6f0145ac84b91ac277b35de39ad1d6f402a8e46414952ce0d9ea1311a4ece283e2b01558c7078b040cfaa40dd63b3e6cProof = 66caee75bf2460429f620f6ad3e811d524cb8ddd848a435fc5d89af48877abf6506ee341a0b6f67c2d76cd021e5f3d1c9abe5aa9f0dce016da746135fedba2af41ed1d01659bfd6180d96bc1b7f320c0cb6926011ce392ecca748662564892bae66516acaac6ca39aadf6fcca95af406ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522bOutput = 4423f6dcc1740688ea201de57d76824d59cd6b859e1f9884b7eebc49b0b971358cf9cb075df1536a8ea31bcf55c3e31c2ba9cfa8efe54448d17091daeb9924ed
A.2.3.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112BlindedElement = 12082b6a381c6c51e85d00f2a3d828cdeab3f5cb19a10b9c014c33826764ab7e7cfb8b4ff6f411bddb2d64e62a472af1cd816e5b712790c6EvaluationElement = f2919b7eedc05ab807c221fce2b12c4ae9e19e6909c4784564b690d1972d2994ca623f273afc67444d84ea40cbc58fcdab7945f321a52848Proof = a295677c54d1bc4286330907fc2490a7de163da26f9ce03a462a452fea422b19ade296ba031359b3b6841e48455d20519ad01b4ac4f0b92e76d3cf16fbef0a3f72791a8401ef2d7081d361e502e96b2c60608b9fa566f43d4611c2f161d83aabef7f8017332b26ed1daaf80440772022ProofRandomScalar = b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522bOutput = 8691905500510843902c44bdd9730ab9dc3925aa58ff9dd42765a2baf633126de0c3adb93bef5652f38e5827b6396e87643960163a560fc4ac9738c8de4e4a8d
A.2.3.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 64d37aed22a27f5191de1c1d69fadb899d8862b58eb4220029e036ec65fa3833a26e9388336361686ff1f83df55046504dfecad8549ba112,b1b748135d405ce48c6973401d9455bb8ccd18b01d0295c0627f67661200dbf9569f73fbb3925daa043a070e5f953d80bb464ea369e5522bBlindedElement = 161183c13c6cb33b0e4f9b7365f8c5c12d13c72f8b62d276ca09368d093dce9b42198276b9e9d870ac392dda53efd28d1b7e6e8c060cdc42,fc8847d43fb4cea4e408f585661a8f2867533fa91d22155d3127a22f18d3b007add480f7d300bca93fa47fe87ae06a57b7d0f0d4c30b12f0EvaluationElement = 06ec89dfde25bb2a6f0145ac84b91ac277b35de39ad1d6f402a8e46414952ce0d9ea1311a4ece283e2b01558c7078b040cfaa40dd63b3e6c,2e74c626d07de49b1c8c21d87120fd78105f485e36816af9bde3e3efbeef76815326062fd333925b66c5ce5a20f100bf01770c16609f990aProof = fd94db736f97ea4efe9d0d4ad2933072697a6bbeb32834057b23edf7c7009f011dfa72157f05d2a507c2bbf0b54cad99ab99de05921c021fda7d70e65bcecdb05f9a30154127ace983c74d10fd910b554c5e95f6bd1565fd1f3dbbe3c523ece5c72d57a559b7be1368c4786db4a3c910ProofRandomScalar = 63798726803c9451ba405f00ef3acb633ddf0c420574a2ec6cbf28f840800e355c9fbaac10699686de2724ed22e797a00f3bd93d105a7f23Output = 4423f6dcc1740688ea201de57d76824d59cd6b859e1f9884b7eebc49b0b971358cf9cb075df1536a8ea31bcf55c3e31c2ba9cfa8efe54448d17091daeb9924ed,8691905500510843902c44bdd9730ab9dc3925aa58ff9dd42765a2baf633126de0c3adb93bef5652f38e5827b6396e87643960163a560fc4ac9738c8de4e4a8d

A.3.P256-SHA256

A.3.1.OPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 159749d750713afe245d2d39ccfaae8381c53ce92d098a9375ee70739c7ac0bf
A.3.1.1.Test Vector 1, Batch Size 1
Input = 00Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 03723a1e5c09b8b9c18d1dcbca29e8007e95f14f4732d9346d490ffc195110368dEvaluationElement = 030de02ffec47a1fd53efcdd1c6faf5bdc270912b8749e783c7ca75bb412958832Output = a0b34de5fa4c5b6da07e72af73cc507cceeb48981b97b7285fc375345fe495dd
A.3.1.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 03cc1df781f1c2240a64d1c297b3f3d16262ef5d4cf102734882675c26231b0838EvaluationElement = 03a0395fe3828f2476ffcd1f4fe540e5a8489322d398be3c4e5a869db7fcb7c52cOutput = c748ca6dd327f0ce85f4ae3a8cd6d4d5390bbb804c9e12dcf94f853fece3dcce

A.3.2.VOPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = ca5d94c8807817669a51b196c34c1b7f8442fde4334a7121ae4736364312fca6pkSm = 03e17e70604bcabe198882c0a1f27a92441e774224ed9c702e51dd17038b102462
A.3.2.1.Test Vector 1, Batch Size 1
Input = 00Blind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 02dd05901038bb31a6fae01828fd8d0e49e35a486b5c5d4b4994013648c01277daEvaluationElement = 0209f33cab60cf8fe69239b0afbcfcd261af4c1c5632624f2e9ba29b90ae83e4a2Proof = e7c2b3c5c954c035949f1f74e6bce2ed539a3be267d1481e9ddb178533df4c2664f69d065c604a4fd953e100b856ad83804eb3845189babfa5a702090d6fc5faProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 0412e8f78b02c415ab3a288e228978376f99927767ff37c5718d420010a645a1
A.3.2.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 03cd0f033e791c4d79dfa9c6ed750f2ac009ec46cd4195ca6fd3800d1e9b887dbdEvaluationElement = 030d2985865c693bf7af47ba4d3a3813176576383d19aff003ef7b0784a0d83cf1Proof = 2787d729c57e3d9512d3aa9e8708ad226bc48e0f1750b0767aaff73482c44b8d2873d74ec88aebd3504961acea16790a05c542d9fbff4fe269a77510db00ababProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 771e10dcd6bcd3664e23b8f2a710cfaaa8357747c4a8cbba03133967b5c24f18
A.3.2.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364,f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1BlindedElement = 02dd05901038bb31a6fae01828fd8d0e49e35a486b5c5d4b4994013648c01277da,03462e9ae64cae5b83ba98a6b360d942266389ac369b923eb3d557213b1922f8abEvaluationElement = 0209f33cab60cf8fe69239b0afbcfcd261af4c1c5632624f2e9ba29b90ae83e4a2,02bb24f4d838414aef052a8f044a6771230ca69c0a5677540fff738dd31bb69771Proof = bdcc351707d02a72ce49511c7db990566d29d6153ad6f8982fad2b435d6ce4d60da1e6b3fa740811bde34dd4fe0aa1b5fe6600d0440c9ddee95ea7fad7a60cf2ProofRandomScalar = 350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba51943c8026877963Output = 0412e8f78b02c415ab3a288e228978376f99927767ff37c5718d420010a645a1,771e10dcd6bcd3664e23b8f2a710cfaaa8357747c4a8cbba03133967b5c24f18

A.3.3.POPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 6ad2173efa689ef2c27772566ad7ff6e2d59b3b196f00219451fb2c89ee4dae2pkSm = 030d7ff077fddeec965db14b794f0cc1ba9019b04a2f4fcc1fa525dedf72e2a3e3
A.3.3.1.Test Vector 1, Batch Size 1
Input = 00Info = 7465737420696e666fBlind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 031563e127099a8f61ed51eeede05d747a8da2be329b40ba1f0db0b2bd9dd4e2c0EvaluationElement = 02c5e5300c2d9e6ba7f3f4ad60500ad93a0157e6288eb04b67e125db024a2c74d2Proof = f8a33690b87736c854eadfcaab58a59b8d9c03b569110b6f31f8bf7577f3fbb85a8a0c38468ccde1ba942be501654adb106167c8eb178703ccb42bccffb9231aProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 193a92520bd8fd1f37accb918040a57108daa110dc4f659abe212636d245c592
A.3.3.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 021a440ace8ca667f261c10ac7686adc66a12be31e3520fca317643a1eee9dcd4dEvaluationElement = 0208ca109cbae44f4774fc0bdd2783efdcb868cb4523d52196f700210e777c5de3Proof = 043a8fb7fc7fd31e35770cabda4753c5bf0ecc1e88c68d7d35a62bf2631e875af4613641be2d1875c31d1319d191c4bbc0d04875f4fd03c31d3d17dd8e069b69ProofRandomScalar = f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 1e6d164cfd835d88a31401623549bf6b9b306628ef03a7962921d62bc5ffce8c
A.3.3.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364,f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1BlindedElement = 031563e127099a8f61ed51eeede05d747a8da2be329b40ba1f0db0b2bd9dd4e2c0,03ca4ff41c12fadd7a0bc92cf856732b21df652e01a3abdf0fa8847da053db213cEvaluationElement = 02c5e5300c2d9e6ba7f3f4ad60500ad93a0157e6288eb04b67e125db024a2c74d2,02f0b6bcd467343a8d8555a99dc2eed0215c71898c5edb77a3d97ddd0dbad478e8Proof = 8fbd85a32c13aba79db4b42e762c00687d6dbf9c8cb97b2a225645ccb00d9d7580b383c885cdfd07df448d55e06f50f6173405eee5506c0ed0851ff718d13e68ProofRandomScalar = 350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba51943c8026877963Output = 193a92520bd8fd1f37accb918040a57108daa110dc4f659abe212636d245c592,1e6d164cfd835d88a31401623549bf6b9b306628ef03a7962921d62bc5ffce8c

A.4.P384-SHA384

A.4.1.OPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = dfe7ddc41a4646901184f2b432616c8ba6d452f9bcd0c4f75a5150ef2b2ed02ef40b8b92f60ae591bcabd72a6518f188
A.4.1.1.Test Vector 1, Batch Size 1
Input = 00Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 02a36bc90e6db34096346eaf8b7bc40ee1113582155ad3797003ce614c835a874343701d3f2debbd80d97cbe45de6e5f1fEvaluationElement = 03af2a4fc94770d7a7bf3187ca9cc4faf3732049eded2442ee50fbddda58b70ae2999366f72498cdbc43e6f2fc184afe30Output = ed84ad3f31a552f0456e58935fcc0a3039db42e7f356dcb32aa6d487b6b815a07d5813641fb1398c03ddab5763874357
A.4.1.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 02def6f418e3484f67a124a2ce1bfb19de7a4af568ede6a1ebb2733882510ddd43d05f2b1ab5187936a55e50a847a8b900EvaluationElement = 034e9b9a2960b536f2ef47d8608b21597ba400d5abfa1825fd21c36b75f927f396bf3716c96129d1fa4a77fa1d479c8d7bOutput = dd4f29da869ab9355d60617b60da0991e22aaab243a3460601e48b075859d1c526d36597326f1b985778f781a1682e75

A.4.2.VOPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 051646b9e6e7a71ae27c1e1d0b87b4381db6d3595eeeb1adb41579adbf992f4278f9016eafc944edaa2b43183581779dpkSm = 031d689686c611991b55f1a1d8f4305ccd6cb719446f660a30db61b7aa87b46acf59b7c0d4a9077b3da21c25dd482229a0
A.4.2.1.Test Vector 1, Batch Size 1
Input = 00Blind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 02d338c05cbecb82de13d6700f09cb61190543a7b7e2c6cd4fca56887e564ea82653b27fdad383995ea6d02cf26d0e24d9EvaluationElement = 02a7bba589b3e8672aa19e8fd258de2e6aae20101c8d761246de97a6b5ee9cf105febce4327a326255a3c604f63f600ef6Proof = bfc6cf3859127f5fe25548859856d6b7fa1c7459f0ba5712a806fc091a3000c42d8ba34ff45f32a52e40533efd2a03bc87f3bf4f9f58028297ccb9ccb18ae7182bcd1ef239df77e3be65ef147f3acf8bc9cbfc5524b702263414f043e3b7ca2eProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 3333230886b562ffb8329a8be08fea8025755372817ec969d114d1203d026b4a622beab60220bf19078bca35a529b35c
A.4.2.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 02f27469e059886f221be5f2cca03d2bdc61e55221721c3b3e56fc012e36d31ae5f8dc058109591556a6dbd3a8c69c433bEvaluationElement = 03f16f903947035400e96b7f531a38d4a07ac89a80f89d86a1bf089c525a92c7f4733729ca30c56ce78b1ab4f7d92db8b4Proof = d005d6daaad7571414c1e0c75f7e57f2113ca9f4604e84bc90f9be52da896fff3bee496dcde2a578ae9df315032585f801fb21c6080ac05672b291e575a40295b306d967717b28e08fcc8ad1cab47845d16af73b3e643ddcc191208e71c64630ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = b91c70ea3d4d62ba922eb8a7d03809a441e1c3c7af915cbc2226f485213e895942cd0f8580e6d99f82221e66c40d274f
A.4.2.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364,803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1BlindedElement = 02d338c05cbecb82de13d6700f09cb61190543a7b7e2c6cd4fca56887e564ea82653b27fdad383995ea6d02cf26d0e24d9,02fa02470d7f151018b41e82223c32fad824de6ad4b5ce9f8e9f98083c9a726de9a1fc39d7a0cb6f4f188dd9cea01474cdEvaluationElement = 02a7bba589b3e8672aa19e8fd258de2e6aae20101c8d761246de97a6b5ee9cf105febce4327a326255a3c604f63f600ef6,028e9e115625ff4c2f07bf87ce3fd73fc77994a7a0c1df03d2a630a3d845930e2e63a165b114d98fe34e61b68d23c0b50aProof = 6d8dcbd2fc95550a02211fb78afd013933f307d21e7d855b0b1ed0af78076d8137ad8b0a1bfa05676d325249c1dbb9a52bd81b1c2b7b0efc77cf7b278e1c947f6283f1d4c513053fc0ad19e026fb0c30654b53d9cea4b87b037271b5d2e2d0eaProofRandomScalar = a097e722ed2427de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba51943c8026877963Output = 3333230886b562ffb8329a8be08fea8025755372817ec969d114d1203d026b4a622beab60220bf19078bca35a529b35c,b91c70ea3d4d62ba922eb8a7d03809a441e1c3c7af915cbc2226f485213e895942cd0f8580e6d99f82221e66c40d274f

A.4.3.POPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 5b2690d6954b8fbb159f19935d64133f12770c00b68422559c65431942d721ff79d47d7a75906c30b7818ec0f38b7fb2pkSm = 02f00f0f1de81e5d6cf18140d4926ffdc9b1898c48dc49657ae36eb1e45deb8b951aaf1f10c82d2eaa6d02aafa3f10d2b6
A.4.3.1.Test Vector 1, Batch Size 1
Input = 00Info = 7465737420696e666fBlind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 03859b36b95e6564faa85cd3801175eda2949707f6aa0640ad093cbf8ad2f58e762f08b56b2a1b42a64953aaf49cbf1ae3EvaluationElement = 0220710e2e00306453f5b4f574cb6a512453f35c45080d09373e190c19ce5b185914fbf36582d7e0754bb7c8b683205b91Proof = 82a17ef41c8b57f1e3122311b4d5cd39a63df0f67443ef18d961f9b659c1601ced8d3c64b294f604319ca80230380d437a49c7af0d620e22116669c008ebb767d90283d573b49cdb49e3725889620924c2c4b047a2a6225a3ba27e640ebddd33ProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 0188653cfec38119a6c7dd7948b0f0720460b4310e40824e048bf82a16527303ed449a08caf84272c3bbc972ede797df
A.4.3.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 03f7efcb4aaf000263369d8a0621cb96b81b3206e99876de2a00699ed4c45acf3969cd6e2319215395955d3f8d8cc1c712EvaluationElement = 034993c818369927e74b77c400376fd1ae29b6ac6c6ddb776cf10e4fbc487826531b3cf0b7c8ca4d92c7af90c9def85ce6Proof = 693471b5dff0cd6a5c00ea34d7bf127b2795164e3bdb5f39a1e5edfbd13e443bc516061cd5b8449a473c2ceeccada9f3e5b57302e3d7bc5e28d38d6e3a3056e1e73b6cc030f5180f8a1ffa45aa923ee66d2ad0a07b500f2acc7fb99b5506465cProofRandomScalar = 803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = ff2a527a21cc43b251a567382677f078c6e356336aec069dea8ba36995343ca3b33bb5d6cf15be4d31a7e6d75b30d3f5
A.4.3.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364,803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1BlindedElement = 03859b36b95e6564faa85cd3801175eda2949707f6aa0640ad093cbf8ad2f58e762f08b56b2a1b42a64953aaf49cbf1ae3,021a65d618d645f1a20bc33b06deaa7e73d6d634c8a56a3d02b53a732b69a5c53c5a207ea33d5afdcde9a22d59726bce51EvaluationElement = 0220710e2e00306453f5b4f574cb6a512453f35c45080d09373e190c19ce5b185914fbf36582d7e0754bb7c8b683205b91,02017657b315ec65ef861505e596c8645d94685dd7602cdd092a8f1c1c0194a5d0485fe47d071d972ab514370174cc23f5Proof = 4a0b2fe96d5b2a046a0447fe079b77859ef11a39a3520d6ff7c626aad9b473b724fb0cf188974ec961710a62162a83e97e0baa9eeada73397032d928b3e97b1ea92ad9458208302be3681b8ba78bcc17745bac00f84e0fdc98a6a8cba009c080ProofRandomScalar = a097e722ed2427de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba51943c8026877963Output = 0188653cfec38119a6c7dd7948b0f0720460b4310e40824e048bf82a16527303ed449a08caf84272c3bbc972ede797df,ff2a527a21cc43b251a567382677f078c6e356336aec069dea8ba36995343ca3b33bb5d6cf15be4d31a7e6d75b30d3f5

A.5.P521-SHA512

A.5.1.OPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 0153441b8faedb0340439036d6aed06d1217b34c42f17f8db4c5cc610a4a955d698a688831b16d0dc7713a1aa3611ec60703bffc7dc9c84e3ed673b3dbe1d5fccea6
A.5.1.1.Test Vector 1, Batch Size 1
Input = 00Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 0300e78bf846b0e1e1a3c320e353d758583cd876df56100a3a1e62bacba470fa6e0991be1be80b721c50c5fd0c672ba764457acc18c6200704e9294fbf28859d916351EvaluationElement = 030166371cf827cb2fb9b581f97907121a16e2dc5d8b10ce9f0ede7f7d76a0d047657735e8ad07bcda824907b3e5479bd72cdef6b839b967ba5c58b118b84d26f2ba07Output = 26232de6fff83f812adadadb6cc05d7bbeee5dca043dbb16b03488abb9981d0a1ef4351fad52dbd7e759649af393348f7b9717566c19a6b8856284d69375c809
A.5.1.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 0300c28e57e74361d87e0c1874e5f7cc1cc796d61f9cad50427cf54655cdb455613368d42b27f94bf66f59f53c816db3e95e68e1b113443d66a99b3693bab88afb556bEvaluationElement = 0301ad453607e12d0cc11a3359332a40c3a254eaa1afc64296528d55bed07ba322e72e22cf3bcb50570fd913cb54f7f09c17aff8787af75f6a7faf5640cbb2d9620a6eOutput = ad1f76ef939042175e007738906ac0336bbd1d51e287ebaa66901abdd324ea3ffa40bfc5a68e7939c2845e0fd37a5a6e76dadb9907c6cc8579629757fd4d04ba

A.5.2.VOPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 015c7fc1b4a0b1390925bae915bd9f3d72009d44d9241b962428aad5d13f22803311e7102632a39addc61ea440810222715c9d2f61f03ea424ec9ab1fe5e31cf9238pkSm = 0301505d646f6e4c9102451eb39730c4ba1c4087618641edbdba4a60896b07fd0c9414ce553cbf25b81dfcca50a8f6724ab7a2bc4d0cf736967a287bb6084cc0678ac0
A.5.2.1.Test Vector 1, Batch Size 1
Input = 00Blind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 0301d6e4fb545e043ddb6aee5d5ceeee1b44102615ab04430c27dd0f56988dedcb1df32ef384f160e0e76e718605f14f3f582f9357553d153b996795b4b3628a4f6380EvaluationElement = 03013fdeaf887f3d3d283a79e696a54b66ff0edcb559265e204a958acf840e0930cc147e2a6835148d8199eebc26c03e9394c9762a1c991dde40bca0f8ca003eefb045Proof = 0077fcc8ec6d059d7759b0a61f871e7c1dadc65333502e09a51994328f79e5bda3357b9a4f410a1760a3612c2f8f27cb7cb032951c047cc66da60da583df7b247edd0188e5eb99c71799af1d80d643af16ffa1545acd9e9233fbb370455b10eb257ea12a1667c1b4ee5b0ab7c93d50ae89602006960f083ca9adc4f6276c0ad60440393cProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 5e003d9b2fb540b3d4bab5fedd154912246da1ee5e557afd8f56415faa1a0fadff6517da802ee254437e4f60907b4cda146e7ba19e249eef7be405549f62954b
A.5.2.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 03005b05e656cb609ce5ff5faf063bb746d662d67bbd07c062638396f52f0392180cf2365cabb0ece8e19048961d35eeae5d5fa872328dce98df076ee154dd191c615eEvaluationElement = 0301b19fcf482b1fff04754e282292ed736c5f0aa080d4f42663cd3a416c6596f03129e8e096d8671fe5b0d19838312c511d2ce08d431e43e3ef06199d8cab7426238dProof = 01ec9fece444caa6a57032e8963df0e945286f88fbdf233fb5101f0924f7ea89c47023f5f72f240e61991fd33a299b5b38c45a5e2dd1a67b072e59dfe86708a359c701e38d383c60cf6969463bcf13251bedad47b7941f52e409a3591398e27924410b18a301c0e19f527cad504fa08388050ac634e1b05c5216d337742f2754e1fc502fProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = fa15eebba81ecf40954f7135cb76f69ef22c6bae394d1a4362f9b03066b54b6604d39f2e53369ca6762a3d9787e230e832aa85955af40ecb8deebb009a8cf474
A.5.2.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aBlind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364,015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1BlindedElement = 0301d6e4fb545e043ddb6aee5d5ceeee1b44102615ab04430c27dd0f56988dedcb1df32ef384f160e0e76e718605f14f3f582f9357553d153b996795b4b3628a4f6380,0301403b597538b939b450c93586ba275f9711ba07e42364bac1d5769c6824a8b55be6f9a536df46d952b11ab2188363b3d6737635d9543d4dba14a6e19421b9245bf5EvaluationElement = 03013fdeaf887f3d3d283a79e696a54b66ff0edcb559265e204a958acf840e0930cc147e2a6835148d8199eebc26c03e9394c9762a1c991dde40bca0f8ca003eefb045,03001f96424497e38c46c904978c2fa1636c5c3dd2e634a85d8a7265977c5dce1f02c7e6c118479f0751767b91a39cce6561998258591b5d7c1bb02445a9e08e4f3e8dProof = 00b4d215c8405e57c7a4b53398caf55f1f1623aaeb22408ddb9ea29130909b3f95dbb1ff366e81e86e918f9f2fd8b80dbb344cd498c9499d112905e585417e0068c600fe5dea18b389ef6c4cc062935607b8ccbbb9a84fba3143868a3e8a58efa0bf6ca642804d09dc06e980f64837811227c4267b217f1099a4e28b0854f4e5ee659796ProofRandomScalar = 01ec21c7bb69b0734cb48dfd68433dd93b0fa097e722ed2427de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba51943c8026877963Output = 5e003d9b2fb540b3d4bab5fedd154912246da1ee5e557afd8f56415faa1a0fadff6517da802ee254437e4f60907b4cda146e7ba19e249eef7be405549f62954b,fa15eebba81ecf40954f7135cb76f69ef22c6bae394d1a4362f9b03066b54b6604d39f2e53369ca6762a3d9787e230e832aa85955af40ecb8deebb009a8cf474

A.5.3.POPRF Mode

Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3KeyInfo = 74657374206b6579skSm = 014893130030ce69cf714f536498a02ff6b396888f9bb507985c32928c4427d6d39de10ef509aca4240e8569e3a88debc0d392e3361bcd934cb9bdd59e339dff7b27pkSm = 0301de8ceb9ffe9237b1bba87c320ea0bebcfc3447fe6f278065c6c69886d692d1126b79b6844f829940ace9b52a5e26882cf7cbc9e57503d4cca3cd834584729f812a
A.5.3.1.Test Vector 1, Batch Size 1
Input = 00Info = 7465737420696e666fBlind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 020095cff9d7ecf65bdfee4ea92d6e748d60b02de34ad98094f82e25d33a8bf50138ccc2cc633556f1a97d7ea9438cbb394df612f041c485a515849d5ebb2238f2f0e2EvaluationElement = 0301408e9c5be3ffcc1c16e5ae8f8aa68446223b0804b11962e856af5a6d1c65ebbb5db7278c21db4e8cc06d89a35b6804fb1738a295b691638af77aa1327253f26d01Proof = 0106a89a61eee9dd2417d2849a8e2167bc5f56e3aed5a3ff23e22511fa1b37a29ed44d1bbfd6907d99cfbc558a56aec709282415a864a281e49dc53792a4a638a0660034306d64be12a94dcea5a6d664cf76681911c8b9a84d49bf12d4893307ec14436bd05f791f82446c0de4be6c582d373627b51886f76c4788256e3da7ec8fa18a86ProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c143954882d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733b
A.5.3.2.Test Vector 2, Batch Size 1
Input = 5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364BlindedElement = 030112ea89cf9cf589496189eafc5f9eb13c9f9e170d6ecde7c5b940541cb1a9c5cfeec908b67efe16b81ca00d0ce216e34b3d5f46a658d3fd8573d671bdb6515ed508EvaluationElement = 0200ebc49df1e6fa61f412e6c391e6f074400ecdd2f56c4a8c03fe0f91d9b551f40d4b5258fd891952e8c9b28003bcfa365122e54a5714c8949d5d202767b31b4bf1f6Proof = 0082162c71a7765005cae202d4bd14b84dae63c29067e886b82506992bd994a1c3aac0c1c5309222fe1af8287b6443ed6df5c2e0b0991faddd3564c73c7597aecd9a003b1f1e3c65f28e58ab4e767cfb4adbcaf512441645f4c2aed8bf67d132d966006d35fa71a34145414bf3572c1de1a46c266a344dd9e22e7fb1e90ffba1caf556d9ProofRandomScalar = 015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1Output = 27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af5762c3638afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e3
A.5.3.3.Test Vector 3, Batch Size 2
Input = 00,5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5a5aInfo = 7465737420696e666fBlind = 00d1dccf7a51bafaf75d4a866d53d8cafe4d504650f53df8f16f6861633388936ea23338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364,015e80ae32363b32cb76ad4b95a5a34e46bb803d955f0e073a04aa5d92b3fb739f56f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1BlindedElement = 020095cff9d7ecf65bdfee4ea92d6e748d60b02de34ad98094f82e25d33a8bf50138ccc2cc633556f1a97d7ea9438cbb394df612f041c485a515849d5ebb2238f2f0e2,0201a328cf9f3fdeb86b6db242dd4cbb436b3a488b70b72d2fbbd1e5f50d7b0878b157d6f278c6a95c488f3ad52d6898a421658a82fe7ceb000b01aedea7967522d525EvaluationElement = 0301408e9c5be3ffcc1c16e5ae8f8aa68446223b0804b11962e856af5a6d1c65ebbb5db7278c21db4e8cc06d89a35b6804fb1738a295b691638af77aa1327253f26d01,020062ab51ac3aa829e0f5b7ae50688bcf5f63a18a83a6e0da538666b8d50c7ea2b4ef31f4ac669302318dbebe46660acdda695da30c22cee7ca21f6984a720504502eProof = 00731738844f739bca0cca9d1c8bea204bed4fd00285785738b985763741de5cdfa275152d52b6a2fdf7792ef3779f39ba34581e56d62f78ecad5b7f8083f384961501cd4b43713253c022692669cf076b1d382ecd8293c1de69ea569737f37a24772ab73517983c1e3db5818754ba1f008076267b8058b6481949ae346cdc17a8455fe2ProofRandomScalar = 01ec21c7bb69b0734cb48dfd68433dd93b0fa097e722ed2427de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba51943c8026877963Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c143954882d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733b,27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af5762c3638afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e3

Acknowledgements

This document resulted from the work of the Privacy Pass team[PrivacyPass]. The authors would also like to acknowledge helpfulconversations withHugo Krawczyk.Eli-Shaoul Khedouri providedadditional review and comments on key consistency.Daniel Bourdrez,Tatiana Bradley,Sofia Celi,Frank Denis,Julia Hesse,Russ Housley,Kevin Lewi,Christopher Patton, andBas Westerbaan also providedhelpful input and contributions to the document.

Authors' Addresses

Alex Davidson
Brave Software
Email:alex.davidson92@gmail.com
Armando Faz-Hernandez
Cloudflare, Inc.
101 Townsend St
San Francisco,CA
United States of America
Email:armfazh@cloudflare.com
Nick Sullivan
Cloudflare, Inc.
101 Townsend St
San Francisco,CA
United States of America
Email:nicholas.sullivan+ietf@gmail.com
Christopher A. Wood
Cloudflare, Inc.
101 Townsend St
San Francisco,CA
United States of America
Email:caw@heapingbits.net

[8]ページ先頭

©2009-2025 Movatter.jp