De momento estoy usando Arduino Uno (Atmega328) y había reciclado un DES https://es.wikipedia.org/wiki/Data_Encryption_Standard que usé en otro proyecto (librería de arduino http://spaniakos.github.io/ArduinoDES) pero como voy justo de memoria y tiempo de ciclo pensé en mejorarlo.
Valoré un AES https://es.wikipedia.org/wiki/Advanced_ ... n_Standard del que también tengo librería para arduino https://github.com/DavyLandman/AESLib pero ocupaba demasiado espacio en flash.
Entonces me encuentro la sorpresa, viendo avr-crypto-lib un listado de algoritmos para micros AVR de atmel, veo que existe uno llamado XTEA y su mejora XXTEA https://en.wikipedia.org/wiki/XXTEA muy sencillos de implementar y pensados para dispositivos embebidos!!
Después de un cortapega de la wikipedia y de machacar el teclado he dejado el algorítmo bastante óptimo para Arduino (he visto un par de librerías ya hechas pero son un calco de la publicación original y no aportan mejoras).
Un arduino Uno a 16Mhz tarda en cifrar y descifra un bloque de 64 bytes:
Con DES en modo CBC tarda 284568us y ocupa 2572 bytes de flash
Con XTEA en modo CBC tarda 11008us y ocupa 916 bytes de flash
Con XXTEA tarda 4168us y ocupa 1086 bytes de flash
O sea que es rapidísimo y pequeñito...
La KEY es de 128 bits (mejor que el DES que solo es de 56) aceptable para mi aplicación. Se conocen ataques pero se basan en usar mas de 2^59 "textos planos escogidos", también aceptable!!
El código es extremadamente sencillo, la única desventaja es que sobreescribe los datos planos con los datos encriptados:
Código: Seleccionar todo
#define DELTA 0x9E3779B9
#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((Sum^y) + (Key[(WordCount&3)^KeyIdx] ^ z)))
// =================================================================================
// Cifrador XXTEA (Tiny Encryption Algorithm) Key = 128 bits, 16 bytes
// Blocks = bloques de 32bit, 64 bits min (Blocks = 2)
// https://en.wikipedia.org/wiki/XXTEA
// (c) Heli Tejedor, helitp@gmail.com, Junio 2017
// Licencia Creative Commons 3.0 Reconocimiento, No Comercial, Compartir Igual (CC BY-NC-SA 3.0)
// =================================================================================
void XxteaEncrypt (uint32_t *Data, uint8_t Blocks, uint32_t const Key[4])
{
uint32_t y, z, Sum;
uint8_t WordCount, Rounds, KeyIdx;
Rounds = 6 + 52/Blocks;
Sum = 0;
z = Data[Blocks-1];
do
{
Sum += DELTA;
KeyIdx = ((uint8_t)Sum >> 2) & 3;
for (WordCount = 0; WordCount < Blocks-1; WordCount++)
{
y = Data[WordCount+1];
z = Data[WordCount] += MX;
}
y = Data[0];
z = Data[Blocks-1] += MX;
} while (--Rounds);
}
// =================================================================================
// Descrifrador XXTEA (Tiny Encryption Algorithm) Key = 128 bits, 16 bytes
// =================================================================================
void XxteaDecrypt (uint32_t *Data, uint8_t Blocks, uint32_t const Key[4])
{
uint32_t y, z, Sum;
uint8_t WordCount, Rounds, KeyIdx;
Rounds = 6 + 52/Blocks;
Sum = Rounds*DELTA;
y = Data[0];
do
{
KeyIdx = (Sum >> 2) & 3;
for (WordCount = Blocks-1; WordCount > 0; WordCount--)
{
z = Data[WordCount-1];
y = Data[WordCount] -= MX;
}
z = Data[Blocks-1];
y = Data[0] -= MX;
Sum -= DELTA;
} while (--Rounds);
}
Código: Seleccionar todo
#define MYDATA 64
uint8_t Plain[MYDATA] = {"0123456789012345abcdefghijklmnopABCDEFGHIJKLMNOP-.,_:;?=)(/&%$!"};
uint8_t XteaKey[16] = {0xF3, 0xD5, 0x36, 0x32, 0x13, 0x12, 0x34, 0x56, 0xF4, 0xD5, 0xB6, 0x3F, 0x53, 0x15, 0x64, 0x56 };
XxteaEncrypt ((uint32_t*)Plain, MYDATA/4, (uint32_t*)XteaKey);
XxteaDecrypt ((uint32_t*)Plain, MYDATA/4, (uint32_t*)XteaKey);