Skip to content

OPAQUE Protocol in Safex

OPAQUE (Oblivious Pseudorandom Functions with Applications to Key Exchange) is a modern password-authenticated key exchange (PAKE) protocol that provides advanced security properties for PIN-based authentication in Safex.

Why OPAQUE?

Traditional PIN Problems

In typical systems, PIN verification has several vulnerabilities:

sequenceDiagram participant C as Client participant S as Server participant A as Attacker Note over C,A: Traditional PIN Authentication (Vulnerable) C->>S: PIN in plaintext/hash S->>S: Store PIN hash A->>S: Compromise server A->>A: Offline brute force PIN hash A->>A: Recover original PIN

Security Issues:

  • Server sees the PIN (even if hashed)
  • Server compromise exposes PIN hashes
  • Offline brute-force attacks possible
  • Network eavesdropping can reveal PINs

OPAQUE Solution

OPAQUE eliminates these vulnerabilities through cryptographic innovation:

sequenceDiagram participant C as Client (Browser) participant S as Server (Go Backend) participant R as Rust OPAQUE Note over C,R: OPAQUE Authentication (Secure) C->>C: Generate OPAQUE client state C->>S: Send blinded PIN (no PIN info leaked) S->>R: Process with OPAQUE server R->>S: Generate response (no PIN knowledge) S->>C: Return cryptographic challenge C->>C: Prove PIN knowledge cryptographically C->>S: Send proof (PIN never transmitted) S->>R: Verify proof R->>S: Authentication result (success/failure)

Security Advantages:

  • ✅ Server never sees the PIN
  • ✅ No offline attacks possible
  • ✅ Network traffic reveals nothing about PIN
  • ✅ Quantum-resistant cryptography

How OPAQUE Works in Safex

Registration Flow (Secret Creation)

When a user creates a secret with a PIN:

sequenceDiagram participant U as User participant B as Browser (WASM) participant S as Server participant R as Rust OPAQUE Library U->>B: Enter PIN for new secret B->>B: Start OPAQUE registration Note over B: client.start_registration(pin) B->>S: POST /opaque/register/start S->>R: opaque_registration_response() R->>R: Generate server response R->>S: Server registration data S->>B: Registration response B->>B: Complete registration Note over B: client.finish_registration(response) B->>B: Generate OPAQUE record B->>S: POST /secrets (with OPAQUE record) S->>S: Store OPAQUE record (no PIN info)

Login Flow (Secret Retrieval)

When a user wants to retrieve a secret:

sequenceDiagram participant U as User participant B as Browser (WASM) participant S as Server participant R as Rust OPAQUE Library U->>B: Enter PIN to decrypt secret B->>B: Start OPAQUE login Note over B: client.start_login(pin) B->>S: POST /opaque/login/start S->>S: Load stored OPAQUE record S->>R: opaque_login_start(record, request) R->>R: Verify and generate challenge R->>S: Session ID + credential response S->>B: Return session + challenge B->>B: Complete login proof Note over B: client.finish_login(challenge) B->>S: POST /secrets/reveal (with proof) S->>R: opaque_login_finish(session, proof) R->>R: Verify PIN proof R->>S: Authentication success/failure S->>B: Return encrypted secret (if success) B->>B: Decrypt secret locally