1
//! Macros that can be used to improve your life with regards to crypto.
2

            
3
use derive_deftly::define_derive_deftly;
4

            
5
/// Create an ed25519 keypair wrapper given a visibility and a struct name.
6
///
7
/// # Syntax:
8
/// ```rust,ignore
9
/// define_ed25519_keypair(<visibility> <prefix>)
10
/// ```
11
///
12
/// This macro creates a struct tuple named `<prefix>Keypair` which contains the lower-level
13
/// cryptographic keypair for an ed25519 keypair. It derives the deftly Ed25519Keypair template
14
/// which in turn creates `<prefix>PublicKey` along a series of useful methods.
15
///
16
/// The keypair is NOT clonable by design in order to avoid duplicating secret key material.
17
///
18
/// # Example:
19
///
20
/// ```rust
21
/// use tor_key_forge::define_ed25519_keypair;
22
///
23
/// define_ed25519_keypair!(NonPublicSigning);
24
/// define_ed25519_keypair!(pub PublicSigning);
25
/// define_ed25519_keypair!(pub(crate) CratePublicSigning);
26
/// ```
27
///
28
/// The above results in `NonPublicSigningKeypair` and `NonPublicSigningPublicKey` struct being
29
/// created and usable with a series of useful methods. Same for the other defines.
30
///
31
/// You can then use these objects like so:
32
///
33
/// ```rust
34
/// # use tor_llcrypto::rng::FakeEntropicRng;
35
/// # let mut rng = FakeEntropicRng(rand::rng());
36
/// use rand::Rng;
37
/// use tor_key_forge::Keygen;
38
/// use tor_key_forge::define_ed25519_keypair;
39
/// use tor_llcrypto::pk::ValidatableSignature;
40
/// use tor_llcrypto::pk::ed25519::Ed25519SigningKey;
41
///
42
/// define_ed25519_keypair!(
43
///     /// Our signing key.
44
///     MySigning
45
/// );
46
///
47
/// let signing_kp = MySigningKeypair::generate(&mut rng).expect("Invalid keygen");
48
/// let signing_pubkey = signing_kp.public();
49
/// // Lets sign this wonderful message.
50
/// let message = "Workers want rights, not your opinion".as_bytes();
51
/// let sig = signing_kp.sign(&message);
52
///
53
/// // You can then verify either directly with the keypair or the public key.
54
/// assert!(signing_kp.verify(sig, &message));
55
/// assert!(signing_pubkey.verify(sig, &message));
56
/// ```
57
#[macro_export]
58
macro_rules! define_ed25519_keypair {
59
    ($(#[ $docs_and_attrs:meta ])*
60
     $vis:vis $base_name:ident) => {
61
        $crate::macro_deps::paste! {
62
            #[derive($crate::derive_deftly::Deftly)]
63
            #[derive_deftly($crate::macro_deps::Ed25519Keypair)]
64
            #[deftly(kp(pubkey = $base_name "PublicKey"))]
65
            #[non_exhaustive]
66
            $(#[ $docs_and_attrs ])*
67
            $vis struct [<$base_name "Keypair">]($crate::macro_deps::ed25519::Keypair);
68
        }
69
    };
70
}
71

            
72
define_derive_deftly! {
73
    /// Implement set of helper functions around a type wrapping an ed25519::Keypair.
74
    export Ed25519Keypair for struct:
75

            
76
    // Enforce that the object has a single field. We want to avoid the implementer to start
77
    // storing metadata or other things in this object that is meant specifically to be
78
    // a semantic wrapper around an Ed25519 keypair.
79
    ${if not(approx_equal(${for fields { 1 }}, 1)) { ${error "Single field only"}}}
80

            
81
    ${define KP_NAME $( $fname )}
82
    ${define PK_NAME ${tmeta(kp(pubkey)) as ident}}
83

            
84
    /// Public key component of this keypair. Useful if we move the public key around,
85
    /// it then keeps it semantic with the name and less prone to errors.
86
    #[derive(Clone, Debug, PartialEq, Eq)]
87
    #[derive($crate::macro_deps::derive_more::From, $crate::macro_deps::derive_more::Into)]
88
    #[non_exhaustive]
89
    $tvis struct $PK_NAME ($tvis $crate::macro_deps::ed25519::PublicKey);
90

            
91
    impl $PK_NAME {
92
        /// Verify the signature of a given message.
93
        #[allow(unused)]
94
        $tvis fn verify(&self, sig: $crate::macro_deps::ed25519::Signature, text: &[u8]) -> bool {
95
            use $crate::macro_deps::ValidatableSignature;
96
            $crate::macro_deps::ed25519::ValidatableEd25519Signature::new(self.0, sig, text).is_valid()
97
        }
98
    }
99

            
100
    impl $crate::macro_deps::ed25519::Ed25519PublicKey for $PK_NAME {
101
        fn public_key(&self) -> $crate::macro_deps::ed25519::PublicKey {
102
            self.0
103
        }
104
    }
105

            
106
    // We don't expect all implementations to use all code.
107
    #[allow(unused)]
108
    impl $ttype {
109
        /// Build the raw inner public key into the wrapper public key object.
110
2704
        $tvis fn public(&self) -> $PK_NAME {
111
            $PK_NAME((&self.$KP_NAME).into())
112
        }
113
        /// Verify the signature of a given message.
114
2
        $tvis fn verify(&self, sig: $crate::macro_deps::ed25519::Signature, text: &[u8]) -> bool {
115
            use $crate::macro_deps::ValidatableSignature;
116
            $crate::macro_deps::ed25519::ValidatableEd25519Signature::new(
117
                self.0.verifying_key(), sig, text
118
            ).is_valid()
119
        }
120
        /// Return a Ed25519Identity built from this keypair.
121
2499
        $tvis fn to_ed25519_id(&self) -> $crate::macro_deps::ed25519::Ed25519Identity {
122
            $crate::macro_deps::ed25519::Ed25519Identity::from(&self.public().0)
123
        }
124
    }
125

            
126
    impl From<$crate::macro_deps::ed25519::Keypair> for $ttype {
127
        fn from(kp: $crate::macro_deps::ed25519::Keypair) -> Self {
128
            Self(kp)
129
        }
130
    }
131
    impl $crate::macro_deps::ed25519::Ed25519PublicKey for $ttype {
132
1173
        fn public_key(&self) -> $crate::macro_deps::ed25519::PublicKey {
133
            self.0.public_key()
134
        }
135
    }
136

            
137
    impl $crate::macro_deps::ed25519::Ed25519SigningKey for $ttype {
138
1174
        fn sign(
139
1174
            &self,
140
1174
            msg: &[u8])
141
1174
        -> $crate::macro_deps::ed25519::Signature {
142
            self.0.sign(msg)
143
        }
144
    }
145

            
146
    /// Implementing EncodableItem, ToEncodableKey and Keygen allows this wrapper key to be stored
147
    /// in a keystore.
148

            
149
    impl $crate::ItemType for $ttype {
150
        fn item_type() -> $crate::KeystoreItemType {
151
            $crate::KeyType::Ed25519Keypair.into()
152
        }
153
    }
154

            
155
    impl $crate::EncodableItem for $ttype {
156
        fn as_keystore_item(&self) -> $crate::Result<$crate::KeystoreItem> {
157
            self.$KP_NAME.as_keystore_item()
158
        }
159
    }
160

            
161
    impl $crate::ToEncodableKey for $ttype {
162
        type Key = $crate::macro_deps::ed25519::Keypair;
163
        type KeyPair = $ttype;
164

            
165
        fn to_encodable_key(self) -> Self::Key {
166
            self.$KP_NAME
167
        }
168
4131
        fn from_encodable_key(key: Self::Key) -> Self {
169
            Self(key)
170
        }
171
    }
172

            
173
    impl $crate::Keygen for $ttype {
174
154
        fn generate(mut rng: &mut dyn $crate::KeygenRng) -> $crate::Result<Self>
175
154
        where
176
154
            Self: Sized
177
        {
178
            Ok(Self { $KP_NAME: $crate::macro_deps::ed25519::Keypair::generate(&mut rng) })
179
        }
180
    }
181
}
182

            
183
/// Create a curve25519 keypair wrapper given a visibility and a struct name.
184
///
185
/// # Syntax:
186
/// ```rust,ignore
187
/// define_curve25519_keypair(<visibility> <prefix>)
188
/// ```
189
///
190
/// This macro creates a struct tuple named `<prefix>Keypair` which contains the lower-level
191
/// cryptographic keypair for a curve25519 keypair. It derives the deftly Curve25519Keypair template
192
/// which in turn creates `<prefix>PublicKey` along a series of useful methods.
193
///
194
/// The keypair is NOT clonable by design in order to avoid duplicating secret key material.
195
///
196
/// # Example:
197
///
198
/// ```rust
199
/// use tor_key_forge::define_curve25519_keypair;
200
///
201
/// define_curve25519_keypair!(NonPublicEnc);
202
/// define_curve25519_keypair!(pub PublicEnc);
203
/// define_curve25519_keypair!(pub(crate) CratePublicEnc);
204
/// ```
205
///
206
/// The above results in `NonPublicEncKeypair` and `NonPublicEncPublicKey` struct being created and
207
/// usable with a series of useful methods.
208
///
209
/// You can then use these objects like so:
210
///
211
/// ```rust
212
/// # use tor_llcrypto::rng::FakeEntropicRng;
213
/// # let mut rng = FakeEntropicRng(rand::rng());
214
/// # use rand::Rng;
215
/// use tor_key_forge::define_curve25519_keypair;
216
/// use tor_key_forge::Keygen;
217
///
218
/// define_curve25519_keypair!(
219
///     // This is Alice's keypair.
220
///     AliceEnc
221
/// );
222
/// define_curve25519_keypair!(BobEnc);
223
///
224
/// let alice_kp = AliceEncKeypair::generate(&mut rng).expect("Failed alice keygen");
225
/// let bob_kp = BobEncKeypair::generate(&mut rng).expect("Failed bob keygen");
226
///
227
/// // Using the public key wrapper
228
/// let alice_shared_secret = alice_kp.diffie_hellman(bob_kp.public());
229
/// // Using the direct curve25519::PublicKey.
230
/// let bob_shared_secret = bob_kp.diffie_hellman(&alice_kp.public().0);
231
///
232
/// assert_eq!(alice_shared_secret.as_bytes(), bob_shared_secret.as_bytes());
233
/// ```
234
#[macro_export]
235
macro_rules! define_curve25519_keypair {
236
    ($(#[ $docs_and_attrs:meta ])*
237
    $vis:vis $base_name:ident) => {
238
        $crate::macro_deps::paste! {
239
            #[derive($crate::derive_deftly::Deftly)]
240
            #[derive_deftly($crate::macro_deps::Curve25519Keypair)]
241
            #[deftly(kp(pubkey = $base_name "PublicKey"))]
242
            #[non_exhaustive]
243
            $(#[ $docs_and_attrs ])*
244
            $vis struct [<$base_name "Keypair">]($crate::macro_deps::curve25519::StaticKeypair);
245
        }
246
    };
247
}
248

            
249
define_derive_deftly! {
250
    /// Implement set of helper functions around a type wrapping an ed25519::Keypair.
251
    export Curve25519Keypair for struct:
252

            
253
    // Enforce that the object has a single field. We want to avoid the implementer to start
254
    // storing metadata or other things in this object that is meant specifically to be
255
    // a semantic wrapper around an Curve25519 keypair.
256
    ${if not(approx_equal(${for fields { 1 }}, 1)) { ${error "Single field only"}}}
257

            
258
    ${define KP_NAME $( $fname )}
259
    ${define PK_NAME ${tmeta(kp(pubkey)) as ident}}
260

            
261
    /// Public key component of this keypair. Useful if we move the public key around,
262
    /// it then keeps it semantic with the name and less prone to errors.
263
    #[derive(Clone, Debug, PartialEq, Eq)]
264
    #[derive($crate::macro_deps::derive_more::From, $crate::macro_deps::derive_more::Into)]
265
    #[non_exhaustive]
266
    $tvis struct $PK_NAME ($crate::macro_deps::curve25519::PublicKey);
267

            
268
    impl std::borrow::Borrow<$crate::macro_deps::curve25519::PublicKey> for $PK_NAME {
269
        #[inline]
270
        fn borrow(&self) -> &$crate::macro_deps::curve25519::PublicKey {
271
            &self.0
272
        }
273
    }
274

            
275
    impl $PK_NAME {
276
        /// Get the inner [`PublicKey`]($crate::macro_deps::curve25519::PublicKey).
277
        // This can be nicer to use than
278
        // `<FooPublicKey as Borrow<curve25519::PublicKey>>::borrow(&foo)`.
279
        #[inline]
280
8
        $tvis fn inner(&self) -> &$crate::macro_deps::curve25519::PublicKey {
281
            &self.0
282
        }
283
    }
284

            
285
    impl $ttype {
286
        /// Build the raw inner public key into the wrapper public key object.
287
408
        $tvis fn public(&self) -> $PK_NAME {
288
            $PK_NAME(self.public_raw().clone())
289
        }
290

            
291
        /// The raw inner public key.
292
        ///
293
        /// It's expected that this method will be called only just before the key is needed,
294
        /// in situations where [`public()`](Self::public) would be inconvenient.
295
        ///
296
        /// If you intend to keep an owned version of the key around,
297
        /// prefer `public()` to store its wrapper type
298
        /// which gives semantic information indicating the purpose of the key.
299
1581
        $tvis fn public_raw(&self) -> &$crate::macro_deps::curve25519::PublicKey {
300
            &self.$KP_NAME.public
301
        }
302

            
303
        /// The raw inner secret key.
304
        ///
305
        /// We return it directly without a wrapper type because it's expected that the secret key
306
        /// will not be moved around,
307
        /// and instead accessed only just before it's needed.
308
306
        $tvis fn secret(&self) -> &$crate::macro_deps::curve25519::StaticSecret {
309
            &self.$KP_NAME.secret
310
        }
311

            
312
        /// Wrapper around the diffie_hellman() function of the underlying type. This is pretty fun
313
        /// because it accepts both the PK_NAME wrapper or the raw inner curve25519::PublicKey.
314
        $tvis fn diffie_hellman<T>(&self, pk: T) -> $crate::macro_deps::curve25519::SharedSecret
315
        where
316
            T: std::borrow::Borrow<$crate::macro_deps::curve25519::PublicKey>
317
        {
318
            self.$KP_NAME.secret.diffie_hellman(pk.borrow())
319
        }
320
    }
321

            
322
    impl From<$crate::macro_deps::curve25519::StaticKeypair> for $ttype {
323
2193
        fn from(kp: $crate::macro_deps::curve25519::StaticKeypair) -> Self {
324
            Self(kp)
325
        }
326
    }
327

            
328
    /// Implementing EncodableItem, ToEncodableKey and Keygen allows this wrapper key to be stored
329
    /// in a keystore.
330

            
331
    impl $crate::ItemType for $ttype {
332
        fn item_type() -> $crate::KeystoreItemType {
333
            $crate::KeyType::X25519StaticKeypair.into()
334
        }
335
    }
336

            
337
    impl $crate::EncodableItem for $ttype {
338
        fn as_keystore_item(&self) -> $crate::Result<$crate::KeystoreItem> {
339
            self.$KP_NAME.as_keystore_item()
340
        }
341
    }
342

            
343
    impl $crate::ToEncodableKey for $ttype {
344
        type Key = $crate::macro_deps::curve25519::StaticKeypair;
345
        type KeyPair = $ttype;
346

            
347
        fn to_encodable_key(self) -> Self::Key {
348
            self.$KP_NAME
349
        }
350
1122
        fn from_encodable_key(key: Self::Key) -> Self {
351
            Self(key)
352
        }
353
    }
354

            
355
    impl $crate::Keygen for $ttype {
356
        fn generate(mut rng: &mut dyn $crate::KeygenRng) -> $crate::Result<Self>
357
        where
358
            Self: Sized
359
        {
360
            let secret = $crate::macro_deps::curve25519::StaticSecret::random_from_rng(rng);
361
            let public: $crate::macro_deps::curve25519::PublicKey = (&secret).into();
362
            let kp = $crate::macro_deps::curve25519::StaticKeypair {
363
                secret: secret.into(),
364
                public: public.into(),
365
            };
366
            Ok(kp.into())
367
        }
368
    }
369
}
370

            
371
/// Create an RSA keypair wrapper given a visibility and a struct name.
372
///
373
/// # Syntax:
374
/// ```rust,ignore
375
/// define_rsa_keypair(<visibility> <prefix>)
376
/// ```
377
///
378
/// This macro creates a struct tuple named `<prefix>Keypair` which contains the lower-level
379
/// cryptographic keypair for an RSA keypair. It derives the deftly RsaKeypair template
380
/// which in turn creates `<prefix>PublicKey` along a series of useful methods.
381
///
382
/// The keypair is NOT clonable by design in order to avoid duplicating secret key material.
383
///
384
/// # Example:
385
///
386
/// ```rust
387
/// use tor_key_forge::define_rsa_keypair;
388
///
389
/// define_rsa_keypair!(NonPublicSigning);
390
/// define_rsa_keypair!(pub PublicSigning);
391
/// define_rsa_keypair!(pub(crate) CratePublicSigning);
392
/// ```
393
///
394
/// The above results in `NonPublicSigningKeypair` and `NonPublicSigningPublicKey` struct being
395
/// created and usable with a series of useful methods. Same for the other defines.
396
///
397
/// You can then use these objects like so:
398
///
399
/// ```rust
400
/// # use tor_llcrypto::rng::FakeEntropicRng;
401
/// # let mut rng = FakeEntropicRng(rand::rng());
402
/// use rand::Rng;
403
/// use tor_key_forge::Keygen;
404
/// use tor_key_forge::define_rsa_keypair;
405
/// use tor_llcrypto::pk::ValidatableSignature;
406
/// use tor_llcrypto::pk::rsa::KeyPair;
407
///
408
/// define_rsa_keypair!(
409
///     /// Our signing key.
410
///     MyRsa
411
/// );
412
///
413
/// let signing_kp = MyRsaKeypair::generate(&mut rng).expect("Invalid keygen");
414
/// let signing_pubkey = signing_kp.public();
415
/// // Lets sign this wonderful message.
416
/// let message = "Workers want rights, not your opinion".as_bytes();
417
/// let sig = signing_kp.sign(&message).expect("Error signing message");
418
///
419
/// // You can then verify either directly with the keypair or the public key.
420
/// assert!(signing_kp.verify(&sig, &message));
421
/// assert!(signing_pubkey.verify(&sig, &message));
422
/// ```
423
#[macro_export]
424
macro_rules! define_rsa_keypair {
425
    ($(#[ $docs_and_attrs:meta ])*
426
     $vis:vis $base_name:ident) => {
427
        $crate::macro_deps::paste! {
428
            #[derive($crate::derive_deftly::Deftly)]
429
            #[derive_deftly($crate::macro_deps::RsaKeypair)]
430
            #[deftly(kp(pubkey = $base_name "PublicKey"))]
431
            #[non_exhaustive]
432
            $(#[ $docs_and_attrs ])*
433
            $vis struct [<$base_name "Keypair">]($crate::macro_deps::rsa::KeyPair);
434
        }
435
    };
436
}
437

            
438
define_derive_deftly! {
439
    /// Implement set of helper functions around a type wrapping a rsa::KeyPair.
440
    export RsaKeypair for struct:
441

            
442
    // Enforce that the object has a single field. We want to avoid the implementer to start
443
    // storing metadata or other things in this object that is meant specifically to be
444
    // a semantic wrapper around an RSA keypair.
445
    ${if not(approx_equal(${for fields { 1 }}, 1)) { ${error "Single field only"}}}
446

            
447
    ${define KP_NAME $( $fname )}
448
    ${define PK_NAME ${tmeta(kp(pubkey)) as ident}}
449

            
450
    /// Public key component of this keypair. Useful if we move the public key around,
451
    /// it then keeps it semantic with the name and less prone to errors.
452
    #[derive(Clone, Debug, PartialEq, Eq)]
453
    #[derive($crate::macro_deps::derive_more::From, $crate::macro_deps::derive_more::Into)]
454
    #[non_exhaustive]
455
    $tvis struct $PK_NAME ($tvis $crate::macro_deps::rsa::PublicKey);
456

            
457
    impl $PK_NAME {
458
        /// Verify the signature of a given message.
459
        #[allow(unused)]
460
        $tvis fn verify(&self, sig: &[u8], text: &[u8]) -> bool {
461
            use $crate::macro_deps::ValidatableSignature;
462
            $crate::macro_deps::rsa::ValidatableRsaSignature::new(&self.0, sig, text).is_valid()
463
        }
464
    }
465

            
466
    // We don't expect all implementations to use all code.
467
    #[allow(unused)]
468
    impl $ttype {
469
        /// Build the raw inner public key into the wrapper public key object.
470
154
        $tvis fn public(&self) -> $PK_NAME {
471
            $PK_NAME((&self.$KP_NAME).into())
472
        }
473

            
474
        /// Reference to the internal keypair.
475
306
        $tvis fn keypair(&self) -> &$crate::macro_deps::rsa::KeyPair {
476
            &self.0
477
        }
478

            
479
        /// Sign the given message.
480
1
        $tvis fn sign(&self, message: &[u8]) -> Result<Vec<u8>, $crate::macro_deps::rsa::Error> {
481
            self.0.sign(message)
482
        }
483

            
484
        /// Verify the signature of a given message.
485
2
        $tvis fn verify(&self, sig: &[u8], text: &[u8]) -> bool {
486
            use $crate::macro_deps::ValidatableSignature;
487
            $crate::macro_deps::rsa::ValidatableRsaSignature::new(
488
                &self.0.to_public_key(), sig, text
489
            ).is_valid()
490
        }
491

            
492
        /// Return a RsaIdentity built from this keypair.
493
        $tvis fn to_rsa_identity(&self) -> $crate::macro_deps::rsa::RsaIdentity {
494
            self.public().0.to_rsa_identity()
495
        }
496
    }
497

            
498
    impl From<$crate::macro_deps::rsa::KeyPair> for $ttype {
499
        fn from(kp: $crate::macro_deps::rsa::KeyPair) -> Self {
500
            Self(kp)
501
        }
502
    }
503

            
504
    /// Implementing EncodableItem, ToEncodableKey and Keygen allows this wrapper key to be stored
505
    /// in a keystore.
506

            
507
    impl $crate::ItemType for $ttype {
508
        fn item_type() -> $crate::KeystoreItemType {
509
            $crate::KeyType::RsaKeypair.into()
510
        }
511
    }
512

            
513
    impl $crate::EncodableItem for $ttype {
514
        fn as_keystore_item(&self) -> $crate::Result<$crate::KeystoreItem> {
515
            self.$KP_NAME.as_keystore_item()
516
        }
517
    }
518

            
519
    impl $crate::ToEncodableKey for $ttype {
520
        type Key = $crate::macro_deps::rsa::KeyPair;
521
        type KeyPair = $ttype;
522

            
523
        fn to_encodable_key(self) -> Self::Key {
524
            self.$KP_NAME
525
        }
526
714
        fn from_encodable_key(key: Self::Key) -> Self {
527
            Self(key)
528
        }
529
    }
530

            
531
    impl $crate::Keygen for $ttype {
532
52
        fn generate(mut rng: &mut dyn $crate::KeygenRng) -> $crate::Result<Self>
533
52
        where
534
52
            Self: Sized
535
        {
536
            Ok(Self { $KP_NAME: $crate::macro_deps::rsa::KeyPair::generate(&mut rng)? })
537
        }
538
    }
539
}
540

            
541
// Re-export dependencies as `tor_key_forge::macro_deps` that we use to make this macro work.
542
#[doc(hidden)]
543
pub mod deps {
544
    pub use derive_deftly_template_Curve25519Keypair;
545
    pub use derive_deftly_template_Ed25519Keypair;
546
    pub use derive_deftly_template_RsaKeypair;
547
    pub use derive_more;
548
    pub use paste::paste;
549
    pub use signature;
550
    pub use tor_llcrypto::pk::{ValidatableSignature, curve25519, ed25519, rsa};
551
}
552

            
553
#[cfg(test)]
554
mod test {
555
    use crate::Keygen;
556
    use tor_basic_utils::test_rng::testing_rng;
557
    use tor_llcrypto::{pk::ed25519::Ed25519SigningKey, rng::FakeEntropicRng};
558

            
559
    #[test]
560
    fn deftly_ed25519_keypair() {
561
        define_ed25519_keypair!(SomeEd25519);
562

            
563
        let mut rng = FakeEntropicRng(testing_rng());
564
        let kp = SomeEd25519Keypair::generate(&mut rng).expect("Failed to gen key");
565

            
566
        // Make sure the generated public key from our wrapper is the same as the
567
        // underlying keypair.
568
        let pubkey = kp.public();
569
        assert_eq!(pubkey.0, kp.0.verifying_key());
570

            
571
        // Message to sign and verify.
572
        let msg: [u8; 4] = [2, 3, 4, 5];
573
        let msg_bad: [u8; 4] = [2, 3, 4, 6];
574

            
575
        let sig = kp.sign(msg.as_slice());
576
        assert!(kp.verify(sig, msg.as_slice()));
577
        // Lets make sure we don't validate another message.
578
        assert!(!kp.verify(sig, msg_bad.as_slice()));
579
    }
580

            
581
    #[test]
582
    fn deftly_rsa_keypair() {
583
        define_rsa_keypair!(SomeRsa);
584

            
585
        let mut rng = FakeEntropicRng(testing_rng());
586
        let kp = SomeRsaKeypair::generate(&mut rng).expect("Failed to gen key");
587

            
588
        // Make sure the generated public key from our wrapper is the same as the
589
        // underlying keypair.
590
        let pubkey = kp.public();
591
        assert_eq!(pubkey.0, kp.0.to_public_key());
592

            
593
        // Message to sign and verify.
594
        let msg: [u8; 4] = [2, 3, 4, 5];
595
        let msg_bad: [u8; 4] = [2, 3, 4, 6];
596

            
597
        let sig = kp.sign(msg.as_slice()).expect("Failed to sign message.");
598
        assert!(kp.verify(&sig, msg.as_slice()));
599
        // Lets make sure we don't validate another message.
600
        assert!(!kp.verify(&sig, msg_bad.as_slice()));
601
    }
602
}