Files
SHA256/sha-256.asm
T
Стас Михайлов WindowsDesktop 80a635688c Закончил Sha256Init
2021-04-28 22:02:00 +03:00

224 lines
12 KiB
NASM

OPTION DOTNAME
include includes\temphls.inc
include includes\win64.inc
include includes\user32.inc
includelib includes\user32.lib
OPTION PROLOGUE:none
OPTION EPILOGUE:none
.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 0 dup (8)
align 16
my3sqrt REAL8 0.3333333333333333333333333333
;xmminst dq 12232434,13342342342
xmmhash xmmword 0 dup (4); 4 Байта в которых хранится хэш
k_konst dd 0 dup (64) ;64 32-битных значения инициированных первыми 32 битами дробной части кубических корней от 2 о 311
myXMMSAVE xmmword 0 dup (10) ;глобальная переменная для сохранения/восстановления регистров XMM6-XMM15 (неизменяемые)
myRnSAVE dq 0 dup (4) ;глобальная переменная для сохранения/восстановления регистров R12-R15 (неизменяемые)
.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
ret
TestHello endp
;Sha256 - Функция, принимающая в качестве параметра 1-Адрес хешируемого объекта;2-его полный размер; 3-Размер отрезка; 4-последний ли он?. Возвращаемое значение: NULL в случае успеха
Sha256 proc __fastcall
enter 128,0
leave
xor rax,rax
ret
Sha256 Endp
;Инициализация хэш функции, ввод исходных значений
Sha256Init proc __fastcall
LOCAL myInt64:QWORD ;Число для преобразования
LOCAL squareRoot:QWORD ;Корень
LOCAL delitel:QWORD ;делитель (равен 1 для извлечения дробной части числа)
LOCAL mnoz:QWORD;множитель для выведение целого числа
LOCAL myxmmword:XMMWORD
enter 8*8,0
lea rdx,prime_nums ;в RDX массив простых чисел
lea r8,xmmhash ;в R8 - адрес инициализированного хэша (его начальных значений)
mov rcx,8 ;в RCX количество повторений цикла. Для процессора нет разницы, обращаться к DL или к RDX, поэтому снижаю расходы приводя всё к единому размеру
mov rax,1373893702338282242
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 ;цикл
leave
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 __fastcall ;вынес вычисление кубического корня в процедуру. На входе, в rcx - простое число, на выходе, в rax 32 бита остатка.
LOCAL myInt64:QWORD ;локальная переменная для хранения простого числа
LOCAL delitel:QWORD ;делитель (равен 1 для извлечения дробной части числа)
LOCAL mnoz:QWORD;множитель для выведение целого числа
LOCAL result:QWORD ;результат
LOCAL regCR:word ;ячейка для сохренения регистра CR (FPU)
enter 5*8,0
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
leave
ret
z3sqrt endp
end