Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
jvdsn
GitHub Repository: jvdsn/crypto-attacks
Path: blob/master/test/test_lcg.py
2587 views
1
import os
2
import sys
3
from unittest import TestCase
4
5
path = os.path.dirname(os.path.dirname(os.path.realpath(os.path.abspath(__file__))))
6
if sys.path[1] != path:
7
sys.path.insert(1, path)
8
9
from attacks.lcg import parameter_recovery
10
from attacks.lcg import truncated_parameter_recovery
11
from attacks.lcg import truncated_state_recovery
12
13
14
class TestLCG(TestCase):
15
def test_parameter_recovery(self):
16
m = 230565400234205371157763985910524799617
17
a = 192101630084837332907895369052393213499
18
c = 212252940839553091477500231998099191939
19
x0 = 182679397636465813399296757573664340382
20
n_y = 10
21
22
y = []
23
x = x0
24
for _ in range(n_y):
25
x = (a * x + c) % m
26
y.append(x)
27
28
m_, a_, c_ = parameter_recovery.attack(y)
29
self.assertIsInstance(m_, int)
30
self.assertEqual(m, m_)
31
self.assertIsInstance(a_, int)
32
self.assertEqual(a, a_)
33
self.assertIsInstance(c_, int)
34
self.assertEqual(c, c_)
35
36
m_, a_, c_ = parameter_recovery.attack(y, m=m)
37
self.assertIsInstance(m_, int)
38
self.assertEqual(m, m_)
39
self.assertIsInstance(a_, int)
40
self.assertEqual(a, a_)
41
self.assertIsInstance(c_, int)
42
self.assertEqual(c, c_)
43
44
m_, a_, c_ = parameter_recovery.attack(y, a=a)
45
self.assertIsInstance(m_, int)
46
self.assertEqual(m, m_)
47
self.assertIsInstance(a_, int)
48
self.assertEqual(a, a_)
49
self.assertIsInstance(c_, int)
50
self.assertEqual(c, c_)
51
52
m_, a_, c_ = parameter_recovery.attack(y, c=c)
53
self.assertIsInstance(m_, int)
54
self.assertEqual(m, m_)
55
self.assertIsInstance(a_, int)
56
self.assertEqual(a, a_)
57
self.assertIsInstance(c_, int)
58
self.assertEqual(c, c_)
59
60
m_, a_, c_ = parameter_recovery.attack(y, m=m, a=a)
61
self.assertIsInstance(m_, int)
62
self.assertEqual(m, m_)
63
self.assertIsInstance(a_, int)
64
self.assertEqual(a, a_)
65
self.assertIsInstance(c_, int)
66
self.assertEqual(c, c_)
67
68
m_, a_, c_ = parameter_recovery.attack(y, m=m, c=c)
69
self.assertIsInstance(m_, int)
70
self.assertEqual(m, m_)
71
self.assertIsInstance(a_, int)
72
self.assertEqual(a, a_)
73
self.assertIsInstance(c_, int)
74
self.assertEqual(c, c_)
75
76
m_, a_, c_ = parameter_recovery.attack(y, a=a, c=c)
77
self.assertIsInstance(m_, int)
78
self.assertEqual(m, m_)
79
self.assertIsInstance(a_, int)
80
self.assertEqual(a, a_)
81
self.assertIsInstance(c_, int)
82
self.assertEqual(c, c_)
83
84
m_, a_, c_ = parameter_recovery.attack(y, m=m, a=a, c=c)
85
self.assertIsInstance(m_, int)
86
self.assertEqual(m, m_)
87
self.assertIsInstance(a_, int)
88
self.assertEqual(a, a_)
89
self.assertIsInstance(c_, int)
90
self.assertEqual(c, c_)
91
92
def test_truncated_parameter_recovery(self):
93
k = 128
94
s = 32
95
m = 236360717458728691963813082060498623380
96
a = 192101630084837332907895369052393213499
97
c = 212252940839553091477500231998099191939
98
x0 = 182679397636465813399296757573664340382
99
n_y = 40
100
# The recovery method is not perfect, so we allow some errors in the generated output.
101
n_test = 200
102
max_failures = 5
103
104
y = []
105
for _ in range(n_y):
106
x0 = (a * x0 + c) % m
107
y.append(x0 >> (k - s))
108
109
m_, a_, c_, x0_ = next(truncated_parameter_recovery.attack(y, k, s))
110
self.assertIsInstance(m_, int)
111
self.assertIsInstance(a_, int)
112
self.assertIsInstance(c_, int)
113
self.assertIsInstance(x0_, int)
114
115
x = x0
116
x_ = x0_
117
for _ in range(n_y):
118
x_ = (a_ * x_ + c_) % m_
119
120
failures = 0
121
for _ in range(n_test):
122
x = (a * x + c) % m
123
x_ = (a_ * x_ + c_) % m_
124
if (x >> (k - s)) != (x_ >> (k - s)):
125
failures += 1
126
127
self.assertLessEqual(failures, max_failures)
128
129
m_, a_, c_, x0_ = next(truncated_parameter_recovery.attack(y, k, s, m=m))
130
self.assertIsInstance(m_, int)
131
self.assertIsInstance(a_, int)
132
self.assertIsInstance(c_, int)
133
self.assertIsInstance(x0_, int)
134
135
x = x0
136
x_ = x0_
137
for _ in range(n_y):
138
x_ = (a_ * x_ + c_) % m_
139
140
failures = 0
141
for _ in range(n_test):
142
x = (a * x + c) % m
143
x_ = (a_ * x_ + c_) % m_
144
if (x >> (k - s)) != (x_ >> (k - s)):
145
failures += 1
146
147
self.assertLessEqual(failures, max_failures)
148
149
m_, a_, c_, x0_ = next(truncated_parameter_recovery.attack(y, k, s, a=a))
150
self.assertIsInstance(m_, int)
151
self.assertIsInstance(a_, int)
152
self.assertIsInstance(c_, int)
153
self.assertIsInstance(x0_, int)
154
155
x = x0
156
x_ = x0_
157
for _ in range(n_y):
158
x_ = (a_ * x_ + c_) % m_
159
160
failures = 0
161
for _ in range(n_test):
162
x = (a * x + c) % m
163
x_ = (a_ * x_ + c_) % m_
164
if (x >> (k - s)) != (x_ >> (k - s)):
165
failures += 1
166
167
self.assertLessEqual(failures, max_failures)
168
169
m_, a_, c_, x0_ = next(truncated_parameter_recovery.attack(y, k, s, m=m, a=a))
170
self.assertIsInstance(m_, int)
171
self.assertIsInstance(a_, int)
172
self.assertIsInstance(c_, int)
173
self.assertIsInstance(x0_, int)
174
175
x = x0
176
x_ = x0_
177
for _ in range(n_y):
178
x_ = (a_ * x_ + c_) % m_
179
180
failures = 0
181
for _ in range(n_test):
182
x = (a * x + c) % m
183
x_ = (a_ * x_ + c_) % m_
184
if (x >> (k - s)) != (x_ >> (k - s)):
185
failures += 1
186
187
self.assertLessEqual(failures, max_failures)
188
189
def test_truncated_state_recovery(self):
190
k = 128
191
s = 32
192
m = 236360717458728691963813082060498623380
193
a = 192101630084837332907895369052393213499
194
c = 212252940839553091477500231998099191939
195
x0 = 182679397636465813399296757573664340382
196
n_y = 40
197
198
y = []
199
x = []
200
for _ in range(n_y):
201
x0 = (a * x0 + c) % m
202
x.append(x0)
203
y.append(x0 >> (k - s))
204
205
x_ = truncated_state_recovery.attack(y, k, s, m, a, c)
206
for i in range(n_y):
207
self.assertIsInstance(x_[i], int)
208
self.assertEqual(x[i], x_[i])
209
210