Skip to content

hpicrypto/age-verification

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Modular Anonymous Credential Demo

A demo implementation of an anonymous credential system in the commit-and-prove paradigm, following the approach described in "Vision: A Modular Framework for Anonymous Credential Systems" by A. Lehmann, A. Sidorenko, and A. Zacharakis.

The concrete use case is age verification: a credential holder proves they are 18 years old without revealing any other attribute, and without the verifier being able to track or link individual presentations.

Structure

The workspace contains four main components:

crypto/modular-ac/   # Core cryptographic library for the commit-and-prove anonymous credential scheme
crypto/agever/       # Age-verification scheme built on modular-ac + Android UniFFI bindings
web/                 # Axum web server — issuer + verifier demo
wallet/              # Android app (Jetpack Compose) — holder demo

crypto/modular-ac

Implements the full commit-and-prove anonymous credential scheme on BLS12-381 / BBS+ 23:

  • Issuer — signs credentials using BBS+ 23, embedding a holder P-256 public key.
  • CommittedDisclosurePresenter — produces a Presentation composed of three sub-proofs:
    1. Base proof — PoK of BBS+ signature with selective disclosure and Pedersen commitments to the hidden messages.
    2. Proof of validity — Bulletproofs++ range proof that nbf < today < exp on the committed timestamps.
    3. Holder-binding proof — equality-across-groups proofs (tom256 ↔ BLS12-381) plus a PoK of ECDSA signature under the committed P-256 holder key.
  • CommittedDisclosureVerifier — verifies all three sub-proofs.

crypto/agever

Implements the age-verification credential scheme on top of modular-ac, and exposes it to Android via UniFFI:

  • Credential scheme — defines a fixed schema (header, above16, above18) and provides AgeVerIssuer, AgeVerPresenter, and AgeVerVerifier that wire up the modular-ac primitives for the age-verification use case.
  • UniFFI bindings — compiles to libagever.so (cdylib) and generates Kotlin bindings via the uniffi-bindgen binary.

web

An Axum HTTP server that acts as both issuer and verifier in the demo flow:

Endpoint Role
POST /issue Verify Android Key Attestation cert chain, issue a JWT credential
GET /ageverification Create a session and display a QR code / deep-link
POST /validate Verify a AgeVerPresentation ZK proof, mark session valid

The /issue endpoint verifies the Android StrongBox Key Attestation certificate chain (Google EC + RSA roots) before issuing a credential, binding the credential to the hardware-attested P-256 key of the wallet.

Environment variables

Variable Default Description
ISSUER_SECRET (OS RNG) Exactly 32-byte ASCII string used as the seed for deterministic issuer keypair generation. If unset, the keypair is sampled from the OS RNG on every start.
REQUIRE_ATTEST true Set to false or 0 to skip the Android StrongBox security-level check.
EXTRA_TRUST_CERTS_PEM_FILE (none) Path to a PEM file containing additional X.509 trust anchors.

wallet

An Android application (min SDK 31, target SDK 37) that:

  1. Generates a P-256 key pair in the StrongBox secure element, if available.
  2. Requests and stores a JWT credential from the /issue endpoint.
  3. Scans a QR code from the verifier web page and submits a ZK presentation to /validate.

Building and running

The following commands build and run the different components of the demo from the root of the workspace.

Note that the builds require a signigicant amount disk space (10-12 GB when all targets are built) due to the dependency on the docknetwork/crypto suite, which includes multiple large Rust libraries and their build artifacts.

Rust library and tests

# Run all crypto tests
cargo test -p modular-ac

> Dependencies:

  • Rust toolchain (2024 edition)

Web server

# Run locally (listens on :3000)
cargo run --bin web

> Dependencies: A local OpenSSL installation is required for the web server to verify the Android Key Attestation certificate chain. The server expects the openssl CLI tool to be available in the system PATH and uses it to perform certificate parsing and chain verification.

# Build and run with Docker
docker build -t agever-demo-srv:latest .
docker run -p 3000:3000 agever-demo-srv

> Dependencies:

  • Docker (for the containerized build and run)

Android wallet

cd wallet
./gradlew assembleDebug

> Dependencies:

  • Android SDK 37, NDK 30.0.14904198
  • Gradle 8+ with Kotlin DSL
  • JNA 5.18.1 for the UniFFI bridge
  • Rust targets aarch64-linux-android and x86_64-linux-android

The gradle build should compile the Rust bindings for both aarch64 and x86_64 Android targets as a part of the buildRust task.

License

See LICENSE and NOTICE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors