naby

导航

SHCTF2024-week3-Crypto

博客做题法,除了最简单那题,其他都是偷的,lock等以后有机会再补把

太难了(哭

Crypto

babyLCG

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

seed = bytes_to_long(flag)

a = getPrime(400)
b = getPrime(400)
p = getPrime(400)
c = []
for i in range(3):
    seed = (seed*a+b)%p
    c.append(seed>>80)
print(f'a = {a}')
print(f'b = {b}')
print(f'p = {p}')
print(f'c = {c}')

想不出来,使劲偷。

参考文献LCG | DexterJie'Blog

(这已经不是参考了,原原又版版啊)

我们有:

\[H_2+L_2=a(H_1+L_1)+b\mod p\\ L_2=aL_1+(aH_1+b-H_2)\mod p\\ \]

\(A_1=a,B_1=(aH_1+b-H_2)\mod p\)

继续推导有:

\[H_3+L_3=a(H_2+L_2)+b\mod p\\ L_3=aL_2+(aH_2+b-H_3)\mod p\\ 将上面L_2,带入得:\\ L_3=a^2L_1+a(aH_1+b-H_2)+(aH_2+b-H_3)\\ \]

\(A_2=a^2,B_2=(aB_1+(aH_2+b-H_3))\mod p\)

所以我们有一般式

\[L_{i+1}=A_iL_1+B_i\mod p\\ A_i=a^i\mod p\\ B_i=aB_{i-1}+(aH_i+b-H_{i+1})\mod p \]

我们构造格

\[L=\left( \begin{matrix} p & 0 & 0 & 0\\ 0 & p & 0 & 0\\ A_1 & A_2 & 1 & 0\\ B_1 & B_2 & 0 & 1\\ \end{matrix} \right)\\ (k_1,k_2,L_1,1)L=(L_2,L_3,L_1,1)\\ 最后为了使目标向量得所有元素大小相同,需要进行配平\\ 让L得最后一行最后一个元素乘上一个K=2^{80}(seed缺失的位数)\\ 最后L=\left( \begin{matrix} p & 0 & 0 & 0\\ 0 & p & 0 & 0\\ A_1 & A_2 & 1 & 0\\ B_1 & B_2 & 0 & K\\ \end{matrix} \right)\\ (k_1,k_2,L_1,1)L=(L_2,L_3,L_1,K)\\ \]

(代码直接抄了)

from Crypto.Util.number import long_to_bytes
a = 2441165060340363548034817419913152429437367671051257983130193376968866003652656064753193540692576823353722522219951236377
b = 2536384599388118977308934726385759683875116193910292140931807458602198040481977699550435249496535909362102559820360131151
p = 1898350626517014951217210423867648293636462375574846448952061608918022029275967066566474923728317050045578381447025802447
c = [1206170611286987749822509820930522025955557233442828617888124729629984583540215838639710785581993, 852222709497386792919622853438477061105763652894458161025475550177341850861286444913870176145661, 1304945544687728464084706289648969970911515894526834307083141183941320491375891396365871606911311]

h = [0] + c

length = len(h)
for i in range(length):
    h[i] <<= 80

A = [1]
B = [0]

for i in range(1, len(h)-1):
	A.append(a*A[i-1] % p)
	B.append((a*B[i-1]+a*h[i]+b-h[i+1]) % p)

A = A[1:]
B = B[1:]



Ge = Matrix(ZZ,length,length)

for i in range(len(A)):
    Ge[i,i] = p
    Ge[-2,i] = A[i]
    Ge[-1,i] = B[i]

K = 2**80
Ge[-2,-2] = 1
Ge[-1,-1] = K

for line in Ge.LLL():
    if abs(line[-1]) == K:
        L1 = line[-2]
        seed1 = h[1] + L1
        seed = (seed1 - b) * inverse_mod(a,p) % p
        print(f"seed = {seed}")
        print(long_to_bytes(seed))

Lattice

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

m = bytes_to_long(flag)
n = getPrime(1024)
x = getPrime(200)
hint = (x*gmpy2.invert(m,n)) % n
print(f'n = {n}')
print(f'hint = {hint}')

\[h=x*m^{-1}\mod n\\ hm=x\mod n\\ m=x*h^{-1}+kn\\ 构造格L=\left( \begin{matrix} 1 & h^{-1}\\ 0 & n\\ \end{matrix} \right)\\ (x,k)L=(x,m)\\ 最后直接输出m,发现不用配平,结束。 \]

说一句我认为构造格最重要的一点,就是让等式的一侧(一般为单个项)为未知的。

from Crypto.Util.number import long_to_bytes
n = 139375501266966354110560987602941579720343298682302380213629012399146702255224092464371860285892594606518682202746469996717869266755804902133065746523678610701447709661598475045236643942670878454454914242366823865911620343171523738762438337620932812380503714497659323917884890957898967721924886002184816388909
hint = 30111064015548195748229136433160596861378053894649564473559454623946601615359833481249637332444935789833334802877702902155500934637824299425212772699568531012251263573286943567743990513595674983034259871038496370389371165018799403318568607201602419538351281864014621535790322463730848699042720151828377672492

h_ni=inverse_mod(hint,n)
L=Matrix(ZZ,[[1,h_ni],
             [0,n]])

L=L.LLL()
print(long_to_bytes(abs(int(L[0][1]))))
#b'SHCTF{1a7t1cE_lS_MADE_Of_LA_tt_1CE_O2}'q

大学×高中√

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

m = bytes_to_long(flag)
assert len(flag)==47
leak = cos(m).n(1000)
print(leak)
# -0.514023686073206542913652284141758854082245379077263654055666061096577058176030971969995601436755843124241044078251685287775109358081348663783038215543924400002063721828036115454284925587327024460032858795786136002614648983181900267223024426488593475898639044647928018383927532133726223655824966624723

之前比赛的题,当时不会,所以直接贴了。

参考文献:第二届黄河流域网络安全技能挑战赛 | DexterJie'Blog

\[leak=cos(m),我们知道三角函数每2k\pi是一个周期,所以我们有\\ m=arccos(leak)+2k\pi\\ 构造格L=\left( \begin{matrix} 1 & 0 & 1\\ 0 & 1 & arccos(leak)\\ 0 & 0 & 2\pi\\ \end{matrix} \right)\\ 有(m,-1,-k)L=(m,-1,0)\\ 显然这个格出不了,需要配平,至于为什么这么配,这个我不知道,就慢慢试出来的。\\ L=\left( \begin{matrix} 1 & 0 & 2^{750}\\ 0 & 2^{375} & arccos(leak)*2^{750}\\ 0 & 0 & 2\pi*2^{750}\\ \end{matrix} \right)\\ 有(m,-1,-k)L=(m,-2^{375},0)\\ \]

from Crypto.Util.number import *

#flag=b'SHCTF{'+b'\x00'*(47-6)
#print(len(bin(bytes_to_long(flag)))-2) # 375


leak = -0.514023686073206542913652284141758854082245379077263654055666061096577058176030971969995601436755843124241044078251685287775109358081348663783038215543924400002063721828036115454284925587327024460032858795786136002614648983181900267223024426488593475898639044647928018383927532133726223655824966624723
acos = arccos(leak)
RR = RealField(1000)
pi = RR(pi)
Ge = Matrix(QQ,[[1,0,2^750],[0,2^375,2^750*acos],[0,0,2^750*2*pi]])
Ge=Ge.LLL()[0]
m = abs(Ge[0])
print(long_to_bytes(int(m)))
#b'SHCTF{arcCo5_LE4RNED_1N_hIGh_5CHoO1_u5Ed_IatER}'

Approximate_n

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

class gen_AGCD():
    def __init__(self):
        self.p = getPrime(512)
        self.q = getPrime(512)

    def enc_(self,M,e):
        C = pow(M,e,self.p*self.q)
        return C

    def re_n(self):
        n = self.p * self.q
        return n

    def re_approximate_n(self):
        k = getPrime(512)
        r = getPrime(247)
        n_approx = k*self.p + r
        return n_approx

if __name__ == '__main__':
    e = 65537
    m1 = flag[:len(flag)//2]
    m2 = flag[len(flag)//2:]
    Encrypt1,Encrypt2 = gen_AGCD(),gen_AGCD()
    C1,C2 = Encrypt1.enc_(bytes_to_long(m1),e),Encrypt2.enc_(bytes_to_long(m2),e)
    N1,N2 = Encrypt1.re_n(),Encrypt2.re_n()

    N1_reveal = []
    for i in range(3):
        N1_reveal.append(Encrypt1.re_approximate_n())

    N2_reveal = Encrypt2.re_approximate_n()

    print('N1 = ',N1)
    print('N1_reveal = ',N1_reveal)
    print('N2 = ',N2)
    print('N2_reveal = ',N2_reveal)
    print('C1 = ',C1)
    print('C2 = ',C2)

第一部分,根据论文https://eprint.iacr.org/2016/215.pdf的第三部分,具体原理我也不懂。(AGCD问题)

\[我们有x_i=k_ip+r_i\\ 构造格L=\left( \begin{matrix} 2^{248+1} & x_1 & x_2\\ 0 & -x_0 & 0\\ 0 & 0 & -x_0\\ \end{matrix} \right)\\ 得(k_0,k_1,k_2)L=(k_02^{248+1},k_0x_1-k_1x_0,k0x_2-k_2x_0)\\ 取第一项除一下得到k_0,直接整除x_0得到p\\ \]

第二部分,偷的鸡块师傅的https://tangcuxiaojikuai.xyz/post/4a67318c.html 第一部分 1.12 12,具体原理还是参考上面那个论文的第五部分,但是这次我连看都看不懂。(ACD问题)

from Crypto.Util.number import *

N1 =  95220181639626796948143489111363011090242644821307671338154270835002234872743806643238045743730383147579107484367700436409496448813817802882720705692308647479031357497697641512864558224737946906678321719550292939790297201774030189554354483674392204774757404512862366152441023131093295296126511526758311787533
N1_reveal =  [135155723555580971102472760772113547068449856046446854944834185144725761315605950196417754719294327893501350155917123418471539586751734839913060001278469803495357936187202804035231480363027024883649894394029336416980140164261450806845325519324810810467082188549167892975300709885928089524964332523979084819616, 108225506327736990488056174532377782531488789170481659195448002422578807037623697635657548142074567159473902317405281775338219092114459739427575748704020302366750567205951022768559028784623405841592241560555854170026194465021522071306555697601208669120660672533978751002577604163682049989736857050431577335988, 97902238601080686791205456188991250567366116257787701998068858649901314188048320624369804248648395722811017072099995983115879965009017127675781815863771820270952769969131391080759752609678760644627826776136946615977348372397823851983199152097271925548232778437840248637945701889965062651061992125582772864886]
N2 =  140467306170270103085247508412489910487748378129459335724515767186097064975754544045630037530915800592540391724032146546032522637400331469533944394808073412880910356816384584939641130518688696505047701134385883270706411370356446043518762317844784816655044013536852156232391544081389664919694551145695399468209
N2_reveal =  112361172352758758900704170210296813010289510849392179799708472107731966956610675285107363588332515564687781269380345968222030537131341680443039011164210540824825702663120697518389091670478368564009900422608869461335061183241377132579449529050747663021748003410091799048984189262111414502180481142308877537330
C1 =  31950452009658012741321403366243455956978705529042164534321777183203324554858632439237234885410149568398983557280801461287159709181598872210801564966331769742332023309821039892558563273355301616744286335388072082262778934580513252668404512993042262043925583364437774382631570617154342054943064279866085770928
C2 =  28043955361950149290736307328827214922496448239701009207491436374533557770205348310700271429655733973145555148184288870618672293135244638728814923159375304575547925591181048341809750424936159673404585158750785837663773658200516125280634048184681727065354159475141953332267189169344585136326725855832157455620

#https://eprint.iacr.org/2016/215.pdf
K=2^249
L=Matrix(ZZ,[[K,N1_reveal[1],N1_reveal[2]],
             [0,-N1_reveal[0],0],
             [0,0,-N1_reveal[0]]])
L=L.LLL()

p1=int(N1_reveal[0]//(abs(L[0][0])//K))
q1=N1//p1
flag1=long_to_bytes(int(pow(C1,inverse_mod(65537,(p1-1)*(q1-1)),N1)))


# https://tangcuxiaojikuai.xyz/post/4a67318c.html 第一部分 1.12 12
#15 [(-271336741980068587844448337263932213024816515815388263122784492996415507, 1)]
#14 [(13863439776247006048821931668679415913595054659189563401850065117344542701, 1)]
r=13863439776247006048821931668679415913595054659189563401850065117344542701
# print(int(r).bit_length())  #243
r=r+2^243*14
p2=GCD(N2,N2_reveal-r)
flag2=long_to_bytes(int(pow(C2,inverse_mod(65537,p2-1),p2)))
print(flag1+flag2)

#b'SHCTF{APPROxiMaTE_n_H4PpY_7hE_NEW_GGag_2_Da}'
"""from tqdm import *
from itertools import *
from multiprocessing import Pool

################################################ gen data
e = 65537
N =  140467306170270103085247508412489910487748378129459335724515767186097064975754544045630037530915800592540391724032146546032522637400331469533944394808073412880910356816384584939641130518688696505047701134385883270706411370356446043518762317844784816655044013536852156232391544081389664919694551145695399468209
m = 1
rho = 243
a = ["pad"] + [112361172352758758900704170210296813010289510849392179799708472107731966956610675285107363588332515564687781269380345968222030537131341680443039011164210540824825702663120697518389091670478368564009900422608869461335061183241377132579449529050747663021748003410091799048984189262111414502180481142308877537330]


def attack(ii):
    a = ["pad"] + [112361172352758758900704170210296813010289510849392179799708472107731966956610675285107363588332515564687781269380345968222030537131341680443039011164210540824825702663120697518389091670478368564009900422608869461335061183241377132579449529050747663021748003410091799048984189262111414502180481142308877537330 - 2^243*ii]

    ################################################ params
    t,k = 20,10
    R = 2^rho
    indices = []
    for i in product([i for i in range(t+1)] , repeat=m):
        if(sum(list(i)) <= t):
            indices.append(["pad"] + list(i))


    ################################################ attack
    PR = ZZ[tuple(f"X{i}" for i in range(m))]
    X = ["pad"] + list(PR.gens())
    poly = []
    monomials=set()
    for i in indices:
        f = 1
        for ij in range(1,len(i)):
            f *= (X[ij] - a[ij])^i[ij]
        l = max(k-sum(i[1:]),0)
        f *= N^l
        poly.append(f)
        for mono in f.monomials():
            monomials.add(mono)


    ################################################# LLL and resultant to find roots
    L = Matrix(ZZ,len(poly),len(monomials))
    monomials = sorted(monomials)
    for row,shift in enumerate(poly):
        for col,monomial in enumerate(monomials):
            L[row,col] = shift.monomial_coefficient(monomial)*monomial(*([R]*m))


    res = L.LLL()
    vec1 = res[0]

    h = 0
    for idx,monomial in enumerate(monomials):
        h += (vec1[idx] // monomial(*([R]*m))) * monomial
    h = h.change_ring(ZZ)
    res1 = h.monic().roots()

    if(res1 != []):
        print(ii,res1)

lists = [i for i in range(2^4)]
with Pool(64) as pool:
    r = list(pool.imap(attack, lists[::-1]))
print(r)
"""

Shamir

from Crypto.Util.number import getPrime,bytes_to_long
import random
from os import getenv

BANNER = """
 __          __  _                            _______       _____ _                     _      
 \ \        / / | |                          |__   __|     / ____| |                   (_)     
  \ \  /\  / /__| | ___ ___  _ __ ___   ___     | | ___   | (___ | |__   __ _ _ __ ___  _ _ __ 
   \ \/  \/ / _ \ |/ __/ _ \| '_ ` _ \ / _ \    | |/ _ \   \___ \| '_ \ / _` | '_ ` _ \| | '__|
    \  /\  /  __/ | (_| (_) | | | | | |  __/    | | (_) |  ____) | | | | (_| | | | | | | | |   
     \/  \/ \___|_|\___\___/|_| |_| |_|\___|    |_|\___/  |_____/|_| |_|\__,_|_| |_| |_|_|_|   
"""
print(BANNER)

flag = getenv("GZCTF_FLAG","GZCTF_NOT_DEFINE")
m = bytes_to_long(flag.encode())
n = getPrime(1024)
coefficients = [m] + [random.randrange(1,n-1) for i in range(100)]
print(f"n = {n}")

def f(x):
    sum = 0
    for i in range(len(coefficients)):
        sum += coefficients[i]*pow(x,i,n) % n
        sum %= n
        
    return sum

while 1:
    x = int(input("Please Input x: "))
    if x == 0:
        print("Not Allowed!!!")
        exit()
    res = (x,f(x))
    print(res)

Shamir门限,我不懂,太难了(哭

直接抄了https://tangcuxiaojikuai.xyz/post/97bbcbc9.html

关键就是需要t个点,然后利用拉格朗日插值法(不懂)

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

r=remote("210.44.150.15",47511)

r.recvuntil(b'n = ')
n=eval(r.recvline().strip().decode())

m=[]
for i in range(1,101+1):
    r.recvuntil(b'Please Input x: ')
    r.sendline(str(i).encode())

    tmp=eval(r.recvline().strip())
    m.append(tmp)

#https://tangcuxiaojikuai.xyz/post/97bbcbc9.html
# 关键需要t个点 此题t=101
flag=0
for i in range(len(m)):
    tmp1=1
    tmp2=1
    for j in range(len(m)):
        if i==j:
            continue
        tmp1*=-m[j][0]
        tmp2*=(m[i][0]-m[j][0])
    flag=(flag+m[i][1]*tmp1*inverse(tmp2,n))%n
print(long_to_bytes(flag))
r.interactive()
#b'SHCTF{5H4miR_N07_sh3rL0CK_f1289fe81dc7}'

*baby_lock

posted on 2024-10-23 09:59  Naby  阅读(206)  评论(0编辑  收藏  举报