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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use std::sync::Arc;
use super::jacopone::hash;

pub struct CipherData{
    message: Arc<Vec<u8>>,
    key: Arc<Vec<u8>>,
    nonce: Arc<Vec<u8>>,
    counter: u64,
    round_keys: Arc<Vec<Vec<u8> > >,
    start : usize,
    end: usize,
}

impl CipherData {

    ///Create new references to message, key, nonce, and counter and store them in CipherData
    pub fn new (message: Vec<u8>, key: Vec<u8>, nonce: Vec<u8>, counter: u64) -> CipherData {
        assert_eq!(nonce.len(), 60, "invalid nonce len: {}. required: {}",nonce.len(), 60);
        assert_eq!(key.len(), 32, "invalid key len: {}. required: {}", key.len(), 32);
        let len = message.len();
        let round_keys = CipherData::generate_round_keys(&key);
        CipherData {message: Arc::new(message), key: Arc::new(key),
            nonce: Arc::new(nonce), counter: counter ,round_keys: Arc::new(round_keys), start: 0, end: len}
    }

    ///Clone the references
    pub fn clone(other: &CipherData) -> CipherData {
        CipherData {message: Arc::clone(&other.message), key: Arc::clone(&other.key),
            nonce: Arc::clone(&other.nonce), counter: other.counter, round_keys: Arc::clone(&other.round_keys), start: other.start, end: other.end}
    }


    ///Return references to portions of original message and different counter. New message is a reference from start to end blocks of other.message
    /// while new counter is equals to other.counter incremented by end
    pub fn clone_slice(other: &CipherData, s: usize, e: usize) -> CipherData {
        CipherData {message: Arc::clone(&other.message), key: Arc::clone(&other.key), 
            nonce: Arc::clone(&other.nonce), counter: other.counter + s as u64, round_keys: Arc::clone(&other.round_keys), start: s * 64, end: e * 64}
 
    }
    
    fn generate_round_keys(key: &[u8]) -> Vec<Vec<u8>> {
        vec![hash(key, &key[0..8]), hash(key, &key[8..16]),
            hash(key, &key[16..24]), hash(key, &key[24..32])]
    }

    pub fn get_message(&self) -> &Arc<Vec<u8>> {
        &self.message
    }

    pub fn get_key(&self) -> &Arc<Vec<u8>> {
        &self.key
    }

    pub fn get_nonce(&self) -> &Arc<Vec<u8>> {
        &self.nonce
    }

    pub fn get_counter(&self) -> u64 {
        self.counter
    }

    pub fn get_start(&self) -> usize {
        self.start
    }

    pub fn get_blocks_len(&self) -> usize {
        (self.end - self.start)/64
    }

    pub fn get_round_keys(&self) -> &Arc<Vec<Vec<u8>>>{
        &self.round_keys
    }
    
}

#[cfg(test)]
mod tests {
    use crate::jacopone::*;
    use crate::CipherData;

    #[test]
    #[should_panic]
    fn assert_invalid_key_1(){
        let message = "aaaaaaaaaa".as_bytes().to_vec();
        let nonce = vec![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,0,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,0];
        let key = vec![3,4,5,6,7,8,9,0,9,8,7,6,5,4,3,2,1,2,3,4,5,6,7,8,9,0,9,8,7,3,5];
        CipherData::new(message, key, nonce, 453);
    }

    #[test]
    #[should_panic]
    fn assert_invalid_key_2(){
        let message = "aaaaaaaaaa".as_bytes().to_vec();
        let nonce = vec![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,0,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,0];
        let key = vec![2,3,4,5,6,7,8,9,0,9,8,7,6,5,4,3,2,1,2,3,4,5,6,7,8,9,0,9,8,7,3,54,1,2,3,4,3];
        CipherData::new(message, key, nonce, 453);
    }

    #[test]
    #[should_panic]
    fn assert_invalid_key_nonce_1(){
        let message = "aaaaaaaaaa".as_bytes().to_vec();
        let key = vec![12,45,98,43,1,32,65,99,1,43,76,98,12,98,43,65,12,45,98,43,1,32,65,99,1,43,76,98,12,98,43,65];
        let nonce = vec![1,2,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,0,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,0];
        CipherData::new(message, key, nonce, 453);
    }

    #[test]
    #[should_panic]
    fn assert_invalid_key_nonce_2(){
        let message = "aaaaaaaaaa".as_bytes().to_vec();
        let key = vec![12,45,98,43,1,32,65,99,1,43,76,98,12,98,43,65,12,45,98,43,1,32,65,99,1,43,76,98,12,98,43,65];
        let nonce = vec![99,4,43,12,43,65,23,65,87,1,98,9,8,7,6,5,4,3,2,1,54,0,87,98,1,45,87,32,8,34,2,34,34,76,32,176,87,231,22,201,234,63,76,9,76,87,1,3,4,8,54,32,13,98,56,44,33,76,54,34,65];
        CipherData::new(message, key, nonce, 453);
    }
}