Skip to content

UofT Anonymous Credentials

Victoria Cimpu, Arjun Rathaur, Mahmoud Shehadeh
Published on 

UofT Anonymous Credentials

There are often scenarios online where users want to show who they are without being tracked or revealing additional details about their identity. A common example of this is proving you are over the age of 18 without giving up your address, name, or other sensitive information found on your ID.

In the context of UofT, suppose that you are a graduate student who wishes to access university-funded counselling services for a conflict you are having with your academic supervisor. However, you wish to remain anonymous throughout the process. Currently, there is no way for students to access university services anonymously. Thus, we propose and evaluate UofTAnonCreds.

Anonymous Credentials Primer

The simple model we work with is as follows: There are issuers, holders, and verifiers. In our case, the issuer (UofT) is responsible for issuing anonymous credentials to users (holders). Credential holders (in our case, students and staff at the university) can then present these credentials to verifiers to prove specific predicates about themselves. The trust in this system exists between the verifiers and the issuers, and is based on cryptographic assumptions.

Figure 1: A simple anonymous credentials model

There are two main properties that are of concern in our examination of anonymous credentials:

  1. Selective Disclosure: Using zero-knowledge proofs to prove predicates without revealing any additional information (for example, proving that a user's age is greater than 18)

  2. Unlinkable Disclosure: Verifiers cannot share information to correlate data between presentations to try and discern a user's identity.

An ongoing concern is the revocability of anonymous credentials, specifically regarding the tradeoffs between different schemes and their performance/scalability. In the context of UofT, we must consider what happens if a student graduates, gets expelled, or faces other circumstances that warrant restriction of access. There are over 100,000 students and staff at the University of Toronto; thus, in our system, scalable revocation is a necessity.

Research Questions

Our research was guided by the following overarching questions:

  1. What frameworks exist in the anonymous credential revocation space?
  2. How is revocation currently implemented in existing systems?
  3. Can we evaluate alternative revocation strategies with existing frameworks to assess scalability?

Other tools

There were several other tools and libraries we attempted to use based on our proposal. However, due to the evolving nature of the anonymous credentials space and the relative immaturity of many of these tools, our attempts were largely unsuccessful.

The initial plan was to use mDoc-based credentials, as this is an ISO standard [ISO18013-5] and is supported by platforms such as Apple Wallet and Android for certain use cases (e.g., mobile IDs). We based our approach to mDoc credentials on LongFellow-ZK, a library developed by Google to enable zero-knowledge (ZK) proofs within mDoc-based systems [FS25]. However, we encountered significant implementation issues and submitted GitHub issues to the project’s repository, where other users reported similar challenges.

Additionally, we explored the Multipaz Open Wallet from the OpenWallet Foundation, which is based on the mDoc standard. While the library provides a foundation for mDoc credentials, its integration with zero-knowledge mechanisms, particularly with LongFellow-ZK, remains under development. Since our revocation model depends on ZK capabilities, and these features are not yet fully implemented or documented within Multipaz, we ultimately decided not to pursue this approach.

Neither of the options explored above provided a sufficient foundation for our project, so we continued to explore alternative solutions.

AnonCreds Libraries

Finally, we came across the AnonCreds v2 library. It is a mature and actively maintained framework within the AnonCreds ecosystem, developed with contributions including the Government of British Columbia and LIT Protocol. Compared to LongFellow-ZK and Multipaz Open Wallet, AnonCreds v2 is more fully realized as a production-oriented credential framework, building on the earlier AnonCreds v1 design, which has already seen real-world adoption.

AnonCreds v1 is based on the Camenisch–Lysyanskaya (CL) signature scheme [CL01], a foundational construction for anonymous credentials that enables selective disclosure and unlinkable presentations. The v1 system follows a “code-first” and highly opinionated design, abstracting much of the underlying cryptographic complexity. Developers primarily interact with high-level credential operations such as issuing, holding, presenting, and verifying credentials, with attributes handled in plaintext at the application layer. This design significantly reduced implementation complexity and contributed to its adoption in applied identity systems.

AnonCreds v2 retains the same conceptual model and interaction patterns as v1, while introducing a more modular architecture. A key enhancement is support for pluggable signature schemes, enabling the integration of modern constructions such as BBS signatures [BBS04], which support efficient multi-message proofs and selective disclosure within a single signature. In addition, v2 includes support for post-quantum signature schemes. Importantly for our work, revocation is a supported and functional feature in v2, making it a suitable basis for evaluating and benchmarking credential systems within our project.

Details on Revocation and Accumulators

Revocation enables the invalidation of credentials (e.g., due to compromise, expiry, or policy changes) by allowing verifiers to check credential validity at presentation time. In privacy-preserving settings, it is important that revocation does not reveal information about the credential being presented. This rules out naive approaches such as identifier-based blacklists or direct lookup tables, which can leak linkability between presentations. The main challenges are maintaining unlinkability, ensuring efficient verification, and supporting scalable updates as the revoked set grows.

AnonCreds v2 uses pairing-based cryptographic accumulators to address these challenges. A cryptographic accumulator compresses a set of values into a single constant-size value, while still allowing membership proofs for individual elements. Each element in the set is associated with a witness, which enables a prover to demonstrate membership without revealing the element itself.

Formally, given a set $S$ represented by an accumulator $A$, each element $a \in S$ has an associated witness $w_{a}$. The witness allows one to prove that $a \in S$ using only $A$ and $w_{a}$ without revealing $a$.

When the set of valid credentials changes, the accumulator is updated accordingly. This requires witnesses to be updated to remain consistent with the current accumulator state. In practice, this means that credential holders must update or “refresh” their witnesses whenever revocation events occur that affect the accumulator state.

In AnonCreds v2, the issuer maintains an accumulator over the set of currently valid credentials. Each credential holder stores a witness corresponding to their membership in this set. When a revocation occurs, the accumulator is updated to reflect the removal of revoked credentials, and remaining holders update their witnesses to stay consistent with the new state. A revoked credential cannot be refreshed into the updated accumulator state, and therefore fails verification. At presentation time, the holder proves validity by providing a witness that demonstrates membership in the current accumulator without revealing the underlying credential identifier or enabling linkability across sessions.

A notable instantiation of accumulator-based revocation is ALLOSAUR [JLM22], which addresses a subtle but critical limitation of naive accumulator updates: the witness refresh process itself is a privacy risk. If a holder must contact a single issuer with user-specific information to refresh their witness, update requests can be correlated with subsequent presentations, undermining the unlinkability that accumulators are meant to provide. ALLOSAUR avoids this by distributing the update process across multiple accumulator managers using Shamir secret sharing [S79]: rather than sending their witness directly to any single server, the holder splits their credential value into shares and sends one share to each manager. Each manager processes only its share and returns a partial result, from which the holder reconstructs the updated witness. Since no individual manager ever sees the underlying credential value, the update remains oblivious as long as fewer than a threshold number of managers collude.

IssuerHolderRevocationManagerVerifierLedgerIssue(Verifiable Credential,Revocation Element)CreateRevReg Returns:AccumulatorRevoke Credentials(Elements) Returns;AccumulatorUpdateAccumulatorGetAccumulatorPresentation Requestwith Accumulator Returns:Non-Revocation ProofBased on Element, WitnessUpdate Witness(Element Shard(s), Accumulator) Returns:Witness Shard(s)

Figure 2: Overview of the AnonCreds v2 architecture. Source: AnonCreds v2 Slides.

Anonymous Credentials Demo

To demonstrate anonymous credentials for UofT students, an interactive browser-based demo was built to walk through the full AnonCreds V2 lifecycle, including blind credential issuance, selective disclosure, revocation, and witness updates.

How to run the demo

The demo requires two services: the AnonCreds API backend (FastAPI, port 8000) and the demo frontend (Flask, port 5000).

# Terminal 1: Start the AnonCreds API backend
cd /home/ubuntu/anoncreds-api
python main.py    # Serves the REST API on port 8000
# Terminal 2: Start the demo web application
cd /home/ubuntu/anoncreds-api/demo
pip install -r requirements.txt
python main.py    # Serves the Flask UI on port 5000

Open http://localhost:5000/e2e in a browser. The interface has a two-column layout (setup on the left, holder and verifier actions on the right) with a shared, timestamped event log that records all operations.

Figure 3: Screenshot of the demo page

UofT AnonCreds lifecycle

The demo models a university student credential system. By default, it defines a credential with five claims: studentName, studentId, age, department, and yearOfStudy, issued by a university registrar to a student holder (Alice). All fields are configurable, allowing users to customize the schema, issuer, and holder.

1. Define the Credential Schema. Define the credential schema including typed claims and whether the credential supports revocation. When revocation is enabled, the schema will implicitly include an additional revocation claim, which is a unique identifier that will be tracked by the issuer's accumulator.

2. Generate Issuer Keys. Set up an issuer by generating a BBS key pair over the BLS12-381 curve. If revocation is enabled, also initialize a dynamic accumulator, which is a compact cryptographic value representing the set of all non-revoked credentials.

3. Define the Presentation Schema. The presentation schema specifies what a verifier will require a holder to prove. The user selects which claims, if any, to disclose. Leaving the disclosed list empty means the resulting proof will be fully zero-knowledge. The presentation schema also includes a revocation reference, which requires the holder to prove the current non-revocation status.

4. Issue the Blind Credential. The user specifies a holder and provides the claim values. The protocol proceeds as follows: the holder commits to a random link secret using a Pedersen commitment, which allows the issuer to verify well-formedness without learning its value. The issuer then issues a credential by signing the commitment together with the claim values using a BBS signature scheme. In parallel, the credential is registered in the revocation system, and the corresponding accumulator state is updated to reflect the set of non-revoked credentials. The issuer provides the holder with the necessary revocation witness material corresponding to the current accumulator state. The holder unblinds the signature and stores the resulting credential and witness locally. At no point does the issuer learn the link secret, preventing correlation of the holder across verifiers. This process can be repeated for multiple holders.

5. Zero-Knowledge Verification. When verification is triggered, the holder generates a zero-knowledge presentation from their credential. They first prove possession of a valid signature over the claims without revealing the signature or hidden values. Next, they show their revocation status is still valid using the current accumulator. Both proofs are bound to a fresh nonce to prevent replay. Any disclosed claims are revealed, while all other claims remain hidden. The verifier checks the proofs against the issuer’s public key, the accumulator, and the nonce. If valid, the credential is accepted as authentic and non-revoked.

6. Credential Revocation. The user selects a previously issued credential and revokes it. Cryptographically, the issuer updates the accumulator to reflect the credential's removal, producing a new accumulator value. This invalidates the existing membership witnesses of all remaining holders, since witnesses must be consistent with the current accumulator state to produce a valid proof. Holders with valid credentials must therefore refresh their witnesses before they can present them successfully.

7. Stale Witness Failure. Verifying any holder immediately after revocation, both the revoked holder and any non-revoked holders will fail: the zero-knowledge non-revocation proof requires a witness consistent with the current accumulator, and no holder possesses one yet.

8. Witness Update. A non-revoked holder can request a witness update from the issuer, who computes a new membership witness against the current accumulator. Since the claim remains included, the update succeeds and the holder’s wallet is refreshed. For a revoked holder, this process fails because a valid membership witness cannot be generated for a claim that has been removed from the accumulator.

9. Post-Update Verification. After the witness update, the non-revoked holder can once again produce a valid presentation. The revoked holder remains unable to do so, confirming their revoked status.

Recommended Demo Steps

  1. Create a credential schema with revocation enabled.
  2. Set up an issuer against that schema.
  3. Create a presentation schema with no disclosed fields.
  4. Issue credentials to two holders (e.g., student-alice and student-bob).
  5. Verify both holders. Both should pass.
  6. Revoke student-alice's credential.
  7. Verify both holders again. Both should fail now, student-alice due to revocation and student-bob due to stale witnesses.
  8. Update student-bob's witness.
  9. Verify both holders a final time, student-bob passes, student-alice remains failed.

To see these steps in action, watch the following demo video

Evaluation

We evaluate the performance impact of revocation in anonymous credential systems, focusing on both holder-side and issuer-side costs. In particular, we examine how accumulator-based revocation (as used in AnonCreds v2) behaves in practice, and compare it against the distributed witness update approach of ALLOSAUR.

Metrics

We measure performance using:

  • Batch revocation latency (time for the issuer to revoke a set of credentials and update the accumulator)
  • Holder witness update latency (time for a holder to refresh their witness against a new accumulator state)

Experimental Setup

The experiments are run on a machine with an AMD Ryzen 7 7745HX processor, 32GB RAM, and 1TB SSD storage. We use the AnonCreds v2 Rust library to measure the performance of accumulator updates and witness refresh operations as the number of revocations in a batch varies across 1, 10, 100, 1,000, and 10,000.

For issuer-side experiments, we measure the time required to perform batch revocation, where multiple credentials are revoked and the accumulator is updated accordingly.

For distributed witness update experiments, we simulate ALLOSAUR updates by varying:

  • n: total number of accumulator managers
  • t: threshold required for witness reconstruction

with configurations (n=3, t=2), (n=5, t=3), and (n=7, t=4).

Results

Revocations in batchMean time (ms)
10.0650
100.0722
1000.1465
1,0001.5380
10,00078.1596

Table 1: Issuer revocation batch cost.

Table 1 reports the time for the issuer to batch revoke credentials and update the accumulator. The operation scales roughly linearly: revoking a single credential takes under 0.1 ms, and cost remains negligible up to 100 revocations. Beyond that, the cost grows more noticeably, reaching ~1.5 ms at 1,000 revocations and ~78 ms at 10,000. Note that this is a one-time issuer-side cost per batch rather than a per-holder cost.

Figure 4 shows the holder-side cost of updating a witness under single-server reissuance versus ALLOSAUR across threshold configurations. In this model, batch revocation and accumulator updates are performed by the issuer independently of the holder; the holder's only cost is refreshing their witness against the new accumulator state. For single-server reissuance, this cost is negligible since the server does the heavy lifting and simply hands back a new witness. Under ALLOSAUR, the holder bears a small additional cost split across two phases: preparing and distributing Shamir shares before contacting the servers (pre-update), and reconstructing the updated witness from the returned shares (post-update). Both phases remain constant regardless of how many credentials were revoked in the batch, as the holder's work depends only on the threshold configuration rather than the size of the revocation event.

For the smallest configuration (n=3, t=2), the total holder cost is 0.38 ms, split between 0.05 ms for pre-update and 0.33 ms for post-update. This grows modestly with larger configurations, reaching 0.57 ms for (n=5, t=3) and 0.75 ms for (n=7, t=4). In all cases the post-update phase dominates, as it involves elliptic curve operations to reconstruct the witness from the returned shares. Compared to single-server reissuance at 0.06 ms, ALLOSAUR introduces a small but bounded overhead in exchange for the privacy guarantees that come with distributing trust across multiple servers.

<rdf:RDF xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> cc:Work <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/> dc:date2026-04-12T23:44:41.634201</dc:date> dc:formatimage/svg+xml</dc:format> dc:creator cc:Agent dc:titleMatplotlib v3.10.7, https://matplotlib.org/</dc:title> </cc:Agent> </dc:creator> </cc:Work> </rdf:RDF>

Figure 4: Holder Update Cost

Future Work

There are several directions for future work, of which the primary two can be organized into research and implementation.

Regarding research, one of the main concerns is ensuring scalability of our system. To do so, we would aim to compare a wider variety of strategies for revocation and benchmark their performance. We could also look at other components of the AnonCreds v2 library and our demo applicaton to identify other bottlenecks, as well as investigate other libraries to replace AnonCreds v2 as they mature (such as LongFellow-ZK).

On the topic of implementation, we believe the largest barrier will be convincing the University of Toronto that a system implementing anonymous credentials is not only feasible, but worthwhile. We would have to engage in dialogue with the university's IT department and security teams to do so, and substantiate our claims to secure support/funding. We note that in the last few years, there was a widespread push to introduce DUO MFA to all university authentication systems, so it is possible to implement changes to authentication workflows at the university. Ideally, anonymous credentials would be set up pairwise with UTORIDs, so when a user joins the university, they are given both their UTORID and anonymous credential access. Once the university sets up an issuer, which we believe to be a very feasible technical challenge, we would have to educate individual departments and teams on the availability and importance of anonymous credentials. As time progresses, they can choose which systems in their department/team would benefit from allowing anonymous credentials (e.g., counselling) and take steps to implement them. This could easily be facilitated through publishing documentation/guidance in a similar fashion to how UTORID authentication integration guidance is available.

Conclusion

Overall, this work presents UofTAnonCreds, a prototype demonstrating how anonymous credentials can be applied in a university setting with support for selective disclosure, unlinkability, and revocation. We explored several emerging approaches before focusing on AnonCreds v2 as a concrete foundation for implementation. Through our design and implementation, we show the full lifecycle of anonymous credentials, including issuance, presentation, revocation, and witness updates in a realistic institutional context.

References

Victoria Cimpu, Arjun Rathaur, Mahmoud Shehadeh
Published on 

Previous: zkPi+