rsa lesson added

This commit is contained in:
2026-01-25 00:53:16 +01:00
parent a6ed5c6bb9
commit 890114066f
17 changed files with 429 additions and 5 deletions

View File

@@ -0,0 +1,45 @@
from Crypto.Util.number import inverse, getPrime, bytes_to_long, long_to_bytes
from sympy import nextprime
import os
import math
flag = "h4tum{...}"
m = bytes_to_long(flag.encode())
p : int = getPrime(512)
diff = int.from_bytes(os.urandom(16), 'big')
q : int = nextprime(p - diff)
n = p * q
phi = (p - 1) * (q - 1)
e = 65537
d = inverse(e, phi)
ciphertext = pow(m, e, n)
print(f"Here is the public key:\nn = {n}\ne = {e}")
print(f"\nHere is the encrypted flag:\n{ciphertext}")
t = math.isqrt(n)
for i in range((n+1)//2 - t + 1):
val = (t + i)**2 - n
if val > 0:
root = math.isqrt(val)
if root * root == val:
r = math.isqrt((t+i)**2 - n)
rec_p = (t+i) - r
rec_q = (t+i) + r
rec_phi = (rec_p-1) * (rec_q-1)
rec_d = inverse(e, rec_phi)
plain_text = pow(ciphertext, rec_d, n)
print("We recovered d yay")
print(f"Cracked flag: {long_to_bytes(plain_text)}")
break
# Here is the public key:
# Here is the encrypted flag:
# 13158607848927768767396122915610010628021182023103983078656746030071489695567187651581550866461152226282740548654306454938594539749024910072164328096542525661951926739718955208177780816184581302682602611753650161772357698132248994074563798067850345731371433620586869504864647385937063506440611160969011596274

View File

@@ -0,0 +1,39 @@
from Crypto.Util.number import inverse, getPrime, bytes_to_long, long_to_bytes
from Crypto.PublicKey import RSA
from wiener_attack import wiener_attack
flag = "h4tum{...}"
m = bytes_to_long(flag.encode())
p = getPrime(512)
q = getPrime(512)
n = p * q
phi = (p - 1) * (q - 1)
d = getPrime(30)
e = inverse(d, phi)
ciphertext = pow(m, e, n)
pubkey = RSA.construct((n, e))
pub_pem = pubkey.export_key(format="PEM")
print(pub_pem.decode())
print(f"\nHere is the encrypted flag:\n{ciphertext}")
rec_d = wiener_attack(e, n)
print(long_to_bytes(pow(ciphertext, d, n)))
# -----BEGIN PUBLIC KEY-----
# MIIBHjANBgkqhkiG9w0BAQEFAAOCAQsAMIIBBgKBgGUboAvXiM8ETI/20wMIDKp4
# Yvh0bh90Rv5ixgn0cwUru18hYZdHMmbVRbbzImcJUl+TiGO6ED71fZARh55vpA+p
# IVwrXsFUnUzpF+5Xt04qo6ums1nSd3Kqx/A1gBerMCk8sO8PPJwKW/SgUu8SpOMn
# XtNB3UCiF5iklNzpRJ9BAoGAWMfZ0dEudQf+xEwd4jq066R781PuIQ+FwsEpDAtC
# oFuPpJgo2JEhw6QHdPbSBSAZiJTeKUBrh34s1Y1ALNQy2HgpDF+UGvfndeqxI+tx
# ZnhnmOKyFWLRS7CElp0YunzaWSjM9B4UeyDqnO70f0wopGhSrHx326ourFJBKDak
# g0k=
# -----END PUBLIC KEY-----
# Here is the encrypted flag:
# 33875780076252799475072801857719625760580293404621927950834466845200175353837317794093362254089677034810036784377827562641344104659319423578279557002930036256051311423722214046538552333691207322585750166331224527229737296960110973126147103391345215399552776397918690683992071757399724992352071896156421861125

View File

@@ -0,0 +1,71 @@
import math
def continued_fraction(numerator, denominator):
"""Generate the continued fraction expansion of numerator/denominator."""
cf = []
while denominator:
a = numerator // denominator
cf.append(a)
numerator, denominator = denominator, numerator - a * denominator
return cf
def convergents_from_cf(cf):
"""Generate convergents (k, d) from a continued fraction sequence cf."""
n0, d0 = cf[0], 1
yield (n0, 1)
if len(cf) == 1:
return
n1 = cf[1] * cf[0] + 1
d1 = cf[1]
yield (n1, d1)
for i in range(2, len(cf)):
ni = cf[i] * n1 + n0
di = cf[i] * d1 + d0
yield (ni, di)
n0, d0, n1, d1 = n1, d1, ni, di
def is_perfect_square(x):
"""Check whether x is a perfect square."""
if x < 0:
return False
s = math.isqrt(x)
return s * s == x
def wiener_attack(e, n):
"""
Attempt to recover the RSA private exponent d using Wiener's attack.
Args:
e: Public exponent
n: Modulus
Returns:
If successful, returns the private exponent d; otherwise returns None.
"""
cf = continued_fraction(e, n)
for k, d in convergents_from_cf(cf):
if k == 0:
continue
# Check whether (e*d - 1) is divisible by k to derive phi
if (e * d - 1) % k != 0:
continue
phi = (e * d - 1) // k
# Discriminant of x^2 - (n - phi + 1)x + n = 0
s = n - phi + 1
discr = s * s - 4 * n
if discr >= 0 and is_perfect_square(discr):
t = math.isqrt(discr)
# Recover p and q
p = (s + t) // 2
q = (s - t) // 2
if p * q == n:
return d
return None

View File

@@ -0,0 +1,50 @@
from Crypto.Util.number import getPrime, bytes_to_long, long_to_bytes
from sympy import gcdex
from math import gcd
flag = "h4tum{...}"
m = bytes_to_long(flag.encode())
e1, e2 = 65537, 17
assert gcd(e1, e2) == 1
while True:
p = getPrime(512)
q = getPrime(512)
n = p * q
phi = (p - 1) * (q - 1)
if gcd(e1, phi) != 1 or gcd(e2, phi) != 1:
continue
if m >= n:
continue
if gcd(m, n) != 1:
continue
break
c1 = pow(m, e1, n)
c2 = pow(m, e2, n)
print(f"n = {n}")
print(f"e1 = {e1}")
print(f"e2 = {e2}")
print(f"c1 = {c1}")
print(f"c2 = {c2}")
x, y, g = gcdex(e1, e2)
x = int(x)
y = int(y)
print(f"x {x} | y {y}")
if g == 1:
print(long_to_bytes(pow((pow(c1, x, n) * pow(c2, y, n)), 1, n)))
# n = 65707100137186888475953513086898008905139437630875837854644107822814283110769943579567177881705884274398390781130006134316686487768614537736768547066999613093550734163327713557603091143994827233687646229561643622445920391793762897858845575115299394349389922615093939357420040773283610664101678989419396092347
# e1 = 65537
# e2 = 17
# c1 = 7884926352513340573382039144424214727926794782607805142710494009270484466220925417591780881028724970568583944980873161206083606075384860708927042438650854760874336954047477893939539790216193654418650762594184302293754065850164791109812773425623526938062911997730089936569977360813014753477745012650386772981
# c2 = 11375974342330610521528067622440162683299269265928514681623828493060125481649837931599740517662407981391104665035998955029942650948493441810229768425798821925645814933013176879334289941104021860757801270190361115580835274215465891021181470368445998384179348332817603554056032081626905073456569537572535147729

View File

@@ -0,0 +1,25 @@
from Crypto.Util.number import inverse, getPrime, bytes_to_long
flag = "h4tum{...}"
m = bytes_to_long(flag.encode())
p = getPrime(512)
q = getPrime(512)
n = p * q
phi = (p - 1) * (q - 1)
e = 3
d = inverse(e, phi)
ciphertext = pow(m, e, n)
print(f"Here is the public key:\nn = {n}\ne = {e}")
print(f"\nHere is the encrypted flag:\n{ciphertext}")
# Here is the public key:
# n = 133754776379084890949396128184054209827880534649872344546551916044637014117738848312911601805615413451730371613447269527792021869628568786604565343522407135622719358245312844577182399504053254247235363664243271537669953064325407487226101646170736997104441396305543325547272540155515055362880210828933349672043
# e = 3
# Here is the encrypted flag:
# 27485520006079233807623807132370137913974673072796110190145166712012781629787795173249446320555776530359265337337323534643030075414274984551090326260078977798035707372748401792308537889036666723735654189543943146031289186076736572201980302715998036022634187371997765033713933871352433152430973165071957865672