1
2
3
4
5
6
7
8 """cryptomath module
9
10 This module has basic math/crypto code."""
11 from __future__ import print_function
12 import os
13 import math
14 import base64
15 import binascii
16
17 from .compat import *
18
19
20
21
22
23
24
25 try:
26 from M2Crypto import m2
27 m2cryptoLoaded = True
28
29 except ImportError:
30 m2cryptoLoaded = False
31
32
33 try:
34 import gmpy
35 gmpyLoaded = True
36 except ImportError:
37 gmpyLoaded = False
38
39
40 try:
41 import Crypto.Cipher.AES
42 pycryptoLoaded = True
43 except ImportError:
44 pycryptoLoaded = False
45
46
47
48
49
50
51
52 import zlib
53 length = len(zlib.compress(os.urandom(1000)))
54 assert(length > 900)
55
57 b = bytearray(os.urandom(howMany))
58 assert(len(b) == howMany)
59 return b
60
61 prngName = "os.urandom"
62
63
64
65
66
67 import hmac
68 import hashlib
69
72
75
80
85
90
91
92
93
94
96 total = 0
97 multiplier = 1
98 for count in range(len(b)-1, -1, -1):
99 byte = b[count]
100 total += multiplier * byte
101 multiplier *= 256
102 return total
103
105 """Convert an integer into a bytearray, zero-pad to howManyBytes.
106
107 The returned bytearray may be smaller than howManyBytes, but will
108 not be larger. The returned bytearray will contain a big-endian
109 encoding of the input integer (n).
110 """
111 if howManyBytes == None:
112 howManyBytes = numBytes(n)
113 b = bytearray(howManyBytes)
114 for count in range(howManyBytes-1, -1, -1):
115 b[count] = int(n % 256)
116 n >>= 8
117 return b
118
120 if (ord(mpi[4]) & 0x80) !=0:
121 raise AssertionError()
122 b = bytearray(mpi[4:])
123 return bytesToNumber(b)
124
139
140
141
142
143
144
146 if n==0:
147 return 0
148 s = "%x" % n
149 return ((len(s)-1)*4) + \
150 {'0':0, '1':1, '2':2, '3':2,
151 '4':3, '5':3, '6':3, '7':3,
152 '8':4, '9':4, 'a':4, 'b':4,
153 'c':4, 'd':4, 'e':4, 'f':4,
154 }[s[0]]
155 return int(math.floor(math.log(n, 2))+1)
156
158 if n==0:
159 return 0
160 bits = numBits(n)
161 return int(math.ceil(bits / 8.0))
162
163
164
165
166
168 if low >= high:
169 raise AssertionError()
170 howManyBits = numBits(high)
171 howManyBytes = numBytes(high)
172 lastBits = howManyBits % 8
173 while 1:
174 bytes = getRandomBytes(howManyBytes)
175 if lastBits:
176 bytes[0] = bytes[0] % (1 << lastBits)
177 n = bytesToNumber(bytes)
178 if n >= low and n < high:
179 return n
180
182 a, b = max(a,b), min(a,b)
183 while b:
184 a, b = b, a % b
185 return a
186
188 return (a * b) // gcd(a, b)
189
190
191
193 c, d = a, b
194 uc, ud = 1, 0
195 while c != 0:
196 q = d // c
197 c, d = d-(q*c), c
198 uc, ud = ud - (q * uc), uc
199 if d == 1:
200 return ud % b
201 return 0
202
203
204 if gmpyLoaded:
205 - def powMod(base, power, modulus):
206 base = gmpy.mpz(base)
207 power = gmpy.mpz(power)
208 modulus = gmpy.mpz(modulus)
209 result = pow(base, power, modulus)
210 return long(result)
211
212 else:
213 - def powMod(base, power, modulus):
214 if power < 0:
215 result = pow(base, power*-1, modulus)
216 result = invMod(result, modulus)
217 return result
218 else:
219 return pow(base, power, modulus)
220
221
223 sieve = list(range(n))
224 for count in range(2, int(math.sqrt(n))+1):
225 if sieve[count] == 0:
226 continue
227 x = sieve[count] * 2
228 while x < len(sieve):
229 sieve[x] = 0
230 x += sieve[count]
231 sieve = [x for x in sieve[2:] if x]
232 return sieve
233
234 sieve = makeSieve(1000)
235
236 -def isPrime(n, iterations=5, display=False):
237
238 for x in sieve:
239 if x >= n: return True
240 if n % x == 0: return False
241
242
243
244 if display: print("*", end=' ')
245 s, t = n-1, 0
246 while s % 2 == 0:
247 s, t = s//2, t+1
248
249 a = 2
250 for count in range(iterations):
251 v = powMod(a, s, n)
252 if v==1:
253 continue
254 i = 0
255 while v != n-1:
256 if i == t-1:
257 return False
258 else:
259 v, i = powMod(v, 2, n), i+1
260 a = getRandomNumber(2, n)
261 return True
262
264 if bits < 10:
265 raise AssertionError()
266
267
268
269
270
271 low = ((2 ** (bits-1)) * 3) // 2
272 high = 2 ** bits - 30
273 p = getRandomNumber(low, high)
274 p += 29 - (p % 30)
275 while 1:
276 if display: print(".", end=' ')
277 p += 30
278 if p >= high:
279 p = getRandomNumber(low, high)
280 p += 29 - (p % 30)
281 if isPrime(p, display=display):
282 return p
283
284
286 if bits < 10:
287 raise AssertionError()
288
289
290
291
292
293 low = (2 ** (bits-2)) * 3//2
294 high = (2 ** (bits-1)) - 30
295 q = getRandomNumber(low, high)
296 q += 29 - (q % 30)
297 while 1:
298 if display: print(".", end=' ')
299 q += 30
300 if (q >= high):
301 q = getRandomNumber(low, high)
302 q += 29 - (q % 30)
303
304
305 if isPrime(q, 0, display=display):
306 p = (2 * q) + 1
307 if isPrime(p, display=display):
308 if isPrime(q, display=display):
309 return p
310