Last active
August 6, 2024 11:19
-
-
Save odzhan/3310d20e9def10128c62cc3154b1c63d to your computer and use it in GitHub Desktop.
ECDH using P-192 prime192v1
This file contains hidden or 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
# | |
# 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