Misay's blog

Back

EZRSA#

从

p = genarate_emojiiiiii_prime(512, 224)
q = genarate_emojiiiiii_prime(512)
py

切入,结合这个函数,不难分析出,q就是18个emoji块,而p的第288位都是emoji块(共8个),而p已知低256位,并且观察生成p的emoji块的组成,十位数表示都是40369911??所以说只用爆破第八个emoji的最后2位,即可得到p的低288位,然后对高位再打一组copper,此时是可以解的,解出来,这里copper的思路是,当x确定,在GF(n)GF(n)\\我们可以用多项式

p=f(x)=x∗2288+(a+i)∗2256+pp≡0 p=f(x)=x*2^{288}+(a+i)*2^{256}+pp\equiv0\\

来约束x,从而copper出可能的值,再用整除性验证即可,脚本如下

解出p,q之后就是e,phi不互素的RSA了,感谢不知道战队的师傅提供的一种简洁的写法TGCTF25 不知道 WP | 不知道のblog (idontknowctf.xyz) ↗

LLLCG#

数字签名问题,题干给出了一个三重LCG计算类,计算公式是

si+3≡asi+bsi+1+csi+2+d  mod  n s_{i+3}\equiv as_{i}+bs_{i+1}+cs_{i+2}+d\;mod\;n\\ s1=seed1  s2=seed2  s2=seed2 s_1=seed_1\;s_2=seed_2\;s_2=seed_2\\
  • 我们先看part1,我们每输入一个msgmsg,都会生成一个kik_i,并且用kik_i进行签名,然后再输出
[ki  mod  pj,....](0<j<10) [k_i\;mod\;p_j,....](0<j<10)\\

注意到已经给了DSA中的q = 1427475768627039429244287846531087092897981204933,这很小,所以我们可以每次都打CRT来恢复kik_i,就这样,我们能恢复12组kik_i 也就是说我们获得了这个三重LCG的连续12轮输出

这样之后,使用groebner方法来解关于a,b,c,d线性同余方程组,这样我们就打穿了这个LCG,

  • 再看向part2,先进行了307次LCG,但是对我们就是白盒,所以这里全程k我们都是知道的,我们回顾一下DSA签名的流程
r≡(gk  mod  p)  mod  q r\equiv(g^k\;mod\;p)\;mod\;q\\ s≡(k−1(h+xr))  mod  q s\equiv(k^{-1}(h+xr))\;mod\;q\\

这里h=hash(msg)h=hash(msg),(r,s)(r,s)就是签名rr代表签名的随机性kk,ss代表签名的唯一性xx,然后就是验证签名过程,假设传达到的明文是msgmsg,传过去的签名是(r0,s0)(r_0,s_0),那么

h=hash(msg) h=hash(msg)\\ w≡s−1  mod  p w\equiv s^{-1}\;mod\;p\\ u1≡h∗w  mod  p u_1\equiv h*w\;mod\;p\\ u2≡r0∗w  mod  p u_2\equiv r_0*w\;mod\;p\\

再计算验证值

v≡((gu1∗yu2)  mod  p)  mod  q v\equiv((g^{u_1}*y^{u_2})\;mod\;p)\;mod\;q\\

如果

v=r0 v=r_0\\

则验证成立,可见这里的验证方式只需要公钥yy

说回题目,part2给我们了10组(ri,si)(r_i,s_i),我们不难推出

x≡si∗k−hri  mod  p  (i=1,2...) x\equiv\frac{s_i*k-h}{r_i}\;mod\;p\;(i=1,2...)

解出x可以说绰绰有余了,

  • 最后是part3,我们只需按照上面的流程跑一遍,就能获得flag了,还是参考不知道战队师傅的wp,非常感谢!exp如下

TGCTF2025
https://www.zt2misay2.cn/blog/tgctf2025
Author Misay
Published at 2025年4月22日