Selectively Disclosed Verifiable Credentials

Selectively Disclosed Verifiable Credentials

From Zero-Knowledge-Proofs to solutions for privacy-enhanced credentials.

Introduction and Motivation

Decentralized Identities (DIDs) and Self-Sovereign-Identity (SSI) are by now a pretty well-known topic in the DLT space. Verifiable Credentials (VC) are a subset of those concepts and aim to provide a form of digital claims for people and assets. Combining the VC concept with Zero-Knowledge-Proofs (ZKP) results in privacy-enhanced credentials. In this article, we will discuss ZKPs in theory and inspect some technical solutions for zero-knowledge enabled credentials.

VCs enable a holder to divulge information about himself, which then can be used to prove a specific statement. Chess player Alice could for instance use VCs to prove to caretaker Bob, that she is indeed a member of the school’s chess club and thus allowed to enter the building. Traditionally, Alice would show her membership card to Bob. Problem is, a lot of additional information is given to Bob, which he does not really need to prove her membership (e.g. age, birthdate, eye color, … ). But what if there’s a way in which Alice could choose to not provide this additional information but still prove to Bob that she is a member of the club? Well, let me tell you, there is!

Verifiable Credentials using Zero-Knowledge-Proofs are allowing holders of those credentials to confirm certain facts about their identity without revealing the whole set of information. Such a solution could bring a wide range of benefits. Some of those benefits are:

  • Tracking of user data would become very hard.
  • Users could decide how much information they want to disclose up to the smallest possible factor.
  • In certain cases users don’t have to get active to prove something.

So basically, VCs using ZKPs are exciting because they enable us to prove something reliably by disclosing even less information than we are currently used to. This allows the user to stay more private and hinders the verifying party to take advantage of the user’s information.

How do we achieve this?

To understand the combination of ZKP and VC, we first have to talk about different proof problems. Two of those are Zero-Knowledge-Set-Membership and Zero-Knowledge-Range-Proofs.

Zero-Knowledge-Set-Membership (ZKSM)

A set membership proof allows us to prove with zero knowledge, that a specific commitment is part of a known set. This means the individual parts of a set don’t have to be in consecutive order. An easy example would be a list of alumni at your university. Given the full list, you would be able to show that you are alumni of this university by proving you hold a single credential that is part of the full list.

Zero-Knowledge-Range-Proofs (ZKRP)

With a range proof, we can prove with zero knowledge that a specific commitment is part of a defined range. The commitment could be the age of 21 in a range of 18–99. The individual parts of a range have to be in consecutive order. ZKRPs are a subset of ZKSM and allow to apply different techniques due to their consecutive order.

To resolve ZKSM or ZKRP problems, several schemes have been developed. Those schemes distinguish in multiple ways. They can be divided into integer and binary-based schemes. This difference describes the initial format of the commitment (subject to prove), thus enabling unique ways to approach the problem. Depending on the methods used, each scheme ends up yielding unique proof time, verification time, and proof size.

Now that we know the basics, I will try to explain some of the specific methods used to solve above described problems. Please beware that this is my attempt at providing a simple explanation based on the information given by this paper published in 2019.

Integer based

  • Square decomposition → The range gets decomposed into a sum of squares such that the output equals sqrt(n). This implementation is best suited for applications that rely on fast verification, low communication, and big secret size.
  • Signature-based → All elements of a set get signed. The prover can now prove that he knows a specific signature of the secret range, which is also proof that the signature’s hidden value is part of the initial range. For example, caretaker Bob could know the list of members — the set — and Alice would need to present her membership signature. This way Bob only gets to know that Alice is indeed a member but he does not get any additional information. A commonly known implementation of this approach in the space of VC is Camenisch-Lysyanskaya anonymous credentials.

Binary based

  • Multi-base decomposition → Using this approach the secret will be split into bit-size. This allows us to prove that it belongs to a range by using boolean arithmetic. Modifications of this approach can be used to create proofs for problems with a relatively small secret size.
  • Bulletproofs → This approach is the only one in the list which does not need a trusted setup to construct a ZKP. Bulletproofs use a method in which an inner product is proven, thus allowing us to generate range proofs. As well as the multi-base approach bulletproofs are optimized for small secret sizes.

Current Solutions

According to the Decentralized Identity Foundation (DIF), some of the available solutions for privacy-enhanced VCs are Mattr, Evernym, Trinsic, and the yet to be implemented one of Microsoft. The first three of them are based on Hyperledger Aries. While most solutions are based on Hyperledger Indy Credentials, some seem to invest a lot of energy in research & development of BBS+ Signature based credentials, which allow the derivation of Zero-Knowledge-Proofs using the signature-based approach described above. Microsoft has chosen a different approach. In their recently published paper, they describe a scheme using the well-known SNARKs.

Practical Examples

All the available solutions are using ZKP credentials to either construct selectively disclosed credentials, which are credentials holding only a subset of their original information, or predicates, which enable to check a value against a certain condition. Let’s have a look at what’s possible with each solution.


For a better understanding of how ZKP credentials are getting issued, I implemented a full example of a credential issuance using Trinsic’s Tutorial and API. For Mattr and Evernym I will not go into this much detail.

First, we have to create two so-called tenants, which are called organizations in Trinsic Studio. Those are our actors, the Chess Club as the issuer and the Caretaker as the verifier. To save space I will only display the Chess Club.

    name: 'Chess Club',
    imageUrl: '',
    network: {
      networkId: 'sovrin-staging',
      networkName: 'Sovrin Staging Network',
      poolProtocolVersion: 2
    tenantId: 'paddxvglsIkNT43P0feb5SiP9gyDQBmT',
    extendedInformation: {
      issuerDid: '',
      issuerKey: '',
      issuerKeyGenerationSeed: '',
      agentDid: '',
      agentKey: '',
      agentKeyGenerationSeed: '',
      agentServiceEndpoint: '',
      transactionEndorsement: 'Shared'

After the tenants are created we need to create a transcript template, which holds the attribute schema and some metadata.

name: 'Membership Transcript',
version: '1.1',
attributes: [ 'First Name', 'Last Name', 'Membership', 'Age' ],
supportsRevocation: false,
schemaId: 'XJigksK68Fvx63oNvs9Zez:2:Membership Transcript:1.1',
definitionId: 'XJigksK68Fvx63oNvs9Zez:3:CL:161401:membership'

This transcript is now to be issued by the club. This is where Alice’s information gets initialized.

    credentialId: 'f65e9706-edb0-45e3-ab17-f40d31fe778b',
    state: 'Offered',
    definitionId: 'XJigksK68Fvx63oNvs9Zez:3:CL:161401:membership',
    schemaId: 'XJigksK68Fvx63oNvs9Zez:2:Membership Transcript:1.1',
    offerData: 'eyJjb21tZW50IjpudWxsLCJjcmVkZW50aWFsX3ByZXZpZXciOnsiYXR0cmlidXRl.......',
    offerUrl: '',
    values: {
      'First Name': 'Alice',
      'Last Name': 'Smith',
      Membership: 'true',
      Age: '21'
    correlationId: 'f65e9706-edb0-45e3-ab17-f40d31fe778b'

Opening the offerUrl Alice is now able to use her Trinsic mobile wallet to scan a QR-Code and receive the offered credential. Now the caretaker can create a policy that says: “Alice has to be a member to be allowed to enter the building”. At this point, he would also have the ability to create predicate policies, which are the zero-knowledge part of this credential. This could be a policy that Alice is above a certain age. If Alice now answers to this policy, the age will not be displayed to the verifier. Trinsic is enabling those proofs for the following operations >, < and ≥, ≤.

policyId: 'efa5cdf0-78b0-4473-4cc3-08d888da8b21',
name: 'Proof of Membership',
version: '1.0',
attributes: [ [Object], [Object], [Object] ],
predicates: [ [Object] ]

Using an established connection he set up with Alice, he is now able to send the policy to Alice as a request to prove her membership.

connectionId: '893cc564-6341-4061-98b6-6c94cc681213',
verificationId: '8593b7ac-91a8-4520-8c20-9111486188db',
definitionId: 'efa5cdf0-78b0-4473-4cc3-08d888da8b21',
state: 'Requested',
createdAtUtc: 2020-11-16T15:41:26.000Z,
updatedAtUtc: 2020-11-16T15:41:26.000Z,
policy: {
name: 'Proof of Membership',
version: '1.0',
attributes: [Array],
predicates: [Array]

Alice does get a notification in which she sees what information the caretaker wants. She is now able to decide whether she wants to make the requested credential available to him or not.

Evernym (Verity)

While I was not able to find an implemented example for Evernym’s ZKP-Credentials I found an example response in their API. It seems like the proof attributes are ordered in revealed, unrevealed, and predicates. This suggests to me, that they offer selective disclosure as well as the ability to check a predicate for a certain condition. Though I have to mention the predicate checks are limited to a “greater than”-condition for the time being.

"result": {
"@type": "did:sov:BzCbsNYhMrjHiqZDTUASHg;spec/present-proof/1.0/status-report",
"@id": "0729a580-2240-11e6-9eb5-0002a5d5c51b",
"~thread": {
"thid": "ccfc6db3-44a2-499f-b7b8-29cb74140111"
"status": "Complete",
"results": {
"requested_presentation": {
"self_attested_attrs": {
"name": "Bob"
"revealed_attrs": {
"name": {
"identifier_index": 0,
"value": "Bob"
"predicates": {
"Age": {
"identifier_index": 0
"unrevealed_attrs": {
"SocialNum": {
"identifier_index": 0
"identifiers": [
"schema_id": "TUWeK6bhVKqQ3TASQuRB3A:2:license:0.1",
"cred_def_id": "TUWeK6bhVKqQ3TASQuRB3A:3:CL:29:tag",
"rev_reg_id": "string",
"timestamp": 0
"verification_result": "ProofValidated"
"error": {
"code": 1,
"error": "Invalid request"
"status": "OK"


Mattr is focusing on BBS+ based credentials instead. I can recommend Mattr’s JSON-LD sample. In this sample, they leverage their own open-sourced BBS+ signature-based scheme to construct a credential. There’s also a video explaining the sample.

Intro to ZKPs using BBS signatures

Sie sehen gerade einen Platzhalterinhalt von Youtube. Um auf den eigentlichen Inhalt zuzugreifen, klicken Sie auf die Schaltfläche unten. Bitte beachten Sie, dass dabei Daten an Drittanbieter weitergegeben werden.

Mehr Informationen


Now that we learned the basics of the different approaches to ZKP-Credentials, it is clear to say that the promises made by such solutions are exciting. We can see that different approaches provide different solutions. While Trinsic provides predicate checks using >, < and ≥, ≤ operations, Mattr focuses on selectively disclosed credentials. Evernym enables both, selective disclosure and predicate checks (at least for the > operator). But do take this “solution x does y”-statement with caution, as this could very well be subject to change.

I for my part, think there’s still a lot of stuff to improve. Accross the board concepts could be named a bit more consistent, as there are quite some different namings used for the same concepts. This would make it way easier for newbies to understand credential issuance for once, rather than having to learn different namings for each solution. Besides that, I think what they need is time to enrich their solutions with other proof schemes. This will help the SSI-Ecosystem to be more mature and applicable in a wider range. All in all, I think those ZKP-Credentials are very promising but still in a relatively early stage of development and adoption.

51nodes GmbH based in Stuttgart is a provider of crypto-economy solutions.

51nodes supports companies and other organizations in realizing their Blockchain projects. 51nodes offers technical consulting and implementation with a focus on smart contracts, decentralized apps (DApps), integration of Blockchain with industry applications, and tokenization of assets.