Older Version
Newer Version
fqvarfort
Apr 4, 2007
[[user:fqvarfort]]
Code to calculate the SHA256 (Secure Hash Algorithm) of a string.
[[code]]
'==============================================
'
' Secure Hash Algorithm (SHA256)
'
' This is a Liberty Basic implementation of
' of the SHA256 one-way encryption algorithm
'
' Ported to Liberty Basic by fmtSoftware at
' http://www.fmtsoftware.com/
'
' License:
' http://creativecommons.org/licenses/by/3.0/
'
' You may use it in any application, including
' commercial products. A credit to the author
' and a link to the website must be included
' in your program's documentation or readme
' file, and in any source code released to
' the public.
'
' http://www.fmtsoftware.com
'
'==============================================
' Version 0.1.0
'==============================================
'Global data for SHA256
DIM SHA256.Data(0)
GLOBAL SHA256.DataCount
'Print a test SHA256 value
Print SHA256.Evaluate$("test")
SUB SHA256.ConvertToWordArray sMessage$
MODULUS.BITS = 512
CONGRUENT.BITS = 448
BITS.TO.A.BYTE = 8
BYTES.TO.A.WORD = 4
BITS.TO.A.WORD = BYTES.TO.A.WORD * BITS.TO.A.BYTE
'Get the length of the source string
lMessageLength = Len(sMessage$)
'Get padded number of words. Message needs to be congruent to 448 bits,
'modulo 512 bits. If it is exactly congruent to 448 bits, modulo 512 bits
'it must still have another 512 bits added. 512 bits = 64 bytes
'(or 16 * 4 byte words), 448 bits = 56 bytes. This means lNumberOfWords must
'be a multiple of 16 (i.e. 16 * 4 (bytes) * 8 (bits))
lNumberOfWords = (Int((lMessageLength + _
Int((MODULUS.BITS - CONGRUENT.BITS) / BITS.TO.A.BYTE)) / _
Int(MODULUS.BITS / BITS.TO.A.BYTE)) + 1) * _
Int(MODULUS.BITS / BITS.TO.A.WORD)
'Resize the word array and store the number of
'elements in the word array for later use
ReDim SHA256.Data(lNumberOfWords - 1)
SHA256.DataCount = lNumberOfWords
'Combine each block of 4 bytes (ascii code of character) into one long
'value and store in the message. The high-order (most significant) bit of
'each byte is listed first. However,
lByteCount = 0
lBytePosition = 0
Do Until lByteCount >= lMessageLength
' Each word is 4 bytes
lWordCount = Int(lByteCount / BYTES.TO.A.WORD)
lBytePosition = (3 - (lByteCount Mod BYTES.TO.A.WORD)) * BITS.TO.A.BYTE
' NOTE: This is where we are using just the first byte of each unicode
' character, you may want to make the change here, or to the SHA256 method
' so it accepts a byte array.
lByte = Asc(Mid$(sMessage$, lByteCount + 1, 1))
SHA256.Data(lWordCount) = SHA256.Data(lWordCount) Or SHA256.LShift(lByte, lBytePosition)
lByteCount = lByteCount + 1
Loop
'Terminate according to SHA-256 rules with a 1 bit, zeros and the length in
'bits stored in the last two words
lWordCount = Int(lByteCount / BYTES.TO.A.WORD)
lBytePosition = (3 - (lByteCount Mod BYTES.TO.A.WORD)) * BITS.TO.A.BYTE
'Add a terminating 1 bit, all the rest of the bits to the end of the
'word array will default to zero
SHA256.Data(lWordCount) = SHA256.Data(lWordCount) Or _
SHA256.LShift(HEXDEC("&H80"), lBytePosition)
'We put the length of the message in bits into the last two words, to get
'the length in bits we need to multiply by 8 (or left shift 3). This left
'shifted value is put in the last word. Any bits shifted off the left edge
'need to be put in the penultimate word, we can work out which bits by shifting
'right the length by 29 bits.
SHA256.Data(lNumberOfWords - 1) = SHA256.LShift(lMessageLength, 3)
SHA256.Data(lNumberOfWords - 2) = SHA256.RShift(lMessageLength, 29)
End Sub
SUB SHA256.Initialize
DIM SHA256.K(64)
'Initialize the K array
SHA256.K(0) = HEXDEC("&H428A2F98")
SHA256.K(1) = HEXDEC("&H71374491")
SHA256.K(2) = HEXDEC("&HB5C0FBCF")
SHA256.K(3) = HEXDEC("&HE9B5DBA5")
SHA256.K(4) = HEXDEC("&H3956C25B")
SHA256.K(5) = HEXDEC("&H59F111F1")
SHA256.K(6) = HEXDEC("&H923F82A4")
SHA256.K(7) = HEXDEC("&HAB1C5ED5")
SHA256.K(8) = HEXDEC("&HD807AA98")
SHA256.K(9) = HEXDEC("&H12835B01")
SHA256.K(10) = HEXDEC("&H243185BE")
SHA256.K(11) = HEXDEC("&H550C7DC3")
SHA256.K(12) = HEXDEC("&H72BE5D74")
SHA256.K(13) = HEXDEC("&H80DEB1FE")
SHA256.K(14) = HEXDEC("&H9BDC06A7")
SHA256.K(15) = HEXDEC("&HC19BF174")
SHA256.K(16) = HEXDEC("&HE49B69C1")
SHA256.K(17) = HEXDEC("&HEFBE4786")
SHA256.K(18) = HEXDEC("&HFC19DC6")
SHA256.K(19) = HEXDEC("&H240CA1CC")
SHA256.K(20) = HEXDEC("&H2DE92C6F")
SHA256.K(21) = HEXDEC("&H4A7484AA")
SHA256.K(22) = HEXDEC("&H5CB0A9DC")
SHA256.K(23) = HEXDEC("&H76F988DA")
SHA256.K(24) = HEXDEC("&H983E5152")
SHA256.K(25) = HEXDEC("&HA831C66D")
SHA256.K(26) = HEXDEC("&HB00327C8")
SHA256.K(27) = HEXDEC("&HBF597FC7")
SHA256.K(28) = HEXDEC("&HC6E00BF3")
SHA256.K(29) = HEXDEC("&HD5A79147")
SHA256.K(30) = HEXDEC("&H6CA6351")
SHA256.K(31) = HEXDEC("&H14292967")
SHA256.K(32) = HEXDEC("&H27B70A85")
SHA256.K(33) = HEXDEC("&H2E1B2138")
SHA256.K(34) = HEXDEC("&H4D2C6DFC")
SHA256.K(35) = HEXDEC("&H53380D13")
SHA256.K(36) = HEXDEC("&H650A7354")
SHA256.K(37) = HEXDEC("&H766A0ABB")
SHA256.K(38) = HEXDEC("&H81C2C92E")
SHA256.K(39) = HEXDEC("&H92722C85")
SHA256.K(40) = HEXDEC("&HA2BFE8A1")
SHA256.K(41) = HEXDEC("&HA81A664B")
SHA256.K(42) = HEXDEC("&HC24B8B70")
SHA256.K(43) = HEXDEC("&HC76C51A3")
SHA256.K(44) = HEXDEC("&HD192E819")
SHA256.K(45) = HEXDEC("&HD6990624")
SHA256.K(46) = HEXDEC("&HF40E3585")
SHA256.K(47) = HEXDEC("&H106AA070")
SHA256.K(48) = HEXDEC("&H19A4C116")
SHA256.K(49) = HEXDEC("&H1E376C08")
SHA256.K(50) = HEXDEC("&H2748774C")
SHA256.K(51) = HEXDEC("&H34B0BCB5")
SHA256.K(52) = HEXDEC("&H391C0CB3")
SHA256.K(53) = HEXDEC("&H4ED8AA4A")
SHA256.K(54) = HEXDEC("&H5B9CCA4F")
SHA256.K(55) = HEXDEC("&H682E6FF3")
SHA256.K(56) = HEXDEC("&H748F82EE")
SHA256.K(57) = HEXDEC("&H78A5636F")
SHA256.K(58) = HEXDEC("&H84C87814")
SHA256.K(59) = HEXDEC("&H8CC70208")
SHA256.K(60) = HEXDEC("&H90BEFFFA")
SHA256.K(61) = HEXDEC("&HA4506CEB")
SHA256.K(62) = HEXDEC("&HBEF9A3F7")
SHA256.K(63) = HEXDEC("&HC67178F2")
END SUB
FUNCTION SHA256.Evaluate$(sMessage$)
Dim SHA256.W(64)
'Initialize the SHA256 object
CALL SHA256.Initialize
'Initial hash values
h0 = HEXDEC("&H6A09E667")
h1 = HEXDEC("&HBB67AE85")
h2 = HEXDEC("&H3C6EF372")
h3 = HEXDEC("&HA54FF53A")
h4 = HEXDEC("&H510E527F")
h5 = HEXDEC("&H9B05688C")
h6 = HEXDEC("&H1F83D9AB")
h7 = HEXDEC("&H5BE0CD19")
'Convert the string into an
'array of numeric values (32-bit)
Call SHA256.ConvertToWordArray sMessage$
'Evaluate the SHA256 digest
For i = 0 To (SHA256.DataCount - 1) Step 16
a = h0
b = h1
c = h2
d = h3
e = h4
f = h5
g = h6
h = h7
For j = 0 To 63
If j < 16 Then
SHA256.W(j) = SHA256.Data(j + i)
Else
SHA256.W(j) = SHA256.AddUnsigned(SHA256.AddUnsigned(SHA256.AddUnsigned(SHA256.Gamma1(SHA256.W(j - 2)), _
SHA256.W(j - 7)), SHA256.Gamma0(SHA256.W(j - 15))), SHA256.W(j - 16))
End If
t1 = SHA256.AddUnsigned(SHA256.AddUnsigned(SHA256.AddUnsigned(SHA256.AddUnsigned(h, SHA256.Sigma1(e)), _
SHA256.Ch(e, f, g)), SHA256.K(j)), SHA256.W(j))
t2 = SHA256.AddUnsigned(SHA256.Sigma0(a), SHA256.Maj(a, b, c))
h = g
g = f
f = e
e = SHA256.AddUnsigned(d, t1)
d = c
c = b
b = a
a = SHA256.AddUnsigned(t1, t2)
Next
h0 = SHA256.AddUnsigned(a, h0)
h1 = SHA256.AddUnsigned(b, h1)
h2 = SHA256.AddUnsigned(c, h2)
h3 = SHA256.AddUnsigned(d, h3)
h4 = SHA256.AddUnsigned(e, h4)
h5 = SHA256.AddUnsigned(f, h5)
h6 = SHA256.AddUnsigned(g, h6)
h7 = SHA256.AddUnsigned(h, h7)
Next
'Output the 256-bit digest
SHA256.Evaluate$ = Lower$(Right$("00000000" + DecHex$(h0), 8) + _
Right$("00000000" + DecHex$(h1), 8) + _
Right$("00000000" + DecHex$(h2), 8) + _
Right$("00000000" + DecHex$(h3), 8) + _
Right$("00000000" + DecHex$(h4), 8) + _
Right$("00000000" + DecHex$(h5), 8) + _
Right$("00000000" + DecHex$(h6), 8) + _
Right$("00000000" + DecHex$(h7), 8))
END FUNCTION
FUNCTION SHA256.BitNot(X)
SHA256.BitNot = 0
For a = 0 To 31
IF ((X And (2 ^ a)) = 0) THEN
SHA256.BitNot = SHA256.BitNot Or (2 ^ a)
END IF
Next
END FUNCTION
FUNCTION SHA256.Ch(X, Y, z)
SHA256.Ch = ((X And Y) Xor ((SHA256.BitNot(X)) And z))
END FUNCTION
FUNCTION SHA256.Maj(X, Y, z)
SHA256.Maj = ((X And Y) Xor (X And z) Xor (Y And z))
END FUNCTION
FUNCTION SHA256.S(X, n)
SHA256.S = (SHA256.RShift(X, n)) Or SHA256.LShift(X, (32 - n))
END FUNCTION
FUNCTION SHA256.R(X, n)
SHA256.R = SHA256.RShift(X, n) 'CInt(n And mlOnBits(4)))
END FUNCTION
FUNCTION SHA256.Sigma0(X)
SHA256.Sigma0 = (SHA256.S(X, 2) Xor SHA256.S(X, 13) Xor SHA256.S(X, 22))
END FUNCTION
FUNCTION SHA256.Sigma1(X)
SHA256.Sigma1 = (SHA256.S(X, 6) Xor SHA256.S(X, 11) Xor SHA256.S(X, 25))
END FUNCTION
FUNCTION SHA256.Gamma0(X)
SHA256.Gamma0 = (SHA256.S(X, 7) Xor SHA256.S(X, 18) Xor SHA256.R(X, 3))
END FUNCTION
FUNCTION SHA256.Gamma1(X)
SHA256.Gamma1 = (SHA256.S(X, 17) Xor SHA256.S(X, 19) Xor SHA256.R(X, 10))
END FUNCTION
FUNCTION SHA256.AddUnsigned(lX, lY)
SHA256.AddUnsigned = (lX + lY) AND HEXDEC("&HFFFFFFFF")
END FUNCTION
FUNCTION SHA256.RShift(lValue, iShiftBits)
For a = 1 To iShiftBits
lValue = lValue AND HEXDEC("&HFFFFFFFE")
lValue = Int(lValue / 2)
lValue = lValue And HEXDEC("&HFFFFFFFF")
Next
SHA256.RShift = lValue And HEXDEC("&HFFFFFFFF")
End Function
FUNCTION SHA256.LShift(lValue, iShiftBits)
For a = 1 To iShiftBits
lValue = lValue AND HEXDEC("&H7FFFFFFF")
lValue = lValue * 2
lValue = lValue And HEXDEC("&HFFFFFFFF")
Next
SHA256.LShift = lValue And HEXDEC("&HFFFFFFFF")
End Function
[[code]]