import gmpy2
def GCRT(mi, ai):
# mi,ai分别表示模数和取模后的值,都为列表结构
assert (isinstance(mi, list) and isinstance(ai, list))
curm, cura = mi[0], ai[0]
for (m, a) in zip(mi[1:], ai[1:]):
d = gmpy2.gcd(gmpy2.mpz(curm), gmpy2.mpz(m))
c = a - cura
assert (c % d == 0) #不成立则不存在解
K = c // d * gmpy2.invert(gmpy2.mpz(curm // d), gmpy2.mpz(m // d))
cura += curm * K
curm = curm * m // d
cura %= curm
return (int(cura % curm), int(curm)) #(解,最小公倍数)
if __name__ == '__main__':
m=[3,5,7,11,13,17,19]
a=[2,3,4,5,6,7,8]
print(GCRT(m,a))
定理:
假定 g c d ( a , b ) = g c d ( c , d ) = 1 gcd(a,b)=gcd(c,d)=1 gcd(a,b)=gcd(c,d)=1且 ∣ a b − c d ∣ < 1 2 d 2 \left|\frac{a}{b}-\frac{c}{d}\right|< \frac{1}{2d^2} ∣∣∣ba−dc∣∣∣<2d21那么 c d \cfrac{c}{d} dc 是 a b \cfrac{a}{b} ba 连分数展开的一个收敛子
摘自 https://www.tr0y.wang/2017/11/06/CTFRSA/index.html
import gmpy2
import time
from binascii import unhexlify
# 展开为连分数
def continuedFra(x, y):
cF = []
while y:
cF += [x // y]
x, y = y, x % y
return cF
def Simplify(ctnf):
numerator = 0
denominator = 1
for x in ctnf[::-1]:
numerator, denominator = denominator, x * denominator + numerator
return (numerator, denominator)
# 连分数化简
def calculateFrac(x, y):
cF = continuedFra(x, y)
cF = map(Simplify, [cF[0:i] for i in range(1, len(cF))])
return cF
# 解韦达定理
def solve_pq(a, b, c):
temp=b*b-4*a*c
if temp>=0:
par = gmpy2.isqrt(temp)
return (-b + par) // (2 * a), (-b - par) // (2 * a)
def wienerAttack(e, n):
for (d, k) in calculateFrac(e, n):
if k == 0: continue
if (e * d - 1) % k != 0: continue
phi = (e * d - 1) // k
if phi<n:
p, q = solve_pq(1, n - phi + 1, n)
if p * q == n:
return abs(int(p)), abs(int(q))
print('not find!')
time.clock()
n = 12238605063252292170613110607692779326628090745751955692266649177882959231822580682548279800443278979485092243645806337103841086023159482786712759291169541633901936290854044069486201989034158882661270017305064348254800318759062921744741432214818915527537124001063995865927527037625277330117588414586505635959411443039463168463608235165929831344586283875119363703480280602514451713723663297066810128769907278246434745483846869482536367912810637275405943566734099622063142293421936734750356828712268385319217225803602442033960930413469179550331907541244416573641309943913383658451409219852933526106735587605884499707827
e = 11850552481503020257392808424743510851763548184936536180317707155841959788151862976445957810691568475609821000653594584717037528429828330763571556164988619635320288125983463358648887090031957900011546300841211712664477474767941406651977784177969001025954167441377912326806132232375497798238928464025466905201977180541053129691501120197010080001677260814313906843670652972019631997467352264392296894192998971542816081534808106792758008676039929763345402657578681818891775091140555977382868531202964486261123748663752490909455324860302967636149379567988941803701512680099398021640317868259975961261408500449965277690517
c = 9472193174575536616954091686751964873836697237500198884451530469300324470671555310791335185133679697207007374620225900775502162690848135615431624557389304657410880981454777737587420426091879654002644281066474715074536611611252677882396384453641127487515845176069574754606670518031472235144795376526854484442135299818868525539923568705203042265537204111153151119105287648912908771710419648445826883069030285651763726003413418764301988228077415599665616637501056116290476861280240577145515875430665394216054222788697052979429015400411487342877096677666406389711074591330476335174211990429870900468249946600544116793793
p, q = wienerAttack(e, n)
print('[+]Found!')
print(' [-]p =',p)
print(' [-]q =',q)
print(' [-]n =',p*q)
d = gmpy2.invert(e,(p-1)*(q-1))
print(' [-]d =', d)
m=hex(pow(c,d,n))
print(' [-]m is:' + str(unhexlify(m[2:])))
print('\n[!]Timer:', round(time.clock(),2), 's')
print('[!]All Done!')
#Tr0y{W1eNer_AttaCk_1s_p0werfu1!}
Rabin 密码体制
设 n = p q n=pq n=pq,其中 p , q p,q p,q为素数,且 p , q ≡ 3 ( m o d 4 ) p,q\equiv 3\pmod 4 p,q≡3(mod4)。设 P = C = Z n ∗ \mathcal{P=C }=\mathbb{Z}_n^* P=C=Zn∗,且定义 K = ( n , p , q ) \mathcal{K}={(n,p,q)} K=(n,p,q)对 K = ( n , p , q ) K=(n,p,q) K=(n,p,q),定义 e K ( x ) = x 2 m o d n d K ( x ) = y m o d n \begin{aligned} e_K(x)&=x^2\mod n\\ d_K(x)&=\sqrt{y}\mod n \end{aligned} eK(x)dK(x)=x2modn=ymodn n n n为公钥, p , q p,q p,q为私钥
import gmpy2
def rabin_decrypt(c, p, q, e=2):
n = p * q
mp=pow(c,(p+1)//4,p)
mq=pow(c,(q+1)//4,q)
yp = gmpy2.invert(p, q)
yq = gmpy2.invert(q, p)
r = (yp * p * mq + yq * q * mp) % n
rr = n - r
s = (yp * p * mq - yq * q * mp) % n
ss = n - s
return (r, rr, s, ss)