1pub use crate::common::sign_hashed as sign;
38pub use crate::common::verify_hashed as verify;
39use fdh::Digest;
40use num_bigint::BigUint;
41use rand::Rng;
42use rsa::internals;
43use rsa::PublicKey;
44
45pub fn hash_message<H: Digest + Clone, P: PublicKey>(
47 signer_public_key: &P,
48 message: &[u8],
49) -> Result<Vec<u8>, crate::Error>
50where
51 H::OutputSize: Clone,
52{
53 let (result, _iv) = crate::common::hash_message::<H, P>(signer_public_key, message)?;
54 Ok(result)
55}
56
57pub fn blind<R: Rng, P: PublicKey>(rng: &mut R, pub_key: P, digest: &[u8]) -> (Vec<u8>, Vec<u8>) {
59 let c = BigUint::from_bytes_be(digest);
60 let (c, unblinder) = internals::blind::<R, P>(rng, &pub_key, &c);
61 (c.to_bytes_be(), unblinder.to_bytes_be())
62}
63
64pub fn unblind(pub_key: impl PublicKey, blinded_sig: &[u8], unblinder: &[u8]) -> Vec<u8> {
66 let blinded_sig = BigUint::from_bytes_be(blinded_sig);
67 let unblinder = BigUint::from_bytes_be(unblinder);
68 let unblinded = internals::unblind(pub_key, &blinded_sig, &unblinder);
69 unblinded.to_bytes_be()
70}
71
72#[cfg(test)]
73mod tests {
74 use crate::blind;
75 use crate::Error;
76 use rsa::PublicKeyParts;
77 use rsa::{RSAPrivateKey, RSAPublicKey};
78 use sha2::Sha256;
79
80 #[test]
81 fn blind_test() -> Result<(), Error> {
82 let mut rng = rand::thread_rng();
85 let message = b"NEVER GOING TO GIVE YOU UP";
86
87 let signer_priv_key = RSAPrivateKey::new(&mut rng, 256).unwrap();
90 let signer_pub_key =
91 RSAPublicKey::new(signer_priv_key.n().clone(), signer_priv_key.e().clone()).unwrap();
92
93 for _ in 0..500 {
95 let digest = blind::hash_message::<Sha256, _>(&signer_pub_key, message)?;
100
101 let (blinded_digest, unblinder) = blind::blind(&mut rng, &signer_pub_key, &digest);
103
104 let blind_signature = blind::sign(&mut rng, &signer_priv_key, &blinded_digest)?;
106
107 assert!(blind::verify(&signer_pub_key, &digest, &blind_signature).is_err());
109
110 let signature = blind::unblind(&signer_pub_key, &blind_signature, &unblinder);
112
113 let check_digest = blind::hash_message::<Sha256, _>(&signer_pub_key, message)?;
118
119 blind::verify(&signer_pub_key, &check_digest, &signature)?;
121 }
122
123 Ok(())
124 }
125
126 #[test]
127 fn error_test() -> Result<(), Error> {
128 let mut rng = rand::thread_rng();
131 let message = b"NEVER GOING TO GIVE YOU UP";
132
133 let key_1 = RSAPrivateKey::new(&mut rng, 256).unwrap();
135 let public_1 = key_1.to_public_key();
136 let digest_1 = blind::hash_message::<Sha256, _>(&public_1, message)?;
137 let (blinded_digest_1, unblinder_1) = blind::blind(&mut rng, &public_1, &digest_1);
138 let blind_signature_1 = blind::sign(&mut rng, &key_1, &blinded_digest_1)?;
139 let signature_1 = blind::unblind(&public_1, &blind_signature_1, &unblinder_1);
140
141 let key_2 = RSAPrivateKey::new(&mut rng, 512).unwrap();
142 let public_2 = key_2.to_public_key();
143 let digest_2 = blind::hash_message::<Sha256, _>(&public_2, message)?;
144 let (blinded_digest_2, unblinder_2) = blind::blind(&mut rng, &public_2, &digest_2);
145 let blind_signature_2 = blind::sign(&mut rng, &key_2, &blinded_digest_2)?;
146 let signature_2 = blind::unblind(&public_2, &blind_signature_2, &unblinder_2);
147
148 assert!(digest_1 != digest_2);
150 assert!(blinded_digest_1 != blinded_digest_2);
151 assert!(unblinder_1 != unblinder_2);
152 assert!(blind_signature_1 != blind_signature_2);
153 assert!(signature_1 != signature_2);
154
155 assert!(blind::sign(&mut rng, &key_1, &blinded_digest_2).is_err());
157 assert!(blind::verify(&public_1, &digest_1, &signature_2).is_err());
158 assert!(blind::verify(&public_1, &digest_2, &signature_1).is_err());
159 assert!(blind::verify(&public_1, &digest_2, &signature_2).is_err());
160 assert!(blind::verify(&public_2, &digest_1, &signature_1).is_err());
161 assert!(blind::verify(&public_2, &digest_1, &signature_2).is_err());
162 assert!(blind::verify(&public_2, &digest_2, &signature_1).is_err());
163
164 Ok(())
165 }
166}