The learning of LWE
Contents
做Ant&d3的时候发现自己Lattice还不会, 所以就去学了一波Lattice, 顺便就了解了一下LWE, 发现这玩意居然有三次比赛用的都是同一个板子, 也每个都去做了分析了一下, 然后就集中在这里了.
感谢一位大大大大大师傅详细的wp,我才能这么快的明白原理,指路 —> https://blog.soreatu.com/
X-NUCA Diamond
题目
1 | #!/usr/bin/env sage |
一些新见到的函数
random_matrix(ZZ, 5, 320, x = 10, y = 1000)
: 随机生成一个整数的$320 \cdot 5$矩阵, 其元素的取值范围是$[x,y)$也就是$[10,1000)$LWE(n = 25, q = 1000, D = DGDIS(3))
: 生成一个25维 $mod \ 1000$的LWE对象D
- an error distribution such as an instance ofDiscreteGaussianDistributionIntegerSampler
stack()
: 在末尾添加一行
题目中给出的一些条件
- 首先是一个
320*5
的矩阵$A$,乘上了一个随机变换矩阵5*7
的矩阵$R$,得到了一个320*7
的矩阵B - 然后是一个LWE,生成了64组数据,$s⋅A_{lwe}+e=a$,没有直接给我们$A_{lwe}$和$a$。只给了$M=A{lwe}\bigoplus A$,以及用$s$作为AES的key,对flag进行了加密。
- 再就是一个knapsack problem,用长度为64的向量$a$与一个另外一个很大的长度为64的随机向量$T$相乘,得到一个很大的数$sum$。给了$T$以及$sum$。
knapsack problem
这里有一个背包问题
$$
a_0T_0+a_1T_1+…+a_{63}T_{63} = sum
$$
其中已知$T_0,T_1,…,T_{63},sum$,而且$T_i$非常大, $a_i \le 1000$ , 可以由上述式子构造格子
$$
A=
\begin{pmatrix}
1&0&\cdots&0&T_0\\
0&1&\cdots&0&T_1\\
\vdots&\vdots&\ddots&0&\vdots\\
0&0&\cdots&1&T_{63}\\
0&0&\cdots&0&-sum
\end{pmatrix}
$$
则有
$$
\begin{pmatrix}
a_0,a_1,…,a_{63},{1}
\end{pmatrix}
\begin{pmatrix}
1&0&\cdots&0&T_0\\
0&1&\cdots&0&T_1\\
\vdots&\vdots&\ddots&0&\vdots\\
0&0&\cdots&1&T_{63}\\
0&0&\cdots&0&-sum
\end{pmatrix}
=
\begin{pmatrix}
a_0,a_1,…,a_{63},{0}
\end{pmatrix}
$$
可以看到$\begin{pmatrix}a_0,a_1,…,a_{63},0\end{pmatrix}$是其中一个格点, 而且非常的小, 可以尝试用LLL将其规约出来
1 | R = [...] |
恢复$A_{lwe}$
这部分还有些不明白,先放着
LWE
$$
s \cdot A + e = a
$$
可以将这个等式理解成$A$是一个格子, $s$是一个线性组合, 那么$b = s \cdot A$是一个格点, $e$是误差, $a = b+e$是一个非格点. LWE就是要找到这么离这个非格点最近的格点. 也就是CVP了
当$s$的长度不是很长的时候, 也就是说维度比较小的时候, 这个CVP还是可以解决的, 而这里$s$的长度是25, 观察一下LWE的式子.
$$
s_0A_{i,0}+s_1A_{i,1}+…+s_{24}A_{i,24} + e_i = a_i \ (mod \ p)
$$
熟悉的造格子前的套路, 将式子化为:
$$
s_0A_{i,0}+s_1A_{i,1}+…+s_{24}A_{i,24} + k_ip + e_i= a_i
$$
那么可以构造出等式:
$$
s \cdot L + e =
(s_0,s_1,…,s_{24},k_0,k_1,…,k_{39})
\begin{pmatrix}
A_{0,0}&A_{1,0}&\cdots&A_{39,0}\\
A_{0,1}&A_{1,1}&\cdots&A_{39,1}\\
\vdots&\vdots&\ddots&\vdots\\
A_{0,24}&A_{1,24}&\cdots&A_{39,24}\\
p&0&\cdots&0\\
0&p&\cdots&0\\
\vdots&\vdots&\ddots&\vdots\\
0&0&\cdots&p\\
\end{pmatrix}
+
(e_0,e_1,…,e_{39})
=
(c_0,c_1,…,c_{39})
$$
先对矩阵$L$进行规约, 得到一个good basis, 再用Babai’s algorithm求解CVP,即可得到离$a$最近的格点$b$。
最后解方程$A_{lwe} \cdot s = b^{T} (mod \ 1000)$
解出$s$这道题基本上就做完了
下面是Babai’s algorithm的板子
1 | def BabaisClosestPlaneAlgorithm(L, w): |
总的exp就没写了, 具体的可以参照着下面两题来写, 反正都是一个板子的
2020祥云杯 Easy Matrix
Problem
1 | import numpy as np |
条件
读取了matrix后就可以知道column = 42
将flag
转成一个1*42
的矩阵$secret$
来看看过程, 先是生成一个42*128
的随机矩阵$matrix$, 元素都$\leq 512$
然后计算$product = matrix \cdot secret \ (mod \ prime)$, 结果应该是一个$1*128$的矩阵
继续生成一个1*128
随机矩阵$offset$
最后计算$result = (product + offset) \ (mod \ prime)$
题目给了$result$和$matrix$
分析
来看一下加密的式子
$$
R = S \cdot M + e \ (mod \ p)
$$
显然是一个LWE, 现在已知的是$M$和$R$, 要求$S$, 将式子写具体
$$
R = (r_0,r_1,..,r_{127}) =
(s_0,s_1,…,s_{41})
\begin{pmatrix}
m_{0,0}&m_{1,0}&\cdots&m_{127,0}\\
m_{0,1}&m_{1,1}&\cdots&m_{127,1}\\
\vdots&\vdots&\ddots&\vdots\\
m_{0,41}&m_{1,42}&\cdots&m_{127,41}
\end{pmatrix}
+
(e_0,e_1,…,e_{41})
(mod \ p)
$$
也就是说
$$
r_i = s_0m_{i,0} + s_1m_{i,1}+…+s_{41}m_{i,41} + e_i (mod \ p)
$$
老套路, 改写成等式有
$$
s_0m_{i,0} + s_1m_{i,1}+…+s_{41}m_{i,41} + e_i + k_ip = r_i \
s \cdot A + e = r
$$
解决LWE可以构造格子, 然后用LLL和babai’s nearest plane来解决, 下面就根据等式构造格子
$$
A=
\begin{pmatrix}
m_{0,0}&m_{1,0}&\cdots&m_{127,0}\\
m_{0,1}&m_{1,1}&\cdots&m_{127,1}\\
\vdots&\vdots&\ddots&\vdots\\
m_{0,41}&m_{1,42}&\cdots&m_{127,41}\\
p&0&\cdots&0\\
0&p&\cdots&0\\
\vdots&\vdots&\ddots&\vdots\\
0&0&\cdots&p
\end{pmatrix}
\begin{pmatrix}
p&0&\cdots&0\\
0&p&\cdots&0\\
\vdots&\vdots&\ddots&\vdots\\
0&0&\cdots&p\\
m_{0,0}&m_{1,0}&\cdots&m_{127,0}\\
m_{0,1}&m_{1,1}&\cdots&m_{127,1}\\
\vdots&\vdots&\ddots&\vdots\\
m_{0,41}&m_{1,42}&\cdots&m_{127,41}\\
\end{pmatrix}\\
$$
实际上做的时候右边的格子才有用, 左边的不行, 具体原因我也搞不清楚, 问了老师也没问出什么结果
然后就可以用LLL格约出good basis 再用babai’s nearest plane解CVP了
解出CVP也就意味着找到了$s \cdot A = b$中的$b$ , $A$又是已知的, 解方程即可
exp
1 | import numpy as np |
2020纵横杯 babyLWE
problem
1 | from sage.crypto.lwe import LWE |
分析
太离谱了, 一个板子三个比赛用, 这题用的还是X-NUCA Diamond的LWE的板子…
但是为了充分理解(就是还没理解)LWE到底是怎么通过格子解出来的
先看看这题造的格子
加密的式子还是$s \cdot M + e = a \ (mod \ q)$, 这里的$s,M$长度32,一共64个式子
这里只知道$M$和$a$要求$s$, 思路都是记$s \cdot M = b $, $b$是格子$M$的一个格点, $a$是格外一个点, 通过对$M$规约找到$good \ basis$ 再利用最近平面算法解决一个CVP, 也就是找到离$a$最近的向量, 也就是$b$
把$s \cdot M = b \ (mod \ q)$再详细点就是
$$
s_0M_{i,0}+s_1M_{i,1}+…+s_{31}M_{i,31} = b_i + k_iq\\
s_0M_{i,0}+s_1M_{i,1}+…+s_{31}M_{i,31}+ k_iq = b_i
$$
那么造出来的格子应该是下面这个矩阵
$$
(s_0,s_1,\cdots,s_{31},k_0,k_1,\cdots,k_{63})
\begin{pmatrix}
M_{0,0}&M_{1,0}&\cdots&M_{63,0}\\
M_{0,1}&M_{1,1}&\cdots&M_{63,1}\\
\vdots&\vdots&\ddots&\vdots\\
M_{0,31}&M_{1,31}&\cdots&M_{63,31}\\
q&0&\cdots&0\\
0&q&\cdots&0\\
\vdots&\vdots&\ddots&\vdots\\
0&0&0&q
\end{pmatrix}
=
(b_0,b_1,\cdots,b_{63})
$$
实际上做题的时候矩阵是上面$p$下面$M$的, 然后还有关于为什么要用64组LWE的问题, 根据某个大佬的博客, 组数越多越好, 所以基本上题目给了多少组就用上多少组
通过对构造出来的格子进行规约得到good basis然后用最近平面算出$(b_0,b_1,…,b_{63})$
再解方程$s \cdot M = b \ (mod \ p)$即可得到$s$
exp
1 | from sage.modules.free_module_integer import IntegerLattice |
2021/3/31 update
因为最近在做大学生密码挑战赛的LWE, 所以学了挺多造格子的姿势
这边记录一个好用的格子, 80维的秘密向量都可以规约出来, 很牛逼
在$As + e = b \mod q$中
我们可以把矩阵$A$和向量$b$看成$A=\begin{pmatrix}A_1 \\ A_2\end{pmatrix}$,$b=\begin{pmatrix}b_1 \\ b_2\end{pmatrix}=\begin{pmatrix}A_1 \\ A_2\end{pmatrix}s + \begin{pmatrix}e_1 \\ e_2\end{pmatrix} $
所以咱们就可以构造出这么一个格子
$$
\begin{pmatrix}
I_n&0&b_1 \\
A_2A_1^{-1}&qI_{m-n}&b_2 \\
0&0&1
\end{pmatrix}
\begin{pmatrix}
A_1s \\
k \\
-1
\end{pmatrix}
=
\begin{pmatrix}
-e_1 \\
-e_2 \\
-1
\end{pmatrix}
$$
规约出来的就直接是噪音$e$了, 有了$e$就能解出$s$, 不过这边还是有几个点要去注意
- 上面式子给出的格子并不是扔进
sage
里规约的格子, 真正扔进去规约的是它的转置, 也不知道是不是sage
默认对行向量规约, 只能把它转置才能规约出结果, 结果也是行向量来的 - 格子中有一个$A_2A_1^{-1}$, 其中的逆矩阵$A_1^{-1}$是模$q$的逆, 有时候会出现模$q$不能求逆的情况, 这个时候可以适当的调换$A$中的行向量, 使得$A_1 \mod q$的逆存在, 但要记得向量$b$也要跟着调换, 而且最后求到的结果也是调换之后的, 需要还原回去
暂时就这两个点了
为了写个板子供以后做题用, 我把祥云杯那道题的数据拿过来写了个exp
, 贴在这边以后要用了可以过来拿.
1 | import numpy as np |
Author: K1rit0
Link: http://tearsjin.github.io/2021/03/31/The-learning-of-LWE/
License: 知识共享署名-非商业性使用 4.0 国际许可协议