Skip to content

Commit

Permalink
Add differential privacy to FixedPointBoundedL2VecSum (divviup#578).
Browse files Browse the repository at this point in the history
Co-Authored-By: Olivia <ovi@posteo.de>
Co-Authored-By: Maxim Urschumzew <u.maxim@live.de>
  • Loading branch information
MxmUrw and ooovi committed Aug 25, 2023
1 parent d45bf21 commit 81306a0
Show file tree
Hide file tree
Showing 20 changed files with 1,488 additions and 162 deletions.
18 changes: 18 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 12 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ fiat-crypto = { version = "0.1.20", optional = true }
fixed = { version = "1.23", optional = true }
getrandom = { version = "0.2.10", features = ["std"] }
hmac = { version = "0.12.1", optional = true }
num-bigint = { version = "0.4.3", optional = true, features = ["rand", "serde"] }
num-integer = { version = "0.1.45", optional = true }
num-iter = { version = "0.1.43", optional = true }
num-rational = { version = "0.4.1", optional = true }
num-traits = { version = "0.2.15", optional = true }
rand = { version = "0.8", optional = true }
rand_core = "0.6.4"
rayon = { version = "1.7.0", optional = true }
serde = { version = "1.0", features = ["derive"] }
Expand Down Expand Up @@ -50,7 +56,7 @@ zipf = "7.0.1"

[features]
default = ["crypto-dependencies"]
experimental = ["bitvec", "fiat-crypto", "fixed"]
experimental = ["bitvec", "fiat-crypto", "fixed", "num-bigint", "num-rational", "num-traits", "num-integer", "num-iter", "rand"]
multithreaded = ["rayon"]
prio2 = ["crypto-dependencies", "hmac", "sha2"]
crypto-dependencies = ["aes", "ctr", "cmac"]
Expand All @@ -69,6 +75,11 @@ harness = false
name = "cycle_counts"
harness = false

[[test]]
name = "discrete_gauss"
path = "tests/discrete_gauss.rs"
required-features = ["experimental"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
Expand Down
71 changes: 61 additions & 10 deletions benches/speed_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ use criterion::{BatchSize, Throughput};
use fixed::types::{I1F15, I1F31};
#[cfg(feature = "experimental")]
use fixed_macro::fixed;
#[cfg(feature = "experimental")]
use num_bigint::BigUint;
#[cfg(feature = "experimental")]
use num_rational::Ratio;
#[cfg(feature = "experimental")]
use num_traits::ToPrimitive;
#[cfg(feature = "experimental")]
use prio::dp::distributions::DiscreteGaussian;
#[cfg(feature = "multithreaded")]
use prio::flp::gadgets::ParallelSumMultithreaded;
#[cfg(feature = "prio2")]
use prio::vdaf::prio2::Prio2;
use prio::{
Expand Down Expand Up @@ -49,6 +59,30 @@ fn prng(c: &mut Criterion) {
group.finish();
}

/// Speed test for generating samples from the discrete gaussian distribution using different
/// standard deviations.
#[cfg(feature = "experimental")]
pub fn dp_noise(c: &mut Criterion) {
let mut group = c.benchmark_group("dp_noise");
let mut rng = StdRng::seed_from_u64(RNG_SEED);

let test_stds = [
Ratio::<BigUint>::from_integer(BigUint::from(u128::MAX)).pow(2),
Ratio::<BigUint>::from_integer(BigUint::from(u64::MAX)),
Ratio::<BigUint>::from_integer(BigUint::from(u32::MAX)),
Ratio::<BigUint>::from_integer(BigUint::from(5u8)),
Ratio::<BigUint>::new(BigUint::from(10000u32), BigUint::from(23u32)),
];
for std in test_stds {
let sampler = DiscreteGaussian::new(std.clone()).unwrap();
group.bench_function(
BenchmarkId::new("discrete_gaussian", std.to_f64().unwrap_or(f64::INFINITY)),
|b| b.iter(|| sampler.sample(&mut rng)),
);
}
group.finish();
}

/// The asymptotic cost of polynomial multiplication is `O(n log n)` using FFT and `O(n^2)` using
/// the naive method. This benchmark demonstrates that the latter has better concrete performance
/// for small polynomials. The result is used to pick the `FFT_THRESHOLD` constant in
Expand Down Expand Up @@ -312,7 +346,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("serial", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum(num_shares, *dimension).unwrap();
let mut measurement = vec![fixed!(0: I1F15); *dimension];
measurement[0] = fixed!(0.5: I1F15);
Expand All @@ -329,7 +363,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("parallel", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum_multithreaded(
num_shares, *dimension,
)
Expand All @@ -350,7 +384,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("series", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum(num_shares, *dimension).unwrap();
let mut measurement = vec![fixed!(0: I1F15); *dimension];
measurement[0] = fixed!(0.5: I1F15);
Expand Down Expand Up @@ -379,7 +413,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("parallel", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F15, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum_multithreaded(
num_shares, *dimension,
)
Expand Down Expand Up @@ -413,7 +447,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("serial", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum(num_shares, *dimension).unwrap();
let mut measurement = vec![fixed!(0: I1F31); *dimension];
measurement[0] = fixed!(0.5: I1F31);
Expand All @@ -430,7 +464,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("parallel", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum_multithreaded(
num_shares, *dimension,
)
Expand All @@ -451,7 +485,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("series", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum(num_shares, *dimension).unwrap();
let mut measurement = vec![fixed!(0: I1F31); *dimension];
measurement[0] = fixed!(0.5: I1F31);
Expand Down Expand Up @@ -480,7 +514,7 @@ fn prio3(c: &mut Criterion) {
BenchmarkId::new("parallel", dimension),
&dimension,
|b, dimension| {
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _, _>, _, 16> =
let vdaf: Prio3<FixedPointBoundedL2VecSum<I1F31, _, _>, _, 16> =
Prio3::new_fixedpoint_boundedl2_vec_sum_multithreaded(
num_shares, *dimension,
)
Expand Down Expand Up @@ -737,9 +771,26 @@ fn poplar1_generate_zipf_distributed_batch(
}

#[cfg(all(feature = "prio2", feature = "experimental"))]
criterion_group!(benches, poplar1, prio3, prio2, poly_mul, prng, idpf);
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);
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")))]
Expand Down
1 change: 1 addition & 0 deletions binaries/src/bin/vdaf_message_sizes.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use fixed::{types::extra::U15, FixedI16};
use fixed_macro::fixed;

use prio::{
codec::Encode,
vdaf::{
Expand Down
Loading

0 comments on commit 81306a0

Please sign in to comment.