对称加密有两大类的算法。以AES、DES为代表的块加密(也叫分组加密)算法,和以ChaCha20、RC4为代表的流加密算法。ChaCha20 是 TLS 1.3 中唯一留存的流密码算法,用以替代已经不再安全的 RC4 算法。在执行效率方面,ChaCha20 在没有 AES 硬件优化的设备上速度可达其三倍,因此非常适用于移动设备。
算法原理
ChaCha20 的算法处理流程非常简单,主要分为两部分:
- 状态矩阵生成
- 20 轮状态变换
状态矩阵生成
将固定常量、密钥、计数器和随机数(或者叫 IV)按照如下方式排列组成矩阵:
0x61707865 | 0x3320646e | 0x79622d32 | 0x6b206574 |
---|---|---|---|
KEY | KEY | KEY | KEY |
KEY | KEY | KEY | KEY |
COUNTER | NONCE | NONCE | NONCE |
状态变换
这部分直接用代码说明:
#include <stdint.h>
#define ROTL(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) /* 循环左移 */
#define QR(a, b, c, d) ( \
a += b, d ^= a, d = ROTL(d, 16), \
c += d, b ^= c, b = ROTL(b, 12), \
a += b, d ^= a, d = ROTL(d, 8), \
c += d, b ^= c, b = ROTL(b, 7))
#define ROUNDS 20
void chacha_block(uint32_t out[16], uint32_t const in[16])
{
int i;
uint32_t x[16];
for (i = 0; i < 16; ++i)
x[i] = in[i];
// 10 loops × 2 rounds/loop = 20 rounds
for (i = 0; i < ROUNDS; i += 2) {
// Odd round
QR(x[0], x[4], x[ 8], x[12]); // column 1
QR(x[1], x[5], x[ 9], x[13]); // column 2
QR(x[2], x[6], x[10], x[14]); // column 3
QR(x[3], x[7], x[11], x[15]); // column 4
// Even round
QR(x[0], x[5], x[10], x[15]); // diagonal 1 (main diagonal)
QR(x[1], x[6], x[11], x[12]); // diagonal 2
QR(x[2], x[7], x[ 8], x[13]); // diagonal 3
QR(x[3], x[4], x[ 9], x[14]); // diagonal 4
}
for (i = 0; i < 16; ++i)
out[i] = x[i] + in[i];
}
此后便获得了 512 bit 的字节流,直接将明文与等长的字节流进行异或操作便可以得到密文。如果明文长度大于 512 bit,则将 counter 递增并生成新的字节流,直至字节流的长度大于明文长度。