def test_random_exact_bits(self): for _ in xrange(1000): a = IntegerGeneric.random(exact_bits=8) self.failIf(a < 128) self.failIf(a >= 256) for bits_value in xrange(1024, 1024 + 8): a = IntegerGeneric.random(exact_bits=bits_value) self.failIf(a < 2**(bits_value - 1)) self.failIf(a >= 2**bits_value)
def test_random_max_bits(self): flag = False for _ in range(1000): a = IntegerGeneric.random(max_bits=8) flag = flag or a < 128 self.assertFalse(a>=256) self.assertTrue(flag) for bits_value in range(1024, 1024 + 8): a = IntegerGeneric.random(max_bits=bits_value) self.assertFalse(a >= 2**bits_value)
def test_random_max_bits(self): flag = False for _ in xrange(1000): a = IntegerGeneric.random(max_bits=8) flag = flag or a < 128 self.failIf(a>=256) self.failUnless(flag) for bits_value in xrange(1024, 1024 + 8): a = IntegerGeneric.random(max_bits=bits_value) self.failIf(a >= 2**bits_value)
def test_random_max_bits(self): flag = False for _ in xrange(1000): a = IntegerGeneric.random(max_bits=8) flag = flag or a < 128 self.failIf(a >= 256) self.failUnless(flag) for bits_value in xrange(1024, 1024 + 8): a = IntegerGeneric.random(max_bits=bits_value) self.failIf(a >= 2**bits_value)
def __mul__(self, scalar): """Return a new point, the scalar product of this one""" if scalar < 0: raise ValueError( "Scalar multiplication only defined for non-negative integers") # Trivial results if scalar == 0 or self.is_point_at_infinity(): return self.point_at_infinity() elif scalar == 1: return self.copy() # Scalar randomization scalar_blind = Integer.random(exact_bits=64) * _curve.order + scalar # Montgomery key ladder r = [self.point_at_infinity().copy(), self.copy()] bit_size = int(scalar_blind.size_in_bits()) scalar_int = int(scalar_blind) for i in range(bit_size, -1, -1): di = scalar_int >> i & 1 r[di ^ 1] += r[di] r[di].double() return r[0]
def __mul__(self, scalar): """Return a new point, the scalar product of this one""" if scalar < 0: raise ValueError("Scalar multiplication only defined for non-negative integers") # Trivial results if scalar == 0 or self.is_point_at_infinity(): return self.point_at_infinity() elif scalar == 1: return self.copy() # Scalar randomization scalar_blind = Integer.random(exact_bits=64) * _curve.order + scalar # Montgomery key ladder r = [self.point_at_infinity().copy(), self.copy()] bit_size = int(scalar_blind.size_in_bits()) scalar_int = int(scalar_blind) for i in range(bit_size, -1, -1): di = scalar_int >> i & 1 r[di ^ 1] += r[di] r[di].double() return r[0]
def generate_probable_prime(**kwargs): """Generate a random probable prime. The prime will not have any specific properties (e.g. it will not be a *strong* prime). Random numbers are evaluated for primality until one passes all tests, consisting of a certain number of Miller-Rabin tests with random bases followed by a single Lucas test. The number of Miller-Rabin iterations is chosen such that the probability that the output number is a non-prime is less than 1E-30 (roughly 2^{-100}). This approach is compliant to `FIPS PUB 186-4`__. :Keywords: exact_bits : integer The desired size in bits of the probable prime. It must be at least 160. randfunc : callable An RNG function where candidate primes are taken from. prime_filter : callable A function that takes an Integer as parameter and returns True if the number can be passed to further primality tests, False if it should be immediately discarded. :Return: A probable prime in the range 2^exact_bits > p > 2^(exact_bits-1). .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf """ exact_bits = kwargs.pop("exact_bits", None) randfunc = kwargs.pop("randfunc", None) prime_filter = kwargs.pop("prime_filter", lambda x: True) if kwargs: raise ValueError("Unknown parameters: " + kwargs.keys()) if exact_bits is None: raise ValueError("Missing exact_bits parameter") if exact_bits < 160: raise ValueError("Prime number is not big enough.") if randfunc is None: randfunc = Random.new().read result = COMPOSITE while result == COMPOSITE: candidate = Integer.random(exact_bits=exact_bits, randfunc=randfunc) | 1 if not prime_filter(candidate): continue result = test_probable_prime(candidate, randfunc) return candidate
def generate_probable_prime(**kwargs): """Generate a random probable prime. The prime will not have any specific properties (e.g. it will not be a *strong* prime). Random numbers are evaluated for primality until one passes all tests, consisting of a certain number of Miller-Rabin tests with random bases followed by a single Lucas test. The number of Miller-Rabin iterations is chosen such that the probability that the output number is a non-prime is less than 1E-30 (roughly 2^{-100}). This approach is compliant to `FIPS PUB 186-4`__. :Keywords: exact_bits : integer The desired size in bits of the probable prime. It must be at least 160. randfunc : callable An RNG function where candidate primes are taken from. prime_filter : callable A function that takes an Integer as parameter and returns True if the number can be passed to further primality tests, False if it should be immediately discarded. :Return: A probable prime in the range 2^exact_bits > p > 2^(exact_bits-1). .. __: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf """ exact_bits = kwargs.pop("exact_bits", None) randfunc = kwargs.pop("randfunc", None) prime_filter = kwargs.pop("prime_filter", lambda x: True) if kwargs: print "Unknown parameters:", kwargs.keys() if exact_bits is None: raise ValueError("Missing exact_bits parameter") if exact_bits < 160: raise ValueError("Prime number is not big enough.") if randfunc is None: randfunc = Random.new().read result = COMPOSITE while result == COMPOSITE: candidate = Integer.random(exact_bits=exact_bits, randfunc=randfunc) | 1 if not prime_filter(candidate): continue result = test_probable_prime(candidate, randfunc) return candidate
def _get_weak_domain(self): from Cryptodome.Math.Numbers import Integer from Cryptodome.Math import Primality p = Integer(4) while p.size_in_bits() != 1024 or Primality.test_probable_prime(p) != Primality.PROBABLY_PRIME: q1 = Integer.random(exact_bits=80) q2 = Integer.random(exact_bits=80) q = q1 * q2 z = Integer.random(exact_bits=1024-160) p = z * q + 1 h = Integer(2) g = 1 while g == 1: g = pow(h, z, p) h += 1 return (p, q, g)
def test_random_bits_custom_rng(self): class CustomRNG(object): def __init__(self): self.counter = 0 def __call__(self, size): self.counter += size return bchr(0) * size custom_rng = CustomRNG() a = IntegerGeneric.random(exact_bits=32, randfunc=custom_rng) self.assertEqual(custom_rng.counter, 4)
def generate_p_q_g(): p = Integer(4) while p.size_in_bits() != 1024 or Primality.test_probable_prime(p) != Primality.PROBABLY_PRIME: q=random.randrange(1 << 159, 1 << 160) if(is_prime(q)): z = Integer.random(exact_bits=1024-160) p = z * q + 1 h = Integer(2) g = 1 while g == 1: g = pow(h, z, p) h += 1 return (p, q, g)
def generate_p_q_g(): start2 = timeit.default_timer() p = Integer(4) while p.size_in_bits() != 1024 or Primality.test_probable_prime( p) != Primality.PROBABLY_PRIME: q = random.randrange(1 << 159, 1 << 160) if (is_prime_4(q)): z = Integer.random(exact_bits=1024 - 160) p = z * q + 1 stop2 = timeit.default_timer() print("Time Reqiued_1: " + str(stop2 - start2)) start1 = timeit.default_timer() h = Integer(2) g = 1 while g == 1: g = power(int(h), int(z), int(p)) h += 1 stop1 = timeit.default_timer() print("Time Reqiued_2: " + str(stop1 - start1)) return (p, q, g)
def _generateProbablePrime(**kwargs): """Modified version of pycryptodome's Cryptodome.Math.Primality.generate_probable_prime to create primes of any size.""" exact_bits = kwargs.pop("exact_bits", None) randfunc = kwargs.pop("randfunc", None) prime_filter = kwargs.pop("prime_filter", lambda x: True) if kwargs: raise ValueError("Unknown parameters: " + kwargs.keys()) if exact_bits is None: raise ValueError("Missing exact_bits parameter") if randfunc is None: randfunc = Random.new().read result = 0 while result == 0: candidate = Integer.random(exact_bits=exact_bits, randfunc=randfunc) | 1 if not prime_filter(candidate): continue result = test_probable_prime(candidate, randfunc) return candidate
def generate_p_q_g(): global L_bit global N_bit start_1 = timeit.default_timer() p = Integer(4) while p.size_in_bits() != N_bit or Primality.test_probable_prime(p) != Primality.PROBABLY_PRIME: q=random.randrange(1 << L_bit-1, 1 << L_bit) if(is_prime(q)): z = Integer.random(exact_bits=N_bit-L_bit) p = z * q + 1 stop_1 = timeit.default_timer() print("Time Required for P & Q: "+str(stop_1-start_1)) start_2 = timeit.default_timer() h = Integer(2) g = 1 while g == 1: g = powmod(int(h), int(z), int(p)) h += 1 stop_2 = timeit.default_timer() print("Time Required for G: "+str(stop_2-start_2)) return (p, q, g)
def generate(bits, randfunc=None, domain=None): """Generate a new DSA key pair. The algorithm follows Appendix A.1/A.2 and B.1 of `FIPS 186-4`_, respectively for domain generation and key pair generation. Args: bits (integer): Key length, or size (in bits) of the DSA modulus *p*. It must be 1024, 2048 or 3072. randfunc (callable): Random number generation function; it accepts a single integer N and return a string of random data N bytes long. If not specified, :func:`Cryptodome.Random.get_random_bytes` is used. domain (tuple): The DSA domain parameters *p*, *q* and *g* as a list of 3 integers. Size of *p* and *q* must comply to `FIPS 186-4`_. If not specified, the parameters are created anew. Returns: :class:`DsaKey` : a new DSA key object Raises: ValueError : when **bits** is too little, too big, or not a multiple of 64. .. _FIPS 186-4: http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf """ if randfunc is None: randfunc = Random.get_random_bytes if domain: p, q, g = map(Integer, domain) ## Perform consistency check on domain parameters # P and Q must be prime fmt_error = test_probable_prime(p) == COMPOSITE fmt_error = test_probable_prime(q) == COMPOSITE # Verify Lagrange's theorem for sub-group fmt_error |= ((p - 1) % q) != 0 fmt_error |= g <= 1 or g >= p fmt_error |= pow(g, q, p) != 1 if fmt_error: raise ValueError("Invalid DSA domain parameters") else: p, q, g, _ = _generate_domain(bits, randfunc) L = p.size_in_bits() N = q.size_in_bits() if L != bits: raise ValueError("Mismatch between size of modulus (%d)" " and 'bits' parameter (%d)" % (L, bits)) if (L, N) not in [(1024, 160), (2048, 224), (2048, 256), (3072, 256)]: raise ValueError("Lengths of p and q (%d, %d) are not compatible" "to FIPS 186-3" % (L, N)) if not 1 < g < p: raise ValueError("Incorrent DSA generator") # B.1.1 c = Integer.random(exact_bits=N + 64) x = c % (q - 1) + 1 # 1 <= x <= q-1 y = pow(g, x, p) key_dict = { 'y':y, 'g':g, 'p':p, 'q':q, 'x':x } return DsaKey(key_dict)