1. 程式人生 > 其它 >CTFshow月餅杯Crypto3_多少離杯WP

CTFshow月餅杯Crypto3_多少離杯WP

題目連結

多少離懷起清夜,人間重望一回圓。

Weird Γ(x).py:

# -*- coding:utf-8 -*-
#Author: Lazzaro

from Crypto.Util.number import getPrime,isPrime
from math import gamma
import random

def nextPrime(n):
    n += 2 if n & 1 else 1
    while not isPrime(n):
        n += 2
    return n

def getNewPrime():
    A = getPrime(512)
    B = nextPrime(A - random.randint(1e4,1e5))
    return nextPrime(gamma(B+2)%A)
	
p = getNewPrime()
q = getNewPrime()
r = getNewPrime()
n = p * q ** 2 * r ** 3
e = 0x10001
c = pow(flag,e,n)

#pA=6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723982789
#pB=6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723922147
#qA=7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477881291
#qB=7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477807457
#n=4451906216583258787166698210560165433649728830889954633721198623488802305844782492171757604711145165920462286487680020347239300947225371917344589502941576734875830871998499135120227347066586066943289430156378296665669974728569678779668142712266780949126509440672273927433367293606776081254094682033167575930701870261219046464773708974194213798032346187463443317770758989273370488582862531630356263732232300508706676725203199729764016766683870925164232508407363688370458877688991733322055785233669885166225464068579486683574954699370175267031949720967812902215635630884502987094547523361027411501285252862476410213277925430392164226297316310465146003494714018456407793759170649913180823814850170639706664167149612984905056804131124522209409607977589884632999710708045656852149371030046919242039957767777840304466948549383597755811307383659188216421501912831203089570725388153416013596114462069777713822433178099904907224119
#c=1996198968748552041728429851810599627895157160099076033250854211280074825148767841655949210593646824507865483166496070951130337321360509148527292165245205219296211294789087358959553387392928560150390604911087085313000622842025416521494799132969818997182731021267942464323979261593380113740152841984062184326431879167516288834455296913822921806893572566867611541664848820247889274979245086440402996661226884320574824077910315143756471444347386795428338020162169391827182914043434253974549636668126789355991920452920806351939782281969098470635517019120996509180703896707990501216102290302162705699788457579330150149320348175742131887213742989509004374645723471497302400169849858253644606818874098604333865973357374444445825761600866472906771935670261641342221394488068630591190697667016958881530367047928341661857241378511420562236766886349565409774340321441504290366223243635878057759623855735794209219474650425139791831374

hint

注意伽馬函式Γ(x)和階乘x!的關係式
威爾遜定理

知識點:

#伽馬函式Γ(x)和階乘x!的關係式
gamma(n)=(n-1)!

#威爾遜定理
當且僅當p為素數時:(p-1)! ≡ -1 (mod p)
推論:(p-2)! ≡ 1 (mod p)

#尤拉函式
若n是質數p的k次冪,phi = p**k - p**(k-1)

我們需要求gamma(B+2)%A,根據伽馬函式Γ(x)和階乘x!的關係式可知(B+1)! % A
而根據威爾遜定理可知(A-2)! % A = 1
x = (A-2)!/(B+1)!``,y = (B+1)!,所以x * y ≡ 1 (mod A)。


而我們需要求的是y % A,y是x關於A的逆元。所以求x % A的逆元即可,用歐幾里得法求逆.

exp1:

import random
import gmpy2
from math import gamma
from Crypto.Util.number import getPrime, isPrime
#參考大佬的exp完善了一下,2333

def getNewPrime():
    A = getPrime(512)
    B = nextPrime(A - random.randint(1e4, 1e5))
    return nextPrime(gamma(B + 2) % A)

def nextPrime(n):
    n += 2 if n & 1 else 1
    while not isPrime(n):
        n += 2
    return n

def getNewPrime2(A, B):
    return nextPrime(gamma2(B, A))

def gcd(a, b):
    while a != 0:
        a, b = b % a, a
    return b

def findModReverse(a, m):  # 這個擴充套件歐幾里得演算法求模逆
    if gcd(a, m) != 1:
        return None
    u1, u2, u3 = 1, 0, a
    v1, v2, v3 = 0, 1, m
    while v3 != 0:
        q = u3 // v3
        v1, v2, v3, u1, u2, u3 = (u1 - q * v1), (u2 - q * v2), (u3 - q * v3), v1, v2, v3
    return u1 % m

def gamma2(b, a):
    res = 1
    # print("final: "+str(a-2+1))
    for i in range(b + 2, a - 2 + 1):
        res = (res * findModReverse(i, a)) % a
    # print(i)
    return res

e = 0x10001
pA = 6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723982789
pB = 6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723922147
qA = 7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477881291
qB = 7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477807457
n = 4451906216583258787166698210560165433649728830889954633721198623488802305844782492171757604711145165920462286487680020347239300947225371917344589502941576734875830871998499135120227347066586066943289430156378296665669974728569678779668142712266780949126509440672273927433367293606776081254094682033167575930701870261219046464773708974194213798032346187463443317770758989273370488582862531630356263732232300508706676725203199729764016766683870925164232508407363688370458877688991733322055785233669885166225464068579486683574954699370175267031949720967812902215635630884502987094547523361027411501285252862476410213277925430392164226297316310465146003494714018456407793759170649913180823814850170639706664167149612984905056804131124522209409607977589884632999710708045656852149371030046919242039957767777840304466948549383597755811307383659188216421501912831203089570725388153416013596114462069777713822433178099904907224119
c = 1996198968748552041728429851810599627895157160099076033250854211280074825148767841655949210593646824507865483166496070951130337321360509148527292165245205219296211294789087358959553387392928560150390604911087085313000622842025416521494799132969818997182731021267942464323979261593380113740152841984062184326431879167516288834455296913822921806893572566867611541664848820247889274979245086440402996661226884320574824077910315143756471444347386795428338020162169391827182914043434253974549636668126789355991920452920806351939782281969098470635517019120996509180703896707990501216102290302162705699788457579330150149320348175742131887213742989509004374645723471497302400169849858253644606818874098604333865973357374444445825761600866472906771935670261641342221394488068630591190697667016958881530367047928341661857241378511420562236766886349565409774340321441504290366223243635878057759623855735794209219474650425139791831374

#求 ((pA-2)!/(pB+1)!)%pA 的逆元,等於((pB+1)!)%pA ,等於gamma(pB+2)%pA
p = 1
max = (pA-2) - (pB+1)
for i in range(0,max):
	p = p * gmpy2.invert((pA-i-2),pA) % pA
p = nextPrime(p)
#print(p)
#求 ((qA-2)!/(qB+1)!)%qA 的逆元,等於((qB+1)!)%qA ,等於gamma(qB+2)%qA
q = 1
max = (qA-2) - (qB+1)
for i in range(0,max):
	q = q * gmpy2.invert((qA-i-2),qA) % qA
q = nextPrime(q)
#print(q)
#p = 721295413363782943575290202453254405609384962866760177823574558139524613289380285395875654962467791028293949737699221240830187032744030384932819874799211
#q = 3112046822677655775872849946553212669700408142233774149727014153992463597788397754366224491840784669131576610049264423785236897140841668817147645049635999

fn = getNewPrime2(p,q)
#print(fn)
#fn = 3
r = gmpy2.iroot(gmpy2.mpz(n//(p*q*q)),3)[0]
#print(r)
#r = 8605581006163978513558138296576032102733660218879126657600237911024254611499452345790192297532366960817162346945271546520036031830535178172751208076290109

phi = (p - 1) * (q * q - q) * (r * r * r - r * r)
d = gmpy2.invert(e,phi)
#print(d)
#d=3893796118845369439235581551299559681130294433914324573287346480568253612056224380636546037500153379857589128641230243165297526124111655151656456885394718320571011164662139031101601805935834789093718455506105414382703229813895443438508544153175032701351201540968823002419519523214390287666578730407931246445871807183537209694071828922295499346083880163169003198594519162159452952535381034048239423912932288087394862004236172433929593269810986943713662824358214779552898877881697861535560993274391395357266197384454357803117633435524780866783488594161973423232638616086772861225974312225600055495130373828730995856136891951667049900975798958834487417185610258985145585210434281769923883162243531194314167637519779543778335295761192135358383400455687647479329697758466764046259467201396085554561420952266156396111233306174055533779858729332820780458072338771340688204365931674201918683102590056383442579221021315973279544753
m = pow(c, d, n)

import binascii
print(binascii.unhexlify(hex(m)[2:]))

exp2:

#純大佬exp,小編xue微改了一下執行中出現的問題,大佬勿怪
from math import gamma
import random
import gmpy2
import binascii
from Cryptodome.Util.number import *

def nextPrime(n):
    n += 2 if n & 1 else 1
    while not isPrime(n):
        n += 2
    return n

def getNewPrime():
    A = getPrime(512)
    B = nextPrime(A - random.randint(1e4,1e5))
    return nextPrime(gamma(B+2)%A)

pA=6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723982789
pB=6814157460586876042804041951834304833424062437744287469257313954502540797027261340622077218188033865281590529907571701131297782609357118357982463723922147
qA=7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477881291
qB=7145646366857234331692232566211321498245533826533958883943688415057871253511271731661019642050252046201115975396366275083424623329930477623781348477807457

e = 0x10001
n=4451906216583258787166698210560165433649728830889954633721198623488802305844782492171757604711145165920462286487680020347239300947225371917344589502941576734875830871998499135120227347066586066943289430156378296665669974728569678779668142712266780949126509440672273927433367293606776081254094682033167575930701870261219046464773708974194213798032346187463443317770758989273370488582862531630356263732232300508706676725203199729764016766683870925164232508407363688370458877688991733322055785233669885166225464068579486683574954699370175267031949720967812902215635630884502987094547523361027411501285252862476410213277925430392164226297316310465146003494714018456407793759170649913180823814850170639706664167149612984905056804131124522209409607977589884632999710708045656852149371030046919242039957767777840304466948549383597755811307383659188216421501912831203089570725388153416013596114462069777713822433178099904907224119
c=1996198968748552041728429851810599627895157160099076033250854211280074825148767841655949210593646824507865483166496070951130337321360509148527292165245205219296211294789087358959553387392928560150390604911087085313000622842025416521494799132969818997182731021267942464323979261593380113740152841984062184326431879167516288834455296913822921806893572566867611541664848820247889274979245086440402996661226884320574824077910315143756471444347386795428338020162169391827182914043434253974549636668126789355991920452920806351939782281969098470635517019120996509180703896707990501216102290302162705699788457579330150149320348175742131887213742989509004374645723471497302400169849858253644606818874098604333865973357374444445825761600866472906771935670261641342221394488068630591190697667016958881530367047928341661857241378511420562236766886349565409774340321441504290366223243635878057759623855735794209219474650425139791831374

#求 ((pA-2)!/(pB+1)!)%pA 的逆元,等於((pB+1)!)%pA ,等於gamma(pB+2)%pA
p = 1
max = (pA-2) - (pB+1)
for i in range(0,max):
	p = p * gmpy2.invert((pA-i-2),pA) % pA
p = nextPrime(p)
#求 ((qA-2)!/(qB+1)!)%qA 的逆元,等於((qB+1)!)%qA ,等於gamma(qB+2)%qA
q = 1
max = (qA-2) - (qB+1)
for i in range(0,max):
	q = q * gmpy2.invert((qA-i-2),qA) % qA
q = nextPrime(q)

r = gmpy2.iroot(gmpy2.mpz(n//(p*q**2)),3)
print(r)

print('p =',p)
print('q =',q)
print('r =',r[0])
phi = (p-1)*(q**2-q)*(r[0]**3-r[0]**2)
d = gmpy2.invert(e,phi)
m = pow(c, d, n)
print(long_to_bytes(m))

得到flag:

flag{N0w_U_knOw_how_70_u5E_W1lS0n'5_Th30r3m~}

大佬1的WP

大佬2的WP