复习一下。顺便配合最近稍微看过的SSE指令来看看优化后的代码是啥样的。
RC4流密码
数据定义
1 | BYTE S[256]; |
初始化
初始化S盒
S中元素的值按升序被置为0-255
$$
S[i]\ =\ i,\ i=0,\ 1,\ 2,…,\ 255
$$
初始化T盒
同时建立一个临时向量T。
将密钥的值循环复制到T向量中。
$$
T[i]\ =\ K[i\ mod\ len(key)],\ i=0,\ 1,\ 2,…,\ 255
$$
通常和S盒的初始化在一个For循环中。
合在一起就是:
1 | for i in range(256): |
排列S盒
用T产生S的初始置换
1 | j = 0; |
特点:
- 索引
j
使用S盒,T盒来更新自身 - 模256
- S盒内部交换
具体啥原理我就不理解了,反正这种S盒替换属于比较非线性的操作了。
生成密钥流
1 | i = 0; |
Data
应该就是输入的明文了。这里直接与明文异或,实现了加密。
解密
由于是对称流密码,所以加解密流程一样。相应的输入的数据要换成密文即可。
C语言
1 | //程序开始 |
实验发现,即使在msvc Release
版本中,循环也没有进行任何优化。
部分优化
尝试了一下写了一个SSE的demo。
1 |
|
暂时只写了一个很简单的初始化S盒,因为后面的话感觉优化挺难的,还是逐字节操作可能比较灵活。(所以这玩意速度真的快嘛?)
实际编译后会直接展开for
循环。
1 | v5[0] = (__int128)_mm_load_si128((const __m128i *)&xmmword_140002290); |
从而增加了不少空间,但显然也加快了少许执行速度。
注意
关于数据结构
- 明文长度 == 密钥流长度 == 密文长度
- S盒大小:256字节
- T盒大小:256字节
- 密钥K:(注意区别于密钥流)通常是16字节,可以是1-256字节。
关于算法特征
- 排列S盒与生成密钥流时皆有交换
for
循环跑256次- 没有硬编码常量,故无法直接
FindCrypt
安全性
已经不太安全了,有针对破解算法。
参考
https://zh.wikipedia.org/wiki/RC4
Intel 向量指令集完全版
https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#
- 本文作者: Taardis
- 本文链接: https://taardisaa.github.io/2022/03/10/RC4/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!