177
school/intro-crypto/uebung/04/lfsr/src/main.rs
Normal file
177
school/intro-crypto/uebung/04/lfsr/src/main.rs
Normal file
@ -0,0 +1,177 @@
|
||||
struct Lfsr {
|
||||
reg: Vec<bool>,
|
||||
p: Vec<bool>,
|
||||
}
|
||||
|
||||
impl Lfsr {
|
||||
fn new(iv: &[bool], p: &[bool]) -> Self {
|
||||
assert_eq!(iv.len(), p.len());
|
||||
Self {
|
||||
reg: iv.iter().cloned().collect(),
|
||||
p: p.iter().cloned().collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn next(&mut self) -> bool {
|
||||
// let res = self.reg[self.len - 1];
|
||||
let next = self
|
||||
.reg
|
||||
.iter()
|
||||
.zip(self.p.iter())
|
||||
.map(|(n, m)| n & m)
|
||||
.fold(false, |acc, v| acc ^ v);
|
||||
self.reg.insert(0, next);
|
||||
let ret = self.reg.pop().unwrap();
|
||||
assert_eq!(self.reg.len(), self.p.len());
|
||||
ret
|
||||
}
|
||||
|
||||
fn state(&self) -> &[bool] {
|
||||
&self.reg
|
||||
}
|
||||
}
|
||||
|
||||
fn convert_state(s: &[bool]) -> String {
|
||||
s.iter()
|
||||
.map(|x| if *x { "1".to_string() } else { "0".to_string() })
|
||||
.collect::<Vec<String>>()
|
||||
.join(" & ")
|
||||
}
|
||||
|
||||
/// helper for 3c)
|
||||
fn recover_keystream(plain: &[bool], cipher: &[bool]) -> Vec<bool> {
|
||||
assert_eq!(plain.len(), cipher.len());
|
||||
plain
|
||||
.iter()
|
||||
.zip(cipher.iter())
|
||||
.map(|(a, b)| a ^ b)
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn decrypt(l: &mut Lfsr, c: &[bool]) -> u8 {
|
||||
let s: String = c
|
||||
.into_iter()
|
||||
.map(|c| c ^ l.next())
|
||||
.map(|c| if c { "1" } else { "0" })
|
||||
.collect();
|
||||
u8::from_str_radix(&s, 2).unwrap()
|
||||
}
|
||||
|
||||
/// main for 3d)
|
||||
fn main() {
|
||||
let p = &[false, true, true, false, false, false, true, true];
|
||||
// let s = &[true, false, true, true, true, false, true, true];
|
||||
// let s = &[true, false, true, false, false, false, false, true];
|
||||
// let s = &[true, false, false, false, false, true, false, true];
|
||||
let s = &[true, true, false, true, true, true, false, true];
|
||||
let mut l = Lfsr::new(s, p);
|
||||
// for _ in 0..17 {
|
||||
// println!("{}", if lfsr.next() { "1" } else { "0" });
|
||||
// }
|
||||
// 00010011
|
||||
// 11010100
|
||||
let c = &[true, true, false, true, false, true, false, false];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 00010011 = 0x13
|
||||
let c = &[false, false, false, true, false, false, true, true];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 00010000 = 0x10
|
||||
let c = &[false, false, false, true, false, false, false, false];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 01110101 = 0x75
|
||||
let c = &[false, true, true, true, false, true, false, true];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 01100000 = 0x60
|
||||
let c = &[false, true, true, false, false, false, false, false];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 00000101 = 0x05
|
||||
let c = &[false, false, false, false, false, true, false, true];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 01111100 = 0x7c
|
||||
let c = &[false, true, true, true, true, true, false, false];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 01010000 = 0x50
|
||||
let c = &[false, true, false, true, false, false, false, false];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 11011011 = 0xdb
|
||||
let c = &[true, true, false, true, true, false, true, true];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
|
||||
// 01110011 = 0x73
|
||||
let c = &[false, true, true, true, false, false, true, true];
|
||||
let d = decrypt(&mut l, c);
|
||||
println!("{}: {}", d, d as char);
|
||||
}
|
||||
|
||||
// fn main() {
|
||||
// let plain = &[
|
||||
// false, true, false, false, true, true, false, true, false, true, true, false, true, true,
|
||||
// true, true,
|
||||
// ];
|
||||
// let cipher = &[
|
||||
// true, true, true, false, true, true, false, false, true, true, false, true, false, true,
|
||||
// false, false,
|
||||
// ];
|
||||
// let key_stream = recover_keystream(plain, cipher);
|
||||
// println!(
|
||||
// "{}",
|
||||
// key_stream
|
||||
// .iter()
|
||||
// .map(|k| if *k { "1, " } else { "0, " })
|
||||
// .collect::<String>()
|
||||
// );
|
||||
// }
|
||||
|
||||
/// main for exercise 1
|
||||
fn main1() {
|
||||
// 1a)
|
||||
// let mut lfsr = Lfsr::new(
|
||||
// &[true, true, false, false, false, false],
|
||||
// // &[true, true, true, true, true, true],
|
||||
// // &[true, false, false, false, false, false],
|
||||
// &[false, true, false, true, true, true],
|
||||
// );
|
||||
|
||||
// 1b)
|
||||
// let mut lfsr = Lfsr::new(
|
||||
// // &[true, true, true, true, true, true],
|
||||
// &[true, false, false, false, false, false],
|
||||
// &[false, false, false, false, true, true],
|
||||
// );
|
||||
|
||||
// 1c)
|
||||
let mut lfsr = Lfsr::new(
|
||||
// &[true, true, true, false, false, false],
|
||||
// &[true, true, false, false, false, false],
|
||||
&[true, false, true, true, false, true],
|
||||
// &[true, true, true, true, true, true],
|
||||
// &[true, false, false, false, false, false],
|
||||
&[false, false, true, true, true, true],
|
||||
);
|
||||
let mut seen = Vec::new();
|
||||
let mut i = 0;
|
||||
while !seen.contains(&lfsr.state().iter().cloned().collect::<Vec<_>>()) {
|
||||
seen.push(lfsr.state().iter().cloned().collect::<Vec<_>>());
|
||||
print!("{}", convert_state(lfsr.state()));
|
||||
println!(" & {} \\\\", if lfsr.next() { 1 } else { 0 });
|
||||
i += 1;
|
||||
}
|
||||
eprintln!("Repetition after {} iterations", i);
|
||||
}
|
Reference in New Issue
Block a user