Skip to content

Commit 972d2d2

Browse files
committed
wip: writer
1 parent 6ce29c7 commit 972d2d2

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

cipher/src/algorithm/chacha20/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
mod core;
2+
mod writer;
3+
4+
pub use writer::ChaCha20Writer;
5+
26
pub use core::{permute, xor_bytes, Block, CHACHA20_NONCE_SIZE, CONSTANTS, STATE_WORDS};
37
use core::{CHACHA20_BLOCK_SIZE, DEFAULT_BLOCKS_PER_THREAD};
48

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use std::{cmp, io::Write};
2+
3+
use crate::Cipher;
4+
5+
use super::core::CHACHA20_BLOCK_SIZE;
6+
7+
const CHUNK_SIZE: usize = CHACHA20_BLOCK_SIZE * 4096;
8+
9+
/// `ChaCha20Writer` is a wrapper around a `Write` implementation that encrypts data using the
10+
/// a stream cipher.
11+
pub struct ChaCha20Writer<W> {
12+
inner: W,
13+
cipher: Cipher,
14+
buffer: Vec<u8>,
15+
}
16+
17+
impl<W: Write> ChaCha20Writer<W> {
18+
pub fn new(inner: W, cipher: Cipher) -> Self {
19+
Self {
20+
inner,
21+
cipher,
22+
buffer: Vec::new(),
23+
}
24+
}
25+
26+
pub fn flush_buffer(&mut self) -> std::io::Result<()> {
27+
if self.buffer.is_empty() {
28+
return Ok(());
29+
}
30+
31+
let mut bytes = self
32+
.buffer
33+
.drain(..cmp::min(self.buffer.len(), CHUNK_SIZE))
34+
.collect::<Vec<u8>>();
35+
self.cipher.encrypt_in_place(&mut bytes);
36+
37+
self.inner.write_all(&bytes)?;
38+
self.buffer.clear();
39+
Ok(())
40+
}
41+
42+
pub fn finalize(mut self) -> std::io::Result<()> {
43+
self.flush_buffer()?;
44+
self.inner.flush()
45+
}
46+
}
47+
48+
impl<W: Write> Write for ChaCha20Writer<W> {
49+
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
50+
self.buffer.extend_from_slice(buf);
51+
52+
if self.buffer.len() >= CHUNK_SIZE {
53+
self.flush_buffer()?;
54+
}
55+
56+
Ok(buf.len())
57+
}
58+
59+
fn flush(&mut self) -> std::io::Result<()> {
60+
self.flush_buffer()
61+
}
62+
}

0 commit comments

Comments
 (0)