From 7fe0cc6081c608d796cdaf0f45b195dbb42841e4 Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sat, 11 Aug 2018 17:06:52 -0400 Subject: Add scrypt to Python --- src/python/botan2.py | 27 +++++++++++++++++++++++---- src/scripts/test_python.py | 11 +++++++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/src/python/botan2.py b/src/python/botan2.py index 5b7c84847..87f1aec86 100755 --- a/src/python/botan2.py +++ b/src/python/botan2.py @@ -196,6 +196,11 @@ botan.botan_pbkdf_timed.argtypes = [c_char_p, POINTER(c_char), c_size_t, c_char_ c_void_p, c_size_t, c_size_t, POINTER(c_size_t)] botan.botan_pbkdf_timed.errcheck = errcheck_for('botan_pbkdf_timed') +# Scrypt +botan.botan_scrypt.argtypes = [POINTER(c_char), c_size_t, c_char_p, POINTER(c_char), c_size_t, + c_size_t, c_size_t, c_size_t] +botan.botan_scrypt.errcheck = errcheck_for('botan_scrypt') + # KDF botan.botan_kdf.argtypes = [c_char_p, POINTER(c_char), c_size_t, POINTER(c_char), c_size_t, POINTER(c_char), c_size_t, POINTER(c_char), c_size_t] @@ -383,14 +388,14 @@ def _ctype_bits(s): if isinstance(s, str): return s else: - raise Exception("Internal error - unexpected type provided to _ctype_bits") + raise Exception("Internal error - unexpected type %s provided to _ctype_bits" % (type(s).__name__)) else: if isinstance(s, bytes): return s elif isinstance(s, str): return s.encode('utf-8') else: - raise Exception("Internal error - unexpected type provided to _ctype_bits") + raise Exception("Internal error - unexpected type %s provided to _ctype_bits" % (type(s).__name__)) def _ctype_bufout(buf): if version_info[0] < 3: @@ -591,19 +596,33 @@ def check_bcrypt(passwd, passwd_hash): # # PBKDF # -def pbkdf(algo, password, out_len, iterations=10000, salt=rng().get(12)): +def pbkdf(algo, password, out_len, iterations=10000, salt=None): + if salt is None: + salt = rng().get(12) out_buf = create_string_buffer(out_len) botan.botan_pbkdf(_ctype_str(algo), out_buf, out_len, _ctype_str(password), salt, len(salt), iterations) return (salt, iterations, out_buf.raw) -def pbkdf_timed(algo, password, out_len, ms_to_run=300, salt=rng().get(12)): +def pbkdf_timed(algo, password, out_len, ms_to_run=300, salt=None): + if salt is None: + salt = rng().get(12) out_buf = create_string_buffer(out_len) iterations = c_size_t(0) botan.botan_pbkdf_timed(_ctype_str(algo), out_buf, out_len, _ctype_str(password), salt, len(salt), ms_to_run, byref(iterations)) return (salt, iterations.value, out_buf.raw) +# +# Scrypt +# +def scrypt(out_len, password, salt, n=1024, r=8, p=8): + out_buf = create_string_buffer(out_len) + botan.botan_scrypt(out_buf, out_len, _ctype_str(password), + _ctype_bits(salt), len(salt), n, r, p) + + return out_buf.raw + # # KDF # diff --git a/src/scripts/test_python.py b/src/scripts/test_python.py index 075560670..e7fb76f0c 100644 --- a/src/scripts/test_python.py +++ b/src/scripts/test_python.py @@ -45,6 +45,16 @@ def test(): print('x %s' % hex_encode(psk)) print('y %s\n' % (hex_encode(botan2.pbkdf('PBKDF2(SHA-256)', 'xyz', 32, iterations, salt)[2]))) + def test_scrypt(): + scrypt = botan2.scrypt(10, '', '', 16, 1, 1) + print(hex_encode(scrypt)) + assert hex_encode(scrypt) == "77d6576238657b203b19" + + scrypt = botan2.scrypt(32, 'password', 'NaCl', 1024, 8, 16) + print(hex_encode(scrypt)) + assert hex_encode(scrypt) == "fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b373162" + + def test_bcrypt(): print("Testing Bcrypt...") r = botan2.rng() @@ -248,6 +258,7 @@ def test(): test_version() test_kdf() test_pbkdf() + test_scrypt() test_bcrypt() test_hmac() test_rng() -- cgit v1.2.3