Add crypto exercise
All checks were successful
the build was successful

This commit is contained in:
Valentin Brandl
2018-12-06 00:05:43 +01:00
parent 55f4546a9f
commit fe21c8548d
7 changed files with 411 additions and 0 deletions

View File

@ -0,0 +1,2 @@
/target
**/*.rs.bk

View File

@ -0,0 +1,4 @@
[[package]]
name = "des"
version = "0.1.0"

View File

@ -0,0 +1,6 @@
[package]
name = "des"
version = "0.1.0"
authors = ["Valentin Brandl <vbrandl@riseup.net>"]
[dependencies]

View File

@ -0,0 +1,235 @@
use std::collections::HashSet;
const P_1: [usize; 32] = [
9, 17, 23, 31, 13, 28, 2, 18, 24, 16, 30, 6, 26, 20, 10, 1, 8, 14, 25, 3, 4, 29, 11, 19, 32,
12, 22, 7, 5, 27, 15, 21,
];
const P: [usize; 32] = [
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19,
13, 30, 6, 22, 11, 4, 25,
];
const E: [usize; 48] = [
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17, 16, 17, 18,
19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1,
];
fn permutate<T: Copy + Default>(i: &[T], b: &[usize]) -> Vec<T> {
let mut res: Vec<_> = (0..b.len()).map(|_| T::default()).collect();
for (i, p) in i.iter().zip(b.iter()) {
res[*p - 1] = *i;
}
res
}
trait Split {
fn split(&self) -> (u32, u32);
}
impl Split for u64 {
fn split(&self) -> (u32, u32) {
((*self >> 32) as u32, *self as u32)
}
}
fn xor(a: &[bool], b: &[bool]) -> Vec<bool> {
assert!(a.len() == b.len());
a.iter().zip(b.iter()).map(|(a, b)| a ^ b).collect()
}
fn to_bin<T: std::fmt::Binary>(i: T) -> Vec<bool> {
format!("{:b}", i)
.chars()
.map(|c| if c == '1' { true } else { false })
.collect()
}
fn show(b: &[bool], split: u8) {
let mut i = 1;
b.iter().map(|c| if *c { '1' } else { '0' }).for_each(|c| {
print!("{}", c);
if i % split == 0 {
print!(" ");
}
i += 1;
});
println!();
}
fn reverse_des(i: u64, o: u64) {
let (l0, r0) = i.split();
let (l1, r1) = o.split();
let e_out = permutate(&to_bin(r0), &E);
println!("e_out: ");
show(&e_out, 100);
let f_out = r1 ^ l0;
let s_out = permutate(&to_bin(f_out), &P_1);
assert!(&to_bin(f_out) == &permutate(&s_out, &P));
println!("s_out: ");
show(&s_out, 4);
println!();
}
fn do_it(s: &[[[bool; 6]; 4]], x: &[bool]) -> HashSet<Vec<bool>> {
let mut set1 = HashSet::new();
for a in s[0].iter() {
for b in s[1].iter() {
for c in s[2].iter() {
for d in s[3].iter() {
for e in s[4].iter() {
for f in s[5].iter() {
for g in s[6].iter() {
for h in s[7].iter() {
let mut v = Vec::with_capacity(48);
v.extend(a);
v.extend(b);
v.extend(c);
v.extend(d);
v.extend(e);
v.extend(f);
v.extend(g);
v.extend(h);
let r = xor(&v, x);
set1.insert(r);
}
}
}
}
}
}
}
}
set1
}
fn main() {
let x1: u64 = 0xF57DDDB12EAA799D;
let y1: u64 = 0x2EAA799D332924D8;
let x2: u64 = 0x15837977D5202437;
let y2: u64 = 0xD5202437B5D8FC31;
let s_in_1 = [
[
[false, true, true, true, true, false],
[false, false, false, true, false, true],
[true, true, false, true, true, false],
[true, false, true, true, true, true],
],
[
[false, true, true, false, true, false],
[false, false, false, false, true, true],
[true, false, true, true, false, false],
[true, false, false, false, false, true],
],
[
[false, false, false, true, false, false],
[false, false, false, true, true, true],
[true, false, false, true, true, false],
[true, false, true, false, true, true],
],
[
[false, true, false, true, true, false],
[false, false, false, true, true, true],
[true, true, true, false, false, false],
[true, true, false, true, false, true],
],
[
[false, false, true, true, false, false],
[false, false, false, false, true, true],
[true, false, false, true, true, false],
[true, false, false, false, false, true],
],
[
[false, false, false, false, false, false],
[false, false, true, false, true, true],
[true, false, true, true, false, false],
[true, false, false, true, true, true],
],
[
[false, true, false, true, false, false],
[false, false, true, false, true, true],
[true, true, true, true, false, false],
[true, true, false, false, false, true],
],
[
[false, true, true, false, true, false],
[false, true, true, false, false, true],
[true, true, false, false, false, false],
[true, true, false, true, true, true],
],
];
let e_out_1 = [
false, true, true, true, false, true, false, true, false, false, true, true, false, false,
true, false, true, true, true, false, true, false, false, false, false, false, false,
false, false, false, false, true, false, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false,
];
let s_in_2 = [
[
[false, false, true, true, true, false],
[false, true, true, true, true, true],
[true, false, false, true, true, false],
[true, false, false, true, false, true],
],
[
[false, true, true, true, false, false],
[false, true, true, true, true, true],
[true, true, false, false, false, false],
[true, true, true, false, true, true],
],
[
[false, true, false, false, true, false],
[false, false, false, false, false, true],
[true, false, false, false, false, false],
[true, false, false, true, false, true],
],
[
[false, false, false, true, true, false],
[false, false, true, true, true, true],
[true, true, false, true, false, false],
[true, false, false, false, false, true],
],
[
[false, false, false, false, false, false],
[false, false, false, true, false, true],
[true, false, false, false, true, false],
[true, false, true, true, false, true],
],
[
[false, false, true, false, true, false],
[false, false, false, true, true, true],
[true, false, true, false, false, false],
[true, false, false, true, false, true],
],
[
[false, true, true, true, false, false],
[false, true, true, true, true, true],
[true, true, false, true, false, false],
[true, false, false, false, false, true],
],
[
[false, true, false, false, false, false],
[false, false, false, true, true, true],
[true, true, true, true, true, false],
[true, false, true, true, false, true],
],
];
let e_out_2 = [
true, false, true, false, true, false, false, false, false, false, false, true, false,
false, true, false, false, true, true, true, true, false, false, false, false, false,
false, false, false, false, false, true, false, false, false, false, false, false, false,
false, false, false, false, false, false, false, false, false,
];
let set1 = do_it(&s_in_1, &e_out_1);
let set2 = do_it(&s_in_2, &e_out_2);
let intersection: HashSet<_> = set1.intersection(&set2).collect();
println!("{}", intersection.len());
// reverse_des(x1, y1);
// reverse_des(x2, y2);
}