From d4b5421eae9d48e1e100a34027106a52d14ddafb Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Tue, 11 May 2021 00:33:31 +0000 Subject: [PATCH 01/30] [enh] added support for crypto_stream_xchacha20_xor(_ic) --- README.md | 4 ++++ pysodium/__init__.py | 29 +++++++++++++++++++++++++++++ test/test_pysodium.py | 16 ++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/README.md b/README.md index a32d996..684b920 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ crypto_sign_sk_to_seed(sk) crypto_sign_verify_detached(sig, msg, pk) crypto_stream_chacha20_xor(message, nonce, key) crypto_stream_chacha20_xor_ic(message, nonce, initial_counter, key) +crypto_stream_xchacha20_xor(message, nonce, key) +crypto_stream_xchacha20_xor_ic(message, nonce, initial_counter, key) crypto_stream(cnt, nonce=None, key=None) crypto_stream_xor(msg, cnt, nonce=None, key=None) randombytes(size) @@ -215,6 +217,8 @@ crypto_stream_KEYBYTES crypto_stream_NONCEBYTES crypto_stream_chacha20_NONCEBYTES crypto_stream_chacha20_KEYBYTES +crypto_stream_xchacha20_NONCEBYTES +crypto_stream_xchacha20_KEYBYTES crypto_core_ristretto255_BYTES crypto_core_ristretto255_HASHBYTES crypto_core_ristretto255_SCALARBYTES diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 89c7eed..605347b 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -120,6 +120,8 @@ def wrapper(*args, **kwargs): crypto_stream_NONCEBYTES = sodium.crypto_stream_noncebytes() crypto_stream_chacha20_NONCEBYTES = sodium.crypto_stream_chacha20_noncebytes() crypto_stream_chacha20_KEYBYTES = sodium.crypto_stream_chacha20_keybytes() +crypto_stream_xchacha20_NONCEBYTES = sodium.crypto_stream_xchacha20_noncebytes() +crypto_stream_xchacha20_KEYBYTES = sodium.crypto_stream_xchacha20_keybytes() crypto_generichash_KEYBYTES_MAX = sodium.crypto_generichash_keybytes_max() crypto_generichash_BYTES = sodium.crypto_generichash_bytes() crypto_generichash_BYTES_MIN = sodium.crypto_generichash_bytes_min() @@ -335,6 +337,33 @@ def crypto_stream_chacha20_xor_ic(message, nonce, initial_counter, key): return c.raw +# crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *k) +def crypto_stream_xchacha20_xor(message, nonce, key): + if len(nonce) != crypto_stream_xchacha20_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_stream_xchacha20_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_longlong(len(message)) + + c = ctypes.create_string_buffer(len(message)) + + __check(sodium.crypto_stream_xchacha20_xor(c, message, mlen, nonce, key)) + + return c.raw + +# crypto_stream_xchacha20_xor_ic(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, uint64_t ic, const unsigned char *k) +def crypto_stream_xchacha20_xor_ic(message, nonce, initial_counter, key): + if len(nonce) != crypto_stream_xchacha20_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_stream_xchacha20_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_longlong(len(message)) + ic = ctypes.c_uint64(initial_counter) + + c = ctypes.create_string_buffer(len(message)) + + __check(sodium.crypto_stream_xchacha20_xor_ic(c, message, mlen, nonce, ic, key)) + + return c.raw + # 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); def crypto_aead_chacha20poly1305_encrypt(message, ad, nonce, key): if len(nonce) != crypto_aead_chacha20poly1305_NONCEBYTES: raise ValueError("truncated nonce") diff --git a/test/test_pysodium.py b/test/test_pysodium.py index a7fdcad..22752d7 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -381,6 +381,22 @@ def test_crypto_stream_chacha20_xor_ic(self): output = pysodium.crypto_stream_chacha20_xor_ic(input_, nonce, ic, key) self.assertEqual(binascii.unhexlify(b"9db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9"), output) + def test_crypto_stream_xchacha20_xor(self): + # test vectors taken from: + # https://github.com/jedisct1/libsodium/blob/609e42be75589f91179d218e24f5e35a7124abfd/test/default/xchacha20.c#L102 + key = binascii.unhexlify("9d23bd4149cb979ccf3c5c94dd217e9808cb0e50cd0f67812235eaaf601d6232") + nonce = binascii.unhexlify("c047548266b7c370d33566a2425cbf30d82d1eaf5294109e") + out = binascii.unhexlify("a21209096594de8c5667b1d13ad93f744106d054df210e4782cd396fec692d3515a20bf351eec011a92c367888bc464c32f0807acd6c203a247e0db854148468e9f96bee4cf718d68d5f637cbd5a376457788e6fae90fc31097cfc") + output = pysodium.crypto_stream_xchacha20_xor(out, nonce, key) + self.assertEqual(b'\x00'*len(output), output) + + def test_crypto_stream_xchacha20_xor_ic(self): + key = binascii.unhexlify("9d23bd4149cb979ccf3c5c94dd217e9808cb0e50cd0f67812235eaaf601d6232") + nonce = binascii.unhexlify("c047548266b7c370d33566a2425cbf30d82d1eaf5294109e") + out = binascii.unhexlify("a21209096594de8c5667b1d13ad93f744106d054df210e4782cd396fec692d3515a20bf351eec011a92c367888bc464c32f0807acd6c203a247e0db854148468e9f96bee4cf718d68d5f637cbd5a376457788e6fae90fc31097cfc") + output = pysodium.crypto_stream_xchacha20_xor_ic(out, nonce, 0, key) + self.assertEqual(b'\x00'*len(output), output) + def test_crypto_blake2b(self): message = binascii.unhexlify(b'54686520717569636b2062726f776e20666f78206a756d7073206f76657220746865206c617a7920646f67') key = binascii.unhexlify(b'000102030405060708090a0b0c0d0e0f') From 8f5386f2e9a463f1f2c386134a8f15dabedd1cf5 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Mon, 27 Sep 2021 15:41:07 +0000 Subject: [PATCH 02/30] [mod] bump ver to 0.7.10 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 3b6e411..122bd5c 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.9", + version="0.7.10", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From 7999214dcd6671352785c44ad71e47f2fe13ee12 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 13 Jan 2022 22:52:13 +0000 Subject: [PATCH 03/30] [mod] added BYTES consts for hmacsha512 and sha512 --- pysodium/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 605347b..ed94dba 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -256,6 +256,8 @@ def wrapper(*args, **kwargs): crypto_core_ristretto255_NONREDUCEDSCALARBYTES = sodium.crypto_core_ristretto255_nonreducedscalarbytes() crypto_auth_hmacsha256_BYTES = sodium.crypto_auth_hmacsha256_bytes() crypto_hash_sha256_STATEBYTES = sodium.crypto_hash_sha256_statebytes() + crypto_auth_hmacsha512_BYTES = sodium.crypto_auth_hmacsha512_bytes() + crypto_hash_sha512_STATEBYTES = sodium.crypto_hash_sha512_statebytes() sodium_init = sodium.sodium_init From 88e631c90251d025ea737c8b417bb0dec111a617 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Fri, 14 Jan 2022 21:56:08 +0000 Subject: [PATCH 04/30] [mod] bump version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 122bd5c..749ee17 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.10", + version="0.7.11", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From a48f29cb08a5ded330c07f7b39a00c344edddfe7 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Mon, 16 May 2022 13:57:09 +0200 Subject: [PATCH 05/30] Do not install tests (#105) The tests should only be in the source tarball and not be installed. --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 749ee17..5c01361 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ def read(fname): license="BSD", keywords="cryptography API NaCl libsodium", url="https://github.com/stef/pysodium", - packages=find_packages(), + packages=find_packages(exclude=['test*']), long_description=read('README.md'), requires=["libsodium"], classifiers=["Development Status :: 4 - Beta", From e2b777c059f5caf2931ddac7fce56cf25701ab71 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Mon, 16 May 2022 11:58:56 +0000 Subject: [PATCH 06/30] [mod] bumping v --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5c01361..991e144 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.11", + version="0.7.12", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From af54a371ddc68506fe6ec5c500e3739673623524 Mon Sep 17 00:00:00 2001 From: stsch9 <85763581+stsch9@users.noreply.github.com> Date: Mon, 25 Sep 2023 22:33:40 +0200 Subject: [PATCH 07/30] add crypto_stream_chacha20_ietf (#106) --- README.md | 4 ++++ pysodium/__init__.py | 29 +++++++++++++++++++++++++++++ test/test_pysodium.py | 16 ++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/README.md b/README.md index 684b920..1844d73 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,8 @@ crypto_sign_sk_to_seed(sk) crypto_sign_verify_detached(sig, msg, pk) crypto_stream_chacha20_xor(message, nonce, key) crypto_stream_chacha20_xor_ic(message, nonce, initial_counter, key) +crypto_stream_chacha20_ietf_xor(message, nonce, key) +crypto_stream_chacha20_ietf_xor_ic(message, nonce, initial_counter, key) crypto_stream_xchacha20_xor(message, nonce, key) crypto_stream_xchacha20_xor_ic(message, nonce, initial_counter, key) crypto_stream(cnt, nonce=None, key=None) @@ -217,6 +219,8 @@ crypto_stream_KEYBYTES crypto_stream_NONCEBYTES crypto_stream_chacha20_NONCEBYTES crypto_stream_chacha20_KEYBYTES +crypto_stream_chacha20_ietf_NONCEBYTES +crypto_stream_chacha20_ietf_KEYBYTES crypto_stream_xchacha20_NONCEBYTES crypto_stream_xchacha20_KEYBYTES crypto_core_ristretto255_BYTES diff --git a/pysodium/__init__.py b/pysodium/__init__.py index ed94dba..f4237f2 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -120,6 +120,8 @@ def wrapper(*args, **kwargs): crypto_stream_NONCEBYTES = sodium.crypto_stream_noncebytes() crypto_stream_chacha20_NONCEBYTES = sodium.crypto_stream_chacha20_noncebytes() crypto_stream_chacha20_KEYBYTES = sodium.crypto_stream_chacha20_keybytes() +crypto_stream_chacha20_ietf_NONCEBYTES = sodium.crypto_stream_chacha20_ietf_noncebytes() +crypto_stream_chacha20_ietf_KEYBYTES = sodium.crypto_stream_chacha20_ietf_keybytes() crypto_stream_xchacha20_NONCEBYTES = sodium.crypto_stream_xchacha20_noncebytes() crypto_stream_xchacha20_KEYBYTES = sodium.crypto_stream_xchacha20_keybytes() crypto_generichash_KEYBYTES_MAX = sodium.crypto_generichash_keybytes_max() @@ -339,6 +341,33 @@ def crypto_stream_chacha20_xor_ic(message, nonce, initial_counter, key): return c.raw +# crypto_stream_chacha20_ietf_xor(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *k) +def crypto_stream_chacha20_ietf_xor(message, nonce, key): + if len(nonce) != crypto_stream_chacha20_ietf_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_stream_chacha20_ietf_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_longlong(len(message)) + + c = ctypes.create_string_buffer(len(message)) + + __check(sodium.crypto_stream_chacha20_ietf_xor(c, message, mlen, nonce, key)) + + return c.raw + +# crypto_stream_chacha20_ietf_xor_ic(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, uint64_t ic, const unsigned char *k) +def crypto_stream_chacha20_ietf_xor_ic(message, nonce, initial_counter, key): + if len(nonce) != crypto_stream_chacha20_ietf_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_stream_chacha20_ietf_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_longlong(len(message)) + ic = ctypes.c_uint64(initial_counter) + + c = ctypes.create_string_buffer(len(message)) + + __check(sodium.crypto_stream_chacha20_ietf_xor_ic(c, message, mlen, nonce, ic, key)) + + return c.raw + # crypto_stream_xchacha20_xor(unsigned char *c, const unsigned char *m, unsigned long long mlen, const unsigned char *n, const unsigned char *k) def crypto_stream_xchacha20_xor(message, nonce, key): if len(nonce) != crypto_stream_xchacha20_NONCEBYTES: raise ValueError("truncated nonce") diff --git a/test/test_pysodium.py b/test/test_pysodium.py index 22752d7..5875087 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -381,6 +381,22 @@ def test_crypto_stream_chacha20_xor_ic(self): output = pysodium.crypto_stream_chacha20_xor_ic(input_, nonce, ic, key) self.assertEqual(binascii.unhexlify(b"9db9d4f7c7a899151b9a475032b63fc385245fe054e3dd5a97a5f576fe064025d3ce042c566ab2c507b138db853e3d6959660996546cc9c4a6eafdc777c040d70eaf46f76dad3979e5c5360c3317166a1c894c94a371876a94df7628fe4eaaf2ccb27d5aaae0ad7ad0f9d4b6ad3b54098746d4524d38407a6deb3ab78fab78c9"), output) + def test_crypto_stream_chacha20_ietf_xor(self): + key = binascii.unhexlify(b"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + nonce = binascii.unhexlify(b"000000090000004a00000000") + input_ = b'\x00' * 256 + output = pysodium.crypto_stream_chacha20_ietf_xor(input_, nonce, key) + self.assertEqual(binascii.unhexlify(b"8adc91fd9ff4f0f51b0fad50ff15d637e40efda206cc52c783a74200503c1582cd9833367d0a54d57d3c9e998f490ee69ca34c1ff9e939a75584c52d690a35d410f1e7e4d13b5915500fdd1fa32071c4c7d1f4c733c068030422aa9ac3d46c4ed2826446079faa0914c2d705d98b02a2b5129cd1de164eb9cbd083e8a2503c4e0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8e721f89255f9c486bf21679c683d4f9c5cf2fa27865526005b06ca374c86af3bdcbfbdcb83be65862ed5c20eae5a43241d6a92da6dca9a156be25297f51c27188a861e93cc3aeb129a76598baccd27453ac6941b4b4e1e5153a9fee95d1ba00e"), + output) + + def test_crypto_stream_chacha20_ietf_xor_ic(self): + key = binascii.unhexlify(b"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + nonce = binascii.unhexlify(b"000000090000004a00000000") + input_ = b'\x00' * 128 + ic = 2 + output = pysodium.crypto_stream_chacha20_ietf_xor_ic(input_, nonce, ic, key) + self.assertEqual(binascii.unhexlify(b"0a88837739d7bf4ef8ccacb0ea2bb9d69d56c394aa351dfda5bf459f0a2e9fe8e721f89255f9c486bf21679c683d4f9c5cf2fa27865526005b06ca374c86af3bdcbfbdcb83be65862ed5c20eae5a43241d6a92da6dca9a156be25297f51c27188a861e93cc3aeb129a76598baccd27453ac6941b4b4e1e5153a9fee95d1ba00e"), output) + def test_crypto_stream_xchacha20_xor(self): # test vectors taken from: # https://github.com/jedisct1/libsodium/blob/609e42be75589f91179d218e24f5e35a7124abfd/test/default/xchacha20.c#L102 From ee2ff0404a60246cacadeafc448761e4af8a6059 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Mon, 25 Sep 2023 22:35:06 +0200 Subject: [PATCH 08/30] [mod] bumped version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 991e144..07bebd8 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.12", + version="0.7.13", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From 9224850f19adaab59eb17fcda7daac41e6196187 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 6 Oct 2023 01:47:19 +0800 Subject: [PATCH 09/30] [enh] Adds hmacsha{256,512,512256}_{-,keygen,verify} --- pysodium/__init__.py | 139 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index f4237f2..44a3915 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -571,6 +571,145 @@ def crypto_auth_verify(h, m, k): raise ValueError("invalid tag") __check(sodium.crypto_auth_verify(h, m, ctypes.c_ulonglong(len(m)), k)) + +# void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]); +def crypto_auth_hmacsha256_keygen(): + k = ctypes.create_string_buffer(crypto_auth_hmacsha256_KEYBYTES) + __check(sodium.crypto_auth_hmacsha256_keygen(k)) + return k.raw + + +# int crypto_auth_hmacsha256(unsigned char *out, +# const unsigned char *in, +# unsigned long long inlen, +# const unsigned char *k); +def crypto_auth_hmacsha256(m, k): + if not len(k) == crypto_auth_hmacsha256_KEYBYTES: + raise ValueError("invalid parameters") + buf = ctypes.create_string_buffer(crypto_auth_hmacsha256_BYTES) + msg = ctypes.create_string_buffer(m) + key = ctypes.create_string_buffer(k) + __check( + sodium.crypto_auth_hmacsha256( + ctypes.byref(buf), + ctypes.byref(msg), + ctypes.c_ulonglong(len(m)), + ctypes.byref(key), + ) + ) + return buf.raw + + +# int crypto_auth_hmacsha256_verify(const unsigned char *h, +# const unsigned char *in, +# unsigned long long inlen, +# const unsigned char *k); +def crypto_auth_hmacsha256_verify(h, m, k): + if not len(k) == crypto_auth_hmacsha256_KEYBYTES: + raise ValueError("invalid parameters") + hmac = ctypes.create_string_buffer(h) + msg = ctypes.create_string_buffer(m) + mlen = ctypes.c_ulonglong(len(m)) + key = ctypes.create_string_buffer(k) + __check( + sodium.crypto_auth_hmacsha256_verify( + ctypes.byref(hmac), ctypes.byref(msg), mlen, ctypes.byref(key) + ) + ) + + +# void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]); +def crypto_auth_hmacsha512_keygen(): + k = ctypes.create_string_buffer(crypto_auth_hmacsha512_KEYBYTES) + __check(sodium.crypto_auth_hmacsha512_keygen(k)) + return k.raw + + +# int crypto_auth_hmacsha512(unsigned char *out, +# const unsigned char *in, +# unsigned long long inlen, +# const unsigned char *k); +def crypto_auth_hmacsha512(m, k): + if not len(k) == crypto_auth_hmacsha512_KEYBYTES: + raise ValueError("invalid parameters") + buf = ctypes.create_string_buffer(crypto_auth_hmacsha512_BYTES) + msg = ctypes.create_string_buffer(m) + key = ctypes.create_string_buffer(k) + __check( + sodium.crypto_auth_hmacsha512( + ctypes.byref(buf), + ctypes.byref(msg), + ctypes.c_ulonglong(len(m)), + ctypes.byref(key), + ) + ) + return buf.raw + + +# int crypto_auth_hmacsha512_verify(const unsigned char *h, +# const unsigned char *in, +# unsigned long long inlen, +# const unsigned char *k); +def crypto_auth_hmacsha512_verify(h, m, k): + if not len(k) == crypto_auth_hmacsha512_KEYBYTES: + raise ValueError("invalid parameters") + hmac = ctypes.create_string_buffer(h) + msg = ctypes.create_string_buffer(m) + mlen = ctypes.c_ulonglong(len(m)) + key = ctypes.create_string_buffer(k) + __check( + sodium.crypto_auth_hmacsha512_verify( + ctypes.byref(hmac), ctypes.byref(msg), mlen, ctypes.byref(key) + ) + ) + + +# void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]); +def crypto_auth_hmacsha512256_keygen(): + k = ctypes.create_string_buffer(crypto_auth_hmacsha512256_KEYBYTES) + __check(sodium.crypto_auth_hmacsha512256_keygen(k)) + return k.raw + + +# int crypto_auth_hmacsha512256(unsigned char *out, +# const unsigned char *in, +# unsigned long long inlen, +# const unsigned char *k); +def crypto_auth_hmacsha512256(m, k): + if not len(k) == crypto_auth_hmacsha512256_KEYBYTES: + raise ValueError("invalid parameters") + buf = ctypes.create_string_buffer(crypto_auth_hmacsha512256_BYTES) + msg = ctypes.create_string_buffer(m) + key = ctypes.create_string_buffer(k) + __check( + sodium.crypto_auth_hmacsha512256( + ctypes.byref(buf), + ctypes.byref(msg), + ctypes.c_ulonglong(len(m)), + ctypes.byref(key), + ) + ) + return buf.raw + + +# int crypto_auth_hmacsha512256_verify(const unsigned char *h, +# const unsigned char *in, +# unsigned long long inlen, +# const unsigned char *k); +def crypto_auth_hmacsha512256_verify(h, m, k): + if not len(k) == crypto_auth_hmacsha512256_KEYBYTES: + raise ValueError("invalid parameters") + hmac = ctypes.create_string_buffer(h) + msg = ctypes.create_string_buffer(m) + mlen = ctypes.c_ulonglong(len(m)) + key = ctypes.create_string_buffer(k) + __check( + sodium.crypto_auth_hmacsha512256_verify( + ctypes.byref(hmac), ctypes.byref(msg), mlen, ctypes.byref(key) + ) + ) + + # crypto_generichash(unsigned char *out, size_t outlen, const unsigned char *in, unsigned long long inlen, const unsigned char *key, size_t keylen) @encode_strings def crypto_generichash(m, k=b'', outlen=crypto_generichash_BYTES): From fcfc9e0dde68635070491ae83e3a328ae1fbd1a1 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 6 Oct 2023 01:57:48 +0800 Subject: [PATCH 10/30] [fix] add constants for hmacsha{256,512,512256} --- pysodium/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 44a3915..c9d7d25 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -257,9 +257,13 @@ def wrapper(*args, **kwargs): crypto_core_ristretto255_SCALARBYTES = sodium.crypto_core_ristretto255_scalarbytes() crypto_core_ristretto255_NONREDUCEDSCALARBYTES = sodium.crypto_core_ristretto255_nonreducedscalarbytes() crypto_auth_hmacsha256_BYTES = sodium.crypto_auth_hmacsha256_bytes() + crypto_auth_hmacsha256_KEYBYTES = sodium.crypto_auth_hmacsha256_keybytes() crypto_hash_sha256_STATEBYTES = sodium.crypto_hash_sha256_statebytes() crypto_auth_hmacsha512_BYTES = sodium.crypto_auth_hmacsha512_bytes() + crypto_auth_hmacsha512_KEYBYTES = sodium.crypto_auth_hmacsha512_keybytes() crypto_hash_sha512_STATEBYTES = sodium.crypto_hash_sha512_statebytes() + crypto_auth_hmacsha512256_BYTES = sodium.crypto_auth_hmacsha512256_bytes() + crypto_auth_hmacsha512256_KEYBYTES = sodium.crypto_auth_hmacsha512256_keybytes() sodium_init = sodium.sodium_init From 7b89df3aec9f5036609035c0c134715ca598f68e Mon Sep 17 00:00:00 2001 From: Jonathan Date: Fri, 6 Oct 2023 02:18:12 +0800 Subject: [PATCH 11/30] [enh]Tests for crypto_auth_hmacsha{256,512,512256}_{.,keygen,verify} --- test/test_pysodium.py | 78 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/test/test_pysodium.py b/test/test_pysodium.py index 5875087..20bc74f 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -61,6 +61,84 @@ def test_crypto_generichash(self): self.assertNotEqual(pysodium.crypto_generichash( 'salt0'), pysodium.crypto_generichash( 'salt1')) self.assertNotEqual(pysodium.crypto_generichash(b'salt0'), pysodium.crypto_generichash(b'salt1')) + def test_crypto_auth_hmac_256_512_512256(self): + """Taken from https://www.rfc-editor.org/rfc/rfc4231#section-4""" + vectors = [ + { + "k": b"\x0b" * 20 + b"\x00" * 12, + "m": b"Hi There", + "256": bytes.fromhex( + "b0344c61d8db38535ca8afceaf0bf12b" + "881dc200c9833da726e9376c2e32cff7" + ), + "512": bytes.fromhex( + "87aa7cdea5ef619d4ff0b4241a1d6cb0" + "2379f4e2ce4ec2787ad0b30545e17cde" + "daa833b7d6b8a702038b274eaea3f4e4" + "be9d914eeb61f1702e696c203a126854" + ), + "512256": bytes.fromhex( + "87aa7cdea5ef619d4ff0b4241a1d6cb0" + "2379f4e2ce4ec2787ad0b30545e17cde" + ), + }, + { + "k": b"Jefe" + b"\x00" * 28, + "m": b"what do ya want for nothing?", + "256": bytes.fromhex( + "5bdcc146bf60754e6a042426089575c7" + "5a003f089d2739839dec58b964ec3843" + ), + "512": bytes.fromhex( + "164b7a7bfcf819e2e395fbe73b56e0a3" + "87bd64222e831fd610270cd7ea250554" + "9758bf75c05a994a6d034f65f8f0e6fd" + "caeab1a34d4a6b4b636e070a38bce737" + ), + "512256": bytes.fromhex( + "164b7a7bfcf819e2e395fbe73b56e0a3" + "87bd64222e831fd610270cd7ea250554" + ), + }, + ] + + for v in vectors: + self.assertEqual(pysodium.crypto_auth_hmacsha256(v["m"], v["k"]), v["256"]) + self.assertEqual(pysodium.crypto_auth_hmacsha512(v["m"], v["k"]), v["512"]) + self.assertEqual( + pysodium.crypto_auth_hmacsha512256(v["m"], v["k"]), v["512256"] + ) + try: + pysodium.crypto_auth_hmacsha256_verify(v["256"], v["m"], v["k"]) + pysodium.crypto_auth_hmacsha512_verify(v["512"], v["m"], v["k"]) + pysodium.crypto_auth_hmacsha512256_verify(v["512256"], v["m"], v["k"]) + except Exception as e: + self.assertTrue(False, f"verification fail: {e}") + + msg = b"pull request plz" + try: + key = pysodium.crypto_auth_hmacsha256_keygen() + hmac = pysodium.crypto_auth_hmacsha256(msg, key) + pysodium.crypto_auth_hmacsha256_verify(hmac, msg, key) + + except Exception: + self.assertTrue(False) + + try: + key = pysodium.crypto_auth_hmacsha256_keygen() + hmac = pysodium.crypto_auth_hmacsha256(msg, key) + pysodium.crypto_auth_hmacsha256_verify(hmac, msg, key) + + except Exception: + self.assertTrue(False) + + try: + key = pysodium.crypto_auth_hmacsha256_keygen() + hmac = pysodium.crypto_auth_hmacsha256(msg, key) + pysodium.crypto_auth_hmacsha256_verify(hmac, msg, key) + + except Exception: + self.assertTrue(False) def test_crypto_box_pk_from_sk(self): pk1, sk = pysodium.crypto_box_keypair() From a8a9c6389c0f5e949f488371404ca13e49c73db2 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 5 Oct 2023 20:38:25 +0200 Subject: [PATCH 12/30] [doc] added new hmac symbols to readme --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 1844d73..01d9303 100644 --- a/README.md +++ b/README.md @@ -103,6 +103,15 @@ crypto_core_ristretto255_scalar_complement(s) crypto_core_ristretto255_scalar_add(x,y) crypto_core_ristretto255_scalar_sub(x,y) crypto_core_ristretto255_scalar_mul(x,y) +crypto_auth_hmacsha256_keygen +crypto_auth_hmacsha256 +crypto_auth_hmacsha256_verify +crypto_auth_hmacsha512_keygen +crypto_auth_hmacsha512 +crypto_auth_hmacsha512_verify +crypto_auth_hmacsha512256_keygen +crypto_auth_hmacsha512256 +crypto_auth_hmacsha512256_verify ``` Constants: @@ -227,6 +236,12 @@ crypto_core_ristretto255_BYTES crypto_core_ristretto255_HASHBYTES crypto_core_ristretto255_SCALARBYTES crypto_core_ristretto255_NONREDUCEDSCALARBYTES +crypto_auth_hmacsha256_BYTES +crypto_auth_hmacsha256_KEYBYTES +crypto_auth_hmacsha512_BYTES +crypto_auth_hmacsha512_KEYBYTES +crypto_auth_hmacsha512256_BYTES +crypto_auth_hmacsha512256_KEYBYTES ``` From 99c1b643e4e8c1417e3656753025c6c04c911021 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 5 Oct 2023 20:40:40 +0200 Subject: [PATCH 13/30] [doc] added jonathan as author --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index cde6e86..4b77e65 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,3 +17,4 @@ venzen Blaz Bregar berndb84 Chris Topher c@creemama.com +Jonathan Levin From 993d077b0bda8402614a68991bf1858f35327fbd Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 5 Oct 2023 20:41:01 +0200 Subject: [PATCH 14/30] [mod] bumped version --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 07bebd8..aadc19c 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.13", + version="0.7.14", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From 9d078c48f76d5e81a82877a92ac0424f167bf9fc Mon Sep 17 00:00:00 2001 From: stsch9 Date: Wed, 29 Nov 2023 18:07:25 +0100 Subject: [PATCH 15/30] add hkdf and bug fix --- README.md | 10 +++++++ pysodium/__init__.py | 65 +++++++++++++++++++++++++++++++++++++++++-- test/test_pysodium.py | 32 +++++++++++++++++++++ 3 files changed, 104 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 01d9303..164c86e 100644 --- a/README.md +++ b/README.md @@ -112,6 +112,12 @@ crypto_auth_hmacsha512_verify crypto_auth_hmacsha512256_keygen crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_verify +crypto_kdf_hkdf_sha256_extract_init(salt=b'') +crypto_kdf_hkdf_sha256_extract_update(state, ikm=b'') +crypto_kdf_hkdf_sha256_extract_final(state) +crypto_kdf_hkdf_sha256_extract(salt=b'', ikm=b'') +crypto_kdf_hkdf_sha256_keygen() +crypto_kdf_hkdf_sha256_expand(outlen, prk, ctx=b'') ``` Constants: @@ -242,6 +248,10 @@ crypto_auth_hmacsha512_BYTES crypto_auth_hmacsha512_KEYBYTES crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_KEYBYTES +crypto_kdf_hkdf_sha256_KEYBYTES +crypto_kdf_hkdf_sha256_BYTES_MIN +crypto_kdf_hkdf_sha256_BYTES_MAX +crypto_kdf_hkdf_sha256_STATEBYTES ``` diff --git a/pysodium/__init__.py b/pysodium/__init__.py index c9d7d25..71943f1 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -265,6 +265,12 @@ def wrapper(*args, **kwargs): crypto_auth_hmacsha512256_BYTES = sodium.crypto_auth_hmacsha512256_bytes() crypto_auth_hmacsha512256_KEYBYTES = sodium.crypto_auth_hmacsha512256_keybytes() +if sodium_version_check(1, 0, 19): + crypto_kdf_hkdf_sha256_KEYBYTES = sodium.crypto_kdf_hkdf_sha256_keybytes() + crypto_kdf_hkdf_sha256_BYTES_MIN = sodium.crypto_kdf_hkdf_sha256_bytes_min() + crypto_kdf_hkdf_sha256_BYTES_MAX = sodium.crypto_kdf_hkdf_sha256_bytes_max() + crypto_kdf_hkdf_sha256_STATEBYTES = sodium.crypto_kdf_hkdf_sha256_statebytes() + sodium_init = sodium.sodium_init class CryptoSignState(ctypes.Structure): @@ -579,7 +585,7 @@ def crypto_auth_verify(h, m, k): # void crypto_auth_hmacsha256_keygen(unsigned char k[crypto_auth_hmacsha256_KEYBYTES]); def crypto_auth_hmacsha256_keygen(): k = ctypes.create_string_buffer(crypto_auth_hmacsha256_KEYBYTES) - __check(sodium.crypto_auth_hmacsha256_keygen(k)) + sodium.crypto_auth_hmacsha256_keygen(k) return k.raw @@ -625,7 +631,7 @@ def crypto_auth_hmacsha256_verify(h, m, k): # void crypto_auth_hmacsha512_keygen(unsigned char k[crypto_auth_hmacsha512_KEYBYTES]); def crypto_auth_hmacsha512_keygen(): k = ctypes.create_string_buffer(crypto_auth_hmacsha512_KEYBYTES) - __check(sodium.crypto_auth_hmacsha512_keygen(k)) + sodium.crypto_auth_hmacsha512_keygen(k) return k.raw @@ -671,7 +677,7 @@ def crypto_auth_hmacsha512_verify(h, m, k): # void crypto_auth_hmacsha512256_keygen(unsigned char k[crypto_auth_hmacsha512256_KEYBYTES]); def crypto_auth_hmacsha512256_keygen(): k = ctypes.create_string_buffer(crypto_auth_hmacsha512256_KEYBYTES) - __check(sodium.crypto_auth_hmacsha512256_keygen(k)) + sodium.crypto_auth_hmacsha512256_keygen(k) return k.raw @@ -1345,6 +1351,59 @@ def crypto_hash_sha512_final(state): __check(sodium.crypto_hash_sha512_final(state, out)) return out.raw +# int crypto_kdf_hkdf_sha256_extract_init(crypto_kdf_hkdf_sha256_state *state, +# const unsigned char *salt, size_t salt_len) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha256_extract_init(salt=b''): + state = ctypes.create_string_buffer(crypto_kdf_hkdf_sha256_STATEBYTES) + __check(sodium.crypto_kdf_hkdf_sha256_extract_init(state, salt, ctypes.c_size_t(len(salt)))) + return state + +# int crypto_kdf_hkdf_sha256_extract_update(crypto_kdf_hkdf_sha256_state *state, +# const unsigned char *ikm, size_t ikm_len) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha256_extract_update(state, ikm=b''): + if len(state) != crypto_kdf_hkdf_sha256_STATEBYTES: raise ValueError("invalid state") + __check(sodium.crypto_kdf_hkdf_sha256_extract_update(state, ikm, ctypes.c_size_t(len(ikm)))) + return state + +# int crypto_kdf_hkdf_sha256_extract_final(crypto_kdf_hkdf_sha256_state *state, +# unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha256_extract_final(state): + if len(state) != crypto_kdf_hkdf_sha256_STATEBYTES: raise ValueError("invalid state") + prk = ctypes.create_string_buffer(crypto_kdf_hkdf_sha256_KEYBYTES) + __check(sodium.crypto_kdf_hkdf_sha256_extract_final(state, prk)) + return prk.raw + +# int crypto_kdf_hkdf_sha256_extract( +# unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES], +# const unsigned char *salt, size_t salt_len, const unsigned char *ikm, +# size_t ikm_len) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha256_extract(salt=b'', ikm=b''): + prk = ctypes.create_string_buffer(crypto_kdf_hkdf_sha256_KEYBYTES) + __check(sodium.crypto_kdf_hkdf_sha256_extract(prk, salt, ctypes.c_size_t(len(salt)), ikm, ctypes.c_size_t(len(ikm)))) + return prk.raw + +# void crypto_kdf_hkdf_sha256_keygen(unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha256_keygen(): + k = ctypes.create_string_buffer(crypto_kdf_hkdf_sha256_KEYBYTES) + sodium.crypto_kdf_hkdf_sha256_keygen(k) + return k.raw + +# int crypto_kdf_hkdf_sha256_expand(unsigned char *out, size_t out_len, +# const char *ctx, size_t ctx_len, +# const unsigned char prk[crypto_kdf_hkdf_sha256_KEYBYTES]) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha256_expand(outlen, prk, ctx=b''): + if not (crypto_kdf_hkdf_sha256_BYTES_MIN <= outlen <= crypto_kdf_hkdf_sha256_BYTES_MAX): raise ValueError("invalid output len") + if len(prk) != crypto_kdf_hkdf_sha256_KEYBYTES: raise ValueError("invalid prk") + out = ctypes.create_string_buffer(outlen) + __check(sodium.crypto_kdf_hkdf_sha256_expand(out, ctypes.c_size_t(outlen), ctx, ctypes.c_size_t(len(ctx)), prk)) + return out.raw + # int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], # unsigned char sk[crypto_kx_SECRETKEYBYTES]); @sodium_version(1, 0, 12) diff --git a/test/test_pysodium.py b/test/test_pysodium.py index 20bc74f..ce88ebe 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -626,6 +626,38 @@ def test_crypto_auth(self): tag = pysodium.crypto_auth("howdy", sk) pysodium.crypto_auth_verify(tag, "howdy", sk) + def test_crypto_kdf_hkdf_sha256(self): + # test vectors: https://datatracker.ietf.org/doc/html/rfc5869 + if not pysodium.sodium_version_check(1, 0, 19): return + expected_prk = bytes.fromhex("077709362c2e32df0ddc3f0dc47bba6390b6c73bb50f9c3122ec844ad7c2b3e5") + expected_out = bytes.fromhex("3cb25f25faacd57a90434f64d0362f2a2d2d0a90cf1a5a4c5db02d56ecc4c5bf34007208d5b887185865") + ikm = bytes.fromhex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b") + salt = bytes.fromhex("000102030405060708090a0b0c") + ctx = bytes.fromhex("f0f1f2f3f4f5f6f7f8f9") + outlen = 42 + self.assertEqual(expected_prk, pysodium.crypto_kdf_hkdf_sha256_extract(salt, ikm)) + self.assertEqual(expected_out, pysodium.crypto_kdf_hkdf_sha256_expand(outlen, expected_prk, ctx)) + + expected_prk = bytes.fromhex("06a6b88c5853361a06104c9ceb35b45cef760014904671014a193f40c15fc244") + expected_out = bytes.fromhex("b11e398dc80327a1c8e7f78c596a49344f012eda2d4efad8a050cc4c19afa97c59045a99cac7827271cb41c65e590e09da3275600c2f09b8367793a9aca3db71cc30c58179ec3e87c14c01d5c1f3434f1d87") + ikm = bytes.fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f") + salt = bytes.fromhex("606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeaf") + ctx = bytes.fromhex("b0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff") + outlen = 82 + self.assertEqual(expected_prk, pysodium.crypto_kdf_hkdf_sha256_extract(salt, ikm)) + self.assertEqual(expected_out, pysodium.crypto_kdf_hkdf_sha256_expand(outlen, expected_prk, ctx)) + + expected_prk = bytes.fromhex("19ef24a32c717b167f33a91d6f648bdf96596776afdb6377ac434c1c293ccb04") + expected_out = bytes.fromhex("8da4e775a563c18f715f802a063c5a31b8a11f5c5ee1879ec3454e5f3c738d2d9d201395faa4b61a96c8") + ikm = bytes.fromhex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b") + salt = bytes.fromhex("") + ctx = bytes.fromhex("") + outlen = 42 + state = pysodium.crypto_kdf_hkdf_sha256_extract_init(salt) + state = pysodium.crypto_kdf_hkdf_sha256_extract_update(state, ikm) + self.assertEqual(expected_prk, pysodium.crypto_kdf_hkdf_sha256_extract_final(state)) + self.assertEqual(expected_out, pysodium.crypto_kdf_hkdf_sha256_expand(outlen, expected_prk, ctx)) + def test_crypto_kx(self): if not pysodium.sodium_version_check(1, 0, 12): return client_pk, client_sk = pysodium.crypto_kx_keypair() From a99ea4f00f78602e580e46101513eca5df6ab945 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Wed, 29 Nov 2023 19:44:57 +0100 Subject: [PATCH 16/30] [mod] bump version to 0.7.15 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index aadc19c..d70b037 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.14", + version="0.7.15", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From 9904e55759ccdffb6b67cbc718f067c749da8dc3 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 29 Nov 2023 22:30:32 +0100 Subject: [PATCH 17/30] Fix funky indentation --- pysodium/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 71943f1..b817ebe 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -888,10 +888,10 @@ def crypto_box_seal_open(c, pk, sk): return msg.raw # int crypto_secretbox_detached(unsigned char *c, unsigned char *mac, -# const unsigned char *m, -# unsigned long long mlen, -# const unsigned char *n, -# const unsigned char *k); +# const unsigned char *m, +# unsigned long long mlen, +# const unsigned char *n, +# const unsigned char *k); def crypto_secretbox_detached(msg, nonce, k): if None in (msg, nonce, k): raise ValueError("invalid parameters") From d244da8939be6258b26e2a092aea44f2a0ff6f71 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 29 Nov 2023 22:30:00 +0100 Subject: [PATCH 18/30] Add crypto_kdf_hkdf_sha512() --- README.md | 6 +++++ pysodium/__init__.py | 59 +++++++++++++++++++++++++++++++++++++++++++ test/test_pysodium.py | 11 ++++++++ 3 files changed, 76 insertions(+) diff --git a/README.md b/README.md index 164c86e..d1fe1e8 100644 --- a/README.md +++ b/README.md @@ -118,6 +118,12 @@ crypto_kdf_hkdf_sha256_extract_final(state) crypto_kdf_hkdf_sha256_extract(salt=b'', ikm=b'') crypto_kdf_hkdf_sha256_keygen() crypto_kdf_hkdf_sha256_expand(outlen, prk, ctx=b'') +crypto_kdf_hkdf_sha512_extract_init(salt=b'') +crypto_kdf_hkdf_sha512_extract_update(state, ikm=b'') +crypto_kdf_hkdf_sha512_extract_final(state) +crypto_kdf_hkdf_sha512_extract(salt=b'', ikm=b'') +crypto_kdf_hkdf_sha512_keygen() +crypto_kdf_hkdf_sha512_expand(outlen, prk, ctx=b'') ``` Constants: diff --git a/pysodium/__init__.py b/pysodium/__init__.py index b817ebe..ef4cd16 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -270,6 +270,12 @@ def wrapper(*args, **kwargs): crypto_kdf_hkdf_sha256_BYTES_MIN = sodium.crypto_kdf_hkdf_sha256_bytes_min() crypto_kdf_hkdf_sha256_BYTES_MAX = sodium.crypto_kdf_hkdf_sha256_bytes_max() crypto_kdf_hkdf_sha256_STATEBYTES = sodium.crypto_kdf_hkdf_sha256_statebytes() + crypto_kdf_hkdf_sha512_KEYBYTES = sodium.crypto_kdf_hkdf_sha512_keybytes() + crypto_kdf_hkdf_sha512_BYTES_MIN = sodium.crypto_kdf_hkdf_sha512_bytes_min() + crypto_kdf_hkdf_sha512_BYTES_MAX = sodium.crypto_kdf_hkdf_sha512_bytes_max() + +if sodium_version_check(1, 0, 20): + crypto_kdf_hkdf_sha512_STATEBYTES = sodium.crypto_kdf_hkdf_sha512_statebytes() sodium_init = sodium.sodium_init @@ -1404,6 +1410,59 @@ def crypto_kdf_hkdf_sha256_expand(outlen, prk, ctx=b''): __check(sodium.crypto_kdf_hkdf_sha256_expand(out, ctypes.c_size_t(outlen), ctx, ctypes.c_size_t(len(ctx)), prk)) return out.raw +# int crypto_kdf_hkdf_sha512_extract_init(crypto_kdf_hkdf_sha512_state *state, +# const unsigned char *salt, size_t salt_len) +@sodium_version(1, 0, 20) +def crypto_kdf_hkdf_sha512_extract_init(salt=b''): + state = ctypes.create_string_buffer(crypto_kdf_hkdf_sha512_STATEBYTES) + __check(sodium.crypto_kdf_hkdf_sha512_extract_init(state, salt, ctypes.c_size_t(len(salt)))) + return state + +# int crypto_kdf_hkdf_sha512_extract_update(crypto_kdf_hkdf_sha512_state *state, +# const unsigned char *ikm, size_t ikm_len) +@sodium_version(1, 0, 20) +def crypto_kdf_hkdf_sha512_extract_update(state, ikm=b''): + if len(state) != crypto_kdf_hkdf_sha512_STATEBYTES: raise ValueError("invalid state") + __check(sodium.crypto_kdf_hkdf_sha512_extract_update(state, ikm, ctypes.c_size_t(len(ikm)))) + return state + +# int crypto_kdf_hkdf_sha512_extract_final(crypto_kdf_hkdf_sha512_state *state, +# unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) +@sodium_version(1, 0, 20) +def crypto_kdf_hkdf_sha512_extract_final(state): + if len(state) != crypto_kdf_hkdf_sha512_STATEBYTES: raise ValueError("invalid state") + prk = ctypes.create_string_buffer(crypto_kdf_hkdf_sha512_KEYBYTES) + __check(sodium.crypto_kdf_hkdf_sha512_extract_final(state, prk)) + return prk.raw + +# int crypto_kdf_hkdf_sha512_extract( +# unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES], +# const unsigned char *salt, size_t salt_len, const unsigned char *ikm, +# size_t ikm_len) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha512_extract(salt=b'', ikm=b''): + prk = ctypes.create_string_buffer(crypto_kdf_hkdf_sha512_KEYBYTES) + __check(sodium.crypto_kdf_hkdf_sha512_extract(prk, salt, ctypes.c_size_t(len(salt)), ikm, ctypes.c_size_t(len(ikm)))) + return prk.raw + +# void crypto_kdf_hkdf_sha512_keygen(unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha512_keygen(): + k = ctypes.create_string_buffer(crypto_kdf_hkdf_sha512_KEYBYTES) + sodium.crypto_kdf_hkdf_sha512_keygen(k) + return k.raw + +# int crypto_kdf_hkdf_sha512_expand(unsigned char *out, size_t out_len, +# const char *ctx, size_t ctx_len, +# const unsigned char prk[crypto_kdf_hkdf_sha512_KEYBYTES]) +@sodium_version(1, 0, 19) +def crypto_kdf_hkdf_sha512_expand(outlen, prk, ctx=b''): + if not (crypto_kdf_hkdf_sha512_BYTES_MIN <= outlen <= crypto_kdf_hkdf_sha512_BYTES_MAX): raise ValueError("invalid output len") + if len(prk) != crypto_kdf_hkdf_sha512_KEYBYTES: raise ValueError("invalid prk") + out = ctypes.create_string_buffer(outlen) + __check(sodium.crypto_kdf_hkdf_sha512_expand(out, ctypes.c_size_t(outlen), ctx, ctypes.c_size_t(len(ctx)), prk)) + return out.raw + # int crypto_kx_keypair(unsigned char pk[crypto_kx_PUBLICKEYBYTES], # unsigned char sk[crypto_kx_SECRETKEYBYTES]); @sodium_version(1, 0, 12) diff --git a/test/test_pysodium.py b/test/test_pysodium.py index ce88ebe..5dfe39a 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -658,6 +658,17 @@ def test_crypto_kdf_hkdf_sha256(self): self.assertEqual(expected_prk, pysodium.crypto_kdf_hkdf_sha256_extract_final(state)) self.assertEqual(expected_out, pysodium.crypto_kdf_hkdf_sha256_expand(outlen, expected_prk, ctx)) + def test_crypto_kdf_hkdf_sha512(self): + if not pysodium.sodium_version_check(1, 0, 19): return + expected_prk = bytes.fromhex("665799823737ded04a88e47e54a5890bb2c3d247c7a4254a8e61350723590a26c36238127d8661b88cf80ef802d57e2f7cebcf1e00e083848be19929c61b4237") + expected_out = bytes.fromhex("832390086cda71fb47625bb5ceb168e4c8e26a1a16ed34d9fc7fe92c1481579338da362cb8d9f925d7cb") + ikm = bytes.fromhex("0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b") + salt = bytes.fromhex("000102030405060708090a0b0c") + ctx = bytes.fromhex("f0f1f2f3f4f5f6f7f8f9") + outlen = 42 + self.assertEqual(expected_prk, pysodium.crypto_kdf_hkdf_sha512_extract(salt, ikm)) + self.assertEqual(expected_out, pysodium.crypto_kdf_hkdf_sha512_expand(outlen, expected_prk, ctx)) + def test_crypto_kx(self): if not pysodium.sodium_version_check(1, 0, 12): return client_pk, client_sk = pysodium.crypto_kx_keypair() From 7a034fc35b9bc406aa2622ee215259042d869c10 Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Wed, 29 Nov 2023 23:04:24 +0100 Subject: [PATCH 19/30] Add support for AEGIS-128L, AEGIS-256 Also don't hardcode the tag length in other AEADs. --- README.md | 8 +++ pysodium/__init__.py | 146 ++++++++++++++++++++++++++++++++++++++++-- test/test_pysodium.py | 22 +++++++ 3 files changed, 169 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index d1fe1e8..0467f62 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,14 @@ This wrapper requires a pre-installed libsodium from: then it provides access to the following functions: ``` +crypto_aead_aegis128l_decrypt(ciphertext, ad, nonce, key) +crypto_aead_aegis128l_encrypt(message, ad, nonce, key) +crypto_aead_aegis128l_decrypt_detached(ciphertext, mac, ad, nonce, key) +crypto_aead_aegis128l_encrypt_detached(message, ad, nonce, key) +crypto_aead_aegis256_decrypt(ciphertext, ad, nonce, key) +crypto_aead_aegis256_encrypt(message, ad, nonce, key) +crypto_aead_aegis256_decrypt_detached(ciphertext, mac, ad, nonce, key) +crypto_aead_aegis256_encrypt_detached(message, ad, nonce, key) crypto_aead_chacha20poly1305_decrypt(ciphertext, ad, nonce, key) crypto_aead_chacha20poly1305_encrypt(message, ad, nonce, key) crypto_aead_chacha20poly1305_decrypt_detached(ciphertext, mac, ad, nonce, key) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index ef4cd16..2ed7c3e 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -153,6 +153,18 @@ def wrapper(*args, **kwargs): crypto_aead_chacha20poly1305_NONCEBYTES = crypto_aead_chacha20poly1305_NPUBBYTES crypto_aead_chacha20poly1305_ABYTES = sodium.crypto_aead_chacha20poly1305_abytes() +if sodium_version_check(1, 0, 19): + crypto_aead_aegis128l_KEYBYTES = sodium.crypto_aead_aegis128l_keybytes() + crypto_aead_aegis128l_NPUBBYTES = sodium.crypto_aead_aegis128l_npubbytes() + crypto_aead_aegis128l_NONCEBYTES = crypto_aead_aegis128l_NPUBBYTES + crypto_aead_aegis128l_ABYTES = sodium.crypto_aead_aegis128l_abytes() + crypto_aead_aegis128l_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis128l_messagebytes_max()) + crypto_aead_aegis256_KEYBYTES = sodium.crypto_aead_aegis256_keybytes() + crypto_aead_aegis256_NPUBBYTES = sodium.crypto_aead_aegis256_npubbytes() + crypto_aead_aegis256_NONCEBYTES = crypto_aead_aegis256_NPUBBYTES + crypto_aead_aegis256_ABYTES = sodium.crypto_aead_aegis256_abytes() + crypto_aead_aegis256_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis256_messagebytes_max()) + if sodium_version_check(1, 0, 9): crypto_aead_chacha20poly1305_ietf_KEYBYTES = sodium.crypto_aead_chacha20poly1305_ietf_keybytes() crypto_aead_chacha20poly1305_ietf_NPUBBYTES = sodium.crypto_aead_chacha20poly1305_ietf_npubbytes() @@ -245,7 +257,7 @@ def wrapper(*args, **kwargs): crypto_secretstream_xchacha20poly1305_ABYTES = sodium.crypto_secretstream_xchacha20poly1305_abytes() crypto_secretstream_xchacha20poly1305_HEADERBYTES = sodium.crypto_secretstream_xchacha20poly1305_headerbytes() crypto_secretstream_xchacha20poly1305_KEYBYTES = sodium.crypto_secretstream_xchacha20poly1305_keybytes() - crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = sodium.crypto_secretstream_xchacha20poly1305_messagebytes_max() + crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_secretstream_xchacha20poly1305_messagebytes_max()) crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = sodium.crypto_secretstream_xchacha20poly1305_tag_message() crypto_secretstream_xchacha20poly1305_TAG_PUSH = sodium.crypto_secretstream_xchacha20poly1305_tag_push() crypto_secretstream_xchacha20poly1305_TAG_REKEY = sodium.crypto_secretstream_xchacha20poly1305_tag_rekey() @@ -419,7 +431,7 @@ def crypto_aead_chacha20poly1305_encrypt(message, ad, nonce, key): mlen = ctypes.c_ulonglong(len(message)) adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) - c = ctypes.create_string_buffer(mlen.value + 16) + c = ctypes.create_string_buffer(mlen.value + crypto_aead_chacha20poly1305_ABYTES) clen = ctypes.c_ulonglong(0) __check(sodium.crypto_aead_chacha20poly1305_encrypt(c, ctypes.byref(clen), message, mlen, ad, adlen, None, nonce, key)) @@ -431,7 +443,7 @@ def crypto_aead_chacha20poly1305_decrypt(ciphertext, ad, nonce, key): if len(nonce) != crypto_aead_chacha20poly1305_NONCEBYTES: raise ValueError("truncated nonce") if len(key) != crypto_aead_chacha20poly1305_KEYBYTES: raise ValueError("truncated key") - m = ctypes.create_string_buffer(len(ciphertext) - 16) + m = ctypes.create_string_buffer(len(ciphertext) - crypto_aead_chacha20poly1305_ABYTES) mlen = ctypes.c_ulonglong(0) clen = ctypes.c_ulonglong(len(ciphertext)) adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) @@ -469,6 +481,126 @@ def crypto_aead_chacha20poly1305_decrypt_detached(ciphertext, mac, ad, nonce, ke __check(sodium.crypto_aead_chacha20poly1305_decrypt_detached(m, None, ciphertext, clen, mac, ad, adlen, nonce, key)) return m.raw +# crypto_aead_aegis128l_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); +@sodium_version(1, 0, 19) +def crypto_aead_aegis128l_encrypt(message, ad, nonce, key): + if len(nonce) != crypto_aead_aegis128l_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis128l_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_ulonglong(len(message)) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + + c = ctypes.create_string_buffer(mlen.value + crypto_aead_aegis128l_ABYTES) + clen = ctypes.c_ulonglong(0) + + __check(sodium.crypto_aead_aegis128l_encrypt(c, ctypes.byref(clen), message, mlen, ad, adlen, None, nonce, key)) + return c.raw + + +# crypto_aead_aegis128l_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, 19) +def crypto_aead_aegis128l_decrypt(ciphertext, ad, nonce, key): + if len(nonce) != crypto_aead_aegis128l_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis128l_KEYBYTES: raise ValueError("truncated key") + + m = ctypes.create_string_buffer(len(ciphertext) - crypto_aead_aegis128l_ABYTES) + mlen = ctypes.c_ulonglong(0) + clen = ctypes.c_ulonglong(len(ciphertext)) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + __check(sodium.crypto_aead_aegis128l_decrypt(m, ctypes.byref(mlen), None, ciphertext, clen, ad, adlen, nonce, key)) + return m.raw + +# crypto_aead_aegis128l_encrypt_detached(unsigned char *c, unsigned char *mac, unsigned long long *maclen_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, 19) +def crypto_aead_aegis128l_encrypt_detached(message, ad, nonce, key): + """ Return ciphertext, mac tag """ + if len(nonce) != crypto_aead_aegis128l_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis128l_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_ulonglong(len(message)) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + c = ctypes.create_string_buffer(mlen.value) + maclen_p = ctypes.c_ulonglong(crypto_aead_aegis128l_ABYTES) + mac = ctypes.create_string_buffer(maclen_p.value) + + __check(sodium.crypto_aead_aegis128l_encrypt_detached(c, mac, ctypes.byref(maclen_p), message, mlen, ad, adlen, None, nonce, key)) + return c.raw, mac.raw + +# crypto_aead_aegis128l_decrypt_detached(unsigned char *m, unsigned char *nsec, const unsigned char *c, unsigned long long clen, const unsigned char *mac, const unsigned char *ad, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) +@sodium_version(1, 0, 19) +def crypto_aead_aegis128l_decrypt_detached(ciphertext, mac, ad, nonce, key): + """ Return message if successful or -1 (ValueError) if not successful""" + if len(nonce) != crypto_aead_aegis128l_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis128l_KEYBYTES: raise ValueError("truncated key") + if len(mac) != crypto_aead_aegis128l_ABYTES: + raise ValueError("mac length != %i" % crypto_aead_aegis128l_ABYTES) + + clen = ctypes.c_ulonglong(len(ciphertext)) + m = ctypes.create_string_buffer(clen.value) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + __check(sodium.crypto_aead_aegis128l_decrypt_detached(m, None, ciphertext, clen, mac, ad, adlen, nonce, key)) + return m.raw + +# crypto_aead_aegis256_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); +@sodium_version(1, 0, 19) +def crypto_aead_aegis256_encrypt(message, ad, nonce, key): + if len(nonce) != crypto_aead_aegis256_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis256_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_ulonglong(len(message)) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + + c = ctypes.create_string_buffer(mlen.value + crypto_aead_aegis256_ABYTES) + clen = ctypes.c_ulonglong(0) + + __check(sodium.crypto_aead_aegis256_encrypt(c, ctypes.byref(clen), message, mlen, ad, adlen, None, nonce, key)) + return c.raw + + +# crypto_aead_aegis256_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, 19) +def crypto_aead_aegis256_decrypt(ciphertext, ad, nonce, key): + if len(nonce) != crypto_aead_aegis256_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis256_KEYBYTES: raise ValueError("truncated key") + + m = ctypes.create_string_buffer(len(ciphertext) - crypto_aead_aegis256_ABYTES) + mlen = ctypes.c_ulonglong(0) + clen = ctypes.c_ulonglong(len(ciphertext)) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + __check(sodium.crypto_aead_aegis256_decrypt(m, ctypes.byref(mlen), None, ciphertext, clen, ad, adlen, nonce, key)) + return m.raw + +# crypto_aead_aegis256_encrypt_detached(unsigned char *c, unsigned char *mac, unsigned long long *maclen_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, 19) +def crypto_aead_aegis256_encrypt_detached(message, ad, nonce, key): + """ Return ciphertext, mac tag """ + if len(nonce) != crypto_aead_aegis256_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis256_KEYBYTES: raise ValueError("truncated key") + + mlen = ctypes.c_ulonglong(len(message)) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + c = ctypes.create_string_buffer(mlen.value) + maclen_p = ctypes.c_ulonglong(crypto_aead_aegis256_ABYTES) + mac = ctypes.create_string_buffer(maclen_p.value) + + __check(sodium.crypto_aead_aegis256_encrypt_detached(c, mac, ctypes.byref(maclen_p), message, mlen, ad, adlen, None, nonce, key)) + return c.raw, mac.raw + +# crypto_aead_aegis256_decrypt_detached(unsigned char *m, unsigned char *nsec, const unsigned char *c, unsigned long long clen, const unsigned char *mac, const unsigned char *ad, unsigned long long adlen, const unsigned char *npub, const unsigned char *k) +@sodium_version(1, 0, 19) +def crypto_aead_aegis256_decrypt_detached(ciphertext, mac, ad, nonce, key): + """ Return message if successful or -1 (ValueError) if not successful""" + if len(nonce) != crypto_aead_aegis256_NONCEBYTES: raise ValueError("truncated nonce") + if len(key) != crypto_aead_aegis256_KEYBYTES: raise ValueError("truncated key") + if len(mac) != crypto_aead_aegis256_ABYTES: + raise ValueError("mac length != %i" % crypto_aead_aegis256_ABYTES) + + clen = ctypes.c_ulonglong(len(ciphertext)) + m = ctypes.create_string_buffer(clen.value) + adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) + __check(sodium.crypto_aead_aegis256_decrypt_detached(m, None, ciphertext, clen, mac, ad, adlen, nonce, key)) + return m.raw + # 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) def crypto_aead_chacha20poly1305_ietf_encrypt(message, ad, nonce, key): @@ -477,7 +609,7 @@ def crypto_aead_chacha20poly1305_ietf_encrypt(message, ad, nonce, key): mlen = ctypes.c_ulonglong(len(message)) adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) - c = ctypes.create_string_buffer(mlen.value + 16) + c = ctypes.create_string_buffer(mlen.value + crypto_aead_chacha20poly1305_ietf_ABYTES) clen = ctypes.c_ulonglong(0) __check(sodium.crypto_aead_chacha20poly1305_ietf_encrypt(c, ctypes.byref(clen), message, mlen, ad, adlen, None, nonce, key)) @@ -489,7 +621,7 @@ def crypto_aead_chacha20poly1305_ietf_decrypt(ciphertext, ad, nonce, key): if len(nonce) != crypto_aead_chacha20poly1305_ietf_NONCEBYTES: raise ValueError("truncated nonce") if len(key) != crypto_aead_chacha20poly1305_ietf_KEYBYTES: raise ValueError("truncated key") - m = ctypes.create_string_buffer(len(ciphertext) - 16) + m = ctypes.create_string_buffer(len(ciphertext) - crypto_aead_chacha20poly1305_ietf_ABYTES) mlen = ctypes.c_ulonglong(0) clen = ctypes.c_ulonglong(len(ciphertext)) adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) @@ -537,7 +669,7 @@ def crypto_aead_xchacha20poly1305_ietf_encrypt(message, ad, nonce, key): if len(key) != crypto_aead_xchacha20poly1305_ietf_KEYBYTES: raise ValueError("truncated key") mlen = ctypes.c_ulonglong(len(message)) adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) - c = ctypes.create_string_buffer(mlen.value + 16) + c = ctypes.create_string_buffer(mlen.value + crypto_aead_xchacha20poly1305_ietf_ABYTES) clen = ctypes.c_ulonglong(0) __check(sodium.crypto_aead_xchacha20poly1305_ietf_encrypt(c, ctypes.byref(clen), @@ -556,7 +688,7 @@ def crypto_aead_xchacha20poly1305_ietf_decrypt(ciphertext, ad, nonce, key): if len(nonce) != crypto_aead_xchacha20poly1305_ietf_NPUBBYTES: raise ValueError("truncated nonce") if len(key) != crypto_aead_xchacha20poly1305_ietf_KEYBYTES: raise ValueError("truncated key") - m = ctypes.create_string_buffer(len(ciphertext) - 16) + m = ctypes.create_string_buffer(len(ciphertext) - crypto_aead_xchacha20poly1305_ietf_ABYTES) mlen = ctypes.c_ulonglong(0) clen = ctypes.c_ulonglong(len(ciphertext)) adlen = ctypes.c_ulonglong(len(ad)) if ad is not None else ctypes.c_ulonglong(0) diff --git a/test/test_pysodium.py b/test/test_pysodium.py index 5dfe39a..8a7004d 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -379,6 +379,28 @@ def test_crypto_sign_seed_keypair(self): self.assertEqual(pk, pk2) self.assertEqual(sk, sk2) + def test_aead_aegis128l(self): + key = binascii.unhexlify(b"4290bcb154173531f314af57f3be3b50") + input_ = binascii.unhexlify(b"86d09974840bded2a5ca") + nonce = binascii.unhexlify(b"087b5f9fadfb515388394f8035482608") + ad = binascii.unhexlify(b"87e229d4500845a079c0") + ct = binascii.unhexlify(b"a4fa71e3508259ff98e9e2874d98f97b7b3e14a033b835f25e335735385f604afe227394ad9032c1bcea") + output = pysodium.crypto_aead_aegis128l_encrypt(input_, ad, nonce, key) + self.assertEqual(bytes.hex(ct), bytes.hex(output)) + output = pysodium.crypto_aead_aegis128l_decrypt(output, ad, nonce, key) + self.assertEqual(output, input_) + + def test_aead_aegis256(self): + key = binascii.unhexlify(b"4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007") + input_ = binascii.unhexlify(b"86d09974840bded2a5ca") + nonce = binascii.unhexlify(b"087b5f9fadfb515388394f8035482608e17b07153e560e301406cfad9f12c164") + ad = binascii.unhexlify(b"87e229d4500845a079c0") + ct = binascii.unhexlify(b"5b0b85a1a45a52e0950b2336fa9df3aacd14862fc4e7f670eafd04d6697be30973fa0f6c82cdfbfb1b7a") + output = pysodium.crypto_aead_aegis256_encrypt(input_, ad, nonce, key) + self.assertEqual(bytes.hex(ct), bytes.hex(output)) + output = pysodium.crypto_aead_aegis256_decrypt(output, ad, nonce, key) + self.assertEqual(output, input_) + def test_aead_chacha20poly1305(self): key = binascii.unhexlify(b"4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007") input_ = binascii.unhexlify(b"86d09974840bded2a5ca") From 81d40c8cd5bea1311e3ad6fdf1ef833211c310c4 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 30 Nov 2023 00:31:47 +0100 Subject: [PATCH 20/30] [mod] merged two sections for constants for libsodium v1.0.19 --- pysodium/__init__.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 2ed7c3e..e639c3f 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -153,18 +153,6 @@ def wrapper(*args, **kwargs): crypto_aead_chacha20poly1305_NONCEBYTES = crypto_aead_chacha20poly1305_NPUBBYTES crypto_aead_chacha20poly1305_ABYTES = sodium.crypto_aead_chacha20poly1305_abytes() -if sodium_version_check(1, 0, 19): - crypto_aead_aegis128l_KEYBYTES = sodium.crypto_aead_aegis128l_keybytes() - crypto_aead_aegis128l_NPUBBYTES = sodium.crypto_aead_aegis128l_npubbytes() - crypto_aead_aegis128l_NONCEBYTES = crypto_aead_aegis128l_NPUBBYTES - crypto_aead_aegis128l_ABYTES = sodium.crypto_aead_aegis128l_abytes() - crypto_aead_aegis128l_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis128l_messagebytes_max()) - crypto_aead_aegis256_KEYBYTES = sodium.crypto_aead_aegis256_keybytes() - crypto_aead_aegis256_NPUBBYTES = sodium.crypto_aead_aegis256_npubbytes() - crypto_aead_aegis256_NONCEBYTES = crypto_aead_aegis256_NPUBBYTES - crypto_aead_aegis256_ABYTES = sodium.crypto_aead_aegis256_abytes() - crypto_aead_aegis256_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis256_messagebytes_max()) - if sodium_version_check(1, 0, 9): crypto_aead_chacha20poly1305_ietf_KEYBYTES = sodium.crypto_aead_chacha20poly1305_ietf_keybytes() crypto_aead_chacha20poly1305_ietf_NPUBBYTES = sodium.crypto_aead_chacha20poly1305_ietf_npubbytes() @@ -285,6 +273,16 @@ def wrapper(*args, **kwargs): crypto_kdf_hkdf_sha512_KEYBYTES = sodium.crypto_kdf_hkdf_sha512_keybytes() crypto_kdf_hkdf_sha512_BYTES_MIN = sodium.crypto_kdf_hkdf_sha512_bytes_min() crypto_kdf_hkdf_sha512_BYTES_MAX = sodium.crypto_kdf_hkdf_sha512_bytes_max() + crypto_aead_aegis128l_KEYBYTES = sodium.crypto_aead_aegis128l_keybytes() + crypto_aead_aegis128l_NPUBBYTES = sodium.crypto_aead_aegis128l_npubbytes() + crypto_aead_aegis128l_NONCEBYTES = crypto_aead_aegis128l_NPUBBYTES + crypto_aead_aegis128l_ABYTES = sodium.crypto_aead_aegis128l_abytes() + crypto_aead_aegis128l_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis128l_messagebytes_max()) + crypto_aead_aegis256_KEYBYTES = sodium.crypto_aead_aegis256_keybytes() + crypto_aead_aegis256_NPUBBYTES = sodium.crypto_aead_aegis256_npubbytes() + crypto_aead_aegis256_NONCEBYTES = crypto_aead_aegis256_NPUBBYTES + crypto_aead_aegis256_ABYTES = sodium.crypto_aead_aegis256_abytes() + crypto_aead_aegis256_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis256_messagebytes_max()) if sodium_version_check(1, 0, 20): crypto_kdf_hkdf_sha512_STATEBYTES = sodium.crypto_kdf_hkdf_sha512_statebytes() From 6effe685ec65b444dc2bc8259724ac4af5f59356 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 30 Nov 2023 00:32:17 +0100 Subject: [PATCH 21/30] [fix] added version guard to the aegis test-cases --- test/test_pysodium.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test_pysodium.py b/test/test_pysodium.py index 8a7004d..1fa4594 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -380,6 +380,7 @@ def test_crypto_sign_seed_keypair(self): self.assertEqual(sk, sk2) def test_aead_aegis128l(self): + if not pysodium.sodium_version_check(1, 0, 19): return key = binascii.unhexlify(b"4290bcb154173531f314af57f3be3b50") input_ = binascii.unhexlify(b"86d09974840bded2a5ca") nonce = binascii.unhexlify(b"087b5f9fadfb515388394f8035482608") @@ -391,6 +392,7 @@ def test_aead_aegis128l(self): self.assertEqual(output, input_) def test_aead_aegis256(self): + if not pysodium.sodium_version_check(1, 0, 19): return key = binascii.unhexlify(b"4290bcb154173531f314af57f3be3b5006da371ece272afa1b5dbdd1100a1007") input_ = binascii.unhexlify(b"86d09974840bded2a5ca") nonce = binascii.unhexlify(b"087b5f9fadfb515388394f8035482608e17b07153e560e301406cfad9f12c164") From 0eae2f27668a79327fb1310ce2538fd3501616db Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 30 Nov 2023 00:34:35 +0100 Subject: [PATCH 22/30] [mod] bumped version to v0.7.16 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index d70b037..69fce2d 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.15", + version="0.7.16", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From c6cdef732e5cfef40180ffa8aade1ff97c7004e3 Mon Sep 17 00:00:00 2001 From: stsch9 Date: Thu, 30 Nov 2023 08:15:56 +0100 Subject: [PATCH 23/30] update authors --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 4b77e65..3cb9a05 100644 --- a/AUTHORS +++ b/AUTHORS @@ -18,3 +18,4 @@ Blaz Bregar berndb84 Chris Topher c@creemama.com Jonathan Levin +Stefan Schaubeck From ccfa3f77ecfa5a03e9781fc563cbcc0eea5a115f Mon Sep 17 00:00:00 2001 From: stsch9 <85763581+stsch9@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:42:42 +0100 Subject: [PATCH 24/30] update authors (#110) --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 4b77e65..3cb9a05 100644 --- a/AUTHORS +++ b/AUTHORS @@ -18,3 +18,4 @@ Blaz Bregar berndb84 Chris Topher c@creemama.com Jonathan Levin +Stefan Schaubeck From 8d2c6d897b0fc6e20470d8e554679a5b693ae4e4 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Wed, 13 Dec 2023 02:07:07 +0100 Subject: [PATCH 25/30] [fix] invalid max msg sizes #111 --- pysodium/__init__.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index e639c3f..182ebeb 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -1,8 +1,8 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python """ Wrapper for libsodium library -Copyright (c) 2013-2014, Marsiske Stefan. +Copyright (c) 2013-2023, Marsiske Stefan. All rights reserved. Redistribution and use in source and binary forms, with or without modification, @@ -245,7 +245,8 @@ def wrapper(*args, **kwargs): crypto_secretstream_xchacha20poly1305_ABYTES = sodium.crypto_secretstream_xchacha20poly1305_abytes() crypto_secretstream_xchacha20poly1305_HEADERBYTES = sodium.crypto_secretstream_xchacha20poly1305_headerbytes() crypto_secretstream_xchacha20poly1305_KEYBYTES = sodium.crypto_secretstream_xchacha20poly1305_keybytes() - crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_secretstream_xchacha20poly1305_messagebytes_max()) + sodium.crypto_secretstream_xchacha20poly1305_messagebytes_max.restype = ctypes.c_size_t + crypto_secretstream_xchacha20poly1305_MESSAGEBYTES_MAX = sodium.crypto_secretstream_xchacha20poly1305_messagebytes_max() crypto_secretstream_xchacha20poly1305_TAG_MESSAGE = sodium.crypto_secretstream_xchacha20poly1305_tag_message() crypto_secretstream_xchacha20poly1305_TAG_PUSH = sodium.crypto_secretstream_xchacha20poly1305_tag_push() crypto_secretstream_xchacha20poly1305_TAG_REKEY = sodium.crypto_secretstream_xchacha20poly1305_tag_rekey() @@ -277,12 +278,14 @@ def wrapper(*args, **kwargs): crypto_aead_aegis128l_NPUBBYTES = sodium.crypto_aead_aegis128l_npubbytes() crypto_aead_aegis128l_NONCEBYTES = crypto_aead_aegis128l_NPUBBYTES crypto_aead_aegis128l_ABYTES = sodium.crypto_aead_aegis128l_abytes() - crypto_aead_aegis128l_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis128l_messagebytes_max()) + sodium.crypto_aead_aegis128l_messagebytes_max.restype = ctypes.c_size_t + crypto_aead_aegis128l_MESSAGEBYTES_MAX = sodium.crypto_aead_aegis128l_messagebytes_max() crypto_aead_aegis256_KEYBYTES = sodium.crypto_aead_aegis256_keybytes() crypto_aead_aegis256_NPUBBYTES = sodium.crypto_aead_aegis256_npubbytes() crypto_aead_aegis256_NONCEBYTES = crypto_aead_aegis256_NPUBBYTES crypto_aead_aegis256_ABYTES = sodium.crypto_aead_aegis256_abytes() - crypto_aead_aegis256_MESSAGEBYTES_MAX = ctypes.c_size_t(sodium.crypto_aead_aegis256_messagebytes_max()) + sodium.crypto_aead_aegis256_messagebytes_max.restype = ctypes.c_size_t + crypto_aead_aegis256_MESSAGEBYTES_MAX = sodium.crypto_aead_aegis256_messagebytes_max() if sodium_version_check(1, 0, 20): crypto_kdf_hkdf_sha512_STATEBYTES = sodium.crypto_kdf_hkdf_sha512_statebytes() From 202e09b62c9afa3acdd40f93afb5f5319b5d53a3 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Wed, 13 Dec 2023 02:09:17 +0100 Subject: [PATCH 26/30] [mod] bumped version to 0.7.17 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 69fce2d..521e944 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.16", + version="0.7.17", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From 4f6c9d68aa95f7904273a618bba4fc534d8b8711 Mon Sep 17 00:00:00 2001 From: stsch9 Date: Thu, 4 Jan 2024 23:07:23 +0100 Subject: [PATCH 27/30] add crypto_kdf_ functions --- README.md | 6 ++++++ pysodium/__init__.py | 23 +++++++++++++++++++++++ test/test_pysodium.py | 18 ++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/README.md b/README.md index 0467f62..b638ff9 100644 --- a/README.md +++ b/README.md @@ -120,6 +120,8 @@ crypto_auth_hmacsha512_verify crypto_auth_hmacsha512256_keygen crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_verify +crypto_kdf_derive_from_key(subkey_len, subkey_id, ctx, key) +crypto_kdf_keygen() crypto_kdf_hkdf_sha256_extract_init(salt=b'') crypto_kdf_hkdf_sha256_extract_update(state, ikm=b'') crypto_kdf_hkdf_sha256_extract_final(state) @@ -262,6 +264,10 @@ crypto_auth_hmacsha512_BYTES crypto_auth_hmacsha512_KEYBYTES crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_KEYBYTES +crypto_kdf_BYTES_MIN +crypto_kdf_BYTES_MAX +crypto_kdf_CONTEXTBYTES +crypto_kdf_KEYBYTES crypto_kdf_hkdf_sha256_KEYBYTES crypto_kdf_hkdf_sha256_BYTES_MIN crypto_kdf_hkdf_sha256_BYTES_MAX diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 182ebeb..1052bc7 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -152,6 +152,10 @@ def wrapper(*args, **kwargs): crypto_aead_chacha20poly1305_NPUBBYTES = sodium.crypto_aead_chacha20poly1305_npubbytes() crypto_aead_chacha20poly1305_NONCEBYTES = crypto_aead_chacha20poly1305_NPUBBYTES crypto_aead_chacha20poly1305_ABYTES = sodium.crypto_aead_chacha20poly1305_abytes() +crypto_kdf_BYTES_MIN = sodium.crypto_kdf_bytes_min() +crypto_kdf_BYTES_MAX = sodium.crypto_kdf_bytes_max() +crypto_kdf_CONTEXTBYTES = sodium.crypto_kdf_contextbytes() +crypto_kdf_KEYBYTES = sodium.crypto_kdf_keybytes() if sodium_version_check(1, 0, 9): crypto_aead_chacha20poly1305_ietf_KEYBYTES = sodium.crypto_aead_chacha20poly1305_ietf_keybytes() @@ -1490,6 +1494,25 @@ def crypto_hash_sha512_final(state): __check(sodium.crypto_hash_sha512_final(state, out)) return out.raw +# int crypto_kdf_derive_from_key(unsigned char *subkey, size_t subkey_len, +# uint64_t subkey_id, +# const char ctx[crypto_kdf_CONTEXTBYTES], +# const unsigned char key[crypto_kdf_KEYBYTES]) +def crypto_kdf_derive_from_key(subkey_len, subkey_id, ctx, key): + if len(ctx) != crypto_kdf_CONTEXTBYTES: raise ValueError("invalid context") + if len(key) != crypto_kdf_KEYBYTES: raise ValueError("invalid context") + if not (crypto_kdf_BYTES_MIN <= subkey_len <= crypto_kdf_BYTES_MAX): raise ValueError("invalid subkey len") + subkey = ctypes.create_string_buffer(subkey_len) + si = ctypes.c_uint64(subkey_id) + __check(sodium.crypto_kdf_derive_from_key(subkey, ctypes.c_size_t(subkey_len), si, ctx, key)) + return subkey.raw + +# void crypto_kdf_keygen(unsigned char k[crypto_kdf_KEYBYTES]) +def crypto_kdf_keygen(): + k = ctypes.create_string_buffer(crypto_kdf_KEYBYTES) + sodium.crypto_kdf_keygen(k) + return k.raw + # int crypto_kdf_hkdf_sha256_extract_init(crypto_kdf_hkdf_sha256_state *state, # const unsigned char *salt, size_t salt_len) @sodium_version(1, 0, 19) diff --git a/test/test_pysodium.py b/test/test_pysodium.py index 1fa4594..954f8a6 100755 --- a/test/test_pysodium.py +++ b/test/test_pysodium.py @@ -650,6 +650,24 @@ def test_crypto_auth(self): tag = pysodium.crypto_auth("howdy", sk) pysodium.crypto_auth_verify(tag, "howdy", sk) + def test_crypto_kdf_keygen(self): + key = pysodium.crypto_kdf_keygen() + self.assertEqual(pysodium.crypto_kdf_KEYBYTES, len(key)) + + def test_crypto_kdf_derive_from_key(self): + # https://github.com/jedisct1/libsodium/blob/master/test/default/kdf.exp + expected_subkey = bytes.fromhex("a0c724404728c8bb95e5433eb6a9716171144d61efb23e74b873fcbeda51d8071b5d70aae12066dfc94ce943f145aa176c055040c3dd73b0a15e36254d450614") + subkey_id = 0 + ctx = b'KDF test' + key = bytes.fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + self.assertEqual(expected_subkey, pysodium. crypto_kdf_derive_from_key(pysodium.crypto_kdf_BYTES_MAX, subkey_id, ctx, key)) + + expected_subkey = bytes.fromhex("02507f144fa9bf19010bf7c70b235b4c2663cc00e074f929602a5e2c10a780757d2a3993d06debc378a90efdac196dd841817b977d67b786804f6d3cd585bab5") + subkey_id = 1 + ctx = b'KDF test' + key = bytes.fromhex("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f") + self.assertEqual(expected_subkey, pysodium.crypto_kdf_derive_from_key(pysodium.crypto_kdf_BYTES_MAX, subkey_id, ctx, key)) + def test_crypto_kdf_hkdf_sha256(self): # test vectors: https://datatracker.ietf.org/doc/html/rfc5869 if not pysodium.sodium_version_check(1, 0, 19): return From 4aa44f8aa893ae0694150eec8dd8ba6d23abc37d Mon Sep 17 00:00:00 2001 From: stsch9 Date: Thu, 4 Jan 2024 23:16:41 +0100 Subject: [PATCH 28/30] fix typo --- pysodium/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pysodium/__init__.py b/pysodium/__init__.py index 1052bc7..8edea73 100755 --- a/pysodium/__init__.py +++ b/pysodium/__init__.py @@ -1500,7 +1500,7 @@ def crypto_hash_sha512_final(state): # const unsigned char key[crypto_kdf_KEYBYTES]) def crypto_kdf_derive_from_key(subkey_len, subkey_id, ctx, key): if len(ctx) != crypto_kdf_CONTEXTBYTES: raise ValueError("invalid context") - if len(key) != crypto_kdf_KEYBYTES: raise ValueError("invalid context") + if len(key) != crypto_kdf_KEYBYTES: raise ValueError("invalid key") if not (crypto_kdf_BYTES_MIN <= subkey_len <= crypto_kdf_BYTES_MAX): raise ValueError("invalid subkey len") subkey = ctypes.create_string_buffer(subkey_len) si = ctypes.c_uint64(subkey_id) From baf11790a6bd454441393b5377bad7cc591089ae Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Wed, 7 Aug 2024 13:46:52 +0200 Subject: [PATCH 29/30] [mod] bump to v0.7.18 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 521e944..16e61a2 100644 --- a/setup.py +++ b/setup.py @@ -11,7 +11,7 @@ def read(fname): setup( name="pysodium", - version="0.7.17", + version="0.7.18", author="Stefan Marsiske", author_email="s@ctrlc.hu", description="python libsodium wrapper", From 50bc3c812f4112fd98fc6b7a8806dabc3d7a3820 Mon Sep 17 00:00:00 2001 From: stf <7o5rfu92t@ctrlc.hu> Date: Thu, 14 Nov 2024 15:38:54 +0100 Subject: [PATCH 30/30] [enh] added trusted publisher workflow --- .github/workflows/release.yml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..cd1a741 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,24 @@ +jobs: + pypi-publish: + name: Upload release to PyPI + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/pysodium + permissions: + id-token: write + steps: + - uses: actions/checkout@v4 + - name: Set up Python + uses: actions/setup-python@v3 + with: + python-version: '3.x' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install build + - name: Build package + run: python -m build + - name: Publish package distributions to PyPI + uses: pypa/gh-action-pypi-publish@release/v1