Backpack Cryptography

Backpack Cryptography

Challenge files:

-source.py

-output.txt

题目描述

这是一个背包密码系统(Backpack Cryptography)的破解问题。题目提供了加密算法的源代码和输出结果,需要从公钥和加密后的flag中恢复原始消息。

解题思路

背包密码系统基于超递增序列,通过模数q和乘数r进行伪装。攻击的基本思想是使用格基约化(LLL算法)来寻找短向量,从而恢复明文,而不需要找出正确的模数q和乘数r。

简单来说LLL硬上就结束了。

解题过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
from sage.all import *

# 从output.txt读取数据
with open('output.txt', 'r') as f:
data = f.read()

# 解析公钥和加密的flag
public_key = eval(data.split('Public key:')[1].split('Encrypted Flag:')[0].strip())
encrypted_flag = int(data.split('Encrypted Flag:')[1].strip())

n = len(public_key)

# 构造格基
M = matrix(ZZ, n+1, n+1)
for i in range(n):
M[i, i] = 2
M[i, n] = public_key[i]
M[n, :n] = 1
M[n, n] = encrypted_flag

# 应用LLL算法
M_lll = M.LLL()

# 寻找包含解的行
for row in M_lll:
if row[-1] == 0:
# 提取比特位
bits = []
for i in range(n):
if abs(row[i]) == 1:
bits.append(1 if row[i] > 0 else 0)
else:
bits.append(0)

# 转换为字节
flag = 0
for i in range(n):
flag |= bits[i] << i

# 转换为字符串
try:
flag_bytes = int.to_bytes(flag, (n+7)//8, 'little')
flag_str = flag_bytes.decode('ascii')
if 'crypto{' in flag_str:
print(f"Found flag: {flag_str}")
break
except:
continue