First commit
This commit is contained in:
commit
43a72c3fb7
12 changed files with 213 additions and 0 deletions
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
cr/
|
||||||
|
.venv/
|
BIN
lib/__pycache__/arithmetics.cpython-313.pyc
Normal file
BIN
lib/__pycache__/arithmetics.cpython-313.pyc
Normal file
Binary file not shown.
BIN
lib/__pycache__/diffie_hellman.cpython-313.pyc
Normal file
BIN
lib/__pycache__/diffie_hellman.cpython-313.pyc
Normal file
Binary file not shown.
BIN
lib/__pycache__/miller_rabin.cpython-313.pyc
Normal file
BIN
lib/__pycache__/miller_rabin.cpython-313.pyc
Normal file
Binary file not shown.
BIN
lib/__pycache__/rsa.cpython-313.pyc
Normal file
BIN
lib/__pycache__/rsa.cpython-313.pyc
Normal file
Binary file not shown.
39
lib/arithmetics.py
Normal file
39
lib/arithmetics.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
# Arithmetics functions implementaton
|
||||||
|
|
||||||
|
def modpow(a: int, b: int, m: int) -> int:
|
||||||
|
result = 1
|
||||||
|
while b > 0:
|
||||||
|
if (b & 1) > 0:
|
||||||
|
result = (result * a) % m
|
||||||
|
b = b >> 1
|
||||||
|
a = (a * a) % m
|
||||||
|
return result
|
||||||
|
|
||||||
|
def gcd(a: int, b: int) -> int:
|
||||||
|
if b == 0:
|
||||||
|
return a
|
||||||
|
return gcd(b, a % b)
|
||||||
|
|
||||||
|
def mod_inverse(A: int, M: int) -> int:
|
||||||
|
m0 = M
|
||||||
|
y = 0
|
||||||
|
x = 1
|
||||||
|
if (M == 1):
|
||||||
|
return 0
|
||||||
|
while (A > 1):
|
||||||
|
# q is quotient
|
||||||
|
q = A // M
|
||||||
|
t = M
|
||||||
|
# m is remainder now, process
|
||||||
|
# same as Euclid's algo
|
||||||
|
M = A % M
|
||||||
|
A = t
|
||||||
|
t = y
|
||||||
|
# Update x and y
|
||||||
|
y = x - q * y
|
||||||
|
x = t
|
||||||
|
# Make x positive
|
||||||
|
if (x < 0):
|
||||||
|
x = x + m0
|
||||||
|
return x
|
||||||
|
|
21
lib/diffie_hellman.py
Normal file
21
lib/diffie_hellman.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# Python Diffie-Hillman implémentation
|
||||||
|
|
||||||
|
import random
|
||||||
|
|
||||||
|
import lib.miller_rabin as miller
|
||||||
|
import lib.arithmetics as arithm
|
||||||
|
|
||||||
|
def get_p_and_g(n: int) -> (int, int):
|
||||||
|
p = miller.get_random_prime(n)
|
||||||
|
g = random.randint(2**(n-1), p)
|
||||||
|
return (p, g)
|
||||||
|
|
||||||
|
def get_x(n: int) -> int:
|
||||||
|
return random.randint(2**(n-1), 2**n - 1)
|
||||||
|
|
||||||
|
def get_X(x: int, p: int, g: int) -> int:
|
||||||
|
return arithm.modpow(g, x, p)
|
||||||
|
|
||||||
|
def get_K(X: int, y: int, p: int):
|
||||||
|
return arithm.modpow(X, y, p)
|
||||||
|
|
40
lib/miller_rabin.py
Normal file
40
lib/miller_rabin.py
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
# Python Miller-Rabin implementation
|
||||||
|
|
||||||
|
import random
|
||||||
|
import lib.arithmetics as arithm
|
||||||
|
|
||||||
|
def get_d_and_s(n: int) -> (int, int):
|
||||||
|
d = n - 1
|
||||||
|
s = 0
|
||||||
|
while d % 2 == 0:
|
||||||
|
d //= 2
|
||||||
|
s += 1
|
||||||
|
return (d, s)
|
||||||
|
|
||||||
|
def rabin_witness(n: int, a: int) -> bool:
|
||||||
|
d, s = get_d_and_s(n)
|
||||||
|
x = arithm.modpow(a, d, n)
|
||||||
|
if x == 1 or x == n - 1:
|
||||||
|
return False
|
||||||
|
for _ in range(s - 1):
|
||||||
|
x = arithm.modpow(x, 2, n)
|
||||||
|
if x == n - 1:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def miller_rabin(n: int, k: int) -> bool:
|
||||||
|
if n < 3: return False
|
||||||
|
for _ in range(k):
|
||||||
|
a = random.randint(2, n - 1)
|
||||||
|
if rabin_witness(n, a): return False
|
||||||
|
return True
|
||||||
|
|
||||||
|
def is_prime(n: int) -> bool:
|
||||||
|
return miller_rabin(n, 25)
|
||||||
|
|
||||||
|
def get_random_prime(n: int) -> int:
|
||||||
|
a = random.randint(2**(n-1), 2**(n) - 1)
|
||||||
|
while not is_prime(a):
|
||||||
|
a = random.randint(2**(n-1), 2**(n) - 1)
|
||||||
|
return a
|
||||||
|
|
35
lib/rsa.py
Normal file
35
lib/rsa.py
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Python RSA implementation
|
||||||
|
|
||||||
|
import random
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import lib.arithmetics as arithm
|
||||||
|
import lib.miller_rabin as miller
|
||||||
|
|
||||||
|
def get_p_and_q(n: int) -> (int, int):
|
||||||
|
# Get two random prime numbers
|
||||||
|
p = miller.get_random_prime(n)
|
||||||
|
q = miller.get_random_prime(n)
|
||||||
|
# Ensure the two numbers are differents
|
||||||
|
while p == q:
|
||||||
|
q = get_random_prime(n)
|
||||||
|
return (p, q)
|
||||||
|
|
||||||
|
def get_keys(l: int) -> int:
|
||||||
|
p, q = get_p_and_q(l // 2)
|
||||||
|
n = p * q
|
||||||
|
phy_n = (p - 1) * (q - 1)
|
||||||
|
e = 65537
|
||||||
|
while arithm.gcd(e, phy_n) != 1:
|
||||||
|
p, q = get_p_and_q(l // 2)
|
||||||
|
n = p * q
|
||||||
|
phy_n = (p - 1) * (q - 1)
|
||||||
|
d = arithm.mod_inverse(e, phy_n)
|
||||||
|
return (e, d, n)
|
||||||
|
|
||||||
|
def encrypt(m: int, e: int, n: int) -> int:
|
||||||
|
return arithm.modpow(m, e, n)
|
||||||
|
|
||||||
|
def decrypt(c: int, d: int, n: int) -> int:
|
||||||
|
return arithm.modpow(c, d, n)
|
||||||
|
|
59
main.py
Normal file
59
main.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
import lib.rsa as rsa
|
||||||
|
import lib.diffie_hellman as diffie
|
||||||
|
from hashlib import sha256
|
||||||
|
|
||||||
|
BITS = 32
|
||||||
|
ALPH = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5, 'g': 6, 'h': 7, 'i': 8, 'j': 9, 'k': 10, 'l': 11, 'm': 12, 'n': 13, 'o': 14, 'p': 15, 'q': 16, 'r': 17, 's': 18, 't': 19, 'u': 20, 'v': 21, 'w': 22, 'x': 23, 'y': 24, 'z': 25, ' ': 26}
|
||||||
|
LEN = BITS // 5
|
||||||
|
|
||||||
|
def encode(text):
|
||||||
|
sum = 0
|
||||||
|
for i in range(len(text)):
|
||||||
|
sum += ALPH[text[i]] * 27 ** i
|
||||||
|
return sum
|
||||||
|
|
||||||
|
def decode(num):
|
||||||
|
text = ""
|
||||||
|
while num > 0:
|
||||||
|
text += list(ALPH.keys())[num % 27]
|
||||||
|
num //= 27
|
||||||
|
return text
|
||||||
|
|
||||||
|
def encrypt(text, e, n):
|
||||||
|
crypt = []
|
||||||
|
while len(text) > 0:
|
||||||
|
if len(text) >= LEN:
|
||||||
|
crypt.append(rsa.encrypt(encode(text[:LEN]), e, n))
|
||||||
|
text = text[LEN:]
|
||||||
|
else:
|
||||||
|
crypt.append(rsa.encrypt(encode(text), e, n))
|
||||||
|
text = ""
|
||||||
|
return crypt
|
||||||
|
|
||||||
|
def decrypt(crypt, d, n):
|
||||||
|
text = ""
|
||||||
|
for i in range(len(crypt)):
|
||||||
|
text += decode(rsa.decrypt(crypt[i], d, n))
|
||||||
|
return text
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
p, g = diffie.get_p_and_g(BITS)
|
||||||
|
|
||||||
|
a = diffie.get_x(BITS)
|
||||||
|
b = diffie.get_x(BITS)
|
||||||
|
|
||||||
|
A = diffie.get_X(a, p, g)
|
||||||
|
B = diffie.get_X(b, p, g)
|
||||||
|
|
||||||
|
K_a = diffie.get_K(B, a, p)
|
||||||
|
K_b = diffie.get_K(A, b, p)
|
||||||
|
|
||||||
|
e, d, n = rsa.get_keys(BITS)
|
||||||
|
|
||||||
|
c_d = d ^ K_a
|
||||||
|
h_d = sha256(str(c_d).encode())
|
||||||
|
|
||||||
|
m = "hello world"
|
||||||
|
crypt = encrypt(m, e, n)
|
||||||
|
print(crypt)
|
||||||
|
print(decrypt(crypt, d, n))
|
1
requirements.txt
Normal file
1
requirements.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
|
16
tests.py
Normal file
16
tests.py
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import lib.rsa as rsa
|
||||||
|
import lib.arithmetics as arithm
|
||||||
|
import lib.miller_rabin as miller
|
||||||
|
|
||||||
|
for i in range(100):
|
||||||
|
for j in range(100):
|
||||||
|
assert arithm.modpow(i, j, 20) == pow(i, j, 20)
|
||||||
|
|
||||||
|
for i in range(3, 100):
|
||||||
|
if miller.is_prime(i): print(i)
|
||||||
|
|
||||||
|
e, d, n = rsa.get_keys(2048)
|
||||||
|
c = rsa.encrypt(22, e, n)
|
||||||
|
m = rsa.decrypt(c, d, n)
|
||||||
|
print(m)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue