1#![no_std]
17
18use core::iter::{Cycle, Iterator, Peekable};
19use core::slice::Iter;
20
21pub type ChiPattern = ([bool; 41], [bool; 31], [bool; 29], [bool; 26], [bool; 23]);
22pub type MuPattern = ([bool; 37], [bool; 61]);
23pub type PsiPattern = ([bool; 43], [bool; 47], [bool; 51], [bool; 53], [bool; 59]);
24
25pub struct Machine<'a> {
27 chi: &'a ChiPattern,
28 mu: &'a MuPattern,
29 psi: &'a PsiPattern,
30}
31
32impl<'a> Machine<'a> {
33 pub fn new((chi, mu, psi): &'a (ChiPattern, MuPattern, PsiPattern)) -> Self {
35 Machine { chi, mu, psi }
36 }
37
38 pub fn keystream(&self) -> Keystream {
40 Keystream {
41 chi: (
45 self.chi.0.iter().cycle().peekable(),
46 self.chi.1.iter().cycle().peekable(),
47 self.chi.2.iter().cycle().peekable(),
48 self.chi.3.iter().cycle().peekable(),
49 self.chi.4.iter().cycle().peekable(),
50 ),
51 mu: (
52 self.mu.0.iter().cycle().peekable(),
53 self.mu.1.iter().cycle().peekable(),
54 ),
55 psi: (
56 self.psi.0.iter().cycle().peekable(),
57 self.psi.1.iter().cycle().peekable(),
58 self.psi.2.iter().cycle().peekable(),
59 self.psi.3.iter().cycle().peekable(),
60 self.psi.4.iter().cycle().peekable(),
61 ),
62 }
63 }
64}
65
66type Impulse<'a> = Peekable<Cycle<Iter<'a, bool>>>;
67
68pub struct Keystream<'a> {
70 chi: (
71 Impulse<'a>,
72 Impulse<'a>,
73 Impulse<'a>,
74 Impulse<'a>,
75 Impulse<'a>,
76 ),
77 mu: (Impulse<'a>, Impulse<'a>),
78 psi: (
79 Impulse<'a>,
80 Impulse<'a>,
81 Impulse<'a>,
82 Impulse<'a>,
83 Impulse<'a>,
84 ),
85}
86
87impl<'a> Iterator for Keystream<'a> {
88 type Item = u32;
89
90 fn next(&mut self) -> Option<Self::Item> {
91 let basic_motor: bool = if *self.mu.1.next().unwrap() {
94 *self.mu.0.next().unwrap()
95 } else {
96 **self.mu.0.peek().unwrap()
97 };
98 let total_motor = basic_motor;
99
100 let chi: u32 = (*self.chi.0.next().unwrap() as u32)
102 | ((*self.chi.1.next().unwrap() as u32) << 1)
103 | ((*self.chi.2.next().unwrap() as u32) << 2)
104 | ((*self.chi.3.next().unwrap() as u32) << 3)
105 | ((*self.chi.4.next().unwrap() as u32) << 4);
106 if total_motor {
107 Some(
108 chi ^ ((*self.psi.0.next().unwrap() as u32)
109 | ((*self.psi.1.next().unwrap() as u32) << 1)
110 | ((*self.psi.2.next().unwrap() as u32) << 2)
111 | ((*self.psi.3.next().unwrap() as u32) << 3)
112 | ((*self.psi.4.next().unwrap() as u32) << 4)),
113 )
114 } else {
115 Some(
116 chi ^ ((**self.psi.0.peek().unwrap() as u32)
117 | ((**self.psi.1.peek().unwrap() as u32) << 1)
118 | ((**self.psi.2.peek().unwrap() as u32) << 2)
119 | ((**self.psi.3.peek().unwrap() as u32) << 3)
120 | ((**self.psi.4.peek().unwrap() as u32) << 4)),
121 )
122 }
123 }
124}
125
126#[cfg(test)]
127mod test {
128 use super::*;
129
130 #[test]
131 fn it_produces_zmug_keystream() {
132 let machine = Machine::new(&patterns::ZMUG_PATTERN);
134 let mut keystream = machine.keystream();
135 assert_eq!(keystream.next(), Some(0b01010 ^ 0b10001));
136 assert_eq!(keystream.next(), Some(0b11000 ^ 0b10001));
137 assert_eq!(keystream.next(), Some(0b00101 ^ 0b01110));
138 assert_eq!(keystream.next(), Some(0b11101 ^ 0b10110));
139 assert_eq!(keystream.next(), Some(0b00110 ^ 0b11100));
140 let mut keystream = keystream.skip(995);
141 assert_eq!(keystream.next(), Some(0b11110));
142 assert_eq!(keystream.next(), Some(0b01110));
143 assert_eq!(keystream.next(), Some(0b11111));
144 assert_eq!(keystream.next(), Some(0b10111));
145 assert_eq!(keystream.next(), Some(0b11010));
146 }
147}
148
149pub mod patterns {
150 use crate::{ChiPattern, MuPattern, PsiPattern};
151
152 #[rustfmt::skip]
154 pub const ZMUG_PATTERN: (ChiPattern, MuPattern, PsiPattern) = (
155 (
156 [false, false, true , true , false, false, true , true , true , false, false, false, false, true , true , true , false, false, true , true , true , false, false, false, false, true , false, false, true , true , false, true , true , false, false, false, true , true , false, true , true ],
157 [true , false, false, false, true , true , false, false, true , true , false, false, false, true , false, true , true , true , true , false, true , true , true , false, false, false, false, true , true , false, true ],
158 [false, false, true , true , true , true , false, true , true , false, false, false, true , true , true , false, false, false, true , true , false, false, false, true , true , false, false, true , false],
159 [true , true , false, true , false, false, true , true , true , false, true , false, false, true , true , false, false, false, true , true , false, false, true , false, true , false],
160 [false, true , false, true , false, false, false, false, true , true , true , false, true , false, false, false, true , true , true , true , false, false, true ],
161 ),
162 (
163 [false, true , true , true , false, true , true , true , false, true , true , true , false, true , false, true , true , false, true , true , true , false, true , true , true , false, true , true , false, true , false, true , true , false, true , false, true ],
164 [true , true , false, true , false, true , false, true , true , true , true , false, true , false, true , false, true , true , true , false, true , true , true , false, true , true , true , false, true , true , false, true , true , false, true , true , false, true , true , false, true , true , true , false, true , false, true , false, true , true , true , false, true , true , true , false, true , false, true , true , false],
165 ),
166 (
167 [true , false, false, false, true , true , true , false, false, true , true , true , false, false, true , true , true , true , false, false, false, true , true , false, false, false, true , true , false, false, true , true , true , false, false, false, true , true , false, false, true , false, true ],
168 [false, true , true , false, true , false, false, true , true , true , false, false, true , true , true , false, false, true , true , false, false, false, true , true , true , true , false, false, false, true , true , true , false, false, true , true , false, false, true , true , true , false, false, false, true , false, false],
169 [false, true , true , true , false, false, true , true , false, false, false, true , true , false, false, false, true , true , true , false, false, false, true , false, false, false, true , true , true , true , false, false, false, true , false, false, true , true , true , false, false, true , true , true , false, false, true , true , false, false, true ],
170 [false, true , false, true , true , true , false, false, true , true , false, false, false, true , true , false, false, true , false, false, true , true , true , false, false, true , true , false, false, false, true , false, false, false, true , true , true , true , false, false, true , true , true , false, false, true , true , false, false, true , true , true , false],
171 [true , false, true , true , false, false, false, true , false, false, true , true , true , false, false, true , true , false, false, true , true , true , false, false, true , true , false, false, false, true , true , true , true , false, false, true , false, false, true , true , true , false, false, true , true , true , true , false, false, false, true , false, false, false, true , true , true , false, false],
172 ),
173 );
174}