6 KiB
6 KiB
Hidden Log Factoring - crypto
Den Schnippsel in https://sagecell.sagemath.org/ kopieren:
# Deine Werte
p = 200167626629249973590210748210664315551571227173732968065685194568612605520816305417784745648399324178485097581867501503778073506528170960879344249321872139638179291829086442429009723480288604047975360660822750743411854623254328369265079475034447044479229192540942687284442586906047953374527204596869578972378578818243592790149118451253249
y = 44209577951808382329528773174800640982676772266062718570752782238450958062000992024007390942331777802579750741643234627722057238001117859851305258592175283446986950906322475842276682130684406699583969531658154117541036033175624316123630171940523312498410797292015306505441358652764718889371372744612329404629522344917215516711582956706994
g = 11
# Erstelle den Restklassenring/Körper
R = Integers(p)
target = R(y)
base = R(g)
# Nutze die globale discrete_log Funktion mit der Schranke 2^100
# bounds=(untergrenze, obergrenze) beschleunigt die Suche enorm
s = discrete_log(target, base, bounds=(1, 1 << 100))
print(f"Gefundenes s: {s}")
Gefundenes s: 485391067385099231898174017598
LLM genereated:
def decrypt(c, p, q):
n = p * q
# Berechnung der Quadratwurzeln modulo p und q
# Dies ist für p, q ≡ 3 (mod 4) besonders einfach
mp = pow(c, (p + 1) // 4, p)
mq = pow(c, (q + 1) // 4, q)
# Erweiterter Euklidischer Algorithmus für yp*p + yq*q = 1
def extended_gcd(a, b):
if a == 0: return b, 0, 1
gcd, x1, y1 = extended_gcd(b % a, a)
return gcd, y1 - (b // a) * x1, x1
_, yp, yq = extended_gcd(p, q)
# Die vier möglichen Wurzeln (Kombination via Chinesischem Restsatz)
r1 = (yp * p * mq + yq * q * mp) % n
r2 = n - r1
r3 = (yp * p * mq - yq * q * mp) % n
r4 = n - r3
return [r1, r2, r3, r4]
Ehrenlos zusammengevibed:
from Crypto.Util.number import long_to_bytes, bytes_to_long
from cryptography.hazmat.primitives.kdf.hkdf import HKDF
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.backends import default_backend
# --- Gegebene Daten einfügen ---
n=71016310005824589926747341243598522145452505235842335510488353587223142066921470760443852767377534776713566052988373656012584808377496091765373981120165220471527586994259252074709653090148780742972203779666231432769553199154214563039426087870098774883375566546770723222752131892953195949848583409407713489831
e = 65537
p = 200167626629249973590210748210664315551571227173732968065685194568612605520816305417784745648399324178485097581867501503778073506528170960879344249321872139638179291829086442429009723480288604047975360660822750743411854623254328369265079475034447044479229192540942687284442586906047953374527204596869578972378578818243592790149118451253249
g = 11
A=44209577951808382329528773174800640982676772266062718570752782238450958062000992024007390942331777802579750741643234627722057238001117859851305258592175283446986950906322475842276682130684406699583969531658154117541036033175624316123630171940523312498410797292015306505441358652764718889371372744612329404629522344917215516711582956706994
D=9478993126102369804166465392238441359765254122557022102787395039760473484373917895152043164556897759129379257347258713397227019255397523784552330568551257950882564054224108445256766524125007082113207841784651721510041313068567959041923601780557243220011462176445589034556139643023098611601440872439110251624
c=1479919887254219636530919475050983663848182436330538045427636138917562865693442211774911655964940989306960131568709021476461747472930022641984797332621318327273825157712858569934666380955735263664889604798016194035704361047493027641699022507373990773216443687431071760958198437503246519811635672063448591496
# --- 1. DLP lösen mit Sage ---
print("[*] Löse DLP für s...")
# Erstelle den Restklassenring/Körper
R = Integers(p)
target = R(A)
base = R(g)
# Nutze die globale discrete_log Funktion mit der Schranke 2^100
# bounds=(untergrenze, obergrenze) beschleunigt die Suche enorm
s = discrete_log(target, base, bounds=(1, 1 << 100))
print(f"[+] s gefunden: {s}")
# --- 2. d-Maske berechnen ---
def get_mask(s_val, bit_len):
hkdf = HKDF(
algorithm=hashes.SHA256(),
length=bit_len // 8,
salt=None,
info=b"rsa-d-mask",
backend=default_backend()
)
return bytes_to_long(hkdf.derive(long_to_bytes(s_val)))
# Wir nehmen an, dass d etwa so lang wie n ist
mask = get_mask(s, n.bit_length())
d = int(D ^ mask)
print(f"[+] d={d} berechnet.")
# --- 3. n faktorisieren (via e und d) ---
# In Sage gibt es eingebaute Methoden, oder wir nutzen den Standard-Algorithmus
def factor_n_ed(n, e, d):
k = d * e - 1
g = 2
while True:
t = k
while t % 2 == 0:
t //= 2
x = pow(g, t, n)
if x > 1:
y = gcd(x - 1, n)
if y > 1 and y < n:
return int(y), int(n // y)
g = next_prime(g)
q1, q2 = factor_n_ed(n, e, d)
print(f"[+] Faktoren gefunden: q1={q1}, q2={q2}")
# Nutze die Faktoren q1 und q2 für die schnelle Berechnung
def general_rabin_decrypt(c, p, q):
# Berechnet Wurzeln für JEDE Primzahl (auch wenn p != 3 mod 4)
# Fp und Fq sind die endlichen Körper
Fp = GF(p)
Fq = GF(q)
# sqrt() in GF(p) findet alle Wurzeln
roots_p = Fp(c).sqrt(all=True)
roots_q = Fq(c).sqrt(all=True)
results = []
for rp in roots_p:
for rq in roots_q:
# Kombiniere alle Paarungen via Chinesischem Restsatz
res = crt([int(rp), int(rq)], [int(p), int(q)])
results.append(res)
return results
potential_roots = general_rabin_decrypt(c, q1, q2)
for r in potential_roots:
# Umwandlung von Integer zu Bytes
try:
flag_candidate = long_to_bytes(int(r))
print(f"Gefundene Nachricht: {flag_candidate}")
if b"flag" in flag_candidate.lower() or b"{" in flag_candidate:
print(f"\n[!!!] DAS IST DIE FLAGGE: {flag_candidate.decode(errors='ignore')}")
except:
continue