WMCTF2023 Crypto

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+drnextdlnext=2dl以此我们从1爆破dlres=s1s2s2,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=2dl0+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)

同样是概率性,不过好像比上一题小,反正能弄出一组解

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值