3

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

SamGibson
  • 17,231
  • 5
  • 37
  • 58
  • 1
    Do you have **any** example of code that does the kind of encryption you want? If so, compile it for the architecture of your choice and tell us how big it is and how much RAM it needs. If not, then your question belongs on another site. – Elliot Alderson Jul 28 '19 at 19:03
  • 1
    I have no problem to migrate my question to another field site of stackoverflow, more appropriate... – just_learning Jul 28 '19 at 19:05
  • This sort of question doesn't really fit the stack exchange mission. Can it be done? Yes, unless you run out of memory. But how to do it is a search for an off-site tutorial or example, which is out of scope. – Chris Stratton Jul 28 '19 at 19:14
  • 2
    Before designing a product with encryption, you really should read a practical book about encryption. I recommend *Applied Cryptography* by Bruce Schneier. He will convince you that any home-grown technique will almost certainly be weak. – Mattman944 Jul 28 '19 at 20:09
  • 1
    I agree with @Mattman944 Bruce is THE best and so was his Two-Fish AEC2000 submission that came in 2nd. Ha, I remember we used the Apple IIe's Random function and it only addressed a few thousand repeating sectors on the disk, so we had to hash it. or maybe that was Salting it. Which was early 80's HDD test software to verify BER on DMA cartridge drives. Bruce S. is one of my security heroes. https://www.schneier.com/crypto-gram/ – Tony Stewart EE75 Jul 28 '19 at 21:02
  • 1
    His latest post explains why China will win the AI arms race and dominate the next century – Tony Stewart EE75 Jul 28 '19 at 21:09
  • 2
    @Mattman944 I would **not** recommend _Applied Cryptography_ anymore. It's 25 years old, and is consequently rather dated. –  Jul 29 '19 at 02:06

2 Answers2

1

That is a public/private key algorithm. As it is a quite slow operation (takes 1 second to perform each of the calculations on the AVR), it is usually used to exchange secret encryption keys between two systems or cryptographically "sign" data. In key exchange, it is used so that each device must only know it's own private key and the public key of the other device to calculate the same shared secret. This shared secret can then be used as encryption key to a faster symmetrical encryption algorithm used to actually encrypt and decrypt data. So basically, it is not an encryption algorithm itself, just an algorithm used to exchange encryption keys. This kind of reads in the uECC library header as well.

Justme
  • 127,425
  • 3
  • 97
  • 261
1

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.