特殊剪枝

题目:

import sympy
from Crypto.Util.number import *
from secret import flag
e = 65537
p1 = sympy.randprime(2 ** 1023,2 ** 1024)
q1 = sympy.randprime(2 ** 1023,2 ** 1024)
a1 = p1 ^ q1
b1 = p1 * q1
c1 = pow(bytes_to_long(flag[:19]),e,p1*q1)
p2 = sympy.randprime(2 ** 511, 2 ** 512)
q2 = sympy.randprime(2 ** 511, 2 ** 512)
a2 = (p2 * q2) ^ (p2 + q2)
b2 = (p2 * q2) ^ (p2 - q2)
c2 = pow(bytes_to_long(flag[19:]),e,p2*q2)
f= open('output.txt','w')
f.write(str(a1)+'\n')
f.write(str(b1)+'\n')
f.write(str(c1)+'\n')
f.write(str(a2)+'\n')
f.write(str(b2)+'\n')
f.write(str(c2)+'\n')
'''
a1=67739512154277162085770157687437441198363095490607019903179640765859289435128844487312739643781929328039885340492248268381181927215444058044731882600621443249379470235583032722854561171610662253187419453432598163528304052508578209017561499836803166110456130462444164049945234353225230736363194196935115979960
b1=17185396829856546439605443867156437815015135756541052637907770783830686534153389303291740769607944691156059669175157827203495395745826694347428694508457493991041224390283763876476601200114028282946724348906485066220181559142937065978299071246507281834301352443856315199896106182934770582627129779923357891915723961923663378398066801894395956482176730300442901078199030200112352639266103862753546370851947797706641058966862813099369195689336228579744994641830699890792017097474275824545664085264972274642572927392940910981115837831275773192989084712813373293435228956787629490757407431010258942490818726318175944867633
c1=2180773316568266715369209198734610509148388893757598741330158376506447322216176787253641696053169188685408469718202047474660716095850135317790263924418449270019680259700945680062960717565507426032265137192689118286560945331123730529355709043463330231284484658907466172538703301303440062783852136344472063837313195697915205569416630439851250171277336484771753816776835527532090668694986220968152676688392975798850738947165707984817923309381811015047150056144403783079156300625762879231698942313672034730244627530962258121618021680413439757194393609777357848156392150372631861473658135778661768208071991812674187273360
a2=102834527596695950719979111423985349726489864165244791755647652205679952999516919199218636781810880771255724153293007819995198831162629014290926266777774940370836206596205967641213842702547665263659933022253549718321445029287279257463914991950587622466780705329578580061019164231870445205566240956950369224751
b2=102834527596695950719979111423985349726489864165244791755647652205679952999516919199218636781810880771255724153293007819995198831162629014290926266777774949520538413350277489291427420271328741830415622921056457371226207219443304838109001023043838810016379140438034881290332449739051404396455209891630254998985
c2=46285230821397377383998198689981002335902850753318921384068480704506522918467396194184971163720421808774010121239873784436865080818119851642074388303787396280596526597467664310187113430990219486840906481260493087443528880139543560763852844535689852804877233056126591516506599561944164619603448246607830867682
'''

解题思路:

第一部分:

  • 参考p^q的方法

第二部分:

已知条件:

  • (p2 * q2)(p2 + q2)的异或值,记为a2
  • (p2 * q2)(p2 - q2)的异或值,记为b2

搜索方式:

  • 从低位向高位搜索
  • 每一次搜索,需利用当前a2,b2的最低位
  • 硬搜索当前位的所有四种可能:00,01,10,11

剪枝条件:

  • 若当前已搜索了k位,则需满足:
t1 = (int(p,2)*int(q,2))
t2 = (int(p,2)+int(q,2))
t3 = (int(p,2)-int(q,2))
mask = 2**k-1
((t1^t2)&mask) == (a2&mask) and ((t1^t3)&mask) == (b2&mask)

按照此方式就可以递归深搜出p2,q2

解答:

from Crypto.Util.number import *
import sys
sys.setrecursionlimit(1500)

#part1,剪枝
a1=67739512154277162085770157687437441198363095490607019903179640765859289435128844487312739643781929328039885340492248268381181927215444058044731882600621443249379470235583032722854561171610662253187419453432598163528304052508578209017561499836803166110456130462444164049945234353225230736363194196935115979960
b1=17185396829856546439605443867156437815015135756541052637907770783830686534153389303291740769607944691156059669175157827203495395745826694347428694508457493991041224390283763876476601200114028282946724348906485066220181559142937065978299071246507281834301352443856315199896106182934770582627129779923357891915723961923663378398066801894395956482176730300442901078199030200112352639266103862753546370851947797706641058966862813099369195689336228579744994641830699890792017097474275824545664085264972274642572927392940910981115837831275773192989084712813373293435228956787629490757407431010258942490818726318175944867633
c1=2180773316568266715369209198734610509148388893757598741330158376506447322216176787253641696053169188685408469718202047474660716095850135317790263924418449270019680259700945680062960717565507426032265137192689118286560945331123730529355709043463330231284484658907466172538703301303440062783852136344472063837313195697915205569416630439851250171277336484771753816776835527532090668694986220968152676688392975798850738947165707984817923309381811015047150056144403783079156300625762879231698942313672034730244627530962258121618021680413439757194393609777357848156392150372631861473658135778661768208071991812674187273360
e = 65537
a1 = "0" + str(bin(a1)[2:])

def find(p,q):
    l = len(p)
    tmp0 = p + (1024-l)*"0"
    tmp1 = p + (1024-l)*"1"
    tmq0 = q + (1024-l)*"0"
    tmq1 = q + (1024-l)*"1"
    if(int(tmp0,2) < int(tmq0,2)):
        return 
    if(int(tmp0,2)*int(tmq0,2) > b1):
        return 
    elif(int(tmp1,2)*int(tmq1,2) < b1):
        return

    if(l == 1024):
        pp = int(tmp0,2)
        qq = int(tmq0,2)
        d = inverse(e,(pp-1)*(qq-1))
        m = long_to_bytes(pow(c1,d,pp*qq))
        print(str(m)[2:-1],end = "")
        
    else:
        if(a1[l] == "1"):
            find(p+"1",q+"0")
            find(p+"0",q+"1")
        else:
            find(p+"0",q+"0")
            find(p+"1",q+"1")

tempp = ""
tempq = ""
find(tempp,tempq)


#part2 硬剪枝
a2=102834527596695950719979111423985349726489864165244791755647652205679952999516919199218636781810880771255724153293007819995198831162629014290926266777774940370836206596205967641213842702547665263659933022253549718321445029287279257463914991950587622466780705329578580061019164231870445205566240956950369224751
b2=102834527596695950719979111423985349726489864165244791755647652205679952999516919199218636781810880771255724153293007819995198831162629014290926266777774949520538413350277489291427420271328741830415622921056457371226207219443304838109001023043838810016379140438034881290332449739051404396455209891630254998985
c2=46285230821397377383998198689981002335902850753318921384068480704506522918467396194184971163720421808774010121239873784436865080818119851642074388303787396280596526597467664310187113430990219486840906481260493087443528880139543560763852844535689852804877233056126591516506599561944164619603448246607830867682
e = 65537

def find(p,q,k):
    mask = 2**k-1

    t1 = (int(p,2)*int(q,2))
    t2 = (int(p,2)+int(q,2))
    t3 = (int(p,2)-int(q,2))
    
    if(len(bin(int(p,2))[2:]) == 512 and len(bin(int(q,2))[2:]) == 512):
        pp = int(p,2)
        qq = int(q,2)
        d = inverse(e,(pp-1)*(qq-1))
        m = long_to_bytes(pow(c2,d,pp*qq))
        if(len(m) < 20):
            print(str(m)[2:-1])
            exit()

    if(((t1^t2)&mask) == (a2&mask) and ((t1^t3)&mask) == (b2&mask)):
        find("0"+p,"0"+q,k+1)
        find("0"+p,"1"+q,k+1)
        find("1"+p,"0"+q,k+1)
        find("1"+p,"1"+q,k+1)
    else:
        return

p = "1"
q = "1"

find(p,q,1)
#flag{u2w6tnettv2a9fbo5qh73k8082h2q9j3}
posted @ 2025-03-11 22:12  sevensnight  阅读(40)  评论(0)    收藏  举报