TEA(Tiny Encryption Algorithm)微型加密算法
TEA加密
我这又来水文章了,原来我的想法是找一个实现起来简单的加密,越简单越好,然后这个加密算法,突然映入眼帘,只是因为在人群当中看了你一眼,我就相中了你的简单,下面是老套路了,简单的说一下这个算法是怎么来的。
算法概况
❝在密码学中,微型加密算法(Tiny Encryption Algorithm,TEA)是一种易于描述和执行的块密码,通常只需要很少的代码就可实现。其设计者是剑桥大学计算机实验室的大卫·惠勒与罗杰·尼达姆。这项技术最初于1994年提交给鲁汶的快速软件加密的研讨会上,并在该研讨会上演讲中首次发表。【维基百科】
❞
对于这个加密算法,在维基百科当中其实也没描述如何对多字节的处理,下面给出维基百科上面的原话:
❝请留意这个参考实现对多字节的处理。原稿中并未指定出如何从二进制或者其他内容中派生出这些得到的数字。
at the reference implementation acts on multi-byte numeric values. The original paper does not specify how to derive the numbers it acts on from binary or other content.
❞
因此呢,在后面的实现当中,我也不给出多字节的实现了,在这里简单说一下,如果把这个看作为分组加密,那么剩余的分组模式是都可以使用的,这个算法的入参呢就是两个u32, 也就是64bit数据,其实也就是分组大小为64bit, 然后呢,密钥长度为128位。
算法描述
算法结构
加密
有关加密,这个算法还是比较容易理解的,其中用到了一个常量delta = 0x9E3779B9
, 然后就是32轮和密钥有关的操作,具体的操作如上图所示。
对于这个delta是怎么来的,实际上这个魔数来自于的下取整。其中呢是黄金分割数字(1.618033988749
)。
解密
有关解密操作, 其实就是加密操作的逆过程,注意,这里的sum是加密最后运算的结果。
好了,这个加密算法其实到这里就解释完了,非常符合他的名字,哈哈哈。
代码实现
回归老本行了,还是拿rust来实现了
const DELTA: u32 = 0x9e3779b9; struct TEA {} impl TEA { pub fn encrypt(v: [u32; 2], k: [u32; 4]) -> [u32; 2] { let mut v0 = v[0]; let mut v1 = v[1]; let mut sum = 0u32; for _ in 0..32 { sum = sum.wrapping_add(DELTA); v0 = v0.wrapping_add(v1.wrapping_shl(4).wrapping_add(k[0]) ^ (v1.wrapping_add(sum)) ^ v1.wrapping_shr(5).wrapping_add(k[1])); v1 = v1.wrapping_add(v0.wrapping_shl(4).wrapping_add(k[2]) ^ (v0.wrapping_add(sum)) ^ v0.wrapping_shr(5).wrapping_add(k[3])); } return [v0, v1]; } pub fn decrypt(v: [u32; 2], k: [u32; 4]) -> [u32; 2] { let mut v0 = v[0]; let mut v1 = v[1]; let mut sum = 0xC6EF3720_u32; for _ in 0..32 { v1 = v1.wrapping_sub(v0.wrapping_shl(4).wrapping_add(k[2]) ^ (v0.wrapping_add(sum)) ^ v0.wrapping_shr(5).wrapping_add(k[3])); v0 = v0.wrapping_sub(v1.wrapping_shl(4).wrapping_add(k[0]) ^ (v1.wrapping_add(sum)) ^ v1.wrapping_shr(5).wrapping_add(k[1])); sum = sum.wrapping_sub(DELTA); } return [v0, v1]; } } #[cfg(test)] mod test { use crate::tea::TEA; #[test] fn test() { let result = TEA::encrypt([1, 2], [2, 3, 4, 5]); println!("{:?}", result); let result = TEA::decrypt(result, [2, 3, 4, 5]); println!("{:?}", result) } }