1. from random import *
    2. from sympy import nextprime
    3. from serct import flag
    4. def Printprime(bits):
    5. A1=getprime(bits)
    6. A2=getprime(bits)
    7. c=randint(1,bits)
    8. B=(A1&(2**bits -1))>>c<<c
    9. temp=A1*A2
    10. print B
    11. print temp
    12. B1=(A1&(2**1024 -1))>>10<<10
    13. retrn A1,B1
    14. p1,q1=Printprime(1024)
    15. #B1=106672572720048882245660511958712758437546239973820056988685173758158387505232286222345308433971608941789148315811224011373367452106624375614858115402658270967073303108417429716363790098705093167287547128233883046603422138051729608392226373427044742935820547926346986700993433110025346422649463516306117492736
    16. #temp1=18223408528938169563926297587705487122400521640144380302276492241065231360197061692156705171767387290791148541561476206560745923631684641131760019914136599820986994476711070781431006040501812087737193539402386241242517740267076091571026828269589016751672519420720282198833660352448501015746469864270887304810845950763013784529734523829259854050111750385439938542892934956015656186706709145463150202092953765596173302945107138213341531230951256986478565603356167357434402810865412234907275857841643625096319566068656995222254979424537359861594456585561427700014906151549675951595460571359557824293390454141212479211953
    17. p2,q2=Printprime(1024)
    18. #B2=91877168566039491657305870670623199089479881202304232943572017885574139886174920491635129611163469509914703088351415537136643846568888402564414425238913656847647811500708341665196970357054465257253155806724008810425186336247727840542478123737508362772116597089289402649681073921122899377392328647691871453184
    19. #temp2=10752981800150852696615563967881183599965159757324046388359973939317020898441759042947405484639238309399736743934033107178433518473681342641181213615317215639871849837008763067553426720824753891424475137916504324486720764803530300240955353341899560507971266902592160865957525943891842840187409215141446461696280549372905972385938708196767232048124561700402455255379531118578921913216752577417339268065778869076797335588047205958424875533168419129102310280661151613698902457676601785179734346052695408018278262324802910968046484470735194722038791302419051610443221479467600861127174611095684288611709562448544247273209
    20. s1=nextprime((q1!)%p1)
    21. s2=nextprime((q2!)%p2)
    22. N=s1*s2
    23. e=0x10001
    24. c=pow(flag,e,n)
    25. '''
    26. N=402578570588989011906570974065635937836078609932235040229555379679839344402431378637094396812095407833305090207407212999030856266457870166813619476187500056486139989534715354006264939545095618222505483434352481960643166460370364037889685327790334910772475718818257316134282259815647802558834005326533813682323692197154897833084645060766766206530892477886113760677908927345577239531704573351071636043686822034521516668710069458255874802928450423278843190165962415917958305925239507648246803381332359355415021339069241284375116735895430101301850196917182567902398283167486452437848411633833758460403705565382613658367
    27. c=257219466169584626430317895847625453300903766165345929735330675689224900452052640693187275057781527958416216799173373604530220596162237821541564525255992497174490505760337958793285092180161001615733433429635155570988111639066535536344186373487468032512963711380368877832845219013378230192621831685917905614682144243446410642717728189211599904992797336342529661659885203669580272027538396825189492963272218286519957838724526284897979415278563773983550358918900302656283455164088875610481023867345293117711686899541264690484693138375715496362591852380643486782321366972801503945491161057276658293915561697253892732835
    28. '''

    分析PrintPrime可以得知,注释中的B和temp分别是A1高位和N,那么就可以利用coppersmith攻击得到原本的A1。
    常见的已知p高位攻击是直接移位,而这题给移回来了,所以不能用之前的脚本,否则计算kbit = bits - hight_p.nbits()时得到的结果是0。
    这里需要直接把B1给转成2进制,看看最后有多少个0,就是kbit的值。

    1. >>> p=106672572720048882245660511958712758437546239973820056988685173758158387505232286222345308433971608941789148315811224011373367452106624375614858115402658270967073303108417429716363790098705093167287547128233883046603422138051729608392226373427044742935820547926346986700993433110025346422649463516306117492736
    2. >>> bin(p)
    3. '0b1001011111101000001000110001111100000101011001001110001101011010010010010101101110000111100101011101010010010110101100100000101101011111100001000001011110101101110010110011111101001000110011100010000011101100001101110010011011110000011110010010101111000101100111110100111010100000110000110100001110011000110100011000101111100010010001001111000110000110110001001111000010101000111101000001000010001100011101110111000101001101011111001001011110101011010010111101101110001101010110111001011111000011001011100010110101011101010011101011001001111001001000110110001011100001110000100110011001111111001000110000110100001111100000001111100101110111110100110010111011110100111101001110010100110001000010000101100111001110101000000111011100101110110111010111100100000111001011100011110011100100100000101010010101110010000010001000001010111100011101110101110110111011010101100111001000100100110001100110010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000'

    可以得知最后有130位。利用脚本得到原本的A1,也就是p1,得到p1后就可以计算出q1

    1. hight_p = 106672572720048882245660511958712758437546239973820056988685173758158387505232286222345308433971608941789148315811224011373367452106624375614858115402658270967073303108417429716363790098705093167287547128233883046603422138051729608392226373427044742935820547926346986700993433110025346422649463516306117492736
    2. n = 18223408528938169563926297587705487122400521640144380302276492241065231360197061692156705171767387290791148541561476206560745923631684641131760019914136599820986994476711070781431006040501812087737193539402386241242517740267076091571026828269589016751672519420720282198833660352448501015746469864270887304810845950763013784529734523829259854050111750385439938542892934956015656186706709145463150202092953765596173302945107138213341531230951256986478565603356167357434402810865412234907275857841643625096319566068656995222254979424537359861594456585561427700014906151549675951595460571359557824293390454141212479211953
    3. PR.<x> = PolynomialRing(Zmod(n))
    4. f = x + hight_p
    5. x0 = f.small_roots(X=2^130, beta=0.4)[0]
    6. print("x: %s" %hex(int(x0)))
    7. p = hight_p+x0
    8. print("p: ", int(p))
    9. q=(int(p)&(2**1024 -1))>>10<<10
    10. print("q: ", int(q))
    11. # x: 0xd174e59b2ccf39cef6bc3bbb98c529db
    12. # p: 106672572720048882245660511958712758437546239973820056988685173758158387505232286222345308433971608941789148315811224011373367452106624375614858115402658270967073303108417429716363790098705093167287547128233883046603422138051729608392226373427044742935820547926346986701271848724546016167104265505521615055323
    13. # q: 106672572720048882245660511958712758437546239973820056988685173758158387505232286222345308433971608941789148315811224011373367452106624375614858115402658270967073303108417429716363790098705093167287547128233883046603422138051729608392226373427044742935820547926346986701271848724546016167104265505521615054848

    同理可得p2,q2:

    1. x: 0x48d87b37cdbc02bd8bde90e45420261b
    2. p: 91877168566039491657305870670623199089479881202304232943572017885574139886174920491635129611163469509914703088351415537136643846568888402564414425238913656847647811500708341665196970357054465257253155806724008810425186336247727840542478123737508362772116597089289402649777902372098458748457875593766253897243
    3. q: 91877168566039491657305870670623199089479881202304232943572017885574139886174920491635129611163469509914703088351415537136643846568888402564414425238913656847647811500708341665196970357054465257253155806724008810425186336247727840542478123737508362772116597089289402649777902372098458748457875593766253896704

    接着到第二步,可以看到题目中有用到阶乘,所以联想到wilson定理:当且仅当p为素数时:( p -1 )! ≡ -1 ( mod p )
    于是我们就可以通过invert函数,一步步将A推成B,这样就可以很快的解除p,q的值,得到flag

    1. s1 = p1-1
    2. for i in range(q1+1, p1, 1):
    3. s1 = s1 * inverse(i, p1) % p1
    4. s2 = p2-1
    5. for i in range(q2+1, p2, 1):
    6. s2 = s2 * inverse(i, p2) % p2
    7. s1=nextprime(s1)
    8. s2=nextprime(s2)
    9. N=s1*s2

    然后就是正常的RSA解密

    1. N=402578570588989011906570974065635937836078609932235040229555379679839344402431378637094396812095407833305090207407212999030856266457870166813619476187500056486139989534715354006264939545095618222505483434352481960643166460370364037889685327790334910772475718818257316134282259815647802558834005326533813682323692197154897833084645060766766206530892477886113760677908927345577239531704573351071636043686822034521516668710069458255874802928450423278843190165962415917958305925239507648246803381332359355415021339069241284375116735895430101301850196917182567902398283167486452437848411633833758460403705565382613658367
    2. p = s1
    3. q = N // p
    4. c=257219466169584626430317895847625453300903766165345929735330675689224900452052640693187275057781527958416216799173373604530220596162237821541564525255992497174490505760337958793285092180161001615733433429635155570988111639066535536344186373487468032512963711380368877832845219013378230192621831685917905614682144243446410642717728189211599904992797336342529661659885203669580272027538396825189492963272218286519957838724526284897979415278563773983550358918900302656283455164088875610481023867345293117711686899541264690484693138375715496362591852380643486782321366972801503945491161057276658293915561697253892732835
    5. e=0x10001
    6. d = inverse(e, (p-1)*(q-1))
    7. m = pow(c, d, N)
    8. print(long_to_bytes(m))