Announcement

Collapse
1 of 2 < >

Announcement

2 of 2 < >

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Class: SHA512

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • PBWin Class: SHA512

    Here a Class for SHA512 based on Code by Greg Turgeon. It is a very fast code for this generator.
    This class can be used to process any file. In addition, a progress indicator can be connected..



    Code:
    ' PowerSHA512_m.inc
    '
    '
    MACRO align(p,alignment)=((p+(alignment-1)) AND (NOT(alignment-1)))
    
    '--------------------
    MACRO ROR8_128(XMMReg,RotateVal)
    '-- Returns (x >> n) | (x << (64 - n))
    '-- Destroys eax, edx, xmm6, xmm7
    !  mov      eax,     RotateVal
    !  mov      edx,     64
    !  sub      edx,     eax
    
    !  movd     xmm6,     edx
    !  movdqa   xmm7,     XMMReg        ;copy to xmm7
    
    !  psrlq    XMMReg,  RotateVal      ;shift each quad right
    !  psllq    xmm7,    xmm6           ;shift each quad left by edx
    !  por      XMMReg,  xmm7           ;OR the results
    END MACRO
    
    '--------------------
    MACRO ROR8_64(MMXReg,RotateVal)
    '-- Returns (x >> n) | (x << (64 - n))
    '-- Destroys eax, edx, mm6, mm7
    !  mov      eax,     RotateVal
    !  mov      edx,     64
    !  sub      edx,     eax
    
    !  movd     mm6,     edx
    !  movq     mm7,     MMXReg       ;copy to mm7
    
    !  psrlq    MMXReg,  RotateVal    ;shift right
    !  psllq    mm7,     mm6          ;shift left by edx
    !  por      MMXReg,  mm7          ;OR the results
    END MACRO
    
    '--------------------
    MACRO ROR8(pQuad,RotateVal)
    MACROTEMP RorStore
    '-- Destroys eax, ecx, edx
    !  mov      eax,     pQuad
    !  mov      ecx,     RotateVal
    !  mov      edx,     [eax+4]
    !  mov      eax,     [eax]
    !  mov      ebx,     eax         ;duplicate ebx = QuadLO
    !  and      ecx,     63          ;RotateVal mod 64
    
    !  shrd     eax,     edx,  cl
    !  shrd     edx,     ebx,  cl
    !  test     ecx,     32          ;RotateVal > 31?
    !  jz       RorStore             ;done if yes
    !  xchg     eax,     edx         ;otherwise rotate edx:eax, 32
    RorStore:
    !  mov      ecx,     pQuad
    !  mov      [ecx],   eax
    !  mov      [ecx+4], edx
    END MACRO
    
    
    '--------------------
    MACRO SHR8_128(XMMReg,ShiftVal)
    !  psrlq    XMMReg,     ShiftVal
    END MACRO
    
    '--------------------
    MACRO SHR8_64(MMXReg,ShiftVal)
    !  psrlq    MMXReg,     ShiftVal
    END MACRO
    
    '--------------------
    MACRO SHR8(pQuad,ShiftVal)
    '-- Destroys eax, ecx, edx
    MACROTEMP SHR8Done
    !  mov      eax,     pQuad
    !  mov      ecx,     ShiftVal
    !  mov      edx,     [eax+4]
    !  mov      eax,     [eax]
    !  and      ecx,     63          ;ShiftVal mod 64
    
    !  shrd     eax,     edx, cl     ;edx:eax shr (ShiftVal mod 32 )
    !  shr      edx,     cl
    !  test     ecx,     32          ;ShiftVal > 31?
    !  jz                SHR8Done    ;done if yes
    !  mov      eax,     edx         ;otherwise shift right edx:eax, 32
    !  xor      edx,     edx
    SHR8Done:
    !  mov      ecx,     pQuad
    !  mov      [ecx],   eax
    !  mov      [ecx+4], edx
    END MACRO
    
    
    '--------------------
    MACRO XOR8(px,py,pz)
    '-- Destroys eax, ebx, ecx, edx
    '-- Returns result at [px]
    !  mov      edx,     pz
    !  mov      ecx,     py
    !  mov      edx,     [edx]
    !  mov      ecx,     [ecx]
    
    !  mov      eax,     px
    !  xor      edx,     ecx         ;edx = (pzLO XOR pyLO)
    !  mov      ebx,     eax         ;save ebx --> px
    !  mov      ecx,     [eax]
    !  xor      edx,     ecx         ;edx = (pzLO XOR pyLO) XOR pxLO
    !  mov      [ebx],   edx         ;store low dword to pxLO
    
    !  mov      ecx,     py
    !  mov      edx,     [eax+4]
    !  mov      ecx,     [ecx+4]
    !  mov      eax,     pz
    !  xor      edx,     ecx         ;edx = (pxHI XOR pyHI)
    
    !  mov      ecx,     [eax+4]
    !  xor      edx,     ecx         ;edx = (pxHI XOR pyHI) XOR pzHI
    !  mov      [ebx+4], edx         ;store hi dword to pxHI
    END MACRO
    
    
    '--------------------
    MACRO Chh128(px,py,pz,presult)
    '-- Chh(x,y,z)=(z XOR (x AND (y XOR z)))
    '-- Returns presult at [presult]
    '-- Destroys eax, ecx, edx, xmm0, xmm1, xmm2
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      edx,     pz
    !  movq     xmm0,    [eax]
    !  movq     xmm1,    [ecx]
    !  movq     xmm2,    [edx]
    
    !  mov      eax,     presult
    !  pxor     xmm1,    xmm2         ;(y XOR z)
    !  pand     xmm0,    xmm1         ;(x AND (y XOR z)))
    !  pxor     xmm2,    xmm0         ;(z XOR (x AND (y XOR z)))
    !  movq     [eax],   xmm2
    END MACRO
    
    '--------------------
    MACRO Chh64(px,py,pz,presult)
    '-- Chh(x,y,z)=(z XOR (x AND (y XOR z)))
    '-- Returns presult at [presult]
    '-- Destroys eax, ecx, edx, mm0, mm1, mm2
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      edx,     pz
    !  movq     mm0,     [eax]
    !  movq     mm1,     [ecx]
    !  movq     mm2,     [edx]
    
    !  mov      eax,     presult
    !  pxor     mm1,     mm2         ;(y XOR z)
    !  pand     mm0,     mm1         ;(x AND (y XOR z)))
    !  pxor     mm2,     mm0         ;(z XOR (x AND (y XOR z)))
    !  movq     [eax],   mm2
    END MACRO
    
    '--------------------
    MACRO Chh(px,py,pz,presult)
    '-- Chh(x,y,z)=(z XOR (x AND (y XOR z)))
    '-- Returns presult at [presult]
    '-- Destroys eax, ecx, edx
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      edx,     pz
    !  mov      eax,     [eax]
    !  mov      ecx,     [ecx]
    !  mov      edx,     [edx]
    
    !  xor      ecx,     edx         ;ecx = (y XOR z)
    !  and      eax,     ecx         ;eax = (x AND (y XOR z))
    !  mov      ecx,     presult
    !  xor      edx,     eax         ;edx = (z XOR (x AND (y XOR z)))
    !  mov      [ecx],   edx
    
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      edx,     pz
    !  mov      eax,     [eax+4]
    !  mov      ecx,     [ecx+4]
    !  mov      edx,     [edx+4]
    
    !  xor      ecx,     edx         ;ecx = (y XOR z)
    !  and      eax,     ecx         ;eax = (x AND (y XOR z))
    !  mov      ecx,     presult
    !  xor      edx,     eax         ;edx = (z XOR (x AND (y XOR z)))
    !  mov      [ecx+4], edx
    END MACRO
    
    
    '--------------------
    MACRO Maj128(px,py,pz,presult)
    '-- Maj(x,y,z)=(((x OR y) AND z) OR (x AND y))
    '-- Destroys eax, ecx, edx, xmm0, xmm1, xmm2, xmm3
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      edx,     pz
    !  movq     xmm0,    [eax]      ;xmm0 = [px]
    !  movq     xmm1,    [ecx]      ;xmm1 = [py]
    !  movdqa   xmm3,    xmm0       ;copy: xmm3 = xmm0 = [px]
    !  movq     xmm2,    [edx]      ;xmm2 = [pz]
    !  por      xmm0,    xmm1       ;xmm0 =  (x OR y)
    !  pand     xmm3,    xmm1       ;xmm3 =  (x AND y)
    !  pand     xmm0,    xmm2       ;xmm0 = ((x OR y) AND z)
    !  mov      eax,     presult
    !  por      xmm0,    xmm3       ;xmm0 = ((x OR y) AND z) OR (x AND y)
    !  movq     [eax],   xmm0
    END MACRO
    
    '--------------------
    MACRO Maj64(px,py,pz,presult)
    '-- Maj(x,y,z)=(((x OR y) AND z) OR (x AND y))
    '-- Destroys eax, ecx, edx, mm0, mm1, mm2, mm3
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      edx,     pz
    !  movq     mm0,     [eax]       ;mm0 = [px]
    !  movq     mm1,     [ecx]       ;mm1 = [py]
    !  movq     mm3,     mm0         ;copy: mm0 = [px]
    !  movq     mm2,     [edx]       ;mm2 = [pz]
    !  por      mm0,     mm1         ;mm0 =  (x OR y)
    !  pand     mm3,     mm1         ;mm3 =  (x AND y)
    !  pand     mm0,     mm2         ;mm0 = ((x OR y) AND z)
    !  mov      eax,     presult
    !  por      mm0,     mm3         ;mm0 = ((x OR y) AND z) OR (x AND y)
    !  movq     [eax],   mm0
    END MACRO
    
    '--------------------
    MACRO Maj(px,py,pz,presult)
    '-- Maj(x,y,z)=(((x OR y) AND z) OR (x AND y))
    '-- Destroys eax, ebx, ecx, edx
    !  push     esi
    !  push     edi
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      edx,     pz
    !  mov      eax,     [eax]       ;eax = [pxLO]
    !  mov      esi,     [ecx]       ;esi = [pyLO]
    !  mov      edi,     [edx]       ;edi = [pzLO]
    !  mov      ebx,     eax         ;copy: ebx = pxLO
    !  or       eax,     esi         ;eax =  (x OR y)
    !  and      ebx,     esi         ;ebx =  (x AND y)
    !  and      eax,     edi         ;eax = ((x OR y) AND z)
    !  or       eax,     ebx         ;eax = ((x OR y) AND z) OR (x AND y)
    !  mov      edi,     presult
    !  mov      [edi],   eax         ;presultLO
    
    !  mov      eax,     px
    !  mov      ecx,     py
    !  mov      eax,     [eax+4]     ;eax = [pxHI]
    !  mov      esi,     [ecx+4]     ;esi = [pyHI]
    !  mov      edi,     [edx+4]     ;edi = [pzHI]
    !  mov      ebx,     eax         ;save: ebx = pxHI
    !  or       eax,     esi         ;eax =  (x OR y)
    !  and      ebx,     esi         ;ebx =  (x AND y)
    !  and      eax,     edi         ;eax = ((x OR y) AND z)
    !  or       eax,     ebx         ;eax = ((x OR y) AND z) OR (x AND y)
    !  mov      edi,     presult
    !  mov      [edi+4], eax         ;presultHI
    !  pop      edi
    !  pop      esi
    END MACRO
    
    
    '--------------------
    MACRO Sigma0_128(pn,presult)
    '-- Destroys edx, xmm0, xmm1, xmm2
    !  mov      edx,     pn
    !  movq     xmm0,    [edx]
    !  movdqa   xmm1,    xmm0
    !  movdqa   xmm2,    xmm0
    ROR8_128(xmm0,28) : ROR8_128(xmm1,34) : ROR8_128(xmm2,39)
    !  pxor     xmm0,    xmm1
    !  mov      edx,     presult
    !  pxor     xmm0,    xmm2
    !  movq     [edx],   xmm0
    END MACRO
    
    '--------------------
    MACRO Sigma0_64(pn,presult)
    '-- Destroys edx, mm0, mm1, mm2
    !  mov      edx,     pn
    !  movq     mm0,     [edx]
    !  movq     mm1,     mm0
    !  movq     mm2,     mm0
    ROR8_64(mm0,28) : ROR8_64(mm1,34) : ROR8_64(mm2,39)
    !  pxor     mm0,     mm1
    !  mov      edx,     presult
    !  pxor     mm0,     mm2
    !  movq     [edx],   mm0
    END MACRO
    
    '--------------------
    MACRO Sigma0(pn,presult)
    Copy8XtoY(pn,xx) : Copy8XtoY(pn,yy) : Copy8XtoY(pn,zz)
    ROR8(xx,28)      : ROR8(yy,34)      : ROR8(zz,39)
    XOR8(xx,yy,zz)
    Copy8XtoY(xx,presult)
    END MACRO
    
    
    '--------------------
    MACRO Sigma1_128(pn,presult)
    '-- Destroys edx, xmm0, xmm1, xmm2
    !  mov      edx,     pn
    !  movq     xmm0,    [edx]
    !  movdqa   xmm1,    xmm0
    !  movdqa   xmm2,    xmm0
    ROR8_128(xmm0,14) : ROR8_128(xmm1,18) : ROR8_128(xmm2,41)
    !  pxor     xmm0,    xmm1
    !  mov      edx,     presult
    !  pxor     xmm0,    xmm2
    !  movq     [edx],   xmm0
    END MACRO
    
    '--------------------
    MACRO Sigma1_64(pn,presult)
    '-- Destroys edx, mm0, mm1, mm2
    !  mov      edx,     pn
    !  movq     mm0,     [edx]
    !  movq     mm1,     mm0
    !  movq     mm2,     mm0
    ROR8_64(mm0,14) : ROR8_64(mm1,18) : ROR8_64(mm2,41)
    !  pxor     mm0,     mm1
    !  mov      edx,     presult
    !  pxor     mm0,     mm2
    !  movq     [edx],   mm0
    END MACRO
    
    '--------------------
    MACRO Sigma1(pn,presult)
    Copy8XtoY(pn,xx) : Copy8XtoY(pn,yy) : Copy8XtoY(pn,zz)
    ROR8(xx,14)      : ROR8(yy,18)      : ROR8(zz,41)
    XOR8(xx,yy,zz)
    Copy8XtoY(xx,presult)
    END MACRO
    
    
    '--------------------
    MACRO Gamma0_128(pn,presult)
    '-- Destroys edx, xmm0, xmm1, xmm2
    !  mov      edx,     pn
    !  movq     xmm0,    [edx]
    !  movdqa   xmm1,    xmm0
    !  movdqa   xmm2,    xmm0
    ROR8_128(xmm0,1) : ROR8_128(xmm1,8) : SHR8_128(xmm2,7)
    !  pxor     xmm0,    xmm1
    !  mov      edx,     presult
    !  pxor     xmm0,    xmm2
    !  movq     [edx],   xmm0
    END MACRO
    
    '--------------------
    MACRO Gamma0_64(pn,presult)
    '-- Destroys edx, mm0, mm1, mm2
    !  mov      edx,     pn
    !  movq     mm0,     [edx]
    !  movq     mm1,     mm0
    !  movq     mm2,     mm0
    ROR8_64(mm0,1) : ROR8_64(mm1,8) : SHR8_64(mm2,7)
    !  pxor     mm0,     mm1
    !  mov      edx,     presult
    !  pxor     mm0,     mm2
    !  movq     [edx],   mm0
    END MACRO
    
    '--------------------
    MACRO Gamma0(pn,presult)
    Copy8XtoY(pn,xx) : Copy8XtoY(pn,yy) : Copy8XtoY(pn,zz)
    ROR8(xx,1)       : ROR8(yy,8)       : SHR8(zz,7)
    XOR8(xx,yy,zz)
    Copy8XtoY(xx,presult)
    END MACRO
    
    
    '--------------------
    MACRO Gamma1_128(pn,presult)
    '-- Destroys edx, xmm0, xmm1, xmm2
    !  mov      edx,     pn
    !  movq     xmm0,    [edx]
    !  movdqa   xmm1,    xmm0
    !  movdqa   xmm2,    xmm0
    ROR8_128(xmm0,19) : ROR8_128(xmm1,61) : SHR8_128(xmm2,6)
    !  pxor     xmm0,    xmm1
    !  mov      edx,     presult
    !  pxor     xmm0,    xmm2
    !  movq     [edx],   xmm0
    END MACRO
    
    '--------------------
    MACRO Gamma1_64(pn,presult)
    '-- Destroys edx, mm0, mm1, mm2
    !  mov      edx,     pn
    !  movq     mm0,     [edx]
    !  movq     mm1,     mm0
    !  movq     mm2,     mm0
    ROR8_64(mm0,19) : ROR8_64(mm1,61) : SHR8_64(mm2,6)
    !  pxor     mm0,     mm1
    !  mov      edx,     presult
    !  pxor     mm0,     mm2
    !  movq     [edx],   mm0
    END MACRO
    
    '--------------------
    MACRO Gamma1(pn,presult)
    Copy8XtoY(pn,xx) : Copy8XtoY(pn,yy) : Copy8XtoY(pn,zz)
    ROR8(xx,19)      : ROR8(yy,61)      : SHR8(zz,6)
    XOR8(xx,yy,zz)
    Copy8XtoY(xx,presult)
    END MACRO
    
    
    '--------------------
    MACRO Copy8XtoY128(px,py)
    '-- Destroys eax, edx, xmm0
    !  mov      eax,     px
    !  mov      edx,     py
    !  movq     xmm0,    [eax]
    !  movq     [edx],   xmm0
    END MACRO
    
    '--------------------
    MACRO Copy8XtoY64(px,py)
    '-- Destroys eax, edx, mm0
    !  mov      eax,     px
    !  mov      edx,     py
    !  movq     mm0,     [eax]
    !  movq     [edx],   mm0
    END MACRO
    
    '--------------------
    MACRO Copy8XtoY(px,py)
    '-- Destroys eax, ebx, ecx, edx
    !  mov      eax,     px
    !  mov      edx,     py
    !  mov      ebx,     [eax]
    !  mov      ecx,     [eax+4]
    !  mov      [edx],   ebx
    !  mov      [edx+4], ecx
    END MACRO
    
    
    '--------------------
    MACRO Add8XtoY128(px,py)
    '-- Destroys eax, edx, xmm6, xmm7
    !  mov      edx,     py          ;edx --> y throughout (target)
    !  mov      eax,     px          ;eax --> x throughout
    !  movq     xmm6,    [edx]
    !  movq     xmm7,    [eax]
    !  paddq    xmm6,    xmm7
    !  movq     [edx],   xmm6
    END MACRO
    
    '--------------------
    MACRO Add8XtoY64(px,py)
    Add8XtoY(px,py)
    END MACRO
    
    '--------------------
    MACRO Add8XtoY(px,py)
    '-- Destroys eax, ebx, ecx, edx
    !  mov      edx,     py          ;edx --> y throughout (target)
    !  mov      eax,     px          ;eax --> x throughout
    !  mov      ecx,     [edx]       ;ecx  = y[0]
    !  add      ecx,     [eax]       ;y[0] = y[0] + x[0]
    !  mov      [edx],   ecx         ;store to y[0]
    !  mov      ecx,     [edx+4]     ;ecx = y[3]
    !  adc      ecx,     [eax+4]     ;ecx = y[3] + x[3]
    !  mov      [edx+4], ecx         ;store to y[3]
    END MACRO



    Code:
    ' PowerSHA512.inc
    '
    '
    '=====================================================================
    ' This class 'PowerSHA512.inc' was generated
    ' from the following code:
    '=====================================================================
    '-- Implementation of the SHA512 secure hash algorithm
    '-- Compiles with either PBWIN 9+ or PBCC 5+
    '-- WIN32 API not required
    '-- Uses no global data
    '   Greg Turgeon  10/2008
    '   http://www.powerbasic.com/support/pbforums/showthread.php?t=38747
    '=====================================================================
    ' The class can also be compiled as SLL:
    '---------------------------------------------------------------------
    ' #COMPILE SLL "PowerSHA512.sll"
    ' #DIM ALL
    ' %UNICODE = 1
    ' #INCLUDE "win32api.inc"
    '=====================================================================
    
    
    $C_POWER_SHA512_DATA_CID             = GUID$("{A350F17D-3A60-487B-B241-4980EA745416}")
    $C_POWER_SHA512_DATA_IID             = GUID$("{D0F50941-CB74-4CC0-AED5-E6566D9E3E53}")
    $C_POWER_SHA512_MAIN_CID             = GUID$("{DF0873F9-FB84-4F09-9FD6-405DDABDD3A1}")
    $C_POWER_SHA512_MAIN_IID             = GUID$("{43FEDEFD-E6B9-4477-9845-B7068F63543F}")
    
    
    
    
    %C_POWER_SHA512_RETURN_LITTLE_ENDIAN = %TRUE                            '-- Set to %FALSE to return big-endian hash$
    %C_POWER_SHA512_ALIGNMENT            = 16
    %C_POWER_SHA512_HASHLEN              = 64                               'bytes
    %C_POWER_SHA512_BLOCKSIZE            = 128                              'bytes
    %C_POWER_SHA512_FILE_BUFFERSIZE      = 32768                            'bytes
    %C_POWER_SHA512_WORKSPACESIZE        = ((8*8)+(80*8)+(8*8))             's_array+w_array+xx,t0,t1,etc.
    
    
    
    TYPE SHA512_CONTEXT
       stat((%C_POWER_SHA512_HASHLEN\8)+(%C_POWER_SHA512_ALIGNMENT\8)) AS QUAD      'here, 80 bytes
       lendata     AS DWORD
       pdata       AS BYTE PTR
       pstate      AS QUAD PTR
       k_array     AS QUAD PTR
       s_array     AS BYTE PTR
       w_array     AS BYTE PTR
       pworkspace  AS BYTE PTR
       dummy1      AS LONG                             'padding for 64-byte alignment
       workspace   AS STRING * (%C_POWER_SHA512_WORKSPACESIZE + %C_POWER_SHA512_ALIGNMENT)
    END TYPE
    
    
    '#ALIGN 16
    ASMDATA K_Array_Data
        DD  &hD728AE22,&h428A2F98,  &h23EF65CD,&h71374491,  &hEC4D3B2F,&hB5C0FBCF,  &h8189DBBC,&hE9B5DBA5
        DD  &hF348B538,&h3956C25B,  &hB605D019,&h59F111F1,  &hAF194F9B,&h923F82A4,  &hDA6D8118,&hAB1C5ED5
        DD  &hA3030242,&hD807AA98,  &h45706FBE,&h12835B01,  &h4EE4B28C,&h243185BE,  &hD5FFB4E2,&h550C7DC3
        DD  &hF27B896F,&h72BE5D74,  &h3B1696B1,&h80DEB1FE,  &h25C71235,&h9BDC06A7,  &hCF692694,&hC19BF174
        DD  &h9EF14AD2,&hE49B69C1,  &h384F25E3,&hEFBE4786,  &h8B8CD5B5,&h0FC19DC6,  &h77AC9C65,&h240CA1CC
        DD  &h592B0275,&h2DE92C6F,  &h6EA6E483,&h4A7484AA,  &hBD41FBD4,&h5CB0A9DC,  &h831153B5,&h76F988DA
        DD  &hEE66DFAB,&h983E5152,  &h2DB43210,&hA831C66D,  &h98FB213F,&hB00327C8,  &hBEEF0EE4,&hBF597FC7
        DD  &h3DA88FC2,&hC6E00BF3,  &h930AA725,&hD5A79147,  &hE003826F,&h06CA6351,  &h0A0E6E70,&h14292967
        DD  &h46D22FFC,&h27B70A85,  &h5C26C926,&h2E1B2138,  &h5AC42AED,&h4D2C6DFC,  &h9D95B3DF,&h53380D13
        DD  &h8BAF63DE,&h650A7354,  &h3C77B2A8,&h766A0ABB,  &h47EDAEE6,&h81C2C92E,  &h1482353B,&h92722C85
        DD  &h4CF10364,&hA2BFE8A1,  &hBC423001,&hA81A664B,  &hD0F89791,&hC24B8B70,  &h0654BE30,&hC76C51A3
        DD  &hD6EF5218,&hD192E819,  &h5565A910,&hD6990624,  &h5771202A,&hF40E3585,  &h32BBD1B8,&h106AA070
        DD  &hB8D2D0C8,&h19A4C116,  &h5141AB53,&h1E376C08,  &hDF8EEB99,&h2748774C,  &hE19B48A8,&h34B0BCB5
        DD  &hC5C95A63,&h391C0CB3,  &hE3418ACB,&h4ED8AA4A,  &h7763E373,&h5B9CCA4F,  &hD6B2B8A3,&h682E6FF3
        DD  &h5DEFB2FC,&h748F82EE,  &h43172F60,&h78A5636F,  &hA1F0AB72,&h84C87814,  &h1A6439EC,&h8CC70208
        DD  &h23631E28,&h90BEFFFA,  &hDE82BDE9,&hA4506CEB,  &hB2C67915,&hBEF9A3F7,  &hE372532B,&hC67178F2
        DD  &hEA26619C,&hCA273ECE,  &h21C0C207,&hD186B8C7,  &hCDE0EB1E,&hEADA7DD6,  &hEE6ED178,&hF57D4F7F
        DD  &h72176FBA,&h06F067AA,  &hA2C898A6,&h0A637DC5,  &hBEF90DAE,&h113F9804,  &h131C471B,&h1B710B35
        DD  &h23047D84,&h28DB77F5,  &h40C72493,&h32CAAB7B,  &h15C9BEBC,&h3C9EBE0A,  &h9C100D4C,&h431D67C4
        DD  &hCB3E42B6,&h4CC5D4BE,  &hFC657E2A,&h597F299C,  &h3AD6FAEC,&h5FCB6FAB,  &h4A475817,&h6C44198C
    END ASMDATA
    
    
    CLASS cSHA512main $C_POWER_SHA512_MAIN_CID COMMON
    INSTANCE ThreadParam          AS DWORD
    INSTANCE iDataFace            AS iSHA512data
    INSTANCE m_hashmem            AS STRING * %C_POWER_SHA512_HASHLEN
    INSTANCE m_ctx                AS SHA512_CONTEXT
    INSTANCE m_compress           AS LONG
    INSTANCE m_bytesleft          AS QUAD
    INSTANCE m_buffer             AS STRING
    INSTANCE m_padding            AS STRING
    INSTANCE m_hashptr            AS DWORD
    INSTANCE m_hFile              AS DWORD
    INSTANCE m_lastpass           AS LONG
    INSTANCE m_maxstring          AS LONG
    INSTANCE m_Cancel             AS LONG
    INSTANCE m_Status_Count       AS LONG
    INSTANCE m_Status_Index       AS LONG
    INSTANCE m_Status_Percent     AS LONG
    INSTANCE m_Status_Bytes       AS QUAD
    INSTANCE m_Status_Total       AS QUAD
    INSTANCE m_Status_Bytes_1P    AS QUAD
    INSTANCE m_Status_Bytes_tmp   AS QUAD
    
        THREAD METHOD MAIN() AS LONG
        LOCAL file AS WSTRINGZ * %MAX_PATH
        LOCAL hash AS STRING
        LOCAL aerr AS LONG
        LOCAL i    AS LONG
        LOCAL lb   AS LONG
        LOCAL ub   AS LONG
            lb = iDataFace.p_lbound
            ub = iDataFace.p_ubound
            FOR i = lb TO ub
                IF ( iDataFace.GetError(i) = 0 ) THEN
                    INCR m_Status_Count
                    m_Status_Index = i
                    file = iDataFace.GetFile(i)
                    aerr = me.calcFile (file)
                    hash = IIF$(aerr=0,me.HexHash(),"")
                    CALL iDataFace.SetHash(i,hash)
                    CALL iDataFace.SetError(i,aerr)
                END IF
                IF ( ISTRUE m_Cancel ) THEN EXIT METHOD
            NEXT i
            IF ( m_Status_Bytes = m_Status_Total ) THEN
                m_Status_Percent  = 100
            END IF
        END METHOD
    
    
        '====================
        CLASS METHOD HexHash() THREADSAFE AS STRING
        LOCAL bHash AS BYTE PTR
        LOCAL rHash AS STRING
        LOCAL i     AS LONG
            bHash = m_hashptr
            FOR i = 0 TO %C_POWER_SHA512_HASHLEN - 1
                rHash = rHash + HEX$(@bHash[i],2)
            NEXT i
            METHOD = LCASE$(rHash)
        END METHOD
    
    
        '====================
        CLASS METHOD Compress128()
        '-- Requires SSE2
        '-- In macros, EBX is considered always available; ESI & EDI are
        '   preserved around use
        #REGISTER NONE
        LOCAL i, x, xx, t0, t1, pstate, result AS LONG
        LOCAL s_array, w_array, k_array AS LONG
        LOCAL aa, bb, cc, ddd, ee, ff, gg, hh AS LONG
    
            s_array = m_ctx.s_array : w_array = m_ctx.w_array : k_array = m_ctx.k_array
    
            '-- Local vars aa-hh overlay s_array&&(0-7)
            aa = s_array    : bb = s_array+8  : cc = s_array+16 : ddd = s_array+24
            ee = s_array+32 : ff = s_array+40 : gg = s_array+48 : hh  = s_array+56
            xx = m_ctx.pworkspace : t0 = xx+16  : t1 = xx+32      : result = xx+48
    
            i = m_ctx.pdata
            pstate = m_ctx.pstate
    
            !  push     ebx
            !  push     esi
            !  push     edi
    
            '-- Copy current state into s_array&&()
            'poke$ s, peek$(Ctx.pstate, %HASHLEN)
            !  mov      esi,     pstate
            !  mov      edi,     s_array
            !  movdqa   xmm0,    [esi]
            !  movdqa   xmm1,    [esi+16]
            !  movdqa   xmm2,    [esi+32]
            !  movdqa   xmm3,    [esi+48]
            !  movdqa   [edi],   xmm0
            !  movdqa   [edi+16],xmm1
            !  movdqa   [edi+32],xmm2
            !  movdqa   [edi+48],xmm3
    
            '-- Copy target data into w&&(0-15) w/64-bit little-to-big endian conversion
            !  mov      esi,     i              ;i = Ctx.pdata = unaligned
            !  mov      edi,     w_array
            !  mov      ecx,     %C_POWER_SHA512_BLOCKSIZE
            '-- 64-bit BSWAP * 2 /loop
            #ALIGN 16
            BSwapCopyTop:
            !  sub      ecx,     16
            !  movdqu   xmm0,    [esi+ecx]
    
            !  sub      ecx,     16
            !  movdqu   xmm2,    [esi+ecx]
    
            !  movdqa   xmm1,    xmm0
            !  movdqa   xmm3,    xmm2
    
            !  psllw    xmm0,    8
            !  psllw    xmm2,    8
    
            !  psrlw    xmm1,    8
            !  psrlw    xmm3,    8
    
            !  por      xmm0,    xmm1
            !  por      xmm2,    xmm3
    
            !  pshufhw  xmm0,    xmm0, &b00011011
            !  pshufhw  xmm2,    xmm2, &b00011011
    
            !  pshuflw  xmm0,    xmm0, &b00011011
            !  pshuflw  xmm2,    xmm2, &b00011011
    
            !  movdqa   [edi+ecx+16],  xmm0
            !  movdqa   [edi+ecx],     xmm2
            !  test     ecx,     ecx
            !  jnz      BSwapCopyTop
    
            '-- Fill w&&(16-79)
            '   for i = 16 to 79
            '      @w[i] = Gamma1(@w[i-2]) + @w[i-7] + Gamma0(@w[i-15]) + @w[i-16]
            '   next i
            !  mov      esi,     16             ;edi = w_array from above
            #ALIGN 16
            TopLoop1:
               !  mov      ebx,     esi
               !  sub      ebx,     2
               !  lea      eax,     [edi+ebx*8] ;x = w+((i-2)*8)
               !  mov      x,       eax         ;x --> w[i-2]
               Gamma1_128(x,result)             'result = Gamma1(@w[i-2])
    
               !  mov      ebx,     esi
               !  mov      edx,     result
               !  sub      ebx,     7
               !  lea      eax,     [edi+ebx*8] ;eax --> @w[i-7]
               '!  mov      x,    eax         ;x --> w[i-2]
               'Add8XtoY128(x,result)        'result = result + @w[i-2]
               !  movq     xmm6,    [edx]
               !  movq     xmm7,    [eax]
               !  paddq    xmm6,    xmm7
               !  movq     [edx],   xmm6
    
               !  mov      ebx,     esi
               !  sub      ebx,     15
               !  lea      eax,     [edi+ebx*8]
               !  mov      x,       eax         ;x --> w[i-15]
               Gamma0_128(x,xx)
               Add8XtoY128(xx,result)          'result = result + Gamma0(@w[i-15])
    
               !  mov      ebx,     esi
               !  mov      edx,     result
               !  sub      ebx,     16
               'Add8XtoY128(x,result)          'result = result + @w[i-16]
               !  lea      eax,     [edi+ebx*8] ;eax --> @w[i-16]
               !  movq     xmm6,    [edx]
               !  movq     xmm7,    [eax]
               !  paddq    xmm6,    xmm7
               !  movq     [edx],   xmm6
    
               !  lea      eax,     [edi+esi*8] ;x = w+(i*8)
               !  mov      edx,     result
               'Copy8XtoY128(result,x)         '@w[i] = @result
               !  movq     xmm0,    [edx]
               !  movq     [eax],   xmm0
    
            !  inc      esi
            !  cmp      esi,     79
            !  jng      TopLoop1
    
            'for i = 79 to 0 step -1
            !  xor      esi,     esi
            !  mov      edi,     80
            #ALIGN 16
            TopLoop2:
               't0 = @hh + Sigma1&&(@ee) + Chh(@ee, @ff, @gg) + @CTX.k_array[i] + @w[i]
               Copy8XtoY128(hh,t0)
               Sigma1_128(ee,result)
               Add8XtoY128(result,t0)
               Chh128(ee,ff,gg,result)
               Add8XtoY128(result,t0)
    
               !  mov      ebx,     k_array
               !  mov      edx,     t0
               !  lea      eax,     [ebx+esi]
               'Add8XtoY128(x,t0)
               !  movq     xmm6,    [edx]
               !  movq     xmm7,    [eax]
               !  paddq    xmm6,    xmm7
               !  movq     [edx],   xmm6
    
               !  mov      ebx,     w_array
               !  lea      eax,     [ebx+esi]
               'Add8XtoY128(x,t0)
               !  movq     xmm6,    [edx]
               !  movq     xmm7,    [eax]
               !  paddq    xmm6,    xmm7
               !  movq     [edx],   xmm6
    
               Sigma0_128(aa,t1)
               Maj128(aa,bb,cc,result)
               Add8XtoY128(result,t1)
    
               'Copy8XtoY64(gg,hh)
               'Copy8XtoY64(ff,gg)
               'Copy8XtoY64(ee,ff)
               'Copy8XtoY64(ddd,ee)
               '-- aa, cc, ee, gg = aligned
               !  mov      edx,     gg
               !  mov      ecx,     ff
               !  mov      ebx,     ee
               !  mov      eax,     ddd
               !  movq     xmm3,    [edx]
               !  movq     xmm2,    [ecx]
               !  movq     xmm1,    [ebx]
               !  movq     xmm0,    [eax]
               !  movq     [edx+8], xmm3
               !  movq     [edx],   xmm2
               !  movq     [ecx],   xmm1
               !  movq     [ebx],   xmm0
               Add8XtoY128(t0,ee)
    
               'Copy8XtoY64(cc,ddd)
               'Copy8XtoY64(bb,cc)
               'Copy8XtoY64(aa,bb)
               '@aa = t0 + t1
               !  mov      ecx,     cc
               !  mov      ebx,     bb
               !  mov      eax,     aa
               !  mov      edx,     t0
               !  movq     xmm3,    [ecx]
               !  movq     xmm2,    [ebx]
               !  movq     xmm1,    [eax]
               !  movq     xmm0,    [edx]
               !  movq     [ecx+8], xmm3
               !  movq     [ecx],   xmm2
               !  movq     [ebx],   xmm1
               !  movq     [eax],   xmm0
               Add8XtoY128(t1,aa)
            'next i
            !  add      esi,  8
            !  dec      edi
            !  jnz      TopLoop2
    
            'for i = 0 to 7 : CTX.@pstate[i] = CTX.@pstate[i] + @s[i] : next i
            !  mov      esi,     s_array        ;esi --> s_array&&(0) (aligned)
            !  mov      edi,     pstate         ;edi --> Ctx.State(0)
    
            !  movdqa   xmm0,    [edi]
            !  movdqa   xmm1,    [edi+16]
            !  movdqa   xmm2,    [edi+32]
            !  movdqa   xmm3,    [edi+48]
    
            !  paddq    xmm0,    [esi]
            !  paddq    xmm1,    [esi+16]
            !  paddq    xmm2,    [esi+32]
            !  paddq    xmm3,    [esi+48]
    
            !  movdqa   [edi],      xmm0
            !  movdqa   [edi+16],   xmm1
            !  movdqa   [edi+32],   xmm2
            !  movdqa   [edi+48],   xmm3
    
            '-- Burn context's temp values (poke$ Ctx.pworkspace, nul$(%WORKSPACESIZE))
            !  mov      ecx,        %C_POWER_SHA512_WORKSPACESIZE
            !  pxor     xmm0,       xmm0
            !  lea      edi,        [esi+ecx]   ;point to end of workspace
            !  pxor     xmm1,       xmm1
            !  neg      ecx
            BurnTop:
            !  movdqa   [edi+ecx],  xmm0
            !  movdqa   [edi+ecx+16],  xmm0
            !  add      ecx,        32
            !  jnz      BurnTop
    
            !  pop      edi
            !  pop      esi
            !  pop      ebx
        END METHOD
    
    
        '====================
        CLASS METHOD Compress64()
        '-- Requires MMX
        '-- In macros, EBX is considered always available; ESI & EDI are
        '   preserved around use
        #REGISTER NONE
        LOCAL i, x, xx, yy, zz, pstate, t0, t1, result AS LONG
        LOCAL s_array, w_array, k_array AS LONG
        LOCAL aa, bb, cc, ddd, ee, ff, gg, hh AS LONG
    
            s_array = m_ctx.s_array : w_array = m_ctx.w_array : k_array = m_ctx.k_array
    
            '-- Local vars aa-hh overlay s_array&&(0-7)
            aa = s_array    : bb = s_array+8  : cc = s_array+16 : ddd = s_array+24
            ee = s_array+32 : ff = s_array+40 : gg = s_array+48 : hh  = s_array+56
            xx = m_ctx.pworkspace : yy = xx+8   : zz  = xx+16
            t0 = xx+24 : t1 = xx+32 : result = xx+40
    
            i = m_ctx.pdata
            pstate = m_ctx.pstate
    
            !  push     ebx
            !  push     esi
            !  push     edi
            '-- Copy current state into s_array&&()
            'poke$ s, peek$(Ctx.pstate, %HASHLEN)
            !  mov      esi,     pstate
            !  mov      edi,     s_array
            !  movq     mm0,     [esi]
            !  movq     mm1,     [esi+8]
            !  movq     mm2,     [esi+16]
            !  movq     mm3,     [esi+24]
            !  movq     mm4,     [esi+32]
            !  movq     mm5,     [esi+40]
            !  movq     mm6,     [esi+48]
            !  movq     mm7,     [esi+56]
            !  movq     [edi],   mm0
            !  movq     [edi+8], mm1
            !  movq     [edi+16],mm2
            !  movq     [edi+24],mm3
            !  movq     [edi+32],mm4
            !  movq     [edi+40],mm5
            !  movq     [edi+48],mm6
            !  movq     [edi+56],mm7
    
            '-- Copy target data into w&&(0-15) w/64-bit little-to-big endian conversion
            !  mov      esi,     i
            !  mov      edi,     w_array
            !  mov      ecx,     %C_POWER_SHA512_BLOCKSIZE
            #ALIGN 4
            BSwapCopyTop:
            !  sub      ecx,     4
            !  mov      eax,     [esi+ecx]
            !  sub      ecx,     4
            !  bswap    eax
            !  mov      edx,     [esi+ecx]
            !  mov      [edi+ecx], eax
            !  bswap    edx
            !  test     ecx,     ecx
            !  mov      [edi+ecx+4], edx
            !  jnz      BSwapCopyTop
    
            '-- Fill w&&(16-79)
            '   for i = 16 to 79
            '      @w[i] = Gamma1(@w[i-2]) + @w[i-7] + Gamma0(@w[i-15]) + @w[i-16]
            '   next i
            !  mov         esi,  16          'edi = w from above
            #ALIGN 8
            TopLoop1:
               !  mov      ebx,  esi
               !  sub      ebx,  2
               !  lea      eax,  [edi+ebx*8] ;x = w+((i-2)*8)
               !  mov      x,    eax         ;x --> w[i-2]
               Gamma1_64(x,result)           'result = Gamma1(@w[i-2])
    
               !  mov      ebx,  esi
               !  sub      ebx,  7
               !  lea      eax,  [edi+ebx*8]
               !  mov      x,    eax         ;x --> @w[i-7] (x = w+((i-7)*8))
               Add8XtoY64(x,result)            'result = result + @w[i-7]
    
               !  mov      ebx,  esi
               !  sub      ebx,  15
               !  lea      eax,  [edi+ebx*8]
               !  mov      x,    eax         ;x --> w[i-15]
               Gamma0_64(x,xx)
               Add8XtoY64(xx,result)           'result = result + Gamma0(@w[i-15])
    
               !  mov      ebx,  esi
               !  sub      ebx,  16
               !  lea      eax,  [edi+ebx*8]
               !  mov      x,    eax         ;x --> @w[i-16]
               Add8XtoY64(x,result)            'result = result + @w[i-16]
    
               !  mov      edx,  result
               !  lea      eax,  [edi+esi*8] ;x = w+(i*8) (@w[i])
               'Copy8XtoY64(result,x)       '@w[i] = @result
               !  movq     mm0,  [edx]
               !  movq     [eax],mm0
    
            !  inc      esi
            !  cmp      esi,     79
            !  jng      TopLoop1
    
            'for i = 79 to 0 step -1
            !  xor      esi,     esi
            !  mov      edi,     80
            #ALIGN 8
            TopLoop2:
               't0 = @hh + Sigma1&&(@ee) + Chh(@ee, @ff, @gg) + @CTX.k_array[i] + @w[i]
               Copy8XtoY64(hh,t0)
               Sigma1_64(ee,result)
               Add8XtoY64(result,t0)
               Chh64(ee,ff,gg,result)
               Add8XtoY64(result,t0)
    
               !  mov      ebx,  k_array
               !  lea      eax,  [ebx+esi]
               !  mov      x,    eax
               Add8XtoY64(x,t0)
    
               !  mov      ebx,   w_array
               !  lea      eax,   [ebx+esi]
               !  mov      x,     eax
               Add8XtoY64(x,t0)
    
               Sigma0_64(aa,t1)
               Maj64(aa,bb,cc,result)
               Add8XtoY64(result,t1)
    
               'Copy8XtoY64(gg,hh)
               'Copy8XtoY64(ff,gg)
               'Copy8XtoY64(ee,ff)
               'Copy8XtoY64(ddd,ee)
               !  mov      edx,     gg
               !  mov      ecx,     ff
               !  mov      ebx,     ee
               !  mov      eax,     ddd
               !  movq     mm3,     [edx]
               !  movq     mm2,     [ecx]
               !  movq     mm1,     [ebx]
               !  movq     mm0,     [eax]
               !  movq     [edx+8], mm3
               !  movq     [edx],   mm2
               !  movq     [ecx],   mm1
               !  movq     [ebx],   mm0
               Add8XtoY64(t0,ee)
    
               'Copy8XtoY64(cc,ddd)
               'Copy8XtoY64(bb,cc)
               'Copy8XtoY64(aa,bb)
               '@aa = t0 + t1
               !  mov      ecx,     cc
               !  mov      ebx,     bb
               !  mov      eax,     aa
               !  mov      edx,     t0
               !  movq     mm3,     [ecx]
               !  movq     mm2,     [ebx]
               !  movq     mm1,     [eax]
               !  movq     mm0,     [edx]
               !  movq     [ecx+8], mm3
               !  movq     [ecx],   mm2
               !  movq     [ebx],   mm1
               !  movq     [eax],   mm0
               Add8XtoY64(t1,aa)
            'next i
            !  add      esi,     8
            !  dec      edi
            !  jnz      TopLoop2
    
            'for i = 0 to 7 : CTX.@pstate[i] = CTX.@pstate[i] + @s[i] : next i
            !  mov      eax,     s_array     ;eax --> s_array&&(0)
            !  mov      edx,     pstate      ;edx --> Ctx.State(0)
            !  mov      xx,      eax         ;xx  --> s_array&&(0)
            !  mov      yy,      edx         ;yy  --> Ctx.state0
            !  mov      edi,     8
            !  mov      esi,     7
            Add8XtoY64(xx,yy)
            #ALIGN 4
            TopLoop3:
               'advance pointers
               !  add      xx,   edi         ;xx --> s[i]
               !  add      yy,   edi         ;yy --> pcurrent_state[i]
               Add8XtoY64(xx,yy)
            !  dec      esi
            !  jnz      TopLoop3
    
            '-- Burn context's temp values (poke$ Ctx.pworkspace, nul$(%WORKSPACESIZE))
            !  mov      edi,     s_array
            !  xor      eax,     eax
            !  mov      ecx,     (%C_POWER_SHA512_WORKSPACESIZE\4)
            !  cld
            !  rep      stosd
    
            !  pop      edi
            !  pop      esi
            !  pop      ebx
            !  emms
        END METHOD
    
    
        '====================
        CLASS METHOD Compress32()
        '-- Uses 32-bit code only
        '-- In macros, EBX is considered always available; ESI & EDI are
        '   preserved around use
        #REGISTER NONE
        LOCAL i, x, xx, yy, zz, pstate, t0, t1, result AS LONG
        LOCAL s_array, w_array, k_array AS LONG
        LOCAL aa, bb, cc, ddd, ee, ff, gg, hh AS LONG
    
            s_array = m_ctx.s_array : w_array = m_ctx.w_array : k_array = m_ctx.k_array
            '-- Local vars aa-hh overlay s_array&&(0-7)
            aa = s_array    : bb = s_array+8  : cc = s_array+16 : ddd = s_array+24
            ee = s_array+32 : ff = s_array+40 : gg = s_array+48 : hh  = s_array+56
            xx = m_ctx.pworkspace : yy = xx+8   : zz  = xx+16
            t0 = xx+24 : t1 = xx+32 : result = xx+40
    
            pstate = m_ctx.pstate
            '-- Copy current state into s_array&&()
            POKE$ s_array, PEEK$(pstate, %C_POWER_SHA512_HASHLEN)
    
            '-- Copy target data into w&&(0-15) w/64-bit little-to-big endian conversion
            i = m_ctx.pdata
            !  push     ebx
            !  push     esi
            !  push     edi
    
            !  mov      esi,  i
            !  mov      edi,  w_array
            !  mov      ecx,  %C_POWER_SHA512_BLOCKSIZE
            #ALIGN 4
            BSwapCopyTop:
            !  sub      ecx,  4
            !  mov      eax,  [esi+ecx]
            !  sub      ecx,  4
            !  bswap    eax
            !  mov      edx,  [esi+ecx]
            !  mov      [edi+ecx], eax
            !  bswap    edx
            !  test     ecx,  ecx
            !  mov      [edi+ecx+4], edx
            !  jnz      BSwapCopyTop
    
            '-- Fill w&&(16-79)
            '   for i = 16 to 79
            '      @w[i] = Gamma1(@w[i-2]) + @w[i-7] + Gamma0(@w[i-15]) + @w[i-16]
            '   next i
            !  mov      esi,  16             ;edi = w from above
            #ALIGN 4
            TopLoop1:
               '@w[i] = Gamma1(@w[i-2]) + @w[i-7] + Gamma0(@w[i-15]) + @w[i-16]
               !  mov      ebx,  esi
               !  sub      ebx,  2
               !  lea      eax,  [edi+ebx*8] ;x = w+((i-2)*8)
               !  mov      x,    eax         ;x --> w[i-2]
               Gamma1(x,result)              'result = Gamma1(@w[i-2])
    
               !  mov      ebx,  esi
               !  sub      ebx,  7
               !  lea      eax,  [edi+ebx*8]
               !  mov      x,    eax         ;x --> @w[i-7] (x = w+((i-7)*8))
               Add8XtoY(x,result)            'result = total + @w[i-7]
    
               !  mov      ebx,  esi
               !  sub      ebx,  15
               !  lea      eax,  [edi+ebx*8]
               !  mov      x,    eax         ;x --> w[i-15]
               Gamma0(x,xx)
               Add8XtoY(xx,result)           'result = result + Gamma0(@w[i-15])
    
               !  mov      ebx,  esi
               !  sub      ebx,  16
               !  lea      eax,  [edi+ebx*8]
               !  mov      x,    eax         ;x --> @w[i-16]
               Add8XtoY(x,result)            'result = result + @w[i-16]
    
               !  lea      eax,  [edi+esi*8] ;x = w+(i*8)
               !  mov      x,    eax         ;x --> @w[i]
               Copy8XtoY(result,x)           '@w[i] = @result
            !  inc      esi
            !  cmp      esi,  79
            !  jng      TopLoop1
    
            'for i = 79 to 0 step -1
            !  xor      esi,  esi
            !  mov      edi,  80
            #ALIGN 4
            TopLoop2:
               't0 = @hh + Sigma1&&(@ee) + Chh(@ee, @ff, @gg) + @CTX.k_array[i] + @w[i]
               Copy8XtoY(hh,t0)
               Sigma1(ee,result)
               Add8XtoY(result,t0)
               Chh(ee,ff,gg,result)
               Add8XtoY(result,t0)
    
               !  mov      ebx,  k_array
               !  lea      eax,  [ebx+esi]
               !  mov      x,    eax
               Add8XtoY(x,t0)
    
               !  mov      ebx,  w_array
               !  lea      eax,  [ebx+esi]
               !  mov      x,    eax
               Add8XtoY(x,t0)
    
               Sigma0(aa,t1)
               Maj(aa,bb,cc,result)
               Add8XtoY(result,t1)
    
               Copy8XtoY(gg,hh)
               Copy8XtoY(ff,gg)
               Copy8XtoY(ee,ff)
               Copy8XtoY(ddd,ee)
               Add8XtoY(t0,ee)
    
               Copy8XtoY(cc,ddd)
               Copy8XtoY(bb,cc)
               Copy8XtoY(aa,bb)
               Copy8XtoY(t0,aa)
               Add8XtoY(t1,aa)
            'next i
            !  add      esi,  8
            !  dec      edi
            !  jnz      TopLoop2
    
            'for i = 0 to 7 : CTX.@pstate[i] = CTX.@pstate[i] + @s[i] : next i
            !  mov      eax,  s_array        ;eax --> s_array&&(0)
            !  mov      edx,  pstate         ;edx --> Ctx.State(0)
            !  mov      xx,   eax            ;xx  --> s_array&&(0)
            !  mov      yy,   edx            ;yy  --> Ctx.state0
            !  mov      edi,  8
            !  mov      esi,  7
            Add8XtoY(xx,yy)
            #ALIGN 4
            TopLoop3:
               'advance pointers
               !  add   xx,  edi             ;xx --> s[i]
               !  add   yy,  edi             ;yy --> pcurrent_state[i]
               Add8XtoY(xx,yy)
            !  dec   esi
            !  jnz   TopLoop3
    
            '-- Burn context's temp values (poke$ Ctx.pworkspace, nul$(%WORKSPACESIZE))
            !  mov      edi,  s_array
            !  xor      eax,  eax
            !  mov      ecx,  (%C_POWER_SHA512_WORKSPACESIZE\4)
            !  cld
            !  rep      stosd
    
            !  pop      edi
            !  pop      esi
            !  pop      ebx
        END METHOD
    
    
        '====================
        CLASS METHOD calcFile (pFile AS WSTRINGZ) THREADSAFE AS LONG
        REGISTER i       AS LONG
        LOCAL apiErr     AS LONG
        LOCAL pstate     AS LONG
        LOCAL phash      AS DWORD PTR
        LOCAL pInit      AS DWORD
        LOCAL pworkspace AS LONG
        LOCAL readBytes  AS DWORD
    
            RESET m_ctx
    
            pInit             = VARPTR(m_ctx.stat(0))
            m_ctx.pstate      = align(pInit,%C_POWER_SHA512_ALIGNMENT)
            m_ctx.@pstate[0]  = &h6A09E667F3BCC908&&
            m_ctx.@pstate[1]  = &hBB67AE8584CAA73B&&
            m_ctx.@pstate[2]  = &h3C6EF372FE94F82B&&
            m_ctx.@pstate[3]  = &hA54FF53A5F1D36F1&&
            m_ctx.@pstate[4]  = &h510E527FADE682D1&&
            m_ctx.@pstate[5]  = &h9B05688C2B3E6C1F&&
            m_ctx.@pstate[6]  = &h1F83D9ABFB41BD6B&&
            m_ctx.@pstate[7]  = &h5BE0CD19137E2179&&
    
            m_ctx.k_array     = CODEPTR(K_Array_Data)
    
            pInit             = VARPTR(m_ctx.workspace)
            pInit             = align(pInit,%C_POWER_SHA512_ALIGNMENT)
            m_ctx.s_array     = pInit
            m_ctx.w_array     = pInit+(8*8)              ' allow for 16-byte alignment in Compress128()
            m_ctx.pworkspace  = pInit+((8*8)+(80*8))
    
            ' ----------------------------------------------------------------------
    
            m_hFile = CreateFile ( pFile, BYVAL %GENERIC_READ, BYVAL %FILE_SHARE_READ, BYVAL %NULL, BYVAL %OPEN_EXISTING, BYVAL %FILE_FLAG_SEQUENTIAL_SCAN, BYVAL %NULL )
            IF ( m_hFile = %INVALID_HANDLE_VALUE ) THEN
                METHOD = GetLastError()
                EXIT METHOD
            END IF
    
            i = GetFileSizeEx (m_hFile, m_bytesleft)
            IF ( i = 0 ) THEN
                apiErr = GetLastError()
                GOTO FN_EXIT
            END IF
    
            m_buffer      = STRING$(%C_POWER_SHA512_FILE_BUFFERSIZE, 0)
            m_maxstring   = %C_POWER_SHA512_FILE_BUFFERSIZE
            m_ctx.lendata = %C_POWER_SHA512_BLOCKSIZE
            m_lastpass    = 0
            m_padding     = me.MakePadding (m_bytesleft)
    
            WHILE ( m_lastpass < 1 )
                ' ----------------------------------------------------------------------------------
                IF m_bytesleft =< m_maxstring THEN          'Resize if necessary & flag final buffer
                    m_maxstring = CLNG(m_bytesleft)
                    m_buffer = STRING$(m_maxstring, 0)
                    INCR m_lastpass
                END IF
                ' ----------------------------------------------------------------------------------
                i = ReadFile (m_hFile, STRPTR(m_buffer), LEN(m_buffer), readBytes, BYVAL %NULL)
                IF ( i = 0 ) THEN
                    apiErr = GetLastError()
                    GOTO FN_EXIT
                END IF
                ' ----------------------------------------------------------------------------------
                IF m_lastpass THEN
                    m_buffer = m_buffer + m_padding
                END IF
                ' ----------------------------------------------------------------------------------
                m_ctx.pdata = STRPTR(m_buffer)
                SELECT CASE m_compress
                CASE 128
                    FOR i = 1 TO (LEN(m_buffer) \ %C_POWER_SHA512_BLOCKSIZE)
                        CALL me.Compress128()
                        m_ctx.pdata = m_ctx.pdata + %C_POWER_SHA512_BLOCKSIZE
                    NEXT i
                CASE 64
                    FOR i = 1 TO (LEN(m_buffer) \ %C_POWER_SHA512_BLOCKSIZE)
                        CALL me.Compress64()
                        m_ctx.pdata = m_ctx.pdata + %C_POWER_SHA512_BLOCKSIZE
                    NEXT i
                CASE ELSE
                    FOR i = 1 TO (LEN(m_buffer) \ %C_POWER_SHA512_BLOCKSIZE)
                        CALL me.Compress32()
                        m_ctx.pdata = m_ctx.pdata + %C_POWER_SHA512_BLOCKSIZE
                    NEXT i
                END SELECT
                ' ----------------------------------------------------------------------------------
                m_bytesleft        = m_bytesleft        - m_maxstring
                m_Status_Bytes     = m_Status_Bytes     + m_maxstring
                m_Status_Bytes_tmp = m_Status_Bytes_tmp + m_maxstring
                IF ( m_Status_Bytes_tmp >= m_Status_Bytes_1P ) THEN
                    m_Status_Percent = IIF(m_Status_Total<1, 100, m_Status_Bytes * 100 / m_Status_Total)
                    RESET m_Status_Bytes_tmp
                    'DIALOG send m_Status_Dlg, m_Status_WM_Percent, m_Status_Percent, -1
                    'RAISEEVENT iSHA256status.RefreshStatus (m_Status_Dlg, 1004, m_Status_Percent)
                END IF
            WEND
    
            phash  = m_hashptr
            pstate = m_ctx.pstate
    
            '-- Copy current state
            'Local i as long : for i = 0 to (%HASHLEN\8)-1 : @phash[i] = m_ctx.@pstate[i] : next i : exit method
    
            !  push     esi
            !  push     edi
            !  mov      esi,     pstate      ;esi -> m_ctx.state(0)
            !  mov      edi,     phash
            #IF %C_POWER_SHA512_RETURN_LITTLE_ENDIAN
            !  xor      ecx,     ecx
            LoopTop:
            !  mov      edx,     [esi+ecx*4+4]
            !  mov      eax,     [esi+ecx*4]
            !  bswap    edx
            !  bswap    eax
            !  mov      [edi+ecx*4],   edx
            !  inc      ecx
            !  mov      [edi+ecx*4],   eax
            !  inc      ecx
            !  test     ecx,     (%C_POWER_SHA512_HASHLEN\4)
            !  jz       LoopTop
            #ELSE
            !  mov      ecx,     (%C_POWER_SHA512_HASHLEN\4)
            !  cld
            !  rep      movsd
            #ENDIF
            !  pop      edi
            !  pop      esi
    
        FN_EXIT:
            CALL CloseHandle ( m_hFile )
            RESET m_hFile
            METHOD = apiErr
    
        END METHOD
    
    
        '=========================
        '-- Creates the necessary string to append to targeted data buffer
        CLASS METHOD MakePadding (BYVAL TotalBytes AS QUAD) AS STRING
        REGISTER i AS LONG, padBytes AS LONG
        LOCAL buffbits AS QUAD
        LOCAL padding  AS STRING
        LOCAL pbyte1   AS BYTE PTR
        LOCAL pbyte2   AS BYTE PTR
    
            buffBits = TotalBytes * 8
            padding  = NUL$(16)
            pbyte1   = STRPTR(padding)+8
            pbyte2   = VARPTR(buffBits)
    
            '-- Reverse bytes during copy
            FOR i = 0 TO 7
                @pbyte1[i] = @pbyte2[7 - i]
            NEXT i
    
            padBytes = %C_POWER_SHA512_BLOCKSIZE - ((TotalBytes+17) AND (%C_POWER_SHA512_BLOCKSIZE-1))
            METHOD = CHR$(&h80) + NUL$(padBytes) + padding
        END METHOD
    
    
        '===================
        CLASS METHOD HasSSE2() AS LONG
        !  mov      eax, 1
        !  cpuid
        !  xor      eax, eax
        !  test     edx, &h04000000   ;bit 26
        !  setnz    al                ;rem to force downgrade to MMX
        !  mov      METHOD, eax
        END METHOD
    
    
        '===================
        CLASS METHOD HasMMX() AS LONG
        !  mov      eax, 1
        !  cpuid
        !  xor      eax, eax
        !  test     edx, &h800000     ;bit 23
        !  setnz    al                ;rem to force downgrade to 32-bit
        !  mov      METHOD, eax
        END METHOD
    
    
        '====================
        CLASS METHOD Init()
        LOCAL pInit AS DWORD
    
            RESET m_ctx
    
            pInit             = VARPTR(m_ctx.stat(0))
            m_ctx.pstate      = align(pInit,%C_POWER_SHA512_ALIGNMENT)
            m_ctx.@pstate[0]  = &h6A09E667F3BCC908&&
            m_ctx.@pstate[1]  = &hBB67AE8584CAA73B&&
            m_ctx.@pstate[2]  = &h3C6EF372FE94F82B&&
            m_ctx.@pstate[3]  = &hA54FF53A5F1D36F1&&
            m_ctx.@pstate[4]  = &h510E527FADE682D1&&
            m_ctx.@pstate[5]  = &h9B05688C2B3E6C1F&&
            m_ctx.@pstate[6]  = &h1F83D9ABFB41BD6B&&
            m_ctx.@pstate[7]  = &h5BE0CD19137E2179&&
    
            m_ctx.k_array     = CODEPTR(K_Array_Data)
    
            pInit             = VARPTR(m_ctx.workspace)
            pInit             = align(pInit,%C_POWER_SHA512_ALIGNMENT)
            m_ctx.s_array     = pInit
            m_ctx.w_array     = pInit+(8*8)              ' allow for 16-byte alignment in Compress128()
            m_ctx.pworkspace  = pInit+((8*8)+(80*8))
    
        END METHOD
    
    
        '====================
        '-- Expects parameter Hash to point to buffer of correct size of %HASHLEN bytes (256bits\8)
        CLASS METHOD calcBuffer (BYVAL hData AS DWORD, BYVAL Length AS DWORD) AS LONG
        REGISTER i AS DWORD
        LOCAL pstate     AS LONG
        LOCAL lastbuff   AS STRING
        LOCAL DataBuffer AS BYTE PTR
        LOCAL phash      AS QUAD PTR
    
            DataBuffer    = hData
            i             = Length AND (%C_POWER_SHA512_BLOCKSIZE-1)
            lastbuff      = PEEK$((DataBuffer+Length)-i, i)
            lastbuff      = lastbuff + me.MakePadding(Length)
            m_ctx.lendata = Length
            m_ctx.pdata   = DataBuffer
    
            i = Length AND (NOT %C_POWER_SHA512_BLOCKSIZE-1)
            DO WHILE i > 0
                SELECT CASE m_compress
                CASE 128:  CALL me.Compress128()
                CASE  64:  CALL me.Compress64()
                CASE ELSE: CALL me.Compress32()
                END SELECT
                m_ctx.pdata = m_ctx.pdata + %C_POWER_SHA512_BLOCKSIZE
                i = i - %C_POWER_SHA512_BLOCKSIZE
            LOOP
    
            m_ctx.pdata = STRPTR(lastbuff)
            m_ctx.lendata = LEN(lastbuff)
    
            DO WHILE m_ctx.lendata > 0
                SELECT CASE m_compress
                CASE 128:  CALL me.Compress128()
                CASE  64:  CALL me.Compress64()
                CASE ELSE: CALL me.Compress32()
                END SELECT
                m_ctx.pdata = m_ctx.pdata + %C_POWER_SHA512_BLOCKSIZE
                m_ctx.lendata = m_ctx.lendata - %C_POWER_SHA512_BLOCKSIZE
            LOOP
    
            phash  = m_hashptr
            pstate = m_ctx.pstate
    
            '-- Copy current state from s&() to Hash
            'for i = 0 to (%HASHLEN\4)-1 : @phash[i] = m_ctx.@pstate[i] : next i: exit method
    
            !  push     esi
            !  push     edi
            !  mov      esi,     pstate      ;esi -> m_ctx.state(0)
            !  mov      edi,     phash
            #IF %C_POWER_SHA512_RETURN_LITTLE_ENDIAN
            !  xor      ecx,     ecx
            LoopTop:
            !  mov      edx,     [esi+ecx*4+4]
            !  mov      eax,     [esi+ecx*4]
            !  bswap    edx
            !  bswap    eax
            !  mov      [edi+ecx*4],   edx
            !  inc      ecx
            !  mov      [edi+ecx*4],   eax
            !  inc      ecx
            !  test     ecx,     (%C_POWER_SHA512_HASHLEN\4)
            !  jz       LoopTop
            #ELSE
            !  mov      ecx,     (%C_POWER_SHA512_HASHLEN\4)
            !  cld
            !  rep      movsd
            #ENDIF
            !  pop      edi
            !  pop      esi
        END METHOD
    
    
        '===================
        CLASS METHOD CREATE()
            IF me.HasSSE2() THEN
                m_compress = 128
            ELSEIF me.HasMMX() THEN
                m_compress = 64
            ELSE
                m_compress = 32
            END IF
            m_Status_Bytes     = 0
            m_Status_Bytes_tmp = 0
            m_Status_Bytes_1P  = 0
            m_Status_Percent   = 0
            m_Status_Count     = 0
            m_Status_Index     = -1
            m_Cancel           = %FALSE
            m_hashptr          = VARPTR(m_hashmem)
        END METHOD
    
    
        '===================
        CLASS METHOD DESTROY()
            IF ( m_hFile <> %INVALID_HANDLE_VALUE ) THEN
                CALL CloseHandle ( m_hFile )
                RESET m_hFile
            END IF
        END METHOD
    
    
        ' ====================================================
        INTERFACE iSHA512main $C_POWER_SHA512_MAIN_IID : INHERIT IPOWERTHREAD
    
            PROPERTY SET p_Data ( value AS iSHA512data )
                iDataFace = value
            END PROPERTY
    
            PROPERTY GET p_Status_Total () AS QUAD
                PROPERTY = m_Status_Total
            END PROPERTY
            PROPERTY SET p_Status_Total (BYVAL value AS QUAD)
                IF ( value > 0 ) THEN
                    m_Status_Total    = value
                    m_Status_Bytes_1P = value / 100
                ELSE
                    m_Status_Total    = 0
                    m_Status_Bytes_1P = 0
                END IF
            END PROPERTY
    
            PROPERTY GET p_Status_Bytes () AS QUAD
                PROPERTY = m_Status_Bytes
            END PROPERTY
    
            PROPERTY GET p_Status_Percent () AS LONG
                PROPERTY = m_Status_Percent
            END PROPERTY
    
            PROPERTY GET p_Status_Index () AS LONG
                PROPERTY = m_Status_Index
            END PROPERTY
    
            PROPERTY GET p_Status_Count () AS LONG
                PROPERTY = m_Status_Count
            END PROPERTY
    
            ' ====================================================
    
            PROPERTY GET p_Cancel () AS LONG
                PROPERTY = m_Cancel
            END PROPERTY
            PROPERTY SET p_Cancel (BYVAL value AS LONG)
                IF ( ISTRUE value ) THEN
                    INCR m_lastpass
                    m_Cancel = %TRUE
                ELSE
                    m_Cancel = %FALSE
                END IF
            END PROPERTY
    
            ' ====================================================
    
            METHOD GetHexHash (BYVAL bArrayPtr AS DWORD) AS STRING
            LOCAL bHash AS BYTE PTR
            LOCAL sHash AS STRING
            LOCAL i     AS LONG
                IF ( bArrayPtr ) THEN
                    bHash = bArrayPtr
                    FOR i = 0 TO %C_POWER_SHA512_HASHLEN-1
                        sHash = sHash + HEX$(@bHash[i],2)
                    NEXT i
                END IF
                METHOD = LCASE$(sHash)
            END METHOD
    
            METHOD calc_buffer_init ()
                CALL me.Init()
            END METHOD
    
            METHOD calc_buffer (BYVAL dataPtr AS LONG, BYVAL dataLen AS DWORD, BYVAL hashPtr AS DWORD)
                CALL me.calcBuffer (dataPtr, dataLen)
                MEMORY COPY m_hashptr, hashPtr, %C_POWER_SHA512_HASHLEN
            END METHOD
    
        END INTERFACE
    
    END CLASS
    
    
    CLASS cSHA512data $C_POWER_SHA512_DATA_CID COMMON
    INSTANCE m_lbound          AS LONG
    INSTANCE m_ubound          AS LONG
    INSTANCE m_Files()         AS WSTRING
    INSTANCE m_Hashs()         AS STRING
    INSTANCE m_Errors()        AS LONG
    
        '===================
        CLASS METHOD CREATE()
        END METHOD
    
        '===================
        CLASS METHOD DESTROY()
        END METHOD
    
        ' ====================================================
    
        INTERFACE iSHA512data $C_POWER_SHA512_DATA_IID : INHERIT DUAL
    
        ' ====================================================
    
            PROPERTY GET p_lbound () AS LONG
                PROPERTY = m_lbound
            END PROPERTY
    
            PROPERTY GET p_ubound () AS LONG
                PROPERTY = m_ubound
            END PROPERTY
    
            ' ====================================================
    
            METHOD GetFile ( BYVAL i AS LONG ) AS WSTRING
                METHOD = m_Files(i)
            END METHOD
    
            METHOD GetHash ( BYVAL i AS LONG ) AS STRING
                METHOD = m_Hashs(i)
            END METHOD
            METHOD SetHash ( BYVAL i AS LONG, BYVAL hash AS STRING )
                m_Hashs(i) = hash
            END METHOD
    
            METHOD GetError ( BYVAL i AS LONG ) AS LONG
                METHOD = m_Errors(i)
            END METHOD
            METHOD SetError ( BYVAL i AS LONG, BYVAL ErrNum AS LONG )
                m_Errors(i) = ErrNum
            END METHOD
    
            METHOD DimAT (BYVAL pFiles AS DWORD, BYVAL pHashs AS DWORD, BYVAL pErrors AS DWORD, BYVAL lb AS LONG, BYVAL ub AS LONG)
                m_lbound = lb
                m_ubound = ub
                REDIM m_Files  (lb TO ub) AS INSTANCE WSTRING AT pFiles
                REDIM m_Hashs  (lb TO ub) AS INSTANCE  STRING AT pHashs
                REDIM m_Errors (lb TO ub) AS INSTANCE    LONG AT pErrors
            END METHOD
    
        END INTERFACE
    
    END CLASS
    Last edited by Bernhard Fomm; 12 Feb 2017, 11:50 AM.

  • #2
    Demo program for SHA512-PowerTHREAD-Class


    Code:
    ' PowerHash_SHA512_Demo.bas
    '
    '
    '------------------------------------------
    ' Demo program for SHA512-PowerTHREAD-Class
    '------------------------------------------
    #COMPILER PBWIN 10
    #COMPILE EXE "PowerHash_SHA512_Demo.exe"
    #DIM ALL
    %UNICODE = 1
    #INCLUDE ONCE "WIN32API.INC"
    #INCLUDE "PowerSHA512_m.inc"
    #INCLUDE "PowerSHA512.inc"
    '#LINK "..\PowerSHA512.sll"
    
    
    %IDD_DIALOG1       =  101
    %IDC_TX_RESULTS    = 1001
    %IDC_LB_PROGRESS1  = 1002
    %IDC_LB_PROGRESS2  = 1003
    %IDC_PROGRESSBAR1  = 1004
    %IDC_BN_FILESELECT = 1005
    %IDC_BN_STOP       = 1006
    %IDC_TIMER_STATUS  = 1999
    
    
    GLOBAL goHashMain   AS iSHA512main
    GLOBAL goHashData   AS iSHA512data
    GLOBAL gFile   ()   AS WSTRING
    GLOBAL gHash   ()   AS STRING
    GLOBAL gErr    ()   AS LONG
    
    
    SUB SetGlobalArrays (BYVAL pFileList AS WSTRING)
    LOCAL i,c    AS LONG
    LOCAL folder AS WSTRING
    
        pFileList = RTRIM$(pFileList,$$NUL)
    
        IF ISFILE (pFileList) THEN                                     ' if only one file selected
            c = 1
            REDIM gFile (1 TO 1)
            gFile (1) = pFileList
        ELSE                                                           ' if multiple files selected
            folder = PARSE$(pFileList, $$NUL, 1)
            folder = RTRIM$(folder,"\") + "\"
            c = PARSECOUNT(pFileList,$$NUL) - 1
            REDIM gFile (1 TO c)
            FOR i = 1 TO c
                gFile (i) = folder + PARSE$(pFileList, $$NUL, 1+i)
            NEXT i
        END IF
    
        REDIM gHash(1 TO c)
        REDIM gErr (1 TO c)
    
    END SUB
    
    
    FUNCTION GetTotalSize () AS QUAD
    LOCAL i,f   AS LONG
    LOCAL fsize AS QUAD
    
        FOR i = LBOUND(gFile) TO UBOUND(gFile)
            f = FREEFILE
            OPEN gFile (i) FOR BINARY ACCESS READ LOCK SHARED AS #f
                fsize = fsize + LOF(#f)
            CLOSE #f
        NEXT i
    
        FUNCTION = fsize
    END FUNCTION
    
    
    SUB PowerHash_SHA512 (BYVAL hDlg AS DWORD, BYVAL pAllBytes AS QUAD)
    LOCAL i       AS LONG
    LOCAL time    AS SINGLE
    LOCAL tmp     AS WSTRING
    
        goHashMain   = CLASS "cSHA512main"
        goHashData   = CLASS "cSHA512data"
    
        goHashMain.p_Data         = goHashData
        goHashMain.p_Status_Total = pAllBytes
    
        CALL goHashData.DimAT (VARPTR(gFile(1)), VARPTR(gHash(1)), VARPTR(gErr(1)), LBOUND(gFile), UBOUND(gFile))
    
        SetTimer hDlg, %IDC_TIMER_STATUS, 200, BYVAL 0
    
        time = TIMER
        goHashMain.launch (BYVAL 0)
        WHILE goHashMain.isalive()
            DIALOG DOEVENTS
        WEND
        time = TIMER-time
    
        KillTimer hDlg, %IDC_TIMER_STATUS
    
        IF ISFALSE (goHashMain.p_Cancel) THEN
            FOR i = LBOUND(gFile) TO UBOUND(gFile)
                IF gErr(i) = 0 THEN
                    tmp = tmp + gFile(i) + $CRLF + " --> " + gHash(i) + $CRLF + $CRLF
                ELSE
                    tmp = tmp + gFile(i) + $CRLF + " --> " + "Api-Error:" + STR$(gErr(i)) + $CRLF + $CRLF
                END IF
            NEXT i
            CONTROL SET TEXT hDlg, %IDC_TX_RESULTS, tmp
            PROGRESSBAR SET POS hDlg, %IDC_PROGRESSBAR1, 100
            CONTROL SET TEXT hDlg, %IDC_LB_PROGRESS1, FORMAT$(goHashMain.p_Status_Bytes) + " Bytes --> " + FORMAT$(goHashMain.p_Status_Total) + " --> " + FORMAT$(goHashMain.p_Status_Percent) + "% --> Time:" + STR$(time)
            CONTROL SET TEXT hDlg, %IDC_LB_PROGRESS2, ""
        END IF
    
        goHashData   = NOTHING
        goHashMain   = NOTHING
    END SUB
    
    
    CALLBACK FUNCTION DIALOG_PROC()
    STATIC fMouse     AS LONG
    STATIC oldPercent AS LONG
    STATIC newPercent AS LONG
    STATIC oldIndex   AS LONG
    STATIC newIndex   AS LONG
    LOCAL files       AS WSTRING
    LOCAL allBytes    AS QUAD
    
        SELECT CASE AS LONG CB.MSG
        CASE %WM_INITDIALOG
            PROGRESSBAR SET RANGE CBHNDL, %IDC_PROGRESSBAR1, 0, 100
    
        CASE %WM_NCACTIVATE
            STATIC hWndSaveFocus AS DWORD
            IF ISFALSE CB.WPARAM THEN
                hWndSaveFocus = GetFocus()
            ELSEIF hWndSaveFocus THEN
                SetFocus(hWndSaveFocus)
                hWndSaveFocus = 0
            END IF
    
        CASE %WM_SETCURSOR
            IF ( ISTRUE fMouse ) THEN MOUSEPTR 13 : FUNCTION = 1
    
        CASE %WM_TIMER
            SELECT CASE CBWPARAM
            CASE %IDC_TIMER_STATUS
                IF ISOBJECT(goHashMain) THEN
                    IF goHashMain.isalive() THEN
                        newPercent = goHashMain.p_Status_Percent
                        newIndex   = goHashMain.p_Status_Index
                        IF ( newPercent <> oldPercent ) THEN
                            PROGRESSBAR SET POS CBHNDL, %IDC_PROGRESSBAR1, newPercent
                            CONTROL SET TEXT CBHNDL, %IDC_LB_PROGRESS1, FORMAT$(goHashMain.p_Status_Bytes) + " --> " + FORMAT$(goHashMain.p_Status_Total) + " --> " + FORMAT$(goHashMain.p_Status_Percent) + "%"
                            oldPercent = newPercent
                        END IF
                        IF ( newIndex <> oldIndex ) THEN
                            CONTROL SET TEXT CBHNDL, %IDC_LB_PROGRESS2, PATHNAME$(NAMEX,gFile(newIndex))
                            oldIndex = newIndex
                        END IF
                    END IF
                END IF
            END SELECT
    
        CASE %WM_COMMAND
            SELECT CASE AS LONG CB.CTL
    
            CASE %IDC_BN_FILESELECT
                IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                    DISPLAY OPENFILE CBHNDL, , , "Select file(s)", "", "", "", "", %OFN_ENABLESIZING OR %OFN_FILEMUSTEXIST OR %OFN_ALLOWMULTISELECT TO files
                    IF ( files <> "" ) THEN
                        CONTROL DISABLE CBHNDL, %IDC_BN_FILESELECT
                        fMouse = %TRUE
                        MOUSEPTR 13
                        CALL SetGlobalArrays (files)
                        allBytes = GetTotalSize()
                        CALL PowerHash_SHA512 (CBHNDL, allBytes)
                        CONTROL ENABLE CBHNDL, %IDC_BN_FILESELECT
                        fMouse = %FALSE
                        MOUSEPTR 1
                    END IF
                END IF
    
            CASE %IDC_BN_STOP
                IF CB.CTLMSG = %BN_CLICKED OR CB.CTLMSG = 1 THEN
                    IF ISOBJECT(goHashMain) THEN
                        IF goHashMain.isalive() THEN
                            KillTimer CBHNDL, %IDC_TIMER_STATUS
                            goHashMain.suspend()
                            IF MSGBOX ( "Stop?", %MB_YESNO, EXE.NAME$ ) = %IDNO THEN
                                goHashMain.resume()
                                SetTimer CBHNDL, %IDC_TIMER_STATUS, 100, BYVAL 0
                                EXIT FUNCTION
                            END IF
                            goHashMain.p_Cancel = %TRUE
                            goHashMain.resume()
    
                        END IF
                    END IF
                END IF
    
            END SELECT
    
        CASE %WM_DESTROY
            KillTimer CBHNDL, %IDC_TIMER_STATUS
            IF ISOBJECT(goHashMain) THEN
                IF goHashMain.isalive() THEN
                    goHashMain.p_Cancel = %TRUE
                    SLEEP 50
                END IF
            END IF
    
        END SELECT
    END FUNCTION
    
    
    FUNCTION DIALOG_SHOW(BYVAL hParent AS DWORD) AS LONG
        LOCAL lRslt  AS LONG
    
    #PBFORMS BEGIN DIALOG %IDD_DIALOG->->
        LOCAL hDlg   AS DWORD
        LOCAL hFont1 AS DWORD
    
        DIALOG NEW PIXELS, hParent, "Demo program for SHA512-PowerTHREAD-Class", 222, 147, 800, 640, _
            %WS_POPUP OR %WS_BORDER OR %WS_DLGFRAME OR %WS_SYSMENU OR _
            %WS_MINIMIZEBOX OR %WS_CLIPSIBLINGS OR %WS_VISIBLE OR %DS_MODALFRAME _
            OR %DS_3DLOOK OR %DS_NOFAILCREATE OR %DS_SETFONT, _
            %WS_EX_CONTROLPARENT OR %WS_EX_LEFT OR %WS_EX_LTRREADING OR _
            %WS_EX_RIGHTSCROLLBAR, TO hDlg
        CONTROL ADD LABEL,       hDlg, %IDC_LB_PROGRESS1, "", 28, 580, 408, 20
        CONTROL ADD LABEL,       hDlg, %IDC_LB_PROGRESS2, "", 28, 600, 408, 24
        CONTROL ADD PROGRESSBAR, hDlg, %IDC_PROGRESSBAR1, "ProgressBar1", 28, _
            552, 408, 25
        CONTROL ADD BUTTON,      hDlg, %IDC_BN_FILESELECT, "File(s)...", 564, 576, 82, _
            29
        CONTROL ADD BUTTON,      hDlg, %IDC_BN_STOP, "Stop...", 468, 576, 80, 28
        CONTROL ADD TEXTBOX,     hDlg, %IDC_TX_RESULTS, "", 12, 8, 774, 532, _
            %WS_CHILD OR %WS_VISIBLE OR %WS_TABSTOP OR %WS_VSCROLL OR %ES_LEFT _
            OR %ES_MULTILINE OR %ES_AUTOHSCROLL OR %ES_AUTOVSCROLL OR _
            %ES_WANTRETURN, %WS_EX_CLIENTEDGE OR %WS_EX_LEFT OR _
            %WS_EX_LTRREADING OR %WS_EX_RIGHTSCROLLBAR
    
        FONT NEW "MS Sans Serif", 10, 0, %ANSI_CHARSET TO hFont1
    
        CONTROL SET FONT hDlg, %IDC_TX_RESULTS, hFont1
        CONTROL SET FONT hDlg, %IDC_LB_PROGRESS1, hFont1
        CONTROL SET FONT hDlg, %IDC_LB_PROGRESS2, hFont1
        CONTROL SET FONT hDlg, %IDC_BN_FILESELECT, hFont1
        CONTROL SET FONT hDlg, %IDC_BN_STOP, hFont1
    
    #PBFORMS END DIALOG
    
        DIALOG SHOW MODAL hDlg, CALL DIALOG_PROC TO lRslt
    
    #PBFORMS BEGIN CLEANUP %IDD_DIALOG
        FONT END hFont1
    #PBFORMS END CLEANUP
    
        FUNCTION = lRslt
    END FUNCTION
    '------------------------------------------------------------------------------
    
    
    FUNCTION PBMAIN()
    
        DIM gFile(0) AS WSTRING
        DIM gHash(0) AS STRING
        DIM gErr (0) AS LONG
    
        DIALOG_SHOW %HWND_DESKTOP
    
    END FUNCTION

    Comment

    Working...
    X