1use crate::UnwrappedKey;
6use aes::Aes256;
7use aes::cipher::generic_array::GenericArray;
8use aes::cipher::{BlockEncrypt, KeyInit};
9use byteorder::{BigEndian, ByteOrder};
10
11#[derive(Clone)]
15pub struct Ff1 {
16    initial_block: [u8; 16],
17    cipher: Aes256,
18}
19
20impl Ff1 {
21    pub fn new(key: &UnwrappedKey) -> Self {
22        let cipher = Aes256::new(GenericArray::from_slice(key));
23        let mut initial_block = [1, 2, 1, 0, 0, 2, 10, 16, 0, 0, 0, 32, 0, 0, 0, 0];
25        cipher.encrypt_block(GenericArray::from_mut_slice(&mut initial_block));
26        Self { initial_block, cipher }
28    }
29
30    pub fn encrypt(&self, data: u32) -> u32 {
31        let mut a = (data >> 16) as u16;
33        let mut b = data as u16;
34
35        for i in 0..10 {
37            let mut block = self.initial_block.clone();
39            block[13] ^= i;
41            block[14] ^= (b >> 8) as u8;
42            block[15] ^= b as u8;
43            self.cipher.encrypt_block(GenericArray::from_mut_slice(&mut block));
44            let c = a.wrapping_add(BigEndian::read_u16(&block[6..8]));
48            a = b;
49            b = c;
50        }
51        (a as u32) << 16 | b as u32
52    }
53
54    pub fn decrypt(&self, data: u32) -> u32 {
58        let mut a = (data >> 16) as u16;
59        let mut b = data as u16;
60
61        for i in (0..10).rev() {
62            let mut block = self.initial_block.clone();
64            block[13] ^= i;
66            block[14] ^= (a >> 8) as u8;
67            block[15] ^= a as u8;
68            self.cipher.encrypt_block(GenericArray::from_mut_slice(&mut block));
69            let c = b.wrapping_sub(BigEndian::read_u16(&block[6..8]));
73            b = a;
74            a = c;
75        }
76        (a as u32) << 16 | b as u32
77    }
78}
79
80#[cfg(test)]
81mod tests {
82    use super::Ff1;
83    use crate::UnwrappedKey;
84
85    #[test]
86    fn test_ff1() {
87        let ff1 = Ff1::new(&UnwrappedKey::new(vec![0; 32]));
91        assert_eq!(ff1.encrypt(1), 0x27c9468);
92        assert_eq!(ff1.encrypt(999), 0x87a92dd5);
93        assert_eq!(ff1.encrypt(11471928), 0x70c679b1);
94        assert_eq!(ff1.encrypt(318689559), 0xdec5199a);
95
96        let ff1 = Ff1::new(&UnwrappedKey::new(vec![
97            1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
98            0, 1, 2,
99        ]));
100        assert_eq!(ff1.encrypt(1), 0x92fac14e);
101        assert_eq!(ff1.encrypt(999), 0x6d2cd513);
102        assert_eq!(ff1.encrypt(11471928), 0xdb672d05);
103        assert_eq!(ff1.encrypt(318689559), 0x66d58b7e);
104
105        let ff1 = Ff1::new(&UnwrappedKey::new(vec![
106            0xf8, 0x24, 0x6b, 0x2c, 0x38, 0x39, 0xfa, 0x6d, 0x98, 0xe8, 0x56, 0x17, 0x0c, 0xdd,
107            0xf4, 0xf1, 0x1b, 0xa5, 0xa6, 0xcb, 0x07, 0x06, 0x58, 0x4c, 0x2a, 0x63, 0x9d, 0x32,
108            0x22, 0x80, 0xe6, 0xf1,
109        ]));
110        assert_eq!(ff1.encrypt(1), 0xfc049c96);
111        assert_eq!(ff1.encrypt(999), 0xbe10a02a);
112        assert_eq!(ff1.encrypt(11471928), 0xe1290afd);
113        assert_eq!(ff1.encrypt(318689559), 0xf4fcf414);
114
115        for _ in 0..100 {
116            let v = rand::random();
117            assert_eq!(ff1.decrypt(ff1.encrypt(v)), v);
118        }
119    }
120}