Imagine Alice and Bob who have never meet other want to establish a secure communication channel with each other, over a network that anyone could be listening to, like the internet? How can they agree on a secret key to encrypt their conversation without an eavesdropper also getting a copy? This is the classic key exchange problem, and one of the most elegant solutions is the Diffie-Hellman Key Exchange.
Published in 1976 by Whitfield Diffie and Martin Hellman, this protocol was one of the first practical examples of public-key cryptography. It allows two parties, let’s call them Alice and Bob, to jointly establish a shared secret key over an insecure channel.
Diffie-Hellman Key Exchange
Before the exchange can begin, Alice and Bob must agree on two public numbers. These numbers are not secret and can be known by everyone, including a potential eavesdropper, Eve.
- A large prime number, p: This is the modulus.
- A generator, g: This is a primitive root modulo p. In simple terms, it’s a number such that when raised to different powers modulo p, it can generate a large number of the values between 1 and p-1.
Let’s say Alice and Bob agree on a public p and g.
Note: The security of the protocol depends on p being a very large number, making certain mathematical problems computationally infeasible to solve.
The Protocol
Now, Alice and Bob will use these public numbers, along with their own private secrets, to generate a shared secret that only they will know.
Step 1: Alice Generates Her Keys
Alice chooses a secret integer a. This is her private key. She must keep this number absolutely secret.
Using her private key a and the public numbers p and g, she computes her public key, A.
A = g^a \bmod pShe then sends her public key A to Bob over the insecure channel.
Step 2: Bob Generates His Keys
Bob does the same thing. He chooses his own secret integer b, his private key.
He then computes his public key, B, using his private key b.
B = g^b \bmod pBob sends his public key B to Alice.
Step 3: Generating the Shared Secret
At this point, Alice and Bob have each other’s public keys.
- Alice has her private key a and Bob’s public key B.
- Bob has his private key b and Alice’s public key A.
Now, Alice computes a value s using her private key a and Bob’s public key B:
s = B^a \bmod pSimilarly, Bob computes a value s using his private key b and Alice’s public key A:
s = A^b \bmod pWhy It Works
Believe it or not, both Alice and Bob have independently calculated the exact same value, s. This value is their shared secret. They can now use s as the key for a symmetric encryption algorithm (like AES) to communicate securely.
But how did they arrive at the same number? Let’s look at the math.
Alice calculated:
s = B^a \bmod pShe knows that B = g^b \bmod p. By substituting this into her equation, she actually calculated:
s = (g^b)^a \bmod p = g^{ba} \bmod pBob calculated:
s = A^b \bmod pHe knows that A = g^a \bmod p. By substituting this into his equation, he actually calculated:
s = (g^a)^b \bmod p = g^{ab} \bmod pSince g^{ba} \bmod p = g^{ab} \bmod p, both parties arrive at the identical secret key!
An eavesdropper, Eve, who was listening to the entire exchange, would know p, g, A, and B. However, she cannot compute the shared secret s. To do so, she would need either Alice’s private key a or Bob’s private key b.
To get a, she would have to solve for it in the equation A = g^a \bmod p. This is known as the discrete logarithm problem. For large prime numbers p, this problem is computationally infeasible to solve with current technology, which is what makes the Diffie-Hellman exchange secure.
Man-in-the-Middle Attack
The Diffie-Hellman exchange we just described is brilliant, but it has one significant vulnerability: it’s anonymous. Alice and Bob generate a shared secret, but they have no cryptographic proof of who is on the other end of the line.
This opens the door for a classic man-in-the-middle (MITM) attack. Hereโs how it works:
- Alice wants to talk to Bob, so she sends her public key, A, to him.
- Eve intercepts Alice’s message. She saves Alice’s public key, A, and sends her own public key, E, to Bob instead.
- Bob, thinking he’s received Alice’s key, sends his public key, B, back.
- Eve intercepts Bob’s key. She saves B and sends her own public key, E, to Alice.
- Now, Alice computes a shared secret with Eve (s_{AE} = E^a \bmod p), thinking she’s talking to Bob. Bob also computes a shared secret with Eve (s_{BE} = E^b \bmod p), thinking he’s talking to Alice. Eve can now decrypt messages from Alice, re-encrypt them with Bob’s key, and forward them, reading and modifying everything without either party knowing.
Authenticating with a Password
This is where Password Authenticated Key Exchange (PAKE) protocols come in. PAKE protocols enhance Diffie-Hellman by incorporating a shared, low-entropy secretโlike a human-memorable passwordโto authenticate the participants.
The core idea is that Alice and Bob use their shared password to mathematically transform the key exchange. Both parties must know the password to correctly perform the protocol and derive the same final session key. An attacker like Eve, who doesn’t know the password, cannot successfully complete the handshake on either side.
How PAKE Works
While there are many different PAKE protocols, most of them modify the standard DH exchange. Instead of just exchanging A = g^a, the value sent is a more complex construction that involves both the private key (a) and the shared password.
For example, the password might be used to “blind” the values being exchanged. This ensures that the numbers sent over the wire reveal no information about the password itself. If Eve tries to impersonate Bob, she won’t be able to generate the correct blinded value because she lacks the password, and her side of the exchange will fail Alice’s verification check.
Resisting Offline Attacks
One of the most powerful features of PAKE is its resistance to offline dictionary attacks. If Eve captures a full PAKE session, she cannot take that data and try guessing the password against it repeatedly on her own machine. The design of the protocol forces an attacker to interact with the legitimate server for each password guess, making attacks slow, noisy, and easy to detect.
A well-known and widely used PAKE protocol is the Secure Remote Password (SRP) protocol, which provides exactly this kind of security. It allows a user to authenticate to a server using a password without ever sending the password (or a simple hash of it) over the network.
Secure Remote Password (SRP) Protocol
The Secure Remote Password (SRP) protocol is a widely respected Password Authenticated Key Exchange (PAKE). It’s designed to be a “zero-knowledge proof” protocol, meaning a client can prove to a server that they know a password without ever revealing the password or any data from which the password could be easily derived.
Let’s formally define the steps involved.
Protocol Parameters & Setup
First, the server and client must agree on some public parameters. These are not secret.
- N: A large, safe prime number. All arithmetic is performed modulo N.
- g: A generator for the multiplicative group modulo N.
- H(): A cryptographic hash function, such as SHA-256.
- k: A multiplier parameter, derived from the public parameters, often as k = H(N, g).
The following values are also used throughout the protocol:
- I: The user’s identity (username).
- P: The user’s password.
- s: A random salt, unique for each user.
- a, b: Ephemeral, secret random numbers generated by the client and server, respectively.
- A, B: The corresponding public ephemeral keys.
- v: The password verifier, stored by the server.
Step 1: Registration (One-Time Setup)
Before a user can authenticate, they must register their password with the server.
- The client (Alice) provides her chosen username I and password P.
- The server generates a random salt s for Alice.
- The client computes a private value, x, by hashing the salt and password:
x = H(s, P)
- The client then computes the password verifier, v:
v = g^x \bmod N
- The client sends (I, s, v) to the server. The server stores I, s, and v in its database.
Crucially, the server never stores the password P or the derived value x. An attacker who compromises the server database only gets the verifier v, which is computationally difficult to reverse to find x (the discrete logarithm problem).
Step 2: Authentication Exchange
This is the multi-step process for logging in.
- Client to Server: Initiate a session
- The client generates a random ephemeral private value a.
- It computes its public key A = g^a \bmod N.
- The client sends its identity I and public key A to the server.
- Server to Client: Respond with a challenge
- The server receives I and A. It first checks if A \bmod N is not zero.
- It looks up the user’s salt s and verifier v from its database.
- The server generates its own random ephemeral private value b.
- It computes its public key B. This calculation cleverly combines the password verifier v with the server’s public component:
B = (k \cdot v + g^b) \bmod N
- The server sends the user’s salt s and its public key B to the client.
- Both Sides Compute the Shared Secret
- First, both client and server compute a common “scrambling parameter” u by hashing the two public keys, A and B:
u = H(A, B)
- The client computes its session key, S_{client}:
- It first re-computes x = H(s, P) using its known salt and password.
- It then computes the session key using its private key a, the server’s public key B, and the scrambling parameter u:
S_{client} = (B – k \cdot g^x)^{(a + u \cdot x)} \bmod N
- The server computes its session key, S_{server}:
- It computes the session key using its private key b, the client’s public key A, its stored verifier v, and the scrambling parameter u:
S_{server} = (A \cdot v^u)^b \bmod N
- It computes the session key using its private key b, the client’s public key A, its stored verifier v, and the scrambling parameter u:
- First, both client and server compute a common “scrambling parameter” u by hashing the two public keys, A and B:
Mathematically, both S_{client} and S_{server} will resolve to the same value. They have now derived a strong, shared secret key S without ever transmitting the password.
How the Keys Match
Let’s walk through the math step-by-step.
The Starting Point
First, let’s recall the final formulas each party uses to compute the session key, S:
- Client’s Formula:
S_{client} = (B – k \cdot g^x)^{(a + u \cdot x)} \bmod N
- Server’s Formula:
S_{server} = (A \cdot v^u)^b \bmod N
Our goal is to show that S_{client} = S_{server} by expanding each formula using the definitions of the variables A, B, and v.
Breaking Down the Client’s Calculation
Let’s begin with the client’s side.
- The client starts with:
S_{client} = (B – k \cdot g^x)^{(a + u \cdot x)} \bmod N
- The client received B from the server, which was calculated as B = (k \cdot v + g^b) \bmod N. We substitute this into the equation:
S_{client} = ((k \cdot v + g^b) – k \cdot g^x)^{(a + u \cdot x)} \bmod N
- The client also knows the password verifier is defined as v = g^x \bmod N. Let’s substitute v:
S_{client} = ((k \cdot g^x + g^b) – k \cdot g^x)^{(a + u \cdot x)} \bmod N
- Now we can simplify the base of the exponent. The k \cdot g^x terms cancel each other out:
S_{client} = (g^b)^{(a + u \cdot x)} \bmod N
- Finally, the simplified form for the client’s key:
S_{client} = g^{b(a + ux)} \bmod N
Breaking Down the Server’s Calculation
Now let’s do the same for the server.
- The server starts with:
S_{server} = (A \cdot v^u)^b \bmod N
- The server received A from the client, where A = g^a \bmod N. Let’s substitute this in:
S_{server} = (g^a \cdot v^u)^b \bmod N
- The server has the stored password verifier v = g^x \bmod N. Substituting this gives:
S_{server} = (g^a \cdot (g^x)^u)^b \bmod N
- We apply the exponent rule latex^n = x^{mn}[/latex] to the second term inside the parentheses:
S_{server} = (g^a \cdot g^{xu})^b \bmod N
- Next, we use the rule m \cdot x^n = x^{m+n} to combine the terms inside the parentheses:
S_{server} = (g^{a + xu})^b \bmod N
- The server’s final simplified form:
S_{server} = g^{(a + xu)b} \bmod N
The Final Result
By expanding both formulas, we can see they resolve to the exact same expression:
S_{client} = g^{b(a + ux)} \bmod N \quad \equiv \quad S_{server} = g^{(a + xu)b} \bmod NThus, S_{client} = S_{server}. Both parties successfully and independently compute an identical shared secret key, S, without ever transmitting their private values (a, b) or the password-derived secret (x) over the network.
Step 3: Mutual Verification
The final step is for both parties to prove to each other that they have the same key S.
- Client proves to Server:
- The client computes a verifier hash M_1 = H(A, B, S_{client}).
- It sends M_1 to the server.
- The server computes its own version of M_1 using S_{server} and verifies that it matches what the client sent. If it doesn’t match, the server aborts the connection.
- Server proves to Client:
- If the client’s proof was valid, the server computes its own proof, M_2 = H(A, M_1, S_{server}).
- It sends M_2 to the client.
- The client computes its version of M_2 and verifies that it matches. If it does, the authentication is successful.
At this point, both parties have authenticated each other and possess a shared, cryptographically strong session key S that can be used for subsequent encrypted communication.
Fuzzy Password-Authenticated Key Exchange
Standard PAKE protocols like SRP are powerful, but they are also brittle. They operate on a simple binary condition: if the passwords match exactly, a key is established; if they differ by even a single character, the authentication fails. This works well for typed passwords, but what about secrets that are inherently “fuzzy” or noisy?
Consider biometrics like an iris scan, or data from a Physical Unclonable Function (PUF). Two readings of the same biometric will never be perfectly identical due to minor variations in measurement. Furthermore, these “pass-strings” often have low entropy, making them vulnerable to guessing.
This introduces a two-fold problem:
- Noise: The two parties’ copies of the secret may not match exactly.
- Low Entropy: The secret may be guessable.
Traditional methods are insufficient here. Standard PAKE fails because of the noise, and classic error-correction techniques (like fuzzy extractors) fail because they require high-entropy secrets and do not protect against offline dictionary attacks.
This is the exact problem that Fuzzy Password-Authenticated Key Exchange (fPAKE) is designed to solve. An fPAKE protocol allows two parties to agree on a shared, high-entropy key as long as their initial pass-strings are “close enough” according to some distance metric (e.g., Hamming distance), while still preventing offline attacks.
The Core Concept of fPAKE
An fPAKE protocol extends the security guarantees of PAKE to a noisy environment. The core idea is as follows:
- Two parties, Alice and Bob, hold pass-strings pw_A and pw_B.
- They agree on a distance metric d(\cdot, \cdot) and a tolerance threshold \delta.
- They execute the fPAKE protocol.
- If d(pw_A, pw_B) \le \delta, they successfully derive the same high-entropy session key.
- If d(pw_A, pw_B) > \delta, they derive independent, random keys (i.e., the protocol fails safely).
The critical security guarantee is that an attacker cannot learn the key, nor can they perform an offline dictionary attack. To make a guess, an attacker must engage in a full, online protocol exchange. This means that even for low-entropy pass-strings (like a 30-bit biometric reading), the cost of guessing is prohibitively high.
Functionality and Leakage
A key innovation in modeling fPAKE is acknowledging that some information leakage might be acceptable to achieve more efficient protocols. The security can be defined with two thresholds:
- Functionality Threshold \delta: If the parties’ pass-strings are within distance \delta, they can successfully agree on a key.
- Security Threshold \gamma (\ge \delta): If an adversary makes a guess that is within distance \gamma of the correct pass-string, the protocol might leak some information. If the guess is farther than \gamma, it leaks nothing.
The type of leakage can vary. In the weakest (but still useful) models, if an adversary’s guess is close enough (within \gamma), the protocol might leak the entire correct pass-string. This is considered acceptable because a guess that close would likely allow the adversary to authenticate successfully anyway. More advanced constructions aim to make the gap between \gamma and \delta as small as possible (ideally, \gamma = \delta) and to minimize any leakage.
Fuzzy PAKE Protocol: The Garbled Circuit Construction
The research paper “Fuzzy Password-Authenticated Key Exchange” proposes fPAKE. This section details the secure, general construction using Garbled Circuits. Its primary advantage is its flexibilityโit can be adapted to any distance metric (like Hamming distance or edit distance) that can be computed by a circuit.
Cryptographic Building Blocks
This protocol combines two powerful cryptographic primitives that you’ve covered previously:
- Yao’s Garbled Circuits (YGC): As described in the post on Garbled Circuits, this technique allows two parties to compute a function on their private inputs. One party, the Garbler, creates an encrypted version of the circuit, \tilde{F}. The other, the Evaluator, runs \tilde{F} on garbled inputs to get a garbled output, which they can then decode.
- 1-out-of-2 Oblivious Transfer (OT): As detailed in the post on Oblivious Transfer, OT is used here to securely provide the Evaluator with the garbled inputs (wire labels) corresponding to their private pass-string bits, without the Garbler learning the Evaluator’s input.
The Protocol
The protocol uses a technique called dual execution, where both parties act as a Garbler and an Evaluator simultaneously to achieve security against malicious adversaries.
Let’s denote the two parties as \mathcal{P}_0 and \mathcal{P}_1, holding fuzzy pass-strings pw_0 and pw_1. The goal is to agree on a key if the distance d(pw_0, pw_1) \le \delta, where \delta is an agreed-upon error tolerance. The core of the protocol is a circuit, f, that takes two pass-strings and outputs ‘1’ if they are close and ‘0’ otherwise.
Step 1: Garbling Phase (Parallel)
Both parties simultaneously prepare a garbled circuit.
- \mathcal{P}_0 garbles the distance-checking circuit f.
(\tilde{F}0, e_0, d_0) \leftarrow \text{Garble}(1^\lambda, f)
Here, \tilde{F}0 is the garbled circuit, e_0 contains the input wire labels, and d_0 contains the decoding information. For a single-bit output, d_0 consists of two random-looking strings, which we’ll call the output labels: k{0,\text{correct}} (for ‘1’) and k{0,\text{wrong}} (for ‘0’).
- \mathcal{P}_1 does the exact same thing independently.
(\tilde{F}1, e_1, d_1) \leftarrow \text{Garble}(1^\lambda, f)
This yields its own garbled circuit \tilde{F}1 and output labels k{1,\text{correct}} and k{1,\text{wrong}}.
Step 2: Input Transfer Phase (Parallel)
The parties now exchange the materials needed for evaluation.
- \mathcal{P}_0 sends its garbled circuit \tilde{F}_0 to \mathcal{P}_1. Symmetrically, \mathcal{P}_1 sends \tilde{F}_1 to \mathcal{P}_0.
- The parties must now get the garbled inputs (wire labels) to evaluate the circuit they just received.
- To evaluate \tilde{F}_1, \mathcal{P}_0 needs garbled inputs for both pw_0 and pw_1. \mathcal{P}_1 directly sends the labels from e_1 that correspond to its own input, pw_1. For \mathcal{P}_0‘s input pw_0, they engage in an Oblivious Transfer. \mathcal{P}_1 acts as the OT Sender with the pair of labels for each bit of pw_0, and \mathcal{P}_0 acts as the OT Receiver, using its bits from pw_0 to select the correct labels.
- This process happens symmetrically for \mathcal{P}_1 to get the labels it needs from \mathcal{P}_0 to evaluate \tilde{F}_0.
Step 3: Evaluation Phase (Parallel)
Each party evaluates the circuit it received from its partner.
- \mathcal{P}_0 evaluates \tilde{F}_1 using the combined garbled inputs X_1 for (pw_0, pw_1).
Y_1 \leftarrow \text{Eval}(\tilde{F}1, X_1)
The result, Y_1, is one of \mathcal{P}1‘s garbled output labels (either k{1,\text{correct}} or k{1,\text{wrong}}).
- Symmetrically, \mathcal{P}_1 evaluates \tilde{F}_0.
Y_0 \leftarrow \text{Eval}(\tilde{F}_0, X_0)
The result, Y_0, is one of \mathcal{P}_0‘s output labels.
Step 4: Key Derivation
This final step cleverly combines key agreement with a consistency check.
- \mathcal{P}0 computes its session key k_0:
k_0 = k{0,\text{correct}} \oplus Y_1
- \mathcal{P}1 computes its session key k_1:
k_1 = k{1,\text{correct}} \oplus Y_0
Why It Works
This elegant key derivation ensures agreement if and only if the pass-strings are close.
- Case 1: Pass-strings are close (d(pw_0, pw_1) \le \delta)
The circuit f outputs ‘1’.
The keys match: k_0 = k_1. A shared secret is established.
- Case 2: Pass-strings are far (d(pw_0, pw_1) > \delta)
The circuit f outputs ‘0’.
Since all four output labels are essentially random, independent strings, k_0 \ne k_1. The keys do not match, and no shared secret is established, failing securely.
Conclusion
We started with the foundational Diffie-Hellman Key Exchange, an elegant solution that allows two parties to establish a shared secret over an insecure channel. While revolutionary, its anonymity makes it vulnerable to man-in-the-middle attacks. To solve this, we introduced Password Authenticated Key Exchange (PAKE) protocols like SRP, which anchor the key exchange to a shared, low-entropy secret like a password. This authenticates the parties and crucially defends against offline dictionary attacks, forcing adversaries into a slower, observable online guessing game. Finally, we addressed the challenge of authenticating with “fuzzy” secrets like biometric data, which are never exactly the same twice. Standard PAKE fails here, but Fuzzy PAKE (fPAKE) provides a solution. By integrating concepts like fuzzy extractors or using advanced cryptographic tools like garbled circuits, fPAKE allows for secure, authenticated key exchange as long as the parties’ secrets are “close enough”. This opens the door to robust authentication systems based on biometrics, PUFs, and other real-world noisy data sources, all while retaining the essential security properties of PAKE.
