146 lines
5.4 KiB
Markdown
146 lines
5.4 KiB
Markdown
# RustCrypto: ChaCha20
|
|
|
|
[![Crate][crate-image]][crate-link]
|
|
[![Docs][docs-image]][docs-link]
|
|
[![Build Status][build-image]][build-link]
|
|
![Apache2/MIT licensed][license-image]
|
|
![Rust Version][rustc-image]
|
|
[![Project Chat][chat-image]][chat-link]
|
|
[![HAZMAT][hazmat-image]][hazmat-link]
|
|
|
|
Implementation of the [ChaCha] family of stream ciphers.
|
|
|
|
ChaCha improves upon the previous [Salsa] family of stream ciphers
|
|
with increased per-round diffusion at no cost to performance.
|
|
|
|
This crate also contains an implementation of the [XChaCha] family of stream ciphers
|
|
with an extended 192-bit (24-byte) nonce, gated under the `xchacha` Cargo feature,
|
|
and "legacy" (a.k.a "djb") variant with 64-bit nonce, gated under the `legacy` crate feature.
|
|
|
|
**WARNING:** This implementation internally uses 32-bit counter,
|
|
while the original "legacy" variant implementation uses 64-bit counter.
|
|
In other words, it does not allow encryption of more than 256 GiB of data.
|
|
|
|
## Security
|
|
|
|
### ⚠️ Warning: [Hazmat!][hazmat-link]
|
|
|
|
This crate does not ensure ciphertexts are authentic (i.e. by using a MAC to
|
|
verify ciphertext integrity), which can lead to serious vulnerabilities
|
|
if used incorrectly!
|
|
|
|
To avoid this, use an [AEAD] mode based on ChaCha20, e.g. [`chacha20poly1305`].
|
|
See the [RustCrypto/AEADs] repository for more information.
|
|
|
|
USE AT YOUR OWN RISK!
|
|
|
|
### Notes
|
|
|
|
This crate has received one [security audit by NCC Group][NCC-AUDIT], with no significant
|
|
findings. We would like to thank [MobileCoin] for funding the audit.
|
|
|
|
All implementations contained in the crate (along with the underlying ChaCha20
|
|
stream cipher itself) are designed to execute in constant time.
|
|
|
|
## Examples
|
|
|
|
```rust
|
|
// This example requires `cipher` crate feature
|
|
#[cfg(feature = "cipher")] {
|
|
|
|
use chacha20::ChaCha20;
|
|
use chacha20::cipher::{KeyIvInit, StreamCipher, StreamCipherSeek};
|
|
use hex_literal::hex;
|
|
|
|
let key = [0x42; 32];
|
|
let nonce = [0x24; 12];
|
|
let plaintext = hex!("000102030405060708090A0B0C0D0E0F");
|
|
let ciphertext = hex!("e405626e4f1236b3670ee428332ea20e");
|
|
|
|
// Key and IV must be references to the `Array` type.
|
|
// Here we use the `Into` trait to convert arrays into it.
|
|
let mut cipher = ChaCha20::new(&key.into(), &nonce.into());
|
|
|
|
let mut buffer = plaintext;
|
|
|
|
// apply keystream (encrypt)
|
|
cipher.apply_keystream(&mut buffer);
|
|
assert_eq!(buffer, ciphertext);
|
|
|
|
let ciphertext = buffer;
|
|
|
|
// ChaCha ciphers support seeking
|
|
cipher.seek(0u32);
|
|
|
|
// decrypt ciphertext by applying keystream again
|
|
cipher.apply_keystream(&mut buffer);
|
|
assert_eq!(buffer, plaintext);
|
|
|
|
// stream ciphers can be used with streaming messages
|
|
cipher.seek(0u32);
|
|
for chunk in buffer.chunks_mut(3) {
|
|
cipher.apply_keystream(chunk);
|
|
}
|
|
assert_eq!(buffer, ciphertext);
|
|
}
|
|
```
|
|
|
|
## Configuration Flags
|
|
|
|
You can modify crate using the following configuration flags:
|
|
|
|
- `chacha20_backend="avx2"`: force AVX2 backend on x86/x86_64 targets.
|
|
Requires enabled AVX2 target feature. Ignored on non-x86(_64) targets.
|
|
- `chacha20_backend="avx512"`: force AVX-512 backend on x86/x86_64 targets.
|
|
Requires enabled AVX-512 target feature (MSRV 1.89). Ignored on non-x86(_64) targets.
|
|
- `chacha20_backend="soft"`: force software backend.
|
|
- `chacha20_backend="sse2"`: force SSE2 backend on x86/x86_64 targets.
|
|
Requires enabled SSE2 target feature. Ignored on non-x86(-64) targets.
|
|
|
|
To use the MSRV 1.89 AVX-512 support with autodetection, you must enable it using
|
|
`chacha20_avx512` configuration flag.
|
|
|
|
The flags can be enabled using `RUSTFLAGS` environmental variable
|
|
(e.g. `RUSTFLAGS='--cfg chacha20_backend="avx2"'`) or by modifying `.cargo/config.toml`.
|
|
|
|
## License
|
|
|
|
Licensed under either of:
|
|
|
|
- [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
|
- [MIT license](http://opensource.org/licenses/MIT)
|
|
|
|
at your option.
|
|
|
|
### Contribution
|
|
|
|
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
|
|
dual licensed as above, without any additional terms or conditions.
|
|
|
|
[//]: # (badges)
|
|
|
|
[crate-image]: https://img.shields.io/crates/v/chacha20.svg
|
|
[crate-link]: https://crates.io/crates/chacha20
|
|
[docs-image]: https://docs.rs/chacha20/badge.svg
|
|
[docs-link]: https://docs.rs/chacha20/
|
|
[build-image]: https://github.com/RustCrypto/stream-ciphers/actions/workflows/chacha20.yml/badge.svg
|
|
[build-link]: https://github.com/RustCrypto/stream-ciphers/actions/workflows/chacha20.yml
|
|
[license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg
|
|
[rustc-image]: https://img.shields.io/badge/rustc-1.85+-blue.svg
|
|
[chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg
|
|
[chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260049-stream-ciphers
|
|
[hazmat-image]: https://img.shields.io/badge/crypto-hazmat%E2%9A%A0-red.svg
|
|
[hazmat-link]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md
|
|
|
|
[//]: # (footnotes)
|
|
|
|
[ChaCha]: https://en.wikipedia.org/wiki/Salsa20#ChaCha_variant
|
|
[Salsa]: https://en.wikipedia.org/wiki/Salsa20
|
|
[XChaCha]: https://tools.ietf.org/html/draft-arciszewski-xchacha-02
|
|
[AEAD]: https://en.wikipedia.org/wiki/Authenticated_encryption
|
|
[`chacha20poly1305`]: https://docs.rs/chacha20poly1305
|
|
[RustCrypto/AEADs]: https://github.com/RustCrypto/AEADs
|
|
[NCC-AUDIT]: https://web.archive.org/web/20240108154854/https://research.nccgroup.com/wp-content/uploads/2020/02/NCC_Group_MobileCoin_RustCrypto_AESGCM_ChaCha20Poly1305_Implementation_Review_2020-02-12_v1.0.pdf
|
|
[MobileCoin]: https://www.mobilecoin.com/
|