Revert "ecdsa: use blanket impl from signature 3 (#945)" (#955)

This reverts commit 8e6bb26c26.
This commit is contained in:
Arthur Gautier
2025-05-04 06:17:56 -07:00
committed by GitHub
parent 692353d7c6
commit d2a93b3d5a
8 changed files with 178 additions and 111 deletions
-8
View File
@@ -4,14 +4,6 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## 0.17.0 (UNRELEASED)
### Changed
- `DigestPrimitive` was moved off of hazmat ([#945])
- `DigestPrimitive` has been renamed `DigestAlgorithm` ([#945])
[#945]: https://github.com/RustCrypto/signatures/pull/945
## 0.16.9 (2023-11-16)
### Changed
- Loosen `signature` bound to `2.0, <2.3` ([#756])
-1
View File
@@ -45,7 +45,6 @@ digest = ["dep:digest", "elliptic-curve/digest", "signature/digest"]
hazmat = []
pkcs8 = ["digest", "elliptic-curve/pkcs8", "der"]
pem = ["elliptic-curve/pem", "pkcs8"]
rfc6979 = ["arithmetic", "digest", "dep:rfc6979"]
serde = ["elliptic-curve/serde", "pkcs8", "serdect"]
signing = ["arithmetic", "digest", "hazmat", "rfc6979"]
verifying = ["arithmetic", "digest", "hazmat"]
+2 -2
View File
@@ -382,10 +382,10 @@ fn find_scalar_range(outer: &[u8], inner: &[u8]) -> Result<Range<usize>> {
Ok(Range { start, end })
}
#[cfg(feature = "digest")]
#[cfg(all(feature = "digest", feature = "hazmat"))]
impl<C> signature::PrehashSignature for Signature<C>
where
C: EcdsaCurve + crate::DigestAlgorithm,
C: EcdsaCurve + crate::hazmat::DigestPrimitive,
MaxSize<C>: ArraySize,
<FieldBytesSize<C> as Add>::Output: Add<MaxOverhead> + ArraySize,
{
+34 -9
View File
@@ -27,21 +27,46 @@ use {
},
};
#[cfg(feature = "rfc6979")]
#[cfg(feature = "digest")]
use {
elliptic_curve::FieldBytesEncoding,
signature::digest::{Digest, FixedOutput, FixedOutputReset, core_api::BlockSizeUser},
elliptic_curve::FieldBytesSize,
signature::{
PrehashSignature,
digest::{Digest, FixedOutput, FixedOutputReset, core_api::BlockSizeUser},
},
};
#[cfg(any(feature = "arithmetic", feature = "rfc6979"))]
#[cfg(feature = "rfc6979")]
use elliptic_curve::FieldBytesEncoding;
#[cfg(any(feature = "arithmetic", feature = "digest"))]
use crate::{Signature, elliptic_curve::array::ArraySize};
/// Bind a preferred [`Digest`] algorithm to an elliptic curve type.
///
/// Generally there is a preferred variety of the SHA-2 family used with ECDSA
/// for a particular elliptic curve.
///
/// This trait can be used to specify it, and with it receive a blanket impl of
/// [`PrehashSignature`], used by [`signature_derive`][1]) for the [`Signature`]
/// type for a particular elliptic curve.
///
/// [1]: https://github.com/RustCrypto/traits/tree/master/signature/derive
#[cfg(feature = "digest")]
#[deprecated(
since = "0.17.0",
note = "`DigestAlgorithm` is no longer in `hazmat`, please use `ecdsa::DigestAlgorithm` instead"
)]
pub use crate::DigestAlgorithm;
pub trait DigestPrimitive: EcdsaCurve {
/// Preferred digest to use when computing ECDSA signatures for this
/// elliptic curve. This is typically a member of the SHA-2 family.
type Digest: BlockSizeUser + Digest + FixedOutput + FixedOutputReset;
}
#[cfg(feature = "digest")]
impl<C> PrehashSignature for Signature<C>
where
C: DigestPrimitive,
<FieldBytesSize<C> as core::ops::Add>::Output: ArraySize,
{
type Digest = C::Digest;
}
/// Partial implementation of the `bits2int` function as defined in
/// [RFC6979 § 2.3.2] as well as [SEC1] § 2.3.8.
+12 -42
View File
@@ -102,13 +102,9 @@ use {
};
#[cfg(feature = "digest")]
use {
digest::{
Digest, FixedOutput, FixedOutputReset,
const_oid::{AssociatedOid, ObjectIdentifier},
core_api::BlockSizeUser,
},
signature::PrehashSignature,
use digest::{
Digest,
const_oid::{AssociatedOid, ObjectIdentifier},
};
#[cfg(feature = "pkcs8")]
@@ -468,15 +464,15 @@ where
///
/// To support non-default digest algorithms, use the [`SignatureWithOid`]
/// type instead.
#[cfg(feature = "digest")]
#[cfg(all(feature = "digest", feature = "hazmat"))]
impl<C> AssociatedOid for Signature<C>
where
C: DigestAlgorithm,
C: hazmat::DigestPrimitive,
C::Digest: AssociatedOid,
{
const OID: ObjectIdentifier = match ecdsa_oid_for_digest(C::Digest::OID) {
Some(oid) => oid,
None => panic!("no RFC5758 ECDSA OID defined for DigestAlgorithm::Digest"),
None => panic!("no RFC5758 ECDSA OID defined for DigestPrimitive::Digest"),
};
}
@@ -725,14 +721,14 @@ where
}
/// NOTE: this implementation assumes the default digest for the given elliptic
/// curve as defined by [`DigestAlgorithm`].
/// curve as defined by [`hazmat::DigestPrimitive`].
///
/// When working with alternative digests, you will need to use e.g.
/// [`SignatureWithOid::new_with_digest`].
#[cfg(feature = "digest")]
#[cfg(all(feature = "digest", feature = "hazmat"))]
impl<C> SignatureEncoding for SignatureWithOid<C>
where
C: DigestAlgorithm,
C: hazmat::DigestPrimitive,
C::Digest: AssociatedOid,
SignatureSize<C>: ArraySize,
{
@@ -740,14 +736,14 @@ where
}
/// NOTE: this implementation assumes the default digest for the given elliptic
/// curve as defined by [`DigestAlgorithm`].
/// curve as defined by [`hazmat::DigestPrimitive`].
///
/// When working with alternative digests, you will need to use e.g.
/// [`SignatureWithOid::new_with_digest`].
#[cfg(feature = "digest")]
#[cfg(all(feature = "digest", feature = "hazmat"))]
impl<C> TryFrom<&[u8]> for SignatureWithOid<C>
where
C: DigestAlgorithm,
C: hazmat::DigestPrimitive,
C::Digest: AssociatedOid,
SignatureSize<C>: ArraySize,
{
@@ -782,29 +778,3 @@ const fn ecdsa_oid_for_digest(digest_oid: ObjectIdentifier) -> Option<ObjectIden
_ => None,
}
}
/// Bind a preferred [`Digest`] algorithm to an elliptic curve type.
///
/// Generally there is a preferred variety of the SHA-2 family used with ECDSA
/// for a particular elliptic curve.
///
/// This trait can be used to specify it, and with it receive a blanket impl of
/// [`PrehashSignature`], used by [`signature_derive`][1]) for the [`Signature`]
/// type for a particular elliptic curve.
///
/// [1]: https://github.com/RustCrypto/traits/tree/master/signature/derive
#[cfg(feature = "digest")]
pub trait DigestAlgorithm: EcdsaCurve {
/// Preferred digest to use when computing ECDSA signatures for this
/// elliptic curve. This is typically a member of the SHA-2 family.
type Digest: BlockSizeUser + Digest + FixedOutput + FixedOutputReset;
}
#[cfg(feature = "digest")]
impl<C> PrehashSignature for Signature<C>
where
C: DigestAlgorithm,
<FieldBytesSize<C> as Add>::Output: ArraySize,
{
type Digest = C::Digest;
}
+25 -10
View File
@@ -7,7 +7,7 @@ use {
crate::{SigningKey, hazmat::sign_prehashed_rfc6979},
elliptic_curve::{FieldBytes, subtle::CtOption},
signature::{
DigestSigner, RandomizedDigestSigner,
DigestSigner, RandomizedDigestSigner, Signer,
digest::FixedOutput,
hazmat::{PrehashSigner, RandomizedPrehashSigner},
rand_core::TryCryptoRng,
@@ -28,7 +28,10 @@ use {
#[cfg(any(feature = "signing", feature = "verifying"))]
use {
crate::{DigestAlgorithm, EcdsaCurve, Signature, SignatureSize, hazmat::bits2field},
crate::{
EcdsaCurve, Signature, SignatureSize,
hazmat::{DigestPrimitive, bits2field},
},
elliptic_curve::{CurveArithmetic, Scalar, array::ArraySize, ops::Invert},
signature::digest::Digest,
};
@@ -97,7 +100,7 @@ impl RecoveryId {
signature: &Signature<C>,
) -> Result<Self>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
AffinePoint<C>: DecompressPoint<C> + FromEncodedPoint<C> + ToEncodedPoint<C>,
FieldBytesSize<C>: sec1::ModulusSize,
SignatureSize<C>: ArraySize,
@@ -176,7 +179,7 @@ impl From<RecoveryId> for u8 {
#[cfg(feature = "signing")]
impl<C> SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
@@ -225,7 +228,7 @@ where
#[cfg(feature = "signing")]
impl<C, D> DigestSigner<D, (Signature<C>, RecoveryId)> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
D: Digest,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
@@ -238,7 +241,7 @@ where
#[cfg(feature = "signing")]
impl<C> RandomizedPrehashSigner<(Signature<C>, RecoveryId)> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
@@ -254,7 +257,7 @@ where
#[cfg(feature = "signing")]
impl<C, D> RandomizedDigestSigner<D, (Signature<C>, RecoveryId)> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
D: Digest + FixedOutput,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
@@ -271,7 +274,7 @@ where
#[cfg(feature = "signing")]
impl<C> PrehashSigner<(Signature<C>, RecoveryId)> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
@@ -280,6 +283,18 @@ where
}
}
#[cfg(feature = "signing")]
impl<C> Signer<(Signature<C>, RecoveryId)> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign(&self, msg: &[u8]) -> Result<(Signature<C>, RecoveryId)> {
self.sign_recoverable(msg)
}
}
#[cfg(feature = "verifying")]
impl<C> VerifyingKey<C>
where
@@ -291,14 +306,14 @@ where
/// Recover a [`VerifyingKey`] from the given message, signature, and
/// [`RecoveryId`].
///
/// The message is first hashed using this curve's [`DigestAlgorithm`].
/// The message is first hashed using this curve's [`DigestPrimitive`].
pub fn recover_from_msg(
msg: &[u8],
signature: &Signature<C>,
recovery_id: RecoveryId,
) -> Result<Self>
where
C: DigestAlgorithm,
C: DigestPrimitive,
{
Self::recover_from_digest(C::Digest::new_with_prefix(msg), signature, recovery_id)
}
+77 -33
View File
@@ -1,9 +1,8 @@
//! ECDSA signing: producing signatures using a [`SigningKey`].
use crate::{
DigestAlgorithm, EcdsaCurve, Error, Result, Signature, SignatureSize, SignatureWithOid,
ecdsa_oid_for_digest,
hazmat::{bits2field, sign_prehashed_rfc6979},
EcdsaCurve, Error, Result, Signature, SignatureSize, SignatureWithOid, ecdsa_oid_for_digest,
hazmat::{DigestPrimitive, bits2field, sign_prehashed_rfc6979},
};
use core::fmt::{self, Debug};
use digest::{Digest, FixedOutput, const_oid::AssociatedOid};
@@ -16,7 +15,7 @@ use elliptic_curve::{
zeroize::{Zeroize, ZeroizeOnDrop},
};
use signature::{
DigestSigner, RandomizedDigestSigner, Signer,
DigestSigner, RandomizedDigestSigner, RandomizedSigner, Signer,
hazmat::{PrehashSigner, RandomizedPrehashSigner},
rand_core::{CryptoRng, TryCryptoRng},
};
@@ -140,7 +139,7 @@ where
/// [RFC6979 § 3.2]: https://tools.ietf.org/html/rfc6979#section-3
impl<C, D> DigestSigner<D, Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
D: Digest + FixedOutput,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
@@ -156,7 +155,7 @@ where
/// [RFC6979 § 3.2]: https://tools.ietf.org/html/rfc6979#section-3
impl<C> PrehashSigner<Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
@@ -166,9 +165,24 @@ where
}
}
/// Sign message using a deterministic ephemeral scalar (`k`)
/// computed using the algorithm described in [RFC6979 § 3.2].
///
/// [RFC6979 § 3.2]: https://tools.ietf.org/html/rfc6979#section-3
impl<C> Signer<Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign(&self, msg: &[u8]) -> Result<Signature<C>> {
self.try_sign_digest(C::Digest::new_with_prefix(msg))
}
}
impl<C, D> RandomizedDigestSigner<D, Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
D: Digest + FixedOutput,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
@@ -184,7 +198,7 @@ where
impl<C> RandomizedPrehashSigner<Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
@@ -208,9 +222,25 @@ where
}
}
impl<C> RandomizedSigner<Signature<C>> for SigningKey<C>
where
Self: RandomizedDigestSigner<C::Digest, Signature<C>>,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign_with_rng<R: TryCryptoRng + ?Sized>(
&self,
rng: &mut R,
msg: &[u8],
) -> Result<Signature<C>> {
self.try_sign_digest_with_rng(rng, C::Digest::new_with_prefix(msg))
}
}
impl<C, D> DigestSigner<D, SignatureWithOid<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
D: AssociatedOid + Digest + FixedOutput,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
@@ -224,7 +254,7 @@ where
impl<C> Signer<SignatureWithOid<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
C::Digest: AssociatedOid,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
@@ -237,7 +267,7 @@ where
#[cfg(feature = "der")]
impl<C> PrehashSigner<der::Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
der::MaxSize<C>: ArraySize,
@@ -248,10 +278,44 @@ where
}
}
#[cfg(feature = "der")]
impl<C> Signer<der::Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
der::MaxSize<C>: ArraySize,
<FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArraySize,
{
fn try_sign(&self, msg: &[u8]) -> Result<der::Signature<C>> {
Signer::<Signature<C>>::try_sign(self, msg).map(Into::into)
}
}
#[cfg(feature = "der")]
impl<C, D> RandomizedDigestSigner<D, der::Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
D: Digest + FixedOutput,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
der::MaxSize<C>: ArraySize,
<FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArraySize,
{
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized>(
&self,
rng: &mut R,
msg_digest: D,
) -> Result<der::Signature<C>> {
RandomizedDigestSigner::<D, Signature<C>>::try_sign_digest_with_rng(self, rng, msg_digest)
.map(Into::into)
}
}
#[cfg(feature = "der")]
impl<C> RandomizedPrehashSigner<der::Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
der::MaxSize<C>: ArraySize,
@@ -270,7 +334,7 @@ where
#[cfg(feature = "der")]
impl<D, C> DigestSigner<D, der::Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
D: Digest + FixedOutput,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
@@ -282,26 +346,6 @@ where
}
}
#[cfg(feature = "der")]
impl<C, D> RandomizedDigestSigner<D, der::Signature<C>> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
D: Digest + FixedOutput,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
der::MaxSize<C>: ArraySize,
<FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArraySize,
{
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized>(
&self,
rng: &mut R,
msg_digest: D,
) -> Result<der::Signature<C>> {
RandomizedDigestSigner::<D, Signature<C>>::try_sign_digest_with_rng(self, rng, msg_digest)
.map(Into::into)
}
}
//
// Other trait impls
//
+28 -6
View File
@@ -2,7 +2,7 @@
use crate::{
EcdsaCurve, Error, Result, Signature, SignatureSize,
hazmat::{self, bits2field},
hazmat::{self, DigestPrimitive, bits2field},
};
use core::{cmp::Ordering, fmt::Debug};
use elliptic_curve::{
@@ -13,7 +13,7 @@ use elliptic_curve::{
sec1::{self, CompressedPoint, EncodedPoint, FromEncodedPoint, ToEncodedPoint},
};
use signature::{
DigestVerifier,
DigestVerifier, Verifier,
digest::{Digest, FixedOutput},
hazmat::PrehashVerifier,
};
@@ -42,11 +42,9 @@ use serdect::serde::{Deserialize, Serialize, de, ser};
#[cfg(feature = "sha2")]
use {
crate::{
DigestAlgorithm, ECDSA_SHA224_OID, ECDSA_SHA256_OID, ECDSA_SHA384_OID, ECDSA_SHA512_OID,
SignatureWithOid,
ECDSA_SHA224_OID, ECDSA_SHA256_OID, ECDSA_SHA384_OID, ECDSA_SHA512_OID, SignatureWithOid,
},
sha2::{Sha224, Sha256, Sha384, Sha512},
signature::Verifier,
};
#[cfg(all(feature = "alloc", feature = "pkcs8"))]
@@ -174,10 +172,20 @@ where
}
}
impl<C> Verifier<Signature<C>> for VerifyingKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
SignatureSize<C>: ArraySize,
{
fn verify(&self, msg: &[u8], signature: &Signature<C>) -> Result<()> {
self.verify_digest(C::Digest::new_with_prefix(msg), signature)
}
}
#[cfg(feature = "sha2")]
impl<C> Verifier<SignatureWithOid<C>> for VerifyingKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
SignatureSize<C>: ArraySize,
{
fn verify(&self, msg: &[u8], sig: &SignatureWithOid<C>) -> Result<()> {
@@ -220,6 +228,20 @@ where
}
}
#[cfg(feature = "der")]
impl<C> Verifier<der::Signature<C>> for VerifyingKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestPrimitive,
SignatureSize<C>: ArraySize,
der::MaxSize<C>: ArraySize,
<FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArraySize,
{
fn verify(&self, msg: &[u8], signature: &der::Signature<C>) -> Result<()> {
let signature = Signature::<C>::try_from(signature.clone())?;
Verifier::<Signature<C>>::verify(self, msg, &signature)
}
}
//
// Other trait impls
//