Salchicha.Chacha (Salchicha v0.1.0)
View SourceImplementation of the ChaCha20 and XChaCha20 Ciphers
Internal module
This module is not intended to be used directly and is documented for completeness and curious cryptographic cats.
Purpose
Erlang's :crypto
module supports the chacha20_poly1305 AEAD stream cipher.
Analogously to Salsa20 and XSalsa20, XChaCha20 is a way to use 192-bit nonces
with ChaCha20 by hashing the key and part of the extended nonce to generate a
sub-key, which is used as the input key for ChaCha20.
To leverage the crypto module, we had to implement the HChaCha20 hash function
in elixir to then pass the resulting sub-key to the :crypto.crypto_one_time_aead/7
.
Implementation
The HChaCha20 function takes the first 16-bytes of the extended 24-byte XChaCha20 nonce, expands the key and the 16-byte nonce slice into a block in place of the block count and usual smaller nonce. That block has 20 rounds of mutation, and instead of summing the block with its starting state as is done with keystream generation, 8 of the 16 bytes are taken and used as the sub-key, which is the input key for the chacha20 cipher.
Even though we've implemented the bulk of what's needed to generate chacha20 key streams
for encryption and decryption, we're only using this module to generate the inputs to
use the :crypto
module's chacha20_poly1305 functionality in the capacity of xchacha20.
This is all in service of leveraging the performance benefits of the the NIF crypto
functions, which are necessarily going to be more performant than anything implemented
in pure elixir/erlang like the :kcl
package.
ChaCha20 is a variant of the Salsa20 cipher. I will discuss in greater detail the implementation
in the Salchicha.Salsa
module, where much is applicable here.
References for Salsa family of ciphers
- https://cr.yp.to/snuffle/spec.pdf
- https://cr.yp.to/chacha/chacha-20080128.pdf
- https://cr.yp.to/snuffle/xsalsa-20110204.pdf
- https://datatracker.ietf.org/doc/html/rfc7539
- https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-xchacha
Performance considerations
After the XChaCha20 sub-key is generated in elixir, the crypto NIF function performs the heavy lifting. Performance should be speedy.
Summary
Functions
HChaCha20 hash function for deriving a sub-key for XChaCha20.
Functions
@spec hchacha20(Salchicha.secret_key(), Salchicha.nonce()) :: Salchicha.secret_key()
HChaCha20 hash function for deriving a sub-key for XChaCha20.