Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
aes-soft: use fixslicing for AES-128/AES-256 encryption
Fixslicing is defined for these operations only, but we can replace bitslicing in these capacities with the faster fixslicing approach. This is useful for AES-CTR, which needs only the encryption operation. AES-192, as well as AES-128/AES-256 decryption, still leverage the previous bitsliced implementation.
- Loading branch information
Showing
9 changed files
with
553 additions
and
563 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
//! AES-128 | ||
|
||
use cipher::{ | ||
consts::{U11, U16, U8}, | ||
BlockCipher, NewBlockCipher, | ||
}; | ||
|
||
use crate::{ | ||
bitslice::{ | ||
bit_slice_1x128_with_u32x4, bit_slice_1x16_with_u16, bit_slice_4x4_with_u16, | ||
bit_slice_fill_4x4_with_u32x4, decrypt_core, un_bit_slice_1x128_with_u32x4, | ||
un_bit_slice_1x16_with_u16, Bs8State, | ||
}, | ||
consts::U32X4_0, | ||
expand::expand_key, | ||
fixslice::{self, FixsliceKeys128}, | ||
simd::u32x4, | ||
Block, ParBlocks, | ||
}; | ||
|
||
/// AES-128 key | ||
pub type Key = cipher::block::Key<Aes128>; | ||
|
||
/// AES-128 block cipher instance | ||
#[derive(Clone)] | ||
pub struct Aes128 { | ||
enc_keys: FixsliceKeys128, | ||
dec_keys: [Bs8State<u16>; 11], | ||
dec_keys8: [Bs8State<u32x4>; 11], | ||
} | ||
|
||
impl NewBlockCipher for Aes128 { | ||
type KeySize = U16; | ||
|
||
#[inline] | ||
fn new(key: &Key) -> Self { | ||
let dk = expand_key::<U16, U11>(key).1; | ||
|
||
let k8 = Bs8State( | ||
U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, | ||
); | ||
|
||
let mut c = Self { | ||
enc_keys: fixslice::aes128_key_schedule(key), | ||
dec_keys: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0); 11], | ||
dec_keys8: [k8; 11], | ||
}; | ||
|
||
for i in 0..11 { | ||
c.dec_keys[i] = bit_slice_4x4_with_u16(dk[i][0], dk[i][1], dk[i][2], dk[i][3]); | ||
c.dec_keys8[i] = bit_slice_fill_4x4_with_u32x4(dk[i][0], dk[i][1], dk[i][2], dk[i][3]); | ||
} | ||
|
||
c | ||
} | ||
} | ||
|
||
impl BlockCipher for Aes128 { | ||
type BlockSize = U16; | ||
type ParBlocks = U8; | ||
|
||
#[inline] | ||
fn encrypt_block(&self, block: &mut Block) { | ||
let mut blocks = [Block::default(); 2]; | ||
blocks[0].copy_from_slice(block); | ||
fixslice::aes128_encrypt(&self.enc_keys, &mut blocks); | ||
block.copy_from_slice(&blocks[0]); | ||
} | ||
|
||
#[inline] | ||
fn decrypt_block(&self, block: &mut Block) { | ||
let mut bs = bit_slice_1x16_with_u16(block); | ||
bs = decrypt_core(&bs, &self.dec_keys); | ||
un_bit_slice_1x16_with_u16(&bs, block); | ||
} | ||
|
||
#[inline] | ||
fn encrypt_blocks(&self, blocks: &mut ParBlocks) { | ||
for chunk in blocks.chunks_mut(2) { | ||
fixslice::aes128_encrypt(&self.enc_keys, chunk); | ||
} | ||
} | ||
|
||
#[inline] | ||
fn decrypt_blocks(&self, blocks: &mut ParBlocks) { | ||
#[allow(unsafe_code)] | ||
let blocks: &mut [u8; 16 * 8] = unsafe { &mut *(blocks as *mut _ as *mut [u8; 128]) }; | ||
let bs = bit_slice_1x128_with_u32x4(blocks); | ||
let bs2 = decrypt_core(&bs, &self.dec_keys8); | ||
un_bit_slice_1x128_with_u32x4(bs2, blocks); | ||
} | ||
} | ||
|
||
opaque_debug::implement!(Aes128); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
//! AES-192 | ||
|
||
use cipher::{ | ||
consts::{U13, U16, U24, U8}, | ||
BlockCipher, NewBlockCipher, | ||
}; | ||
|
||
use crate::{ | ||
bitslice::{ | ||
bit_slice_1x128_with_u32x4, bit_slice_1x16_with_u16, bit_slice_4x4_with_u16, | ||
bit_slice_fill_4x4_with_u32x4, decrypt_core, encrypt_core, un_bit_slice_1x128_with_u32x4, | ||
un_bit_slice_1x16_with_u16, Bs8State, | ||
}, | ||
consts::U32X4_0, | ||
expand::expand_key, | ||
simd::u32x4, | ||
Block, ParBlocks, | ||
}; | ||
|
||
/// AES-192 key | ||
pub type Key = cipher::block::Key<Aes192>; | ||
|
||
/// AES-192 block cipher instance | ||
#[derive(Clone)] | ||
pub struct Aes192 { | ||
enc_keys: [Bs8State<u16>; 13], | ||
dec_keys: [Bs8State<u16>; 13], | ||
enc_keys8: [Bs8State<u32x4>; 13], | ||
dec_keys8: [Bs8State<u32x4>; 13], | ||
} | ||
|
||
impl NewBlockCipher for Aes192 { | ||
type KeySize = U24; | ||
|
||
#[inline] | ||
fn new(key: &Key) -> Self { | ||
let (ek, dk) = expand_key::<U24, U13>(key); | ||
|
||
let k8 = Bs8State( | ||
U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, | ||
); | ||
|
||
let mut c = Self { | ||
enc_keys: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0); 13], | ||
dec_keys: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0); 13], | ||
enc_keys8: [k8; 13], | ||
dec_keys8: [k8; 13], | ||
}; | ||
|
||
for i in 0..13 { | ||
c.enc_keys[i] = bit_slice_4x4_with_u16(ek[i][0], ek[i][1], ek[i][2], ek[i][3]); | ||
c.dec_keys[i] = bit_slice_4x4_with_u16(dk[i][0], dk[i][1], dk[i][2], dk[i][3]); | ||
c.enc_keys8[i] = bit_slice_fill_4x4_with_u32x4(ek[i][0], ek[i][1], ek[i][2], ek[i][3]); | ||
c.dec_keys8[i] = bit_slice_fill_4x4_with_u32x4(dk[i][0], dk[i][1], dk[i][2], dk[i][3]); | ||
} | ||
|
||
c | ||
} | ||
} | ||
|
||
impl BlockCipher for Aes192 { | ||
type BlockSize = U16; | ||
type ParBlocks = U8; | ||
|
||
#[inline] | ||
fn encrypt_block(&self, block: &mut Block) { | ||
let mut bs = bit_slice_1x16_with_u16(block); | ||
bs = encrypt_core(&bs, &self.enc_keys); | ||
un_bit_slice_1x16_with_u16(&bs, block); | ||
} | ||
|
||
#[inline] | ||
fn decrypt_block(&self, block: &mut Block) { | ||
let mut bs = bit_slice_1x16_with_u16(block); | ||
bs = decrypt_core(&bs, &self.dec_keys); | ||
un_bit_slice_1x16_with_u16(&bs, block); | ||
} | ||
|
||
#[inline] | ||
fn encrypt_blocks(&self, blocks: &mut ParBlocks) { | ||
#[allow(unsafe_code)] | ||
let blocks: &mut [u8; 16 * 8] = unsafe { &mut *(blocks as *mut _ as *mut [u8; 128]) }; | ||
let bs = bit_slice_1x128_with_u32x4(blocks); | ||
let bs2 = encrypt_core(&bs, &self.enc_keys8); | ||
un_bit_slice_1x128_with_u32x4(bs2, blocks); | ||
} | ||
|
||
#[inline] | ||
fn decrypt_blocks(&self, blocks: &mut ParBlocks) { | ||
#[allow(unsafe_code)] | ||
let blocks: &mut [u8; 16 * 8] = unsafe { &mut *(blocks as *mut _ as *mut [u8; 128]) }; | ||
let bs = bit_slice_1x128_with_u32x4(blocks); | ||
let bs2 = decrypt_core(&bs, &self.dec_keys8); | ||
un_bit_slice_1x128_with_u32x4(bs2, blocks); | ||
} | ||
} | ||
|
||
opaque_debug::implement!(Aes192); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
//! AES-256 | ||
|
||
use cipher::{ | ||
consts::{U15, U16, U32, U8}, | ||
BlockCipher, NewBlockCipher, | ||
}; | ||
|
||
use crate::{ | ||
bitslice::{ | ||
bit_slice_1x128_with_u32x4, bit_slice_1x16_with_u16, bit_slice_4x4_with_u16, | ||
bit_slice_fill_4x4_with_u32x4, decrypt_core, un_bit_slice_1x128_with_u32x4, | ||
un_bit_slice_1x16_with_u16, Bs8State, | ||
}, | ||
consts::U32X4_0, | ||
expand::expand_key, | ||
fixslice::{self, FixsliceKeys256}, | ||
simd::u32x4, | ||
Block, ParBlocks, | ||
}; | ||
|
||
/// AES-256 key | ||
pub type Key = cipher::block::Key<Aes256>; | ||
|
||
/// AES-256 block cipher instance | ||
#[derive(Clone)] | ||
pub struct Aes256 { | ||
enc_keys: FixsliceKeys256, | ||
dec_keys: [Bs8State<u16>; 15], | ||
dec_keys8: [Bs8State<u32x4>; 15], | ||
} | ||
|
||
impl NewBlockCipher for Aes256 { | ||
type KeySize = U32; | ||
|
||
#[inline] | ||
fn new(key: &Key) -> Self { | ||
let dk = expand_key::<U32, U15>(key).1; | ||
|
||
let k8 = Bs8State( | ||
U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, U32X4_0, | ||
); | ||
|
||
let mut c = Self { | ||
enc_keys: fixslice::aes256_key_schedule(key), | ||
dec_keys: [Bs8State(0, 0, 0, 0, 0, 0, 0, 0); 15], | ||
dec_keys8: [k8; 15], | ||
}; | ||
|
||
for i in 0..15 { | ||
c.dec_keys[i] = bit_slice_4x4_with_u16(dk[i][0], dk[i][1], dk[i][2], dk[i][3]); | ||
c.dec_keys8[i] = bit_slice_fill_4x4_with_u32x4(dk[i][0], dk[i][1], dk[i][2], dk[i][3]); | ||
} | ||
|
||
c | ||
} | ||
} | ||
|
||
impl BlockCipher for Aes256 { | ||
type BlockSize = U16; | ||
type ParBlocks = U8; | ||
|
||
#[inline] | ||
fn encrypt_block(&self, block: &mut Block) { | ||
let mut blocks = [Block::default(); 2]; | ||
blocks[0].copy_from_slice(block); | ||
fixslice::aes256_encrypt(&self.enc_keys, &mut blocks); | ||
block.copy_from_slice(&blocks[0]); | ||
} | ||
|
||
#[inline] | ||
fn decrypt_block(&self, block: &mut Block) { | ||
let mut bs = bit_slice_1x16_with_u16(block); | ||
bs = decrypt_core(&bs, &self.dec_keys); | ||
un_bit_slice_1x16_with_u16(&bs, block); | ||
} | ||
|
||
#[inline] | ||
fn encrypt_blocks(&self, blocks: &mut ParBlocks) { | ||
for chunk in blocks.chunks_mut(2) { | ||
fixslice::aes256_encrypt(&self.enc_keys, chunk); | ||
} | ||
} | ||
|
||
#[inline] | ||
fn decrypt_blocks(&self, blocks: &mut ParBlocks) { | ||
#[allow(unsafe_code)] | ||
let blocks: &mut [u8; 16 * 8] = unsafe { &mut *(blocks as *mut _ as *mut [u8; 128]) }; | ||
let bs = bit_slice_1x128_with_u32x4(blocks); | ||
let bs2 = decrypt_core(&bs, &self.dec_keys8); | ||
un_bit_slice_1x128_with_u32x4(bs2, blocks); | ||
} | ||
} | ||
|
||
opaque_debug::implement!(Aes256); |
Oops, something went wrong.