Code: Alles auswählen
;- SHA256, based (Pseudo-Code) on engl. Wikipedia
;- "Helle" Klaus Helbing, 07.08.2011, PB 4.51 (x86)
;- 32-Bit-Windows-Version with SSE2
Procedure Padding(BufferA)
;Size wird auf Vielfaches von 512 Bit (64 Byte) gebracht (Blocklänge ist 512 Bit)
!mov eax,[p.v_BufferA]
!push ebx
!push edi
!push esi
!mov ebx,eax
!mov edi,[ebx+352]
!add edi,ebx
!mov eax,[ebx+12] ;MemAv
!mov esi,eax
!mov ecx,64 ;512 Bit
!xor edx,edx ;hier mal so (ist ja unsigned)
!div ecx ;Modulo steht in edx
!inc eax ;eine Runde wollen wir ja wenigstens!
!mov [ebx+8],eax ;Chunks
!mov eax,[ebx+12] ;MemAv
!mov byte[edi+eax],80h ;1 gesetztes Bit anhängen
!or edx,edx ;edx=0?
;1.Fall: EDX=0. Letzter 512-Bit-Block ist Vielfaches von 512 Bit (64 Byte). Es wird ein kompletter 512-Bit-Block angehängt
!jz @f
;2.Fall: EDX<56. Letzter 512-Bit-Block ist kleiner als 448 Bit (56 Byte), aber größer Null
!sub esi,edx
!cmp edx,56 ;448 Bit
!jb @f
;3.Fall: EDX>=56. Letzter 512-Bit-Block ist größer/gleich als 448 Bit (56 Byte). Dieser Block wird aufgefüllt (Bitwert 1 drangehängt,
; Rest Null) und ein weiterer Block drangehängt mit Nullen und am Ende Original-Länge als 64-Bit-Big-Endian-Wert
!add edi,64
!add dword[ebx+8],1 ;Chunks, es wurde ja ein Block drangehängt
!@@:
!add edi,esi
!mov edx,8
!mov eax,[ebx] ;Size, ist Quad!
!mul edx ;nicht SHL bei großen Dateien
!mov ecx,eax
!mov esi,edx
!mov edx,8 ;"Kaskadierung" für größere Dateien
!mov eax,[ebx+4] ;Size, ist Quad!
!mul edx
!add eax,esi ;reicht so für heutige Festplatten/Filelängen
!bswap ecx
!bswap eax
!mov [edi+56],eax ;Original-Länge als 64-Bit-Big-Endian-Wert anhängen
!mov [edi+60],ecx
!pop esi
!pop edi
!pop ebx
EndProcedure
Procedure Main(BufferA)
!mov eax,[p.v_BufferA]
!push ebp
!push ebx
!push edi
!push esi
!mov ebp,eax
;W[0] bis W[15]
!mov esi,[eax+352]
!add esi,eax
!mov edi,eax
!add edi,96
!mov ecx,8
!@@:
!mov eax,[esi]
!mov edx,[esi+4]
!bswap eax
!bswap edx
!mov [edi],eax
!mov [edi+4],edx
!add edi,8
!add esi,8
!dec ecx
!jnz @b
;W[16] bis W[63]
!mov ecx,48
!mov esi,ebp
!add esi,96+64
!@@:
;s0
!mov eax,dword[esi-60]
!mov edx,eax
!mov edi,eax
!ror eax,7
!ror edx,18
!shr edi,3
!xor eax,edx
!xor edi,eax
;s1
!mov eax,dword[esi-8]
!mov edx,eax
!mov ebx,eax
!ror eax,17
!ror edx,19
!xor eax,edx
!shr ebx,10
!xor eax,ebx
;W[i]
!mov edx,dword[esi-64]
!add edx,edi ;edi=s0
!add edx,dword[esi-28]
!add edx,eax ;eax=s1
!mov dword[esi],edx
!add esi,4
!dec ecx
!jnz @b
;Initialisierung
!mov esi,ebp ;[p.v_BufferA]
!add esi,16 ;p_a_h_A
!mov eax,ebp
!add eax,64
!movdqa xmm0,[eax]
!movdqa xmm1,[eax+16]
!movdqa [esi],xmm0
!movdqa [esi+16],xmm1
;Main Loop
!xor ecx,ecx ;hier mal so
!@@:
;s0
!mov eax,[esi]
!mov edx,eax
!mov edi,eax
!ror eax,2
!ror edx,13
!xor eax,edx
!ror edi,22
!xor edi,eax ;edi=s0
;maj (major) maj = (a and b) + (c and (a xor b))
!mov eax,[esi] ;a
!mov edx,eax
!mov ebx,[esi+4] ;b
!xor eax,ebx ;(a xor b)
!and ebx,edx ;(a and b)
!and eax,[esi+8] ;c
!add ebx,eax ;ebx=maj
;t2
!add ebx,edi ;ebx=t2, edi=s0
;s1
!mov eax,[esi+16]
!mov edx,eax
!mov edi,eax
!ror eax,6
!ror edx,11
!xor eax,edx
!ror edi,25
!xor edi,eax ;edi=s1
;ch ch = g xor (e and (f xor g))
!mov eax,[esi+24] ;g
!mov edx,eax
!xor edx,[esi+20] ;f
!and edx,[esi+16] ;e
!xor edx,eax
;t1
!mov eax,[esi+28]
!add eax,edi ;s1
!add eax,edx ;ch
!lea edi,[k_256] ;Data
!add eax,dword[edi+ecx] ;k[i]
!mov edi,ebp
!add edi,96
!add eax,dword[edi+ecx] ;eax=t1, edi+ecx=W[i]
;Vertauschungen
!mov edx,[esi+12] ;"altes" d
!add edx,eax ;eax=t1
!movdqa xmm0,[esi]
!movdqa xmm1,[esi+16]
!movdqu [esi+4],xmm0 ;mit Versatz von 4 Bytes zurückkopieren
!movdqu [esi+20],xmm1
!add eax,ebx ;eax=t1, ebx=t2
!mov [esi],eax ;"neues" a
!mov [esi+16],edx ;"neues" e
!add ecx,4
!cmp ecx,256
!jb @b
;am Ende jedes Chunks Hashs zu vorhandenen Werten aufaddieren (Überträge werden ignoriert!)
!mov edi,ebp
!add edi,64
!movdqa xmm0,[edi]
!paddd xmm0,[esi]
!movdqa [edi],xmm0
!movdqa xmm0,[edi+16]
!paddd xmm0,[esi+16]
!movdqa [edi+16],xmm0
!mov eax,ebp
!add dword[eax+352],64 ;512 Bit (64 Byte) weiter, nächster Chunk
!pop esi
!pop edi
!pop ebx
!pop ebp
EndProcedure
Procedure.s SHA256Fingerprint_32(*Source, Length)
SizeAv = Length
If Length > $40000
MemAv = $40000
LCopy = $40000
Chunks = $1000
ChunksOld = Chunks
Else
MemAv = Length
LCopy = Length
EndIf
Buffer = AllocateMemory(356 + MemAv + 128)
i = Buffer % 16
If i
BufferA = Buffer - i + 16 ;Alignment 16
Else
BufferA = Buffer
EndIf
CopyMemory(?HashBase_256, BufferA + 64, 32) ;to pHashA
PokeQ(BufferA, Length)
pAllBlocksStart = 356
PokeL(BufferA + 352, pAllBlocksStart) ;Pointer in pAllBlocksA
If Length = 0
PokeL(BufferA + 12, MemAv)
Padding(BufferA)
Chunks = PeekL(BufferA + 8)
Main(BufferA)
EndIf
While SizeAv
CopyMemory(*Source + Seek, BufferA + pAllBlocksStart, LCopy) ;to pAllBlocksA
BytesCopy = LCopy
Seek + BytesCopy
SizeAv - BytesCopy
If SizeAv < LCopy
LCopy = SizeAv
EndIf
If SizeAv = 0
PokeL(BufferA + 12, MemAv)
Padding(BufferA)
Chunks = PeekL(BufferA + 8)
EndIf
While Chunks ;512 Bit (64 Byte)
Main(BufferA)
Chunks - 1
Wend
PokeL(BufferA + 352, pAllBlocksStart)
If SizeAv <= MemAv
MemAv = SizeAv
NewMem = MemAv + 128
For i = 0 To NewMem
PokeB(BufferA + 356 + i, 0)
Next
Else
Chunks = ChunksOld
EndIf
Wend
SHA256$ = ""
For i = 0 To 28 Step 4
SHA256$ + RSet(Hex(PeekL(BufferA + 64 + i) & $FFFFFFFF), 8, "0")
Next
FreeMemory(Buffer)
ProcedureReturn SHA256$
DataSection ;Read only, evtl. ohne
HashBase_256: ;The first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19, Big-Endian!
Data.l $6a09e667, $bb67ae85, $3c6ef372, $a54ff53a, $510e527f, $9b05688c, $1f83d9ab, $5be0cd19
!k_256: ;The first 32 bits of the fractional parts of the cube roots of the first 64 primes 2...311, Big-Endian!
Data.l $428a2f98, $71374491, $b5c0fbcf, $e9b5dba5, $3956c25b, $59f111f1, $923f82a4, $ab1c5ed5
Data.l $d807aa98, $12835b01, $243185be, $550c7dc3, $72be5d74, $80deb1fe, $9bdc06a7, $c19bf174
Data.l $e49b69c1, $efbe4786, $0fc19dc6, $240ca1cc, $2de92c6f, $4a7484aa, $5cb0a9dc, $76f988da
Data.l $983e5152, $a831c66d, $b00327c8, $bf597fc7, $c6e00bf3, $d5a79147, $06ca6351, $14292967
Data.l $27b70a85, $2e1b2138, $4d2c6dfc, $53380d13, $650a7354, $766a0abb, $81c2c92e, $92722c85
Data.l $a2bfe8a1, $a81a664b, $c24b8b70, $c76c51a3, $d192e819, $d6990624, $f40e3585, $106aa070
Data.l $19a4c116, $1e376c08, $2748774c, $34b0bcb5, $391c0cb3, $4ed8aa4a, $5b9cca4f, $682e6ff3
Data.l $748f82ee, $78a5636f, $84c87814, $8cc70208, $90befffa, $a4506ceb, $bef9a3f7, $c67178f2
EndDataSection
EndProcedure
;SHA256-Test
Test256$ = "The quick brown fox jumps over the lazy dog" ;D7A8FBB307D7809469CA9ABCB0082E4F8D5651E46D3CDB762D02D0BF37C9E592
SHA256$ = SHA256Fingerprint_32(@Test256$, StringByteLength(Test256$))
MessageRequester("SHA256 Fingerprint", SHA256$)
Test256$ = "The quick brown fox jumps over the lazy dog." ;EF537F25C895BFA782526529A9B63D97AA631564D5D789C2B765448C8635FB6C
SHA256$ = SHA256Fingerprint_32(@Test256$, StringByteLength(Test256$))
MessageRequester("SHA256 Fingerprint", SHA256$)
Code: Alles auswählen
;- HMAC256, based (Pseudo-Code) on engl. Wikipedia
;- "Helle" Klaus Helbing, 07.08.2011, PB 4.51 (x86)
;- 32-Bit-Windows-Version with SSE2
Procedure Key_XOR(Buffer, Source)
!mov eax,[p.v_Source]
!movdqu xmm0,[eax]
!mov ecx,4
!mov edx,[p.v_Buffer]
!@@:
!movdqu xmm1,[edx]
!pxor xmm1,xmm0
!movdqu [edx],xmm1
!add edx,16
!dec ecx
!jnz @b
EndProcedure
Procedure Concatenation(Buffer, Hash)
!mov eax,[p.v_Hash]
!mov edx,[p.v_Buffer]
!mov ecx,8
!push ebx
!@@:
!mov ebx,[eax]
!bswap ebx
!mov [edx],ebx
!add eax,4
!add edx,4
!dec ecx
!jne @b
!pop ebx
EndProcedure
Procedure.s HMAC256_32(*Source, LengthSource, *Key, LengthKey)
pMem = AllocateMemory(64 + LengthSource)
If LengthKey <= 64
CopyMemory(*Key, pMem, LengthKey)
Else
HashKey$ = SHA256Fingerprint_32(*Key, LengthKey)
;HashKey$ wieder zurück in Bytes
HashKey = AllocateMemory(32)
For i = 0 To 28 Step 4
PokeL(HashKey + i, Val("$" + Mid(HashKey$, (i * 2 ) + 1, 8)) & $FFFFFFFF)
Next
Concatenation(pMem, HashKey) ;bswap!
EndIf
;Key XOR ipad
Key_XOR(pMem, ?ipad) ;$36
CopyMemory(*Source, pMem + 64, LengthSource)
Hash1$ = SHA256Fingerprint_32(pMem, LengthSource + 64)
FreeMemory(pMem)
pMem = AllocateMemory(96)
If LengthKey <= 64
CopyMemory(*Key, pMem, LengthKey)
Else
Concatenation(pMem, HashKey) ;bswap!
FreeMemory(HashKey)
EndIf
;Key XOR opad
Key_XOR(pMem, ?opad) ;$5C
Hash1 = AllocateMemory(32)
;Hash1$ wieder zurück in Bytes
For i = 0 To 28 Step 4
PokeL(Hash1 + i, Val("$" + Mid(Hash1$, (i * 2 ) + 1, 8)) & $FFFFFFFF)
Next
Concatenation(pMem + 64, Hash1) ;bswap!
FreeMemory(Hash1)
HMAC$ = SHA256Fingerprint_32(pMem, 96)
FreeMemory(pMem)
ProcedureReturn HMAC$
DataSection
ipad:
Data.q $3636363636363636, $3636363636363636
opad:
Data.q $5c5c5c5c5c5c5c5c, $5c5c5c5c5c5c5c5c
EndDataSection
EndProcedure
;HMAC256-Test
Test256$ = "The quick brown fox jumps over the lazy dog" ;45B777B61761A73762CA620A2F9FAD388117A89C59DEA32D9AE207827E26C174
Key$ = "Yappadappadu"
HMAC256$ = HMAC256_32(@Test256$, StringByteLength(Test256$), @Key$, StringByteLength(Key$))
MessageRequester("HMAC256_32", HMAC256$)
Test256$ = "The quick brown fox jumps over the lazy dog" ;F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8
Key$ = "key"
HMAC256$ = HMAC256_32(@Test256$, StringByteLength(Test256$), @Key$, StringByteLength(Key$))
MessageRequester("HMAC256_32", HMAC256$)
Test256$ = "The quick brown fox jumps over the lazy dog" ;E7FE7008B311BFD50176A4CA546838B9E90A42094F5577EB58194FC0307651AE
Key$ = "This is a very, very, very, very, very, very, very, very, very, long key"
HMAC256$ = HMAC256_32(@Test256$, StringByteLength(Test256$), @Key$, StringByteLength(Key$))
MessageRequester("HMAC256_32", HMAC256$)
Helle