Skip to main content

FixedCtrBlockCipher

Struct FixedCtrBlockCipher 

Source
pub struct FixedCtrBlockCipher<C, const N: usize> { /* private fields */ }
Expand description

Allocation-free Counter (CTR) mode over an N-byte block cipher, called SIC (Segmented Integer Counter) in Bouncy Castle.

The engine encrypts successive counter blocks to produce a keystream, and each block is XORed with it. Encryption and decryption are the same operation, so the requested direction is ignored and the engine is always initialized for encryption.

The IV is required. It fills the leading bytes of the counter block and the rest start at zero; it may leave at most min(8, N / 2) bytes of counter, so AES needs 8 to 16 bytes. The counter spans the whole block and carries into the IV bytes, so keep each message below 2^(8 * (N - iv_len)) blocks. A counter block must never repeat under one key: never reuse an IV, and keep messages under one key from overlapping.

Initialization rejects an engine whose block size is not N. The state is stored inline and wiped on drop.

Constant time exactly when the engine is: the mode adds only XORs, copies and a branch-free counter increment.

§Example

A 12-byte nonce and a message that ends in a partial block:

use tc_aes::AesEngine;
use tc_block_cipher::{BlockCipher, BlockCipherInit, CipherDirection};
use tc_block_modes::{BlockCipherMode, FixedCtrBlockCipher, KeyWithIvRef};

fn apply(
    mode: &mut FixedCtrBlockCipher<AesEngine, 16>,
    data: &mut [u8],
) -> Result<(), Box<dyn core::error::Error>> {
    for chunk in data.chunks_mut(16) {
        let mut block = [0; 16];
        block[..chunk.len()].copy_from_slice(chunk);
        let mut keyed = [0; 16];
        mode.process_block(&block, &mut keyed)?;
        chunk.copy_from_slice(&keyed[..chunk.len()]);
    }
    Ok(())
}

let (key, nonce) = ([0x42; 16], [0x24; 12]);
let mut mode = FixedCtrBlockCipher::<_, 16>::new(AesEngine::new());
mode.init(CipherDirection::Encrypt, &KeyWithIvRef::new(&key, &nonce))?;

let mut data = *b"twenty byte message!";
apply(&mut mode, &mut data)?;
assert_ne!(&data, b"twenty byte message!");

mode.reset();
apply(&mut mode, &mut data)?;
assert_eq!(&data, b"twenty byte message!");
assert_eq!(mode.to_string(), "AES/CTR");

Implementations§

Source§

impl<C, const N: usize> FixedCtrBlockCipher<C, N>

Source

pub const fn new(cipher: C) -> Self

Wraps cipher without allocating. Constant time: nothing is inspected.

Trait Implementations§

Source§

impl<C: BlockCipher, const N: usize> BlockCipher for FixedCtrBlockCipher<C, N>

Source§

fn block_size(&self) -> usize

Returns N. Constant time.

Source§

fn process_block( &mut self, input: &[u8], output: &mut [u8], ) -> Result<usize, Self::Error>

XORs the first N bytes with the next keystream block, advances the counter and returns N.

Returns NotInitialised before a successful init and BufferTooShort when either buffer is shorter than N, leaving the counter unchanged. Constant time exactly when the engine’s process_block is.

Source§

type Error = BlockModeError<<C as BlockCipher>::Error>

The engine’s processing error, such as crate::BlockError.
Source§

impl<C, P, const N: usize> BlockCipherInit<P> for FixedCtrBlockCipher<C, N>

Source§

fn init( &mut self, _direction: CipherDirection, params: &P, ) -> Result<(), <Self as BlockCipherInit<P>>::Error>

Checks the block size and IV, initializes the engine for encryption, then installs the IV and restarts the counter. The direction is ignored.

Returns UnsupportedBlockSize for an engine whose block is not N, InvalidIvLength for an IV longer than N or leaving more than min(8, N / 2) bytes of counter, or the engine’s error; each leaves the previous IV and counter in place. Constant time exactly when the engine’s init is: the mode only checks public lengths and copies the IV.

Source§

type Error = BlockModeInitError<<C as BlockCipherInit<P>>::Error>

The engine’s initialization error, such as crate::InitError.
Source§

impl<C: BlockCipher, const N: usize> BlockCipherMode for FixedCtrBlockCipher<C, N>

Source§

fn underlying_cipher(&self) -> &Self::Cipher

Returns the wrapped engine. Constant time.

Source§

fn is_partial_block_okay(&self) -> bool

Returns true: a final partial block can be processed through a block-sized buffer. Constant time.

Source§

fn reset(&mut self)

Restarts the counter from the IV installed by the last init. Constant time.

Source§

type Cipher = C

The block cipher wrapped by this mode.
Source§

impl<C: Display, const N: usize> Display for FixedCtrBlockCipher<C, N>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Writes the engine’s name followed by /CTR. Constant time with respect to the key when the engine’s Display is; output timing depends on the formatter.

Source§

impl<C, const N: usize> Drop for FixedCtrBlockCipher<C, N>

Source§

fn drop(&mut self)

Wipes the IV and the chaining or keystream state; the engine wipes its own key schedule. Constant time.

Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<C, const N: usize> Freeze for FixedCtrBlockCipher<C, N>
where C: Freeze, [u8; N]: Freeze,

§

impl<C, const N: usize> RefUnwindSafe for FixedCtrBlockCipher<C, N>

§

impl<C, const N: usize> Send for FixedCtrBlockCipher<C, N>
where C: Send, [u8; N]: Send,

§

impl<C, const N: usize> Sync for FixedCtrBlockCipher<C, N>
where C: Sync, [u8; N]: Sync,

§

impl<C, const N: usize> Unpin for FixedCtrBlockCipher<C, N>
where C: Unpin, [u8; N]: Unpin,

§

impl<C, const N: usize> UnsafeUnpin for FixedCtrBlockCipher<C, N>
where C: UnsafeUnpin, [u8; N]: UnsafeUnpin,

§

impl<C, const N: usize> UnwindSafe for FixedCtrBlockCipher<C, N>
where C: UnwindSafe, [u8; N]: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.