Skip to content

Commit

Permalink
Eliminate prio2 Cargo feature (#903)
Browse files Browse the repository at this point in the history
* Eliminate prio2 Cargo feature

* Update doc(cfg) attributes
  • Loading branch information
divergentdave authored Jan 12, 2024
1 parent ee64547 commit 2900fec
Show file tree
Hide file tree
Showing 13 changed files with 57 additions and 80 deletions.
1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ zipf = "7.0.1"
default = ["crypto-dependencies"]
experimental = ["bitvec", "fiat-crypto", "fixed", "num-bigint", "num-rational", "num-traits", "num-integer", "num-iter", "rand"]
multithreaded = ["rayon"]
prio2 = ["crypto-dependencies"]
crypto-dependencies = ["aes", "ctr", "hmac", "sha2"]
test-util = ["hex", "rand", "serde_json"]

Expand Down
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,3 @@ This crate defines the following feature flags:
|`crypto-dependencies`|Yes|Enables dependencies on various RustCrypto crates, and uses them to implement `XofTurboShake128` to support VDAFs.|
|`experimental`|No|Certain experimental APIs are guarded by this feature. They may undergo breaking changes in future patch releases, as an exception to semantic versioning.|
|`multithreaded`|No|Enables certain Prio3 VDAF implementations that use `rayon` for parallelization of gadget evaluations.|
|`prio2`|No|Enables the Prio v2 API, and a VDAF based on the Prio2 system.|
59 changes: 19 additions & 40 deletions benches/cycle_counts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@ use iai::black_box;
#[cfg(feature = "experimental")]
use prio::{
codec::{Decode, Encode, ParameterizedDecode},
field::{Field255, FieldElement},
field::{Field255, FieldElement, FieldPrio2},
idpf::{Idpf, IdpfInput, IdpfPublicShare, RingBufferCache},
vdaf::{poplar1::Poplar1IdpfValue, xof::Seed},
};
#[cfg(feature = "prio2")]
use prio::{
field::FieldPrio2,
vdaf::{
poplar1::Poplar1IdpfValue,
prio2::{Prio2, Prio2PrepareShare},
xof::Seed,
Aggregator, Share,
},
};
Expand Down Expand Up @@ -45,30 +42,30 @@ fn prng_4096() -> Vec<Field128> {
prng(4096)
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_client(size: usize) -> Vec<Share<FieldPrio2, 32>> {
let prio2 = Prio2::new(size).unwrap();
let input = vec![0u32; size];
let nonce = [0; 16];
prio2.shard(&black_box(input), &black_box(nonce)).unwrap().1
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_client_10() -> Vec<Share<FieldPrio2, 32>> {
prio2_client(10)
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_client_100() -> Vec<Share<FieldPrio2, 32>> {
prio2_client(100)
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_client_1000() -> Vec<Share<FieldPrio2, 32>> {
prio2_client(1000)
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare(size: usize) -> Prio2PrepareShare {
let prio2 = Prio2::new(size).unwrap();
let input = vec![0u32; size];
Expand All @@ -80,17 +77,17 @@ fn prio2_shard_and_prepare(size: usize) -> Prio2PrepareShare {
.1
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare_10() -> Prio2PrepareShare {
prio2_shard_and_prepare(10)
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare_100() -> Prio2PrepareShare {
prio2_shard_and_prepare(100)
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare_1000() -> Prio2PrepareShare {
prio2_shard_and_prepare(1000)
}
Expand Down Expand Up @@ -261,34 +258,10 @@ macro_rules! main_base {
};
}

#[cfg(feature = "prio2")]
macro_rules! main_add_prio2 {
( $( $func_name:ident ),* $(,)* ) => {
main_base!(
prio2_client_10,
prio2_client_100,
prio2_client_1000,
prio2_shard_and_prepare_10,
prio2_shard_and_prepare_100,
prio2_shard_and_prepare_1000,
$( $func_name, )*
);
};
}

#[cfg(not(feature = "prio2"))]
macro_rules! main_add_prio2 {
( $( $func_name:ident ),* $(,)* ) => {
main_base!(
$( $func_name, )*
);
};
}

#[cfg(feature = "multithreaded")]
macro_rules! main_add_multithreaded {
( $( $func_name:ident ),* $(,)* ) => {
main_add_prio2!(
main_base!(
prio3_client_count_vec_multithreaded_1000,
$( $func_name, )*
);
Expand All @@ -298,7 +271,7 @@ macro_rules! main_add_multithreaded {
#[cfg(not(feature = "multithreaded"))]
macro_rules! main_add_multithreaded {
( $( $func_name:ident ),* $(,)* ) => {
main_add_prio2!(
main_base!(
$( $func_name, )*
);
};
Expand All @@ -308,6 +281,12 @@ macro_rules! main_add_multithreaded {
macro_rules! main_add_experimental {
( $( $func_name:ident ),* $(,)* ) => {
main_add_multithreaded!(
prio2_client_10,
prio2_client_100,
prio2_client_1000,
prio2_shard_and_prepare_10,
prio2_shard_and_prepare_100,
prio2_shard_and_prepare_1000,
idpf_codec,
idpf_poplar_gen_8,
idpf_poplar_gen_128,
Expand Down
12 changes: 4 additions & 8 deletions benches/speed_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use num_rational::Ratio;
use num_traits::ToPrimitive;
#[cfg(feature = "experimental")]
use prio::dp::distributions::DiscreteGaussian;
#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
use prio::vdaf::prio2::Prio2;
use prio::{
benchmarked::*,
Expand Down Expand Up @@ -116,7 +116,7 @@ fn poly_mul(c: &mut Criterion) {
}

/// Benchmark prio2.
#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn prio2(c: &mut Criterion) {
let mut group = c.benchmark_group("prio2_shard");
for input_length in [10, 100, 1_000] {
Expand Down Expand Up @@ -864,13 +864,9 @@ fn poplar1_generate_zipf_distributed_batch(
(samples, prefix_tree)
}

#[cfg(all(feature = "prio2", feature = "experimental"))]
#[cfg(feature = "experimental")]
criterion_group!(benches, poplar1, prio3, prio2, poly_mul, prng, idpf, dp_noise);
#[cfg(all(not(feature = "prio2"), feature = "experimental"))]
criterion_group!(benches, poplar1, prio3, poly_mul, prng, idpf, dp_noise);
#[cfg(all(feature = "prio2", not(feature = "experimental")))]
criterion_group!(benches, prio3, prio2, prng, poly_mul);
#[cfg(all(not(feature = "prio2"), not(feature = "experimental")))]
#[cfg(not(feature = "experimental"))]
criterion_group!(benches, prio3, prng, poly_mul);

criterion_main!(benches);
2 changes: 1 addition & 1 deletion binaries/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ repository = "https://github.com/divviup/libprio-rs"
base64 = "0.21.6"
fixed = "1.23"
fixed-macro = "1.2.0"
prio = { path = "..", features = ["prio2", "experimental"] }
prio = { path = "..", features = ["experimental"] }
3 changes: 3 additions & 0 deletions src/flp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ pub trait Type: Sized + Eq + Clone + Debug {

/// A type which supports adding noise to aggregate shares for Server Differential Privacy.
#[cfg(feature = "experimental")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
pub trait TypeWithNoise<S>: Type
where
S: DifferentialPrivacyStrategy,
Expand Down Expand Up @@ -749,11 +750,13 @@ pub(crate) fn gadget_poly_len(gadget_degree: usize, wire_poly_len: usize) -> usi

/// Utilities for testing FLPs.
#[cfg(feature = "test-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
pub mod test_utils {
use super::*;
use crate::field::{random_vector, FieldElement, FieldElementWithInteger};

/// Various tests for an FLP.
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
pub struct FlpTest<'a, T: Type> {
/// The FLP.
pub flp: &'a T,
Expand Down
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
pub mod benchmarked;
pub mod codec;
#[cfg(feature = "experimental")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
pub mod dp;
mod fft;
pub mod field;
Expand Down
4 changes: 2 additions & 2 deletions src/polynomial.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

//! Functions for polynomial interpolation and evaluation

#[cfg(feature = "prio2")]
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
use crate::fft::{discrete_fourier_transform, discrete_fourier_transform_inv_finish};
use crate::field::FftFriendlyFieldElement;

Expand Down Expand Up @@ -204,7 +204,7 @@ pub fn poly_mul<F: FftFriendlyFieldElement>(p: &[F], q: &[F]) -> Vec<F> {
out
}

#[cfg(feature = "prio2")]
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
#[inline]
pub fn poly_interpret_eval<F: FftFriendlyFieldElement>(
points: &[F],
Expand Down
22 changes: 10 additions & 12 deletions src/prng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
//! NOTE: The public API for this module is a work in progress.

use crate::field::{FieldElement, FieldElementExt};
#[cfg(feature = "prio2")]
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
use crate::vdaf::xof::SeedStreamAes128;
use crate::vdaf::xof::{Seed, SeedStreamTurboShake128, Xof, XofTurboShake128};
use rand_core::RngCore;
Expand Down Expand Up @@ -35,7 +35,7 @@ pub(crate) struct Prng<F, S> {
buffer_index: usize,
}

#[cfg(feature = "prio2")]
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
impl<F: FieldElement> Prng<F, SeedStreamAes128> {
/// Create a [`Prng`] from a seed for Prio 2. The first 16 bytes of the seed and the last 16
/// bytes of the seed are used, respectively, for the key and initialization vector for AES128
Expand Down Expand Up @@ -131,21 +131,19 @@ where
mod tests {
use super::*;
#[cfg(feature = "experimental")]
use crate::field::Field128;
#[cfg(feature = "prio2")]
use crate::field::{encode_fieldvec, FieldPrio2};
use crate::field::{encode_fieldvec, Field128, FieldPrio2};
use crate::{
codec::Decode,
field::Field64,
vdaf::xof::{Seed, SeedStreamTurboShake128, Xof, XofTurboShake128},
};
#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
use base64::{engine::Engine, prelude::BASE64_STANDARD};
#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
use sha2::{Digest, Sha256};

#[test]
#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn secret_sharing_interop() {
let seed = [
0xcd, 0x85, 0x5b, 0xd4, 0x86, 0x48, 0xa4, 0xce, 0x52, 0x5c, 0x36, 0xee, 0x5a, 0x71,
Expand All @@ -167,22 +165,22 @@ mod tests {
}

/// takes a seed and hash as base64 encoded strings
#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn random_data_interop(seed_base64: &str, hash_base64: &str, len: usize) {
let seed = BASE64_STANDARD.decode(seed_base64).unwrap();
let random_data = extract_share_from_seed::<FieldPrio2>(len, &seed);

let mut random_bytes = Vec::new();
encode_fieldvec(&random_data, &mut random_bytes).unwrap();

let mut hasher = Sha256::new();
let mut hasher = <Sha256 as Digest>::new();
hasher.update(&random_bytes);
let digest = hasher.finalize();
assert_eq!(BASE64_STANDARD.encode(digest), hash_base64);
}

#[test]
#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn test_hash_interop() {
random_data_interop(
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=",
Expand Down Expand Up @@ -216,7 +214,7 @@ mod tests {
);
}

#[cfg(feature = "prio2")]
#[cfg(feature = "experimental")]
fn extract_share_from_seed<F: FieldElement>(length: usize, seed: &[u8]) -> Vec<F> {
assert_eq!(seed.len(), 32);
Prng::from_prio2_seed(seed.try_into().unwrap())
Expand Down
22 changes: 8 additions & 14 deletions src/vdaf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,18 +72,6 @@ pub enum Share<F, const SEED_SIZE: usize> {
Helper(Seed<SEED_SIZE>),
}

impl<F: Clone, const SEED_SIZE: usize> Share<F, SEED_SIZE> {
/// Truncate the Leader's share to the given length. If this is the Helper's share, then this
/// method clones the input without modifying it.
#[cfg(feature = "prio2")]
pub(crate) fn truncated(&self, len: usize) -> Self {
match self {
Self::Leader(ref data) => Self::Leader(data[..len].to_vec()),
Self::Helper(ref seed) => Self::Helper(seed.clone()),
}
}
}

impl<F: ConstantTimeEq, const SEED_SIZE: usize> PartialEq for Share<F, SEED_SIZE> {
fn eq(&self, other: &Self) -> bool {
self.ct_eq(other).into()
Expand Down Expand Up @@ -300,6 +288,7 @@ pub trait Aggregator<const VERIFY_KEY_SIZE: usize, const NONCE_SIZE: usize>: Vda

/// Aggregator that implements differential privacy with Aggregator-side noise addition.
#[cfg(feature = "experimental")]
#[cfg_attr(docsrs, doc(cfg(feature = "experimental")))]
pub trait AggregatorWithNoise<
const VERIFY_KEY_SIZE: usize,
const NONCE_SIZE: usize,
Expand Down Expand Up @@ -712,17 +701,22 @@ mod tests {
}

#[cfg(feature = "test-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
pub mod dummy;
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "crypto-dependencies", feature = "experimental")))
)]
pub mod poplar1;
#[cfg(feature = "prio2")]
#[cfg_attr(docsrs, doc(cfg(feature = "prio2")))]
#[cfg(all(feature = "crypto-dependencies", feature = "experimental"))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "crypto-dependencies", feature = "experimental")))
)]
pub mod prio2;
pub mod prio3;
#[cfg(any(test, feature = "test-util"))]
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
pub mod prio3_test;
pub mod xof;
7 changes: 6 additions & 1 deletion src/vdaf/prio2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,13 @@ impl Prio2 {
)
.map_err(|e| VdafError::Uncategorized(e.to_string()))?;

let truncated_share = match input_share {
Share::Leader(data) => Share::Leader(data[..self.input_len].to_vec()),
Share::Helper(seed) => Share::Helper(seed.clone()),
};

Ok((
Prio2PrepareState(input_share.truncated(self.input_len)),
Prio2PrepareState(truncated_share),
Prio2PrepareShare(verifier_share),
))
}
Expand Down
2 changes: 2 additions & 0 deletions src/vdaf/prio3_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ where
/// This version allows customizing the deserialization of measurements, via an additional type
/// parameter.
#[cfg(feature = "test-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
pub fn check_test_vec_custom_de<MS, MP, A, T, P, const SEED_SIZE: usize>(
test_vec_json_str: &str,
new_vdaf: impl Fn(&HashMap<String, serde_json::Value>, u8) -> Prio3<T, P, SEED_SIZE>,
Expand All @@ -213,6 +214,7 @@ pub fn check_test_vec_custom_de<MS, MP, A, T, P, const SEED_SIZE: usize>(
/// Evaluate a Prio3 test vector. The instance of Prio3 is constructed from the `new_vdaf` callback,
/// which takes in the VDAF parameters encoded by the test vectors and the number of shares.
#[cfg(feature = "test-util")]
#[cfg_attr(docsrs, doc(cfg(feature = "test-util")))]
pub fn check_test_vec<M, A, T, P, const SEED_SIZE: usize>(
test_vec_json_str: &str,
new_vdaf: impl Fn(&HashMap<String, serde_json::Value>, u8) -> Prio3<T, P, SEED_SIZE>,
Expand Down
Loading

0 comments on commit 2900fec

Please sign in to comment.