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