chore: checkpoint before Python removal

This commit is contained in:
2026-03-26 22:33:59 +00:00
parent 683cec9307
commit e568ddf82a
29972 changed files with 11269302 additions and 2 deletions

31
vendor/signature/src/encoding.rs vendored Normal file
View File

@@ -0,0 +1,31 @@
//! Encoding support.
#[cfg(feature = "alloc")]
use alloc::vec::Vec;
/// Support for decoding/encoding signatures as bytes.
pub trait SignatureEncoding:
Clone + Sized + for<'a> TryFrom<&'a [u8]> + TryInto<Self::Repr>
{
/// Byte representation of a signature.
type Repr: 'static + AsRef<[u8]> + Clone + Send + Sync;
/// Encode signature as its byte representation.
fn to_bytes(&self) -> Self::Repr {
self.clone()
.try_into()
.ok()
.expect("signature encoding error")
}
/// Encode signature as a byte vector.
#[cfg(feature = "alloc")]
fn to_vec(&self) -> Vec<u8> {
self.to_bytes().as_ref().to_vec()
}
/// Get the length of this signature when encoded.
fn encoded_len(&self) -> usize {
self.to_bytes().as_ref().len()
}
}

116
vendor/signature/src/error.rs vendored Normal file
View File

@@ -0,0 +1,116 @@
//! Signature error types
use core::fmt::{self, Debug, Display};
#[cfg(feature = "std")]
use std::boxed::Box;
/// Result type.
///
/// A result with the `signature` crate's [`Error`] type.
pub type Result<T> = core::result::Result<T, Error>;
/// Signature errors.
///
/// This type is deliberately opaque as to avoid sidechannel leakage which
/// could potentially be used recover signing private keys or forge signatures
/// (e.g. [BB'06]).
///
/// When the `std` feature is enabled, it impls [`std::error::Error`] and
/// supports an optional [`std::error::Error::source`], which can be used by
/// things like remote signers (e.g. HSM, KMS) to report I/O or auth errors.
///
/// [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher
#[derive(Default)]
#[non_exhaustive]
pub struct Error {
/// Source of the error (if applicable).
#[cfg(feature = "std")]
source: Option<Box<dyn std::error::Error + Send + Sync + 'static>>,
}
impl Error {
/// Create a new error with no associated source
pub fn new() -> Self {
Self::default()
}
/// Create a new error with an associated source.
///
/// **NOTE:** The "source" should **NOT** be used to propagate cryptographic
/// errors e.g. signature parsing or verification errors. The intended use
/// cases are for propagating errors related to external signers, e.g.
/// communication/authentication errors with HSMs, KMS, etc.
#[cfg(feature = "std")]
pub fn from_source(
source: impl Into<Box<dyn std::error::Error + Send + Sync + 'static>>,
) -> Self {
Self {
source: Some(source.into()),
}
}
}
impl Debug for Error {
#[cfg(not(feature = "std"))]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("signature::Error {}")
}
#[cfg(feature = "std")]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("signature::Error { source: ")?;
if let Some(source) = &self.source {
write!(f, "Some({})", source)?;
} else {
f.write_str("None")?;
}
f.write_str(" }")
}
}
impl Display for Error {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("signature error")?;
#[cfg(feature = "std")]
{
if let Some(source) = &self.source {
write!(f, ": {}", source)?;
}
}
Ok(())
}
}
#[cfg(feature = "std")]
impl From<Box<dyn std::error::Error + Send + Sync + 'static>> for Error {
fn from(source: Box<dyn std::error::Error + Send + Sync + 'static>) -> Error {
Self::from_source(source)
}
}
#[cfg(feature = "rand_core")]
impl From<rand_core::Error> for Error {
#[cfg(not(feature = "std"))]
fn from(_source: rand_core::Error) -> Error {
Error::new()
}
#[cfg(feature = "std")]
fn from(source: rand_core::Error) -> Error {
Error::from_source(source)
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.source
.as_ref()
.map(|source| source.as_ref() as &(dyn std::error::Error + 'static))
}
}

70
vendor/signature/src/hazmat.rs vendored Normal file
View File

@@ -0,0 +1,70 @@
//! Hazardous Materials: low-level APIs which can be insecure if misused.
//!
//! The traits in this module are not generally recommended, and should only be
//! used in special cases where they are specifically needed.
//!
//! Using them incorrectly can introduce security vulnerabilities. Please
//! carefully read the documentation before attempting to use them.
use crate::Error;
#[cfg(feature = "rand_core")]
use crate::rand_core::CryptoRngCore;
/// Sign the provided message prehash, returning a digital signature.
pub trait PrehashSigner<S> {
/// Attempt to sign the given message digest, returning a digital signature
/// on success, or an error if something went wrong.
///
/// The `prehash` parameter should be the output of a secure cryptographic
/// hash function.
///
/// This API takes a `prehash` byte slice as there can potentially be many
/// compatible lengths for the message digest for a given concrete signature
/// algorithm.
///
/// Allowed lengths are algorithm-dependent and up to a particular
/// implementation to decide.
fn sign_prehash(&self, prehash: &[u8]) -> Result<S, Error>;
}
/// Sign the provided message prehash using the provided external randomness source, returning a digital signature.
#[cfg(feature = "rand_core")]
pub trait RandomizedPrehashSigner<S> {
/// Attempt to sign the given message digest, returning a digital signature
/// on success, or an error if something went wrong.
///
/// The `prehash` parameter should be the output of a secure cryptographic
/// hash function.
///
/// This API takes a `prehash` byte slice as there can potentially be many
/// compatible lengths for the message digest for a given concrete signature
/// algorithm.
///
/// Allowed lengths are algorithm-dependent and up to a particular
/// implementation to decide.
fn sign_prehash_with_rng(
&self,
rng: &mut impl CryptoRngCore,
prehash: &[u8],
) -> Result<S, Error>;
}
/// Verify the provided message prehash using `Self` (e.g. a public key)
pub trait PrehashVerifier<S> {
/// Use `Self` to verify that the provided signature for a given message
/// `prehash` is authentic.
///
/// The `prehash` parameter should be the output of a secure cryptographic
/// hash function.
///
/// Returns `Error` if it is inauthentic or some other error occurred, or
/// otherwise returns `Ok(())`.
///
/// # ⚠️ Security Warning
///
/// If `prehash` is something other than the output of a cryptographically
/// secure hash function, an attacker can potentially forge signatures by
/// solving a system of linear equations.
fn verify_prehash(&self, prehash: &[u8], signature: &S) -> Result<(), Error>;
}

29
vendor/signature/src/keypair.rs vendored Normal file
View File

@@ -0,0 +1,29 @@
//! Signing keypairs.
/// Signing keypair with an associated verifying key.
///
/// This represents a type which holds both a signing key and a verifying key.
pub trait Keypair {
/// Verifying key type for this keypair.
type VerifyingKey: Clone;
/// Get the verifying key which can verify signatures produced by the
/// signing key portion of this keypair.
fn verifying_key(&self) -> Self::VerifyingKey;
}
/// Signing keypair with an associated verifying key.
///
/// This represents a type which holds both a signing key and a verifying key.
pub trait KeypairRef: AsRef<Self::VerifyingKey> {
/// Verifying key type for this keypair.
type VerifyingKey: Clone;
}
impl<K: KeypairRef> Keypair for K {
type VerifyingKey = <Self as KeypairRef>::VerifyingKey;
fn verifying_key(&self) -> Self::VerifyingKey {
self.as_ref().clone()
}
}

158
vendor/signature/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,158 @@
#![no_std]
#![doc = include_str!("../README.md")]
#![doc(
html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg",
html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg"
)]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![forbid(unsafe_code)]
#![warn(
clippy::mod_module_files,
clippy::unwrap_used,
missing_docs,
rust_2018_idioms,
unused_lifetimes,
unused_qualifications
)]
//! # Design
//!
//! This crate provides a common set of traits for signing and verifying
//! digital signatures intended to be implemented by libraries which produce
//! or contain implementations of digital signature algorithms, and used by
//! libraries which want to produce or verify digital signatures while
//! generically supporting any compatible backend.
//!
//! ## Goals
//!
//! The traits provided by this crate were designed with the following goals
//! in mind:
//!
//! - Provide an easy-to-use, misuse resistant API optimized for consumers
//! (as opposed to implementers) of its traits.
//! - Support common type-safe wrappers around "bag-of-bytes" representations
//! which can be directly parsed from or written to the "wire".
//! - Expose a trait/object-safe API where signers/verifiers spanning multiple
//! homogeneous provider implementations can be seamlessly leveraged together
//! in the same logical "keyring" so long as they operate on the same
//! underlying signature type.
//! - Allow one provider type to potentially implement support (including
//! being generic over) several signature types.
//! - Keep signature algorithm customizations / "knobs" out-of-band from the
//! signing/verification APIs, ideally pushing such concerns into the type
//! system so that algorithm mismatches are caught as type errors.
//! - Opaque error type which minimizes information leaked from cryptographic
//! failures, as "rich" error types in these scenarios are often a source
//! of sidechannel information for attackers (e.g. [BB'06])
//!
//! [BB'06]: https://en.wikipedia.org/wiki/Daniel_Bleichenbacher
//!
//! ## Implementation
//!
//! To accomplish the above goals, the [`Signer`] and [`Verifier`] traits
//! provided by this are generic over a signature value, and use generic
//! parameters rather than associated types. Notably, they use such a parameter
//! for the return value, allowing it to be inferred by the type checker based
//! on the desired signature type.
//!
//! ## Alternatives considered
//!
//! This crate is based on many years of exploration of how to encapsulate
//! digital signature systems in the most flexible, developer-friendly way.
//! During that time many design alternatives were explored, tradeoffs
//! compared, and ultimately the provided API was selected.
//!
//! The tradeoffs made in this API have all been to improve simplicity,
//! ergonomics, type safety, and flexibility for *consumers* of the traits.
//! At times, this has come at a cost to implementers. Below are some concerns
//! we are cognizant of which were considered in the design of the API:
//!
//! - "Bag-of-bytes" serialization precludes signature providers from using
//! their own internal representation of a signature, which can be helpful
//! for many reasons (e.g. advanced signature system features like batch
//! verification).
//! - Associated types, rather than generic parameters of traits, could allow
//! more customization of the types used by a particular signature system,
//! e.g. using custom error types.
//!
//! It may still make sense to continue to explore the above tradeoffs, but
//! with a *new* set of traits which are intended to be implementor-friendly,
//! rather than consumer friendly. The existing [`Signer`] and [`Verifier`]
//! traits could have blanket impls for the "provider-friendly" traits.
//! However, as noted above this is a design space easily explored after
//! stabilizing the consumer-oriented traits, and thus we consider these
//! more important.
//!
//! That said, below are some caveats of trying to design such traits, and
//! why we haven't actively pursued them:
//!
//! - Generics in the return position are already used to select which trait
//! impl to use, i.e. for a particular signature algorithm/system. Avoiding
//! a unified, concrete signature type adds another dimension to complexity
//! and compiler errors, and in our experience makes them unsuitable for this
//! sort of API. We believe such an API is the natural one for signature
//! systems, reflecting the natural way they are written absent a trait.
//! - Associated types preclude multiple implementations of the same trait.
//! These parameters are common in signature systems, notably ones which
//! support different serializations of a signature (e.g. raw vs ASN.1).
//! - Digital signatures are almost always larger than the present 32-entry
//! trait impl limitation on array types, which complicates bounds
//! for these types (particularly things like `From` or `Borrow` bounds).
//!
//! ## Unstable features
//!
//! Despite being post-1.0, this crate includes off-by-default unstable
//! optional features, each of which depends on a pre-1.0
//! crate.
//!
//! These features are considered exempt from SemVer. See the
//! [SemVer policy](#semver-policy) above for more information.
//!
//! The following unstable features are presently supported:
//!
//! - `digest`: enables the [`DigestSigner`] and [`DigestVerifier`]
//! traits which are based on the [`Digest`] trait from the [`digest`] crate.
//! These traits are used for representing signature systems based on the
//! [Fiat-Shamir heuristic] which compute a random challenge value to sign
//! by computing a cryptographically secure digest of the input message.
//! - `rand_core`: enables the [`RandomizedSigner`] trait for signature
//! systems which rely on a cryptographically secure random number generator
//! for security.
//!
//! NOTE: the [`async-signature`] crate contains experimental `async` support
//! for [`Signer`] and [`DigestSigner`].
//!
//! [`async-signature`]: https://docs.rs/async-signature
//! [`digest`]: https://docs.rs/digest/
//! [`Digest`]: https://docs.rs/digest/latest/digest/trait.Digest.html
//! [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
pub mod hazmat;
mod encoding;
mod error;
mod keypair;
mod signer;
mod verifier;
#[cfg(feature = "digest")]
mod prehash_signature;
pub use crate::{encoding::*, error::*, keypair::*, signer::*, verifier::*};
#[cfg(feature = "derive")]
pub use derive::{Signer, Verifier};
#[cfg(all(feature = "derive", feature = "digest"))]
pub use derive::{DigestSigner, DigestVerifier};
#[cfg(feature = "digest")]
pub use {crate::prehash_signature::*, digest};
#[cfg(feature = "rand_core")]
pub use rand_core;

View File

@@ -0,0 +1,31 @@
//! `PrehashSignature` trait.
/// For intra-doc link resolution.
#[allow(unused_imports)]
use crate::{
signer::{DigestSigner, Signer},
verifier::{DigestVerifier, Verifier},
};
/// Marker trait for `Signature` types computable as `𝐒(𝐇(𝒎))`
/// i.e. ones which prehash a message to be signed as `𝐇(𝒎)`
///
/// Where:
///
/// - `𝐒`: signature algorithm
/// - `𝐇`: hash (a.k.a. digest) function
/// - `𝒎`: message
///
/// This approach is relatively common in signature schemes based on the
/// [Fiat-Shamir heuristic].
///
/// For signature types that implement this trait, when the `derive` crate
/// feature is enabled a custom derive for [`Signer`] is available for any
/// types that impl [`DigestSigner`], and likewise for deriving [`Verifier`] for
/// types which impl [`DigestVerifier`].
///
/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
pub trait PrehashSignature {
/// Preferred `Digest` algorithm to use when computing this signature type.
type Digest: digest::Digest;
}

118
vendor/signature/src/signer.rs vendored Normal file
View File

@@ -0,0 +1,118 @@
//! Traits for generating digital signatures
use crate::error::Error;
#[cfg(feature = "digest")]
use crate::digest::Digest;
#[cfg(feature = "rand_core")]
use crate::rand_core::CryptoRngCore;
/// Sign the provided message bytestring using `Self` (e.g. a cryptographic key
/// or connection to an HSM), returning a digital signature.
pub trait Signer<S> {
/// Sign the given message and return a digital signature
fn sign(&self, msg: &[u8]) -> S {
self.try_sign(msg).expect("signature operation failed")
}
/// Attempt to sign the given message, returning a digital signature on
/// success, or an error if something went wrong.
///
/// The main intended use case for signing errors is when communicating
/// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
fn try_sign(&self, msg: &[u8]) -> Result<S, Error>;
}
/// Sign the provided message bytestring using `&mut Self` (e.g. an evolving
/// cryptographic key such as a stateful hash-based signature), returning a
/// digital signature.
pub trait SignerMut<S> {
/// Sign the given message, update the state, and return a digital signature.
fn sign(&mut self, msg: &[u8]) -> S {
self.try_sign(msg).expect("signature operation failed")
}
/// Attempt to sign the given message, updating the state, and returning a
/// digital signature on success, or an error if something went wrong.
///
/// Signing can fail, e.g., if the number of time periods allowed by the
/// current key is exceeded.
fn try_sign(&mut self, msg: &[u8]) -> Result<S, Error>;
}
/// Blanket impl of [`SignerMut`] for all [`Signer`] types.
impl<S, T: Signer<S>> SignerMut<S> for T {
fn try_sign(&mut self, msg: &[u8]) -> Result<S, Error> {
T::try_sign(self, msg)
}
}
/// Sign the given prehashed message [`Digest`] using `Self`.
///
/// ## Notes
///
/// This trait is primarily intended for signature algorithms based on the
/// [Fiat-Shamir heuristic], a method for converting an interactive
/// challenge/response-based proof-of-knowledge protocol into an offline
/// digital signature through the use of a random oracle, i.e. a digest
/// function.
///
/// The security of such protocols critically rests upon the inability of
/// an attacker to solve for the output of the random oracle, as generally
/// otherwise such signature algorithms are a system of linear equations and
/// therefore doing so would allow the attacker to trivially forge signatures.
///
/// To prevent misuse which would potentially allow this to be possible, this
/// API accepts a [`Digest`] instance, rather than a raw digest value.
///
/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
#[cfg(feature = "digest")]
pub trait DigestSigner<D: Digest, S> {
/// Sign the given prehashed message [`Digest`], returning a signature.
///
/// Panics in the event of a signing error.
fn sign_digest(&self, digest: D) -> S {
self.try_sign_digest(digest)
.expect("signature operation failed")
}
/// Attempt to sign the given prehashed message [`Digest`], returning a
/// digital signature on success, or an error if something went wrong.
fn try_sign_digest(&self, digest: D) -> Result<S, Error>;
}
/// Sign the given message using the provided external randomness source.
#[cfg(feature = "rand_core")]
pub trait RandomizedSigner<S> {
/// Sign the given message and return a digital signature
fn sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> S {
self.try_sign_with_rng(rng, msg)
.expect("signature operation failed")
}
/// Attempt to sign the given message, returning a digital signature on
/// success, or an error if something went wrong.
///
/// The main intended use case for signing errors is when communicating
/// with external signers, e.g. cloud KMS, HSMs, or other hardware tokens.
fn try_sign_with_rng(&self, rng: &mut impl CryptoRngCore, msg: &[u8]) -> Result<S, Error>;
}
/// Combination of [`DigestSigner`] and [`RandomizedSigner`] with support for
/// computing a signature over a digest which requires entropy from an RNG.
#[cfg(all(feature = "digest", feature = "rand_core"))]
pub trait RandomizedDigestSigner<D: Digest, S> {
/// Sign the given prehashed message `Digest`, returning a signature.
///
/// Panics in the event of a signing error.
fn sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D) -> S {
self.try_sign_digest_with_rng(rng, digest)
.expect("signature operation failed")
}
/// Attempt to sign the given prehashed message `Digest`, returning a
/// digital signature on success, or an error if something went wrong.
fn try_sign_digest_with_rng(&self, rng: &mut impl CryptoRngCore, digest: D)
-> Result<S, Error>;
}

41
vendor/signature/src/verifier.rs vendored Normal file
View File

@@ -0,0 +1,41 @@
//! Trait for verifying digital signatures
use crate::error::Error;
#[cfg(feature = "digest")]
use crate::digest::Digest;
/// Verify the provided message bytestring using `Self` (e.g. a public key)
pub trait Verifier<S> {
/// Use `Self` to verify that the provided signature for a given message
/// bytestring is authentic.
///
/// Returns `Error` if it is inauthentic, or otherwise returns `()`.
fn verify(&self, msg: &[u8], signature: &S) -> Result<(), Error>;
}
/// Verify the provided signature for the given prehashed message [`Digest`]
/// is authentic.
///
/// ## Notes
///
/// This trait is primarily intended for signature algorithms based on the
/// [Fiat-Shamir heuristic], a method for converting an interactive
/// challenge/response-based proof-of-knowledge protocol into an offline
/// digital signature through the use of a random oracle, i.e. a digest
/// function.
///
/// The security of such protocols critically rests upon the inability of
/// an attacker to solve for the output of the random oracle, as generally
/// otherwise such signature algorithms are a system of linear equations and
/// therefore doing so would allow the attacker to trivially forge signatures.
///
/// To prevent misuse which would potentially allow this to be possible, this
/// API accepts a [`Digest`] instance, rather than a raw digest value.
///
/// [Fiat-Shamir heuristic]: https://en.wikipedia.org/wiki/Fiat%E2%80%93Shamir_heuristic
#[cfg(feature = "digest")]
pub trait DigestVerifier<D: Digest, S> {
/// Verify the signature against the given [`Digest`] output.
fn verify_digest(&self, digest: D, signature: &S) -> Result<(), Error>;
}