This document outlines a proposed "practical" implementation of the ALLOSAUR verifiable credential (VC) revocation scheme based on cryptographic accumulators for scaled use cases. "Practical" in this context means that is manageable from a deployment and governance perspective, and sufficiently performant for all participants. We then consider the privacy characteristics of the design – what do the participants learn about one another in processing the data? The goal is to determine if there is sufficient unlinkability and privacy in the approach. Is the approach practical and safe?
For those with a knowledge of VCs, revocation, and the use of cryptographic accumulators, here is a quick summary of the idea, and participants and a diagram of the flow:
The remainder of this document describes in greater detail the approach, participants, data models, and flow.
The revocation scheme is based on the use of Accumulators, as first described in Nyugen (2005).
The layman's description of the process, without getting into the math, is as follows:
witness
(a number) for their VC. Given their element and witness, the holder can generate a proof that their credential is not revoked without sharing either their element or witness.The challenging part of this process is the calculation of the holder's witness. For a sufficiently scaled use case (millions of credentials with many revocations), the calculation of a witness is beyond the capabilities of a mobile wallet. When the issuer publishes the accumulator and list of elements of newly revoked credentials, holders using that accumulator must update their witness based on all the revocation elements since their last witness update. If that list is large, the calculation could take a long time – many seconds to minutes – on a mobile phone. As such, ALLOSAUR proposes the use of a "Witness Service" (WS in this article) to do the witness calculations on behalf of the holder. The Holder provides the WS with their witness and the timestamp it was last updated, and the WS returns a new witness and timestamp based on the revocations done between the two timestamps.
ALLOSAUR defines key two enhancements to the core approach, one for security, and one for privacy.
For security, the private key used for a Revocation Registry can be generated and used by multi-parties using a multi-party computation (MPC). That way, no individual holds the private key, and multiple parties must be compromised to get the key.
For privacy, the ALLOSAUR WS can be implemented such that instead of the holder giving its entire witness, it shards the witness and makes a set of calls to one or more WS instances, passing to each a shard and its last update timestamp. The holder receives back a set of responses (shard of new witness and timestamp) and from those, can assemble a new witness at a new timestamp.
In this article, we are neutral on whether the security feature is used (irrelevant for the discussion) and only consider the case of not using the privacy feature. The use of the privacy features changes the timing and flow of the process, and so requires a significant recalculation of the process.
The proposed design is summarized in the earlier diagram that shows a single instance of each participant.
The issuer creates a RevReg as needed, and publishes it as two data files (revocations
and accumulators
). The RevReg identifier is resolvable to the location of the RevReg files. Both files grow over time, as the issuer revokes batches of credentials. The formats of the two files are defined below.
In creating a RevReg, the Issuer generates a key pair. The public key will go into the accumulators
file as the first record in the file.
The issuer must interact with the Revocation Manager (which it will likely operate) as follows:
delta
for each revoked credential, returning the batch of deltas, the timestamp, and new accumulator at that timestamp.
On issueance of a credential to a holder, the issuer includes in the issued VC the revocation GUID for the credential, plus the calculated witness and its corresponding timestamp.
The accumulators
file contains:
{ "pk" : "<mulitkey public key>" }
).
ts
) for the batch (matching the batch'sts
value in the revocations
file), the number of revoked credentials in the batch, and the accumulator for that batch.The accumulators
file is needed by the verifier to verify the presentations from holders whose credentials are in the RevReg.
{
"ts": "<timestamp>",
"metadata": [ "ver" : "1.0", "pk" : "<multikey>" ],
"accumulator": "<base64 accum>"
}
The revocations
file contains a record for each batch (1 or more) credential revocations. Each record contains the timestamp (ts
) of the batch, and an array containing the GUIDs anddeltas
from the credentials revoked in this batch. Each guid
is 16 characters, then a literal -
, and each delta is a 64-character base64 value, for a total of 65 bytes per revoked credential.
{
"ts": <timestamp>,
"revoked": [
"<guid>-<delta>",
"<guid>-<delta>",
...
]
}
The revocations
file is used to update holder witnesses, either by the holders themselves, or by Witness Servers. The revocations file might also have a specially defined signal to indicate that all of the credentials in the Revocation Registry have been revoked. That can be accomplished by an update to the accumulator such that all non-revocation proofs fail to verify, but an indicator in the revocations
file would notify all of the holders of the situation without each having to check to see if their proof could be verified.
A record for a new batch is appended to the end of the two data files, using JSON Lines.
An interesting optimization is that instead of using time-based (using Unix Time) timestamps, the value of ts
could be the length of the revocations
file at the end of the current record. Given such a "timestamp", a witness updater could make an HTTP request to retrieve the file starting from the next record to the end of the file, reducing the transmitted data. We'll see where that might come into play shortly.
The holder retrieves an issued VC from the issuer. In addition to storing the VC, the holder stores the RevReg data it needs:
ts
associated with their current witness.When presenting a revokable credential, the holder must have a witness for a sufficiently recent (ideally, the most recent) batch of revocations. Ideally, the verifier will tell the holder how fresh their proof of non-revocation must be based on the business case.
We'll get to how the holder stays up to date with its witness later.
The verifier sends a presentation request to the holder. The verifier may or may specify what specific credential (type and/or issuer) they will accept, and may or may not know what RevReg the holder will need to use. The verifier may not even know if a holder will respond with credentials that are revokable, non-revokable or a combination of both.
Ideally, the verifier provides an indicator of how fresh any non-revocation proofs need be. Only the most mission critical use cases should need "up to the minute" revocation proofs, and the more lenient the verifier can be, the better for all. For example, a week would be ideal.
A Witness Server (WS) serves one more holders, each of whom may be in one or more RevRegs. We propose that the WS be designed to continually monitor all of the RevRegs asked for by its holder clients, and update the witnesses for those clients. This might work as follows:
The WS updates all the of the witnesses for all of its holders. It does something like:
As part of the installation process of a holder's wallet, it would request the services of one or more WSs. It might want to use several Witness Servers so that each only knows about some of the credentials it holds. That said, the use of multiple WS might create UX challenges.
On receiving a revokable credential, a holder would decide if and which WS will be used to update its witness.
defintion
) and learn that the rate of revocations is low enough that it doesn't need the services of a WS for that credential.Periodically, it updates its witnesses.