flag = "flag{____________________________}" nbit = 256 p, q = keygen(nbit) m = bytes_to_long(flag.encode()) e= 65537 n = p * q c = pow(m, e, n)
print(f'n = {n}') print(f'c = {c}')
""" n = 97500437901440388417198788454954892885829765317271438600836638419723842224011100091990654907349042873594131382232421640267091732569264390052236076620148372084122607139079558728860385251369576795723604753566616558793072715394596559965112752835650808765911364805382628147988309718393764596614456741590220757591 c = 7738615614182124736230909980262535479827406389377664909203540758689122759528168600427345931034997504030657746278863273550729288326235414854206217548620396163736109673531409510422631464901846302450760457216706035370273167926580473904029057693564485585891556568420324605915383565319685765532478198539656924536 """
defdfs(idx, current_s): global s_found if s_found: return
# Base case: we have determined all 256 bits if idx == 256: p = get_p_fast(current_s) q = get_q_fast(current_s) if p * q == n: s_found = current_s return
# Check mask: Verify n mod 2^(2*bit_index + 2) # Bit `idx` of s affects p at position 2*idx. # So we can verify up to 2*idx + 2 bits of precision. mask = (1 << (2 * idx + 2)) - 1 # Try bit 0 and bit 1 # Constraint: s is generated by getPrime(256), so MSB (bit 255) must be 1. candidates = [0, 1] if idx == 255: candidates = [1]
for bit in candidates: next_s = current_s | (bit << idx) # We calculate p and q with the bits we know so far. # Higher bits are 0, which contributes 0 to the variable subtraction in p, # which is mathematically consistent for modulo checking the lower bits. p_val = get_p_fast(next_s) q_val = get_q_fast(next_s) if (p_val * q_val) & mask == n & mask: dfs(idx + 1, next_s)
print("[*] Starting DFS to recover s...") dfs(0, 0)
if s_found: print(f"[+] Found s: {s_found}") p = get_p_fast(s_found) q = get_q_fast(s_found) phi = (p - 1) * (q - 1) d = pow(e, -1, phi) m = pow(c, d, n) flag = long_to_bytes(m) print(f"[+] Flag: {flag.decode()}") else: print("[-] Failed to find s.") #flag{n1ce_th1s_RSA_I_can_do_it}
defgen_rev_sum(m,p): sum = 0 round = 0 while m > 0: digit = m % p ifround % 2 == 0: sum -= digit else: sum += digit m = m // p round += 1 returnsum // 2025
e = 65537 p = getPrime(256) q = getPrime(256) n = p*q
from Crypto.Util.number import long_to_bytes, inverse import math
# --- Data from the challenge --- m1 = 17322548249387769406385507000191215801044910756841784387283679508067232037647009879640247663005640315645559929483973978388785385751219073137080976227046261663059832428571101292873255962114141666488474602734594597852331665601154571683480014721045567844719377268571343706508041194359642732322649799872642255094259428635455750138217286588825326703937255171250131117864604764478573786940615096044575610751081788573681131616312486987096717266320380202191909867687322859634487150465591581523036586129341984826904474237818210411872793917742756628712320922128969576851582027757934655202892557206052328142121974846460835879379 m2 = 29770749505949559271464509877642735633388289947852331255230201935471628731047838190019590503471311260422939188831886032391799282413808339483805109656799786202448656409753608524222447399741340441803183979217817801933166848028113568228217090419247166878248450792302177597130681740006379413412297487888656975884867850858832779733076818160854085244264177562471933684902341628858046181331683501978826962693104997686104748486850900546849316714934730338449894336151567737740558472664876717516650156395237362632196760323299658988296623556674223583771795447537227301625104687705109034611911834940501083977979641467845119043780 sum1 = -108877560874638575191632670246326227208412819991287356983577291185528002487 sum2 = -47122048431044787786292644180145597499319125719652288525187634667738055282 n = 9020951256034058214321622067945640395058903219618790136239198219605516437223449048642101160150934286238922049363203171871230111420670637737169565825694393 c = 3323425622556846027480153848276857423081641901016156494250966280342935316300495906916254739461788219592704051961044937129981786472345610933524261214506540 e = 65537
defrecover_flag(): # Base values before adding the remainders V1 = m1 + 2025 * sum1 V2 = m2 + 2025 * sum2 # We are looking for remainders r1, r2 in [0, 2024] # such that gcd(V1 + r1, V2 + r2) contains the factor (p + 1) limit = 2025 print(f"[*] Starting brute force for r1, r2 in range({limit})...") # Optimization: Pre-calculate V2 list to avoid addition in inner loop v2_list = [V2 + r for r inrange(limit)] for r1 inrange(limit): target_v1 = V1 + r1 # We only print occasionally to keep output clean if r1 % 500 == 0: print(f"[*] Checking r1 = {r1}...") for r2 inrange(limit): target_v2 = v2_list[r2] # Compute GCD g = math.gcd(target_v1, target_v2) # Filter: p is 256 bits, so p+1 is 256 bits. # We look for a GCD that is significant (at least 250 bits) if g.bit_length() > 250: # g is likely k * (p + 1). # Since m1, m2 are random, k is likely very small (often 1). # We try dividing g by small k to find p. for k inrange(1, 20): # Check small factors if g % k == 0: candidate_p_plus_1 = g // k candidate_p = candidate_p_plus_1 - 1 # Verify prime candidate against n if candidate_p > 1and n % candidate_p == 0: print(f"[+] Found p with r1={r1}, r2={r2}, k={k}") return candidate_p returnNone
p = recover_flag()
if p: q = n // p print(f"[+] p = {p}") print(f"[+] q = {q}") # Standard RSA Decryption phi = (p - 1) * (q - 1) d = inverse(e, phi) m = pow(c, d, n) flag = long_to_bytes(m).decode() print(f"\n[+] Flag: {flag}") else: print("[-] Failed to find p.") #flag{Reverse_Sum_Mod_p+i_GCD_2025!}
flag = "flag{_______________________________}" m = bin(bytes_to_long(flag.encode()))[2:] p = getPrime(300) q = getPrime(300) n = p * q
R.<x> = PolynomialRing(Zmod(n))
def gen(m): C = [] for bit in m: if bit == '0': C.append(random.randint(1, n-1)) else: x = random.randint(1, 2^80) y = random.randint(1, p-1) val = 65537 + x*(1-x) +(q - x)*y + (y + x)*(q + x) C.append(R(val)) return C
# ========================================== # PASTE YOUR VALUES HERE # ========================================== n = ... c = ... # ==========================================
def solve(): print(f"[*] Analyzing {len(c)} ciphertext chunks...") # Define the Polynomial Ring over Zmod(n) P.<x> = PolynomialRing(Zmod(n)) q_recovered = None # We attempt to find the prime factor q using the first few ciphertexts. # We assume at least one of the first few bits corresponds to a '1'. # For '1', c = 65537 + x + k*q. # This implies x is a small root of (c - 65537 - x) mod q. for i in range(min(5, len(c))): try: # Construct the polynomial f(x) = x - constant # We want to find x such that constant - x = 0 (mod q) # constant here is (c[i] - 65537) target_val = c[i] - 65537 f = x - target_val # Coppersmith parameters: # We are looking for a root x < 2^80 # The modulus is q, which is a factor of n with size approx n^0.5 # beta = 0.5 (approximate size of divisor q relative to n) roots = f.small_roots(X=2^80, beta=0.45) if roots: x_candidate = Integer(roots[0]) # If we found x, then (c[i] - 65537 - x) must be a multiple of q # q = gcd(computed_val, n) val_check = c[i] - 65537 - x_candidate q_candidate = gcd(val_check, n) if q_candidate > 1 and q_candidate < n: q_recovered = q_candidate print(f"[+] Recovered q using index {i}: {q_recovered}") break except Exception as e: print(f"[-] Optimization failed at index {i}: {e}") continue
if not q_recovered: print("[-] Failed to recover q. The first few bits might be 0 or parameters need tuning.") return
# Decrypt the bitstream # For '1' bits: (c - 65537) % q should be small (< 2^80) # For '0' bits: (c - 65537) % q should be random (approx 2^300) bits = "" threshold = 2**85 # Slightly higher than 2^80 to be safe for val in c: # Calculate residue modulo q residue = (val - 65537) % q_recovered if residue < threshold: bits += "1" else: bits += "0" print(f"[*] Recovered bits: {bits}") # Convert bits to flag try: flag_int = int(bits, 2) flag = long_to_bytes(flag_int) print(f"\n[+] FLAG: {flag.decode(errors='ignore')}") except Exception as e: print(f"[-] Error decoding flag: {e}")
from Crypto.Util.number import * from gmpy2 import * import random
get_context().precision = 2048
L = 5 S = getPrime(144) a = getPrime(32) b = random.randint(0, S - 1)
defsplit_and_pad_single_char_rule(msg, L): segments = [] assert L >= 1 pad_len = L - 1 for char_idx, char_byte inenumerate(msg): char_ascii = char_byte pad_bytes = bytes([(char_ascii + i + 1) % 256for i inrange(pad_len)]) seg_bytes = bytes([char_byte]) + pad_bytes segments.append(bytes_to_long(seg_bytes)) return segments
defencrypt_segment(m_i, a, b, M): return (a * m_i + b) % M
flag = "flag{___________________}" msg_bytes = flag.encode() m_segments = split_and_pad_single_char_rule(msg_bytes, L) c_segments = [encrypt_segment(mi, a, b, S) for mi in m_segments]
enc = 77779248799562415787538731320739960822457760506615718084036279480880899171418681853821326436404494983875803921684003465855970542931724878457768817162166413967384579329072032251210520838992258491716245608876204830909672245330785235016998427930933850050898878548191256398496024681498083646200326639489612460844 gift = 27203859362379532209762716293585970661584968016465564915669656593570376250661463300469214869975225133883120425672896040102408082124157996563344160198308488970094544684114508100388704667496464400261830996514109943777210955076236899363247079300339008914936852187908757699066223721473477803084358704291887973927 n = 99350851709648177478181442570691890135193362203180628334780894515389735176666242281991349782055218048443285160186921692026870729324336754641181928398906259668775047724023372863155472201773397077316170491389813660679924150036914095032544796724427607899057109320556570067643629947815982002736525967748207154359
defhopfield_network(input_vector, weights, max_iter=20): """ Simulates a Hopfield network using -1 and 1 states. Args: input_vector: The initial state vector (flattened, with -1 and 1). weights: The weight matrix. max_iter: Maximum number of iterations. Returns: The final stable state vector. """ state = np.copy(input_vector) for i inrange(max_iter): # Standard Hopfield update rule new_state = np.sign(np.dot(weights, state)) # np.sign can return 0 for zero inputs, replace with 1 (or -1, convention varies) # Let's stick to the previous state's value in that case. new_state[new_state == 0] = state[new_state == 0]
if np.array_equal(new_state, state): print(f"Network converged after {i+1} iterations.") return new_state state = new_state print("Network did not converge after max iterations.") return state
defrun(): # Load the data try: c = np.load('c.npy') weights = np.load('weights.npy') except Exception as e: print(f"Error loading files: {e}") return
# Transform c from {0, 1} to {-1, 1} for the Hopfield network c_transformed = c * 2 - 1 input_pattern = c_transformed.flatten() print("--- Processing the flattened c matrix with -1/1 states ---") # Run the Hopfield network simulation final_state = hopfield_network(input_pattern, weights)
if final_state isnotNone: try: # Convert the {-1, 1} state back to {0, 1} for decoding final_state_01 = ((final_state + 1) / 2).astype(int) # Reshape the output into a 4x76 matrix to be displayed as art image_matrix = final_state_01.reshape(4, 76) print("--- Displaying the result as an image ---") for row in image_matrix: line = "".join(['#'if pixel == 1else' 'for pixel in row]) print(line)
except Exception as e: print(f"Could not reshape the output: {e}") print("\\n" + "="*30 + "\\n")
# 打包为 zip with zipfile.ZipFile(ZIP_PATH, "w", compression=zipfile.ZIP_DEFLATED) as zf: for root, dirs, files in os.walk(OUT_DIR): for fname in files: full = os.path.join(root, fname) arcname = os.path.relpath(full, OUT_DIR) zf.write(full, arcname)