49 lines
1.1 KiB
Python
49 lines
1.1 KiB
Python
import random
|
|
from functools import reduce
|
|
from math import floor, log2
|
|
|
|
from params import a, b, c, d, e, f, g, h, i, j, k, m, n, o, p, q, r, u, v, w
|
|
|
|
|
|
# a < b => b
|
|
# (a // b) * c + (a % b)
|
|
def wut(a, b, c):
|
|
def wuuuuut(z):
|
|
if z <= b:
|
|
return z
|
|
x, y = divmod(z, b)
|
|
return wuuuuut(x * c + y)
|
|
|
|
return wuuuuut(a)
|
|
|
|
|
|
def wutwut(a, b, c, d):
|
|
return reduce(
|
|
lambda x, y: (
|
|
wut(x * x, c, d) if not (b >> y) & 1 else wut(wut(x * x, c, d) * a, c, d)
|
|
),
|
|
reversed(range(floor(log2(b)))),
|
|
wut(a, c, d),
|
|
)
|
|
|
|
|
|
def rsa_decrypt(ciphertext):
|
|
s = wutwut(wut(ciphertext, o, p), a * b + c * d, o, p)
|
|
t = wutwut(wut(ciphertext, q, r), f * g + h * i, q, r)
|
|
|
|
x = s - t
|
|
y = (x * j + x * k) * u
|
|
x = y * r
|
|
y = t + v + y * m
|
|
return (y - x - w) % n
|
|
|
|
|
|
# check if the code works correctly :)
|
|
for _ in range(1000):
|
|
# encrypt 100 random plaintexts with public key
|
|
random_plaintext = random.randint(0, n - 1)
|
|
print(random_plaintext)
|
|
|
|
# verify that the decryption works correctly
|
|
assert rsa_decrypt(pow(random_plaintext, e, n)) == random_plaintext
|