> 文章列表 > 2023 红明谷杯 --- Crypto It Takes Two! wp

2023 红明谷杯 --- Crypto It Takes Two! wp

2023 红明谷杯 --- Crypto It Takes Two! wp

题目

from sage.all import *
from Crypto.Util.number import *
from os import urandom
from secret import flagn = 16
bound = 2^15A = [ZZ.random_element(-bound, bound) for _ in range(n*n)]
A = Matrix(ZZ, n, n, A)B = [ZZ.random_element(-bound, bound) for _ in range(n*n)]
B = Matrix(ZZ, n, n, B)res = []
for i in range(5):bound = 2^15S = [ZZ.random_element(-bound, bound) for _ in range(n*n)]S = Matrix(ZZ, n, n, S)tmp = []for i in range(0, 60):S = S*A+Bbound = 2^(int(S[0, 0]).bit_length())if i % 3 == 2:tmp.append(Matrix(ZZ,n,n,[ZZ.random_element(-bound, bound) for _ in range(n*n)]))continuetmp.append(S)res.append(tmp)e = A.LLL().determinant()p = getPrime(512)
q = getPrime(512)
n = p * q
m = bytes_to_long(urandom(int(n).bit_length() // 8 - len(flag) - 1) + flag)
c = pow(m, e, n)
h1 = pow(p+q, e, n)
h2 = pow(p-q, e, n)f = open('双人成行.txt', 'w')
f.writelines(str(res)+'\\n')
f.writelines(str(n)+'\\n')
f.writelines(str(c)+'\\n')
f.writelines(str(h1)+'\\n')
f.writelines(str(h2)+'\\n')
f.close()

过程分析

A和B是固定的,五轮大循环,每一轮循环会生成随机矩阵S,然后进行60次循环 S = S ∗ A + B S = S*A+B S=SA+B,每三次循环中,第2次会生成一个新的n*n随机矩阵,否则使用更新后的S矩阵。这部分和LCG类似,我们可以通过两组LCG数据来计算出A,模3为2的矩阵不能取,所以我们取 S 0 , S 1 , S 3 , S 4 S_0,S_1,S_3,S_4 S0,S1,S3,S4,计算A,进而获得e。
S 1 = S 0 ∗ A + B S_1 = S_0*A+B S1=S0A+B
S 4 = S 3 ∗ A + B S_4 = S_3*A+B S4=S3A+B
两式相减
S 4 − S 1 = ( S 3 − S 0 ) ∗ A S_4-S_1 = (S_3-S_0)*A S4S1=(S3S0)A
⇒ A = ( S 4 − S 1 ) ∗ ( S 3 − S 0 ) − 1 \\Rightarrow A = (S_4-S_1)*(S_3-S_0)^{-1} A=(S4S1)(S3S0)1
此时得到e是奇数
另外一部分是二项式展开
h 1 ≡ ( p + q ) e m o d n ≡ p e + q e m o d n h_1 \\equiv (p+q)^e \\space mod \\space n \\equiv p^e+q^e \\space mod \\space n h1(p+q)e mod npe+qe mod n
h 2 ≡ ( p − q ) e m o d n ≡ p e − q e m o d n h_2 \\equiv (p-q)^e \\space mod \\space n \\equiv p^e -q^e \\space mod \\space n h2(pq)e mod npeqe mod n
两式相加
h 1 + h 2 ≡ 2 ∗ p e m o d n h_1+h_2 \\equiv 2*p^e \\space mod \\space n h1+h22pe mod n
发现h1+h2与n存在最大公约数p,进而求得
p = g c d ( h 1 + h 2 , n ) p = gcd(h_1+h_2,n) p=gcd(h1+h2,n)
经过计算e和phi不互素,且gcd(e,phi)=21,直接对解出的m开21次方未得到flag,显然经过padding后的m,其 m 21 = c m^{21}=c m21=c大于n,于是我们转换到有限域下对c开方,然后CRT组合一下得到flag.

PS:出题人我真是谢谢你嗷,所有矩阵append到一个列表里面,找矩阵还得小半天!!!

解题代码

from Crypto.Util.number import *
import gmpy2s0 = 
s1 = 
s3 = 
s4 = s0=matrix(s0)
s1=matrix(s1)
s3=matrix(s3)
s4=matrix(s4)
A=((s3-s0)^-1)*(s4-s1)
e = A.LLL().determinant()
n = 126930298936285661712486297662920895162569606037310367763354747221281175771655642407136326621695910623038808779778530112406355314071209370688157872928010633181351390724545013677593062556323119308457918805555312069055604237211117650220178416298165021603211366843640334616217695418858036626587483782452105122653
c = 113627841667808982839757084973426219545127121566516056267404541633803040730885409234473068650543791446730694746311695177758797711077000091232969424826171863685060090359260225102836081852105845748467870581394884564134418376982186965340367386781824886506478939204791426457255483148486730526127180397268053506840
h1 = 87021607670080656750728189202811647321664825322085967432146885995538140004901574830625347954724344331514731852873721100175299656618161173874818773415684739773055620673258848991693719847569489515642296650035465632567910004553054397894647697286044465567405142149926303968235362573821060105908856127568162452912
h2 = 70528801000055618659638315463133504198238507722722570127215098017082205934290867816695737682738831717228470799826957490782948760796844881508632060312080331264474968266753069687287034453036854258618280625776346633340081217397502423530180647548747144401922660710323623212890923488339464759360304751017490144695
p = gmpy2.gcd(h1+h2,n)
q = n//p
phi = (p-1)*(q-1)
t = gmpy2.gcd(gmpy2.mpz(e),int(phi))
d = gmpy2.invert(e//t,int(phi))
m = pow(c,d,n)R.<x> = Zmod(p)[]
f = x^t-m
f = f.monic()
results1 = f.roots()R.<x> = Zmod(q)[]
f = x^t-m
f = f.monic()
results2 = f.roots()for i in results1:for j in results2:param1 = [int(i[0]),int(j[0])]param2 = [p,q]M = CRT_list(param1,param2)flag = long_to_bytes(int(M))if b'flag' in flag:print(flag)break

flag:

flag{5a6814eb-8848-11ed-aee3-d812656dd8d8}

【我认为真正的爱情应该是一种小型共产主义,我是奉献但不是付出,能够不把奉献看成付出,不计较得失,便不会总是处于一种患得患失的心态,你我之间的爱情应当如此。】