JPake Implementation

22-02-2021 / Edit on Github

The Yakk JPake Implementation 🔗

PAKE 🔗

password_strength_xkcd

It's a well-known fact -- strong passwords are better! (up until you can't remember them that is).

When creating YAKK, I wanted a way of allowing 2 users to share a signalling connection, but without mandating that they use a large secure key to encrypt the connection information. In addition, I was adamant that the controller of the communication channel between these 2 users cannot evesdrop on the messages sent without knowing the shared password, and is not able to brute-force guess the password. (TLDR: see it in action here)

Enter Password Authenticated Key Exchange (PAKE).

PAKE allows our 2 parties, Alice and Bob, to establish a shared cryptographic key using a weak shared secret (like a simple password), without needing to trust the communication channel used to establish the shared key.

JPake using modular arithmetic 🔗

J-PAKE (Password Authenticated Key Exchange by Juggling) is one such PAKE protocol, proposed by Hao and Ryan.

It consists of 2 stages:

  • one-time key establishment
  • key confirmation

A quick summary of the protocol can be written as follows.

Round 0 🔗

First, both Alice and Bob separately derive secret value ss from a shared low-entropy password ss'.

In our implementation, this is done as s=H(asBase64String(s)) mod qs = H(asBase64String(s')) \text{ mod } q. This is because ss has to be in the range [1,q1][1,q-1]. Alice and Bob also both check that ss is not equal to zero

AliceBob
Select x1x_1 uniformly from [0,q1][0,q-1]Select x3x_3 uniformly from [0,q1][0,q-1]
Select x2x_2 uniformly from [0,q1][0,q-1]Select x4x_4 uniformly from [0,q1][0,q-1]

Round 1 🔗

Alice -> BobBob -> Alice
xG1=gx1 mod pxG1 = g^{x_1} \text{ mod } pxG3=gx3 mod pxG3 = g^{x_3} \text{ mod } p
xG2=gx2 mod pxG2 = g^{x_2} \text{ mod } pxG4=gx4 mod pxG4 = g^{x_4} \text{ mod } p
ZKP for x1x_1 and x2x_2ZKP for x3x_3 and x4x_4

Round 2 🔗

Alice -> BobBob -> Alice
Verify received ZKP for x3x_3 and x4x_4Verify received ZKP for x1x_1 and x2x_2
A=(xG1xG3xG4)x2s mod pA = (xG1*xG3*xG4)^{x_2s} \text{ mod } pB=(xG1xG2xG3)x4s mod pB = (xG1*xG2*xG3)^{x_4s} \text{ mod } p
ZKP for x2sx_2sZKP for x4sx_4s

Compute Shared Key 🔗

Alice's Shared KeyBob's Shared Key
Verify received ZKP for x2sx_2sVerify received ZKP for x4sx_4s
Ka=(BxG4x2s)x2 mod pK_a = (\frac{B}{xG4^{x_2s}})^{x_2} \text{ mod } pKb=(AxG2x4s)x4 mod pK_b = (\frac{A}{xG2^{x_4s}})^{x_4} \text{ mod } p

Here, K=Ka=Kb=g((x1+x3)x2x4s) mod pK = K_a = K_b = g^{((x_1+x_3)*x_2*x_4*s)} \text{ mod } p

Using KK as an input, we can then apply a Key Derivation Function (KDF) to derive a common session key kk. In our implementation, we do this by doing:

k=H(asBase64String(K.x))k = H(asBase64String(K.x))

JPake using elliptic curves 🔗

The discrete log problem 🔗

Let G be a group with binary operation \oplus.
Let g be any element of G. For any positive integer k, the expression bkb^k denotes performing the operation \oplus on bb with itself kk times.

i.e. gk=ggg...gk timesg^k = \underbrace{g \oplus g \oplus g ... \oplus g}_{\text{k times}}.

Any integer kk which solves the equation gk=ag^k = a is termed to be a discrete logarithm of aa to the base gg, i.e. k=loggak = \log_ga.

In the above setting, we used the group (Zp)x(Z_p)^x to perform our cryptographic operations. This is the group of multiplication modulo the prime pp.

Eg: In the group 343^4 in the group (Z17)x(Z_{17})^x, is calculated as: 34mod173^4 mod 17.

Note that the discrete log problem is only hard in certain carefully chosen groups. Other than the group of (Zp)x(Z_p)^x we saw earlier, another group which is useful to us in the cryptographic context is based on elliptic curves.

Elliptic curves 🔗

For cryptographic purposes, an elliptic curve is defined as a plane curve over a finite field which consists of points satisfying the equation

y2=x3+ax+by^2 = x^3 + ax + b

Combined with a group operation \oplus as an addition of 2 elements in the group, allows us to reformulate our discrete log problem as:

gk=ggg...gk times=g+g+g+...+gk times=kgg^k = \underbrace{g \oplus g \oplus g ... \oplus g}_{\text{k times}} = \underbrace{g +g + g + ... + g}_{\text{k times}} = kg

We can convert operations from the group (Zp)x(Z_p)^x to the elliptic curve setting by converting them as the following:

(Zp)x(Z_p)^x methodsElliptic curve methods (over a finite field p)
exponentiation gx mod pg^x \text{ mod } p->multiplication xGxG
multiplication gxgy mod pg^xg^y \text{ mod } p->point addition xG+yGxG + yG
division gxgy mod p\frac{g^x}{g^y} \text{ mod } p->point subtraction $(xG - yG)

JPake using elliptic curves 🔗

With this knowledge, we can then convert our modular arithmetic operations into elliptic curve operations using the generator GG.

Round 0 🔗

AliceBob
Select x1x_1 uniformly from [0,q1][0,q-1]Select x3x_3 uniformly from [0,q1][0,q-1]
Select x2x_2 uniformly from [0,q1][0,q-1]Select x4x_4 uniformly from [0,q1][0,q-1]

Round 1 🔗

Alice -> BobBob -> Alice
xG1=x1GxG1 = x_1Gx3G=x3Gx3G = x_3G
xG2=x2GxG2 = x_2GxG4=x4GxG4 = x_4G
ZKP for x1x_1 and x2x_2ZKP for x1x_1 and x2x_2

Round 2 🔗

Alice -> BobBob -> Alice
Verify received ZKP for x3x_3 and x4x_4Verify received ZKP for x1x_1 and x2x_2
A=(xG1+xG3+xG4)×x2sA = (xG1+xG3+xG4) \times x_2sB=(xG1+xG2+xG3)×x4sB = (xG1+xG2+xG3) \times x_4s
ZKP for x2sx_2sZKP for x4sx_4s

Compute Shared Key 🔗

Alice's Shared KeyBob's Shared Key
Verify received ZKP for x2sx_2sVerify received ZKP for x4sx_4s
Ka=x2×(B(x2s)×x4G)K_a = x_2 \times (B - (x_2s) \times x_4G)Kb=x4×(A(x4s)×x2G)K_b = x_4 \times (A - (x_4s) \times x_2G)