Merge bitcoin/bitcoin#29390: test: speedup bip324_cipher.py unit test

a8c3454ba137dfac20b3c89bc558374de0524114 test: speedup bip324_cipher.py unit test (Sebastian Falbesoner)

Pull request description:

  Executing the unit tests for the bip324_cipher.py module currently takes quite long (>60 seconds on my older notebook). Most time here is spent in empty plaintext/ciphertext encryption/decryption loops in `test_fschacha20poly1305aead`:

  9eeee7caa3/test/functional/test_framework/crypto/bip324_cipher.py (L193-L194)
  9eeee7caa3/test/functional/test_framework/crypto/bip324_cipher.py (L198-L199)

  Their sole purpose is increasing the FSChaCha20Poly1305 packet counter in order to trigger rekeying, i.e. the actual encryption/decryption is not relevant, as the result is thrown away. This commit speeds up the tests by supporting to pass "None" as plaintext/ciphertext, indicating to the routines that no actual encryption/decryption should be done.

  The approach here is a bit hacky, a cleaner alternative would probably be to introduce a special `seek`/`skip_packets` method and not touch the encrypt/decrypt routines, but that seemed overkill to me only for speeding up a unit test. Open for suggestions.

  master branch:

  ```
  $ python3 -m unittest ./test/functional/test_framework/crypto/bip324_cipher.py
  ..
  ----------------------------------------------------------------------
  Ran 2 tests in 64.658s
  ```
  PR branch:

  ```
  $ python3 -m unittest ./test/functional/test_framework/crypto/bip324_cipher.py
  ..
  ----------------------------------------------------------------------
  Ran 2 tests in 0.822s
  ```

ACKs for top commit:
  delta1:
    Concept ACK a8c3454
  epiccurious:
    Tested ACK a8c3454ba137dfac20b3c89bc558374de0524114.
  achow101:
    ACK a8c3454ba137dfac20b3c89bc558374de0524114
  marcofleon:
    ACK a8c3454ba137dfac20b3c89bc558374de0524114. The comments at the top of `bip324_cipher.py` specify that this should only be used for testing, so I think this optimization makes sense in that context.
  cbergqvist:
    ACK a8c3454!
  stratospher:
    ACK a8c3454. I think it's worth it because of the significant speedup in the unit test.

Tree-SHA512: 737dd805a850be6e035aa3c6d9e2c5b5b5e89ddc564f84a045c37e0238fef6419912de7c902139b64914abdd647c649fe02a694f1a5e1741d7d4459c041caccc
This commit is contained in:
Ava Chow 2024-02-29 15:06:15 -05:00
commit be5399e785
No known key found for this signature in database
GPG Key ID: 17565732E08E5E41

View File

@ -25,6 +25,8 @@ def pad16(x):
def aead_chacha20_poly1305_encrypt(key, nonce, aad, plaintext):
"""Encrypt a plaintext using ChaCha20Poly1305."""
if plaintext is None:
return None
ret = bytearray()
msg_len = len(plaintext)
for i in range((msg_len + 63) // 64):
@ -42,7 +44,7 @@ def aead_chacha20_poly1305_encrypt(key, nonce, aad, plaintext):
def aead_chacha20_poly1305_decrypt(key, nonce, aad, ciphertext):
"""Decrypt a ChaCha20Poly1305 ciphertext."""
if len(ciphertext) < 16:
if ciphertext is None or len(ciphertext) < 16:
return None
msg_len = len(ciphertext) - 16
poly1305 = Poly1305(chacha20_block(key, nonce, 0)[:32])
@ -191,11 +193,11 @@ class TestFrameworkAEAD(unittest.TestCase):
dec_aead = FSChaCha20Poly1305(key)
for _ in range(msg_idx):
enc_aead.encrypt(b"", b"")
enc_aead.encrypt(b"", None)
ciphertext = enc_aead.encrypt(aad, plain)
self.assertEqual(hex_cipher, ciphertext.hex())
for _ in range(msg_idx):
dec_aead.decrypt(b"", bytes(16))
dec_aead.decrypt(b"", None)
plaintext = dec_aead.decrypt(aad, ciphertext)
self.assertEqual(plain, plaintext)