rfc9497.original   rfc9497.txt 
Network Working Group A. Davidson Internet Research Task Force (IRTF) A. Davidson
Internet-Draft Brave Software Request for Comments: 9497 Brave Software
Intended status: Informational A. Faz-Hernandez Category: Informational A. Faz-Hernandez
Expires: 25 August 2023 N. Sullivan ISSN: 2070-1721 N. Sullivan
C. A. Wood C. A. Wood
Cloudflare, Inc. Cloudflare, Inc.
21 February 2023 December 2023
Oblivious Pseudorandom Functions (OPRFs) using Prime-Order Groups Oblivious Pseudorandom Functions (OPRFs) Using Prime-Order Groups
draft-irtf-cfrg-voprf-21
Abstract Abstract
An Oblivious Pseudorandom Function (OPRF) is a two-party protocol An Oblivious Pseudorandom Function (OPRF) is a two-party protocol
between client and server for computing the output of a Pseudorandom between a client and a server for computing the output of a
Function (PRF). The server provides the PRF private key, and the Pseudorandom Function (PRF). The server provides the PRF private
client provides the PRF input. At the end of the protocol, the key, and the client provides the PRF input. At the end of the
client learns the PRF output without learning anything about the PRF protocol, the client learns the PRF output without learning anything
private key, and the server learns neither the PRF input nor output. about the PRF private key, and the server learns neither the PRF
An OPRF can also satisfy a notion of 'verifiability', called a VOPRF. input nor output. An OPRF can also satisfy a notion of
A VOPRF ensures clients can verify that the server used a specific 'verifiability', called a VOPRF. A VOPRF ensures clients can verify
private key during the execution of the protocol. A VOPRF can also that the server used a specific private key during the execution of
be partially-oblivious, called a POPRF. A POPRF allows clients and the protocol. A VOPRF can also be partially oblivious, called a
servers to provide public input to the PRF computation. This POPRF. A POPRF allows clients and servers to provide public input to
document specifies an OPRF, VOPRF, and POPRF instantiated within the PRF computation. This document specifies an OPRF, VOPRF, and
standard prime-order groups, including elliptic curves. This POPRF instantiated within standard prime-order groups, including
document is a product of the Crypto Forum Research Group (CFRG) in elliptic curves. This document is a product of the Crypto Forum
the IRTF. Research Group (CFRG) in the IRTF.
Discussion Venues
This note is to be removed before publishing as an RFC.
Source for this draft and an issue tracker can be found at
https://github.com/cfrg/draft-irtf-cfrg-voprf.
Status of This Memo Status of This Memo
This Internet-Draft is submitted in full conformance with the This document is not an Internet Standards Track specification; it is
provisions of BCP 78 and BCP 79. published for informational purposes.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months This document is a product of the Internet Research Task Force
and may be updated, replaced, or obsoleted by other documents at any (IRTF). The IRTF publishes the results of Internet-related research
time. It is inappropriate to use Internet-Drafts as reference and development activities. These results might not be suitable for
material or to cite them other than as "work in progress." deployment. This RFC represents the consensus of the Crypto Forum
Research Group of the Internet Research Task Force (IRTF). Documents
approved for publication by the IRSG are not candidates for any level
of Internet Standard; see Section 2 of RFC 7841.
This Internet-Draft will expire on 25 August 2023. Information about the current status of this document, any errata,
and how to provide feedback on it may be obtained at
https://www.rfc-editor.org/info/rfc9497.
Copyright Notice Copyright Notice
Copyright (c) 2023 IETF Trust and the persons identified as the Copyright (c) 2023 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/ Provisions Relating to IETF Documents
license-info) in effect on the date of publication of this document. (https://trustee.ietf.org/license-info) in effect on the date of
Please review these documents carefully, as they describe your rights publication of this document. Please review these documents
and restrictions with respect to this document. Code Components carefully, as they describe your rights and restrictions with respect
extracted from this document must include Revised BSD License text as to this document.
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4 1. Introduction
1.1. Change log . . . . . . . . . . . . . . . . . . . . . . . 4 1.1. Requirements Language
1.2. Requirements . . . . . . . . . . . . . . . . . . . . . . 8 1.2. Notation and Terminology
1.3. Notation and Terminology . . . . . . . . . . . . . . . . 8 2. Preliminaries
2. Preliminaries . . . . . . . . . . . . . . . . . . . . . . . . 9 2.1. Prime-Order Group
2.1. Prime-Order Group . . . . . . . . . . . . . . . . . . . . 10 2.2. Discrete Logarithm Equivalence Proofs
2.2. Discrete Logarithm Equivalence Proofs . . . . . . . . . . 11 2.2.1. Proof Generation
2.2.1. Proof Generation . . . . . . . . . . . . . . . . . . 12 2.2.2. Proof Verification
2.2.2. Proof Verification . . . . . . . . . . . . . . . . . 15 3. Protocol
3. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 18 3.1. Configuration
3.1. Configuration . . . . . . . . . . . . . . . . . . . . . . 20 3.2. Key Generation and Context Setup
3.2. Key Generation and Context Setup . . . . . . . . . . . . 20 3.2.1. Deterministic Key Generation
3.2.1. Deterministic Key Generation . . . . . . . . . . . . 22 3.3. Online Protocol
3.3. Online Protocol . . . . . . . . . . . . . . . . . . . . . 23 3.3.1. OPRF Protocol
3.3.1. OPRF Protocol . . . . . . . . . . . . . . . . . . . . 24 3.3.2. VOPRF Protocol
3.3.2. VOPRF Protocol . . . . . . . . . . . . . . . . . . . 26 3.3.3. POPRF Protocol
3.3.3. POPRF Protocol . . . . . . . . . . . . . . . . . . . 29 4. Ciphersuites
4. Ciphersuites . . . . . . . . . . . . . . . . . . . . . . . . 33 4.1. OPRF(ristretto255, SHA-512)
4.1. OPRF(ristretto255, SHA-512) . . . . . . . . . . . . . . . 33 4.2. OPRF(decaf448, SHAKE-256)
4.2. OPRF(decaf448, SHAKE-256) . . . . . . . . . . . . . . . . 34 4.3. OPRF(P-256, SHA-256)
4.3. OPRF(P-256, SHA-256) . . . . . . . . . . . . . . . . . . 36 4.4. OPRF(P-384, SHA-384)
4.4. OPRF(P-384, SHA-384) . . . . . . . . . . . . . . . . . . 37 4.5. OPRF(P-521, SHA-512)
4.5. OPRF(P-521, SHA-512) . . . . . . . . . . . . . . . . . . 38 4.6. Future Ciphersuites
4.6. Future Ciphersuites . . . . . . . . . . . . . . . . . . . 39 4.7. Random Scalar Generation
4.7. Random Scalar Generation . . . . . . . . . . . . . . . . 40 4.7.1. Rejection Sampling
4.7.1. Rejection Sampling . . . . . . . . . . . . . . . . . 40 4.7.2. Random Number Generation Using Extra Random Bits
4.7.2. Random Number Generation Using Extra Random Bits . . 40 5. Application Considerations
5. Application Considerations . . . . . . . . . . . . . . . . . 40 5.1. Input Limits
5.1. Input Limits . . . . . . . . . . . . . . . . . . . . . . 41 5.2. External Interface Recommendations
5.2. External Interface Recommendations . . . . . . . . . . . 41 5.3. Error Considerations
5.3. Error Considerations . . . . . . . . . . . . . . . . . . 41 5.4. POPRF Public Input
5.4. POPRF Public Input . . . . . . . . . . . . . . . . . . . 42 6. IANA Considerations
6. IANA considerations . . . . . . . . . . . . . . . . . . . . . 42 7. Security Considerations
7. Security Considerations . . . . . . . . . . . . . . . . . . . 42 7.1. Security Properties
7.1. Security Properties . . . . . . . . . . . . . . . . . . . 42 7.2. Security Assumptions
7.2. Security Assumptions . . . . . . . . . . . . . . . . . . 44 7.2.1. OPRF and VOPRF Assumptions
7.2.1. OPRF and VOPRF Assumptions . . . . . . . . . . . . . 44 7.2.2. POPRF Assumptions
7.2.2. POPRF Assumptions . . . . . . . . . . . . . . . . . . 45 7.2.3. Static Diffie-Hellman Attack and Security Limits
7.2.3. Static Diffie Hellman Attack and Security Limits . . 45 7.3. Domain Separation
7.3. Domain Separation . . . . . . . . . . . . . . . . . . . . 46 7.4. Timing Leaks
7.4. Timing Leaks . . . . . . . . . . . . . . . . . . . . . . 46 8. References
8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 46 8.1. Normative References
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 46 8.2. Informative References
9.1. Normative References . . . . . . . . . . . . . . . . . . 46 Appendix A. Test Vectors
9.2. Informative References . . . . . . . . . . . . . . . . . 47 A.1. ristretto255-SHA512
Appendix A. Test Vectors . . . . . . . . . . . . . . . . . . . . 49 A.1.1. OPRF Mode
A.1. ristretto255-SHA512 . . . . . . . . . . . . . . . . . . . 50 A.1.2. VOPRF Mode
A.1.1. OPRF Mode . . . . . . . . . . . . . . . . . . . . . . 50 A.1.3. POPRF Mode
A.1.2. VOPRF Mode . . . . . . . . . . . . . . . . . . . . . 51 A.2. decaf448-SHAKE256
A.1.3. POPRF Mode . . . . . . . . . . . . . . . . . . . . . 53 A.2.1. OPRF Mode
A.2. decaf448-SHAKE256 . . . . . . . . . . . . . . . . . . . . 54 A.2.2. VOPRF Mode
A.2.1. OPRF Mode . . . . . . . . . . . . . . . . . . . . . . 54 A.2.3. POPRF Mode
A.2.2. VOPRF Mode . . . . . . . . . . . . . . . . . . . . . 55 A.3. P256-SHA256
A.2.3. POPRF Mode . . . . . . . . . . . . . . . . . . . . . 57 A.3.1. OPRF Mode
A.3. P256-SHA256 . . . . . . . . . . . . . . . . . . . . . . . 59 A.3.2. VOPRF Mode
A.3.1. OPRF Mode . . . . . . . . . . . . . . . . . . . . . . 59 A.3.3. POPRF Mode
A.3.2. VOPRF Mode . . . . . . . . . . . . . . . . . . . . . 60 A.4. P384-SHA384
A.3.3. POPRF Mode . . . . . . . . . . . . . . . . . . . . . 61 A.4.1. OPRF Mode
A.4. P384-SHA384 . . . . . . . . . . . . . . . . . . . . . . . 63 A.4.2. VOPRF Mode
A.4.1. OPRF Mode . . . . . . . . . . . . . . . . . . . . . . 63 A.4.3. POPRF Mode
A.4.2. VOPRF Mode . . . . . . . . . . . . . . . . . . . . . 64 A.5. P521-SHA512
A.4.3. POPRF Mode . . . . . . . . . . . . . . . . . . . . . 65 A.5.1. OPRF Mode
A.5. P521-SHA512 . . . . . . . . . . . . . . . . . . . . . . . 67 A.5.2. VOPRF Mode
A.5.1. OPRF Mode . . . . . . . . . . . . . . . . . . . . . . 67 A.5.3. POPRF Mode
A.5.2. VOPRF Mode . . . . . . . . . . . . . . . . . . . . . 68 Acknowledgements
A.5.3. POPRF Mode . . . . . . . . . . . . . . . . . . . . . 70 Authors' Addresses
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 72
1. Introduction 1. Introduction
A Pseudorandom Function (PRF) F(k, x) is an efficiently computable A Pseudorandom Function (PRF) F(k, x) is an efficiently computable
function taking a private key k and a value x as input. This function taking a private key k and a value x as input. This
function is pseudorandom if the keyed function K(_) = F(k, _) is function is pseudorandom if the keyed function K(_) = F(k, _) is
indistinguishable from a randomly sampled function acting on the same indistinguishable from a randomly sampled function acting on the same
domain and range as K(). An Oblivious PRF (OPRF) is a two-party domain and range as K(). An Oblivious PRF (OPRF) is a two-party
protocol between a server and a client, where the server holds a PRF protocol between a server and a client, wherein the server holds a
key k and the client holds some input x. The protocol allows both PRF key k and the client holds some input x. The protocol allows
parties to cooperate in computing F(k, x) such that the client learns both parties to cooperate in computing F(k, x), such that the client
F(k, x) without learning anything about k; and the server does not learns F(k, x) without learning anything about k and the server does
learn anything about x or F(k, x). A Verifiable OPRF (VOPRF) is an not learn anything about x or F(k, x). A Verifiable OPRF (VOPRF) is
OPRF wherein the server also proves to the client that F(k, x) was an OPRF, wherein the server also proves to the client that F(k, x)
produced by the key k corresponding to the server's public key, which was produced by the key k corresponding to the server's public key,
the client knows. A Partially-Oblivious PRF (POPRF) is a variant of which the client knows. A Partially Oblivious PRF (POPRF) is a
a VOPRF wherein client and server interact in computing F(k, x, y), variant of a VOPRF, where the client and server interact in computing
for some PRF F with server-provided key k, client-provided input x, F(k, x, y), for some PRF F with server-provided key k, client-
and public input y, and client receives proof that F(k, x, y) was provided input x, and public input y, and the client receives proof
computed using k corresponding to the public key that the client that F(k, x, y) was computed using k corresponding to the public key
knows. A POPRF with fixed input y is functionally equivalent to a that the client knows. A POPRF with fixed input y is functionally
VOPRF. equivalent to a VOPRF.
OPRFs have a variety of applications, including: password-protected OPRFs have a variety of applications, including password-protected
secret sharing schemes [JKKX16], privacy-preserving password stores secret sharing schemes [JKKX16], privacy-preserving password stores
[SJKS17], and password-authenticated key exchange or PAKE [OPAQUE]. [SJKS17], and password-authenticated key exchange (PAKE) [OPAQUE].
Verifiable OPRFs are necessary in some applications such as Privacy Verifiable OPRFs are necessary in some applications, such as Privacy
Pass [PRIVACYPASS]. Verifiable OPRFs have also been used for Pass [PRIVACY-PASS]. Verifiable OPRFs have also been used for
password-protected secret sharing schemes such as that of [JKK14]. password-protected secret sharing schemes, such as that of [JKK14].
This document specifies OPRF, VOPRF, and POPRF protocols built upon This document specifies OPRF, VOPRF, and POPRF protocols built upon
prime-order groups. The document describes each protocol variant, prime-order groups. The document describes each protocol variant,
along with application considerations, and their security properties. along with application considerations, and their security properties.
This document represents the consensus of the Crypto Forum Research This document represents the consensus of the Crypto Forum Research
Group (CFRG). It is not an IETF product and is not a standard. Group (CFRG). It is not an IETF product and is not a standard.
1.1. Change log 1.1. Requirements Language
draft-21 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-21):
* Apply more IRSG review comments.
draft-20 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-20):
* Address IRSG comments.
draft-19 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-19):
* Fix error.
draft-18 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-18):
* Apply editorial suggestions from CFRG chair review.
draft-17 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-17):
* Change how suites are identified and finalize test vectors.
* Apply editorial suggestions from IRTF chair review.
draft-16 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-16):
* Apply editorial suggestions from document shepherd.
draft-15 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-15):
* Apply editorial suggestions from CFRG RGLC.
draft-14 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-14):
* Correct current state of formal analysis for the VOPRF protocol
variant.
draft-13 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-13):
* Editorial improvements based on Crypto Panel Review.
draft-12 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-12):
* Small editorial fixes
draft-11 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-11):
* Change Evaluate to BlindEvaluate, and add Evaluate for PRF
evaluation
draft-10 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-10):
* Editorial improvements
draft-09 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-09):
* Split syntax for OPRF, VOPRF, and POPRF functionalities.
* Make Blind function fallible for invalid private and public
inputs.
* Specify key generation.
* Remove serialization steps from core protocol functions.
* Refactor protocol presentation for clarity.
* Simplify security considerations.
* Update application interface considerations.
* Update test vectors.
draft-08 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-08):
* Adopt partially-oblivious PRF construction from [TCRSTW21].
* Update P-384 suite to use SHA-384 instead of SHA-512.
* Update test vectors.
* Apply various editorial changes.
draft-07 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-07):
* Bind blinding mechanism to mode (additive for verifiable mode and
multiplicative for base mode).
* Add explicit errors for deserialization.
* Document explicit errors and API considerations.
* Adopt SHAKE-256 for decaf448 ciphersuite.
* Normalize HashToScalar functionality for all ciphersuites.
* Refactor and generalize DLEQ proof functionality and domain
separation tags for use in other protocols.
* Update test vectors.
* Apply various editorial changes.
draft-06 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-06):
* Specify of group element and scalar serialization.
* Remove info parameter from the protocol API and update domain
separation guidance.
* Fold Unblind function into Finalize.
* Optimize ComputeComposites for servers (using knowledge of the
private key).
* Specify deterministic key generation method.
* Update test vectors.
* Apply various editorial changes.
draft-05 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-05):
* Move to ristretto255 and decaf448 ciphersuites.
* Clean up ciphersuite definitions.
* Pin domain separation tag construction to draft version.
* Move key generation outside of context construction functions.
* Editorial changes.
draft-04 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-04):
* Introduce Client and Server contexts for controlling verifiability
and required functionality.
* Condense API.
* Remove batching from standard functionality (included as an
extension)
* Add Curve25519 and P-256 ciphersuites for applications that
prevent strong-DH oracle attacks.
* Provide explicit prime-order group API and instantiation advice
for each ciphersuite.
* Proof-of-concept implementation in sage.
* Remove privacy considerations advice as this depends on
applications.
draft-03 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-03):
* Certify public key during VerifiableFinalize.
* Remove protocol integration advice.
* Add text discussing how to perform domain separation.
* Drop OPRF_/VOPRF_ prefix from algorithm names.
* Make prime-order group assumption explicit.
* Changes to algorithms accepting batched inputs.
* Changes to construction of batched DLEQ proofs.
* Updated ciphersuites to be consistent with hash-to-curve and added
OPRF specific ciphersuites.
draft-02 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-02):
* Added section discussing cryptographic security and static DH
oracles.
* Updated batched proof algorithms.
draft-01 (https://tools.ietf.org/html/draft-irtf-cfrg-voprf-01):
* Updated ciphersuites to be in line with
https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-04.
* Made some necessary modular reductions more explicit.
1.2. Requirements
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in "OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here. capitals, as shown here.
1.3. Notation and Terminology 1.2. Notation and Terminology
The following functions and notation are used throughout the The following functions and notation are used throughout the
document. document.
* For any object x, we write len(x) to denote its length in bytes. * For any object x, we write len(x) to denote its length in bytes.
* For two byte arrays x and y, write x || y to denote their * For two-byte arrays x and y, write x || y to denote their
concatenation. concatenation.
* I2OSP(x, xLen): Converts a non-negative integer x into a byte * I2OSP(x, xLen) converts a non-negative integer x into a byte array
array of specified length xLen as described in [RFC8017]. Note of specified length xLen, as described in [RFC8017]. Note that
that this function returns a byte array in big-endian byte order. this function returns a byte array in big-endian byte order.
* The notation T U[N] refers to an array called U containing N items * The notation T U[N] refers to an array called U, containing N
of type T. The type opaque means one single byte of uninterpreted items of type T. The type opaque means one single byte of
data. Items of the array are zero-indexed and referred as U[j] uninterpreted data. Items of the array are zero-indexed and
such that 0 <= j < N. referred to as U[j], such that 0 <= j < N.
All algorithms and procedures described in this document are laid out All algorithms and procedures described in this document are laid out
in a Python-like pseudocode. Each function takes a set of inputs and in a Python-like pseudocode. Each function takes a set of inputs and
parameters and produces a set of output values. Parameters become parameters and produces a set of output values. Parameters become
constant values once the protocol variant and the ciphersuite are constant values once the protocol variant and the ciphersuite are
fixed. fixed.
The PrivateInput data type refers to inputs that are known only to The PrivateInput data type refers to inputs that are known only to
the client in the protocol, whereas the PublicInput data type refers the client in the protocol, whereas the PublicInput data type refers
to inputs that are known to both client and server in the protocol. to inputs that are known to both the client and server in the
Both PrivateInput and PublicInput are opaque byte strings of protocol. Both PrivateInput and PublicInput are opaque byte strings
arbitrary length no larger than 2^16 - 1 bytes. This length of arbitrary length no larger than 2^16 - 1 bytes. This length
restriction exists because PublicInput and PrivateInput values are restriction exists because PublicInput and PrivateInput values are
length-prefixed with two bytes before use throughout the protocol. length-prefixed with two bytes before use throughout the protocol.
String values such as "DeriveKeyPair", "Seed-", and "Finalize" are String values, such as "DeriveKeyPair", "Seed-", and "Finalize", are
ASCII string literals. ASCII string literals.
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: Protocol initiator. Learns pseudorandom function Client: Protocol initiator. Learns PRF evaluation as the output of
evaluation as the output of the protocol. the protocol.
* Server: Computes the pseudorandom function using a private key. Server: Computes the PRF using a private key. Learns nothing about
Learns nothing about the client's input or output. the 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 Hash: A cryptographic hash function whose output length is Nh bytes.
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. (There may, however, exist different representations of the order of the group. (However, different representations of the group
group for a single p. Section 4 lists specific groups which indicate for a single p may exist. Section 4 lists specific groups that
both 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 are 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}. This represented as the set of integers defined by {0, 1, ..., p - 1}.
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.
* HashToGroup(x): Deterministically maps an array of bytes x to an HashToGroup(x): Deterministically maps an array of bytes x to an
element of Group. The map must ensure that, for any adversary element of Group. The map must ensure that, for any adversary
receiving R = HashToGroup(x), it is computationally difficult to receiving R = HashToGroup(x), it is computationally difficult to
reverse the mapping. This function is optionally parameterized by reverse the mapping. This function is optionally parameterized by
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 [I-D.irtf-cfrg-hash-to-curve]. 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 [I-D.irtf-cfrg-hash-to-curve], Section 10.5. described in [RFC9380], Section 10.5.
* RandomScalar(): Chooses at random a non-zero 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 SerializeElement(A): Maps an Element A to a canonical byte array buf
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 a Scalar s to a canonical byte array buf SerializeScalar(s): Maps Scalar s to a canonical byte array buf of
of fixed length Ns. fixed-length Ns.
* DeserializeScalar(buf): Attempts to map a byte array buf to a DeserializeScalar(buf): Attempts to map a byte array buf to Scalar
Scalar s. This function can raise a DeserializeError if s. This function can raise a DeserializeError if deserialization
deserialization fails; see Section 4 for group-specific input fails; see Section 4 for group-specific input validation steps.
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.
2.2. Discrete Logarithm Equivalence Proofs 2.2. Discrete Logarithm Equivalence Proofs
A proof of knowledge allows a prover to convince a verifier that some A proof of knowledge allows a prover to convince a verifier that some
statement is true. If the prover can generate a proof without statement is true. If the prover can generate a proof without
interaction with the verifier, the proof is noninteractive. If the interaction with the verifier, the proof is noninteractive. If the
verifier learns nothing other than whether the statement claimed by verifier learns nothing other than whether the statement claimed by
the prover is true or false, the proof is zero-knowledge. the prover is true or false, the proof is zero-knowledge.
This section describes a noninteractive zero-knowledge proof for This section describes a noninteractive, zero-knowledge proof for
discrete logarithm equivalence (DLEQ), which is used in the discrete logarithm equivalence (DLEQ), which is used in the
construction of VOPRF and POPRF. A DLEQ proof demonstrates that two construction of VOPRF and POPRF. A DLEQ proof demonstrates that two
pairs of group elements have the same discrete logarithm without pairs of group elements have the same discrete logarithm without
revealing the discrete logarithm. revealing the discrete logarithm.
The DLEQ proof resembles the Chaum-Pedersen [ChaumPedersen] proof, The DLEQ proof resembles the Chaum-Pedersen [ChaumPedersen] proof,
which is shown to be zero-knowledge by Jarecki, et al. [JKK14] and which is shown to be zero-knowledge by Jarecki, et al. [JKK14] and is
is noninteractive after applying the Fiat-Shamir transform [FS00]. noninteractive after applying the Fiat-Shamir transform [FS00].
Furthermore, Davidson, et al. [DGSTV18] showed a proof system for Furthermore, Davidson, et al. [DGSTV18] showed a proof system for
batching DLEQ proofs that has constant-size proofs with respect to batching DLEQ proofs that has constant-size proofs with respect to
the number of inputs. The specific DLEQ proof system presented below the number of inputs. The specific DLEQ proof system presented below
follows this latter construction with two modifications: (1) the follows this latter construction with two modifications: (1) the
transcript used to generate the seed includes more context transcript used to generate the seed includes more context
information, and (2) the individual challenges for each element in information and (2) the individual challenges for each element in the
the 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 PRNG. The description is rather than being sampled from a seeded Pseudorandom Number Generator
split into two sub-sections: one for generating the proof, which is (PRNG). The description is split into two subsections: one for
done by servers in the verifiable protocols, and another for generating the proof, which is done by servers in the verifiable
verifying the proof, which is done by clients in the protocol. protocols, and another for verifying the proof, which is done by
clients in the protocol.
2.2.1. Proof Generation 2.2.1. Proof Generation
Generating a proof is done with the GenerateProof function, defined Generating a proof is done with the GenerateProof function, as
below. Given elements A and B, two non-empty lists of elements C and defined below. Given Element values A and B, two non-empty lists of
D of length m, and a scalar k; this function produces a proof that Element values C and D of length m, and Scalar k, this function
k*A == B and k*C[i] == D[i] for each i in [0, ..., m - 1]. The produces a proof that k * A == B and k * C[i] == D[i] for each i in
output is a value of type Proof, which is a tuple of two Scalar [0, ..., m - 1]. The output is a value of type Proof, which is a
values. We use the notation proof[0] and proof[1] to denote the tuple of two Scalar values. We use the notation proof[0] and
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 page 13, line 21 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 page 13, line 47 skipping to change at line 400
I2OSP(len(a1), 2) || a1 || I2OSP(len(a1), 2) || a1 ||
I2OSP(len(a2), 2) || a2 || I2OSP(len(a2), 2) || a2 ||
I2OSP(len(a3), 2) || a3 || I2OSP(len(a3), 2) || a3 ||
"Challenge" "Challenge"
c = G.HashToScalar(challengeTranscript) c = G.HashToScalar(challengeTranscript)
s = r - c * k s = r - c * k
return [c, s] return [c, s]
The helper function ComputeCompositesFast is as defined below, and is The helper function ComputeCompositesFast is as defined below and is
an optimization of the ComputeComposites function for servers since an optimization of the ComputeComposites function for servers since
they have knowledge of the private key. they have knowledge of the private key.
Input: Input:
Scalar k Scalar k
Element B Element B
Element C[m] Element C[m]
Element D[m] Element D[m]
skipping to change at page 15, line 7 skipping to change at line 451
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, 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 page 18, line 9 skipping to change at line 552
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.
3. Protocol 3. Protocol
In this section, we define and describe three protocol variants In this section, we define and describe three protocol variants
referred to as the OPRF, VOPRF, and POPRF modes. Each of these referred to as the OPRF, VOPRF, and POPRF modes. Each of these
variants involve two messages between client and server but differ variants involves two messages between the client and server, but
slightly in terms of the security properties; see Section 7.1 for they differ slightly in terms of the security properties; see
more information. A high level description of the functionality of Section 7.1 for more information. A high-level description of the
each mode follows. functionality of each mode follows.
In the OPRF mode, a client and server interact to compute output = In the OPRF mode, a client and server interact to compute output =
F(skS, input), where input is the client's private input, skS is the F(skS, input), where input is the client's private input, skS is the
server's private key, and output is the OPRF output. After the server's private key, and output is the OPRF output. After the
execution of the protocol, the client learns output and the server execution of the protocol, the client learns the output and the
learns nothing. This interaction is shown below. server learns nothing. This interaction is shown below.
Client(input) Server(skS) Client(input) Server(skS)
------------------------------------------------------------------- -------------------------------------------------------------------
blind, blindedElement = Blind(input) blind, blindedElement = Blind(input)
blindedElement blindedElement
----------> ---------->
evaluatedElement = BlindEvaluate(skS, blindedElement) evaluatedElement = BlindEvaluate(skS, blindedElement)
evaluatedElement evaluatedElement
<---------- <----------
output = Finalize(input, blind, evaluatedElement) output = Finalize(input, blind, evaluatedElement)
Figure 1: OPRF protocol overview Figure 1: OPRF Protocol Overview
In the VOPRF mode, the client additionally receives proof that the In the VOPRF mode, the client additionally receives proof that the
server used skS in computing the function. To achieve verifiability, server used skS in computing the function. To achieve verifiability,
as in [JKK14], the server provides a zero-knowledge proof that the as in [JKK14], the server provides a zero-knowledge proof that the
key provided as input by the server in the BlindEvaluate function is key provided as input by the server in the BlindEvaluate function is
the same key as it used to produce the server's public key, pkS, the same key as is used to produce the server's public key, pkS,
which the client receives as input to the protocol. This proof does which the client receives as input to the protocol. This proof does
not reveal the server's private key to the client. This interaction not reveal the server's private key to the client. This interaction
is shown below. is shown below.
Client(input, pkS) <---- pkS ------ Server(skS, pkS) Client(input, pkS) <---- pkS ------ Server(skS, pkS)
------------------------------------------------------------------- -------------------------------------------------------------------
blind, blindedElement = Blind(input) blind, blindedElement = Blind(input)
blindedElement blindedElement
----------> ---------->
evaluatedElement, proof = BlindEvaluate(skS, pkS, evaluatedElement, proof = BlindEvaluate(skS, pkS,
blindedElement) blindedElement)
evaluatedElement, proof evaluatedElement, proof
<---------- <----------
output = Finalize(input, blind, evaluatedElement, output = Finalize(input, blind, evaluatedElement,
blindedElement, pkS, proof) blindedElement, pkS, proof)
Figure 2: VOPRF protocol overview with additional proof Figure 2: VOPRF Protocol Overview with Additional Proof
The POPRF mode extends the VOPRF mode such that the client and server The POPRF mode extends the VOPRF mode such that the client and server
can additionally provide a public input info that is used in can additionally provide the public input info, which is used in
computing the pseudorandom function. That is, the client and server computing the PRF. That is, the client and server interact to
interact to compute output = F(skS, input, info) as is shown below. compute output = F(skS, input, info), as is shown below.
Client(input, pkS, info) <---- pkS ------ Server(skS, pkS, info) Client(input, pkS, info) <---- pkS ------ Server(skS, pkS, info)
------------------------------------------------------------------- -------------------------------------------------------------------
blind, blindedElement, tweakedKey = Blind(input, info, pkS) blind, blindedElement, tweakedKey = Blind(input, info, pkS)
blindedElement blindedElement
----------> ---------->
evaluatedElement, proof = BlindEvaluate(skS, blindedElement, evaluatedElement, proof = BlindEvaluate(skS, blindedElement,
info) info)
evaluatedElement, proof evaluatedElement, proof
<---------- <----------
output = Finalize(input, blind, evaluatedElement, output = Finalize(input, blind, evaluatedElement,
blindedElement, proof, info, tweakedKey) blindedElement, proof, info, tweakedKey)
Figure 3: POPRF protocol overview with additional public input Figure 3: POPRF Protocol Overview with Additional Public Input
Each protocol consists of an offline setup phase and an online phase, Each protocol consists of an offline setup phase and an online phase,
described in Section 3.2 and Section 3.3, respectively. as described in Sections 3.2 and 3.3, respectively. Configuration
Configuration details for the offline phase are described in details for the offline phase are described in Section 3.1.
Section 3.1.
3.1. Configuration 3.1. Configuration
Each of the three protocol variants are identified with a one-byte Each of the three protocol variants are identified with a one-byte
value (in hexadecimal): value (in hexadecimal):
+===========+=======+ +===========+=======+
| Mode | Value | | Mode | Value |
+===========+=======+ +===========+=======+
| modeOPRF | 0x00 | | modeOPRF | 0x00 |
+-----------+-------+ +-----------+-------+
| modeVOPRF | 0x01 | | modeVOPRF | 0x01 |
+-----------+-------+ +-----------+-------+
| modePOPRF | 0x02 | | modePOPRF | 0x02 |
+-----------+-------+ +-----------+-------+
Table 1: Identifiers Table 1: Identifiers
for protocol variants. for Protocol Variants
Additionally, each protocol variant is instantiated with a Additionally, each protocol variant is instantiated with a
ciphersuite, or suite. Each ciphersuite is identified with an ASCII ciphersuite or suite. Each ciphersuite is identified with an ASCII
string identifier, referred to as identifier; see Section 4 for the string identifier, referred to as identifier; see Section 4 for the
set of initial ciphersuite values. set of initial ciphersuite values.
The mode and ciphersuite identifier values are combined to create a The mode and ciphersuite identifier values are combined to create a
"context string" used throughout the protocol with the following "context string" used throughout the protocol with the following
function: function:
def CreateContextString(mode, identifier): def CreateContextString(mode, identifier):
return "OPRFV1-" || I2OSP(mode, 1) || "-" || identifier return "OPRFV1-" || I2OSP(mode, 1) || "-" || identifier
skipping to change at page 21, line 22 skipping to change at line 686
Parameters: Parameters:
Group G Group G
def GenerateKeyPair(): def GenerateKeyPair():
skS = G.RandomScalar() skS = G.RandomScalar()
pkS = G.ScalarMultGen(skS) pkS = G.ScalarMultGen(skS)
return skS, pkS return skS, pkS
The second way to generate the key pair is via the deterministic key The second way to generate the key pair is via the deterministic key
generation function DeriveKeyPair described in Section 3.2.1. generation function DeriveKeyPair, as described in Section 3.2.1.
Applications and implementations can use either method in practice. Applications and implementations can use either method in practice.
Also during the offline setup phase, both the client and server Also during the offline setup phase, both the client and server
create a context used for executing the online phase of the protocol create a context used for executing the online phase of the protocol
after agreeing on a mode and ciphersuite identifier. The context, after agreeing on a mode and ciphersuite identifier. The context,
such as OPRFServerContext, is an implementation-specific data such as OPRFServerContext, is an implementation-specific data
structure that stores a context string and the relevant key material structure that stores a context string and the relevant key material
for each party. for each party.
The OPRF variant server and client contexts are created as follows: The OPRF variant server and client contexts are created as follows:
skipping to change at page 22, line 16 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 page 23, line 37 skipping to change at line 768
if counter > 255: if counter > 255:
raise DeriveKeyPairError raise DeriveKeyPairError
skS = G.HashToScalar(deriveInput || I2OSP(counter, 1), skS = G.HashToScalar(deriveInput || I2OSP(counter, 1),
DST = "DeriveKeyPair" || contextString) DST = "DeriveKeyPair" || contextString)
counter = counter + 1 counter = counter + 1
pkS = G.ScalarMultGen(skS) pkS = G.ScalarMultGen(skS)
return skS, pkS return skS, pkS
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 G: a prime-order group implementing the API described in Section 2.1
Section 2.1.
* contextString, a PublicInput domain separation tag constructed contextString: a PublicInput domain separation tag constructed
during context setup as created in Section 3.1. during context setup, as created in Section 3.1
* skS and pkS, a Scalar and Element representing the private and skS and pkS: a Scalar and Element representing the private and
public keys configured for client and server in Section 3.2. public keys configured for the client and server in Section 3.2
Applications serialize protocol messages between client and server Applications serialize protocol messages between the client and
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
skipping to change at page 24, line 49 skipping to change at line 825
def Blind(input): def Blind(input):
blind = G.RandomScalar() blind = G.RandomScalar()
inputElement = G.HashToGroup(input) inputElement = G.HashToGroup(input)
if inputElement == G.Identity(): if inputElement == G.Identity():
raise InvalidInputError raise InvalidInputError
blindedElement = blind * inputElement blindedElement = blind * inputElement
return blind, blindedElement return blind, blindedElement
Clients store blind locally, and send blindedElement to the server Clients store blind locally and send blindedElement to the server for
for evaluation. Upon receipt, servers process blindedElement using evaluation. Upon receipt, servers process blindedElement using the
the BlindEvaluate function described below. BlindEvaluate function described below.
Input: Input:
Scalar skS Scalar skS
Element blindedElement Element blindedElement
Output: Output:
Element evaluatedElement Element evaluatedElement
def BlindEvaluate(skS, blindedElement): def BlindEvaluate(skS, blindedElement):
evaluatedElement = skS * blindedElement evaluatedElement = skS * blindedElement
return evaluatedElement return evaluatedElement
Servers send the output evaluatedElement to clients for processing. Servers send the output evaluatedElement to clients for processing.
Recall that servers may process multiple client inputs by applying Recall that servers may process multiple client inputs by applying
the BlindEvaluate function to each blindedElement received, and the BlindEvaluate function to each blindedElement received and
returning an array with the corresponding evaluatedElement values. returning an array with the corresponding evaluatedElement values.
Upon receipt of evaluatedElement, clients process it to complete the Upon receipt of evaluatedElement, clients process it to complete the
OPRF evaluation with the Finalize function described below. OPRF evaluation with the Finalize function described below.
Input: Input:
PrivateInput input PrivateInput input
Scalar blind Scalar blind
Element evaluatedElement Element evaluatedElement
skipping to change at page 25, line 49 skipping to change at line 873
def Finalize(input, blind, evaluatedElement): def Finalize(input, blind, evaluatedElement):
N = G.ScalarInverse(blind) * evaluatedElement N = G.ScalarInverse(blind) * evaluatedElement
unblindedElement = G.SerializeElement(N) unblindedElement = G.SerializeElement(N)
hashInput = I2OSP(len(input), 2) || input || hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(unblindedElement), 2) || unblindedElement || I2OSP(len(unblindedElement), 2) || unblindedElement ||
"Finalize" "Finalize"
return Hash(hashInput) return Hash(hashInput)
An entity which knows both the private key and the input can compute An entity that knows both the private key and the input can compute
the PRF result using the following Evaluate function. the PRF result using the following Evaluate function.
Input: Input:
Scalar skS Scalar skS
PrivateInput input PrivateInput input
Output: Output:
opaque output[Nh] opaque output[Nh]
skipping to change at page 26, line 38 skipping to change at line 909
I2OSP(len(issuedElement), 2) || issuedElement || I2OSP(len(issuedElement), 2) || issuedElement ||
"Finalize" "Finalize"
return Hash(hashInput) return Hash(hashInput)
3.3.2. VOPRF Protocol 3.3.2. VOPRF Protocol
The VOPRF protocol begins with the client blinding its input, using The VOPRF protocol begins with the client blinding its input, using
the same Blind function as in Section 3.3.1. Clients store the the same Blind function as in Section 3.3.1. Clients store the
output blind locally and send blindedElement to the server for output blind locally and send blindedElement to the server for
evaluation. Upon receipt, servers process blindedElement to compute evaluation. Upon receipt, servers process blindedElement to compute
an evaluated element and DLEQ proof using the following BlindEvaluate an evaluated element and a DLEQ proof using the following
function. BlindEvaluate function.
Input: Input:
Scalar skS Scalar skS
Element pkS Element pkS
Element blindedElement Element blindedElement
Output: Output:
Element evaluatedElement Element evaluatedElement
skipping to change at page 28, line 44 skipping to change at line 982
hashInput = I2OSP(len(input), 2) || input || hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(unblindedElement), 2) || unblindedElement || I2OSP(len(unblindedElement), 2) || unblindedElement ||
"Finalize" "Finalize"
return Hash(hashInput) return Hash(hashInput)
As in BlindEvaluate, inputs to VerifyProof are one-item lists. As in BlindEvaluate, inputs to VerifyProof are one-item lists.
Clients can verify multiple inputs at once whenever the server Clients can verify multiple inputs at once whenever the server
produced a batched DLEQ proof for them. produced a batched DLEQ proof for them.
Finally, an entity which knows both the private key and the input can Finally, an entity that knows both the private key and the input can
compute the PRF result using the Evaluate function described in compute the PRF result using the Evaluate function described in
Section 3.3.1. Section 3.3.1.
3.3.3. POPRF Protocol 3.3.3. POPRF Protocol
The POPRF protocol begins with the client blinding its input, using The POPRF protocol begins with the client blinding its input, using
the following modified Blind function. In this step, the client also the following modified Blind function. In this step, the client also
binds a public info value, which produces an additional tweakedKey to binds a public info value, which produces an additional tweakedKey to
be used later in the protocol. Note that this function can fail with be used later in the protocol. Note that this function can fail with
an InvalidInputError error for certain private inputs that map to the an InvalidInputError error for certain private inputs that map to the
skipping to change at page 30, line 7 skipping to change at line 1035
inputElement = G.HashToGroup(input) inputElement = G.HashToGroup(input)
if inputElement == G.Identity(): if inputElement == G.Identity():
raise InvalidInputError raise InvalidInputError
blindedElement = blind * inputElement blindedElement = blind * inputElement
return blind, blindedElement, tweakedKey return blind, blindedElement, tweakedKey
Clients store the outputs blind and tweakedKey locally and send Clients store the outputs blind and tweakedKey locally and send
blindedElement to the server for evaluation. Upon receipt, servers blindedElement to the server for evaluation. Upon receipt, servers
process blindedElement to compute an evaluated element and DLEQ proof process blindedElement to compute an evaluated element and a DLEQ
using the following BlindEvaluate function. proof using the following BlindEvaluate function.
Input: Input:
Scalar skS Scalar skS
Element blindedElement Element blindedElement
PublicInput info PublicInput info
Output: Output:
Element evaluatedElement Element evaluatedElement
skipping to change at page 32, line 9 skipping to change at line 1129
hashInput = I2OSP(len(input), 2) || input || hashInput = I2OSP(len(input), 2) || input ||
I2OSP(len(info), 2) || info || I2OSP(len(info), 2) || info ||
I2OSP(len(unblindedElement), 2) || unblindedElement || I2OSP(len(unblindedElement), 2) || unblindedElement ||
"Finalize" "Finalize"
return Hash(hashInput) return Hash(hashInput)
As in BlindEvaluate, inputs to VerifyProof are one-item lists. As in BlindEvaluate, inputs to VerifyProof are one-item lists.
Clients can verify multiple inputs at once whenever the server Clients can verify multiple inputs at once whenever the server
produced a batched DLEQ proof for them. produced a batched DLEQ proof for them.
Finally, an entity which knows both the private key and the input can Finally, an entity that knows both the private key and the input can
compute the PRF result using the Evaluate function described below. compute the PRF result using the Evaluate function described below.
Input: Input:
Scalar skS Scalar skS
PrivateInput input PrivateInput input
PublicInput info PublicInput info
Output: Output:
skipping to change at page 33, line 16 skipping to change at line 1178
A ciphersuite (also referred to as 'suite' in this document) for the A ciphersuite (also referred to as 'suite' in this document) for the
protocol wraps the functionality required for the protocol to take protocol wraps the functionality required for the protocol to take
place. The ciphersuite should be available to both the client and place. The ciphersuite should be available to both the client and
server, and agreement on the specific instantiation is assumed server, and agreement on the specific instantiation is assumed
throughout. throughout.
A ciphersuite contains instantiations of the following A ciphersuite contains instantiations of the following
functionalities: functionalities:
* Group: A prime-order Group exposing the API detailed in Group: A prime-order group exposing the API detailed in Section 2.1,
Section 2.1, with the generator element defined in the with the generator element defined in the corresponding reference
corresponding reference for each group. Each group also specifies for each group. Each group also specifies HashToGroup,
HashToGroup, HashToScalar, and serialization functionalities. For HashToScalar, and serialization functionalities. For HashToGroup,
HashToGroup, the domain separation tag (DST) is constructed in the domain separation tag (DST) is constructed in accordance with
accordance with the recommendations in the recommendations in [RFC9380], Section 3.1. For HashToScalar,
[I-D.irtf-cfrg-hash-to-curve], Section 3.1. For HashToScalar,
each group specifies an integer order that is used in reducing each group specifies an integer order that is used in reducing
integer values to a member of the corresponding scalar field. integer values to a member of the corresponding scalar field.
* Hash: A cryptographic hash function whose output length is Nh Hash: A cryptographic hash function whose output length is Nh bytes
bytes long. long.
This section includes an initial set of ciphersuites with supported This section includes an initial set of ciphersuites with supported
groups and hash functions. It also includes implementation details groups and hash functions. It also includes implementation details
for each ciphersuite, focusing on input validation. Future documents for each ciphersuite, focusing on input validation. Future documents
can specify additional ciphersuites as needed provided they meet the can specify additional ciphersuites as needed, provided they meet the
requirements in Section 4.6. requirements in Section 4.6.
For each ciphersuite, contextString is that which is computed in the For each ciphersuite, contextString is that which is computed in the
Setup functions. Applications should take caution in using Setup functions. Applications should take caution in using
ciphersuites targeting P-256 and ristretto255. See Section 7.2 for ciphersuites targeting P-256 and ristretto255. See Section 7.2 for
related discussion. related discussion.
4.1. OPRF(ristretto255, SHA-512) 4.1. OPRF(ristretto255, SHA-512)
This ciphersuite uses ristretto255 [RISTRETTO] for the Group and This ciphersuite uses ristretto255 [RFC9496] for the Group and
SHA-512 for the Hash function. The value of the ciphersuite SHA-512 for the hash function. The value of the ciphersuite
identifier is "ristretto255-SHA512". identifier is "ristretto255-SHA512".
* Group: ristretto255 [RISTRETTO] Group: ristretto255 [RFC9496]
- Order(): Return 2^252 + 27742317777372353535851937790883648493 Order(): Return 2^252 + 27742317777372353535851937790883648493
(see [RISTRETTO]) (see [RFC9496]).
- Identity(): As defined in [RISTRETTO]. Identity(): As defined in [RFC9496].
- Generator(): As defined in [RISTRETTO]. Generator(): As defined in [RFC9496].
- HashToGroup(): Use hash_to_ristretto255 HashToGroup(): Use hash_to_ristretto255 [RFC9380] with DST =
[I-D.irtf-cfrg-hash-to-curve] with DST = "HashToGroup-" || "HashToGroup-" || contextString and expand_message =
contextString, and expand_message = expand_message_xmd using expand_message_xmd using SHA-512.
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(): Implemented by returning a uniformly random RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7 Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance. for implementation guidance.
- SerializeElement(A): Implemented using the 'Encode' function SerializeElement(A): Implemented using the Encode function from
from Section 4.3.2 of [RISTRETTO]; Ne = 32. Section 4.3.2 of [RFC9496]; Ne = 32.
- DeserializeElement(buf): Implemented using the 'Decode' DeserializeElement(buf): Implemented using the Decode function
function from Section 4.3.1 of [RISTRETTO]. Additionally, this from Section 4.3.1 of [RFC9496]. Additionally, this function
function validates that the resulting element is not the group validates that the resulting element is not the group identity
identity element. If these checks fail, deserialization element. If these checks fail, deserialization returns an
returns an InputValidationError error. InputValidationError error.
- SerializeScalar(s): Implemented by outputting the little-endian SerializeScalar(s): Implemented by outputting the little-endian,
32-byte encoding of the Scalar value with the top three bits 32-byte encoding of the Scalar value with the top three bits
set to zero; Ns = 32. set to zero; Ns = 32.
- DeserializeScalar(buf): Implemented by attempting to DeserializeScalar(buf): Implemented by attempting to deserialize
deserialize a Scalar from a little-endian 32-byte string. This a Scalar from a little-endian, 32-byte string. This function
function can fail if the input does not represent a Scalar in can fail if the input does not represent a Scalar in the range
the range [0, G.Order() - 1]. Note that this means the top [0, G.Order() - 1]. Note that this means the top three bits of
three bits of the input MUST be zero. the input MUST 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 [RISTRETTO] for the Group and This ciphersuite uses decaf448 [RFC9496] for the Group and SHAKE-256
SHAKE-256 for the Hash function. The value of the ciphersuite for the hash function. The value of the ciphersuite identifier is
identifier is "decaf448-SHAKE256". "decaf448-SHAKE256".
* Group: decaf448 [RISTRETTO] Group: decaf448 [RFC9496]
- Order(): Return 2^446 - 138180668098951153520073867485154268803
36692474882178609894547503885
- Identity(): As defined in [RISTRETTO]. Order(): Return 2^446 - 13818066809895115352007386748515426880336
692474882178609894547503885.
- Generator(): As defined in [RISTRETTO]. Identity(): As defined in [RFC9496].
- RandomScalar(): Implemented by returning a uniformly random Generator(): As defined in [RFC9496].
RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7 Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance. for implementation guidance.
- HashToGroup(): Use hash_to_decaf448 HashToGroup(): Use hash_to_decaf448 [RFC9380] with DST =
[I-D.irtf-cfrg-hash-to-curve] with DST = "HashToGroup-" || "HashToGroup-" || contextString and expand_message =
contextString, and expand_message = expand_message_xof using expand_message_xof using SHAKE-256.
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 SerializeElement(A): Implemented using the Encode function from
from Section 5.3.2 of [RISTRETTO]; Ne = 56. Section 5.3.2 of [RFC9496]; Ne = 56.
- DeserializeElement(buf): Implemented using the 'Decode' DeserializeElement(buf): Implemented using the Decode function
function from Section 5.3.1 of [RISTRETTO]. Additionally, this from Section 5.3.1 of [RFC9496]. Additionally, this function
function validates that the resulting element is not the group validates that the resulting element is not the group identity
identity element. If these checks fail, deserialization element. If these checks fail, deserialization returns an
returns an InputValidationError error. InputValidationError error.
- SerializeScalar(s): Implemented by outputting the little-endian SerializeScalar(s): Implemented by outputting the little-endian,
56-byte encoding of the Scalar value; Ns = 56. 56-byte encoding of the Scalar value; Ns = 56.
- DeserializeScalar(buf): Implemented by attempting to DeserializeScalar(buf): Implemented by attempting to deserialize
deserialize a Scalar from a little-endian 56-byte string. This a Scalar from a little-endian, 56-byte string. This function
function can fail if the input does not represent a Scalar in can fail if the input does not represent a Scalar in the range
the range [0, G.Order() - 1]. [0, G.Order() - 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(): Return 0xffffffff00000000ffffffffffffffffbce6faada7179 Order(): Return 0xffffffff00000000ffffffffffffffffbce6faada7179e8
e84f3b9cac2fc632551. 4f3b9cac2fc632551.
- Identity(): As defined in [NISTCurves]. Identity(): As defined in [NISTCurves].
- Generator(): As defined in [NISTCurves]. Generator(): As defined in [NISTCurves].
- RandomScalar(): Implemented by returning a uniformly random RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7 Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance. for implementation guidance.
- HashToGroup(): Use hash_to_curve with suite P256_XMD:SHA- HashToGroup(): Use hash_to_curve with suite P256_XMD:SHA-
256_SSWU_RO_ [I-D.irtf-cfrg-hash-to-curve] and DST = 256_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
"HashToGroup-" || contextString. contextString.
- HashToScalar(): Use hash_to_field from HashToScalar(): Use hash_to_field from [RFC9380] using L = 48,
[I-D.irtf-cfrg-hash-to-curve] using L = 48, expand_message_xmd expand_message_xmd with SHA-256, DST = "HashToScalar-" ||
with SHA-256, DST = "HashToScalar-" || contextString, and prime contextString, and a prime modulus equal to Group.Order().
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): Implemented using the compressed Elliptic- SerializeElement(A): Implemented using the compressed Elliptic-
Curve-Point-to-Octet-String method according to [SEC1]; Ne = Curve-Point-to-Octet-String method according to [SEC1]; Ne =
33. 33.
- DeserializeElement(buf): Implemented by attempting to DeserializeElement(buf): Implemented by attempting to deserialize
deserialize a 33 byte input string to a public key using the a 33-byte input string to a public key using the compressed
compressed Octet-String-to-Elliptic-Curve-Point method Octet-String-to-Elliptic-Curve-Point method according to [SEC1]
according to [SEC1], and then performs partial public-key and then performing partial public-key validation, as defined
validation as defined in section 5.6.2.3.4 of [KEYAGREEMENT]. in Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
This includes checking that the coordinates of the resulting that the coordinates of the resulting point are in the correct
point are in the correct range, that the point is on the curve, range, that the point is on the curve, and that the point is
and that the point is not the group identity element. If these not the group identity element. If these checks fail,
checks fail, deserialization returns an InputValidationError deserialization returns an InputValidationError error.
error.
- SerializeScalar(s): Implemented using the Field-Element-to- SerializeScalar(s): Implemented using the Field-Element-to-Octet-
Octet-String conversion according to [SEC1]; Ns = 32. String conversion according to [SEC1]; Ns = 32.
- DeserializeScalar(buf): Implemented by attempting to DeserializeScalar(buf): Implemented by attempting to deserialize
deserialize a Scalar from a 32-byte string using Octet-String- a Scalar from a 32-byte string using Octet-String-to-Field-
to-Field-Element from [SEC1]. This function can fail if the Element from [SEC1]. This function can fail if the input does
input does not represent a Scalar in the range [0, G.Order() - not represent a Scalar in the range [0, G.Order() - 1].
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(): Return 0xfffffffffffffffffffffffffffffffffffffffffffff Order(): Return 0xfffffffffffffffffffffffffffffffffffffffffffffff
fffc7634d81f4372ddf581a0db248b0a77aecec196accc52973. fc7634d81f4372ddf581a0db248b0a77aecec196accc52973.
- Identity(): As defined in [NISTCurves]. Identity(): As defined in [NISTCurves].
- Generator(): As defined in [NISTCurves]. Generator(): As defined in [NISTCurves].
- RandomScalar(): Implemented by returning a uniformly random RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7 Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance. for implementation guidance.
- HashToGroup(): Use hash_to_curve with suite P384_XMD:SHA- HashToGroup(): Use hash_to_curve with suite P384_XMD:SHA-
384_SSWU_RO_ [I-D.irtf-cfrg-hash-to-curve] and DST = 384_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
"HashToGroup-" || contextString. contextString.
- HashToScalar(): Use hash_to_field from HashToScalar(): Use hash_to_field from [RFC9380] using L = 72,
[I-D.irtf-cfrg-hash-to-curve] using L = 72, expand_message_xmd expand_message_xmd with SHA-384, DST = "HashToScalar-" ||
with SHA-384, DST = "HashToScalar-" || contextString, and prime contextString, and a prime modulus equal to Group.Order().
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): Implemented using the compressed Elliptic- SerializeElement(A): Implemented using the compressed Elliptic-
Curve-Point-to-Octet-String method according to [SEC1]; Ne = Curve-Point-to-Octet-String method according to [SEC1]; Ne =
49. 49.
- DeserializeElement(buf): Implemented by attempting to DeserializeElement(buf): Implemented by attempting to deserialize
deserialize a 49-byte array to a public key using the a 49-byte array to a public key using the compressed Octet-
compressed Octet-String-to-Elliptic-Curve-Point method String-to-Elliptic-Curve-Point method according to [SEC1] and
according to [SEC1], and then performs partial public-key then performing partial public-key validation, as defined in
validation as defined in section 5.6.2.3.4 of [KEYAGREEMENT]. Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
that the coordinates of the resulting point are in the correct
This includes checking that the coordinates of the resulting range, that the point is on the curve, and that the point is
point are in the correct range, that the point is on the curve, not the point at infinity. Additionally, this function
and that the point is not the point at infinity. Additionally, validates that the resulting element is not the group identity
this function validates that the resulting element is not the element. If these checks fail, deserialization returns an
group identity element. If these checks fail, deserialization InputValidationError error.
returns an InputValidationError error.
- SerializeScalar(s): Implemented using the Field-Element-to- SerializeScalar(s): Implemented using the Field-Element-to-Octet-
Octet-String conversion according to [SEC1]; Ns = 48. String conversion according to [SEC1]; Ns = 48.
- DeserializeScalar(buf): Implemented by attempting to DeserializeScalar(buf): Implemented by attempting to deserialize
deserialize a Scalar from a 48-byte string using Octet-String- a Scalar from a 48-byte string using Octet-String-to-Field-
to-Field-Element from [SEC1]. This function can fail if the Element from [SEC1]. This function can fail if the input does
input does not represent a Scalar in the range [0, G.Order() - not represent a Scalar in the range [0, G.Order() - 1].
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(): Return 0x01fffffffffffffffffffffffffffffffffffffffffff Order(): Return 0x01fffffffffffffffffffffffffffffffffffffffffffff
ffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8 ffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b889
899c47aebb6fb71e91386409. 9c47aebb6fb71e91386409.
- Identity(): As defined in [NISTCurves]. Identity(): As defined in [NISTCurves].
- Generator(): As defined in [NISTCurves]. Generator(): As defined in [NISTCurves].
- RandomScalar(): Implemented by returning a uniformly random RandomScalar(): Implemented by returning a uniformly random
Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7 Scalar in the range [0, G.Order() - 1]. Refer to Section 4.7
for implementation guidance. for implementation guidance.
- HashToGroup(): Use hash_to_curve with suite P521_XMD:SHA- HashToGroup(): Use hash_to_curve with suite P521_XMD:SHA-
512_SSWU_RO_ [I-D.irtf-cfrg-hash-to-curve] and DST = 512_SSWU_RO_ [RFC9380] and DST = "HashToGroup-" ||
"HashToGroup-" || contextString. contextString.
- HashToScalar(): Use hash_to_field from HashToScalar(): Use hash_to_field from [RFC9380] using L = 98,
[I-D.irtf-cfrg-hash-to-curve] using L = 98, expand_message_xmd expand_message_xmd with SHA-512, DST = "HashToScalar-" ||
with SHA-512, DST = "HashToScalar-" || contextString, and prime contextString, and a prime modulus equal to Group.Order().
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): Implemented using the compressed Elliptic- SerializeElement(A): Implemented using the compressed Elliptic-
Curve-Point-to-Octet-String method according to [SEC1]; Ne = Curve-Point-to-Octet-String method according to [SEC1]; Ne =
67. 67.
- DeserializeElement(buf): Implemented by attempting to DeserializeElement(buf): Implemented by attempting to deserialize
deserialize a 49 byte input string to a public key using the a 67-byte input string to a public key using the compressed
compressed Octet-String-to-Elliptic-Curve-Point method Octet-String-to-Elliptic-Curve-Point method according to [SEC1]
according to [SEC1], and then performs partial public-key and then performing partial public-key validation, as defined
validation as defined in section 5.6.2.3.4 of [KEYAGREEMENT]. in Section 5.6.2.3.4 of [KEYAGREEMENT]. This includes checking
This includes checking that the coordinates of the resulting that the coordinates of the resulting point are in the correct
point are in the correct range, that the point is on the curve, range, that the point is on the curve, and that the point is
and that the point is not the point at infinity. Additionally, not the point at infinity. Additionally, this function
this function validates that the resulting element is not the validates that the resulting element is not the group identity
group identity element. If these checks fail, deserialization element. If these checks fail, deserialization returns an
returns an InputValidationError error. InputValidationError error.
- SerializeScalar(s): Implemented using the Field-Element-to- SerializeScalar(s): Implemented using the Field-Element-to-Octet-
Octet-String conversion according to [SEC1]; Ns = 66. String conversion according to [SEC1]; Ns = 66.
- DeserializeScalar(buf): Implemented by attempting to DeserializeScalar(buf): Implemented by attempting to deserialize
deserialize a Scalar from a 66-byte string using Octet-String- a Scalar from a 66-byte string using Octet-String-to-Field-
to-Field-Element from [SEC1]. This function can fail if the Element from [SEC1]. This function can fail if the input does
input does not represent a Scalar in the range [0, G.Order() - not represent a Scalar in the range [0, G.Order() - 1].
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,
that 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.
In the security proof of the construction Hash is modeled as a random In the security proof of the construction, Hash is modeled as a
oracle. This implies that any instantiation of HashToGroup must be random oracle. This implies that any instantiation of HashToGroup
pre-image and collision resistant. In Section 4 we give must be pre-image and collision resistant. In Section 4, we give
instantiations of this functionality based on the functions described instantiations of this functionality based on the functions described
in [I-D.irtf-cfrg-hash-to-curve]. Consequently, any OPRF in [RFC9380]. Consequently, any OPRF implementation must adhere to
implementation must adhere to the implementation and security the implementation and security considerations discussed in [RFC9380]
considerations discussed in [I-D.irtf-cfrg-hash-to-curve] when when instantiating the function.
instantiating the function.
The DeserializeElement and DeserializeScalar functions instantiated The DeserializeElement and DeserializeScalar functions instantiated
for a particular prime-order group corresponding to a ciphersuite for a particular prime-order group corresponding to a ciphersuite
MUST adhere to the description in Section 2.1. Future ciphersuites MUST adhere to the description in Section 2.1. Future ciphersuites
MUST describe how input validation is done for DeserializeElement and MUST describe how input validation is done for DeserializeElement and
DeserializeScalar. DeserializeScalar.
Additionally, future ciphersuites must take care when choosing the Additionally, future ciphersuites must take care when choosing the
security level of the group. See Section 7.2.3 for additional security level of the group. See Section 7.2.3 for additional
details. details.
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 as follows: distributed in the range [0, G.Order() - 1] are described in the
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 random byte array until the procedure succeeds. Failure to implement
implement DeserializeScalar in constant time can leak information DeserializeScalar in constant time can leak information about the
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 *
ceil(log2(G.Order()))) / 2) / 8) bytes, and interpret it as an ceil(log2(G.Order()))) / 2) / 8) bytes, and interpret it as an
integer; reduce the integer modulo G.Order() and return the result. integer; reduce the integer modulo G.Order(), and return the result.
See [I-D.irtf-cfrg-hash-to-curve], Section 5 for the underlying See [RFC9380], Section 5 for the underlying derivation of L.
derivation of L.
5. Application Considerations 5. Application Considerations
This section describes considerations for applications, including This section describes considerations for applications, including
external interface recommendations, explicit error treatment, and external interface recommendations, explicit error treatment, and
public input representation for the POPRF protocol variant. public input representation for the POPRF protocol variant.
5.1. Input Limits 5.1. Input Limits
Application inputs, expressed as PrivateInput or PublicInput values, Application inputs, expressed as PrivateInput or PublicInput values,
MUST be smaller than 2^16-1 bytes in length. Applications that MUST be smaller than 2^16 - 1 bytes in length. Applications that
require longer inputs can use a cryptographic hash function to map require longer inputs can use a cryptographic hash function to map
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; VerifyError: Verifiable OPRF proof verification failed (Sections
Section 3.3.2 and Section 3.3.3. 3.3.2 and 3.3.3).
* DeserializeError: Group Element or Scalar deserialization failure; DeserializeError: Group Element or Scalar deserialization failure
Section 2.1 and Section 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; Section 3.3.1 and Section 3.3.3. element (Sections 3.3.1 and 3.3.3).
* InverseError: A tweaked private key is invalid (has no InverseError: A tweaked private key is invalid, i.e., has no
multiplicative inverse); Section 2.1 and Section 3.3. multiplicative 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 page 42, line 25 skipping to change at line 1599
additional data to the POPRF output. A POPRF with fixed public input additional data to the POPRF output. A POPRF with fixed public input
is functionally equivalent to a VOPRF. However, there are is functionally equivalent to a VOPRF. However, there are
differences in the underlying security assumptions made about each differences in the underlying security assumptions made about each
variant; see Section 7.2 for more details. variant; see Section 7.2 for more details.
This public input is known to both parties at the start of the This public input is known to both parties at the start of the
protocol. It is RECOMMENDED that this public input be constructed protocol. It is RECOMMENDED that this public input be constructed
with some type of higher-level domain separation to avoid cross with some type of higher-level domain separation to avoid cross
protocol attacks or related issues. For example, protocols using protocol attacks or related issues. For example, protocols using
this construction might ensure that the public input uses a unique, this construction might ensure that the public input uses a unique,
prefix-free encoding. See [I-D.irtf-cfrg-hash-to-curve], prefix-free encoding. See [RFC9380], Section 10.4 for further
Section 10.4 for further discussion on constructing domain separation discussion on constructing domain separation values.
values.
Implementations of the POPRF may choose to not let applications Implementations of the POPRF may choose to not let applications
control info in cases where this value is fixed or otherwise not control info in cases where this value is fixed or otherwise not
useful to the application. In this case, the resulting protocol is useful to the application. In this case, the resulting protocol is
functionally equivalent to the VOPRF, which does not admit public functionally equivalent to the VOPRF, which does not admit public
input. input.
6. IANA considerations 6. IANA Considerations
This document has no IANA actions. This document has no IANA actions.
7. Security Considerations 7. Security Considerations
This section discusses the security of the protocols defined in this This section discusses the security of the protocols defined in this
specification, along with some suggestions and trade-offs that arise specification, along with some suggestions and trade-offs that arise
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: For a random sampling of k, F is pseudorandom if Pseudorandomness: For a random sampling of k, F is pseudorandom if
the output y = F(k, x) on any input x is indistinguishable from the output y = F(k, x) on any input x is indistinguishable from
uniformly sampling any element in F's range. uniformly 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 non-malleable (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 non-malleable with high probability, and so a pseudorandom be nonmalleable with high probability, so a pseudorandom function
function must be non-malleable to maintain indistinguishability. must be nonmalleable to maintain indistinguishability.
* Unconditional input secrecy: The server does not learn anything Unconditional input secrecy: The server does not learn anything
about the client input x, even with unbounded computation. about the client input x, even 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 secret, 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: The client must only complete execution of the Verifiable: The client must only complete execution of the protocol
protocol if it can successfully assert that the output it computes if it can successfully assert that the output it computes is
is correct. This is taken with respect to the private key held by correct. This 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: The client and server must be able to Partial obliviousness: The client and server must be able to perform
perform the PRF on client's private input and public input. Both the PRF on the client's private and public input. Both the client
client and server know the public input, but similar to the OPRF and server know the public input, but similar to the OPRF and
and VOPRF protocols, the server learns nothing about the client's VOPRF protocols, the server learns nothing about the client's
private input or the output of the function, and the client learns private input or the output of the function, and the client learns
nothing about the server's private key. nothing 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 server's keys. Note that partial operations, such as the rotation of the server's keys. Note that
obliviousness only applies to the POPRF variant because neither the partial obliviousness only applies to the POPRF variant because
OPRF nor VOPRF variants accept public input to the protocol. neither the OPRF nor VOPRF variants accept public input to the
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: For a random sampling of k, F is pseudorandom if Pseudorandomness: For a random sampling of k, F is pseudorandom if
the output y = F(k, x, info) on any input pairs (x, info) is the output y = F(k, x, info) on any input pairs (x, info) is
indistinguishable from uniformly sampling any element in F's indistinguishable 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
[JKK14]. In particular, the VOPRF construction is similar to the [JKK14]. In particular, the VOPRF construction is similar to the
[JKK14] construction with the following distinguishing properties: [JKK14] construction with the following distinguishing properties:
1. This document does not use session identifiers to differentiate 1. This document does not use session identifiers to differentiate
different instances of the protocol; and different instances of the protocol.
2. This document supports batching so that multiple evaluations can 2. This document supports batching so that multiple evaluations can
happen at once whilst only constructing one DLEQ proof object. happen at once whilst only constructing one DLEQ proof object.
This is enabled using an established batching technique This is enabled using an established batching technique
[DGSTV18]. [DGSTV18].
The pseudorandomness and input secrecy (and verifiability) of the The pseudorandomness and input secrecy (and verifiability) of the
OPRF (and VOPRF) protocols in [JKK14] are based on the One-More Gap OPRF (and VOPRF) protocols in [JKK14] are based on the One-More Gap
Computational Diffie Hellman assumption that is computationally Computational Diffie-Hellman assumption that is computationally
difficult to solve in the corresponding prime-order group. In difficult to solve in the corresponding prime-order group. In
[JKK14], these properties are proven for one instance (i.e., one key) [JKK14], these properties are proven for one instance (i.e., one key)
of the VOPRF protocol, and without batching. There is currently no of the VOPRF protocol and without batching. There is currently no
security analysis available for the VOPRF protocol described in this security analysis available for the VOPRF protocol described in this
document in a setting with multiple server keys or batching. document in a setting with multiple server keys or batching.
7.2.2. POPRF Assumptions 7.2.2. POPRF Assumptions
The POPRF construction in this document is based on the construction The POPRF construction in this document is based on the construction
known as 3HashSDHI given by [TCRSTW21]. The construction is known as 3HashSDHI, given by [TCRSTW21]. The construction is
identical to 3HashSDHI, except that this design can optionally identical to 3HashSDHI, except that this design can optionally
perform multiple POPRF evaluations in one batch, whilst only perform multiple POPRF evaluations in one batch, whilst only
constructing one DLEQ proof object. This is enabled using an constructing one DLEQ proof object. This is enabled using an
established batching technique [DGSTV18]. established batching technique [DGSTV18].
Pseudorandomness, input secrecy, verifiability, and partial Pseudorandomness, input secrecy, verifiability, and partial
obliviousness of the POPRF variant is based on the assumption that obliviousness of the POPRF variant is based on the assumption that
the One-More Gap Strong Diffie-Hellman Inversion (SDHI) assumption the One-More Gap Strong Diffie-Hellman Inversion (SDHI) assumption
from [TCRSTW21] is computationally difficult to solve in the from [TCRSTW21] is computationally difficult to solve in the
corresponding prime-order group. Tyagi et al. [TCRSTW21] show that corresponding prime-order group. Tyagi et al. [TCRSTW21] show that
both the One-More Gap Computational Diffie Hellman assumption and the both the One-More Gap Computational Diffie-Hellman assumption and the
One-More Gap SDHI assumption reduce to the q-DL (Discrete Log) One-More Gap SDHI assumption reduce to the q-DL (Discrete Log)
assumption in the algebraic group model, for some q number of assumption in the algebraic group model for some q number of
BlindEvaluate queries. (The One-More Gap Computational Diffie BlindEvaluate queries. (The One-More Gap Computational Diffie-
Hellman assumption was the hardness assumption used to evaluate the Hellman assumption was the hardness assumption used to evaluate the
OPRF and VOPRF designs based on [JKK14], which is a predecessor to OPRF and VOPRF designs based on [JKK14], which is a predecessor to
the POPRF variant in Section 3.3.3.) the POPRF variant in Section 3.3.3.)
7.2.3. Static Diffie Hellman Attack and Security Limits 7.2.3. Static Diffie-Hellman Attack and Security Limits
A side-effect of the OPRF protocol variants in this document is that A side effect of the OPRF protocol variants in this document is that
they allow instantiation of an oracle for constructing static DH they allow instantiation of an oracle for constructing static Diffie-
samples; see [BG04] and [Cheon06]. These attacks are meant to Hellman (DH) samples; see [BG04] and [Cheon06]. These attacks are
recover (bits of) the server private key. Best-known attacks reduce meant to recover (bits of) the server private key. Best-known
the security of the prime-order group instantiation by log_2(Q)/2 attacks reduce the security of the prime-order group instantiation by
bits, where Q is the number of BlindEvaluate calls made by the log_2(Q) / 2 bits, where Q is the number of BlindEvaluate calls made
attacker. by the attacker.
As a result of this class of attacks, choosing prime-order groups As a result of this class of attacks, choosing prime-order groups
with a 128-bit security level instantiates an OPRF with a reduced with a 128-bit security level instantiates an OPRF with a reduced
security level of 128-(log_2(Q)/2) bits of security. Moreover, such security level of 128 - (log_2(Q) / 2) bits of security. Moreover,
attacks are only possible for those certain applications where the such attacks are only possible for those certain applications where
adversary can query the OPRF directly. Applications can mitigate the adversary can query the OPRF directly. Applications can mitigate
against this problem in a variety of ways, e.g., by rate-limiting against this problem in a variety of ways, e.g., by rate-limiting
client queries to BlindEvaluate or by rotating private keys. In client queries to BlindEvaluate or by rotating private keys. In
applications where such an oracle is not made available this security applications where such an oracle is not made available, this
loss does not apply. security loss does not apply.
In most cases, it would require an informed and persistent attacker In most cases, it would require an informed and persistent attacker
to launch a highly expensive attack to reduce security to anything to launch a highly expensive attack to reduce security to anything
much below 100 bits of security. Applications that admit the much below 100 bits of security. Applications that admit the
aforementioned oracle functionality, and that cannot tolerate aforementioned oracle functionality and that cannot tolerate discrete
discrete logarithm security of lower than 128 bits, are RECOMMENDED logarithm security of lower than 128 bits are RECOMMENDED to choose
to choose groups that target a higher security level, such as groups that target a higher security level, such as decaf448 (used by
decaf448 (used by ciphersuite decaf448-SHAKE256), P-384 (used by ciphersuite decaf448-SHAKE256), P-384 (used by ciphersuite
ciphersuite P384-SHA384), or P-521 (used by ciphersuite P521-SHA512). P384-SHA384), or P-521 (used by ciphersuite P521-SHA512).
7.3. Domain Separation 7.3. Domain Separation
Applications SHOULD construct input to the protocol to provide domain Applications SHOULD construct input to the protocol to provide domain
separation. Any system which has multiple OPRF applications should separation. Any system that has multiple OPRF applications should
distinguish client inputs to ensure the OPRF results are separate. distinguish client inputs to ensure the OPRF results are separate.
Guidance for constructing info can be found in Guidance for constructing info can be found in [RFC9380],
[I-D.irtf-cfrg-hash-to-curve], Section 3.1. Section 3.1.
7.4. Timing Leaks 7.4. Timing Leaks
To ensure no information is leaked during protocol execution, all To ensure no information is leaked during protocol execution, all
operations that use secret data MUST run in constant time. This operations that use secret data MUST run in constant time. This
includes all prime-order group operations and proof-specific includes all prime-order group operations and proof-specific
operations that operate on secret data, including GenerateProof and operations that operate on secret data, including GenerateProof and
BlindEvaluate. BlindEvaluate.
8. Acknowledgements 8. References
This document resulted from the work of the Privacy Pass team
[PrivacyPass]. The authors would also like to acknowledge helpful
conversations with Hugo Krawczyk. Eli-Shaoul Khedouri provided
additional review and comments on key consistency. Daniel Bourdrez,
Tatiana Bradley, Sofia Celi, Frank Denis, Julia Hesse, Russ Housley,
Kevin Lewi, Christopher Patton, and Bas Westerbaan also provided
helpful input and contributions to the document.
9. References
9.1. Normative References
[I-D.irtf-cfrg-hash-to-curve] 8.1. Normative References
Faz-Hernandez, A., Scott, S., Sullivan, N., Wahby, R. S.,
and C. A. Wood, "Hashing to Elliptic Curves", Work in
Progress, Internet-Draft, draft-irtf-cfrg-hash-to-curve-
16, 15 June 2022, <https://datatracker.ietf.org/doc/html/
draft-irtf-cfrg-hash-to-curve-16>.
[KEYAGREEMENT] [KEYAGREEMENT]
Barker, E., Chen, L., Roginsky, A., Vassilev, A., and R. Barker, E., Chen, L., Roginsky, A., Vassilev, A., and R.
Davis, "Recommendation for pair-wise key-establishment Davis, "Recommendation for pair-wise key-establishment
schemes using discrete logarithm cryptography", National schemes using discrete logarithm cryptography", NIST
Institute of Standards and Technology report, SP 800-56A (Rev. 3), DOI 10.6028/nist.sp.800-56ar3, April
DOI 10.6028/nist.sp.800-56ar3, April 2018, 2018, <https://doi.org/10.6028/nist.sp.800-56ar3>.
<https://doi.org/10.6028/nist.sp.800-56ar3>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997, DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/rfc/rfc2119>. <https://www.rfc-editor.org/info/rfc2119>.
[RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, [RFC8017] Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch,
"PKCS #1: RSA Cryptography Specifications Version 2.2", "PKCS #1: RSA Cryptography Specifications Version 2.2",
RFC 8017, DOI 10.17487/RFC8017, November 2016, RFC 8017, DOI 10.17487/RFC8017, November 2016,
<https://www.rfc-editor.org/rfc/rfc8017>. <https://www.rfc-editor.org/info/rfc8017>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>. May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RISTRETTO] [RFC9380] Faz-Hernandez, A., Scott, S., Sullivan, N., Wahby, R. S.,
de Valence, H., Grigg, J., Hamburg, M., Lovecruft, I., and C. A. Wood, "Hashing to Elliptic Curves", RFC 9380,
DOI 10.17487/RFC9380, August 2023,
<https://www.rfc-editor.org/info/rfc9380>.
[RFC9496] de Valence, H., Grigg, J., Hamburg, M., Lovecruft, I.,
Tankersley, G., and F. Valsorda, "The ristretto255 and Tankersley, G., and F. Valsorda, "The ristretto255 and
decaf448 Groups", Work in Progress, Internet-Draft, draft- decaf448 Groups", RFC 9496, DOI 10.17487/RFC9496, December
irtf-cfrg-ristretto255-decaf448-06, 13 February 2023, 2023, <https://www.rfc-editor.org/info/rfc9496>.
<https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-
ristretto255-decaf448-06>.
9.2. Informative References 8.2. Informative References
[BG04] Brown, D. and R. Gallant, "The Static Diffie-Hellman [BG04] Brown, D. and R. Gallant, "The Static Diffie-Hellman
Problem", <https://eprint.iacr.org/2004/306>. Problem", November 2004,
<https://eprint.iacr.org/2004/306>.
[ChaumPedersen] [ChaumPedersen]
Chaum, D. and T. Pedersen, "Wallet Databases with Chaum, D. and T. Pedersen, "Wallet Databases with
Observers", Advances in Cryptology - CRYPTO' 92 pp. Observers", Advances in Cryptology - CRYPTO' 92, pp.
89-105, DOI 10.1007/3-540-48071-4_7, August 2007, 89-105, DOI 10.1007/3-540-48071-4_7, August 1992,
<https://doi.org/10.1007/3-540-48071-4_7>. <https://doi.org/10.1007/3-540-48071-4_7>.
[Cheon06] Cheon, J., "Security Analysis of the Strong Diffie-Hellman [Cheon06] Cheon, J., "Security Analysis of the Strong Diffie-Hellman
Problem", Advances in Cryptology - EUROCRYPT 2006 pp. Problem", Advances in Cryptology - EUROCRYPT 2006, pp.
1-11, DOI 10.1007/11761679_1, 2006, 1-11, DOI 10.1007/11761679_1, 2006,
<https://doi.org/10.1007/11761679_1>. <https://doi.org/10.1007/11761679_1>.
[DGSTV18] Davidson, A., Goldberg, I., Sullivan, N., Tankersley, G., [DGSTV18] Davidson, A., Goldberg, I., Sullivan, N., Tankersley, G.,
and F. Valsorda, "Privacy Pass: Bypassing Internet and F. Valsorda, "Privacy Pass: Bypassing Internet
Challenges Anonymously", Proceedings on Privacy Enhancing Challenges Anonymously", Proceedings on Privacy Enhancing
Technologies vol. 2018, no. 3, pp. 164-180, DOI Technologies, vol. 2018, no. 3, pp. 164-180, DOI
10.1515/popets-2018-0026, April 2018, 10.1515/popets-2018-0026, April 2018,
<https://doi.org/10.1515/popets-2018-0026>. <https://doi.org/10.1515/popets-2018-0026>.
[FS00] Fiat, A. and A. Shamir, "How To Prove Yourself: Practical [FS00] Fiat, A. and A. Shamir, "How To Prove Yourself: Practical
Solutions to Identification and Signature Problems", Solutions to Identification and Signature Problems",
Advances in Cryptology - CRYPTO' 86 pp. 186-194, Advances in Cryptology - CRYPTO' 86, pp. 186-194,
DOI 10.1007/3-540-47721-7_12, April 2007, DOI 10.1007/3-540-47721-7_12, 1986,
<https://doi.org/10.1007/3-540-47721-7_12>. <https://doi.org/10.1007/3-540-47721-7_12>.
[JKK14] Jarecki, S., Kiayias, A., and H. Krawczyk, "Round-Optimal [JKK14] Jarecki, S., Kiayias, A., and H. Krawczyk, "Round-Optimal
Password-Protected Secret Sharing and T-PAKE in the Password-Protected Secret Sharing and T-PAKE in the
Password-Only Model", Lecture Notes in Computer Password-Only Model", Lecture Notes in Computer Science,
Science pp. 233-253, DOI 10.1007/978-3-662-45608-8_13, pp. 233-253, DOI 10.1007/978-3-662-45608-8_13, 2014,
2014, <https://doi.org/10.1007/978-3-662-45608-8_13>. <https://doi.org/10.1007/978-3-662-45608-8_13>.
[JKKX16] Jarecki, S., Kiayias, A., Krawczyk, H., 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 2016 IEEE European Symposium on Security and Privacy
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]
"Digital Signature Standard (DSS)", National Institute of National Institute of Standards and Technology (NIST),
Standards and Technology report, "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-09, 6 July 2022, Internet-Draft, draft-irtf-cfrg-opaque-13, 18 December
<https://datatracker.ietf.org/doc/html/draft-irtf-cfrg- 2023, <https://datatracker.ietf.org/doc/html/draft-irtf-
opaque-09>. cfrg-opaque-13>.
[PrivacyPass] [PRIVACY-PASS]
"Privacy Pass", <https://github.com/privacypass/team>. Celi, S., Davidson, A., Valdez, S., and C. A. Wood,
"Privacy Pass Issuance Protocol", Work in Progress,
Internet-Draft, draft-ietf-privacypass-protocol-16, 3
October 2023, <https://datatracker.ietf.org/doc/html/
draft-ietf-privacypass-protocol-16>.
[PRIVACYPASS] [PrivacyPass]
Celi, S., Davidson, A., Faz-Hernandez, A., Valdez, S., and "Privacy Pass", commit 085380a, March 2018,
C. A. Wood, "Privacy Pass Issuance Protocol", Work in <https://github.com/privacypass/team>.
Progress, Internet-Draft, draft-ietf-privacypass-protocol-
08, 30 January 2023,
<https://datatracker.ietf.org/doc/html/draft-ietf-
privacypass-protocol-08>.
[RFC7748] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves [RFC7748] Langley, A., Hamburg, M., and S. Turner, "Elliptic Curves
for Security", RFC 7748, DOI 10.17487/RFC7748, January for Security", RFC 7748, DOI 10.17487/RFC7748, January
2016, <https://www.rfc-editor.org/rfc/rfc7748>. 2016, <https://www.rfc-editor.org/info/rfc7748>.
[SEC1] Standards for Efficient Cryptography Group (SECG), "SEC 1: [SEC1] Standards for Efficient Cryptography Group (SECG), "SEC 1:
Elliptic Curve Cryptography", Elliptic Curve Cryptography", May 2009,
<https://www.secg.org/sec1-v2.pdf>. <https://www.secg.org/sec1-v2.pdf>.
[SJKS17] Shirvanian, M., Jarecki, S., Krawczyk, H., and N. Saxena, [SJKS17] Shirvanian, M., Jarecki, S., Krawczyk, H., and N. Saxena,
"SPHINX: A Password Store that Perfectly Hides Passwords "SPHINX: A Password Store that Perfectly Hides Passwords
from Itself", In 2017 IEEE 37th International Conference from Itself", 2017 IEEE 37th International Conference on
on Distributed Computing Systems (ICDCS), Distributed Computing Systems (ICDCS),
DOI 10.1109/ICDCS.2017.64, June 2017, DOI 10.1109/ICDCS.2017.64, June 2017,
<https://doi.org/10.1109/ICDCS.2017.64>. <https://doi.org/10.1109/ICDCS.2017.64>.
[TCRSTW21] Tyagi, N., Celi, S., Ristenpart, T., Sullivan, N., [TCRSTW21] Tyagi, N., Celi, S., Ristenpart, T., Sullivan, N.,
Tessaro, S., and C. Wood, "A Fast and Simple Partially Tessaro, S., and C. A. Wood, "A Fast and Simple Partially
Oblivious PRF, with Applications", Advances in Cryptology Oblivious PRF, with Applications", Advances in Cryptology
- EUROCRYPT 2022 pp. 674-705, - EUROCRYPT 2022 pp. 674-705,
DOI 10.1007/978-3-031-07085-3_23, 2022, DOI 10.1007/978-3-031-07085-3_23, May 2022,
<https://doi.org/10.1007/978-3-031-07085-3_23>. <https://doi.org/10.1007/978-3-031-07085-3_23>.
Appendix A. Test Vectors Appendix A. Test Vectors
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 run Section 4, there is a set of test vectors for the protocol when
the OPRF, VOPRF, and POPRF modes. Each test vector lists the batch running the OPRF, VOPRF, and POPRF modes. Each test vector lists the
size for the evaluation. Each test vector value is encoded as a batch size for the evaluation. Each test vector value is encoded as
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": The public info, an opaque byte string. Only present for "Info": The public info, an opaque byte string. Only present for
POPRF test vectors. POPRF 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 "BlindedElement": The blinded value output by Blind(), a serialized
serialized Element of Ne bytes long. Element of Ne bytes long.
* "EvaluatedElement": The evaluated element output by "EvaluatedElement": The evaluated element output by BlindEvaluate(),
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 of Ns bytes long. Only of two serialized Scalar values, each Ns bytes long. Only present
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 length Nh "Output": The protocol output, an opaque byte string of Nh bytes
bytes. 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
skipping to change at page 72, line 33 skipping to change at line 2873
961501cd4b43713253c022692669cf076b1d382ecd8293c1de69ea569737f37a2477 961501cd4b43713253c022692669cf076b1d382ecd8293c1de69ea569737f37a2477
2ab73517983c1e3db5818754ba1f008076267b8058b6481949ae346cdc17a8455fe2 2ab73517983c1e3db5818754ba1f008076267b8058b6481949ae346cdc17a8455fe2
ProofRandomScalar = 01ec21c7bb69b0734cb48dfd68433dd93b0fa097e722ed24 ProofRandomScalar = 01ec21c7bb69b0734cb48dfd68433dd93b0fa097e722ed24
27de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba 27de86966910acba9f5c350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba
51943c8026877963 51943c8026877963
Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c1439548 Output = 808ae5b87662eaaf0b39151dd85991b94c96ef214cb14a68bf5c1439548
82d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733 82d330da8953a80eea20788e552bc8bbbfff3100e89f9d6e341197b122c46a208733
b,27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af5762c36 b,27032e24b1a52a82ab7f4646f3c5df0f070f499db98b9c5df33972bd5af5762c36
38afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e3 38afae7912a6c1acdb1ae2ab2fa670bd5486c645a0e55412e08d33a4a0d6e3
Acknowledgements
This document resulted from the work of the Privacy Pass team
[PrivacyPass]. The authors would also like to acknowledge helpful
conversations with Hugo Krawczyk. Eli-Shaoul Khedouri provided
additional review and comments on key consistency. Daniel Bourdrez,
Tatiana Bradley, Sofia Celi, Frank Denis, Julia Hesse, Russ Housley,
Kevin Lewi, Christopher Patton, and Bas Westerbaan also provided
helpful input and contributions to the document.
Authors' Addresses Authors' Addresses
Alex Davidson Alex Davidson
Brave Software Brave Software
Email: alex.davidson92@gmail.com Email: alex.davidson92@gmail.com
Armando Faz-Hernandez Armando Faz-Hernandez
Cloudflare, Inc. Cloudflare, Inc.
101 Townsend St 101 Townsend St
San Francisco, San Francisco, CA
United States of America United States of America
Email: armfazh@cloudflare.com Email: armfazh@cloudflare.com
Nick Sullivan Nick Sullivan
Cloudflare, Inc. Cloudflare, Inc.
101 Townsend St 101 Townsend St
San Francisco, San Francisco, CA
United States of America United States of America
Email: nick@cloudflare.com Email: nicholas.sullivan+ietf@gmail.com
Christopher A. Wood Christopher A. Wood
Cloudflare, Inc. Cloudflare, Inc.
101 Townsend St 101 Townsend St
San Francisco, San Francisco, CA
United States of America United States of America
Email: caw@heapingbits.net Email: caw@heapingbits.net
 End of changes. 235 change blocks. 
815 lines changed or deleted 599 lines changed or added

This html diff was produced by rfcdiff 1.48.