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