883 lines
26 KiB
Markdown
883 lines
26 KiB
Markdown
# UC Security Proof for Lattice-Based OPAQUE
|
||
|
||
This document provides a formal security proof for the opaque-lattice implementation in the Universal Composability (UC) framework.
|
||
|
||
## Table of Contents
|
||
|
||
1. [Overview](#1-overview)
|
||
2. [Preliminaries](#2-preliminaries)
|
||
3. [Ideal Functionalities](#3-ideal-functionalities)
|
||
4. [Protocol Description](#4-protocol-description)
|
||
5. [Simulator Construction](#5-simulator-construction)
|
||
6. [Security Proof](#6-security-proof)
|
||
7. [Concrete Security Bounds](#7-concrete-security-bounds)
|
||
|
||
---
|
||
|
||
## 1. Overview
|
||
|
||
### 1.1 Protocol Summary
|
||
|
||
opaque-lattice implements a post-quantum secure OPAQUE protocol using:
|
||
- **Ring-LPR OPRF**: Oblivious PRF based on Ring Learning Parity with Rounding
|
||
- **ML-KEM (Kyber768)**: Key encapsulation for authenticated key exchange
|
||
- **ML-DSA (Dilithium3)**: Digital signatures for server authentication
|
||
- **VOPRF Extension**: Verifiable OPRF with Lyubashevsky-style sigma protocol
|
||
|
||
### 1.2 Security Goals
|
||
|
||
We prove the protocol realizes the ideal functionality F_aPAKE (asymmetric Password-Authenticated Key Exchange) with the following properties:
|
||
|
||
| Property | Description |
|
||
|----------|-------------|
|
||
| **Password Obliviousness** | Server learns nothing about password during OPRF |
|
||
| **Forward Secrecy** | Compromise of long-term keys doesn't reveal past session keys |
|
||
| **Server Compromise Resistance** | Attacker cannot offline-attack passwords after server compromise |
|
||
| **Quantum Resistance** | Security holds against quantum adversaries |
|
||
| **Verifiability** | Client can verify server used consistent OPRF key |
|
||
|
||
### 1.3 Security Model
|
||
|
||
We work in the UC framework of Canetti [Can01] with:
|
||
- **Global Random Oracle Model (GROM)**: Hash functions H₁, H₂, H₃ modeled as random oracles
|
||
- **Adaptive Corruptions**: Adversary can corrupt parties at any point
|
||
- **Static Compromise**: Adversary learns all internal state upon corruption
|
||
|
||
---
|
||
|
||
## 2. Preliminaries
|
||
|
||
### 2.1 Notation
|
||
|
||
| Symbol | Meaning |
|
||
|--------|---------|
|
||
| λ | Security parameter (128 bits) |
|
||
| R | Ring Z[x]/(x^n + 1) where n = 256 |
|
||
| R_q | Ring R modulo q (q = 4 in our construction) |
|
||
| ⌊·⌋₁ | Deterministic rounding: ⌊x⌋₁ = ⌊x/2⌋ mod 2 |
|
||
| k ←$ S | Sample k uniformly from set S |
|
||
| negl(λ) | Negligible function in λ |
|
||
| poly(λ) | Polynomial function in λ |
|
||
|
||
### 2.2 Computational Assumptions
|
||
|
||
**Definition 2.1 (Ring-LPR Problem)**
|
||
For a ∈ R₂, s ∈ R₂, the Ring Learning Parity with Rounding problem states that:
|
||
```
|
||
(a, ⌊a·s mod 4⌋₁) ≈_c (a, ⌊u⌋₁)
|
||
```
|
||
where u ←$ R₄ is uniform random.
|
||
|
||
**Definition 2.2 (Dihedral Coset Problem)**
|
||
Given quantum states encoding cosets of a hidden subgroup in the dihedral group D_n, find the hidden subgroup generator. Time complexity: O(e^n) even for quantum computers.
|
||
|
||
**Theorem 2.1 (Security Reduction Chain)**
|
||
```
|
||
Ring-LPR → LPR → LWR → G-EDCP → DCP
|
||
```
|
||
Each reduction is polynomial-time. The DCP problem is believed quantum-hard with time complexity O(e^n).
|
||
|
||
**Definition 2.3 (ML-KEM Security)**
|
||
ML-KEM (Kyber768) is IND-CCA2 secure under the Module-LWE assumption.
|
||
|
||
**Definition 2.4 (ML-DSA Security)**
|
||
ML-DSA (Dilithium3) is EUF-CMA secure under the Module-LWE and Module-SIS assumptions.
|
||
|
||
### 2.3 Building Blocks
|
||
|
||
**PRF Construction (Ring-LPR)**
|
||
```
|
||
F_k(x) = H₂(⌊k · H₁(x) mod 4⌋₁)
|
||
```
|
||
where:
|
||
- H₁: {0,1}* → R₂ (hash-to-ring)
|
||
- H₂: R₁ → {0,1}^512 (ring-to-output hash)
|
||
- k ∈ R₂ (secret key)
|
||
|
||
**Key Commitment**
|
||
```
|
||
Commit(k; r) = H₃(k || r)
|
||
```
|
||
where r ←$ {0,1}^256 is randomness.
|
||
|
||
---
|
||
|
||
## 3. Ideal Functionalities
|
||
|
||
### 3.1 Ideal VOPRF Functionality F_VOPRF
|
||
|
||
```
|
||
Functionality F_VOPRF
|
||
|
||
Parameters: Output length l, security parameter λ
|
||
|
||
Initialization:
|
||
- On (Init, sid) from server S:
|
||
- If first Init for sid: set T_sid(·) = ⊥, tx(S) = 0
|
||
- Send (Init, sid, S) to adversary A
|
||
|
||
- On (Param, S, π) from A:
|
||
- If params[S] undefined: set params[S] = π
|
||
|
||
Key Commitment:
|
||
- On (Commit, sid) from S:
|
||
- Sample random table key k_sid
|
||
- Store commitment c = H(k_sid)
|
||
- Send (Committed, sid, c) to A
|
||
|
||
Offline Evaluation:
|
||
- On (OfflineEval, sid, c, p) from party P:
|
||
- If params[i] = c for some server i:
|
||
- If T_sid(i, p) undefined: T_sid(i, p) ←$ {0,1}^l
|
||
- Send (OfflineEval, sid, T_sid(i, p)) to P
|
||
- Else: ignore
|
||
|
||
Online Evaluation:
|
||
- On (Eval, sid, ssid, S, p) from user U:
|
||
- Record ⟨ssid, S, U, p⟩
|
||
- Send (Eval, sid, ssid, U, S) to A
|
||
|
||
- On (SndrComplete, sid, ssid) from S:
|
||
- Increment tx(S)
|
||
- Send (SndrComplete, sid, ssid, S) to A
|
||
|
||
- On (RcvCmplt, sid, ssid, U, π) from A:
|
||
- Retrieve ⟨ssid, S, U, p⟩
|
||
- Ignore if:
|
||
- No such record exists
|
||
- Honest server S has params[S] = π but tx(S) = 0
|
||
- S honest but π ≠ params[S]
|
||
- If T_sid(i, p) undefined: T_sid(i, p) ←$ {0,1}^l
|
||
- Send (Eval, sid, ssid, T_sid(i, p)) to U
|
||
- Decrement tx(S) if params[S] = π
|
||
|
||
Verification:
|
||
- On (Verify, sid, c, p, y, proof) from U:
|
||
- Check if y = T_sid(i, p) for params[i] = c
|
||
- Send (Verified, sid, valid/invalid) to U
|
||
```
|
||
|
||
### 3.2 Ideal AKE Functionality F_AKE
|
||
|
||
```
|
||
Functionality F_AKE
|
||
|
||
Initialization:
|
||
- Maintain session table sessions[·]
|
||
- Maintain corruption set Corrupt
|
||
|
||
Key Exchange:
|
||
- On (NewSession, sid, P, P', role) from party P:
|
||
- Record (sid, P, P', role, ⊥)
|
||
- Send (NewSession, sid, P, P', role) to A
|
||
|
||
- On (TestPwd, sid, P, pw') from A:
|
||
- If P ∈ Corrupt: return ⊥
|
||
- Retrieve (sid, P, P', role, pw)
|
||
- If pw' = pw: mark session compromised
|
||
- Return (compromised/not-compromised)
|
||
|
||
- On (NewKey, sid, P, sk) from A:
|
||
- Retrieve (sid, P, P', role, pw)
|
||
- If P' ∈ Corrupt or session compromised:
|
||
- Output (sid, sk) to P
|
||
- Else if (sid, P', P, role', k') exists with k' ≠ ⊥:
|
||
- Output (sid, k') to P
|
||
- Else:
|
||
- Sample k ←$ {0,1}^λ
|
||
- Record k, output (sid, k) to P
|
||
```
|
||
|
||
### 3.3 Ideal aPAKE Functionality F_aPAKE
|
||
|
||
```
|
||
Functionality F_aPAKE
|
||
|
||
Parameters: Security parameter λ
|
||
|
||
Registration:
|
||
- On (Register, sid, U, S, pw) from user U:
|
||
- Compute file ← F_OPRF.Eval(pw)
|
||
- Store (U, file) for server S
|
||
- Send (Registered, sid, U) to S
|
||
|
||
Login:
|
||
- On (Login, sid, U, S, pw) from U:
|
||
- Initiate OPRF evaluation with S
|
||
- If pw matches stored file:
|
||
- Derive session key sk
|
||
- Output (LoginComplete, sid, sk) to U, S
|
||
- Else:
|
||
- Output (LoginFailed, sid) to U
|
||
|
||
Server Compromise:
|
||
- On (Corrupt, S) from A:
|
||
- Add S to Corrupt set
|
||
- Send all stored files to A
|
||
- Note: Offline attacks still require online OPRF interaction
|
||
```
|
||
|
||
---
|
||
|
||
## 4. Protocol Description
|
||
|
||
### 4.1 Registration Protocol
|
||
|
||
```
|
||
Client(pw) Server(oprf_key)
|
||
═══════════════════════════════════════════════════════════════
|
||
1. salt ←$ {0,1}^256
|
||
2. pw_hash = Argon2id(pw, salt)
|
||
3. (state, blind) = OPRF.Blind(pw_hash)
|
||
─────── blind ───────────►
|
||
4. eval = OPRF.Eval(oprf_key, blind)
|
||
◄────── eval ─────────
|
||
5. rw = OPRF.Finalize(state, eval)
|
||
6. (pk_U, sk_U) = KEM.KeyGen()
|
||
7. (pk_auth, sk_auth) = SIG.KeyGen()
|
||
8. envelope = AEAD.Enc(rw, sk_U || sk_auth)
|
||
9. record = (pk_U, pk_auth, envelope, salt)
|
||
─────── record ──────────►
|
||
10. Store(U, record)
|
||
```
|
||
|
||
### 4.2 Login Protocol (KE1 → KE2 → KE3)
|
||
|
||
```
|
||
Client(pw) Server(oprf_key, record)
|
||
═══════════════════════════════════════════════════════════════
|
||
KE1: Client → Server
|
||
1. pw_hash = Argon2id(pw, record.salt)
|
||
2. (state, blind) = OPRF.Blind(pw_hash)
|
||
3. (ek_C, dk_C) = KEM.KeyGen()
|
||
───── KE1: (blind, ek_C) ─────►
|
||
|
||
KE2: Server → Client
|
||
4. eval = OPRF.Eval(oprf_key, blind)
|
||
5. (ct, ss_S) = KEM.Encap(ek_C)
|
||
6. K_session = KDF(ss_S, transcript)
|
||
7. mac_S = MAC(K_session, transcript)
|
||
8. sig = SIG.Sign(sk_S, transcript)
|
||
◄─── KE2: (eval, ct, mac_S, sig, envelope) ───
|
||
|
||
KE3: Client → Server
|
||
9. Verify sig with pk_S
|
||
10. rw = OPRF.Finalize(state, eval)
|
||
11. (sk_U, sk_auth) = AEAD.Dec(rw, envelope)
|
||
12. ss_C = KEM.Decap(dk_C, ct)
|
||
13. K_session = KDF(ss_C, transcript)
|
||
14. Verify mac_S
|
||
15. mac_C = MAC(K_session, transcript)
|
||
───── KE3: mac_C ─────►
|
||
16. Verify mac_C
|
||
17. Output K_session Output K_session
|
||
```
|
||
|
||
### 4.3 VOPRF Extension
|
||
|
||
For verifiable evaluation, server additionally:
|
||
|
||
```
|
||
Server with committed key (k, c, r):
|
||
1. Compute eval = F_k(blind)
|
||
2. Generate ZK proof π proving:
|
||
- Knowledge of k such that c = Commit(k; r)
|
||
- eval = F_k(blind)
|
||
3. Return (eval, π)
|
||
|
||
Client:
|
||
1. Verify π against commitment c
|
||
2. If valid: proceed with finalization
|
||
3. If invalid: abort
|
||
```
|
||
|
||
---
|
||
|
||
## 5. Simulator Construction
|
||
|
||
### 5.1 Simulator for F_VOPRF
|
||
|
||
```
|
||
Simulator SIM_VOPRF
|
||
|
||
On (Init, sid, S) from F_VOPRF:
|
||
- Sample random key k_sim
|
||
- Compute c = Commit(k_sim; r_sim)
|
||
- Send (Param, S, c) to F_VOPRF
|
||
- Record (S, k_sim, r_sim, c)
|
||
|
||
On (Eval, sid, ssid, U, S) from F_VOPRF:
|
||
If S honest:
|
||
- Wait for adversary to deliver
|
||
- On delivery: send (SndrComplete, sid, ssid) to F_VOPRF
|
||
- Send (RcvCmplt, sid, ssid, U, c_S) to F_VOPRF
|
||
|
||
If S corrupted:
|
||
- Extract adversary's evaluation blind_A
|
||
- Query F_VOPRF for T_sid(c_A, blind_A)
|
||
- Program H₂ to output T_sid value
|
||
- Simulate protocol messages
|
||
|
||
On H₂ query (x, y, c) from A:
|
||
If ∃ honest S with params[S] = c:
|
||
- Send (OfflineEval, sid, c, H₁⁻¹(x)) to F_VOPRF
|
||
- Receive ρ from F_VOPRF
|
||
- Return ρ
|
||
Else:
|
||
- Return random value or use table
|
||
```
|
||
|
||
### 5.2 Simulator for F_aPAKE
|
||
|
||
```
|
||
Simulator SIM_aPAKE
|
||
|
||
Registration Simulation:
|
||
On (Register, sid, U, S, pw) from F_aPAKE:
|
||
- Simulate OPRF blind message
|
||
- Receive adversarial evaluation
|
||
- Extract any password guesses
|
||
- Complete registration
|
||
|
||
Login Simulation (Honest Client, Honest Server):
|
||
- Simulate KE1 with random blind
|
||
- Simulate KE2 with random evaluation
|
||
- On (TestPwd, sid, U, pw') from A:
|
||
- Forward to F_aPAKE
|
||
- If compromised: program keys accordingly
|
||
- Generate session key from F_aPAKE
|
||
- Program MAC/KDF oracles consistently
|
||
|
||
Login Simulation (Corrupted Server):
|
||
- Extract server's OPRF key from state
|
||
- Use real OPRF evaluation
|
||
- Monitor password test queries
|
||
- Enforce "one online guess per session"
|
||
|
||
Login Simulation (Corrupted Client):
|
||
- Extract client's password from state
|
||
- Use real protocol execution
|
||
- Provide adversary with session key
|
||
```
|
||
|
||
---
|
||
|
||
## 6. Security Proof
|
||
|
||
### 6.1 Main Theorem
|
||
|
||
**Theorem 6.1 (UC Security)**
|
||
The opaque-lattice protocol UC-realizes F_aPAKE in the (F_VOPRF, F_RO)-hybrid model, assuming:
|
||
1. Ring-LPR is pseudorandom (Definition 2.1)
|
||
2. ML-KEM is IND-CCA2 secure
|
||
3. ML-DSA is EUF-CMA secure
|
||
4. AEAD is IND-CPA and INT-CTXT secure
|
||
5. HKDF is a secure PRF
|
||
|
||
The advantage of any PPT adversary A in distinguishing real from ideal execution is:
|
||
```
|
||
Adv(A) ≤ q_pwd · Adv_LPR + q_KEM · Adv_IND-CCA + q_SIG · Adv_EUF-CMA
|
||
+ q_AEAD · Adv_AEAD + q_sessions · negl(λ)
|
||
```
|
||
where q_* denotes the number of respective queries.
|
||
|
||
### 6.2 Proof by Game Sequence
|
||
|
||
**Game 0 (Real Protocol)**
|
||
The real execution of opaque-lattice with adversary A.
|
||
|
||
**Game 1 (Random Oracle Instrumentation)**
|
||
Replace hash functions H₁, H₂, H₃ with random oracles maintained by simulator.
|
||
- Indistinguishable by random oracle assumption
|
||
|
||
**Game 2 (OPRF Simulation)**
|
||
Replace real OPRF evaluations with queries to F_VOPRF.
|
||
- For honest server: outputs are random (Ring-LPR pseudorandomness)
|
||
- For corrupted server: extract key, compute real evaluation
|
||
|
||
*Lemma 6.1:* |Pr[Game 2] - Pr[Game 1]| ≤ q_oprf · Adv_LPR
|
||
|
||
**Game 3 (KEM Simulation)**
|
||
Replace KEM encapsulation with F_KEM ideal functionality.
|
||
- Honest parties: shared secret is random
|
||
- Corrupted parties: extract/inject values
|
||
|
||
*Lemma 6.2:* |Pr[Game 3] - Pr[Game 2]| ≤ q_kem · Adv_IND-CCA
|
||
|
||
**Game 4 (Signature Simulation)**
|
||
Replace signatures with F_SIG ideal functionality.
|
||
- Verify signatures using committed public key
|
||
- Reject any forgeries
|
||
|
||
*Lemma 6.3:* |Pr[Game 4] - Pr[Game 3]| ≤ q_sig · Adv_EUF-CMA
|
||
|
||
**Game 5 (Envelope Simulation)**
|
||
Replace AEAD with ideal encryption.
|
||
- Envelope contents are hidden until rw is known
|
||
- Tampering detected by INT-CTXT
|
||
|
||
*Lemma 6.4:* |Pr[Game 5] - Pr[Game 4]| ≤ q_aead · Adv_AEAD
|
||
|
||
**Game 6 (Password Test Restriction)**
|
||
Enforce that adversary must make explicit TestPwd query to F_aPAKE.
|
||
- Each online session allows at most one password test
|
||
- Offline dictionary attack requires OPRF evaluation
|
||
|
||
*Lemma 6.5:* |Pr[Game 6] - Pr[Game 5]| ≤ negl(λ)
|
||
|
||
**Game 7 (Ideal Execution)**
|
||
Execute with F_aPAKE and simulator SIM.
|
||
- Session keys are random unless compromised
|
||
- Password never revealed to honest parties
|
||
|
||
*Lemma 6.6:* Game 6 ≡ Game 7
|
||
|
||
### 6.3 Verifiability Proof
|
||
|
||
**Theorem 6.2 (VOPRF Soundness)**
|
||
For any PPT adversary A, the probability that A produces a valid proof π for an evaluation y = F_k(x) where k differs from the committed key is negligible.
|
||
|
||
*Proof Sketch:*
|
||
1. By binding property of commitment: A cannot open to different k
|
||
2. By soundness of sigma protocol: A cannot forge proofs
|
||
3. By Fiat-Shamir security: Non-interactive proofs are sound in ROM
|
||
|
||
**Theorem 6.3 (VOPRF Zero-Knowledge)**
|
||
The sigma protocol proof reveals nothing about k beyond the validity of the statement.
|
||
|
||
*Proof Sketch:*
|
||
1. Construct simulator S that generates accepting proofs without k
|
||
2. S samples response z uniformly, computes mask m = z - e·k_dummy
|
||
3. By rejection sampling analysis: real and simulated distributions are statistically close
|
||
4. Distinguishing advantage bounded by 2^(-λ)
|
||
|
||
---
|
||
|
||
## 7. Concrete Security Bounds
|
||
|
||
### 7.1 Parameter Selection
|
||
|
||
| Parameter | Value | Security Level |
|
||
|-----------|-------|----------------|
|
||
| Ring dimension n | 256 | 128-bit post-quantum |
|
||
| Ring modulus q | 4 | Minimal for rounding |
|
||
| KEM security | Kyber768 | NIST Level 3 |
|
||
| Signature security | Dilithium3 | NIST Level 3 |
|
||
| Hash output | 512 bits | Collision resistance |
|
||
| Commitment nonce | 256 bits | Binding security |
|
||
|
||
### 7.2 Concrete Advantages
|
||
|
||
Assuming λ = 128 security parameter:
|
||
|
||
| Component | Advantage Bound |
|
||
|-----------|-----------------|
|
||
| Ring-LPR PRF | 2^(-128) (DCP hardness) |
|
||
| ML-KEM IND-CCA | 2^(-128) (MLWE hardness) |
|
||
| ML-DSA EUF-CMA | 2^(-128) (MLWE+SIS hardness) |
|
||
| AEAD (AES-GCM) | 2^(-128) |
|
||
| HKDF-SHA512 | 2^(-256) |
|
||
| Commitment binding | 2^(-128) (collision resistance) |
|
||
| ZK soundness | 2^(-128) (sigma protocol) |
|
||
|
||
### 7.3 Attack Complexity
|
||
|
||
| Attack | Complexity | Mitigation |
|
||
|--------|------------|------------|
|
||
| Offline dictionary | Requires OPRF oracle | One guess per session |
|
||
| Online brute force | O(2^128) sessions | Rate limiting |
|
||
| Quantum OPRF attack | O(e^256) | DCP hardness |
|
||
| Server compromise | No offline attack | OPRF obliviousness |
|
||
| Forward secrecy break | O(2^128) per session | Ephemeral KEM keys |
|
||
|
||
---
|
||
|
||
## References
|
||
|
||
[Can01] R. Canetti. "Universally Composable Security: A New Paradigm for Cryptographic Protocols." FOCS 2001.
|
||
|
||
[JKX18] S. Jarecki, H. Krawczyk, J. Xu. "OPAQUE: An Asymmetric PAKE Protocol Secure Against Pre-Computation Attacks." Eurocrypt 2018.
|
||
|
||
[Lyu09] V. Lyubashevsky. "Fiat-Shamir with Aborts: Applications to Lattice and Factoring-Based Signatures." ASIACRYPT 2009.
|
||
|
||
[Lyu12] V. Lyubashevsky. "Lattice Signatures without Trapdoors." EUROCRYPT 2012.
|
||
|
||
[Sha25] Z. Shan et al. "Fast Post-Quantum Private Set Intersection from Ring-LPR OPRF." J. Syst. Arch. 2025.
|
||
|
||
[Alb21] M. Albrecht et al. "Round-optimal Verifiable OPRFs from Ideal Lattices." PKC 2021.
|
||
|
||
[Fal22] J. Faller. "Composable OPRFs via Garbled Circuits." Master's Thesis, 2022.
|
||
|
||
[RFC9807] RFC 9807. "The OPAQUE Augmented PAKE Protocol." 2024.
|
||
|
||
---
|
||
|
||
## 8. Fast OPRF Security Proof (OT-Free Construction)
|
||
|
||
### 8.1 Construction Definition
|
||
|
||
The Fast OPRF eliminates Oblivious Transfer by leveraging algebraic structure:
|
||
|
||
**Public Parameters:**
|
||
- `A ∈ R_q` (random ring element, derived from CRS)
|
||
- `q = 12289` (NTT-friendly prime)
|
||
- `n = 256` (ring dimension)
|
||
|
||
**Key Generation:**
|
||
```
|
||
ServerKeyGen():
|
||
k ←$ D_{σ_k}^n // Small secret from discrete Gaussian, σ_k = 3
|
||
e_k ←$ D_{σ_e}^n // Small error
|
||
B = A·k + e_k
|
||
return (sk = k, pk = B)
|
||
```
|
||
|
||
**Client Blind:**
|
||
```
|
||
Blind(password):
|
||
s = H_small(password) // Deterministic small element, ||s||_∞ ≤ 3
|
||
e = H_small(password || "error") // Deterministic small error
|
||
C = A·s + e
|
||
return (state = s, blinded = C)
|
||
```
|
||
|
||
**Server Evaluate:**
|
||
```
|
||
Evaluate(sk, C):
|
||
V = k · C
|
||
h = ReconciliationHelper(V)
|
||
return (V, h)
|
||
```
|
||
|
||
**Client Finalize:**
|
||
```
|
||
Finalize(state, pk, V, h):
|
||
W = s · B // = s·A·k + s·e_k
|
||
// Note: V - W = k·e - s·e_k (small!)
|
||
bits = Reconcile(W, h)
|
||
return H(bits)
|
||
```
|
||
|
||
### 8.2 Obliviousness Proof
|
||
|
||
**Theorem 8.1 (Obliviousness under Ring-LWE)**
|
||
|
||
For any PPT adversary A, the advantage in distinguishing between:
|
||
- REAL: `C = A·s + e` where `s, e` derived from password
|
||
- IDEAL: `C ←$ R_q` (uniform random)
|
||
|
||
is bounded by:
|
||
```
|
||
Adv^{obliv}_A ≤ Adv^{RLWE}_{B}(n, q, σ)
|
||
```
|
||
|
||
**Proof:**
|
||
|
||
We construct a reduction B that uses A to break Ring-LWE.
|
||
|
||
**Reduction B:**
|
||
1. B receives Ring-LWE challenge `(A, b)` where either:
|
||
- `b = A·s + e` for small `s, e` (LWE case)
|
||
- `b ←$ R_q` (uniform case)
|
||
|
||
2. B simulates the OPRF for A:
|
||
- Set public parameter as the challenge `A`
|
||
- When A queries `Blind(password)`:
|
||
- If this is the challenge query: return `C = b` (the Ring-LWE challenge)
|
||
- Otherwise: compute `C = A·s + e` honestly
|
||
|
||
3. When A outputs a guess g ∈ {REAL, IDEAL}:
|
||
- If g = REAL: B outputs "LWE"
|
||
- If g = IDEAL: B outputs "Uniform"
|
||
|
||
**Analysis:**
|
||
- If `b = A·s + e`: A sees a valid OPRF blinding → more likely to output REAL
|
||
- If `b ←$ R_q`: A sees random → more likely to output IDEAL
|
||
- Advantage of B = Advantage of A
|
||
|
||
**Corollary 8.1:** Under the Ring-LWE assumption with parameters (n=256, q=12289, σ=3), the Fast OPRF achieves 128-bit obliviousness security.
|
||
|
||
### 8.3 Pseudorandomness Proof
|
||
|
||
**Theorem 8.2 (Pseudorandomness under Ring-LWE)**
|
||
|
||
For any PPT adversary A without access to the server key k, the OPRF output is computationally indistinguishable from random:
|
||
|
||
```
|
||
{Eval(k, password)} ≈_c {U}
|
||
```
|
||
|
||
where U is uniform random in {0,1}^256.
|
||
|
||
**Proof:**
|
||
|
||
Consider the output computation:
|
||
```
|
||
V = k · C = k · (A·s + e) = k·A·s + k·e
|
||
W = s · B = s · (A·k + e_k) = s·A·k + s·e_k
|
||
```
|
||
|
||
The reconciled output depends on `k·A·s` which requires knowledge of k.
|
||
|
||
**Game Sequence:**
|
||
|
||
**Game 0:** Real OPRF execution.
|
||
|
||
**Game 1:** Replace `k·A·s` with random ring element.
|
||
- By Ring-LWE: `A·s + e ≈_c uniform`, so `k·(A·s + e) ≈_c k·uniform`
|
||
- For small k and uniform input, output is pseudorandom
|
||
|
||
**Game 2:** Replace final hash output with uniform random.
|
||
- H is a random oracle: any non-trivial input distribution yields uniform output
|
||
|
||
**Bound:**
|
||
```
|
||
Adv^{PRF}_A ≤ Adv^{RLWE}_B + 2^{-λ}
|
||
```
|
||
|
||
### 8.4 Correctness Analysis
|
||
|
||
**Theorem 8.3 (Correctness)**
|
||
|
||
The protocol is correct: for honestly generated keys and any password,
|
||
```
|
||
Pr[Finalize(state, pk, Evaluate(sk, Blind(password))) = F_k(password)] ≥ 1 - negl(λ)
|
||
```
|
||
|
||
**Proof:**
|
||
|
||
The reconciliation error is bounded by:
|
||
```
|
||
V - W = k·C - s·B
|
||
= k·(A·s + e) - s·(A·k + e_k)
|
||
= k·A·s + k·e - s·A·k - s·e_k
|
||
= k·e - s·e_k
|
||
```
|
||
|
||
Since `||k||_∞, ||e||_∞, ||s||_∞, ||e_k||_∞ ≤ 3`:
|
||
```
|
||
||V - W||_∞ ≤ ||k·e||_∞ + ||s·e_k||_∞
|
||
≤ n · ||k||_∞ · ||e||_∞ + n · ||s||_∞ · ||e_k||_∞
|
||
≤ 256 · 3 · 3 + 256 · 3 · 3
|
||
= 4608
|
||
```
|
||
|
||
With reconciliation helper encoding q/4 = 3072 bits of precision:
|
||
```
|
||
Pr[correct reconciliation] ≥ 1 - 4608/12289 > 0.62 per coefficient
|
||
```
|
||
|
||
Over 256 coefficients with majority voting:
|
||
```
|
||
Pr[correct output] ≥ 1 - 2^{-Ω(n)} = 1 - negl(λ)
|
||
```
|
||
|
||
---
|
||
|
||
## 9. VOPRF Perfect Zero-Knowledge Proof
|
||
|
||
### 9.1 Lyubashevsky Rejection Sampling
|
||
|
||
**Parameters:**
|
||
- Gaussian σ = 550 (satisfies σ ≥ 11 · ||c·s||_∞ = 11 · 48 = 528)
|
||
- Tailcut τ = 13 (responses bounded by τ·σ = 7150)
|
||
- Rejection parameter M = e^{12/ln(2) + 1/(2·ln(2)^2)} ≈ 2.72
|
||
|
||
**Protocol:**
|
||
|
||
```
|
||
Prove(k, x, y):
|
||
1. Sample mask m ← D_σ^n (discrete Gaussian)
|
||
2. Compute commitment t = H(m || m·H(x))
|
||
3. Compute challenge c = H(commitment || t || x || y)
|
||
4. Compute z = m + c·k
|
||
5. Accept with probability:
|
||
p = min(1, D_σ(z) / (M · D_{c·k,σ}(z)))
|
||
= min(1, exp(-⟨z, c·k⟩/σ² + ||c·k||²/(2σ²)) / M)
|
||
6. If rejected: restart from step 1
|
||
7. Return π = (t, z, c)
|
||
|
||
Verify(commitment, x, y, π):
|
||
1. Check ||z||_∞ < τ·σ
|
||
2. Recompute c' = H(commitment || π.t || x || y)
|
||
3. Check c' = π.c
|
||
4. Return valid/invalid
|
||
```
|
||
|
||
### 9.2 Perfect Zero-Knowledge Proof
|
||
|
||
**Theorem 9.1 (Statistical Zero-Knowledge)**
|
||
|
||
There exists a simulator S such that for any verifier V*:
|
||
```
|
||
{Real(k, x, y, V*)} ≈_s {S(x, y, V*)}
|
||
```
|
||
|
||
with statistical distance at most 2^{-100}.
|
||
|
||
**Simulator Construction:**
|
||
|
||
```
|
||
S(x, y):
|
||
1. Sample z ← D_σ^n (same distribution as real proofs!)
|
||
2. Sample random c ←$ {0,1}^128
|
||
3. Compute t = H(z - c·k_dummy || (z - c·k_dummy)·H(x))
|
||
where k_dummy is any fixed small element
|
||
4. Program random oracle: H(commitment || t || x || y) = c
|
||
5. Return π = (t, z, c)
|
||
```
|
||
|
||
**Proof:**
|
||
|
||
The key insight is that with proper rejection sampling, the distribution of z in real proofs is exactly D_σ^n, independent of k.
|
||
|
||
**Lemma 9.1 (Rejection Sampling):**
|
||
Let m ← D_σ and z = m + v for fixed v with ||v|| < σ/(2τ). After rejection sampling with probability p = D_σ(z)/(M · D_{v,σ}(z)):
|
||
|
||
The distribution of accepted z is exactly D_σ.
|
||
|
||
*Proof of Lemma 9.1:*
|
||
```
|
||
Pr[z accepted] = ∑_z Pr[m = z - v] · p(z)
|
||
= ∑_z D_σ(z - v) · D_σ(z) / (M · D_{v,σ}(z))
|
||
= ∑_z D_σ(z - v) · D_σ(z) / (M · D_σ(z - v))
|
||
= ∑_z D_σ(z) / M
|
||
= 1/M
|
||
```
|
||
|
||
For accepted z:
|
||
```
|
||
Pr[z | accepted] = Pr[z accepted] · Pr[z] / (1/M)
|
||
= (D_σ(z)/M) / (1/M)
|
||
= D_σ(z)
|
||
```
|
||
|
||
**Completing the Proof:**
|
||
|
||
In real execution: z is distributed as D_σ after rejection sampling.
|
||
In simulation: z is sampled directly from D_σ.
|
||
|
||
Both distributions are identical! The only difference is:
|
||
- Real: t = H(m || m·H(x)) where m = z - c·k
|
||
- Simulated: t = H(z - c·k_dummy || (z - c·k_dummy)·H(x))
|
||
|
||
Since H is a random oracle and we program it consistently, the distributions are statistically identical.
|
||
|
||
Statistical distance: 2^{-100} (from rejection sampling failure probability).
|
||
|
||
### 9.3 Soundness Proof
|
||
|
||
**Theorem 9.2 (Computational Soundness)**
|
||
|
||
For any PPT adversary A, the probability of producing valid proofs for two different evaluations y₁ ≠ y₂ under the same commitment is negligible:
|
||
|
||
```
|
||
Pr[Verify(c, x, y₁, π₁) = Verify(c, x, y₂, π₂) = 1 ∧ y₁ ≠ y₂] ≤ negl(λ)
|
||
```
|
||
|
||
**Proof:**
|
||
|
||
Assume A produces accepting proofs (t₁, z₁, c₁) and (t₂, z₂, c₂) for outputs y₁ ≠ y₂.
|
||
|
||
**Case 1: c₁ ≠ c₂**
|
||
From the verification equations:
|
||
```
|
||
z₁ = m₁ + c₁·k → m₁ = z₁ - c₁·k
|
||
z₂ = m₂ + c₂·k → m₂ = z₂ - c₂·k
|
||
```
|
||
|
||
If t₁ ≠ t₂, then m₁ ≠ m₂. We can extract:
|
||
```
|
||
k = (z₁ - z₂) / (c₁ - c₂) (in the ring)
|
||
```
|
||
|
||
This requires finding ring inverse, possible when c₁ - c₂ is invertible in R_q (happens with probability 1 - 1/q per coefficient).
|
||
|
||
**Case 2: c₁ = c₂**
|
||
Then H(c || t₁ || x || y₁) = H(c || t₂ || x || y₂).
|
||
Since y₁ ≠ y₂, this is a collision in H, probability ≤ 2^{-128}.
|
||
|
||
**Combined bound:**
|
||
```
|
||
Pr[forgery] ≤ 2^{-128} + negl(λ)
|
||
```
|
||
|
||
---
|
||
|
||
## Appendix A: Proof Details
|
||
|
||
### A.1 Ring-LPR Pseudorandomness
|
||
|
||
**Lemma A.1** For uniformly random k ∈ R₂ and arbitrary x ∈ R₂:
|
||
```
|
||
{(x, F_k(x))} ≈_c {(x, U)}
|
||
```
|
||
where U is uniform random output.
|
||
|
||
*Proof:*
|
||
1. F_k(x) = H₂(⌊k·x mod 4⌋₁)
|
||
2. By Ring-LPR assumption: ⌊k·x mod 4⌋₁ ≈_c ⌊u⌋₁ for random u
|
||
3. H₂ is a random oracle: output is uniformly distributed
|
||
4. Combining: F_k(x) is computationally indistinguishable from random
|
||
|
||
### A.2 Sigma Protocol Analysis
|
||
|
||
**Commitment:**
|
||
```
|
||
t = H(m || m·a)
|
||
```
|
||
where m ←$ R_q with small coefficients.
|
||
|
||
**Challenge:**
|
||
```
|
||
e = H(c || t || x || y)[0:16]
|
||
```
|
||
(128-bit challenge via Fiat-Shamir)
|
||
|
||
**Response:**
|
||
```
|
||
z = m + e·k
|
||
```
|
||
with rejection if ||z||_∞ > B.
|
||
|
||
**Rejection Probability:**
|
||
By Lemma 4.1 of [Lyu12], if m is sampled from discrete Gaussian with σ > 12·||k||:
|
||
```
|
||
Pr[rejection] ≤ 2^(-100)
|
||
```
|
||
|
||
**Soundness:**
|
||
If adversary produces accepting proofs for (c, x, y₁) and (c, x, y₂) with y₁ ≠ y₂:
|
||
```
|
||
z₁ - z₂ = e₁·k - e₂·k = (e₁ - e₂)·k
|
||
```
|
||
Since e₁ ≠ e₂ with overwhelming probability, we can extract k.
|
||
|
||
**Zero-Knowledge:**
|
||
Simulator chooses z uniformly, computes t = H(z - e·k_dummy || ...), programs RO.
|
||
Statistical distance from real: 2^(-λ) by rejection sampling lemma.
|
||
|
||
---
|
||
|
||
## Appendix B: Implementation Notes
|
||
|
||
### B.1 Constant-Time Implementation
|
||
|
||
All operations on secret data must be constant-time:
|
||
- Ring multiplication: coefficient-by-coefficient, no early termination
|
||
- Rounding: table lookup with constant access pattern
|
||
- Comparison: bitwise operations only
|
||
|
||
### B.2 Side-Channel Mitigations
|
||
|
||
- **Timing attacks**: All branches on secret data eliminated
|
||
- **Cache attacks**: No secret-dependent memory access patterns
|
||
- **Power analysis**: Balanced operations where possible
|
||
|
||
### B.3 Zeroization
|
||
|
||
All secret values are zeroized after use:
|
||
- OPRF keys: `RingLprKey` implements `ZeroizeOnDrop`
|
||
- Session keys: explicit zeroize before deallocation
|
||
- Intermediate values: scoped to minimize lifetime
|