WMCTF2023 Crypto
密码题又少,难度也不大。
signin
签到
badprime
比签到还简单
welcomesigner2
把代码逻辑搞清楚就逐位爆破,这里直接给出与fastexp等价的函数
def get_B(m,N,N_,d):
d = bin(d)[2:][::-1]
n = len(d)
R=[]
BB=m
for i in range(n):
R.append(BB)
BB=BB**2 %N
return R
def test(m,j,N,N_,BB,d):
d=bin(d)[2:]
n=len(d)
return (pow(m, int(d[j:], 2), N) * pow(BB, 2 * int(d[:j], 2), N_)) % N_
for i in range(1,1023):
assert myfastexp(msg,d,n,i,n_)==test(msg,i,n,n_,B[l-i-1],d)
将 d 分成 d l , d r . s 1 = m d r m o d n s 2 = B i d l m o d n _ 若当前位为 0 ,则 m d r = = m 0 + d r n e x t , d l n e x t = 2 ∗ d l 以此我们从 1 爆破 d l , r e s = s 1 ∗ s 2 则 s 2 , r e s 为已知值,判断当前步与下一步的 s 1 是否相等即可 将d分成dl,dr.\\ s1=m^{dr}\mod n\\ s2=B_i^{dl}\mod n\_\\ 若当前位为0,则m^{dr}==m^{0+dr_{next}},dl_{next}=2*dl\\ 以此我们从1爆破dl,res=s1*s2\\ 则s2,res为已知值,判断当前步与下一步的s1是否相等即可 将d分成dl,dr.s1=mdrmodns2=Bidlmodn_若当前位为0,则mdr==m0+drnext,dlnext=2∗dl以此我们从1爆破dl,res=s1∗s2则s2,res为已知值,判断当前步与下一步的s1是否相等即可
贴一下自己的
D='1'
B=get_B(msg,n,n_,d)
for i in range(1,1023):
t1=myfastexp(msg,d,n,i,n_)*inverse(pow(B[l-i-1],2*int(D,2),n_),n_) %n_
t2=myfastexp(msg,d,n,i+1,n_)*inverse(pow(B[l-i-2],4*int(D,2),n_),n_) %n_
if t1==t2:
D+='0'
else:
D+='1'
if '111111111111111' in D:
break
print(D)
B数组生成只用到了d的长度,这里可以默认为1023,不过代码是概率性成功的
welcomesigner1
跟上面题目一样
先看一下直观的等价表达
def myfastexp(m,d,N,j,N_):
A = 1
d = bin(d)[2:]
n = len(d)
# print(d)
dd=d[::-1]
temp=pow(m,int(dd[:n-j],2),N)
temp=pow(temp,2**j,N_)*pow(m,int(dd[n-j:],2),N_) %N_
for i in range(n-1,-1,-1):
if i < j:
N = N_
A = A*A % N
if d[i] == "1":
A = A * m % N
assert A==temp
return A
反向d之后以n-j分成两部分dr,dl
s
1
=
m
d
r
m
o
d
n
s
2
=
m
d
l
m
o
d
n
_
r
e
s
=
(
s
1
<
<
j
)
∗
s
2
m
o
d
n
_
s1=m^{dr}\mod n\\s2=m^{dl}\mod n\_\\res=(s1<<j)*s2\mod n\_
s1=mdrmodns2=mdlmodn_res=(s1<<j)∗s2modn_
类似上题,这题从dl往dr爆破
当前为0时
d
l
n
e
x
t
=
2
∗
d
l
0
+
d
r
n
e
x
t
=
d
r
dl_{next}=2*dl\\0+dr_{next}=dr
dlnext=2∗dl0+drnext=dr
还是以s1不变建立关系
这里由于最开始有一步reverse(d)操作,所以整体逻辑上从l-1开始爆破。中间的左右逻辑关系稍微有点变化,自行理解
D='1'
for i in range(l-1,0,-1):
temp=pow(msg,int(D,2),n)
temp1=pow(temp,2**i,n_)
temp=pow(msg,2*int(D,2),n)
temp2=pow(temp,2**(i-1),n_)
t1=myfastexp(msg,d,n,i,n_)*inverse(temp1,n_) %n_
t2=myfastexp(msg,d,n,i-1,n_)*inverse(temp2,n_) %n_
if t1==t2:
D+='0'
else:
D+='1'
if '111111111111111' in D:
break
print(D)
同样是概率性,不过好像比上一题小,反正能弄出一组解