Введение
Интегральная микросхема процессора «Байкал-Т1» (далее – процессор «Байкал-Т1») – первый процессор в линейке многоядерных систем-на-кристалле от компании АО «Байкал Электроникс». Он оптимизирован для применения в коммуникационном и сетевом оборудовании, а также во встраиваемых системах различного назначения и сочетает высокую производительность с низким энергопотреблением. В состав процессора «Байкал-Т1» входит многопроцессорная двуядерная система семейства MIPS32 P5600, а также набор высокоскоростных интерфейсов для обмена данными и низкоскоростных для управления периферийными устройствами. Структурная схема процессора показана на рисунке 1.
Рис. 1. Структурная схема процессора
Подробное описание процессора «Байкал-Т1» см. на сайте компании [1].
В состав каждого из двух ядер входит SIMD-блок, позволяющий работать со 128-разрядными векторами. При использовании метода SIMD осуществляется обработка не одного отсчета, а всего вектора, который может содержать несколько отсчетов, т.е. одна команда применяется сразу ко всему вектору (массиву) данных. Таким образом, за один командный цикл обрабатывается несколько отсчетов. В процессоре используется блок MIPS32 SIMD, что позволяет работать с 32 128-бит регистрами. Каждый регистр может содержать векторы следующих размерностей: 8×16; 16×8; 4×32 или 2×64 бит. Возможно использование более 150 инструкций по обработке данных: целочисленных, с плавающей и фиксированной точкой, включая битовые операции, операции сравнения, конвертации
Целью данной статьи является демонстрация применения SIMD-блока в процессоре «Байкал-Т1» для задачи шифрования по ГОСТ 28147-89, режим ECB.
Оценка эффективности векторных вычислений
Арифметический сопроцессор ядра процессора «Байкал-Т1» совмещает в себе традиционный процессор плавающей запятой и параллельный процессор SIMD, ориентированный на эффективную обработку векторов и оцифрованных сигналов [3]. Оценка производительности векторного сопроцессора SIMD была проведена в 2017 г. на инструментальной системе БФК 1.6 компании АО «Байкал Электроникс» с двуядерным процессором «Байкал-Т1». Тестовой задачей было декодирование видеоролика, закодированного с использованием свободных библиотек x264 (демонстрационный клип H.264) и x265 (видеофайл HEVC) с получением скриншотов через равные промежутки времени.
Как и ожидалось, было отмечено заметное повышение быстродействия процессорного ядра на задачах FFmpeg при использовании аппаратных возможностей SIMD. Результаты тестирования приведены в таблице.
Таблица. Сравнение времени выполнения декодирования видеоролика с использованием сопроцессора SIMD и без него
Алгоритм |
безSIMD |
сSIMD |
относительноеускорение |
||
Декодированиеx264 |
164 |
с |
113 |
с |
1,45 |
Декодированиеx265 |
52 |
с |
22 |
с |
2,36 |
Алгоритм ГОСТ 28147-89
Поскольку алгоритмы преобразования информации по ГОСТ 28147-89 достаточно подробно описаны в [2], в этой статье рассматриваются только основные характеристики для понимания кода и оптимизации.
1. Алгоритм построен на сети Фейстеля.
2. Алгоритм состоит из 32 раундов.
3. Раунд состоит из подмешивания ключа и замены восьми частей по четыре бита по таблице со сдвигом на 11 битов.
Сеть Фейстеля состоит из ячеек Фейстеля. На вход каждой ячейки поступают данные и ключ. На выходе каждой ячейки получают измененные данные и измененный ключ. Все ячейки однотипны, сеть представляет собой определенную многократно повторяющуюся структуру. Ключ выбирается в зависимости от алгоритма шифрования/дешифрования и меняется при переходе от одной ячейки к другой. При шифровании и дешифровании выполняются одни и те же операции; отличается только порядок ключей.
Структурная схема алгоритма показана на рисунке 2. Алгоритм является блочным, т.е. данные в нем разбиваются на блоки размером по 64 бита каждый.
Рис. 2. Структурная схема алгоритма. На рисунке приняты следующие обозначения:
N – накопитель; R – сдвиговый регистр; X – ключ; КЗУ – устройство запоминания ключей; СМ – сумматор
Реализация алгоритма без использования SIMD-блока
Для сравнения алгоритмы были вначале реализованы с использованием стандартных, «невекторизованных» команд. Предложенный ниже код позволяет шифровать один блок 64 бит за 450 нс (или ~150 Мбит/с) при штатной частоте процессора 1200 МГц. В вычислениях задействовано только одно ядро.
Подготовка таблицы замены подразумевает ее разворачивание в 32-бит представление для ускорения работы раунда: вместо замены по четыре бита с маскированием и сдвигом заранее подготовленная таблица осуществляет замену по восемь битов. Этапы программирования код 1 – код 3 приведены ниже.
Код 1:
uint8_tsbox_test[8][16] = {
{0x9, 0x6, 0x3, 0x2, 0x8, 0xb, 0x1, 0x7, 0xa, 0x4, 0xe, 0xf, 0xc, 0x0, 0xd, 0x5},
{0x3, 0x7, 0xe, 0x9, 0x8, 0xa, 0xf, 0x0, 0x5, 0x2, 0x6, 0xc, 0xb, 0x4, 0xd, 0x1},
{0xe, 0x4, 0x6, 0x2, 0xb, 0x3, 0xd, 0x8, 0xc, 0xf, 0x5, 0xa, 0x0, 0x7, 0x1, 0x9},
{0xe, 0x7, 0xa, 0xc, 0xd, 0x1, 0x3, 0x9, 0x0, 0x2, 0xb, 0x4, 0xf, 0x8, 0x5, 0x6},
{0xb, 0x5, 0x1, 0x9, 0x8, 0xd, 0xf, 0x0, 0xe, 0x4, 0x2, 0x3, 0xc, 0x7, 0xa, 0x6},
{0x3, 0xa, 0xd, 0xc, 0x1, 0x2, 0x0, 0xb, 0x7, 0x5, 0x9, 0x4, 0x8, 0xf, 0xe, 0x6},
{0x1, 0xd, 0x2, 0x9, 0x7, 0xa, 0x6, 0x0, 0x8, 0xc, 0x4, 0x5, 0xf, 0x3, 0xb, 0xe},
{0xb, 0xa, 0xf, 0x5, 0x0, 0xc, 0xe, 0x8, 0x6, 0x2, 0x3, 0x9, 0x1, 0x7, 0xd, 0x4}
};
uint32_t sbox_cvt[4*256];
for (i = 0; i
uint32_t p;
p = sbox[7][i >> 4]
p = p > 21;
sbox_cvt[i] = p; // S87
p = sbox[5][i >> 4]
p = p > 21;
sbox_cvt[256 + i] = p; // S65
p = sbox[3][i >> 4]
p = p > 21;
sbox_cvt[256 * 2 + i] = p; // S43
p = sbox[1][i >> 4]
p = p > 21;
sbox_cvt[256 * 3 + i] = p; // S21
}
Шифрование блока – 32-кратный повтор раунда с использованием ключа.Код 2:
// input: a0 — &in, a1 — &out, a2 — &key, a3 — &sbox_cvt
LEAF(gost_encrypt_block_asm)
.set reorder
lw n1, (a0) // n1, IN
lw n2, 4(a0) // n2, IN + 4
lw t0, (a2) // key[0] -> t0
gostround n1, n2, 1
gostround n2, n1, 2
gostround n1, n2, 3
gostround n2, n1, 4
gostround n1, n2, 5
gostround n2, n1, 6
gostround n1, n2, 7
gostround n2, n1, 0
gostround n1, n2, 1
gostround n2, n1, 2
gostround n1, n2, 3
gostround n2, n1, 4
gostround n1, n2, 5
gostround n2, n1, 6
gostround n1, n2, 7
gostround n2, n1, 0
gostround n1, n2, 1
gostround n2, n1, 2
gostround n1, n2, 3
gostround n2, n1, 4
gostround n1, n2, 5
gostround n2, n1, 6
gostround n1, n2, 7
gostround n2, n1, 7
gostround n1, n2, 6
gostround n2, n1, 5
gostround n1, n2, 4
gostround n2, n1, 3
gostround n1, n2, 2
gostround n2, n1, 1
gostround n1, n2, 0
gostround n2, n1, 0
1: sw n2, (a1)
sw n1, 4(a1)
jr ra
nop
END(gost_encrypt_block_asm)
Раунд с развернутой таблицей – замена по таблице. Код 3:
.macro gostround x_in, x_out, rkey
addu t8, t0, x_in /* key[0] + n1 = x */
lw t0, rkey * 4 (a2) /* next key to t0 */
ext t2, t8, 24, 8 /* get bits [24,31] */
ext t3, t8, 16, 8 /* get bits [16,23] */
ext t4, t8, 8, 8 /* get bits [8,15] */
ext t5, t8, 0, 8 /* get bits [0, 7] */
sll t2, t2, 2 /* convert to dw offset */
sll t3, t3, 2 /* convert to dw offset */
sll t4, t4, 2 /* convert to dw offset */
sll t5, t5, 2 /* convert to dw offset */
addu t2, t2, a3 /* add sbox_cvt */
addu t3, t3, a3 /* add sbox_cvt */
addu t4, t4, a3 /* add sbox_cvt */
addu t5, t5, a3 /* add sbox_cvt */
lw t6, (t2) /* sbox[x[3]] -> t2 */
lw t7, 256*4(t3) /* sbox[256 + x[2]] -> t3 */
lw t9, 256*2*4(t4) /* sbox[256 *2 + x[1]] -> t4 */
lw t1, 256*3*4(t5) /* sbox[256 *3 + x[0]] -> t5 */
or t2, t7, t6 /* | */
or t3, t1, t9 /* | */
ort2, t2, t3 /* | */
xor x_out, x_out, t2 /* n2 ^= f(…) */
.endm
Реализация алгоритма с использованием SIMD-блока процессора «Байкал-Т1»
Предложенный ниже код позволяет шифровать одновременно четыре блока по 64 бита за 720 нс (или ~350 Мбит/с) при тех же условиях: частота процессора 1200 МГц, одно ядро.
Замена производится в двух четверках и сразу в четырех блоках инструкцией shuffle и последующим маскированием значимых четверок.
Развертывание таблицы замен:
for(i = 0; i
sbox_cvt_simd[i] = (sbox[7][i]
sbox_cvt_simd[16 + i] = (sbox[1][i]
sbox_cvt_simd[32 + i] = (sbox[5][i]
sbox_cvt_simd[48 + i] = (sbox[3][i]
}
Этапы программирования Код 11– Код 13 приведены ниже.
Код 11 – инициализация масок:
l0123: .int 0x0f0f0f0f
.int 0xf000000f /* substitute from $w8 [7 0] mask in w12*/
.int 0x0f0000f0 /* substitute from $w9 [6 1] mask in w13*/
.int 0x00f00f00 /* substitute from $w10 [5 2] mask in w14*/
.int 0x000ff000 /* substitute from $w11 [4 3] mask in w15*/
.int 0x000f000f /* mask $w16 x N x N */
.int 0x0f000f00 /* mask $w17 N x N x */
LEAF(gost_prepare_asm)
.set reorder
.set msa
la t1, l0123 /* masks */
lw t2, (t1)
lw t3, 4(t1)
lw t4, 8(t1)
lw t5, 12(t1)
lw t6, 16(t1)
lw t7, 20(t1)
lw t8, 24(t1)
fill.w $w2, t2 /* 0f0f0f0f -> w2 */
fill.w $w12, t3 /* f000000f -> w12*/
fill.w $w13, t4 /* 0f0000f0 -> w13*/
fill.w $w14, t5 /* 00f00f00 -> w14*/
fill.w $w15, t6 /* 000ff000 -> w15*/
fill.w $w16, t7 /* 000f000f -> w16*/
fill.w $w17, t8 /* 0f000f00 -> w17*/
ld.b $w8, (a0) /* load sbox */
ld.b $w9, 16(a0)
ld.b $w10, 32(a0)
ld.b $w11, 48(a0)
jr ra
nop
END(gost_prepare_asm)
Шифрование четырех блоков. Раунд с использованием команд SIMD-блока с расчетом четырех блоков одновременно. Код 12:
LEAF(gost_encrypt_4block_asm)
.setreorder
.setmsa
lwt1, (a0) // n1, IN
lwt2, 4(a0) // n2, IN + 4
lwt3, 8(a0) // n1, IN + 8
lw t4, 12(a0) // n2, IN + 12
lw t5, 16(a0) // n1, IN + 16
lw t6, 20(a0) // n2, IN + 20
lw t7, 24(a0) // n1, IN + 24
lw t8, 28(a0) // n2, IN + 28
lw t0, (a2) // key[0] -> t0
insert.w ns1[0],t1
insert.w ns2[0],t2
insert.w ns1[1],t3
insert.w ns2[1],t4
insert.w ns1[2],t5
insert.w ns2[2],t6
insert.w ns1[3],t7
insert.w ns2[3],t8
gostround4 ns1, ns2, 1
gostround4 ns2, ns1, 2
gostround4 ns1, ns2, 3
gostround4 ns2, ns1, 4
gostround4 ns1, ns2, 5
gostround4 ns2, ns1, 6
gostround4 ns1, ns2, 7
gostround4 ns2, ns1, 0
gostround4 ns1, ns2, 1
gostround4 ns2, ns1, 2
gostround4 ns1, ns2, 3
gostround4 ns2, ns1, 4
gostround4 ns1, ns2, 5
gostround4 ns2, ns1, 6
gostround4 ns1, ns2, 7
gostround4 ns2, ns1, 0
gostround4 ns1, ns2, 1
gostround4 ns2, ns1, 2
gostround4 ns1, ns2, 3
gostround4 ns2, ns1, 4
gostround4 ns1, ns2, 5
gostround4 ns2, ns1, 6
gostround4 ns1, ns2, 7
gostround4 ns2, ns1, 7
gostround4 ns1, ns2, 6
gostround4 ns2, ns1, 5
gostround4 ns1, ns2, 4
gostround4 ns2, ns1, 3
gostround4 ns1, ns2, 2
gostround4 ns2, ns1, 1
gostround4 ns1, ns2, 0
gostround4 ns2, ns1, 0
1:
copy_s.w t1,ns2[0]
copy_s.w t2,ns1[0]
copy_s.w t3,ns2[1]
copy_s.w t4,ns1[1]
copy_s.w t5,ns2[2]
copy_s.w t6,ns1[2]
copy_s.w t7,ns2[3]
copy_s.w t8,ns1[3]
sw t1, (a1) // n2, OUT
sw t2, 4(a1) // n1, OUT + 4
sw t3, 8(a1) // n2, OUT + 8
sw t4, 12(a1) // n1, OUT + 12
sw t5, 16(a1) // n2, OUT + 16
sw t6, 20(a1) // n1, OUT + 20
sw t7, 24(a1) // n2, OUT + 24
sw t8, 28(a1) // n1, OUT + 28
jr ra
nop
END(gost_encrypt_4block_asm)
Код 13:
.macro gostround4 x_in, x_out, rkey
fill.w $w0, t0 /* key -> Vi */
addv.w $w1, $w0, x_in /* key[0] + n1 = x */
srli.b $w3, $w1, 4 /* $w1 >> 4 */
and.v $w4, $w1, $w16 /* x 4 x 0*/
and.v $w5, $w1, $w17 /* 6 x 2 x*/
and.v $w6, $w3, $w17 /* 7 x 3 x */
and.v $w7, $w3, $w16 /* x 5 x 1 */
lw t0, rkey * 4(a2) /* next key -> t0 */
or.v $w4, $w6, $w4 /* 7 4 3 0 */
or.v $w5, $w5, $w7 /* 6 5 2 1 */
move.v $w6, $w5 /* 6 5 2 1 */
move.v $w7, $w4 /* 7 4 3 0 */
/* 7 x x 0 */
/* 6 x x 1 */
/* x 5 2 x */
/* x 4 3 x */
vshf.b $w4, $w8, $w8 /* substitute $w8 [7 0] */
and.v $w4, $w4, $w12
vshf.b $w5, $w9, $w9 /* substitute $w9 [6 1] */
and.v $w5, $w5, $w13
vshf.b $w6, $w10, $w10 /* substitute $w10 [5 2] */
and.v $w6, $w6, $w14
vshf.b $w7, $w11, $w11 /* substitute $w11 [4 3] */
and.v $w7, $w7, $w15
or.v $w4, $w4, $w5
or.v $w6, $w6, $w7
or.v $w4, $w4, $w6
srli.w $w1, $w4, 21 /* $w4 >> 21 */
slli.w $w3, $w4, 11 /* $w4
or.v $w1, $w1, $w3
xor.v x_out, x_out, $w1
.endm
Выводы
Использование SIMD-блока процессора «Байкал-Т1» обеспечивает скорость преобразования информации по алгоритмам ГОСТ 28147-89 около 350 Мбит/с, что в 2,5 раза превышает скорость в реализации на стандартных командах. Процессор «Байкал-Т1» содержит два ядра, что теоретически позволяет шифровать поток со скоростью около 700 Мбит/с.
Примечание. Пропускная способность канала в тестовой реализации IPsec с шифрованием по ГОСТ 28147-89 составила ~400Мбит/с (дуплекс).
Литература
1. Сайт компании АО «Байкал Электроникс»//www.baikalelectronics.ru.
2. ГОСТ 28147-89 http://docs.cntd.ru/document/gost-28147-89.
3. С. Жельнио. Технология MIPS SIMD и процессор «Байкал-Т1»//www.silicon-russia.com.