http://localhost:8080
All endpoints use JSON for request and response bodies. The /verify endpoint requires a session token in the Authorization header.
All large integers (y1, y2, a1, a2, s, p, q, g, h) are serialized as lowercase hexadecimal strings without prefixes.
Return the group parameters used for cryptographic operations.
Endpoint: GET /params
Success Response:
Code: 200 OK
Content:
{
"p": "hex",
"q": "hex",
"g": "hex",
"h": "hex",
"bits": 2048,
"mode": "predefined"
}Client-side registration: the client computes y1, y2, and salt locally and submits them.
Endpoint: POST /register
Request Headers:
Content-Type: application/json
Request Body:
{
"username": "string",
"y1": "hex",
"y2": "hex",
"salt": "hex"
}Parameters:
username(string, required): Username (3-50 alphanumeric characters)y1,y2(hex, required): Public keys computed from password-derived secretsalt(hex, required): 256-bit random salt
Success Response:
Code: 200 OK
Content:
{
"message": "User registered successfully",
"username": "alice"
}Error Responses:
Code: 400 Bad Request
Content:
{
"error": "Missing username, y1, y2, or salt"
}or
{
"error": "Username must be 3-50 characters"
}Code: 409 Conflict
Content:
{
"error": "User already exists"
}Example:
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"username": "alice", "y1": "<hex>", "y2": "<hex>", "salt": "<hex>"}'Obtain a one-time nonce and the user’s public data to build a proof locally.
Endpoint: POST /challenge
Request Headers:
Content-Type: application/json
Request Body:
{
"username": "string"
}Success Response:
Code: 200 OK
Content:
{
"username": "alice",
"y1": "hex",
"y2": "hex",
"salt": "hex",
"nonce": "hex",
"expires_at": 1730812345
}Submit a zero-knowledge proof for verification to obtain a session token.
Endpoint: POST /authenticate
Request Headers:
Content-Type: application/json
Request Body:
{
"username": "string",
"a1": "hex",
"a2": "hex",
"s": "hex",
"nonce": "hex"
}Parameters:
username(string, required): Registered usernamea1,a2,s(hex, required): Proof values computed client-sidenonce(hex, required): Nonce from/challenge, single-use and time-limited
Success Response:
Code: 200 OK
Content:
{
"message": "Authentication successful",
"token": "a1b2c3d4e5f6789...",
"username": "alice"
}Error Responses:
Code: 400 Bad Request
Content:
{
"error": "Missing username, a1, a2, s, or nonce"
}Code: 401 Unauthorized
Content:
{
"error": "Invalid credentials"
}or
{
"error": "Authentication failed"
}Example:
curl -X POST http://localhost:8080/authenticate \
-H "Content-Type: application/json" \
-d '{"username": "alice", "a1": "<hex>", "a2": "<hex>", "s": "<hex>", "nonce": "<hex>"}'Verify if a session token is valid.
Endpoint: GET /verify
Request Headers:
Authorization: Bearer <token>
Parameters:
Authorizationheader (string, required): Session token with "Bearer " prefix
Success Response:
Code: 200 OK
Content:
{
"valid": true,
"message": "Session is valid"
}Error Responses:
Code: 401 Unauthorized
Content:
{
"error": "Missing authorization header"
}or
{
"valid": false,
"error": "Invalid or expired session"
}Example:
curl -X GET http://localhost:8080/verify \
-H "Authorization: Bearer a1b2c3d4e5f6789..."{
"y1": "hex",
"y2": "hex",
"salt": "hex"
}
{
"a1": "hex", // g^k mod p
"a2": "hex", // h^k mod p
"s": "hex" // (k - c·x) mod q
}
struct Session {
std::string username; // Username associated with session
uint64_t expiryTime; // Unix timestamp when session expires
}| Code | Description |
|---|---|
| 200 | Success |
| 400 | Bad Request - Invalid input or malformed request |
| 401 | Unauthorized - Invalid credentials or expired session |
| 409 | Conflict - Resource already exists (e.g., duplicate username) |
- Session tokens are 256-bit random values encoded in hexadecimal
- Sessions expire after 1 hour (3600 seconds)
- Expired sessions are cleaned up automatically during verification
- Server issues one-time nonces to prevent replay attacks
- Nonces are valid for a short time (default: 5 minutes) and single-use
- Challenge is computed using SHA-256 hash of commitments, public keys, and nonce
- Passwords are never transmitted in plaintext to the server (only used for proof generation)
- Server never stores or sees user passwords
- Passwords are hashed with username and salt before use in cryptographic operations
- System uses 2048-bit safe primes (p = 2q + 1)
- Generators g and h are verified to be valid for the prime p
- All random values are generated using cryptographically secure RNG
Currently, no rate limiting is implemented. In integrations, consider adding:
- Request rate limits per IP address
- Failed authentication attempt tracking
- Temporary account lockout after multiple failed attempts
- Register a new user:
curl -X POST http://localhost:8080/register \
-H "Content-Type: application/json" \
-d '{"username": "alice", "y1": "<hex>", "y2": "<hex>", "salt": "<hex>"}'Response:
{
"message": "User registered successfully",
"username": "alice"
}- Request a challenge (nonce):
curl -X POST http://localhost:8080/challenge \
-H "Content-Type: application/json" \
-d '{"username": "alice"}'Response (example):
{
"username": "alice",
"y1": "...",
"y2": "...",
"salt": "...",
"nonce": "...",
"expires_at": 1730812345
}- Compute proof locally and authenticate:
curl -X POST http://localhost:8080/authenticate \
-H "Content-Type: application/json" \
-d '{"username": "alice", "a1": "<hex>", "a2": "<hex>", "s": "<hex>", "nonce": "<hex>"}'Response:
{
"message": "Authentication successful",
"token": "f4a3b2c1d5e6...",
"username": "alice"
}- Verify the session:
curl -X GET http://localhost:8080/verify \
-H "Authorization: Bearer f4a3b2c1d5e6..."Response:
{
"valid": true,
"message": "Session is valid"
}