Skip to main content

origin_crypto_sdk/aead/
streaming.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! Streaming encryption for large files
4
5use super::XChaCha20Poly1305;
6use crate::error::{CryptoError, Result};
7use std::io::{Read, Write};
8
9/// Streaming encryption for large files
10/// Encrypts data in chunks to support files larger than available memory
11pub fn encrypt_stream<R: Read, W: Write>(
12    mut reader: R,
13    mut writer: W,
14    key: &[u8; 32],
15    nonce: &[u8; 24],
16    chunk_size: usize,
17) -> Result<u64> {
18    let mut buffer = vec![0u8; chunk_size];
19    let mut total_bytes = 0u64;
20
21    loop {
22        let bytes_read = reader.read(&mut buffer).map_err(CryptoError::Io)?;
23        if bytes_read == 0 {
24            break;
25        }
26
27        let chunk = &buffer[..bytes_read];
28        let encrypted = XChaCha20Poly1305::encrypt(key, nonce, chunk)?;
29
30        writer.write_all(&encrypted).map_err(CryptoError::Io)?;
31        total_bytes += bytes_read as u64;
32    }
33
34    Ok(total_bytes)
35}
36
37/// Streaming decryption for large files
38/// Decrypts data in chunks to support files larger than available memory
39pub fn decrypt_stream<R: Read, W: Write>(
40    mut reader: R,
41    mut writer: W,
42    key: &[u8; 32],
43    nonce: &[u8; 24],
44    chunk_size: usize,
45) -> Result<u64> {
46    let mut buffer = vec![0u8; chunk_size + 16]; // +16 for AEAD tag
47    let mut total_bytes = 0u64;
48
49    loop {
50        let bytes_read = reader.read(&mut buffer).map_err(CryptoError::Io)?;
51        if bytes_read == 0 {
52            break;
53        }
54
55        let chunk = &buffer[..bytes_read];
56        let decrypted = XChaCha20Poly1305::decrypt(key, nonce, chunk)?;
57
58        writer.write_all(&decrypted).map_err(CryptoError::Io)?;
59        total_bytes += decrypted.len() as u64;
60    }
61
62    Ok(total_bytes)
63}