<commit_before>//! Module for the ChaCha20 stream cipher.
use byteorder::{ByteOrder, LittleEndian};

/// A ChaCha20 iterator that can be used as a stream cipher or pseudorandom generator.
///
/// Initialized with a 32-byte key and 12-byte nonce. If reusing a key for encryption, be sure to
/// generate a unique nonce so that a given (key, nonce) pair is never used twice.
///
/// # Overflow Behavior
///
/// Iterating past 256 GB of the bytestream will cause the block counter to overflow.
pub struct Stream {
    chacha20: ChaCha20,
    counter: u32,
    block: [u8; 64],
    block_index: u8,
}

impl Stream {
    /// Initializes a ChaCha20 stream given a key and nonce.
    ///
    /// # Panics
    ///
    /// Panics if `key.len()` is not equal to 32 or if `nonce.len()` is not equal to 12.
    pub fn new(key: &[u8], nonce: &[u8]) -> Self {
        let chacha20 = ChaCha20::new(key, nonce);
        let block = chacha20.block(0);
        Self {
            chacha20: chacha20,
            counter: 0,
            block: block,
            block_index: 0,
        }
    }

    /// Encrypts a message into a ciphertext.
    ///
    /// # Panics
    ///
    /// Panics if `message.len()` is not equal to `ciphertext.len()`.
    pub fn encrypt(&mut self, message: &[u8], ciphertext: &mut [u8]) {
        self.xor(message, ciphertext)
    }

    /// Decrypts a ciphertext into a message.
    ///
    /// # Panics
    ///
    /// Panics if `message.len()` is not equal to `ciphertext.len()`.
    pub fn decrypt(&mut self, ciphertext: &[u8], message: &mut [u8]) {
        self.xor(ciphertext, message)
    }

    fn xor(&mut self, input: &[u8], output: &mut [u8]) {
        assert_eq!(input.len(), output.len());
        for (x, (y, z)) in output.iter_mut().zip(self.take(input.len()).zip(input)) {
            *x = y ^ z;
        }
    }
}

impl Iterator for Stream {
    type Item = u8;

    fn next(&mut self) -> Option<Self::Item> {
        if self.block_index == 64 {
            self.counter += 1; // could overflow
            self.block = self.chacha20.block(self.counter);
            self.block_index = 0;
        }
        let byte = self.block[self.block_index as usize];
        self.block_index += 1;
        Some(byte)
    }<commit_msg>chacha20: change signatures<commit_after>//! Module for the ChaCha20 stream cipher.
use byteorder::{ByteOrder, LittleEndian};

/// A ChaCha20 iterator that can be used as a stream cipher or pseudorandom generator.
///
/// Initialized with a 32-byte key and 12-byte nonce. If reusing a key for encryption, be sure to
/// generate a unique nonce so that a given (key, nonce) pair is never used twice.
///
/// # Overflow Behavior
///
/// Iterating past 256 GB of the bytestream will cause the block counter to overflow.
pub struct Stream {
    chacha20: ChaCha20,
    counter: u32,
    block: [u8; 64],
    block_index: u8,
}

impl Stream {
    /// Initializes a ChaCha20 stream given a key and nonce.
    ///
    /// # Panics
    ///
    /// Panics if `key.len()` is not equal to 32 or if `nonce.len()` is not equal to 12.
    pub fn new(key: &[u8], nonce: &[u8]) -> Self {
        let chacha20 = ChaCha20::new(key, nonce);
        let block = chacha20.block(0);
        Self {
            chacha20: chacha20,
            counter: 0,
            block: block,
            block_index: 0,
        }
    }

    /// Encrypts a message into a ciphertext.
    ///
    /// # Panics
    ///
    /// Panics if `input.len()` is not equal to `output.len()`.
    pub fn encrypt(&mut self, input: &[u8], output: &mut [u8]) {
        self.process(input, output)
    }

    /// Decrypts a ciphertext into a message.
    ///
    /// # Panics
    ///
    /// Panics if `input.len()` is not equal to `output.len()`.
    pub fn decrypt(&mut self, input: &[u8], output: &mut [u8]) {
        self.process(input, output)
    }

    fn process(&mut self, input: &[u8], output: &mut [u8]) {
        assert_eq!(input.len(), output.len());
        for (x, (y, z)) in output.iter_mut().zip(self.take(input.len()).zip(input)) {
            *x = y ^ z;
        }
    }
}

impl Iterator for Stream {
    type Item = u8;

    fn next(&mut self) -> Option<Self::Item> {
        if self.block_index == 64 {
            self.counter += 1; // could overflow
            self.block = self.chacha20.block(self.counter);
            self.block_index = 0;
        }
        let byte = self.block[self.block_index as usize];
        self.block_index += 1;
        Some(byte)
    }
{'fraction_non_alphanumeric': 0.14416221033868093, 'fraction_numerical': 0.02540106951871658, 'mean_word_length': 2.002675585284281, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2306232', 'n_tokens_mistral': 1568, 'n_tokens_neox': 1445, 'n_words': 474}