mirror of
https://github.com/autistic-symposium/sec-pentesting-toolkit.git
synced 2025-04-27 11:09:09 -04:00
107 lines
2.6 KiB
Python
107 lines
2.6 KiB
Python
import math
|
|
import primes
|
|
|
|
def invmod(a, p, maxiter=1000000):
|
|
"""The multiplicitive inverse of a in the integers modulo p:
|
|
a * b == 1 mod p
|
|
Returns b.
|
|
(http://code.activestate.com/recipes/576737-inverse-modulo-p/)"""
|
|
if a == 0:
|
|
raise ValueError('0 has no inverse mod %d' % p)
|
|
r = a
|
|
d = 1
|
|
for i in xrange(min(p, maxiter)):
|
|
d = ((p // r + 1) * d) % p
|
|
r = (d * a) % p
|
|
if r == 1:
|
|
break
|
|
else:
|
|
raise ValueError('%d has no inverse mod %d' % (a, p))
|
|
return d
|
|
|
|
def modpow(base, exponent, modulus):
|
|
"""Modular exponent:
|
|
c = b ^ e mod m
|
|
Returns c.
|
|
(http://www.programmish.com/?p=34)"""
|
|
result = 1
|
|
while exponent > 0:
|
|
if exponent & 1 == 1:
|
|
result = (result * base) % modulus
|
|
exponent = exponent >> 1
|
|
base = (base * base) % modulus
|
|
return result
|
|
|
|
class PrivateKey(object):
|
|
def __init__(self, p, q, n):
|
|
self.l = (p-1) * (q-1)
|
|
self.m = invmod(self.l, n)
|
|
|
|
class PublicKey(object):
|
|
def __init__(self, n):
|
|
self.n = n
|
|
self.n_sq = n * n
|
|
self.g = n + 1
|
|
|
|
def generate_keypair(bits):
|
|
p = primes.generate_prime(bits / 2)
|
|
q = primes.generate_prime(bits / 2)
|
|
n = p * q
|
|
return PrivateKey(p, q, n), PublicKey(n)
|
|
|
|
def encrypt(pub, plain):
|
|
while True:
|
|
r = primes.generate_prime(long(round(math.log(pub.n, 2))))
|
|
if r > 0 and r < pub.n:
|
|
break
|
|
x = pow(r, pub.n, pub.n_sq)
|
|
cipher = (pow(pub.g, plain, pub.n_sq) * x) % pub.n_sq
|
|
return cipher
|
|
|
|
def e_add(pub, a, b):
|
|
"""Add one encrypted integer to another"""
|
|
return a * b % pub.n_sq
|
|
|
|
def e_add_const(pub, a, n):
|
|
"""Add constant n to an encrypted integer"""
|
|
return a * modpow(pub.g, n, pub.n_sq) % pub.n_sq
|
|
|
|
def e_mul_const(pub, a, n):
|
|
"""Multiplies an ancrypted integer by a constant"""
|
|
return modpow(a, n, pub.n_sq)
|
|
|
|
def decrypt(priv, pub, cipher):
|
|
x = pow(cipher, priv.l, pub.n_sq) - 1
|
|
plain = ((x // pub.n) * priv.m) % pub.n
|
|
return plain
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
print "Generating keypair..."
|
|
priv, pub = generate_keypair(512)
|
|
|
|
x = 3
|
|
print "x =", x
|
|
print "Encrypting x..."
|
|
cx = encrypt(pub, x)
|
|
print "cx =", cx
|
|
|
|
y = 5
|
|
print "y =", y
|
|
print "Encrypting y..."
|
|
cy = encrypt(pub, y)
|
|
print "cy =", cy
|
|
|
|
print "Computing cx + cy..."
|
|
cz = e_add(pub, cx, cy)
|
|
print "cz =", cz
|
|
|
|
print "Decrypting cz..."
|
|
z = decrypt(priv, pub, cz)
|
|
print "z =", z
|
|
|
|
print "Computing decrypt((cz + 2) * 3) ..."
|
|
print "result =", decrypt(priv, pub,
|
|
e_mul_const(pub, e_add_const(pub, cz, 2), 3))
|