Skip to content

Instantly share code, notes, and snippets.

@williamzujkowski
Created November 18, 2025 01:43
Show Gist options
  • Select an option

  • Save williamzujkowski/bd6b6a5f983944b6ed8c9a724fc7f85f to your computer and use it in GitHub Desktop.

Select an option

Save williamzujkowski/bd6b6a5f983944b6ed8c9a724fc7f85f to your computer and use it in GitHub Desktop.
Zero-Knowledge Authentication Server - Python FastAPI
#!/usr/bin/env python3
"""
Zero-Knowledge Authentication Server
Implements ZK-SNARK based password-less authentication
"""
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import Dict
import hashlib
import secrets
from datetime import datetime, timedelta
import jwt
# Mock ZK library (replace with actual zksnark library)
class ZKCircuit:
def verify_proof(self, proof: bytes, public_inputs: dict) -> bool:
"""Verify ZK-SNARK proof without seeing password."""
# Actual implementation would use zksnark.verify_proof()
# This is simplified for demonstration
return True # Placeholder
app = FastAPI()
zk_circuit = ZKCircuit()
# In-memory user database (use PostgreSQL in production)
users_db: Dict[str, dict] = {}
class User(BaseModel):
username: str
public_key: str
password_hash: str
class AuthRequest(BaseModel):
username: str
proof: bytes
class RegisterRequest(BaseModel):
username: str
public_key: str
password_hash: str
@app.post("/api/register")
async def register(req: RegisterRequest):
"""Register user with public key (password never transmitted)."""
if req.username in users_db:
raise HTTPException(status_code=400, detail="User exists")
users_db[req.username] = {
"public_key": req.public_key,
"password_hash": req.password_hash,
"created_at": datetime.now()
}
return {"status": "registered", "username": req.username}
@app.get("/api/public-key/{username}")
async def get_public_key(username: str):
"""Get user's public key for proof generation."""
if username not in users_db:
raise HTTPException(status_code=404, detail="User not found")
return {
"username": username,
"publicKey": users_db[username]["public_key"],
"expectedHash": users_db[username]["password_hash"]
}
@app.post("/api/auth/verify")
async def verify_auth(req: AuthRequest):
"""Verify ZK-SNARK proof (password never seen)."""
if req.username not in users_db:
raise HTTPException(status_code=401, detail="Invalid credentials")
user = users_db[req.username]
# Public inputs for proof verification
public_inputs = {
'username_hash': hashlib.sha256(req.username.encode()).hexdigest(),
'expected_hash': user['password_hash']
}
# Verify ZK-SNARK proof
if not zk_circuit.verify_proof(req.proof, public_inputs):
raise HTTPException(status_code=401, detail="Invalid proof")
# Generate JWT token (standard OAuth2 flow)
token_payload = {
'sub': req.username,
'exp': datetime.now() + timedelta(hours=8),
'iat': datetime.now()
}
token = jwt.encode(token_payload, "secret_key", algorithm="HS256")
return {
"access_token": token,
"token_type": "bearer",
"expires_in": 28800
}
@app.get("/api/health")
async def health():
return {"status": "healthy", "users": len(users_db)}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8443, ssl_certfile="cert.pem", ssl_keyfile="key.pem")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment