diff options
| author | Louis Burda <quent.burda@gmail.com> | 2024-05-25 00:52:54 +0200 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2024-05-25 00:52:54 +0200 |
| commit | a7f46b9f7c31c7ae936588b969bae92d561aebaa (patch) | |
| tree | 14f9c2b664cf526a97da2c69700d2616b5c6ac46 /solve/solve.py | |
| download | cscg2020-cry3-master.tar.gz cscg2020-cry3-master.zip | |
Diffstat (limited to 'solve/solve.py')
| -rw-r--r-- | solve/solve.py | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/solve/solve.py b/solve/solve.py new file mode 100644 index 0000000..4f38cde --- /dev/null +++ b/solve/solve.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +from Crypto.PublicKey import RSA +from Crypto.Util.number import long_to_bytes +from gmpy2 import iroot +from sympy import primefactors + +# Hastad Boardcast: Multiple unpadded ciphertexts with small e. +# Use Chinese Remainder Theorem to extract plaintext. +# Possible since N1*N2*N3 larger than M^e for e = 3. + +recipients = [ + RSA.importKey(open("german_government.pem").read()), + RSA.importKey(open("us_government.pem").read()), + RSA.importKey(open("russian_government.pem").read()), +] +ciphertexts = [int(l.split(": ")[1]) for l in open("intercepted-messages.txt").readlines()] + +# C1 = K mod N1, C2 = K mod N2, C3 = K mod N3 +# K = C1 * N2 * N3 * pow(N2 * N3, -1, N1) + ... (mod N1 * N2 * N3) +# K % N1 = C1 * N2 * N3 * pow(N2 * N3, -1, N1) = C1 + +N = 1 +for r in recipients: + assert(r.e == 3) + N *= r.n + +K = 0 +for i in range(3): + K += ciphertexts[i] * (N // recipients[i].n) \ + * pow(N // recipients[i].n, -1, recipients[i].n) +K %= N + +plaintext, real = iroot(K, 3) +assert(real) + +print(long_to_bytes(plaintext).decode().lstrip("A")) |
