I was wondering, if the output of following type of ChaCha + HMAC scheme is indistinguishable from randomness:

from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.primitives import hashes, hmac

def chachaHMAC(key, nonce, data): #Do not reuse nonce!!!
    #Make different key from chacha key to use as hmac key
    sha3_256 = hashes.Hash(hashes.SHA3_256())
    hm = hmac.HMAC(sha3_256.finalize(), hashes.SHA3_256())

    encryptor = Cipher(algorithms.ChaCha20(key, nonce), mode=None).encryptor()
    ct = encryptor.update(data)

    output = ct + hm.finalize() #Is this data indistinguishable from randomness?
    return output

Is it possible to statistically find this kind of data when mixed with random information eg.

key = os.urandom(32)
nonce = os.urandom(16)
ciphertext = chachaHMAC(key, nonce, b"Test data...")

#Replace 32 with random lengths
random_data = os.urandom(32) + ciphertext + os.urandom(32)
#Is it feasible to find that there is ciphertext protected with such scheme in the random_data ?

I am aware that ChaCha20 can also be used as CSPRNG, so does this mean that the text encrypted with ChaCha20 is indistinquishable? Also it is said about output of SHA3_256 that it is also indistinguishable from randomness if calculated with enought entropy (this does not seem to apply to SHA2 series hash funtions?). Do these properties still apply when the ChaCha20 encrypted data is HMAC:ed with SHA3 series function?

EDIT: Could this be used with AES CTR or other mode also without making it more feasible to recognize ciphertext from amongst random data?

  • $\begingroup$ Looks like you're pretty safe, but please don't forget about ciphertext sizes and the frequency of messages - those may not be random in the slightest. $\endgroup$
    – Maarten Bodewes
    Aug 16, 2022 at 11:07
  • $\begingroup$ @MaartenBodewes What kind of vulnerability would knowing the ciphertext length allow? Do you have recommendations for fixing that vulnerability? $\endgroup$ Aug 16, 2022 at 11:14
  • 2
    $\begingroup$ That depends entirely on the data you are sending/ the use case. Obviously if a movie is precisely 50.xxx.xxx.xxx bytes then that may hint somebody about the contents. A well known issue is also sending variable rate compressed voice over a secure channel with separate messages as you would easily be able to get information about gaps & frequency, even if that is being encrypted. In the latter case adding fake info, or using a constant size stream would fix the issue. $\endgroup$
    – Maarten Bodewes
    Aug 16, 2022 at 12:59


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Browse other questions tagged or ask your own question.