Summary

  • Revision 12 of the BBS signature draft lets a holder prove knowledge of one multi-message signature while revealing only selected signed messages. Its unlinkability statement is deliberately bounded: the randomized proof value does not expose a common signature or prover, but the header, presentation header, disclosed values, message count and indexes, issuer key, network address and surrounding application data can still correlate presentations.
  • A valid BBS proof is therefore one receipt in a longer chain. It proves a defined cryptographic relationship under a named public key; it does not by itself prove a holder’s civil identity, issuance checks, current status, completeness, authorization, end-to-end unlinkability or a successful operation.

The incident begins with a privacy dashboard that is technically correct. It records that two BBS proofs are different and that both verify. The dashboard therefore marks the sessions “unlinkable.” A separate fraud system joins them in milliseconds.

It did not break the pairing curve. It did not recover the hidden signature or an undisclosed message. It matched a signer-selected header found in only one credential batch, a ten-message layout used by one programme, the same uncommon pair of disclosed indexes, one issuer public key assigned to a small cohort and a device telemetry identifier outside the proof. Every cryptographic assertion remained true. The organizational assertion—“these visits cannot be connected”—had never been proved.

That distinction is the operational centre of draft-irtf-cfrg-bbs-signatures-12. The document describes a strong primitive, and then spends its privacy section limiting the claim to the right object. Leadership should read the limitation as part of the feature, not as a footnote to be removed by marketing.

Revision 12 made the test concrete, not the deployment private

The BBS draft is active CFRG research-group work intended for Informational publication. Revision 12 was uploaded on 28 September 2026 and remains an Internet-Draft. It is not an RFC, an IETF Standards Track approval, a certification programme or evidence that a named wallet or verifier deployed the scheme correctly.

The move from revision 11 to revision 12 is unusually visible. The newer text fills template placeholders with concrete ciphersuite constants, message scalars, generators, signatures and proof fixtures. Implementers can now feed exact inputs into their code and compare exact outputs. That is valuable running-code evidence: a parser, serializer or mathematical routine can be shown to agree with the published fixture.

But a fixture operates in a closed world. It supplies the key, header, messages and mocked randomness. A production privacy claim lives in an open one. Who distributed the issuer key? Did every holder see the same key set? Was the header shared by millions of credentials or unique to one person? Did the wallet reuse randomness? Did the verifier retain an IP address, account cookie or device attestation? A passed vector cannot answer any of these questions.

This is a recurring governance failure. A deterministic conformance result is promoted into a systems claim because it is the easiest artifact to place in a release packet. The BBS vectors can prove that a chosen algorithm path produced the expected bytes. They cannot prove that the organization chose privacy-preserving inputs or kept the surrounding envelope from identifying the holder.

Read the verification result as a bounded sentence

BBS signs a list of messages with one constant-size signature. The holder can later create a randomized zero-knowledge proof of knowledge of that signature and reveal any chosen subset of the signed messages. Verification takes the signer’s public key, the proof, a signature-bound header, a proof-bound presentation_header, the disclosed messages and their original indexes.

When ProofVerify returns valid, the responsible sentence is narrow: the prover knows a valid BBS signature under this public key covering a message list of the inferred length; the disclosed values occupied these indexes; and the proof binds the supplied header and presentation header. The verifier does not learn the hidden signature or the values of undisclosed messages from the proof.

Several tempting conclusions are absent. Verification does not say which person controls the prover software. It does not say how the issuer established any real-world claim before signing. It does not say that a hidden status field is current, that no relevant claim was withheld, or that the disclosed subset satisfies a policy. It does not consult a revocation source unless an application profile adds one. It does not authorize a payment, border crossing, account recovery or building entry. It does not observe what happened after the decision.

The live RFC 9901 coverage already owns the completeness problem for SD-JWT: a verifier can validate selected disclosures without proving that the presented record is complete. BBS deserves a different commission. Its distinctive lesson is that even the proof’s cryptographic unlinkability can coexist with an identifying presentation envelope.

The signature header can become a permanent name

The draft defines two headers with different owners and lifetimes. The signer chooses header. It is bound to the original signature and every derived proof. The prover must reveal it to every verifier. That makes it useful for shared context such as an application identifier, deployment domain or low-cardinality version. It also makes it dangerous.

If an issuer places a random credential identifier, precise expiry instant, email address or other high-entropy value in the header, every presentation from that credential repeats the value. Randomizing the proof no longer protects the interaction from correlation; the stable header supplies an easier join key. The draft therefore says the issuer must use a low-entropy header shared by a large population.

“Low entropy” cannot be approved once in a design meeting. Cardinality depends on the population actually using a key and header combination. A country code may be broad in a global programme but identifying in a tiny diplomatic cohort. A software version may be common on launch day and rare after most devices update. A deployment identifier shared by a million holders can become a one-person bucket when combined with a region, message shape and verifier log.

The issuer owns this risk because the holder cannot replace the signature-bound header. The audit receipt should therefore include the exact header bytes, the rule that generated them, the estimated and observed cohort size, the issuer key with which they appear, and a prohibition on per-holder exceptions. A privacy review that inspects only the proof value looks at the one field the issuer designed not to repeat.

A presentation header can prove freshness and still leak context

The prover chooses presentation_header for one proof. It can bind a verifier-supplied nonce, audience, domain, validity interval or a message signed by the same prover that generated the proof. Used well, it lets the verifier distinguish a fresh response to this challenge from a copied proof.

Freshness, however, is not a property of a random-looking string. The verifier needs to show who generated the nonce, which session and audience it names, how long it remains valid, whether it has already been accepted and what happens after timeout. In a non-interactive design, the verifier must be able to establish uniqueness by another method. A nonce copied from one channel to another may be unique and still bind the wrong transaction.

The privacy rule is equally specific. A high-entropy presentation header can be safe if it is new for every proof and does not contain identifying data. Reusing it creates a stable handle. Embedding an account number, precise location or device build can identify the prover even if the value never repeats elsewhere. A cryptographically bound field is not automatically a privacy-preserving field.

Operationally, log the source, creation time, audience, session binding, acceptance state and retention policy for the presentation header. Do not store a broad “nonce valid” boolean and discard the values needed to reconstruct the decision. Equally, do not retain every challenge forever merely because the proof system authenticated it. Freshness and minimization are separate controls.

The shape of hidden data is still data

A BBS proof hides undisclosed message values, but it does not hide every fact about the signed list. Proof length and the number of disclosures reveal the total number of signed messages. The disclosed indexes reveal where the visible values sat in the original schema. An unusual count or ordering can identify a credential family or a small holder group.

Imagine one programme signs five fields, another signs nine, and a protected witness programme signs thirteen. No hidden value needs to leak for a verifier to classify the presenter. If only one cohort reveals indexes two and eleven together, that pair becomes a fingerprint. When several verifiers compare logs, the combinations can narrow the holder further.

The draft recommends common padding and consistent ordering where possible. Those are not cosmetic encoding choices. They are population-design controls. Their evidence should include the schema version, total-slot distribution, padding rule, index map and tests showing that optional claims do not silently create one-person shapes.

Padding also has a cost. It increases proof size and implementation complexity, and a rare padding policy can become its own fingerprint. The leadership decision is therefore not “always pad.” It is to define which populations need to be indistinguishable, measure the distribution actually emitted and document the residual classification risk.

A public key can partition the population

Proofs are verified under a signer public key. If the issuer uses one key for a single holder or tiny cohort, every proof under that key identifies the cohort even though no two proof values can be linked to the same signature. A privacy architecture can fail at key distribution before proof generation begins.

This failure can be accidental. Regional infrastructure may rotate keys at different times. A canary deployment may assign a new key to twenty users. An incident response may isolate a cohort. It can also be malicious: an issuer can present different key views to different holders and verifiers, creating silent tags.

The receipt is not merely “public key valid.” It needs the key identifier, key bytes, publication channel, activation and retirement time, intended population, observed population and consistency evidence. The Privacy Pass key-consistency work cited by the BBS draft is one possible design direction, but the general obligation is broader: a holder and verifier need evidence that the key view was not selectively fragmented.

A global key can reduce one correlation surface while increasing blast radius and rotation difficulty. A hierarchy can improve operational separation while producing smaller anonymity sets. There is no universal topology. The policy must state the privacy population each key is meant to preserve and test whether actual issuance matches it.

Disclosed truth can identify more efficiently than a hidden signature

Selective disclosure is not anonymous disclosure. A full name, government number, email address or phone number may be legitimately signed and deliberately revealed. If the same high-entropy value appears twice, it links the presentations directly. A rare combination of ordinary claims—profession, small town and exact birth date—can do the same.

The base BBS scheme proves authenticity and integrity of disclosed messages. It does not decide which values a verifier truly needs. That is an application-policy question owned by the requesting service and constrained by purpose, proportionality and retention rules. A verifier that asks for a unique identifier when a broad eligibility statement would suffice defeats the privacy benefit without violating the proof algorithm.

Range and set-membership proofs can reduce some disclosure, but they are separate constructions and introduce their own parameters and evidence. The base draft does not magically turn an exact age into “over eighteen,” nor does it prove non-revocation merely because a revocation identifier remains hidden. Leadership should require a field-by-field justification and reject the phrase “privacy preserving” unless the disclosed combination has been tested against the real population.

Randomness is part of confidentiality, not implementation decoration

ProofGen is randomized. It requires multiple independent scalars that are unique for each call and indistinguishable from uniform. Reuse, prediction or known relationships among them can reveal undisclosed messages or the hidden signature. A proof API can therefore return syntactically valid output while its privacy property has already collapsed.

The draft also describes a quieter risk: compromised randomness can become an exfiltration channel even when an attacker does not visibly break the proof. One mitigation for sensitive systems is a deterministic generator, such as a ChaCha20-based construction, seeded once with a unique uniformly random seed. That narrows the bits an attacker can manipulate; it does not remove the need for trustworthy entropy and seed custody.

Evidence should identify the random generator and library build, seed-generation path, health tests, process and device boundaries, fork or snapshot behavior, failure handling and whether a proof-generation call ever retried with reused state. “Uses system RNG” is a design claim, not a runtime receipt.

Other implementation duties remain independent: deserialize and validate the public key, perform subgroup membership checks, use correct domain-separation tags, keep secret-dependent curve operations resistant to side channels, and give every participant the same message-to-scalar preprocessing rules. A passed mathematical vector can coexist with a skipped subgroup check or locale-dependent string normalization.

Do not borrow features from adjacent drafts

The base scheme’s presentation privacy is often described using the language of credentials. That makes it easy to attribute related features to the wrong protocol.

Blind BBS signatures are a separate extension. They let the signer issue a signature containing holder-provided messages hidden behind a commitment. Ordinary BBS selective disclosure hides messages from the verifier at presentation time; it does not prove that the issuer was blind to those messages during issuance.

Per-verifier linkability is another separate extension. It introduces a context-bound pseudonym so one verifier can recognize repeat presentations while different contexts remain unlinkable under its assumptions. Base BBS does not give a verifier a stable pseudonym merely because the same holder generated several proofs.

The W3C bbs-2023 cryptosuite is an application profile that maps verifiable-credential statements, mandatory pointers and selective pointers into BBS operations and describes optional holder-binding and pseudonym features. Its verification result belongs to that profile. It must not be back-projected as a property of every BBS deployment.

The boundary matters during procurement. A product may truthfully say “supports BBS” while omitting blind issuance, pseudonyms, key consistency, revocation processing or the exact profile another system expects. A capability matrix should name the draft revision, ciphersuite, interface, extension and application profile separately.

Quantum risk splits authenticity from hiding

BBS relies on discrete-logarithm hardness for authenticity. The draft says it is not post-quantum secure. A cryptographically relevant quantum computer could recover a signing secret from the public key, create signatures over chosen messages and then create valid proofs from those forged signatures.

The draft makes a different statement about proof confidentiality. Its zero-knowledge hiding of undisclosed messages and the signature is information-theoretic; already generated BBS proofs do not expose those hidden values even to an adversary with unbounded computation and the signer secret. That is an important “everlasting privacy” property of the proof, not a blanket quantum-safety claim for the credential system.

Migration plans must therefore separate two clocks. Authenticity needs a replacement before quantum forgery becomes relevant to the lifetime of the decision or record. Stored proof transcripts may preserve hiding, but their surrounding metadata and disclosed values remain as linkable as before. Re-signing, key rollover and trust-anchor changes do not delete old verifier logs.

Build the receipt around the whole interaction

A defensible record joins at least eighteen elements: document revision and ciphersuite; issuer-key provenance; key-view consistency; issuance mode; exact header and its cohort; schema count, ordering and padding; disclosed values; disclosed indexes; presentation header and nonce ownership; proof bytes and verification result; randomness evidence; parser and subgroup checks; transport and device metadata; status or revocation evidence; policy input and decision; authorization; effect; retention; and migration state.

No central authority has to own every element. The issuer owns key and header design. The wallet owns disclosure selection and proof generation. The verifier owns challenge, validation and logs. The application owner owns sufficiency and authorization. Security engineering owns implementation assurance. Privacy governance owns purpose and retention. The elements join through a bounded transaction identifier and time, not through one overloaded “verified” flag.

This follows Lu Heng’s minimum-initial-specification discipline. The common cryptographic layer should say exactly what independent implementations need to agree on. Local authorities remain responsible for the claims, keys, metadata and consequences they control. Reality-layer discipline prevents a zero-knowledge proof from borrowing the authority of an authorization decision. Running-Code Primacy asks which key view, schema, header, RNG, binary and log path actually ran.

The right conclusion is not that BBS privacy is weak. The proof primitive makes a strong and unusually explicit promise. The failure comes when organizations enlarge that promise without collecting new evidence. Two proofs can be unlinkable. Two presentations can still be the same person wearing the same envelope.

Sources