Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions chacha20/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ legacy = ["cipher"]
rng = ["dep:rand_core"]
xchacha = ["cipher"]

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
[lints.rust]
missing_copy_implementations = "warn"
missing_debug_implementations = "warn"
missing_docs = "warn"
trivial_casts = "warn"
trivial_numeric_casts = "warn"
unused_lifetimes = "warn"
unused_qualifications = "warn"

[lints.rust.unexpected_cfgs]
level = "warn"
Expand All @@ -51,4 +56,35 @@ check-cfg = [
]

[lints.clippy]
borrow_as_ptr = "warn"
cast_lossless = "warn"
cast_possible_truncation = "warn"
cast_possible_wrap = "warn"
cast_precision_loss = "warn"
cast_sign_loss = "warn"
checked_conversions = "warn"
from_iter_instead_of_collect = "warn"
implicit_saturating_sub = "warn"
manual_assert = "warn"
map_unwrap_or = "warn"
missing_errors_doc = "warn"
missing_panics_doc = "warn"
mod_module_files = "warn"
must_use_candidate = "warn"
needless_range_loop = "allow"
ptr_as_ptr = "warn"
redundant_closure_for_method_calls = "warn"
ref_as_ptr = "warn"
return_self_not_must_use = "warn"
semicolon_if_nothing_returned = "warn"
trivially_copy_pass_by_ref = "warn"
std_instead_of_alloc = "warn"
std_instead_of_core = "warn"
undocumented_unsafe_blocks = "warn"
unnecessary_safety_comment = "warn"
unwrap_in_result = "warn"
unwrap_used = "warn"

[package.metadata.docs.rs]
all-features = true
rustdoc-args = ["--cfg", "docsrs"]
39 changes: 24 additions & 15 deletions chacha20/src/backends/avx2.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
#![allow(unsafe_op_in_unsafe_fn)]
//! AVX2 backend.

#![allow(unsafe_op_in_unsafe_fn, reason = "needs triage")]
#![allow(clippy::cast_possible_truncation, reason = "needs triage")]
#![allow(clippy::cast_possible_wrap, reason = "needs triage")]
#![allow(clippy::cast_sign_loss, reason = "needs triage")]
#![allow(clippy::undocumented_unsafe_blocks, reason = "TODO")]

use crate::{Rounds, Variant};
use core::marker::PhantomData;

#[cfg(feature = "rng")]
use crate::ChaChaCore;

#[cfg(feature = "cipher")]
use crate::{chacha::Block, STATE_WORDS};
use crate::{STATE_WORDS, chacha::Block};

#[cfg(feature = "cipher")]
use cipher::{
consts::{U4, U64},
BlockSizeUser, ParBlocks, ParBlocksSizeUser, StreamCipherBackend, StreamCipherClosure,
consts::{U4, U64},
};

#[cfg(target_arch = "x86")]
Expand All @@ -34,7 +41,7 @@ where
F: StreamCipherClosure<BlockSize = U64>,
V: Variant,
{
let state_ptr = state.as_ptr() as *const __m128i;
let state_ptr = state.as_ptr().cast::<__m128i>();
let v = [
_mm256_broadcastsi128_si256(_mm_loadu_si128(state_ptr.add(0))),
_mm256_broadcastsi128_si256(_mm_loadu_si128(state_ptr.add(1))),
Expand All @@ -44,7 +51,7 @@ where
c = match size_of::<V::Counter>() {
4 => _mm256_add_epi32(c, _mm256_set_epi32(0, 0, 0, 1, 0, 0, 0, 0)),
8 => _mm256_add_epi64(c, _mm256_set_epi64x(0, 1, 0, 0)),
_ => unreachable!()
_ => unreachable!(),
};
let mut ctr = [c; N];
for i in 0..N {
Expand All @@ -65,9 +72,9 @@ where

state[12] = _mm256_extract_epi32(backend.ctr[0], 0) as u32;
match size_of::<V::Counter>() {
4 => {},
4 => {}
8 => state[13] = _mm256_extract_epi32(backend.ctr[0], 1) as u32,
_ => unreachable!()
_ => unreachable!(),
}
}

Expand All @@ -79,7 +86,7 @@ where
R: Rounds,
V: Variant,
{
let state_ptr = core.state.as_ptr() as *const __m128i;
let state_ptr = core.state.as_ptr().cast::<__m128i>();
let v = [
_mm256_broadcastsi128_si256(_mm_loadu_si128(state_ptr.add(0))),
_mm256_broadcastsi128_si256(_mm_loadu_si128(state_ptr.add(1))),
Expand Down Expand Up @@ -130,13 +137,13 @@ impl<R: Rounds, V: Variant> StreamCipherBackend for Backend<R, V> {
*c = match size_of::<V::Counter>() {
4 => _mm256_add_epi32(*c, _mm256_set_epi32(0, 0, 0, 1, 0, 0, 0, 1)),
8 => _mm256_add_epi64(*c, _mm256_set_epi64x(0, 1, 0, 1)),
_ => unreachable!()
_ => unreachable!(),
};
}

let res0: [__m128i; 8] = core::mem::transmute(res[0]);

let block_ptr = block.as_mut_ptr() as *mut __m128i;
let block_ptr = block.as_mut_ptr().cast::<__m128i>();
for i in 0..4 {
_mm_storeu_si128(block_ptr.add(i), res0[2 * i]);
}
Expand All @@ -152,12 +159,14 @@ impl<R: Rounds, V: Variant> StreamCipherBackend for Backend<R, V> {
for c in self.ctr.iter_mut() {
*c = match size_of::<V::Counter>() {
4 => _mm256_add_epi32(*c, _mm256_set_epi32(0, 0, 0, pb, 0, 0, 0, pb)),
8 => _mm256_add_epi64(*c, _mm256_set_epi64x(0, pb as i64, 0, pb as i64)),
_ => unreachable!()
8 => {
_mm256_add_epi64(*c, _mm256_set_epi64x(0, i64::from(pb), 0, i64::from(pb)))
}
_ => unreachable!(),
}
}

let mut block_ptr = blocks.as_mut_ptr() as *mut __m128i;
let mut block_ptr = blocks.as_mut_ptr().cast::<__m128i>();
for v in vs {
let t: [__m128i; 8] = core::mem::transmute(v);
for i in 0..4 {
Expand All @@ -179,10 +188,10 @@ impl<R: Rounds, V: Variant> Backend<R, V> {

let pb = PAR_BLOCKS as i32;
for c in self.ctr.iter_mut() {
*c = _mm256_add_epi64(*c, _mm256_set_epi64x(0, pb as i64, 0, pb as i64));
*c = _mm256_add_epi64(*c, _mm256_set_epi64x(0, i64::from(pb), 0, i64::from(pb)));
}

let mut block_ptr = blocks.as_mut_ptr() as *mut __m128i;
let mut block_ptr = blocks.as_mut_ptr().cast::<__m128i>();
for v in vs {
let t: [__m128i; 8] = core::mem::transmute(v);
for i in 0..4 {
Expand Down
14 changes: 10 additions & 4 deletions chacha20/src/backends/neon.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#![allow(unsafe_op_in_unsafe_fn)]
//! NEON-optimized implementation for aarch64 CPUs.
//!
//! Adapted from the Crypto++ `chacha_simd` implementation by Jack Lloyd and
//! Jeffrey Walton (public domain).

#![allow(unsafe_op_in_unsafe_fn, reason = "needs triage")]

use crate::{Rounds, STATE_WORDS, Variant};
use core::{arch::aarch64::*, marker::PhantomData};

Expand Down Expand Up @@ -77,7 +78,7 @@ where
match size_of::<V::Counter>() {
4 => state[12] = vgetq_lane_u32(backend.state[3], 0),
8 => vst1q_u64(
state.as_mut_ptr().offset(12) as *mut u64,
state.as_mut_ptr().offset(12).cast::<u64>(),
vreinterpretq_u64_u32(backend.state[3]),
),
_ => unreachable!(),
Expand All @@ -98,7 +99,7 @@ where
backend.write_par_ks_blocks(buffer);

vst1q_u64(
core.state.as_mut_ptr().offset(12) as *mut u64,
core.state.as_mut_ptr().offset(12).cast::<u64>(),
vreinterpretq_u64_u32(backend.state[3]),
);
}
Expand Down Expand Up @@ -127,13 +128,16 @@ impl<R: Rounds, V: Variant> StreamCipherBackend for Backend<R, V> {
let mut par = ParBlocks::<Self>::default();
self.gen_par_ks_blocks(&mut par);
*block = par[0];

// SAFETY: we have used conditional compilation to ensure NEON is available
unsafe {
self.state[3] = add_counter!(state3, vld1q_u32([1, 0, 0, 0].as_ptr()), V);
}
}

#[inline(always)]
fn gen_par_ks_blocks(&mut self, dest: &mut ParBlocks<Self>) {
// SAFETY: we have used conditional compilation to ensure NEON is available
unsafe {
let mut blocks = [
[self.state[0], self.state[1], self.state[2], self.state[3]],
Expand Down Expand Up @@ -176,6 +180,7 @@ impl<R: Rounds, V: Variant> StreamCipherBackend for Backend<R, V> {
}
// write blocks to dest
for state_row in 0..4 {
#[allow(clippy::cast_sign_loss, reason = "needs triage")]
vst1q_u8(
dest[block].as_mut_ptr().offset(state_row << 4),
vreinterpretq_u8_u32(blocks[block][state_row as usize]),
Expand Down Expand Up @@ -245,7 +250,7 @@ impl<R: Rounds, V: Variant> Backend<R, V> {
double_quarter_round(&mut blocks);
}

let mut dest_ptr = buffer.as_mut_ptr() as *mut u8;
let mut dest_ptr = buffer.as_mut_ptr().cast::<u8>();
for block in 0..4 {
// add state to block
for state_row in 0..3 {
Expand All @@ -261,6 +266,7 @@ impl<R: Rounds, V: Variant> Backend<R, V> {
}
// write blocks to buffer
for state_row in 0..4 {
#[allow(clippy::cast_sign_loss)]
vst1q_u8(
dest_ptr.offset(state_row << 4),
vreinterpretq_u8_u32(blocks[block][state_row as usize]),
Expand Down
9 changes: 5 additions & 4 deletions chacha20/src/backends/soft.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Portable implementation which does not rely on architecture-specific
//! intrinsics.
//! Portable implementation which does not rely on architecture-specific intrinsics.

#![allow(clippy::cast_possible_truncation)]

use crate::{ChaChaCore, Rounds, STATE_WORDS, Variant, quarter_round};

Expand Down Expand Up @@ -35,7 +36,7 @@ impl<R: Rounds, V: Variant> StreamCipherBackend for Backend<'_, R, V> {
ctr = ctr.wrapping_add(1);
self.0.state[12] = ctr as u32;
if size_of::<V::Counter>() == 8 {
self.0.state[13] = (ctr >> 32) as u32
self.0.state[13] = (ctr >> 32) as u32;
}

for (chunk, val) in block.chunks_exact_mut(4).zip(res.iter()) {
Expand All @@ -50,7 +51,7 @@ impl<R: Rounds, V: Variant> Backend<'_, R, V> {
pub(crate) fn gen_ks_blocks(&mut self, buffer: &mut [u32; 64]) {
for block in 0..4 {
let res = run_rounds::<R>(&self.0.state);
let mut ctr = u64::from(self.0.state[13]) << 32 | u64::from(self.0.state[12]);
let mut ctr = (u64::from(self.0.state[13]) << 32) | u64::from(self.0.state[12]);
ctr = ctr.wrapping_add(1);
self.0.state[12] = ctr as u32;
self.0.state[13] = (ctr >> 32) as u32;
Expand Down
35 changes: 21 additions & 14 deletions chacha20/src/backends/sse2.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
#![allow(unsafe_op_in_unsafe_fn)]
//! SSE2 backend.

#![allow(unsafe_op_in_unsafe_fn, reason = "needs triage")]
#![allow(clippy::cast_possible_truncation, reason = "needs triage")]
#![allow(clippy::cast_possible_wrap, reason = "needs triage")]
#![allow(clippy::cast_sign_loss, reason = "needs triage")]
#![allow(clippy::undocumented_unsafe_blocks, reason = "TODO")]

use crate::{Rounds, Variant};

#[cfg(feature = "rng")]
use crate::{ChaChaCore};
use crate::ChaChaCore;

#[cfg(feature = "cipher")]
use crate::{chacha::Block, STATE_WORDS};
use crate::{STATE_WORDS, chacha::Block};
#[cfg(feature = "cipher")]
use cipher::{
consts::{U4, U64},
BlockSizeUser, ParBlocksSizeUser, StreamCipherBackend, StreamCipherClosure,
consts::{U4, U64},
};
use core::marker::PhantomData;

Expand All @@ -29,7 +36,7 @@ where
F: StreamCipherClosure<BlockSize = U64>,
V: Variant,
{
let state_ptr = state.as_ptr() as *const __m128i;
let state_ptr = state.as_ptr().cast::<__m128i>();
let mut backend = Backend::<R, V> {
v: [
_mm_loadu_si128(state_ptr.add(0)),
Expand All @@ -44,7 +51,7 @@ where

state[12] = _mm_cvtsi128_si32(backend.v[3]) as u32;
if size_of::<V::Counter>() == 8 {
state[13] = _mm_extract_epi32(backend.v[3], 1) as u32
state[13] = _mm_extract_epi32(backend.v[3], 1) as u32;
}
}

Expand Down Expand Up @@ -72,10 +79,10 @@ impl<R: Rounds, V: Variant> StreamCipherBackend for Backend<R, V> {
self.v[3] = match size_of::<V::Counter>() {
4 => _mm_add_epi32(self.v[3], _mm_set_epi32(0, 0, 0, 1)),
8 => _mm_add_epi64(self.v[3], _mm_set_epi64x(0, 1)),
_ => unreachable!()
_ => unreachable!(),
};

let block_ptr = block.as_mut_ptr() as *mut __m128i;
let block_ptr = block.as_mut_ptr().cast::<__m128i>();
for i in 0..4 {
_mm_storeu_si128(block_ptr.add(i), res[0][i]);
}
Expand All @@ -88,10 +95,10 @@ impl<R: Rounds, V: Variant> StreamCipherBackend for Backend<R, V> {
self.v[3] = match size_of::<V::Counter>() {
4 => _mm_add_epi32(self.v[3], _mm_set_epi32(0, 0, 0, PAR_BLOCKS as i32)),
8 => _mm_add_epi64(self.v[3], _mm_set_epi64x(0, PAR_BLOCKS as i64)),
_ => unreachable!()
_ => unreachable!(),
};

let blocks_ptr = blocks.as_mut_ptr() as *mut __m128i;
let blocks_ptr = blocks.as_mut_ptr().cast::<__m128i>();
for block in 0..PAR_BLOCKS {
for i in 0..4 {
_mm_storeu_si128(blocks_ptr.add(i + block * PAR_BLOCKS), res[block][i]);
Expand All @@ -109,7 +116,7 @@ where
R: Rounds,
V: Variant,
{
let state_ptr = core.state.as_ptr() as *const __m128i;
let state_ptr = core.state.as_ptr().cast::<__m128i>();
let mut backend = Backend::<R, V> {
v: [
_mm_loadu_si128(state_ptr.add(0)),
Expand All @@ -135,7 +142,7 @@ impl<R: Rounds, V: Variant> Backend<R, V> {
let res = rounds::<R, V>(&self.v);
self.v[3] = _mm_add_epi64(self.v[3], _mm_set_epi64x(0, PAR_BLOCKS as i64));

let blocks_ptr = block.as_mut_ptr() as *mut __m128i;
let blocks_ptr = block.as_mut_ptr().cast::<__m128i>();
for block in 0..PAR_BLOCKS {
for i in 0..4 {
_mm_storeu_si128(blocks_ptr.add(i + block * PAR_BLOCKS), res[block][i]);
Expand All @@ -153,7 +160,7 @@ unsafe fn rounds<R: Rounds, V: Variant>(v: &[__m128i; 4]) -> [[__m128i; 4]; PAR_
res[block][3] = match size_of::<V::Counter>() {
4 => _mm_add_epi32(res[block][3], _mm_set_epi32(0, 0, 0, block as i32)),
8 => _mm_add_epi64(res[block][3], _mm_set_epi64x(0, block as i64)),
_ => unreachable!()
_ => unreachable!(),
}
}

Expand All @@ -168,7 +175,7 @@ unsafe fn rounds<R: Rounds, V: Variant>(v: &[__m128i; 4]) -> [[__m128i; 4]; PAR_
let ctr = match size_of::<V::Counter>() {
4 => _mm_add_epi32(v[3], _mm_set_epi32(0, 0, 0, block as i32)),
8 => _mm_add_epi64(v[3], _mm_set_epi64x(0, block as i64)),
_ => unreachable!()
_ => unreachable!(),
};
res[block][3] = _mm_add_epi32(res[block][3], ctr);
}
Expand Down
Loading