Setup
- 5 synthetic users, each with a throwaway wallet and its own key vault.
- Each writes 10 records through one relayer (
k = 5, max wait 30 s, at least 5 blocks between flushes), with the SDK’s normal behaviour: one record in flight per user and a random 0–15 s delay before each submission. - Every record has the same app attribute and a JSON payload with 0–60 bytes of random filler, so raw sizes differ.
- The ground truth (who wrote what) is kept only by the test, never on Arkiv.
tests/phase3.ts,
observer: tests/observer.ts.
What the observer reads
Only public data:The attack
Records are grouped into batches by transaction. For each record in batch t, the observer guesses which record in batch t+1 belongs to the same person, using the best signal available, in order:- the same
$owner(a reused address); - the same position inside the transaction;
- the same payload size and the same lifetime.
Results
With owners never reused, sizes padded, lifetimes bucketed and order shuffled, the only signal left
is position, and shuffling makes position random. The observer’s precision sits around chance; with
45 pairs per run, single runs scatter on either side of it.
Related evidence
The repository’s on-chain edge-case suite (27 checks) also passes on Tiramisu, including:- no read made by a client names the user’s record keys or owners;
- a second device finds every record with nothing but the wallet;
- a relayer that tampers, misdirects or crashes after writing is caught without duplicates;
minAnonymityholds or refuses small batches;- requests through the OHTTP relay never reach the relayer directly.
What this does not show
- The relayer itself sees request times and, without OHTTP, IP addresses. This experiment is about outside observers.
- Anonymity is per batch. In quiet periods a batch can be smaller than
k;minAnonymityrefuses small batches when the user asks. - Content can identify a person on its own.
check()warns but cannot catch everything. - Five users is a small population. The bound is the batch size: from these signals an observer cannot do better than one in the batch size.