mirror of
https://github.com/jixunmoe/tc_tea_rust
synced 2026-03-07 20:19:49 +00:00
refactor: use u64 as internal states for ecb
This commit is contained in:
48
src/ecb.rs
48
src/ecb.rs
@@ -1,50 +1,18 @@
|
||||
use crate::ecb_impl;
|
||||
use byteorder::{ByteOrder, BE};
|
||||
|
||||
// Tencent chooses 16 rounds instead of traditional 32 rounds.
|
||||
const ROUNDS: u32 = 16;
|
||||
const DELTA: u32 = 0x9e3779b9;
|
||||
|
||||
/// Perform a single round of encrypting/decrypting wrapping arithmetics
|
||||
fn ecb_single_round(value: u32, sum: u32, key1: u32, key2: u32) -> u32 {
|
||||
let left = value.wrapping_shl(4).wrapping_add(key1);
|
||||
let right = value.wrapping_shr(5).wrapping_add(key2);
|
||||
let mid = sum.wrapping_add(value);
|
||||
|
||||
left ^ mid ^ right
|
||||
}
|
||||
|
||||
/// Perform a 16 round TEA ECB encryption.
|
||||
pub fn encrypt(block: &mut [u8; 8], k: &[u32; 4]) {
|
||||
let mut y = BE::read_u32(&block[..4]);
|
||||
let mut z = BE::read_u32(&block[4..]);
|
||||
let mut sum = 0_u32;
|
||||
|
||||
for _ in 0..ROUNDS {
|
||||
sum = sum.wrapping_add(DELTA);
|
||||
|
||||
y = y.wrapping_add(ecb_single_round(z, sum, k[0], k[1]));
|
||||
z = z.wrapping_add(ecb_single_round(y, sum, k[2], k[3]));
|
||||
}
|
||||
|
||||
BE::write_u32(&mut block[..4], y);
|
||||
BE::write_u32(&mut block[4..], z);
|
||||
pub fn encrypt(block: &mut [u8; 8], key: &[u32; 4]) {
|
||||
let state = BE::read_u64(block);
|
||||
let state = ecb_impl::encrypt(state, key);
|
||||
BE::write_u64(block, state);
|
||||
}
|
||||
|
||||
/// Perform a 16 round TEA ECB decryption.
|
||||
pub fn decrypt(block: &mut [u8; 8], key: &[u32; 4]) {
|
||||
let mut y = BE::read_u32(&block[..4]);
|
||||
let mut z = BE::read_u32(&block[4..]);
|
||||
let mut sum = DELTA.wrapping_mul(ROUNDS);
|
||||
|
||||
for _ in 0..ROUNDS {
|
||||
z = z.wrapping_sub(ecb_single_round(y, sum, key[2], key[3]));
|
||||
y = y.wrapping_sub(ecb_single_round(z, sum, key[0], key[1]));
|
||||
|
||||
sum = sum.wrapping_sub(DELTA);
|
||||
}
|
||||
|
||||
BE::write_u32(&mut block[..4], y);
|
||||
BE::write_u32(&mut block[4..], z);
|
||||
let state = BE::read_u64(block);
|
||||
let state = ecb_impl::decrypt(state, key);
|
||||
BE::write_u64(block, state);
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
52
src/ecb_impl.rs
Normal file
52
src/ecb_impl.rs
Normal file
@@ -0,0 +1,52 @@
|
||||
// Tencent chooses 16 rounds instead of traditional 32 rounds.
|
||||
const ROUNDS: u32 = 16;
|
||||
const DELTA: u32 = 0x9e3779b9;
|
||||
|
||||
/// Perform a single round of encrypting/decrypting wrapping arithmetics
|
||||
fn ecb_single_round(value: u32, sum: u32, key1: u32, key2: u32) -> u32 {
|
||||
let left = value.wrapping_shl(4).wrapping_add(key1);
|
||||
let right = value.wrapping_shr(5).wrapping_add(key2);
|
||||
let mid = sum.wrapping_add(value);
|
||||
|
||||
left ^ mid ^ right
|
||||
}
|
||||
|
||||
fn parse_tea_u64(state: u64) -> (u32, u32) {
|
||||
let y = (state >> 32) as u32;
|
||||
let z = state as u32;
|
||||
(y, z)
|
||||
}
|
||||
|
||||
fn make_tea_u64(y: u32, z: u32) -> u64 {
|
||||
(y as u64) << 32 | (z as u64)
|
||||
}
|
||||
|
||||
/// Perform a 16 round TEA ECB encryption.
|
||||
pub fn encrypt(block: u64, key: &[u32; 4]) -> u64 {
|
||||
let (mut y, mut z) = parse_tea_u64(block);
|
||||
let mut sum = 0_u32;
|
||||
|
||||
for _ in 0..ROUNDS {
|
||||
sum = sum.wrapping_add(DELTA);
|
||||
|
||||
y = y.wrapping_add(ecb_single_round(z, sum, key[0], key[1]));
|
||||
z = z.wrapping_add(ecb_single_round(y, sum, key[2], key[3]));
|
||||
}
|
||||
|
||||
make_tea_u64(y, z)
|
||||
}
|
||||
|
||||
/// Perform a 16 round TEA ECB decryption.
|
||||
pub fn decrypt(block: u64, key: &[u32; 4]) -> u64 {
|
||||
let (mut y, mut z) = parse_tea_u64(block);
|
||||
let mut sum = DELTA.wrapping_mul(ROUNDS);
|
||||
|
||||
for _ in 0..ROUNDS {
|
||||
z = z.wrapping_sub(ecb_single_round(y, sum, key[2], key[3]));
|
||||
y = y.wrapping_sub(ecb_single_round(z, sum, key[0], key[1]));
|
||||
|
||||
sum = sum.wrapping_sub(DELTA);
|
||||
}
|
||||
|
||||
make_tea_u64(y, z)
|
||||
}
|
||||
@@ -7,6 +7,7 @@ use thiserror::Error;
|
||||
|
||||
pub mod cbc;
|
||||
pub mod ecb;
|
||||
mod ecb_impl;
|
||||
|
||||
#[derive(Error, Debug, PartialEq)]
|
||||
pub enum TcTeaError {
|
||||
|
||||
Reference in New Issue
Block a user