Add #[inline] to all trivial functions in crypto
What changed, and why it matters
This commit only adds compiler hints (#[inline]) to small functions in the crypto module. It does not change any behavior, logic, or data handling. There is no security issue here.
No security action needed. This is a routine optimization commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit adds #[inline] attributes to trivial functions in crypto/src/ecdsa.rs, crypto/src/sighash.rs, and crypto/src/taproot.rs. These are pure performance/optimization hints to the Rust compiler. No code logic, parsing, validation, or cryptographic operations were modified. The changes are syntactic annotations only.
Changed components
crypto/src/ecdsa.rscrypto/src/sighash.rscrypto/src/taproot.rsInspect captured patch +62 / −0
diff --git a/crypto/src/ecdsa.rs b/crypto/src/ecdsa.rs
index 6277f5e0..527db78a 100644
--- a/crypto/src/ecdsa.rs
+++ b/crypto/src/ecdsa.rs
@@ -51,6 +51,7 @@ pub struct Signature {
impl Signature {
/// Constructs a new ECDSA Bitcoin signature for [`EcdsaSighashType::All`].
+ #[inline]
pub fn sighash_all(signature: secp256k1::ecdsa::Signature) -> Self {
Self { signature, sighash_type: EcdsaSighashType::All }
}
@@ -73,6 +74,7 @@ impl Signature {
/// Serializes an ECDSA signature (inner secp256k1 signature in DER format).
///
/// This does **not** perform extra heap allocation.
+ #[inline]
pub fn serialize(&self) -> SerializedSignature {
let mut buf = [0u8; MAX_SIG_LEN];
let signature = self.signature.serialize_der();
@@ -98,6 +100,7 @@ impl Signature {
#[cfg(feature = "hex")]
impl fmt::Display for Signature {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.signature.serialize_der().as_hex(), f)?;
fmt::LowerHex::fmt(&[self.sighash_type as u8].as_hex(), f)
@@ -109,6 +112,7 @@ impl fmt::Display for Signature {
impl FromStr for Signature {
type Err = ParseSignatureError;
+ #[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
let bytes = hex::decode_to_vec(s).map_err(ParseSignatureError::Hex)?;
Self::from_slice(&bytes).map_err(ParseSignatureError::Decode)
@@ -218,20 +222,24 @@ impl PartialEq<SerializedSignature> for [u8] {
}
impl PartialOrd for SerializedSignature {
+ #[inline]
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { Some(self.cmp(other)) }
}
impl Ord for SerializedSignature {
+ #[inline]
fn cmp(&self, other: &Self) -> core::cmp::Ordering { (**self).cmp(&**other) }
}
impl PartialOrd<[u8]> for SerializedSignature {
+ #[inline]
fn partial_cmp(&self, other: &[u8]) -> Option<core::cmp::Ordering> {
(**self).partial_cmp(other)
}
}
impl PartialOrd<SerializedSignature> for [u8] {
+ #[inline]
fn partial_cmp(&self, other: &SerializedSignature) -> Option<core::cmp::Ordering> {
self.partial_cmp(&**other)
}
@@ -240,6 +248,7 @@ impl PartialOrd<SerializedSignature> for [u8] {
impl Eq for SerializedSignature {}
impl core::hash::Hash for SerializedSignature {
+ #[inline]
fn hash<H: core::hash::Hasher>(&self, state: &mut H) { core::hash::Hash::hash(&**self, state) }
}
@@ -290,10 +299,12 @@ pub mod error {
}
impl From<Infallible> for DecodeError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for DecodeError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::SighashType(ref e) => write_err!(f, "non-standard signature hash type"; e),
@@ -305,6 +316,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for DecodeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::InvalidDer(ref e) => Some(e),
@@ -320,15 +332,18 @@ pub mod error {
pub struct InvalidDerError;
impl From<Infallible> for InvalidDerError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for InvalidDerError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "invalid DER encoding") }
}
#[cfg(feature = "std")]
impl std::error::Error for InvalidDerError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self {} = self;
None
@@ -348,11 +363,13 @@ pub mod error {
#[cfg(feature = "hex")]
impl From<Infallible> for ParseSignatureError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
#[cfg(feature = "hex")]
impl fmt::Display for ParseSignatureError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Hex(ref e) => write_err!(f, "signature hex decoding error"; e),
@@ -364,6 +381,7 @@ pub mod error {
#[cfg(feature = "hex")]
#[cfg(feature = "std")]
impl std::error::Error for ParseSignatureError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Hex(ref e) => Some(e),
diff --git a/crypto/src/sighash.rs b/crypto/src/sighash.rs
index bc634da1..1398c262 100644
--- a/crypto/src/sighash.rs
+++ b/crypto/src/sighash.rs
@@ -44,6 +44,7 @@ pub enum TapSighashType {
internals::serde_string_impl!(TapSighashType, "a TapSighashType data");
impl fmt::Display for TapSighashType {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::Default => "SIGHASH_DEFAULT",
@@ -61,6 +62,7 @@ impl fmt::Display for TapSighashType {
impl str::FromStr for TapSighashType {
type Err = SighashTypeParseError;
+ #[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"SIGHASH_DEFAULT" => Ok(Self::Default),
@@ -81,6 +83,7 @@ impl TapSighashType {
/// # Errors
///
/// This method fails if the provided sighash type is not valid.
+ #[inline]
pub fn from_consensus_u8(sighash_type: u8) -> Result<Self, InvalidSighashTypeError> {
Ok(match sighash_type {
0x00 => Self::Default,
@@ -121,6 +124,7 @@ pub enum EcdsaSighashType {
internals::serde_string_impl!(EcdsaSighashType, "a EcdsaSighashType data");
impl fmt::Display for EcdsaSighashType {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let s = match self {
Self::All => "SIGHASH_ALL",
@@ -137,6 +141,7 @@ impl fmt::Display for EcdsaSighashType {
impl str::FromStr for EcdsaSighashType {
type Err = SighashTypeParseError;
+ #[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"SIGHASH_ALL" => Ok(Self::All),
@@ -157,6 +162,7 @@ impl EcdsaSighashType {
/// type (after masking with 0x1f), regardless of the ANYONECANPAY flag.
///
/// See: <https://github.com/bitcoin/bitcoin/blob/e486597/src/script/interpreter.cpp#L1618-L1619>
+ #[inline]
pub fn is_single(&self) -> bool { matches!(self, Self::Single | Self::SinglePlusAnyoneCanPay) }
/// Constructs a new [`EcdsaSighashType`] from a raw `u32`.
@@ -168,6 +174,7 @@ impl EcdsaSighashType {
/// `EcdsaSighashType::from_consensus(n) as u32 != n` for non-standard values of `n`. While
/// verifying signatures, the user should retain the `n` and use it to compute the signature hash
/// message.
+ #[inline]
pub fn from_consensus(n: u32) -> Self {
// In Bitcoin Core, the SignatureHash function will mask the (int32) value with
// 0x1f to (apparently) deactivate ACP when checking for SINGLE and NONE bits.
@@ -193,6 +200,7 @@ impl EcdsaSighashType {
/// # Errors
///
/// If `n` is a non-standard sighash value.
+ #[inline]
pub fn from_standard(n: u32) -> Result<Self, NonStandardSighashTypeError> {
match n {
// Standard sighashes, see https://github.com/bitcoin/bitcoin/blob/b805dbb0b9c90dadef0424e5b3bf86ac308e103e/src/script/interpreter.cpp#L189-L198
@@ -209,10 +217,12 @@ impl EcdsaSighashType {
/// Converts [`EcdsaSighashType`] to a `u32` sighash flag.
///
/// The returned value is guaranteed to be a valid according to standardness rules.
+ #[inline]
pub fn to_u32(self) -> u32 { self as u32 }
}
impl From<EcdsaSighashType> for TapSighashType {
+ #[inline]
fn from(s: EcdsaSighashType) -> Self {
match s {
EcdsaSighashType::All => Self::All,
@@ -237,10 +247,12 @@ pub mod error {
pub struct InvalidSighashTypeError(pub(crate) u32);
impl From<Infallible> for InvalidSighashTypeError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for InvalidSighashTypeError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "invalid sighash type {}", self.0)
}
@@ -248,6 +260,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for InvalidSighashTypeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self(_) = self;
None
@@ -260,10 +273,12 @@ pub mod error {
pub struct NonStandardSighashTypeError(pub(crate) u32);
impl From<Infallible> for NonStandardSighashTypeError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for NonStandardSighashTypeError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "non-standard sighash type {}", self.0)
}
@@ -271,6 +286,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for NonStandardSighashTypeError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self(_) = self;
None
@@ -288,10 +304,12 @@ pub mod error {
}
impl From<Infallible> for SighashTypeParseError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for SighashTypeParseError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.unrecognized.display_cannot_parse("SIGHASH string"))
}
@@ -299,6 +317,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for SighashTypeParseError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
let Self { unrecognized: _ } = self;
None
@@ -308,6 +327,7 @@ pub mod error {
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for EcdsaSighashType {
+ #[inline]
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let choice = u.int_in_range(0..=5)?;
match choice {
@@ -323,6 +343,7 @@ impl<'a> Arbitrary<'a> for EcdsaSighashType {
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for TapSighashType {
+ #[inline]
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let choice = u.int_in_range(0..=6)?;
match choice {
diff --git a/crypto/src/taproot.rs b/crypto/src/taproot.rs
index 9938e37b..2cd0bab5 100644
--- a/crypto/src/taproot.rs
+++ b/crypto/src/taproot.rs
@@ -76,6 +76,7 @@ impl Signature {
///
/// This returns a type with an API very similar to that of `Box<[u8]>`.
/// You can get a slice from it using deref coercions or turn it into an iterator.
+ #[inline]
pub fn serialize(self) -> SerializedSignature {
let mut buf = [0; MAX_LEN];
let ser_sig = self.signature.to_byte_array();
@@ -94,6 +95,7 @@ impl Signature {
///
/// Note: this allocates on the heap, prefer [`serialize`](Self::serialize) if vec is not needed.
#[cfg(feature = "alloc")]
+ #[inline]
pub fn to_vec(self) -> Vec<u8> {
let mut ser_sig = self.signature.as_ref().to_vec();
// If default sighash type, don't add extra sighash byte
@@ -106,6 +108,7 @@ impl Signature {
#[cfg(feature = "hex")]
impl fmt::Display for Signature {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&self.serialize(), f)
}
@@ -113,6 +116,7 @@ impl fmt::Display for Signature {
#[cfg(feature = "hex")]
impl fmt::LowerHex for Signature {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::LowerHex::fmt(&self.serialize(), f)
}
@@ -120,6 +124,7 @@ impl fmt::LowerHex for Signature {
#[cfg(feature = "hex")]
impl fmt::UpperHex for Signature {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::UpperHex::fmt(&self.serialize(), f)
}
@@ -129,6 +134,7 @@ impl fmt::UpperHex for Signature {
impl FromStr for Signature {
type Err = ParseSignatureError;
+ #[inline]
fn from_str(s: &str) -> Result<Self, Self::Err> {
match hex::decode_to_array::<64>(s) {
Ok(bytes) => Self::from_slice(&bytes).map_err(ParseSignatureError::Decode),
@@ -217,6 +223,7 @@ impl SerializedSignature {
}
impl fmt::Debug for SerializedSignature {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
#[cfg(feature = "hex")]
{
@@ -234,6 +241,7 @@ impl fmt::Debug for SerializedSignature {
#[cfg(feature = "hex")]
impl fmt::Display for SerializedSignature {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fmt::LowerHex::fmt(self, f) }
}
@@ -269,20 +277,24 @@ impl PartialEq<SerializedSignature> for [u8] {
}
impl PartialOrd for SerializedSignature {
+ #[inline]
fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> { Some(self.cmp(other)) }
}
impl Ord for SerializedSignature {
+ #[inline]
fn cmp(&self, other: &Self) -> core::cmp::Ordering { (**self).cmp(&**other) }
}
impl PartialOrd<[u8]> for SerializedSignature {
+ #[inline]
fn partial_cmp(&self, other: &[u8]) -> Option<core::cmp::Ordering> {
(**self).partial_cmp(other)
}
}
impl PartialOrd<SerializedSignature> for [u8] {
+ #[inline]
fn partial_cmp(&self, other: &SerializedSignature) -> Option<core::cmp::Ordering> {
self.partial_cmp(&**other)
}
@@ -291,6 +303,7 @@ impl PartialOrd<SerializedSignature> for [u8] {
impl Eq for SerializedSignature {}
impl core::hash::Hash for SerializedSignature {
+ #[inline]
fn hash<H: core::hash::Hasher>(&self, state: &mut H) { (**self).hash(state) }
}
@@ -328,18 +341,21 @@ impl<'a> IntoIterator for &'a SerializedSignature {
}
impl From<Signature> for SerializedSignature {
+ #[inline]
fn from(value: Signature) -> Self { Self::from_signature(value) }
}
impl TryFrom<SerializedSignature> for Signature {
type Error = SigFromSliceError;
+ #[inline]
fn try_from(value: SerializedSignature) -> Result<Self, Self::Error> { value.to_signature() }
}
impl<'a> TryFrom<&'a SerializedSignature> for Signature {
type Error = SigFromSliceError;
+ #[inline]
fn try_from(value: &'a SerializedSignature) -> Result<Self, Self::Error> {
value.to_signature()
}
@@ -455,10 +471,12 @@ pub mod error {
}
impl From<Infallible> for SigFromSliceError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
impl fmt::Display for SigFromSliceError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::SighashType(ref e) => write_err!(f, "sighash"; e),
@@ -470,6 +488,7 @@ pub mod error {
#[cfg(feature = "std")]
impl std::error::Error for SigFromSliceError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::SighashType(ref e) => Some(e),
@@ -493,11 +512,13 @@ pub mod error {
#[cfg(feature = "hex")]
impl From<Infallible> for ParseSignatureError {
+ #[inline]
fn from(never: Infallible) -> Self { match never {} }
}
#[cfg(feature = "hex")]
impl fmt::Display for ParseSignatureError {
+ #[inline]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::InvalidLength(len) => write!(
@@ -514,6 +535,7 @@ pub mod error {
#[cfg(feature = "hex")]
#[cfg(feature = "std")]
impl std::error::Error for ParseSignatureError {
+ #[inline]
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::InvalidLength(_) => None,
@@ -526,6 +548,7 @@ pub mod error {
#[cfg(feature = "arbitrary")]
impl<'a> Arbitrary<'a> for Signature {
+ #[inline]
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
let arbitrary_bytes: [u8; secp256k1::constants::SCHNORR_SIGNATURE_SIZE] = u.arbitrary()?;
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.