Marcin Pawlowski e9b79ce90a
blend: attribution evidence at the reported scale, and a figure for the timing study
Two gaps left by the previous review.

Section 3.4 quoted the attribution bracket at N=20,000 while the only committed
evidence carrying those columns was the timing run at N=2,000, so a reader diffing
report against data saw different numbers for the same quantity. Added
configs/attribution.yaml and a make target: it records both bounds and the graph
hop distance at the reported scale, cheaply, since the adversary and
deanonymization metrics are closed-form and the hop distance is a property of the
topology. It reproduces the section exactly -- L = 2.58 and neighbourhood
confidence 0.640 at degree 8, f_adv 0.2.

It also surfaces a result the smaller run could not: degree cuts both ways. A
sparser graph has longer routes, so it offers the adversary more upstream places
to see the message -- L is 4.18 at degree 4 against 1.93 at degree 16, lifting
neighbourhood confidence from 0.61 to 0.72. The low diameter that makes
propagation fast also starves the adversary, one of the few places where raising
the degree helps anonymity rather than hurting it.

Section 3.11 was the only section without a figure. Fig 25 plots MAP success
against the effective anonymity set for both release designs: the dashed sets
separate far faster than the solid best-guess curves, which is the whole argument
for not trusting perplexity alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 18:00:02 +02:00

64 lines
2.2 KiB
Makefile

VENV ?= .venv
PY := $(VENV)/bin/python
STAMP := $(VENV)/.installed
# Keep numpy/scipy BLAS single-threaded so joblib process parallelism doesn't oversubscribe.
export OMP_NUM_THREADS := 1
export OPENBLAS_NUM_THREADS := 1
export MKL_NUM_THREADS := 1
export NUMEXPR_NUM_THREADS := 1
.PHONY: install smoke sweep sweep-fullscale redundancy percolation correlated-churn cover-traffic timing attribution figures verify test lint clean
# The stamp is the real install; targets below depend on it so `make sweep` (etc.) auto-installs
# on a fresh checkout and re-installs whenever pyproject.toml changes.
$(STAMP): pyproject.toml
python3 -m venv $(VENV)
$(PY) -m pip install -U pip
$(PY) -m pip install -e ".[dev]"
@touch $(STAMP)
install: $(STAMP)
smoke: $(STAMP) ## fast end-to-end (seconds): tiny N, few rounds/seeds
$(PY) -m blend.sweep --config configs/smoke.yaml
sweep: $(STAMP)
$(PY) -m blend.sweep --config configs/default.yaml
sweep-fullscale: $(STAMP)
$(PY) -m blend.sweep --config configs/fullscale.yaml
redundancy: $(STAMP) ## messaging redundancy R=1..4 (delivery vs deanonymization, time-to-link)
$(PY) -m blend.sweep --config configs/redundancy.yaml
percolation: $(STAMP) ## churn threshold: coverage collapse at u_c = 1 - 1/(degree-1)
$(PY) -m blend.sweep --config configs/percolation.yaml
attribution: $(STAMP) ## attribution confidence: the local bound and the neighbourhood bound
$(PY) -m blend.sweep --config configs/attribution.yaml
cover-traffic: $(STAMP) ## cover traffic: blending, mixing, and the emission-quota ceiling
$(PY) -m blend.sweep --config configs/cover-traffic.yaml
timing: $(STAMP) ## release designs under a timing attack (jitter vs clock tick)
$(PY) -m blend.sweep --config configs/timing.yaml
correlated-churn: $(STAMP) ## correlated AS/region outages vs uniform churn, matched fractions
$(PY) -m blend.sweep --config configs/correlated-churn.yaml
figures: $(STAMP) ## make figures RUN=runs/<dir>
$(PY) -m blend.plotting.make_figures --run $(RUN)
verify: $(STAMP)
$(PY) -m blend.verify
test: $(STAMP)
$(PY) -m pytest
lint: $(STAMP)
$(VENV)/bin/ruff check src scripts tests
clean:
rm -rf runs/* figures/* .pytest_cache .ruff_cache .mypy_cache