crypto: Remove alloc feature gate from taproot module
What changed, and why it matters
This change is a routine code cleanup, not a security fix. It removes an overly broad feature gate so that parts of the Taproot cryptographic module are available even when the optional 'alloc' feature is disabled, while keeping functions that actually need memory allocation behind the gate. There is no indication it fixes a vulnerability.
No security action needed. Treat as normal maintenance; review for build/compilation issues in no-alloc configurations if integrating this change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors feature gating in rust-bitcoin’s crypto/taproot module. Previously the entire module was hidden unless the ‘alloc’ feature was enabled. Now the module is always compiled, and only items that require Vec/String/hex formatting are gated with #[cfg(feature = “alloc”)]. This aligns the module with the existing ecdsa module and improves no-std/no-alloc support. No unsafe code, cryptographic algorithm changes, or bug fixes are present.
Changed components
crypto/src/lib.rscrypto/src/taproot.rsInspect captured patch +8 / −1
diff --git a/crypto/src/lib.rs b/crypto/src/lib.rs
index 880c33fa..85b61f4d 100644
--- a/crypto/src/lib.rs
+++ b/crypto/src/lib.rs
@@ -26,7 +26,6 @@ pub extern crate secp256k1;
pub mod ecdsa;
pub mod key;
pub mod sighash;
-#[cfg(feature = "alloc")]
pub mod taproot;
#[doc(inline)]
diff --git a/crypto/src/taproot.rs b/crypto/src/taproot.rs
index e2a91d42..573bee9f 100644
--- a/crypto/src/taproot.rs
+++ b/crypto/src/taproot.rs
@@ -4,6 +4,7 @@
//!
//! This module provides Taproot signatures used by Bitcoin that can be roundtrip (de)serialized.
+#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use core::borrow::Borrow;
use core::fmt;
@@ -13,6 +14,7 @@ use core::str::FromStr;
#[cfg(feature = "arbitrary")]
use arbitrary::{Arbitrary, Unstructured};
use internals::array::ArrayExt;
+#[cfg(feature = "alloc")]
use internals::impl_to_hex_from_lower_hex;
pub use self::into_iter::IntoIter;
@@ -84,6 +86,7 @@ impl Signature {
/// Serializes the signature.
///
/// Note: this allocates on the heap, prefer [`serialize`](Self::serialize) if vec is not needed.
+ #[cfg(feature = "alloc")]
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
@@ -218,6 +221,7 @@ impl fmt::LowerHex for SerializedSignature {
self.fmt_internal(f, hex_unstable::Case::Lower)
}
}
+#[cfg(feature = "alloc")]
impl_to_hex_from_lower_hex!(SerializedSignature, |signature: &SerializedSignature| signature.len
* 2);
@@ -523,6 +527,7 @@ impl<'a> Arbitrary<'a> for Signature {
#[cfg(test)]
mod tests {
+ #[cfg(feature = "alloc")]
use alloc::string::ToString;
use super::*;
@@ -558,6 +563,7 @@ mod tests {
}
}
+ #[cfg(feature = "alloc")]
const SIG_STRINGS: &[&str] = &[
// default sighash type
"abababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababababab",
@@ -569,6 +575,7 @@ mod tests {
];
#[test]
+ #[cfg(feature = "alloc")]
fn signature_hex_roundtrip() {
for &want in SIG_STRINGS {
let sig = want.parse::<Signature>().unwrap();
@@ -588,6 +595,7 @@ mod tests {
}
#[test]
+ #[cfg(feature = "alloc")]
fn serialized_signature_hex() {
for &want in SIG_STRINGS {
let sig = want.parse::<Signature>().unwrap();
Why this scored 18/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.