Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,6 @@ lms-signature = { path = "./lms" }
ml-dsa = { path = "./ml-dsa" }
rfc6979 = { path = "./rfc6979" }
slh-dsa = { path = "./slh-dsa" }

# https://github.com/RustCrypto/traits/pull/2004
signature = { git = "https://github.com/RustCrypto/traits", rev = "77c001c5abdfea97c7710173c196c76253490734" }
5 changes: 3 additions & 2 deletions dsa/examples/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ fn main() {
let signing_key = SigningKey::generate(&mut rng, components);
let verifying_key = signing_key.verifying_key();

let signature = signing_key
.sign_digest_with_rng(&mut rand::rng(), Sha1::new().chain_update(b"hello world"));
let signature = signing_key.sign_digest_with_rng(&mut rand::rng(), |digest: &mut Sha1| {
digest.update(b"hello world")
});

let signing_key_bytes = signing_key.to_pkcs8_pem(LineEnding::LF).unwrap();
let verifying_key_bytes = verifying_key.to_public_key_pem(LineEnding::LF).unwrap();
Expand Down
27 changes: 19 additions & 8 deletions dsa/src/signing_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crypto_bigint::{
BoxedUint, NonZero, Resize,
modular::{BoxedMontyForm, BoxedMontyParams},
};
use digest::{Digest, FixedOutputReset, block_api::BlockSizeUser};
use digest::{Digest, FixedOutputReset, Update, block_api::BlockSizeUser};
use signature::{
DigestSigner, MultipartSigner, RandomizedDigestSigner, Signer,
hazmat::{PrehashSigner, RandomizedPrehashSigner},
Expand Down Expand Up @@ -157,9 +157,10 @@ impl Signer<Signature> for SigningKey {

impl MultipartSigner<Signature> for SigningKey {
fn try_multipart_sign(&self, msg: &[&[u8]]) -> Result<Signature, signature::Error> {
let mut digest = sha2::Sha256::new();
msg.iter().for_each(|slice| digest.update(slice));
self.try_sign_digest(digest)
self.try_sign_digest(|digest: &mut sha2::Sha256| {
msg.iter().for_each(|slice| Digest::update(digest, slice));
Ok(())
})
}
}

Expand Down Expand Up @@ -191,7 +192,12 @@ impl<D> DigestSigner<D, Signature> for SigningKey
where
D: Digest + BlockSizeUser + FixedOutputReset,
{
fn try_sign_digest(&self, digest: D) -> Result<Signature, signature::Error> {
fn try_sign_digest<F: Fn(&mut D) -> Result<(), signature::Error>>(
&self,
f: F,
) -> Result<Signature, signature::Error> {
let mut digest = D::new();
f(&mut digest)?;
let hash = digest.finalize_fixed();
let ks = crate::generate::secret_number_rfc6979::<D>(self, &hash)?;

Expand All @@ -201,15 +207,20 @@ where

impl<D> RandomizedDigestSigner<D, Signature> for SigningKey
where
D: Digest,
D: Digest + Update,
{
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized>(
fn try_sign_digest_with_rng<
R: TryCryptoRng + ?Sized,
F: Fn(&mut D) -> Result<(), signature::Error>,
>(
&self,
rng: &mut R,
digest: D,
f: F,
) -> Result<Signature, signature::Error> {
let ks = crate::generate::secret_number(rng, self.verifying_key().components())?
.ok_or_else(signature::Error::new)?;
let mut digest = D::new();
f(&mut digest)?;
let hash = digest.finalize();

self.sign_prehashed(ks, &hash)
Expand Down
22 changes: 16 additions & 6 deletions dsa/src/verifying_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crypto_bigint::{
BoxedUint, NonZero, Resize,
modular::{BoxedMontyForm, BoxedMontyParams},
};
use digest::Digest;
use digest::{Digest, Update};
use signature::{DigestVerifier, MultipartVerifier, Verifier, hazmat::PrehashVerifier};

#[cfg(feature = "pkcs8")]
Expand Down Expand Up @@ -124,9 +124,13 @@ impl MultipartVerifier<Signature> for VerifyingKey {
msg: &[&[u8]],
signature: &Signature,
) -> Result<(), signature::Error> {
let mut digest = sha2::Sha256::new();
msg.iter().for_each(|slice| digest.update(slice));
self.verify_digest(digest, signature)
self.verify_digest(
|digest: &mut sha2::Sha256| {
msg.iter().for_each(|slice| Digest::update(digest, slice));
Ok(())
},
signature,
)
}
}

Expand All @@ -146,9 +150,15 @@ impl PrehashVerifier<Signature> for VerifyingKey {

impl<D> DigestVerifier<D, Signature> for VerifyingKey
where
D: Digest,
D: Digest + Update,
{
fn verify_digest(&self, digest: D, signature: &Signature) -> Result<(), signature::Error> {
fn verify_digest<F: Fn(&mut D) -> Result<(), signature::Error>>(
&self,
f: F,
signature: &Signature,
) -> Result<(), signature::Error> {
let mut digest = D::new();
f(&mut digest)?;
let hash = digest.finalize();

let is_valid = self
Expand Down
2 changes: 1 addition & 1 deletion dsa/tests/deterministic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ fn generate_signature<D>(signing_key: SigningKey, data: &[u8]) -> Signature
where
D: Digest + BlockSizeUser + FixedOutputReset,
{
signing_key.sign_digest(<D as Digest>::new().chain_update(data))
signing_key.sign_digest(|digest: &mut D| Digest::update(digest, data))
}

/// Generate a signature using the 1024-bit DSA key
Expand Down
22 changes: 18 additions & 4 deletions dsa/tests/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,10 @@ fn decode_encode_signature() {
#[test]
fn sign_message() {
let signing_key = generate_deterministic_keypair();
let generated_signature =
signing_key.sign_digest_with_rng(&mut seeded_csprng(), Sha256::new().chain_update(MESSAGE));
let generated_signature = signing_key
.sign_digest_with_rng(&mut seeded_csprng(), |digest: &mut Sha256| {
digest.update(MESSAGE)
});

let expected_signature =
Signature::from_der(MESSAGE_SIGNATURE_CRATE_ASN1).expect("Failed to decode signature");
Expand All @@ -90,7 +92,13 @@ fn verify_signature() {

assert!(
verifying_key
.verify_digest(Sha256::new().chain_update(MESSAGE), &signature)
.verify_digest(
|digest: &mut Sha256| {
digest.update(MESSAGE);
Ok(())
},
&signature
)
.is_ok()
);
}
Expand Down Expand Up @@ -160,6 +168,12 @@ fn verify_signature_precision() {
let signature = Signature::from_der(&asn1)
.expect("Failed to parse ASN.1 representation of the test signature");

let _ = verifying_key.verify_digest(Sha256::new().chain_update(MESSAGE), &signature);
let _ = verifying_key.verify_digest(
|digest: &mut Sha256| {
digest.update(MESSAGE);
Ok(())
},
&signature,
);
}
}
14 changes: 11 additions & 3 deletions dsa/tests/signing_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,20 @@ fn sign_and_verify() {
let signing_key = generate_keypair();
let verifying_key = signing_key.verifying_key();

let signature =
signing_key.sign_digest_with_rng(&mut rand::thread_rng(), Sha1::new().chain_update(DATA));
let signature = signing_key
.sign_digest_with_rng(&mut rand::thread_rng(), |digest: &mut Sha1| {
digest.update(DATA)
});

assert!(
verifying_key
.verify_digest(Sha1::new().chain_update(DATA), &signature)
.verify_digest(
|digest: &mut Sha1| {
digest.update(DATA);
Ok(())
},
&signature
)
.is_ok()
);
}
Expand Down
24 changes: 16 additions & 8 deletions ecdsa/src/recovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use {
elliptic_curve::{FieldBytes, subtle::CtOption},
signature::{
DigestSigner, MultipartSigner, RandomizedDigestSigner, Signer,
digest::FixedOutput,
digest::{FixedOutput, Update},
hazmat::{PrehashSigner, RandomizedPrehashSigner},
rand_core::TryCryptoRng,
},
Expand Down Expand Up @@ -229,12 +229,17 @@ where
impl<C, D> DigestSigner<D, (Signature<C>, RecoveryId)> for SigningKey<C>
where
C: EcdsaCurve + CurveArithmetic + DigestAlgorithm,
D: Digest,
D: Digest + Update,
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign_digest(&self, msg_digest: D) -> Result<(Signature<C>, RecoveryId)> {
self.sign_digest_recoverable(msg_digest)
fn try_sign_digest<F: Fn(&mut D) -> Result<()>>(
&self,
f: F,
) -> Result<(Signature<C>, RecoveryId)> {
let mut digest = D::new();
f(&mut digest)?;
self.sign_digest_recoverable(digest)
}
}

Expand Down Expand Up @@ -262,12 +267,14 @@ where
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized>(
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized, F: Fn(&mut D) -> Result<()>>(
&self,
rng: &mut R,
msg_digest: D,
f: F,
) -> Result<(Signature<C>, RecoveryId)> {
self.sign_prehash_with_rng(rng, &msg_digest.finalize_fixed())
let mut digest = D::new();
f(&mut digest)?;
self.sign_prehash_with_rng(rng, &digest.finalize_fixed())
}
}

Expand Down Expand Up @@ -304,7 +311,8 @@ where
{
fn try_multipart_sign(&self, msg: &[&[u8]]) -> Result<(Signature<C>, RecoveryId)> {
let mut digest = C::Digest::new();
msg.iter().for_each(|slice| digest.update(slice));
msg.iter()
.for_each(|slice| Digest::update(&mut digest, slice));
self.sign_digest_recoverable(digest)
}
}
Expand Down
49 changes: 28 additions & 21 deletions ecdsa/src/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,10 @@ where
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign_digest(&self, msg_digest: D) -> Result<Signature<C>> {
self.sign_prehash(&msg_digest.finalize_fixed())
fn try_sign_digest<F: Fn(&mut D) -> Result<()>>(&self, f: F) -> Result<Signature<C>> {
let mut digest = D::new();
f(&mut digest)?;
self.sign_prehash(&digest.finalize_fixed())
}
}

Expand Down Expand Up @@ -188,9 +190,10 @@ where
SignatureSize<C>: ArraySize,
{
fn try_multipart_sign(&self, msg: &[&[u8]]) -> core::result::Result<Signature<C>, Error> {
let mut digest = C::Digest::new();
msg.iter().for_each(|slice| digest.update(slice));
self.try_sign_digest(digest)
self.try_sign_digest(|digest: &mut C::Digest| {
msg.iter().for_each(|slice| digest.update(slice));
Ok(())
})
}
}

Expand All @@ -201,12 +204,14 @@ where
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized>(
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized, F: Fn(&mut D) -> Result<()>>(
&self,
rng: &mut R,
msg_digest: D,
f: F,
) -> Result<Signature<C>> {
self.sign_prehash_with_rng(rng, &msg_digest.finalize_fixed())
let mut digest = D::new();
f(&mut digest)?;
self.sign_prehash_with_rng(rng, &digest.finalize_fixed())
}
}

Expand Down Expand Up @@ -264,9 +269,10 @@ where
rng: &mut R,
msg: &[&[u8]],
) -> Result<Signature<C>> {
let mut digest = C::Digest::new();
msg.iter().for_each(|slice| digest.update(slice));
self.try_sign_digest_with_rng(rng, digest)
self.try_sign_digest_with_rng(rng, |digest: &mut C::Digest| {
msg.iter().for_each(|slice| digest.update(slice));
Ok(())
})
}
}

Expand All @@ -277,8 +283,8 @@ where
Scalar<C>: Invert<Output = CtOption<Scalar<C>>>,
SignatureSize<C>: ArraySize,
{
fn try_sign_digest(&self, msg_digest: D) -> Result<SignatureWithOid<C>> {
let signature: Signature<C> = self.try_sign_digest(msg_digest)?;
fn try_sign_digest<F: Fn(&mut D) -> Result<()>>(&self, f: F) -> Result<SignatureWithOid<C>> {
let signature: Signature<C> = self.try_sign_digest(f)?;
let oid = ecdsa_oid_for_digest(D::OID).ok_or_else(Error::new)?;
SignatureWithOid::new(signature, oid)
}
Expand All @@ -304,9 +310,10 @@ where
SignatureSize<C>: ArraySize,
{
fn try_multipart_sign(&self, msg: &[&[u8]]) -> Result<SignatureWithOid<C>> {
let mut digest = C::Digest::new();
msg.iter().for_each(|slice| digest.update(slice));
self.try_sign_digest(digest)
self.try_sign_digest(|digest: &mut C::Digest| {
msg.iter().for_each(|slice| digest.update(slice));
Ok(())
})
}
}

Expand Down Expand Up @@ -348,12 +355,12 @@ where
der::MaxSize<C>: ArraySize,
<FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArraySize,
{
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized>(
fn try_sign_digest_with_rng<R: TryCryptoRng + ?Sized, F: Fn(&mut D) -> Result<()>>(
&self,
rng: &mut R,
msg_digest: D,
f: F,
) -> Result<der::Signature<C>> {
RandomizedDigestSigner::<D, Signature<C>>::try_sign_digest_with_rng(self, rng, msg_digest)
RandomizedDigestSigner::<D, Signature<C>>::try_sign_digest_with_rng(self, rng, f)
.map(Into::into)
}
}
Expand Down Expand Up @@ -387,8 +394,8 @@ where
der::MaxSize<C>: ArraySize,
<FieldBytesSize<C> as Add>::Output: Add<der::MaxOverhead> + ArraySize,
{
fn try_sign_digest(&self, msg_digest: D) -> Result<der::Signature<C>> {
DigestSigner::<D, Signature<C>>::try_sign_digest(self, msg_digest).map(Into::into)
fn try_sign_digest<F: Fn(&mut D) -> Result<()>>(&self, f: F) -> Result<der::Signature<C>> {
DigestSigner::<D, Signature<C>>::try_sign_digest(self, f).map(Into::into)
}
}

Expand Down
Loading
Loading