Announcement

Collapse

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

SHA-1 secure hash

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

    SHA-1 secure hash

    DO NOT USE THIS CODE The result SHA string has an endian problem. The code at http://www.powerbasic.com/support/fo...ML/000755.html also returns incorrect hash.

    I'll leave it here as an example of an easy mistake to make. Corrected code in next post.
    Code:
    '*******************************************************************************
    'File: SHA-1.inc
    'Contains the CalcSHA function.
    'An implementation of Secure Hash Algorithm 1 (SHA-1) described in the Federal
    'Information Processing Standards (FIPS) Publication 180-2, dated
    '2002 August 1 (supersedes FIPS 180-1).
    '
    '             *************************************************
    '             * This implementation of SHA-1 is placed in the *
    '             * Public Domain without warranty of any kind.   *
    '             *         - Use at your own risk. -             *
    '             *************************************************
    '
    '     ## Important Note ###############################################
    '     # From FIPS 180-2, paragraph 8:                                 #
    '     #   "Only algorithm implementations that are validated by       #
    '     #   NIST will be considered as complying with this standard."   #
    '     #                                                               #
    '     # While this implementation correctly calculates the examples   #
    '     # in FIPS 180-2, Appendix A; it has NOT been validated by NIST. #
    '     #################################################################
    '
    '-------------------------------------------------------------------------------
    'Credits/info as downloaded from -
    ' http://www.pbcrypto.com/view.php?algorithm=sha-1
    'NAME: SHA-1
    'CREATOR: NIST and NSA
    'PB AUTHOR: Semen Matusovski
    'DESCRIPTION: Creates a 160-bit hash (message digest) from messages up to
    '264 bits.
    'NOTES: Produces a message digest of 160 bits, providing no more than 80 bits
    'of security against collision attacks.
    'SOURCE: http://www.powerbasic.com/support/forums/Forum7/HTML/000755.html
    '-------------------------------------------------------------------------------
    'Modifications by Dale Yarker.
    ' I probably could not have written a SHA-1 function myself using only the
    ' information in the FIPS, and certainly not in assembly. Thanks Semen!
    ' While trying to read through the code to understand how it works, and to
    ' compare it with the FIPS, I was struck by the lack of comments and
    ' meaningful indentation. My objective is to make the code "over commented" for
    ' everyone except very beginner programmers.
    '
    'Comments within curly braces, "{}", describe changes I made to Semen's code.
    '
    'Comments within square braces, "[]", are the variable names used in
    ' FIPS 180-2; which may, or may not be different here.
    '
    'Other comments maybe Semen's or mine.
    '*******************************************************************************
    '#compile exe 'as opposed to dll.
    '#register none 'turn off automatic assignment of vars to CPU registers by the
                   'compiler due to heavy use of registers in assember section.
    '#dim all 'force declaration/casting of vars before use.
    '#Include "Win32Api.Inc"
    '{Didn't have this file, then turned out not to matter. See Speed Test.}
    '$FileNm = "Win322.hlp"
    
    '{Type name from "SHA" to "SHAtype" because it conflicted with variable
    ' having the same name at compile time. Long to dword.}
    'type DWrd5_Type
    '  H0 as dword
    '  H1 as dword
    '  H2 as dword
    '  H3 as dword
    '  H4 as dword
    'end type
    'union DWrd5_Str_Union
    '  dw5 as DWrd5_Type
    '  Str as string * 20
    'end union
    '-------------------------------------------------------------------------------
    sub CalcSHA1 alias "CALCULATE_SECURE_HASH_ALGORITHM_1" (byref Str as string, _
                                                 byref SH_Out as string * 20) export
      #register none '- - - - - - - - - - - - - -
      local lStr as long '[l message in bits], here as length in bytes
      dim nq as long '[N] number of blocks in Message (padded)
      local n as long 'Nunber of dwords in Message
      local adrW, adrWW as dword 'pointers to Message and Schedule arrays.
      'local SH as DWrd5_Str_Union '[H0 - H4] Hash Values as dword or string
      local H0, H1, H2, H3, H4 as dword
      local pSH_Out as dword pointer
      dim W(0 to 79) as dword '[W] Message Schedule {colon to TO}
      local A, B, C, D, E as dword '[working variables]
      local TEMP as long '[TEMP]
      '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      'Pad last block of 512 bits (is 64 bytes or 16 dwords)
      lStr = len(Str)
      nq = fix((lStr + 8) / 64) + 1 'calc number of blocks
      n = 16 * nq 'calc number of dwords in WW()
      redim WW(0 to n - 1) as dword '[M] The Message, last block padded with "0"s.
    
      WW(n - 1) = lStr * 8 'Put count of last block Message bits in last dword.
      adrW = varptr(W(0))
      adrWW = varptr(WW(0))
      A = strptr(Str)
      'Labels CalcSHA_Lbl01 thru CalcSHA_Lbl04 used to form loops.
      'Labels CalcSHA_Lbl05 thru CalcSHA_Lbl08 are jump targets, conditionally
      'skipping sections of code (all jumps forward).
      'save current EDI and ESI to stack before using those registers
      ! PUSH EDI
      ! PUSH ESI
    
      ! MOV EDI, adrWW
      ! MOV ESI, A
      ! MOV ECX, lStr
      ! REP MOVSB 'repeat string operation
      'Append a "1" bit after last Message bit in last block
      ! MOV CL, &H80
      ! MOV [EDI], CL
      'Loop 1 setup
      ! MOV EDI, adrWW
      ! MOV ECX, 2
      'Start Loop 1, copy Str to WW()
      CalcSHA_Lbl01:
        ! MOV AX, [EDI]
        ! MOV DX, [EDI + 2]
        ! MOV [EDI], DH
        ! MOV [EDI + 1], DL
        ! MOV [EDI + 2], AH
        ! MOV [EDI + 3], AL
        ! ADD EDI, 4
        ! INC ECX
        ! CMP ECX, n
        ! JNE CalcSHA_Lbl01
      'End Loop 1
      'set initial hash value
      ! MOV H0, &H67452301&
      ! MOV H1, &HEFCDAB89&
      ! MOV H2, &H98BADCFE&
      ! MOV H3, &H10325476&
      ! MOV H4, &HC3D2E1F0&
      'Start Loop 2, move a block from Message into Message schedule
      CalcSHA_Lbl02:
        ! MOV EDI, adrW
        ! MOV ESI, adrWW
        ! MOV ECX, 64
        ! REP MOVSB
        ! MOV adrWW, ESI
        'Loop 3 setup
        ! MOV ECX, 0
        'Start Loop 3
        CalcSHA_Lbl03:
          ! MOV ESI, ECX
          ! ADD ESI, ESI
          ! ADD ESI, ESI
          ! ADD ESI, adrW
    
          ! MOV EAX, [ESI + 52]
          ! XOR EAX, [ESI + 32]
          ! XOR EAX, [ESI + 8]
          ! XOR EAX, [ESI]
    
          ! MOV EDX, EAX
          ! SHL EAX, 1
          ! SHR EDX, 31
          ! OR  EAX, EDX
          ! MOV [ESI + 64], EAX
    
          ! INC ECX
          ! CMP ECX, 64
          ! JNE CalcSHA_Lbl03
        'End Loop 3
        ! MOV EAX, H0
        ! MOV A, EAX
        ! MOV EAX, H1
        ! MOV B, EAX
        ! MOV EAX, H2
        ! MOV C, EAX
        ! MOV EAX, H3
        ! MOV D, EAX
        ! MOV EAX, H4
        ! MOV E, EAX
        'Loop 4 setup
        ! MOV EDI, 0
        'Start Loop 4
        CalcSHA_Lbl04:
          ! CMP EDI, 19
          ! JA CalcSHA_Lbl05
    
          ! MOV ECX, B
          ! AND ECX, C
          ! MOV EAX, B
          ! NOT EAX
          ! AND EAX, D
          ! OR  ECX, EAX
          ! ADD ECX, &H5A827999&
          ! JMP CalcSHA_Lbl08
    
          CalcSHA_Lbl05:
          ! CMP EDI, 39
          ! JA CalcSHA_Lbl06
    
          ! MOV ECX, B
          ! XOR ECX, C
          ! XOR ECX, D
          ! ADD ECX, &H6ED9EBA1&
          ! JMP CalcSHA_Lbl08
    
          CalcSHA_Lbl06:
          ! CMP EDI, 59
          ! JA CalcSHA_Lbl07
    
          ! MOV EAX, B
          ! AND EAX, C
          ! MOV ECX, B
          ! AND ECX, D
          ! MOV EDX, C
          ! AND EDX, D
          ! OR  ECX, EAX
          ! OR  ECX, EDX
          ! ADD ECX, &H8F1BBCDC&
          ! JMP CalcSHA_Lbl08
    
          CalcSHA_Lbl07:
          ! MOV ECX, B
          ! XOR ECX, C
          ! XOR ECX, D
          ! ADD ECX, &HCA62C1D6&
    
          CalcSHA_Lbl08:
          ! MOV EAX, A
          ! MOV EDX, EAX
          ! SHL EAX, 5
          ! SHR EDX, 27
          ! OR  EAX, EDX
          ! ADD EAX, E
          ! ADD ECX, EAX
    
          ! MOV ESI, EDI
          ! ADD ESI, ESI
          ! ADD ESI, ESI
          ! ADD ESI, adrW
          ! MOV ESI, [ESI]
          ! MOV TEMP, ESI
    
          ! ADD Temp, ECX
          ! MOV EAX, D
          ! MOV E, EAX
          ! MOV EAX, C
          ! MOV D, EAX
          ! MOV EAX, B
          ! MOV EDX, EAX
          ! SHL EAX, 30
          ! SHR EDX, 2
          ! OR  EAX, EDX
          ! MOV C, EAX
          ! MOV EAX, A
          ! MOV B, EAX
          ! MOV EAX, TEMP
          ! MOV A, EAX
    
          ! INC EDI
          ! CMP EDI, 80
          ! JNE CalcSHA_Lbl04
        'End Loop 4
        ! MOV EAX, A
        ! ADD H0, EAX
        ! MOV EAX, B
        ! ADD H1, EAX
        ! MOV EAX, C
        ! ADD H2, EAX
        ! MOV EAX, D
        ! ADD H3, EAX
        ! MOV EAX, E
        ! ADD H4, EAX
    
        ! SUB nq, 1
        ! JNE CalcSHA_Lbl02 'done if nq = 0
      'End Loop 2
      'restore previous ESI and EDI from stack
      ! POP ESI
      ! POP EDI
      'set return hash
      pSH_Out = varptr(SH_Out)
      @pSH_Out = H0
      incr pSH_Out
      @pSH_Out = H1
      incr pSH_Out
      @pSH_Out = H2
      incr pSH_Out
      @pSH_Out = H3
      incr pSH_Out
      @pSH_Out = H4
      incr pSH_Out
    end sub
    '-------------------------------------------------------------------------------
    Last edited by Dale Yarker; 22 Mar 2008, 07:17 AM.
    Dale

    #2
    Code with endian problem fixed. The only change is 15 lines of assembly near the bottom.
    Code:
    '*******************************************************************************
    'File: SHA-1.inc
    'Contains the CalcSHA function.
    'An implementation of Secure Hash Algorithm 1 (SHA-1) described in the Federal
    'Information Processing Standards (FIPS) Publication 180-2, dated
    '2002 August 1 (supersedes FIPS 180-1).
    '
    '             *************************************************
    '             * This implementation of SHA-1 is placed in the *
    '             * Public Domain without warranty of any kind.   *
    '             *         - Use at your own risk. -             *
    '             *************************************************
    '
    '     ## Important Note ###############################################
    '     # From FIPS 180-2, paragraph 8:                                 #
    '     #   "Only algorithm implementations that are validated by       #
    '     #   NIST will be considered as complying with this standard."   #
    '     #                                                               #
    '     # While this implementation correctly calculates the examples   #
    '     # in FIPS 180-2, Appendix A; it has NOT been validated by NIST. #
    '     #################################################################
    '
    '-------------------------------------------------------------------------------
    'Credits/info as downloaded from -
    ' http://www.pbcrypto.com/view.php?algorithm=sha-1
    'NAME: SHA-1
    'CREATOR: NIST and NSA
    'PB AUTHOR: Semen Matusovski
    'DESCRIPTION: Creates a 160-bit hash (message digest) from messages up to
    '264 bits.
    'NOTES: Produces a message digest of 160 bits, providing no more than 80 bits
    'of security against collision attacks.
    'SOURCE: http://www.powerbasic.com/support/forums/Forum7/HTML/000755.html
    '-------------------------------------------------------------------------------
    'Modifications by Dale Yarker.
    ' I probably could not have written a SHA-1 function myself using only the
    ' information in the FIPS, and certainly not in assembly. Thanks Semen!
    ' While trying to read through the code to understand how it works, and to
    ' compare it with the FIPS, I was struck by the lack of comments and
    ' meaningful indentation. My objective is to make the code "over commented" for
    ' everyone except very beginner programmers.
    '
    'Comments within curly braces, "{}", describe changes I made to Semen's code.
    '
    'Comments within square braces, "[]", are the variable names used in
    ' FIPS 180-2; which may, or may not be different here.
    '
    'Other comments maybe Semen's or mine.
    '*******************************************************************************
    '#compile exe 'as opposed to dll.
    '#register none 'turn off automatic assignment of vars to CPU registers by the
                   'compiler due to heavy use of registers in assember section.
    '#dim all 'force declaration/casting of vars before use.
    '#Include "Win32Api.Inc"
    '{Didn't have this file, then turned out not to matter. See Speed Test.}
    '$FileNm = "Win322.hlp"
    
    '{UDT unneeded, removed.}
    '-------------------------------------------------------------------------------
    sub CalcSHA1 alias "CALCULATE_SECURE_HASH_ALGORITHM_1" (byref Str as string, _
                                                 byref SH_Out as string * 20) export
      #register none '- - - - - - - - - - - - - -
      local lStr as long '[l message in bits], here as length in bytes
      dim nq as long '[N] number of blocks in Message (padded)
      local n as long 'Nunber of dwords in Message
      local adrW, adrWW as dword 'pointers to Message and Schedule arrays.
      'local SH as DWrd5_Str_Union '[H0 - H4] Hash Values as dword or string
      local H0, H1, H2, H3, H4 as dword
      local pSH_Out as dword pointer
      dim W(0 to 79) as dword '[W] Message Schedule {colon to TO}
      local A, B, C, D, E as dword '[working variables]
      local TEMP as long '[TEMP]
      '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      'Pad last block of 512 bits (is 64 bytes or 16 dwords)
      lStr = len(Str)
      nq = fix((lStr + 8) / 64) + 1 'calc number of blocks
      n = 16 * nq 'calc number of dwords in WW()
      redim WW(0 to n - 1) as dword '[M] The Message, last block padded with "0"s.
    
      WW(n - 1) = lStr * 8 'Put count of last block Message bits in last dword.
      adrW = varptr(W(0))
      adrWW = varptr(WW(0))
      A = strptr(Str)
      'Labels CalcSHA_Lbl01 thru CalcSHA_Lbl04 used to form loops.
      'Labels CalcSHA_Lbl05 thru CalcSHA_Lbl08 are jump targets, conditionally
      'skipping sections of code (all jumps forward).
      'save current EDI and ESI to stack before using those registers
      ! PUSH EDI
      ! PUSH ESI
    
      ! MOV EDI, adrWW
      ! MOV ESI, A
      ! MOV ECX, lStr
      ! REP MOVSB 'repeat string operation
      'Append a "1" bit after last Message bit in last block
      ! MOV CL, &H80
      ! MOV [EDI], CL
      'Loop 1 setup
      ! MOV EDI, adrWW
      ! MOV ECX, 2
      'Start Loop 1, copy Str to WW()
      CalcSHA_Lbl01:
        ! MOV AX, [EDI]
        ! MOV DX, [EDI + 2]
        ! MOV [EDI], DH
        ! MOV [EDI + 1], DL
        ! MOV [EDI + 2], AH
        ! MOV [EDI + 3], AL
        ! ADD EDI, 4
        ! INC ECX
        ! CMP ECX, n
        ! JNE CalcSHA_Lbl01
      'End Loop 1
      'set initial hash value
      ! MOV H0, &H67452301&
      ! MOV H1, &HEFCDAB89&
      ! MOV H2, &H98BADCFE&
      ! MOV H3, &H10325476&
      ! MOV H4, &HC3D2E1F0&
      'Start Loop 2, move a block from Message into Message schedule
      CalcSHA_Lbl02:
        ! MOV EDI, adrW
        ! MOV ESI, adrWW
        ! MOV ECX, 64
        ! REP MOVSB
        ! MOV adrWW, ESI
        'Loop 3 setup
        ! MOV ECX, 0
        'Start Loop 3
        CalcSHA_Lbl03:
          ! MOV ESI, ECX
          ! ADD ESI, ESI
          ! ADD ESI, ESI
          ! ADD ESI, adrW
    
          ! MOV EAX, [ESI + 52]
          ! XOR EAX, [ESI + 32]
          ! XOR EAX, [ESI + 8]
          ! XOR EAX, [ESI]
    
          ! MOV EDX, EAX
          ! SHL EAX, 1
          ! SHR EDX, 31
          ! OR  EAX, EDX
          ! MOV [ESI + 64], EAX
    
          ! INC ECX
          ! CMP ECX, 64
          ! JNE CalcSHA_Lbl03
        'End Loop 3
        ! MOV EAX, H0
        ! MOV A, EAX
        ! MOV EAX, H1
        ! MOV B, EAX
        ! MOV EAX, H2
        ! MOV C, EAX
        ! MOV EAX, H3
        ! MOV D, EAX
        ! MOV EAX, H4
        ! MOV E, EAX
        'Loop 4 setup
        ! MOV EDI, 0
        'Start Loop 4
        CalcSHA_Lbl04:
          ! CMP EDI, 19
          ! JA CalcSHA_Lbl05
    
          ! MOV ECX, B
          ! AND ECX, C
          ! MOV EAX, B
          ! NOT EAX
          ! AND EAX, D
          ! OR  ECX, EAX
          ! ADD ECX, &H5A827999&
          ! JMP CalcSHA_Lbl08
    
          CalcSHA_Lbl05:
          ! CMP EDI, 39
          ! JA CalcSHA_Lbl06
    
          ! MOV ECX, B
          ! XOR ECX, C
          ! XOR ECX, D
          ! ADD ECX, &H6ED9EBA1&
          ! JMP CalcSHA_Lbl08
    
          CalcSHA_Lbl06:
          ! CMP EDI, 59
          ! JA CalcSHA_Lbl07
    
          ! MOV EAX, B
          ! AND EAX, C
          ! MOV ECX, B
          ! AND ECX, D
          ! MOV EDX, C
          ! AND EDX, D
          ! OR  ECX, EAX
          ! OR  ECX, EDX
          ! ADD ECX, &H8F1BBCDC&
          ! JMP CalcSHA_Lbl08
    
          CalcSHA_Lbl07:
          ! MOV ECX, B
          ! XOR ECX, C
          ! XOR ECX, D
          ! ADD ECX, &HCA62C1D6&
    
          CalcSHA_Lbl08:
          ! MOV EAX, A
          ! MOV EDX, EAX
          ! SHL EAX, 5
          ! SHR EDX, 27
          ! OR  EAX, EDX
          ! ADD EAX, E
          ! ADD ECX, EAX
    
          ! MOV ESI, EDI
          ! ADD ESI, ESI
          ! ADD ESI, ESI
          ! ADD ESI, adrW
          ! MOV ESI, [ESI]
          ! MOV TEMP, ESI
    
          ! ADD Temp, ECX
          ! MOV EAX, D
          ! MOV E, EAX
          ! MOV EAX, C
          ! MOV D, EAX
          ! MOV EAX, B
          ! MOV EDX, EAX
          ! SHL EAX, 30
          ! SHR EDX, 2
          ! OR  EAX, EDX
          ! MOV C, EAX
          ! MOV EAX, A
          ! MOV B, EAX
          ! MOV EAX, TEMP
          ! MOV A, EAX
    
          ! INC EDI
          ! CMP EDI, 80
          ! JNE CalcSHA_Lbl04
        'End Loop 4
        ! MOV EAX, A
        ! ADD H0, EAX
        ! MOV EAX, B
        ! ADD H1, EAX
        ! MOV EAX, C
        ! ADD H2, EAX
        ! MOV EAX, D
        ! ADD H3, EAX
        ! MOV EAX, E
        ! ADD H4, EAX
    
        ! SUB nq, 1
        ! JNE CalcSHA_Lbl02 'done if nq = 0
      'End Loop 2
      'Byte swap for correct endian sequence <--- {Added}
      ! MOV EAX, H0
      ! BSWAP EAX
      ! MOV H0, EAX
      ! MOV EAX, H1
      ! BSWAP EAX
      ! MOV H1, EAX
      ! MOV EAX, H2
      ! BSWAP EAX
      ! MOV H2, EAX
      ! MOV EAX, H3
      ! BSWAP EAX
      ! MOV H3, EAX
      ! MOV EAX, H4
      ! BSWAP EAX
      ! MOV H4, EAX ; <--- {end of added code}
      'restore previous ESI and EDI from stack
      ! POP ESI
      ! POP EDI
      'set return hash
      pSH_Out = varptr(SH_Out)
      @pSH_Out = H0
      incr pSH_Out
      @pSH_Out = H1
      incr pSH_Out
      @pSH_Out = H2
      incr pSH_Out
      @pSH_Out = H3
      incr pSH_Out
      @pSH_Out = H4
      incr pSH_Out
    end sub
    '-------------------------------------------------------------------------------
    Dale

    Comment


      #3
      Test code for CalcSHA1

      Test code for both PBCC and PBWin versions.

      PBCC:
      Code:
      '-------------------------------------------------------------------------------
      #register none 'turn off automatic assignment of vars to CPU registers by the
                     'compiler due to heavy use of registers in assember section.
      #dim all 'force declaration/casting of vars before use.
      
      #include "SHA1_Hash.inc"
      '-------------------------------------------------------------------------------
      'Byte-by-byte binary to hex string
      function tSHA (SHA as string * 20) as string
        local pByte as byte pointer
        local Result as string
        local x as long
        local y as long
        pByte = varptr(SHA)
        for x = 1 to 5
          for y = 1 to 4
            Result = Result + hex$(@pByte, 2)
            incr pByte
          next
          Result = Result + " "
        next
        function = Result
      end function
      '-------------------------------------------------------------------------------
      function pbmain
        '{DIM to LOCAL}
        local SHA as string * 20
      
        ' Control samples from official document
        'FIPS 180-2, A.1 example.
        CalcSHA1("abc", SHA)
        print "Input = abc"
        print "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D" + _
              " FIPS 180-2, A.1"
        print tSHA(SHA) + "As calculated by CalcSHA1."
        print
        '
        'FIPS 180-2, A.2 example.
        CalcSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", SHA)
        print "Input = abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
        print "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1" + _
              " FIPS 180-2, A.2"
        print tSHA(SHA) + "As calculated by CalcSHA1."
        print
        '
        'FIPS 180-2, A.3 example.
        CalcSHA1(string$(1000000, "a"), SHA)
        print "Input = 1000000 lower case " + $dq + "a" + $dq
        print "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F" + _
              " FIPS 180-2, A.3"
        print tSHA(SHA) + "As calculated by CalcSHA1."
        print
      '  '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      '  ' Test of speed
      '  '{On my 2.6GHz Pentium the original speed test returned "0 KB per second".
      '  ' Changing input string to 2 GB returns "9.99999999999999E+998 per
      '  ' second". Rediculous! PC too fast for meaningful change in TIMER with
      '  ' one iteration of CalcSHA. So, wrote new speed test.}
        local Tmp as string 'Input
        local T1, T2 as double 'Start/Stop TIMER values
        local x as long 'FOR/NEXT counter
        '
        print "Speed test, please wait ..."
        Tmp = string$(1000000, "w")
        sleep 0
        T1 = timer
        for x = 1 to 100
          CalcSHA1(Tmp, SHA)
        next
        T2 = timer
        print format$(100000000 / 1000000 / (T2 - T1)) + " MB per second"
        color 2, 15
        print "Press any key to exit"
        waitstat
      end function
      PBWin:
      Code:
      '-------------------------------------------------------------------------------
      #compile exe 'as opposed to dll.
      #register none 'turn off automatic assignment of vars to CPU registers by the
                     'compiler due to heavy use of registers in assember section.
      #dim all 'force declaration/casting of vars before use.
      
      #include "SHA1_Hash.inc"
      '-------------------------------------------------------------------------------
      'Byte-by-byte binary to hex string
      function tSHA (SHA as string * 20) as string
        local pByte as byte pointer
        local Result as string
        local x as long
        local y as long
        pByte = varptr(SHA)
        for x = 1 to 5
          for y = 1 to 4
            Result = Result + hex$(@pByte, 2)
            incr pByte
          next
          Result = Result + " "
        next
        function = Result
      end function
      '-------------------------------------------------------------------------------
      function pbmain
        '{DIM to LOCAL}
        local SHA as string * 20
      
        ' Control samples from official document
        'FIPS 180-2, A.1 example.
        CalcSHA1("abc", SHA)
        msgbox "Input = abc" + $crlf + _
               "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D" + _
               " FIPS 180-2, A.1" + $crlf + _
               tSHA(SHA) + "As calculated by CalcSHA1."
        '
        'FIPS 180-2, A.2 example.
        CalcSHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", SHA)
        msgbox "Input = abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" + _
               $crlf + _
               "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1" + _
               " FIPS 180-2, A.2" + $crlf + _
               tSHA(SHA) + "As calculated by CalcSHA1."
        '
        'FIPS 180-2, A.3 example.
        CalcSHA1(string$(1000000, "a"), SHA)
        msgbox "Input = 1000000 lower case " + $dq + "a" + $dq + $crlf + _
               "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F" + _
               " FIPS 180-2, A.3" + $crlf + _
               tSHA(SHA) + "As calculated by CalcSHA1."
        '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
        ' Test of speed
        '{On my 2.6GHz Pentium the original speed test returned "0 KB per second".
        ' Changing input string to 2 GB returns "9.99999999999999E+998 per
        ' second". Rediculous! PC too fast for meaningful change in TIMER with
        ' one iteration of CalcSHA. So, wrote new speed test.}
        local Tmp as string 'Input
        local T1, T2 as double 'Start/Stop TIMER values
        local x as long 'FOR/NEXT counter
        '
        Tmp = string$(1000000, "w")
        sleep 0
        T1 = timer
        for x = 1 to 100
          CalcSHA1(Tmp, SHA)
        next
        T2 = timer
        msgbox format$(100000000 / 1000000 / (T2 - T1)) + " MB per second"
      end function
      Dale

      Comment

      Working...
      X
      😀
      🥰
      🤢
      😎
      😡
      👍
      👎