参考资料:

  1. A Gentle Tutorial for Lattice-Based Cryptanalysis

  2. Improved low-density subset sum algorithms

  3. Solving low-density multiple subset sum problems with SVP oracle

  4. Extended Hidden Number Problem and Its Cryptanalytic Applications

  5. Extending Wiener’s Attack in the Presence of Many Decrypting Exponents

格(Lattice)

格的概念

定义:一个n维的格LRn的一个离散可加的子群. 对于格L,其可以被表示为由Rnm个线性无关的基向量{bb1,bb2,,bbm}组成的基BB,向量的个数m被称为格L的秩,所以格L也能表示为: L=L(BB)={i=1maibbi|aiZ,i=1,2,,m} 格的很多性质与记号与线性空间(向量空间)类似。 逐次最小长度:对于一个秩维n的格L,对于i{1,2,n},若r是使得格L拥有i个长度最大为r且线性无关的向量的最小值,则称r为格L的第i逐次最小长度,记为λi(L)=r 关于逐次最小长度,我们有闵可夫斯基(Minkowski)第一定理: 闵可夫斯基(Minkowski)第一定理:设L是一个n维满秩格,则: λ1(L)n|det(L)|1/n 闵可夫斯基第一定理表明我们可以以λ1(L)为标准来评判格中向量的长度.

关于格的问题

最短向量问题(Shortest Vector Problem, SVP):给定格L的基BB,找到格L上的一个非零向量vv满足||vv||=λ1(L). 最近向量问题(Closest Vector Problem, CVP):给定格L的基BB以及一个目标向量tt(不一定在格L上),找到格L上的一个非零向量vv满足 ||vvtt||=minwwL||wwtt|| 上述问题均为NP-Hard问题,这些问题的宽松版本如下: 近似最短向量问题(Approximate Shortest Vector Problem, SVPγ):给定格L的基BB与近似因子γ,找到格L上的一个非零向量vv满足||vv||γλ1(L). 近似最近向量问题(Approximate Closest Vector Problem, CVPγ):给定格L的基BB、一个目标向量tt(不一定在格L上)以及一个近似因子γ,找到格L上的一个非零向量vv满足 ||vvtt||=γminwwL||wwtt||SVPγCVPγ对于确定的参数均存在有效的解决方案,所以我们可以通过解决SVPγCVPγ来近似地解决SVPCVP. 我们可以通过格基规约来解决上述两个可计算问题.

格基规约

格基规约的目标是将一个任意一个格转化为另外一个基相同但是具有更短、更多的正交向量。由于我们要找的是“短向量”,所以格基规约可能会提供解决近似最短向量问题的方法.

LLL算法

LLL算法是一个迭代算法,由Lenstra、Lenstra与Lovász提出. 这个迭代算法的第一步是通过施密特正交化获得基BB={bb1,bb2,,bbn}的一组正交基,通过施密特正交化,我们可以将格基进行约减,对于上面的基BB,施密特正交化过程如下: {bbi=bbi,i=1bbi=bbij=1i1μi,jbbj,1<inμi,j=bbi,bbjbbj,bbj 而对于δ(14,1),如果基BB={bb1,bb2,,bbn}满足:

  1. (尺寸约减,size-reduction)对于任意i>j,有|μi,j|12
  2. (Lovász条件,Lovász condition)对于任意i{1,2,,n1},有(δμi+1,i2)||bbi||2||bbi+1||2

则称基BBδ-LLL约减基,通过结合这两个条件,Lenstra、Lenstra与Lovász给出了LLL算法: Pasted image 20250203175051 而对于格中最短向量的下界,我们有如下定理: 设格基BB={bb1,bb2,,bbn}对应的施密特正交基为基BB={bb1,bb2,,bbn},则有: λ1(L(BB))mini{1,,n}||bbi|| 通过这个定理,我们可以导出如下命题: 假若BB={bb1,bb2,,bbn}是一个δ-LLL约减基,则必然有: ||bb1||(24δ1)n1n|det(L)|1/n

这条式子往往可以帮助我们判断一个格基是否能通过LLL来约减出最短向量. 在sage中内置了现成的LLL算法,例如我们要解决A Gentle Tutorial for Lattice-Based Cryptanalysis中的例3.12(如下图): Pasted image 20250203182155 则可以通过下面的步骤来获得结果: Pasted image 20250203182349 显然可以得到结果为bb1=(0,1),bb2=(2,0).

解决CVP

LLL算法同样可以用来解决近似最近向量问题,但是需要结合Babai最近平面算法或者Kannan嵌入法

Babai最近平面算法(Babai’s Nearest Plane Algorithm)

Babai最近平面算法首先要获得输入格的约减基BB={bb1,bb2,,bbn},然后对于目标向量tt,我们令tt=ttcnbbn,其中:cn=tt,bbn/bbn,bbn(其中表示四舍五入),然后对前n1个向量与tt进行操作,得到tt=ttcn1bbn1,其中cn=tt,bbn1/bbn1,bbn1,以此类推,就可以得到完整的Babai最近平面算法: Pasted image 20250204163747

Kannan嵌入法

Kannan嵌入法是通过将目标向量嵌入格基,从而将CVP转化为SVP进行求解,设输入的格基为BB={bb1,bb2,,bbn},而目标向量为tt=(t1,t2,,tn),我们设CVP的解为c1bb1+c2bb2++cnbbn,即: tti=1ncibbi 也就有: tt=i=1ncibbi+ee 其中||ee||很小,所以我们就可以构造出一个n+1维的格: BB=(BB0ttq) 因为有: (c1,c2,,cn,1)BB=(ee,q) 所以这个格显然包含短向量(ee,q),由此我们就可以得到CVP的解为ttee. 在这里,整数q称为嵌入因子,它会影响到通过LLL算法寻找正确向量的成功率,应根据实际情况选取.

格在密码学中的应用

背包问题(Knapsack Problem)

背包问题是NP完全问题,其经常被用于作为公钥密码体系的陷阱门。在密码学中,背包问题的常见版本为子集和问题,即:给定n个正数a1,a2,,an与一个整数s,寻找集合{a1,a2,,an}的子集使得其和为s。也就是找到e1,e2,,en{0,1}使得: s=i=1neiai

低密度子集和问题

集合{a1,a2,,an}的密度d可以通过下式计算: d=nlog2maxi{1,2,,n}(ai) 研究表明,当d<0.9408时,我们可以将子集和问题转换为求解SVP. 一般策略为构造一个格,其中有一个短向量包含{e1,e2,,en},这样我们就可以构造出下面的格基矩阵: BB=(1a11a21ans) 显然线性组合(e1,e2,,en,1)会生成一个短向量(e1,e2,,en,1)BB=(e1,e2,,en,0),所以我们的预期是通过LLL算法对上述格进行规约得到这个短向量,但是这个方法在密度比较高的时候会失效,所以Coster等人提出了CJLOSS算法,使得我们可以在d<0.9408的时候通过将子集和问题转换为SVP从而在多项式时间内求解这个问题,CJLOSS算法中构造的格为: BB=(1Na11Na21Nan121212Ns) 其中整数N>n,在这个格内,线性组合(e1,e2,,en,1)会生成另外一个短向量: (e1,e2,,en,1)BB=(e112,e212,,en12,0) 显然这条短向量的模为n2,我们很容易可以通过LLL算法求解出这条短向量(这个短向量一般是规约后的格的第一个向量,且前n个元素往往为12ei)。 使用sage通过CJLOSS算法求解低密度子集和的代码如下:

python
def CJLOSS(A, s):
n = len(A)
N = ceil(sqrt(n))
L = matrix(QQ, n + 1)
for i in range(n):
L[i, i] = 1
L[n, i] = 1/2
L[i, n] = N * A[i]
L[n, n] = N * s
res = L.LLL()
for v in res:
if all(x in [-1/2, 1/2] for x in v[:-1]):
out = [1/2 - a for a in v[:-1]]
return out
例如,对于一个集合{71,73,79,107,89,91},求出满足和为269的一个子集,我们就可以通过CJLOSS算法进行求解(计算可得d=6log21070.8900<0.9408): Pasted image 20250204213311 所以可以得到和为269的一个子集为{73,107,89}.

低密度多重子集和问题

通过对子集和问题的扩展,我们可以得到多重子集和问题:给定kn个正整数a1,1,a1,2,ak,n以及k个整数s1,,sk,找到e1,e2,,en{0,1}满足对任意j1,2,,ksj=i=1neiaj,i 实际上多重子集和问题总体与普通子集和问题差不多,但是集合更多,此时我们通过下式对密度d进行计算: d=nklog2max(aj,i) 根据潘彦斌等人研究可以得出,当d<0.9408时,我们可以通过构造如下格来将低密度多重子集和问题转换为SVP进行求解: BB=(10Na1,1Na2,1Nak,110Na1,2Na2,2Nak,210Na1,nNa2,nNak,n12121212Ns1Ns2Nsk) 其中整数N>n+14,此时在这个格内,线性组合(e1,e2,,en,1)会生成一个短向量: (e1,e2,,en,1)BB=(e112,e212,,en12,12,0,,0) 通过LLL算法我们就可以得到这个短向量.

低密度模子集和问题与低密度多重模子集和问题

通过对子集和问题的扩充,我们可以得到模子集和问题:给定n个模M下的正整数a1,a2,,an,再给出一个整数s,找到e1,e2,,en{0,1},使得: si=1neiai(modM) 从而可以推广为多重模子集和问题:给定kn个模M下的正整数a1,1,a1,2,ak,n以及k个整数s1,,sk,找到e1,e2,,en{0,1}满足对任意j1,2,,ksji=1neiaj,i(modM) 实际上,模子集和问题问题可以视作k=1的多重模子集和问题,我们可以通过下式对多重模子集和问题的密度d进行计算: d=nklog2M 根据潘彦斌等人研究可以得出,当d<0.9408k=ο(nlog2((n+1)n+1))时,我们可以通过构造如下格来将低密度多重模子集和问题转换为SVP进行求解: BB=(10Na1,1Na2,1Nak,110Na1,2Na2,2Nak,210Na1,nNa2,nNak,nNMNMNM12121212Ns1Ns2Nsk) 使用LLL算法进行规约就可以得到目标短向量(e112,e212,,en12,12,0,,0).

隐藏数问题(Hidden Number Problem,HNP)

隐藏数问题的形式一般为给定一个质数p,令α[1,p1]作为“被隐藏的数字”,给定m个数对{(ti,ai)}i=1m使得: βitiα+ai0(modp) 其中|βi|<K<p,我们需要从中恢复出α. 为解决这类问题,我们可以重写βitiα+ai0(modp)βi+ai=tiα+kip,这样我们就可以构造出下面的格: BB=(pppt1t2tm1p) 对于向量vv=(k1,,km,α)vvBB=(β1+a1,,βm+am,α/p),显然这个向量并不是很短,但是我们注意到: vvBB=(a1,,am,0)+(β1,,βm,α/p) 那么令tt=(a1,,am,0),uu=(β1,,βm,α/p),我们就可以得到: vvBBtt=uu 其中||uu||<m+1K,显然我们可以通过将求解HNP转换为求解CVP,通过Kannan嵌入法,令嵌入因子为K,我们就可以得到下面的格: BB=(pppt1t2tmKpa1a2amK) 其包含向量uu=(β1,,βm,Kα/p,K),且||uu||<m+2Kdet(BB)=pm1K2,显然有: ||uu||<m+2K<(24δ1)m+1m+2|det(BB)|1/(m+2) 所以我们可以通过LLL来找到短向量uu,但是这个向量并不是最短的,因为格上存在另一个向量(0,,0,K,0),它比uu更短,所以uu一般在规约后的第二个向量.

扩展隐藏数问题(Extended Hidden Number Problem,EHNP)

通过对一般的隐藏数问题的扩展我们可以得到扩展隐藏数问题:给定素数p,对整数x[1,p1],有: x=x+j=1m2πjxj 其中x以及πj均已知,而未知整数xj对于一个已知的整数νj满足0xj<2νj,给出d条方程: αij=1m2πjxj+j=1liρi,jki,jβiαix(modp) 其中对于1idαi0(modp)ρi,j以及βi均为已知的整数,未知正整数ki,j的上界为2μi,jμi,j已知,则扩展隐藏数问题(EHNP)则是通过上述条件恢复x. 为解决EHNP,我们可以构造格: BB=(pIIdAAXXRRKK) 其中: AA=(α12π1α22π1αd2π1α12π2α22π2αd2π2α12πmα22πmαd2πm)XX=diag(δ2ν1,δ2ν2,,δ2νm)RR=(ρ1,1ρ1,2ρ1,l1ρd,1ρd,2ρd,ld)KK=diag(δ2μ1,1,,δ2μ1,l1,,δ2μd,1,,δ2μd,ld)L=l1+l2++ldD=d+m+L,计算: κD=2D/4(m+L)1/2+12 通过κD,我们可以得到δ满足0<δκD<1。令 vv=(β1αix,,βdαdx,δ2,,δ2) 我们需要根据上述的δ构造格L=L(BB,δ),在格L中找到向量uu使得: ||uuvv||2D4minttL||vvtt|| 通过LLL算法对我们构造的格进行规约可以得到: uu=(β1αix,,βdαdx,x1δ2ν1,,xmδ2νm,k1,1δ2μ1,1,,k1,l1δ2μ1,l1,,kd,1δ2μd,1,,kd,ldδ2μd,ld) 然后令xj=1δ(uud+j2νj)1jm),最后计算: x=x+j=1m2πjxjmodp 这样得到的x就是我们需要的x. 在论文Extended Hidden Number Problem and Its Cryptanalytic Applications中还提及了一种通过狄利克雷近似计算双洞隐藏数问题(Hidden Number Problem with Two Holes, HNP-2H),具体方法与步骤在通过狄利克雷近似解决HNP-2H | Triode Field有写.

Coppersmith方法

Howgrave-Graham定理

h(x1,,xn)Z[x1,,xn]是一个由ω个单项式组成的多项式,如果:

  1. 存在|r1|<X1,,|rn|<Xn,有f(r1,,rn)0(modN)
  2. ||h(x1X1,,xnXn)||<Nω

那么f(r1,,rn)=0在整数域同样成立.

这个定理是Coppersmith方法的关键所在。

一元Coppersmith

对于度为k的一元本原多项式p(x)=xk+ak1xk1++a1x+a0Z[x],Coppersmith方法可以找到方程p(x)0(modN)(其中N是一个合数)的一个小根xx0(modN)|x0|<X,其中X是一个自然数,且XN1/k) 这个算法的主要思想就是构造一个多项式h(x)使得h(x0)=0,而求解h(x)=0这个方程是很简单的,所以我们可以将求解p(x)0(modN)这一任务转化为求解h(x)=0。我们可以构造格: BB=(NXNX2NXk1Na0a1Xa2X2ad1Xd1Xd) 然后通过LLL规约得到一个矩阵: BB=(b0b1bd1bd) 则有: h(Xx)=bdxd+bd1xd1++b1x+b0 可以得到: h(x)=(bdXd)xd+(bd1Xd1)xd1++(b1X)x+b0 解该方程得到的整数解就有可能是我们要的x0。 在实际应用中,我们可以直接利用sage的small_roots来进行求解。

多元Coppersmith

那堆东西暂时没看懂,先贴个从某些地方搜刮来的板子

python
def small_roots(f, bounds, m=1, d=None):
import itertools
if not d:
d = f.degree()
R = f.base_ring()
N = R.cardinality()
f /= f.coefficients().pop(0)
f = f.change_ring(ZZ)
G = Sequence([], f.parent())
for i in range(m + 1):
base = N ^ (m - i) * f ^ i
for shifts in itertools.product(range(d), repeat=f.nvariables()):
g = base * prod(map(power, f.variables(), shifts))
G.append(g)
B, monomials = G.coefficients_monomials()
monomials = vector(monomials)
factors = [monomial(*bounds) for monomial in monomials]
for i, factor in enumerate(factors):
B.rescale_col(i, factor)
B = B.dense_matrix().LLL()
B = B.change_ring(QQ)
for i, factor in enumerate(factors):
B.rescale_col(i, 1 / factor)
H = Sequence([], f.parent().change_ring(QQ))
for h in filter(None, B * monomials):
H.append(h)
I = H.ideal()
if I.dimension() == -1:
H.pop()
elif I.dimension() == 0:
roots = []
for root in I.variety(ring=ZZ):
root = tuple(R(root[var]) for var in f.variables())
roots.append(root)
return roots
return []

一般维纳攻击的格方法

维纳方法:对于N=pq,假设λ(N)e均与N接近,而且解密指数d<N1/4,那么因为ed满足edkλ(N)=1,所以令λ(N)=(p1)(q1)/g,又令s=1pq,就可以得到: edgkN=g+ks 那么有: eNkdg=ksdgN+1dN 由于eN|s|N1/2,那么可以得到kdg1,所以上述方程的值约等于N1/2,由勒让德定理,如果N1/2<1/[2(dg)2],那么kdg会是e/N的渐进分数,所以我们可以通过连分数来得到d,或者分解出p,q,上述讨论中一般情况下g=1。 令g=1,实际上此时λ(N)=φ(N),我们注意到,在上述条件下得到的edkN=1+ks一式存在线性关系,所以可以考虑使用格来求解,考虑构造如下格: BB=(1e0N) 其中目标向量为vv=(d,1+ks),其中s=1pq,可以知道|s|N1/2d<N1/4,则有|det(BB)|=N,可以知道 ||vv||=d2+(1+ks)2>2N1/2>2|det(BB)|1/2 显然,通过闵可夫斯基第一定理,我们几乎不可能通过规约得到我们的目标向量,那么我们要进行格基配平,根据分析,我们构造如下格: BB=(2αe0N) (其中αN的比特数的1/2),这样就可以通过LLL算法规约得到目标向量(2αd,1+ks).