summaryrefslogtreecommitdiff
path: root/paramiko/primes.py
diff options
context:
space:
mode:
Diffstat (limited to 'paramiko/primes.py')
-rw-r--r--paramiko/primes.py63
1 files changed, 22 insertions, 41 deletions
diff --git a/paramiko/primes.py b/paramiko/primes.py
index 9419cd6..8e02e80 100644
--- a/paramiko/primes.py
+++ b/paramiko/primes.py
@@ -20,33 +20,17 @@
Utility functions for dealing with primes.
"""
-from Crypto.Util import number
+import os
from paramiko import util
+from paramiko.py3compat import byte_mask, long
from paramiko.ssh_exception import SSHException
-def _generate_prime(bits, rng):
- "primtive attempt at prime generation"
- hbyte_mask = pow(2, bits % 8) - 1
- while True:
- # loop catches the case where we increment n into a higher bit-range
- x = rng.read((bits+7) // 8)
- if hbyte_mask > 0:
- x = chr(ord(x[0]) & hbyte_mask) + x[1:]
- n = util.inflate_long(x, 1)
- n |= 1
- n |= (1 << (bits - 1))
- while not number.isPrime(n):
- n += 2
- if util.bit_length(n) == bits:
- break
- return n
-
-def _roll_random(rng, n):
- "returns a random # from 0 to N-1"
- bits = util.bit_length(n-1)
- bytes = (bits + 7) // 8
+def _roll_random(n):
+ """returns a random # from 0 to N-1"""
+ bits = util.bit_length(n - 1)
+ byte_count = (bits + 7) // 8
hbyte_mask = pow(2, bits % 8) - 1
# so here's the plan:
@@ -56,9 +40,9 @@ def _roll_random(rng, n):
# fits, so i can't guarantee that this loop will ever finish, but the odds
# of it looping forever should be infinitesimal.
while True:
- x = rng.read(bytes)
+ x = os.urandom(byte_count)
if hbyte_mask > 0:
- x = chr(ord(x[0]) & hbyte_mask) + x[1:]
+ x = byte_mask(x[0], hbyte_mask) + x[1:]
num = util.inflate_long(x, 1)
if num < n:
break
@@ -71,11 +55,10 @@ class ModulusPack (object):
on systems that have such a file.
"""
- def __init__(self, rpool):
+ def __init__(self):
# pack is a hash of: bits -> [ (generator, modulus) ... ]
self.pack = {}
self.discarded = []
- self.rng = rpool
def _parse_modulus(self, line):
timestamp, mod_type, tests, tries, size, generator, modulus = line.split()
@@ -109,29 +92,27 @@ class ModulusPack (object):
def read_file(self, filename):
"""
- @raise IOError: passed from any file operations that fail.
+ :raises IOError: passed from any file operations that fail.
"""
self.pack = {}
- f = open(filename, 'r')
- for line in f:
- line = line.strip()
- if (len(line) == 0) or (line[0] == '#'):
- continue
- try:
- self._parse_modulus(line)
- except:
- continue
- f.close()
+ with open(filename, 'r') as f:
+ for line in f:
+ line = line.strip()
+ if (len(line) == 0) or (line[0] == '#'):
+ continue
+ try:
+ self._parse_modulus(line)
+ except:
+ continue
def get_modulus(self, min, prefer, max):
- bitsizes = self.pack.keys()
- bitsizes.sort()
+ bitsizes = sorted(self.pack.keys())
if len(bitsizes) == 0:
raise SSHException('no moduli available')
good = -1
# find nearest bitsize >= preferred
for b in bitsizes:
- if (b >= prefer) and (b < max) and ((b < good) or (good == -1)):
+ if (b >= prefer) and (b < max) and (b < good or good == -1):
good = b
# if that failed, find greatest bitsize >= min
if good == -1:
@@ -147,5 +128,5 @@ class ModulusPack (object):
if min > good:
good = bitsizes[-1]
# now pick a random modulus of this bitsize
- n = _roll_random(self.rng, len(self.pack[good]))
+ n = _roll_random(len(self.pack[good]))
return self.pack[good][n]