Marcin Pawlowski fb49a790fc
blend: make sections 3.11 and the attribution bracket reproducible
Review finding: the timing study and the neighbourhood-confidence numbers were
produced by ad-hoc analysis, not by the simulator. timing_linkability,
neighbourhood_confidence and mean_upstream_hops had no callers outside their own
modules; min_blend_delay and release_mode were declared on SweepConfig, validated
and keyed, but never read by sweep.py, so a YAML setting them was silently
ignored; and propagation.py called mix_wait without the minimum, leaving the knob
inert on the delay tables of 3.1-3.2. Section 6 promised every number was
reproducible and data/README claimed to hold the evidence behind every number --
both were false for 3.11.

Now wired end to end: release_designs() is a real sweep axis, the engine measures
the timing attack per design and records it in traffic.parquet, and the deanon
table carries the full attribution bracket (local confidence, attributable
fractions, upstream hops, neighbourhood confidence). Added configs/timing.yaml
and a make target.

The committed sweep reproduces 3.11: MAP success 0.993/0.905/0.683 for clock and
0.989/0.832/0.550 for jitter across the swept rates, and the minimum interval
changes nothing (0.993 vs 0.993). Evidence checked in under data/timing.

Three regression tests pin the wiring so a measure cannot go back to living only
in analysis.

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

31 lines
1.3 KiB
YAML

# Release designs under a timing attack (report section 3.11).
#
# A blend relay holds a message and re-emits it; a node merely forwarding passes it straight
# through. If that delay is visible so is the relay's role, and matching an outgoing message to the
# incoming one links both ends of a hop. This sweeps the two ways of delaying at a MATCHED latency
# budget, so they differ only in HOW they delay:
#
# clock -- the free-running tick: everything held leaves together at the next tick.
# jitter -- each message waits its own independent draw, same mean as the clock's residual.
#
# min_blend_delay 0 vs 1 tests whether forbidding instant re-release buys anything. It should not:
# a zero-length gap is instantaneous, so it never covers an arrival and is never sampled.
#
# The rate is swept because section 3.10 predicts the answer is dominated by traffic, not delay --
# a relay holding ~one message has nothing to be confused with under either design.
n_nodes: [2000]
degree: [8]
blend_hops: [3]
max_blend_delay: [30]
min_blend_delay: [0, 1]
release_mode: [clock, jitter]
cover_rate_mult: [1.0, 16.0, 64.0]
unresponsive_frac: [0.0]
f_adv: [0.2]
adversary_mode: [random]
seeds: 3
base:
traffic_window_slots: 120
n_rounds: 10 # propagation is not the subject here
n_placements: 1