from Crypto.Util.number import long_to_bytes from sympy.ntheory.residue_ntheory import sqrt_mod
# 将题目中的 N 和 ct 填入。 N = ... ct = ...
candidates = [ct] for _ inrange(4): next_candidates = [] for value in candidates: roots = sqrt_mod(value, N, all_roots=True) next_candidates.extend(int(root) for root in roots) candidates = next_candidates
for candidate in candidates: try: text = long_to_bytes(candidate).decode() except UnicodeDecodeError: continue if text.startswith("crypto{"): print(text)
最终得到:
1
crypto{m0dul4r_squ4r3_r00t}
Noise Free
题目分析
服务端使用如下线性加密:
其中 q = 65537,A 是 64 维随机向量,S 是固定的 64 维私钥,m 是明文字符。
先反复请求 m = 0 的加密结果,就能得到足够多组:
收集至少 64 组线性无关的样本后,用模 q 的高斯消元恢复 S。拿到 S 后,对每个 flag 字符计算:
defsolve_mod(matrix, values, modulus): augmented = [ [value % modulus for value in row] + [values[i] % modulus] for i, row inenumerate(matrix) ] row = 0 for column inrange(len(matrix[0])): pivot = next( (i for i inrange(row, len(augmented)) if augmented[i][column] % modulus), None, ) if pivot isNone: continue
for other inrange(len(augmented)): if other == row: continue factor = augmented[other][column] if factor: augmented[other] = [ (left - factor * right) % modulus for left, right inzip(augmented[other], augmented[row]) ] row += 1
solution = [0] * len(matrix[0]) for current in augmented: pivot = next( (i for i, value inenumerate(current[:-1]) if value == 1), None, ) if pivot isnotNone: solution[pivot] = current[-1] return solution
💬 评论与讨论
分享你的想法和见解