Created
September 8, 2019 19:56
-
-
Save odzhan/d3fb190510f0657cabbdf140a7cc6984 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// naive implementation of ecdh using secp192r1 | |
// odzhan | |
import java.math.*; | |
import java.security.spec.ECPoint; | |
import java.security.*; | |
public class ECDH { | |
static BigInteger TWO = new BigInteger("2"); | |
static BigInteger THREE = new BigInteger("3"); | |
static BigInteger m = new BigInteger("fffffffffffffffffffffffffffffffeffffffffffffffff", 16); | |
static BigInteger a = new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffc", 16); | |
static BigInteger gx= new BigInteger("188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", 16); | |
static BigInteger gy= new BigInteger("07192b95ffc8da78631011ed6b24cdd573f977a11e794811", 16); | |
static ECPoint G = new ECPoint(gx, gy); // generator | |
public static void main(String[] args) { | |
ECPoint s1, s2, pk1, pk2; | |
BigInteger sk1, sk2; | |
SecureRandom r; | |
byte r1[] = new byte[24]; | |
byte r2[] = new byte[24]; | |
r = new SecureRandom(); | |
// generate random secret keys for doris + boris | |
r.nextBytes(r1); r.nextBytes(r2); | |
sk1 = new BigInteger(r1).mod(m); | |
sk2 = new BigInteger(r2).mod(m); | |
System.out.print("Doris private key : " + | |
sk1.toString(16) + "\n"); | |
System.out.println("Boris private key : " + | |
sk2.toString(16) + "\n"); | |
// generate public keys | |
pk1 = scalmult(G, sk1); | |
pk2 = scalmult(G, sk2); | |
System.out.print("Doris public key : " + | |
pk1.getAffineX().toString(16) + "\n"); | |
System.out.println("Boris public key : " + | |
pk2.getAffineX().toString(16) + "\n"); | |
// doris and boris exchange pk1 and pk2 | |
// generate shared keys | |
s1 = scalmult(pk2, sk1); | |
s2 = scalmult(pk1, sk2); | |
System.out.print("Doris session key : " + | |
s1.getAffineX().toString(16) + "\n"); | |
System.out.print("Boris session key : " + | |
s2.getAffineX().toString(16) + "\n"); | |
} | |
// modular arithmetic | |
// return a - b % m | |
public static BigInteger modSub(BigInteger a, BigInteger b) { | |
return a.subtract(b).mod(m); | |
} | |
// return a + b % m | |
public static BigInteger modAdd(BigInteger a, BigInteger b) { | |
return a.add(b).mod(m); | |
} | |
// return a * b % m | |
public static BigInteger modMul(BigInteger a, BigInteger b) { | |
return a.multiply(b).mod(m); | |
} | |
// return a ^ -1 % m | |
public static BigInteger modInv(BigInteger a) { | |
return a.modInverse(m); | |
} | |
// return a ^ e % m | |
public static BigInteger modPow(BigInteger a, BigInteger e) { | |
return a.modPow(e, m); | |
} | |
// Scalar Multiplication | |
// R = k * A | |
public static ECPoint scalmult(ECPoint A, BigInteger kin){ | |
ECPoint R = ECPoint.POINT_INFINITY, N = A; | |
BigInteger k = kin.mod(m); | |
int i, bitLength = k.bitLength(); | |
for (i=0; i<bitLength; i++){ | |
if (k.testBit(i)) { | |
R = addPoint(R, N); | |
} | |
N = doublePoint(N); | |
} | |
return R; | |
} | |
// add points | |
public static ECPoint addPoint(ECPoint p, ECPoint q) { | |
BigInteger rx, ry, s, t1, t2; | |
BigInteger px, py, qy, qx; | |
px = p.getAffineX(); py = p.getAffineY(); | |
qx = q.getAffineX(); qy = q.getAffineY(); | |
if (p.equals(q)) { | |
return doublePoint(p); | |
} else if (p.equals(ECPoint.POINT_INFINITY)) { | |
return q; | |
} else if (q.equals(ECPoint.POINT_INFINITY)) { | |
return p; | |
} | |
// t1 = py - qy | |
t1 = modSub(py, qy); | |
// t2 = px - qx | |
t2 = modSub(px, qx); | |
// s = (t1 * (t2 ^ -1)) | |
s = modMul(t1, modInv(t2)); | |
// rx = (((s ^ 2) - px) - qx) | |
rx = modSub(modSub(modPow(s, TWO), px), qx); | |
// ry = (s * (px - rx)) - py | |
ry = modSub(modMul(s, modSub(px, rx)), py); | |
return new ECPoint(rx, ry); | |
} | |
// double point | |
public static ECPoint doublePoint(ECPoint p) { | |
BigInteger rx, ry, s; | |
BigInteger px, py; | |
px = p.getAffineX(); py = p.getAffineY(); | |
if (p.equals(ECPoint.POINT_INFINITY)) { | |
return p; | |
} | |
// s = ((px ^ 2) * 3) + a | |
s = modAdd(modMul(modPow(px, TWO), THREE), a); | |
// s = s * ((py * 2) ^ -1) | |
s = modMul(s, modInv(modMul(py, TWO))); | |
// rx = (s ^ 2) - 2px | |
rx = modSub(modPow(s, TWO), modMul(px, TWO)); | |
// ry = s * (px - rx) - py | |
ry = modSub(modMul(s, modSub(px, rx)), py); | |
return new ECPoint(rx, ry); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment