1,6 → 1,6 |
; libcrash -- cryptographic hash functions |
; |
; Copyright (C) 2013 Ivan Baravy (dunkaist) |
; Copyright (C) 2013,2016 Ivan Baravy (dunkaist) |
; |
; This program is free software: you can redistribute it and/or modify |
; it under the terms of the GNU General Public License as published by |
15,7 → 15,39 |
; You should have received a copy of the GNU General Public License |
; along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
macro keccak_rol_xor nd, ncl, ncr |
|
SHA3224_BLOCK_SIZE = 144 |
SHA3256_BLOCK_SIZE = 136 |
SHA3384_BLOCK_SIZE = 104 |
SHA3512_BLOCK_SIZE = 72 |
SHA3MAX_BLOCK_SIZE = SHA3224_BLOCK_SIZE |
|
SHA3_INIT_SIZE = 200 |
|
SHA3224_HASH_SIZE = 28 |
SHA3256_HASH_SIZE = 32 |
SHA3384_HASH_SIZE = 48 |
SHA3512_HASH_SIZE = 64 |
|
SHA3_ALIGN = 16 |
SHA3_ALIGN_MASK = SHA3_ALIGN-1 |
|
struct ctx_sha3 |
hash rb SHA3_INIT_SIZE |
rb SHA3_ALIGN - (SHA3_INIT_SIZE mod SHA3_ALIGN) |
block rb SHA3MAX_BLOCK_SIZE |
rb SHA3_ALIGN - (SHA3MAX_BLOCK_SIZE mod SHA3_ALIGN) |
index rd 1 |
block_size rd 1 |
rounds_cnt rd 1 |
rd 1 ; align |
; tmp vars |
C rq 5 |
D rq 5 |
ends |
|
|
macro sha3._.rol_xor nd, ncl, ncr |
{ |
movq mm0, [C + 8*(ncl)] |
movq mm1, mm0 |
26,11 → 58,13 |
movq [D + 8*(nd)], mm0 |
} |
|
proc keccak_theta |
locals |
C rq 5 |
D rq 5 |
endl |
proc sha3._.theta |
;locals |
; C rq 5 |
; D rq 5 |
;endl |
C equ ebx + ctx_sha3.C |
D equ ebx + ctx_sha3.D |
|
repeat 5 |
movq mm0, [edi + 8*(%-1 + 0)] |
41,11 → 75,11 |
movq [C + 8*(%-1)], mm0 |
end repeat |
|
keccak_rol_xor 0, 1, 4 |
keccak_rol_xor 1, 2, 0 |
keccak_rol_xor 2, 3, 1 |
keccak_rol_xor 3, 4, 2 |
keccak_rol_xor 4, 0, 3 |
sha3._.rol_xor 0, 1, 4 |
sha3._.rol_xor 1, 2, 0 |
sha3._.rol_xor 2, 3, 1 |
sha3._.rol_xor 3, 4, 2 |
sha3._.rol_xor 4, 0, 3 |
|
repeat 5 |
movq mm1, [D + 8*(%-1)] |
66,11 → 100,12 |
movq [edi + 8*(%-1 + 20)], mm0 |
end repeat |
|
restore C,D |
ret |
endp |
|
|
proc keccak_pi |
proc sha3._.pi |
movq mm1, [edi + 8*1] |
movq mm0, [edi + 8*6] |
movq [edi + 8*1], mm0 |
124,7 → 159,7 |
endp |
|
|
proc keccak_chi |
proc sha3._.chi |
|
mov eax, 0xffffffff |
movd mm0, eax |
174,7 → 209,7 |
endp |
|
|
macro keccak_rol_mov n, c |
macro sha3._.rol_mov n, c |
{ |
movq mm0, [edi + 8*(n)] |
movq mm1, mm0 |
184,41 → 219,41 |
movq [edi + 8*(n)], mm0 |
} |
|
proc keccak_permutation |
proc sha3._.permutation |
|
repeat 24 |
stdcall keccak_theta |
stdcall sha3._.theta |
|
keccak_rol_mov 1, 1 |
keccak_rol_mov 2, 62 |
keccak_rol_mov 3, 28 |
keccak_rol_mov 4, 27 |
keccak_rol_mov 5, 36 |
keccak_rol_mov 6, 44 |
keccak_rol_mov 7, 6 |
keccak_rol_mov 8, 55 |
keccak_rol_mov 9, 20 |
keccak_rol_mov 10, 3 |
keccak_rol_mov 11, 10 |
keccak_rol_mov 12, 43 |
keccak_rol_mov 13, 25 |
keccak_rol_mov 14, 39 |
keccak_rol_mov 15, 41 |
keccak_rol_mov 16, 45 |
keccak_rol_mov 17, 15 |
keccak_rol_mov 18, 21 |
keccak_rol_mov 19, 8 |
keccak_rol_mov 20, 18 |
keccak_rol_mov 21, 2 |
keccak_rol_mov 22, 61 |
keccak_rol_mov 23, 56 |
keccak_rol_mov 24, 14 |
sha3._.rol_mov 1, 1 |
sha3._.rol_mov 2, 62 |
sha3._.rol_mov 3, 28 |
sha3._.rol_mov 4, 27 |
sha3._.rol_mov 5, 36 |
sha3._.rol_mov 6, 44 |
sha3._.rol_mov 7, 6 |
sha3._.rol_mov 8, 55 |
sha3._.rol_mov 9, 20 |
sha3._.rol_mov 10, 3 |
sha3._.rol_mov 11, 10 |
sha3._.rol_mov 12, 43 |
sha3._.rol_mov 13, 25 |
sha3._.rol_mov 14, 39 |
sha3._.rol_mov 15, 41 |
sha3._.rol_mov 16, 45 |
sha3._.rol_mov 17, 15 |
sha3._.rol_mov 18, 21 |
sha3._.rol_mov 19, 8 |
sha3._.rol_mov 20, 18 |
sha3._.rol_mov 21, 2 |
sha3._.rol_mov 22, 61 |
sha3._.rol_mov 23, 56 |
sha3._.rol_mov 24, 14 |
|
stdcall keccak_pi |
stdcall keccak_chi |
stdcall sha3._.pi |
stdcall sha3._.chi |
|
movq mm0, [edi + 8*(0)] |
pxor mm0, [crash._.sha3_round + 8*(%-1)] |
pxor mm0, [sha3._.round + 8*(%-1)] |
movq [edi + 8*(0)], mm0 |
end repeat |
|
226,66 → 261,180 |
endp |
|
|
proc crash.sha3_224 _hash, _data |
mov edi, [_hash] |
proc sha3._.init _ctx |
mov [ebx + ctx_sha3.block_size], eax |
shr eax, 3 |
dec eax |
mov [ebx + ctx_sha3.rounds_cnt], eax |
xor eax, eax |
lea edi, [ebx + ctx_sha3.hash] |
mov ecx, SHA3_INIT_SIZE/4 |
rep stosd |
mov [ebx + ctx_sha3.index], eax |
ret |
endp |
|
repeat 18 |
movq mm0, [esi + 8*(%-1)] |
pxor mm0, [edi + 8*(%-1)] |
movq [edi + 8*(%-1)], mm0 |
end repeat |
|
stdcall keccak_permutation |
proc sha3224.init _ctx |
mov ebx, [_ctx] |
mov eax, SHA3224_BLOCK_SIZE |
stdcall sha3._.init |
ret |
endp |
|
add esi, 144 |
|
proc sha3256.init _ctx |
mov ebx, [_ctx] |
mov eax, SHA3256_BLOCK_SIZE |
stdcall sha3._.init |
ret |
endp |
|
|
proc crash.sha3_256 _hash, _data |
mov edi, [_hash] |
proc sha3384.init _ctx |
mov ebx, [_ctx] |
mov eax, SHA3384_BLOCK_SIZE |
stdcall sha3._.init |
ret |
endp |
|
repeat 17 |
movq mm0, [esi + 8*(%-1)] |
pxor mm0, [edi + 8*(%-1)] |
movq [edi + 8*(%-1)], mm0 |
end repeat |
|
stdcall keccak_permutation |
|
add esi, 136 |
proc sha3512.init _ctx |
mov ebx, [_ctx] |
mov eax, SHA3512_BLOCK_SIZE |
stdcall sha3._.init |
ret |
endp |
|
|
proc crash.sha3_384 _hash, _data |
proc sha3._.block _hash |
mov ecx, [ebx + ctx_sha3.rounds_cnt] |
mov edi, [_hash] |
|
repeat 13 |
movq mm0, [esi + 8*(%-1)] |
pxor mm0, [edi + 8*(%-1)] |
movq [edi + 8*(%-1)], mm0 |
end repeat |
@@: |
movq mm0, [esi + 8*ecx] |
pxor mm0, [edi + 8*ecx] |
movq [edi + 8*ecx], mm0 |
dec ecx |
jns @b |
|
stdcall keccak_permutation |
stdcall sha3._.permutation |
|
add esi, 104 |
ret |
endp |
|
|
proc crash.sha3_512 _hash, _data |
mov edi, [_hash] |
proc sha3.update _ctx, _msg, _size |
.next_block: |
mov ebx, [_ctx] |
mov esi, [_msg] |
mov eax, [ebx + ctx_sha3.index] |
test eax, eax |
jnz .copy_to_buf |
test esi, SHA3_ALIGN_MASK |
jnz .copy_to_buf |
.no_copy: |
; data is aligned, hash it in place without copying |
mov ebx, [_ctx] |
mov eax, [ebx + ctx_sha3.block_size] |
cmp [_size], eax |
jb .copy_quit |
lea eax, [ebx + ctx_sha3.hash] |
push ebx esi |
stdcall sha3._.block, eax |
pop esi ebx |
mov eax, [ebx + ctx_sha3.block_size] |
sub [_size], eax |
add esi, [ebx + ctx_sha3.block_size] |
jmp .no_copy |
|
repeat 9 |
movq mm0, [esi + 8*(%-1)] |
pxor mm0, [edi + 8*(%-1)] |
movq [edi + 8*(%-1)], mm0 |
end repeat |
.copy_to_buf: |
lea edi, [ebx + ctx_sha3.block] |
add edi, eax |
mov ecx, [ebx + ctx_sha3.block_size] |
sub ecx, eax |
cmp [_size], ecx |
jb .copy_quit |
sub [_size], ecx |
add [_msg], ecx |
add [ebx + ctx_sha3.index], ecx |
mov eax, [ebx + ctx_sha3.block_size] |
cmp [ebx + ctx_sha3.index], eax |
jb @f |
sub [ebx + ctx_sha3.index], eax |
@@: |
rep movsb |
lea eax, [ebx + ctx_sha3.hash] |
lea esi, [ebx + ctx_sha3.block] |
stdcall sha3._.block, eax |
jmp .next_block |
|
stdcall keccak_permutation |
.copy_quit: |
mov ebx, [_ctx] |
lea edi, [ebx + ctx_sha3.block] |
mov eax, [ebx + ctx_sha3.index] |
add edi, eax |
mov ecx, [_size] |
add [ebx + ctx_sha3.index], ecx |
rep movsb |
.quit: |
ret |
endp |
|
add esi, 72 |
|
proc sha3.final _ctx |
pushad |
mov ebx, [_ctx] |
mov eax, [ebx + ctx_sha3.index] |
xor edx, edx |
mov ecx, [ebx + ctx_sha3.block_size] |
div ecx |
sub ecx, edx |
ja @f |
add ecx, [ebx + ctx_sha3.block_size] |
@@: |
add [ebx + ctx_sha3.index], ecx |
mov eax, [ebx + ctx_sha3.block_size] |
cmp [ebx + ctx_sha3.index], eax |
jb @f |
sub [ebx + ctx_sha3.index], eax |
@@: |
|
mov byte[edi], 0x06 |
inc edi |
dec ecx |
xor eax, eax |
rep stosb |
or byte[edi - 1], 0x80 |
|
mov ebx, [_ctx] |
lea esi, [ebx + ctx_sha3.block] |
lea eax, [ebx + ctx_sha3.hash] |
stdcall sha3._.block, eax |
|
mov ebx, [_ctx] |
lea eax, [ebx + ctx_sha3.hash] |
stdcall sha3._.postprocess, ebx, eax |
|
popad |
ret |
endp |
|
|
proc sha3._.postprocess _ctx, _hash |
emms |
ret |
endp |
|
|
align SHA3_ALIGN |
|
sha3._.round dq 0x0000000000000001, 0x0000000000008082, 0x800000000000808A,\ |
0x8000000080008000, 0x000000000000808B, 0x0000000080000001,\ |
0x8000000080008081, 0x8000000000008009, 0x000000000000008A,\ |
0x0000000000000088, 0x0000000080008009, 0x000000008000000A,\ |
0x000000008000808B, 0x800000000000008B, 0x8000000000008089,\ |
0x8000000000008003, 0x8000000000008002, 0x8000000000000080,\ |
0x000000000000800A, 0x800000008000000A, 0x8000000080008081,\ |
0x8000000000008080, 0x0000000080000001, 0x8000000080008008 |
|