tcrypto: chacha20-methods: make associated_data param optional - electrum - Electrum Bitcoin wallet
 (HTM) git clone https://git.parazyd.org/electrum
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) Submodules
       ---
 (DIR) commit 725b6f15649c4f93dedfa2c241b6cbf7a82a65f0
 (DIR) parent b9db16327a1feb9b345d6194859603b5b12a5eff
 (HTM) Author: SomberNight <somber.night@protonmail.com>
       Date:   Wed, 17 Jun 2020 17:32:51 +0200
       
       crypto: chacha20-methods: make associated_data param optional
       
       Diffstat:
         M electrum/crypto.py                  |      26 ++++++++++++++++++++------
         M electrum/tests/test_bitcoin.py      |      24 ++++++++++++++++++++++--
       
       2 files changed, 42 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/electrum/crypto.py b/electrum/crypto.py
       t@@ -268,14 +268,21 @@ def hmac_oneshot(key: bytes, msg: bytes, digest) -> bytes:
                return hmac.new(key, msg, digest).digest()
        
        
       -def chacha20_poly1305_encrypt(*, key: bytes, nonce: bytes, associated_data: bytes, data: bytes) -> bytes:
       +def chacha20_poly1305_encrypt(
       +        *,
       +        key: bytes,
       +        nonce: bytes,
       +        associated_data: bytes = None,
       +        data: bytes
       +) -> bytes:
            assert isinstance(key, (bytes, bytearray))
            assert isinstance(nonce, (bytes, bytearray))
       -    assert isinstance(associated_data, (bytes, bytearray))
       +    assert isinstance(associated_data, (bytes, bytearray, type(None)))
            assert isinstance(data, (bytes, bytearray))
            if HAS_CRYPTODOME:
                cipher = CD_ChaCha20_Poly1305.new(key=key, nonce=nonce)
       -        cipher.update(associated_data)
       +        if associated_data is not None:
       +            cipher.update(associated_data)
                ciphertext, mac = cipher.encrypt_and_digest(plaintext=data)
                return ciphertext + mac
            if HAS_CRYPTOGRAPHY:
       t@@ -284,14 +291,21 @@ def chacha20_poly1305_encrypt(*, key: bytes, nonce: bytes, associated_data: byte
            raise Exception("no chacha20 backend found")
        
        
       -def chacha20_poly1305_decrypt(*, key: bytes, nonce: bytes, associated_data: bytes, data: bytes) -> bytes:
       +def chacha20_poly1305_decrypt(
       +        *,
       +        key: bytes,
       +        nonce: bytes,
       +        associated_data: bytes = None,
       +        data: bytes
       +) -> bytes:
            assert isinstance(key, (bytes, bytearray))
            assert isinstance(nonce, (bytes, bytearray))
       -    assert isinstance(associated_data, (bytes, bytearray))
       +    assert isinstance(associated_data, (bytes, bytearray, type(None)))
            assert isinstance(data, (bytes, bytearray))
            if HAS_CRYPTODOME:
                cipher = CD_ChaCha20_Poly1305.new(key=key, nonce=nonce)
       -        cipher.update(associated_data)
       +        if associated_data is not None:
       +            cipher.update(associated_data)
                # raises ValueError if not valid (e.g. incorrect MAC)
                return cipher.decrypt_and_verify(ciphertext=data[:-16], received_mac_tag=data[-16:])
            if HAS_CRYPTOGRAPHY:
 (DIR) diff --git a/electrum/tests/test_bitcoin.py b/electrum/tests/test_bitcoin.py
       t@@ -261,7 +261,7 @@ class Test_bitcoin(ElectrumTestCase):
                    crypto.pw_decode(enc, wrong_password, version=1)
        
            @needs_test_with_all_chacha20_implementations
       -    def test_chacha20_poly1305_encrypt(self):
       +    def test_chacha20_poly1305_encrypt__with_associated_data(self):
                key = bytes.fromhex('37326d9d69a83b815ddfd947d21b0dd39111e5b6a5a44042c44d570ea03e3179')
                nonce = bytes.fromhex('010203040506070809101112')
                associated_data = bytes.fromhex('30c9572d4305d4f3ccb766b1db884da6f1e0086f55136a39740700c272095717')
       t@@ -270,7 +270,7 @@ class Test_bitcoin(ElectrumTestCase):
                                 crypto.chacha20_poly1305_encrypt(key=key, nonce=nonce, associated_data=associated_data, data=data))
        
            @needs_test_with_all_chacha20_implementations
       -    def test_chacha20_poly1305_decrypt(self):
       +    def test_chacha20_poly1305_decrypt__with_associated_data(self):
                key = bytes.fromhex('37326d9d69a83b815ddfd947d21b0dd39111e5b6a5a44042c44d570ea03e3179')
                nonce = bytes.fromhex('010203040506070809101112')
                associated_data = bytes.fromhex('30c9572d4305d4f3ccb766b1db884da6f1e0086f55136a39740700c272095717')
       t@@ -281,6 +281,26 @@ class Test_bitcoin(ElectrumTestCase):
                    crypto.chacha20_poly1305_decrypt(key=key, nonce=nonce, associated_data=b'', data=data)
        
            @needs_test_with_all_chacha20_implementations
       +    def test_chacha20_poly1305_encrypt__without_associated_data(self):
       +        key = bytes.fromhex('37326d9d69a83b815ddfd947d21b0dd39111e5b6a5a44042c44d570ea03e3179')
       +        nonce = bytes.fromhex('010203040506070809101112')
       +        data = bytes.fromhex('4a6cd75da76cedf0a8a47e3a5734a328')
       +        self.assertEqual(bytes.fromhex('90fb51fcde1fbe4013500bd7a322804469c2be9b1385bc5ded5cd96be510280f'),
       +                         crypto.chacha20_poly1305_encrypt(key=key, nonce=nonce, data=data))
       +        self.assertEqual(bytes.fromhex('90fb51fcde1fbe4013500bd7a322804469c2be9b1385bc5ded5cd96be510280f'),
       +                         crypto.chacha20_poly1305_encrypt(key=key, nonce=nonce, data=data, associated_data=b''))
       +
       +    @needs_test_with_all_chacha20_implementations
       +    def test_chacha20_poly1305_decrypt__without_associated_data(self):
       +        key = bytes.fromhex('37326d9d69a83b815ddfd947d21b0dd39111e5b6a5a44042c44d570ea03e3179')
       +        nonce = bytes.fromhex('010203040506070809101112')
       +        data = bytes.fromhex('90fb51fcde1fbe4013500bd7a322804469c2be9b1385bc5ded5cd96be510280f')
       +        self.assertEqual(bytes.fromhex('4a6cd75da76cedf0a8a47e3a5734a328'),
       +                         crypto.chacha20_poly1305_decrypt(key=key, nonce=nonce, data=data))
       +        self.assertEqual(bytes.fromhex('4a6cd75da76cedf0a8a47e3a5734a328'),
       +                         crypto.chacha20_poly1305_decrypt(key=key, nonce=nonce, data=data, associated_data=b''))
       +
       +    @needs_test_with_all_chacha20_implementations
            def test_chacha20_encrypt(self):
                key = bytes.fromhex('37326d9d69a83b815ddfd947d21b0dd39111e5b6a5a44042c44d570ea03e3179')
                nonce = bytes.fromhex('0102030405060708')