mirror of
https://github.com/stasenso/SHA256.git
synced 2026-06-27 05:42:43 +03:00
483 lines
25 KiB
NASM
483 lines
25 KiB
NASM
OPTION DOTNAME
|
||
include includes\temphls.inc
|
||
include includes\win64.inc
|
||
include includes\user32.inc
|
||
includelib includes\user32.lib
|
||
OPTION PROLOGUE:PrologueDef
|
||
OPTION EPILOGUE:EpilogueDef
|
||
.data
|
||
AppName: ;DLL Skeleton
|
||
dw 0044h,004ch,004ch,0020h,0053h,006bh,0065h,006ch,0065h,0074h,006fh,006eh,0000h
|
||
HelloMsg: ;Вызвана функция TestHello
|
||
dw 0412h,044bh,0437h,0432h,0430h,043dh,0430h,0020h,0444h,0443h,043dh,043ah,0446h,0438h,044fh,0020h,0054h,0065h,0073h,0074h,0048h,0065h,006ch,006ch,006fh,0000h
|
||
LoadMsg: ;DLL Загружена
|
||
dw 0044h,004ch,004ch,0020h,0417h,0430h,0433h,0440h,0443h,0436h,0435h,043dh,0430h,0000h
|
||
UnloadMsg: ;DLL выгружена
|
||
dw 0044h,004ch,004ch,0020h,0432h,044bh,0433h,0440h,0443h,0436h,0435h,043dh,0430h,0000h
|
||
SHAMsg: ;"SHA256 Запущена!"
|
||
dw 0053h,0048h,0041h,0032h,0035h,0036h,0020h,0417h,0430h,043fh,0443h,0449h,0435h,043dh,0430h,0021h,0000h
|
||
|
||
DllAtata: ;Неожиданно прилетел DLL_THREAD_ATTACH
|
||
dw 041dh,0435h,043eh,0436h,0438h,0434h,0430h,043dh,043dh,043eh,0020h,043fh,0440h,0438h,043bh,0435h,0442h,0435h,043bh,0020h,0044h,004ch,004ch,005fh,0054h,0048h,0052h,0045h,0041h,0044h,005fh,0041h,0054h,0054h,0041h,0043h,0048h,0000h
|
||
prime2nums: ;Простые числа от 2 до 311
|
||
dw 02h,03h,05h,07h,0Bh,0Dh,11h,13h,17h,1Dh,1Fh,25h,29h,2Bh,2Fh,35h,3Bh,3Dh,43h,47h,49h,4Fh,53h,59h
|
||
dw 61h,65h,67h,6Bh,6Dh,71h,7Fh,83h,89h,8Bh,95h,97h,9Dh,0A3h,0A7h,0ADh,0B3h,0B5h,0BFh,0C1h,0C5h,0C7h,0D3h,0DFh
|
||
dw 0E3h,0E5h,0E9h,0EFh,0F1h,0FBh,101h,107h,10Dh,10Fh,115h,119h,11Bh,125h,133h,137h
|
||
|
||
DllDetata: ;Неожиданно прилетел DLL_PROCESS_DETACH
|
||
dw 041dh,0435h,043eh,0436h,0438h,0434h,0430h,043dh,043dh,043eh,0020h,043fh,0440h,0438h,043bh,0435h,0442h,0435h,\
|
||
043bh,0020h,0044h,004ch,004ch,005fh,0050h,0052h,004fh,0043h,0045h,0053h,0053h,005fh,0044h,0045h,0054h,0041h,0043h,0048h,0000h
|
||
|
||
prime_nums: ; 8 байт с простыми числами от 2 до 19
|
||
db 8 dup (0)
|
||
align 16
|
||
k_konst dd 64 dup (0) ;64 32-битных значения инициированных первыми 32 битами дробной части кубических корней от 2 о 311
|
||
align 16
|
||
my3sqrt REAL8 0.3333333333333333333333333333
|
||
;xmminst dq 12232434,13342342342
|
||
|
||
.code
|
||
DllMain proc hInstDLL:QWORD, reason:QWORD, unused:QWORD
|
||
;push rbp
|
||
;mov rbp,rsp
|
||
;sub rsp,28h
|
||
.if edx==DLL_PROCESS_ATTACH ;Обрабатываю событие вызова DLL
|
||
call _isAvxSupported
|
||
pshufd xmm0,xmm0,10010011b ;Перераспределяет 32-битные qword'ы в xmm согласно битовой маске: 2 бита, числа от 0-3 сообщают
|
||
pshufd xmm0,xmm0,10010011b ;слева направо новое расположение qword'ов в регистре XMM. Например: 3-2-1-0 -> 2-1-0-3(10010011b)
|
||
pshufd xmm0,xmm0,10010011b
|
||
pshufd xmm0,xmm0,10010011b
|
||
mov eax,001020304h ;вычисляю Σ0
|
||
xor rcx,rcx
|
||
ror eax,2
|
||
xor ecx,eax
|
||
ror eax,11
|
||
xor ecx,eax
|
||
ror eax,9
|
||
xor ecx,eax
|
||
;вычисляю ключ
|
||
mov eax,001020304h
|
||
xor eax,ecx
|
||
mov edx,eax ; в EDX - ключ
|
||
mov eax,001020304h
|
||
xor eax,edx
|
||
;смотрю, подходит ли он для других чисел
|
||
mov eax,005040304h ;вычисляю Σ0
|
||
xor rcx,rcx
|
||
ror eax,2
|
||
xor ecx,eax
|
||
ror eax,11
|
||
xor ecx,eax
|
||
ror eax,9
|
||
xor ecx,eax
|
||
;Подставляю ключ из первого примера
|
||
mov eax,005040304h
|
||
xor eax,edx
|
||
lea rdx,LoadMsg ;Указатель на сообщение "DLL загружена"
|
||
.elseif edx==DLL_PROCESS_DETACH ;Обрабатываю событие закрытия DLL
|
||
lea rdx,UnloadMsg ;Указатель на сообщение "DLL выгружена"
|
||
.elseif edx==DLL_THREAD_ATTACH ;Обрабатываю событие создания треда в вызывающем процессе
|
||
;(ох и попило крови это событие: не обрабатывал, а по-умолчанию падало на другой обработчик)
|
||
;lea rdx,DllAtata ;Указатель на сообщение "неожиданно прилетел DLL_THREAD_ATTACH"
|
||
;add rsp,28h ;восстанавливаю вершину стека
|
||
xor rax,rax ;возвращаю ноль
|
||
ret ;Выхожу
|
||
.elseif edx==DLL_THREAD_DETACH ;Обрабатываю событие закрытия треда в вызывающем процессе
|
||
;lea rdx,DllDetata ;Указатель на сообщение "Неожиданно прилетел DLL_PROCESS_DETACH"
|
||
;add rsp,28h ;восстанавливаю вершину стека
|
||
xor rax,rax ;возвращаю ноль
|
||
ret ;Выхожу
|
||
.endif
|
||
mov r9d,MB_OK ;
|
||
jmp exit
|
||
DllMain Endp
|
||
TestHello proc
|
||
;sub rsp,28h
|
||
lea rdx,HelloMsg
|
||
mov r9d,MB_OK + MB_ICONERROR
|
||
exit:: lea r8,AppName
|
||
xor rcx,rcx
|
||
call MessageBoxW
|
||
;mov rsp,rbp
|
||
;pop rbp
|
||
;add rsp,28h
|
||
mov rax,TRUE
|
||
leave
|
||
ret
|
||
TestHello endp
|
||
; Sha256 - хэш-Функция. Возвращаемое значение: NULL в случае успеха, CF_digests заполняется хэш-суммой.
|
||
;1-CF_Addr-Адрес хешируемого объекта:QWORD
|
||
;2-CF_FullSize-его полный размер:QWORD
|
||
;3-CF_CurrSize-Размер отрезка:QWORD
|
||
;4-CF_digests-адрес 8 байт хэша (если ноль, то это первый отрезок):QWORD
|
||
;5-CF_Last-последний ли он?:QWORD
|
||
align 16
|
||
Sha256 proc CF_Addr:QWORD,CF_FullSize:QWORD,CF_CurrSize:QWORD,CF_digests:QWORD,CF_Last:QWORD
|
||
LOCAL myXMMSAVE[10]:xmmword ;локальная область для сохранения/восстановления регистров XMM6-XMM15 (неизменяемые)
|
||
LOCAL myRnSAVE[4]:QWORD ;локальная область для сохранения/восстановления регистров R12-R15 (неизменяемые)
|
||
LOCAL myBuff2Hash[8]:DWORD ;локальная область, куда будут перекинуты данные для хэширования
|
||
LOCAL lastblock[32]:DWORD ;32 двойных слова (1024 бит) - место для одного или двух блоков дописанного кончания файла (блока)
|
||
LOCAL lastblocksize:DWORD ;тут интересен только последний бит: 0-переполнения не было, окончание 512 бит; 1-переполнение было, окончание 1024 бита
|
||
LOCAL myOffset2End:QWORD ;локальная переменная для сохранения смещения до последнего байта хэшируемого отрезка
|
||
LOCAL cyclesInSegment:DWORD ;локальная переменная для сохранения количества циклов перебора отрезка. Перебирается весь отрезок кроме "хвоста"
|
||
LOCAL endingOfSegment:DWORD ;локальная переменная для сохранения размера хвоста файла<=64,который необходимо закончить по SHA-256
|
||
;Сохраняю входные данные
|
||
mov CF_Addr,rcx ;Сохраняю адрес объекта
|
||
mov CF_FullSize,rdx ;Сохраняю его полный размер
|
||
mov CF_CurrSize,r8 ;Сохраняю размер данного отрезка
|
||
mov CF_digests,r9 ;Адрес хэша
|
||
;mov rax,[rbp+32]
|
||
;mov CF_Last,rax ;Сохреняю флаг, последний-ли отрезок
|
||
;Сохраняю в выровненную локальную область 10 XMM Регистров с XMM6-XMM15, r12-r15.
|
||
movdqu myXMMSAVE,XMM6
|
||
movdqu myXMMSAVE+16,XMM7
|
||
movdqu myXMMSAVE+32,XMM8
|
||
movdqu myXMMSAVE+48,XMM9
|
||
movdqu myXMMSAVE+64,XMM10
|
||
movdqu myXMMSAVE+80,XMM11
|
||
movdqu myXMMSAVE+96,XMM12
|
||
movdqu myXMMSAVE+112,XMM13
|
||
movdqu myXMMSAVE+128,XMM14
|
||
movdqu myXMMSAVE+144,XMM15
|
||
mov myRnSAVE,r12
|
||
mov myRnSAVE+4,r13
|
||
mov myRnSAVE+8,r14
|
||
mov myRnSAVE+12,r15
|
||
;если хэш по предложенному адресу = 0, запускаем Sha256Init
|
||
mov rax,qword ptr [r9]
|
||
add r9,8
|
||
or rax,qword ptr [r9]
|
||
add r9,8
|
||
or rax,qword ptr [r9]
|
||
add r9,8
|
||
or rax,qword ptr [r9]
|
||
test rax,rax
|
||
jnz Inithash
|
||
mov rcx,CF_digests
|
||
call Sha256Init
|
||
Inithash: ;Инициирую R12D-r15D (ХЭШ)
|
||
mov rax,CF_digests
|
||
mov r12,QWORD PTR [rax]
|
||
mov r13,QWORD PTR [rax+8]
|
||
mov r14,QWORD PTR [rax+16]
|
||
mov r15,QWORD PTR [rax+24]
|
||
;Является ли массив последним?
|
||
mov rax,CF_Last
|
||
cmp rax,1 ;1-блок является последним
|
||
jnz cycleCheck
|
||
;Да. Копирую окончание массива в локальную область. Заканчиваю блок
|
||
mov lastblocksize,0 ; инициирцю lastblocksize. 0, значит - переполнения не было и дописанный "хвост" будет умещён в 1 блок
|
||
mov rax,CF_FullSize ; В rax=полный размер файла
|
||
xor rdx,rdx ; Обнуляю RDX т.к. он участвукт в расчётах
|
||
mov rbx,CF_CurrSize ; в rbx=размер отрезка
|
||
div rbx ; делю по модулю rax/rbx
|
||
mov myOffset2End,rdx ; в rdx теперь смещение до конца файла в отрезке
|
||
mov rax,rdx ; сохраняю rdx для следующего деления
|
||
xor rdx,rdx ; Обнуляю RDX т.к. он участвукт в расчётах
|
||
mov rbx,64 ; в rbx=64-х байтный отрезок, размер хешированя sha256
|
||
div rbx ; делю по модулю rax/rbx
|
||
mov cyclesInSegment,eax ;в rax теперь количество ЦЕЛЫХ отрезков по 64 байта в массиве
|
||
mov endingOfSegment,edx ;в rdx теперь остаток от деления по модулю 64 (отрезок,<64 байта,который необходимо закончить по SHA-256 )
|
||
mov rax,CF_Addr ;--------------------------------------|
|
||
add rax,myOffset2End;Получаю адрес начала "хвоста" массива-|
|
||
sub rax,rdx ;--------------------------------------|
|
||
cmp rdx,56 ;сравниваю "хвост" с 56 (448)
|
||
jb endingofsegment1 ;Переходим, если меньше
|
||
mov lastblocksize,1 ;сообщаю, что произойдёт переполнение и блока будет 2 (1024 бита)
|
||
endingofsegment1: ;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||
lea rcx,lastblock ;rcx - указатель ┃
|
||
endingofsegment2: ; ┃
|
||
mov bl,[rax] ; перебрасываю хвост в локальную область ┃
|
||
mov [rcx],bl ; ┃
|
||
inc rax ; ┃
|
||
inc rcx ; ┃
|
||
dec rdx ; ┃
|
||
jnz endingofsegment2;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||
mov BYTE ptr [rcx],128 ;дописываю 1 и 7 бит
|
||
mov edx,endingOfSegment
|
||
inc rdx ;в rdx - длинна хвоста + 8 бит
|
||
cmp lastblocksize,1 ;далее разный расчёт в зависимости от того было ли переполнение или нет.
|
||
je endingofsegment3 ;если переполнение было, то посылаем на endingofsegment3
|
||
mov rcx,56
|
||
sub rcx,rdx ;в rcx количество байт, необходимых для дописания нулей до значения 56 (448 бит)
|
||
jmp endingofsegment4
|
||
endingofsegment3:
|
||
mov rcx,120
|
||
sub rcx,rdx ;в rcx количество байт, необходимых для дописания нулей до значения 120 (960 бит)
|
||
endingofsegment4:
|
||
lea rax,lastblock
|
||
add rax,rdx ;в rax следующий байт за дописанным 10000000
|
||
loop_endingofsegment: ;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||
cmp rcx,0 ; ┃
|
||
je end_loop_endingofsegment ; ┃
|
||
mov BYTE PTR [rax],0 ;заполняю нулями до кратного 56 или 120 байт ┃
|
||
inc rax ; ┃
|
||
dec rcx ; ┃
|
||
jmp loop_endingofsegment ;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||
end_loop_endingofsegment: ;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||
mov rbx,CF_FullSize ; ┃
|
||
shl rbx,3 ;дописываю в конец 8 байт размера файла ┃
|
||
bswap rbx ; ┃
|
||
mov QWORD PTR [rax],rbx ;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||
;Счётчик цикла=0?
|
||
cycleCheck:
|
||
mov eax,cyclesInSegment
|
||
cmp eax,0
|
||
je exithash
|
||
;Беру очередной блок 64B В XMM0-XMM4
|
||
mov rax,CF_Addr
|
||
movdqu XMM0,XMMWORD PTR [rax]
|
||
movdqu XMM1,XMMWORD PTR [rax+16]
|
||
movdqu XMM2,XMMWORD PTR [rax+32]
|
||
movdqu XMM3,XMMWORD PTR [rax+48]
|
||
;Готовлю очередь сообщений W в регистрах XMM0-XMM15 от младшего слова к старшему, от 0 до 15
|
||
call Wt ;
|
||
;--------------------------------------------------------------------------
|
||
|
||
;Да. Беру окончание массива (64 или 128 байт), хэширую их
|
||
exithash:
|
||
;Беру очередной блок 64B В XMM0-XMM4
|
||
lea rax,lastblock
|
||
movdqu XMM0,XMMWORD PTR [rax]
|
||
movdqu XMM1,XMMWORD PTR [rax+16]
|
||
movdqu XMM2,XMMWORD PTR [rax+32]
|
||
movdqu XMM3,XMMWORD PTR [rax+48]
|
||
call Wt
|
||
ret
|
||
Sha256 Endp
|
||
;Инициализация хэш функции, ввод исходных значений
|
||
Sha256Init proc;__fastcall
|
||
LOCAL myInt64:QWORD ;Число для преобразования
|
||
LOCAL squareRoot:QWORD ;Корень
|
||
LOCAL delitel:QWORD ;делитель (равен 1 для извлечения дробной части числа)
|
||
LOCAL mnoz:QWORD;множитель для выведение целого числа
|
||
LOCAL myxmmword:XMMWORD
|
||
;push rbp ;пролог, для того что бы по rbp-n \
|
||
;mov rbp,rsp ;\обращаться к локальным переменным
|
||
;sub rsp,4*8 ;создаю стековый фрйм, нахуя он нужен в душе не ябу(((
|
||
lea rdx,prime_nums ;в RDX массив простых чисел
|
||
mov r8,rcx ;в R8 - адрес инициализированного хэша переданного вызывающей процедурой
|
||
mov rcx,8 ;в RCX количество повторений цикла. Для процессора нет разницы, обращаться к DL или к RDX, поэтому снижаю расходы приводя всё к единому размеру
|
||
mov rax,1373893702338282242 ;8 простых чисел от 2 до 19-ти, прекрасно ложатся в 16 байт 64-битного регистра. Поэтому сунул их в один регистр
|
||
mov QWORD PTR [rdx],rax ; инициализирую простые числа от 2 до 19
|
||
loop1:
|
||
finit
|
||
mov al, BYTE PTR [rdx] ;беру текущее простое число
|
||
and rax,255
|
||
mov myInt64,rax
|
||
mov delitel,1 ;делитель 1 нужен для отсечения целой части, при делениии на 1 по модулю
|
||
mov rax,4294967296 ;множитель 2^32, нужен...\
|
||
mov QWORD PTR mnoz,rax ;...для сдвига дробной части на 32 бита
|
||
fild QWORD PTR mnoz ; сохраняю всё в стек FPU
|
||
fild QWORD PTR delitel
|
||
fild QWORD PTR myInt64
|
||
fsqrt ;извлекаю корень
|
||
fprem ;делю на 1 по модулю
|
||
fmul ST,ST(2) ;сдвигаю на 32
|
||
fisttp qword ptr squareRoot ;сохраняю для проверки
|
||
mov eax,dword ptr squareRoot ;сохраняю результат в хеше
|
||
mov dword ptr [r8],eax
|
||
add r8,4;сдвигаю указатель на хэш
|
||
inc rdx ;сдвигаю указатель на простое число
|
||
dec rcx
|
||
jnz loop1 ;цикл
|
||
; Далее, инициализирую константы (k) кубическим корнем ряда первых 64 простых числел от 2 до 311
|
||
lea rdx,prime2nums ;в RDX адресс массива простых числел
|
||
forxmm0: ;Заполняю регистр XMM0 значениями 4-х корней
|
||
mov r8,64 ;счётчик цикла
|
||
lea r9,k_konst ;указатель на буфер k_konst
|
||
loopxmm0:
|
||
mov cx, word ptr [rdx]; беру текущее простое число
|
||
and rcx,65535 ;обнуляю остальные биты
|
||
call z3sqrt ;вызываю процедуру рассчёта дробной части от кубического корня от числа в rcx
|
||
mov dword ptr [r9],eax ;сохраняю результат в буфер
|
||
add rdx,2 ;сдвигаю указатель на простое число
|
||
add r9,4 ;сдвигаю указатель на буфер k_konst
|
||
dec r8 ;уменьшаю счётчик
|
||
jnz loopxmm0 ;цикл
|
||
ret
|
||
Sha256Init Endp
|
||
_isAvxSupported: ; extern "C" int isAvxSupported()
|
||
xor eax, eax
|
||
cpuid
|
||
cmp eax, 1 ; Поддерживает ли CPUID параметр eax = 1?
|
||
jb not_supported
|
||
mov eax, 1
|
||
cpuid
|
||
and ecx, 018000000h ; Проверяем, что установлены биты 27 (ОС использует XSAVE/XRSTOR)
|
||
cmp ecx, 018000000h ; и 28 (поддержка AVX процессором)
|
||
jne not_supported
|
||
xor ecx, ecx ; Номер регистра XFEATURE_ENABLED_MASK/XCR0 есть 0
|
||
xgetbv ; Регистр XFEATURE_ENABLED_MASK теперь в edx:eax
|
||
and eax, 110b
|
||
cmp eax, 110b ; Убеждаемся, что ОС сохраняет AVX регистры при переключении контекста
|
||
jne not_supported
|
||
mov eax, 1
|
||
ret
|
||
not_supported:
|
||
xor eax, eax
|
||
ret
|
||
z3sqrt proc ;вынес вычисление кубического корня в процедуру. На входе, в rcx - простое число, на выходе, в rax 32 бита остатка.
|
||
LOCAL myInt64:QWORD ;локальная переменная для хранения простого числа
|
||
LOCAL delitel:QWORD ;делитель (равен 1 для извлечения дробной части числа)
|
||
LOCAL mnoz:QWORD;множитель для выведение целого числа
|
||
LOCAL result:QWORD ;результат
|
||
LOCAL regCR:word ;ячейка для сохренения регистра CR (FPU)
|
||
mov myInt64,rcx ;сохраняю в переменную
|
||
mov delitel,1 ;единица для деления по модулю
|
||
mov rax,4294967296 ;множитель 2^32, нужен...\
|
||
mov QWORD PTR mnoz,rax ;...для сдвига дробной части на 32 бита
|
||
finit
|
||
fstcw regCR ;сохраняю регистр CR (FPU), для изменения значения бита округления
|
||
or word ptr regCR,3072 ;включаю 10 и 11 биты, сообщающие, что нужно округлять до нуля (в сторону нуля)
|
||
fldcw regCR ;записываю изменённые значения в регистра CR
|
||
fild QWORD PTR mnoz ; сохраняю всё в стек FPU
|
||
fild QWORD PTR delitel
|
||
fld QWORD PTR my3sqrt ;загружаю 1/3
|
||
fild QWORD PTR myInt64 ;текущее простое число
|
||
FYL2X ;получаю LN(x)
|
||
fld ST(0) ;Создаем еще одну копию LN(x)
|
||
frndint ;Округляем
|
||
fsubr st(0),st(1) ;ST(1)=z, ST(0)=z-trunc(z)
|
||
f2xm1 ;ST(1)=z, ST(0)=2**(z-trunc(z))-1
|
||
fld1
|
||
faddp ;ST(1)=z, ST(0)=2**(z-trunc(z))
|
||
fscale ;ST(1)=z, ST(0)=(2**trunc(z))*(2**(z-trunc(z)))=2**t
|
||
fxch st(1)
|
||
fstp st ;Результат остается на вершине стека ST(0)
|
||
fprem ;делю на 1 по модулю
|
||
fmul ST,ST(2) ;сдвигаю на 32
|
||
fisttp qword ptr result ;сохраняю результат
|
||
mov rax,result
|
||
ret
|
||
z3sqrt endp
|
||
Wt proc; вынес в отдельную процедуру заполнение Wt. На выходе - заполненные XMM регистры
|
||
xorps xmm4,xmm4 ;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
||
xorps xmm5,xmm5 ; ┃
|
||
xorps xmm6,xmm6 ; ┃
|
||
xorps xmm7,xmm7 ; ┃
|
||
xorps xmm8,xmm8 ; ┃
|
||
xorps xmm9,xmm9 ; ┃
|
||
xorps xmm10,xmm10 ;инициирую xmm регистры нулями ┃
|
||
xorps xmm11,xmm11 ; ┃
|
||
xorps xmm12,xmm12 ; ┃
|
||
xorps xmm13,xmm13 ; ┃
|
||
xorps xmm14,xmm14 ; ┃
|
||
xorps xmm15,xmm15 ;━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
||
;W16--------------------------------------------------------------------------
|
||
xor rcx,rcx ;в ecx будет xor трёх вращений
|
||
pshufd xmm0,xmm0,00111001b ;-15. 1-е слово двигается на младшую позицию XMM
|
||
movd eax,xmm0
|
||
bswap eax
|
||
ror eax,7
|
||
xor ecx,eax
|
||
ror eax,11
|
||
xor ecx,eax
|
||
rol eax,15
|
||
and eax,1fffffffh
|
||
xor ecx,eax ; S0
|
||
pshufd xmm3,xmm3,01001110b ;-2. 14-е слово двигается на младшую позицию XMM
|
||
xor rbx,rbx ;в ebx будет xor трёх вращений
|
||
movd eax,xmm3
|
||
bswap eax
|
||
ror eax,17
|
||
xor ebx,eax
|
||
ror eax,2
|
||
xor ebx,eax
|
||
rol eax,9
|
||
and eax,3fffffh
|
||
xor ebx,eax ;S1
|
||
pshufd xmm0,xmm0,10010011b ;-16. 0-е слово двигается на младшую позицию XMM
|
||
xor rdx,rdx
|
||
movd eax,xmm0
|
||
bswap eax
|
||
add edx,eax
|
||
add edx,ecx
|
||
pshufd xmm2,xmm2,00111001b ;-7. 9-е слово двигается на младшую позицию XMM
|
||
movd eax,xmm2
|
||
bswap eax
|
||
add edx,eax
|
||
add edx,ebx ;w[i]=w[i-16]+s0+w[i-7]+s1
|
||
;pshufd xmm4,xmm4,11100100b ;16-е слово двигается на младшую позицию XMM
|
||
;bswap edx
|
||
movd xmm4,edx
|
||
;movd eax,xmm4;проверяю, как хранить данные в xmm/
|
||
;W17---------------------------------------------------------------------------
|
||
xor rcx,rcx ;в ecx будет xor трёх вращений
|
||
pshufd xmm0,xmm0,01001110b ;-15. 2-е слово двигается на младшую позицию XMM
|
||
movd eax,xmm0
|
||
bswap eax
|
||
ror eax,7
|
||
xor ecx,eax
|
||
ror eax,11
|
||
xor ecx,eax
|
||
rol eax,15
|
||
and eax,1fffffffh
|
||
xor ecx,eax ; S0
|
||
pshufd xmm3,xmm3,00111001b ;-2. 15-е слово двигается на младшую позицию XMM
|
||
xor rbx,rbx ;в ebx будет xor трёх вращений
|
||
movd eax,xmm3
|
||
bswap eax
|
||
ror eax,17
|
||
xor ebx,eax
|
||
ror eax,2
|
||
xor ebx,eax
|
||
rol eax,9
|
||
and eax,3fffffh
|
||
xor ebx,eax ;S1
|
||
pshufd xmm0,xmm0,10010011b ;-16. 1-е слово двигается на младшую позицию XMM
|
||
xor rdx,rdx
|
||
movd eax,xmm0
|
||
bswap eax
|
||
add edx,eax
|
||
add edx,ecx
|
||
pshufd xmm2,xmm2,00111001b ;-7. 10-е слово двигается на младшую позицию XMM
|
||
movd eax,xmm2
|
||
bswap eax
|
||
add edx,eax
|
||
add edx,ebx ;w[i]=w[i-16]+s0+w[i-7]+s1
|
||
pshufd xmm4,xmm4,00111001b ;17-е слово двигается на младшую позицию XMM
|
||
;bswap edx
|
||
movd xmm15,edx
|
||
orpd xmm4,xmm15
|
||
;W18---------------------------------------------------------------------------
|
||
xor rcx,rcx ;в ecx будет xor трёх вращений
|
||
pshufd xmm0,xmm0,01001110b ;-15. 3-е слово двигается на младшую позицию XMM
|
||
movd eax,xmm0
|
||
bswap eax
|
||
ror eax,7
|
||
xor ecx,eax
|
||
ror eax,11
|
||
xor ecx,eax
|
||
rol eax,15
|
||
and eax,1fffffffh
|
||
xor ecx,eax ; S0
|
||
pshufd xmm4,xmm4,10010011b ;-2. 16-е слово двигается на младшую позицию XMM
|
||
xor rbx,rbx ;в ebx будет xor трёх вращений
|
||
movd eax,xmm4
|
||
bswap eax
|
||
ror eax,17
|
||
xor ebx,eax
|
||
ror eax,2
|
||
xor ebx,eax
|
||
rol eax,9
|
||
and eax,3fffffh
|
||
xor ebx,eax ;S1
|
||
pshufd xmm0,xmm0,10010011b ;-16. 2-е слово двигается на младшую позицию XMM
|
||
xor rdx,rdx
|
||
movd eax,xmm0
|
||
bswap eax
|
||
add edx,eax
|
||
add edx,ecx
|
||
pshufd xmm2,xmm2,00111001b ;-7. 11-е слово двигается на младшую позицию XMM
|
||
movd eax,xmm2
|
||
bswap eax
|
||
add edx,eax
|
||
add edx,ebx ;w[i]=w[i-16]+s0+w[i-7]+s1
|
||
pshufd xmm4,xmm4,01001110b ;18-е слово двигается на младшую позицию XMM
|
||
;bswap edx
|
||
movd xmm15,edx
|
||
orpd xmm4,xmm15
|
||
ret
|
||
Wt Endp
|
||
end |