Skip to content

Commit 319a426

Browse files
authored
IGE mode code improvements (#212)
1 parent a66fd23 commit 319a426

File tree

5 files changed

+49
-77
lines changed

5 files changed

+49
-77
lines changed

Cargo.lock

-7
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

block-modes/CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [Unreleased]
9+
### Changed
10+
- Upgrade to `cipher v0.3` ([#202])
11+
12+
### Added
13+
- Infinite Garble Extension (IGE) block mode ([#211])
14+
15+
[#202]: https://github.com/RustCrypto/block-ciphers/pull/202
16+
[#211]: https://github.com/RustCrypto/block-ciphers/pull/211
17+
818
## 0.7.0 (2020-10-16)
919
### Changed
1020
- Replace `block-cipher`/`stream-cipher` with `cipher` crate ([#167])

block-modes/Cargo.toml

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ keywords = ["crypto", "block-cipher", "ciphers"]
1212

1313
[dependencies]
1414
block-padding = "0.2"
15-
byte-tools = "0.3"
1615
cipher = "=0.3.0-pre"
1716

1817
[dev-dependencies]

block-modes/src/ige.rs

+20-39
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@ use crate::{
33
utils::{xor, Block},
44
};
55
use block_padding::Padding;
6-
use byte_tools::copy;
76
use cipher::{
87
block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher},
98
generic_array::{
10-
typenum::{Prod, UInt, UTerm, Unsigned, B0, B1, U2},
9+
typenum::{Prod, Unsigned, U2},
1110
ArrayLength, GenericArray,
1211
},
1312
};
@@ -22,71 +21,53 @@ pub struct Ige<C, P>
2221
where
2322
C: BlockCipher + NewBlockCipher + BlockEncrypt + BlockDecrypt,
2423
P: Padding,
25-
C::BlockSize: Mul<UInt<UInt<UTerm, B1>, B0>>,
26-
<C::BlockSize as Mul<UInt<UInt<UTerm, B1>, B0>>>::Output: ArrayLength<u8>,
24+
C::BlockSize: Mul<U2>,
25+
IgeIvBlockSize<C>: ArrayLength<u8>,
2726
{
2827
cipher: C,
29-
iv: GenericArray<u8, IgeIvBlockSize<C>>,
28+
x: GenericArray<u8, C::BlockSize>,
29+
y: GenericArray<u8, C::BlockSize>,
3030
_p: PhantomData<P>,
3131
}
3232

33-
// Implementation derived from:
34-
// https://mgp25.com/AESIGE/
35-
3633
impl<C, P> BlockMode<C, P> for Ige<C, P>
3734
where
3835
C: BlockCipher + NewBlockCipher + BlockEncrypt + BlockDecrypt,
3936
P: Padding,
40-
C::BlockSize: Mul<UInt<UInt<UTerm, B1>, B0>>,
41-
<C::BlockSize as Mul<UInt<UInt<UTerm, B1>, B0>>>::Output: ArrayLength<u8>,
37+
C::BlockSize: Mul<U2>,
38+
IgeIvBlockSize<C>: ArrayLength<u8>,
4239
{
4340
type IvSize = IgeIvBlockSize<C>;
4441

4542
fn new(cipher: C, iv: &GenericArray<u8, Self::IvSize>) -> Self {
43+
let (y, x) = iv.split_at(C::BlockSize::to_usize());
4644
Ige {
4745
cipher,
48-
iv: iv.clone(),
46+
x: GenericArray::clone_from_slice(x),
47+
y: GenericArray::clone_from_slice(y),
4948
_p: Default::default(),
5049
}
5150
}
5251

5352
fn encrypt_blocks(&mut self, blocks: &mut [Block<C>]) {
54-
let block_size = C::BlockSize::to_usize();
55-
56-
let (mut y_prev, x_prev) = self.iv.split_at_mut(block_size);
57-
let mut x_temp = GenericArray::<u8, C::BlockSize>::default();
58-
5953
for block in blocks {
60-
copy(block, &mut x_temp);
61-
62-
xor(block, y_prev);
63-
54+
let t = block.clone();
55+
xor(block, &self.y);
6456
self.cipher.encrypt_block(block);
65-
66-
xor(block, x_prev);
67-
68-
copy(&x_temp, x_prev);
69-
y_prev = block;
57+
xor(block, &self.x);
58+
self.x = t;
59+
self.y = block.clone();
7060
}
7161
}
7262

7363
fn decrypt_blocks(&mut self, blocks: &mut [Block<C>]) {
74-
let block_size = C::BlockSize::to_usize();
75-
76-
let (x_prev, mut y_prev) = self.iv.split_at_mut(block_size);
77-
let mut x_temp = GenericArray::<u8, C::BlockSize>::default();
78-
7964
for block in blocks {
80-
copy(block, &mut x_temp);
81-
82-
xor(block, y_prev);
83-
65+
let t = block.clone();
66+
xor(block, &self.x);
8467
self.cipher.decrypt_block(block);
85-
86-
xor(block, x_prev);
87-
88-
copy(&x_temp, x_prev);
89-
y_prev = block;
68+
xor(block, &self.y);
69+
self.y = t;
70+
self.x = block.clone();
9071
}
9172
}
9273
}

block-modes/tests/lib.rs

+19-30
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,23 @@
11
//! Test vectors generated with OpenSSL
22
33
use aes::Aes128;
4-
use block_modes::block_padding::{NoPadding, ZeroPadding};
4+
use block_modes::block_padding::NoPadding;
55
use block_modes::BlockMode;
66
use block_modes::{Cbc, Ecb, Ige};
7-
use cipher::generic_array::GenericArray;
87

98
#[test]
109
fn ecb_aes128() {
1110
let key = include_bytes!("data/aes128.key.bin");
1211
let plaintext = include_bytes!("data/aes128.plaintext.bin");
1312
let ciphertext = include_bytes!("data/ecb-aes128.ciphertext.bin");
14-
1513
// ECB mode ignores IV
1614
let iv = Default::default();
17-
let mode = Ecb::<Aes128, ZeroPadding>::new_var(key, iv).unwrap();
18-
let mut pt = plaintext.to_vec();
19-
let n = pt.len();
20-
mode.encrypt(&mut pt, n).unwrap();
21-
assert_eq!(pt, &ciphertext[..]);
22-
23-
let mode = Ecb::<Aes128, ZeroPadding>::new_var(key, iv).unwrap();
24-
let mut ct = ciphertext.to_vec();
25-
mode.decrypt(&mut ct).unwrap();
26-
assert_eq!(ct, &plaintext[..]);
15+
16+
let mode = Ecb::<Aes128, NoPadding>::new_var(key, iv).unwrap();
17+
assert_eq!(mode.encrypt_vec(plaintext), &ciphertext[..]);
18+
19+
let mode = Ecb::<Aes128, NoPadding>::new_var(key, iv).unwrap();
20+
assert_eq!(mode.decrypt_vec(ciphertext).unwrap(), &plaintext[..]);
2721
}
2822

2923
#[test]
@@ -33,16 +27,11 @@ fn cbc_aes128() {
3327
let plaintext = include_bytes!("data/aes128.plaintext.bin");
3428
let ciphertext = include_bytes!("data/cbc-aes128.ciphertext.bin");
3529

36-
let mode = Cbc::<Aes128, ZeroPadding>::new_var(key, iv).unwrap();
37-
let mut pt = plaintext.to_vec();
38-
let n = pt.len();
39-
mode.encrypt(&mut pt, n).unwrap();
40-
assert_eq!(pt, &ciphertext[..]);
30+
let mode = Cbc::<Aes128, NoPadding>::new_var(key, iv).unwrap();
31+
assert_eq!(mode.encrypt_vec(plaintext), &ciphertext[..]);
4132

42-
let mode = Cbc::<Aes128, ZeroPadding>::new_var(key, iv).unwrap();
43-
let mut ct = ciphertext.to_vec();
44-
mode.decrypt(&mut ct).unwrap();
45-
assert_eq!(ct, &plaintext[..]);
33+
let mode = Cbc::<Aes128, NoPadding>::new_var(key, iv).unwrap();
34+
assert_eq!(mode.decrypt_vec(ciphertext).unwrap(), &plaintext[..]);
4635
}
4736

4837
/// Test that parallel code works correctly
@@ -73,28 +62,28 @@ fn par_blocks() {
7362

7463
#[test]
7564
fn ige_aes256_1() {
76-
let key = GenericArray::from_slice(include_bytes!("data/ige-aes128-1.key.bin"));
77-
let iv = GenericArray::from_slice(include_bytes!("data/ige-aes128-1.iv.bin"));
65+
let key = include_bytes!("data/ige-aes128-1.key.bin");
66+
let iv = include_bytes!("data/ige-aes128-1.iv.bin");
7867
let plaintext = include_bytes!("data/ige-aes128-1.plaintext.bin");
7968
let ciphertext = include_bytes!("data/ige-aes128-1.ciphertext.bin");
8069

81-
let mode = Ige::<Aes128, NoPadding>::new_fix(key, iv);
70+
let mode = Ige::<Aes128, NoPadding>::new_var(key, iv).unwrap();
8271
assert_eq!(mode.encrypt_vec(plaintext), &ciphertext[..]);
8372

84-
let mode = Ige::<Aes128, NoPadding>::new_fix(key, iv);
73+
let mode = Ige::<Aes128, NoPadding>::new_var(key, iv).unwrap();
8574
assert_eq!(mode.decrypt_vec(ciphertext).unwrap(), &plaintext[..]);
8675
}
8776

8877
#[test]
8978
fn ige_aes256_2() {
90-
let key = GenericArray::from_slice(include_bytes!("data/ige-aes128-2.key.bin"));
91-
let iv = GenericArray::from_slice(include_bytes!("data/ige-aes128-2.iv.bin"));
79+
let key = include_bytes!("data/ige-aes128-2.key.bin");
80+
let iv = include_bytes!("data/ige-aes128-2.iv.bin");
9281
let plaintext = include_bytes!("data/ige-aes128-2.plaintext.bin");
9382
let ciphertext = include_bytes!("data/ige-aes128-2.ciphertext.bin");
9483

95-
let mode = Ige::<Aes128, NoPadding>::new_fix(key, iv);
84+
let mode = Ige::<Aes128, NoPadding>::new_var(key, iv).unwrap();
9685
assert_eq!(mode.encrypt_vec(plaintext), &ciphertext[..]);
9786

98-
let mode = Ige::<Aes128, NoPadding>::new_fix(key, iv);
87+
let mode = Ige::<Aes128, NoPadding>::new_var(key, iv).unwrap();
9988
assert_eq!(mode.decrypt_vec(ciphertext).unwrap(), &plaintext[..]);
10089
}

0 commit comments

Comments
 (0)