from Crypto.Util.number import * from secret import flag
p = getPrime(1024) q = getPrime(1024) n = p * q e = 65537 phi = (p - 1) * (q - 1)
u = getPrime(16) t = 2 * u x = phi - 1 y = t + 1 k = 485723311775451084490131424696603828503121391558424003875128327297219030209620409301965720801386755451211861235029553063690749071961769290228672699730274712790110328643361418488523850331864608239660637323505924467595552293954200495174815985511827027913668477355984099228100469167128884236364008368230807336455721259701674165150959031166621381089213574626382643770012299575625039962530813909883594225301664728207560469046767485067146540498028505317113631970909809355823386324477936590351860786770580377775431764048693195017557432320430650328751116174124989038139756718362090105378540643587230129563930454260456320785629555493541609065309679709263733546183441765688806201058755252368942465271917663774868678682736973621371451440269201543952580232165981094719134791956854961433894740133317928275468758142862373593473875148862015695758191730229010960894713851228770656646728682145295722403096813082295018446712479920173040974429645523244575300611492359684052455691388127306813958610152185716611576776736342210195290674162667807163446158064125000445084485749597675094544031166691527647433823855652513968545236726519051559119550903995500324781631036492013723999955841701455597918532359171203698303815049834141108746893552928431581707889710001424400
''' n = 14070754234209585800232634546325624819982185952673905053702891604674100339022883248944477908133810472748877029408864634701590339742452010000798957135872412483891523031580735317558166390805963001389999673532396972009696089072742463405543527845901369617515343242940788986578427709036923957774197805224415531570285914497828532354144069019482248200179658346673726866641476722431602154777272137461817946690611413973565446874772983684785869431957078489177937408583077761820157276339873500082526060431619271198751378603409721518832711634990892781578484012381667814631979944383411800101335129369193315802989383955827098934489 e = 65537 c = 12312807681090775663449755503116041117407837995529562718510452391461356192258329776159493018768087453289696353524051692157990247921285844615014418841030154700106173452384129940303909074742769886414052488853604191654590458187680183616318236293852380899979151260836670423218871805674446000309373481725774969422672736229527525591328471860345983778028010745586148340546463680818388894336222353977838015397994043740268968888435671821802946193800752173055888706754526261663215087248329005557071106096518012133237897251421810710854712833248875972001538173403966229724632452895508035768462851571544231619079557987628227178358 '''
这题主要是泄露一个式子,这个式子是如下:
其中y=t+1=2u+1
其中x=ϕ(n)−1=n−(p+q)
(x2+1)∗(y2+1)−2∗(x−y)∗(x∗y−1)=4∗(k+x∗y)
直接用sagemath的factor可以对该式子进行因式分解。
1 2 3 4 5 6 7
k = P.<x,y> = PolynomialRing(ZZ) f = (x**2 + 1)*(y**2 + 1) - 2*(x - y)*(x*y - 1) - 4*(k + x*y) factor(f) """ (x*y - x + y - 1393877055949269988542645243428109045917075304843782382429915848142225727784284860406937870535551533051449256287300948442808942235566781014699146291793792925479262054554450802027947079006020306843696147659466308841224513975724013909879952955470681477050304932332200438588432205712615761105027582981141051388392159273596829524704974472089813228846063327501722097548108345551791276998575277090833776802524595075326766440599729740043377678343501840792538888378631673472796302603318988296687557395913791350975450144017092753174292943668507487115213145616331361471787389920378850483532964105278405545043850373460301697589493241) * (x*y - x + y + 1393877055949269988542645243428109045917075304843782382429915848142225727784284860406937870535551533051449256287300948442808942235566781014699146291793792925479262054554450802027947079006020306843696147659466308841224513975724013909879952955470681477050304932332200438588432205712615761105027582981141051388392159273596829524704974472089813228846063327501722097548108345551791276998575277090833776802524595075326766440599729740043377678343501840792538888378631673472796302603318988296687557395913791350975450144017092753174292943668507487115213145616331361471787389920378850483532964105278405545043850373460301697589493239) """
from Crypto.Util.number import * import gmpy2 import tqdm n = e = c = b = candidate = [] for i inrange(2^15,2^16-1): if isPrime(i): candidate.append(i) #print(candidate) x,y= var('x,y') sol = 0 for j in tqdm.tqdm(candidate,leave=True): eq1 = y == j*2+1 eq2 = x*y-x+y-b==0 result = solve([eq1,eq2],[x,y]) a = int(result[0][0].rhs()) d = a*(j*2+1)-a+(j*2+1)-b if d==0: sol = a print(a) break
p,q = var('p,q') eq3 = p*q==n eq4 = n-(p+q) == sol res = solve([eq3,eq4],[p,q]) p = int(res[0][0].rhs()) q = n//p
phi = (p-1)*(q-1) d = gmpy2.invert(e,phi) m = pow(c,d,n) print(long_to_bytes(int(m))) # VNCTF{hell0_rsa_w0rld!}
# 得到安全的随机数 # data = rng_state + counter # counter+=1 def_get_secure_random_bits(self, bits: int) -> int: """ Get cryptographically secure random bits using seeded CSPRNG """ data = self.rng_state + self.counter.to_bytes(8, 'big') self.counter += 1 result = 0 whilelen(bin(result)[2:]) < bits: hash_output = sha256(data).digest() result = (result << 256) | int.from_bytes(hash_output, 'big') data = hash_output + self.counter.to_bytes(8, 'big') self.counter += 1 return result % (1 << bits) # 构造方法有出现过,生成随机数 def_get_prime(self, bits: int) -> int: """ Generate a random prime of specified bit length """ whileTrue: num = self._get_secure_random_bits(bits) num |= (1 << (bits - 1)) | 1 if isPrime(num): return num # 构造方法有出现过,生成生成元 def_get_random_element(self) -> int: """ Get a random element in range [2, p-2] """ return self._get_secure_random_bits(self.p.bit_length() - 1) % (self.p - 2) + 2 # 运行 defrun(self): """ Execute the Schnorr zero-knowledge proof protocol 运行Schnorr零知识证明协议 """ # Opening statement print("=" * 10) # 这个挑战中我知道flag print("I know the flag for this challenge!") # 但是我将证明我知道它 print("But I will ONLY prove that I know it.") # 你从我的证明中获取不了任何信息 print("You CANNOT extract ANY information about the flag from my proof!") print("=" * 10) print() # 展现公共参数g,p,A # Show public parameters print("[PUBLIC PARAMETERS]") print(f"p = {self.p}") print(f"g = {self.g}") print(f"A = {self.A}") print() # flag是指数a,满足A = g^a mod p print("Note: The flag is the witness 'a' such that A = g^a mod p") print(" where a = bytes_to_long(flag) mod (p-1)") print()
# Commitment phase # 生成一个安全的伪随机数b = print("[COMMITMENT]") b = self._get_secure_random_bits(self.p.bit_length() - 1) % (self.p - 2) + 1 # 计算 B = g^{b} mod p ,并生成B B = pow(self.g, b, self.p) print(f"B = {B}") print() # Challenge phase # 挑战如下,如果你是一个诚实的验证着,你应该提供一个随机挑战 print("[CHALLENGE]") print("(If you are an HONEST verifier, you should provide a RANDOM challenge!)") print(f"Please provide challenge x (integer: 1 ≤ x ≤ {self.p - 2}):") # 尝试输入x,x必须在[1,p-2]之间 whileTrue: try: x = int(input("x = ").strip()) if1 <= x < self.p - 1: break print(f"Invalid! x must be between 1 and {self.p - 2}") except (ValueError, EOFError): print("Invalid input!") exit(0) print() #响应 # Response phase print("[RESPONSE]") # 计算z = (x*a+b)% p - 1 ,并输入z z = (x * self.secret_a + b) % (self.p - 1) print(f"z = {z}") print() # 验证 # Verification print("[VERIFICATION]") # g^{z} = A ^ x * B mod p = g ^{x*a+b % p-q} = g^{ax}*g^{b} print("Check if: g^z ≡ A^x · B (mod p)") # 计算左边 left = pow(self.g, z, self.p) # 计算右边 right = (pow(self.A, x, self.p) * B) % self.p # 左边等于右边就成功,不等于就认证失败 if left == right: print("✓ Equation holds! This round proves I know the secret with high probability!") else: print("✗ Verification failed!") print() # Ask to continue # 询问是否要继续下一轮 print("Continue to next round? (y/n):") choice = input().strip().lower() if choice != 'y': break print() print() print("=" * 10) print(f"Protocol completed after {round_num} round(s).") print("You learned ZERO knowledge about the flag!") print("=" * 10)
if __name__ == "__main__": prover = SecureSchnorrProver(security_bits=512) prover.run()
from Crypto.Util.number import * p = 11565557559424798855333327185204068437310136641385409496567722412564615038600900851617108696669858871646341524790068395795451926393494538092546156560682769 g = 5709717688325332497153440522153605353533637683454644113681576752846043064532331863137676063898756084627767432188906997886676715684730693730695936906091975 A = 4075109126848443012116179641277409498928032598430732000322152241884992550579472218626670987682594558001578403106661239073541536564712500451802717571116369 B = 839528130192525498479196454308970890042461603337469455817068565917490873930542949929568677947770767753921850053408870301884485829608926952532972851114534 z1 = 5126408682185857289501793408251290530347266275247495774627779479648526776486060620907045751170023832479804967167488894956624796038122089749883466638659144 z2 = 5126408682185857289501793408251290530347266275247507856050972117936209951513207975663030001582866857246463549745300296061801461774337384147721517521027525 flag = z2-z1 % (p-1) print(long_to_bytes(flag)) # b'VNCTF{9415658f-8a8e-4cf9-b3f7-07c81df05223}'
# 点转换为列表 # 虚部在前实部在后 # 每个参数形如输出的时候是虚部在第一项,虚部在第二项 # 转换的时候是实部在第一项,虚部在第二项 defpoint_to_list(P): return [int(c) for c in P[0].polynomial()] + [int(c) for c in P[1].polynomial()] # 多项式环转换为列表 # 每个参数形如输出的时候是虚部在第一项,虚部在第二项 # 转换的时候是实部在第一项,虚部在第二项 deffp2_to_list(x): return [int(c) for c in x.polynomial()]
# 将p作为状态,作为LCG的seed state = int(p) defnext_rand(): global state state = (state * 1664525 + 1013904223) % 2**32 return state
# 维数为12 dim = 12 # bob的矩阵为12*12的矩阵 # 按一定规律生成矩阵 M_bob = matrix(ZZ, dim, dim) for r inrange(dim): for c inrange(dim): M_bob[r,c] = (next_rand() % 10 + 10) if r == c else (next_rand() % 5) # 将前面泄露的bob_raw数据转换为向量与矩阵相乘 Y_bob = vector(ZZ, bob_raw) * M_bob
# Alice也同样如此 M_alice = matrix(ZZ, dim, dim) for r inrange(dim): for c inrange(dim): M_alice[r,c] = (next_rand() % 10 + 10) if r == c else (next_rand() % 5) Y_alice = vector(ZZ, alice_raw) * M_alice
# 输出参数 output = { "params": {"a": a, "b": b}, "points": { "Pa": point_to_list(P2), "Qa": point_to_list(Q2), "Pb": point_to_list(P3), "Qb": point_to_list(Q3) }, "bob_obfuscated": [int(x) for x in Y_bob], "alice_obfuscated": [int(x) for x in Y_alice], "iv": iv.hex(), "ciphertext": ciphertext.hex() } print(output) #with open("output.txt", "w") as f: # f.write(str(output))
import os from hashlib import sha256 from Crypto.Cipher import AES from Crypto.Util.Padding import pad p = 7592261594411736127573939894551922818228028390244351
state = int(p) defnext_rand(): global state state = (state * 1664525 + 1013904223) % 2**32 return state dim = 12 M_bob = matrix(ZZ, dim, dim) for r inrange(dim): for c inrange(dim): M_bob[r,c] = (next_rand() % 10 + 10) if r == c else (next_rand() % 5) M_alice = matrix(ZZ, dim, dim) for r inrange(dim): for c inrange(dim): M_alice[r,c] = (next_rand() % 10 + 10) if r == c else (next_rand() % 5) solB = [203216789142581305197722930125351051178489832272874948, 103451143990351090548150562828305766374778166367334743, 128385043821113943220154406817301591600434705357425337, 148721712019250874702421429405961145245884308621636284, 107450918943296049650435208380326306041925061431182755, 108464709125122928458164660443532606143146211433427714, 223429435910571460464979624202352016712591253148328955, 158116135335965154112308826699937612715840377818614605, 167803599172317038283177182077091592826307156540816241, 143817839441487927738837134600596555719979620674913418, 186175056475907603625656541033372102161902994275461358, 195952285339273458274453344082354272141798683842481140]
xB = vector(ZZ,solB) xA = vector(ZZ,solA) # 求解方程 BBB = M_bob.solve_left(xB) AAA = M_alice.solve_left(xA) AAA = [ZZ(x) % p for x in AAA] BBB = [ZZ(x) % p for x in BBB]
E_start = EllipticCurve(Fp2, [0,6,0,1,0]) E_start.set_order((p+1)^2) # Speeds things up in Sage
# Generation of the endomorphism 2i two_i = generate_distortion_map(E_start)
# Generate public torsion points, for SIKE implementations # these are fixed but to save loading in constants we can # just generate them on the fly #P2, Q2, P3, Q3 = generate_torsion_points(E_start, a, b) #check_torsion_points(E_start, a, b, P2, Q2, P3, Q3)
print(f"Running the attack against Baby SIDHp64 parameters, which has a prime: 2^{a}*3^{b} - 1") #print(f"If all goes well then the following digits should be found: {solution}")
if __name__ == '__main__'and'__file__'inglobals(): if'--parallel'in sys.argv: # Set number of cores for parallel computation num_cores = os.cpu_count() print(f"Performing the attack in parallel using {num_cores} cores") else: num_cores = 1 recovered_key = RunAttack(num_cores)
from Crypto.Cipher import AES from Crypto.Util.Padding import pad #from secret import flag import random import os flag = 'test_flag' classNumberGuesser: def__init__(self,MAX_CHANCES: int = 10, n: int = 624): self.MAX_CHANCES = MAX_CHANCES self.n = n self.seed = os.urandom(8) random.seed(self.seed)
self.hints = [random.getrandbits(32) for _ inrange(self.n)] self.enc = self.encrypt_flag(flag,self.seed)
defencrypt_flag(self,flag: str, iv:bytes) -> bytes: key = random.getrandbits(128).to_bytes(16,'big') ct = AES.new(key,AES.MODE_CBC,iv*2).encrypt(pad(flag.encode(), AES.block_size)) return ct defbanner(self): print("=== Number Guess Challenge ===") print(f"- Internally generates {self.n} 32-bit random numbers") print(f"- You may query at most {self.MAX_CHANCES} indices (0 ~ {self.n - 1})") print("- The seed is 8 bytes of true randomness, influencing AES-CBC key generation\n") print("Encrypted flag:") print(self.enc.hex(), "\n")
defquery_loop(self): for CHANCES inrange(1, self.MAX_CHANCES + 1): print(f"[{CHANCES}/{self.MAX_CHANCES}]") try: index = int(input(f"Enter index (0~{self.n - 1}): ").strip()) if0 <= index < self.n: print(f"hint[{index}] = {self.hints[index]}\n") else: print("Index out of range.\n") except ValueError: print("Invalid input. Please enter an integer.\n") print("Query phase ended. Use the hints to recover the PRNG state and decrypt the flag.")
defmain(): # 获取flag flag = os.getenv('A1CTF_FLAG') # 定义 o,v o, v = 64, 64 # n = o + v = 128 n = o+v # q = 65537 q = 0x10001 # 打开公钥文件 pub = [] withopen('pub.txt', 'r') as file: for i inrange(o): file.readline() # 构造公钥矩阵 pub.append(matrix(GF(q), eval(''.join([file.readline().strip() for _ inrange(n)]))))
# Fs目前是什么还不明白 Fs = [] T = None # 打开秘密,继续构造矩阵,Fs应该是用秘密构造的矩阵 withopen('secret.txt', 'r') as file: for i inrange(o): file.readline() Fs.append(matrix(GF(q), eval(''.join([file.readline().strip() for _ inrange(n)])))) # T也是用秘密构造的矩阵 file.readline() T = matrix(GF(q), eval(''.join([file.readline().strip() for _ inrange(n)]))) # 私钥 priv = (Fs, T) # 创建OV类,传递(64,64,65537),并且会传入公钥矩阵和私钥矩阵 ov = OV(o, v, q, key=(pub, priv)) ov = OV(o, v, q) # 开始挑战 whileTrue: menu() try: choice = int(input('>')) # 选项1是签名 if choice == 1: # 输入消息 msg = input('your msg:') # 对消息进行数据类型的处理 ifisinstance(msg, bytes): msg = msg.decode() # 如果要签名的消息是admin,直接报错 if msg == 'admin': raise RuntimeError # 对消息进行签名操作 sig = ov.sign(msg) print(f' signature: {sig}') # 选项2是认证,如果是admin身份就会打印出flag if choice == 2: sig = input('your signature:').strip()[1:-1] ifisinstance(sig, bytes): sig = sig.decode() sig = vector(GF(q), [int(_.strip()) for _ in sig.split(',')]) if ov.verify('admin', sig): print(flag) except: print('error!') sys.exit()