use alloc::vec::Vec;
use super::emsa;
use super::{Error, RsaPrivateKey, RsaPublicKey};
use crate::hash::Digest;
use crate::rng::RngCore;
impl<const LIMBS: usize> RsaPrivateKey<LIMBS> {
pub fn sign_pss<D: Digest, R: RngCore>(
&self,
msg: &[u8],
rng: &mut R,
) -> Result<Vec<u8>, Error> {
emsa::sign_pss::<D, _, R>(self, msg, rng)
}
}
impl<const LIMBS: usize> RsaPublicKey<LIMBS> {
pub fn verify_pss<D: Digest>(&self, msg: &[u8], sig: &[u8]) -> Result<(), Error> {
emsa::verify_pss::<D, _>(self, msg, sig)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::hash::Sha256;
use crate::rng::HmacDrbg;
use crate::test_util::rsa_test_key_a;
#[test]
fn sign_verify_roundtrip() {
let key = rsa_test_key_a();
let pk = key.public_key();
let mut r = HmacDrbg::<Sha256>::new(b"rsa-pss", b"nonce", &[]);
let sig = key.sign_pss::<Sha256, _>(b"pss message", &mut r).unwrap();
pk.verify_pss::<Sha256>(b"pss message", &sig).unwrap();
assert_eq!(
pk.verify_pss::<Sha256>(b"other", &sig),
Err(Error::Verification)
);
let mut bad = sig.clone();
bad[20] ^= 1;
assert_eq!(
pk.verify_pss::<Sha256>(b"pss message", &bad),
Err(Error::Verification)
);
}
#[test]
fn pss_is_randomized() {
let key = rsa_test_key_a();
let pk = key.public_key();
let mut r = HmacDrbg::<Sha256>::new(b"rsa-pss-rand", b"nonce", &[]);
let a = key.sign_pss::<Sha256, _>(b"m", &mut r).unwrap();
let b = key.sign_pss::<Sha256, _>(b"m", &mut r).unwrap();
assert_ne!(a, b);
pk.verify_pss::<Sha256>(b"m", &a).unwrap();
pk.verify_pss::<Sha256>(b"m", &b).unwrap();
}
}