1 //! The ChaCha20 stream cipher ([RFC 8439]) 2 //! 3 //! ChaCha20 is a lightweight stream cipher which is amenable to fast, 4 //! constant-time implementations in software. It improves upon the previous 5 //! [Salsa20] stream cipher, providing increased per-round diffusion 6 //! with no cost to performance. 7 //! 8 //! Cipher functionality is accessed using traits from re-exported 9 //! [`cipher`](https://docs.rs/cipher) crate. 10 //! 11 //! This crate contains the following variants of the ChaCha20 core algorithm: 12 //! 13 //! - [`ChaCha20`]: standard IETF variant with 96-bit nonce 14 //! - [`ChaCha20Legacy`]: (gated under the `legacy` feature) "djb" variant with 64-bit nonce 15 //! - [`ChaCha8`] / [`ChaCha12`]: reduced round variants of ChaCha20 16 //! - [`XChaCha20`]: (gated under the `xchacha20` feature) 192-bit extended nonce variant 17 //! 18 //! # ⚠️ Security Warning: [Hazmat!] 19 //! 20 //! This crate does not ensure ciphertexts are authentic, which can lead to 21 //! serious vulnerabilities if used incorrectly! 22 //! 23 //! If in doubt, use the [`chacha20poly1305`](https://docs.rs/chacha20poly1305) 24 //! crate instead, which provides an authenticated mode on top of ChaCha20. 25 //! 26 //! **USE AT YOUR OWN RISK!** 27 //! 28 //! # Diagram 29 //! 30 //! This diagram illustrates the ChaCha quarter round function. 31 //! Each round consists of four quarter-rounds: 32 //! 33 //! <img src="https://raw.githubusercontent.com/RustCrypto/meta/master/img/stream-ciphers/chacha20.png" width="300px"> 34 //! 35 //! Legend: 36 //! 37 //! - ⊞ add 38 //! - ‹‹‹ rotate 39 //! - ⊕ xor 40 //! 41 //! # Usage 42 //! 43 //! ``` 44 //! use chacha20::{ChaCha20, Key, Nonce}; 45 //! use chacha20::cipher::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek}; 46 //! 47 //! let mut data = [1, 2, 3, 4, 5, 6, 7]; 48 //! 49 //! let key = Key::from_slice(b"an example very very secret key."); 50 //! let nonce = Nonce::from_slice(b"secret nonce"); 51 //! 52 //! // create cipher instance 53 //! let mut cipher = ChaCha20::new(&key, &nonce); 54 //! 55 //! // apply keystream (encrypt) 56 //! cipher.apply_keystream(&mut data); 57 //! assert_eq!(data, [73, 98, 234, 202, 73, 143, 0]); 58 //! 59 //! // seek to the keystream beginning and apply it again to the `data` (decrypt) 60 //! cipher.seek(0); 61 //! cipher.apply_keystream(&mut data); 62 //! assert_eq!(data, [1, 2, 3, 4, 5, 6, 7]); 63 //! ``` 64 //! 65 //! [RFC 8439]: https://tools.ietf.org/html/rfc8439 66 //! [Salsa20]: https://docs.rs/salsa20 67 //! [Hazmat!]: https://github.com/RustCrypto/meta/blob/master/HAZMAT.md 68 69 #![no_std] 70 #![doc( 71 html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", 72 html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" 73 )] 74 #![cfg_attr(docsrs, feature(doc_cfg))] 75 #![warn(missing_docs, rust_2018_idioms, trivial_casts, unused_qualifications)] 76 77 mod block; 78 #[cfg(feature = "cipher")] 79 mod chacha; 80 #[cfg(feature = "legacy")] 81 mod legacy; 82 #[cfg(feature = "rng")] 83 mod rng; 84 mod rounds; 85 #[cfg(feature = "xchacha20")] 86 mod xchacha; 87 88 #[cfg(feature = "cipher")] 89 pub use cipher; 90 91 #[cfg(feature = "cipher")] 92 pub use self::chacha::{ChaCha, ChaCha12, ChaCha20, ChaCha8, Key, Nonce}; 93 94 #[cfg(feature = "legacy")] 95 pub use self::legacy::{ChaCha20Legacy, LegacyNonce}; 96 97 #[cfg(feature = "rng")] 98 pub use rng::{ 99 ChaCha12Rng, ChaCha12RngCore, ChaCha20Rng, ChaCha20RngCore, ChaCha8Rng, ChaCha8RngCore, 100 }; 101 102 #[cfg(feature = "xchacha20")] 103 pub use self::xchacha::{XChaCha20, XNonce}; 104 105 /// Size of a ChaCha20 block in bytes 106 pub const BLOCK_SIZE: usize = 64; 107 108 /// Size of a ChaCha20 key in bytes 109 pub const KEY_SIZE: usize = 32; 110 111 /// Maximum number of blocks that can be encrypted with ChaCha20 before the 112 /// counter overflows. 113 pub const MAX_BLOCKS: usize = core::u32::MAX as usize; 114 115 /// Number of bytes in the core (non-extended) ChaCha20 IV 116 const IV_SIZE: usize = 8; 117 118 /// Number of 32-bit words in the ChaCha20 state 119 const STATE_WORDS: usize = 16; 120 121 /// State initialization constant ("expand 32-byte k") 122 const CONSTANTS: [u32; 4] = [0x6170_7865, 0x3320_646e, 0x7962_2d32, 0x6b20_6574]; 123