Electronic – Encrypting/Decrypting messages with Elliptic Curves in Arduino

eccencryption

Is there any possibility to encrypt/decrypt messages using only Elliptic Curves Algorithms? I found this library ECC Arduino library but it only generates numbers, there is no function for encrypting/decrypting.

I am thinking, maybe it is not possible to encrypt/decrypt messages with only using ECC? Maybe I need AES or any other encryption library too? I don't know. That is why I am asking this here.

I compiled the test code of this library:

#include <uECC.h>

extern "C" 
{
    int RNG(uint8_t *dest, unsigned size) 
    {
        // Use the least-significant bits from the ADC for an unconnected pin (or connected to a source of 
        // random noise). This can take a long time to generate random data if the result of analogRead(0) 
        // doesn't change very frequently.
        while (size) 
        {
            uint8_t val = 0;
            for (unsigned i = 0; i < 8; ++i) 
            {
                int init = analogRead(0);
                int count = 0;
                while (analogRead(0) == init) 
                {
                    ++count;
                }
                if (count == 0) 
                {
                    val = (val << 1) | (init & 0x01);
                } 
                else 
                {
                    val = (val << 1) | (count & 0x01);
                }
            }
            *dest = val;
            ++dest;
            --size;
        }
        // NOTE: it would be a good idea to hash the resulting random data using SHA-256 or similar.
        return 1;
    }
}  // extern "C"

void setup() 
{
    Serial.begin(115200);
    Serial.print("Testing ecc\n");
    uECC_set_rng(&RNG);
}

void loop() 
{
    const struct uECC_Curve_t * curve = uECC_secp160r1();
    uint8_t private1[21];
    uint8_t private2[21];

    uint8_t public1[40];
    uint8_t public2[40];

    uint8_t secret1[20];
    uint8_t secret2[20];

    unsigned long a = millis();
    uECC_make_key(public1, private1, curve);
    unsigned long b = millis();

    Serial.print("Made key 1 in "); Serial.println(b-a);
    a = millis();
    uECC_make_key(public2, private2, curve);
    b = millis();
    Serial.print("Made key 2 in "); Serial.println(b-a);

    a = millis();
    int r = uECC_shared_secret(public2, private1, secret1, curve);
    b = millis();
    Serial.print("Shared secret 1 in "); Serial.println(b-a);
    if (!r) 
    {
        Serial.print("shared_secret() failed (1)\n");
        return;
    }

    a = millis();
    r = uECC_shared_secret(public1, private2, secret2, curve);
    b = millis();
    Serial.print("Shared secret 2 in "); Serial.println(b-a);
    if (!r) 
    {
        Serial.print("shared_secret() failed (2)\n");
        return;
    }

    if (memcmp(secret1, secret2, 20) != 0) 
    {
        Serial.print("Shared secrets are not identical!\n");
    } 
    else 
    {
        Serial.print("Shared secrets are identical\n");
    }
}

It gives me this output:

Testing ecc
Made key 1 in 1108
Made key 2 in 1107
Shared secret 1 in 1096
Shared secret 2 in 1101
Shared secrets are identical 

and the RAM it uses is 566 bytes (6%) and 9846 bytes (3%) of flash, running on Arduino MEGA 2560 R3

Thank you

Best Answer

The library you're using implements ECDH and ECDSA. These are key agreement and signature algorithms (respectively) -- they cannot be used directly to encrypt messages.

To encrypt a message to a known public key, one can use ECIES:

  • Generate a new, ephemeral EC key pair (uECC_make_key())
  • Use ECDH ( uECC_shared_secret()) with the private component of that key pair and the known public key to generate a shared secret.
  • Use a key derivation function to turn that shared secret into a key for a symmetric encryption algorithm. (Neither of these components is implemented in micro-ecc.)
  • Use that symmetric key to encrypt your message.
  • Transmit the message along with the public component of the ephemeral key, then discard the ephemeral key.
  • The recipient can use ECDH with its private key and the public component of the ephemeral key to recreate the same shared secret, then use the KDF to decrypt the message.