philbin 1.0.1

A pure Rust AEGIS library with SIMD and runtime CPU detection
Documentation
/// Stores a reference to plaintext bytes.
///
/// This type exists to help prevent accidental parameter swaps in function
/// calls. It can be created from a [`&[u8]`][slice], a [`&mut [u8]`][slice] or
/// any other type that implements [`AsRef<[u8]>`][AsRef].
///
/// See [`PlaintextMut`] for the `&mut` version.
///
/// A "plaintext" is the _secret, unencrypted_ data that the sender wishes to
/// [AEAD][ae] encrypt to provide _confidentiality_, _integrity_ and
/// _authentication_.
///
/// Note that [`From`] impls are intentionally omitted to prevent accidental
/// parameter swaps. The goal is to force the caller to spell out the name of
/// this type.
///
/// [ae]: https://en.wikipedia.org/wiki/Authenticated_encryption
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct Plaintext<'a>(&'a [u8]);

impl<'a> Plaintext<'a> {
  /// Creates a new `Plaintext`.
  ///
  /// Accepts a reference to _any_ type that implements [`AsRef<[u8]>`][AsRef].
  ///
  /// # Examples
  ///
  /// ```
  /// # use philbin::easy::Plaintext;
  /// let plaintext1 = Plaintext::new(b"vewy secwet data");
  ///
  /// let raw_data: Vec<u8> = vec![1, 2, 3];
  /// let plaintext2 = Plaintext::new(&raw_data);
  /// ```
  pub fn new<T>(data: &'a T) -> Self
  where
    T: AsRef<[u8]> + ?Sized,
  {
    Plaintext(data.as_ref())
  }

  /// Returns the stored reference.
  #[must_use]
  pub fn as_bytes(&self) -> &[u8] {
    self.0
  }
}

/// Stores a _mutable_ reference to plaintext bytes.
///
/// This type exists to help prevent accidental parameter swaps in function
/// calls. It can be created from a [`&mut [u8]`][slice] or any other type that
/// implements [`AsMut<[u8]>`][AsMut].
///
/// See [`Plaintext`] for the shared reference version.
///
/// A "plaintext" is the _secret, unencrypted_ data that the sender wishes to
/// [AEAD][ae] encrypt to provide _confidentiality_, _integrity_ and
/// _authentication_.
///
/// Note that [`From`] impls are intentionally omitted to prevent accidental
/// parameter swaps. The goal is to force the caller to spell out the name of
/// this type.
///
/// [ae]: https://en.wikipedia.org/wiki/Authenticated_encryption
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct PlaintextMut<'a>(&'a mut [u8]);

impl<'a> PlaintextMut<'a> {
  /// Creates a new `PlaintextMut`.
  ///
  /// Accepts a reference to _any_ type that implements [`AsMut<[u8]>`][AsMut].
  ///
  /// # Examples
  ///
  /// ```
  /// # use philbin::easy::PlaintextMut;
  /// let mut raw_data: Vec<u8> = vec![1, 2, 3];
  /// let plaintext_mut = PlaintextMut::new(&mut raw_data);
  /// ```
  pub fn new<T>(data: &'a mut T) -> Self
  where
    T: AsMut<[u8]> + ?Sized,
  {
    PlaintextMut(data.as_mut())
  }

  /// Returns the stored reference as `&mut [u8]`.
  pub fn as_bytes_mut(&mut self) -> &mut [u8] {
    self.0
  }

  /// Returns the stored reference as `&[u8]`.
  #[must_use]
  pub fn as_bytes(&self) -> &[u8] {
    self.0
  }
}

/// Stores a reference to ciphertext bytes.
///
/// This type exists to help prevent accidental parameter swaps in function
/// calls. It can be created from a [`&[u8]`][slice], a [`&mut [u8]`][slice] or
/// any other type that implements [`AsRef<[u8]>`][AsRef].
///
/// See [`CiphertextMut`] for the `&mut` version.
///
/// A "ciphertext" is the _public, encrypted data_ produced from a secret
/// plaintext. Ciphertext produced by an [AEAD][ae] cipher like AEGIS provides
/// _confidentiality_, _integrity_ and _authentication_.
///
/// Some Philbin functions take a Ciphertext parameter that stores a
/// `ciphertext || authentication tag` or a `nonce || ciphertext ||
/// authentication tag` byte sequence.[^1]
///
/// Note that [`From`] impls are intentionally omitted to prevent accidental
/// parameter swaps. The goal is to force the caller to spell out the name of
/// this type.
///
/// [^1]: `||` represents concatenation.
///
/// [ae]: https://en.wikipedia.org/wiki/Authenticated_encryption
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct Ciphertext<'a>(&'a [u8]);

impl<'a> Ciphertext<'a> {
  /// Creates a new Ciphertext.
  ///
  /// Accepts a reference to _any_ type that implements [`AsRef<[u8]>`][AsRef].
  ///
  /// # Examples
  ///
  /// ```
  /// # use philbin::easy::Ciphertext;
  /// let ciphertext1 = Ciphertext::new(b"707411Y3NCR7P73D");
  ///
  /// let raw_data: Vec<u8> = vec![1, 2, 3];
  /// let ciphertext2 = Ciphertext::new(&raw_data);
  /// ```
  pub fn new<T>(data: &'a T) -> Self
  where
    T: AsRef<[u8]> + ?Sized,
  {
    Ciphertext(data.as_ref())
  }

  /// Returns the stored reference.
  #[must_use]
  pub fn as_bytes(&self) -> &[u8] {
    self.0
  }
}

/// Stores a _mutable_ reference to ciphertext bytes.
///
/// This type exists to help prevent accidental parameter swaps in function
/// calls. It can be created from a [`&mut [u8]`][slice] or any other type that
/// implements [`AsMut<[u8]>`][AsMut].
///
/// See [`Ciphertext`] for the shared reference version.
///
/// A "ciphertext" is the _public, encrypted data_ produced from a secret
/// plaintext. Ciphertext produced by an [AEAD][ae] cipher like AEGIS provides
/// _confidentiality_, _integrity_ and _authentication_.
///
/// Note that [`From`] impls are intentionally omitted to prevent accidental
/// parameter swaps. The goal is to force the caller to spell out the name of
/// this type.
///
/// [ae]: https://en.wikipedia.org/wiki/Authenticated_encryption
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct CiphertextMut<'a>(&'a mut [u8]);

impl<'a> CiphertextMut<'a> {
  /// Creates a new `CiphertextMut`.
  ///
  /// Accepts a reference to _any_ type that implements [`AsMut<[u8]>`][AsMut].
  ///
  /// # Examples
  ///
  /// ```
  /// # use philbin::easy::CiphertextMut;
  /// let mut raw_data: Vec<u8> = vec![1, 2, 3];
  /// let ciphertext_mut = CiphertextMut::new(&mut raw_data);
  /// ```
  pub fn new<T>(data: &'a mut T) -> Self
  where
    T: AsMut<[u8]> + ?Sized,
  {
    CiphertextMut(data.as_mut())
  }

  /// Returns the stored reference as `&mut [u8]`.
  pub fn as_bytes_mut(&mut self) -> &mut [u8] {
    self.0
  }

  /// Returns the stored reference as `&[u8]`.
  #[must_use]
  pub fn as_bytes(&self) -> &[u8] {
    self.0
  }
}

/// Stores a reference to associated data bytes.
///
/// This type exists to help prevent accidental parameter swaps in function
/// calls. It can be created from a [`&[u8]`][slice], a [`&mut [u8]`][slice] or
/// any other type that implements [`AsRef<[u8]>`][AsRef].
///
/// "Associated data" is the _public additional data_ that the sender will
/// provide along with the ciphertext to the receiver. This data is NOT
/// _encrypted_, but it is _authenticated_ along with the ciphertext during
/// decryption.
///
/// It's common for associated data to be empty when there's no need for it. See
/// [`AssociatedData::EMPTY`][crate::easy::AssociatedData::EMPTY]; the
/// [`Default`] impl returns
/// [`AssociatedData::EMPTY`][crate::easy::AssociatedData::EMPTY] as well.
///
/// The concept of "associated data" can be confusing without understanding
/// _why_ someone might want to _authenticate_ data without encrypting it.
///
/// Imagine we wish to encrypt the payload of an [IP] packet. We _cannot_
/// encrypt the _source_ and _destination_ fields of the packet because they
/// must remain public so that [routers] can route the packet. Yet we still want
/// to ensure that these fields are _not modified by an attacker_ between the
/// sender and receiver. Including the source and destination data as
/// _associated data_ during the encryption of the packet payload provides
/// the data _integrity_ we desire. When the receiver tries to decrypt the
/// packet payload, they will include the sender and receiver data as the
/// associated data. The decryption process will fail with an error if the
/// associated data was modified.
///
/// Note that [`From`] impls are intentionally omitted to prevent accidental
/// parameter swaps. The goal is to force the caller to spell out the name of
/// this type.
///
/// [IP]: https://en.wikipedia.org/wiki/Internet_Protocol
/// [routers]: https://en.wikipedia.org/wiki/Router_(computing)
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
pub struct AssociatedData<'a>(&'a [u8]);

impl<'a> AssociatedData<'a> {
  /// Creates a new `AssociatedData`.
  ///
  /// Accepts a reference to _any_ type that implements [`AsRef<[u8]>`][AsRef].
  ///
  /// # Examples
  ///
  /// ```
  /// # use philbin::easy::AssociatedData;
  /// use std::net::Ipv4Addr;
  /// let src = Ipv4Addr::new(192, 168, 0, 1);
  /// let dst = Ipv4Addr::new(10, 0, 0, 1);
  /// let src_and_dst = [src.octets(), dst.octets()];
  /// let associated_data1 = AssociatedData::new(src_and_dst.as_flattened());
  ///
  /// let raw_data: Vec<u8> = vec![1, 2, 3];
  /// let associated_data2 = AssociatedData::new(&raw_data);
  /// ```
  pub fn new<T>(data: &'a T) -> Self
  where
    T: AsRef<[u8]> + ?Sized,
  {
    AssociatedData(data.as_ref())
  }

  /// Returns the stored reference.
  #[must_use]
  pub fn as_bytes(&self) -> &[u8] {
    self.0
  }

  /// An `AssociatedData` storing a reference to an empty byte array.
  pub const EMPTY: AssociatedData<'static> = AssociatedData(b"");
}

impl<'a> Default for AssociatedData<'a> {
  fn default() -> Self {
    AssociatedData::EMPTY
  }
}