p.s. Имеется в виду, что функция F — линейная, и в процессе шифрации, и в процессе дешифрации ее задача одна и та же и принцип работы не меняется. Что касаемо самого алоритма, то в случае дешифрации меняется порядок использования ключей. Просто проследите за логикой работы на схемах шифрации/дешифрации, которая приведена в статье.
Там команд то… на пальцах задней ноги пересчитать можно. Что по поводу флагов, то:
«The packed arithmetic instructions operate on a set of bytes, words, or double words within a 64-bit block. For example, the PADDW instruction computes four 16-bit sums of two operand simultaneously. None of these instructions affect the CPU's FLAGs register. Therefore, there is no indication of overflow, underflow, zero result, negative result, etc.»
Судя по сгенерированному коду, полином задается через константы. Мне кажется исполняемый код не даст такие же результаты, если полином будет меняться в процессе работы, например циклический сдвиг. Фактически, вся логика работы с 256 битами данных (регистр и маска), была сокращена до 128 и аккуратно разбросана по стандартным регистрам.
Я немного оптимизировал код. Он стал похож на Ваш и jcmvbkbc вариант, только вместо таблиц у меня lahf/not:
mov ecx, RR_
l1:
; Apply LFSR mask
movq mm(inRTmpH),mm(inRSH)
pand mm(inRTmpH),mm(inRMH)
movq mm(inRTmpL),mm(inRSL)
pand mm(inRTmpL),mm(inRML)
; Calculate new bit
pxor mm(inRTmpH),mm(inRTmpL)
movd ebx, mm(inRTmpH)
psrlq mm(inRTmpH),020h
movd eax, mm(inRTmpH)
xor ebx,eax
mov ax,bx
sar ebx,010h
xor ax,bx
xor al,ah
lahf
not eax
sar eax,0Ah
and eax,01h
; Append new bit
psrlq mm(inRSL),01h
movq mm(inRTmp),mm(inRSH)
psllq mm(inRTmp),03Fh
por mm(inRSL),mm(inRTmp)
psrlq mm(inRSH),01h
movd mm(inRTmp), eax
psllq mm(inRTmp),03Fh
por mm(inRSH),mm(inRTmp)
loop l1
На 2^21 циклах скорость работы ~0.02 с. Но, зато, я легко могу добавить конструкцию следующего типа без обращения к памяти:
movq mm(inRTmpH),mm(inRSH)
movq mm(inRTmpL),mm(inRSH)
psllq mm(inRTmpH),03Fh
psllq mm(inRTmpL),03Fh
psrlq mm(inRSH),01h
psrlq mm(inRSL),01h
por mm(inRSH),mm(inRTmpL)
por mm(inRSL),mm(inRTmpH)
Согласен :) Более того, если я правильно помню, то на тот момент, когда мне необходим был этот код, технология SSE2 была очень молода, а команды SSE мне показались не очень «удобными».
Отчасти. Конечно, в силу простоты реализации в электронике, LFSR используют в потоковых шифраторах и для скрэмблинга передаваемых данных. Но, скажем так, алгоритм LFSR нашел свое применение не только в электронике, но и в программном коде. Например, при организации пула для энтропии в рамках псевдоустройства /dev/random в версиях Linux.
Похоже, использование таблиц в данном случае эффективнее.
Кстати, вот тоже работающий вариант не использующий XOR в принципе (:
(правда медленный):
Отсюда: Art of Assembly: MMX Technology Instructions
Жаль, что не ввели сразу «горизонтальную» арифметку. Сильно упростило бы.
25 78563412
конечно же…
Судя по сгенерированному коду, полином задается через константы. Мне кажется исполняемый код не даст такие же результаты, если полином будет меняться в процессе работы, например циклический сдвиг. Фактически, вся логика работы с 256 битами данных (регистр и маска), была сокращена до 128 и аккуратно разбросана по стандартным регистрам.
Я немного оптимизировал код. Он стал похож на Ваш и jcmvbkbc вариант, только вместо таблиц у меня lahf/not:
На 2^21 циклах скорость работы ~0.02 с. Но, зато, я легко могу добавить конструкцию следующего типа без обращения к памяти:
Жаль что в MMX нет SHLD :)