Beispiel #1
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 `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 range(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 range(0, key_len * num_keys, key_len)
    ]
    return kol
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 xrange(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 xrange(0, key_len * num_keys, key_len)
    ]
    return kol
Beispiel #3
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 `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
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 xrange(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 xrange(0, key_len * num_keys, key_len)]
    return kol