[NPUCTF2020]认清形势,建立信心
[NPUCTF2020]认清形势,建立信心
题目
from Crypto.Util.number import *
from gmpy2 import *
from secret import flag
p = getPrime(25)
e = # Hidden
q = getPrime(25)
n = p * q
m = bytes_to_long(flag.strip(b"npuctf{").strip(b"}"))
c = pow(m, e, n)
print(c)
print(pow(2, e, n))
print(pow(4, e, n))
print(pow(8, e, n))
'''
169169912654178
128509160179202
518818742414340
358553002064450
'''
题解
首先我们看看题目给的条件,没给e,但是给了c,c1,c2,c3,其中:
\(c=m^e\,mod\,n\)
\(c1=2^e\,mod\,n\)
\(c2=4^e\,mod\,n\)
\(c3=8^e\,mod\,n\)
此时,根据定义得到:\(c_{1}^2=c_{2}+k_{1}n\) ------式1
进而得到:\(k_{1}n=c_{1}^2-c_{2}\)
同理:\(c_{1}c_{2}=c_{3}+k_{2}n\) ------式2
联立方程,求最大公因数:n = \(gcd( c_{1} ^ 2 - c_{2} , c_{1} * c_{2} -c_{3})\)
1054494004042394
由此得到n。
分解n:
由此可以得到p,q,最后就可以常规做题。
关于e,此处需要用离散对数求解:
求解 g^x = a mod n
python(sympy库) x=sympy.discrete_log(n,a,g)
from Crypto.Util.number import*
from gmpy2 import*
from sympy import*
from libnum import*
c = 169169912654178
p = 28977097
q = 18195301
n = p*q
e = discrete_log(n,c1,2)#通过离散对数求出e
phi = (p-1)*(q-1)
d= invert(e,phi)
m = n2s(pow(c,int(d),n))
print(m)
b'345y!'
附录
MOD运算
取余与取模还是有区别的,见 https://blog.csdn.net/coder_panyy/article/details/73743722
mod运算,即求余(取模)运算,是在整数运算中求一个整数 x 除以另一个整数y的余数的运算,且不考虑运算的商。在计算机程序设计中都有MOD运算,其格式为: mod(nExp1,nExp2),即是两个数值表达式作除法运算后的余数。
给定一个正整数p,任意一个整数n,一定存在等式 :
取模运算:a % p(或a mod p),表示a除以p的余数。
运算规则
模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a + b) % p = (a % p + b % p) % p (1)
(a - b) % p = (a % p - b % p) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
a ^ b % p = ((a % p)^b) % p (4)
结合律:
((a+b) % p + c) % p = (a + (b+c) % p) % p (5)
((ab) % p * c)% p = (a * (bc) % p) % p (6)
交换律:
(a + b) % p = (b+a) % p (7)
(a * b) % p = (b * a) % p (8)
分配律:
(a+b) % p = ( a % p + b % p ) % p (9)
((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (10)
重要定理:
若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);(11)
若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);(12)
若a≡b (% p),c≡d (% p),则 (a + c) ≡ (b + d) (%p),(a - c) ≡ (b - d) (%p),(a * c) ≡ (b * d) (%p);