贡献者:李岱耕
目录:
在此目录下执行以下命令:
clang++ birthday_attack.cpp -std=c++2a -o birthday_attack.exe -O3
./birthday_attack.exe
注:修改 birthday_attack.cpp 中 hash_size
的值可改变 hash 函数的输出字节数,例如,将 hash_size
设置为 6
即可测试针对 48 位简化 SM3 算法(即只保留原始 SM3 算法输出的前 48 位)的生日攻击。
生日攻击所利用的是概率论中生日问题的数学原理。定义一字典 D,其键值表示某一消息的哈希值,内容是原始消息。依次对不同消息计算哈希值,然后判断哈希值在字典中是否已经存在,若存在,则输出当前消息以及字典中的哈希值所对应的消息,否则将该哈希值与消息本身存入字典中,继续计算。该算法的时间复杂度和空间复杂度均为
针对 32 位简化 SM3 算法的生日攻击,在 O3 优化下单次攻击平均耗时约 30 ms, 最大内存占用量 4.7 MB.
针对 48 位简化 SM3 算法的生日攻击,在 O3 优化下单次攻击耗时 12 s, 最大内存占用量 1.3 GB.
针对 64 位简化 SM3 算法的生日攻击,在 O3 优化下单次攻击耗时间约 40 min, 最大内存占用量约 90 GB.
在此目录下执行以下命令:
clang++ rho_method.cpp -std=c++2a -o rho_method.exe -O3
./rho_method.exe
注:修改 rho_method.cpp 中 hash_size
的值可改变 hash 函数的输出字节数,例如,将 hash_size
设置为 8
即可测试针对 64 位简化 SM3 算法(即只保留原始 SM3 算法输出的前 64 位)的 Rho Method 攻击。
注:该算法对原始 Rho Method 攻击进行了部分修改和优化。
考虑数列
令变量
伪代码如下:
func get_rho(seed):
i = seed
for n = 1, 2, 4, 8, ...:
t = i
for rho = 1 .. n:
i = hash(i)
if i == t:
return rho
func rho_method(seed):
rho = get_rho(seed)
x = y = seed
for i = 1 .. rho:
y = hash(y)
while 1:
if hash(x) == hash(y):
return x, y
x = hash(x)
y = hash(y)
Rho Method 攻击的时间复杂度为
针对 32 位简化 SM3 算法的 Rho Method 攻击,经测试在 O3 优化下单次攻击耗时约 30 ms:
针对 64 位简化 SM3 算法的 Rho Method 攻击,在 O3 优化下单次攻击耗时约 18 min:
针对 72 位简化 SM3 算法的 Rho Method 攻击,在 O3 优化下单次攻击耗时约 13 h:
在此目录下执行以下命令:
clang++ length_extension_attack.cpp -std=c++2a -o length_extension_attack.exe -O3
./length_extension_attack.exe
先通过 SM3 算法计算出信息 a = "ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
对应的哈希值 Ha
, 对其进行长度扩展攻击,扩充一段信息 b = "0123456789"
并计算出新的哈希值 Hb
, 然后与直接计算 c = a || padding || b
得到的哈希值 Hc
进行比较验证。
在此目录下执行以下命令:
clang++ sm3_test.cpp -std=c++2a -o sm3_test.exe -O3
./sm3_test.exe test_file
-
使用了查表优化,提前计算出 K 循环移位的结果,减少了在程序运行过程中对 K 进行循环移位所消耗的时间。
-
调整了一些运算的次序,减少重复计算。
经测试,优化后的算法在 O3 优化下计算 1 GB 文件的哈希值耗时约 3.8 s,使用 GmSSL 中的算法则需要约 10s.
依据协议 RFC6962 实现 Merkel 树,构造具有 10w 叶节点的 Merkle 树,可以对指定元素构建包含关系的证明,可以对指定元素构建不包含关系的证明。
在此目录下执行以下命令:
clang++ merkle_tree.cpp -std=c++2a -o merkle_tree.exe -O3
./merkle_tree.exe
创建 MerkleTree
类,通过递归实现其创建和遍历,验证某一元素是否存在时,先通过遍历找到其对应的叶子节点,若未找到则证明不存在,否则依次验证该叶子节点每个父节点是否正确,如果全部正确则证明存在,否则返回异常。