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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
cipher: v0.3 changes (without block-modes integration) by tarcieri · Pull Request #435 · RustCrypto/traits · GitHub
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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' cipher: v0.3 changes (without block-modes integration) by tarcieri · Pull Request #435 · RustCrypto/traits · GitHub
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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' cipher: v0.3 changes (without block-modes integration) by tarcieri · Pull Request #435 · RustCrypto/traits · GitHub
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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' cipher: v0.3 changes (without block-modes integration) by tarcieri · Pull Request #435 · RustCrypto/traits · GitHub
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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' cipher: v0.3 changes (without block-modes integration) by tarcieri · Pull Request #435 · RustCrypto/traits · GitHub
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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' cipher: v0.3 changes (without block-modes integration) by tarcieri · Pull Request #435 · RustCrypto/traits · GitHub
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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); cipher: v0.3 changes (without block-modes integration) by tarcieri · Pull Request #435 · RustCrypto/traits · GitHub
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
16 changes: 6 additions & 10 deletions cipher/src/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,21 +9,17 @@
//! [1]: https://en.wikipedia.org/wiki/Block_cipher
//! [2]: https://en.wikipedia.org/wiki/Symmetric-key_algorithm

#[cfg(feature = "dev")]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
pub mod dev;

use crate::errors::InvalidLength;
use core::convert::TryInto;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewBlockCipher`].
pub type Key<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;
pub type BlockCipherKey<B> = GenericArray<u8, <B as NewBlockCipher>::KeySize>;

/// Block on which a [`BlockCipher`] operates.
pub type Block<B> = GenericArray<u8, <B as BlockCipher>::BlockSize>;

/// Blocks being acted over in parallel.
/// Block on which a [`BlockCipher`] operates in parallel.
pub type ParBlocks<B> = GenericArray<Block<B>, <B as BlockCipher>::ParBlocks>;

/// Instantiate a [`BlockCipher`] algorithm.
Expand All@@ -32,13 +28,13 @@ pub trait NewBlockCipher: Sized {
type KeySize: ArrayLength<u8>;

/// Create new block cipher instance from key with fixed size.
fn new(key: &Key<Self>) -> Self;
fn new(key: &BlockCipherKey<Self>) -> Self;

/// Create new block cipher instance from key with variable size.
///
/// Default implementation will accept only keys with length equal to
/// `KeySize`, but some ciphers can accept range of key lengths.
fn new_varkey(key: &[u8]) -> Result<Self, InvalidLength> {
fn new_var(key: &[u8]) -> Result<Self, InvalidLength> {

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as we're bikeshedding this method name, I've thought it would be clearer if it had slice in the name, e.g. new_from_slice or from_slice.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

new_from_slice sounds good! from_slice is shorter, but I think will be more confusing, since it could be mistaken for a specialized version of the From trait. Also usually from* methods imply simple conversion, which is not the case here.

i wonder if for stream cipher and block modes we should use plural new_from_slices, since they accept two slices.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@newpavlov sounds good

if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Expand All@@ -57,7 +53,7 @@ pub trait BlockCipher {
type ParBlocks: ArrayLength<Block<Self>>;
}

/// Encrypt-only functionality for block ciphers
/// Encrypt-only functionality for block ciphers.
pub trait BlockEncrypt: BlockCipher {
/// Encrypt block in-place
fn encrypt_block(&self, block: &mut Block<Self>);
Expand DownExpand Up@@ -94,7 +90,7 @@ pub trait BlockEncrypt: BlockCipher {
}
}

/// Decrypt-only functionality for block ciphers
/// Decrypt-only functionality for block ciphers.
pub trait BlockDecrypt: BlockCipher {
/// Decrypt block in-place
fn decrypt_block(&self, block: &mut Block<Self>);
Expand Down
79 changes: 79 additions & 0 deletions cipher/src/common.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
use crate::{errors::InvalidLength, BlockCipher, NewBlockCipher};
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};

/// Key for an algorithm that implements [`NewCipher`].
pub type CipherKey<C> = GenericArray<u8, <C as NewCipher>::KeySize>;

/// Nonce for an algorithm that implements [`NewCipher`].
pub type Nonce<C> = GenericArray<u8, <C as NewCipher>::NonceSize>;

/// Cipher creation trait.
///
/// It can be used for creation of block modes, synchronous and asynchronous stream ciphers.
pub trait NewCipher: Sized {
/// Key size in bytes
type KeySize: ArrayLength<u8>;

/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Create new stream cipher instance from variable length key and nonce.
fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> Self;

/// Create new stream cipher instance from variable length key and nonce.
#[inline]
fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
let kl = Self::KeySize::to_usize();
let nl = Self::NonceSize::to_usize();
if key.len() != kl || nonce.len() != nl {
Err(InvalidLength)
} else {
let key = GenericArray::from_slice(key);
let nonce = GenericArray::from_slice(nonce);
Ok(Self::new(key, nonce))
}
}
}

/// Trait for types which can be initialized from a block cipher and nonce.
pub trait FromBlockCipher {
/// Block cipher
type BlockCipher: BlockCipher;
/// Nonce size in bytes
type NonceSize: ArrayLength<u8>;

/// Instantiate a stream cipher from a block cipher
fn from_block_cipher(
cipher: Self::BlockCipher,
nonce: &GenericArray<u8, Self::NonceSize>,
) -> Self;
}

impl<C> NewCipher for C
where
C: FromBlockCipher,
C::BlockCipher: NewBlockCipher,
{
type KeySize = <<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::KeySize;
type NonceSize = <Self as FromBlockCipher>::NonceSize;

fn new(key: &CipherKey<Self>, nonce: &Nonce<Self>) -> C {
C::from_block_cipher(
<<Self as FromBlockCipher>::BlockCipher as NewBlockCipher>::new(key),
nonce,
)
}

fn new_var(key: &[u8], nonce: &[u8]) -> Result<Self, InvalidLength> {
if nonce.len() != Self::NonceSize::USIZE {
Err(InvalidLength)
} else {
C::BlockCipher::new_var(key)
.map_err(|_| InvalidLength)
.map(|cipher| {
let nonce = GenericArray::from_slice(nonce);
Self::from_block_cipher(cipher, nonce)
})
}
}
}
2 changes: 2 additions & 0 deletions cipher/src/dev.rs
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
mod block;
mod stream;
16 changes: 8 additions & 8 deletions cipher/src/block/dev.rs → cipher/src/dev/block.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,13 +9,13 @@ macro_rules! block_cipher_test {
($name:ident, $test_name:expr, $cipher:ty) => {
#[test]
fn $name() {
use cipher::block::{
dev::blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};
use cipher::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};

fn run_test(key: &[u8], pt: &[u8], ct: &[u8]) -> bool {
let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let mut block = GenericArray::clone_from_slice(pt);
state.encrypt_block(&mut block);
Expand All@@ -37,7 +37,7 @@ macro_rules! block_cipher_test {
type Block = GenericArray<u8, BlockSize>;
type ParBlock = GenericArray<Block, ParBlocks>;

let state = <$cipher as NewBlockCipher>::new_varkey(key).unwrap();
let state = <$cipher as NewBlockCipher>::new_var(key).unwrap();

let block = Block::clone_from_slice(pt);
let mut blocks1 = ParBlock::default();
Expand DownExpand Up@@ -113,12 +113,12 @@ macro_rules! block_cipher_bench {
($cipher:path, $key_len:expr) => {
extern crate test;

use cipher::block::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use cipher::{BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher};
use test::Bencher;

#[bench]
pub fn encrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand All@@ -130,7 +130,7 @@ macro_rules! block_cipher_bench {

#[bench]
pub fn decrypt(bh: &mut Bencher) {
let state = <$cipher>::new_varkey(&[1u8; $key_len]).unwrap();
let state = <$cipher>::new_var(&[1u8; $key_len]).unwrap();
let mut block = Default::default();

bh.iter(|| {
Expand Down
14 changes: 6 additions & 8 deletions cipher/src/stream/dev.rs → cipher/src/dev/stream.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,12 +3,12 @@
/// Test core functionality of synchronous stream cipher
#[macro_export]
#[cfg_attr(docsrs, doc(cfg(feature = "dev")))]
macro_rules! stream_cipher_sync_test {
macro_rules! stream_cipher_test {
($name:ident, $cipher:ty, $test_name:expr) => {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, SyncStreamCipher};
use cipher::{blobby::Blob4Iterator, NewCipher, StreamCipher};

let data = include_bytes!(concat!("data/", $test_name, ".blb"));
for (i, row) in Blob4Iterator::new(data).unwrap().enumerate() {
Expand DownExpand Up@@ -44,7 +44,7 @@ macro_rules! stream_cipher_seek_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher, SyncStreamCipherSeek};
use cipher::{NewCipher, StreamCipher, StreamCipherSeek};

fn get_cipher() -> $cipher {
<$cipher>::new(&Default::default(), &Default::default())
Expand DownExpand Up@@ -97,7 +97,7 @@ macro_rules! stream_cipher_async_test {
#[test]
fn $name() {
use cipher::generic_array::GenericArray;
use cipher::stream::{blobby::Blob4Iterator, NewStreamCipher, StreamCipher};
use cipher::{blobby::Blob4Iterator, AsyncStreamCipher, NewCipher};

fn run_test(
key: &[u8],
Expand DownExpand Up@@ -172,8 +172,7 @@ macro_rules! stream_cipher_sync_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, SyncStreamCipher};
use cipher::{generic_array::GenericArray, NewCipher, StreamCipher};
use test::Bencher;

#[inline(never)]
Expand DownExpand Up@@ -225,8 +224,7 @@ macro_rules! stream_cipher_async_bench {
($cipher:path) => {
extern crate test;

use cipher::generic_array::GenericArray;
use cipher::stream::{NewStreamCipher, StreamCipher};
use cipher::{generic_array::GenericArray, AsyncStreamCipher, NewCipher};
use test::Bencher;

#[inline(never)]
Expand Down
2 changes: 1 addition & 1 deletion cipher/src/errors.rs
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
//! Error types
//! Error types.

use core::fmt;

Expand Down
17 changes: 9 additions & 8 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -16,14 +16,15 @@
#[cfg(feature = "std")]
extern crate std;

pub mod block;
#[cfg(feature = "dev")]
pub use blobby;

mod block;
mod common;
#[cfg(feature = "dev")]
mod dev;
pub mod errors;
pub mod stream;
mod stream;

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
};
pub use crate::{block::*, common::*, stream::*};
pub use generic_array::{self, typenum::consts};
Loading