For our privacy-preserving protocol, an encrypted channel is established. In order to protect our system from man-in-the-middle attacks, a signature-based approach is used. After we've implemented it with RSA, we decided to optimize the protocol a bit by using ECDSA. The result was very surprising: on Android, signing and verifying in the case of ECDSA was 10 times slower than for RSA with the corresponding key length!

Any viable explanation for this?

Maybe the android smartphones don't have hardware support for elliptic curves, and for RSA operations they do?

The exact parameters are below:

RSA:   signing: 52ms,  verifying:   6ms  
ECDSA: signing: 692ms, verifying: 975ms  

Smartphone: Samsung Galaxy S Advance, GT-I9070P with CPU: 1 GHz STE U8500 DualCore  
Crypto-lib: SpongyCastle  
The elliptic curve used: 224 bit, secp224r1  
ECC signature: SHA256 with ECDSA  
RSA 2048 signature: SHA1 with RSA 
  • 1
    $\begingroup$ Why are you using SHA256 with ECDSA and comparing that with SHA1 with RSA? You should be keeping the hash function constant between the two to make the comparison fair. I'd be curious to see how that changes your numbers. $\endgroup$ – mikeazo May 13 '14 at 14:01
  • 2
    $\begingroup$ Did you use the same providers for both? Try getProvider() on the signature. It may be that ECDSA ran as byte code using Spongy and that the other ran using OpenSSL in the background. Also, the hash algorithm gains in imporance the bigger the data. $\endgroup$ – Maarten Bodewes May 13 '14 at 14:44
  • $\begingroup$ To add to owlstead, BigInteger is really slow for certain operations. If the RSA code is not using BigInteger, but the ECDSA is, that would be your reason right there. $\endgroup$ – mikeazo May 13 '14 at 14:49
  • 1
    $\begingroup$ One real possibility is that RSA 2048 has a native provider (perhaps tied to the so-called hardware-backed keystore), while all the others are using BigInteger. See this useful answer and my confirmation comment $\endgroup$ – fgrieu May 13 '14 at 15:46
  • 3
    $\begingroup$ Initially I thought this should be considered off topic. After seeing CodesInChaos' answer, though, I'm not so sure. Yes it is about implementation, but it is more in the weeds of crypto than any other SE site (likely) cares about. Personally I'm okay with in-the-weeds implementation type questions. $\endgroup$ – mikeazo May 13 '14 at 17:41

BouncyCastle has a really bad ECC implementation. It uses affine coordinates which incur a huge performance hit (factor 20 or so) since it computes a field inversion after every single step. Good implementations use Jacobi coordinates (or a similar approach) where denominators are kept and there is only one field inversion at the end.

It's also potentially vulnerable to side channel attacks since it branches on secret data (only relevant to signing, not verification).

As another ECC benchmark you could look at the the ref10 branch of str4d/ed25519-java. This uses a different elliptic curve, Ed25519, but the main difference is that the implementation has been optimized more than the one you tested. But this is still new and experimental code, so be careful.

  • $\begingroup$ Do you know if BouncyCastle uses BigInteger or some sort of native large integer library? $\endgroup$ – mikeazo May 13 '14 at 17:21
  • $\begingroup$ @mikeazo It uses its own BigInteger library. But even with pure java code you can get much better performance. $\endgroup$ – CodesInChaos May 13 '14 at 17:30
  • 2
    $\begingroup$ Hmm, interesting as they are currently trying to get FIPS approval. $\endgroup$ – Maarten Bodewes May 13 '14 at 20:15
  • 1
    $\begingroup$ @user13397 My point is that the main reason for ECDSA being slow in your test is not that it's implemented in pure java, it's because the implementation has not been optimized. Native code usually results in a speedup, but a smaller one. I'd guess a good java implementation would be 50 times faster than your code and native code would result in a factor 2-3 speedup beyond the best possible java implementation. But I don't have java/android experience, so these are very rough guesses coming from my experience with writing crypto code in C#. $\endgroup$ – CodesInChaos May 14 '14 at 11:33
  • 1
    $\begingroup$ @CodesInChaos Thanks a lot for you feedback, as soon as I have the ECC benchmark you suggested tested, I'll post the results $\endgroup$ – OnTarget May 14 '14 at 11:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.