Code : Tout sélectionner
;======================================================================
; Module: SHA3.pbi
;
; Author: sec
; Date: Sep 03, 2013
; Version: 1.4.4
; Target Compiler: PureBasic 5.20+
; Target OS: All
; License: Free, unrestricted, no warranty whatsoever
; Use at your own risk
;======================================================================
DeclareModule SHA3
Declare$ sha224(*Buffer, Size)
Declare$ sha256(*Buffer, Size)
Declare$ sha384(*Buffer, Size)
Declare$ sha512(*Buffer, Size)
EndDeclareModule
Module SHA3
EnableExplicit
;-Internal functions
;credit: Danilo
DataSection
_rndc:
Data.q $0000000000000001, $0000000000008082, $800000000000808a
Data.q $8000000080008000, $000000000000808b, $0000000080000001
Data.q $8000000080008081, $8000000000008009, $000000000000008a
Data.q $0000000000000088, $0000000080008009, $000000008000000a
Data.q $000000008000808b, $800000000000008b, $8000000000008089
Data.q $8000000000008003, $8000000000008002, $8000000000000080
Data.q $000000000000800a, $800000008000000a, $8000000080008081
Data.q $8000000000008080, $0000000080000001, $8000000080008008
_rotc:
Data.l 1, 3, 6, 10, 15, 21, 28, 36, 45, 55, 2, 14
Data.l 27, 41, 56, 8, 25, 43, 62, 18, 39, 61, 20, 44
_piln:
Data.l 10, 7, 11, 17, 18, 3, 5, 16, 8, 21, 24, 4
Data.l 15, 23, 19, 13, 12, 2, 20, 14, 22, 9, 6, 1
EndDataSection
Structure QuadArray : q.q[0] : EndStructure
Structure LongArray : l.l[0] : EndStructure
;credit: wilbert
Procedure.q Rotl64(val.q, n)
!mov ecx, [p.v_n]
CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
!mov rax, [p.v_val]
!rol rax, cl
CompilerElse
!btr ecx, 5
!jc rotl64_1
!mov eax, [p.v_val]
!mov edx, [p.v_val + 4]
!jmp rotl64_2
!rotl64_1:
!mov edx, [p.v_val]
!mov eax, [p.v_val + 4]
!rotl64_2:
!push ebx
!mov ebx, eax
!shld eax, edx, cl
!shld edx, ebx, cl
!pop ebx
CompilerEndIf
ProcedureReturn
EndProcedure
#KECCAK_ROUNDS = 24
Procedure keccakf(Array st.q(1), rounds.i)
Define *rndc.QuadArray = ?_rndc
Define *rotc.LongArray = ?_rotc
Define *piln.LongArray = ?_piln
Define.i i, j, round
Define.q t
Dim bc.q(5-1)
For round = 0 To rounds -1
;Theta
For i = 0 To 4
bc(i) = st(i) ! st(i + 5) ! st(i + 10) ! st(i + 15) ! st(i + 20)
Next
For i = 0 To 4
t = bc((i + 4) % 5) ! ROTL64(bc((i + 1) % 5), 1)
For j = 0 To 24 Step 5
st(j + i) ! t
Next
Next
;Rho Pi
t = st(1)
For i = 0 To 23
j = *piln\l[i]
bc(0) = st(j)
st(j) = ROTL64(t, *rotc\l[i])
t = bc(0)
Next
;Chi
For j = 0 To 24 Step 5
For i = 0 To 4
bc(i) = st(j + i)
Next
For i = 0 To 4
st(j + i) ! ((~bc((i + 1) % 5)) & bc((i + 2) % 5))
Next
Next
;Iota
st(0) ! *rndc\q[round]
Next
EndProcedure
Procedure$ keccak(in, inlen, mdlen)
Dim st.q(25)
Dim temp.a(144)
Define.i i, rsiz, rsizw
Define stemp$
rsiz = 200 - 2 * mdlen
rsizw = rsiz / 8
FillMemory(@st(),SizeOf(Quad) + SizeOf(Quad)*ArraySize(st()))
While inlen >= rsiz
For i = 0 To rsizw-1
st(i) ! PeekQ(in+i*SizeOf(Quad))
Next
keccakf(st(), #KECCAK_ROUNDS)
inlen - rsiz
in + rsiz
Wend
;last block And padding
CopyMemory(in, @temp(), inlen)
temp(inlen) = 1
inlen+1
FillMemory(@temp() + inlen,rsiz - inlen + 1 ,0)
temp(rsiz - 1) | $80
For i = 0 To rsizw -1
st(i) ! PeekQ(@temp(i*SizeOf(Quad)))
Next
keccakf(st(), #KECCAK_ROUNDS)
stemp$=""
For i = 0 To mdlen -1
stemp$ + RSet(Hex(PeekA(@st()+i)),2,"0")
Next
ProcedureReturn stemp$
EndProcedure
;-SHA3 functions
Procedure$ sha224(*Buffer, Size)
ProcedureReturn keccak(*Buffer, Size, 28)
EndProcedure
Procedure$ sha256(*Buffer, Size)
ProcedureReturn keccak(*Buffer, Size, 32)
EndProcedure
Procedure$ sha384(*Buffer, Size)
ProcedureReturn keccak(*Buffer, Size, 48)
EndProcedure
Procedure$ sha512(*Buffer, Size)
ProcedureReturn keccak(*Buffer, Size, 64)
EndProcedure
EndModule
;-Usage - Example
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
Define msg$ = "The quick brown fox jumps over the lazy dog."
Define msglen = StringByteLength(msg$)
Debug SHA3::sha224(@msg$, msglen)
Debug SHA3::sha256(@msg$, msglen)
Debug SHA3::sha384(@msg$, msglen)
Debug SHA3::sha512(@msg$, msglen)
CompilerEndIf
sec