格密码
线性独立空间上有集合
,格(Lattices)就是这些向量的线性组合,用公式表示为:
。
格
的维数等于格中向量的个数。
假定
是格
的基,
,则必然存在整系数
使得:
这样,格的问题就是矩阵运算了。
最短向量问题(SVP,The Shortest Vector Problem):
寻找一个格
中最短的非零向量。即,寻找一个
满足其欧几里德范数
最小。
最接近向量问题(CVP,The Closest Vector Problem):
对于一个非格
中的向量
,在格中寻找一个向量
,使得
最小。
CVP和SVP都是NP完备问题,因此求解起来十分困难,因此这两个问题都是可以作为密钥体制的基础的。
构造示例
NRTU格密码
NTRU是一个带有专利保护的开源公开密钥加密系统,使用基于格的加密算法来加密数据。它包括两部分算法:NTRUEncrypt用来加密,NTRUSign用来进行数字签名。与其他流行的公钥加密系统不同,它可以防止被Shor算法破解,并显著提升了性能。
在同等加密强度下,NTRU执行大开销的私钥操作比RSA算法快得多。RSA算法的私钥操作耗时与密钥长度呈三次方关系,而NTRU相应操作为二次方关系。
NTRU密码体制,需要三个整数参数
和四个次数为
的整系数多项式集合
,在这里
为一素数,
可以不必为素数,但为安全,要求
,且
远大于
。
NTRU工作于多项式整数环
,当
,可以把
表示为多项式或向量形式,
。
在这里记
,选取三个确定的整数
,多项式集合
,而
。
-
密钥生成
B随机选择两个多项式
和
,
,要求
关于模
和模
的逆
都存在,也即
和
,这里可以用扩展欧几里得算法计算出
和
。为此,
首先应满足
,如果有一个逆不存在,需重新选择
。
然后,B计算
,则公钥为
,私钥为
,但在实际中,还将存储
,因而一般认为私钥为
。
-
加密
假设A想发送信息
给B,他将根据参数
随机选择一个
,然后,他利用B的公钥
计算
A把密文
发送给B。
-
解密
当B收到密文
后,他首先利用私钥
计算
选择
的系数位于
之间,然后计算
则多项式
就是明文
。
-
构造矩阵
其中
是根据公钥多项式的系数生成的循环矩阵。
构建一个这样的矩阵,然后进行LLL算法得到解密密钥。
-
参考
Practical lattice-based cryptography: NTRUEncrypt and NTRUSign
1 |
|
1 |
|
GGH加密
1997年,Goldreich、Goldwasser、Halevi三人受Ajtai在格难题上的研究所启发,提出了一个基于格中最近向量难题的非对称密码学算法:GGH Cryptosystem。
1999年,Nguyen发现在这个密码学算法设计中,有一个很大的缺陷,可以使攻击者从密文中获取到明文的部分信息,且可以将原来的最近向量难题转化为一个较为简单的最近向量难题。基于这个观察,Nguyen解出了设计者放在网上的5个challenge中的4个(其中有2个被设计者认为是不可能攻破的),足以证明该密码算法是broken的。
-
定义
GGH包含一个私钥和一个公钥,选取格
的一组好基
和一个幺模矩阵
作为私钥,计算
的另一组基
作为公钥。
选定
值,明文向量
。
- 加密
- 给定明文 ,误差向量 ,和公钥 ,计算 ;
- 密文 。
- 解密
- 计算 ;
- 如果 足够小,可利用Babai最近平面算法的变种Babai rounding technique去除;
- 最后计算 得到明文。
GGH中的误差向量的选取是3或者-3。
- 加密
-
求解
利用Nguyen’s Attack算法。
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
c = []
c = vector(ZZ, c)
B = []
B = matrix(ZZ, B)
n = 150
delta = 3
s = vector(ZZ, [delta]*n)
B6 = B.change_ring(Zmod(2*delta))
left = (c + s).change_ring(Zmod(2*delta))
m6 = (B6.solve_left(left)).change_ring(ZZ)
new_c = (c - m6*B) * 2 / (2*delta)
new_B = (B*2).stack(new_c).augment(vector(ZZ, [0]*n + [1]))
new_B = new_B.change_ring(ZZ)
new_B_BKZ = new_B.BKZ()
shortest_vector = new_B_BKZ[0]
mbar = (B*2).solve_left(new_c - shortest_vector[:-1])
m = mbar * (2*delta) + m6
print(bytes.fromhex(hex(m)[2:])) -
参考
LWE问题
容错学习问题 (LWE问题, Learning With Errors)是一个机器学习领域中的怀疑难解问题,由Oded Regev 在2005年提出,他因此赢得2018年哥德尔奖。这是一个极性学习问题的一般形式。
-
定义
随机选取一个矩阵
,一个随机向量
,和一个随机的噪音
。
一个LWE系统的输出
。
一个LWE问题是,给定一个矩阵
,和LWE系统的输出
,还原
。
LWE的误差向量是一个满足正态分布的小向量。
因为加入了一些误差,如果使用高斯消元法的话,这些误差会聚集起来,使得解出来的东西跟实际值差很多。
-
求解
利用LLL算法和Babai最近平面算法,可以在多项式时间内找到近似解。
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
from sage.modules.free_module_integer import IntegerLattice
row =
column =
prime =
ma =
res =
W = matrix(ZZ, ma)
cc = vector(ZZ, res)
def Babai_closest_vector(M, G, target):
small = target
for _ in range(5):
for i in reversed(range(M.nrows())):
c = ((small * G[i]) / (G[i] * G[i])).round()
small -= M[i] * c
return target - small
A1 = matrix.identity(column)
Ap = matrix.identity(row) * prime
B = block_matrix([[Ap], [W]])
lattice = IntegerLattice(B, lll_reduce=True)
print("LLL done")
gram = lattice.reduced_basis.gram_schmidt()[0]
target = vector(ZZ, res)
re = Babai_closest_vector(lattice.reduced_basis, gram, target)
print("Closest Vector: {}".format(re))
R = IntegerModRing(prime)
M = Matrix(R, ma)
M = M.transpose()
ingredients = M.solve_right(re)
print("Ingredients: {}".format(ingredients))
m = ''
for i in range(len(ingredients)):
m += chr(ingredients[i])
print(m)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
from sage.modules.free_module_integer import IntegerLattice
from random import randint
import sys
from itertools import starmap
from operator import mul
def Babai_closest_vector(M, G, target):
small = target
for _ in range(1):
for i in reversed(range(M.nrows())):
c = ((small * G[i]) / (G[i] * G[i])).round()
small -= M[i] * c
return target - small
m =
n =
q =
A_values =
b_values =
A = matrix(ZZ, m + n, m)
for i in range(m):
A[i, i] = q
for x in range(m):
for y in range(n):
A[m + y, x] = A_values[x][y]
lattice = IntegerLattice(A, lll_reduce=True)
print("LLL done")
gram = lattice.reduced_basis.gram_schmidt()[0]
target = vector(ZZ, b_values)
res = Babai_closest_vector(lattice.reduced_basis, gram, target)
print("Closest Vector: {}".format(res))
R = IntegerModRing(q)
M = Matrix(R, A_values)
ingredients = M.solve_right(res)
print("Ingredients: {}".format(ingredients))
for row, b in zip(A_values, b_values):
effect = sum(starmap(mul, zip(map(int, ingredients), row))) % q
assert(abs(b - effect) < 2 ** 37)
print("ok") -
参考
祥云杯 2020 - easy matrix
OWASP Top 10 2021 是全新的,具有新的图形设计和一页有用的信息图。2021 年前 10 名发生了什么变化有三个新类别,四个类别的命名和范围发生了变化,并且 2021 年的前 10 名中进行了一些合并。A01:2021-Broken Access…
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论