[Geek Challenge 2022] crypto部分

news2024/11/28 8:38:58

这个比赛是一个网友让我看看的,这个比赛很有意思,crypto题全是百度网盘,pwn题全是谷歌网盘,这样我这pwn题就基本over了。还好这些crypto都不怎么难,都答出来了。最后成绩到10名了。

w_or_m?

第1个50分的题,还真不会,看来看去,由于flag头是SYC{所以可以找到一些线索We后是间隔3字符,前边(右边)是间隔4字符,看上去就是栅栏,根据字符猜就是welcome,然后猜第2行,与第1行方向相反。经网友提示是Rail Fence就是一种特殊的栅栏,前边被题目的说明zigzag误导了。这个好像真没啥关系。

0_cmdo1elfe_2_}WtoC!{0mr!C__7!YtepoS34
  ^   ^   ^    ^    ^    ^    ^    ^    <---从右向左
  c   1   e    W    {    C    Y    S    
0  m   e   _    t    0    _    t    3   <---从左向右
    d   l   2    o    m    _    e       <---右向左
 _   o   f   _    C    r    7    p   4
               }   !    !    !    o

正确的应该解法是

(1)倒序
'0_cmdo1elfe_2_}WtoC!{0mr!C__7!YtepoS34'[::-1]
'43SopetY!7__C!rm0{!CotW}_2_efle1odmc_0'

(2)cyberchef->Rail Fence Cipher Decode
Key:9
Offset:27
}!!!o4p7rC_fo_dl2om_e3t_0t_em0c1eW{CYS

(3)倒序
'}!!!o4p7rC_fo_dl2om_e3t_0t_em0c1eW{CYS'[::-1]
'SYC{We1c0me_t0_t3e_mo2ld_of_Cr7p4o!!!}'

 

ez_classic

题目给了个摩尔斯电码

-../.-../.-./---/.--/---/-/.--./-.--/.-./-.-./---/.-../.-.././....

解码后再反过来

dlrowotpyrcolleh
SYC{hellocryptoworld}

definitely ez RSA

一个标准的小指数攻击题e=6,m很小n很大

from Crypto.Util.number import *
import libnum

flag = b'****hidden_message****'
p = getPrime(512)
q = getPrime(512)
n = p * q
e = 6
m = libnum.s2n(flag)
c = pow(m,e,n)
print(c)
print(n)

'''
*****************************************************
c = 50072006338339389555118552154159240037219794211505206943873038914830972293138548550568229783754227896661905769853250134014183574039535969574789925550365619292404703617997980492432173682029840923107651199593049684918577536870537471401209938966780904496397505606866028917883152417396458811357069626629334483341
n = 147194403642833538539720995718314310463580322118979932658805936518215523735242613107271741138837389303135352865058107054820876285524238471152015504027014461168105771913435200522726300893493981125032256531337768716089003105857799620333243431585087621669813946444872568719527503184655024233193716871553607529747
*****************************************************
'''

解法就是直接开根号,不够开就加个n,因为6次一般情况不会溢出多少。

from gmpy2 import iroot

c = ...
n = ...

while True:
    v,k = iroot(c,6)
    if k:
        print(bytes.fromhex(hex(int(v))[2:]))
        break
    c +=n	
#SYC{0ops_y0u_f1Nd_m3!}
'''
R.<x> = PolynomialRing(Zmod(n))
f = x^6 - c 
f.monic()
f.roots()
'''

 

Pairs

给了一个密文:3tl2nv2zl2zl2zl4pg6gh5tr2z76kf2nt5zc56a6w0

一共42字节,也要放到网盘上。有提示:hint: My twin brother send me a message.Can you decrypt it? 1、 Alice and Bob are twins of Hex

一个twin-hex加密,直接找网站解

StarterRSA

又一个rsa的题,仅给了n,c,e但明显n非常小,可以直接分解

n= 69984814757288857831977509185208500866724771756561629279687819301222483218728663
e= 65537
c= 67672845063517415442486175096448664617581579564885311842326107871805595697454701

经过分解发现p是一个小因子,直接解rsa

from gmpy2 import *
from Crypto.Util.number import long_to_bytes

n= 69984814757288857831977509185208500866724771756561629279687819301222483218728663
e= 65537
c= 67672845063517415442486175096448664617581579564885311842326107871805595697454701

p = 733
q = 95477237049507309456995237633299455479842799122185033123721445158557275878211
phi = (p-1)*(q-1)
d = invert(e, phi)
m = pow(c,d,n)
print(long_to_bytes(m))

#SYC{5t4rt_R5A_ls_1t_3a5y?}

 

Blind

还是个rsa题,题目有点长,先是加密m得到c但n没有给出,后边两个paper提示是对p,q分别进行的rsa加密

flag = b'xxxxxx'
p = getPrime(1024)
q = getPrime(1024)
m = bytes_to_long(flag)
n = p*q
e = 65537
c = pow(m,e,n)
print('c={}'.format(c))

p1 = getPrime(1024)
q1 = getPrime(1024)
n1 = p1*q1
e1 = 65537
assert gcd(e1,(p1-1)*(q1-1)) == 1
c1 = pow(p,e1,n1)
print('n1={}'.format(n1))
print('c1={}'.format(c1))
hint1 = pow(2022 * p1 + q1, 222222, n1)
hint2 = pow(2023 * p1 + 232323, q1, n1)
print('hint1={}'.format(hint1))
print('hint2={}'.format(hint2))

p2 = getPrime(1024)
q2 = getPrime(1024)
n2 = p2*q2
e2 = 65537
assert gcd(e1,(p2-1)*(q2-1)) == 1
c2 = pow(q,e2,n2)
hint3 = pow(2022 * p2 + 2023 * q2, 222222, n2)
hint4 = pow(2023 * p2 + 2022 * q2, 232323, n2)
print('n2={}'.format(n2))
print('c2={}'.format(c2))
print('hint3={}'.format(hint3))
print('hint4={}'.format(hint4))

这种曾经作过类似的也就没有难度了。第一步先对q1取模得到仅含p1的两个算式,将p1约掉后得到q1,再与n1取公约数得到q1,然后解Rsa得到p

#p 
t1 = hint1 * pow(2022, -222222, n1) % n1 
t2 = (hint2 - 232323) * pow(2023,-1, n1) % n1 
q1 = gcd(t1 - pow(t2, 222222, n1) , n1)
p1 = n1//q1 
phi1 = (p1 - 1)* (q1 - 1)
d1 = invert(e, phi1)
p = pow(c1, d1, n1)
print(f'p = {p}')

 第2步同理得到q

#q  
t3 = pow(hint3 * pow(2023, -222222, n2),232323,n2)
t4 = pow(hint4 * pow(2022, -232323, n2),222222,n2)
p2 = gcd(t3-t4, n2)
q2 = n2//p2 
phi2 = (p2-1)*(q2-1)
d2 = invert(e, phi2)
q = pow(c2, d2, n2)
print(f'q = {q}')

最后由p,q得到m

n = p*q 
phi = (p-1)*(q-1)
d = invert(e, phi)
flag = pow(c,d,n)
print(long_to_bytes(flag))

#The_key_I_am_white_Please_continue_decryting

 这时候还没完,flag.txt是维吉尼亚加密的,得到的是key:iamwhite,到网站上在线解得到

#Key:iamwhite
#密文(flag.txt文件): ayo{2ek_g0n_v3i11y_4ujk_bai_zisda_ig5amr}
#SYC{2dz_y0a_s3a11y_4iiz_tnf_rigcp_at5xer}

link_start

又是一个rsa,两个m分别是m加上两个padding得到的,而padding已知,所以这个用关联信息

from Crypto.Util.number import *
flag = b'xxxxxxxxxx'
m = bytes_to_long(flag)
e = 3
p = getPrime(256)
q = getPrime(256)
n = p * q
pad1 = 105932791230388043786415766547423404991945041940365436758701967602353965252168
pad2 = 927899423531845853332048235055407925992275378422616390929
m1 = m + pad1
m2 = m + pad2
c1 = pow(m1,e,n)
c2 = pow(m2,e,n)
print("c1 =",c1)
print("c2 =",c2)
print("n =",n)
 
 
'''
c1 = 3720637940274958886432460233359341402765303073408436397771852426914390218432084755791424796944302399361378059153348441733368574505589165431342734218087692
c2 = 1857483070190148986251195374434228339562792548542508665250465210130431058280559201968992393617573644598954953409645690993451979549050973992242158354491780
n = 5106069782765072129956779902712742815006764735937158686628819801242945179548793829832666946413859309545558089370129318039174135569850663668730057188261837
'''

这个关联信息攻击有模板,只当个搬运工。

def related_message_attack(c1,c2, di, e,n):
    from Crypto.Util.number import GCD
    #展开(x+a)^e的系数,杨辉三角
    def poly_coef(a, e):
        assert e >= 0
        if e == 0:
            return 1
        elif e == 1:
            return [1,1]
        else:
            res = [1]
            coe_prev = poly_coef(a, e-1)
            for i in range(len(coe_prev)-1):
                res.append(sum(coe_prev[i:i+2]))
            res.append(1)
            return res

    def poly_extend(a, e, n,c):
        coef = poly_coef(a, e)
        res = [a**i * coef[i] for i in range(len(coef))]

        res[-1] = res[-1] + c
        res = [x%n for x in res]

        return res
        
    #化首1
    def poly_monic(pl,n):
        from gmpy2 import invert
        for p in pl:
            if p!=0:
                inv = invert(p,n)
                break
        return [int((x*inv)%n) for x in pl]

    #模运算,这部分写的不是很好,待优化
    def poly_mod(pl1,pl2,n):
        from functools import reduce
        assert len(pl1) == len(pl2)
        pl1 = poly_monic(pl1,n)
        pl2 = poly_monic(pl2,n)
        for i in range(len(pl1)):
            if pl1[i] > pl2[i]:
                break
            elif pl1[i] < pl2[i]:
                return poly_mod(pl2,pl1,n)
        else:
            return 0
        idx = -1
        for i in range(len(pl1)):
            if pl1[i] == 1:
                idx = i
                break
        for i in range(idx,len(pl2)):
            if pl2[i] == 1:
                pl2 = pl2[:idx] + pl2[i:]
                pl2 += [0]*(len(pl1)-len(pl2))
                break
        
        res = []
        for i in range(len(pl1)):
            if pl2[i] == 0:
                res.append(pl1[i])
            else:
                res.append(pl1[i]-pl2[i])
        
        res = [int(x%n) for x in res]
        g = int(reduce(GCD,res))
        if g > 1:
            res = [x//g for x in res]
        return res
    #最大公因式
    def poly_gcd(pl1,pl2,n):
        while pl2 != 0:
            pl1,pl2 = pl2, poly_mod(pl1,pl2,n)
        pl1 = poly_monic(pl1,n)

        return pl1

    #x^e-c1
    #(x+di)^e-c2
    pl1 = poly_extend(0,e,n,-c1)
    pl2 = poly_extend(di,e,n,-c2)

    pl_d = poly_gcd(pl1,pl2,n)

    #求得(x-m),所以取负数即为m
    m = n - pl_d[-1]
    return m

x = related_message_attack(c1, c2, pad2-pad1, e, n)
bytes.fromhex(hex(x-pad2)[2:])
#SYC{1_c4n_d0_th15_a1l_d@y}

 

Long_But_Short

终于走出rsa了,这里给出了q=p+1然后c = (m+p)**q %p 

from Crypto.Util.number import *
from secret import flag
flag = bytes_to_long(flag)

p = getPrime(1024)
q = p+1
assert flag**2 < p
a = pow(flag+p, q, p)

print('p=',p) 
print('a=',a)

'''
p= 132485702522161146757217734716447479208806639208543182360084149642567339473293168036770464973129405874692085101982109256055320486303869520189058357502693388509190430447787056423080714947904812339604787610679547711291646116182650401371922642011766279740399192613052280061981102203595808184804858315094410004923
a= 1718205151527213531940354061216609955728503626623437131525315244599535856595391286686273033612529023037466615611832668265075325829196053041494716601943531710744433426780718569225
'''

根据费马小定理,先把这个q分成p-1+2,将p-1去掉,后边就剩个开平方了,模p的话flag+p=flag

long_to_bytes(iroot(a,2)[0])
#SYC{7ca905c9dbba1ffe7ff0ee3ee93f1ac1}

 

just lcg

这题目很长很长,但一看也没内容,已经一个很普通的式子运算

import signal
import socketserver
import os
import string, random
from hashlib import sha256
from secret import flag
 
num = 1000
 
class Task(socketserver.BaseRequestHandler):
    def _recvall(self):
        BUFF_SIZE = 2048
        data = b''
        while True:
            part = self.request.recv(BUFF_SIZE)
            data += part
            if len(part) < BUFF_SIZE:
                break
        return data.strip()
 
    def send(self, msg, newline=True):
        try:
            if newline:
                msg += b'\n'
            self.request.sendall(msg)
        except:
            pass
 
    def recv(self, prompt=b'[+]'):
        self.send(prompt, newline=False)
        return self._recvall()
 
    def close(self):
        self.send(b"Remember to solve me later~")
        self.request.close()
 
    def cal(self):
        from Crypto.Util.number import getRandomNBitInteger
        k = 2753645094
        n = 17968909282851700307
        c = getRandomNBitInteger(56)
        a = getRandomNBitInteger(36)
        b = (a * k + c) % n
        self.send(b'[+] k = ' + str(k).encode())
        self.send(b'[+] n = ' + str(n).encode())
        self.send(b'[+] a = ' + str(a).encode())
        self.send(b'[+] b = ' + str(b).encode())
        self.send(b'[+] b = (a * k + c) % n')
        self.send(b'Please give me c:')
        return self.recv(prompt=b'[+] c = ').decode() == str(c)
 
    def handle(self):
        for turn in range(num):
            if not self.cal():
                self.send(b"It's wrong. Please try again!")
                return
            else:
                self.send(b'Good job!')
        self.send(b'the encflag is = ' + str(flag).encode())
 
 
 
class ThreadedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass
 
 
class ForkedServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
    pass
 
 
if __name__ == "__main__":
    HOST, PORT = '0.0.0.0', 80
    server = ForkedServer((HOST, PORT), Task)
    server.allow_reuse_address = True
    server.serve_forever()

因为不知道它什么时候结束,只能读到爆为止

from pwn import *

p = remote('124.71.215.231', 2223)
context.log_level = 'debug'
def aaa():
    k = eval(p.recvline().split(b' = ')[1])
    n = eval(p.recvline().split(b' = ')[1])
    a = eval(p.recvline().split(b' = ')[1])
    b = eval(p.recvline().split(b' = ')[1])
    print(k,n,a,b)
    c = (b - a*k)%n
    p.sendlineafter(b'[+] c = ', str(c).encode())
    res = p.recvline()
    return b'Good' in res

while True:
    aaa()
    
'''
[DEBUG] Received 0x92 bytes:
    b'[+] k = 2753645094\n'
    b'[+] n = 17968909282851700307\n'
    b'[+] a = 67398904367\n'
    b'[+] b = 5963091574066878625\n'
    b'[+] b = (a * k + c) % n\n'
    b'Please give me c:\n'
    b'[+] c = '
2753645094 17968909282851700307 67398904367 5963091574066878625
[DEBUG] Sent 0x12 bytes:
    b'59522051419156197\n'
[DEBUG] Received 0x4f bytes:
    b'Good job!\n'
    b"the encflag is = b'U1lDezEwMDBfTENHX0BuZF95MHVfa24wd18zaGVfZjFAZ30='\n"
'''

Anime picture

一个非常长的程序

from PIL import Image
from Crypto.Util.number import *
from numpy import array, zeros, uint8
from random import randint
from secret import x,y
import cv2
import hashlib
import gmpy2

def gen_key(a,b):
    key = ''
    for i in range(len(a)):
        if a[i] >= '1' and a[i] <= '9':
            key += '0'
        else:
            key += '1'
    for j in range(len(b)):
        if b[j] >= '1' and b[j] <= '9':
            key += '1'
        else:
            key += '0'
    return key

def add(n):
    s = 0
    for i in range(0,len(n),2):
        s += int(n[i])
    return s

image = cv2.imread("flag.jpg")
img_array = array(image)
dim1 = len(img_array)
dim2 = len(img_array[0])
dim3 = 3
count = 0
a = randint(1,2**64)
b = randint(1,2**64)

assert a * x + b * y == gmpy2.gcd(a, b)
tmp_1 = hashlib.md5(str(x).encode('utf-8')).hexdigest()
tmp_2 = hashlib.md5(str(y).encode('utf-8')).hexdigest()
key = gen_key(tmp_1,tmp_2)

for i in range(len(key)):
    if key[i] == '1':
        count += 1
    else:
        continue

s = add(key)
enc_img = zeros(shape=[dim1, dim2, dim3], dtype=uint8)
for t in range(0,count):
    for i in range(0, dim1):
        for j in range(0, dim2):
            for k in range(0, dim3):
                enc_img[i][j][k] = (img_array[i][j][k] ^ (s + int(key)%3))
            s += 3

enc_array = Image.fromarray(enc_img)
enc_array.show()
enc_array.save("encflag.jpg")
print("a = ",a)
print("b = ",b)


'''
a = 12071216147395236101
b = 12613118707743158458
'''

题目长到不想看,就是把一个东西加密成写成图片,其实这跟图也没啥关系就是个数据。因为前边有md5然后再把数据变成01也基本不可逆。唯一办法就是爆破,不过对于jpg图来说,差点也没关系,大概能看出来就行,眼的容错率很高

from PIL import Image
from Crypto.Util.number import *
from numpy import array, zeros, uint8
import cv2
import hashlib
import gmpy2

'''
tmp_1 = hashlib.md5(str(x).encode('utf-8')).hexdigest()
tmp_2 = hashlib.md5(str(y).encode('utf-8')).hexdigest()
key = gen_key(tmp_1,tmp_2)

for i in range(len(key)):  #根据key计算count MD5 64位16进制 count<128
    if key[i] == '1':
        count += 1
    else:
        continue

s = add(key)
enc_img = zeros(shape=[dim1, dim2, dim3], dtype=uint8)
for t in range(0,count):
    for i in range(0, dim1):
        for j in range(0, dim2):
            for k in range(0, dim3):
                enc_img[i][j][k] = (img_array[i][j][k] ^ (s + int(key)%3))
            s += 3
'''

image = cv2.imread("encflag.jpg")
img_array = array(image)
dim1 = len(img_array)
dim2 = len(img_array[0])
dim3 = 3

#s<64
ps = 0
for key_3 in range(1):
    for count in range(128):
        for s in range(64):
            ps = s
            enc_img = zeros(shape=[dim1, dim2, dim3], dtype=uint8)
            for t in range(0,count):
                for i in range(0, dim1):
                    for j in range(0, dim2):
                        for k in range(0, dim3):
                            enc_img[i][j][k] = (img_array[i][j][k] ^ (s + key_3))
                        s += 3
            enc_array = Image.fromarray(enc_img)
            enc_array.save(f"./img/f{key_3}_{count}_{ps}.jpg")

#SYC{not_n1c0_Nico_n1_1t_i5_l0velive}

 这个程序会生成很多图片,每过一段就会越来越清楚,比较清楚的就能看到flag

 

Crypto1957

最后几个题干脆名字都没有了。这个把flag与密文异或

from Crypto.Util.number import * 
from flag import flag 

key = bytes_to_long(flag) 
f = open('message.txt','r').read().split('\n')
cipher = open('cipher.txt','w') 
for i in f: 
    i = bytes_to_long(i.encode()) 
    c = i ^ key 
    cipher.write(hex(c)[2:]+'\n') 
cipher.close()

好像也没有好办法,前一段作一题叫snake就是一个个字母猜,开头有4个已知SYC{拿这个异或后得到一堆数据

0 b'The '
1 b'd by'
2 b'cord'
3 b' by '
4 b'sinc'
5 b' if '
6 b'5 de'
7 b'rota'
8 b'e el'
9 b'put '
10 b'ol s'
11 b'le f'
12 b' its'
13 b' is '
14 b'd as'
15 b'"lea'
16 b'ying'
17 b' in '
18 b'et w'
19 b'f th'
20 b'four'
21 b' tar'
22 b'n an'
23 b' fro'
24 b' mis'
25 b'ngle'
26 b'ptio'
27 b' ang'

 这里可以猜的字符很多,比如19行猜是the,14行后边可能是空格,这样用程序辅助一个个猜。单词猜中的面还是比较大的,而且越往后越容易。

c = open('cipher.txt','r').read().split()
a = [bytes.fromhex(i) for i in c[:-1]]
#print(a)
flag = b'SYC{' #b'SYC{A1m9_1nfr4r3d_guid4nc3}'
flag+= bytes([a[19][len(flag)]^ord('e')])
print(flag)
for i,v in enumerate(a):
    print(i, bytes([v[j]^flag[j] for j in range(len(flag))]))

Crypto20xx

给了c和一个缺两位的公钥

-----BEGIN PUBLIC KEY-----
MC??DQYJKoZIhvcNAQEBBQADGwAwGAIRAIO444FSJFXBf/yDN67IcCMCAwZpnQ==
-----END PUBLIC KEY-----

c = 85806005072257465677925369913039323947  

因为就差两位,基本上就等于直接给了,爆破出来就行,而且公钥非常小,很容易分解

 

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP
from Crypto.Util.number import long_to_bytes
from gmpy2 import invert

a = 'MC??DQYJKoZIhvcNAQEBBQADGwAwGAIRAIO444FSJFXBf/yDN67IcCMCAwZpnQ=='

b64s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'

for i in b64s:
    for j in b64s:
        c = a[:2]+i+j+a[4:]
        kstr = "-----BEGIN PUBLIC KEY-----\n"+c+"\n-----END PUBLIC KEY-----\n"
        try:
            f = kstr.encode()
            pub = RSA.importKey(f)
            print('n,e=',pub.n,',',pub.e)
        except:
            pass 

c = 85806005072257465677925369913039323947             
n,e= 175088864422629078008785584658147995683 , 420253
p = 12865536769562115787
q = 13609137928614252809
phi = (p-1)*(q-1)
d = invert(e,phi)
m = pow(c,d,n)
print(long_to_bytes(m))
#Panzer_Vor!
#SYC{Panzer_Vor!}  

Crypto1976

这个题给了个远程,就是算 e=(r*h+p)%q 的p,其中e,h,q已知

import signal 
from Crypto.Util.number import *
import gmpy2 as gp 
import random 
import hashlib 
from secret import flag 
 

def gen(self,bound):
    q=getPrime(bound)
    bound1=int(gp.iroot(q//2,2)[0])
    bound2=int(gp.iroot(q//4,2)[0])
    while True:
        f,g=random.randint(1,bound1),random.randint(bound2,bound1)
        if gp.gcd(f,q*g) == 1 :
            break
    h=(gp.invert(f,q)*g)%q
    return q,h,f,g 
 
def gen_m(self,bound):
    p=getPrime(gp.iroot(bound//4,2)[0])
    p_=long_to_bytes(p)
    hash=hashlib.md5()
    hash.update(p_)
    return p,hash.hexdigest() 
 
def dec(self,e,f,g,q):
    a=f*e%q 
    b=gp.invert(f,g)*a%g 
    return b 
 
def check(self,rec,hash):
    hash_=hashlib.md5()
    hash_.update(rec) 
    if hash == hash_.hexdigest():
        return 1
    else:
        return 0
 
 
 
 
signal.alarm(60)
bound=1024
f=1
for i in range(50):
    q,h,f,g=gen(bound)
     
    p,hash=gen_m(bound)
    r=getPrime(bound//2)
    e=(r*h+p)%q     
    print(b'q= '+f'{q}'.encode()+b'\n'+b'h= '+f'{h}'.encode()+b'\n'+b'e= '+f'{e}'.encode()+b'\n')
 
    rec = input(b'Input md5 p: ')
    if rec.decode() == hash:
        print(b'YES!')
        continue
    else:
        print(b'NO!')
        f=0
        break
if f :
    print(flag) 

这个题是一个很标准的NRTU,也就是求最短向量问题(SVP),先前存了个模板,直接套就行了。

from pwn import *
import hashlib
from Crypto.Util.number import long_to_bytes

io = remote('124.71.215.231', 1145)
context.log_level = 'debug'

def get_v():
    #c = rh + m mod p
    p = eval(io.recvline().split(b'= ')[1])
    h = eval(io.recvline().split(b'= ')[1])
    c = eval(io.recvline().split(b'= ')[1])
    print(p,h,c)
    M = matrix(ZZ, [[1,h],[0,p]])
    f,g = shortest_vector = M.LLL()[0]
    if f<0:
        f = -f 
    if g<0:
        g = -g

    a = f*c % p % g
    m = a * inverse_mod(f, g) % g
    print('m = ', m)
    hs = hashlib.md5()
    hs.update(long_to_bytes(m))
    v = hs.hexdigest()
    print('v = ', v)
    io.sendlineafter(b'Input md5 p: ', v.encode())
    io.recvline()

for i in range(50):
    get_v()

print(p.recvline())

 

Crypto1985

这题以前没遇到过LWE问题有提示,网友给了搜到的贴子

from Crypto.Util.number import * 
import gmpy2 as gp 
from secret import flag
m = 132
n = 400
p = 3
q = 2^20

def gen_mat():
  return matrix(ZZ, [[q//2 - randrange(q) for _ in range(n)] for _ in range(m)])


rp,rq = getPrime(m*3),getPrime(400)   
sp,sq = bin(rp)[2:] ,bin(rq)[2:]
A, B, C = gen_mat(), gen_mat(), gen_mat()

x = vector(ZZ, [int(sp[i]) for i in range(0,m)])
y = vector(ZZ, [int(sp[i]) for i in range(m,2*m)]) 
z = vector(ZZ, [int(sp[i]) for i in range(2*m,3*m)]) 
e = vector(ZZ, [int(i) for i in sq]) 
c = x*A+y*B+z*C+e


flag = bytes_to_long(flag) 
n = rp * rq 
re=65537 
h = gp.powmod(flag,re,n) 


print('A = \n',A)
print('B = \n',B) 
print('C = \n',C)
print('c = ',c)
print('h = ',h)
print('n = ',n)

#

把p(396位)分成3段,分别乘上个随机矩阵,然后加一起再加上q,这里q分成位0和1,对于LWE就是那个误差,解法直接套。p这396位先合到一起,组成矩阵,ABC合到一起,求出误差e来取前400位就是q

from text import *

#A,B,C,c
M = matrix(ZZ, 0, 400)

for t in [A,B,C]:
    for r in t:
        M = M.stack(vector(r))

c = matrix(ZZ, c)

# c = X*M + e
z = matrix(ZZ, [0 for _ in range(396)]).transpose()
beta = matrix(ZZ, [1])
T = block_matrix([[M, z], [matrix(c), beta]])

L = T.LLL()
print(L[0])

#e = (1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1)
q = int(''.join([str(i) for i in L[0][:400]]), 2)
p = n//q
m = pow(h,inverse_mod(65537,(p-1)*(q-1)),n)
print(bytes.fromhex(hex(m)[2:]))
#{afb65e240bf2b8c5d67756967e2ec2d6}
#SYC{afb65e240bf2b8c5d67756967e2ec2d6}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/26846.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

股票level2接口-API程序化文档说明

股票level2接口-API程序化文档说明&#xff0c;新手在API程序化上跟随老手进行。这是一种新的模式&#xff0c;适合那些想要而不知道如何投资正确项目的人。 股票level2接口TickRecord 逐笔说明&#xff08;部分&#xff09; 现在网络发展&#xff0c;使用组也很常见&#xff…

Html代替<iframe>标签的三种方法<object>, <embed>和<video>

背景 某平台对iframe标签做了些许限制但是前端代码有bug导致提交不了代码, 最开始想着是不是能够在本地替换js文件从而绕过bug 简单搜索后找到了 chrome浏览器F12调式&#xff0c;修改替换js文件这篇博客, 简单试了下虽然能替换成功但是效果不理想, 改不了平台就只能适应平台了…

mysql日志持久化机制

文章目录前言binlog的持久化机制redo log 的持久化机制组提交MySQL的io瓶颈性能优化总结前言 之前的文章介绍过&#xff0c;mysql 的日志是保证数据恢复的关键。那么日志肯定是要持久化到磁盘的&#xff0c;不然也会出现断电或者重启丢失的问题。那么接下来&#xff0c;我们将…

哈佛大学:三个简单的方式,患癌风险降低60%以上

癌症是全球主要的公共卫生问题&#xff0c;近年来&#xff0c;由于饮食、环境、人口的老龄化等因素&#xff0c;全球癌症发病率不断增长&#xff0c;癌症作为主要死因的情况日益突出。根据国际癌症研究机构&#xff08;IARC&#xff09;发布的2020年全球最新癌症数据&#xff0…

求斐波那契数(递归,非递归)

目录 一、斐波那契数&#xff1f; 二、递归实现求第n个斐波那契数 2.1代码与运行结果 2.1.1图解递归过程 三、非递归求法 3.1为什么不用递归求法 3.2非递归 一、斐波那契数&#xff1f; 它指的是这样的数列&#xff1a;1&#xff0c;1&#xff0c;2&#xff0c;3&#xff0…

【附源码】计算机毕业设计JAVA智能社区管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; Springboot mybatis Maven Vue 等等组成&#xff0c;B/…

安泰测试-信号发生器常见的故障与解决方法

信号发生器是一种能提供各种频率、波形和输出电平电信号的设备。在测量各种电信系统或电信设备的振幅特性、频率特性、传输特性及其它电参数时&#xff0c;以及测量元器件的特性与参数时&#xff0c;用作测试的信号源或激励源&#xff0c;经常和示波器是老搭档&#xff0c;也是…

三菱FX3U——ST编程流水灯

当D0的默认值为0时&#xff0c;赋值1&#xff1b; TON_1每隔1秒触发输出M1&#xff0c;M1触发D0左移一位&#xff0c;D0的值相当于每1秒乘以2&#xff1b; 在通过M1复位定时TON_1; 每一秒使一个输出得电&#xff0c;当D0的值不在选项内的值&#xff0c;将D0赋值为0&#xff1…

无序和混乱终结者,极狐GitLab Workflow 到底有什么魔力?

效率和质量是软件产品追求的两个核心关键点&#xff0c;软件产品研发是一个覆盖多阶段、涉及多团队的过程&#xff0c;业界也已经总结出了一些很好的实践&#xff0c;在保证研发效率的同时还能保证代码质量。比如代码提交规范、Code Review、代码准入、CI/CD。 但是由于缺乏行之…

冒死开源。阿里新产Spring Boot+Spring Cloud微服务开发实战笔记

昨天跟粉丝聊到了一个问题&#xff0c;他说现在很多招聘要求需要有微服务经验&#xff0c;本人目前生产上没有微服务经验&#xff0c;该如何弥补&#xff1f; 小编在这儿就分享一份学习资料&#xff0c;这份资料既是初学者学习微服务开发的技术宝典&#xff0c;又是中级开发人…

不同版本的谷歌浏览器跨域怎么设置?

由于项目前端使用8001端口&#xff0c;后端使用的8080端口&#xff0c;因此前端调用后端接口时需要跨域&#xff0c;在浏览器中需要设置跨域&#xff0c;否则会由于跨域安全性导致请求失败。 一. 浏览器版本大于49 1.在chrome中&#xff0c;需要新建一个chrome浏览器的快捷方…

HiveSQL分位数函数percentile()使用详解+实例代码

前言 作为数据分析师每个SQL数据库的函数以及使用技能操作都得点满&#xff0c;尤其是关于统计函数的使用方法。关于统计出数据的中位数&#xff0c;众数和分位数的方法必须掌握几种&#xff0c;一般在实际业务上大部分都是以写SQL查询为主&#xff0c;因为如果想用Python的Pa…

植物大战僵尸变态辅助开发系列教程(E语言实现和VC6实现)(下)

植物大战僵尸变态辅助开发系列教程&#xff08;E语言实现和VC6实现&#xff09;&#xff08;下&#xff09;36、全屏秒杀37、秒杀实现37、PVZ聚怪38、种植CALL的查找与调用39、OpenProcess错误40、错误&#xff1a;constchar[19]”转换为“LPCWSTR”附录&#xff1a;36、全屏秒…

opencv的相机校准和3D建模的理论知识

一、相机标定的四个坐标系 1、世界坐标系&#xff08;Xw&#xff0c;Yw&#xff0c;Zw)&#xff1a;也称真实或现实世界坐标系&#xff0c;或全局坐标系。它是客观世界的绝对坐标&#xff0c;由用户任意定义的三维空间坐标系。一般的3&#xff24;场景都用这个坐标系来表示。 …

SSM框架使用多数据源(druid连接池)

最近有个数据归集的需求用到了多数据源&#xff0c;在业务库保存后同时向归集库插入或数据。之前好像还没做过这块的东西&#xff0c;简单记录下防止下次又忘记了~ 踩过的几个坑都是某些知识点不熟悉导致的&#xff0c;而且都是框架配置相关的.. 先上代码&#xff0c;再扯淡 …

PyQt5 拖拽与剪贴板

拖拽与剪切板拖拽剪贴板拖拽 基于MIME类型的拖拽数据传输时基于QDrag类的QMimeData对象管理的数据与其对应的MIME类型相关联。 MimeData类函数允许检测和使用方法的MIME类型 判断函数设置函数获取函数MIME类型hasText()text()setText()text/plainhasHtml()html()setHtml()tex…

【Java八股文总结】之SpringBoot

文章目录SpringBoot1、Spring Boot的优点&#xff1f;2、Spring Boot自动配置原理3、如何定义一个SpringBoot Starter&#xff1f;4、SpringBoot启动原理&#xff1f;5、SpringBoot的常用注解Spring Cache1、Spring Cache介绍2、Spring Cache注解Sharding-JDBCSpringBoot 1、S…

关于vector的迭代器失效

目录 关于迭代器失效的判定 1 迭代器指向的位置是野指针&#xff08;全部迭代器失效&#xff09; 原因&#xff1a; 解决 2 erase或者insert之后迭代器被更改了&#xff08;部分迭代器失效&#xff09; 原因 迭代器失效的场景&#xff1a; 改进之后 部分迭代器失效之越…

十年前的AlexNet,今天的NeurIPS 2022时间检验奖

目录&#xff1a;十年前的AlexNet&#xff0c;今天的NeurIPS 2022时间检验奖一、前言二、时间检验奖一、前言 作为当前全球最负盛名的 AI 学术会议之一&#xff0c;NeurIPS 是每年学界的重要事件&#xff0c;通常在每年 12 月举办。大会讨论的内容包含深度学习、计算机视觉、大…

三款“非主流”日志查询分析产品初探

前言 近些年在开源领域&#xff0c;用于构建日志系统的软件有两类典型&#xff1a; Elasticsearch&#xff1a;基于 Lucene 构建倒排索引提供搜索功能&#xff0c;DocValue 存储支持了其统计分析能力。Clickhouse&#xff1a;列式存储是其优秀 OLAP 性能的保障。 这里把上述系…