anonsurv · proof of concept

Share the genome,
not the name.

An open, low-cost protocol that lets food companies send pathogen genomes to public health anonymously but with proof that they are authorised, and get a private warning back if their strain matches human cases. No blockchain, no licences, only open standards.

View the code on GitHub

The problem

Food companies isolate and increasingly sequence Listeria, Salmonella, STEC and other pathogens from their plants and products. A plant isolate that matches human cases is often the strongest evidence in an outbreak investigation. Yet these genomes rarely reach public health: once a sequence can be attributed to a company, it can bring inspections, recalls, liability and bad press.

Today the data arrive only when authorities ask for them during an investigation. By then, the early-warning value is gone. Anonymising through a trusted intermediary helps, but anonymity then depends on that intermediary: if it can be compelled to disclose, anonymity is a promise, not a guarantee.

The idea. Make anonymity a property of the protocol, not of whoever runs it. A company proves "I am an authorised food business" without saying which one, using cryptography standardised by the IETF.

Actors

contributor

Food company

Sequences isolates; wants early warning without being named.

gatekeeper

Issuer

Checks the company is in the official register; signs tokens it cannot read.

store

Platform

Accepts records with a valid, unused token. Stores no identity.

analysis

Public-health lab

Clusters records with human cases; sends encrypted alerts.

governance

Consortium

Independent bodies that audit the log and, optionally, can jointly lift anonymity.

How it works, step by step

Follow one cheese maker from enrolment to a private warning. Use the buttons or the ← → keys.

Step 1 of 10

The company logs in

A cheese maker in Abruzzo (region ITF1, category dairy) logs in to the issuer with its real identity. The issuer checks that it is in the official register of food establishments and that it has not used up its yearly quota (e.g. 50 tokens).

  • Food company sees its own identity
  • Issuer sees who the company is, how many tokens it asks for
  • Issuer does not see anything about future submissions
Step 2 of 10

Tokens are made at home

On its own computer the client draws 50 random tokens and, for each, a secret random number r. It seals each token in an “envelope”: b = token · rᵉ mod n. The tokens and the r values never leave the company.

  • Food company sees tokens and secret r values
  • Issuer does not see the tokens
  • Platform does not see anything yet
Step 3 of 10

The issuer signs without looking

The company sends the 50 envelopes. To the issuer they look like random numbers. It signs each one with its private key and sends them back, and records only one fact: “this company received 50 tokens”.

  • Issuer sees 50 random-looking envelopes, a counter
  • Issuer does not see the tokens, or the signatures the company will end up with
Step 4 of 10

The company opens the envelopes

Dividing by r removes the envelope and leaves a valid issuer signature on each token. The client checks each signature against the issuer’s single public key, published in the log, then throws r away. The tokens wait days or weeks before use, so times cannot be matched.

  • Food company sees 50 signed tokens
  • Issuer does not see which signed token came from which envelope: mathematically impossible
Step 5 of 10

An isolate is sequenced

Months later environmental monitoring finds Listeria. The contract lab sequences it and the client computes the cgMLST profile (1748 alleles). Metadata are reduced to species, month, region and category, and generalised if fewer than k = 5 companies share them. The client also makes a fresh key pair for this record only.

  • Food company sees everything about its isolate
  • Platform does not see the exact date, the plant, the product
Step 6 of 10

Anonymous submission

The client sends token, signature, profile, coarse metadata and the one-time public key through a relay that hides its network address. The platform checks the signature with the issuer’s public key, checks the token was never used, checks k-anonymity, then stores the record and appends its hash to the log.

  • Platform sees a valid token, a profile, ‘Listeria, 2026-10, ITF1, dairy’
  • Platform does not see who sent it
  • Issuer does not see that this token was spent by this company
Step 7 of 10

Public health clusters

The lab compares the profile with human cases. Here it is within 7 alleles of three patients, the cgMLST threshold for Listeria. The genome was not altered, so detection is as good as with identified data.

  • Public-health lab sees a record in a cluster with human cases
  • Public-health lab does not see which company it belongs to
Step 8 of 10

A private alert

The lab encrypts an alert to the one-time key that came with the record (HPKE) and posts it on a public bulletin. The ciphertext looks the same as every other alert on the bulletin.

  • Public-health lab sees that it sent an alert to record X
  • Platform does not see who can read it
Step 9 of 10

Only one company can read it

Every company downloads the whole bulletin and tries its own keys. Only the cheese maker’s key fits. It can now act: clean, investigate, test product, contact the authority, before the cluster becomes public. Because everyone downloads everything, nobody learns who got an alert.

  • Food company sees “your isolate matches human cases”
  • Platform does not see who opened which alert
  • Public-health lab does not see who opened which alert
Step 10 of 10

Optional: lifting anonymity

Only if the system is set up with an identity escrow, and only in a serious outbreak under published rules, at least t of the n consortium members (e.g. ministry, institute, region, trade association) can jointly open the identity of one record. The vote is logged; no member can do it alone. Many deployments skip this step entirely.

  • Consortium sees one identity, only if t members agree
  • Consortium does not see any other record

The anonymous token

The core trick is the blind signature (Chaum, 1982; standardised as RFC 9474). Think of a carbon-lined envelope: the company puts a random token inside and closes it; the issuer signs the outside; the signature passes through onto the token. The company opens the envelope and has a signed token the issuer has never seen, so when it is spent, nobody, not even the issuer, can say whose it was.

Why it works

The company picks a token m and a secret random number r, and sends the envelope b = m·re mod n. The issuer signs with its private key: bd = md·r mod n. The company divides by r and is left with md, a valid signature on m. Anyone checks it with the public key: (md)e = m.

Try it with toy numbers

Key: n = 33, public e = 3, private d = 7. Real keys have 617 digits.

Toy numbers only. The implementation uses RSA-2048 with the PSS encoding of RFC 9474 and reproduces the RFC's official test vectors.

Who knows what

Company identityWhich record is whoseGenome profileWho got an alert
Issueryes (and token count)nonono
Platformnonoyesno
Issuer + platform togetheryesnoyesno
Public-health labnonoyesno (only which record)
The companyits ownits ownits ownits own alerts

Even if issuer and platform are the same organisation and pool everything they have, they cannot link a record to a company: the issuer only ever saw envelopes that look random.

Private alerts

Each record carries a fresh public key made for that record only. The lab encrypts the alert to it (HPKE, RFC 9180) and posts it on a public bulletin. Every company downloads the whole bulletin and tries its own keys. Because everyone downloads everything, nobody learns who was looking for what; because only one secret key fits, nobody else can read it.

Metadata: enough to be useful, not enough to identify

Only four fields leave the company: species, month, region and food category. A record is accepted only if at least k enrolled companies share its region and category (k-anonymity, k = 5 in the prototype). If not, the client generalises automatically:

LevelRegionFood categoryTime
0NUTS-2 (e.g. ITF1, Abruzzo)specific (e.g. dairy)month
1NUTS-1 (e.g. ITF, South)specificmonth
2NUTS-1anymonth
3countryspecificmonth
4countryanymonth

The genome profile is never altered, so cluster detection is exactly as good as with identified data.

Where it runs

Anonymity comes from the tokens in every option. The choice of infrastructure only decides who can tamper with the record and who, if anyone, can lift anonymity.

pilot

A · One operator

A single public institute runs a database. Cheapest. The operator cannot de-anonymise, but must be trusted to keep records intact.

recommended

B · Database + shared log

One database plus a tamper-evident log whose latest hash every consortium member keeps. Rewriting is detected. Optional escrow keys are split t-of-n.

only if needed

C · Permissioned blockchain

Every member runs a node; rewriting is prevented. Worth it only when several countries want joint operation. Adds nothing to anonymity.

Built only on open standards

NeedMechanismStandard
Authorised but anonymousBlind-signed single-use tokensRFC 9474 (RSA blind signatures), Privacy Pass RFC 9576–9578
Private feedbackAlerts encrypted to one-time keysRFC 9180 (HPKE)
Hide the network addressThird-party relayRFC 9458 (Oblivious HTTP)
Tamper evidenceAppend-only hash-chained logRFC 9162 (Certificate Transparency), Trillian / Rekor
Optional disclosureKey split among t of n bodiesShamir secret sharing; RFC 9591 (FROST)
Comparable genomescgMLST allele profilesPublic cgMLST schemes, e.g. chewBBACA

All dependencies are open source (cryptography, pyhpke, FastAPI, SQLite) and the standards are royalty-free.

Try it

git clone https://github.com/genpat-it/blind-genome-sharing.git
cd blind-genome-sharing
python3 -m venv .venv && .venv/bin/pip install -r requirements.txt
.venv/bin/python demo.py          # end-to-end scenario on synthetic data
.venv/bin/python -m pytest -q     # RFC 9474 test vectors + protocol tests
.venv/bin/python bench.py         # timings

The demo enrols 40 synthetic companies, submits their isolates, tries six kinds of cheating (reused token, forged token, wrong key, exact date, unregistered company, over quota), clusters with human cases, delivers alerts and detects a rewritten record.

Cost on one server core (RSA-2048, median)

OperationWhereTime
Blind a tokencompany0.4 ms
Sign a blinded tokenissuer5.4 ms
Verify a tokenplatform0.04 ms
Enrolment, end to endper token≈ 7 ms
Submission, end to endper record≈ 5 ms

A year of tokens for 10,000 companies (50 each) is about 45 minutes of one core.

Limits, stated plainly

  • Proof of concept, synthetic data. Not audited, not for production.
  • The genome itself is a fingerprint. A persistent strain already linked to a plant identifies it; the protocol hides who submitted, not what the strain is.
  • Small regions or sectors force coarser metadata.
  • Legal duties remain. Anonymity does not suspend a company's obligation to act on unsafe food placed on the market.
  • Not yet implemented: threshold escrow, Oblivious HTTP relay, real identity login, Merkle-tree log.