Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions belt-ctr/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.2.1 (2026-05-20)
### Added
- Implementation of the `SetIvState` trait ([#114])

[#114]: https://github.com/RustCrypto/block-modes/pull/114

## 0.2.0 (2026-04-10)
## Added
- `GenericBeltCtr` and `GenericBeltCtrCore` types ([#112])
Expand Down
12 changes: 6 additions & 6 deletions belt-ctr/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
[package]
name = "belt-ctr"
version = "0.2.0"
description = "CTR block mode of operation specified by the BelT standard"
version = "0.2.1"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
edition = "2024"
rust-version = "1.85"
readme = "README.md"
documentation = "https://docs.rs/belt-ctr"
readme = "README.md"
repository = "https://github.com/RustCrypto/block-modes"
license = "MIT OR Apache-2.0"
keywords = ["crypto", "block-mode", "stream-cipher", "ciphers", "belt"]
categories = ["cryptography", "no-std"]
description = "CTR block mode of operation specified by the BelT standard"

[dependencies]
cipher = { version = "0.5", features = ["stream-wrapper"] }
cipher = { version = "0.5.2", features = ["stream-wrapper"] }
belt-block = "0.2"

[dev-dependencies]
cipher = { version = "0.5.2", features = ["dev"] }
hex-literal = "1"
cipher = { version = "0.5", features = ["dev"] }

[features]
alloc = ["cipher/alloc"]
Expand Down
21 changes: 20 additions & 1 deletion belt-ctr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use belt_block::BeltBlock;
use cipher::{
AlgorithmName, Block, BlockCipherDecrypt, BlockCipherEncBackend, BlockCipherEncClosure,
BlockCipherEncrypt, BlockSizeUser, InOut, InnerIvInit, Iv, IvSizeUser, IvState, ParBlocks,
ParBlocksSizeUser, StreamCipherBackend, StreamCipherClosure, StreamCipherCore,
ParBlocksSizeUser, SetIvState, StreamCipherBackend, StreamCipherClosure, StreamCipherCore,
StreamCipherCoreWrapper, StreamCipherSeekCore, array::Array, common::InnerUser, consts::U16,
};
use core::fmt;
Expand Down Expand Up @@ -41,11 +41,13 @@ impl<C> StreamCipherCore for GenericBeltCtrCore<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16>,
{
#[inline]
fn remaining_blocks(&self) -> Option<usize> {
let used = self.s.wrapping_sub(self.s_init);
(u128::MAX - used).try_into().ok()
}

#[inline]
fn process_with_backend(&mut self, f: impl StreamCipherClosure<BlockSize = Self::BlockSize>) {
struct Closure<'a, C: StreamCipherClosure<BlockSize = U16>> {
s: &'a mut u128,
Expand Down Expand Up @@ -75,10 +77,12 @@ where
{
type Counter = u128;

#[inline]
fn get_block_pos(&self) -> Self::Counter {
self.s.wrapping_sub(self.s_init)
}

#[inline]
fn set_block_pos(&mut self, pos: Self::Counter) {
self.s = self.s_init.wrapping_add(pos);
}
Expand Down Expand Up @@ -126,17 +130,31 @@ impl<C> IvState for GenericBeltCtrCore<C>
where
C: BlockCipherEncrypt + BlockCipherDecrypt + BlockSizeUser<BlockSize = U16>,
{
#[inline]
fn iv_state(&self) -> Iv<Self> {
let mut t = self.s.to_le_bytes().into();
self.cipher.decrypt_block(&mut t);
t
}
}

impl<C> SetIvState for GenericBeltCtrCore<C>
where
C: BlockCipherEncrypt + BlockCipherDecrypt + BlockSizeUser<BlockSize = U16>,
{
#[inline]
fn set_iv(&mut self, iv: &Iv<Self>) {
let mut iv = *iv;
self.cipher.encrypt_block(&mut iv);
self.s = u128::from_le_bytes(iv.0);
}
}

impl<C> AlgorithmName for GenericBeltCtrCore<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16> + AlgorithmName,
{
#[inline]
fn write_alg_name(f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("BeltCtr<")?;
<C as AlgorithmName>::write_alg_name(f)?;
Expand All @@ -160,6 +178,7 @@ impl<C: BlockCipherEncrypt> Drop for GenericBeltCtrCore<C>
where
C: BlockCipherEncrypt + BlockSizeUser<BlockSize = U16>,
{
#[inline]
fn drop(&mut self) {
#[cfg(feature = "zeroize")]
{
Expand Down
33 changes: 33 additions & 0 deletions belt-ctr/tests/iv_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
//! Basic tests for `IvState` and `SetIvState` trait impls
use belt_ctr::BeltCtrCore;
use cipher::{IvState, KeyIvInit, SetIvState, StreamCipherCore};

cipher::iv_state_test!(belt_ctr_iv_state, BeltCtrCore, apply_ks);

#[test]
fn belt_ctr_set_iv() {
let key = Default::default();
let iv = Default::default();
let mut mode = BeltCtrCore::new(&key, &iv);

let mut blocks = [Default::default(); 16];

mode.apply_keystream_blocks(&mut blocks);
let iv = mode.iv_state();

let mut buf1 = blocks;
let mut buf2 = blocks;

mode.peek(|m| m.apply_keystream_blocks(&mut buf1));
assert_eq!(mode.iv_state(), iv);

mode.apply_keystream_blocks(&mut blocks);
let iv2 = mode.iv_state();

mode.set_iv(&iv);
mode.apply_keystream_blocks(&mut buf2);

assert_eq!(blocks, buf1);
assert_eq!(blocks, buf2);
assert_eq!(mode.iv_state(), iv2);
}
3 changes: 1 addition & 2 deletions belt-ctr/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Test vectors from the BelT standard (tables A.15 and A.16):
//! https://apmi.bsu.by/assets/files/std/belt-spec371.pdf
use belt_ctr::{BeltCtr, BeltCtrCore};
use belt_ctr::BeltCtr;

cipher::stream_cipher_test!(belt_ctr_core, "belt-ctr", BeltCtr);
cipher::stream_cipher_seek_test!(belt_ctr_seek, BeltCtr);
cipher::iv_state_test!(belt_ctr_iv_state, BeltCtrCore, apply_ks);
6 changes: 6 additions & 0 deletions cbc/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.2.1 (2026-05-20)
### Added
- Implementation of the `SetIvState` trait ([#114])

[#114]: https://github.com/RustCrypto/block-modes/pull/114

## 0.2.0 (2026-04-10)
### Removed
- `std` feature ([#76])
Expand Down
14 changes: 7 additions & 7 deletions cbc/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
[package]
name = "cbc"
version = "0.2.0"
description = "Cipher Block Chaining (CBC) block cipher mode of operation"
version = "0.2.1"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
edition = "2024"
rust-version = "1.85"
readme = "README.md"
documentation = "https://docs.rs/cbc"
readme = "README.md"
repository = "https://github.com/RustCrypto/block-modes"
license = "MIT OR Apache-2.0"
keywords = ["crypto", "block-mode", "ciphers"]
categories = ["cryptography", "no-std"]
description = "Cipher Block Chaining (CBC) block cipher mode of operation"

[dependencies]
cipher = "0.5"
cipher = "0.5.2"

[dev-dependencies]
aes = "0.9"
cipher = { version = "0.5", features = ["dev"] }
cipher = { version = "0.5.2", features = ["dev"] }
hex-literal = "1"
aes = "0.9"

[features]
default = ["block-padding"]
Expand Down
12 changes: 11 additions & 1 deletion cbc/src/decrypt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::xor;
use cipher::{
AlgorithmName, Block, BlockCipherDecBackend, BlockCipherDecClosure, BlockCipherDecrypt,
BlockModeDecBackend, BlockModeDecClosure, BlockModeDecrypt, BlockSizeUser, InnerIvInit, Iv,
IvState, ParBlocks, ParBlocksSizeUser,
IvState, ParBlocks, ParBlocksSizeUser, SetIvState,
array::{Array, ArraySize},
common::{InnerUser, IvSizeUser},
inout::InOut,
Expand Down Expand Up @@ -107,6 +107,16 @@ where
}
}

impl<C> SetIvState for Decryptor<C>
where
C: BlockCipherDecrypt,
{
#[inline]
fn set_iv(&mut self, iv: &Iv<Self>) {
self.iv = iv.clone();
}
}

impl<C> AlgorithmName for Decryptor<C>
where
C: BlockCipherDecrypt + AlgorithmName,
Expand Down
Loading
Loading