【密码学】一文读懂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);
    }
}


相关文章
|
存储 Rust 并行计算
【密码学】一文读懂XTS模式
这篇文章的灵感来源于我偶然翻到的一个某U盘有关磁盘加密的一个介绍(这一篇不是广告蛤), 然后发现这个模式我之前还真没遇到过,因此呢,就学习了一下,就出来了这一篇文章。
7943 0
【密码学】一文读懂XTS模式
|
Rust 算法 网络安全
【密码学】一文读懂CMAC
介于上一篇文章比较水,然后这个和上一篇也比较相似,CMAC是为了解决DAA当中安全性不足的问题而出现的,这个算法一共有三个密钥,K, K1, K2, 其中K1和K2可以由K导出,接下来就来一起看一下CMAC的具体过程吧,这一篇文章其实也不长。
5141 0
【密码学】一文读懂CMAC
|
Rust 算法 Go
【密码学】一文读懂MurMurHash3
本文应该是MurMurHash算法介绍的最后一篇,来一起看一下最新的MurMurHash算法的具体过程,对于最新的算法来说,整个流程和之前的其实也比较相似,这里从维基百科当中找到了伪代码,也就不贴出来Google官方给出的推荐代码了,先来看一下维基百科给出的伪代码,这里只有32位的伪代码。
3036 0
【密码学】一文读懂MurMurHash3
|
Rust 算法 安全
【密码学】一文读懂MurMurHash2
上次我们聊过了一代的MurMurHash算法,是的,我又来水文章了,今天呢,接着来聊一下二代的MurMurHash算法,二代算法的整体结构实际上和一代算法差不太多,只是对于每一轮数据的处理过程当中的运算有一些差异,算法的来源依然是来自于Google官网给提供的源码,对着源码看的结构,对于这个算法呢,有两个版本,一个是32位的,一个是64位的,对于32位的算法和64位的算法,区别在于两个初始的魔数不同,整体运算过程还是十分相似的。
2800 0
【密码学】一文读懂MurMurHash2
|
Rust 算法 安全
【密码学】一文读懂HMAC
本文将来聊一聊基于哈希函数的消息认证码,在此之前,先来科普一下什么是 「消息认证码」 (MAC), 先来看一个简单的栗子
2346 0
【密码学】一文读懂HMAC
|
算法 网络安全 数据安全/隐私保护
【密码学】手摸手带你手算AES
本文带着大家手动计算了一下完整的简化版AES的整个流程,其实主要都参考了密码学与网络安全这本书,大部分的公式都是从这本书上来的,我是真的喜欢这个例子,麻雀虽小,五脏俱全,用来学习AES的入门感觉非常的合适,如果能够完整的自己手算下来这个例子,然后再去看完整版的AES算法,会简单非常多,主要就是规模扩大了一下,核心的流程还是上面这一套。最后,感谢能看到这里的读者,如果本文对大佬们理解AES有一点点的帮助,也不枉我手动敲了这么多的公式和矩阵了。
1339 0
【密码学】手摸手带你手算AES
|
并行计算 算法 搜索推荐
简单学习一下AES算法:GCM、ECB、CFB、OFB等
简单学习一下AES算法:GCM、ECB、CFB、OFB等
2357 0
|
算法 数据安全/隐私保护
【密码学】一文读懂Whirlpool
首先呢,祝大家今晚节日快乐,Whirlpool是由Vincent Rijmen(高级加密标准的联合创始人)和Paulo S.L.M.Barreto设计的,后者于2000年首次提出了它。
1593 0
【密码学】一文读懂Whirlpool
|
存储 算法 数据安全/隐私保护
【密码学】一文读懂白盒AES(Chow方案)(一)
本文主要参考了文献^[1], 代码参考了^[2], 这里感谢文献作者和代码作者,如果有能力的大佬,可以自行查看原文献,个人水平有限,有哪里写的不对的地方,也欢迎读者指正。
4843 0
【密码学】一文读懂白盒AES(Chow方案)(一)
|
算法 安全 Go
【密码学】一文读懂HKDF
我这又来水一篇文章,来聊一下HKDF(基于HMAC的密钥导出函数)。密钥派生函数是密钥管理的组成部分,他的目标是通过一些初始的数据派生出来密码学安全的随机密钥。
3882 1
【密码学】一文读懂HKDF