use crate::errors::UnknownCryptoError;
pub use crate::hazardous::mac::poly1305::Tag;
pub use crate::hazardous::stream::{chacha20::SecretKey, xchacha20::Nonce};
use crate::hazardous::{aead::chacha20poly1305::ChaCha20Poly1305, stream::xchacha20::XChaCha20};
#[derive(Debug)]
pub struct XChaCha20Poly1305 {}
impl XChaCha20Poly1305 {
#[must_use = "SECURITY WARNING: Ignoring a Result can have real security implications."]
pub fn seal_inplace(
sk: &SecretKey,
n: &Nonce,
ad: Option<&[u8]>,
bytes: &mut [u8],
) -> Result<Tag, UnknownCryptoError> {
let (subkey, ietf_nonce) = XChaCha20::subkey_and_ietf_nonce(sk, n);
ChaCha20Poly1305::seal_inplace(&subkey, &ietf_nonce, ad, bytes)
}
#[must_use = "SECURITY WARNING: Ignoring a Result can have real security implications."]
pub fn open_inplace(
sk: &SecretKey,
n: &Nonce,
tag: &Tag,
ad: Option<&[u8]>,
bytes: &mut [u8],
) -> Result<(), UnknownCryptoError> {
let (subkey, ietf_nonce) = XChaCha20::subkey_and_ietf_nonce(sk, n);
ChaCha20Poly1305::open_inplace(&subkey, &ietf_nonce, tag, ad, bytes)
}
#[must_use = "SECURITY WARNING: Ignoring a Result can have real security implications."]
pub fn seal(
sk: &SecretKey,
n: &Nonce,
plaintext: &[u8],
ad: Option<&[u8]>,
dst_out: &mut [u8],
) -> Result<(), UnknownCryptoError> {
let (subkey, ietf_nonce) = XChaCha20::subkey_and_ietf_nonce(sk, n);
ChaCha20Poly1305::seal(&subkey, &ietf_nonce, plaintext, ad, dst_out)
}
#[must_use = "SECURITY WARNING: Ignoring a Result can have real security implications."]
pub fn open(
sk: &SecretKey,
n: &Nonce,
ciphertext_with_tag: &[u8],
ad: Option<&[u8]>,
dst_out: &mut [u8],
) -> Result<(), UnknownCryptoError> {
let (subkey, ietf_nonce) = XChaCha20::subkey_and_ietf_nonce(sk, n);
ChaCha20Poly1305::open(&subkey, &ietf_nonce, ciphertext_with_tag, ad, dst_out)
}
}
#[cfg(test)]
mod public {
use super::*;
use crate::hazardous::mac::poly1305::{POLY1305_OUTSIZE, Poly1305Tag};
use crate::hazardous::stream::chacha20::{CHACHA_KEYSIZE, ChaCha20Key};
use crate::hazardous::stream::xchacha20::{XCHACHA_NONCESIZE, XChaCha20Nonce};
use crate::test_framework::aead_interface::{AeadTestRunner, TestableAead};
impl TestableAead for XChaCha20Poly1305 {
type Key = ChaCha20Key;
type Nonce = XChaCha20Nonce;
type Tag = Poly1305Tag;
fn _seal_inplace(
sk: &crate::Secret<Self::Key>,
n: &crate::Public<Self::Nonce>,
ad: Option<&[u8]>,
bytes: &mut [u8],
) -> Result<crate::Secret<Self::Tag>, UnknownCryptoError> {
XChaCha20Poly1305::seal_inplace(sk, n, ad, bytes)
}
fn _open_inplace(
sk: &crate::Secret<Self::Key>,
n: &crate::Public<Self::Nonce>,
tag: &crate::Secret<Self::Tag>,
ad: Option<&[u8]>,
bytes: &mut [u8],
) -> Result<(), UnknownCryptoError> {
XChaCha20Poly1305::open_inplace(sk, n, tag, ad, bytes)
}
fn _seal(
sk: &crate::Secret<Self::Key>,
n: &crate::Public<Self::Nonce>,
plaintext: &[u8],
ad: Option<&[u8]>,
dst_out: &mut [u8],
) -> Result<(), UnknownCryptoError> {
XChaCha20Poly1305::seal(sk, n, plaintext, ad, dst_out)
}
fn _open(
sk: &crate::Secret<Self::Key>,
n: &crate::Public<Self::Nonce>,
ciphertext_with_tag: &[u8],
ad: Option<&[u8]>,
dst_out: &mut [u8],
) -> Result<(), UnknownCryptoError> {
XChaCha20Poly1305::open(sk, n, ciphertext_with_tag, ad, dst_out)
}
}
#[test]
fn test_aead_interface() {
AeadTestRunner::<XChaCha20Poly1305, CHACHA_KEYSIZE, XCHACHA_NONCESIZE, POLY1305_OUTSIZE>::run_all_tests(&[213u8; 512]);
}
#[quickcheck]
#[cfg(feature = "safe_api")]
fn prop_aead_interface(input: Vec<u8>) -> bool {
AeadTestRunner::<XChaCha20Poly1305, CHACHA_KEYSIZE, XCHACHA_NONCESIZE, POLY1305_OUTSIZE>::run_all_tests(&input);
true
}
}