Skip to main content
We measured whether an outside observer, reading only public chain data, can tell which Arkognito records were written by the same person. Runs were on the Tiramisu testnet in October 2026.

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.
Script: 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:
  1. the same $owner (a reused address);
  2. the same position inside the transaction;
  3. the same payload size and the same lifetime.
Precision is the share of guessed pairs that really belong to one person.

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. 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;
  • minAnonymity holds or refuses small batches;
  • requests through the OHTTP relay never reach the relayer directly.
See the edge-case register.

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; minAnonymity refuses 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.
Last modified on October 12, 2026