vitaminc_aead/ciphertext/
mod.rs1mod read_monads;
2mod write_monads;
3use bytes::Bytes;
4use read_monads::CipherTextReader;
5use serde::{Deserialize, Serialize};
6pub use write_monads::CipherTextBuilder;
7
8#[derive(Debug, Serialize, Deserialize)]
9#[serde(transparent)]
10pub struct LocalCipherText(Bytes);
11
12impl LocalCipherText {
13 pub fn into_inner(self) -> Bytes {
14 self.0
15 }
16
17 pub fn into_reader(self) -> CipherTextReader {
18 CipherTextReader::new(self.0)
19 }
20}
21
22impl AsRef<[u8]> for LocalCipherText {
23 fn as_ref(&self) -> &[u8] {
24 self.0.as_ref()
25 }
26}
27
28impl From<Vec<u8>> for LocalCipherText {
29 fn from(bytes: Vec<u8>) -> Self {
30 LocalCipherText(Bytes::from(bytes))
31 }
32}
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37 use crate::Nonce;
38 use vitaminc_protected::{Controlled, Protected};
39
40 #[test]
41 fn test_ciphertext_builder_with_plaintext_in_place() -> Result<(), ()> {
42 let nonce = Nonce::new([1u8; 12]);
43 let plaintext = vec![0u8; 10];
44 let ciphertext = CipherTextBuilder::new()
45 .append_nonce(nonce)
46 .append_target_plaintext(plaintext)
47 .accepts_ciphertext_and_tag_ok(|mut ciphertext| {
48 ciphertext.copy_from_slice(&[2u8; 10]);
49 ciphertext.extend([3u8; 16]);
50 Ok(ciphertext)
51 })
52 .build()?;
53
54 assert_eq!(ciphertext.0.len(), 38);
55 assert_eq!(&ciphertext.0[..12], &[1u8; 12]);
56 assert_eq!(&ciphertext.0[12..22], &[2u8; 10]);
57 assert_eq!(&ciphertext.0[22..], &[3u8; 16]);
58
59 Ok(())
60 }
61
62 #[test]
63 fn test_ciphertext_reader() -> Result<(), ()> {
64 let nonce = Nonce::new([1u8; 12]);
65 let plaintext: Protected<Vec<u8>> = Protected::new(vec![0u8; 10]);
66
67 let ciphertext = CipherTextBuilder::new()
68 .append_nonce(nonce)
69 .append_target_plaintext(plaintext)
70 .accepts_ciphertext_and_tag_ok(|mut ciphertext| {
71 ciphertext.copy_from_slice(&[2u8; 10]);
72 ciphertext.extend([3u8; 16]);
73 Ok(ciphertext)
74 })
75 .build()?;
76
77 let (nonce, reader) = ciphertext.into_reader().read_nonce::<12>();
78
79 let plaintext = reader
80 .accepts_plaintext_ok(|data| {
81 assert_eq!(data.len(), 26);
82 assert_eq!(&data[..10], [2u8; 10]);
83 assert_eq!(&data[10..], [3u8; 16]);
84 data[..10].copy_from_slice(&[0u8; 10]);
86 Ok(10)
87 })
88 .read()?;
89
90 assert_eq!(nonce.into_inner(), [1u8; 12]);
91 assert_eq!(plaintext.risky_unwrap()[..10], vec![0u8; 10]);
92
93 Ok(())
94 }
95}