Exemple #1
0
def _generate_domain(L, randfunc):
    """Generate a new set of DSA domain parameters"""

    N = { 1024:160, 2048:224, 3072:256 }.get(L)
    if N is None:
        raise ValueError("Invalid modulus length (%d)" % L)

    outlen = SHA256.digest_size * 8
    n = (L + outlen - 1) // outlen - 1  # ceil(L/outlen) -1
    b_ = L - 1 - (n * outlen)

    # Generate q (A.1.1.2)
    q = Integer(4)
    upper_bit = 1 << (N - 1)
    while test_probable_prime(q, randfunc) != PROBABLY_PRIME:
        seed = randfunc(64)
        U = Integer.from_bytes(SHA256.new(seed).digest()) & (upper_bit - 1)
        q = U | upper_bit | 1

    assert(q.size_in_bits() == N)

    # Generate p (A.1.1.2)
    offset = 1
    upper_bit = 1 << (L - 1)
    while True:
        V = [ SHA256.new(seed + Integer(offset + j).to_bytes()).digest()
              for j in xrange(n + 1) ]
        V = [ Integer.from_bytes(v) for v in V ]
        W = sum([V[i] * (1 << (i * outlen)) for i in xrange(n)],
                (V[n] & (1 << b_ - 1)) * (1 << (n * outlen)))

        X = Integer(W + upper_bit) # 2^{L-1} < X < 2^{L}
        assert(X.size_in_bits() == L)

        c = X % (q * 2)
        p = X - (c - 1)  # 2q divides (p-1)
        if p.size_in_bits() == L and \
           test_probable_prime(p, randfunc) == PROBABLY_PRIME:
               break
        offset += n + 1

    # Generate g (A.2.3, index=1)
    e = (p - 1) // q
    for count in itertools.count(1):
        U = seed + b("ggen") + bchr(1) + Integer(count).to_bytes()
        W = Integer.from_bytes(SHA256.new(U).digest())
        g = pow(W, e, p)
        if g != 1:
            break

    return (p, q, g, seed)
Exemple #2
0
    def test_is_prime(self):
        primes = (170141183460469231731687303715884105727,
                  19175002942688032928599,
                  1363005552434666078217421284621279933627102780881053358473,
                  2 ** 521 - 1)
        for p in primes:
            self.assertEqual(test_probable_prime(p), PROBABLY_PRIME)

        not_primes = (
                    4754868377601046732119933839981363081972014948522510826417784001,
                    1334733877147062382486934807105197899496002201113849920496510541601,
                    260849323075371835669784094383812120359260783810157225730623388382401,
                    )
        for np in not_primes:
            self.assertEqual(test_probable_prime(np), COMPOSITE)
Exemple #3
0
def construct(tup, consistency_check=True):
    """Construct a DSA key from a tuple of valid DSA components.

    Args:
      tup (tuple):
        A tuple of long integers, with 4 or 5 items
        in the following order:

            1. Public key (*y*).
            2. Sub-group generator (*g*).
            3. Modulus, finite field order (*p*).
            4. Sub-group order (*q*).
            5. Private key (*x*). Optional.

      consistency_check (boolean):
        If ``True``, the library will verify that the provided components
        fulfil the main DSA properties.

    Raises:
      ValueError: when the key being imported fails the most basic DSA validity checks.

    Returns:
      :class:`DsaKey` : a DSA key object
    """

    key_dict = dict(zip(('y', 'g', 'p', 'q', 'x'), map(Integer, tup)))
    key = DsaKey(key_dict)

    fmt_error = False
    if consistency_check:
        # P and Q must be prime
        fmt_error = test_probable_prime(key.p) == COMPOSITE
        fmt_error = test_probable_prime(key.q) == COMPOSITE
        # Verify Lagrange's theorem for sub-group
        fmt_error |= ((key.p - 1) % key.q) != 0
        fmt_error |= key.g <= 1 or key.g >= key.p
        fmt_error |= pow(key.g, key.q, key.p) != 1
        # Public key
        fmt_error |= key.y <= 0 or key.y >= key.p
        if hasattr(key, 'x'):
            fmt_error |= key.x <= 0 or key.x >= key.q
            fmt_error |= pow(key.g, key.x, key.p) != key.y

    if fmt_error:
        raise ValueError("Invalid DSA key components")

    return key
Exemple #4
0
def construct(tup, consistency_check=True):
    """Construct a DSA key from a tuple of valid DSA components.

    Args:
      tup (tuple):
        A tuple of long integers, with 4 or 5 items
        in the following order:

            1. Public key (*y*).
            2. Sub-group generator (*g*).
            3. Modulus, finite field order (*p*).
            4. Sub-group order (*q*).
            5. Private key (*x*). Optional.

      consistency_check (boolean):
        If ``True``, the library will verify that the provided components
        fulfil the main DSA properties.

    Raises:
      ValueError: when the key being imported fails the most basic DSA validity checks.

    Returns:
      :class:`DsaKey` : a DSA key object
    """

    key_dict = dict(zip(('y', 'g', 'p', 'q', 'x'), map(Integer, tup)))
    key = DsaKey(key_dict)

    fmt_error = False
    if consistency_check:
        # P and Q must be prime
        fmt_error = test_probable_prime(key.p) == COMPOSITE
        fmt_error |= test_probable_prime(key.q) == COMPOSITE
        # Verify Lagrange's theorem for sub-group
        fmt_error |= ((key.p - 1) % key.q) != 0
        fmt_error |= key.g <= 1 or key.g >= key.p
        fmt_error |= pow(key.g, key.q, key.p) != 1
        # Public key
        fmt_error |= key.y <= 0 or key.y >= key.p
        if hasattr(key, 'x'):
            fmt_error |= key.x <= 0 or key.x >= key.q
            fmt_error |= pow(key.g, key.x, key.p) != key.y

    if fmt_error:
        raise ValueError("Invalid DSA key components")

    return key
Exemple #5
0
    def test_is_prime(self):
        primes = (170141183460469231731687303715884105727,
                  19175002942688032928599,
                  1363005552434666078217421284621279933627102780881053358473,
                  2**521 - 1)
        for p in primes:
            self.assertEqual(test_probable_prime(p), PROBABLY_PRIME)

        not_primes = (
            4754868377601046732119933839981363081972014948522510826417784001,
            1334733877147062382486934807105197899496002201113849920496510541601,
            260849323075371835669784094383812120359260783810157225730623388382401,
        )
        for np in not_primes:
            self.assertEqual(test_probable_prime(np), COMPOSITE)

        from Crypto.Util.number import sieve_base
        for p in sieve_base[:100]:
            res = test_probable_prime(p)
            self.assertEqual(res, PROBABLY_PRIME)
Exemple #6
0
def construct(tup):
    r"""Construct an ElGamal key from a tuple of valid ElGamal components.

    The modulus *p* must be a prime.
    The following conditions must apply:

    .. math::

        \begin{align}
        &1 < g < p-1 \\
        &g^{p-1} = 1 \text{ mod } 1 \\
        &1 < x < p-1 \\
        &g^x = y \text{ mod } p
        \end{align}

    Args:
      tup (tuple):
        A tuple with either 3 or 4 integers,
        in the following order:

        1. Modulus (*p*).
        2. Generator (*g*).
        3. Public key (*y*).
        4. Private key (*x*). Optional.

    Raises:
        ValueError: when the key being imported fails the most basic ElGamal validity checks.

    Returns:
        an :class:`ElGamalKey` object
    """

    obj = ElGamalKey()
    if len(tup) not in [3, 4]:
        raise ValueError('argument for construct() wrong length')
    for i in range(len(tup)):
        field = obj._keydata[i]
        setattr(obj, field, Integer(tup[i]))

    fmt_error = test_probable_prime(obj.p) == COMPOSITE
    fmt_error |= obj.g <= 1 or obj.g >= obj.p
    fmt_error |= pow(obj.g, obj.p - 1, obj.p) != 1
    fmt_error |= obj.y < 1 or obj.y >= obj.p
    if len(tup) == 4:
        fmt_error |= obj.x <= 1 or obj.x >= obj.p
        fmt_error |= pow(obj.g, obj.x, obj.p) != obj.y

    if fmt_error:
        raise ValueError("Invalid ElGamal key components")

    return obj
def construct(tup):
    r"""Construct an ElGamal key from a tuple of valid ElGamal components.

    The modulus *p* must be a prime.
    The following conditions must apply:

    .. math::

        \begin{align}
        &1 < g < p-1 \\
        &g^{p-1} = 1 \text{ mod } 1 \\
        &1 < x < p-1 \\
        &g^x = y \text{ mod } p
        \end{align}

    Args:
      tup (tuple):
        A tuple with either 3 or 4 integers,
        in the following order:

        1. Modulus (*p*).
        2. Generator (*g*).
        3. Public key (*y*).
        4. Private key (*x*). Optional.

    Raises:
        ValueError: when the key being imported fails the most basic ElGamal validity checks.

    Returns:
        an :class:`ElGamalKey` object
    """

    obj=ElGamalKey()
    if len(tup) not in [3,4]:
        raise ValueError('argument for construct() wrong length')
    for i in range(len(tup)):
        field = obj._keydata[i]
        setattr(obj, field, Integer(tup[i]))

    fmt_error = test_probable_prime(obj.p) == COMPOSITE
    fmt_error |= obj.g<=1 or obj.g>=obj.p
    fmt_error |= pow(obj.g, obj.p-1, obj.p)!=1
    fmt_error |= obj.y<1 or obj.y>=obj.p
    if len(tup)==4:
        fmt_error |= obj.x<=1 or obj.x>=obj.p
        fmt_error |= pow(obj.g, obj.x, obj.p)!=obj.y

    if fmt_error:
        raise ValueError("Invalid ElGamal key components")

    return obj
Exemple #8
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
Exemple #9
0
def construct(tup):
    """Construct an ElGamal key from a tuple of valid ElGamal components.

    The modulus *p* must be a prime.

    The following conditions must apply:

    - 1 < g < p-1
    - g^{p-1} = 1 mod p
    - 1 < x < p-1
    - g^x = y mod p

    :Parameters:
        tup : tuple
            A tuple of long integers, with 3 or 4 items
            in the following order:

            1. Modulus (*p*).
            2. Generator (*g*).
            3. Public key (*y*).
            4. Private key (*x*). Optional.

    :Raise PublicKey.ValueError:
        When the key being imported fails the most basic ElGamal validity checks.
    :Return: An ElGamal key object (`ElGamalKey`).
    """

    obj=ElGamalKey()
    if len(tup) not in [3,4]:
        raise ValueError('argument for construct() wrong length')
    for i in range(len(tup)):
        field = obj._keydata[i]
        setattr(obj, field, Integer(tup[i]))

    fmt_error = test_probable_prime(obj.p) == COMPOSITE
    fmt_error |= obj.g<=1 or obj.g>=obj.p
    fmt_error |= pow(obj.g, obj.p-1, obj.p)!=1
    fmt_error |= obj.y<1 or obj.y>=obj.p
    if len(tup)==4:
        fmt_error |= obj.x<=1 or obj.x>=obj.p
        fmt_error |= pow(obj.g, obj.x, obj.p)!=obj.y

    if fmt_error:
        raise ValueError("Invalid ElGamal key components")

    return obj
Exemple #10
0
def construct(tup, consistency_check=True):
    """Construct an RSA key from a tuple of valid RSA components.

    The modulus **n** must be the product of two primes.
    The public exponent **e** must be odd and larger than 1.

    In case of a private key, the following equations must apply:

    - e != 1
    - p*q = n
    - e*d = 1 mod lcm[(p-1)(q-1)]
    - p*u = 1 mod q

    :Parameters:
     tup : tuple
        A tuple of long integers, with at least 2 and no
        more than 6 items. The items come in the following order:

            1. RSA modulus (*n*).
            2. Public exponent (*e*).
            3. Private exponent (*d*).
               Only required if the key is private.
            4. First factor of *n* (*p*).
               Optional, but factor q must also be present.
            5. Second factor of *n* (*q*). Optional.
            6. CRT coefficient, *(1/p) mod q* (*u*). Optional.
     consistency_check : boolean
        If *True*, the library will verify that the provided components
        fulfil the main RSA properties.

    :Raise ValueError:
        When the key being imported fails the most basic RSA validity checks.
    :Return: An RSA key object (`RsaKey`).
    """

    comp_names = 'n', 'e', 'd', 'p', 'q', 'u'
    key_dict = dict(zip(comp_names, map(Integer, tup)))
    n, e, d, p, q, u = [key_dict.get(comp) for comp in comp_names]

    if d is not None:

        if None in (p, q):
            # Compute factors p and q from the private exponent d.
            # We assume that n has no more than two factors.
            # See 8.2.2(i) in Handbook of Applied Cryptography.
            ktot = d * e - 1
            # The quantity d*e-1 is a multiple of phi(n), even,
            # and can be represented as t*2^s.
            t = ktot
            while t % 2 ==0:
                t //= 2
            # Cycle through all multiplicative inverses in Zn.
            # The algorithm is non-deterministic, but there is a 50% chance
            # any candidate a leads to successful factoring.
            # See "Digitalized Signatures and Public Key Functions as Intractable
            # as Factorization", M. Rabin, 1979
            spotted = False
            a = Integer(2)
            while not spotted and a < 100:
                k = Integer(t)
                # Cycle through all values a^{t*2^i}=a^k
                while k < ktot:
                    cand = pow(a, k, n)
                    # Check if a^k is a non-trivial root of unity (mod n)
                    if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1:
                        # We have found a number such that (cand-1)(cand+1)=0 (mod n).
                        # Either of the terms divides n.
                        p = Integer(n).gcd(cand + 1)
                        spotted = True
                        break
                    k *= 2
                # This value was not any good... let's try another!
                a += 2
            if not spotted:
                raise ValueError("Unable to compute factors p and q from exponent d.")
            # Found !
            assert ((n % p) == 0)
            q = n // p

        if u is None:
            u = p.inverse(q)

        key_dict['p'] = p
        key_dict['q'] = q
        key_dict['u'] = u

    # Build key object
    key = RsaKey(key_dict)

    # Very consistency of the key
    fmt_error = False
    if consistency_check:
        # Modulus and public exponent must be coprime
        fmt_error = e <= 1 or e >= n
        fmt_error |= Integer(n).gcd(e) != 1

        # For RSA, modulus must be odd
        fmt_error |= not n & 1

        if not fmt_error and key.has_private():
            # Modulus and private exponent must be coprime
            fmt_error = d <= 1 or d >= n
            fmt_error |= Integer(n).gcd(d) != 1
            # Modulus must be product of 2 primes
            fmt_error |= (p * q != n)
            fmt_error |= test_probable_prime(p) == COMPOSITE
            fmt_error |= test_probable_prime(q) == COMPOSITE
            # See Carmichael theorem
            phi = (p - 1) * (q - 1)
            lcm = phi // (p - 1).gcd(q - 1)
            fmt_error |= (e * d % int(lcm)) != 1
            if hasattr(key, 'u'):
                # CRT coefficient
                fmt_error |= u <= 1 or u >= q
                fmt_error |= (p * u % q) != 1
            else:
                fmt_error = True

    if fmt_error:
        raise ValueError("Invalid RSA key components")

    return key
Exemple #11
0
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.

    :Parameters:
      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, the default from ``Crypto.Random`` is used.

      domain : list
        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.

    :Return: A DSA key object (`DsaKey`).

    :Raise 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)
Exemple #12
0
def construct(rsa_components, consistency_check=True):
    r"""Construct an RSA key from a tuple of valid RSA components.

    The modulus **n** must be the product of two primes.
    The public exponent **e** must be odd and larger than 1.

    In case of a private key, the following equations must apply:

    .. math::

        \begin{align}
        p*q &= n \\
        e*d &\equiv 1 ( \text{mod lcm} [(p-1)(q-1)]) \\
        p*u &\equiv 1 ( \text{mod } q)
        \end{align}

    Args:
        rsa_components (tuple):
            A tuple of integers, with at least 2 and no
            more than 6 items. The items come in the following order:

            1. RSA modulus *n*.
            2. Public exponent *e*.
            3. Private exponent *d*.
               Only required if the key is private.
            4. First factor of *n* (*p*).
               Optional, but the other factor *q* must also be present.
            5. Second factor of *n* (*q*). Optional.
            6. CRT coefficient *q*, that is :math:`p^{-1} \text{mod }q`. Optional.

        consistency_check (boolean):
            If ``True``, the library will verify that the provided components
            fulfil the main RSA properties.

    Raises:
        ValueError: when the key being imported fails the most basic RSA validity checks.

    Returns: An RSA key object (:class:`RsaKey`).
    """
    class InputComps(object):
        pass

    input_comps = InputComps()
    for (comp, value) in zip(('n', 'e', 'd', 'p', 'q', 'u'), rsa_components):
        setattr(input_comps, comp, Integer(value))

    n = input_comps.n
    e = input_comps.e
    if not hasattr(input_comps, 'd'):
        key = RsaKey(n=n, e=e)
    else:
        d = input_comps.d
        if hasattr(input_comps, 'q'):
            p = input_comps.p
            q = input_comps.q
        else:
            # Compute factors p and q from the private exponent d.
            # We assume that n has no more than two factors.
            # See 8.2.2(i) in Handbook of Applied Cryptography.
            ktot = d * e - 1
            # The quantity d*e-1 is a multiple of phi(n), even,
            # and can be represented as t*2^s.
            t = ktot
            while t % 2 == 0:
                t //= 2
            # Cycle through all multiplicative inverses in Zn.
            # The algorithm is non-deterministic, but there is a 50% chance
            # any candidate a leads to successful factoring.
            # See "Digitalized Signatures and Public Key Functions as Intractable
            # as Factorization", M. Rabin, 1979
            spotted = False
            a = Integer(2)
            while not spotted and a < 100:
                k = Integer(t)
                # Cycle through all values a^{t*2^i}=a^k
                while k < ktot:
                    cand = pow(a, k, n)
                    # Check if a^k is a non-trivial root of unity (mod n)
                    if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1:
                        # We have found a number such that (cand-1)(cand+1)=0 (mod n).
                        # Either of the terms divides n.
                        p = Integer(n).gcd(cand + 1)
                        spotted = True
                        break
                    k *= 2
                # This value was not any good... let's try another!
                a += 2
            if not spotted:
                raise ValueError(
                    "Unable to compute factors p and q from exponent d.")
            # Found !
            assert ((n % p) == 0)
            q = n // p

        if hasattr(input_comps, 'u'):
            u = input_comps.u
        else:
            u = p.inverse(q)

        # Build key object
        key = RsaKey(n=n, e=e, d=d, p=p, q=q, u=u)

    # Very consistency of the key
    fmt_error = False
    if consistency_check:
        # Modulus and public exponent must be coprime
        fmt_error = e <= 1 or e >= n
        fmt_error |= Integer(n).gcd(e) != 1

        # For RSA, modulus must be odd
        fmt_error |= not n & 1

        if not fmt_error and key.has_private():
            # Modulus and private exponent must be coprime
            fmt_error = d <= 1 or d >= n
            fmt_error |= Integer(n).gcd(d) != 1
            # Modulus must be product of 2 primes
            fmt_error |= (p * q != n)
            fmt_error |= test_probable_prime(p) == COMPOSITE
            fmt_error |= test_probable_prime(q) == COMPOSITE
            # See Carmichael theorem
            phi = (p - 1) * (q - 1)
            lcm = phi // (p - 1).gcd(q - 1)
            fmt_error |= (e * d % int(lcm)) != 1
            if hasattr(key, 'u'):
                # CRT coefficient
                fmt_error |= u <= 1 or u >= q
                fmt_error |= (p * u % q) != 1
            else:
                fmt_error = True

    if fmt_error:
        raise ValueError("Invalid RSA key components")

    return key
def construct(tup, consistency_check=True):
    """Construct an RSA key from a tuple of valid RSA components.

    The modulus **n** must be the product of two primes.
    The public exponent **e** must be odd and larger than 1.

    In case of a private key, the following equations must apply:

    - e != 1
    - p*q = n
    - e*d = 1 mod lcm[(p-1)(q-1)]
    - p*u = 1 mod q

    :Parameters:
     tup : tuple
        A tuple of long integers, with at least 2 and no
        more than 6 items. The items come in the following order:

            1. RSA modulus (*n*).
            2. Public exponent (*e*).
            3. Private exponent (*d*).
               Only required if the key is private.
            4. First factor of *n* (*p*).
               Optional, but factor q must also be present.
            5. Second factor of *n* (*q*). Optional.
            6. CRT coefficient, *(1/p) mod q* (*u*). Optional.
     consistency_check : boolean
        If *True*, the library will verify that the provided components
        fulfil the main RSA properties.

    :Raise ValueError:
        When the key being imported fails the most basic RSA validity checks.
    :Return: An RSA key object (`RsaKey`).
    """

    comp_names = 'n', 'e', 'd', 'p', 'q', 'u'
    key_dict = dict(zip(comp_names, map(Integer, tup)))
    n, e, d, p, q, u = [key_dict.get(comp) for comp in comp_names]

    if d is not None:

        if None in (p, q):
            # Compute factors p and q from the private exponent d.
            # We assume that n has no more than two factors.
            # See 8.2.2(i) in Handbook of Applied Cryptography.
            ktot = d * e - 1
            # The quantity d*e-1 is a multiple of phi(n), even,
            # and can be represented as t*2^s.
            t = ktot
            while t % 2 == 0:
                t //= 2
            # Cycle through all multiplicative inverses in Zn.
            # The algorithm is non-deterministic, but there is a 50% chance
            # any candidate a leads to successful factoring.
            # See "Digitalized Signatures and Public Key Functions as Intractable
            # as Factorization", M. Rabin, 1979
            spotted = False
            a = Integer(2)
            while not spotted and a < 100:
                k = Integer(t)
                # Cycle through all values a^{t*2^i}=a^k
                while k < ktot:
                    cand = pow(a, k, n)
                    # Check if a^k is a non-trivial root of unity (mod n)
                    if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1:
                        # We have found a number such that (cand-1)(cand+1)=0 (mod n).
                        # Either of the terms divides n.
                        p = Integer(n).gcd(cand + 1)
                        spotted = True
                        break
                    k *= 2
                # This value was not any good... let's try another!
                a += 2
            if not spotted:
                raise ValueError(
                    "Unable to compute factors p and q from exponent d.")
            # Found !
            assert ((n % p) == 0)
            q = n // p

        if u is None:
            u = p.inverse(q)

        key_dict['p'] = p
        key_dict['q'] = q
        key_dict['u'] = u

    # Build key object
    key = RsaKey(key_dict)

    # Very consistency of the key
    fmt_error = False
    if consistency_check:
        # Modulus and public exponent must be coprime
        fmt_error = e <= 1 or e >= n
        fmt_error |= Integer(n).gcd(e) != 1

        # For RSA, modulus must be odd
        fmt_error |= not n & 1

        if not fmt_error and key.has_private():
            # Modulus and private exponent must be coprime
            fmt_error = d <= 1 or d >= n
            fmt_error |= Integer(n).gcd(d) != 1
            # Modulus must be product of 2 primes
            fmt_error |= (p * q != n)
            fmt_error |= test_probable_prime(p) == COMPOSITE
            fmt_error |= test_probable_prime(q) == COMPOSITE
            # See Carmichael theorem
            phi = (p - 1) * (q - 1)
            lcm = phi // (p - 1).gcd(q - 1)
            fmt_error |= (e * d % int(lcm)) != 1
            if hasattr(key, 'u'):
                # CRT coefficient
                fmt_error |= u <= 1 or u >= q
                fmt_error |= (p * u % q) != 1
            else:
                fmt_error = True

    if fmt_error:
        raise ValueError("Invalid RSA key components")

    return key
Exemple #14
0
def construct(rsa_components, consistency_check=True):
    r"""Construct an RSA key from a tuple of valid RSA components.

    The modulus **n** must be the product of two primes.
    The public exponent **e** must be odd and larger than 1.

    In case of a private key, the following equations must apply:

    .. math::

        \begin{align}
        p*q &= n \\
        e*d &\equiv 1 ( \text{mod lcm} [(p-1)(q-1)]) \\
        p*u &\equiv 1 ( \text{mod } q)
        \end{align}

    Args:
        rsa_components (tuple):
            A tuple of integers, with at least 2 and no
            more than 6 items. The items come in the following order:

            1. RSA modulus *n*.
            2. Public exponent *e*.
            3. Private exponent *d*.
               Only required if the key is private.
            4. First factor of *n* (*p*).
               Optional, but the other factor *q* must also be present.
            5. Second factor of *n* (*q*). Optional.
            6. CRT coefficient *q*, that is :math:`p^{-1} \text{mod }q`. Optional.

        consistency_check (boolean):
            If ``True``, the library will verify that the provided components
            fulfil the main RSA properties.

    Raises:
        ValueError: when the key being imported fails the most basic RSA validity checks.

    Returns: An RSA key object (:class:`RsaKey`).
    """

    class InputComps(object):
        pass

    input_comps = InputComps()
    for (comp, value) in zip(('n', 'e', 'd', 'p', 'q', 'u'), rsa_components):
        setattr(input_comps, comp, Integer(value))

    n = input_comps.n
    e = input_comps.e
    if not hasattr(input_comps, 'd'):
        key = RsaKey(n=n, e=e)
    else:
        d = input_comps.d
        if hasattr(input_comps, 'q'):
            p = input_comps.p
            q = input_comps.q
        else:
            # Compute factors p and q from the private exponent d.
            # We assume that n has no more than two factors.
            # See 8.2.2(i) in Handbook of Applied Cryptography.
            ktot = d * e - 1
            # The quantity d*e-1 is a multiple of phi(n), even,
            # and can be represented as t*2^s.
            t = ktot
            while t % 2 == 0:
                t //= 2
            # Cycle through all multiplicative inverses in Zn.
            # The algorithm is non-deterministic, but there is a 50% chance
            # any candidate a leads to successful factoring.
            # See "Digitalized Signatures and Public Key Functions as Intractable
            # as Factorization", M. Rabin, 1979
            spotted = False
            a = Integer(2)
            while not spotted and a < 100:
                k = Integer(t)
                # Cycle through all values a^{t*2^i}=a^k
                while k < ktot:
                    cand = pow(a, k, n)
                    # Check if a^k is a non-trivial root of unity (mod n)
                    if cand != 1 and cand != (n - 1) and pow(cand, 2, n) == 1:
                        # We have found a number such that (cand-1)(cand+1)=0 (mod n).
                        # Either of the terms divides n.
                        p = Integer(n).gcd(cand + 1)
                        spotted = True
                        break
                    k *= 2
                # This value was not any good... let's try another!
                a += 2
            if not spotted:
                raise ValueError("Unable to compute factors p and q from exponent d.")
            # Found !
            assert ((n % p) == 0)
            q = n // p

        if hasattr(input_comps, 'u'):
            u = input_comps.u
        else:
            u = p.inverse(q)

        # Build key object
        key = RsaKey(n=n, e=e, d=d, p=p, q=q, u=u)

    # Very consistency of the key
    fmt_error = False
    if consistency_check:
        # Modulus and public exponent must be coprime
        fmt_error = e <= 1 or e >= n
        fmt_error |= Integer(n).gcd(e) != 1

        # For RSA, modulus must be odd
        fmt_error |= not n & 1

        if not fmt_error and key.has_private():
            # Modulus and private exponent must be coprime
            fmt_error = d <= 1 or d >= n
            fmt_error |= Integer(n).gcd(d) != 1
            # Modulus must be product of 2 primes
            fmt_error |= (p * q != n)
            fmt_error |= test_probable_prime(p) == COMPOSITE
            fmt_error |= test_probable_prime(q) == COMPOSITE
            # See Carmichael theorem
            phi = (p - 1) * (q - 1)
            lcm = phi // (p - 1).gcd(q - 1)
            fmt_error |= (e * d % int(lcm)) != 1
            if hasattr(key, 'u'):
                # CRT coefficient
                fmt_error |= u <= 1 or u >= q
                fmt_error |= (p * u % q) != 1
            else:
                fmt_error = True

    if fmt_error:
        raise ValueError("Invalid RSA key components")

    return key
Exemple #15
0
]
"""
WSGI_APPLICATION = 'is521_ca.wsgi.application'

from Crypto.Math.Primality import test_probable_prime
from Crypto.Util.number import getPrime
from Crypto.Math.Numbers import Integer
from Crypto.PublicKey import RSA
import os

if not os.path.exists("Keys/privatekey.pri"):
    q = Integer(getPrime(2048))
    p = Integer(2) * q - 1
    while True:
        p = p - 2
        if test_probable_prime(p) == 1:
            break
    n = p * q
    lcm = (p - 1).lcm(q - 1)
    while True:
        d = Integer(getPrime(128))
        if (p - 1).gcd(d) == 1 and (q - 1).gcd(d) == 1:
            break
    e = d.inverse(lcm)
    u = p.inverse(q)
    key = RSA.construct((n, e, d, p, q, u), True)
    f = open('Keys/privatekey.pri', 'wb')
    f.write(key.export_key('PEM', passphrase='mypass'))
    f.close()
    f = open('Keys/publickey.pub', 'wb')
    f.write(key.publickey().export_key('PEM'))