【密码学】一文读懂ChaCha20

简介: 好久没写新的加密算法的原理了, 这次所选取的加密算法结构比较简单, 一起来看一下吧。

一文读懂ChaCha20


3~KZK2IW1)SB{T%{4]XA6_Y.png一文读懂ChaCha20

好久没写新的加密算法的原理了, 这次所选取的加密算法结构比较简单, 一起来看一下吧。


算法简介

Google选择了伯恩斯坦设计的,带Poly1305消息认证码的ChaCha20(即ChaCha20-Poly1305),作为OpenSSL中RC4的替代品,用以完成互联网的安全通信。Google最初实现了HTTPS (TLS/SSL)流量在Chrome浏览器(Android手机版)与Google网站之间的通信。【维基百科】

本文只是介绍ChaCha20, 暂时将不会介绍带有Poly1305验证码的ChaCha20, 至于为啥叫ChaCha20可能是因为它有20轮的迭代吧。


算法原理

还是老样子, 直接来看这个加密的具体原理吧。

1/4轮操作

在ChaCha20算法当中, 一个基础的操作即为1/4轮运算, 它主要操作4个32位的无符号整数,具体操作如下:

a += b; d ^= a; d <<<= 16;
c += d; b ^= c; b <<<= 12;
a += b; d ^= a; d <<<= 8;
c += d; b ^= c; b <<<= 7;

初始化矩阵

矩阵的输入为一个256位的密钥、32位随机数、96位计数器值以及4×32位的常数,它们均填充在32位整型数组中作为初始矩阵,如下图所示:

image.gifChaCha20初始化矩阵

块函数(ChaCha20 Block Function)

这个块函数输入是之前所生成的状态矩阵, 最终输出64bit的"随机化"的字节, 具体操作如下所示:

initial_state = state
for i in 10:
    QUARTERROUND(0, 4, 8, 12)
    QUARTERROUND(1, 5, 9, 13)
    QUARTERROUND(2, 6, 10, 14)
    QUARTERROUND(3, 7, 11, 15)
    QUARTERROUND(0, 5, 10, 15)
    QUARTERROUND(1, 6, 11, 12)
    QUARTERROUND(2, 7, 8, 13)
    QUARTERROUND(3, 4, 9, 14)
state += initial_state
output state

到这里, ChaCha20的基本原理就结束了, 整个密码结构并不是很复杂, 整体思路也比较清晰。


代码实现

依然采用rust来实现这个代码

// https://datatracker.ietf.org/doc/html/rfc8439
pub struct ChaCha20 {
    state: [u32; 16],
}
fn quarter_round(state: &mut [u32; 16], a: usize, b: usize, c: usize, d: usize) {
    state[a] = state[a].wrapping_add(state[b]);
    state[d] = (state[d] ^ state[a]).rotate_left(16);
    state[c] = state[c].wrapping_add(state[d]);
    state[b] = (state[b] ^ state[c]).rotate_left(12);
    state[a] = state[a].wrapping_add(state[b]);
    state[d] = (state[d] ^ state[a]).rotate_left(8);
    state[c] = state[c].wrapping_add(state[d]);
    state[b] = (state[b] ^ state[c]).rotate_left(7);
}
impl ChaCha20 {
    pub fn new(key: [u32; 8], counter: u32, nonce: [u32; 3]) -> ChaCha20 {
        return ChaCha20 {
            state: [
                0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
                key[0], key[1], key[2], key[3],
                key[4], key[5], key[6], key[7],
                counter, nonce[0], nonce[1], nonce[2],
            ]
        };
    }
    fn chacha20_block(&mut self) -> Vec<u8> {
        let mut key_stream = vec![];
        let mut initial_state = self.state;
        for _ in 1..=10 {
            quarter_round(&mut initial_state, 0, 4, 8, 12);
            quarter_round(&mut initial_state, 1, 5, 9, 13);
            quarter_round(&mut initial_state, 2, 6, 10, 14);
            quarter_round(&mut initial_state, 3, 7, 11, 15);
            quarter_round(&mut initial_state, 0, 5, 10, 15);
            quarter_round(&mut initial_state, 1, 6, 11, 12);
            quarter_round(&mut initial_state, 2, 7, 8, 13);
            quarter_round(&mut initial_state, 3, 4, 9, 14);
        }
        for (index, value) in initial_state.iter().enumerate() {
            let new_value = self.state[index].wrapping_add(*value);
            for &x in new_value.to_le_bytes().iter() {
                key_stream.push(x);
            }
        }
        key_stream
    }
    pub fn encrypt(&mut self, message: &[u8]) -> Vec<u8> {
        let mut result = vec![];
        for chunk in message.chunks(64) {
            for (&key, value) in chunk.iter().zip(self.chacha20_block()) {
                result.push(key ^ value);
            }
            self.state[12] += 1;
        }
        return result;
    }
}
#[cfg(test)]
mod test {
    use crate::chacha20::ChaCha20;
    #[test]
    fn test() {
        let key = [0u32; 8];
        let nonce = [0x0u32; 3];
        let mut cc20 = ChaCha20::new(key, 1, nonce);
        let result = cc20.encrypt("1234".as_bytes());
        println!("{:?}", result);
    }
}


相关文章
|
算法 数据安全/隐私保护
【密码学】一文读懂Whirlpool
首先呢,祝大家今晚节日快乐,Whirlpool是由Vincent Rijmen(高级加密标准的联合创始人)和Paulo S.L.M.Barreto设计的,后者于2000年首次提出了它。
【密码学】一文读懂Whirlpool
|
Rust 算法 Go
【密码学】一文读懂MurMurHash3
本文应该是MurMurHash算法介绍的最后一篇,来一起看一下最新的MurMurHash算法的具体过程,对于最新的算法来说,整个流程和之前的其实也比较相似,这里从维基百科当中找到了伪代码,也就不贴出来Google官方给出的推荐代码了,先来看一下维基百科给出的伪代码,这里只有32位的伪代码。
1205 0
【密码学】一文读懂MurMurHash3
|
Rust 算法 安全
【密码学】一文读懂MurMurHash2
上次我们聊过了一代的MurMurHash算法,是的,我又来水文章了,今天呢,接着来聊一下二代的MurMurHash算法,二代算法的整体结构实际上和一代算法差不太多,只是对于每一轮数据的处理过程当中的运算有一些差异,算法的来源依然是来自于Google官网给提供的源码,对着源码看的结构,对于这个算法呢,有两个版本,一个是32位的,一个是64位的,对于32位的算法和64位的算法,区别在于两个初始的魔数不同,整体运算过程还是十分相似的。
1684 0
【密码学】一文读懂MurMurHash2
|
Rust 算法 网络安全
【密码学】一文读懂CMAC
介于上一篇文章比较水,然后这个和上一篇也比较相似,CMAC是为了解决DAA当中安全性不足的问题而出现的,这个算法一共有三个密钥,K, K1, K2, 其中K1和K2可以由K导出,接下来就来一起看一下CMAC的具体过程吧,这一篇文章其实也不长。
2786 0
【密码学】一文读懂CMAC
|
Rust 算法 数据安全/隐私保护
【密码学】一文读懂XTEA加密
本篇文章,我们来看一下上一次讲过的TEA加密算法的一个升级版XTEA, 相比于TEA, XTEA的安全性显然是更高的,其中的过程要比TEA稍微复杂一点点。
1021 0
【密码学】一文读懂XTEA加密
|
存储 Rust 并行计算
【密码学】一文读懂XTS模式
这篇文章的灵感来源于我偶然翻到的一个某U盘有关磁盘加密的一个介绍(这一篇不是广告蛤), 然后发现这个模式我之前还真没遇到过,因此呢,就学习了一下,就出来了这一篇文章。
3511 0
【密码学】一文读懂XTS模式
|
算法 安全 Go
【密码学】一文读懂HKDF
我这又来水一篇文章,来聊一下HKDF(基于HMAC的密钥导出函数)。密钥派生函数是密钥管理的组成部分,他的目标是通过一些初始的数据派生出来密码学安全的随机密钥。
2759 0
【密码学】一文读懂HKDF
|
Rust 算法 数据安全/隐私保护
【密码学】一文读懂ElGamal
上篇文章我们聊到了Diffie-Hellman的密钥交换协议,这次来聊一个和Diffie-Hellman相似的一个加密算法--ElGamal加密算法,该算法同样选择一个素数p和它的一个原根作为公开密钥。
【密码学】一文读懂ElGamal
|
存储 算法 安全
【密码学】一文读懂PBE
本文主要来聊一下基于口令的加密(Pasword Based Encrytion), 我更倾向于把password翻译成为口令,这是为了和密码学当中密码区分开,这里的password不是指的某种密码体制,而是相当于容易记忆的一串字符(当然也包括那些用随机字符串所密码的)。
【密码学】一文读懂PBE
|
算法 搜索推荐 安全
【密码学】一文读懂CCM
本文简单介绍了CCM模式下的认证和加密机制,实际上这个是AES-CTR模式和CMAC的一个组合,如果理解了前面这两个,本文应该还是比较好理解的。
2831 0
【密码学】一文读懂CCM