Skip to content

Commit 4af8b5a

Browse files
committed
Implement RandomizedDigestSigner, DigestVerifier for PSS structs
Implement the experimental (preview) RandomizedDigestSigner and DigestVerifier traits for the PSS structs. Signed-off-by: Dmitry Baryshkov <[email protected]>
1 parent db1b854 commit 4af8b5a

File tree

1 file changed

+152
-0
lines changed

1 file changed

+152
-0
lines changed

src/pss.rs

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ use core::fmt::{Debug, Display, Formatter, LowerHex, UpperHex};
55
use core::marker::PhantomData;
66
use digest::{Digest, DynDigest};
77
use rand_core::{CryptoRng, RngCore};
8+
#[cfg(feature = "digest-preview")]
9+
use signature::{DigestVerifier, RandomizedDigestSigner};
810
use signature::{RandomizedSigner, Signature as SignSignature, Verifier};
911
use subtle::ConstantTimeEq;
1012

@@ -373,6 +375,29 @@ where
373375
}
374376
}
375377

378+
#[cfg(feature = "digest-preview")]
379+
impl<D> RandomizedDigestSigner<D, Signature> for SigningKey<D>
380+
where
381+
D: Digest + DynDigest,
382+
{
383+
fn try_sign_digest_with_rng(
384+
&self,
385+
mut rng: impl CryptoRng + RngCore,
386+
digest: D,
387+
) -> signature::Result<Signature> {
388+
sign(
389+
&mut rng,
390+
false,
391+
&self.inner,
392+
&digest.finalize(),
393+
self.salt_len,
394+
&mut D::new(),
395+
)
396+
.map(|v| v.into())
397+
.map_err(|e| e.into())
398+
}
399+
}
400+
376401
pub struct BlindedSigningKey<D>
377402
where
378403
D: Digest + DynDigest,
@@ -429,6 +454,29 @@ where
429454
}
430455
}
431456

457+
#[cfg(feature = "digest-preview")]
458+
impl<D> RandomizedDigestSigner<D, Signature> for BlindedSigningKey<D>
459+
where
460+
D: Digest + DynDigest,
461+
{
462+
fn try_sign_digest_with_rng(
463+
&self,
464+
mut rng: impl CryptoRng + RngCore,
465+
digest: D,
466+
) -> signature::Result<Signature> {
467+
sign(
468+
&mut rng,
469+
true,
470+
&self.inner,
471+
&digest.finalize(),
472+
self.salt_len,
473+
&mut D::new(),
474+
)
475+
.map(|v| v.into())
476+
.map_err(|e| e.into())
477+
}
478+
}
479+
432480
pub struct VerifyingKey<D>
433481
where
434482
D: Digest + DynDigest,
@@ -512,6 +560,22 @@ where
512560
}
513561
}
514562

563+
#[cfg(feature = "digest-preview")]
564+
impl<D> DigestVerifier<D, Signature> for VerifyingKey<D>
565+
where
566+
D: Digest + DynDigest,
567+
{
568+
fn verify_digest(&self, digest: D, signature: &Signature) -> signature::Result<()> {
569+
verify(
570+
&self.inner,
571+
&digest.finalize(),
572+
signature.as_ref(),
573+
&mut D::new(),
574+
)
575+
.map_err(|e| e.into())
576+
}
577+
}
578+
515579
#[cfg(test)]
516580
mod test {
517581
use crate::pss::{BlindedSigningKey, SigningKey, VerifyingKey};
@@ -522,6 +586,8 @@ mod test {
522586
use num_traits::{FromPrimitive, Num};
523587
use rand_chacha::{rand_core::SeedableRng, ChaCha8Rng};
524588
use sha1::{Digest, Sha1};
589+
#[cfg(feature = "digest-preview")]
590+
use signature::{DigestVerifier, RandomizedDigestSigner};
525591
use signature::{RandomizedSigner, Signature, Verifier};
526592

527593
fn get_private_key() -> RsaPrivateKey {
@@ -622,6 +688,46 @@ mod test {
622688
}
623689
}
624690

691+
#[cfg(feature = "digest-preview")]
692+
#[test]
693+
fn test_verify_pss_digest_signer() {
694+
let priv_key = get_private_key();
695+
696+
let tests = [
697+
(
698+
"test\n",
699+
hex!(
700+
"6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
701+
"30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962f"
702+
),
703+
true,
704+
),
705+
(
706+
"test\n",
707+
hex!(
708+
"6f86f26b14372b2279f79fb6807c49889835c204f71e38249b4c5601462da8ae"
709+
"30f26ffdd9c13f1c75eee172bebe7b7c89f2f1526c722833b9737d6c172a962e"
710+
),
711+
false,
712+
),
713+
];
714+
let pub_key: RsaPublicKey = priv_key.into();
715+
let verifying_key: VerifyingKey<_> = VerifyingKey::new(pub_key);
716+
717+
for (text, sig, expected) in &tests {
718+
let mut digest = Sha1::new();
719+
digest.update(text.as_bytes());
720+
let result = verifying_key.verify_digest(digest, &Signature::from_bytes(sig).unwrap());
721+
match expected {
722+
true => result.expect("failed to verify"),
723+
false => {
724+
result.expect_err("expected verifying error");
725+
()
726+
}
727+
}
728+
}
729+
}
730+
625731
#[test]
626732
fn test_sign_and_verify_roundtrip() {
627733
let priv_key = get_private_key();
@@ -693,4 +799,50 @@ mod test {
693799
.expect("failed to verify");
694800
}
695801
}
802+
803+
#[cfg(feature = "digest-preview")]
804+
#[test]
805+
fn test_sign_and_verify_roundtrip_digest_signer() {
806+
let priv_key = get_private_key();
807+
808+
let tests = ["test\n"];
809+
let mut rng = ChaCha8Rng::from_seed([42; 32]);
810+
let signing_key = SigningKey::new(priv_key);
811+
let verifying_key: VerifyingKey<_> = (&signing_key).into();
812+
813+
for test in &tests {
814+
let mut digest = Sha1::new();
815+
digest.update(test.as_bytes());
816+
let sig = signing_key.sign_digest_with_rng(&mut rng, digest);
817+
818+
let mut digest = Sha1::new();
819+
digest.update(test.as_bytes());
820+
verifying_key
821+
.verify_digest(digest, &sig)
822+
.expect("failed to verify");
823+
}
824+
}
825+
826+
#[cfg(feature = "digest-preview")]
827+
#[test]
828+
fn test_sign_and_verify_roundtrip_blinded_digest_signer() {
829+
let priv_key = get_private_key();
830+
831+
let tests = ["test\n"];
832+
let mut rng = ChaCha8Rng::from_seed([42; 32]);
833+
let signing_key = BlindedSigningKey::<Sha1>::new(priv_key);
834+
let verifying_key: VerifyingKey<_> = (&signing_key).into();
835+
836+
for test in &tests {
837+
let mut digest = Sha1::new();
838+
digest.update(test.as_bytes());
839+
let sig = signing_key.sign_digest_with_rng(&mut rng, digest);
840+
841+
let mut digest = Sha1::new();
842+
digest.update(test.as_bytes());
843+
verifying_key
844+
.verify_digest(digest, &sig)
845+
.expect("failed to verify");
846+
}
847+
}
696848
}

0 commit comments

Comments
 (0)