doby started as a fork of [aef](https://github.com/wyhaya/aef) by [wyhaya](https://github.com/wyhaya) with the goal of becoming the fastest and most lightweight CLI utility for symmetric encryption. It aims to replace the old [ccrypt](http://ccrypt.sourceforge.net) tool which doesn't seem to be very secure.
* Fast: written in [rust](https://www.rust-lang.org), encrypts with [AES-256-CTR](https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation#Counter_(CTR)) or [XChaCha20](https://en.wikipedia.org/wiki/Salsa20#XChaCha)
doby is provided "as is", without any warranty of any kind. I'm not a professional cryptographer. This program didn't receive any security audit and therefore __shouldn't be considered fully secure__.
doby first derives your password with Argon2 (version 19) in Argon2id mode with a 64 bytes long random salt. A `master_key` of 32 bytes is thus generated.
Then, doby uses [HKDF](https://en.wikipedia.org/wiki/HKDF) with the previous random salt to compute the `nonce`, the `encryption_key`and the `authentication_key`.
NOTE: To reduce the size of the header, the `nonce` is derived from the `master_key` instead of being generated purely at random then stored in the encrypted file.
Next, doby initializes a [BLAKE2b](https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE2) HMAC with `authentication_key` and add all public encryption parameters to it.
Now, doby initializes a symmetric cipher with `encryption_key` and `nonce` (either AES-CTR or XChaCha20, based on the `--cipher` option) and starts the actual encryption. It reads chunks from the plaintext (according to the `--block-size` parameter), encrypts them with the cipher and updates the HMAC with the ciphertext.
`nonce`, `encryption_key`and `authentication_key` are computed from `master_key` in the same way as during encryption. The HMAC is also initialized and updated with the values read from the header.
_If you find any weakness or security issue is this protocol, please open an issue._
## Why not using authenticated encryption such as AES-GCM instead of AES-CTR + HMAC ?
In order to encrypt data larger than memory, we need to split the plaintext into severavl smaller chunks and encrypt each of these chunks one by one. With authenticated encryption such as AES-GCM, this involves adding an authentication tag to each chunk. As a result, the final ciphertext size would be:
```
ciphertext size = plaintext size + (number of chunks ྾ tag size)
```
For example, a 50MB file encrypted with AES-GCM by chunks of 64KiB would be 12.2KB larger than the original plaintext, just to authenticate the file.
doby solves this problem by performing authentication independently of encryption. By using AES-CTR, the ciphertext remains the same size as the plaintext. The HMAC can be computed incrementally, one chunk at a time. Only one hash needs to be included in the final file. Thus, doby encrypted files are only 142 bytes larger than the plaintext, no matter how big the original file is.