11

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 1.50.0.0
The elliptic curve used: 224 bit, secp224r1
ECC signature: SHA256 with ECDSA
RSA 2048 signature: SHA1 with RSA

R1w
  • 1,952
  • 4
  • 20
  • 45
OnTarget
  • 453
  • 4
  • 11
  • 1
    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. – mikeazo May 13 '14 at 14:01
  • 2
    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. – Maarten Bodewes May 13 '14 at 14:44
  • 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. – mikeazo May 13 '14 at 14:49
  • 1
    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 – fgrieu May 13 '14 at 15:46
  • 3
    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. – mikeazo May 13 '14 at 17:41
  • @mikeazo Agreed… retracted close-vote accordingly. – e-sushi May 14 '14 at 02:40
  • Concerning different hash algorithm: we've tested it and it turned out to have no influence on the outcome (at least for the small number that was signed). – OnTarget May 14 '14 at 11:30
  • About the provider: that's Spoungy Castle in both cases. – OnTarget May 14 '14 at 11:30
  • You may find this paper useful, which speaks to a perf test done by Samsung on ECC: https://koclab.cs.ucsb.edu/teaching/ecc/project/2015Projects/Cenar+Sebastian.pdf – Nik Feb 19 '17 at 11:55
  • @R1w You have submitted a series of minor grammar changes (and in fact, not improvements) to very old posts. In particular, please don't edit text that is directly quoted from other sources. Please stop. – Mike Ounsworth Jan 21 '21 at 17:06
  • @fgrieu want to draw your attention to the series of edits by R1w (see my previous comment) – Mike Ounsworth Jan 21 '21 at 17:08

1 Answers1

8

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.

CodesInChaos
  • 24,841
  • 2
  • 89
  • 128
  • Do you know if BouncyCastle uses BigInteger or some sort of native large integer library? – mikeazo May 13 '14 at 17:21
  • @mikeazo It uses its own BigInteger library. But even with pure java code you can get much better performance. – CodesInChaos May 13 '14 at 17:30
  • 2
    Hmm, interesting as they are currently trying to get FIPS approval. – Maarten Bodewes May 13 '14 at 20:15
  • Thanks for you comments/answers! @CodesInChaos, do you suggest that it would have been more efficient to implement ECDSA using "pure Java Code"? For this, however, some additional BigInteger-like library would be necessary, right? Or am I missing something... Have you done something similar already? – OnTarget May 14 '14 at 11:25
  • 1
    @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#. – CodesInChaos May 14 '14 at 11:33
  • 1
    @CodesInChaos Thanks a lot for you feedback, as soon as I have the ECC benchmark you suggested tested, I'll post the results – OnTarget May 14 '14 at 11:40