如果B使用的e很小,如e=3,且A传给B的明文也很小,如几个字节
那么,c = m^ e mod n 如果n很大 则可能 c = m^ e 即 c=m^ 3 即对c开三次根号
就可以得到m
如果m的三次方大于n但是没有超过太多
即 k*n
k*n - c = m^3
例题1、
n=47966708183289639962501363163761864399454241691014467172805658518368423135168025285144721028476297179341434450931955275325060173656301959484440112740411109153032840150659
e=3
c=10968126341413081941567552025256642365567988931403833266852196599058668508079150528128483441934584299102782386592369069626088211004467782012298322278772376088171342152839
from Crypto.Util.number import long_to_bytes, bytes_to_long, getPrime, isPrime
import primefac
def modinv(a, n):
return primefac.modinv(a, n) % n
n = 47966708183289639962501363163761864399454241691014467172805658518368423135168025285144721028476297179341434450931955275325060173656301959484440112740411109153032840150659
e = 3
c = 10968126341413081941567552025256642365567988931403833266852196599058668508079150528128483441934584299102782386592369069626088211004467782012298322278772376088171342152839
import gmpy2
i = 0
while 1:
if (gmpy2.iroot(c + i * n, 3)[1] == 1):
print long_to_bytes(gmpy2.iroot(c + i * n, 3)[0])
break
i = i + 1
import gmpy2
gmpy2.mpz(n)#初始化一个大整数
gmpy2.mpfr(x)# 初始化一个高精度浮点数x
d = gmpy2.invert(e,n) # 求逆元,de = 1 mod n
C = gmpy2.powmod(M,e,n)# 幂取模,结果是 C = (M^e) mod n
gmpy2.is_prime(n) #素性检测
gmpy2.gcd(a,b) #欧几里得算法,最大公约数
gmpy2.gcdext(a,b) #扩展欧几里得算法
gmpy2.iroot(x,n) #x开n次根
如果可以对任意密文解密
但不能对c解密
则使用选择密文攻击
首先求出c在n上的逆元 c^-1
再求 c^-1 的明文m ’ 为明文的逆元
再求逆
如果存在交互可以对任意密文进行解密,并获取1bit的话,则可以实现RSA parity oracle攻击
如果B使用的e仍然是3,同时A在密文m前加了段说明,即密文的一部分已泄露
或者B泄露p或q的部分
可以通过Coppersmith method求得明文
例题2、
n=6605504825889906202615748618066615187648800018528841933516316527012434141085944518043517968365397208826746013914157780887914632131531725863903538584417200527430582588764927544641557369303652648618292067488950921453386626677080964591489000067415450844331150724748818976858613279276478837816955089131430026237158610099210296694041096318330028075396562522499372070896421812111982381954403594724817813599972527870269930328689605408419124792951097063104670279395547265345199330843872092262422909324703892472836919443820718316384657112213693649570846294917435669334446894791207245948586388312000876428472397897528075326181
e=3
base=0x9876543210fedcba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
m=base+x
c=509143472960679964712061323134017269675726146763840337342493411055818623664115844443674190631269444040761374004286322788918255893217259171816916764385142572139730607623044481570957838700886892396989322684261802615250176830520657672566986118693899055342488599895558649859959818014882032199503639959456476815874298279286366688505291464700166422158955162203921387290954912301297909167283802751188777341587497155942072022517346786613010384892896362040794853435381349
目前,GitHub上提供了进行LLLattack的sage代码 参考Git 脚本
使用sage-online sagemath
选择CoCalc 注册账号 sign in ,然后 create new project
import time
debug = True
# display matrix picture with 0 and X
def matrix_overview(BB, bound):
for ii in range(BB.dimensions()[0]):
a = ('%02d ' % ii)
for jj in range(BB.dimensions()[1]):
a += '0' if BB[ii,jj] == 0 else 'X'
a += ' '
if BB[ii, ii] >= bound:
a += '~'
print a
def coppersmith_howgrave_univariate(pol, modulus, beta, mm, tt, XX):
"""
Coppersmith revisited by Howgrave-Graham
finds a solution if:
* b|modulus, b >= modulus^beta , 0 < beta <= 1
* |x| < XX
"""
#
# init
#
dd = pol.degree()
nn = dd * mm + tt
#
# checks
#
if not 0 < beta <= 1:
raise ValueError("beta should belongs in (0, 1]")
if not pol.is_monic():
raise ArithmeticError("Polynomial must be monic.")
#
# calculate bounds and display them
#
"""
* we want to find g(x) such that ||g(xX)|| <= b^m / sqrt(n)
* we know LLL will give us a short vector v such that:
||v|| <= 2^((n - 1)/4) * det(L)^(1/n)
* we will use that vector as a coefficient vector for our g(x)
* so we want to satisfy:
2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n)
so we can obtain ||v|| < N^(beta*m) / sqrt(n) <= b^m / sqrt(n)
(it's important to use N because we might not know b)
"""
if debug:
# t optimized?
print "\n# Optimized t?\n"
print "we want X^(n-1) < N^(beta*m) so that each vector is helpful"
cond1 = RR(XX^(nn-1))
print "* X^(n-1) = ", cond1
cond2 = pow(modulus, beta*mm)
print "* N^(beta*m) = ", cond2
print "* X^(n-1) < N^(beta*m) \n-> GOOD" if cond1 < cond2 else "* X^(n-1) >= N^(beta*m) \n-> NOT GOOD"
# bound for X
print "\n# X bound respected?\n"
print "we want X <= N^(((2*beta*m)/(n-1)) - ((delta*m*(m+1))/(n*(n-1)))) / 2 = M"
print "* X =", XX
cond2 = RR(modulus^(((2*beta*mm)/(nn-1)) - ((dd*mm*(mm+1))/(nn*(nn-1)))) / 2)
print "* M =", cond2
print "* X <= M \n-> GOOD" if XX <= cond2 else "* X > M \n-> NOT GOOD"
# solution possible?
print "\n# Solutions possible?\n"
detL = RR(modulus^(dd * mm * (mm + 1) / 2) * XX^(nn * (nn - 1) / 2))
print "we can find a solution if 2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n)"
cond1 = RR(2^((nn - 1)/4) * detL^(1/nn))
print "* 2^((n - 1)/4) * det(L)^(1/n) = ", cond1
cond2 = RR(modulus^(beta*mm) / sqrt(nn))
print "* N^(beta*m) / sqrt(n) = ", cond2
print "* 2^((n - 1)/4) * det(L)^(1/n) < N^(beta*m) / sqrt(n) \n-> SOLUTION WILL BE FOUND" if cond1 < cond2 else "* 2^((n - 1)/4) * det(L)^(1/n) >= N^(beta*m) / sqroot(n) \n-> NO SOLUTIONS MIGHT BE FOUND (but we never know)"
# warning about X
print "\n# Note that no solutions will be found _for sure_ if you don't respect:\n* |root| < X \n* b >= modulus^beta\n"
#
# Coppersmith revisited algo for univariate
#
# change ring of pol and x
polZ = pol.change_ring(ZZ)
x = polZ.parent().gen()
# compute polynomials
gg = []
for ii in range(mm):
for jj in range(dd):
gg.append((x * XX)**jj * modulus**(mm - ii) * polZ(x * XX)**ii)
for ii in range(tt):
gg.append((x * XX)**ii * polZ(x * XX)**mm)
# construct lattice B
BB = Matrix(ZZ, nn)
for ii in range(nn):
for jj in range(ii+1):
BB[ii, jj] = gg[ii][jj]
# display basis matrix
if debug:
matrix_overview(BB, modulus^mm)
# LLL
BB = BB.LLL()
# transform shortest vector in polynomial
new_pol = 0
for ii in range(nn):
new_pol += x**ii * BB[0, ii] / XX**ii
# factor polynomial
potential_roots = new_pol.roots()
print "potential roots:", potential_roots
# test roots
roots = []
for root in potential_roots:
if root[0].is_integer():
result = polZ(ZZ(root[0]))
if gcd(modulus, result) >= modulus^beta:
roots.append(ZZ(root[0]))
return roots
length_N = 1024 # size of the modulus
Kbits = 120 # size of the root
e = 3
N=66055048258899062026157486180666151876488000185288419335163165270124341410859445180435179683653972088267460139141577808879146321315317258639035385844172005274305825887649275446415573693036526486182920674889509214533866266770809645914890000674154508443311507247488189768586132792764788378169550891314300262371586100992102966940410963183300280753965625224993720
708964218121119823819544035947248178135999725278702699303286896054084191247929510970631046702793955472653451993308438720922624229093247038924728369194438207183163846571122136936495
70846294917435669334446894791207245948586388312000876428472397897528075326181
ZmodN = Zmod(N);
C=509143472960679964712061323134017269675726146763840337342493411055818623664115844443674190631269444040761374004286322788918255893217259171816916764385142572139730607623044481570957838700886892396989322684261802615250176830520657672566986118693899055342488599895558649859959818014882032199503639959456476815874298279286366688505291464700166422158955162203921387290954912301297909167283802751188777341587497155942072022517346786613010384892896362040794853435381349
# Problem to equation (default)
P. = PolynomialRing(ZmodN) #, implementation='NTL')
base=0x9876543210fedcba0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
pol = (2^length_N - 2^Kbits + x)^e - C
print 2^length_N
print 2^Kbits
print x
pol = (base - 2^Kbits + x)^e - C
dd = pol.degree()
# Tweak those
beta = 1 # b = N
epsilon = beta / 7 # <= beta / 7
mm = ceil(beta**2 / (dd * epsilon)) # optimized value
tt = floor(dd * mm * ((1/beta) - 1)) # optimized value
XX = ceil(N**((beta**2/dd) - epsilon)) # optimized value
# Coppersmith
start_time = time.time()
roots = coppersmith_howgrave_univariate(pol, N, beta, mm, tt, XX)
# output
print "\n# Solutions"
#print "we want to find:",str(K)
print "we found:", str(roots)
print("in: %s seconds " % (time.time() - start_time))
print "\n"
得到m=1861040492750592458109753184254913405
m=1861040492750592458109753184254913405
print long_to_bytes(m)
如果B选择的e很大 且d很小
就是维纳攻击
参考Git 脚本
例题3、
n=13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227
e=12472643612658556362688127761946639081739344859218714559709965256052431749454548817304848413467042472979918287245463205407261868802360251297270401156355632353781495808009882081279433630964865363142433940032882642884450512435389188371663310332918875493370370678126485453550431880160141317463203769606991758739033821056257388276263873215055545829450351157247182688694880384130007649807631727142268128439032681266998342978959845080161998058458873402929597438304194185927609154133353292494116640984586259361644245928207767098232359227782789358653930183953329941354597878943049060831604918661559869393575572607525778785647
c=2484709721197628568638797402073216500708160464312296481998154858152984191027965025447989735734511441378560655450049827280421394684794686868637129792025922467050637633861712489439050924034250791362044295391037523401336182117452300215045245450296408968446161318116489796932195251728012370464275380708222965034038535444718036607417409791819713679701286765333564430457444950590872952872847451701520252433653744766600366204445415719316381678856907782811329370712566969122411760039675147452944459447458029499649366966091750148097800564333924237813299417594128610382764223185901473523134684572326437208151512306054708160038
'''
Created on Dec 14, 2011
@author: pablocelayes
'''
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
import sys
sys.setrecursionlimit(10000000) #增加回溯的空间
def hack_RSA(e,n):
'''
Finds d knowing (e,n)
applying the Wiener continued fraction attack
'''
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k,d) in convergents:
#check if d is actually the key
if k!=0 and (e*d-1)%k == 0:
phi = (e*d-1)//k
s = n - phi + 1
# check if the equation x^2 - s*x + n = 0
# has integer roots
discr = s*s - 4*n
if(discr>=0):
t = Arithmetic.is_perfect_square(discr)
if t!=-1 and (s+t)%2==0:
print("Hacked!")
return d
# TEST functions
if __name__ == "__main__":
n = 13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227
e =12472643612658556362688127761946639081739344859218714559709965256052431749454548817304848413467042472979918287245463205407261868802360251297270401156355632353781495808009882081279433630964865363142433940032882642884450512435389188371663310332918875493370370678126485453550431880160141317463203769606991758739033821056257388276263873215055545829450351157247182688694880384130007649807631727142268128439032681266998342978959845080161998058458873402929597438304194185927609154133353292494116640984586259361644245928207767098232359227782789358653930183953329941354597878943049060831604918661559869393575572607525778785647
print hack_RSA(e, n)
n = 13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227
c = 2484709721197628568638797402073216500708160464312296481998154858152984191027965025447989735734511441378560655450049827280421394684794686868637129792025922467050637633861712489439050924034250791362044295391037523401336182117452300215045245450296408968446161318116489796932195251728012370464275380708222965034038535444718036607417409791819713679701286765333564430457444950590872952872847451701520252433653744766600366204445415719316381678856907782811329370712566969122411760039675147452944459447458029499649366966091750148097800564333924237813299417594128610382764223185901473523134684572326437208151512306054708160038
d=2355246239
m=pow(c,d,n)
def num2str(num):
tmp=hex(num)[2:].replace("L","")
if len(tmp) % 2 == 0:
return tmp.decode("hex")
else:
return ("0"+tmp).decode("hex")
print num2str(m)
如果d没有足够小,则尝试Boneh Durfee attack进行攻击 ,参考Git的相关脚本
B在两次通信中使用相同的n
A对相同的m加密
攻击者可以不计算d而直接算出m
例题4、
n1=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e1=65537
c1=11623242520063564721509699039034210329314238234068836130756457335142671659158578379060500554276831657322012285562047706736377103534543565179660863796496071187533860896148153856845638989384429658963134915230898572173720454271369543435708994457280819363318783413033774014447450648051500214508699056865320506104733203716242071136228269326451412159760818676814129428252523248822316633339393821052614033884661649376604245744651142959498917235138077366818109892738298251161767344501687113868331134288984466294415889635863660753717476594011236542159800099371872396181448655448842148998667568104710807411358117939831241620315
n2=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e2=70001
c2=8180690717251057689732022736872836938270075717486355807317876695012318283159440935866297644561407238807004565510263413544530421072353735781284166685919420305808123063907272925594909852212249704923889776430284878600408776341129645414000647100303326242514023325498519509077311907161849407990649396330146146728447312754091670139159346316264091798623764434932753276554781692238428057951593104821823029665203821775755835076337570281155689527215367647821372680421305939449511621244288104229290161484649056505784641486376741409443450331991557221540050574024894427139331416236263783977068315294198184169154352536388685040531
from Crypto.Util.number import long_to_bytes,bytes_to_long,getPrime,isPrime
import primefac
def same_n_attack(n,e1,e2,c1,c2):
def egcd(a, b):
x, lastX = 0, 1
y, lastY = 1, 0
while (b != 0):
q = a // b #整除
a, b = b, a % b
x, lastX = lastX - q * x, x
y, lastY = lastY - q * y, y
return (lastX, lastY)
s = egcd(e1, e2)
s1 = s[0]
s2 = s[1]
if s1<0:
s1 = - s1
c1 = primefac.modinv(c1, n)
if c1<0:
c1+=n
elif s2<0:
s2 = - s2
c2 = primefac.modinv(c2, n)
if c2<0:
c2+=n
m=(pow(c1,s1,n)*pow(c2,s2,n)) % n
return m
n1=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e1=65537
c1=11623242520063564721509699039034210329314238234068836130756457335142671659158578379060500554276831657322012285562047706736377103534543565179660863796496071187533860896148153856845638989384429658963134915230898572173720454271369543435708994457280819363318783413033774014447450648051500214508699056865320506104733203716242071136228269326451412159760818676814129428252523248822316633339393821052614033884661649376604245744651142959498917235138077366818109892738298251161767344501687113868331134288984466294415889635863660753717476594011236542159800099371872396181448655448842148998667568104710807411358117939831241620315
n2=21660190931013270559487983141966347279666044468572000325628282578595119101840917794617733535995976710097702806131277006786522442555607842485975616689297559583352413160087163656851019769465637856967511819803473940154712516380580146620018921406354668604523723340895843009899397618067679200188650754096242296166060735958270930743173912010852467114047301529983496669250671342730804149428700280401481421735184899965468191802844285699985370238528163505674350380528600143880619512293622576854525700785474101747293316814980311297382429844950643977825771268757304088259531258222093667847468898823367251824316888563269155865061
e2=70001
c2=8180690717251057689732022736872836938270075717486355807317876695012318283159440935866297644561407238807004565510263413544530421072353735781284166685919420305808123063907272925594909852212249704923889776430284878600408776341129645414000647100303326242514023325498519509077311907161849407990649396330146146728447312754091670139159346316264091798623764434932753276554781692238428057951593104821823029665203821775755835076337570281155689527215367647821372680421305939449511621244288104229290161484649056505784641486376741409443450331991557221540050574024894427139331416236263783977068315294198184169154352536388685040531
print long_to_bytes(same_n_attack(n1,e1,e2,c1,c2))
B选择的e较小,且几次加密的信息m相同
c1 = m ^ e mod n1
c2 = m ^ e mod n2
c3 = m ^ e mod n3
根据[中国剩余定理]计算出cx (https://baike.baidu.com/item/%E5%AD%99%E5%AD%90%E5%AE%9A%E7%90%86/2841597?fromtitle=%E4%B8%AD%E5%9B%BD%E5%89%A9%E4%BD%99%E5%AE%9A%E7%90%86&fromid=11200132&fr=aladdin)
cx = m ^ 3 mod n1n2n3
对cx开三次方即可得到m
例题5、
n1=3184273000603708051896374137923057198211094334842809424557962637794782294801864792420893981755335234175142208934607215450839499631632458122838975649379772518852683463113247078803930872516973728738441477403263782150655688059864351001382601317415565787754938842833471427987313456225237136522569229199767714029113186946128721192639026803724478281061905375839801790561887634449609831256952724334929701867762108269704279672633736501207795045621445495684841694147281740978497396349681590938795053712843157558911448741672887265329408905522288945271247306062164169083799080581576844026544196507061780947576680321314108392647
e1=3
c1=1865207266799996243228817304785105186128313762026459662106438140987810119638576035455810918192610162974644804325700727033397631237565568309250447997692957047117948414605262707210503694076217753671199536395804376735980939475943306552210578935155360834667472016665676094531937175375189119576834726559914368446599747335583484488400218726081559377872231484682832323487891260169871842137971634220678913614199693895028277295936272132967943949212045133910468330075523225546555284462267175192647725355824897112645323595082325014848213949996106219123466528151645552827456831521727714312875817605387842910776003281468632177134
n2=5947242496412590165886022830117979031270849438565414718945540769656801659060145414012439040675436355554730985758732378038388730643183490705333543982433697770161034284340019436698252581207947899331724870247713348112513551744856203618474445966867979101613482134937251288025326239040546312157563226597808206728974063266847623663376197620795712476379614206184866600891814266441420096950858632266041468432728039098235219202429667813023866281876260313319408789799168671371967931911067693233943058351630136956131977019545880612393331500862363561705686291751808121307659369950091831457743559304935521177616970170121899847499
e2=3
c2=5329839376003386424531390530291755253783136537372306970258380778841411938968277820730736914044469924457037948618895817081183967847747849864612418345235974595324704489015633061981019979529325160156304788684511539016419138205029103288532049627836528718735354249479611169423184818835225060964820758060879400538668119624133333610160075028319073912202797807572706643548716922456176911646487273693616082924469901327385014547016959814916531765625265956350393314015819147117668292817998166701212842593565668481237562334160409111280245721133821729698831956884879852048076463825139448367617549344936160289592539599562603182308
n3=1619477568975952701259057615681948469998598727467548920567987371583808541608865794715674249299251982223554463245267913319011439540372690719318616625432515649945415072879857399935962243093033020212726392446482688722523597117616715421450234027457487384685541370636909037532024494764235715359165776748613722244237454618534625777019222793493467304333894049695939845924618377175428182083061659479862995561534893358459425241809160308555104350834921888371703396141707886926364364568511870728602018394122222536081801604623257186337824087463875063459411092787941122075073888812296045329605966948887174839303850054066549742331
e3=3
c3=56537261971453461628378794041129292234708934241500623599492236054809993089458119558859048280887450688383162997431051833341166123967621065567645821142714578598634926086505265631519468437627610732981529419608470499569773474149861616309893753444615252761070299110608388653964994342395869950839385196794419980540285703423073352381718752590813640713624989959818173320902028724671829912267909600281104679202709735798484743339777607531820611774508541070974653249746559131361804224877198967927897074633208445500712006065089400145934143164857831974809927265562676588011008120329753404441512900600390241426493424854902736641
三次都使用e=3作为加密指数
假设三次加密的明文是相同的
'''
Created on Dec 14, 2011
@author: pablocelayes
'''
import ContinuedFractions, Arithmetic, RSAvulnerableKeyGenerator
import sys
sys.setrecursionlimit(10000000)
def hack_RSA(e,n):
'''
Finds d knowing (e,n)
applying the Wiener continued fraction attack
'''
frac = ContinuedFractions.rational_to_contfrac(e, n)
convergents = ContinuedFractions.convergents_from_contfrac(frac)
for (k,d) in convergents:
#check if d is actually the key
if k!=0 and (e*d-1)%k == 0:
phi = (e*d-1)//k
s = n - phi + 1
# check if the equation x^2 - s*x + n = 0
# has integer roots
discr = s*s - 4*n
if(discr>=0):
t = Arithmetic.is_perfect_square(discr)
if t!=-1 and (s+t)%2==0:
print("Hacked!")
return d
# TEST functions
if __name__ == "__main__":
n = 13135748152922068851807562259991833526175730777484124023612993851829955443156593171810566108770514215820542984343663846287282386582824043046503748787889589613007129391469246232735543477149929538968188602282461287596233699800185109030346300685879023327539247264141675982725321923319965267452566983753865159969071487636488204871579930383673347045053870063722175608993080162716415486448027532424383724695071801571322005261106334877334047211659397929333555608837107626755393427056320625857002257080722498437768960750360112169740061492146894798308307571752422769821088492368556922971780160003588288119154938395902573141227
e =12472643612658556362688127761946639081739344859218714559709965256052431749454548817304848413467042472979918287245463205407261868802360251297270401156355632353781495808009882081279433630964865363142433940032882642884450512435389188371663310332918875493370370678126485453550431880160141317463203769606991758739033821056257388276263873215055545829450351157247182688694880384130007649807631727142268128439032681266998342978959845080161998058458873402929597438304194185927609154133353292494116640984586259361644245928207767098232359227782789358653930183953329941354597878943049060831604918661559869393575572607525778785647
print hack_RSA(e, n)
A使用同一公钥对两个具有某种线性关系的消息m1,m2进行加密为c1,c2
发给B
攻击者可以获得m1,m2
假设线性关系为 m1 = a * m2 + b
且 e = 3 可以得到 m2 =
要怎么知道a和b
且满足以上关系?
题目会给吧?
def relate_message_attack(a, b, c1, c2, n):
b3 = gmpy2.powmod(b, 3, n)
part1 = b * (c1 + 2 * c2 - b3) % n
part2 = a * (c1 - c2 + 2 * b3) % n
part2 = gmpy2.invert(part2, n)
return part1 * part2 % n
离散对数问题
使用相同的k 和 r
。。。