Prove who you are without revealing what you know. Chaum-Pedersen zero-knowledge proof authentication over gRPC, written in Rust.
Traditional authentication sends passwords — hashed or not — across the wire. If the server is compromised, an attacker gets credential material. Even challenge-response schemes often leak enough for offline attacks.
Zero-knowledge proofs flip the model: the prover demonstrates knowledge of a secret without ever transmitting it. The server learns only one bit — "this person knows the password" — and nothing else.
This project implements the Chaum-Pedersen protocol — a discrete-logarithm-based ZKP scheme — over a gRPC interface.
┌─────────┐ ┌─────────┐
│ Client │ │ Server │
│ (Prover) │ │(Verifier)│
└────┬─────┘ └────┬─────┘
│ │
│ Register(y1, y2) │
│ y1 = α^x mod p │
│ y2 = β^x mod p │
│────────────────────────────────────────▶│
│ │ stores (y1, y2)
│ │
│ CreateAuthenticationChallenge(r1, r2) │
│ r1 = α^k mod p │
│ r2 = β^k mod p │
│────────────────────────────────────────▶│
│ c ← random │
│◀────────────────────────────────────────│
│ │
│ VerifyAuthentication(s) │
│ s = k - c·x mod q │
│────────────────────────────────────────▶│
│ │ checks:
│ │ α^s · y1^c ≡ r1 (mod p)
│ │ β^s · y2^c ≡ r2 (mod p)
│ session_id ← granted│
│◀────────────────────────────────────────│
│ │
At no point does x (the secret) leave the client. The server only ever sees commitments and the solution to a random challenge.
The implementation uses RFC 5114 standard parameters:
| Parameter | Size | Description |
|---|---|---|
p |
1024-bit | Safe prime modulus |
q |
160-bit | Prime-order subgroup size |
α |
1024-bit | Generator of the subgroup |
β |
derived | Second generator (α^i mod p) |
Tests cover toy examples (23-bit), 1024-bit, and 2048-bit parameter sets.
- Rust (2021 edition)
protobuf-compiler(apt install protobuf-compileron Linux,brew install protobufon macOS)- Docker (optional, for containerized deployment)
# Clone
git clone https://github.com/Giri-Aayush/zkp-authentication.git
cd zkp-authentication
# Build
cargo build --release
# Terminal 1 — start the server
cargo run --bin server --release
# Terminal 2 — run the client
cargo run --bin client --releaseThe client will prompt for a username and password in hexadecimal. After registration, use the same credentials to authenticate and receive a session ID.
# Build and start
docker-compose build zkpserver
docker-compose run --rm zkpserver
# Inside the container
cargo run --bin server --release
# (in another shell into the same container)
cargo run --bin client --releasezkp-authentication/
├── proto/
│ └── zkp_auth.proto # gRPC service definition (Register, Challenge, Verify)
├── src/
│ ├── lib.rs # ZKP library — compute_pair, solve, verify
│ ├── server.rs # gRPC server (tonic)
│ └── client.rs # gRPC client (tonic)
├── build.rs # Proto compilation via tonic-build
├── Cargo.toml
├── Dockerfile
└── docker-compose.yaml
cargo testThe test suite includes:
- Toy example — small primes (p=23) with known expected values
- Randomized toy example — same small primes with random
kandc - 1024-bit RFC 5114 — production-grade parameters
- 2048-bit RFC 5114 — higher security parameters
- Negative test — verifies that a wrong secret is rejected