ECDH-Curve25519-Mobile: Elliptic Curve Diffie-Hellman Key Exchange for Android Devices with Curve 25519

tl;dr

ECDH-Curve25519-Mobile implements Diffie-Hellman key exchange based on the Elliptic Curve 25519 for Android devices. It is released into the public domain and available through GitGub.

How I came across Curve 25519 … and the problem to be solved

Recently, I had to implement Diffie-Hellman key exchange for an Internet of Things (IoT) application, namely, a smart door lock (more about this later in another post). This system consists of a low-power embedded device featuring an ARM Cortex M0 microcontroller communicating via Bluetooth Low-Energy (BLE) with an Android app.

First, I had some doubts whether compute-intensive asymmetric cryptography could be implemented efficiently on a weak ARM Cortex M0. However, then I came across the Curve 25519, an elliptic curve proposed by Daniel J. Bernstein for Elliptic Curve Diffie-Hellman (ECDH) key exchange. In addition to the fact that Curve 25519 can be implemented very efficiently, there exists an implementation targeting ARM Cortex M0 from the Micro NaCl project. So I gave this implementation a try, and it turned out to be really fast.

So I decided to use ECDH with Curve 25519 for my IoT system. Thanks to Micro NaCl, the part for the microcontroller was implemented very quickly. However, I also needed an implementation for Android. My first thought was to use the popular Bouncy/Spongy Castle crypto library. However, it turned out that although they come with a definition of Curve 25519, they use a different elliptic curve representation, namly, the Weierstrass form rather than the Montgomery form used by NaCl. One option would have been to convert between the two representations, but to me it seemed less intuitive to convert the Montgomery curve back and forth when I could stick to one representation.

So the problem was now to find a Curve 25519 implementation for Android using the Montgomery form. And that was not so easy. So I finally decided to take the code from the NaCl project and make it accessible to the Android world. And the result is ECDH-Curve25519-Mobile.

What is ECDH-Curve25519-Mobile?

ECDH-Curve25519-Mobile implements Diffie-Hellman key exchange based on the Elliptic Curve 25519 for Android devices.

ECDH-Curve25519-Mobile is based on the NaCl crypto implementation, more specifically AVRNaCl, written by Michael Hutter and Peter Schwabe, who dedicated their implementation to the public domain. ECDH-Curve25519-Mobile follows their example and also dedicates the code to the public domain using the Unlicense. Actually, the core of ECDH-Curve25519-Mobile is NaCl code, and ECDH-Curve25519-Mobile is just a simple JNI (Java Native Interface) wrapper around it to make it accessible from Java on Android devices. So I gratefully acknowledge the work of the NaCl team and their generous dedication of their code to the public domain!

ECDH-Curve25519-Mobile is a native Android library since NaCl is implemented in C rather than Java. However, it can be easily compiled for all Android platforms like ARM or x86, so this is not a practical limitation compared to a Java implementation. The decision to base ECDH-Curve25519-Mobile on NaCl was not so much the performance you can gain from a native implementation—actually AVRNaCl leaves some room for performance improvements since it originally targeted 8 bit microcontrollers—, but using an implementation from crypto experts who actually work together with Daniel J. Bernstein as the inventor of Curve 25519.

How to use it?

I do not want to repeat everything already said in the description of ECDH-Curve25519-Mobile available at GitHub. Let me just show you some code to give you an impression that it is really easy to use from within your Android app:

// Create Alice's secret key from a big random number.
SecureRandom random = new SecureRandom();
byte[] alice_secret_key = ECDHCurve25519.generate_secret_key(random);
// Create Alice's public key.
byte[] alice_public_key = ECDHCurve25519.generate_public_key(alice_secret_key);

// Bob is also calculating a key pair.
byte[] bob_secret_key = ECDHCurve25519.generate_secret_key(random);
byte[] bob_public_key = ECDHCurve25519.generate_public_key(bob_secret_key);

// Assume that Alice and Bob have exchanged their public keys.

// Alice is calculating the shared secret.
byte[] alice_shared_secret = ECDHCurve25519.generate_shared_secret(
    alice_secret_key, bob_public_key);

// Bob is also calculating the shared secret.
byte[] bob_shared_secret = ECDHCurve25519.generate_shared_secret(
    bob_secret_key, alice_public_key);

More details can be found on the ECDH-Curve25519-Mobile project page at GitHub. Hope to see you there!