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
use crateLfsr;
use crateFlipFlop;
/// Reconstructs the original message from a sequence encrypted using an LFSR.
///
/// This function performs a reverse operation on a stream cipher that uses a
/// Linear Feedback Shift Register (LFSR). Given:
///
/// - `y`: the encrypted sequence
/// - `x`: the known plaintext (or known keystream portion)
/// - `n`: the number of flip-flops (LFSR size)
/// - `rule`: the feedback function used by the LFSR
///
/// The function first reconstructs the initial LFSR state using the XOR
/// between the known plaintext and the encrypted sequence. Then, it rebuilds
/// the keystream using the LFSR and decrypts the entire message.
///
/// # Arguments
///
/// * `y` - The encrypted sequence as a vector of `FlipFlop`s
/// * `n` - The number of flip-flops in the LFSR
/// * `x` - Known plaintext or known keystream prefix
/// * `rule` - Feedback function used by the LFSR
///
/// # Returns
///
/// Returns a `Result` containing:
///
/// * `Ok(Vec<FlipFlop>)` — The reconstructed original message
/// * `Err` — If the known plaintext is shorter than the LFSR size
///
/// # Errors
///
/// Returns an error if:
///
/// * `x.len() < n`, meaning there is not enough known data to reconstruct
/// the initial LFSR state.
///
/// # Example
///
/// ```
/// use cryptograph::tools::flip_flop::FlipFlop;
/// use cryptograph::pseudorandom_generator::lfsr::Lfsr;
/// use cryptograph::cryptoanalysis::reverse_lfsr::reverse_lfsr;
///
/// let y = vec![
/// FlipFlop::new(true),
/// FlipFlop::new(false),
/// FlipFlop::new(true),
/// ];
///
/// let x = vec![
/// FlipFlop::new(false),
/// FlipFlop::new(true),
/// FlipFlop::new(false),
/// ];
///
/// let result = reverse_lfsr(
/// y,
/// 3,
/// x,
/// |ff| ff[0].get() ^ ff[ff.len() - 1].get(),
/// );
///
/// assert!(result.is_ok());
/// ```