diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/block.rs | 5 | ||||
| -rw-r--r-- | src/lib.rs | 28 | 
2 files changed, 25 insertions, 8 deletions
diff --git a/src/block.rs b/src/block.rs index 8327286..e1140e7 100644 --- a/src/block.rs +++ b/src/block.rs @@ -1,4 +1,9 @@ +#[cfg(feature = "std")]  use std::ops::{BitAnd, BitOr, BitXor, Index, IndexMut, Mul, Shl, Shr}; +#[cfg(not(feature = "std"))] +use core::ops::{BitAnd, BitOr, BitXor, Index, IndexMut, Mul, Shl, Shr}; + +  #[cfg(feature = "simd")]  use std::simd::prelude::*; @@ -1,4 +1,5 @@  #![cfg_attr(feature = "simd", feature(portable_simd))] +#![cfg_attr(not(feature = "std"), no_std)]  //! AEZ *\[sic!\]* v5 encryption implemented in Rust.  //!  //! # ☣️ Cryptographic hazmat ☣️ @@ -67,6 +68,8 @@  //!  //! ```  //! # use zears::*; +//! # #[cfg(feature = "std")] +//! # fn main() {  //! let aez = Aez::new(b"my secret key!");  //! let cipher = aez.encrypt(b"nonce", &[b"associated data"], 16, b"message");  //! let plaintext = aez.decrypt(b"nonce", &[b"associated data"], 16, &cipher); @@ -82,6 +85,9 @@  //! let cipher = aez.encrypt(b"nonce", &[b"foo"], 16, b"message");  //! let plaintext = aez.decrypt(b"nonce", &[b"bar"], 16, &cipher);  //! assert!(plaintext.is_none()); +//! # } +//! # #[cfg(not(feature = "std"))] +//! # fn main() {}  //! ```  //!  //! # Feature flags & compilation hints @@ -102,6 +108,9 @@  //! | +simd, target-cpu=native | 3.3272 GiB/s | +592.01% |  //! | `aez` crate              | 4.8996 GiB/s |          | +#[cfg(not(feature = "std"))] +use core::iter; +#[cfg(feature = "std")]  use std::iter;  use constant_time_eq::constant_time_eq; @@ -188,6 +197,7 @@ impl Aez {      ///   provides a "hash" that verifies the integrity of the associated data.      ///      /// Returns the ciphertext, which will be of length `data.len() + tau`. +    #[cfg(feature = "std")]      pub fn encrypt(          &self,          nonce: &[u8], @@ -208,6 +218,7 @@ impl Aez {      /// If `tau == 0`, the vector will not be expanded.      ///      /// The parameters are the same as for [`Aez::encrypt`]. +    #[cfg(feature = "std")]      pub fn encrypt_vec(          &self,          nonce: &[u8], @@ -270,6 +281,7 @@ impl Aez {      ///      /// Returns the decrypted content. If the integrity check fails, returns `None` instead. The      /// returned vector has length `data.len() - tau`. +    #[cfg(feature = "std")]      pub fn decrypt(          &self,          nonce: &[u8], @@ -380,14 +392,14 @@ fn decrypt<'a, 't, A: AsRef<[u8]> + 't, T: IntoIterator<Item = &'t A>>(  }  fn is_zeroes(data: &[u8]) -> bool { -    let comparator = if data.len() <= ZEROES.len() { -        &ZEROES[..data.len()] -    } else { -        // We should find a way to do this without allocating a separate buffer full of zeroes, but -        // I don't want to hand-roll my constant-time-is-zeroes yet. -        &vec![0; data.len()] -    }; -    constant_time_eq(data, comparator) +    const PATTERN: u32 = 0xDEADBABE; +    let mut accum = 0u32; +    for chunk in data.chunks(ZEROES.len()) { +        // this is accum = accum | !(chunk == 0...0) +        // basically, accum will say if one chunk was not zeroes +        accum |= (1 - (constant_time_eq(chunk, &ZEROES[..chunk.len()]) as u32)) * PATTERN; +    } +    accum == 0  }  fn encipher<A: AsRef<[u8]>, T: IntoIterator<Item = A>>(aez: &Aez, tweaks: T, message: &mut [u8]) {  | 
