The mask that helps the attacker: a mechanism, not a bug¶
scripts/masking_mechanism.py, datasets/results/masking-mechanism.json. Closes the open item
"explain the non-monotonicity in noise", which survived the move to the 77-client pool and so was
not the finite-pool artefact I had guessed.
The detector scores a cosine, and a cosine is scale free: a mask cannot hurt it by shortening the
difference vector, only by turning it. Adding an isotropic mask n to a difference v attenuates
the cosine by about ||v|| / sqrt(||v||^2 + ||n||^2), which depends on v's own length -- and the
two classes differ in exactly that length. A member round's difference carries the target's update
at 1/size; a non-member round's carries only which outsiders happened to be drawn. Averaging over
rounds removes the sampling term from both, so the member class keeps a length and the null class
loses one, and the same mask deflates the null further.
Measured on the C++ clients, AOSP the target, five redraws per cell:
| rounds | attenuation, member | attenuation, null | unmasked AUC | AUC at a 1x mask |
|---|---|---|---|---|
| 1 | 0.632 | 0.629 | 0.607 (sd 0.020) | 0.597 |
| 10 | 0.653 | 0.627 | 0.791 (sd 0.028) | 0.797 |
| 50 | 0.725 | 0.627 | 0.941 (sd 0.008) | 0.959 |
| 200 | 0.844 | 0.627 | 0.991 (sd 0.003) | 0.999 |
The null's attenuation is constant at 0.627 and the member's climbs to 0.844: the gap is the whole effect, and it appears only where averaging has done its work. At one round there is no gap and no rise. A per-draw model -- attenuate each draw by its own length and add the mask's projection on the reference direction -- predicts every cell within 0.01, including the rise at 200 rounds (0.998 predicted against 0.999 measured) and the collapse at a 16x mask (0.954 against 0.959).
What it means for the defence claim. Masking is not merely a delay against this attacker; below some size it is worse than nothing, because it removes the null draws whose difference vector was too short to point anywhere reliably -- the very draws that produced the attacker's false alarms. A defence evaluated against a scale-free statistic must be reported this way, and the finding generalises past this study: a cosine detector is the wrong thing to calibrate a noise budget against.
Two things this does not say. The updates replayed are one round's, so rounds measures the
arithmetic of averaging and not a source's persistence across a moving global model. And the mask
here is per round with no composition, so it is not a differential privacy guarantee, whose
accounting would grow the noise with the rounds rather than hold it fixed.
Incidental, and worth keeping: the first pass of this script read one draw per cell and reported a 0.05 swing between RNG streams as an effect. Repeats were added before any number here was written down.
Read by a statistic that is not scale free (same draws, the difference's projection on the reference direction rather than its cosine):
| rounds | mask | cosine AUC | projection AUC |
|---|---|---|---|
| 50 | none | 0.939 | 0.963 |
| 50 | 1x | 0.959 | 0.968 |
| 50 | 4x | 0.951 | 0.952 |
| 50 | 16x | 0.800 | 0.800 |
| 200 | none | 0.992 | 1.000 |
| 200 | 1x | 0.999 | 1.000 |
| 200 | 4x | 0.999 | 1.000 |
| 200 | 16x | 0.959 | 0.959 |
Two things follow. The projection is the stronger attacker wherever the two differ, by 0.024 at 50 rounds and 0.008 at 200, so normalising threw information away: the leakage this study reports with a cosine is a lower bound on what the same observations allow. And under the stronger statistic the curve is monotone at 200 rounds and nearly so at 50 (a 0.005 rise at a 1x mask, about one standard deviation), which places most of the anomaly in the statistic rather than in the defence. The honest statement is therefore narrower than the one above: masking degrades this attacker monotonically once the attacker stops discarding the difference's length, and the striking non-monotonicity belongs to the scale-free reading of it.
This applies to the difference statistic the defence curve scores. The aggregate attack's detector is a different quantity -- the cosine between one round's aggregate and a reference direction, where no subtraction has removed the outsiders -- and whether it too leaves information on the table is not measured here.