Files
voprf-vx/src/lib.rs
T

524 lines
19 KiB
Rust
Raw Normal View History

2021-09-09 01:56:54 -07:00
// Copyright (c) Facebook, Inc. and its affiliates.
//
2021-09-27 18:53:06 -07:00
// This source code is licensed under both the MIT license found in the
// LICENSE-MIT file in the root directory of this source tree and the Apache
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
// of this source tree.
2021-09-09 01:56:54 -07:00
2021-09-15 17:49:31 -07:00
//! An implementation of a verifiable oblivious pseudorandom function (VOPRF)
//!
//! Note: This implementation is in sync with
//! [draft-irtf-cfrg-voprf-08](https://www.ietf.org/archive/id/draft-irtf-cfrg-voprf-08.html),
2021-09-20 00:17:53 -07:00
//! but this specification is subject to change, until the final version
//! published by the IETF.
2021-09-15 17:49:31 -07:00
//!
2021-09-20 00:17:53 -07:00
//! # Overview
2021-09-15 17:49:31 -07:00
//!
2021-12-23 01:17:03 +01:00
//! A verifiable oblivious pseudorandom function is a protocol that is evaluated
//! between a client and a server. They must first agree on a collection of
//! primitives to be kept consistent throughout protocol execution. These
//! include:
2021-09-20 00:17:53 -07:00
//! - a finite cyclic group along with a point representation, and
//! - a hashing function.
//!
//! We will use the following choices in this example:
//!
2021-12-23 07:50:48 +01:00
//! ```ignore
2022-01-21 22:52:09 +01:00
//! type CipherSuite = voprf::Ristretto255;
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ## Modes of Operation
//!
//! VOPRF can be used in two modes:
2021-12-23 01:17:03 +01:00
//! - [Base Mode](#base-mode), which corresponds to a normal OPRF evaluation
//! with no support for the verification of the OPRF outputs
//! - [Verifiable Mode](#verifiable-mode), which corresponds to an OPRF
//! evaluation where the outputs can be verified against a server public key
2021-09-20 00:17:53 -07:00
//!
2021-12-23 01:17:03 +01:00
//! In either mode, the protocol begins with a client blinding, followed by a
//! server evaluation, and finishes with a client finalization.
2021-09-20 00:17:53 -07:00
//!
//! ## Base Mode
//!
2022-02-13 04:00:11 -08:00
//! In base mode, a [OprfClient] interacts with a [OprfServer]
2021-12-23 01:17:03 +01:00
//! to compute the output of the VOPRF.
2021-09-20 00:17:53 -07:00
//!
//! ### Server Setup
//!
//! The protocol begins with a setup phase, in which the server must run
2022-02-13 04:00:11 -08:00
//! [OprfServer::new()] to produce an instance of itself. This instance
2021-12-23 01:17:03 +01:00
//! must be persisted on the server and used for online client evaluations.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2021-12-23 01:17:03 +01:00
//! use rand::rngs::OsRng;
//! use rand::RngCore;
2022-02-13 04:00:11 -08:00
//! use voprf::OprfServer;
2021-09-20 00:17:53 -07:00
//!
//! let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! let server = OprfServer::<CipherSuite>::new(&mut server_rng);
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ### Client Blinding
//!
//! In the first step, the client chooses an input, and runs
2022-02-13 04:00:11 -08:00
//! [OprfClient::blind] to produce a [OprfClientBlindResult],
2021-09-20 00:17:53 -07:00
//! which consists of a [BlindedElement] to be sent to the server and a
2022-02-13 04:00:11 -08:00
//! [OprfClient] which must be persisted on the client for the final
2021-09-20 00:17:53 -07:00
//! step of the VOPRF protocol.
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2021-12-23 01:17:03 +01:00
//! use rand::rngs::OsRng;
//! use rand::RngCore;
2022-02-13 04:00:11 -08:00
//! use voprf::OprfClient;
2021-09-20 00:17:53 -07:00
//!
//! let mut client_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! let client_blind_result = OprfClient::<CipherSuite>::blind(b"input", &mut client_rng)
2021-12-23 21:03:38 +01:00
//! .expect("Unable to construct client");
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ### Server Evaluation
//!
//! In the second step, the server takes as input the message from
2022-02-13 04:00:11 -08:00
//! [OprfClient::blind] (a [BlindedElement]), and runs
//! [OprfServer::evaluate] to produce [EvaluationElement] to be sent to
2022-01-28 01:38:17 +01:00
//! the client.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::OprfClient;
2021-09-20 00:17:53 -07:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! # let mut client_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let client_blind_result = OprfClient::<CipherSuite>::blind(
2021-12-23 21:03:38 +01:00
//! # b"input",
2021-09-20 00:17:53 -07:00
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
2022-02-13 04:00:11 -08:00
//! # use voprf::OprfServer;
2021-09-20 00:17:53 -07:00
//! # let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let server = OprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let server_evaluate_result = server.evaluate(&client_blind_result.message);
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ### Client Finalization
//!
//! In the final step, the client takes as input the message from
2022-02-13 04:00:11 -08:00
//! [OprfServer::evaluate] (an [EvaluationElement]), and runs
//! [OprfClient::finalize] to produce an output for the protocol.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::OprfClient;
2021-09-20 00:17:53 -07:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! # let mut client_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let client_blind_result = OprfClient::<CipherSuite>::blind(
2021-12-23 21:03:38 +01:00
//! # b"input",
2021-09-20 00:17:53 -07:00
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
2022-02-13 04:00:11 -08:00
//! # use voprf::OprfServer;
2021-09-20 00:17:53 -07:00
//! # let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let server = OprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! # let message = server.evaluate(&client_blind_result.message);
2021-12-23 01:17:03 +01:00
//! let client_finalize_result = client_blind_result
//! .state
2022-02-13 04:00:11 -08:00
//! .finalize(b"input", &message)
2021-12-23 01:17:03 +01:00
//! .expect("Unable to perform client finalization");
2021-09-20 00:17:53 -07:00
//!
2021-10-06 00:53:18 +02:00
//! println!("VOPRF output: {:?}", client_finalize_result.to_vec());
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ## Verifiable Mode
//!
2022-02-13 04:00:11 -08:00
//! In verifiable mode, a [VoprfClient] interacts with a [VoprfServer]
2021-12-23 01:17:03 +01:00
//! to compute the output of the VOPRF. In order to verify the server's
//! computation, the client checks a server-generated proof against the server's
//! public key. If the proof fails to verify, then the client does not receive
//! an output.
2021-09-20 00:17:53 -07:00
//!
//! In batch mode, a single proof can be used for multiple VOPRF evaluations.
2021-12-23 01:17:03 +01:00
//! See [the batching section](#batching) for more details on how to perform
//! batch evaluations.
2021-09-20 00:17:53 -07:00
//!
//! ### Server Setup
//!
//! The protocol begins with a setup phase, in which the server must run
2022-02-13 04:00:11 -08:00
//! [VoprfServer::new()] to produce an instance of itself. This instance
2021-12-23 01:17:03 +01:00
//! must be persisted on the server and used for online client evaluations.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2021-12-23 01:17:03 +01:00
//! use rand::rngs::OsRng;
//! use rand::RngCore;
2022-02-13 04:00:11 -08:00
//! use voprf::VoprfServer;
2021-09-20 00:17:53 -07:00
//!
//! let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
2021-09-20 00:17:53 -07:00
//!
//! // To be sent to the client
//! println!("Server public key: {:?}", server.get_public_key());
//! ```
//!
2021-12-23 01:17:03 +01:00
//! The public key should be sent to the client, since the client will need it
//! in the final step of the protocol in order to complete the evaluation of the
//! VOPRF.
2021-09-20 00:17:53 -07:00
//!
//! ### Client Blinding
//!
//! In the first step, the client chooses an input, and runs
2022-02-13 04:00:11 -08:00
//! [VoprfClient::blind] to produce a [VoprfClientBlindResult], which
2021-12-23 01:17:03 +01:00
//! consists of a [BlindedElement] to be sent to the server and a
2022-02-13 04:00:11 -08:00
//! [VoprfClient] which must be persisted on the client for the final step
2021-12-23 01:17:03 +01:00
//! of the VOPRF protocol.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2021-12-23 01:17:03 +01:00
//! use rand::rngs::OsRng;
//! use rand::RngCore;
2022-02-13 04:00:11 -08:00
//! use voprf::VoprfClient;
2021-09-20 00:17:53 -07:00
//!
//! let mut client_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! let client_blind_result = VoprfClient::<CipherSuite>::blind(b"input", &mut client_rng)
2021-12-23 21:03:38 +01:00
//! .expect("Unable to construct client");
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ### Server Evaluation
//!
//! In the second step, the server takes as input the message from
2022-02-13 04:00:11 -08:00
//! [VoprfClient::blind] (a [BlindedElement]), and runs
//! [VoprfServer::evaluate] to produce a [VoprfServerEvaluateResult],
2021-12-23 01:17:03 +01:00
//! which consists of an [EvaluationElement] to be sent to the client along with
//! a proof.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::{VoprfServerEvaluateResult, VoprfClient};
2021-09-20 00:17:53 -07:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! # let mut client_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let client_blind_result = VoprfClient::<CipherSuite>::blind(
2021-12-23 21:03:38 +01:00
//! # b"input",
2021-09-20 00:17:53 -07:00
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
2022-02-13 04:00:11 -08:00
//! # use voprf::VoprfServer;
2021-09-20 00:17:53 -07:00
//! # let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let VoprfServerEvaluateResult { message, proof } =
//! server.evaluate(&mut server_rng, &client_blind_result.message);
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ### Client Finalization
//!
//! In the final step, the client takes as input the message from
2022-02-13 04:00:11 -08:00
//! [VoprfServer::evaluate] (an [EvaluationElement]), the proof, and the
//! server's public key, and runs [VoprfClient::finalize] to produce an
2021-12-23 01:17:03 +01:00
//! output for the protocol.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::VoprfClient;
2021-09-20 00:17:53 -07:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! # let mut client_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let client_blind_result = VoprfClient::<CipherSuite>::blind(
2021-12-23 21:03:38 +01:00
//! # b"input",
2021-09-20 00:17:53 -07:00
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
2022-02-13 04:00:11 -08:00
//! # use voprf::VoprfServer;
2021-09-20 00:17:53 -07:00
//! # let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
2021-09-20 00:17:53 -07:00
//! # let server_evaluate_result = server.evaluate(
//! # &mut server_rng,
2021-12-21 20:17:02 +01:00
//! # &client_blind_result.message,
2022-02-13 04:00:11 -08:00
//! # );
2021-12-23 01:17:03 +01:00
//! let client_finalize_result = client_blind_result
//! .state
//! .finalize(
2021-12-23 21:03:38 +01:00
//! b"input",
2021-12-23 01:17:03 +01:00
//! &server_evaluate_result.message,
//! &server_evaluate_result.proof,
//! server.get_public_key(),
//! )
//! .expect("Unable to perform client finalization");
2021-09-20 00:17:53 -07:00
//!
2021-10-06 00:53:18 +02:00
//! println!("VOPRF output: {:?}", client_finalize_result.to_vec());
2021-09-20 00:17:53 -07:00
//! ```
//!
//! # Advanced Usage
//!
//! There are two additional (and optional) extensions to the core VOPRF
//! protocol: support for batching of evaluations, and support for public
//! metadata.
//!
//! ## Batching
//!
2021-12-23 01:17:03 +01:00
//! It is sometimes desirable to generate only a single, constant-size proof for
//! an unbounded number of VOPRF evaluations (on arbitrary inputs).
2022-02-13 04:00:11 -08:00
//! [VoprfClient] and [VoprfServer] support a batch API for handling
2021-12-23 01:17:03 +01:00
//! this case. In the following example, we show how to use the batch API to
//! produce a single proof for 10 parallel VOPRF evaluations.
2021-09-20 00:17:53 -07:00
//!
2021-12-23 01:17:03 +01:00
//! First, the client produces 10 blindings, storing their resulting states and
//! messages:
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::VoprfClient;
2021-09-20 00:17:53 -07:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! let mut client_rng = OsRng;
//! let mut client_states = vec![];
//! let mut client_messages = vec![];
//! for _ in 0..10 {
2022-02-13 04:00:11 -08:00
//! let client_blind_result = VoprfClient::<CipherSuite>::blind(b"input", &mut client_rng)
2021-12-23 21:03:38 +01:00
//! .expect("Unable to construct client");
2021-09-20 00:17:53 -07:00
//! client_states.push(client_blind_result.state);
//! client_messages.push(client_blind_result.message);
//! }
2021-12-29 09:14:28 +01:00
//! ```
//!
2022-02-13 04:00:11 -08:00
//! Next, the server calls the [VoprfServer::batch_evaluate_prepare] and
//! [VoprfServer::batch_evaluate_finish] function on a set of client
2021-12-29 09:14:28 +01:00
//! messages, to produce a corresponding set of messages to be returned to the
//! client (returned in the same order), along with a single proof:
//!
//! ```
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::{VoprfServerBatchEvaluateFinishResult, VoprfClient};
2021-12-29 09:14:28 +01:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! # let mut client_rng = OsRng;
//! # let mut client_states = vec![];
//! # let mut client_messages = vec![];
//! # for _ in 0..10 {
2022-02-13 04:00:11 -08:00
//! # let client_blind_result = VoprfClient::<CipherSuite>::blind(
2021-12-29 09:14:28 +01:00
//! # b"input",
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # client_states.push(client_blind_result.state);
//! # client_messages.push(client_blind_result.message);
2021-12-23 21:03:38 +01:00
//! # }
2022-02-13 04:00:11 -08:00
//! # use voprf::VoprfServer;
2021-12-29 09:14:28 +01:00
//! let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let prepared_evaluation_elements = server.batch_evaluate_prepare(client_messages.iter());
2021-12-29 09:14:28 +01:00
//! let prepared_elements: Vec<_> = prepared_evaluation_elements.collect();
2022-02-13 04:00:11 -08:00
//! let VoprfServerBatchEvaluateFinishResult { messages, proof } = server
//! .batch_evaluate_finish(&mut server_rng, client_messages.iter(), &prepared_elements)
2021-12-29 09:14:28 +01:00
//! .expect("Unable to perform server batch evaluate");
//! let messages: Vec<_> = messages.collect();
2021-09-20 00:17:53 -07:00
//! ```
//!
//! If `alloc` is available, [VoprfServer::batch_evaluate] can be called
2021-12-29 09:14:28 +01:00
//! to avoid having to collect output manually:
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 21:03:38 +01:00
//! # #[cfg(feature = "alloc")] {
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::{VoprfServerBatchEvaluateResult, VoprfClient};
2021-09-20 00:17:53 -07:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! # let mut client_rng = OsRng;
//! # let mut client_states = vec![];
//! # let mut client_messages = vec![];
//! # for _ in 0..10 {
2022-02-13 04:00:11 -08:00
//! # let client_blind_result = VoprfClient::<CipherSuite>::blind(
2021-12-23 21:03:38 +01:00
//! # b"input",
2021-09-20 00:17:53 -07:00
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # client_states.push(client_blind_result.state);
//! # client_messages.push(client_blind_result.message);
//! # }
2022-02-13 04:00:11 -08:00
//! # use voprf::VoprfServer;
2021-09-20 00:17:53 -07:00
//! let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! let VoprfServerBatchEvaluateResult { messages, proof } = server
//! .batch_evaluate(&mut server_rng, &client_messages)
2021-12-23 01:17:03 +01:00
//! .expect("Unable to perform server batch evaluate");
2021-12-23 21:03:38 +01:00
//! # }
2021-09-20 00:17:53 -07:00
//! ```
//!
2022-02-13 04:00:11 -08:00
//! Then, the client calls [VoprfClient::batch_finalize] on the client
2021-12-23 01:17:03 +01:00
//! states saved from the first step, along with the messages returned by the
//! server, along with the server's proof, in order to produce a vector of
//! outputs if the proof verifies correctly.
2021-09-20 00:17:53 -07:00
//!
//! ```
2021-12-23 21:03:38 +01:00
//! # #[cfg(feature = "alloc")] {
2021-12-23 07:50:48 +01:00
//! # #[cfg(feature = "ristretto255")]
2022-01-21 22:52:09 +01:00
//! # type CipherSuite = voprf::Ristretto255;
//! # #[cfg(not(feature = "ristretto255"))]
//! # type CipherSuite = p256::NistP256;
2022-02-13 04:00:11 -08:00
//! # use voprf::{VoprfServerBatchEvaluateResult, VoprfClient};
2021-09-20 00:17:53 -07:00
//! # use rand::{rngs::OsRng, RngCore};
//! #
//! # let mut client_rng = OsRng;
//! # let mut client_states = vec![];
//! # let mut client_messages = vec![];
//! # for _ in 0..10 {
2022-02-13 04:00:11 -08:00
//! # let client_blind_result = VoprfClient::<CipherSuite>::blind(
2021-12-23 21:03:38 +01:00
//! # b"input",
2021-09-20 00:17:53 -07:00
//! # &mut client_rng,
//! # ).expect("Unable to construct client");
//! # client_states.push(client_blind_result.state);
//! # client_messages.push(client_blind_result.message);
//! # }
2022-02-13 04:00:11 -08:00
//! # use voprf::VoprfServer;
2021-12-29 09:14:28 +01:00
//! # let mut server_rng = OsRng;
2022-02-13 04:00:11 -08:00
//! # let server = VoprfServer::<CipherSuite>::new(&mut server_rng).unwrap();
//! # let VoprfServerBatchEvaluateResult { messages, proof } = server
//! # .batch_evaluate(&mut server_rng, &client_messages)
2021-12-29 09:14:28 +01:00
//! # .expect("Unable to perform server batch evaluate");
2022-02-13 04:00:11 -08:00
//! let client_batch_finalize_result = VoprfClient::batch_finalize(
2021-12-23 21:03:38 +01:00
//! &[b"input"; 10],
//! &client_states,
2021-12-29 09:14:28 +01:00
//! &messages,
//! &proof,
2021-09-20 00:17:53 -07:00
//! server.get_public_key(),
2021-12-23 01:17:03 +01:00
//! )
2021-12-23 21:03:38 +01:00
//! .expect("Unable to perform client batch finalization")
//! .collect::<Vec<_>>();
2021-09-20 00:17:53 -07:00
//!
2021-10-06 00:53:18 +02:00
//! println!("VOPRF batch outputs: {:?}", client_batch_finalize_result);
2021-12-23 21:03:38 +01:00
//! # }
2021-09-20 00:17:53 -07:00
//! ```
//!
//! ## Metadata
//!
//! The optional metadata parameter included in the protocol allows clients and
//! servers (of either mode) to cryptographically bind additional data to the
2021-12-23 01:17:03 +01:00
//! VOPRF output. This metadata is known to both parties at the start of the
//! protocol, and is inserted under the server's evaluate step and the client's
//! finalize step. This metadata can be constructed with some type of
//! higher-level domain separation to avoid cross-protocol attacks or related
//! issues.
2021-09-20 00:17:53 -07:00
//!
2021-12-23 01:17:03 +01:00
//! A custom metadata can be specified, for example, by:
//! `Some(b"custom metadata")`.
2021-09-20 00:17:53 -07:00
//!
//! # Features
//!
//! - The `alloc` feature requires Rust's `alloc` crate and enables batching
2021-12-23 21:03:38 +01:00
//! VOPRF evaluations.
//!
2021-12-23 01:17:03 +01:00
//! - The `serde` feature, enabled by default, provides convenience functions
//! for serializing and deserializing with [serde](https://serde.rs/).
//!
//! - The `danger` feature, disabled by default, exposes functions for setting
//! and getting internal values not available in the default API. These
//! functions are intended for use in by higher-level cryptographic protocols
//! that need access to these raw values and are able to perform the necessary
//! validations on them (such as being valid group elements).
//!
2022-01-21 22:52:09 +01:00
//! - The `ristretto255-ciphersuite` features enables using [`Ristretto255`] as
//! a [`CipherSuite`].
//!
2022-01-18 12:34:28 +01:00
//! - The `ristretto255` feature enables using [`Ristretto255`] as the
//! underlying group for the [Group] choice. A backend feature, which are
//! re-exported from [curve25519-dalek] and allow for selecting the
//! corresponding backend for the curve arithmetic used, has to be selected,
2022-01-21 22:52:09 +01:00
//! otherwise compilation will fail. The `ristretto255-u64` feature is
//! included as the default. Other features are mapped as `ristretto255-u32`,
//! `ristretto255-fiat-u64` and `ristretto255-fiat-u32`. Any `ristretto255-*`
2022-01-18 12:34:28 +01:00
//! backend feature will enable the `ristretto255` feature.
//!
2022-01-21 22:52:09 +01:00
//! - The `ristretto255-simd` feature is re-exported from [curve25519-dalek] and
2022-01-18 12:34:28 +01:00
//! enables parallel formulas, using either AVX2 or AVX512-IFMA. This will
2022-01-21 22:52:09 +01:00
//! automatically enable the `ristretto255-u64` feature and requires Rust
2021-12-23 01:17:03 +01:00
//! nightly.
2022-01-18 12:34:28 +01:00
//!
//! [curve25519-dalek]: (https://doc.dalek.rs/curve25519_dalek/index.html#backends-and-features)
2021-09-15 17:49:31 -07:00
2022-01-28 12:37:55 +01:00
#![cfg_attr(not(test), deny(unsafe_code))]
2021-12-21 20:17:02 +01:00
#![no_std]
2022-01-28 01:38:17 +01:00
#![warn(
clippy::cargo,
clippy::missing_errors_doc,
missing_debug_implementations,
missing_docs
)]
#![allow(clippy::multiple_crate_versions)]
2021-09-09 01:56:54 -07:00
2021-12-23 21:03:38 +01:00
#[cfg(any(feature = "alloc", test))]
2021-09-09 01:56:54 -07:00
extern crate alloc;
2021-12-21 20:17:02 +01:00
#[cfg(feature = "std")]
extern crate std;
2022-01-28 01:38:17 +01:00
#[cfg(feature = "serde")]
extern crate serde_ as serde;
2022-01-21 22:52:09 +01:00
mod ciphersuite;
2021-12-25 22:54:27 +01:00
mod error;
mod group;
2022-02-13 04:00:11 -08:00
mod oprf;
mod poprf;
2022-01-21 22:52:09 +01:00
mod serialization;
mod util;
2021-09-20 00:17:53 -07:00
mod voprf;
2021-09-09 01:56:54 -07:00
#[cfg(test)]
mod tests;
2021-09-20 00:17:53 -07:00
// Exports
2022-01-21 22:52:09 +01:00
pub use crate::ciphersuite::CipherSuite;
2022-01-25 05:55:02 +01:00
pub use crate::error::{Error, InternalError, Result};
2021-12-25 22:54:27 +01:00
pub use crate::group::Group;
2022-01-21 22:52:09 +01:00
#[cfg(feature = "ristretto255")]
pub use crate::group::Ristretto255;
2022-02-13 04:00:11 -08:00
pub use crate::oprf::{OprfClient, OprfClientBlindResult, OprfServer};
#[cfg(feature = "alloc")]
pub use crate::poprf::PoprfServerBatchEvaluateResult;
pub use crate::poprf::{
PoprfClient, PoprfClientBatchFinalizeResult, PoprfPreparedTweak, PoprfServer,
PoprfServerBatchEvaluateFinishResult, PoprfServerBatchEvaluateFinishedMessages,
PoprfServerBatchEvaluatePrepareResult, PoprfServerBatchEvaluatePreparedEvaluationElements,
};
2022-01-21 22:52:09 +01:00
pub use crate::serialization::{
2022-02-13 04:00:11 -08:00
BlindedElementLen, EvaluationElementLen, OprfClientLen, OprfServerLen, PoprfClientLen,
PoprfServerLen, ProofLen, VoprfClientLen, VoprfServerLen,
2022-01-21 22:52:09 +01:00
};
2022-02-13 04:00:11 -08:00
pub use crate::util::{BlindedElement, EvaluationElement, Mode, PreparedEvaluationElement, Proof};
2021-12-25 22:54:27 +01:00
#[cfg(feature = "alloc")]
2022-02-13 04:00:11 -08:00
pub use crate::voprf::VoprfServerBatchEvaluateResult;
2021-09-20 00:17:53 -07:00
pub use crate::voprf::{
2022-02-13 04:00:11 -08:00
VoprfClient, VoprfClientBatchFinalizeResult, VoprfClientBlindResult, VoprfServer,
VoprfServerBatchEvaluateFinishResult, VoprfServerBatchEvaluateFinishedMessages,
VoprfServerBatchEvaluatePreparedEvaluationElements, VoprfServerEvaluateResult,
2021-09-20 00:17:53 -07:00
};