0%

[tangcuxiaojkuai]easy_mod

2024-03-28 09:04By
tangcuxiaojkuai
格基规约格相关CRYPTO

Problem: [tangcuxiaojkuai]easy_mod

[[toc]]

思路

可以看到m的特殊性在于:除了NSSCTF{}组成的前后缀以外,仅由0-7的数字拼接而成,一共有70个数字。

那么思路首先肯定是把前后缀给去掉,从而减小明文数量级。由字节转数字的方式可以知道m其实可以写成如下形式(其中pre指"NSSCTF{",suf指"}",m0就是中间的长为70数字串):

m = 256^{71}pre + 256m_0 + suf

那么就有:

c = (256^{71}pre + 256m_0 + suf) \quad(mod\;p)

就可以得到m0模p的值:

m_0 = 256^{-1}(c - 256^{71}pre - suf) \quad(mod\;p)

接下来的问题是如何利用m0的特殊性去求解他,由于m0仅由0-7的数字组成,用ASCII码的角度去看就是48-53,所以一个很自然的思路是把m0写成如下形式(记m0的每个字节值为si):

m_0 = \sum_{i=0}^{69}256^is_i =s_0 + 256s_1 + 256^2s^2 + ... + 256^{69}s^{69} \quad (mod\;p)

那么可以写成一个等式即:

m_0 = \sum_{i=0}^{69}256^is_i + kp

这个等式就给造格提供了一个依据,可以造出如下格:

\left(\begin{matrix} 1 &&& &&1\\ &1&& &&256\\ &&\ddots& &&\vdots\\ &&&1 &&256^{69}\\ &&& &1&-m_0\\ &&& &&p\\ \end{matrix}\right)

具有的线性关系是:

(s_0,s_1,...,s_{69},1,k) \left(\begin{matrix} 1 &&& &&1\\ &1&& &&256\\ &&\ddots& &&\vdots\\ &&&1 &&256^{69}\\ &&& &1&-m_0\\ &&& &&p\\ \end{matrix}\right) = (s_0,s_1,...,s_{69},1,0)

那么如果界符合的话,用这个等式去造格,规约出来的向量预期应该是由48-53的一系列值组成的短向量,但一做就知道这样并不能得到预期结果。

然后一个朴素的优化想法就是,不妨新令一组变量:

t_i = s_i - 48

那么就可以将刚才的等式做如下处理:

m_0 = \sum_{i=0}^{69}256^i(t_i+48) \quad(mod\;p)

那么减去48(也就是0对应的ASCII码值)之后,预期规约出的向量就都变成了0-7的短向量,机会就大很多。并且由于48与256^i的乘积都可以计算,所以可以仅处理上面格中的m0项而不需要改动其他地方,也就是:

m_1 = m_0 - 48\sum_{i=0}^{69}256^i

此时造格的等式为:

m_1 = \sum_{i=0}^{69}256^it_i + kp

然后是做一些老生常谈的使格规约本身更有利的一些优化,比如说,现在目标向量为:

(t_0,t_1,...,t_{69},1,0)

为了保证规约出0,就要给格的最后一列配上个大系数。同时,ti的取值为0-7,也就是说平均值在3、4左右,因此给倒数第二列配上个3、4能使目标向量中值的数量级更加接近。

EXP

exp:

from Crypto.Util.number import * p = 501785758961383005891491265699612686883993041794260611346802080899615437298977076093878384543577171 c = 327005346153237517234971706274055111857447948791422192829214537757745905845319188257204611848165263 prefix = b"NSSCTF{" suffix = b"}" length = 78 - len(prefix) - len(suffix) #part1 remove prefix and suffix c -= 256^(len(suffix) + length) * bytes_to_long(prefix) c -= bytes_to_long(suffix) c = c * inverse(256,p) % p L = Matrix(ZZ,length+2,length+2) for i in range(length): L[i,i] = 1 L[i,-1] = 256^i c -= 256^i*48 L[-2,-2] = 4 L[-2,-1] = -c L[-1,-1] = p L[:,-1:] *= p res = L.BKZ() flag = "" for i in res[:-1]: if(abs(i[-2]) == 4 and all(abs(j) < 8 for j in i[:-2])): for j in i[:-2][::-1]: flag += chr(48 + abs(j)) print(flag) #NSSCTF{5036541772751046406531362142757356307107252723754051320011253505562041}
还没有人赞赏,快来当第一个赞赏的人吧!
  
© 著作权归作者所有

加载中...

加载失败
广告
×
评论区
添加新评论

佬,为什么

L[-2,-1] = -c%p

反而不行了ques

这个运算顺序也许是-(c%p)?

加载中...