Hi Sid,
I've made an initial comment on your stackoverflow post, and perhaps it
would be best to just continue the discussion there, but a few comments
here for those interested.
It appears the 1.7 release was used, which would be expected to give
very poor results for many small encryptions with the same key. This is
almost certainly due to the precomputation that is done (the
key-dependent memory McGrew is referring to). Recent changes ensure the
precomputation is not repeated unless the key actually changed, but it
was previously done for every Init call.
The default precomputation is Tables8KGcmMultiplier, which is a fairly
good default choice. The Tables1K- or Tables64K- alternatives give
different tradeoffs, and might be considered for specific use cases. One
of the GcmBlockCipher constructors allows this to be configured.
The stackoverflow results use very small texts. It's not clear if you
made an equivalent test (to the OpenSSL one below) for BC with 10MB
file. I would be very surprised if BC is 18x slower than OpenSSL on a
single 10MB encryption (even with the 1.7 code)! That also sounds like a
case where the Tables64KGcmMultiplier might be worth the extra setup time.
Nevertheless if there are still performance issues, we'll be glad to
investigate them further.
Regards,
Pete Dettman
On 29/01/2013 10:44 AM, Sid Shetye wrote:
Hi guys,
I was seeing some very poor performance in AES-GCM mode. I tried
profiling the code but want into a wall (posted on stackoverflow at
http://stackoverflow.com/questions/14573972/code-profiling-to-improve-performance-see-cpu-cycles-inside-mscorlib-dll)
In particular, it seems that AES-GCM should be faster than AES-CBC; at
least based on literature:
"/The Galois/Counter Mode of Operation (GCM)/" paper by David A.
McGrew, I read "/Multiplication in a binary field can use a variety of
time-memory tradeoffs. It can be implemented with no key-dependent
memory, in which case it will generally run several times slower than
AES. Implementations that are willing to sacrifice modest amounts of
memory can easily realize///*/speeds greater than that of AES/*/./"
To test that theory, I tried the same on OpenSSL. I found AES-GCM is
about 2x the speed of AES-CBC. What I did was measure (100 times=>
average it)
·Time to only in invoking OpenSSL (=15ms)
·Time to OpenSSL AES-GCM encrypt a 10MB file (=32ms = > just encrypt =
17ms)
·Time to OpenSSL AES-CBC encrypt a 10MB file (=45ms => just encrypt =
30ms)
The code itself is rough but tiny -- listed at
https://gist.github.com/4661615.
This experiment seems to corroborate the theory in that paper. However
in BouncyCastle (C#, 1.7) I'm finding the opposite. AES-GCM is about
_18x slower_ compared to AES-CBC mode! Altogether, the difference is
about 2x fast in OpenSSL + 18x slow in BouncyCastle => 36x slow from
it's potential!
*Question: Does anyone know why that is the case? Is anyone interested
in poking deeper?*I think there might be a lot of room for
improvement. Unfortunately, I don't think I'm qualified to implement
any such improvement (not without substantial investment of time!)
Thanks
Sid