use crate::{seeds, Aes128Ctr128, Aes128Ctr64, Aes256Ctr128, Aes256Ctr64, Jump, Random};
#[cfg(feature = "getrandom")]
use crate::secure_bytes;
macro_rules! safely_call {
($what:expr) => {
#[cfg(not(any(
not(any(
all(
any(target_arch = "x86_64", target_arch = "x86"),
target_feature = "sse2",
target_feature = "aes",
),
all(target_arch = "riscv64", feature = "experimental_riscv"),
all(
target_arch = "aarch64",
target_feature = "neon",
target_feature = "aes",
),
)),
feature = "force_runtime_detection",
feature = "force_software"
)))]
unsafe {
$what
}
#[cfg(any(
not(any(
all(
any(target_arch = "x86_64", target_arch = "x86"),
target_feature = "sse2",
target_feature = "aes",
),
all(target_arch = "riscv64", feature = "experimental_riscv"),
all(
target_arch = "aarch64",
target_feature = "neon",
target_feature = "aes",
),
)),
feature = "force_runtime_detection",
feature = "force_software"
))]
$what
};
}
impl core::fmt::Debug for Aes128Ctr64 {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
fmt.debug_struct("Aes128Ctr64").finish_non_exhaustive()
}
}
impl core::fmt::Debug for Aes128Ctr128 {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
fmt.debug_struct("Aes128Ctr128").finish_non_exhaustive()
}
}
impl core::fmt::Debug for Aes256Ctr64 {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
fmt.debug_struct("Aes256Ctr64").finish_non_exhaustive()
}
}
impl core::fmt::Debug for Aes256Ctr128 {
fn fmt(&self, fmt: &mut core::fmt::Formatter) -> core::fmt::Result {
fmt.debug_struct("Aes256Ctr128").finish_non_exhaustive()
}
}
impl Random for Aes128Ctr64 {
type Seed = seeds::Aes128Ctr64Seed;
type Counter = u64;
fn from_seed(seed: Self::Seed) -> Self {
let mut seed_bytes = [0u8; 16];
let mut nonce_bytes = [0u8; 8];
let mut counter_bytes = [0u8; 8];
seed_bytes.copy_from_slice(&seed.as_ref()[..16]);
nonce_bytes.copy_from_slice(&seed.as_ref()[16..24]);
counter_bytes.copy_from_slice(&seed.as_ref()[24..32]);
safely_call! { Aes128Ctr64::from_seed_impl(seed_bytes, nonce_bytes, counter_bytes) }
}
fn seed(&self, seed: Self::Seed) {
let mut seed_bytes = [0u8; 16];
let mut nonce_bytes = [0u8; 8];
let mut counter_bytes = [0u8; 8];
seed_bytes.copy_from_slice(&seed.as_ref()[..16]);
nonce_bytes.copy_from_slice(&seed.as_ref()[16..24]);
counter_bytes.copy_from_slice(&seed.as_ref()[24..32]);
safely_call! { self.seed_impl(seed_bytes, nonce_bytes, counter_bytes) }
}
#[cfg(feature = "getrandom")]
fn from_entropy() -> Self {
let bytes: [u8; 32] = secure_bytes();
Random::from_seed(bytes.into())
}
#[cfg(feature = "getrandom")]
fn seed_from_entropy(&self) {
safely_call! { self.seed_impl(secure_bytes(), secure_bytes(), secure_bytes()) }
}
fn is_hardware_accelerated(&self) -> bool {
self.is_hardware_accelerated_impl()
}
fn counter(&self) -> Self::Counter {
self.counter_impl()
}
#[inline(always)]
fn next(&self) -> u128 {
safely_call! { Aes128Ctr64::next_impl(self) }
}
}
impl Random for Aes128Ctr128 {
type Seed = seeds::Aes128Ctr128Seed;
type Counter = u128;
fn from_seed(seed: Self::Seed) -> Self {
let mut seed_bytes = [0u8; 16];
let mut counter_bytes = [0u8; 16];
seed_bytes.copy_from_slice(&seed.as_ref()[..16]);
counter_bytes.copy_from_slice(&seed.as_ref()[16..32]);
safely_call! { Aes128Ctr128::from_seed_impl(seed_bytes, counter_bytes) }
}
fn seed(&self, seed: Self::Seed) {
let mut seed_bytes = [0u8; 16];
let mut counter_bytes = [0u8; 16];
seed_bytes.copy_from_slice(&seed.as_ref()[..16]);
counter_bytes.copy_from_slice(&seed.as_ref()[16..32]);
safely_call! { self.seed_impl(seed_bytes, counter_bytes) }
}
#[cfg(feature = "getrandom")]
fn from_entropy() -> Self {
let bytes: [u8; 32] = secure_bytes();
Random::from_seed(bytes.into())
}
#[cfg(feature = "getrandom")]
fn seed_from_entropy(&self) {
safely_call! { self.seed_impl(secure_bytes(), secure_bytes()) }
}
fn is_hardware_accelerated(&self) -> bool {
self.is_hardware_accelerated_impl()
}
fn counter(&self) -> Self::Counter {
self.counter_impl()
}
#[inline(always)]
fn next(&self) -> u128 {
safely_call! { Aes128Ctr128::next_impl(self) }
}
}
impl Random for Aes256Ctr64 {
type Seed = seeds::Aes256Ctr64Seed;
type Counter = u64;
fn from_seed(seed: Self::Seed) -> Self {
let mut seed_bytes = [0u8; 32];
let mut nonce_bytes = [0u8; 8];
let mut counter_bytes = [0u8; 8];
seed_bytes.copy_from_slice(&seed.as_ref()[..32]);
nonce_bytes.copy_from_slice(&seed.as_ref()[32..40]);
counter_bytes.copy_from_slice(&seed.as_ref()[40..48]);
safely_call! { Aes256Ctr64::from_seed_impl(seed_bytes, nonce_bytes, counter_bytes) }
}
fn seed(&self, seed: Self::Seed) {
let mut seed_bytes = [0u8; 32];
let mut nonce_bytes = [0u8; 8];
let mut counter_bytes = [0u8; 8];
seed_bytes.copy_from_slice(&seed.as_ref()[..32]);
nonce_bytes.copy_from_slice(&seed.as_ref()[32..40]);
counter_bytes.copy_from_slice(&seed.as_ref()[40..48]);
safely_call! { self.seed_impl(seed_bytes, nonce_bytes, counter_bytes) }
}
#[cfg(feature = "getrandom")]
fn from_entropy() -> Self {
let bytes: [u8; 48] = secure_bytes();
Random::from_seed(bytes.into())
}
#[cfg(feature = "getrandom")]
fn seed_from_entropy(&self) {
safely_call! { self.seed_impl(secure_bytes(), secure_bytes(), secure_bytes()) }
}
fn is_hardware_accelerated(&self) -> bool {
self.is_hardware_accelerated_impl()
}
fn counter(&self) -> Self::Counter {
self.counter_impl()
}
#[inline(always)]
fn next(&self) -> u128 {
safely_call! { Aes256Ctr64::next_impl(self) }
}
}
impl Random for Aes256Ctr128 {
type Seed = seeds::Aes256Ctr128Seed;
type Counter = u128;
fn from_seed(seed: Self::Seed) -> Self {
let mut seed_bytes = [0u8; 32];
let mut counter_bytes = [0u8; 16];
seed_bytes.copy_from_slice(&seed.as_ref()[..32]);
counter_bytes.copy_from_slice(&seed.as_ref()[32..48]);
safely_call! { Aes256Ctr128::from_seed_impl(seed_bytes, counter_bytes) }
}
fn seed(&self, seed: Self::Seed) {
let mut seed_bytes = [0u8; 32];
let mut counter_bytes = [0u8; 16];
seed_bytes.copy_from_slice(&seed.as_ref()[..32]);
counter_bytes.copy_from_slice(&seed.as_ref()[32..48]);
safely_call! { self.seed_impl(seed_bytes, counter_bytes) }
}
#[cfg(feature = "getrandom")]
fn from_entropy() -> Self {
let bytes: [u8; 48] = secure_bytes();
Random::from_seed(bytes.into())
}
#[cfg(feature = "getrandom")]
fn seed_from_entropy(&self) {
safely_call! { self.seed_impl(secure_bytes(), secure_bytes()) }
}
fn is_hardware_accelerated(&self) -> bool {
self.is_hardware_accelerated_impl()
}
fn counter(&self) -> Self::Counter {
self.counter_impl()
}
#[inline(always)]
fn next(&self) -> u128 {
safely_call! { Aes256Ctr128::next_impl(self) }
}
}
impl Jump for Aes128Ctr128 {
fn jump(&self) -> Self {
self.jump_impl()
}
fn long_jump(&self) -> Self {
self.long_jump_impl()
}
}
impl Jump for Aes256Ctr128 {
fn jump(&self) -> Self {
self.jump_impl()
}
fn long_jump(&self) -> Self {
self.long_jump_impl()
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::RngCore for Aes128Ctr64 {
#[inline(always)]
fn next_u32(&mut self) -> u32 {
safely_call! { self.next_impl() as u32 }
}
#[inline(always)]
fn next_u64(&mut self) -> u64 {
safely_call! { self.next_impl() as u64 }
}
#[inline(always)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
Random::fill_bytes(self, dest);
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::RngCore for Aes128Ctr128 {
#[inline(always)]
fn next_u32(&mut self) -> u32 {
safely_call! { self.next_impl() as u32 }
}
#[inline(always)]
fn next_u64(&mut self) -> u64 {
safely_call! { self.next_impl() as u64 }
}
#[inline(always)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
Random::fill_bytes(self, dest);
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::RngCore for Aes256Ctr64 {
#[inline(always)]
fn next_u32(&mut self) -> u32 {
safely_call! { self.next_impl() as u32 }
}
#[inline(always)]
fn next_u64(&mut self) -> u64 {
safely_call! { self.next_impl() as u64 }
}
#[inline(always)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
Random::fill_bytes(self, dest);
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::RngCore for Aes256Ctr128 {
#[inline(always)]
fn next_u32(&mut self) -> u32 {
safely_call! { self.next_impl() as u32 }
}
#[inline(always)]
fn next_u64(&mut self) -> u64 {
safely_call! { self.next_impl() as u64 }
}
#[inline(always)]
fn fill_bytes(&mut self, dest: &mut [u8]) {
Random::fill_bytes(self, dest);
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::SeedableRng for Aes128Ctr64 {
type Seed = seeds::Aes128Ctr64Seed;
fn from_seed(seed: Self::Seed) -> Self {
Random::from_seed(seed)
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::SeedableRng for Aes128Ctr128 {
type Seed = seeds::Aes128Ctr128Seed;
fn from_seed(seed: Self::Seed) -> Self {
Random::from_seed(seed)
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::SeedableRng for Aes256Ctr64 {
type Seed = seeds::Aes256Ctr64Seed;
fn from_seed(seed: Self::Seed) -> Self {
Random::from_seed(seed)
}
}
#[cfg(feature = "rand_core")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand_core")))]
impl rand_core::SeedableRng for Aes256Ctr128 {
type Seed = seeds::Aes256Ctr128Seed;
fn from_seed(seed: Self::Seed) -> Self {
Random::from_seed(seed)
}
}