不动点

蹉跎千万次,我仍是我。——不动点

原理简介

不动点,是一个函数术语,在数学中是指“被这个函数映射到其自身一个点”。在函数的有限次迭代之后回到相同值的点叫做周期点;不动点是周期等于 1 的周期点。
不动点原理是数学上一个重要的原理,也叫压缩映像原理或巴拿赫(Banach)不动点定理,完整的表达:完备的度量空间上,到自身的一个压缩映射存在唯一的不动点。用初等数学可以这么理解:连续映射f的定义域包含值域,则存在一个x使得f(x)=x。不动点的概念可以推广到一般的拓扑空间上。假设X是拓扑空间,f: X→X是一个连续映射,且存在x∈X,使得f(x)=x,就称x是不动点。

举例

例如,定义在实数上的函数f,f(x)=x2-3x+4,则2是函数f的一个不动点,因为 f(2)=2。
也不是每一个函数都具有不动点。例如定义在实数上的函数f(x)=x+1就没有不动点。因为对于任意的实数,x永远不会等于x+1。用几何的观点来看,不动点意味着点 (x,f(x))在直线y=x上,或者换句话说,函数f的图像与那根直线有共点。上例 f(x)=x+1的情况是,这个函数的图像与那根直线是一对平行线。

CTF例题

SECCONCTF2022-bbb
from Crypto.Util.number import bytes_to_long, getPrime
from random import randint
from math import gcd
from secret import FLAG
from os import urandom


assert len(FLAG) < 100


def generate_key(rng, seed):
    e = rng(seed)
    while True:
        for _ in range(randint(10,100)):
            e = rng(e)
        p = getPrime(1024)
        q = getPrime(1024)
        phi = (p-1)*(q-1)
        if gcd(e, phi) == 1:
            break

    n = p*q
    return (n, e)


def generate_params():
    p = getPrime(1024)
    a = randint(0, p-1)

    return (p,a)


def main():
    p,a = generate_params()
    print("[+] The parameters of RNG:")
    print(f"{a=}")
    print(f"{p=}")
    b = int(input("[+] Inject [b]ackdoor!!: "))
    rng = lambda x: (x**2 + a*x + b) % p

    keys = []
    seeds = []
    for i in range(5):
        seed = int(input("[+] Please input seed: "))
        seed %= p
        if seed in seeds:
            print("[!] Same seeds are not allowed!!")
            exit()
        seeds.append(seed)
        n, e = generate_key(rng, seed)
        if e <= 10:
            print("[!] `e` is so small!!")
            exit()

        keys.append((n,e))

    flag = bytes_to_long(FLAG + urandom(16))
    for n,e in keys:
        c = pow(flag, e, n)
        print("[+] Public Key:")
        print(f"{n=}")
        print(f"{e=}")
        print("[+] Cipher Text:", c)


if __name__ == "__main__":
    main()

题目基于rng = lambda x: (x**2 + a*x + b) % p这个函数,每次随机生成a和p,而把b当作后门让我们自己确定。generate_key则是迭代若干次rng函数,若最后的值大于10,则作为e返回。并且会用返回的e加密5次flag返回5组n e。
考虑一下如果我们能够控制五次加密e的大小可以如何进行攻击:显然最好是取5次一样的e,这样的话有机会利用Hastad attack获得flag。具体地,我们如果能够使得每轮e=11,那么五组密文crt之后得到的是模2048*5比特的结果,也就是\(\small m^{11}\;mod\;N\),由于\(\small m^{11}\)小于N,所以是可行的。
所以问题转化为如何得到五组等于11的e。由于b是可控的,所以问题就转化成\(\small x^2+ax+b\;mod\;p=x\)在控制b的情况下使得x=11,也就是使得x=11是一个不动点。在这样的条件下,令\(\small b=(11 - 11\cdot 11 - a\cdot11)\;mod\;p\)即可。但这只找到了一组e,我们还需要4组,严格来说一元二次函数的不动点仅一两个,但在模p的条件下可就不一定了。我们只需要用sagemath的roots解方程即可,f = x * x + a * x + b - target tt = f.roots()
target为每次找到的不动点,反复迭代几次就行。最后的exp:

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

conn = remote("BBB.seccon.games", 8080)
print(conn.recvline())
a = int(conn.recvline()[2:])
p = int(conn.recvline()[2:])

b = (11 - 11 * 11 - a * 11) % p 

conn.sendline(str(b).encode())

POL = PolynomialRing(GF(p), 'x')
x = POL.gen()

conn.sendline(b"11")
seeds = []

target = 11
seeds.append(11)

from tqdm import tqdm
c = 1
for i in tqdm(range(5)):
    f = x * x + a * x + b - target 
    tt = f.roots()
    for (rt, mul) in tt:
        print(i, rt)
        if int(rt) not in seeds:
            print(f"go")
            print(rt)
            seeds.append(int(rt))
            target = int(rt)
            conn.sendline(str(rt).encode())
            c = c+1
            #break 
        if c == 5:
            break
    if c == 5:
        break
        
for i in range(20):
    print(conn.recvline())

from Crypto.Util.number import long_to_bytes
from sympy.ntheory.modular import crt
from gmpy2 import iroot

n1=23848145370960037408759017314364686176512389301957694794655939353314579680913587707540863488201593333788393348905924774693877254441312212702271843713657125697969943257205892523915596521728761492596073216489401574519236739314013904765851524026750730203618952142520566161003908455177022260317054589498231552678157380684523511012659617200201966154562601527977260254686201527571789123775697879398351474099254584684835757150484025185527690074632275529846914635605784175240524171892844809809487633663289255708333883821970313113919232600794946058441504013860857647356066786942119382078993820979666946368924584693867320234377
c1=4341883375957096254558504187527404890062159259547437641538529478377040570779611127967056447993971290073610597320811472170205342203319859561339627866345834083420445267165557315720897722503122663075179252207745429563001548455399254062420201162758455742882792061670934246461081646718638812842567159799763073829868977641664310890748918762906587836773690381721671955661232728359677659014236919106176712072055108207074510161533197714050503159888064933978894588486069346922863450426286935844515236486086067570488347209790412305336928157437066384055222321205278527902044434404110490951179451114114836094870743150343064755577
n2=13716093283834491656092320519022302914994455441351420629693675543747488940024820878538630036708866970341444075387428763005137595917302480799500153461072871505065958980776756637205604542191117633396935695194442432031593053474508247786252794834666131031849436658534154375457106142588387380933221867096340562357559375572080814458647564925856567728311735942439290329256686556954867973766417921692085486520398263940986992038639092005259478425108180207565366775037223479049882840211466482329939360504985491797790930691598570676850794867180572181618436472909372592848977096277705940734173614655075733883482224206852449770401
c2=8144137031460100533401346060143755527179494577053364203908592319162213620561553919621149997965029329895066754455520762866609581116838196969104167954309229196921575093812809206573828594682515914979109295732301909493165046372308336130166942318670113359414403621835205942999135974387843169831196946969706842721194780141711207688650295215201983146190442778805271399232028224319746952026561948239120732913033127436966870339059223283959585252494937059575497617499635061652866056314453568411204691617325607172079977406154276662228040011989881765848196856143273191803883704188540689174104768660665747126072356089498528844778
n3=14330532618957313843156341161318263961313026528694856525294140396703290671777897960630878004273548102301484883620435822548255054160825637753869102466560588263765054631139457740009028252909394325288165423833791463021843479740165244454977876403478612995363462418474349803556343279192446710824223796564936670258192612430234474381680839633985991523389269998882937543052561598052472203273307693397298848259444921674337880617756392598049764390439591532589468908408998628995484259674371733508605656431770873076709839700081365204703874191369477258629601752695575829201310438329645953766082920087943775036154718258601375771103
c3=1255245617532656013582139385244880463637905726611031290463304666827573555165748961613099427912291520180598746420404135115689752228638613030037612162171800361476109564133189141988620032027425477026282693747221952549490113278352987557459491325849725202492036709933858627568438201817681093275099107493805060618254237775718362978478551439713542586813848146954319833212379400195886629509330189848393090391531778768356579762760761112075914021514664288861760820017541765743051895059556506552853771776459915358250595457334010986903952733567259423669862625000012572605090235727875984288423504986549615357306649855509430011146
n4=12880068157485052594689501699851393466529999865125834812525642340277979926825070935429491124275809456135596861024957501840342971155692967817125354724204771842380874384988791936244483597066735105501277627192948246484792166513467308076535849525511246329781177499189109549418367832675866246395347769275378720696639949946564077734875405064825726542208811687377617892220823920436785026151320201665831832203275499105964527332017466711575852531803935535746424365653818760781519306820161902864327714295440428417778854924644723080806895115674498876552042492000062774568884394814888026030852072022216660655238569903499646011213
c4=3041333726695881089015576114951163593804882069753052452981525482505478627952585802894785826181330980991340367465946405262490263226900536506224977990992663459990029089720098291275648715480484915462276584567021492007262643405330290419265732481013336322585837693750907454782339139806632500979475997884521030926302454274308039344159109131135216646658870702699759760789669339812723685695427093612881873914865915364188789956497354618817764883119473895780587346271096338105796365935875389391107588171205579148710410828270331240766331432780571664036141317718717548824773409348015618866857424924340284538225927231293794210178
n5=10979403971535377093688120061414447030233767826151760561157463644385772367228369402567591106517779633987602528114586463231383645708265488986906153197281360778035185174123342353558111810825791908778191571001200125012402876147362566709067211236643249028930221803901676222456851022333838374804310683118475771129452853389643224628967298364406479948819494437975172246759524852920680770895074795642940885365479123388048885175943389199695390328364544037637611086087638264946742904468544604216285399902238519645620710472280876185348734430255925299282883747018791794602226761462200946396007912061947602322487004644942604499231
c5=6716774061785462710724017457529103581463688510852684282403059311324447368565287963799006910999848296565129258624148637910318274401127937539239133691842215262860748029498490245388547240723175129821246187780521129501530032586047005814175189229848110409043532366988366995580062401070609756449974393024323245670828212708950636578763051466382921680484606536445822922338294466563828378984634012307571116943291302297736960136975679015940269519758664177834420112669794965117474493434667870052255732787528045193162602978409820861876676380660583480330486419670444345573962814711447825218397265927969727705232898015599023349631

solv = crt([n1,n2,n3,n4,n5],[c1,c2,c3,c4,c5])[0]
m = iroot(solv,11)[0]
print(long_to_bytes(m))
posted @ 2022-11-25 12:07  ZimaB1ue  阅读(730)  评论(0编辑  收藏  举报