diff --git a/CHANGELOG.md b/CHANGELOG.md index b87ad198..f76d4046 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] +## [0.9.27] - 2024-12-11 +### Fixed +- Fix gaussian tau. + ## [0.9.26] - 2024-12-05 ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 76d25acd..00d016a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] authors = ["Nicolas Grislain "] name = "qrlew" -version = "0.9.26" +version = "0.9.27" edition = "2021" description = "Sarus Qrlew Engine" documentation = "https://docs.rs/qrlew" @@ -34,7 +34,7 @@ r2d2_postgres = "0.18" rust_decimal = { version = "1.35", features = [ "tokio-pg" ] } statrs = "0.16.0" sqlx = { version = "0.6.3", features = ["mssql", "runtime-tokio-native-tls", "offline", "any"], optional = true } -tokio = { version = "1", features = ["full"], optional = true } +tokio = { version = "1.37.0", features = ["full"], optional = true } # bigquery dependencies gcp-bigquery-client = { version = "=0.20.0", optional = true } diff --git a/src/differential_privacy/dp_event.rs b/src/differential_privacy/dp_event.rs index bb428b8a..31345a57 100644 --- a/src/differential_privacy/dp_event.rs +++ b/src/differential_privacy/dp_event.rs @@ -1,8 +1,5 @@ use itertools::Itertools; -use statrs::{ - distribution::{ContinuousCDF, Normal}, - prec::F64_PREC, -}; +use statrs::distribution::{ContinuousCDF, Normal}; use std::fmt; /// An object inspired by Google's [DPEvent](https://github.com/google/differential-privacy/blob/main/python/dp_accounting/dp_event.py) @@ -169,9 +166,9 @@ pub fn gaussian_noise_multiplier(epsilon: f64, delta: f64) -> f64 { ((2. * (1.25_f64 / delta).ln()).sqrt() / epsilon).clamp(0.0, f64::MAX) } -pub fn gaussian_tau(epsilon: f64, delta: f64, sensitivity: f64) -> f64 { +pub fn gaussian_tau(epsilon: f64, delta: f64, max_privacy_unit_groups: f64) -> f64 { let dist = Normal::new(0.0, 1.0).unwrap(); - let scale = gaussian_noise(epsilon, delta, sensitivity); + let scale = gaussian_noise(epsilon, delta, max_privacy_unit_groups.sqrt()); // TODO: we want to overestimate tau - 1. + scale * dist.inverse_cdf((1. - delta / 2.).powf(1. / sensitivity)) + F64_PREC + 1. + scale * dist.inverse_cdf((1. - delta).powf(1. / max_privacy_unit_groups)) } diff --git a/src/differential_privacy/dp_parameters.rs b/src/differential_privacy/dp_parameters.rs index de623413..3cd389c3 100644 --- a/src/differential_privacy/dp_parameters.rs +++ b/src/differential_privacy/dp_parameters.rs @@ -39,7 +39,7 @@ impl DpParameters { pub fn from_epsilon_delta(epsilon: f64, delta: f64) -> DpParameters { // These default values are underestimating the bounds - DpParameters::new(epsilon, delta, 0.5, 100.0, 0.1, 1) + DpParameters::new(epsilon, delta, 0.5, 100.0, 0.1, 5) } pub fn with_tau_thresholding_share(self, tau_thresholding_share: f64) -> DpParameters { diff --git a/src/differential_privacy/group_by.rs b/src/differential_privacy/group_by.rs index fb26ff2e..58877734 100644 --- a/src/differential_privacy/group_by.rs +++ b/src/differential_privacy/group_by.rs @@ -107,7 +107,7 @@ impl PupRelation { // Apply noise let name_sigmas = vec![( COUNT_DISTINCT_PID, - dp_event::gaussian_noise(epsilon, delta, max_privacy_unit_groups as f64), + dp_event::gaussian_noise(epsilon, delta, (max_privacy_unit_groups as f64).sqrt()), )]; let rel = rel.add_gaussian_noise(&name_sigmas);