# 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/