Skip to content

Instantly share code, notes, and snippets.

@zargony
Created January 29, 2019 22:25
Show Gist options
  • Save zargony/717f3812e95e8bfbf1b2ab0ca3f72390 to your computer and use it in GitHub Desktop.
Save zargony/717f3812e95e8bfbf1b2ab0ca3f72390 to your computer and use it in GitHub Desktop.
Der Dialog der Schwestern
// Der Dialog der Schwestern
// Quick 'n dirty solution in Rust
// see https://www.heise.de/ct/artikel/Der-Dialog-der-Schwestern-4274601.html
#[derive(Debug)]
struct Encryption {
n: u32, // encryption modulus
e: u32, // encryption exponent
n2: u32, // decryption modulus
e2: u32, // decryption exponent
}
impl Encryption {
fn new(p: u32, q: u32, e: u32) -> Self {
let n = p * q;
let n2 = (p-1) * (q-1);
let e2 = (n2 + 1) / e;
Self { n, e, n2, e2 }
}
fn decrypt(&self, ciphertext: &[u32]) -> Vec<u32> {
ciphertext.iter().map(|ch| {
(((ch % self.n) as u64).pow(self.e2) % self.n as u64) as u32
}).collect()
}
}
fn print(text: &[u32]) {
const ALPHABET: [char; 26] = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
for ch in text {
if *ch >= 1 && *ch <= ALPHABET.len() as u32 {
print!("{}", ALPHABET[*ch as usize - 1]);
} else {
print!("?");
}
}
println!();
}
fn main() {
let key = Encryption::new(3, 227, 151);
println!("key: {:?}", key);
let ciphertext = [172, 1734, 315, 641, 372, 3491, 360, 387, 586, 602, 2358];
println!("ciphertext: {:?}", ciphertext);
let plaintext = key.decrypt(&ciphertext);
println!("plaintext: {:?}", plaintext);
print(&plaintext);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn smoke() {
let key = Encryption::new(3, 17, 3);
assert_eq!(key.n, 51);
assert_eq!(key.e, 3);
assert_eq!(key.n2, 32);
assert_eq!(key.e2, 11);
assert_eq!(
key.decrypt(&[1647, 741, 665, 1487, 780, 2897, 620, 525, 2500, 2336, 486, 1174]),
[9, 3, 8, 2, 9, 14, 2, 9, 1, 14, 3, 1] // ICHBINBIANCA
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment