Skip to content

Commit

Permalink
Merge pull request #69 from RustCrypto/reduced-round-variants
Browse files Browse the repository at this point in the history
chacha20poly1305: Add ChaCha8/ChaCha20 reduced round variants
  • Loading branch information
tarcieri authored Jan 16, 2020
2 parents 82340e5 + bd1fa9e commit 509904c
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 61 deletions.
9 changes: 6 additions & 3 deletions chacha20poly1305/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@
name = "chacha20poly1305"
version = "0.3.0"
description = """
Pure Rust implementation of the ChaCha20Poly1305 (and XChaCha20Poly1305)
Authenticated Encryption with Additional Data Ciphers (RFC 8439) with optional
architecture-specific hardware acceleration
Pure Rust implementation of the ChaCha20Poly1305 Authenticated Encryption
with Additional Data Ciphers (RFC 8439) with optional architecture-specific
hardware acceleration. Also contains implementations of the XChaCha20Poly1305
extended nonce variant of ChaCha20Poly1305, and the reduced-round
ChaCha8Poly1305 and ChaCha12Poly1305 lightweight variants.
"""
authors = ["RustCrypto Developers"]
edition = "2018"
Expand Down Expand Up @@ -32,6 +34,7 @@ criterion-cycles-per-byte = "0.1.1"
default = ["alloc", "xchacha20poly1305"]
alloc = ["aead/alloc"]
heapless = ["aead/heapless"]
reduced-round = []
xchacha20poly1305 = ["chacha20/xchacha20"]

[[bench]]
Expand Down
146 changes: 88 additions & 58 deletions chacha20poly1305/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
//! cipher amenable to fast, constant-time implementations in software, based on
//! the [ChaCha20][3] stream cipher and [Poly1305][4] universal hash function.
//!
//! This crate also contains an implementation of [`XChaCha20Poly1305`] -
//! a variant of ChaCha20Poly1305 with an extended 192-bit (24-byte) nonce.
//! This crate also contains the following `ChaCha20Poly1305` variants:
//! - [`XChaCha20Poly1305`] - ChaCha20Poly1305 variant with an extended 192-bit (24-byte) nonce.
//! - [`ChaCha8Poly1305`] / [`ChaCha12Poly1305`] - nonstandard, reduced round variants
//! (gated under the `reduced-round` Cargo feature). See the [Too Much Crypto][5]
//! paper for background and rationale on when these constructions shoudl be used.
//! When in doubt, prefer `ChaCha20Poly1305`.
//!
//! ## Performance Notes
//!
Expand Down Expand Up @@ -55,12 +59,12 @@
//! This crate has an optional `alloc` feature which can be disabled in e.g.
//! microcontroller environments that don't have a heap.
//!
//! The [`Aead::encrypt_in_place`][5] and [`Aead::decrypt_in_place`][6]
//! methods accept any type that impls the [`aead::Buffer`][7] trait which
//! The [`Aead::encrypt_in_place`][6] and [`Aead::decrypt_in_place`][7]
//! methods accept any type that impls the [`aead::Buffer`][8] trait which
//! contains the plaintext for encryption or ciphertext for decryption.
//!
//! Note that if you enable the `heapless` feature of this crate,
//! you will receive an impl of `aead::Buffer` for [`heapless::Vec`][8]
//! you will receive an impl of `aead::Buffer` for [`heapless::Vec`][9]
//! (re-exported from the `aead` crate as `aead::heapless::Vec`),
//! which can then be passed as the `buffer` parameter to the in-place encrypt
//! and decrypt methods:
Expand Down Expand Up @@ -94,10 +98,11 @@
//! [2]: https://en.wikipedia.org/wiki/Authenticated_encryption
//! [3]: https:/RustCrypto/stream-ciphers/tree/master/chacha20
//! [4]: https:/RustCrypto/universal-hashes/tree/master/poly1305
//! [5]: https://docs.rs/aead/latest/aead/trait.Aead.html#method.encrypt_in_place
//! [6]: https://docs.rs/aead/latest/aead/trait.Aead.html#method.decrypt_in_place
//! [7]: https://docs.rs/aead/latest/aead/trait.Buffer.html
//! [8]: https://docs.rs/heapless/latest/heapless/struct.Vec.html
//! [5]: https://eprint.iacr.org/2019/1492.pdf
//! [6]: https://docs.rs/aead/latest/aead/trait.Aead.html#method.encrypt_in_place
//! [7]: https://docs.rs/aead/latest/aead/trait.Aead.html#method.decrypt_in_place
//! [8]: https://docs.rs/aead/latest/aead/trait.Buffer.html
//! [9]: https://docs.rs/heapless/latest/heapless/struct.Vec.html

#![no_std]
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
Expand All @@ -120,62 +125,87 @@ use aead::{Aead, Error, NewAead};
use chacha20::{stream_cipher::NewStreamCipher, ChaCha20};
use zeroize::Zeroize;

#[cfg(feature = "reduced-round")]
use chacha20::{ChaCha12, ChaCha8};

/// Poly1305 tags
pub type Tag = GenericArray<u8, U16>;

/// ChaCha20Poly1305 Authenticated Encryption with Additional Data (AEAD).
///
/// The [`Aead`] and [`NewAead`] traits provide the primary API for using this
/// construction.
///
/// See the [toplevel documentation](https://docs.rs/chacha20poly1305) for
/// a usage example.
#[derive(Clone)]
pub struct ChaCha20Poly1305 {
/// Secret key
key: GenericArray<u8, U32>,
}
macro_rules! impl_chachapoly {
($name:ident, $cipher:ident, $doc:expr) => {
#[doc = $doc]
#[doc = "\n"]
#[doc = "The [`Aead`] and [`NewAead`] traits provide the primary API for using this construction."]
#[doc = "\n"]
#[doc = "See the [toplevel documentation](https://docs.rs/chacha20poly1305) for a usage example."]
#[derive(Clone)]
pub struct $name {
/// Secret key
key: GenericArray<u8, U32>,
}

impl NewAead for ChaCha20Poly1305 {
type KeySize = U32;
impl NewAead for $name {
type KeySize = U32;

fn new(key: GenericArray<u8, U32>) -> Self {
ChaCha20Poly1305 { key }
}
}
fn new(key: GenericArray<u8, U32>) -> Self {
Self { key }
}
}

impl Aead for ChaCha20Poly1305 {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;

fn encrypt_in_place_detached(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<Tag, Error> {
Cipher::new(ChaCha20::new(&self.key, nonce))
.encrypt_in_place_detached(associated_data, buffer)
}
impl Aead for $name {
type NonceSize = U12;
type TagSize = U16;
type CiphertextOverhead = U0;

fn decrypt_in_place_detached(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &Tag,
) -> Result<(), Error> {
Cipher::new(ChaCha20::new(&self.key, nonce)).decrypt_in_place_detached(
associated_data,
buffer,
tag,
)
}
}
fn encrypt_in_place_detached(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut [u8],
) -> Result<Tag, Error> {
Cipher::new($cipher::new(&self.key, nonce))
.encrypt_in_place_detached(associated_data, buffer)
}

fn decrypt_in_place_detached(
&self,
nonce: &GenericArray<u8, Self::NonceSize>,
associated_data: &[u8],
buffer: &mut [u8],
tag: &Tag,
) -> Result<(), Error> {
Cipher::new($cipher::new(&self.key, nonce)).decrypt_in_place_detached(
associated_data,
buffer,
tag,
)
}
}

impl Drop for ChaCha20Poly1305 {
fn drop(&mut self) {
self.key.as_mut_slice().zeroize();
impl Drop for $name {
fn drop(&mut self) {
self.key.as_mut_slice().zeroize();
}
}
}
}

#[cfg(feature = "reduced-round")]
impl_chachapoly!(
ChaCha8Poly1305,
ChaCha8,
"ChaCha8Poly1305 (reduced round variant) Authenticated Encryption with Additional Data (AEAD)."
);

#[cfg(feature = "reduced-round")]
impl_chachapoly!(
ChaCha12Poly1305,
ChaCha12,
"ChaCha12Poly1305 (reduced round variant) Authenticated Encryption with Additional Data (AEAD)."
);

impl_chachapoly!(
ChaCha20Poly1305,
ChaCha20,
"ChaCha20Poly1305 Authenticated Encryption with Additional Data (AEAD)."
);

0 comments on commit 509904c

Please sign in to comment.