

Elliptic curve arithmetic and cryptography library in Rust - bren2013
https://github.com/Bren2010/ecc

======
nullc
Uh, users almost never want ElGamal encryption. It has a few interesting
applications, but its very easy to make insecure systems using it. Where it's
used it should be packaged up into a complete protocol that handles the
footgunnery.

This claims to have constant time operations, but the addition law is very
clearly not constant time:
[https://github.com/Bren2010/ecc/blob/master/src/curves.rs#L9...](https://github.com/Bren2010/ecc/blob/master/src/curves.rs#L93)
Likewise, the field operations are not constant time. Simply doing both the 1
and 0 path and throwing the other side out is not generally adequate to
achieve constant time behaviour when the underlying operations are variable
time (and also see, for example, the flush/reload attacks in the literature).

Also the field operations appear to be variable time. (So, it looks like the
inversions to convert back to affine would leak shared secret data for ECDH,
or information about the nonce in ECDSA.) It looks like the reduction in kinv
alone would likely leak log2(k^-1) pretty directly in timing, so if you could
capture some large number of signatures with a single key you could probably
recover it, potentially even remotely. (Not trying to be harsh here, OpenSSL
is just as bad for their generic code... but if someone is advertised as
constant time, it ought to meet the strongest definition of it since the
caller is not going to be a cryptographer and he's going to treat it as a
black box and inevitably use it in the most exploitable way possible. :) )

General question about rust: Is there any way to reliably write constant time
code in it? Or are you always at the mercy of the compiler undermining you?
E.g. happily unrolling loops, optimizing out dummy operations, and turning
branchless comparisons into branchy ones. (I wouldn't have expected that would
be, since there isn't really in C; unless you're able to audit the compiler
output ... and rust is even higher level).

~~~
bren2013
About ElGamal: Agreed. I only planned to implement it for my own satisfaction,
more than for anything else.

The addition law only leaks general cases--doubling, negatives, one argument
is zero. Is that not generally considered okay? Intuitively, it doesn't seem
like terribly valuable information--in the case of the Montgomery ladder, the
attacker already knows we do one doubling and one addition per bit.

Earlier, I was using Euler's theorem for inversions, which should have been
more constant-time than Euclid's algorithm. The only problem is, it took
slightly over a minute to do one scalar multiplication. Could you describe an
attack that would come from knowing information about the z-coordinate? Is
there a good way to do constant-time inversion?

Edit: I just added a second benchmark testing scalar multiplication for a
random value vs one with lots of zeros, and they produce different
distributions with or without the #[const_time] (assuming I'm using it right).
Thank you for bringing this up! I'll look into what needs tweaking.

~~~
bren2013
I missed my edit window...

I actually take the above back. Scalar multiplication on a point IS constant-
time (the two distributions are indistinguishable).

Field exponentiation isn't constant-time and I will work on that.

~~~
pbsd
The way your scalar multiplication is performed leaves you open to two
attacks:

\- Scalar multiplication _is_ variable-time, with the variation being
correlated with the position of the most significant bit of the exponent (see
[https://github.com/Bren2010/ecc/blob/bd75261b6fe7839ddc751d6...](https://github.com/Bren2010/ecc/blob/bd75261b6fe7839ddc751d680b9021adaa232957/src/curves.rs#L214)).
An attack like [1] on ECDSA seems plausible.

\- The Montgomery ladder uses different code paths depending on whether the
exponent bit is 0 or 1; this makes FLUSH+RELOAD attacks possible, as in [2].

[1] [https://eprint.iacr.org/2011/232](https://eprint.iacr.org/2011/232)

[2] [https://eprint.iacr.org/2014/140](https://eprint.iacr.org/2014/140)

~~~
bren2013
Issue #1: Yes, it's supposed to be like that. The point is that any n-bit
scalar takes the same amount of time as any other n-bit scalar.

Issue #2: Rust has explicitly taken all memory management away from me.
There's nothing I can do about that.

------
erickt
If anyone is interested in rust and cryptography, we have a meetup this
Thursday in San Francsico focused on it:

[http://www.meetup.com/Rust-Bay-
Area/events/210632582/](http://www.meetup.com/Rust-Bay-Area/events/210632582/)

We are currently full, but we are live streaming it on:

[https://air.mozilla.org/bay-area-rust-meetup-
december-2014/](https://air.mozilla.org/bay-area-rust-meetup-december-2014/)

We also have about 10-15 people unrsvp the day-of, so there is a chance spots
for free up between now and then.

------
indeyets
Do you plan to have implementation of DJB's curves/primitives?

~~~
bren2013
Not for a while. DJB's curves have entirely too much structure and I'd prefer
to get something general purpose working first.

I don't even like having to implement NIST's speedup for A = -3, and it's
fairly trivial.

