Skip to content

Commit

Permalink
[enh] added support for crypto_stream_xchacha20_xor(_ic)
Browse files Browse the repository at this point in the history
  • Loading branch information
stef committed May 11, 2021
1 parent 03cd6db commit d4b5421
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
29 changes: 29 additions & 0 deletions pysodium/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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")
Expand Down
16 changes: 16 additions & 0 deletions test/test_pysodium.py
Original file line number Diff line number Diff line change
Expand Up @@ -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')
Expand Down

0 comments on commit d4b5421

Please sign in to comment.