CTFshow月餅杯Crypto3_多少離杯WP
阿新 • • 發佈:2021-10-20
多少離懷起清夜,人間重望一回圓。
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~}