Пример #1
0
    def _bits2int(self, bstr):
        """See 2.3.2 in RFC6979"""

        result = bytes_to_long(bstr)
        q_len = bit_size(self._key.q)
        b_len = len(bstr) * 8
        if b_len > q_len:
            result >>= (b_len - q_len)
        return result
Пример #2
0
def scrypt(password, salt, key_len, N, r, p, num_keys=1):
    """Derive one or more keys from a passphrase.

    This function performs key derivation according to
    the `scrypt`_ algorithm, introduced in Percival's paper
    `"Stronger key derivation via sequential memory-hard functions"`__.

    This implementation is based on the `RFC draft`__.

    :Parameters:
     password : string
        The secret pass phrase to generate the keys from.
     salt : string
        A string to use for better protection from dictionary attacks.
        This value does not need to be kept secret,
        but it should be randomly chosen for each derivation.
        It is recommended to be at least 8 bytes long.
     key_len : integer
        The length in bytes of every derived key.
     N : integer
        CPU/Memory cost parameter. It must be a power of 2 and less
        than ``2**32``.
     r : integer
        Block size parameter.
     p : integer
        Parallelization parameter.
        It must be no greater than ``(2**32-1)/(4r)``.
     num_keys : integer
        The number of keys to derive. Every key is ``key_len`` bytes long.
        By default, only 1 key is generated.
        The maximum cumulative length of all keys is ``(2**32-1)*32``
        (that is, 128TB).

    A good choice of parameters *(N, r , p)* was suggested
    by Colin Percival in his `presentation in 2009`__:

    - *(16384, 8, 1)* for interactive logins (<=100ms)
    - *(1048576, 8, 1)* for file encryption (<=5s)

    :Return: A byte string or a tuple of byte strings.

    .. _scrypt: http://www.tarsnap.com/scrypt.html
    .. __: http://www.tarsnap.com/scrypt/scrypt.pdf
    .. __: http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-03
    .. __: http://www.tarsnap.com/scrypt/scrypt-slides.pdf
    """

    if 2 ** (bit_size(N) - 1) != N:
        raise ValueError("N must be a power of 2")
    if N >= 2 ** 32:
        raise ValueError("N is too big")
    if p > ((2 ** 32 - 1) * 32)  // (128 * r):
        raise ValueError("p or r are too big")

    prf_hmac_sha256 = lambda p, s: HMAC.new(p, s, SHA256).digest()

    blocks = PBKDF2(password, salt, p * 128 * r, 1, prf=prf_hmac_sha256)

    blocks = b("").join([_scryptROMix(blocks[x:x + 128 * r], N)
                         for x in range(0, len(blocks), 128 * r)])

    dk = PBKDF2(password, blocks, key_len * num_keys, 1,
                prf=prf_hmac_sha256)

    if num_keys == 1:
        return dk

    kol = [dk[idx:idx + key_len]
           for idx in range(0, key_len * num_keys, key_len)]
    return kol
Пример #3
0
    def __init__(self, key, mode, encoding='binary', randfunc=None):
        """Initialize this Digital Signature Standard object.

        :Parameters:
          key : a DSA key object
            If the key has the private half, both signature and
            verification are possible.
            If it only has the public half, verification is possible
            but not signature generation.

            Let *L* and *N* be the bit lengths of the modules *p* and *q*.

            If mode is *'fips-186-3'*,
            the combination *(L,N)* must apper in the following list,
            in compliance to section 4.2 of `FIPS-186`__:

            - (1024, 160)
            - (2048, 224)
            - (2048, 256)
            - (3072, 256)

            Note that the FIPS specification also defines how the key
            must be generated. PyCrypto does not generate DSA keys
            in a FIPS compliant way.

          mode : string
            The parameter can take these values:

            - *'fips-186-3'*. The signature generation is carried out
              according to `FIPS-186`__: the nonce *k* is taken from the RNG.
            - *'deterministic-rfc6979'*. The signature generation
              process does not rely on a random generator.
              See RFC6979_.

          encoding : string
            How the signature is encoded. This value determines the output of
            ``sign`` and the input of ``verify``.

            The following values are accepted:

            - *'binary'*, the signature is the raw concatenation
              of *r* and *s*. The size in bytes of the signature is always
              two times the size of *q*.

            - *'der'*, the signature is a DER encoded SEQUENCE with two
              INTEGERs, *r* and *s*. The size of the signature is variable.

          randfunc : callable
            The source of randomness. If `None`, the internal RNG is used.
            It is not used under mode *'deterministic-rfc6979'*.

        .. __: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
        .. __: http://csrc.nist.gov/publications/fips/fips186-3/fips_186-3.pdf
        .. _RFC6979: http://tools.ietf.org/html/rfc6979
        """

        # The goal of the 'mode' parameter is to avoid to
        # have the current version of the standard as default.
        #
        # Over time, such version will be superseded by (for instance)
        # FIPS 186-4 and it will be odd to have -3 as default.

        self._deterministic = False
        if mode == 'deterministic-rfc6979':
            self._deterministic = True
        elif mode not in ('fips-186-3', ):
            raise ValueError("Unknown DSS mode '%s'" % mode)

        if encoding not in ('binary', 'der'):
            raise ValueError("Unknown encoding '%s'" % encoding)

        if randfunc is None:
            randfunc = Random.get_random_bytes

        self._encoding = encoding
        self._randfunc = randfunc

        # Verify that lengths of p and q are standard compliant
        self._l, self._n = [(bit_size(x) + 7) >> 3 for x in (key.p, key.q)]
        if not self._deterministic:
            if (self._l * 8, self._n * 8) not in self.fips_186_3_ln:
                raise ValueError("L/N (%d, %d) is not compliant"
                                 " to FIPS 186-3" %
                                 (self._l, self._n))
        self._key = key
def scrypt(password, salt, key_len, N, r, p, num_keys=1):
    """Derive one or more keys from a passphrase.

    This function performs key derivation according to
    the `scrypt`_ algorithm, introduced in Percival's paper
    `"Stronger key derivation via sequential memory-hard functions"`__.

    This implementation is based on `RFC7914`__.

    Args:
     password (string):
        The secret pass phrase to generate the keys from.
     salt (string):
        A string to use for better protection from dictionary attacks.
        This value does not need to be kept secret,
        but it should be randomly chosen for each derivation.
        It is recommended to be at least 8 bytes long.
     key_len (integer):
        The length in bytes of every derived key.
     N (integer):
        CPU/Memory cost parameter. It must be a power of 2 and less
        than :math:`2^{32}`.
     r (integer):
        Block size parameter.
     p (integer):
        Parallelization parameter.
        It must be no greater than :math:`(2^{32}-1)/(4r)`.
     num_keys (integer):
        The number of keys to derive. Every key is :data:`key_len` bytes long.
        By default, only 1 key is generated.
        The maximum cumulative length of all keys is :math:`(2^{32}-1)*32`
        (that is, 128TB).

    A good choice of parameters *(N, r , p)* was suggested
    by Colin Percival in his `presentation in 2009`__:

    - *(16384, 8, 1)* for interactive logins (<=100ms)
    - *(1048576, 8, 1)* for file encryption (<=5s)

    Return:
        A byte string or a tuple of byte strings.

    .. _scrypt: http://www.tarsnap.com/scrypt.html
    .. __: http://www.tarsnap.com/scrypt/scrypt.pdf
    .. __: https://tools.ietf.org/html/rfc7914
    .. __: http://www.tarsnap.com/scrypt/scrypt-slides.pdf
    """

    if 2 ** (bit_size(N) - 1) != N:
        raise ValueError("N must be a power of 2")
    if N >= 2 ** 32:
        raise ValueError("N is too big")
    if p > ((2 ** 32 - 1) * 32)  // (128 * r):
        raise ValueError("p or r are too big")

    prf_hmac_sha256 = lambda p, s: HMAC.new(p, s, SHA256).digest()

    stage_1 = PBKDF2(password, salt, p * 128 * r, 1, prf=prf_hmac_sha256)

    scryptROMix = _raw_scrypt_lib.scryptROMix
    core = _raw_salsa20_lib.Salsa20_8_core

    # Parallelize into p flows
    data_out = []
    for flow in xrange(p):
        idx = flow * 128 * r
        buffer_out = create_string_buffer(128 * r)
        result = scryptROMix(stage_1[idx : idx + 128 * r],
                             buffer_out,
                             c_size_t(128 * r),
                             N,
                             core)
        if result:
            raise ValueError("Error %X while running scrypt" % result)
        data_out += [ get_raw_buffer(buffer_out) ]

    dk = PBKDF2(password,
                b"".join(data_out),
                key_len * num_keys, 1,
                prf=prf_hmac_sha256)

    if num_keys == 1:
        return dk

    kol = [dk[idx:idx + key_len]
           for idx in xrange(0, key_len * num_keys, key_len)]
    return kol