Skip to content

Privacy budgets

The platform represents each privacy allowance as one frozen value object:

  • PureDPBudget(eps)
  • ApproxDPBudget(eps, delta)
  • ZCDPBudget(rho)

Algorithms receive the allowance through one interface:

run(metadata, input, budget: DPBudget, seed: int)

Budget objects have no arithmetic or conversion methods. They remain typed through delegation and composition; a mechanism extracts a bare epsilon or rho only where it performs the corresponding privacy arithmetic.

Spending across privacy families

dp_testing_platform.core.accounting is the single conversion boundary. A mechanism may spend an offered allowance only by realizing a guarantee that implies the offered family.

Offered allowance Pure-DP mechanism zCDP mechanism Gaussian mechanism
PureDPBudget(eps) spend eps refused refused
ApproxDPBudget(eps, delta) spend eps; delta remains unused spend the largest rho admitted by the implemented sound conversion analytic-Gaussian calibration
ZCDPBudget(rho) spend sqrt(2*rho) spend rho sigma = sensitivity / sqrt(2*rho)

The helpers are accounting.spend_as_pure, accounting.spend_as_zcdp, and accounting.calibrate_gaussian_sigma. Unsupported directions raise instead of silently weakening the guarantee. Native approximate-DP mechanisms whose theorem does not pass through one of these conversions require ApproxDPBudget directly.

The pure-DP-to-zCDP and Gaussian-to-zCDP rows follow Bun and Steinke, “Concentrated Differential Privacy”, Propositions 1.4 and 1.6. Approximate-DP Gaussian calibration follows Balle and Wang, “Improving the Gaussian Mechanism for Differential Privacy”.

Constructing evaluation grids

Concrete budgets are the primary engine axis:

from dp_testing_platform import (
    ApproxDPBudget,
    PureDPBudget,
    ZCDPBudget,
    run_experiment,
)

budgets = [
    PureDPBudget(1.0),
    ApproxDPBudget(1.0, 1e-5),
    ZCDPBudget(0.5),
]

results = run_experiment(
    task,
    algorithms,
    instance_generators,
    budgets=budgets,
)

The CLI flags --epsilons and --deltas are convenience syntax. An omitted delta, or a delta of zero, constructs a pure-DP budget; a positive delta constructs an approximate-DP budget. Identical realized budgets are deduplicated while preserving their first occurrence.

Budgets may depend on public instance metadata. For example, a caller can construct ApproxDPBudget(eps, 1 / metadata.n_samples**2). The engine stores the concrete allowance that each cell actually received; it does not persist or infer a budget rule.

Result identity

Each result records the canonical dataclass representation in budget, for example PureDPBudget(eps=1.0) or ZCDPBudget(rho=0.5). That string is the privacy-budget part of row identity and of the output-sidecar key. The non-identity convenience columns budget_family, eps, delta, and rho make filtering and plotting easy; parameters that do not apply to a family are blank. Never reconstruct identity from those convenience columns. Budget class and field names are therefore storage-schema elements; renaming one requires an explicit migration of persisted records.

Our class-based budget setup is similar to that employed by Tumult Analytics.