Я попытался разместить реализацию NSA SPECK в 8-битном микроконтроллере PIC.
В бесплатной версии их компилятора (на основе CLANG) не будет разрешена оптимизация, поэтому мне не хватило памяти. Я попробовал "пробную" версию, которая включает -O2, -O3 и -Os (оптимизировать по размеру) С помощью -Os удалось разместить мой код в памяти программной области 2K.
Вот код:
#include <stdint.h>
#include <string.h>
#define ROR(x, r) ((x >> r) | (x << (32 - r)))
#define ROL(x, r) ((x << r) | (x >> (32 - r)))
#define R(x, y, k) (x = ROR(x, 8), x += y, x ^= k, y = ROL(y, 3), y ^= x)
#define ROUNDS 27
void encrypt_block(uint32_t ct[2],
uint32_t const pt[2],
uint32_t const K[4]) {
uint32_t x = pt[0], y = pt[1];
uint32_t a = K[0], b = K[1], c = K[2], d = K[3];
R(y, x, a);
for (int i = 0; i < ROUNDS - 3; i += 3) {
R(b, a, i);
R(y, x, a);
R(c, a, i + 1);
R(y, x, a);
R(d, a, i + 2);
R(y, x, a);
}
R(b, a, ROUNDS - 3);
R(y, x, a);
R(c, a, ROUNDS - 2);
R(y, x, a);
ct[0] = x;
ct[1] = y;
}
К сожалению, при отладке его построчно, сравнивая его с тестовыми векторами в руководстве по реализации со стр. 32, "15 тестовых векторов SPECK64 / 128", результаты отличаются от ожидаемых результатов.
Вот способ вызова этой функции:
uint32_t out[2];
uint32_t in[] = { 0x7475432d, 0x3b726574 };
uint32_t key[] = { 0x3020100, 0xb0a0908, 0x13121110, 0x1b1a1918 };
encrypt_block(out, in, key);
assert(out[0] == 0x454e028b);
assert(out[1] == 0x8c6fa548);
Ожидаемое значение для «out», согласно руководству, должно составлять 0x454e028b, 0x8c6fa548
.
Результат, который я получаю с -O2, равен 0x8FA3FED7 0x53D8CEA8
.
С -O1 я получаю 0x454e028b, 0x8c6fa548
, что является правильным результатом.
пошаговая отладка
Руководство по внедрению включает в себя все значения промежуточного ключевого расписания и другие значения, поэтому я пошагово прошел по коду кода, сравнивая результаты с руководством.
Ожидаемые результаты для «x»: 03020100
, 131d0309
, bbd80d53
, 0d334df3
. Я начинаю пошаговую отладку, но при достижении 4-го результата, 0d334df3
, в окне отладчика отображается 0d334df0
. К следующему раунду ожидаемое значение 7fa43565
равно 7FA43578
и ухудшается с каждой итерацией.
Это происходит только при включенном -O2 или выше. Без оптимизации или с параметром -O1 код работает должным образом.