A JavaScript implementation that explores Selective Disclosure in the context of Self-Sovereign Identity (SSI). It demonstrates how users can reveal only specific attributes of their digital identity credentials using cryptographic techniques, enhancing privacy and control. This project is designed to simulate the interactions between three main actors in an SSI ecosystem:
- Issuer: Issues Verifiable Credentials (VCs)
- Holder: Holds credentials and selectively discloses attributes
- Verifier: Verifies disclosed attributes and proofs
The selective disclosure approach supported by this library are:
- Atomic-based: It is a simple approach for providing selective disclosure, where the issuer produces Verifiable Credentials containing exactly one claim, and the subject can selectively disclose only the claims they want by inserting only the corresponding credentials in a Verifiable Presentation. The approach has been suggested as a solution by the W3C in the Verifiable Credentials Implementation Guidelines 1.0.
- Hash-based: The hash-based approach exploits hash functions to selectively reveal different parts of a credential and it has been used in several application domains, in combination with the blockchain, to protect the confidentiality of credentials while making them verifiable. A version of this approach (named SD-JWT) is currently in the process of being standardized by IETF and it is implemented by using JSON Web Token (JWT).
- Encryption-based: It exploits cryptographic algorithms to hide the values of the claims in Verifiable Credentials. The issuer encrypts the claims of the credentials they produce by using secret keys which are shared with the subject. In turn, the verifier decrypts only the ciphertext of the claims for which they receive the corresponding keys from the subject.
- Tree-based: It exploits cryptographic hash data structure to keep secret and verifiable all the claims of the credentials.
- Signature-based: Finally, the signature-based approach includes various preliminary solutions that aim to define signature schemes that natively support the selective disclosure of claims.
In this library the JSON Web Token standard (JWT) is used as external proof mechanism to encode Verifiable Credentials and Presentations. The Ethereum
blockchain was selected as the best candidate to take the role of verifiable data registry. The ethr DID method uses any Ethereum address or secp256k1 public key as DID identifier and it is used to identify issuers and holder.
The ethr DID method implements the verifiable data registry as a smart contract deployed on Ethereum. In our implementation, the registry smart contract is deployed on a local Ganache network that simulates Ethereum.
DIDs are resolved using the ethr DID Resolver, a program that takes in input a DID and returns the corresponding DID document.
The implementation is done with NodeJs v20.19.5, and we used the native crypto library to import the cryptographic operations such as hashing and encryption. We also imported the following libraries: merkletreejs6 for implementing Merkle trees; merkle-patricia-tree for implementing Merkle Patricia Tries; bbs-signatures for implementing BBS+ signatures.
selectiveDisclosureSSI/
├── atomic/ -> Implementation of the Atomic-based approach
│ └── main.js
├── auth/ -> Implementation of the Signature-based approach
│ ├── bbs_example.js
│ ├── bbs_script.js
│ └── main.js
├── baseline/ -> Implementation of the baseline approach (without selective disclosure)
│ └── main.js
├── config.json
├── contracts/ -> Smart Contract of the Ethr DID method
│ ├── EthereumDIDRegistry.sol
│ └── Migrations.sol
├── encryption/ -> Implementation of the Encryption-based approach
│ ├── cipherSymmetricKey.js
│ ├── main.js
│ └── verifyAttributes.js
├── hash/ -> Implementation of the Hash-based approach
│ ├── hashAttributes.js
│ ├── main.js
│ └── verifyAttributes.js
├── main.js -> Main execution point
├── MPT/ -> Implementation of the Tree-based approach (Merkle Patricia Tries)
│ ├── createPatriciaMerkleTree.js
│ ├── main.js
│ └── verifyAttributesPatricia.js
├── MT/ -> Implementation of the Tree-based approach (Merkle trees)
│ ├── creationMekleTree.js
│ ├── main.js
│ └── verifyAttributes.js
├── package.json -> Package JSON file for npm
├── README.md -> This file
└── truffle-config.cjs -> Truffle configuration for the deployment of Smart Contracts
- Node.js (v20+ recommended)
- npm
- Ganache
- Truffle
git clone https://github.com/andreadesalve/selectiveDisclosureSSI.git
cd selectiveDisclosureSSI
npm install
npm run ganache
Deploy smart contract by using the truffle-config.cjs
npm run ganache
node main.js
The config.json file allows you to customize various parameters that control the execution of the program. Below is a description of the available configuration options:
maxClaims (default value 11)
Exponent for base 2, representing the maximum number of claims used in the experiments. For example, a value of 11 generates VCs with the following number of claims: 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024.
runs (default value 30)
Number of executions for each VC configuration.
mnemonic (default value "family dress industry stage bike shrimp replace design author amateur reopen script")
Mnemonic phrase used to derive public and private keys from Ganache.
disclosedClaims (default value 0.75)
Fraction of claims disclosed by the VC holder.
symmetricKey
Cryptographic system used for encryption
K (default value aes-128-cbc)
Length of the key in bit
symmetrickeylength (default value 128)
hash
Hash algorithm for HMAC
H (default value sha3-256)
Key length in bit for HMAC
keylength (default value 512)
Merkle trees
merkleTree
Hash function used in HMAC to compute the leaves of the tree
HLeaves (default value keccak256)
Key length in bit for HMAC
keyLengthHLeaves (default value 256)
Hash function used by internal nodes
HTree (default value sha3-256)
Merkle Patricia Tries
merklePatriciaTree
Hash function used in HMAC to compute the leaves of the tree
HTree (default value sha3-256)
Hash function used by internal nodes
HLeaves (default value keccak256)
Key length in bit for HMAC
keyLength (default value 256)
Configure the main in order to use a specific approach:
- Baseline approach (without selective disclosure)
import * as baseline from './baseline/main.js' - Atomic-based approach
import * as atomic from './atomic/main.js' - Hash-based approach
import * as hash from './hash/main.js' - Encryption-based approach
import * as encryption from './encryption/main.js' - Hash Tree-based approach (Merkle trees)
import * as mt from './MT/main.js' - Hash Tree-based approach (Merkle Patricia Tries)
import * as mpt from './MPT/main.js' - Signature-based approach
import * as auth from './auth/main.js'
Each approach provide the following methods:
- Issue a VC
issueVC - Verify a VC
verifyVC - Issue a VP
issueVP - Verify a VP
verifyVP
To extend the proposed framework by integrating a new selective disclosure method, simply implement the required methods.