BJJ_SIG_2021), which the AIR team enables per request. Where SD-JWT reveals the values a user chooses to share, Iden3 lets the user prove a statement about a value without revealing it, such as “tier is above Bronze” or “age is over 18”, and every proof looks different, so verifiers cannot link them.
It achieves this by turning the credential into Merkle trees that a zero-knowledge circuit can reason about.
The issuer’s identity
An Iden3 issuer is not a domain. It is a cryptographic identity:- A BabyJubJub key pair, derived from the issuer service’s secret 32-byte seed. BabyJubJub is an elliptic curve designed to be cheap inside zero-knowledge circuits.
-
Three sparse Merkle trees that describe the issuer’s state:
- The issuer state: one hash computed from the three tree roots. Any change to the trees, such as a revocation, produces a new state.
-
The issuer DID (
did:air:…), derived from the issuer’s first (genesis) state. Changing the seed creates a different issuer.
What a credential is made of
An Iden3 credential is a W3C Verifiable Credential in JSON-LD, plus a compact signed “core claim” that circuits can read.1
The JSON-LD credential
The readable credential: the holder DID as
credentialSubject.id, the claim fields, the schema URL, the JSON-LD context URL, the expiry, and a credentialStatus pointing to the issuer’s /credential-status endpoint with a revocation number.2
Merklization
Every field of the credential is turned into a key and value, using the JSON-LD context to give each field a precise meaning, and inserted into a sparse Merkle tree. The tree’s root, the merklized root, commits to every field at once. This is why claim names and types must match the schema exactly: a mismatch changes the tree.
3
The core claim
A fixed-size record holding the schema hash, the holder’s DID (in its index part), the merklized root (in its value part), the revocation number, and the expiry.
4
The signature
The issuer signs the core claim with its BabyJubJub key. The signature, with the issuer’s state and the proof that the issuer’s key is in its claims tree, is attached to the credential as its
BJJSignature2021 proof.How a proof works
When a verification program asks a question such as “istier above Bronze?”, the holder’s device runs a Circom circuit and produces a Groth16 zero-knowledge proof. The proof convinces the verifier that all of these are true, without revealing the credential:
The verifier receives the proof (
pi_a, pi_b, pi_c), its public signals (the inputs and outputs the verifier is allowed to see, such as the issuer, the condition, and the result), and the circuit ID. It does not receive the field value unless the program asked for it. Generating a proof takes a few seconds of computation on the user’s device.
A program can also ask for a field’s actual value. The proof then shows the value is genuine, and the credential otherwise stays hidden.
How a proof is verified
How revocation works
To revoke, the issuer adds the credential’s revocation number to its revocation tree, which produces a new issuer state. When the holder builds a proof, it fetches a fresh non-revocation proof from the issuer’s/credential-status/:nonce endpoint: a Merkle proof that the number is absent, together with the issuer’s current tree roots and state. The issuer also answers the standard /revocation-status/:nonce endpoint. There is no token status list.
SD-JWT and Iden3 compared
For setup, see Issue Iden3 credentials. For verification modes, see Zero-knowledge verification.