Pull to refresh
4
0
Andrey Breeze @security

User

Send message
p.s. Имеется в виду, что функция F — линейная, и в процессе шифрации, и в процессе дешифрации ее задача одна и та же и принцип работы не меняется. Что касаемо самого алоритма, то в случае дешифрации меняется порядок использования ключей. Просто проследите за логикой работы на схемах шифрации/дешифрации, которая приведена в статье.
Функция F в обратную сторону не работает (: Это раундовые ключи местами меняются.
Да, так и есть. Запутали меня (:

013E1400   > 8BC7           MOV EAX,EDI
013E1402   . 2305 44303E01  AND EAX,DWORD PTR DS:[13E3044]
013E1408   . 8BE9           MOV EBP,ECX
013E140A   . 232D 40303E01  AND EBP,DWORD PTR DS:[13E3040]
013E1410   . 33C5           XOR EAX,EBP
013E1412   . 8BEA           MOV EBP,EDX
013E1414   . 232D 3C303E01  AND EBP,DWORD PTR DS:[13E303C]
013E141A   . 33C5           XOR EAX,EBP
013E141C   . 8BEE           MOV EBP,ESI
013E141E   . 232D 38303E01  AND EBP,DWORD PTR DS:[13E3038]

Похоже, использование таблиц в данном случае эффективнее.

Кстати, вот тоже работающий вариант не использующий XOR в принципе (:
(правда медленный):

.data
  SH_ dq 0FFFFFFFFFFFFFFFFh ; Sequence[127-64]
  SL_ dq 0FFFFFFFFFFFFFFFFh ;         [63-0]
  MH_ dq 00000000000000000h ; Mask[127-64] taps: 128,126,101,99
  ML_ dq 00000000028000005h ;     [63-0]
  RR_ dd 0001FFFE0h         ; Amount of rounds

  _55 dq 05555555555555555h
  _33 dq 03333333333333333h
  _0F dq 00F0F0F0F0F0F0F0Fh
  _FF dq 000FF00FF00FF00FFh

.code
  ; Initialize MMX registers
  movq mm(inRSH),SH_
  movq mm(inRSL),SL_
  movq mm(inRMH),MH_
  movq mm(inRML),ML_

  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
  movq mm(inRTmp),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),01h
  pand mm(inRTmpH),_55
  pand mm(inRTmpL),_55
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),02h
  pand mm(inRTmpH),_33
  pand mm(inRTmpL),_33
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),04h
  pand mm(inRTmpH),_0F
  pand mm(inRTmpL),_0F
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),08h
  pand mm(inRTmpH),_FF
  pand mm(inRTmpL),_FF
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psllq mm(inRTmpL),020h
  paddd mm(inRTmpH),mm(inRTmpL)
  movq mm(inRTmpL),mm(inRTmpH)
  psllq mm(inRTmpL),010h
  paddw mm(inRTmpH),mm(inRTmpL)
  psllq mm(inRTmpH),0Fh
  movq mm(inRTmpL),mm(inRTmp)
  movq mm(inRTmp),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),01h
  pand mm(inRTmpH),_55
  pand mm(inRTmpL),_55
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),02h
  pand mm(inRTmpH),_33
  pand mm(inRTmpL),_33
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),04h
  pand mm(inRTmpH),_0F
  pand mm(inRTmpL),_0F
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psrlw mm(inRTmpH),08h
  pand mm(inRTmpH),_FF
  pand mm(inRTmpL),_FF
  paddw mm(inRTmpL),mm(inRTmpH)
  movq mm(inRTmpH),mm(inRTmpL)
  psllq mm(inRTmpL),020h
  paddd mm(inRTmpH),mm(inRTmpL)
  movq mm(inRTmpL),mm(inRTmpH)
  psllq mm(inRTmpL),010h
  paddw mm(inRTmpH),mm(inRTmpL)
  psllq mm(inRTmpH),0Fh
  paddw mm(inRTmpH),mm(inRTmp)
  psrlq mm(inRTmpH),03Fh
  psllq mm(inRTmpH),03Fh

  ; 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
  por mm(inRSH),mm(inRTmpH)
Спасибо… Кажется, я был прав (смещение в EXE-файле: 0x05B5):

002811B5  |. 8BDA                            ||MOV EBX,EDX
002811B7  |. 81E3 563412F0                   ||AND EBX,F0123456
002811BD  |. 8BC8                            ||MOV ECX,EAX
002811BF  |. 81E1 F0DEBC9A                   ||AND ECX,9ABCDEF0
002811C5  |. 33D9                            ||XOR EBX,ECX
Андрей, а можете поделиться уже скомпилированным кодом?
Там команд то… на пальцах задней ноги пересчитать можно. Что по поводу флагов, то:

«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.»

Отсюда: Art of Assembly: MMX Technology Instructions

Жаль, что не ввели сразу «горизонтальную» арифметку. Сильно упростило бы.
А Вы уверены, что на выходе компилера, эта инструкция не превращается что-то типа в следующий opcode? :)

25 78563412
Да, это бесспорно. Но опять же, маска остается константой. Да и в инструкциях MMX нет аналога ADC, к сожалению.
  movq mm(inRTmpH),mm(inRMH)
  movq mm(inRTmpL),mm(inRML)
  psllq mm(inRTmpH),03Fh
  psllq mm(inRTmpL),03Fh
  psrlq mm(inRMH),01h  
  psrlq mm(inRML),01h  
  por mm(inRMH),mm(inRTmpL)
  por mm(inRML),mm(inRTmpH)


конечно же…
Вы об ошибках с «d<<1»? :)

Судя по сгенерированному коду, полином задается через константы. Мне кажется исполняемый код не даст такие же результаты, если полином будет меняться в процессе работы, например циклический сдвиг. Фактически, вся логика работы с 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)


Жаль что в MMX нет SHLD :)
Согласен :) Более того, если я правильно помню, то на тот момент, когда мне необходим был этот код, технология SSE2 была очень молода, а команды SSE мне показались не очень «удобными».
Отлично… Ну что же, мой результат ~0.04 с
Хах :) Действительно, забыл добавить условие вывода на экран всех вычисленных функцией обратной связи битов.
Отчасти. Конечно, в силу простоты реализации в электронике, LFSR используют в потоковых шифраторах и для скрэмблинга передаваемых данных. Но, скажем так, алгоритм LFSR нашел свое применение не только в электронике, но и в программном коде. Например, при организации пула для энтропии в рамках псевдоустройства /dev/random в версиях Linux.
12 ...
7

Information

Rating
Does not participate
Date of birth
Registered
Activity