ChaCha20 - Salsa20学习笔记
前几天做 mcmc
遇到一个魔改的 Chacha20算法,顺便学一下,抄的这份博客 。
Chacha20 加密算法
算法简介
ChaCha20-Poly1305 是一种 认证加密 算法。 ChaCha20-Poly1305加密时无需硬件加速,而且加密速度通常比AES-GCM更快,所以某些 移动设备中会优先采用ChaCha20-Poly1305加密算法。ChaCha20-Poly1305由两部分组成,分别是Poly1305和ChaCha20。 —— 摘自【维基百科】
初始化矩阵
ChaCha20 加密的初始状态包括
- 一个128位常量(Constant),常量的内容为
0x61707865, 0x3320646e, 0x79622d32, 0x6b206574
- 一个256位密钥(Key)
- 一个64位计数(Counter)
- 一个64位随机数(Nonce)
一共64字节其排列成 4 * 4 的 32 位字矩阵如下所示:(实际运算为小端)
1 | 2 | 3 | 4 |
---|---|---|---|
Constant | Constant | Constant | Constant |
Key | Key | Key | Key |
Key | Key | Key | Key |
Pos | Pos | Nonce | Nonce |
1/4 轮操作
在ChaCha20算法当中,一个基础的操作即为1/4轮运算,它主要操作4个32位的无符号整数,具体操作如下:
代码如下:
1 | static void chacha20_quarterround(uint32_t *x, int a, int b, int c, int d) |
块函数
块函数输入是之前所生成的状态矩阵,最终输出64bit的”随机化”的字节块函数加密时分两种情况,一种是计数为奇数时,进行行变换,如下:
Original Matrix | Row Transform(Odd round) |
---|---|
x[0], x[1], x[2], x[3] |
x[0], x[4], x[8], x[C] |
x[4], x[5], x[6], x[7] |
x[1], x[5], x[9], x[D] |
x[8], x[9], x[A], x[B] |
x[2], x[6], x[A], x[E] |
x[C], x[D], x[E], x[F] |
x[3], x[7], x[B], x[F] |
为偶数的时候进行列变换,如下:
Original Matrix | Row Transform(Odd round) | Diagonal Transform(even round) |
---|---|---|
x[0], x[1], x[2], x[3] |
x[0], x[4], x[8], x[C] |
x[0], x[5], x[A], x[F] |
x[4], x[5], x[6], x[7] |
x[1], x[5], x[9], x[D] |
x[1], x[6], x[B], x[C] |
x[8], x[9], x[A], x[B] |
x[2], x[6], x[A], x[E] |
x[2], x[7], x[8], x[D] |
x[C], x[D], x[E], x[F] |
x[3], x[7], x[B], x[F] |
x[3], x[4], x[9], x[E] |
代码如下:
1 | static void chacha20_block(uint32_t in[16], uint8_t out[64], int num_rounds) |
再嫖一个完整的轮子
C语言实现
Chacha20.cpp
1 | # |
Chacha20.h
1 | # |
main.cpp
1 | # |
python 实现
1 | def main(): |
Salsa20 加密算法
其实Salsa20加密和ChaCha20特别相似,ChaCha20是对Salsa20上稍微做了调整,数据bit扩散更快。每一个1/4 round会修改一个字两次,每一个输入字也会影响到输出字。两种加密算法只有四分之一论操作有一点点不同:
ChaCha20是这样的:
1 | static inline uint32_t rotl32(uint32_t x, int n) { |
Salsa20则是这样的:
1 |
代码实现
C语言实现
1 |
|
python 实现
1 | class Salsa: |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 EPs1l0h's Castle!
评论