diff --git a/dhkem/src/lib.rs b/dhkem/src/lib.rs index b81c4c0..50e2abb 100644 --- a/dhkem/src/lib.rs +++ b/dhkem/src/lib.rs @@ -5,7 +5,6 @@ html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" )] -#![warn(missing_docs)] //! # Diffie-Hellman (DH) based Key Encapsulation Mechanisms (KEM) //! diff --git a/frodo-kem/Cargo.toml b/frodo-kem/Cargo.toml index beef424..1ea8aa0 100644 --- a/frodo-kem/Cargo.toml +++ b/frodo-kem/Cargo.toml @@ -101,6 +101,9 @@ features = [ ] rustdoc-args = ["--cfg", "docsrs"] +[lints] +workspace = true + [[bench]] name = "frodo" harness = false diff --git a/frodo-kem/benches/frodo.rs b/frodo-kem/benches/frodo.rs index 401658d..aa7961a 100644 --- a/frodo-kem/benches/frodo.rs +++ b/frodo-kem/benches/frodo.rs @@ -1,3 +1,8 @@ +//! `FrodoKEM` benchmarks. + +#![allow(missing_docs, reason = "benchmarks")] +#![allow(clippy::unwrap_used, reason = "benchmarks")] + use criterion::{ BenchmarkGroup, Criterion, criterion_group, criterion_main, measurement::Measurement, }; diff --git a/frodo-kem/src/error.rs b/frodo-kem/src/error.rs index 912b07f..7f364e4 100644 --- a/frodo-kem/src/error.rs +++ b/frodo-kem/src/error.rs @@ -1,6 +1,6 @@ use thiserror::Error; -/// The errors that can occur for FrodoKEM +/// The errors that can occur for `FrodoKEM` #[derive(Error, Copy, Clone, Debug)] pub enum Error { /// The secret key length is invalid @@ -23,5 +23,5 @@ pub enum Error { UnsupportedAlgorithm, } -/// The result type for FrodoKEM +/// The result type for `FrodoKEM` pub type FrodoResult = Result; diff --git a/frodo-kem/src/hazmat.rs b/frodo-kem/src/hazmat.rs index aee023b..b0abb3a 100644 --- a/frodo-kem/src/hazmat.rs +++ b/frodo-kem/src/hazmat.rs @@ -27,7 +27,7 @@ //! [`FrodoKem640Aes`], [`FrodoKem976Aes`], and [`FrodoKem1344Aes`] for the FrodoKEM-AES algorithms. //! [`FrodoKem640Shake`], [`FrodoKem976Shake`], and [`FrodoKem1344Shake`] for the FrodoKEM-SHAKE algorithms. -#![allow(clippy::unwrap_used)] +#![allow(unreachable_pub, clippy::unwrap_used)] mod models; mod traits; diff --git a/frodo-kem/src/hazmat/models.rs b/frodo-kem/src/hazmat/models.rs index b191ade..0208a44 100644 --- a/frodo-kem/src/hazmat/models.rs +++ b/frodo-kem/src/hazmat/models.rs @@ -1,6 +1,8 @@ +#![allow(unsafe_code)] + use super::{Expanded, Kem, Params, Sample}; use crate::{Error, FrodoResult}; -use std::marker::PhantomData; +use core::marker::PhantomData; use zeroize::{Zeroize, ZeroizeOnDrop}; macro_rules! from_slice_impl { @@ -95,6 +97,7 @@ impl Ciphertext

{ /// Returns a reference to the c1 component #[allow(dead_code)] + #[must_use] pub fn c1(&self) -> &[u8] { &self.0[..P::LOG_Q_X_N_X_N_BAR_DIV_8] } @@ -106,6 +109,7 @@ impl Ciphertext

{ /// Returns a reference to the c2 component #[allow(dead_code)] + #[must_use] pub fn c2(&self) -> &[u8] { &self.0[P::LOG_Q_X_N_X_N_BAR_DIV_8..P::CIPHERTEXT_LENGTH - P::BYTES_SALT] } @@ -117,6 +121,7 @@ impl Ciphertext

{ /// Returns a reference to the salt #[allow(dead_code)] + #[must_use] pub fn salt(&self) -> &[u8] { &self.0[P::CIPHERTEXT_LENGTH - P::BYTES_SALT..] } @@ -154,22 +159,26 @@ impl<'a, P: Params> CiphertextRef<'a, P> { } /// Returns a reference to the c1 component + #[must_use] pub fn c1(&self) -> &[u8] { &self.0[..P::LOG_Q_X_N_X_N_BAR_DIV_8] } /// Returns a reference to the c2 component + #[must_use] pub fn c2(&self) -> &[u8] { &self.0[P::LOG_Q_X_N_X_N_BAR_DIV_8..P::CIPHERTEXT_LENGTH - P::BYTES_SALT] } /// Returns a reference to the salt + #[must_use] pub fn salt(&self) -> &[u8] { &self.0[P::CIPHERTEXT_LENGTH - P::BYTES_SALT..] } /// Convert the ciphertext reference into an owned ciphertext #[allow(dead_code)] + #[must_use] pub fn to_owned(&self) -> Ciphertext

{ Ciphertext(self.0.to_vec(), PhantomData) } @@ -217,6 +226,7 @@ impl EncryptionKey

{ } /// Returns a reference to the seed A + #[must_use] pub fn seed_a(&self) -> &[u8] { &self.0[..P::BYTES_SEED_A] } @@ -228,6 +238,7 @@ impl EncryptionKey

{ /// Returns a reference to the matrix B #[allow(dead_code)] + #[must_use] pub fn matrix_b(&self) -> &[u8] { &self.0[P::BYTES_SEED_A..] } @@ -252,17 +263,20 @@ impl<'a, P: Params> EncryptionKeyRef<'a, P> { } /// Returns a reference to the seed A + #[must_use] pub fn seed_a(&self) -> &[u8] { &self.0[..P::BYTES_SEED_A] } /// Returns a reference to the matrix B + #[must_use] pub fn matrix_b(&self) -> &[u8] { &self.0[P::BYTES_SEED_A..] } /// Convert the public key reference into an owned public key #[allow(dead_code)] + #[must_use] pub fn to_owned(&self) -> EncryptionKey

{ EncryptionKey(self.0.to_vec(), PhantomData) } @@ -286,7 +300,7 @@ impl Default for DecryptionKey

{ impl Zeroize for DecryptionKey

{ fn zeroize(&mut self) { - self.0.zeroize() + self.0.zeroize(); } } @@ -307,6 +321,7 @@ impl DecryptionKey

{ /// Returns a reference to the shared secret #[allow(dead_code)] + #[must_use] pub fn random_s(&self) -> &[u8] { &self.0[..P::SHARED_SECRET_LENGTH] } @@ -317,6 +332,7 @@ impl DecryptionKey

{ } /// Returns a reference to the public key + #[must_use] pub fn public_key(&self) -> &[u8] { &self.0[P::SHARED_SECRET_LENGTH..P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH] } @@ -328,6 +344,7 @@ impl DecryptionKey

{ /// Returns a reference to the matrix s #[allow(dead_code)] + #[must_use] pub fn matrix_s(&self) -> &[u8] { &self.0[P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH ..P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH + P::TWO_N_X_N_BAR] @@ -341,6 +358,7 @@ impl DecryptionKey

{ /// Returns a reference to the hash of the public key #[allow(dead_code)] + #[must_use] pub fn hpk(&self) -> &[u8] { &self.0[P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH + P::TWO_N_X_N_BAR..] } @@ -378,28 +396,33 @@ impl<'a, P: Params> DecryptionKeyRef<'a, P> { /// Returns a reference to the shared secret #[allow(dead_code)] + #[must_use] pub fn random_s(&self) -> &[u8] { &self.0[..P::SHARED_SECRET_LENGTH] } /// Returns a reference to the public key + #[must_use] pub fn public_key(&self) -> &[u8] { &self.0[P::SHARED_SECRET_LENGTH..P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH] } /// Returns a reference to the matrix s + #[must_use] pub fn matrix_s(&self) -> &[u8] { &self.0[P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH ..P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH + P::TWO_N_X_N_BAR] } /// Returns a reference to the hash of the public key + #[must_use] pub fn hpk(&self) -> &[u8] { &self.0[P::SHARED_SECRET_LENGTH + P::PUBLIC_KEY_LENGTH + P::TWO_N_X_N_BAR..] } /// Convert the secret key reference into an owned secret key #[allow(dead_code)] + #[must_use] pub fn to_owned(&self) -> DecryptionKey

{ DecryptionKey(self.0.to_vec(), PhantomData) } @@ -471,6 +494,7 @@ impl<'a, P: Params> SharedSecretRef<'a, P> { /// Convert the shared secret reference into an owned shared secret #[allow(dead_code)] + #[must_use] pub fn to_owned(&self) -> SharedSecret

{ SharedSecret(self.0.to_vec(), PhantomData) } @@ -522,7 +546,7 @@ impl Expanded for FrodoKem { const METHOD: &'static str = E::METHOD; fn expand_a(&self, seed_a: &[u8], a: &mut [u16]) { - E::expand_a(&E::default(), seed_a, a) + E::expand_a(&E::default(), seed_a, a); } } @@ -536,7 +560,7 @@ impl Expanded for FrodoKem { ))] impl Sample for FrodoKem { fn sample(&self, s: &mut [u16]) { - S::sample(&S::default(), s) + S::sample(&S::default(), s); } } @@ -598,7 +622,7 @@ impl Expanded for EphemeralFrodoKem const METHOD: &'static str = E::METHOD; fn expand_a(&self, seed_a: &[u8], a: &mut [u16]) { - E::expand_a(&E::default(), seed_a, a) + E::expand_a(&E::default(), seed_a, a); } } @@ -612,7 +636,7 @@ impl Expanded for EphemeralFrodoKem ))] impl Sample for EphemeralFrodoKem { fn sample(&self, s: &mut [u16]) { - S::sample(&S::default(), s) + S::sample(&S::default(), s); } } @@ -876,7 +900,10 @@ impl Expanded for FrodoAes

{ // Treat `a` as blocks then overwrite in place to avoid allocation let blocks = unsafe { - std::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut Block, P::N_X_N / P::STRIPE_STEP) + core::slice::from_raw_parts_mut( + a.as_mut_ptr().cast::(), + P::N_X_N / P::STRIPE_STEP, + ) }; let mut pos = 0; for i in 0..P::N { @@ -921,7 +948,7 @@ impl Expanded for FrodoAes

{ debug_assert_eq!(seed_a.len(), 16); let in_blocks = - unsafe { std::slice::from_raw_parts_mut(a.as_mut_ptr() as *mut u8, P::N_X_N * 2) }; + unsafe { core::slice::from_raw_parts_mut(a.as_mut_ptr().cast::(), P::N_X_N * 2) }; let mut in_block = [0u8; 16]; let mut pos = 0; for i in 0..P::N { @@ -936,15 +963,13 @@ impl Expanded for FrodoAes

{ } unsafe { let aes_key_schedule = openssl_sys::EVP_CIPHER_CTX_new(); - if aes_key_schedule.is_null() { - panic!("EVP_CIPHER_CTX_new failed"); - } + assert!(!aes_key_schedule.is_null(), "EVP_CIPHER_CTX_new failed"); if openssl_sys::EVP_EncryptInit_ex( aes_key_schedule, openssl_sys::EVP_aes_128_ecb(), - std::ptr::null_mut(), + core::ptr::null_mut(), seed_a.as_ptr(), - std::ptr::null_mut(), + core::ptr::null_mut(), ) != 1 { panic!("EVP_EncryptInit_ex failed"); @@ -954,7 +979,7 @@ impl Expanded for FrodoAes

{ if openssl_sys::EVP_EncryptUpdate( aes_key_schedule, in_blocks.as_mut_ptr(), - &mut olen, + &raw mut olen, in_blocks.as_ptr(), ilen, ) != 1 @@ -1021,7 +1046,7 @@ impl Expanded for FrodoShake

{ shake.update(&seed_separated); let a_temp = &mut a[ii..ii + P::N]; let bytes = unsafe { - std::slice::from_raw_parts_mut(a_temp.as_mut_ptr() as *mut u8, a_temp.len() * 2) + core::slice::from_raw_parts_mut(a_temp.as_mut_ptr().cast::(), a_temp.len() * 2) }; shake.finalize_xof_reset_into(bytes); #[cfg(target_endian = "big")] @@ -1063,20 +1088,18 @@ impl Expanded for FrodoShake

{ seed_separated[0..2].copy_from_slice(&(i as u16).to_le_bytes()); unsafe { let shake = openssl_sys::EVP_MD_CTX_new(); - if shake.is_null() { - panic!("EVP_MD_CTX_new failed"); - } + assert!(!shake.is_null(), "EVP_MD_CTX_new failed"); if openssl_sys::EVP_DigestInit_ex( shake, openssl_sys::EVP_shake128(), - std::ptr::null_mut(), + core::ptr::null_mut(), ) != 1 { panic!("EVP_DigestInit_ex failed"); } if openssl_sys::EVP_DigestUpdate( shake, - seed_separated.as_ptr() as *const _, + seed_separated.as_ptr().cast(), seed_separated.len(), ) != 1 { @@ -1084,7 +1107,7 @@ impl Expanded for FrodoShake

{ } if openssl_sys::EVP_DigestFinalXOF( shake, - a[ii..ii + P::N].as_mut_ptr() as *mut u8, + a[ii..ii + P::N].as_mut_ptr().cast::(), P::TWO_N, ) != 1 { diff --git a/frodo-kem/src/hazmat/traits.rs b/frodo-kem/src/hazmat/traits.rs index 9fa4605..342d905 100644 --- a/frodo-kem/src/hazmat/traits.rs +++ b/frodo-kem/src/hazmat/traits.rs @@ -1,3 +1,5 @@ +#![allow(unsafe_code)] + use crate::hazmat::{ Ciphertext, CiphertextRef, DecryptionKey, DecryptionKeyRef, EncryptionKey, EncryptionKeyRef, SharedSecret, @@ -137,7 +139,10 @@ pub trait Kem: Params + Expanded + Sample { let mut bytes_se = vec![0u16; Self::TWO_N_X_N_BAR]; { let bytes_se = unsafe { - std::slice::from_raw_parts_mut(bytes_se.as_mut_ptr() as *mut u8, bytes_se.len() * 2) + core::slice::from_raw_parts_mut( + bytes_se.as_mut_ptr().cast::(), + bytes_se.len() * 2, + ) }; shake.finalize_xof_reset_into(bytes_se); } @@ -231,8 +236,9 @@ pub trait Kem: Params + Expanded + Sample { shake.update(&[0x96]); shake.update(&g2_out[..Self::BYTES_SEED_SE]); { - let bytes_sp = - unsafe { std::slice::from_raw_parts_mut(sp.as_mut_ptr() as *mut u8, sp.len() * 2) }; + let bytes_sp = unsafe { + core::slice::from_raw_parts_mut(sp.as_mut_ptr().cast::(), sp.len() * 2) + }; shake.finalize_xof_reset_into(bytes_sp); } #[cfg(target_endian = "big")] @@ -349,8 +355,9 @@ pub trait Kem: Params + Expanded + Sample { shake.update(&[0x96]); shake.update(&g2_out[..Self::BYTES_SEED_SE]); { - let bytes_sp = - unsafe { std::slice::from_raw_parts_mut(sp.as_mut_ptr() as *mut u8, sp.len() * 2) }; + let bytes_sp = unsafe { + core::slice::from_raw_parts_mut(sp.as_mut_ptr().cast::(), sp.len() * 2) + }; shake.finalize_xof_reset_into(bytes_sp); } #[cfg(target_endian = "big")] @@ -621,7 +628,7 @@ pub trait Kem: Params + Expanded + Sample { let mut temp = 0; let ii = i * Self::EXTRACTED_BITS; for j in 0..Self::EXTRACTED_BITS { - let t = msg[ii + j] as u64; + let t = u64::from(msg[ii + j]); temp |= t << (8 * j); } for _ in 0..8 { @@ -648,7 +655,7 @@ pub trait Kem: Params + Expanded + Sample { for j in 0..8 { let mut t = (input[index] & Self::Q_MASK).wrapping_add(add); t >>= Self::SHIFT; - temp |= ((t & Self::EXTRACTED_BITS_MASK) as u64) << (Self::EXTRACTED_BITS * j); + temp |= u64::from(t & Self::EXTRACTED_BITS_MASK) << (Self::EXTRACTED_BITS * j); index += 1; } let ii = i * Self::EXTRACTED_BITS; @@ -675,12 +682,12 @@ pub trait Kem: Params + Expanded + Sample { let mut b = 0u8; while b < 8 { - let nbits = std::cmp::min(8 - b, bits); + let nbits = core::cmp::min(8 - b, bits); let mask = (1u16 << nbits).wrapping_sub(1); let w_shifted = w >> (bits - nbits); - let t = (w_shifted & mask) as u32; + let t = u32::from(w_shifted & mask); let t_shifted = (t << (8 - b - nbits)) as u8; @@ -725,14 +732,14 @@ pub trait Kem: Params + Expanded + Sample { let mut b = 0u8; while b < lsb { - let nbits = std::cmp::min(lsb - b, bits); + let nbits = core::cmp::min(lsb - b, bits); let mask = (1u16 << nbits).wrapping_sub(1); let w_shifted = w >> (bits.wrapping_sub(nbits)); let t = w_shifted & (mask as u8); - let t_shifted = ((t as u32) << (lsb - b - nbits)) as u16; + let t_shifted = (u32::from(t) << (lsb - b - nbits)) as u16; output[i] = output[i].wrapping_add(t_shifted); b = b.wrapping_add(nbits); diff --git a/frodo-kem/src/lib.rs b/frodo-kem/src/lib.rs index b751dbc..292bca4 100644 --- a/frodo-kem/src/lib.rs +++ b/frodo-kem/src/lib.rs @@ -1,6 +1,25 @@ +// #![no_std] TODO +#![cfg_attr(docsrs, feature(doc_cfg))] +#![doc = include_str!("../README.md")] +#![doc( + html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" +)] +#![allow( + clippy::cast_possible_truncation, + clippy::cast_possible_wrap, + clippy::cast_sign_loss, + clippy::doc_markdown, + clippy::integer_division_remainder_used, + clippy::missing_errors_doc, + clippy::trivially_copy_pass_by_ref, + clippy::undocumented_unsafe_blocks, + reason = "TODO" +)] + //! ## Usage //! -//! The standard safe method for FrodoKEM is to use [`Algorithm`], +//! The standard safe method for `FrodoKEM` is to use [`Algorithm`], //! `encapsulate` a randomly generated value, //! and `decapsulate` it on the other side. //! @@ -57,20 +76,9 @@ //! //! ## Custom //! -//! To create a custom implementation of FrodoKEM, use the `hazmat` feature, to access +//! To create a custom implementation of `FrodoKEM`, use the `hazmat` feature, to access //! the necessary traits and models for creating a custom implementation. //! Be warned, this is not recommended unless you are sure of what you are doing. -#![cfg_attr(docsrs, feature(doc_cfg))] -#![warn( - missing_docs, - missing_debug_implementations, - missing_copy_implementations, - trivial_casts, - trivial_numeric_casts, - unused, - clippy::mod_module_files -)] -#![deny(clippy::unwrap_used)] #[cfg(not(any( feature = "efrodo640aes", @@ -98,8 +106,8 @@ mod hazmat; use hazmat::*; +use core::marker::PhantomData; use rand_core::CryptoRng; -use std::marker::PhantomData; use subtle::{Choice, ConstantTimeEq}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -144,7 +152,7 @@ macro_rules! serde_impl { impl<'de> serde::de::Visitor<'de> for FieldVisitor { type Value = $name; - fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "a struct with two fields") } @@ -191,7 +199,7 @@ macro_rules! serde_impl { impl<'de> serde::de::Visitor<'de> for BytesVisitor { type Value = $name; - fn expecting(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + fn expecting(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "a byte sequence") } @@ -234,7 +242,7 @@ macro_rules! ct_eq_imp { }; } -/// A FrodoKEM ciphertext key +/// A `FrodoKEM` ciphertext key #[derive(Debug, Clone, Default)] pub struct Ciphertext { pub(crate) algorithm: Algorithm, @@ -253,11 +261,13 @@ serde_impl!(Ciphertext, ciphertext_from_bytes); impl Ciphertext { /// Get the algorithm + #[must_use] pub fn algorithm(&self) -> Algorithm { self.algorithm } /// Get the value + #[must_use] pub fn value(&self) -> &[u8] { self.value.as_slice() } @@ -268,7 +278,7 @@ impl Ciphertext { } } -/// A FrodoKEM public key +/// A `FrodoKEM` public key #[derive(Debug, Clone, Default)] pub struct EncryptionKey { pub(crate) algorithm: Algorithm, @@ -295,11 +305,13 @@ serde_impl!(EncryptionKey, encryption_key_from_bytes); impl EncryptionKey { /// Get the algorithm + #[must_use] pub fn algorithm(&self) -> Algorithm { self.algorithm } /// Get the value + #[must_use] pub fn value(&self) -> &[u8] { self.value.as_slice() } @@ -331,7 +343,7 @@ impl EncryptionKey { } } -/// A FrodoKEM secret key +/// A `FrodoKEM` secret key #[derive(Debug, Clone, Default)] pub struct DecryptionKey { pub(crate) algorithm: Algorithm, @@ -358,11 +370,13 @@ impl ZeroizeOnDrop for DecryptionKey {} impl DecryptionKey { /// Get the algorithm + #[must_use] pub fn algorithm(&self) -> Algorithm { self.algorithm } /// Get the value + #[must_use] pub fn value(&self) -> &[u8] { self.value.as_slice() } @@ -382,7 +396,7 @@ impl DecryptionKey { } } -/// A FrodoKEM shared secret +/// A `FrodoKEM` shared secret #[derive(Debug, Clone, Default)] pub struct SharedSecret { pub(crate) algorithm: Algorithm, @@ -409,11 +423,13 @@ impl ZeroizeOnDrop for SharedSecret {} impl SharedSecret { /// Get the algorithm + #[must_use] pub fn algorithm(&self) -> Algorithm { self.algorithm } /// Get the value + #[must_use] pub fn value(&self) -> &[u8] { self.value.as_slice() } @@ -424,7 +440,7 @@ impl SharedSecret { } } -/// The supported FrodoKem algorithms +/// The supported `FrodoKem` algorithms #[derive(Debug, Clone, Copy, PartialEq, Eq, Ord, PartialOrd, Hash)] pub enum Algorithm { #[cfg(feature = "frodo640aes")] @@ -503,8 +519,8 @@ impl Default for Algorithm { } } -impl std::fmt::Display for Algorithm { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { +impl core::fmt::Display for Algorithm { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { static ALGORITHMS: std::sync::LazyLock> = std::sync::LazyLock::new(|| { let mut set = std::collections::HashMap::new(); @@ -576,7 +592,7 @@ impl std::fmt::Display for Algorithm { } } -impl std::str::FromStr for Algorithm { +impl core::str::FromStr for Algorithm { type Err = Error; fn from_str(s: &str) -> Result { @@ -686,26 +702,26 @@ impl From for u8 { impl From for u16 { fn from(alg: Algorithm) -> u16 { - u8::from(alg) as u16 + u16::from(u8::from(alg)) } } impl From for u32 { fn from(alg: Algorithm) -> u32 { - u8::from(alg) as u32 + u32::from(u8::from(alg)) } } impl From for u64 { fn from(alg: Algorithm) -> u64 { - u8::from(alg) as u64 + u64::from(u8::from(alg)) } } #[cfg(target_pointer_width = "64")] impl From for u128 { fn from(alg: Algorithm) -> u128 { - u8::from(alg) as u128 + u128::from(u8::from(alg)) } } @@ -827,6 +843,7 @@ impl<'de> serde::Deserialize<'de> for Algorithm { impl Algorithm { /// Get the enabled algorithms + #[must_use] pub fn enabled_algorithms() -> &'static [Algorithm] { &[ #[cfg(feature = "frodo640aes")] @@ -857,6 +874,7 @@ impl Algorithm { } /// Get the parameters for this algorithm + #[must_use] pub const fn params(&self) -> AlgorithmParams { match self { #[cfg(feature = "frodo640aes")] @@ -908,6 +926,7 @@ impl Algorithm { } /// Get the [`EncryptionKey`] from a [`DecryptionKey`] + #[must_use] pub fn encryption_key_from_decryption_key(&self, secret_key: &DecryptionKey) -> EncryptionKey { match self { #[cfg(feature = "frodo640aes")] diff --git a/frodo-kem/tests/frodo.rs b/frodo-kem/tests/frodo.rs index c09b5e7..f038042 100644 --- a/frodo-kem/tests/frodo.rs +++ b/frodo-kem/tests/frodo.rs @@ -1,4 +1,4 @@ -//! Tests for the FrodoKEM and FrodoKEM-640 schemes +//! Tests for the `FrodoKEM` and FrodoKEM-640 schemes use rstest::*; use std::path::PathBuf; diff --git a/frodo-kem/tests/rng.rs b/frodo-kem/tests/rng.rs index de9293a..6461baf 100644 --- a/frodo-kem/tests/rng.rs +++ b/frodo-kem/tests/rng.rs @@ -1,5 +1,10 @@ //! Random number generator for testing //! AES-CTR DRBG + +#![allow(dead_code)] +#![allow(clippy::integer_division_remainder_used, reason = "tests")] +#![allow(clippy::unwrap_used, clippy::unwrap_in_result, reason = "tests")] + use aes::{ Aes256Enc, Block, cipher::{BlockCipherEncrypt, KeyInit}, @@ -9,11 +14,11 @@ use hybrid_array::{Array, typenum::U48}; use rand_core::{Rng, SeedableRng, TryCryptoRng, TryRng}; /// Seed type for the AES-CTR DRBG -pub type RngSeed = Array; +pub(crate) type RngSeed = Array; /// AES-CTR DRBG #[derive(Debug, Default, Copy, Clone)] -pub struct AesCtrDrbg { +pub(crate) struct AesCtrDrbg { reseed_counter: usize, key: [u8; 32], counter: [u8; 16], @@ -75,7 +80,7 @@ impl TryCryptoRng for AesCtrDrbg {} impl AesCtrDrbg { /// Reseed the DRBG with a new seed - pub fn reseed(&mut self, seed: &RngSeed) { + pub(crate) fn reseed(&mut self, seed: &RngSeed) { self.counter.iter_mut().for_each(|c| *c = 0); self.key.iter_mut().for_each(|k| *k = 0); diff --git a/frodo-kem/tests/rsp_reader.rs b/frodo-kem/tests/rsp_reader.rs index b227767..1bc8660 100644 --- a/frodo-kem/tests/rsp_reader.rs +++ b/frodo-kem/tests/rsp_reader.rs @@ -1,4 +1,8 @@ //! Reader for Frodo KAT files and test vectors + +#![allow(dead_code)] +#![allow(clippy::unwrap_used, reason = "tests")] + use frodo_kem::*; use hybrid_array::{Array, typenum::U48}; use std::path::Path; @@ -9,29 +13,29 @@ use std::{ type RngSeed = Array; -/// "count = ".len() +/// "count = ".`len()` const COUNT_PREFIX: usize = 8; -/// "seed = ".len() +/// "seed = ".`len()` const SEED_PREFIX: usize = 7; -/// "pk = ".len() +/// "pk = ".`len()` const PK_PREFIX: usize = 5; -/// "sk = ".len() +/// "sk = ".`len()` const SK_PREFIX: usize = 5; -/// "ct = ".len() +/// "ct = ".`len()` const CT_PREFIX: usize = 5; -/// "ss = ".len() +/// "ss = ".`len()` const SS_PREFIX: usize = 5; /// Reader for Frodo KAT files #[derive(Debug)] -pub struct RspReader { +pub(crate) struct RspReader { lines: Lines>, scheme: Algorithm, } impl RspReader { - /// Create a new RspReader from a file - pub fn new>(file: P) -> Self { + /// Create a new `RspReader` from a file + pub(crate) fn new>(file: P) -> Self { let path = file.as_ref(); assert!( path.is_file(), @@ -65,7 +69,7 @@ impl Iterator for RspReader { let seed_line = self.lines.next()?.unwrap(); let seed_bytes = hex::decode(seed_line[SEED_PREFIX..].trim_end()).unwrap(); assert_eq!(seed_bytes.len(), 48); - let seed = RngSeed::from_iter(seed_bytes.iter().copied()); + let seed = seed_bytes.iter().copied().collect::(); let pk_line = self.lines.next()?.unwrap(); let pk_bytes = hex::decode(pk_line[PK_PREFIX..].trim_end()).unwrap(); let pk = self.scheme.encryption_key_from_bytes(&pk_bytes).unwrap(); @@ -94,7 +98,7 @@ impl Iterator for RspReader { /// Test vector data #[derive(Debug, Clone, Default)] -pub struct RspData { +pub(crate) struct RspData { /// Algorithm used in the test vector pub scheme: Algorithm, /// Test vector number diff --git a/module-lattice/Cargo.toml b/module-lattice/Cargo.toml index 85bf7f5..c802229 100644 --- a/module-lattice/Cargo.toml +++ b/module-lattice/Cargo.toml @@ -32,3 +32,6 @@ zeroize = ["array/zeroize", "dep:zeroize"] [lints] workspace = true + +[package.metadata.docs.rs] +all-features = true