// Optimized Speck Encryption Algorithm for 8-bit Microcontrollers
#include <Arduino.h>
#define SPECK_ROUNDS 26 // Number of rounds for SPECK-64/96
#define SPECK_WORD_SIZE 32 // Word size in bits for SPECK-64/96
typedef uint32_t word_t; // Use 32-bit words
// Rotate right
inline word_t rotate_right(word_t x, uint8_t r) {
return (x >> r) | (x << (SPECK_WORD_SIZE - r));
}
// Rotate left
inline word_t rotate_left(word_t x, uint8_t r) {
return (x << r) | (x >> (SPECK_WORD_SIZE - r));
}
// Key schedule for SPECK-64/96
void speck_key_schedule(const word_t key[2], word_t round_keys[SPECK_ROUNDS]) {
word_t b = key[0], a = key[1];
round_keys[0] = b;
for (uint8_t i = 0; i < SPECK_ROUNDS - 1; i++) {
b = (rotate_right(b, 8) + a) ^ i;
a = rotate_left(a, 3) ^ b;
round_keys[i + 1] = b;
}
}
// Encrypt a plaintext block with SPECK-64/96
void speck_encrypt(const word_t plaintext[2], word_t ciphertext[2], const word_t round_keys[SPECK_ROUNDS]) {
word_t left = plaintext[0], right = plaintext[1];
for (uint8_t i = 0; i < SPECK_ROUNDS; i++) {
left = (rotate_right(left, 8) + right) ^ round_keys[i];
right = rotate_left(right, 3) ^ left;
}
ciphertext[0] = left;
ciphertext[1] = right;
}
// Decrypt a ciphertext block with SPECK-64/96
void speck_decrypt(const word_t ciphertext[2], word_t plaintext[2], const word_t round_keys[SPECK_ROUNDS]) {
word_t left = ciphertext[0], right = ciphertext[1];
for (int8_t i = SPECK_ROUNDS - 1; i >= 0; i--) {
right = rotate_right(right ^ left, 3);
left = rotate_left((left ^ round_keys[i]) - right, 8);
}
plaintext[0] = left;
plaintext[1] = right;
}
void setup() {
Serial.begin(9600);
word_t key[2] = {0x19181716, 0x15141312}; // 64-bit key (8 bytes)
word_t round_keys[SPECK_ROUNDS];
speck_key_schedule(key, round_keys);
word_t plaintext[4] = {0x3B726574, 0x7475432D, 0x54686520, 0x506C6169}; // 16 bytes
word_t ciphertext[4];
word_t decrypted[4];
Serial.println("Original Plaintext:");
for (uint8_t i = 0; i < 4; i++) {
Serial.print("Block "); Serial.print(i); Serial.print(": 0x"); Serial.println(plaintext[i], HEX);
}
for (uint8_t i = 0; i < 2; i++) {
speck_encrypt(&plaintext[2 * i], &ciphertext[2 * i], round_keys);
}
Serial.println("\nCiphertext:");
for (uint8_t i = 0; i < 4; i++) {
Serial.print("Block "); Serial.print(i); Serial.print(": 0x"); Serial.println(ciphertext[i], HEX);
}
for (uint8_t i = 0; i < 2; i++) {
speck_decrypt(&ciphertext[2 * i], &decrypted[2 * i], round_keys);
}
Serial.println("\nDecrypted Plaintext:");
for (uint8_t i = 0; i < 4; i++) {
Serial.print("Block "); Serial.print(i); Serial.print(": 0x"); Serial.println(decrypted[i], HEX);
}
}
void loop() {
// No repeated action
}