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
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