Skip to content

Instantly share code, notes, and snippets.

@odzhan
Last active August 6, 2024 11:19
Show Gist options
  • Save odzhan/3310d20e9def10128c62cc3154b1c63d to your computer and use it in GitHub Desktop.
Save odzhan/3310d20e9def10128c62cc3154b1c63d to your computer and use it in GitHub Desktop.
ECDH using P-192 prime192v1
#
# ECDH using P-192 prime192v1
#
# Runs very slow because of binary methods used.
#
import random
# Elliptic curve parameters P-192 prime192v1
p = 0xfffffffffffffffffffffffffffffffeffffffffffffffff
a = 0xfffffffffffffffffffffffffffffffefffffffffffffffc
b = 0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1
Gx = 0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012
Gy = 0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811
def addmod(a, b, m):
return (a + b) % m
def submod(a, b, m):
return (a - b) % m
def mulmod(a, b, m):
r = 0
a = a % m
while b:
if b & 1:
r = addmod(r, a, m)
a = addmod(a, a, m)
b = b >> 1
return r
def modexp(b, e, m):
r = 1
b = b % m
while e:
if e & 1:
r = mulmod(r, b, m)
b = mulmod(b, b, m)
e = e >> 1
return r
def modinv(a, m):
return modexp(a, m - 2, m)
def ecpadd(P, Q):
if (Q == (0, 0)):
return P
if (P == (0, 0)):
return Q
px, py = P
qx, qy = Q
if P != Q:
t1 = submod(py, qy, p)
t2 = submod(px, qx, p)
else:
t1 = mulmod(qx, qx, p)
t1 = mulmod(3, t1, p)
t1 = addmod(t1, a, p)
t2 = addmod(qy, qy, p)
t2 = modinv(t2, p)
s = mulmod(t1, t2, p)
t1 = mulmod(s, s, p)
t2 = addmod(qx, px, p)
rx = submod(t1, t2, p)
t1 = submod(qx, rx, p)
t1 = mulmod(s, t1, p)
ry = submod(t1, qy, p)
return (rx, ry)
def ecpmul(P, n):
Q = (0, 0)
for i in range(n.bit_length()):
if (n >> i) & 1:
Q = ecpadd(Q, P)
P = ecpadd(P, P)
return Q
def test():
print(f"Running test...")
sk = 0xf17d3fea367b74d340851ca4270dcb24c271f445bed9d527
pk_x = 0x42ea6dd9969dd2a61fea1aac7f8e98edcc896c6e55857cc0
pk_y = 0xdfbe5d7c61fac88b11811bde328e8a0d12bf01a9d204b523
secret = 0x803d8ab2e5b6e6fca715737c3a82f7ce3c783124f6d51cd0
skey = ecpmul((pk_x, pk_y), sk)
assert skey[0] == secret
print(f"Passed.")
def main():
#test()
# Generate a private key from random numbers
A_sk = random.randint(1, p-1)
B_sk = random.randint(1, p-1)
print(f"Private Key for Alice : {A_sk}")
print(f"Private Key for Bob : {B_sk}\n")
# Generate public keys.
A_pk = ecpmul((Gx, Gy), A_sk)
B_pk = ecpmul((Gx, Gy), B_sk)
print(f"Public Key for Alice : {A_pk}")
print(f"Public Key for Bob : {B_pk}\n")
# Generate shared secrets
A_secret = ecpmul(B_pk, A_sk)
B_secret = ecpmul(A_pk, B_sk)
print(f"Session Key for Alice : {A_secret}")
print(f"Session Key for Bob : {B_secret}\n")
# Ensure both shared secrets are the same
assert A_secret == B_secret
print("Shared secret:", A_secret[0])
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment