Hello, everyone, I’m writing to get feedbacks and suggestions on something I’ve been working on.
BlindVault
Blindvault is a privacy-preserving credential issuance service that allows clients(applications) to issue and verify one time anonymous credentials without tracking users. It makes uses of BLS12-381 blind signatures and DLEQ proofs alongside deterministic key derivation. Blindvault ultimately serves as a middleware (infrastructure) that can be used by any application through API calls to perverse users privacy, it can be used for private airdrop, access controls, community votes and similar apps.
Description
Many apps tries to preverse users privacy but still fail to do so, either because they need to track a users(accounts) to ensure their are ideed eligibile for rewards or other identifiers. All this weaken users privacy.
Blindvault is a middleware service that only focus on issue and verifying credentials, it let the application handles all the logic(e.g: eligibility checks…)
Blindvault stays stateless, application remains responsible for deciding who’s eligible to receive a credentials, while blindvault issues unlinkable blind signatures that can be redeemed later(technically redemption must only be done once, but it’ll be up to the application to either decide to allow double redemption or not). During redemption the service verifies the credentials without learning which credential is being redeemed
Blindvault was designed as a reusable infrastructure, instead of having every project to implement blind signature, replay attacks protection and key management independently.
How it works
The client needs to generate a scalar, which would be used for both blinding and unblinding, the scalar is as sensitive as the private key of a wallet. It can generated randomly or deterministically( hash(priv_key|appname) ), that’s up to the client to decide
- Client blind a message using the scalar (the content of the message is not important, it can be anything)
- Client send the blinded message to blindvault though API
POST /v1/credential/issue
{
"blinded_message": "<hex-encoded compressed G1 point(blinded message)>/",
"credential_class": "<credential class>"
} - The client on success receive the blind signature, the public key of the server, the epoch, and the DLEQ proof(although the server public key must be publicly available so anyone can verify that it was indeed signed by the server)
{
"blind_signature": "",
"public_key": "",
"key_epoch": "",
"proof": {
"r1": "",
"r2": "",
"s": "",
"c": ""
}
} - The client then make uses of the scalar they generated and unblind the blind signature
- The client can use the unblinded signature for redemption
POST /v1/credential/consume
{
"unblinded_signature": "<hex-encoded compressed G1 point>",
"witness": "<hex-encoded compressed G1 point>",
"credential_class": "<credential class>",
"key_epoch": "<epoch>"
}
The client would mainly receive two type of responsevalid (200)andfailure(409)
valid: for one time redemption
failure: when double or more redemption of the same credentials occurs
All others failures: invalid signature, witness, unsupported epoch fall into 400 error code
Technical Approach
Blindvault is build as a layered system, that allow a clear separation between cryptographic operations, logic, storage, and transport into independent components, that can be tested indivudally.
The core cryptography is BLS12-381 blind signatures. With each credentials belonging to a class, and signing keys derived deterministically from a master seed using HKDF-SHA256 and domain separation. They is no longer a need to store private keys independently. Every credentials that is issued comes with a DLEQ proof which is used to verify that the server used the correct signing key(ensures no tampering, because public key is available online).
Replay attacks are prevented by using deterministic nullifiers derived from credentials, class and epoch.
Use case
Blindvault can be used for many project such as anonymous airdrops, community voting, and many more.
BlindVault guarantees:
- unlinkability between issuance and redemption,
- cryptographic verification of issued credentials,
- detection of replay attempts,
- namespace isolation between credential classes,
- verification that signatures originate from the expected derived key.
Trust Assumptions
- Blindvault assumes that the application correctly verified that the user is eligible before requesting credentials to be issued
- The master key is protected (if the master ends up being compromise, anyone can forge credentials)
What’s Built
- Javascript client(blind, DLEQ proof verification and Unblind) (can be tested with the Go server)
- Go server( Handles the issuance, consumption of credentials, with all security concern)
Features
- Deterministic Key Derivation
- Replay protection using deterministic nullifiers
- In-memory backend for testing
- Credential namespace isolation
- DLEQ proof generation and verification
- REST API for credential issuance and consumption
Working On:
- Epoch and class revocation (completed) (revoking all epoch and class is the same as invalidating all credentials issued by blindvault)
- Distributed Key Generation
- Trusted‑dealer threshold
- Threshold DLEQ proof generation
- Batch Verification
I’m looking forward to hearing you’re feedbacks and suggestions