Articles

OONI Probe's Anonymous Credential System

OONI (Open Observatory of Network Interference) depends on volunteers around the world uploading censorship measurements, and the more people take part, the easier it becomes for fabricated or faulty measurements to slip into the dataset. The usual defences, such as IP blocking, user accounts or device attestation, would expose those volunteers and contradict OONI's commitment to their privacy. OONI's answer is anonymous credentials: cryptographic proof that a measurement comes from an OONI Probe meeting certain conditions, without revealing who the user is, where they are, or linking their activity across networks.

This is our guide to the OONI Team's post Announcing OONI's New Anonymous Credential System (2026-01-30). It summarises the main points and adds our own notes; read the original for the full text and code. The Chinese versions of this page carry a full translation.

The announcement follows two earlier OONI posts, one on why OONI needs an anonymous credential system and one on the security and privacy requirements such a system has to meet. The core problem is establishing trust in uploaded measurements without creating any identifier that could expose a user or allow tracking across networks.

Requirements

OONI's threat model sets five constraints. Identity has to be network-local, with no cross-network linkability. The system must verify metadata such as probe_age, measurement_count and blocklist or trust status without revealing the raw values. It must resist forgery and Sybil attacks, support frequent multi-show presentations because probes upload continuously, and avoid shrinking anonymity sets as more metadata is attached to measurements. Existing credential families, whether built on blind signatures, zero-knowledge-friendly signatures or SNARKs, each cover part of this list. None offers issuer-local verification, efficient range proofs, network-dependent pseudonyms and credential updates together without major compromises.

A Layered Credential Framework

Working with researchers from the University of Waterloo, the Tor Project and Risc Zero, OONI built a layered system for zero-knowledge credentials and protocols. It consists of three Rust crates (cmz, sigma-compiler and sigma-proofs) that implement well-studied sigma protocols and compile high-level statements into efficient, linear-algebra-based proof statements. OONI is also working on the related CFRG drafts, draft-irtf-cfrg-sigma-protocols and draft-irtf-cfrg-fiat-shamir. The framework maps onto OONI's needs directly. OONI's usage resembles keyed-verification anonymous credentials (KVAC), where the issuer is also the verifier, which the CMZ and μCMZ schemes support. Range proofs over coarse buckets such as "more than a week" or "more than 1,000 measurements" are cheap in the sigma-rs stack. A network-local pseudonym is expressed as a constraint of the form pseudonym = secret * DOMAIN.

Credential Attributes and the Submit Protocol

The credential, UserAuthCredential, holds three attributes: nym_id, a stable per-installation secret; age, a coarse bucket; and measurement_count. Submitting a measurement is a μCMZ protocol that presents the old credential and receives a new one. The proof shows that the secret and age are unchanged, that the count has gone up by exactly one, that the submitted pseudonym equals nym_id * DOMAIN, and that age and count fall within the ranges the server asks for. The server sees only the proof, never the attribute values, so a malicious client cannot forge trust metadata and a count cannot run backwards or jump ahead. OONI notes that measurement_count measures how much a user has contributed on that network, and is not used for rate limiting.

Integration with the Go Codebase

The OONI Probe engine is mostly Go, and the credential system is Rust. The Rust side exposes a small C-compatible API, with Go bindings generated by rust2go. Rust handles all the cryptography (issuance, zero-knowledge proofs, verification and updates) as a self-contained crypto engine, while the clients, probe-multiplatform on mobile and probe-cli (miniooni, ooniprobe) on the command line, handle orchestration, persistence and state machines. Only opaque serialized protocol messages, public parameters such as the issuer public key, and network context such as domain separators and the country code and ASN cross the boundary. Long-term keys are kept in the operating system's native stores, the Android Keystore on Android and Keychain services on iOS.

Planned Uses

OONI says data users will soon be able to filter or annotate measurements by long-running versus fresh probes, high-volume contributors, blocklisted or faulty probes, and trusted institutional probes. Full Sybil resistance remains an application-layer problem, for example rate-limiting registrations, but authenticated measurement_count and probe_age buckets add real friction for would-be attackers. The post invites feedback from cryptographers and implementers, and promises more detail on protocol design, performance benchmarks and how sigma-rs will ship with the next major OONI Probe release.

As of 2026-10, OONI's July 2026 engineering post assesses the system's effectiveness and describes it as being rolled out into production, with each measurement marked verified, unverified or failed; our guide to that post is Faulty Measurement Detection and Anonymous Credentials at OONI.

Design Evolution

OONI's February 2025 post Probe Security Without Identification was the literature review behind this system, and some of its context is still useful.

It described two threat patterns. Fake measurements uploaded from one network, for a few sites, over a short period are concentrated and relatively easy to spot. A more capable adversary uploading small amounts of fake data from many networks, for many URLs, over a long period is much harder to detect. The aim might be to cast doubt on OONI as a platform, or to spread misleading claims about censorship in a country or region, such as saying a blocked site is reachable or the reverse. Faulty measurements can also come from broken installations with no malice involved. OONI prioritises user privacy at both the network and application layers, and users can upload through tools such as Tor. Trust has to be established within the checkIn and upload flows, at a scale of hundreds of verifications per second.

The review sorted credentials along two axes. By verification, keyed-verification credentials (KVAC) are issued and verified by the same party using lighter cryptography, with Signal among the adopters, while public-verification credentials let issuer and verifier be different parties. By number of uses, single-show credentials (blind signatures, or the VOPRF used in the IETF Privacy Pass standard) are spent after one presentation, while multi-show schemes include Camenisch–Lysyanskaya, Chase–Meiklejohn–Zaverucha (CMZ) and BBS; CMZ is used in Signal's private groups and in Tor's bridge distribution. Because probes upload repeatedly, issuing batches of single-use tokens would push token inventory and replenishment onto the application layer, which is less efficient than a scheme built for multiple presentations. The review also listed optional extensions that can be added independently of the base scheme, including expiration, network-dependent identity, revocation and range proofs.

The 2026 implementation follows that direction: keyed-verification CMZ and μCMZ, with OONI as both issuer and verifier, plus the range-proof and network-dependent-identity extensions from the review.

Our Perspective

For anyone running a probe, the network-local property matters most. If the same user can be recognised on their home Wi-Fi, their office network and their mobile connection, those observations together can lead back to a real identity or a pattern of movement. One pseudonym per network, unlinkable across networks, closes that path while still letting OONI treat repeated submissions from one installation on one network as a single source.

Coarse ranges are the other design choice worth borrowing. Exact values such as 17,382 measurements over 39 days are close to a unique fingerprint, and attaching them would shrink the anonymity set the system is meant to protect. Proving only that a probe falls within a bucket keeps it among many similar probes. The strict split between Rust and Go also reduces risk in a practical way: Go code treats credentials as opaque bytes and never reimplements cryptography, which is where cross-language projects tend to introduce subtle bugs.

As a community that builds on OONI data for Taiwan and its neighbours, we will be watching the ratio of verified, unverified and failed measurements, and whether credential thresholds hold back new probes on networks that are already thinly observed.