【发布时间】:2013-01-12 11:54:25
【问题描述】:
我做了一个小型测试基准,比较了 .NET 的 System.Security.Cryptography AES 实现与 BouncyCastle.Org 的 AES。
GitHub 代码链接:https://github.com/sidshetye/BouncyBench
我对 AES-GCM 特别感兴趣,因为它是一种“更好”的加密算法,而 .NET 缺少它。我注意到,虽然 .NET 和 BouncyCastle 之间的 AES 实现非常相似,但 GCM 性能却很差(请参阅下面的额外背景了解更多信息)。我怀疑这是由于许多缓冲区副本或其他原因。为了深入了解,我尝试分析代码(VS2012 => Analyze 菜单栏选项 => Launch performance wizard)并注意到 mscorlib.dll 中有很多 CPU 烧毁
问题:在这种情况下,我如何才能弄清楚是什么占用了大部分 CPU? 现在我所知道的只是“Init() 中的一些行/调用在 mscorlib.ni.dll 中消耗 47% 的 CPU” - 但不知道具体是哪些行,我不知道在哪里(尝试和)优化。有什么线索吗?
额外背景:
基于 David A. McGrew 的“The Galois/Counter Mode of Operation (GCM)”论文,我读到“二进制域中的乘法可以使用多种时间-内存权衡。它可以在不依赖密钥的内存的情况下实现,在这种情况下,它的运行速度通常比 AES 慢几倍。愿意牺牲适度内存的实现可以轻松实现 比 AES 更高的速度.”
如果您查看结果,基本的 AES-CBC 引擎性能非常相似。 AES-GCM 添加 GCM 并在 CTR 模式下重用其下方的 AES 引擎(比 CBC 更快)。但是,GCM 除了 CTR 模式外,还在 GF(2^128) 字段中添加了乘法,因此可能存在其他减速区域。无论如何,这就是我尝试分析代码的原因。
对于感兴趣的人,我的快速测试性能基准在哪里。它位于 Windows 8 VM 和 YMMV 中。该测试是可配置的,但目前它是在加密数据库的许多单元格时模拟加密开销(=> 很多但很小的明文输入)
Creating initial random bytes ...
Benchmark test is : Encrypt=>Decrypt 10 bytes 100 times
Name time (ms) plain(bytes) encypted(bytes) byte overhead
.NET ciphers
AES128 1.5969 10 32 220 %
AES256 1.4131 10 32 220 %
AES128-HMACSHA256 2.5834 10 64 540 %
AES256-HMACSHA256 2.6029 10 64 540 %
BouncyCastle Ciphers
AES128/CBC 1.3691 10 32 220 %
AES256/CBC 1.5798 10 32 220 %
AES128-GCM 26.5225 10 42 320 %
AES256-GCM 26.3741 10 42 320 %
R - Rerun tests
C - Change size(10) and iterations(100)
Q - Quit
【问题讨论】:
-
嗨 Sid,我是 BC .NET lib 的首席开发人员,非常欢迎这种基准测试。我克隆了您的 GitHub 代码,但似乎缺少一个类 (TestResult.cs)。同时,我建议您从 CVS 获取最新版本的代码,因为自 1.7 发布以来,AES 速度有了一些小改进,GCM 模式也有了一些重大改进。如果您想在这方面改进您的测试用例,BC 实现了 McGrew 论文中讨论的时间内存权衡的几种变体(请参阅 GcmBlockCipher 的备用构造函数来配置)。
-
嘿彼得,GitHub 的默认 .gitignore 让我明白了。我已经解决了这个问题,并且还移到了 CVS 存储库的顶部。一些改进,但在小尺寸上 AES-GCM 仍然大大落后于 AES-CBC。 github.com/sidshetye/BouncyBench 现在一切正常。感谢您的兴趣!
-
Sid,你解决了一些问题吗?我拉了你的板凳,它似乎比上面的要快得多。当我在你的板凳上运行dottrace 时,
Decrypt中的 GCM 几乎一直是Org.BouncyCastle.Crypto.Modes.Gcm.Tables8kGcmMultiplier.Init(Byte[])和Encrypt是Org.BouncyCastle.Crypto.Modes.GcmBlockCipher.DoFinal(Byte[], Int32)这为什么它比小尺寸字节数组的 CBC 慢是有道理的,因为它是可能会在更大尺寸上摊销的额外工作。 -
嗯,有趣的是,我只是注意到,当我进行 dottrace 分析时,它会比 AES-GCM 显着降低其他加密方法的速度,因此它在相对时间差异上更加平衡。
标签: encryption profiling bouncycastle