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 import sys
17
18 from .compat import *
19
20
21
22
23
24
25
26 try:
27 from M2Crypto import m2
28 m2cryptoLoaded = True
29
30 except ImportError:
31 m2cryptoLoaded = False
32
33
34 try:
35 import gmpy
36 gmpyLoaded = True
37 except ImportError:
38 gmpyLoaded = False
39
40
41 try:
42 import Crypto.Cipher.AES
43 pycryptoLoaded = True
44 except ImportError:
45 pycryptoLoaded = False
46
47
48
49
50
51
52
53 import zlib
54 length = len(zlib.compress(os.urandom(1000)))
55 assert(length > 900)
56 del length
57
59 b = bytearray(os.urandom(howMany))
60 assert(len(b) == howMany)
61 return b
62
63 prngName = "os.urandom"
64
65
66
67
68
69 import hmac
70 import hashlib
71
73 """Return a MD5 digest of data"""
74 return secureHash(b, 'md5')
75
77 """Return a SHA1 digest of data"""
78 return secureHash(b, 'sha1')
79
81 """Return a digest of `data` using `algorithm`"""
82 hashInstance = hashlib.new(algorithm)
83 hashInstance.update(compat26Str(data))
84 return bytearray(hashInstance.digest())
85
90
95
100
105
106
107
108
109
111 total = 0
112 multiplier = 1
113 for count in range(len(b)-1, -1, -1):
114 byte = b[count]
115 total += multiplier * byte
116 multiplier *= 256
117 return total
118
120 """Convert an integer into a bytearray, zero-pad to howManyBytes.
121
122 The returned bytearray may be smaller than howManyBytes, but will
123 not be larger. The returned bytearray will contain a big-endian
124 encoding of the input integer (n).
125 """
126 if howManyBytes == None:
127 howManyBytes = numBytes(n)
128 b = bytearray(howManyBytes)
129 for count in range(howManyBytes-1, -1, -1):
130 b[count] = int(n % 256)
131 n >>= 8
132 return b
133
135 if (ord(mpi[4]) & 0x80) !=0:
136 raise AssertionError()
137 b = bytearray(mpi[4:])
138 return bytesToNumber(b)
139
141 b = numberToByteArray(n)
142 ext = 0
143
144
145 if (numBits(n) & 0x7)==0:
146 ext = 1
147 length = numBytes(n) + ext
148 b = bytearray(4+ext) + b
149 b[0] = (length >> 24) & 0xFF
150 b[1] = (length >> 16) & 0xFF
151 b[2] = (length >> 8) & 0xFF
152 b[3] = length & 0xFF
153 return bytes(b)
154
155
156
157
158
159
161 """Return number of bits necessary to represent the integer in binary"""
162 if n==0:
163 return 0
164 if sys.version_info < (2, 7):
165
166
167 return len(bin(n))-2
168 else:
169 return n.bit_length()
170
172 """Return number of bytes necessary to represent the integer in bytes"""
173 if n==0:
174 return 0
175 bits = numBits(n)
176 return (bits + 7) // 8
177
178
179
180
181
183 if low >= high:
184 raise AssertionError()
185 howManyBits = numBits(high)
186 howManyBytes = numBytes(high)
187 lastBits = howManyBits % 8
188 while 1:
189 bytes = getRandomBytes(howManyBytes)
190 if lastBits:
191 bytes[0] = bytes[0] % (1 << lastBits)
192 n = bytesToNumber(bytes)
193 if n >= low and n < high:
194 return n
195
197 a, b = max(a,b), min(a,b)
198 while b:
199 a, b = b, a % b
200 return a
201
203 return (a * b) // gcd(a, b)
204
205
206
208 c, d = a, b
209 uc, ud = 1, 0
210 while c != 0:
211 q = d // c
212 c, d = d-(q*c), c
213 uc, ud = ud - (q * uc), uc
214 if d == 1:
215 return ud % b
216 return 0
217
218
219 if gmpyLoaded:
220 - def powMod(base, power, modulus):
221 base = gmpy.mpz(base)
222 power = gmpy.mpz(power)
223 modulus = gmpy.mpz(modulus)
224 result = pow(base, power, modulus)
225 return compatLong(result)
226
227 else:
228 - def powMod(base, power, modulus):
229 if power < 0:
230 result = pow(base, power*-1, modulus)
231 result = invMod(result, modulus)
232 return result
233 else:
234 return pow(base, power, modulus)
235
236
238 sieve = list(range(n))
239 for count in range(2, int(math.sqrt(n))+1):
240 if sieve[count] == 0:
241 continue
242 x = sieve[count] * 2
243 while x < len(sieve):
244 sieve[x] = 0
245 x += sieve[count]
246 sieve = [x for x in sieve[2:] if x]
247 return sieve
248
250
251 for x in sieve:
252 if x >= n: return True
253 if n % x == 0: return False
254
255
256
257 if display: print("*", end=' ')
258 s, t = n-1, 0
259 while s % 2 == 0:
260 s, t = s//2, t+1
261
262 a = 2
263 for count in range(iterations):
264 v = powMod(a, s, n)
265 if v==1:
266 continue
267 i = 0
268 while v != n-1:
269 if i == t-1:
270 return False
271 else:
272 v, i = powMod(v, 2, n), i+1
273 a = getRandomNumber(2, n)
274 return True
275
277 if bits < 10:
278 raise AssertionError()
279
280
281
282
283
284 low = ((2 ** (bits-1)) * 3) // 2
285 high = 2 ** bits - 30
286 p = getRandomNumber(low, high)
287 p += 29 - (p % 30)
288 while 1:
289 if display: print(".", end=' ')
290 p += 30
291 if p >= high:
292 p = getRandomNumber(low, high)
293 p += 29 - (p % 30)
294 if isPrime(p, display=display):
295 return p
296
297
299 if bits < 10:
300 raise AssertionError()
301
302
303
304
305
306 low = (2 ** (bits-2)) * 3//2
307 high = (2 ** (bits-1)) - 30
308 q = getRandomNumber(low, high)
309 q += 29 - (q % 30)
310 while 1:
311 if display: print(".", end=' ')
312 q += 30
313 if (q >= high):
314 q = getRandomNumber(low, high)
315 q += 29 - (q % 30)
316
317
318 if isPrime(q, 0, display=display):
319 p = (2 * q) + 1
320 if isPrime(p, display=display):
321 if isPrime(q, display=display):
322 return p
323