Skip to content

Commit

Permalink
rc5: unlock parameter size, add u128 and u8 word size support. (#382)
Browse files Browse the repository at this point in the history
Closes #381
  • Loading branch information
NamedNeon authored Nov 26, 2023
1 parent f415d78 commit 1967139
Show file tree
Hide file tree
Showing 8 changed files with 187 additions and 29 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

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

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

## Unreleased
- Added u8 and u128 word size support.
- Enabled custom word size, key size, and round count values.
- Deprecated old predefined RC5 cipher types.

## 0.0.1 (2023-02-10)
- Initial release
- Initial release
2 changes: 1 addition & 1 deletion rc5/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "rc5"
version = "0.0.1"
version = "0.1.0-pre"
description = "RC5 block cipher"
authors = ["RustCrypto Developers"]
edition = "2021"
Expand Down
11 changes: 6 additions & 5 deletions rc5/benches/mod.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
#![feature(test)]
extern crate test;

use cipher::consts::*;
use cipher::{block_decryptor_bench, block_encryptor_bench};
use rc5::{RC5_32_12_16, RC5_32_16_16};
use rc5::RC5;

block_encryptor_bench!(
Key: RC5_32_12_16,
Key: RC5<u32, U12, U16>,
rc5_32_12_16_encrypt_block,
rc5_32_12_16_encrypt_blocks,
);
block_decryptor_bench!(
Key: RC5_32_12_16,
Key: RC5<u32, U12, U16>,
rc5_32_12_16_decrypt_block,
rc5_32_12_16_decrypt_blocks,
);

block_encryptor_bench!(
Key: RC5_32_16_16,
Key: RC5<u32, U16, U16>,
rc5_32_16_16_encrypt_block,
rc5_32_16_16_encrypt_blocks,
);
block_decryptor_bench!(
Key: RC5_32_16_16,
Key: RC5<u32, U16, U16>,
rc5_32_16_16_decrypt_block,
rc5_32_16_16_decrypt_blocks,
);
13 changes: 11 additions & 2 deletions rc5/src/block_cipher.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use core::ops::{Add, Div, Mul, Sub};

use cipher::{
consts::*,
generic_array::ArrayLength,
inout::InOut,
typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U12, U16, U2, U24, U256, U8},
typenum::{Diff, IsLess, Le, NonZero, Sum, Unsigned, U1, U2, U256},
AlgorithmName, Block, BlockBackend, BlockCipher, BlockDecrypt, BlockEncrypt, BlockSizeUser,
KeyInit, KeySizeUser, ParBlocksSizeUser,
};
Expand Down Expand Up @@ -345,7 +346,15 @@ where
}
}

#[allow(dead_code)]
#[deprecated(since = "0.1.0", note = "use RC5<u16, U16, U8> instead.")]
pub type RC5_16_16_8 = RC5<u16, U16, U8>;
#[allow(dead_code)]
#[deprecated(since = "0.1.0", note = "use RC5<u32, U12, U16> instead.")]
pub type RC5_32_12_16 = RC5<u32, U12, U16>;
#[allow(dead_code)]
#[deprecated(since = "0.1.0", note = "use RC5<u32, U16, U16> instead.")]
pub type RC5_32_16_16 = RC5<u32, U16, U16>;
pub type RC5_16_16_8 = RC5<u16, U16, U8>;
#[allow(dead_code)]
#[deprecated(since = "0.1.0", note = "use RC5<u64, U24, U24> instead.")]
pub type RC5_64_24_24 = RC5<u64, U24, U24>;
121 changes: 107 additions & 14 deletions rc5/src/core/primitives.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::ops::{Add, BitXor};

use cipher::{
generic_array::{ArrayLength, GenericArray},
typenum::{Diff, Prod, Quot, Sum, U1, U2, U4, U8},
typenum::{Diff, Prod, Quot, Sum, U1, U16, U2, U4, U8},
zeroize::DefaultIsZeroes,
};

Expand Down Expand Up @@ -43,54 +43,55 @@ pub trait Word:

mod private {
pub trait Sealed {}

impl Sealed for u32 {}
impl Sealed for u8 {}
impl Sealed for u16 {}
impl Sealed for u32 {}
impl Sealed for u64 {}
impl Sealed for u128 {}
}

impl Word for u32 {
type Bytes = U4;
impl Word for u8 {
type Bytes = U1;

const ZERO: Self = 0;
const THREE: Self = 3;
const EIGHT: Self = 8;

const P: Self = 0xb7e15163;
const Q: Self = 0x9e3779b9;
const P: Self = 0xb7;
const Q: Self = 0x9f;

#[inline(always)]
fn wrapping_add(self, rhs: Self) -> Self {
u32::wrapping_add(self, rhs)
u8::wrapping_add(self, rhs)
}
#[inline(always)]
fn wrapping_sub(self, rhs: Self) -> Self {
u32::wrapping_sub(self, rhs)
u8::wrapping_sub(self, rhs)
}

#[inline(always)]
fn rotate_left(self, n: Self) -> Self {
u32::rotate_left(self, n)
u8::rotate_left(self, n as u32)
}

#[inline(always)]
fn rotate_right(self, n: Self) -> Self {
u32::rotate_right(self, n)
u8::rotate_right(self, n as u32)
}

#[inline(always)]
fn from_le_bytes(bytes: &GenericArray<u8, Self::Bytes>) -> Self {
u32::from_le_bytes(bytes.as_slice().try_into().unwrap())
u8::from_le_bytes(bytes.as_slice().try_into().unwrap())
}

#[inline(always)]
fn to_le_bytes(self) -> GenericArray<u8, Self::Bytes> {
u32::to_le_bytes(self).into()
u8::to_le_bytes(self).into()
}

#[inline(always)]
fn bitxor(self, other: Self) -> Self {
<u32 as BitXor>::bitxor(self, other)
<u8 as BitXor>::bitxor(self, other)
}
}

Expand Down Expand Up @@ -139,6 +140,51 @@ impl Word for u16 {
}
}

impl Word for u32 {
type Bytes = U4;

const ZERO: Self = 0;
const THREE: Self = 3;
const EIGHT: Self = 8;

const P: Self = 0xb7e15163;
const Q: Self = 0x9e3779b9;

#[inline(always)]
fn wrapping_add(self, rhs: Self) -> Self {
u32::wrapping_add(self, rhs)
}
#[inline(always)]
fn wrapping_sub(self, rhs: Self) -> Self {
u32::wrapping_sub(self, rhs)
}

#[inline(always)]
fn rotate_left(self, n: Self) -> Self {
u32::rotate_left(self, n)
}

#[inline(always)]
fn rotate_right(self, n: Self) -> Self {
u32::rotate_right(self, n)
}

#[inline(always)]
fn from_le_bytes(bytes: &GenericArray<u8, Self::Bytes>) -> Self {
u32::from_le_bytes(bytes.as_slice().try_into().unwrap())
}

#[inline(always)]
fn to_le_bytes(self) -> GenericArray<u8, Self::Bytes> {
u32::to_le_bytes(self).into()
}

#[inline(always)]
fn bitxor(self, other: Self) -> Self {
<u32 as BitXor>::bitxor(self, other)
}
}

impl Word for u64 {
type Bytes = U8;

Expand Down Expand Up @@ -185,3 +231,50 @@ impl Word for u64 {
<u64 as BitXor>::bitxor(self, other)
}
}

impl Word for u128 {
type Bytes = U16;

const ZERO: Self = 0;
const THREE: Self = 3;
const EIGHT: Self = 8;

const P: Self = 0xb7e151628aed2a6abf7158809cf4f3c7;
const Q: Self = 0x9e3779b97f4a7c15f39cc0605cedc835;

#[inline(always)]
fn wrapping_add(self, rhs: Self) -> Self {
u128::wrapping_add(self, rhs)
}
#[inline(always)]
fn wrapping_sub(self, rhs: Self) -> Self {
u128::wrapping_sub(self, rhs)
}

#[inline(always)]
fn rotate_left(self, n: Self) -> Self {
let size = Self::BITS;
u128::rotate_left(self, (n % size as u128) as u32)
}

#[inline(always)]
fn rotate_right(self, n: Self) -> Self {
let size = Self::BITS;
u128::rotate_right(self, (n % size as u128) as u32)
}

#[inline(always)]
fn from_le_bytes(bytes: &GenericArray<u8, Self::Bytes>) -> Self {
u128::from_le_bytes(bytes.as_slice().try_into().unwrap())
}

#[inline(always)]
fn to_le_bytes(self) -> GenericArray<u8, Self::Bytes> {
u128::to_le_bytes(self).into()
}

#[inline(always)]
fn bitxor(self, other: Self) -> Self {
<u128 as BitXor>::bitxor(self, other)
}
}
1 change: 1 addition & 0 deletions rc5/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
mod block_cipher;
mod core;

pub use crate::core::RC5;
pub use block_cipher::*;
59 changes: 54 additions & 5 deletions rc5/tests/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
/// generated using the code in: https://www.ietf.org/archive/id/draft-krovetz-rc6-rc5-vectors-00.txt
#[cfg(test)]
mod tests {
use cipher::consts::*;
use cipher::{generic_array::GenericArray, BlockDecrypt, BlockEncrypt, KeyInit};
use rc5::{RC5_16_16_8, RC5_32_12_16, RC5_32_16_16, RC5_64_24_24};
use rc5::RC5;

#[test]
fn enc_dec_8_12_4() {
let key = [0x00, 0x01, 0x02, 0x03];

let pt = [0x00, 0x01];
let ct = [0x21, 0x2A];

let rc5 = <RC5<u8, U12, U4> as KeyInit>::new_from_slice(&key).unwrap();

let mut block = GenericArray::clone_from_slice(&pt);
rc5.encrypt_block(&mut block);

assert_eq!(ct, block[..]);

rc5.decrypt_block(&mut block);
assert_eq!(pt, block[..]);
}

#[test]
fn enc_dec_16_16_8() {
Expand All @@ -11,7 +30,7 @@ mod tests {
let pt = [0x00, 0x01, 0x02, 0x03];
let ct = [0x23, 0xA8, 0xD7, 0x2E];

let rc5 = <RC5_16_16_8 as KeyInit>::new_from_slice(&key).unwrap();
let rc5 = <RC5<u16, U16, U8> as KeyInit>::new_from_slice(&key).unwrap();

let mut block = GenericArray::clone_from_slice(&pt);
rc5.encrypt_block(&mut block);
Expand All @@ -32,7 +51,7 @@ mod tests {
let pt = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
let ct = [0xC8, 0xD3, 0xB3, 0xC4, 0x86, 0x70, 0x0C, 0xFA];

let rc5 = <RC5_32_12_16 as KeyInit>::new_from_slice(&key).unwrap();
let rc5 = <RC5<u32, U12, U16> as KeyInit>::new_from_slice(&key).unwrap();

let mut block = GenericArray::clone_from_slice(&pt);
rc5.encrypt_block(&mut block);
Expand All @@ -53,7 +72,7 @@ mod tests {
let pt = [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07];
let ct = [0x3E, 0x2E, 0x95, 0x35, 0x70, 0x27, 0xD8, 0x96];

let rc5 = <RC5_32_16_16 as KeyInit>::new_from_slice(&key).unwrap();
let rc5 = <RC5<u32, U16, U16> as KeyInit>::new_from_slice(&key).unwrap();

let mut block = GenericArray::clone_from_slice(&pt);
rc5.encrypt_block(&mut block);
Expand All @@ -80,7 +99,37 @@ mod tests {
0x78, 0xDA,
];

let rc5 = <RC5_64_24_24 as KeyInit>::new_from_slice(&key).unwrap();
let rc5 = <RC5<u64, U24, U24> as KeyInit>::new_from_slice(&key).unwrap();

let mut block = GenericArray::clone_from_slice(&pt);
rc5.encrypt_block(&mut block);

assert_eq!(ct, block[..]);

rc5.decrypt_block(&mut block);
assert_eq!(pt, block[..]);
}

#[test]
fn enc_dec_128_28_32() {
let key = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
0x1C, 0x1D, 0x1E, 0x1F,
];

let pt = [
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B,
0x1C, 0x1D, 0x1E, 0x1F,
];
let ct = [
0xEC, 0xA5, 0x91, 0x09, 0x21, 0xA4, 0xF4, 0xCF, 0xDD, 0x7A, 0xD7, 0xAD, 0x20, 0xA1,
0xFC, 0xBA, 0x06, 0x8E, 0xC7, 0xA7, 0xCD, 0x75, 0x2D, 0x68, 0xFE, 0x91, 0x4B, 0x7F,
0xE1, 0x80, 0xB4, 0x40,
];

let rc5 = <RC5<u128, U28, U32> as KeyInit>::new_from_slice(&key).unwrap();

let mut block = GenericArray::clone_from_slice(&pt);
rc5.encrypt_block(&mut block);
Expand Down

0 comments on commit 1967139

Please sign in to comment.