diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 3ef0001..3e91731 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Wrapper for libsodium library @@ -26,7 +26,7 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ - +import sys import ctypes import ctypes.util @@ -63,34 +63,35 @@ def wrapper(*args, **kwargs): return wrapper return decorator -def encode_strings(func): +def check_strings(): """ - This decorator forces the encoding of str function parameters to UTF-8 - to elliminate the differences between Python 3.x and Python 2.x. The only - caveat is that bytes and str are both str types in Python 2.x so it is - possible for the encode() function to fail. It is OK for us to accept that - failure, hence the pass in the except block. - - Use this decorator on any functions that can take strings as parameters - such as crypto_pwhash(). + This decorator forces clients of this library to pass strings of 8-bit + values. This means a bytes object in Python 3 and a str object in Python 2. """ - def wrapper(*args, **kwargs): - largs = [] - for arg in args: - if isinstance(arg, str): - try: - arg = arg.encode(encoding='utf-8') - except: - pass - largs.append(arg) - for k in kwargs.keys(): - if isinstance(kwargs[k], str): - try: - kwargs[k] = kwargs[k].encode(encoding='utf-8') - except: - pass - return func(*largs, **kwargs) - return wrapper + def decorator(func): + if sys.version_info.major == 2: + def wrapper(*args, **kwargs): + for arg in args: + if isinstance(arg, unicode): + raise ValueError('Must pass strings of 8-bit values') + for k in kwargs.keys(): + if isinstance(kwargs[k], unicode): + raise ValueError('Must pass strings of 8-bit values') + return func(*args, **kwargs) + return wrapper + elif sys.version_info.major == 3: + def wrapper(*args, **kwargs): + for arg in args: + if isinstance(arg, str): + raise ValueError('Must pass strings of 8-bit values') + for k in list(kwargs.keys()): + if isinstance(kwargs[k], str): + raise ValueError('Must pass strings of 8-bit values') + return func(*args, **kwargs) + return wrapper + else: + raise RuntimeError('Invalid python version') + return decorator sodium.crypto_pwhash_scryptsalsa208sha256_strprefix.restype = ctypes.c_char_p @@ -168,7 +169,7 @@ def __check(code): if code != 0: raise ValueError - +@check_strings() def pad_buf(buf, length, name = 'buf'): buflen = len(buf) if buflen > length: @@ -180,12 +181,14 @@ def pad_buf(buf, length, name = 'buf'): else: return buf +@check_strings() def crypto_scalarmult_curve25519(n, p): buf = ctypes.create_string_buffer(crypto_scalarmult_BYTES) __check(sodium.crypto_scalarmult_curve25519(buf, n, p)) return buf.raw +@check_strings() def crypto_scalarmult_curve25519_base(n): if n is None: raise ValueError("invalid parameters") @@ -194,6 +197,7 @@ def crypto_scalarmult_curve25519_base(n): return buf.raw # crypto_stream_chacha20_xor(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *k) +@check_strings() def crypto_stream_chacha20_xor(message, nonce, key): mlen = ctypes.c_longlong(len(message)) @@ -206,6 +210,7 @@ def crypto_stream_chacha20_xor(message, nonce, key): # crypto_aead_chacha20poly1305_encrypt(unsigned char *c, unsigned long long *clen, const unsigned char *m, unsigned long long mlen, const unsigned char *ad, unsigned long long adlen, const unsigned char *nsec, const unsigned char *npub, const unsigned char *k); +@check_strings() def crypto_aead_chacha20poly1305_encrypt(message, ad, nonce, key): mlen = ctypes.c_ulonglong(len(message)) @@ -219,6 +224,7 @@ def crypto_aead_chacha20poly1305_encrypt(message, ad, nonce, key): # crypto_aead_chacha20poly1305_decrypt(unsigned char *m, unsigned long long *mlen, unsigned char *nsec, const unsigned char *c, unsigned long long clen, const unsigned char *ad, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) +@check_strings() def crypto_aead_chacha20poly1305_decrypt(ciphertext, ad, nonce, key): m = ctypes.create_string_buffer(len(ciphertext) - 16) @@ -230,6 +236,7 @@ def crypto_aead_chacha20poly1305_decrypt(ciphertext, ad, nonce, key): # crypto_aead_chacha20poly1305_ietf_encrypt(unsigned char *c, unsigned long long *clen_p, const unsigned char *m, unsigned long long mlen, const unsigned char *ad, unsigned long long adlen, const unsigned char *nsec, const unsigned char *npub, const unsigned char *k) @sodium_version(1, 0, 4) +@check_strings() def crypto_aead_chacha20poly1305_ietf_encrypt(message, ad, nonce, key): mlen = ctypes.c_ulonglong(len(message)) @@ -242,6 +249,7 @@ def crypto_aead_chacha20poly1305_ietf_encrypt(message, ad, nonce, key): # crypto_aead_chacha20poly1305_ietf_decrypt(unsigned char *m, unsigned long long *mlen, unsigned char *nsec, const unsigned char *c, unsigned long long clen, const unsigned char *ad, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) @sodium_version(1, 0, 4) +@check_strings() def crypto_aead_chacha20poly1305_ietf_decrypt(ciphertext, ad, nonce, key): m = ctypes.create_string_buffer(len(ciphertext) - 16) @@ -252,6 +260,7 @@ def crypto_aead_chacha20poly1305_ietf_decrypt(ciphertext, ad, nonce, key): return m.raw # crypto_auth(unsigned char *out, const unsigned char *in, unsigned long long inlen, const unsigned char *k) +@check_strings() def crypto_auth(m, k=b''): if m is None: raise ValueError("invalid parameters") @@ -260,6 +269,7 @@ def crypto_auth(m, k=b''): return buf.raw # crypto_auth_verify(const unsigned char *h, const unsigned char *in, unsigned long long inlen, const unsigned char *k) +@check_strings() def crypto_auth_verify(h, m, k=b''): if h is None or m is None: raise ValueError("invalid parameters") @@ -268,6 +278,7 @@ def crypto_auth_verify(h, m, k=b''): __check(sodium.crypto_auth_verify(h, m, ctypes.c_ulonglong(len(m)), k)) # crypto_generichash(unsigned char *out, size_t outlen, const unsigned char *in, unsigned long long inlen, const unsigned char *key, size_t keylen) +@check_strings() def crypto_generichash(m, k=b'', outlen=crypto_generichash_BYTES): buf = ctypes.create_string_buffer(outlen) __check(sodium.crypto_generichash(buf, ctypes.c_size_t(outlen), m, ctypes.c_ulonglong(len(m)), k, ctypes.c_size_t(len(k)))) @@ -275,6 +286,7 @@ def crypto_generichash(m, k=b'', outlen=crypto_generichash_BYTES): # crypto_generichash_init(crypto_generichash_state *state, const unsigned char *key, const size_t keylen, const size_t outlen); +@check_strings() def crypto_generichash_init(outlen=crypto_generichash_BYTES, k=b''): state = CryptoGenericHashState() __check(sodium.crypto_generichash_init(ctypes.byref(state), k, ctypes.c_size_t(len(k)), ctypes.c_size_t(outlen))) @@ -282,6 +294,7 @@ def crypto_generichash_init(outlen=crypto_generichash_BYTES, k=b''): # crypto_generichash_update(crypto_generichash_state *state, const unsigned char *in, unsigned long long inlen); +@check_strings() def crypto_generichash_update(state, m): assert isinstance(state, CryptoGenericHashState) __check(sodium.crypto_generichash_update(ctypes.byref(state), m, ctypes.c_ulonglong(len(m)))) @@ -295,14 +308,15 @@ def crypto_generichash_final(state, outlen=crypto_generichash_BYTES): __check(sodium.crypto_generichash_final(ctypes.byref(state), buf, ctypes.c_size_t(outlen))) return buf.raw +@check_strings() def crypto_generichash_blake2b_salt_personal(message, outlen = crypto_generichash_blake2b_BYTES, key = b'', salt = b'', personal = b''): keylen = len(key) if keylen != 0 and not crypto_generichash_blake2b_BYTES_MIN <= keylen <= crypto_generichash_blake2b_KEYBYTES_MAX: raise ValueError("%d <= len(key) <= %d - %d recieved" % (crypto_generichash_blake2b_BYTES_MIN, crypto_generichash_blake2b_KEYBYTES_MAX, keylen)) - salt = pad_buf(salt, crypto_generichash_blake2b_SALTBYTES, 'salt') - personal = pad_buf(personal, crypto_generichash_blake2b_PERSONALBYTES, 'personal') + salt = pad_buf(salt, crypto_generichash_blake2b_SALTBYTES, b'salt') + personal = pad_buf(personal, crypto_generichash_blake2b_PERSONALBYTES, b'personal') buf = ctypes.create_string_buffer(outlen) outlen = ctypes.c_size_t(outlen) @@ -327,6 +341,7 @@ def crypto_box_keypair(): # int crypto_box_seed_keypair(unsigned char *pk, unsigned char *sk, # const unsigned char *seed); +@check_strings() def crypto_box_seed_keypair(seed): if seed is None: raise ValueError("invalid parameters") @@ -335,6 +350,7 @@ def crypto_box_seed_keypair(seed): __check(sodium.crypto_box_seed_keypair(pk, sk, seed)) return pk.raw, sk.raw +@check_strings() def crypto_box_beforenm(pk, sk): if pk is None or sk is None: raise ValueError("invalid parameters") @@ -342,6 +358,7 @@ def crypto_box_beforenm(pk, sk): __check(sodium.crypto_box_beforenm(c, pk, sk)) return c.raw +@check_strings() def crypto_box(msg, nonce, pk, sk): if None in (msg, nonce, pk, sk): raise ValueError("invalid parameters") @@ -349,6 +366,7 @@ def crypto_box(msg, nonce, pk, sk): __check(sodium.crypto_box_easy(c, msg, ctypes.c_ulonglong(len(msg)), nonce, pk, sk)) return c.raw +@check_strings() def crypto_box_afternm(msg, nonce, k): if None in (msg, nonce, k): raise ValueError("invalid parameters") @@ -356,6 +374,7 @@ def crypto_box_afternm(msg, nonce, k): __check(sodium.crypto_box_easy_afternm(c, msg, ctypes.c_ulonglong(len(msg)), nonce, k)) return c.raw +@check_strings() def crypto_box_open(c, nonce, pk, sk): if None in (c, nonce, pk, sk): raise ValueError("invalid parameters") @@ -363,6 +382,7 @@ def crypto_box_open(c, nonce, pk, sk): __check(sodium.crypto_box_open_easy(msg, c, ctypes.c_ulonglong(len(c)), nonce, pk, sk)) return msg.raw +@check_strings() def crypto_box_open_afternm(c, nonce, k): if None in (c, nonce, k): raise ValueError("invalid parameters") @@ -370,6 +390,7 @@ def crypto_box_open_afternm(c, nonce, k): __check(sodium.crypto_box_open_easy_afternm(msg, c, ctypes.c_ulonglong(len(c)), nonce, k)) return msg.raw +@check_strings() def crypto_secretbox(msg, nonce, k): if None in (msg, nonce, k): raise ValueError("invalid parameters") @@ -379,6 +400,7 @@ def crypto_secretbox(msg, nonce, k): return c.raw[crypto_secretbox_BOXZEROBYTES:] +@check_strings() def crypto_secretbox_open(c, nonce, k): if None in (c, nonce, k): raise ValueError("invalid parameters") @@ -391,6 +413,7 @@ def crypto_secretbox_open(c, nonce, k): # unsigned long long mlen, const unsigned char *pk); @sodium_version(1, 0, 3) +@check_strings() def crypto_box_seal(msg, k): if msg is None or k is None: raise ValueError("invalid parameters") @@ -403,6 +426,7 @@ def crypto_box_seal(msg, k): # const unsigned char *pk, const unsigned char *sk); @sodium_version(1, 0, 3) +@check_strings() def crypto_box_seal_open(c, pk, sk): if None in (c, pk, sk): raise ValueError("invalid parameters") @@ -416,12 +440,13 @@ def crypto_box_seal_open(c, pk, sk): # const unsigned char *n, const unsigned char *pk, # const unsigned char *sk); +@check_strings() def crypto_box_detached(msg, nonce, pk, sk): if None in (msg, nonce, pk, sk): raise ValueError("invalid parameters") c = ctypes.create_string_buffer(len(msg)) mac = ctypes.create_string_buffer(crypto_box_MACBYTES) - __check(sodium.crypto_box_detached(c, mac, msg.encode(), ctypes.c_ulonglong(len(msg)), nonce, pk, sk)) + __check(sodium.crypto_box_detached(c, mac, msg, ctypes.c_ulonglong(len(msg)), nonce, pk, sk)) return c.raw, mac.raw # int crypto_box_open_detached(unsigned char *m, const unsigned char *c, @@ -431,6 +456,7 @@ def crypto_box_detached(msg, nonce, pk, sk): # const unsigned char *pk, # const unsigned char *sk); +@check_strings() def crypto_box_open_detached(c, mac, nonce, pk, sk): if None in (c, mac, nonce, pk, sk): raise ValueError("invalid parameters") @@ -445,12 +471,14 @@ def crypto_sign_keypair(): return pk.raw, sk.raw +@check_strings() def crypto_sign_seed_keypair(seed): pk = ctypes.create_string_buffer(crypto_sign_PUBLICKEYBYTES) sk = ctypes.create_string_buffer(crypto_sign_SECRETKEYBYTES) __check(sodium.crypto_sign_seed_keypair(pk, sk, seed)) return pk.raw, sk.raw +@check_strings() def crypto_sign(m, sk): if m is None or sk is None: raise ValueError("invalid parameters") @@ -460,6 +488,7 @@ def crypto_sign(m, sk): return smsg.raw +@check_strings() def crypto_sign_detached(m, sk): if m is None or sk is None: raise ValueError("invalid parameters") @@ -469,6 +498,7 @@ def crypto_sign_detached(m, sk): return sig.raw +@check_strings() def crypto_sign_open(sm, pk): if sm is None or pk is None: raise ValueError("invalid parameters") @@ -478,6 +508,7 @@ def crypto_sign_open(sm, pk): return msg.raw[:msglen.value] +@check_strings() def crypto_sign_verify_detached(sig, msg, pk): if None in (sig, msg, pk): raise ValueError @@ -488,6 +519,7 @@ def crypto_sign_verify_detached(sig, msg, pk): # int crypto_stream_salsa20(unsigned char *c, unsigned long long clen, # const unsigned char *n, const unsigned char *k); +@check_strings() def crypto_stream(cnt, nonce=None, key=None): res = ctypes.create_string_buffer(cnt) if not nonce: @@ -500,6 +532,7 @@ def crypto_stream(cnt, nonce=None, key=None): # crypto_stream_salsa20_xor(unsigned char *c, const unsigned char *m, unsigned long long mlen, # const unsigned char *n, const unsigned char *k) +@check_strings() def crypto_stream_xor(msg, cnt, nonce=None, key=None): res = ctypes.create_string_buffer(cnt) if not nonce: @@ -510,6 +543,7 @@ def crypto_stream_xor(msg, cnt, nonce=None, key=None): return res.raw +@check_strings() def crypto_sign_pk_to_box_pk(pk): if pk is None: raise ValueError @@ -518,6 +552,7 @@ def crypto_sign_pk_to_box_pk(pk): return res.raw +@check_strings() def crypto_sign_sk_to_box_sk(sk): if sk is None: raise ValueError @@ -525,6 +560,7 @@ def crypto_sign_sk_to_box_sk(sk): __check(sodium.crypto_sign_ed25519_sk_to_curve25519(ctypes.byref(res), sk)) return res.raw +@check_strings() def crypto_sign_sk_to_seed(sk): if sk is None: raise ValueError @@ -540,7 +576,7 @@ def crypto_sign_sk_to_seed(sk): # unsigned long long opslimit, # size_t memlimit, int alg); @sodium_version(1, 0, 9) -@encode_strings +@check_strings() def crypto_pwhash(outlen, passwd, salt, opslimit, memlimit, alg=crypto_pwhash_ALG_DEFAULT): if None in (outlen, passwd, salt, opslimit, memlimit): raise ValueError("invalid parameters") @@ -554,7 +590,7 @@ def crypto_pwhash(outlen, passwd, salt, opslimit, memlimit, alg=crypto_pwhash_AL # unsigned long long opslimit, # size_t memlimit); @sodium_version(1, 0, 9) -@encode_strings +@check_strings() def crypto_pwhash_str(passwd, opslimit, memlimit): if None in (passwd, opslimit, memlimit): raise ValueError("invalid parameters") @@ -566,7 +602,7 @@ def crypto_pwhash_str(passwd, opslimit, memlimit): # const char * const passwd, # unsigned long long passwdlen); @sodium_version(1, 0, 9) -@encode_strings +@check_strings() def crypto_pwhash_str_verify(pstr, passwd): if None in (pstr, passwd) or len(pstr) != crypto_pwhash_STRBYTES: raise ValueError("invalid parameters") @@ -579,6 +615,7 @@ def crypto_pwhash_str_verify(pstr, passwd): # const unsigned char * const salt, # unsigned long long opslimit, # size_t memlimit); +@check_strings() def crypto_pwhash_scryptsalsa208sha256(outlen, passwd, salt, opslimit, memlimit): if None in (outlen, passwd, salt, opslimit, memlimit): raise ValueError @@ -591,6 +628,7 @@ def crypto_pwhash_scryptsalsa208sha256(outlen, passwd, salt, opslimit, memlimit) # unsigned long long passwdlen, # unsigned long long opslimit, # size_t memlimit); +@check_strings() def crypto_pwhash_scryptsalsa208sha256_str(passwd, opslimit, memlimit): if None in (passwd, opslimit, memlimit): raise ValueError @@ -601,12 +639,14 @@ def crypto_pwhash_scryptsalsa208sha256_str(passwd, opslimit, memlimit): #int crypto_pwhash_scryptsalsa208sha256_str_verify(const char str[crypto_pwhash_scryptsalsa208sha256_STRBYTES], # const char * const passwd, # unsigned long long passwdlen); +@check_strings() def crypto_pwhash_scryptsalsa208sha256_str_verify(stored, passwd): if stored is None or passwd is None: raise ValueError __check(sodium.crypto_pwhash_scryptsalsa208sha256_str_verify(stored, passwd, ctypes.c_ulonglong(len(passwd)))) # int crypto_sign_ed25519_sk_to_pk(unsigned char *pk, const unsigned char *sk) +@check_strings() def crypto_sign_sk_to_pk(sk): if sk is None or len(sk) != crypto_sign_ed25519_SECRETKEYBYTES: raise ValueError @@ -616,18 +656,20 @@ def crypto_sign_sk_to_pk(sk): # int crypto_hash_sha256(unsigned char *out, const unsigned char *in, # unsigned long long inlen); +@check_strings() def crypto_hash_sha256(message): if message is None: raise ValueError("invalid parameters") out = ctypes.create_string_buffer(crypto_hash_sha256_BYTES).raw - __check(sodium.crypto_hash_sha256(out, message.encode(), ctypes.c_ulonglong(len(message)))) + __check(sodium.crypto_hash_sha256(out, message, ctypes.c_ulonglong(len(message)))) return out # int crypto_hash_sha512(unsigned char *out, const unsigned char *in, # unsigned long long inlen); +@check_strings() def crypto_hash_sha512(message): if message is None: raise ValueError("invalid parameters") out = ctypes.create_string_buffer(crypto_hash_sha512_BYTES).raw - __check(sodium.crypto_hash_sha512(out, message.encode(), ctypes.c_ulonglong(len(message)))) + __check(sodium.crypto_hash_sha512(out, message, ctypes.c_ulonglong(len(message)))) return out diff --git a/test/test_pysodium.py b/test/test_pysodium.py index 5d4b6a3..f3a616d 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Wrapper for libsodium library @@ -87,7 +87,7 @@ def test_crypto_box_open_afternm(self): def test_crypto_box_open_detached(self): pk, sk = pysodium.crypto_box_keypair() n = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES) - c, mac = pysodium.crypto_box_detached("howdy", n, pk, sk) + c, mac = pysodium.crypto_box_detached(b"howdy", n, pk, sk) pysodium.crypto_box_open_detached(c, mac, n, pk, sk) def test_crypto_secretbox_open(self): @@ -158,14 +158,14 @@ def test_crypto_blake2b(self): def test_crypto_pwhash(self): if not pysodium.sodium_version_check(1, 0, 9): return - pw = "Correct Horse Battery Staple" + pw = b"Correct Horse Battery Staple" salt = binascii.unhexlify(b'0f58b94c7a369fd8a9a7083e4cd75266') out = pysodium.crypto_pwhash(pysodium.crypto_auth_KEYBYTES, pw, salt, pysodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, pysodium.crypto_pwhash_MEMLIMIT_INTERACTIVE) self.assertEqual(binascii.hexlify(out), b'79db3095517c7358449d84ee3b2f81f0e9907fbd4e0bae4e0bcc6c79821427dc') def test_crypto_pwhash_storage(self): if not pysodium.sodium_version_check(1, 0, 9): return - pw = "Correct Horse Battery Staple" + pw = b"Correct Horse Battery Staple" pstr = pysodium.crypto_pwhash_str(pw, pysodium.crypto_pwhash_OPSLIMIT_INTERACTIVE, pysodium.crypto_pwhash_MEMLIMIT_INTERACTIVE) self.assertTrue(pysodium.crypto_pwhash_str_verify(pstr, pw)) @@ -207,7 +207,7 @@ def test_crypto_pwhash_scryptsalsa208sha256_str(self): self.assertTrue(storage_string.startswith(pysodium.crypto_pwhash_scryptsalsa208sha256_STRPREFIX)) self.assertNotIn(b'\x00', storage_string) - self.assertNotEqual(storage_string, pysodium.crypto_pwhash_scryptsalsa208sha256_str(passwd, ops_limit, mem_limit), "Each call should compute a new random salt.") + self.assertNotEqual(storage_string, pysodium.crypto_pwhash_scryptsalsa208sha256_str(passwd, ops_limit, mem_limit), b"Each call should compute a new random salt.") def test_crypto_pwhash_scryptsalsa208sha256_str_verify(self): passwd = b'Correct Horse Battery Staple' @@ -239,7 +239,7 @@ def test_crypto_sign_sk_to_seed(self): def test_AsymCrypto_With_Seeded_Keypair(self): msg = b"correct horse battery staple" nonce = pysodium.randombytes(pysodium.crypto_box_NONCEBYTES) - pk, sk = pysodium.crypto_box_seed_keypair("howdy") + pk, sk = pysodium.crypto_box_seed_keypair(b"howdy") c = pysodium.crypto_box(msg, nonce, pk, sk) m = pysodium.crypto_box_open(c, nonce, pk, sk) @@ -247,42 +247,29 @@ def test_AsymCrypto_With_Seeded_Keypair(self): self.assertEqual(msg, m) def test_crypto_hash_sha256(self): - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha256("test")), - "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08") - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha256("howdy")), - "0f1128046248f83dc9b9ab187e16fad0ff596128f1524d05a9a77c4ad932f10a") - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha256("Correct Horse Battery Staple")), - "af139fa284364215adfa49c889ab7feddc5e5d1c52512ffb2cfc9baeb67f220e") - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha256("pysodium")), - "0a53ef9bc1bea173118a42bbbe8300abb6bbef83139046940e9593d9559a5df7") + self.assertEqual(pysodium.crypto_hash_sha256(b"test"), + binascii.unhexlify(b"9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")) + self.assertEqual(pysodium.crypto_hash_sha256(b"howdy"), + binascii.unhexlify(b"0f1128046248f83dc9b9ab187e16fad0ff596128f1524d05a9a77c4ad932f10a")) + self.assertEqual(pysodium.crypto_hash_sha256(b"Correct Horse Battery Staple"), + binascii.unhexlify(b"af139fa284364215adfa49c889ab7feddc5e5d1c52512ffb2cfc9baeb67f220e")) + self.assertEqual(pysodium.crypto_hash_sha256(b"pysodium"), + binascii.unhexlify(b"0a53ef9bc1bea173118a42bbbe8300abb6bbef83139046940e9593d9559a5df7")) def test_crypto_hash_sha512(self): - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha512("test")), - "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff") - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha512("howdy")), - "905caca5c4685f296c5491d38660d7720ee87bef08f829332e905593522907674de8490de46c969d2c585b40af40439b387562d6f776023507753d1a9554ebbb") - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha512("Correct Horse Battery Staple")), - "0675070bda47bef936f0b65ae721d90f82ca137841df4d7cae27776501ae4b446ab926d64dc1d282c8758ac0eb02cc4aa11b2452d4f8ffeb795023b797fe2b80") - self.assertEqual(self.byteHashToString(pysodium.crypto_hash_sha512("pysodium")), - "ecbc6f4ffdb6e6dcbe6e6beecf0b8e05c11b0cc8a56f2b4098cd613585749fcca5ed1cfda3518e33a5d2c63746ee2857ff6857b9a2eeda4cc208c1e7fd89cc17") - - def byteHashToString(self, input): - import sys - result = "" - for i in range(0, len(input)): - if sys.version_info.major == 3: - tmp = str(hex(ord(chr(input[i]))))[2:] - else: - tmp = str(hex(ord(input[i])))[2:] - if len(tmp) is 1: - tmp = "0" + tmp - result += tmp - return result + self.assertEqual(pysodium.crypto_hash_sha512(b"test"), + binascii.unhexlify(b"ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff")) + self.assertEqual(pysodium.crypto_hash_sha512(b"howdy"), + binascii.unhexlify(b"905caca5c4685f296c5491d38660d7720ee87bef08f829332e905593522907674de8490de46c969d2c585b40af40439b387562d6f776023507753d1a9554ebbb")) + self.assertEqual(pysodium.crypto_hash_sha512(b"Correct Horse Battery Staple"), + binascii.unhexlify(b"0675070bda47bef936f0b65ae721d90f82ca137841df4d7cae27776501ae4b446ab926d64dc1d282c8758ac0eb02cc4aa11b2452d4f8ffeb795023b797fe2b80")) + self.assertEqual(pysodium.crypto_hash_sha512(b"pysodium"), + binascii.unhexlify(b"ecbc6f4ffdb6e6dcbe6e6beecf0b8e05c11b0cc8a56f2b4098cd613585749fcca5ed1cfda3518e33a5d2c63746ee2857ff6857b9a2eeda4cc208c1e7fd89cc17")) def test_crypto_auth(self): sk = pysodium.randombytes(pysodium.crypto_auth_KEYBYTES) - tag = pysodium.crypto_auth("howdy", sk) - pysodium.crypto_auth_verify(tag, "howdy", sk) + tag = pysodium.crypto_auth(b"howdy", sk) + pysodium.crypto_auth_verify(tag, b"howdy", sk) if __name__ == '__main__': unittest.main()