Add intro-crypto exercise 04
Some checks failed
the build failed

This commit is contained in:
Valentin Brandl
2018-11-15 11:54:38 +01:00
parent e432146791
commit ca6e6e1015
68 changed files with 679 additions and 0 deletions

View 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);
}