1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
use rand::{OsRng, Rng};

/// Size of a challenge message
pub const CHALLENGE_SIZE: usize = 8;

/// A challenge message, sent by either host or the card
pub struct Challenge([u8; CHALLENGE_SIZE]);

impl Challenge {
    /// Generate a random Challenge using OsRng
    pub fn random() -> Self {
        Self::new(&mut OsRng::new().expect("RNG failure!"))
    }

    /// Create a new Challenge using the given RNG
    pub fn new(rng: &mut Rng) -> Self {
        let mut challenge = [0u8; CHALLENGE_SIZE];
        rng.fill_bytes(&mut challenge);
        Challenge(challenge)
    }

    /// Create a new challenge from a slice
    ///
    /// Panics if the slice is not 8-bytes
    pub fn from_slice(slice: &[u8]) -> Self {
        assert_eq!(slice.len(), 8, "challenge must be 8-bytes long");

        let mut challenge = [0u8; CHALLENGE_SIZE];
        challenge.copy_from_slice(slice);
        Challenge(challenge)
    }

    /// Borrow the challenge value as a slice
    pub fn as_slice(&self) -> &[u8] {
        &self.0
    }
}