diff --git a/.clippy.toml b/.clippy.toml new file mode 100644 index 0000000..2e06d15 --- /dev/null +++ b/.clippy.toml @@ -0,0 +1,2 @@ +allow-unwrap-in-consts = true +allow-unwrap-in-tests = true diff --git a/.github/workflows/workspace.yml b/.github/workflows/workspace.yml index 1fdf855..862ce4f 100644 --- a/.github/workflows/workspace.yml +++ b/.github/workflows/workspace.yml @@ -17,7 +17,7 @@ jobs: - uses: RustCrypto/actions/cargo-cache@master - uses: dtolnay/rust-toolchain@master with: - toolchain: 1.85.0 + toolchain: 1.95.0 components: clippy - run: cargo clippy --all -- -D warnings diff --git a/Cargo.toml b/Cargo.toml index deb31c4..e9bbb42 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,42 @@ members = [ [profile.dev] opt-level = 2 + +[workspace.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" + +[workspace.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" diff --git a/ascon-xof128/Cargo.toml b/ascon-xof128/Cargo.toml index 5adf5bd..9c3616f 100644 --- a/ascon-xof128/Cargo.toml +++ b/ascon-xof128/Cargo.toml @@ -26,5 +26,8 @@ default = ["alloc"] alloc = ["digest/alloc"] zeroize = ["digest/zeroize", "sponge-cursor/zeroize"] +[lints] +workspace = true + [package.metadata.docs.rs] all-features = true diff --git a/ascon-xof128/benches/mod.rs b/ascon-xof128/benches/mod.rs index 9ca986f..71d7764 100644 --- a/ascon-xof128/benches/mod.rs +++ b/ascon-xof128/benches/mod.rs @@ -1,3 +1,4 @@ +//! Basic benchmarks #![feature(test)] extern crate test; diff --git a/ascon-xof128/src/consts.rs b/ascon-xof128/src/consts.rs index 8ce4f6a..65e5031 100644 --- a/ascon-xof128/src/consts.rs +++ b/ascon-xof128/src/consts.rs @@ -6,7 +6,7 @@ const CXOF_IV: u64 = 0x0000_0800_00CC_0004; pub(crate) const XOF_INIT_STATE: State = init_state(XOF_IV); pub(crate) const CXOF_INIT_STATE: State = init_state(CXOF_IV); -const fn init_state(iv: u64) -> ascon::State { +const fn init_state(iv: u64) -> State { let mut state = [iv, 0, 0, 0, 0]; ascon::permute12(&mut state); state diff --git a/ascon-xof128/src/cxof.rs b/ascon-xof128/src/cxof.rs index 03384af..ec38d17 100644 --- a/ascon-xof128/src/cxof.rs +++ b/ascon-xof128/src/cxof.rs @@ -30,7 +30,9 @@ pub struct AsconCxof128 { impl TryCustomizedInit for AsconCxof128 { type Error = InvalidCustomizationError; + #[inline] + #[allow(clippy::unwrap_in_result)] fn try_new_customized(customization: &[u8]) -> Result { if customization.len() > MAX_CUSTOMIZATION_LEN { return Err(InvalidCustomizationError); @@ -97,7 +99,7 @@ impl ExtendableOutput for AsconCxof128 { impl AlgorithmName for AsconCxof128 { #[inline] - fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("Ascon-CXOF128") } } diff --git a/ascon-xof128/src/lib.rs b/ascon-xof128/src/lib.rs index 05124e9..640db83 100644 --- a/ascon-xof128/src/lib.rs +++ b/ascon-xof128/src/lib.rs @@ -5,7 +5,6 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" )] #![cfg_attr(docsrs, feature(doc_cfg))] -#![warn(missing_docs, unreachable_pub)] #![forbid(unsafe_code)] pub use digest::{self, ExtendableOutput, TryCustomizedInit, Update, XofReader}; diff --git a/ascon-xof128/src/xof.rs b/ascon-xof128/src/xof.rs index d84680f..fcd7193 100644 --- a/ascon-xof128/src/xof.rs +++ b/ascon-xof128/src/xof.rs @@ -82,7 +82,7 @@ impl Reset for AsconXof128 { impl AlgorithmName for AsconXof128 { #[inline] - fn write_alg_name(f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str("Ascon-XOF128") } } diff --git a/ascon-xof128/tests/mod.rs b/ascon-xof128/tests/mod.rs index 6bd494a..c16bf27 100644 --- a/ascon-xof128/tests/mod.rs +++ b/ascon-xof128/tests/mod.rs @@ -1,3 +1,4 @@ +//! Basic tests use ascon_xof128::{AsconCxof128, AsconXof128}; use core::fmt::Debug; use digest::{ @@ -8,11 +9,11 @@ use digest::{ use hex_literal::hex; // Test vectors from: -// https://github.com/ascon/ascon-c/blob/main/crypto_hash/asconxof128/LWC_XOF_KAT_128_512.txt +// digest::new_test!(ascon_xof128_kat, AsconXof128, xof_reset_test); /// Test vectors from: -/// https://github.com/ascon/ascon-c/blob/main/crypto_cxof/asconcxof128/LWC_CXOF_KAT_128_512.txt +/// #[test] fn ascon_cxof128_kat() { digest::dev::blobby::parse_into_structs!( diff --git a/bash-prg-hash/Cargo.toml b/bash-prg-hash/Cargo.toml index a7602f3..dd2b79f 100644 --- a/bash-prg-hash/Cargo.toml +++ b/bash-prg-hash/Cargo.toml @@ -27,5 +27,8 @@ alloc = ["digest/alloc"] oid = ["digest/oid"] zeroize = ["digest/zeroize", "sponge-cursor/zeroize"] +[lints] +workspace = true + [package.metadata.docs.rs] all-features = true diff --git a/bash-prg-hash/benches/mod.rs b/bash-prg-hash/benches/mod.rs index 4659e41..f2ba80f 100644 --- a/bash-prg-hash/benches/mod.rs +++ b/bash-prg-hash/benches/mod.rs @@ -1,3 +1,4 @@ +//! Basic benchmarks #![feature(test)] extern crate test; diff --git a/bash-prg-hash/src/lib.rs b/bash-prg-hash/src/lib.rs index 0f81bd7..f6b5a88 100644 --- a/bash-prg-hash/src/lib.rs +++ b/bash-prg-hash/src/lib.rs @@ -5,7 +5,6 @@ html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/6ee8e381/logo.svg" )] #![cfg_attr(docsrs, feature(doc_cfg))] -#![warn(missing_docs, rust_2018_idioms)] #![forbid(unsafe_code)] pub use digest::{self, Digest}; @@ -63,6 +62,7 @@ impl TryCustomizedInit for BashPrgHash type Error = InvalidHeaderError; #[inline] + #[allow(clippy::unwrap_in_result)] fn try_new_customized(header: &[u8]) -> Result { const { assert!( @@ -71,7 +71,7 @@ impl TryCustomizedInit for BashPrgHash (160, 1) | (128, 2) | (144, 1) | (96, 2) | (128, 1) | (64, 2) ), "invalid combination of RATE and CAPACITY" - ) + ); } const MAX_HEADER_LEN: usize = 60; @@ -212,6 +212,14 @@ impl XofReader for BashPrgHashReader fmt::Debug for BashPrgHashReader { + #[inline] + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let level = 8 * (192 - RATE) / (2 * CAPACITY); + write!(f, "BashPrgHashReader{level}{CAPACITY} {{ ... }}") + } +} + impl Drop for BashPrgHashReader { #[inline] fn drop(&mut self) { @@ -231,7 +239,7 @@ impl digest::zeroize::ZeroizeOnDrop } /// Invalid `bash-prg-hash` header error. -#[derive(Debug)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct InvalidHeaderError; impl fmt::Display for InvalidHeaderError { diff --git a/bash-prg-hash/tests/mod.rs b/bash-prg-hash/tests/mod.rs index 5655d56..cc1f46c 100644 --- a/bash-prg-hash/tests/mod.rs +++ b/bash-prg-hash/tests/mod.rs @@ -1,10 +1,11 @@ +//! Basic tests use bash_prg_hash::{ BashPrgHash1281, BashPrgHash1282, BashPrgHash1921, BashPrgHash1922, BashPrgHash2561, BashPrgHash2562, }; +use core::fmt::Debug; use digest::{ExtendableOutput, TryCustomizedInit, Update}; use hex_literal::hex; -use std::fmt::Debug; #[derive(Debug, Clone, Copy)] struct TestVector { diff --git a/cshake/Cargo.toml b/cshake/Cargo.toml index 7333d0e..44fb770 100644 --- a/cshake/Cargo.toml +++ b/cshake/Cargo.toml @@ -26,5 +26,8 @@ default = ["alloc"] alloc = ["digest/alloc"] zeroize = ["digest/zeroize", "sponge-cursor/zeroize"] +[lints] +workspace = true + [package.metadata.docs.rs] all-features = true diff --git a/cshake/benches/mod.rs b/cshake/benches/mod.rs index f44d613..634751f 100644 --- a/cshake/benches/mod.rs +++ b/cshake/benches/mod.rs @@ -1,3 +1,4 @@ +//! Basic benchmarks #![feature(test)] extern crate test; diff --git a/cshake/src/lib.rs b/cshake/src/lib.rs index 8568fc0..3f502d0 100644 --- a/cshake/src/lib.rs +++ b/cshake/src/lib.rs @@ -6,8 +6,6 @@ )] #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] -#![warn(missing_docs, missing_debug_implementations)] -#![warn(unreachable_pub)] pub use digest; @@ -56,6 +54,8 @@ impl CShake { /// /// Note that the function name is intended for use by NIST and should only be set to /// values defined by NIST. You probably don't need to use this function. + #[must_use] + #[allow(clippy::missing_panics_doc, reason = "the method is panic-free")] pub fn new_with_function_name(function_name: &[u8], customization: &[u8]) -> Self { const { assert!(RATE == 168 || RATE == 136, "unsupported rate"); @@ -77,7 +77,7 @@ impl CShake { fn left_encode(val: u64, b: &mut [u8; 9]) -> &[u8] { b[1..].copy_from_slice(&val.to_be_bytes()); let i = b[1..8].iter().take_while(|&&a| a == 0).count(); - b[i] = (8 - i) as u8; + b[i] = u8::try_from(8 - i).expect("the result always fits into u8"); &b[i..] } diff --git a/cshake/tests/cshake.rs b/cshake/tests/cshake.rs index d37b5ca..2b22430 100644 --- a/cshake/tests/cshake.rs +++ b/cshake/tests/cshake.rs @@ -1,10 +1,11 @@ +//! Basic tests use digest::{CustomizedInit, ExtendableOutput}; #[derive(Debug, Clone, Copy)] -pub struct TestVector { - pub customization: &'static [u8], - pub input: &'static [u8], - pub output: &'static [u8], +struct TestVector { + customization: &'static [u8], + input: &'static [u8], + output: &'static [u8], } pub(crate) fn cshake_test( diff --git a/k12/Cargo.toml b/k12/Cargo.toml index d389e87..7a3501b 100644 --- a/k12/Cargo.toml +++ b/k12/Cargo.toml @@ -26,5 +26,8 @@ default = ["alloc"] alloc = ["digest/alloc"] zeroize = ["digest/zeroize", "sponge-cursor/zeroize"] +[lints] +workspace = true + [package.metadata.docs.rs] all-features = true diff --git a/k12/benches/kt256.rs b/k12/benches/kt256.rs deleted file mode 100644 index 6b3ae5f..0000000 --- a/k12/benches/kt256.rs +++ /dev/null @@ -1,14 +0,0 @@ -#![feature(test)] -extern crate test; - -use test::Bencher; - -digest::bench_update!( - k12::Kt256::default(); - kt256_1_10 10; - kt256_2_100 100; - kt256_3_1k 1000; - kt256_4_10k 10_000; - kt256_5_100k 100_000; - kt256_6_1m 1_000_000; -); diff --git a/k12/benches/kt128.rs b/k12/benches/mod.rs similarity index 53% rename from k12/benches/kt128.rs rename to k12/benches/mod.rs index a8bc1e4..dc11519 100644 --- a/k12/benches/kt128.rs +++ b/k12/benches/mod.rs @@ -1,3 +1,4 @@ +//! Basic benchmarks #![feature(test)] extern crate test; @@ -12,3 +13,13 @@ digest::bench_update!( kt128_5_100k 100_000; kt128_6_1m 1_000_000; ); + +digest::bench_update!( + k12::Kt256::default(); + kt256_1_10 10; + kt256_2_100 100; + kt256_3_1k 1000; + kt256_4_10k 10_000; + kt256_5_100k 100_000; + kt256_6_1m 1_000_000; +); diff --git a/k12/src/custom/borrow.rs b/k12/src/custom/borrow.rs index 9ca4d69..38141ec 100644 --- a/k12/src/custom/borrow.rs +++ b/k12/src/custom/borrow.rs @@ -20,6 +20,7 @@ impl<'a, const RATE: usize> CustomRefKt<'a, RATE> { /// Note that this is an inherent method and `CustomRefKt` does not implement /// the [`CustomizedInit`][digest::CustomizedInit] trait. #[inline] + #[must_use] pub fn new_customized(customization: &'a [u8]) -> Self { Self { customization, diff --git a/k12/src/lib.rs b/k12/src/lib.rs index 9d396c0..8926add 100644 --- a/k12/src/lib.rs +++ b/k12/src/lib.rs @@ -6,7 +6,6 @@ )] #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] -#![warn(missing_docs, unreachable_pub)] pub use digest::{self, ExtendableOutput, Update, XofReader}; diff --git a/k12/src/node_turbo_shake.rs b/k12/src/node_turbo_shake.rs index 93653aa..c020e51 100644 --- a/k12/src/node_turbo_shake.rs +++ b/k12/src/node_turbo_shake.rs @@ -125,6 +125,7 @@ mod tests { const KT128_CVS_LEN: usize = KT128_CV_LEN * CHUNKS; const KT256_CVS_LEN: usize = KT256_CV_LEN * CHUNKS; + #[allow(clippy::cast_possible_truncation)] const DATA: &[u8] = &{ let mut buf = [0u8; CHUNKS * CHUNK_SIZE]; let mut i = 0; diff --git a/k12/src/utils.rs b/k12/src/utils.rs index d3ba997..cfdf3ba 100644 --- a/k12/src/utils.rs +++ b/k12/src/utils.rs @@ -5,7 +5,7 @@ pub(crate) fn xor_block(state: &mut State1600, block: &[u8]) { let mut chunks = block.chunks_exact(size_of::()); for (s, chunk) in state.iter_mut().zip(&mut chunks) { - *s ^= u64::from_le_bytes(chunk.try_into().unwrap()); + *s ^= u64::from_le_bytes(chunk.try_into().expect("chunk has correct length")); } let rem = chunks.remainder(); diff --git a/k12/tests/mod.rs b/k12/tests/mod.rs index acd67cc..85ed964 100644 --- a/k12/tests/mod.rs +++ b/k12/tests/mod.rs @@ -1,3 +1,4 @@ +//! Basic tests use core::iter::repeat_n; use hex_literal::hex; use k12::{ @@ -85,8 +86,8 @@ fn kt128_pat_m() { hex!("3c390782a8a4e89fa6367f72feaaf13255c8d95878481d3cd8ce85f58e880af8"), ]; for (i, exp_res) in expected.into_iter().enumerate() { - let len = 17usize.pow(i as u32); - let m: Vec = (0..len).map(|j| (j % 251) as u8).collect(); + let len = 17usize.pow(u32::try_from(i).unwrap()); + let m = generate_msg(len); let result = kt128_digest_and_box(&m, 32); assert_eq!(result[..], exp_res); } @@ -125,8 +126,8 @@ fn kt256_pat_m() { ), ]; for (i, exp_res) in expected.into_iter().enumerate() { - let len = 17usize.pow(i as u32); - let m: Vec = (0..len).map(|j| (j % 251) as u8).collect(); + let len = 17usize.pow(u32::try_from(i).unwrap()); + let m = generate_msg(len); let result = kt256_digest_and_box(&m, 64); assert_eq!(result[..], exp_res); } @@ -141,10 +142,10 @@ fn kt128_pat_c() { hex!("75d2f86a2e644566726b4fbcfc5657b9dbcf070c7b0dca06450ab291d7443bcf"), ]; for (i, exp_res) in expected.into_iter().enumerate() { - let i = i as u32; + let i = u32::try_from(i).unwrap(); let m: Vec = repeat_n(0xFF, 2usize.pow(i) - 1).collect(); let len = 41usize.pow(i); - let c: Vec = (0..len).map(|j| (j % 251) as u8).collect(); + let c = generate_msg(len); let mut h = k12::CustomRefKt128::new_customized(&c); h.update(&m); @@ -180,10 +181,10 @@ fn kt256_pat_c() { ), ]; for (i, exp_res) in expected.into_iter().enumerate() { - let i = i as u32; + let i = u32::try_from(i).unwrap(); let m: Vec = repeat_n(0xFF, 2usize.pow(i) - 1).collect(); let len = 41usize.pow(i); - let c: Vec = (0..len).map(|j| (j % 251) as u8).collect(); + let c = generate_msg(len); let mut h = k12::CustomRefKt256::new_customized(&c); h.update(&m); @@ -209,7 +210,7 @@ fn kt128_input_multiple_of_chunk_size_minus_one() { ]; for (i, exp_res) in expected.iter().enumerate() { let len = 8192 * (i + 1) - 1; - let m: Vec = (0..len).map(|j| (j % 251) as u8).collect(); + let m = generate_msg(len); let result = kt128_digest_and_box(&m, 32); assert_eq!(result[..], exp_res[..]); } @@ -226,8 +227,14 @@ fn kt128_input_multiple_of_chunk_size() { ]; for (i, exp_res) in expected.iter().enumerate() { let len = 8192 * (i + 1); - let m: Vec = (0..len).map(|j| (j % 251) as u8).collect(); + let m = generate_msg(len); let result = kt128_digest_and_box(&m, 32); assert_eq!(result[..], exp_res[..]); } } + +fn generate_msg(len: usize) -> Vec { + (0..len) + .map(|j| u8::try_from(j % 251).expect("fits into u8")) + .collect() +} diff --git a/shake/Cargo.toml b/shake/Cargo.toml index 1a407f9..654fe91 100644 --- a/shake/Cargo.toml +++ b/shake/Cargo.toml @@ -26,5 +26,8 @@ default = ["alloc"] alloc = ["digest/alloc"] zeroize = ["digest/zeroize", "sponge-cursor/zeroize"] +[lints] +workspace = true + [package.metadata.docs.rs] all-features = true diff --git a/shake/benches/mod.rs b/shake/benches/mod.rs index 4b34fbe..dca8311 100644 --- a/shake/benches/mod.rs +++ b/shake/benches/mod.rs @@ -1,3 +1,4 @@ +//! Basic benchmarks #![feature(test)] extern crate test; diff --git a/shake/src/lib.rs b/shake/src/lib.rs index ff7a068..c069f5f 100644 --- a/shake/src/lib.rs +++ b/shake/src/lib.rs @@ -6,8 +6,6 @@ )] #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] -#![warn(missing_docs, missing_debug_implementations)] -#![warn(unreachable_pub)] pub use digest; pub use digest::{ExtendableOutput, Update, XofReader}; diff --git a/shake/tests/cshake.rs b/shake/tests/cshake.rs index 5c44f77..98d7b87 100644 --- a/shake/tests/cshake.rs +++ b/shake/tests/cshake.rs @@ -1,3 +1,4 @@ +//! Basic tests use digest::dev::xof_reset_test; use digest::new_test; diff --git a/turboshake/Cargo.toml b/turboshake/Cargo.toml index c4039a0..b3ab809 100644 --- a/turboshake/Cargo.toml +++ b/turboshake/Cargo.toml @@ -26,5 +26,8 @@ default = ["alloc"] alloc = ["digest/alloc"] zeroize = ["digest/zeroize", "sponge-cursor/zeroize"] +[lints] +workspace = true + [package.metadata.docs.rs] all-features = true diff --git a/turboshake/benches/mod.rs b/turboshake/benches/mod.rs index 2647748..ac9105b 100644 --- a/turboshake/benches/mod.rs +++ b/turboshake/benches/mod.rs @@ -1,3 +1,4 @@ +//! Basic benchmarks #![feature(test)] extern crate test; diff --git a/turboshake/src/lib.rs b/turboshake/src/lib.rs index 9946960..d217eba 100644 --- a/turboshake/src/lib.rs +++ b/turboshake/src/lib.rs @@ -6,8 +6,6 @@ )] #![cfg_attr(docsrs, feature(doc_cfg))] #![forbid(unsafe_code)] -#![warn(missing_docs, missing_debug_implementations)] -#![warn(unreachable_pub)] pub use digest; use keccak::{Keccak, State1600}; diff --git a/turboshake/tests/turboshake.rs b/turboshake/tests/turboshake.rs index b638a52..2a79b41 100644 --- a/turboshake/tests/turboshake.rs +++ b/turboshake/tests/turboshake.rs @@ -1,13 +1,14 @@ +//! Basic tests use core::fmt::Debug; use digest::ExtendableOutput; use turboshake::{CTurboShake128, CTurboShake256}; #[derive(Debug, Clone, Copy)] -pub struct TestVector { - pub input: &'static [u8], - pub input_pattern_length: &'static [u8], - pub output: &'static [u8], - pub truncate_output: &'static [u8], +struct TestVector { + input: &'static [u8], + input_pattern_length: &'static [u8], + output: &'static [u8], + truncate_output: &'static [u8], } pub(crate) fn turbo_shake_test(