Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/test/test_rsa.py
2587 views
1
import os
2
import sys
3
from hashlib import sha256
4
from math import lcm
5
from random import getrandbits
6
from random import randrange
7
from unittest import TestCase
8
9
from Crypto.Cipher import PKCS1_v1_5
10
from Crypto.PublicKey import RSA
11
from sage.all import crt
12
13
path = os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__))))
14
if sys.path[1] != path:
15
sys.path.insert(1, path)
16
17
from attacks.rsa import bleichenbacher
18
from attacks.rsa import bleichenbacher_signature_forgery
19
from attacks.rsa import boneh_durfee
20
from attacks.rsa import cherkaoui_semmouni
21
from attacks.rsa import common_modulus
22
from attacks.rsa import crt_fault_attack
23
from attacks.rsa import d_fault_attack
24
from attacks.rsa import desmedt_odlyzko
25
from attacks.rsa import extended_wiener_attack
26
from attacks.rsa import hastad_attack
27
from attacks.rsa import known_crt_exponents
28
from attacks.rsa import known_d
29
from attacks.rsa import low_exponent
30
from attacks.rsa import lsb_oracle
31
from attacks.rsa import manger
32
from attacks.rsa import nitaj_crt_rsa
33
from attacks.rsa import non_coprime_exponent
34
from attacks.rsa import partial_key_exposure
35
from attacks.rsa import related_message
36
from attacks.rsa import stereotyped_message
37
from attacks.rsa import wiener_attack
38
from attacks.rsa import wiener_attack_common_prime
39
from attacks.rsa import wiener_attack_lattice
40
from shared.partial_integer import PartialInteger
41
42
43
class TestRSA(TestCase):
44
def _crt_faulty_sign(self, m, p, q, d):
45
sp = pow(m, (d % (p - 1)), p)
46
sq = pow(m, (d % (q - 1)), q)
47
# Random bitflip?
48
return crt([sp, sq ^ 1], [p, q])
49
50
def _valid_padding_v1_5(self, cipher, k, c, sentinel):
51
return cipher.decrypt(c.to_bytes(k, byteorder="big"), sentinel) != sentinel
52
53
def _valid_padding_oaep(self, n, d, B, c):
54
return pow(c, d, n) < B
55
56
def test_bleichenbacher(self):
57
p = 8371433218848358145038188834376952780015970046874950635276595345380605659774957836526221018721547441806561287602735774125878237978059976407232379361297183
58
q = 11466377869587829648871708469119992174705652479796097233499813683057983019116298140412758762054846456284362676185136356912754651085919371755263313171141577
59
n = p * q
60
phi = (p - 1) * (q - 1)
61
e = 65537
62
d = pow(e, -1, phi)
63
k = 128
64
cipher = PKCS1_v1_5.new(RSA.construct((n, e, d)))
65
sentinel = b"\x00" * k
66
67
# We know it doesn't take too long to decrypt this c using Bleichenbacher's attack (~7700 queries).
68
c = 41825379700061736537842449489601003429572348310436151924728709132681706878857980459161227458335791180711615257337302674792944628957924785690808047623816090305399357488221035015598239161665727483209037254608986214222956682098319678174134123989991914343760644546568563066348494878863941359213637733834134515197
69
m = pow(c, d, n)
70
m_ = bleichenbacher.attack(lambda c: self._valid_padding_v1_5(cipher, k, c, sentinel), n, e, c)
71
self.assertIsInstance(m_, int)
72
self.assertEqual(m, m_)
73
74
def test_bleichenbacher_signature_forgery(self):
75
suffix_bit_length = 32
76
suffix = getrandbits(suffix_bit_length) | 1
77
s = bleichenbacher_signature_forgery.attack(suffix, suffix_bit_length)
78
self.assertEqual(suffix, (s ** 3) % (2 ** suffix_bit_length))
79
80
def test_boneh_durfee(self):
81
p = 11227048386374621771175649743442169526805922745751610531569607663416378302561807690656370394330458335919244239976798600743588701676542461805061598571009923
82
q = 7866790440964395011005623971351568677139336343167390105188826934257986271072664643571727955882500173182140478082778193338086048035817634545367411924942763
83
N = p * q
84
phi = (p - 1) * (q - 1)
85
d = 186493804207318317888355025415200212277761144340233864189538741099969492009806507
86
e = pow(d, -1, phi)
87
p_, q_ = boneh_durfee.attack(N, e, 512, delta=0.26, m=3, t=1)
88
self.assertIsInstance(p_, int)
89
self.assertIsInstance(q_, int)
90
self.assertEqual(N, p_ * q_)
91
92
p = 7429785514579250742801544775265919278101812347596990219952070295565832940068576050760172625797740177649856558303705228580697611655581924559792513787731167
93
q = 8956454992912744191779370381876516510424600089358399536385007696509658160926748770877487393045391618009844430934391226063349509549521733003051142111030287
94
N = p * q
95
phi = (p - 1) * (q - 1)
96
d = 223183300830113475659369178959679373721083232456560212434233450629223847114638106475011
97
e = pow(d, -1, phi)
98
p_, q_ = boneh_durfee.attack(N, e, 512, partial_p=PartialInteger.lsb_of(p, 512, 128), delta=0.28, m=1, t=0)
99
self.assertIsInstance(p_, int)
100
self.assertIsInstance(q_, int)
101
self.assertEqual(N, p_ * q_)
102
103
p = 8325745168193178400972753040703564893084541200047412976661161282688302811539795532035273420999644691751298134426448708785219125098284622056451489331098141
104
q = 7080360719238751828185760219712847628159086532214243460775078410347307461032019124186884558243018527644736008056891972556933157682087344942706360469169019
105
r = 8317461401474723268496312721678641458178047856339708030999240370931245730754892293396238744093254583460495063266635764778620495121324799900121222370364617
106
s = 13199869133047572552535353227205776086152310145389840540109659625854798126285664271625603061537083584881441157707264706431629568363715148727252158453179283
107
N = p * q * r * s
108
phi = (p - 1) * (q - 1) * (r - 1) * (s - 1)
109
d = 49488085514473555048624238840378082040802728458021785503334637098083
110
e = pow(d, -1, phi)
111
p_, q_, r_, s_ = boneh_durfee.attack_multi_prime(N, e, 512, 4, delta=0.1, m=6, t=1)
112
self.assertIsInstance(p_, int)
113
self.assertIsInstance(q_, int)
114
self.assertIsInstance(r_, int)
115
self.assertIsInstance(s_, int)
116
self.assertEqual(N, p_ * q_ * r_ * s_)
117
118
def test_cherkaoui_semmouni(self):
119
p = 6970095733639071098312656967411917275080643486698328141048794358773925405193762089371592275422356527243822408600697915626180888948121089544657377661918979
120
q = 18449203001167453683629192798359337118936602406279119934040327468259582280616884846975771623742879592317716054643763931279691320991968677567970772946431553
121
N = p * q
122
e = 656004714415520925304508553062370903160906373260831418376155234031103953028701728516709845078613446850436012766664203901926239975184100878753982194671184344505363800201667709052712179034821539184811191176529116980190742276358408178606066309312751094947345719752727377127867556038310739729060906061649394093586530631375649773615277283004263492460300787257925544540880532938726325093230854039509246401675172466582706119200957333207569754235900939815154013060113002778680466566882320776451125153612349115209357634306021723449044334437447021870514950670965340761003414186271235218807491067981771194625563633604657797629
123
d = pow(e, -1, (p ** 2 - 1) * (q ** 2 - 1))
124
beta = 0.5
125
delta = 0.54
126
p_, q_, d_ = cherkaoui_semmouni.attack(N, e, beta, delta, m=5)
127
self.assertIsInstance(p_, int)
128
self.assertIsInstance(q_, int)
129
self.assertIsInstance(d_, int)
130
self.assertEqual(N, p_ * q_)
131
self.assertEqual(d, d_)
132
133
def test_common_modulus(self):
134
p = 7533786619797084306332779503584785720237908463304409345290805538825354595934248304351730420702977327869673269459606431198799644428816355505475872341745119
135
q = 11736209613542675168896166783523457796515430159358741698291601755512636680940041591293981708617818996457987754784026535146391007150954925977654218732583633
136
n = p * q
137
e1 = 65537
138
c1 = pow(2, e1, n)
139
e2 = 65539
140
c2 = pow(2, e2, n)
141
m = common_modulus.attack(n, e1, c1, e2, c2)
142
self.assertIsInstance(m, int)
143
self.assertEqual(2, m)
144
n = p * q
145
e1 = 63
146
c1 = pow(2, e1, n)
147
e2 = 49
148
c2 = pow(2, e2, n)
149
m = common_modulus.attack(n, e1, c1, e2, c2)
150
self.assertIsInstance(m, int)
151
self.assertEqual(2, m)
152
153
def test_crt_fault_attack(self):
154
p = 8150877473027126093427463792139267852911319917170724105457477564851230704467622727076433793531165751815106108729858930625206375479823641419198589291521783
155
q = 8132196267040442193310214709294656320409440622341548548251972647317954574860663207153805527629987938053400479709802456536736870430458263552910515400645909
156
n = p * q
157
phi = (p - 1) * (q - 1)
158
e = 65537
159
d = pow(e, -1, phi)
160
p_, q_ = crt_fault_attack.attack_known_m(n, e, 2, self._crt_faulty_sign(2, p, q, d))
161
self.assertIsInstance(p_, int)
162
self.assertIsInstance(q_, int)
163
self.assertEqual(n, p_ * q_)
164
165
p_, q_ = crt_fault_attack.attack_unknown_m(n, e, pow(2, d, n), self._crt_faulty_sign(2, p, q, d))
166
self.assertIsInstance(p_, int)
167
self.assertIsInstance(q_, int)
168
self.assertEqual(n, p_ * q_)
169
170
def test_d_fault_attack(self):
171
p = 11711858679422576139240623353912034730578750025305511997160442356437636294934848077337818067479185593605531008093226275733420002636468432350557846723886129
172
q = 11362676749997147110865246846859793005675832462810186294516539616676027025614775954113496330880795201537135407817378604172135795945348591541580522484363839
173
n = p * q
174
phi = (p - 1) * (q - 1)
175
e = 65537
176
d = pow(e, -1, phi)
177
sv = pow(2, d, n)
178
sf = []
179
for i in range(d.bit_length()):
180
sf.append(pow(2, d ^ (2 ** i), n))
181
d_ = d_fault_attack.attack(n, e, sv, sf)
182
self.assertIsInstance(d_, PartialInteger)
183
lsb, lsb_bit_length = d_.get_known_lsb()
184
self.assertIsInstance(lsb, int)
185
self.assertIsInstance(lsb_bit_length, int)
186
self.assertEqual(d, lsb)
187
self.assertEqual(d.bit_length(), lsb_bit_length)
188
189
sf = []
190
for i in range(384):
191
sf.append(pow(2, d ^ (2 ** i), n))
192
d_ = d_fault_attack.attack(n, e, sv, sf)
193
self.assertIsInstance(d_, PartialInteger)
194
lsb, lsb_bit_length = d_.get_known_lsb()
195
self.assertIsInstance(lsb, int)
196
self.assertIsInstance(lsb_bit_length, int)
197
self.assertEqual(d % (2 ** 384), lsb)
198
self.assertEqual(384, lsb_bit_length)
199
200
def test_desmedt_odlyzko(self):
201
p = 97164923933597891368559775050432519012034358306405340946100833095770328943676411310628656642026913097035188965406025957744495809556827045737345114790763524883526919749849156670762148425581036752109600896844274905771163440683527068529651911795698170268844514398131442858441702974028897564993245872764301596397
202
q = 109712022838692588796818474700409969126344450902860551087011803034678579584276407066098123240292070455715313066927016909739145402676756809804326474562269097078787526578676643824546284396305927118696509187348588587237261529370838503470176017203514480490343882354075192486431376267056466433423025173883070036753
203
e = 65537
204
N = p * q
205
phi = (p - 1) * (q - 1)
206
d = pow(e, -1, phi)
207
hash_oracle = lambda m: int.from_bytes(sha256(int.to_bytes(m, length=256, byteorder="big")).digest()[:6], byteorder="big")
208
sign_oracle = lambda m: pow(hash_oracle(m), d, N)
209
m = 226572932144966770252674249388577138444
210
s = desmedt_odlyzko.attack(hash_oracle, sign_oracle, N, e, m)
211
self.assertIsInstance(s, int)
212
self.assertEqual(sign_oracle(m), s)
213
214
def test_extended_wiener_attack(self):
215
p = 8962183829526343305205665485515731618546029297439020752534914809943234334520404067067844789415616008948709769282722944473756884384422045609586429488722819
216
q = 11411892842209276999318813933411657011974573219176710970747439412565013759888750685922800578656539187278906477356731952452991129515326613660882430066260819
217
n = p * q
218
phi = (p - 1) * (q - 1)
219
d = 440954678851095847880440879288062150659228888630394444179267052000328032629057
220
e = pow(d, -1, phi)
221
p_, q_, d_ = extended_wiener_attack.attack(n, e)
222
self.assertIsInstance(p_, int)
223
self.assertIsInstance(q_, int)
224
self.assertIsInstance(d_, int)
225
self.assertEqual(n, p_ * q_)
226
self.assertEqual(d, d_)
227
228
def test_hastad_attack(self):
229
p1 = 12238840029255924128261773522963221621618780074771826797770294317526342852350770883811112904932108204101484192491928770368834167240882579171193850986455837
230
q1 = 13306004827159916516668671929416638896131274743270820358013499224556726271497309928832980035890202435607219787395468188298808904166109749334050937132938949
231
N1 = p1 * q1
232
p2 = 9149751951348929830842108648504857237452181353320105251018875434647249480437833769024227357098540650986406158506119142206123567682084983914483649896955031
233
q2 = 10962586930565548132182648587084973374856002202116447680609772870896293614345215136882972661918694230862242667644357410793563474164022674847478495643859707
234
N2 = p2 * q2
235
p3 = 11284208912156948389112340915544186206038140125122638896201517533912332670535585694142522536564438510193351757394235927874009400917334726959807635615623447
236
q3 = 7144946753190813042748893143186445123501153567914769538177683884450935779036215877932244882643383332398676793582493702385999026643632800861421136743084943
237
N3 = p3 * q3
238
N = [N1, N2, N3]
239
e = 3
240
m = randrange(1, min(N))
241
c = [pow(m, e, n) for n in N]
242
m_ = hastad_attack.attack(N, e, c)
243
self.assertIsInstance(m_, int)
244
self.assertEqual(m, m_)
245
246
def test_known_crt_exponents(self):
247
p = 9734878849445118420073785869554836149487671692719552358756738189651079813869054963335880039395402041883956221923435780797276507555906725160774871585184181
248
q = 11608927577332560028819160266239104364716512653498293226451614650722863458488829019269383773936258272349564355274218301207779572980847476544743569746719093
249
N = p * q
250
phi = (p - 1) * (q - 1)
251
e = 65537
252
d = pow(e, -1, phi)
253
dp = d % (p - 1)
254
dq = d % (q - 1)
255
256
p_, q_ = next(known_crt_exponents.attack(e, e + 2, N=N, dp=dp, dq=dq))
257
self.assertIsInstance(p_, int)
258
self.assertIsInstance(q_, int)
259
self.assertEqual(N, p_ * q_)
260
261
p_, q_ = next(known_crt_exponents.attack(e, e + 2, N=N, dp=dp))
262
self.assertIsInstance(p_, int)
263
self.assertIsInstance(q_, int)
264
self.assertEqual(N, p_ * q_)
265
266
p_, q_ = next(known_crt_exponents.attack(e, e + 2, N=N, dq=dq))
267
self.assertIsInstance(p_, int)
268
self.assertIsInstance(q_, int)
269
self.assertEqual(N, p_ * q_)
270
271
p_, q_ = next(known_crt_exponents.attack(e, e + 2, dp=dp, dq=dq, p_bit_length=512, q_bit_length=512))
272
self.assertIsInstance(p_, int)
273
self.assertIsInstance(q_, int)
274
self.assertEqual(N, p_ * q_)
275
276
p_ = next(known_crt_exponents.attack(e, e + 2, dp=dp, p_bit_length=512))
277
self.assertIsInstance(p_, int)
278
self.assertEqual(p, p_)
279
280
q_ = next(known_crt_exponents.attack(e, e + 2, dq=dq, q_bit_length=512))
281
self.assertIsInstance(q_, int)
282
self.assertEqual(q, q_)
283
284
p_, q_ = known_crt_exponents.attack_partial(N, e, PartialInteger.msb_of(dp, 512, 256), PartialInteger.msb_of(dq, 512, 256), m=12, t=12)
285
self.assertIsInstance(p_, int)
286
self.assertIsInstance(q_, int)
287
self.assertEqual(N, p_ * q_)
288
289
p_, q_ = known_crt_exponents.attack_partial(N, e, PartialInteger.msb_of(dp, 512, 250), PartialInteger.msb_of(dq, 512, 256), m=12, t=12)
290
self.assertIsInstance(p_, int)
291
self.assertIsInstance(q_, int)
292
self.assertEqual(N, p_ * q_)
293
294
p_, q_ = known_crt_exponents.attack_partial(N, e, PartialInteger.msb_of(dp, 512, 256), PartialInteger.msb_of(dq, 512, 250), m=12, t=12)
295
self.assertIsInstance(p_, int)
296
self.assertIsInstance(q_, int)
297
self.assertEqual(N, p_ * q_)
298
299
p_, q_ = known_crt_exponents.attack_partial(N, e, PartialInteger.lsb_of(dp, 512, 256), PartialInteger.lsb_of(dq, 512, 256), m=12, t=12)
300
self.assertIsInstance(p_, int)
301
self.assertIsInstance(q_, int)
302
self.assertEqual(N, p_ * q_)
303
304
def test_known_d(self):
305
p = 10999882285407021659159843781080979389814097626452668846482424135627220062700466847567575264657287989126943263999867722090759547565297969535143544253926071
306
q = 12894820825544912052042889653649757120734073367261758361676140208842841153775542379620171049124260330205408767340830801133280422958906941622318918402459837
307
N = p * q
308
phi = (p - 1) * (q - 1)
309
e = 65537
310
d = pow(e, -1, phi)
311
p_, q_ = known_d.attack(N, e, d)
312
self.assertIsInstance(p_, int)
313
self.assertIsInstance(q_, int)
314
self.assertEqual(N, p_ * q_)
315
316
def test_low_exponent(self):
317
p = 9986125479694016854025755367445175452530216355562157491330590823336719733036951311021826749434458567507026083133496160725058402273547442823833685509967273
318
q = 12293819014809525648804227133537870654400268644981770162408394971640722282699968884616070906255021397809508228502095517082589847093280122278875399671016389
319
N = p * q
320
e = 3
321
m = 2
322
c = pow(m, e, N)
323
m_ = low_exponent.attack(e, c)
324
self.assertIsInstance(m_, int)
325
self.assertEqual(m, m_)
326
327
def test_lsb_oracle(self):
328
p = 12985611093825944663135178568290848860236181456084556611626171071415242183946266010353415826192399871882183745902546414611421756977935905528192863016989159
329
q = 13073385370532298716818627887268175297799825572859798576497950347156227722627325929275754625614964552408176766458085714046147326787707303279702573013743377
330
N = p * q
331
phi = (p - 1) * (q - 1)
332
e = 65537
333
d = pow(e, -1, phi)
334
m = randrange(1, N)
335
c = pow(m, e, N)
336
m_ = lsb_oracle.attack(N, e, c, lambda c: pow(c, d, N) & 1)
337
self.assertIsInstance(m_, int)
338
self.assertEqual(m, m_)
339
340
def test_manger(self):
341
p = 11550140397625831237795340388931764619590203348477070899900744712142057429184408396002838334752152208585447782690486121190515605653404086833126302256665293
342
q = 11235144439517708878544315543777445305219755865213735904183809061384223163112309675101975657775860815518111926557521605302651507623721470417911684612028139
343
n = p * q
344
phi = (p - 1) * (q - 1)
345
e = 65537
346
d = pow(e, -1, phi)
347
k = 128
348
B = 2 ** (8 * (k - 1))
349
350
# We know it doesn't take too long to decrypt this c using Manger's attack (~1000 queries).
351
c = 88724310553655024406998673890906955926769391892532500091257501059546128411164957509885727337380526571122120832873601676837576704085217211100300291225160276367472411100146256463969941418608788600822191439544173046896875356040910136817300727665043174773434871223215069772985286442145129776197191070321384162933
352
m = pow(c, d, n)
353
m_ = manger.attack(lambda c: self._valid_padding_oaep(n, d, B, c), n, e, c)
354
self.assertIsInstance(m_, int)
355
self.assertEqual(m, m_)
356
357
def test_nitaj_crt_rsa(self):
358
# Section 5.1
359
p = 1965268334695819089811552114253
360
q = 1397509985733832541423163654649
361
N = p * q
362
e = 1908717316858446782674807627631
363
364
p_, q_ = nitaj_crt_rsa.attack(N, e, 0.09, m=4, t=2)
365
self.assertIsInstance(p_, int)
366
self.assertIsInstance(q_, int)
367
self.assertEqual(N, p_ * q_)
368
369
def test_non_coprime_exponent(self):
370
# Small primes because the attack needs to perform dlog with order p/q at some point.
371
p = 274313782073159601209986688053803756589
372
q = 232117885131324883095053819722121078767
373
N = p * q
374
phi = (p - 1) * (q - 1)
375
376
for e in [3, 7, 31, 397]:
377
m = randrange(1, N)
378
c = pow(m, e, N)
379
for m_ in non_coprime_exponent.attack(N, e, phi, c):
380
self.assertIsInstance(m_, int)
381
if m_ == m:
382
break
383
else:
384
self.fail()
385
386
def test_partial_key_exposure(self):
387
p = 10910578377493709111333790184427664202765704106579350486788097192764075505932456611273616722978391482349202742319580571195628069062856385333010738300159289
388
q = 9543709188272129636130984528523762431366215631912419189389727421314687517826682117237804919302025420051881375430279526592105566649224606602944612854468009
389
N = p * q
390
phi = (p - 1) * (q - 1)
391
392
e = 1888808636394051038122079426072690800814635584317577992534820937057888325091552888007695019685284192811882682070476179005
393
d = pow(e, -1, phi)
394
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.lsb_and_msb_of(d, 1024, 300, 400), m=4, t=4)
395
self.assertIsInstance(p_, int)
396
self.assertIsInstance(q_, int)
397
self.assertEqual(N, p_ * q_)
398
self.assertIsInstance(d_, int)
399
self.assertEqual(d, d_)
400
401
e = 2537076837624948274678559350627766245659466751393060011134223900150777497232270599983842219210375152450024925559795004985
402
d = pow(e, -1, phi)
403
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.lsb_of(d, 1024, 900), m=3, t=1)
404
self.assertIsInstance(p_, int)
405
self.assertIsInstance(q_, int)
406
self.assertEqual(N, p_ * q_)
407
self.assertIsInstance(d_, int)
408
self.assertEqual(d, d_)
409
410
e = 2105349305652912552595850746930492757880185195571479788917556245368402422744117397035736756548330291811495322726318885363734942001084342282438104629063513807868365772702460864019481
411
d = pow(e, -1, phi)
412
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.lsb_of(d, 1024, 1000), m=4, t=1)
413
self.assertIsInstance(p_, int)
414
self.assertIsInstance(q_, int)
415
self.assertEqual(N, p_ * q_)
416
self.assertIsInstance(d_, int)
417
self.assertEqual(d, d_)
418
419
d = 3043512099664998067963851819644406828326540226040840386777757880704658912729542968149616478325704429171610434683689846221877333398784455635377825449441
420
e = pow(d, -1, phi)
421
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.lsb_of(d, 500, 450), m=2, t=1)
422
self.assertIsInstance(p_, int)
423
self.assertIsInstance(q_, int)
424
self.assertEqual(N, p_ * q_)
425
self.assertIsInstance(d_, int)
426
self.assertEqual(d, d_)
427
428
e = 13
429
d = pow(e, -1, phi)
430
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.lsb_of(d, 1024, 300), m=4, t=4)
431
self.assertIsInstance(p_, int)
432
self.assertIsInstance(q_, int)
433
self.assertEqual(N, p_ * q_)
434
self.assertIsInstance(d_, int)
435
self.assertEqual(d, d_)
436
437
e = 1342190465933073539882079424718736636251811109323478531285823066337637602613426487933457123523547784034204609585360266973
438
d = pow(e, -1, phi)
439
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 1024, 400), m=4, t=4)
440
self.assertIsInstance(p_, int)
441
self.assertIsInstance(q_, int)
442
self.assertEqual(N, p_ * q_)
443
self.assertIsInstance(d_, int)
444
self.assertEqual(d, d_)
445
446
e = 2202357547053544325766272244614293754573709727782759369088138744825304061898264253795423228965992747533679851108128668707
447
d = pow(e, -1, phi)
448
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 1024, 700), factor_e=False)
449
self.assertIsInstance(p_, int)
450
self.assertIsInstance(q_, int)
451
self.assertEqual(N, p_ * q_)
452
self.assertIsInstance(d_, int)
453
self.assertEqual(d, d_)
454
455
e = 3570933230773454036103400438523094494860730146879558128058270144959251135492234076661103748194173734451656482351563013457204873521151688759417651289937071689065482923
456
d = pow(e, -1, phi)
457
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 1024, 800), m=1, t=1)
458
self.assertIsInstance(p_, int)
459
self.assertIsInstance(q_, int)
460
self.assertEqual(N, p_ * q_)
461
self.assertIsInstance(d_, int)
462
self.assertEqual(d, d_)
463
464
d = 1659574478146748254056351432273021460473735684664103384774766229138469185471407591788312141
465
e = pow(d, -1, phi)
466
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 300, 100), m=1, t=0)
467
self.assertIsInstance(p_, int)
468
self.assertIsInstance(q_, int)
469
self.assertEqual(N, p_ * q_)
470
self.assertIsInstance(d_, int)
471
self.assertEqual(d, d_)
472
473
d = 1996027597381396159237243762593978890017801760275363686545665967267636096782071826097658259
474
e = pow(d, -1, phi)
475
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 300, 200), m=1, t=0)
476
self.assertIsInstance(p_, int)
477
self.assertIsInstance(q_, int)
478
self.assertEqual(N, p_ * q_)
479
self.assertIsInstance(d_, int)
480
self.assertEqual(d, d_)
481
482
d = 3761842282390824725562943876986788316204251238160857472939673032260930840975186728596615197353278383991036677817804509912115342372613650607583423246001467907396859682584848725034711
483
e = pow(d, -1, phi)
484
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 600, 470), m=2, t=2)
485
self.assertIsInstance(p_, int)
486
self.assertIsInstance(q_, int)
487
self.assertEqual(N, p_ * q_)
488
self.assertIsInstance(d_, int)
489
self.assertEqual(d, d_)
490
491
d = 3691180879554463786414032222552684036869061510418768071690705916691156971385612730312759706623469266619987662041149793023083742711174850519419974605626258130331917527225448076142783
492
e = pow(d, -1, phi)
493
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 600, 500), m=2, t=0)
494
self.assertIsInstance(p_, int)
495
self.assertIsInstance(q_, int)
496
self.assertEqual(N, p_ * q_)
497
self.assertIsInstance(d_, int)
498
self.assertEqual(d, d_)
499
500
d = 4905300283357849777532376964856253872884896201321425321351015817211702681734510535471350537031834978240585713416514372877338525414401276727225442844983999756914527067870650280651385699873418363576218246007433933765243491292205
501
e = pow(d, -1, phi)
502
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 750, 745), m=2, t=1)
503
self.assertIsInstance(p_, int)
504
self.assertIsInstance(q_, int)
505
self.assertEqual(N, p_ * q_)
506
self.assertIsInstance(d_, int)
507
self.assertEqual(d, d_)
508
509
e = 4767842339321110001693689370200744188846086437972267976524065388471471723930990821354799430207822500359946317313395866439324920870720597904488739040160497744807293179379758447729820982374513639776505527597410218540393194583329
510
d = pow(e, -1, phi)
511
p_, q_, d_ = partial_key_exposure.attack(N, e, PartialInteger.msb_of(d, 1024, 1000), m=2, t=2)
512
self.assertIsInstance(p_, int)
513
self.assertIsInstance(q_, int)
514
self.assertEqual(N, p_ * q_)
515
self.assertIsInstance(d_, int)
516
self.assertEqual(d, d_)
517
518
def test_related_message(self):
519
p = 10690180235993276891093400056791694809626283946283502730568453512667872959585945785000451667658654678765261068382803043783613229940134674528737814179937039
520
q = 7411762482525629906544393574184843204602167584303799343260372455173145005371192234447957537905840062346600154282121917547245422064154573318186796475819689
521
N = p * q
522
e = 1031
523
524
m = 23666958939524101790258867720194152525320477517345668323487634285244809978431237084284966124443690088207420025855469792839817825751436552953357446092968581196135202083607268708161603982373715275645009539354114191781584252216616624903344208624218982897101882857866276445862837761774020714270528809722325935521
525
m1 = m
526
m2 = (m - 1) // 2
527
c1 = pow(m1, e, N)
528
c2 = pow(m2, e, N)
529
m_ = related_message.attack(N, e, c1, c2, lambda x: x, lambda x: (x - 1) / 2)
530
self.assertIsInstance(m_, int)
531
self.assertEqual(m, m_)
532
533
m = 42754674989053816443283755519950895884283393756241669686434758905157442774529527621615381748254419989786450757822289696411178987745998626455343863537512644055792678166036284930353109587229444597470543710233826871159008532286491252285935227027264995423631527072606598822086150352244744620473824760160714055480
534
m1 = m
535
m2 = m + 1234567
536
c1 = pow(m1, e, N)
537
c2 = pow(m2, e, N)
538
m_ = related_message.attack(N, e, c1, c2, lambda x: x, lambda x: x + 1234567)
539
self.assertIsInstance(m_, int)
540
self.assertEqual(m, m_)
541
542
m = 10136879005392890573742803235085883362530393373945578790262356784957820270668573158361435468800458889870260003849261075198298468522200348709133410088411354435142239153233867101217611563773642614889380571544851400417624723436256642495193929038862837559861769334382514380181448468789100535710415683242258774349
543
m1 = m
544
m2 = ((m - 1) // 2) + 1234567
545
c1 = pow(m1, e, N)
546
c2 = pow(m2, e, N)
547
m_ = related_message.attack(N, e, c1, c2, lambda x: x, lambda x: (x - 1) / 2 + 1234567)
548
self.assertIsInstance(m_, int)
549
self.assertEqual(m, m_)
550
551
e = 17
552
553
m = 53224653000473859937061720210017815788685481409955481700796925475147904449592533666897613424328988025976813324933929389695967421938433152183621524617367658473414117389230777531628581382338897188548318700570777346991214418473859214104540988647266458412244959766884014484065581348909258828921355728259479695761
554
# 2^10 possibilities, finishes quite quickly.
555
x = ((1 << 900) | (1 << 800) | (1 << 700) | (1 << 600) | (1 << 500) | (1 << 400) | (1 << 300) | (1 << 200) | (1 << 100) | (1 << 0))
556
m1 = m
557
m2 = m ^ x
558
c1 = pow(m1, e, N)
559
c2 = pow(m2, e, N)
560
for m_ in related_message.attack_xor(N, e, c1, c2, x):
561
self.assertIsInstance(m_, int)
562
if m_ == m:
563
break
564
else:
565
self.fail()
566
567
def test_stereotyped_message(self):
568
p = 9427799621011951541928982832607077548740094159448220696315390638465327417349606285858243970722509063632354007970943596939810149951744601156359969671857449
569
q = 11870402454659943941264241250285724555674252791764405289506083966512661811544805338494879563927626484667192683911307016139516417804102333067626665881499791
570
N = p * q
571
e = 7
572
m = randrange(2 ** 1023, N)
573
c = pow(m, e, N)
574
575
m_ = stereotyped_message.attack(N, e, c, PartialInteger.lsb_of(m, 1024, 950), m=2)
576
self.assertIsInstance(m_, int)
577
self.assertEqual(m, m_)
578
m_ = stereotyped_message.attack(N, e, c, PartialInteger.lsb_and_msb_of(m, 1024, 475, 475), m=2)
579
self.assertIsInstance(m_, int)
580
self.assertEqual(m, m_)
581
m_ = stereotyped_message.attack(N, e, c, PartialInteger.msb_of(m, 1024, 950), m=2)
582
self.assertIsInstance(m_, int)
583
self.assertEqual(m, m_)
584
585
def test_wiener_attack(self):
586
p = 9216552630349497248854461148903581877939724838581072236002328187229938158716983013925360355301876965491548210304574562739493228847611293721830637308804193
587
q = 6933923262781683366316472659407081840385285455077122235753449057801539822308174027541202209776857105782337372767555342676749125109168114988291773001406719
588
N = p * q
589
phi = (p - 1) * (q - 1)
590
d = 82656209786119546586793013314401325784594131342654070912205833037942868600641
591
e = pow(d, -1, phi)
592
p_, q_, d_ = wiener_attack.attack(N, e)
593
self.assertIsInstance(p_, int)
594
self.assertIsInstance(q_, int)
595
self.assertIsInstance(d_, int)
596
self.assertEqual(N, p_ * q_)
597
self.assertEqual(d, d_)
598
599
def test_wiener_attack_common_prime(self):
600
p = 6782064950424760710980284774219634491993236863153483768598482045213175969155112496910085683689731379194662789263026739644356045047675956598858137448376083
601
q = 8504790992500016807878718231498496399986587899005250624106963488787126208070626038486629561793688885242005440622123291666782461185365857422920183086563257
602
N = p * q
603
# Need lcm here to force e to be smaller.
604
phi = lcm(p - 1, q - 1)
605
d = 23036500924799795486061779142562236752665840004239
606
e = pow(d, -1, phi)
607
delta = 0.1604
608
p_, q_, d_ = wiener_attack_common_prime.attack(N, e, delta, m=1, t=0)
609
self.assertIsInstance(p_, int)
610
self.assertIsInstance(q_, int)
611
self.assertEqual(N, p_ * q_)
612
613
def test_wiener_attack_lattice(self):
614
p = 10058836956790351250887686696724836874393543803785063208855808993934035100716802252422366234311980376453091436742252598818654765951361743967196495143096063
615
q = 10874001113447900956838154496899246824857806872110954653566017237316332619466657937241496309167189150705694237173990171548696731451069336818563931754583387
616
N = p * q
617
phi = (p - 1) * (q - 1)
618
d = 65497726446129917535365626530327009614546242659268294033768073839686674115671
619
e = pow(d, -1, phi)
620
p_, q_, d_ = wiener_attack_lattice.attack(N, e)
621
self.assertIsInstance(p_, int)
622
self.assertIsInstance(q_, int)
623
self.assertIsInstance(d_, int)
624
self.assertEqual(N, p_ * q_)
625
self.assertEqual(d, d_)
626
627
p = 9707373803482895302134377941530620744662741435056530454118604655267069802831286734100930399853708141102721652973554127197649680587921565049539702212698839
628
q = 11374685136137203310158373170671675072705752349722317349866285582140309231812087871100889632499496096613924217040608367074870751492553593548559208079478557
629
N = p * q
630
phi = (p - 1) * (q - 1)
631
d = [29896979653954399311751172291337375021672580779310033411186490650071193093363524464620071224022833837646114789024463,
632
25019854538325061792107522866225799565927112598302865902080648493253018459108447971385795260436625922940902252013967,
633
33452119777334311282342590383548706508886474905055793530578662627818750047465037484869963980006683951515949908786219,
634
30902176945037488323367762338464400186721996670348084941392669024310917493670960101204134813192892530148698376953479,
635
34365029755561497376760468700540970025939428887363568419050786877025924818487442157630749173355183822291724562936769]
636
e = [pow(dk, -1, phi) for dk in d]
637
p_, q_ = wiener_attack_lattice.attack_multiple_exponents_1(N, e, alpha=0.375)
638
self.assertIsInstance(p_, int)
639
self.assertIsInstance(q_, int)
640
self.assertEqual(N, p_ * q_)
641
642
p = 9610376535888820350441263004216300807757213335939445761929202141525695641129196390963964051051856250223687604455958313679422621134259277770246808689501543
643
q = 10876741663314961593583004986176743880058095473762017590699463239387487301131642005673032882478524536830364724693892288182401553704334345687286569103637863
644
N = p * q
645
phi = (p - 1) * (q - 1)
646
d = [20522228326090744624755016835235156729825931424580937329081408545393078837487022188538702300004614386298757746546061,
647
27135032143777044064136798941245801906727565702470326573886220420774171519803529965228172508985262077535951244037307,
648
28445544562457171120459201550759208975761283606631130491647251601696334323412204311690811198015516559492511378774121]
649
e = [pow(dk, -1, phi) for dk in d]
650
p_, q_ = wiener_attack_lattice.attack_multiple_exponents_2(N, e, d_bit_length=384)
651
self.assertIsInstance(p_, int)
652
self.assertIsInstance(q_, int)
653
self.assertEqual(N, p_ * q_)
654
655