Cryptohack-LATTICES
Cryptohack-LATTICES
LATTICES
1 Vectors
在某个域是用两个二元运算符定义的集合。对于一个向量.
考虑实数域上的二维向量空间,一个向量.
还可以定义内积(也称为点积),它取两个向量并返回一个标量。从形式上讲,我们认为:对于.
题目:
给出以下三个向量v = (2,6,3)
,w = (1,0,0)
,u = (7,7,2)
,计算3*(2*v - w) · 2*u
。
考察:基本的向量与标量之间的运算
直接计算或使用SageMath计算:
1 | v = vector([2,6,3]) |
2 Size and Basis
一组向量是线性无关的,当且仅当仅在时成立
基是一组线性独立的向量可以写成:
基中的元素数量
是向量空间的维数
向量的大小,定义为||v||
,向量自己和自己做内积:
一组正交基(orthogonal)
是指一组向量基.
一组标准正交基(orthonormal)
是指一组正交基,对于所有.
题目:
给出一个向量v=(4,6,2,5)
,计算它的大小。
考察:求向量的大小或者说向量的模
直接计算或使用SageMath计算:
1 | v = vector([4,6,2,5]) |
3 Gram Schmidt
给出一组向量空间的基.在Jeffrey Hoffstein、Jill Pipher、Joseph H.Silverman所著的《数学密码学导论》中,格拉姆-施密特算法如下:
格拉姆-施密特算法
Loop
= 2,3…,n
Compute . Set )
End Loop
题目:
给出以下一组基向量:
使用格拉姆-施密特算法计算正交基。flag是的第二个成员的浮点数值,保留小数点后五位。
考察:格拉姆-施密特算法计算正交基
使用SageMath计算:
1 | v0 = vector([4,1,3,-1]) |
贴一个Python的Solution:
1 | import numpy as np |
4 What's a Lattice?
给出一组线性无关的向量和对应整系数的组合。格生成的二维格。
使用基向量,我们可以用基向量的整数倍乘来到达格内的任意一点。基向量还定义了基本域:
举一个二维的例子,基本域是由边构成的平行四边形。
我们可以通过基向量计算基本域的体积。例如,取一个以.
题目:
计算由基向量构成的基本域的体积。
考察:基向量构成的基本域的体积
1 | v = vector |
5 Gaussian Reduction
如果你仔细观察,格密码开始在密码学中无处不在。有时,它们通过操纵加密系统出现,破坏了不够安全地生成的参数。最著名的例子是Coppersmith对RSA密码学的攻击。格密码也可用于构建加密协议,其安全性基于两个基本的困难问题:
最短向量问题(SVP):在格L中找到最短的非零向量。换句话说,在取最小值。
最近向量问题(CVP):给定一个不在L中的向量取最小值。
对于一般格来说,SVP很难,但对于足够简单的情况,有有效的算法来计算SVP的解或近似值。当格的维数为4或更小时,我们可以在多项式时间内精确计算;对于更高的维度,我们不得不接受一个近似值。
高斯开发了他的算法,为给定任意基的二维格找到最优基。此外,该算法的输出中最短的非零向量,因此求解了SVP。
ps:对于更高维度,有一种称为LLL算法的格基约减算法,以Lenstra、Lenstra和Lovász的名字命名。如果你经常玩CTF,你就一定会知道。LLL算法在多项式时间内运行。不过,就目前而言,让我们停留在二维空间。
高斯的算法大致通过从另一个基向量中减去一个基向量的倍数来工作,直到不再可能使它们更小。由于这是在二维中工作的,因此很容易可视化。以下是Jeffrey Hoffstein、Jill Pipher和Joseph H.Silverman在《数学密码学导论》中对算法的描述:
高斯格约化算法
Loop
(a) If  (b) Compute  (c) If  (d) 
Continue Loop
请注意,与欧几里德的GCD算法在“交换”和“缩减”步骤上的相似性,我们必须对浮点数进行四舍五入,因为在格上,我们可能只使用整数作为基向量的系数。
题目:
取两个向量,通过高斯算法,找到最优基,flag为新的基向量的内积。
考察:高斯格约化算法求最优基
1 | v = vector([846835985, 9834798552]) |
6 Find the Lattice
正如我们所看到的,格包含一些难题,这些难题可以形成密码系统的陷门函数。我们还发现,在密码分析中,格可以破坏最初似乎与格无关的密码协议。这个挑战使用模块化算法来加密标志,但协议中隐藏着一个二维格。我们强烈建议花时间应对这一挑战,并找到如何用格子打破它。这是一个著名的例子,有很多可用的资源,但知道如何在系统中发现格通常是打破它的关键。
作为提示,您将能够使用前一个挑战的高斯缩减来完成这个挑战。
题目代码如下:
1 | from Crypto.Util.number import getPrime, inverse, bytes_to_long |
题目输出:
Public key: (7638232120454925879231554234011842347641017888219021175304217358715878636183252433454896490677496516149889316745664606749499241420160898019203925115292257, 2163268902194560093843693572170199707501787797497998463462129592239973581462651622978282637513865274199374452805292639586264791317439029535926401109074800)
Encrypted Flag: 5605696495253720664142881956908624307570671858477482119657436163663663844731169035682344974286379049123733356009125671924280312532755241162267269123486523
已知q, h, e,其中
q 512位
f,g 低于256位
h,e 512位
r 256位
m为flag,大小约为231bit
要求得m,需要获得decrypt
的参数,还剩是未知的,由(6)式中可知
用上一题格的思想,构造一个由下面这个矩阵所张成的Lattice:
向量
即满足条件
向量就在这个Lattice上。
对于两个基底向量,(1,h):512位,(0,q):512位
而向量的长度约为256位,相比于基底向量极小,很大概率为此Lattice的最短向量。
EXP(SageMath):
1 | from Crypto.Util.number import * |