发布于 

红帽密码

这个题也是赛中找到了接近正解的攻击方案但没有想到优化精度的模式。

赛中

注意到题目本质是素因数分解但有精度丢失导致的不确定度,所以想的爆破尾位,但发现精度损失过大,爆破复杂度太高,所以就没有继续做。

复现

关于格密码

orz算了我不知道我懂不懂。

LLL算法

个人理解,对于\((\textbf{b}_1,\textbf{b}_2,...,\textbf{b}_n)^T\)这几组基,通过辗转相减规约化,得到一组满足以下两个条件的新的基:

  1. 后边的每个基都比前一个基长度小(但不会小太多)
  2. 接受为正交的误差范围在\(\frac{1}{2}\)内(存疑)

通过这种方式便可以找出一组能在相对可接受范围内与待求向量(往往是最短向量)吻合的向量。

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import math 
from decimal import *
import random
import struct

getcontext().prec = int(100)

primes = [2]
for i in range(3, 100):
f = True
for j in primes:
if i * i < j:
break
if i % j == 0:
f = False
break
if f:
primes.append(i)

keys = []
for i in range(len(primes)):
keys.append(Decimal(int(primes[i])).ln())

arr = []
for v in keys:
arr.append(int(v * int(16) ** int(64)))

ct = 737384863737803670841307970259513146291422299366557325168325233349136771464845311

def encrypt(res):
h = Decimal(int(0))
for i in range(len(keys)):
h += res[i] * keys[i]

ct = int(h * int(16)**int(64))
return ct

def f(N):
ln = len(arr)
A = Matrix(ZZ, ln + 1, ln + 1)
for i in range(ln):
A[i, i] = 1
A[i, ln] = arr[i] // N
A[ln, i] = 64

A[ln, ln] = ct // N

res = A.LLL()

for i in range(ln + 1):
flag = True
for j in range(ln):
if -64 <= res[i][j] < 64:
continue
flag = False
break
if flag:
vec = [int(v + 64) for v in res[i][:-1]]
ret = encrypt(vec)
if ret == ct:
print(N, bytes(vec))
else:
print("NO", ret, bytes(vec))

for i in range(2, 10000):
print(i)
f(i)

本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。

本站由 [@Zuni](http://example.com/) 创建,使用 Stellar 作为主题。