From 7c28727f738f38ac69a8315ed95d99553f8d176c Mon Sep 17 00:00:00 2001 From: Adam Wick Date: Tue, 1 May 2018 22:30:07 -0700 Subject: [PATCH] RSA signature verification. --- src/rsa/gold_tests.rs | 33 +++++++++++++++++++++++++++------ src/rsa/public.rs | 16 ++++++++++++++-- 2 files changed, 41 insertions(+), 8 deletions(-) diff --git a/src/rsa/gold_tests.rs b/src/rsa/gold_tests.rs index f7d9b4b..ae40135 100644 --- a/src/rsa/gold_tests.rs +++ b/src/rsa/gold_tests.rs @@ -1,5 +1,5 @@ use rsa::*; -use testing::{make_unsigned,run_test}; +use testing::run_test; fn get_signing_hash(s: usize) -> &'static SigningHash { match s { @@ -13,17 +13,17 @@ fn get_signing_hash(s: usize) -> &'static SigningHash { } #[test] -fn rsa_signature_tests() +fn rsa_signing_tests() { run_test("tests/rsa/signature.test", 7, |case| { let (neg0, dbytes) = case.get("d").unwrap(); let (neg1, nbytes) = case.get("n").unwrap(); let (neg2, hbytes) = case.get("h").unwrap(); - let (neg2, kbytes) = case.get("k").unwrap(); - let (neg3, msg) = case.get("m").unwrap(); - let (neg4, sig) = case.get("s").unwrap(); + let (neg3, kbytes) = case.get("k").unwrap(); + let (neg4, msg) = case.get("m").unwrap(); + let (neg5, sig) = case.get("s").unwrap(); - assert!(!neg0 & !neg1 & !neg2 & !neg3 & !neg4); + assert!(!neg0 & !neg1 & !neg2 & !neg3 & !neg4 & !neg5); let hash = get_signing_hash(usize::from(UCN::from_bytes(hbytes))); let size = usize::from(UCN::from_bytes(kbytes)); let key = RSAPrivate::new(UCN::from_bytes(nbytes), @@ -35,3 +35,24 @@ fn rsa_signature_tests() assert_eq!(*sig, sig2); }); } + +#[test] +fn rsa_verification_tests() +{ + run_test("tests/rsa/signature.test", 7, |case| { + let (neg1, nbytes) = case.get("n").unwrap(); + let (neg2, hbytes) = case.get("h").unwrap(); + let (neg3, kbytes) = case.get("k").unwrap(); + let (neg4, msg) = case.get("m").unwrap(); + let (neg5, sig) = case.get("s").unwrap(); + + assert!(!neg1 & !neg2 & !neg3 & !neg4 & !neg5); + let hash = get_signing_hash(usize::from(UCN::from_bytes(hbytes))); + let size = usize::from(UCN::from_bytes(kbytes)); + let key = RSAPublic::new(UCN::from_bytes(nbytes), + UCN::from(65537u64)); + + assert_eq!(key.byte_len * 8, size); + assert!(key.verify(hash, &msg, sig)); + }); +} diff --git a/src/rsa/public.rs b/src/rsa/public.rs index 7599e15..1785387 100644 --- a/src/rsa/public.rs +++ b/src/rsa/public.rs @@ -1,5 +1,6 @@ use cryptonum::{BarrettUCN,UCN}; -use rsa::core::ACCEPTABLE_KEY_SIZES; +use rsa::core::{ACCEPTABLE_KEY_SIZES,pkcs1_pad,vp1}; +use rsa::signing_hashes::SigningHash; #[derive(Clone,Debug,PartialEq,Eq)] pub struct RSAPublic { @@ -16,7 +17,7 @@ impl RSAPublic { let len = n.bits(); for &(valid_bits, _) in ACCEPTABLE_KEY_SIZES.iter() { - if valid_bits > len { + if valid_bits >= len { return RSAPublic{ byte_len: valid_bits / 8, n: n.clone(), @@ -27,4 +28,15 @@ impl RSAPublic { } panic!("Invalid RSA key size in new()") } + + /// Verify the signature for a given message, using the given signing hash, + /// returning true iff the signature validates. + pub fn verify(&self, shash: &SigningHash, msg: &[u8], sig: &[u8]) -> bool { + let hash = (shash.run)(msg); + let s = UCN::from_bytes(&sig); + let m = vp1(&self.nu, &self.e, &s); + let em = m.to_bytes(self.byte_len); + let em_ = pkcs1_pad(&shash.ident, &hash, self.byte_len); + (em == em_) + } }