complex


复数rsa,没遇到过这种类型的题,可以记录一下相关知识

先来看一段

from gmpy2 import invert,lcm,is_prime
import sys
sys.setrecursionlimit(2047)

f = (378122348642214690905411683807377396279362526734068034297186493255873563264253248095197659138069664908850853277799239471404715546747080714581633876343291058815268009173602365587463522797812239900814474973941995698621021680129530453282192603316731832323767320307650941745085796583822798379896337325L, 205549984221850341303682190742446959375043769671555741781145106776498798455293849755553794941345135675348633855787880355726112506553703853175271830126908219803257875131387292937296039523359975622001865593227631119497003599166091642640101746534401068507972834895023584843991641629874709898672559632L)
e = 59107
p = 228517792080140341
q = 1675909164550923263854591345270445396052847869117231939809062226222204253885693425526434134321712288675268468398852452684029376569327518089966506865838909486699078280423099271324646863671350838232140981094611254627738568184261530942469845202934677427234062382272736609418198352717

n = p*q

def cadd(a,b,n):
    return (a[0]+b[0]%n,a[1]+b[1]%n)

def cmul(a,b,n):
    return ((a[0]*b[0]-a[1]*b[1])%n,(a[0]*b[1]+a[1]*b[0])%n)

def cpow(a,k,n):
    if(k==0):
        return (1,0)
    if(k==1):
        return a
    if(k%2==0):
        a=cmul(a,a,n)
        return cpow(a,k/2,n)
    else:
        return cmul(a,cpow(cmul(a,a,n),(k-1)/2,n),n)

o=lcm((p*p-1),(q*q-1))
fm=cpow(f,invert(e,o),n)
print(fm)

来源:https://github.com/Ariana1729/CTF-Writeups/blob/master/2019/CryptoCTF/Complex%20RSA/README.md

We first consider the order of C/pC* where p is a prime. The real and imaginary parts ranges from 0 to p-1, so a valid assumption is that the order is a multiple of p*p-1(since 0,0 can't be in the group). The order is exactly p*p-1 for p=3 mod 4 since it cannot be expressed as the sum of 2 squares, but for p=1 mod 4 it is less, and it is a multiple of p*p-1. Thus if we want to find g given g^e=a mod p, we simply invert e under p*p-1. For n=pq, the order is a multiple of lcm(p*p-1,q*q-1), then it's trivial For factoring n we simply use yafu

函数cadd:实现两个复数的加法。
函数cmul:实现两个复数的乘法
函数cpow:实现复数的幂运算,其中k为指数,n为模数

该段实现了一个复数域上的rsa解题过程

复数中欧拉函数:
p h i ( p ) = p 2 − 1 p h i ( q ) = q 2 − 1 p h i ( n ) = ( p 2 − 1 ) ∗ ( q 2 − 1 ) phi(p) = p^2 - 1\\phi(q) = q^2 - 1\\phi(n) = (p^2 - 1)*(q^2 - 1) phi(p)=p21phi(q)=q21phi(n)=(p21)(q21)

[GeekChallenge-2023] EzComplex

题目描述:

from Crypto.Util.number import *
flag = b'FAKE{Do_You_know_Complex_numbers}'
p = random_prime(1 << 384)
q = random_prime(1 << 384)
n = p * q
e = 0x10001
N = pow(p, 2) + pow(q, 2)
m = bytes_to_long(flag)
c = pow(m,e,n)

print(c)
print(N)

'''
122977267154486898127643454001467185956864368276013342450998567212966113302012584153291519651365278888605594000436279106907163024162771486315220072170917153855370362692990814276908399943293854077912175867886513964032241638851526276
973990451943921675425625260267293227445098713194663380695161260771362036776671793195525239267004528550439258233703798932349677698127549891815995206853756301593324349871567926792912475619794804691721625860861059975526781239293017498
'''

题目分析:
N = p 2 + q 2 = ( p + q ∗ i ) ∗ ( p − q ∗ i ) N = p^2 + q^2 = (p + q*i)*(p - q*i) N=p2+q2=(p+qi)(pqi)
遍历所有因子得到p,q,之后常规rsa解密

from Crypto.Util.number import *

c = 122977267154486898127643454001467185956864368276013342450998567212966113302012584153291519651365278888605594000436279106907163024162771486315220072170917153855370362692990814276908399943293854077912175867886513964032241638851526276
N = 973990451943921675425625260267293227445098713194663380695161260771362036776671793195525239267004528550439258233703798932349677698127549891815995206853756301593324349871567926792912475619794804691721625860861059975526781239293017498
e = 65537

zn = ZZ[i](N)
for d in divisors(zn):
    p = int(d[0])
    q = int(d[1])
    if isPrime(p) and isPrime(q) and p.bit_length() > 380:        
        break
        
phi = (p-1)*(q-1)
n  = p*q
d = inverse(e,phi)
print(long_to_bytes(int(pow(c,d,n))))
# SYC{D0_you_like_r41n?_i_pref3r_R1_ng}

ZZ(i)[N]:创建了一个整数高斯环。这个环的元素由整数和虚数部分组成,且整数和虚数部分都是整数。其中N是一个整数,表示高斯环的模,元素中整数和虚数部分的取值范围是[-N/2, N/2]

假设复数: a + b ∗ i a + b * i a+bi,那么 a,b ∈[-N/2, N/2]
其中有一种特殊情况:a = N,b = 0

题2

题目描述:

import os
import hashlib
from Crypto.Util.number import *
from secret import flag, totient
# where totient is a function used to calculate phi

class Complex:
    def __init__(self, re, im):
        self.re = re
        self.im = im
    
    def __mul__(self, c):
        re_ = self.re * c.re - self.im * c.im
        im_ = self.re * c.im + self.im * c.re
        return Complex(re_, im_)
    
    def show(self):
        print([self.re, self.im])

def complex_pow(c, exp, n):
    result = Complex(1, 0)
    while exp > 0:
        if exp & 1:
            result = result * c
            result.re = result.re % n
            result.im = result.im % n
        c = c * c
        c.re = c.re % n
        c.im = c.im % n
        exp >>= 1
    return result

def pad(msg, length):
    pad_length = length - len(msg) - 1
    pad_data = os.urandom(pad_length)
    return msg + b'\x00' + pad_data

def unpad(msg):
    return msg.split(b"\x00")[0]

bits = 512
p = getPrime(bits)
q = getPrime(bits)
n = p * q

sha_flag = hashlib.sha256(flag).digest()

m1 = Complex(
        int.from_bytes(sha_flag[:len(sha_flag)//2], "big"),
        int.from_bytes(sha_flag[len(sha_flag)//2:], "big"),
    )

m2 = Complex(
        int.from_bytes(pad(flag[:len(flag)//2], bits//4-1), "big"),
        int.from_bytes(pad(flag[len(flag)//2:], bits//4-1), "big"),
    )

phi = totient(p, q)
e = q * inverse(p, phi)
c1 = complex_pow(m1, e, n)
c2 = complex_pow(m2, e, n)

c1.show()
c2.show()
print(f'n = {n}')

"""
[90554536599623574119664951128649936419332926063696768860765928746438458550068553748440108394673303800443215316190882880737918820592384729010491685487061658710808286341751196450604089438847354206384322610922839055308138101241906861635339635907663440043442187064090630207952625897567214431195621589834131462698, 9144096375153318849308858335764188418198064372272913164911615933938183103747900881824918069830188301084043148828961577193063557255905230182831945580084452509300200269659063051152684191139872067872645370760797859584822240361290678189844670289832298393156571913616456958845361092243648857334156534377833472900]
[62925714576233017213228404230949787334346543378320798964656732359587152905032848271156799538355748406136742979043729040728123730886381468564779041856310262770766050213464073568850702827835472680885186487027698395099598698463717279017013124488699475168052581476224742146967412904416266652605031934025266540003, 62818668456104375760667670741457826560706388018921820295286033114468271151921637926389738844622672202424650967678199715932465104135980734708459543588178208672956785650944371545080965650112025782049517299538052360417245732776384089052839997333049599655001615752078742624898059780909287845495731050387891926520]
n = 94040393367054633265453751757391098049234338193258976478647369399924701067077628840760704857546243644552533845934146003988635403227234096447871132283820920489003286967145732739404245319615714787916756200564828237043658350145929927911058782352154997346295194977765305107634012698472977467843980475009837261877
"""

题目分析:
可以看出是一道基于复数的rsa,re实部,im虚部
complex_pow(m,e,n)函数计算的是 m e m o d    n m^e \mod n memodn
其中phi = totient(p,q)e = q * inverse(p,phi)
里面提示totient is a function used to calculate phi,而此题又是基于复数域上的,那么可以猜测 p h i = t o t i e n t ( p , q ) = ( p 2 − 1 ) ∗ ( q 2 − 1 ) phi = totient(p,q) = (p^2-1)*(q^2-1) phi=totient(p,q)=(p21)(q21)

从加密流程可以看出:
c1的实部是sha_flag前半部分,虚部是sha_flag后半部分
c2的实部是flag前半部分,虚部是flag后半部分

e ≡ q ∗ p − 1 m o d    p h i e ∗ p ≡ q m o d    p h i e ∗ n ≡ q 2 m o d    p h i c 1 n ≡ m 1 e ∗ n ≡ m 1 q 2 m o d    n c 1 n ≡ m 1 q 2 ≡ m 1 m o d    q ( 回到上面 p h i ( q ) = q 2 − 1 ) e \equiv q * p^{-1} \mod phi\\ e*p \equiv q \mod phi\\ e * n \equiv q^2 \mod phi\\ c_1^n \equiv m_1^{e*n} \equiv m_1^{q^2} \mod n\\ c_1^n \equiv m_1^{q^2} \equiv m_1\mod q\\ (回到上面phi(q) = q^2 - 1)\\ eqp1modphiepqmodphienq2modphic1nm1enm1q2modnc1nm1q2m1modq(回到上面phi(q)=q21)
c 1 n − m 1 = k ∗ q c_1^n - m_1 = k * q c1nm1=kq
m 1 m_1 m1只有128比特,比q的一半位数还小的多,完全可以copper求出 m 1 m_1 m1
之后gcd(k*q,n)得到q,那么p,q就都出了
然后常规rsa解题思路得到flag

注意,这里实现pow用它定义的complex_pow()

from Crypto.Util.number import *
from gmpy2 import *

class Complex:
    def __init__(self, re, im):
        self.re = re
        self.im = im

    def __mul__(self, c):
        re_ = self.re * c.re - self.im * c.im
        im_ = self.re * c.im + self.im * c.re
        return Complex(re_, im_)

    def show(self):
        print([self.re, self.im])

    def get_value(self):
        return self.re,self.im

def complex_pow(c, exp, n):
    result = Complex(1, 0)
    while exp > 0:
        if exp & 1:
            result = result * c
            result.re = result.re % n
            result.im = result.im % n
        c = c * c
        c.re = c.re % n
        c.im = c.im % n
        exp >>= 1
    return result

c1 = [90554536599623574119664951128649936419332926063696768860765928746438458550068553748440108394673303800443215316190882880737918820592384729010491685487061658710808286341751196450604089438847354206384322610922839055308138101241906861635339635907663440043442187064090630207952625897567214431195621589834131462698, 9144096375153318849308858335764188418198064372272913164911615933938183103747900881824918069830188301084043148828961577193063557255905230182831945580084452509300200269659063051152684191139872067872645370760797859584822240361290678189844670289832298393156571913616456958845361092243648857334156534377833472900]
c2 = [62925714576233017213228404230949787334346543378320798964656732359587152905032848271156799538355748406136742979043729040728123730886381468564779041856310262770766050213464073568850702827835472680885186487027698395099598698463717279017013124488699475168052581476224742146967412904416266652605031934025266540003, 62818668456104375760667670741457826560706388018921820295286033114468271151921637926389738844622672202424650967678199715932465104135980734708459543588178208672956785650944371545080965650112025782049517299538052360417245732776384089052839997333049599655001615752078742624898059780909287845495731050387891926520]
n = 94040393367054633265453751757391098049234338193258976478647369399924701067077628840760704857546243644552533845934146003988635403227234096447871132283820920489003286967145732739404245319615714787916756200564828237043658350145929927911058782352154997346295194977765305107634012698472977467843980475009837261877
c1 = Complex(c1[0],c1[1])
c2 = Complex(c2[0],c2[1])
cc1 = complex_pow(c1,n,n).get_value()

P.<m> = Zmod(n)[]
f = cc1[0] - m
f = f.monic()
m1 = f.small_roots(2^128,0.4)[0]

q = gcd(cc1[0]-int(m1),n)
p = n // q
phi = (p^2 - 1) * (q ^ 2 - 1)
e = q * inverse(p, phi)
d = inverse(e,phi)
m2 = complex_pow(c2,d,n).get_value()
print(long_to_bytes(int(m2[0])))
print(long_to_bytes(int(m2[1])))
# flag{3ef6db06-b837-11ed-9825-00155dfcdef9}

感觉这道题真的很有意思

浅记一下:
关键词:复数欧拉,ZZ(i)[N],coppersmith

2024/05/11更新

[XYCTF2024] Complex_rsa

题目描述:

from Crypto.Util.number import *
from secrets import flag


class Complex:
    def __init__(self, re, im):
        self.re = re
        self.im = im

    def __mul__(self, c):
        re_ = self.re * c.re - self.im * c.im
        im_ = self.re * c.im + self.im * c.re
        return Complex(re_, im_)

    def __str__(self):
        if self.im == 0:
            return str(self.re)
        elif self.re == 0:
            if abs(self.im) == 1:
                return f"{'-' if self.im < 0 else ''}i"
            else:
                return f"{self.im}i"
        else:
            return f"{self.re} {'+' if self.im > 0 else '-'} {abs(self.im)}i"


def complex_pow(c, exp, n):
    result = Complex(1, 0)
    while exp > 0:
        if exp & 1:
            result = result * c
            result.re = result.re % n
            result.im = result.im % n
        c = c * c
        c.re = c.re % n
        c.im = c.im % n
        exp >>= 1
    return result


m = bytes_to_long(flag)
key = getRandomNBitInteger(m.bit_length())
c = m ^ key
com = Complex(key, c)
p = getPrime(512)
q = getPrime(512)
e = 9
enc = complex_pow(com, e, p * q)
print(enc)
print(Complex(p, q) * Complex(p, q))
# 66350931528185981323649477263900844564494528747802437244889229343520648562164950914433406604580038018765783183569276743239888668912948977370163046257917321742455772852779551569446155827368453262479370103326286297164105599131090881306108546341785251895116423206455175290083968296281375908109039893280371271943 + 65266730684129269806656018828265187384002656633231286337130178390517924611751697965395744944541329793503617856896706439809241745206839328124348693486741656130890593895436661857688522977866438805549144904296596887218275440542852887148071837153436265722614658566275517205322945316112048487893204059562830581004i
# -28814875173103880290298835537218644402443395484370652510062722255203946330565951328874411874019897676900075613671629765922970689802650462822117767927082712245512492082864958877932682404829188622269636302484189627580600076246836248427780151681898051243380477561480415972565859837597822263289141887833338111120 + 235362412848885579543400940934854106052672292040465052424316433330114813432317923674803623227280862945857543620663672974955235166884830751834386990766053503640556408758413592161122945636548462064584183165189050320898315823173824074873376450569212651128285746330837777597290934043912373820690250920839961482862i

已知 : c = m e ( m o d n ) h = ( p + q i ) ( p + q i ) = ( p 2 − q 2 ) + 2 p q i h 的实部和虚部已知,那么 p , q 便能求出来 之后发现 e 与 p h i 不互素 g c d ( e , p h i ) = e g c d ( e , p 2 − 1 ) = g c d ( e , q 2 − 1 ) = 3 可知 : e ∗ d p ≡ 3 ( m o d p 2 − 1 ) , e ∗ d q ≡ 3 ( m o d q 2 − 1 ) 利用拓展欧几里得算法求出 d p 和 d q , 得到: m e d p ≡ m 3 ≡ c d p ( m o d p ) m e d q ≡ m 3 ≡ c d q ( m o d q ) 设 m = ( a + b i ) ,则 m 3 = ( a 3 − 3 a b 2 ) + ( 3 a 2 b − b 3 ) i 通过 c d p ( m o d p ) , c d q ( m o d q ) 解出所以可能的 a , b ,即 : a p ≡ a ( m o d p ) , a q ≡ a ( m o d q ) ① b p ≡ b ( m o d p ) , b q ≡ b ( m o d q ) ② 对①,②分别进行 c r t 得到所有可能的 a , b ,即 k e y 和 C 然后遍历异或找到最终符合的即可得到最终结果 已知:\\ c = m^e \pmod n\\ h = (p + qi) (p + qi) = (p^2 - q^2) + 2pqi\\ h的实部和虚部已知,那么p,q便能求出来\\ 之后发现e与phi不互素\\ gcd(e,phi) = e\\ gcd(e,p^2 - 1) = gcd(e,q ^ 2 - 1) = 3\\ 可知:\\ e * d_p \equiv 3 \pmod{p^2 - 1},e * d_q \equiv 3 \pmod{q^2 - 1}\\ 利用拓展欧几里得算法求出d_p和d_q,得到:\\ m^{ed_p} \equiv m^3 \equiv c^{d_p} \pmod p\\ m^{ed_q} \equiv m^3 \equiv c^{d_q} \pmod q\\ 设m = (a + bi),则m^3 = (a^3 - 3ab^2) + (3a^2b - b^3)i\\ 通过c^{d_p} \pmod p ,c^{d_q} \pmod q 解出所以可能的a,b,即:\\ a_p \equiv a \pmod p,a_q \equiv a\pmod q ①\\ b_p \equiv b \pmod p,b_q \equiv b\pmod q ②\\ 对①,②分别进行crt得到所有可能的a,b,即key和C\\ 然后遍历异或找到最终符合的即可得到最终结果 已知:c=me(modn)h=(p+qi)(p+qi)=(p2q2)+2pqih的实部和虚部已知,那么p,q便能求出来之后发现ephi不互素gcd(e,phi)=egcd(e,p21)=gcd(e,q21)=3可知:edp3(modp21),edq3(modq21)利用拓展欧几里得算法求出dpdq,得到:medpm3cdp(modp)medqm3cdq(modq)m=(a+bi),则m3=(a33ab2)+(3a2bb3)i通过cdp(modp),cdq(modq)解出所以可能的a,b,即:apa(modp),aqa(modq)bpb(modp),bqb(modq)分别进行crt得到所有可能的a,b,即keyC然后遍历异或找到最终符合的即可得到最终结果

exp:

from Crypto.Util.number import *
from sage.matrix.matrix2 import Matrix
from gmpy2 import *

def resultant(f1, f2, var):
    return Matrix.determinant(f1.sylvester_matrix(f2, var))

class Complex:
    def __init__(self, re, im):
        self.re = re
        self.im = im

    def __mul__(self, c):
        re_ = self.re * c.re - self.im * c.im
        im_ = self.re * c.im + self.im * c.re
        return Complex(re_, im_)

    def __str__(self):
        if self.im == 0:
            return str(self.re)
        elif self.re == 0:
            if abs(self.im) == 1:
                return f"{'-' if self.im < 0 else ''}i"
            else:
                return f"{self.im}i"
        else:
            return f"{self.re} {'+' if self.im > 0 else '-'} {abs(self.im)}i"

def complex_pow(c, exp, n):
    result = Complex(1, 0)
    while exp > 0:
        if exp % 2:
            result = result * c
            result.re = result.re % n
            result.im = result.im % n
        c = c * c
        c.re = c.re % n
        c.im = c.im % n
        exp >>= 1
    return result

p2_q2 = -28814875173103880290298835537218644402443395484370652510062722255203946330565951328874411874019897676900075613671629765922970689802650462822117767927082712245512492082864958877932682404829188622269636302484189627580600076246836248427780151681898051243380477561480415972565859837597822263289141887833338111120
pq2 = 235362412848885579543400940934854106052672292040465052424316433330114813432317923674803623227280862945857543620663672974955235166884830751834386990766053503640556408758413592161122945636548462064584183165189050320898315823173824074873376450569212651128285746330837777597290934043912373820690250920839961482862
e = 9
# print(solve([p^2 - q^2 == p2_q2,p * q * 2 == pq2],[p,q]))
p = 10205509456040823453782883291824829705816298450992336115902525676510986341532486274067943978039013674207011185602314114359146043975207543018267242312660911
q = 11531144714660489617244423924607904114688972598683439999377362467380544567879231460623526800789918614728790840508257630983753525432337178000220918002499321
c = [66350931528185981323649477263900844564494528747802437244889229343520648562164950914433406604580038018765783183569276743239888668912948977370163046257917321742455772852779551569446155827368453262479370103326286297164105599131090881306108546341785251895116423206455175290083968296281375908109039893280371271943,65266730684129269806656018828265187384002656633231286337130178390517924611751697965395744944541329793503617856896706439809241745206839328124348693486741656130890593895436661857688522977866438805549144904296596887218275440542852887148071837153436265722614658566275517205322945316112048487893204059562830581004]
c = Complex(c[0],c[1])
phi = (p ** 2 - 1) * (q ** 2 - 1)

t1,dp,k1 = gmpy2.gcdext(e,p^2-1) # e * dp + k1 * (p ^ 2 - 1) = t1 = 3
t2,dq,k2 = gmpy2.gcdext(e,q^2-1)
dp = dp % (p^2 - 1)
dq = dq % (q^2 - 1)

# 得到a % p, b % p
# dp = inverse(3,(p ** 2 - 1) // 3),两个一起除3,有这种方式吗?
m3 = complex_pow(c,dp,p)
re = m3.re
im = m3.im
PR.<a,b> = PolynomialRing(Zmod(p))
f1 = a ** 3 - 3 * a * b ** 2 - re
f2 = 3 * a ** 2 * b - b ** 3 - im
g = resultant(f1,f2,a)
h = resultant(f2,f1,b)
res_ap = g.univariate_polynomial().monic().roots()
res_bp = h.univariate_polynomial().monic().roots()

# 得到a % q, b % q
m3 = complex_pow(c,dq,q)
re = m3.re
im = m3.im
P.<a,b> = PolynomialRing(Zmod(q))
f1 = a ** 3 - 3 * a * b ** 2 - re
f2 = 3 * a ** 2 * b - b ** 3 - im
g = resultant(f1,f2,a)
h = resultant(f2,f1,b)
res_aq = g.univariate_polynomial().monic().roots()
res_bq = h.univariate_polynomial().monic().roots()

key = []
for i in res_ap:
    for j in res_aq:
        k = CRT_list([int(i[0]),int(j[0])],[p,q])
        if k not in key:
            key.append(k)

C = []
for i in res_bp:
    for j in res_bq:
        cc = CRT_list([int(i[0]),int(j[0])],[p,q])
        if cc not in C:
            C.append(cc)

for i in key:
    for j in C:
        m = long_to_bytes(i ^^ j)
        if b'CTF' in m or b'flag' in m:
            print(m)
            break
# flag{Complex_is_so_fun_and_I_think_you_know_Sylvester!}            

[XYCTF2024] Complex_dlp

题目描述:

from Crypto.Util.number import *
from secrets import flag


class Complex:
    def __init__(self, re, im):
        self.re = re
        self.im = im

    def __mul__(self, c):
        re_ = self.re * c.re - self.im * c.im
        im_ = self.re * c.im + self.im * c.re
        return Complex(re_, im_)

    def __str__(self):
        if self.im == 0:
            return str(self.re)
        elif self.re == 0:
            if abs(self.im) == 1:
                return f"{'-' if self.im < 0 else ''}i"
            else:
                return f"{self.im}i"
        else:
            return f"{self.re} {'+' if self.im > 0 else '-'} {abs(self.im)}i"


def complex_pow(c, exp, n):
    result = Complex(1, 0)
    while exp > 0:
        if exp & 1:
            result = result * c
            result.re = result.re % n
            result.im = result.im % n
        c = c * c
        c.re = c.re % n
        c.im = c.im % n
        exp >>= 1
    return result


flag = flag.strip(b"XYCTF{").strip(b"}")
p = 1127236854942215744482170859284245684922507818478439319428888584898927520579579027
g = Complex(3, 7)
x = bytes_to_long(flag)
print(complex_pow(g, x, p))
# 5699996596230726507553778181714315375600519769517892864468100565238657988087817 + 198037503897625840198829901785272602849546728822078622977599179234202360717671908i

题目分析:
c = a + b i c 的模 : ∣ c ∣ = a 2 + b 2 c 的平方 : c 2 = ( a 2 − b 2 ) + 2 a b i c 方的模 : ∣ c 2 ∣ = ( a 2 − b 2 ) 2 + 4 a 2 b 2 = a 2 + b 2 可以得出 : ∣ c m ∣ = ∣ c ∣ m = ( a 2 + b 2 ) m 知道这个结论那么这题差不多就搞定了,里面的 p 又是光滑数,直接 d i s c r e r t e _ l o g 便能解决 c = a + bi\\ c的模:\\ \left| c \right| = \sqrt{a^2 + b^2}\\ c的平方:\\ c^2 = (a^2 - b^2) + 2abi\\ c方的模:\\ \left| c^2 \right| = \sqrt{(a^2 - b^2)^2 + 4a^2b^2} = a^2 + b^2\\ 可以得出:\\ \left| c^m \right| = \left| c \right| ^ m = (\sqrt{a^2 + b^2})^m\\ 知道这个结论那么这题差不多就搞定了,里面的p又是光滑数,直接discrerte\_log便能解决 c=a+bic的模:c=a2+b2 c的平方:c2=(a2b2)+2abic方的模: c2 =(a2b2)2+4a2b2 =a2+b2可以得出:cm=cm=(a2+b2 )m知道这个结论那么这题差不多就搞定了,里面的p又是光滑数,直接discrerte_log便能解决

exp:

from Crypto.Util.number import *
cc = [5699996596230726507553778181714315375600519769517892864468100565238657988087817,198037503897625840198829901785272602849546728822078622977599179234202360717671908]
p = 1127236854942215744482170859284245684922507818478439319428888584898927520579579027
G = Zmod(p)
c = cc[0] ^ 2 + cc[1] ^ 2
m = discrete_log(G(c),G(3 ** 2 + 7 ** 2))
print(long_to_bytes(m))
# XYCTF{___c0mp13x_d1p_15_3@5y_f0r_y0u___}

只能说又学到了

  • 23
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值