红明谷 2022

crypto

总共就两道crypto,都还算简单的了

easy_ya

附件

m3=c(mod n)

将m=rx+M带入上式,copper求小根x,最后还原回m即可

from Crypto.Util.number import *
r = 7996728164495259362822258548434922741290100998149465194487628664864256950051236186227986990712837371289585870678059397413537714250530572338774305952904473
M = 4159518144549137412048572485195536187606187833861349516326031843059872501654790226936115271091120509781872925030241137272462161485445491493686121954785558
n = 131552964273731742744001439326470035414270864348139594004117959631286500198956302913377947920677525319260242121507196043323292374736595943942956194902814842206268870941485429339132421676367167621812260482624743821671183297023718573293452354284932348802548838847981916748951828826237112194142035380559020560287
e = 3
c = 46794664006708417132147941918719938365671485176293172014575392203162005813544444720181151046818648417346292288656741056411780813044749520725718927535262618317679844671500204720286218754536643881483749892207516758305694529993542296670281548111692443639662220578293714396224325591697834572209746048616144307282
PR.<x>=PolynomialRing(Zmod(n))
f=(r*x+M)^e-c
f=f.monic()
root=f.small_roots(X=2^200)
print(root)
m=r*int(root[0])+M
print(long_to_bytes(m))

sm2

附件

附件看着有点吓人,描述的是个签名算法,看名字sm2估计就是sm2的签名算法照抄了,百度搜了一下,大概流程就是

签名信息为m,私钥为d

生成随机数k,1<k<n-1

计算(x,y)=kG

计算r=H(m)+x(modn)

若r=0或r+k=n则重新选择k

计算s=(1+d)-1(k-rd)mod(n)

回到附件里着重看签名部分

    def sign(self, data, K):
        e = data
        d = self.sk
        k = K

        P1 = self._kg(k, self.ecc_table['g'])
        x = int(P1[0:self.para_len], 16)
        R = ((e + x) % int(self.ecc_table['n'], base=16))
        if R == 0 or R + k == int(self.ecc_table['n'], base=16):
            return None
        d_1 = pow(
            d+1, int(self.ecc_table['n'], base=16) - 2, int(self.ecc_table['n'], base=16))
        S = (d_1*(k + R) - R) % int(self.ecc_table['n'], base=16)
        if S == 0:
            return None
        else:
            return '%064x%064x' % (R, S)

注意到n是素数,所以它的实现和标准算法是一致的

于是对于一组签名我们有

k=(S+R)d+S(mod n)

我们希望求出d,并且此时题目给了我们很多组签名结果,且k的比特数我们是知道的,可以按照hnp问题进行求解

这篇文章可以参考,写的十分详细了

import base64
import hashlib
from Crypto.Cipher import AES
from Crypto.Util.number import long_to_bytes
f=open('output.txt','r')
c=f.readline()[:-1]
sign=eval(f.readline())
n=0xFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123
M=Matrix(102,102)
M=Matrix(QQ,M)
for i in range(100):
    M[i,i]=n
    s=sign[i]
    R=int(s[:64],16)
    S=int(s[64:],16)
    M[100,i]=S+R
    M[101,i]=S
M[100,100]=2**250/n
M[101,101]=2**250
v=M.LLL()[1]
sk=int(v[-2]*n/(2**250))
c=base64.b64decode(c)
key = hashlib.sha256(long_to_bytes(sk)).digest()
cipher = AES.new(key, AES.MODE_ECB)
print(cipher.decrypt(c))
posted @ 2022-03-22 21:47  hash_hash  阅读(256)  评论(0)    收藏  举报