SPEKE (Simple Password Exponential Key Exchange) supports password-authenticated key agreement [1]. With the elliptic curve version, Bob and Alice share a secret password (\(\pi\)) and a pre-defined shared elliptic curve. The password is then hashed and matched to the nearest point on the elliptic curve (\(P_{pass}\)). After this, we use a standard Diffie-Hellman type exchange. Alice generates a random number \(a\) and Bob generates a random number \(b\). Alice then sends \(a P_{pass}\) and Bob sends \(b P_{pass}\). Alice computes the shared key as \(a bP_{pass}\) and Bob computes the shared key as \(b a P_{pass}\). The resultant key is \(abP_{pass}\). [SPEKE][SPEKE (Elliptic Curve)].
SPEKE (Simple Password Exponential Key Exchange) - Elliptic Curve |
Theory
SPEKE (Simple Password Exponential Key Exchange) supports password-authenticated key agreement [1]. With the elliptic curve version, Bob and Alice share a secret password (\(\pi\)) and a pre-defined shared elliptic curve. The password is then hashed and matched to the nearest point on the elliptic curve (\(P_{pass}\)). After this, we use a standard Diffie-Hellman type exchange. Alice generates a random number \(a\) and Bob generates a random number \(b\). Alice then sends:
\(A=a P_{pass}\)
and Bob sends:
\(B = b P_{pass}\)
Alice computes the shared key as:
\(K_a = a bP_{pass}\)
and Bob computes the shared key as:
\(K_b = b a P_{pass}\)
The resultant key is:
\(K=abP_{pass}\)
The code is:
from secp256k1 import curve,scalar_mult,is_on_curve import random import hashlib import sys print("Basepoint:\t", curve.g) pi="Hello12" if (len(sys.argv)>1): pi=(sys.argv[1]) a = random.randrange(1, curve.n) b = random.randrange(1, curve.n) sha1 = hashlib.sha1() sha1.update(pi.encode()) pi_val=int(sha1.hexdigest(),16) while (True): Gpass=scalar_mult(pi_val,curve.g) print (pi_val) if (is_on_curve(Gpass)): break pi_val = pi_val+1 A = scalar_mult(a,Gpass) B= scalar_mult(b,Gpass) K1= scalar_mult(b,A) K2= scalar_mult(a,B) print ("Password: ",pi) print ("\nG Password:\t",Gpass) print ("\na (Alice):\t",a) print ("b (Bob):\t",b) print ("\nA (Alice):\t",A) print ("B (Bob):\t",B) print ("\nKey (Alice):\t",K1[0]) print ("Key (Bob):\t",K2[0]) ab = (a*b) % curve.n K = scalar_mult(ab,Gpass) print ("\nCheck Key (abG):\t",K[0])
A sample run is:
Basepoint: (55066263022277343669578718895168534326250603453777594175500187360389116729240, 32670510020758816978083085130507043184471273380659243275938904335757337482424) 1415821221623963719413415453263690387336440359920 Password: Hello G Password: (65263944084342197025982124855390080779660665968109789976012065852149178226136, 109090808538266950129139030441868732836608221927863983502692128997257182831796) a (Alice): 48185787601198123356043137125673840923931232500115760542256524798506782078508 b (Bob): 29639847004469692476331743385978312761531585925135259595814894165542797423162 A (Alice): (21085828653989277334674342610986873409847711531993257586241279793917261226755, 92221957071356973682119674658656669322901778695497344614187149567674647993412) B (Bob): (8796344150785726626550877995972978159779090732523192035287428403371731204637, 4585514135139190939947207782465169045619890452614570058646501179659359957650) Key (Alice): 96208563962866347524960918151313886255531149937798325149439757292973279449065 Key (Bob): 96208563962866347524960918151313886255531149937798325149439757292973279449065 Check Key (abG): 96208563962866347524960918151313886255531149937798325149439757292973279449065
Presentation
References
[1] Jablon, D. P. (1996). Strong password-only authenticated key exchange. ACM SIGCOMM Computer Communication Review, 26(5), 5-26 [here].