-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchallenge41.py
59 lines (46 loc) · 2.16 KB
/
challenge41.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from common.challenge import MatasanoChallenge
from common.ciphers.pubkey.rsa import RSA
from common.hash.sha1 import SHA1
from common.math.invmod import ModularInverse
from common.math.modexp import ModularExp
from common.tools.converters import BytesToInt, IntToBytes
class UnpaddedRSADecrypter(object):
def __init__(self, one_time_rsa):
self.one_time_rsa = one_time_rsa
def decrypt(self, ciphertext):
e, n = self.one_time_rsa.get_public_key()
int_ciphertext = BytesToInt(ciphertext).value()
# Choose any value s.t. it is coprime with n (since we need it to
# be invertible mod n). Being n = pq, with p and q "big" primes,
# choosing a small prime will do it.
dummy_plaintext = 11
modular_inverse = ModularInverse(n).value(dummy_plaintext)
dummy_ciphertext = ModularExp(n).value(dummy_plaintext, e)
new_ciphertext = (dummy_ciphertext*int_ciphertext) % n
new_ciphertext = IntToBytes(new_ciphertext).value()
obtained_plaintext = self.one_time_rsa.decrypt(new_ciphertext)
integer = BytesToInt(obtained_plaintext).value()
int_plaintext = (integer*modular_inverse) % n
return IntToBytes(int_plaintext).value()
class OneTimeRSA(RSA):
def __init__(self):
RSA.__init__(self)
self.hash_function = SHA1()
self.hashes = set()
def decrypt(self, ciphertext):
ciphertext_hash = self.hash_function.hash(ciphertext)
if ciphertext_hash in self.hashes:
raise RuntimeError('ciphertext already decrypted')
self.hashes.add(ciphertext_hash)
return RSA.decrypt(self, ciphertext)
class Set6Challenge41(MatasanoChallenge):
PLAINTEXT = 'Vos tambien la tenes adentro.'
def expected_value(self):
return self.PLAINTEXT
def value(self):
one_time_rsa = OneTimeRSA()
ciphertext = one_time_rsa.encrypt(self.PLAINTEXT)
# Decrypt this ciphertext and ignore its output (so as to ensure that
# we cannot cheat and decrypt it again after).
one_time_rsa.decrypt(ciphertext)
return UnpaddedRSADecrypter(one_time_rsa).decrypt(ciphertext)