ChaCha20


文档:rfc8439(原RFC7539)

ChaCha20 is a stream cipher designed by Daniel J. Bernstein.

The secret key is 256 bits long (32 bytes).

The cipher requires a nonce, which must not be reused across encryptions performed with the same key.

Nonce lengthDescriptionMax dataIf random nonce and same key
8 bytes (default)The original ChaCha20 designed by Bernstein.No limitationsMax 200 000 messages
12 bytesThe TLS ChaCha20 as defined in RFC7539.256 GBMax 13 billions messages
24 bytesXChaCha20, still in draft stage.256 GBNo limitations

Message Authentication Code (such as HMAC) should be used to authenticate the ciphertext (encrypt-then-mac). Alternatively, ChaCha20_Poly1305 can be used.

1. Introduction

AES的问题:

  • 再优秀的算法也需要有备用替代算法;
  • 在有些平台还是慢;
  • cache-collision timing attacks ([Cache-Collisions]).

RFC 8439介绍了3种算法:

  • The ChaCha20 cipher
    • 软件实现效率是AES的3倍;
    • 可抵御timing attacks.
  • The Poly1305 authenticator, a high-speed MAC;
  • The CHACHA20-POLY1305 AEAD construction.

2. Allgorithms

2.1. The ChaCha Quarter Round

The basic operation of the ChaCha algorithm is the quarter round. It operates on four 32-bit unsigned integers, denoted a, b, c, and d.

#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);  \
}
// ROTL: 循环左移

The algorithm name is “ChaCha”. “ChaCha20” is a specific instance where 20 “rounds” or 80 quarter rounds

2.2. A Quarter Round on the ChaCha State

The ChaCha state does not have four integer numbers: it has 16. So the quarter-round operation works on only four of them – hence the name.

QUARTERROUND(1, 5, 9, 13);
0 *a 2 3
4 *b 6 7
8 *c 10 11
12 *d 14 15

this run of quarter round is part of what is called a “column round”.

2.3. The ChaCha20 Block Function

The ChaCha block function transforms a ChaCha state by running multiple quarter rounds.

uint8_t[64] /*keystream*/ BlockFunc(
    uint8_t key[32]		// 256 bits
    , uint8_t nonce[12]	// 96 bits
    , uint32_t  blockCount	// 32 bits
);

The original ChaCha had a 64-bit nonce and 64-bit block count. We have modified this here to be more consistent with recommendations in Section 3.2 of RFC 5116: An Interface and Algorithms for Authenticated Encryption.

Init

The ChaCha20 state is initialized as follows:

// 1
hash[0] = 0x61707865;
hash[1] = 0x3320646e;
hash[2] = 0x79622d32;
hash[3] = 0x6b206574;
// 2
// Move 256-bit/32-byte key into h[4..11]
for (i=0; i<8; i++) {
    hash[4+i] = u8to32_little(key + 4*i);
}

// hash[12] = block counter


hash[13] = u8to32_little(nonce);
hash[14] = u8to32_little(nonce + 4);
hash[15] = u8to32_little(nonce + 8);

/*
cccccccc cccccccc cccccccc cccccccc
kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk
kkkkkkkk kkkkkkkk kkkkkkkk kkkkkkkk
bbbbbbbb nnnnnnnn nnnnnnnn nnnnnnnn
*/

Pycryptodome src: Nonce must be 8/12 bytes(ChaCha20) or 24 bytes (XChaCha20)

Round

ChaCha20共20轮,4轮"column rounds" 和4轮"diagonal rounds"交替进行。

for (i=0; i<10; i++) {
    /** Column round **/
    QR(h[0], h[4], h[ 8], h[12]);
    QR(h[1], h[5], h[ 9], h[13]);
    QR(h[2], h[6], h[10], h[14]);
    QR(h[3], h[7], h[11], h[15]);
    /** Diagonal round **/
    QR(h[0], h[5], h[10], h[15]);
    QR(h[1], h[6], h[11], h[12]);
    QR(h[2], h[7], h[ 8], h[13]);
    QR(h[3], h[4], h[ 9], h[14]);
}

以上操作是在state副本上操作的,最后需要将原始值和新的值相加,小端存储为key stream作为输出,16个四字节hash,刚好64字节。

2.4. The ChaCha20 Encryption Algorithm

The ChaCha20 function then performs an XOR of this keystream with the plaintext.

There is no requirement for the plaintext to be an integral multiple of 512 bits. If there is extra keystream from the last block, it is discarded.

Specific protocols MAY require that the plaintext and ciphertext have certain length. Such protocols need to specify how the plaintext is padded and how much padding it receives.

实现

https://github.com/C0deStarr/CryptoImp/tree/main/Cipher/StreamCipher

  • chacha20.h
  • chacha20.c

参考资料

RFC 8439: ChaCha20 and Poly1305 for IETF Protocols (rfc-editor.org)

ChaCha20 and XChaCha20 — PyCryptodome 3.17.0 documentation

### ChaCha20 加密算法简介 ChaCha20 是一种基于 Salsa20 的流加密算法,由 Daniel J. Bernstein 设计。它通过改进 Salsa20 提高了性能并增强了安全性。其核心思想是利用伪随机数生成器来创建一系列字节序列,这些字节随后与明文数据进行 XOR 运算以完成加密或解密操作。 #### 算法结构概述 ChaCha20 使用一个 256 位的密钥、一个 96 位的 nonce 和一个 32 位的区块计数器作为输入参数[^1]。该算法的核心是一个四轮迭代的过程,在每一轮中都会执行一组固定的矩阵变换运算。最终输出的是一个长度为 512 位的状态向量,这个状态向量会被截取成所需的比特流并与消息异或得到加密后的结果。 #### IT 实现中的关键点 以下是关于如何在软件开发环境中实现 ChaCha20 的一些重要指导: ##### 初始化阶段 初始化过程中需要设置好初始状态矩阵,这包括填充常数值以及将密钥、nonce 及计数器按特定顺序放置到矩阵当中去。具体而言,标准定义了一组固定字符串用于占据部分位置以便于区分不同版本或者变体之间的差异[^2]。 ```python def initialize_state(key, nonce, counter=0): constants = [0x61707865, 0x3320646e, 0x79622d32, 0x6b206574] key_words = struct.unpack('I' * 8, key) state = constants[:] + list(key_words[:4]) + list(key_words[4:]) + [counter] + list(struct.unpack('I'*3, nonce)) return state ``` ##### 核心循环逻辑 对于每次调用都需要重复做十次双倍回合(即总共二十个单步),每一次都将当前状态复制一份出来再施加 Quarter Round 函数处理四个选定元素直到整个数组都被更新完毕为止[^3]。 ```python def quarter_round(x, a, b, c, d): x[a] ^= rol((x[b]+x[c]), 16) x[d] ^= x[a]; x[b] ^= rol((x[c]+x[d]), 12) x[a] ^= x[b]; x[c] ^= rol((x[d]+x[a]), 8) x[b] ^= x[c]; x[d] ^= rol((x[a]+x[b]), 7) x[c] ^= x[d]; def double_round(state): working_state = copy.deepcopy(state) # Column rounds for i in range(4): quarter_round(working_state,i,(i+4)%4,(i+8)%4,(i+12)%4) # Diagonal rounds for i in range(4): quarter_round(working_state,i,(i+5)%4,(i+10)%4,(i+15)%4) result = [(a+b)&0xFFFFFFFF for (a,b) in zip(state, working_state)] return result ``` ##### 输出生成 最后一步就是把经过多次转换之后的结果加上原始状态一起打包形成最终的 keystream 块,并将其转化为适合传输的形式比如十六进制编码串等等^. ```python def generate_keystream_block(initial_state): final_state = initial_state[:] for _ in range(10): final_state = double_round(final_state) output_bytes = bytearray() for word in final_state: packed_word = struct.pack('>I', word & 0xffffffff) output_bytes.extend(packed_word) return bytes(output_bytes) ``` ### 结论 综上所述,ChaCha20 不仅提供了强大的安全保障而且易于高效地部署在各种平台上。上述代码片段展示了基本构建模块及其组合方式从而实现了完整的加密功能.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值