Closed
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
block::*,
common::*,
stream::*,
};
#[cfg(feature = "block-mode")]
pub use crate::mode::BlockModeCore;
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n 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;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Closed
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
block::*,
common::*,
stream::*,
};
#[cfg(feature = "block-mode")]
pub use crate::mode::BlockModeCore;
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
block::*,
common::*,
stream::*,
};
#[cfg(feature = "block-mode")]
pub use crate::mode::BlockModeCore;
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
block::*,
common::*,
stream::*,
};
#[cfg(feature = "block-mode")]
pub use crate::mode::BlockModeCore;
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Closed
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
block::*,
common::*,
stream::*,
};
#[cfg(feature = "block-mode")]
pub use crate::mode::BlockModeCore;
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
block::*,
common::*,
stream::*,
};
#[cfg(feature = "block-mode")]
pub use crate::mode::BlockModeCore;
pub use generic_array::{self, typenum::consts};
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Closed
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
7 changes: 7 additions & 0 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

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

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

3 changes: 3 additions & 0 deletions cipher/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -14,9 +14,12 @@ categories = ["cryptography", "no-std"]
[dependencies]
generic-array = "0.14"
blobby = { version = "0.3", optional = true }
block-padding = { verstion = "0.2", optional = true }

@tarcieritarcieriDec 26, 2020

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.

Typo: verstion

Suggested change
block-padding = { verstion = "0.2", optional = true }
block-padding = { version = "0.2", optional = true }


[features]
default = ["block-mode"]
std = []
block-mode = ["block-padding"]
dev = ["blobby"]

[package.metadata.docs.rs]
Expand Down
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> {
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 generic_array::{ArrayLength, GenericArray, typenum::Unsigned};
use crate::{BlockCipher, NewBlockCipher, errors::InvalidLength};

/// 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 stream;
mod block;
14 changes: 7 additions & 7 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::{
blobby::Blob3Iterator, BlockCipher, BlockDecrypt, BlockEncrypt, NewBlockCipher,
};
use cipher::generic_array::{typenum::Unsigned, GenericArray};

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, NewCipher, AsyncStreamCipher};

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::{NewCipher, StreamCipher, generic_array::GenericArray};
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::{NewCipher, AsyncStreamCipher, generic_array::GenericArray};
use test::Bencher;

#[inline(never)]
Expand Down
15 changes: 14 additions & 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 DownExpand Up@@ -48,3 +48,16 @@ impl From<OverflowError> for LoopError {

#[cfg(feature = "std")]
impl std::error::Error for OverflowError {}

/// Block mode error.
#[derive(Clone, Copy, Debug)]
pub struct BlockModeError;

impl fmt::Display for BlockModeError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.write_str("BlockModeError")
}
}

#[cfg(feature = "std")]
impl std::error::Error for BlockModeError {}
22 changes: 16 additions & 6 deletions cipher/src/lib.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,15 +15,25 @@

#[cfg(feature = "std")]
extern crate std;
#[cfg(feature = "block-mode")]
pub extern crate block_padding;
#[cfg(feature = "dev")]
pub extern crate blobby;

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

pub use crate::{
block::{
BlockCipher, BlockDecrypt, BlockDecryptMut, BlockEncrypt, BlockEncryptMut, NewBlockCipher,
},
stream::{NewStreamCipher, StreamCipher, SyncStreamCipher, SyncStreamCipherSeek},
block::*,
common::*,
stream::*,
};
#[cfg(feature = "block-mode")]
pub use crate::mode::BlockModeCore;
pub use generic_array::{self, typenum::consts};
Loading