ed25519: configure and apply workspace-level lints (#1323)

Adds the workspace-level config from RustCrypto/utils#1411 to this
repo and applies it to `ed25519`.
This commit is contained in:
Tony Arcieri
2026-05-02 21:21:26 -06:00
committed by GitHub
parent e0d47990aa
commit 2d7866fa4c
10 changed files with 72 additions and 25 deletions
+2
View File
@@ -0,0 +1,2 @@
allow-unwrap-in-consts = true
allow-unwrap-in-tests = true
+1 -1
View File
@@ -34,7 +34,7 @@ jobs:
- uses: actions/checkout@v6.0.2 - uses: actions/checkout@v6.0.2
- uses: dtolnay/rust-toolchain@master - uses: dtolnay/rust-toolchain@master
with: with:
toolchain: 1.85.0 toolchain: 1.95.0
components: clippy components: clippy
- run: cargo clippy --all-features -- -D warnings - run: cargo clippy --all-features -- -D warnings
+40
View File
@@ -16,6 +16,46 @@ members = [
[profile.dev] [profile.dev]
opt-level = 2 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"
doc_markdown = "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_used = "warn"
[workspace.lints.rust]
missing_copy_implementations = "warn"
missing_debug_implementations = "warn"
missing_docs = "warn"
trivial_casts = "warn"
trivial_numeric_casts = "warn"
unreachable_pub = "warn"
unused_lifetimes = "warn"
unused_qualifications = "warn"
[patch.crates-io] [patch.crates-io]
# A global patch crates-io block is used to avoid duplicate dependencies # A global patch crates-io block is used to avoid duplicate dependencies
# when pulling a member crate through git # when pulling a member crate through git
+3
View File
@@ -39,5 +39,8 @@ alloc = ["pkcs8?/alloc"]
pem = ["alloc", "pkcs8/pem"] pem = ["alloc", "pkcs8/pem"]
serde_bytes = ["serde", "dep:serde_bytes"] serde_bytes = ["serde", "dep:serde_bytes"]
[lints]
workspace = true
[package.metadata.docs.rs] [package.metadata.docs.rs]
all-features = true all-features = true
+3 -3
View File
@@ -24,10 +24,10 @@ to be written abstractly in such a way that different signer/verifier
providers can be plugged in, enabling support for using different providers can be plugged in, enabling support for using different
Ed25519 implementations, including HSMs or Cloud KMS services. Ed25519 implementations, including HSMs or Cloud KMS services.
## SemVer Policy ## `SemVer` Policy
- All on-by-default features of this library are covered by SemVer - All on-by-default features of this library are covered by `SemVer`
- MSRV is considered exempt from SemVer as noted above - MSRV is considered exempt from `SemVer` as noted above
- The `pkcs8` module is exempted as it uses a pre-1.0 dependency, however, - The `pkcs8` module is exempted as it uses a pre-1.0 dependency, however,
breaking changes to this module will be accompanied by a minor version bump. breaking changes to this module will be accompanied by a minor version bump.
+9 -12
View File
@@ -4,14 +4,6 @@
#![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")] #![doc(html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo_small.png")]
#![allow(non_snake_case)] #![allow(non_snake_case)]
#![forbid(unsafe_code)] #![forbid(unsafe_code)]
#![warn(
clippy::unwrap_used,
missing_docs,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications,
unreachable_pub
)]
//! # Using Ed25519 generically over algorithm implementations/providers //! # Using Ed25519 generically over algorithm implementations/providers
//! //!
@@ -230,7 +222,7 @@
//! //!
//! - [`ed25519-dalek`] - mature pure Rust implementation of Ed25519 //! - [`ed25519-dalek`] - mature pure Rust implementation of Ed25519
//! - [`ring-compat`] - compatibility wrapper for [*ring*] //! - [`ring-compat`] - compatibility wrapper for [*ring*]
//! - [`yubihsm`] - host-side client library for YubiHSM2 devices from Yubico //! - [`yubihsm`] - host-side client library for `YubiHSM2` devices from Yubico
//! //!
//! [`ed25519-dalek`]: https://docs.rs/ed25519-dalek //! [`ed25519-dalek`]: https://docs.rs/ed25519-dalek
//! [`ring-compat`]: https://docs.rs/ring-compat //! [`ring-compat`]: https://docs.rs/ring-compat
@@ -332,6 +324,7 @@ impl Signature {
pub const BYTE_SIZE: usize = COMPONENT_SIZE * 2; pub const BYTE_SIZE: usize = COMPONENT_SIZE * 2;
/// Parse an Ed25519 signature from a byte slice. /// Parse an Ed25519 signature from a byte slice.
#[must_use]
pub fn from_bytes(bytes: &SignatureBytes) -> Self { pub fn from_bytes(bytes: &SignatureBytes) -> Self {
let mut R = ComponentBytes::default(); let mut R = ComponentBytes::default();
let mut s = ComponentBytes::default(); let mut s = ComponentBytes::default();
@@ -344,15 +337,15 @@ impl Signature {
} }
/// Parse an Ed25519 signature from its `R` and `s` components. /// Parse an Ed25519 signature from its `R` and `s` components.
#[must_use]
pub fn from_components(R: ComponentBytes, s: ComponentBytes) -> Self { pub fn from_components(R: ComponentBytes, s: ComponentBytes) -> Self {
Self { R, s } Self { R, s }
} }
/// Parse an Ed25519 signature from a byte slice. /// Parse an Ed25519 signature from a byte slice.
/// ///
/// # Returns /// # Errors
/// - `Ok` on success /// - Returns [`Error`] if the input byte slice is not 64-bytes.
/// - `Err` if the input byte slice is not 64-bytes
pub fn from_slice(bytes: &[u8]) -> signature::Result<Self> { pub fn from_slice(bytes: &[u8]) -> signature::Result<Self> {
SignatureBytes::try_from(bytes) SignatureBytes::try_from(bytes)
.map(Into::into) .map(Into::into)
@@ -360,16 +353,19 @@ impl Signature {
} }
/// Bytes for the `R` component of a signature. /// Bytes for the `R` component of a signature.
#[must_use]
pub fn r_bytes(&self) -> &ComponentBytes { pub fn r_bytes(&self) -> &ComponentBytes {
&self.R &self.R
} }
/// Bytes for the `s` component of a signature. /// Bytes for the `s` component of a signature.
#[must_use]
pub fn s_bytes(&self) -> &ComponentBytes { pub fn s_bytes(&self) -> &ComponentBytes {
&self.s &self.s
} }
/// Return the inner byte array. /// Return the inner byte array.
#[must_use]
pub fn to_bytes(&self) -> SignatureBytes { pub fn to_bytes(&self) -> SignatureBytes {
let mut ret = [0u8; Self::BYTE_SIZE]; let mut ret = [0u8; Self::BYTE_SIZE];
let (R, s) = ret.split_at_mut(COMPONENT_SIZE); let (R, s) = ret.split_at_mut(COMPONENT_SIZE);
@@ -380,6 +376,7 @@ impl Signature {
/// Convert this signature into a byte vector. /// Convert this signature into a byte vector.
#[cfg(feature = "alloc")] #[cfg(feature = "alloc")]
#[must_use]
pub fn to_vec(&self) -> Vec<u8> { pub fn to_vec(&self) -> Vec<u8> {
self.to_bytes().to_vec() self.to_bytes().to_vec()
} }
+8 -4
View File
@@ -3,9 +3,9 @@
//! Implements Ed25519 PKCS#8 private keys as described in RFC8410 Section 7: //! Implements Ed25519 PKCS#8 private keys as described in RFC8410 Section 7:
//! <https://datatracker.ietf.org/doc/html/rfc8410#section-7> //! <https://datatracker.ietf.org/doc/html/rfc8410#section-7>
//! //!
//! ## SemVer Notes //! ## `SemVer` Notes
//! //!
//! The `pkcs8` module of this crate is exempted from SemVer as it uses a //! The `pkcs8` module of this crate is exempted from `SemVer` as it uses a
//! pre-1.0 dependency (the `pkcs8` crate). //! pre-1.0 dependency (the `pkcs8` crate).
//! //!
//! However, breaking changes to this module will be accompanied by a minor //! However, breaking changes to this module will be accompanied by a minor
@@ -86,7 +86,10 @@ impl KeypairBytes {
const BYTE_SIZE: usize = 64; const BYTE_SIZE: usize = 64;
/// Parse raw keypair from a 64-byte input. /// Parse raw keypair from a 64-byte input.
#[must_use]
#[allow(clippy::missing_panics_doc, reason = "MSRV TODO")]
pub fn from_bytes(bytes: &[u8; Self::BYTE_SIZE]) -> Self { pub fn from_bytes(bytes: &[u8; Self::BYTE_SIZE]) -> Self {
// TODO(tarcieri): use `as_chunks` when MSRV is 1.88
let (sk, pk) = bytes.split_at(Self::BYTE_SIZE / 2); let (sk, pk) = bytes.split_at(Self::BYTE_SIZE / 2);
Self { Self {
@@ -100,9 +103,9 @@ impl KeypairBytes {
/// Serialize as a 64-byte keypair. /// Serialize as a 64-byte keypair.
/// ///
/// # Returns /// # Returns
///
/// - `Some(bytes)` if the `public_key` is present. /// - `Some(bytes)` if the `public_key` is present.
/// - `None` if the `public_key` is absent (i.e. `None`). /// - `None` if the `public_key` is absent (i.e. `None`).
#[must_use]
pub fn to_bytes(&self) -> Option<[u8; Self::BYTE_SIZE]> { pub fn to_bytes(&self) -> Option<[u8; Self::BYTE_SIZE]> {
if let Some(public_key) = &self.public_key { if let Some(public_key) = &self.public_key {
let mut result = [0u8; Self::BYTE_SIZE]; let mut result = [0u8; Self::BYTE_SIZE];
@@ -119,7 +122,7 @@ impl KeypairBytes {
impl Drop for KeypairBytes { impl Drop for KeypairBytes {
fn drop(&mut self) { fn drop(&mut self) {
#[cfg(feature = "zeroize")] #[cfg(feature = "zeroize")]
self.secret_key.zeroize() self.secret_key.zeroize();
} }
} }
@@ -242,6 +245,7 @@ impl PublicKeyBytes {
const BYTE_SIZE: usize = 32; const BYTE_SIZE: usize = 32;
/// Returns the raw bytes of the public key. /// Returns the raw bytes of the public key.
#[must_use]
pub fn to_bytes(&self) -> [u8; Self::BYTE_SIZE] { pub fn to_bytes(&self) -> [u8; Self::BYTE_SIZE] {
self.0 self.0
} }
+4 -4
View File
@@ -1,8 +1,8 @@
//! Hexadecimal display/serialization tests. //! Hexadecimal display/serialization tests.
use core::str::FromStr;
use ed25519::Signature; use ed25519::Signature;
use hex_literal::hex; use hex_literal::hex;
use std::str::FromStr;
/// Test 1 signature from RFC 8032 § 7.1 /// Test 1 signature from RFC 8032 § 7.1
/// <https://datatracker.ietf.org/doc/html/rfc8032#section-7.1> /// <https://datatracker.ietf.org/doc/html/rfc8032#section-7.1>
@@ -19,7 +19,7 @@ fn display() {
assert_eq!( assert_eq!(
sig.to_string(), sig.to_string(),
"E5564300C360AC729086E2CC806E828A84877F1EB8E5D974D873E065224901555FB8821590A33BACC61E39701CF9B46BD25BF5F0595BBE24655141438E7A100B" "E5564300C360AC729086E2CC806E828A84877F1EB8E5D974D873E065224901555FB8821590A33BACC61E39701CF9B46BD25BF5F0595BBE24655141438E7A100B"
) );
} }
#[test] #[test]
@@ -28,7 +28,7 @@ fn lower_hex() {
assert_eq!( assert_eq!(
format!("{:x}", sig), format!("{:x}", sig),
"e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b" "e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b"
) );
} }
#[test] #[test]
@@ -37,7 +37,7 @@ fn upper_hex() {
assert_eq!( assert_eq!(
format!("{:X}", sig), format!("{:X}", sig),
"E5564300C360AC729086E2CC806E828A84877F1EB8E5D974D873E065224901555FB8821590A33BACC61E39701CF9B46BD25BF5F0595BBE24655141438E7A100B" "E5564300C360AC729086E2CC806E828A84877F1EB8E5D974D873E065224901555FB8821590A33BACC61E39701CF9B46BD25BF5F0595BBE24655141438E7A100B"
) );
} }
#[test] #[test]
+1 -1
View File
@@ -13,7 +13,7 @@ const PKCS8_V1_DER: &[u8] = include_bytes!("examples/pkcs8-v1.der");
/// Ed25519 PKCS#8 v2 private key + public key encoded as ASN.1 DER. /// Ed25519 PKCS#8 v2 private key + public key encoded as ASN.1 DER.
const PKCS8_V2_DER: &[u8] = include_bytes!("examples/pkcs8-v2.der"); const PKCS8_V2_DER: &[u8] = include_bytes!("examples/pkcs8-v2.der");
/// Ed25519 SubjectPublicKeyInfo encoded as ASN.1 DER. /// Ed25519 `SubjectPublicKeyInfo` encoded as ASN.1 DER.
const PUBLIC_KEY_DER: &[u8] = include_bytes!("examples/pubkey.der"); const PUBLIC_KEY_DER: &[u8] = include_bytes!("examples/pubkey.der");
#[test] #[test]
+1
View File
@@ -13,6 +13,7 @@ repository = "https://github.com/RustCrypto/signatures"
readme = "README.md" readme = "README.md"
categories = ["cryptography"] categories = ["cryptography"]
keywords = ["xmss", "signature", "crypto", "cryptography", "rfc8391"] keywords = ["xmss", "signature", "crypto", "cryptography", "rfc8391"]
rust-version = "1.85"
[features] [features]
default = [] default = []