zoukankan      html  css  js  c++  java
  • V&N2020 公开赛 easy_RSA

    题目

    from random import randint
    from gmpy2 import *
    from Crypto.Util.number import *
    
    def getprime(bits):
        while 1:
            n = 1
            while n.bit_length() < bits:
                n *= next_prime(randint(1,1000))
            if isPrime(n - 1):
                return n - 1
    
    m = bytes_to_long(b'flag{************************************}')
    
    p = getprime(505)
    q = getPrime(512)
    r = getPrime(512)
    assert m < q
    
    n = p * q * r
    e = 0x10001
    d = invert(q ** 2, p ** 2)
    c = pow(m, 2, r)
    cipher = pow(c, e, n)
    
    print(n)
    print(d)
    print(cipher)
    
    
    '''
    
    7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409
    7515987842794170949444517202158067021118454558360145030399453487603693522695746732547224100845570119375977629070702308991221388721952258969752305904378724402002545947182529859604584400048983091861594720299791743887521228492714135449584003054386457751933095902983841246048952155097668245322664318518861440
    1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200
    
    '''
    

    分析

    1. 从题设代码中可以得到的信息有

    [n=p*q*r ]

    [d=invert(q^2,p^2) ]

    [c=m^2 mod r ]

    [cipher=c^e mod n ]

    1. 同时,注释中已经给出(n)(d)(cipher)的值,所以基本的思路是先由(cipher)求出(c),再由(c)求出(m)
    2. (cipher)求出(c)首先要确定(e mod n)的逆元,所以需要先求出(phi(n)),那么需要先对n进行分解得到(p,q,r)(题设中知道p是最小的那个)
    3. 题设中知道(p,q,r)都是素数,欧拉函数很简单了就是(phi(n)=(p-1)(q-1)(r-1))
    4. 利用gmpy2.invert函数求(e)的逆元(dec)后,有

    [c=cipher^{dec} mod n ]

    1. (m^2=c mod r)的解(m),这里是知识点
    求$x^{n} = a mod p$的解的方法

    from sympy.ntheory.residue_ntheory import nthroot_mod
    x=nthroot_mod(a,n,p)

    完整的解题代码如下

    from Crypto.Util.number import *
    from gmpy2 import *
    from sympy.ntheory.residue_ntheory import nthroot_mod
    
    n = 7941371739956577280160664419383740967516918938781306610817149744988379280561359039016508679365806108722198157199058807892703837558280678711420411242914059658055366348123106473335186505617418956630780649894945233345985279471106888635177256011468979083320605103256178446993230320443790240285158260236926519042413378204298514714890725325831769281505530787739922007367026883959544239568886349070557272869042275528961483412544495589811933856131557221673534170105409
    d = 7515987842794170949444517202158067021118454558360145030399453487603693522695746732547224100845570119375977629070702308991221388721952258969752305904378724402002545947182529859604584400048983091861594720299791743887521228492714135449584003054386457751933095902983841246048952155097668245322664318518861440
    cipher = 1618155233923718966393124032999431934705026408748451436388483012584983753140040289666712916510617403356206112730613485227084128314043665913357106301736817062412927135716281544348612150328867226515184078966397180771624148797528036548243343316501503364783092550480439749404301122277056732857399413805293899249313045684662146333448668209567898831091274930053147799756622844119463942087160062353526056879436998061803187343431081504474584816590199768034450005448200
    
    p = 102634610559478918970860957918259981057327949366949344137104804864768237961662136189827166317524151288799657758536256924609797810164397005081733039415393
    q = 7534810196420932552168708937019691994681052660068275906973480617604535381306041583841106383688654426129050931519275383386503174076258645141589911492908993
    r = 10269028767754306217563721664976261924407940883784193817786660413744866184645984238866463711873380072803747092361041245422348883639933712733051005791543841
    phn = (p-1)*(q-1)*(r-1)
    e = 0x10001
    dec = invert(e,phn)
    print(dec)
    # dec = 696507389127827123706661871654450815284301235334466795840166268431469309011195076922454367593796687564813693144028411855398655084684946537577925810218190635193690686941033400271584581743511646525701770230697389808139688889055897738680146145489141461623210306152017482372340288056132947782754463871096351562634396868323861335480091797855608845695507892749062713128285934572259972389743839646950269761373893877746254763641876362977045864056456449244814748352513
    
    c = pow(cipher,dec,n)
    print(c)
    # c = 8081092455112516397361105816900490085355315574087538340788309885334106796325593823678787887569920404814986643819898763828872716522338864714182757065213683
    
    # nthroot_mod(a,n,p) Find the solutions to x**n = a mod p
    m = nthroot_mod(c,2,r)
    print(m)
    # m = 56006392793430016468251971646527328995718100207125432393433900875091739391190683811783574991236326013
    print(long_to_bytes(m))
    

    flag{fd462593-25e4-4631-a96a-0cd5c72b2d1b}

  • 相关阅读:
    HDU 2089 不要62
    HDU 5038 Grade(分级)
    FZU 2105 Digits Count(位数计算)
    FZU 2218 Simple String Problem(简单字符串问题)
    FZU 2221 RunningMan(跑男)
    FZU 2216 The Longest Straight(最长直道)
    FZU 2212 Super Mobile Charger(超级充电宝)
    FZU 2219 StarCraft(星际争霸)
    FZU 2213 Common Tangents(公切线)
    FZU 2215 Simple Polynomial Problem(简单多项式问题)
  • 原文地址:https://www.cnblogs.com/vict0r/p/13568205.html
Copyright © 2011-2022 走看看