literate_crypto/cipher/
onetimepad.rs1use {
2 crate::{BlockMode, Cipher, CipherDecrypt, CipherEncrypt},
3 docext::docext,
4 std::{fmt, marker::PhantomData},
5};
6
7#[docext]
23#[derive(Debug)]
24pub struct OneTimePad<K>(PhantomData<K>);
25
26impl<K> Default for OneTimePad<K> {
27 fn default() -> Self {
28 Self(Default::default())
29 }
30}
31
32impl<K: Iterator<Item = u8>> Cipher for OneTimePad<K> {
33 type Key = K;
34}
35
36impl<K: Iterator<Item = u8>> BlockMode for OneTimePad<K> {}
37
38impl<K: Iterator<Item = u8>> CipherEncrypt for OneTimePad<K> {
39 type EncryptionErr = KeyTooShort;
40 type EncryptionKey = K;
41
42 fn encrypt(
43 &self,
44 data: Vec<u8>,
45 key: Self::EncryptionKey,
46 ) -> Result<Vec<u8>, Self::EncryptionErr> {
47 cipher(data, key)
48 }
49}
50
51impl<K: Iterator<Item = u8>> CipherDecrypt for OneTimePad<K> {
52 type DecryptionErr = KeyTooShort;
53 type DecryptionKey = K;
54
55 fn decrypt(
56 &self,
57 data: Vec<u8>,
58 key: Self::DecryptionKey,
59 ) -> Result<Vec<u8>, Self::DecryptionErr> {
60 cipher(data, key)
63 }
64}
65
66fn cipher(mut data: Vec<u8>, mut key: impl Iterator<Item = u8>) -> Result<Vec<u8>, KeyTooShort> {
67 for x in data.iter_mut() {
68 *x ^= key.next().ok_or(KeyTooShort)?;
69 }
70 Ok(data)
71}
72
73#[derive(Debug)]
74pub struct KeyTooShort;
75
76impl fmt::Display for KeyTooShort {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 f.write_str("key is too short for one-time pad input")
79 }
80}