rfc9497v1.txt   rfc9497.txt 
Internet Research Task Force (IRTF) A. Davidson Internet Research Task Force (IRTF) A. Davidson
Request for Comments: 9497 Brave Software Request for Comments: 9497 Brave Software
Category: Informational A. Faz-Hernandez Category: Informational A. Faz-Hernandez
ISSN: 2070-1721 N. Sullivan ISSN: 2070-1721 N. Sullivan
C. A. Wood C. A. Wood
Cloudflare, Inc. Cloudflare, Inc.
October 2023 November 2023
Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order Groups Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order Groups
Abstract Abstract
An Oblivious Pseudorandom Function (OPRF) is a two-party protocol An Oblivious Pseudorandom Function (OPRF) is a two-party protocol
between a client and a server for computing the output of a between a client and a server for computing the output of a
Pseudorandom Function (PRF). The server provides the PRF private Pseudorandom Function (PRF). The server provides the PRF private
key, and the client provides the PRF input. At the end of the key, and the client provides the PRF input. At the end of the
protocol, the client learns the PRF output without learning anything protocol, the client learns the PRF output without learning anything
skipping to change at line 218 skipping to change at line 218
The following terms are used throughout this document. The following terms are used throughout this document.
PRF: Pseudorandom Function PRF: Pseudorandom Function
OPRF: Oblivious Pseudorandom Function OPRF: Oblivious Pseudorandom Function
VOPRF: Verifiable Oblivious Pseudorandom Function VOPRF: Verifiable Oblivious Pseudorandom Function
POPRF: Partially Oblivious Pseudorandom Function POPRF: Partially Oblivious Pseudorandom Function
Client: Client: Protocol initiator. Learns PRF evaluation as the output of
Protocol initiator. Learns PRF evaluation as the output of the the protocol.
protocol.
Server: Server: Computes the PRF using a private key. Learns nothing about
Computes the PRF using a private key. Learns nothing about the the client's input or output.
client's input or output.
2. Preliminaries 2. Preliminaries
The protocols in this document have two primary dependencies: The protocols in this document have two primary dependencies:
Group: A prime-order group implementing the API described below in Group: A prime-order group implementing the API described below in
Section 2.1. See Section 4 for specific instances of groups. Section 2.1. See Section 4 for specific instances of groups.
Hash: A cryptographic hash function whose output length is Nh bytes. Hash: A cryptographic hash function whose output length is Nh bytes.
Section 4 specifies ciphersuites as combinations of Group and Hash. Section 4 specifies ciphersuites as combinations of Group and Hash.
2.1. Prime-Order Group 2.1. Prime-Order Group
In this document, we assume the construction of an additive, prime- In this document, we assume the construction of an additive, prime-
order group Group for performing all mathematical operations. In order group, denoted Group, for performing all mathematical
prime-order groups, any element (other than the identity) can operations. In prime-order groups, any element (other than the
generate the other elements of the group. Usually, one element is identity) can generate the other elements of the group. Usually, one
fixed and defined as the group generator. Such groups are uniquely element is fixed and defined as the group generator. Such groups are
determined by the choice of the prime p that defines the order of the uniquely determined by the choice of the prime p that defines the
group. (However, different representations of the group for a single order of the group. (However, different representations of the group
p may exist. Section 4 lists specific groups that indicate both the for a single p may exist. Section 4 lists specific groups that
order and representation.) indicate both the order and representation.)
The fundamental group operation is addition + with identity element The fundamental group operation is addition + with identity element
I. For any elements A and B of the group, A + B = B + A is also a I. For any elements A and B of the group, A + B = B + A is also a
member of the group. Also, for any A in the group, there exists an member of the group. Also, for any A in the group, there exists an
element -A, such that A + (-A) = (-A) + A = I. Scalar multiplication element -A, such that A + (-A) = (-A) + A = I. Scalar multiplication
by r is equivalent to the repeated application of the group operation by r is equivalent to the repeated application of the group operation
on an element A with itself r - 1 times; this is denoted as r * A = A on an element A with itself r - 1 times; this is denoted as r * A = A
+ ... + A. For any element A, p * A = I. The case when the scalar + ... + A. For any element A, p * A = I. The case when the scalar
multiplication is performed on the group generator is denoted as multiplication is performed on the group generator is denoted as
ScalarMultGen(r). Given two elements A and B, the discrete logarithm ScalarMultGen(r). Given two elements A and B, the discrete logarithm
problem is to find an integer k, such that B = k * A. Thus, k is the problem is to find an integer k, such that B = k * A. Thus, k is the
discrete logarithm of B with respect to the base A. The set of discrete logarithm of B with respect to the base A. The set of
scalars corresponds to GF(p), a prime field of order p, and is scalars corresponds to GF(p), a prime field of order p, and is
represented as the set of integers defined by {0, 1, ..., p - 1}. represented as the set of integers defined by {0, 1, ..., p - 1}.
This document uses types element and scalar to denote elements of the This document uses types Element and Scalar to denote elements of the
group and its set of scalars, respectively. group and its set of scalars, respectively.
We now detail a number of member functions that can be invoked on a We now detail a number of member functions that can be invoked on a
prime-order group. prime-order group.
Order(): Outputs the order of the group (i.e., p). Order(): Outputs the order of the group (i.e., p).
Identity(): Outputs the identity element of the group (i.e., I). Identity(): Outputs the identity element of the group (i.e., I).
Generator(): Outputs the generator element of the group. Generator(): Outputs the generator element of the group.
skipping to change at line 288 skipping to change at line 286
a domain separation tag (DST); see Section 4. Security properties a domain separation tag (DST); see Section 4. Security properties
of this function are described in [RFC9380]. of this function are described in [RFC9380].
HashToScalar(x): Deterministically maps an array of bytes x to an HashToScalar(x): Deterministically maps an array of bytes x to an
element in GF(p). This function is optionally parameterized by a element in GF(p). This function is optionally parameterized by a
DST; see Section 4. Security properties of this function are DST; see Section 4. Security properties of this function are
described in [RFC9380], Section 10.5. described in [RFC9380], Section 10.5.
RandomScalar(): Chooses at random a nonzero element in GF(p). RandomScalar(): Chooses at random a nonzero element in GF(p).
ScalarInverse(s): Returns the inverse of input scalar s on GF(p). ScalarInverse(s): Returns the inverse of input Scalar s on GF(p).
SerializeElement(A): Maps an element A to a canonical byte array buf SerializeElement(A): Maps an Element A to a canonical byte array buf
of fixed-length Ne. of fixed-length Ne.
DeserializeElement(buf): Attempts to map a byte array buf to an DeserializeElement(buf): Attempts to map a byte array buf to an
element A and fails if the input is not the valid canonical byte Element A and fails if the input is not the valid canonical byte
representation of an element of the group. This function can representation of an element of the group. This function can
raise a DeserializeError if deserialization fails or A is the raise a DeserializeError if deserialization fails or A is the
identity element of the group; see Section 4 for group-specific identity element of the group; see Section 4 for group-specific
input validation steps. input validation steps.
SerializeScalar(s): Maps scalar s to a canonical byte array buf of SerializeScalar(s): Maps Scalar s to a canonical byte array buf of
fixed-length Ns. fixed-length Ns.
DeserializeScalar(buf): Attempts to map a byte array buf to scalar DeserializeScalar(buf): Attempts to map a byte array buf to Scalar
s. This function can raise a DeserializeError if deserialization s. This function can raise a DeserializeError if deserialization
fails; see Section 4 for group-specific input validation steps. fails; see Section 4 for group-specific input validation steps.
Section 4 contains details for the implementation of this interface Section 4 contains details for the implementation of this interface
for different prime-order groups instantiated over elliptic curves. for different prime-order groups instantiated over elliptic curves.
In particular, for some choices of elliptic curves, e.g., those In particular, for some choices of elliptic curves, e.g., those
detailed in [RFC7748], which require accounting for cofactors, detailed in [RFC7748], which require accounting for cofactors,
Section 4 describes required steps necessary to ensure the resulting Section 4 describes required steps necessary to ensure the resulting
group is of prime order. group is of prime order.
skipping to change at line 347 skipping to change at line 345
proof is derived from a seed-prefixed hash-to-scalar invocation, proof is derived from a seed-prefixed hash-to-scalar invocation,
rather than being sampled from a seeded Pseudorandom Number Generator rather than being sampled from a seeded Pseudorandom Number Generator
(PRNG). The description is split into two subsections: one for (PRNG). The description is split into two subsections: one for
generating the proof, which is done by servers in the verifiable generating the proof, which is done by servers in the verifiable
protocols, and another for verifying the proof, which is done by protocols, and another for verifying the proof, which is done by
clients in the protocol. clients in the protocol.
2.2.1. Proof Generation 2.2.1. Proof Generation
Generating a proof is done with the GenerateProof function, as Generating a proof is done with the GenerateProof function, as
defined below. Given elements A and B, two non-empty lists of defined below. Given Element values A and B, two non-empty lists of
elements C and D of length m, and a scalar k; this function produces Element values C and D of length m, and Scalar k, this function
a proof that k * A == B and k * C[i] == D[i] for each i in [0, ..., m produces a proof that k * A == B and k * C[i] == D[i] for each i in
- 1]. The output is a value of type Proof, which is a tuple of two [0, ..., m - 1]. The output is a value of type Proof, which is a
scalar values. We use the notation proof[0] and proof[1] to denote tuple of two Scalar values. We use the notation proof[0] and
the first and second elements in this tuple, respectively. proof[1] to denote the first and second elements in this tuple,
respectively.
GenerateProof accepts lists of inputs to amortize the cost of proof GenerateProof accepts lists of inputs to amortize the cost of proof
generation. Applications can take advantage of this functionality to generation. Applications can take advantage of this functionality to
produce a single, constant-sized proof for m DLEQ inputs, rather than produce a single, constant-sized proof for m DLEQ inputs, rather than
m proofs for m DLEQ inputs. m proofs for m DLEQ inputs.
Input: Input:
Scalar k Scalar k
Element A Element A
skipping to change at line 375 skipping to change at line 374
Element D[m] Element D[m]
Output: Output:
Proof proof Proof proof
Parameters: Parameters:
Group G Group G
def GenerateProof(k, A, B, C, D) def GenerateProof(k, A, B, C, D):
(M, Z) = ComputeCompositesFast(k, B, C, D) (M, Z) = ComputeCompositesFast(k, B, C, D)
r = G.RandomScalar() r = G.RandomScalar()
t2 = r * A t2 = r * A
t3 = r * M t3 = r * M
Bm = G.SerializeElement(B) Bm = G.SerializeElement(B)
a0 = G.SerializeElement(M) a0 = G.SerializeElement(M)
a1 = G.SerializeElement(Z) a1 = G.SerializeElement(Z)
a2 = G.SerializeElement(t2) a2 = G.SerializeElement(t2)
skipping to change at line 453 skipping to change at line 452
Z = k * M Z = k * M
return (M, Z) return (M, Z)
When used in the protocol described in Section 3, the parameter When used in the protocol described in Section 3, the parameter
contextString is as defined in Section 3.2. contextString is as defined in Section 3.2.
2.2.2. Proof Verification 2.2.2. Proof Verification
Verifying a proof is done with the VerifyProof function, as defined Verifying a proof is done with the VerifyProof function, as defined
below. This function takes elements A and B, two non-empty lists of below. This function takes Element values A and B, two non-empty
elements C and D of length m, and a Proof value output from lists of Element values C and D of length m, and a Proof value output
GenerateProof. It outputs a single boolean value indicating whether from GenerateProof. It outputs a single boolean value indicating
or not the proof is valid for the given DLEQ inputs. Note this whether or not the proof is valid for the given DLEQ inputs. Note
function can verify proofs on lists of inputs whenever the proof was this function can verify proofs on lists of inputs whenever the proof
generated as a batched DLEQ proof with the same inputs. was generated as a batched DLEQ proof with the same inputs.
Input: Input:
Element A Element A
Element B Element B
Element C[m] Element C[m]
Element D[m] Element D[m]
Proof proof Proof proof
Output: Output:
skipping to change at line 730 skipping to change at line 729
contextString = CreateContextString(modePOPRF, identifier) contextString = CreateContextString(modePOPRF, identifier)
return POPRFServerContext(contextString, skS) return POPRFServerContext(contextString, skS)
def SetupPOPRFClient(identifier, pkS): def SetupPOPRFClient(identifier, pkS):
contextString = CreateContextString(modePOPRF, identifier) contextString = CreateContextString(modePOPRF, identifier)
return POPRFClientContext(contextString, pkS) return POPRFClientContext(contextString, pkS)
3.2.1. Deterministic Key Generation 3.2.1. Deterministic Key Generation
This section describes a deterministic key generation function, This section describes a deterministic key generation function,
DeriveKeyPair. It accepts a seed of Ns bytes generated from a DeriveKeyPair. It accepts a seed of 32 bytes generated from a
cryptographically secure random number generator and an optional cryptographically secure random number generator and an optional
(possibly empty) info string. The constant Ns corresponds to the (possibly empty) info string. Note that, by design, knowledge of
size in bytes of a serialized scalar and is defined in Section 2.1. seed and info is necessary to compute this function, which means that
Note that, by design, knowledge of seed and info is necessary to the secrecy of the output private key (skS) depends on the secrecy of
compute this function, which means that the secrecy of the output seed (since the info string is public).
private key (skS) depends on the secrecy of seed (since the info
string is public).
Input: Input:
opaque seed[Ns] opaque seed[32]
PublicInput info PublicInput info
Output: Output:
Scalar skS Scalar skS
Element pkS Element pkS
Parameters: Parameters:
Group G Group G
skipping to change at line 778 skipping to change at line 775
3.3. Online Protocol 3.3. Online Protocol
In the online phase, the client and server engage in a two-message In the online phase, the client and server engage in a two-message
protocol to compute the protocol output. This section describes the protocol to compute the protocol output. This section describes the
protocol details for each protocol variant. Throughout each protocol details for each protocol variant. Throughout each
description, the following parameters are assumed to exist: description, the following parameters are assumed to exist:
G: a prime-order group implementing the API described in Section 2.1 G: a prime-order group implementing the API described in Section 2.1
contextString: contextString: a PublicInput domain separation tag constructed
a PublicInput domain separation tag constructed during context during context setup, as created in Section 3.1
setup, as created in Section 3.1
skS and pkS: skS and pkS: a Scalar and Element representing the private and
a scalar and element representing the private and public keys public keys configured for the client and server in Section 3.2
configured for the client and server in Section 3.2
Applications serialize protocol messages between the client and Applications serialize protocol messages between the client and
server for transmission. Elements and scalars are serialized to byte server for transmission. Element values and Scalar values are
arrays, and values of type Proof are serialized as the concatenation serialized to byte arrays, and values of type Proof are serialized as
of two serialized scalars. Deserializing these values can fail; in the concatenation of two serialized Scalar values. Deserializing
which case, the application MUST abort the protocol, raising a these values can fail; in which case, the application MUST abort the
DeserializeError failure. protocol, raising a DeserializeError failure.
Applications MUST check that input element values received over the Applications MUST check that input Element values received over the
wire are not the group identity element. This check is handled after wire are not the group identity element. This check is handled after
deserializing element values; see Section 4 for more information and deserializing Element values; see Section 4 for more information and
requirements on input validation for each ciphersuite. requirements on input validation for each ciphersuite.
3.3.1. OPRF Protocol 3.3.1. OPRF Protocol
The OPRF protocol begins with the client blinding its input, as The OPRF protocol begins with the client blinding its input, as
described by the Blind function below. Note that this function can described by the Blind function below. Note that this function can
fail with an InvalidInputError error for certain inputs that map to fail with an InvalidInputError error for certain inputs that map to
the group identity element. Dealing with this failure is an the group identity element. Dealing with this failure is an
application-specific decision; see Section 5.3. application-specific decision; see Section 5.3.
skipping to change at line 1227 skipping to change at line 1222
Identity(): As defined in [RFC9496]. Identity(): As defined in [RFC9496].
Generator(): As defined in [RFC9496]. Generator(): As defined in [RFC9496].
HashToGroup(): Use hash_to_ristretto255 [RFC9380] with DST = HashToGroup(): Use hash_to_ristretto255 [RFC9380] with DST =
"HashToGroup-" || contextString and expand_message = "HashToGroup-" || contextString and expand_message =
expand_message_xmd using SHA-512. expand_message_xmd using SHA-512.
HashToScalar(): Compute uniform_bytes using expand_message = HashToScalar(): Compute uniform_bytes using expand_message =
expand_message_xmd, DST = "HashToScalar-" || contextString, and expand_message_xmd, DST = "HashToScalar-" || contextString, and
output length 64, interpret uniform_bytes as a 512-bit integer an output length of 64 bytes, interpret uniform_bytes as a
in little-endian order, and reduce the integer modulo 512-bit integer in little-endian order, and reduce the integer
Group.Order(). modulo Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input ScalarInverse(s): Returns the multiplicative inverse of input
scalar s mod Group.Order(). Scalar s mod Group.Order().
RandomScalar(): RandomScalar(): Implemented by returning a uniformly random
Implemented by returning a uniformly random scalar in the range Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
[0, G.Order() - 1]. Refer to Section 4.7 for implementation for implementation guidance.
guidance.
SerializeElement(A): Implemented using the Encode function from SerializeElement(A): Implemented using the Encode function from
Section 4.3.2 of [RFC9496]; Ne = 32. Section 4.3.2 of [RFC9496]; Ne = 32.
DeserializeElement(buf): Implemented using the Decode function DeserializeElement(buf): Implemented using the Decode function
from Section 4.3.1 of [RFC9496]. Additionally, this function from Section 4.3.1 of [RFC9496]. Additionally, this function
validates that the resulting element is not the group identity validates that the resulting element is not the group identity
element. If these checks fail, deserialization returns an element. If these checks fail, deserialization returns an
InputValidationError error. InputValidationError error.
SerializeScalar(s): SerializeScalar(s): Implemented by outputting the little-endian,
Implemented by outputting the little-endian, 32-byte encoding 32-byte encoding of the Scalar value with the top three bits
of the scalar value with the top three bits set to zero; Ns = set to zero; Ns = 32.
32.
DeserializeScalar(buf): DeserializeScalar(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a scalar from a a Scalar from a little-endian, 32-byte string. This function
little-endian, 32-byte string. This function can fail if the can fail if the input does not represent a Scalar in the range
input does not represent a scalar in the range [0, G.Order() - [0, G.Order() - 1]. Note that this means the top three bits of
1]. Note that this means the top three bits of the input MUST the input MUST be zero.
be zero.
Hash: SHA-512; Nh = 64. Hash: SHA-512; Nh = 64.
4.2. OPRF(decaf448, SHAKE-256) 4.2. OPRF(decaf448, SHAKE-256)
This ciphersuite uses decaf448 [RFC9496] for the Group and SHAKE-256 This ciphersuite uses decaf448 [RFC9496] for the Group and SHAKE-256
for the hash function. The value of the ciphersuite identifier is for the hash function. The value of the ciphersuite identifier is
"decaf448-SHAKE256". "decaf448-SHAKE256".
Group: decaf448 [RFC9496] Group: decaf448 [RFC9496]
Order(): Return 2^446 - 13818066809895115352007386748515426880336 Order(): Return 2^446 - 13818066809895115352007386748515426880336
692474882178609894547503885. 692474882178609894547503885.
Identity(): As defined in [RFC9496]. Identity(): As defined in [RFC9496].
Generator(): As defined in [RFC9496]. Generator(): As defined in [RFC9496].
RandomScalar(): RandomScalar(): Implemented by returning a uniformly random
Implemented by returning a uniformly random scalar in the range Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
[0, G.Order() - 1]. Refer to Section 4.7 for implementation for implementation guidance.
guidance.
HashToGroup(): Use hash_to_decaf448 [RFC9380] with DST = HashToGroup(): Use hash_to_decaf448 [RFC9380] with DST =
"HashToGroup-" || contextString and expand_message = "HashToGroup-" || contextString and expand_message =
expand_message_xof using SHAKE-256. expand_message_xof using SHAKE-256.
HashToScalar(): Compute uniform_bytes using expand_message = HashToScalar(): Compute uniform_bytes using expand_message =
expand_message_xof, DST = "HashToScalar-" || contextString, and expand_message_xof, DST = "HashToScalar-" || contextString, and
output length 64, interpret uniform_bytes as a 512-bit integer output length 64, interpret uniform_bytes as a 512-bit integer
in little-endian order, and reduce the integer modulo in little-endian order, and reduce the integer modulo
Group.Order(). Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input ScalarInverse(s): Returns the multiplicative inverse of input
scalar s mod Group.Order(). Scalar s mod Group.Order().
SerializeElement(A): Implemented using the Encode function from SerializeElement(A): Implemented using the Encode function from
Section 5.3.2 of [RFC9496]; Ne = 56. Section 5.3.2 of [RFC9496]; Ne = 56.
DeserializeElement(buf): Implemented using the Decode function DeserializeElement(buf): Implemented using the Decode function
from Section 5.3.1 of [RFC9496]. Additionally, this function from Section 5.3.1 of [RFC9496]. Additionally, this function
validates that the resulting element is not the group identity validates that the resulting element is not the group identity
element. If these checks fail, deserialization returns an element. If these checks fail, deserialization returns an
InputValidationError error. InputValidationError error.
SerializeScalar(s): SerializeScalar(s): Implemented by outputting the little-endian,
Implemented by outputting the little-endian, 56-byte encoding 56-byte encoding of the Scalar value; Ns = 56.
of the scalar value; Ns = 56.
DeserializeScalar(buf): DeserializeScalar(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a scalar from a a Scalar from a little-endian, 56-byte string. This function
little-endian, 56-byte string. This function can fail if the can fail if the input does not represent a Scalar in the range
input does not represent a scalar in the range [0, G.Order() - [0, G.Order() - 1].
1].
Hash: SHAKE-256; Nh = 64. Hash: SHAKE-256; Nh = 64.
4.3. OPRF(P-256, SHA-256) 4.3. OPRF(P-256, SHA-256)
This ciphersuite uses P-256 [NISTCurves] for the Group and SHA-256 This ciphersuite uses P-256 [NISTCurves] for the Group and SHA-256
for the hash function. The value of the ciphersuite identifier is for the hash function. The value of the ciphersuite identifier is
"P256-SHA256". "P256-SHA256".
Group: P-256 (secp256r1) [NISTCurves] Group: P-256 (secp256r1) [NISTCurves]
Order(): Order(): Return 0xffffffff00000000ffffffffffffffffbce6faada7179e8
Return 0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9ca 4f3b9cac2fc632551.
c2fc632551.
Identity(): As defined in [NISTCurves]. Identity(): As defined in [NISTCurves].
Generator(): As defined in [NISTCurves]. Generator(): As defined in [NISTCurves].
RandomScalar(): RandomScalar(): Implemented by returning a uniformly random
Implemented by returning a uniformly random scalar in the range Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
[0, G.Order() - 1]. Refer to Section 4.7 for implementation for implementation guidance.
guidance.
HashToGroup(): Use hash_to_curve with suite P256_XMD:SHA- HashToGroup(): Use hash_to_curve with suite P256_XMD:SHA-
256_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" || 256_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
contextString. contextString.
HashToScalar(): Use hash_to_field from [RFC9380] using L = 48, HashToScalar(): Use hash_to_field from [RFC9380] using L = 48,
expand_message_xmd with SHA-256, DST = "HashToScalar-" || expand_message_xmd with SHA-256, DST = "HashToScalar-" ||
contextString, and a prime modulus equal to Group.Order(). contextString, and a prime modulus equal to Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input ScalarInverse(s): Returns the multiplicative inverse of input
scalar s mod Group.Order(). Scalar s mod Group.Order().
SerializeElement(A): SerializeElement(A): Implemented using the compressed Elliptic-
Implemented using the compressed Elliptic-Curve-Point-to-Octet- Curve-Point-to-Octet-String method according to [SEC1]; Ne =
String method according to [SEC1]; Ne = 33. 33.
DeserializeElement(buf): DeserializeElement(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a 33-byte input string a 33-byte input string to a public key using the compressed
to a public key using the compressed Octet-String-to-Elliptic- Octet-String-to-Elliptic-Curve-Point method according to [SEC1]
Curve-Point method according to [SEC1] and then performing and then performing partial public-key validation, as defined
partial public-key validation, as defined in Section 5.6.2.3.4 in Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
of [KEYAGREEMENT]. This includes checking that the coordinates that the coordinates of the resulting point are in the correct
of the resulting point are in the correct range, that the point range, that the point is on the curve, and that the point is
is on the curve, and that the point is not the group identity not the group identity element. If these checks fail,
element. If these checks fail, deserialization returns an deserialization returns an InputValidationError error.
InputValidationError error.
SerializeScalar(s): SerializeScalar(s): Implemented using the Field-Element-to-Octet-
Implemented using the Field-Element-to-Octet-String conversion String conversion according to [SEC1]; Ns = 32.
according to [SEC1]; Ns = 32.
DeserializeScalar(buf): DeserializeScalar(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a scalar from a a Scalar from a 32-byte string using Octet-String-to-Field-
32-byte string using Octet-String-to-Field-Element from [SEC1]. Element from [SEC1]. This function can fail if the input does
This function can fail if the input does not represent a scalar not represent a Scalar in the range [0, G.Order() - 1].
in the range [0, G.Order() - 1].
Hash: SHA-256; Nh = 32. Hash: SHA-256; Nh = 32.
4.4. OPRF(P-384, SHA-384) 4.4. OPRF(P-384, SHA-384)
This ciphersuite uses P-384 [NISTCurves] for the Group and SHA-384 This ciphersuite uses P-384 [NISTCurves] for the Group and SHA-384
for the hash function. The value of the ciphersuite identifier is for the hash function. The value of the ciphersuite identifier is
"P384-SHA384". "P384-SHA384".
Group: P-384 (secp384r1) [NISTCurves] Group: P-384 (secp384r1) [NISTCurves]
Order(): Order(): Return 0xfffffffffffffffffffffffffffffffffffffffffffffff
Return 0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d fc7634d81f4372ddf581a0db248b0a77aecec196accc52973.
81f4372ddf581a0db248b0a77aecec196accc52973.
Identity(): As defined in [NISTCurves]. Identity(): As defined in [NISTCurves].
Generator(): As defined in [NISTCurves]. Generator(): As defined in [NISTCurves].
RandomScalar(): RandomScalar(): Implemented by returning a uniformly random
Implemented by returning a uniformly random scalar in the range Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
[0, G.Order() - 1]. Refer to Section 4.7 for implementation for implementation guidance.
guidance.
HashToGroup(): Use hash_to_curve with suite P384_XMD:SHA- HashToGroup(): Use hash_to_curve with suite P384_XMD:SHA-
384_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" || 384_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
contextString. contextString.
HashToScalar(): Use hash_to_field from [RFC9380] using L = 72, HashToScalar(): Use hash_to_field from [RFC9380] using L = 72,
expand_message_xmd with SHA-384, DST = "HashToScalar-" || expand_message_xmd with SHA-384, DST = "HashToScalar-" ||
contextString, and a prime modulus equal to Group.Order(). contextString, and a prime modulus equal to Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input ScalarInverse(s): Returns the multiplicative inverse of input
scalar s mod Group.Order(). Scalar s mod Group.Order().
SerializeElement(A): SerializeElement(A): Implemented using the compressed Elliptic-
Implemented using the compressed Elliptic-Curve-Point-to-Octet- Curve-Point-to-Octet-String method according to [SEC1]; Ne =
String method according to [SEC1]; Ne = 49. 49.
DeserializeElement(buf): DeserializeElement(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a 49-byte array to a a 49-byte array to a public key using the compressed Octet-
public key using the compressed Octet-String-to-Elliptic-Curve- String-to-Elliptic-Curve-Point method according to [SEC1] and
Point method according to [SEC1] and then performing partial then performing partial public-key validation, as defined in
public-key validation, as defined in Section 5.6.2.3.4 of Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
[KEYAGREEMENT]. This includes checking that the coordinates of that the coordinates of the resulting point are in the correct
the resulting point are in the correct range, that the point is range, that the point is on the curve, and that the point is
on the curve, and that the point is not the point at infinity. not the point at infinity. Additionally, this function
Additionally, this function validates that the resulting validates that the resulting element is not the group identity
element is not the group identity element. If these checks element. If these checks fail, deserialization returns an
fail, deserialization returns an InputValidationError error. InputValidationError error.
SerializeScalar(s): SerializeScalar(s): Implemented using the Field-Element-to-Octet-
Implemented using the Field-Element-to-Octet-String conversion String conversion according to [SEC1]; Ns = 48.
according to [SEC1]; Ns = 48.
DeserializeScalar(buf): DeserializeScalar(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a scalar from a a Scalar from a 48-byte string using Octet-String-to-Field-
48-byte string using Octet-String-to-Field-Element from [SEC1]. Element from [SEC1]. This function can fail if the input does
This function can fail if the input does not represent a scalar not represent a Scalar in the range [0, G.Order() - 1].
in the range [0, G.Order() - 1].
Hash: SHA-384; Nh = 48. Hash: SHA-384; Nh = 48.
4.5. OPRF(P-521, SHA-512) 4.5. OPRF(P-521, SHA-512)
This ciphersuite uses P-521 [NISTCurves] for the Group and SHA-512 This ciphersuite uses P-521 [NISTCurves] for the Group and SHA-512
for the hash function. The value of the ciphersuite identifier is for the hash function. The value of the ciphersuite identifier is
"P521-SHA512". "P521-SHA512".
Group: P-521 (secp521r1) [NISTCurves] Group: P-521 (secp521r1) [NISTCurves]
Order(): Order(): Return 0x01fffffffffffffffffffffffffffffffffffffffffffff
Return 0x01ffffffffffffffffffffffffffffffffffffffffffffffffffff ffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b889
fffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aeb 9c47aebb6fb71e91386409.
b6fb71e91386409.
Identity(): As defined in [NISTCurves]. Identity(): As defined in [NISTCurves].
Generator(): As defined in [NISTCurves]. Generator(): As defined in [NISTCurves].
RandomScalar(): RandomScalar(): Implemented by returning a uniformly random
Implemented by returning a uniformly random scalar in the range Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
[0, G.Order() - 1]. Refer to Section 4.7 for implementation for implementation guidance.
guidance.
HashToGroup(): Use hash_to_curve with suite P521_XMD:SHA- HashToGroup(): Use hash_to_curve with suite P521_XMD:SHA-
512_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" || 512_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
contextString. contextString.
HashToScalar(): Use hash_to_field from [RFC9380] using L = 98, HashToScalar(): Use hash_to_field from [RFC9380] using L = 98,
expand_message_xmd with SHA-512, DST = "HashToScalar-" || expand_message_xmd with SHA-512, DST = "HashToScalar-" ||
contextString, and a prime modulus equal to Group.Order(). contextString, and a prime modulus equal to Group.Order().
ScalarInverse(s): Returns the multiplicative inverse of input ScalarInverse(s): Returns the multiplicative inverse of input
scalar s mod Group.Order(). Scalar s mod Group.Order().
SerializeElement(A): SerializeElement(A): Implemented using the compressed Elliptic-
Implemented using the compressed Elliptic-Curve-Point-to-Octet- Curve-Point-to-Octet-String method according to [SEC1]; Ne =
String method according to [SEC1]; Ne = 67. 67.
DeserializeElement(buf): DeserializeElement(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a 49-byte input string a 67-byte input string to a public key using the compressed
to a public key using the compressed Octet-String-to-Elliptic- Octet-String-to-Elliptic-Curve-Point method according to [SEC1]
Curve-Point method according to [SEC1] and then performing and then performing partial public-key validation, as defined
partial public-key validation, as defined in Section 5.6.2.3.4 in Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
of [KEYAGREEMENT]. This includes checking that the coordinates that the coordinates of the resulting point are in the correct
of the resulting point are in the correct range, that the point range, that the point is on the curve, and that the point is
is on the curve, and that the point is not the point at not the point at infinity. Additionally, this function
infinity. Additionally, this function validates that the validates that the resulting element is not the group identity
resulting element is not the group identity element. If these element. If these checks fail, deserialization returns an
checks fail, deserialization returns an InputValidationError InputValidationError error.
error.
SerializeScalar(s): SerializeScalar(s): Implemented using the Field-Element-to-Octet-
Implemented using the Field-Element-to-Octet-String conversion String conversion according to [SEC1]; Ns = 66.
according to [SEC1]; Ns = 66.
DeserializeScalar(buf): DeserializeScalar(buf): Implemented by attempting to deserialize
Implemented by attempting to deserialize a scalar from a a Scalar from a 66-byte string using Octet-String-to-Field-
66-byte string using Octet-String-to-Field-Element from [SEC1]. Element from [SEC1]. This function can fail if the input does
This function can fail if the input does not represent a scalar not represent a Scalar in the range [0, G.Order() - 1].
in the range [0, G.Order() - 1].
Hash: SHA-512; Nh = 64. Hash: SHA-512; Nh = 64.
4.6. Future Ciphersuites 4.6. Future Ciphersuites
A critical requirement of implementing the prime-order group using A critical requirement of implementing the prime-order group using
elliptic curves is a method to instantiate the function HashToGroup, elliptic curves is a method to instantiate the function HashToGroup,
which maps inputs to group elements. In the elliptic curve setting, which maps inputs to group elements. In the elliptic curve setting,
this deterministically maps inputs (as byte arrays) to uniformly this deterministically maps inputs (as byte arrays) to uniformly
chosen points on the curve. chosen points on the curve.
skipping to change at line 1532 skipping to change at line 1507
4.7. Random Scalar Generation 4.7. Random Scalar Generation
Two popular algorithms for generating a random integer uniformly Two popular algorithms for generating a random integer uniformly
distributed in the range [0, G.Order() - 1] are described in the distributed in the range [0, G.Order() - 1] are described in the
following subsections. following subsections.
4.7.1. Rejection Sampling 4.7.1. Rejection Sampling
Generate a random byte array with Ns bytes and attempt to map to a Generate a random byte array with Ns bytes and attempt to map to a
scalar by calling DeserializeScalar in constant time. If it Scalar by calling DeserializeScalar in constant time. If it
succeeds, return the result. If it fails, try again with another succeeds, return the result. If it fails, try again with another
random byte array until the procedure succeeds. Failure to implement random byte array until the procedure succeeds. Failure to implement
DeserializeScalar in constant time can leak information about the DeserializeScalar in constant time can leak information about the
underlying corresponding scalar. underlying corresponding Scalar.
As an optimization, if the group order is very close to a power of 2, As an optimization, if the group order is very close to a power of 2,
it is acceptable to omit the rejection test completely. In it is acceptable to omit the rejection test completely. In
particular, if the group order is p and there is an integer b such particular, if the group order is p and there is an integer b such
that |p - 2^b| is less than 2^(b/2), then RandomScalar can simply that |p - 2^b| is less than 2^(b/2), then RandomScalar can simply
return a uniformly random integer of at most b bits. return a uniformly random integer of at most b bits.
4.7.2. Random Number Generation Using Extra Random Bits 4.7.2. Random Number Generation Using Extra Random Bits
Generate a random byte array with L = ceil(((3 * Generate a random byte array with L = ceil(((3 *
skipping to change at line 1572 skipping to change at line 1547
these longer inputs to a fixed-length input that fits within the these longer inputs to a fixed-length input that fits within the
PublicInput or PrivateInput length bounds. Note that some PublicInput or PrivateInput length bounds. Note that some
cryptographic hash functions have input length restrictions cryptographic hash functions have input length restrictions
themselves, but these limits are often large enough to not be a themselves, but these limits are often large enough to not be a
concern in practice. For example, SHA-256 has an input limit of 2^61 concern in practice. For example, SHA-256 has an input limit of 2^61
bytes. bytes.
5.2. External Interface Recommendations 5.2. External Interface Recommendations
In Section 3.3, the interface of the protocol functions allows that In Section 3.3, the interface of the protocol functions allows that
some inputs (and outputs) to be group elements and scalars. However, some inputs (and outputs) to be group Element and Scalar values.
implementations can instead operate over group elements and scalars However, implementations can instead operate over Element and Scalar
internally and only expose interfaces that operate with an values internally and only expose interfaces that operate with an
application-specific format of messages. application-specific format of messages.
5.3. Error Considerations 5.3. Error Considerations
Some OPRF variants specified in this document have fallible Some OPRF variants specified in this document have fallible
operations. For example, Finalize and BlindEvaluate can fail if any operations. For example, Finalize and BlindEvaluate can fail if any
element received from the peer fails input validation. The explicit element received from the peer fails input validation. The explicit
errors generated throughout this specification, along with the errors generated throughout this specification, along with the
conditions that lead to each error, are as follows: conditions that lead to each error, are as follows:
VerifyError: Verifiable OPRF proof verification failed (Sections VerifyError: Verifiable OPRF proof verification failed (Sections
3.3.2 and 3.3.3). 3.3.2 and 3.3.3).
DeserializeError: Group element or scalar deserialization failure DeserializeError: Group Element or Scalar deserialization failure
(Sections 2.1 and 3.3). (Sections 2.1 and 3.3).
InputValidationError: Validation of byte array inputs failed InputValidationError: Validation of byte array inputs failed
(Section 4). (Section 4).
There are other explicit errors generated in this specification; There are other explicit errors generated in this specification;
however, they occur with negligible probability in practice. We note however, they occur with negligible probability in practice. We note
them here for completeness. them here for completeness.
InvalidInputError: OPRF Blind input produces an invalid output InvalidInputError: OPRF Blind input produces an invalid output
element (Sections 3.3.1 and 3.3.3). element (Sections 3.3.1 and 3.3.3).
InverseError: InverseError: A tweaked private key is invalid, i.e., has no
A tweaked private key is invalid, i.e., has no multiplicative multiplicative inverse (Sections 2.1 and 3.3).
inverse (Sections 2.1 and 3.3).
In general, the errors in this document are meant as a guide to 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 implementors. They are not an exhaustive list of all the errors an
implementation might emit. For example, implementations might run implementation might emit. For example, implementations might run
out of memory and return a corresponding error. out of memory and return a corresponding error.
5.4. POPRF Public Input 5.4. POPRF Public Input
Functionally, the VOPRF and POPRF variants differ in that the POPRF Functionally, the VOPRF and POPRF variants differ in that the POPRF
variant admits public input, whereas the VOPRF variant does not. variant admits public input, whereas the VOPRF variant does not.
skipping to change at line 1652 skipping to change at line 1626
from the implementation of the protocol variants in this document. from the implementation of the protocol variants in this document.
Note that the syntax of the POPRF variant is different from that of Note that the syntax of the POPRF variant is different from that of
the OPRF and VOPRF variants since it admits an additional public the OPRF and VOPRF variants since it admits an additional public
input, but the same security considerations apply. input, but the same security considerations apply.
7.1. Security Properties 7.1. Security Properties
The security properties of an OPRF protocol with functionality y = The security properties of an OPRF protocol with functionality y =
F(k, x) include those of a standard PRF. Specifically: F(k, x) include those of a standard PRF. Specifically:
Pseudorandomness: Pseudorandomness: For a random sampling of k, F is pseudorandom if
For a random sampling of k, F is pseudorandom if the output y = the output y = F(k, x) on any input x is indistinguishable from
F(k, x) on any input x is indistinguishable from uniformly uniformly sampling any element in F's range.
sampling any element in F's range.
In other words, consider an adversary that picks inputs x from the In other words, consider an adversary that picks inputs x from the
domain of F and evaluates F on (k, x) (without knowledge of randomly domain of F and evaluates F on (k, x) (without knowledge of randomly
sampled k). Then, the output distribution F(k, x) is sampled k). Then, the output distribution F(k, x) is
indistinguishable from the output distribution of a randomly chosen indistinguishable from the output distribution of a randomly chosen
function with the same domain and range. function with the same domain and range.
A consequence of showing that a function is pseudorandom is that it A consequence of showing that a function is pseudorandom is that it
is necessarily nonmalleable (i.e., we cannot compute a new evaluation is necessarily nonmalleable (i.e., we cannot compute a new evaluation
of F from an existing evaluation). A genuinely random function will of F from an existing evaluation). A genuinely random function will
be nonmalleable with high probability, so a pseudorandom function be nonmalleable with high probability, so a pseudorandom function
must be nonmalleable to maintain indistinguishability. must be nonmalleable to maintain indistinguishability.
Unconditional input secrecy: Unconditional input secrecy: The server does not learn anything
The server does not learn anything about the client input x, even about the client input x, even with unbounded computation.
with unbounded computation.
In other words, an attacker with infinite computing power cannot In other words, an attacker with infinite computing power cannot
recover any information about the client's private input x from an recover any information about the client's private input x from an
invocation of the protocol. invocation of the protocol.
Essentially, input secrecy is the property that, even if the server Essentially, input secrecy is the property that, even if the server
learns the client's private input x at some point in the future, the learns the client's private input x at some point in the future, the
server cannot link any particular PRF evaluation to x. This property server cannot link any particular PRF evaluation to x. This property
is also known as unlinkability [DGSTV18]. is also known as unlinkability [DGSTV18].
Beyond client input secrecy, in the OPRF protocol, the server learns Beyond client input secrecy, in the OPRF protocol, the server learns
nothing about the output y of the function, nor does the client learn nothing about the output y of the function, nor does the client learn
anything about the server's private key k. anything about the server's private key k.
For the VOPRF and POPRF protocol variants, there is an additional For the VOPRF and POPRF protocol variants, there is an additional
security property: security property:
Verifiable: Verifiable: The client must only complete execution of the protocol
The client must only complete execution of the protocol if it can if it can successfully assert that the output it computes is
successfully assert that the output it computes is correct. This correct. This is taken with respect to the private key held by
is taken with respect to the private key held by the server. the server.
Any VOPRF or POPRF that satisfies the 'verifiable' security property Any VOPRF or POPRF that satisfies the 'verifiable' security property
is known as 'verifiable'. In practice, the notion of verifiability is known as 'verifiable'. In practice, the notion of verifiability
requires that the server commits to the key before the actual requires that the server commits to the key before the actual
protocol execution takes place. Then, the client verifies that the protocol execution takes place. Then, the client verifies that the
server has used the key in the protocol using this commitment. In server has used the key in the protocol using this commitment. In
the following, we may also refer to this commitment as a public key. the following, we may also refer to this commitment as a public key.
Finally, the POPRF variant also has the following security property: Finally, the POPRF variant also has the following security property:
Partial obliviousness: Partial obliviousness: The client and server must be able to perform
The client and server must be able to perform the PRF on the the PRF on the client's private and public input. Both the client
client's private and public input. Both the client and server and server know the public input, but similar to the OPRF and
know the public input, but similar to the OPRF and VOPRF VOPRF protocols, the server learns nothing about the client's
protocols, the server learns nothing about the client's private private input or the output of the function, and the client learns
input or the output of the function, and the client learns nothing nothing about the server's private key.
about the server's private key.
This property becomes useful when dealing with key management This property becomes useful when dealing with key management
operations, such as the rotation of the server's keys. Note that operations, such as the rotation of the server's keys. Note that
partial obliviousness only applies to the POPRF variant because partial obliviousness only applies to the POPRF variant because
neither the OPRF nor VOPRF variants accept public input to the neither the OPRF nor VOPRF variants accept public input to the
protocol. protocol.
Since the POPRF variant has a different syntax than the OPRF and Since the POPRF variant has a different syntax than the OPRF and
VOPRF variants, i.e., y = F(k, x, info), the pseudorandomness VOPRF variants, i.e., y = F(k, x, info), the pseudorandomness
property is generalized: property is generalized:
Pseudorandomness: Pseudorandomness: For a random sampling of k, F is pseudorandom if
For a random sampling of k, F is pseudorandom if the output y = the output y = F(k, x, info) on any input pairs (x, info) is
F(k, x, info) on any input pairs (x, info) is indistinguishable indistinguishable from uniformly sampling any element in F's
from uniformly sampling any element in F's range. range.
7.2. Security Assumptions 7.2. Security Assumptions
Below, we discuss the cryptographic security of each protocol variant Below, we discuss the cryptographic security of each protocol variant
from Section 3, relative to the necessary cryptographic assumptions from Section 3, relative to the necessary cryptographic assumptions
that need to be made. that need to be made.
7.2.1. OPRF and VOPRF Assumptions 7.2.1. OPRF and VOPRF Assumptions
The OPRF and VOPRF protocol variants in this document are based on The OPRF and VOPRF protocol variants in this document are based on
skipping to change at line 1902 skipping to change at line 1873
[JKKX16] Jarecki, S., Kiayias, A., Krawczyk, H., and J. Xu, [JKKX16] Jarecki, S., Kiayias, A., Krawczyk, H., and J. Xu,
"Highly-Efficient and Composable Password-Protected Secret "Highly-Efficient and Composable Password-Protected Secret
Sharing (Or: How to Protect Your Bitcoin Wallet Online)", Sharing (Or: How to Protect Your Bitcoin Wallet Online)",
2016 IEEE European Symposium on Security and Privacy 2016 IEEE European Symposium on Security and Privacy
(EuroS&P), DOI 10.1109/eurosp.2016.30, March 2016, (EuroS&P), DOI 10.1109/eurosp.2016.30, March 2016,
<https://doi.org/10.1109/eurosp.2016.30>. <https://doi.org/10.1109/eurosp.2016.30>.
[NISTCurves] [NISTCurves]
National Institute of Standards and Technology (NIST), National Institute of Standards and Technology (NIST),
"Digital Signature Standard (DSS)", FIPS PUB 186-4, "Digital Signature Standard (DSS)", FIPS PUB 186-5,
DOI 10.6028/nist.fips.186-4, July 2013, DOI 10.6028/NIST.FIPS.186-5, February 2023,
<https://doi.org/10.6028/nist.fips.186-4>. <https://doi.org/10.6028/NIST.FIPS.186-5>.
[OPAQUE] Bourdrez, D., Krawczyk, H., Lewi, K., and C. A. Wood, "The [OPAQUE] Bourdrez, D., Krawczyk, H., Lewi, K., and C. A. Wood, "The
OPAQUE Asymmetric PAKE Protocol", Work in Progress, OPAQUE Asymmetric PAKE Protocol", Work in Progress,
Internet-Draft, draft-irtf-cfrg-opaque-11, 8 June 2023, Internet-Draft, draft-irtf-cfrg-opaque-12, 5 October 2023,
<https://datatracker.ietf.org/doc/html/draft-irtf-cfrg- <https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-
opaque-11>. opaque-12>.
[PRIVACY-PASS] [PRIVACY-PASS]
Celi, S., Davidson, A., Valdez, S., and C. A. Wood, Celi, S., Davidson, A., Valdez, S., and C. A. Wood,
"Privacy Pass Issuance Protocol", Work in Progress, "Privacy Pass Issuance Protocol", Work in Progress,
Internet-Draft, draft-ietf-privacypass-protocol-16, 3 Internet-Draft, draft-ietf-privacypass-protocol-16, 3
October 2023, <https://datatracker.ietf.org/doc/html/ October 2023, <https://datatracker.ietf.org/doc/html/
draft-ietf-privacypass-protocol-16>. draft-ietf-privacypass-protocol-16>.
[PrivacyPass] [PrivacyPass]
"Privacy Pass", commit 085380a, March 2018, "Privacy Pass", commit 085380a, March 2018,
skipping to change at line 1957 skipping to change at line 1928
This section includes test vectors for the protocol variants This section includes test vectors for the protocol variants
specified in this document. For each ciphersuite specified in specified in this document. For each ciphersuite specified in
Section 4, there is a set of test vectors for the protocol when Section 4, there is a set of test vectors for the protocol when
running the OPRF, VOPRF, and POPRF modes. Each test vector lists the running the OPRF, VOPRF, and POPRF modes. Each test vector lists the
batch size for the evaluation. Each test vector value is encoded as batch size for the evaluation. Each test vector value is encoded as
a hexadecimal byte string. The fields of each test vector are a hexadecimal byte string. The fields of each test vector are
described below. described below.
"Input": The private client input, an opaque byte string. "Input": The private client input, an opaque byte string.
"Info": "Info": The public info, an opaque byte string. Only present for
The public info, an opaque byte string. Only present for POPRF POPRF test vectors.
test vectors.
"Blind": The blind value output by Blind(), a serialized scalar of "Blind": The blind value output by Blind(), a serialized Scalar of
Ns bytes long. Ns bytes long.
"BlindedElement": The blinded value output by Blind(), a serialized "BlindedElement": The blinded value output by Blind(), a serialized
element of Ne bytes long. Element of Ne bytes long.
"EvaluatedElement": The evaluated element output by BlindEvaluate(), "EvaluatedElement": The evaluated element output by BlindEvaluate(),
a serialized element of Ne bytes long. a serialized Element of Ne bytes long.
"Proof": The serialized Proof output from GenerateProof() composed "Proof": The serialized Proof output from GenerateProof() composed
of two serialized scalar values, each Ns bytes long. Only present of two serialized Scalar values, each Ns bytes long. Only present
for VOPRF and POPRF test vectors. for VOPRF and POPRF test vectors.
"ProofRandomScalar": The random scalar r computed in "ProofRandomScalar": The random Scalar r computed in
GenerateProof(), a serialized scalar of Ns bytes long. Only GenerateProof(), a serialized Scalar of Ns bytes long. Only
present for VOPRF and POPRF test vectors. present for VOPRF and POPRF test vectors.
"Output": The protocol output, an opaque byte string of Nh bytes "Output": The protocol output, an opaque byte string of Nh bytes
long. long.
Test vectors with batch size B > 1 have inputs separated by a comma Test vectors with batch size B > 1 have inputs separated by a comma
",". Applicable test vectors will have B different values for the ",". Applicable test vectors will have B different values for the
"Input", "Blind", "BlindedElement", "EvaluationElement", and "Output" "Input", "Blind", "BlindedElement", "EvaluationElement", and "Output"
fields. fields.
The server key material, pkSm and skSm, are listed under the mode for The server key material, pkSm and skSm, are listed under the mode for
each ciphersuite. Both pkSm and skSm are the serialized values of each ciphersuite. Both pkSm and skSm are the serialized values of
pkS and skS, respectively, as used in the protocol. Each key pair is pkS and skS, respectively, as used in the protocol. Each key pair is
derived from a seed Seed and info string KeyInfo, which are listed as derived from a seed, denoted Seed, and info string, denoted KeyInfo,
well, using the DeriveKeyPair function from Section 3.2. which are listed as well, using the DeriveKeyPair function from
Section 3.2.
A.1. ristretto255-SHA512 A.1. ristretto255-SHA512
A.1.1. OPRF Mode A.1.1. OPRF Mode
Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a Seed = a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a3a
3a3 3a3
KeyInfo = 74657374206b6579 KeyInfo = 74657374206b6579
skSm = 5ebcea5ee37023ccb9fc2d2019f9d7737be85591ae8652ffa9ef0f4d37063 skSm = 5ebcea5ee37023ccb9fc2d2019f9d7737be85591ae8652ffa9ef0f4d37063
b0e b0e
 End of changes. 71 change blocks. 
224 lines changed or deleted 195 lines changed or added

This html diff was produced by rfcdiff 1.48.