SHA256
Computes the SHA256 hash for the input data.
Private Shared Sub DBL_INT_ADD(ByRef a As UInteger, ByRef b As UInteger, c As UInteger)
If a > &HFFFFFFFFUI - c Then
b += 1
End If
a += c
End Sub
Private Shared Function ROTLEFT(a As UInteger, b As Byte) As UInteger
Return ((a << b) Or (a >> (32 - b)))
End Function
Private Shared Function ROTRIGHT(a As UInteger, b As Byte) As UInteger
Return (((a) >> (b)) Or ((a) << (32 - (b))))
End Function
Private Shared Function CH(x As UInteger, y As UInteger, z As UInteger) As UInteger
Return (((x) And (y)) Xor (Not (x) And (z)))
End Function
Private Shared Function MAJ(x As UInteger, y As UInteger, z As UInteger) As UInteger
Return (((x) And (y)) Xor ((x) And (z)) Xor ((y) And (z)))
End Function
Private Shared Function EP0(x As UInteger) As UInteger
Return (ROTRIGHT(x, 2) Xor ROTRIGHT(x, 13) Xor ROTRIGHT(x, 22))
End Function
Private Shared Function EP1(x As UInteger) As UInteger
Return (ROTRIGHT(x, 6) Xor ROTRIGHT(x, 11) Xor ROTRIGHT(x, 25))
End Function
Private Shared Function SIG0(x As UInteger) As UInteger
Return (ROTRIGHT(x, 7) Xor ROTRIGHT(x, 18) Xor ((x) >> 3))
End Function
Private Shared Function SIG1(x As UInteger) As UInteger
Return (ROTRIGHT(x, 17) Xor ROTRIGHT(x, 19) Xor ((x) >> 10))
End Function
Private Structure SHA256_CTX
Public data As Byte()
Public datalen As UInteger
Public bitlen As UInteger()
Public state As UInteger()
End Structure
Shared k As UInteger() = {&H428A2F98, &H71374491, &HB5C0FBCFUI, &HE9B5DBA5UI, &H3956C25B, &H59F111F1,
&H923F82A4UI, &HAB1C5ED5UI, &HD807AA98UI, &H12835B01, &H243185BE, &H550C7DC3,
&H72BE5D74, &H80DEB1FEUI, &H9BDC06A7UI, &HC19BF174UI, &HE49B69C1UI, &HEFBE4786UI,
&HFC19DC6, &H240CA1CC, &H2DE92C6F, &H4A7484AA, &H5CB0A9DC, &H76F988DA,
&H983E5152UI, &HA831C66DUI, &HB00327C8UI, &HBF597FC7UI, &HC6E00BF3UI, &HD5A79147UI,
&H6CA6351, &H14292967, &H27B70A85, &H2E1B2138, &H4D2C6DFC, &H53380D13,
&H650A7354, &H766A0ABB, &H81C2C92EUI, &H92722C85UI, &HA2BFE8A1UI, &HA81A664BUI,
&HC24B8B70UI, &HC76C51A3UI, &HD192E819UI, &HD6990624UI, &HF40E3585UI, &H106AA070,
&H19A4C116, &H1E376C08, &H2748774C, &H34B0BCB5, &H391C0CB3, &H4ED8AA4A,
&H5B9CCA4F, &H682E6FF3, &H748F82EE, &H78A5636F, &H84C87814UI, &H8CC70208UI,
&H90BEFFFAUI, &HA4506CEBUI, &HBEF9A3F7UI, &HC67178F2UI}
Private Shared Sub SHA256Transform(ByRef ctx As SHA256_CTX, data As Byte())
Dim a As UInteger, b As UInteger, c As UInteger, d As UInteger, e As UInteger, f As UInteger,
g As UInteger, h As UInteger, i As UInteger, j As UInteger, t1 As UInteger, t2 As UInteger
Dim m As UInteger() = New UInteger(63) {}
i = 0
j = 0
While i < 16
m(i) = ((CULng(data(j)) << 24) Or (CULng(data(j + 1)) << 16) Or (CULng(data(j + 2)) << 8) Or (data(j + 3))) And UInteger.MaxValue
i += 1
j += 4
End While
While i < 64
m(i) = CULng(SIG1(m(i - 2))) + m(i - 7) + SIG0(m(i - 15)) + m(i - 16) And UInteger.MaxValue
i += 1
End While
a = ctx.state(0)
b = ctx.state(1)
c = ctx.state(2)
d = ctx.state(3)
e = ctx.state(4)
f = ctx.state(5)
g = ctx.state(6)
h = ctx.state(7)
For i = 0 To 63
t1 = (CULng(h) + EP1(e) + CH(e, f, g) + k(i) + m(i)) And UInteger.MaxValue
t2 = (CULng(EP0(a)) + MAJ(a, b, c)) And UInteger.MaxValue
h = g
g = f
f = e
e = (CULng(d) + t1) And UInteger.MaxValue
d = c
c = b
b = a
a = (CULng(t1) + t2) And UInteger.MaxValue
Next
ctx.state(0) = (CULng(ctx.state(0)) + a) And UInteger.MaxValue
ctx.state(1) = (CULng(ctx.state(1)) + b) And UInteger.MaxValue
ctx.state(2) = (CULng(ctx.state(2)) + c) And UInteger.MaxValue
ctx.state(3) = (CULng(ctx.state(3)) + d) And UInteger.MaxValue
ctx.state(4) = (CULng(ctx.state(4)) + e) And UInteger.MaxValue
ctx.state(5) = (CULng(ctx.state(5)) + f) And UInteger.MaxValue
ctx.state(6) = (CULng(ctx.state(6)) + g) And UInteger.MaxValue
ctx.state(7) = (CULng(ctx.state(7)) + h) And UInteger.MaxValue
End Sub
Private Shared Sub SHA256Init(ByRef ctx As SHA256_CTX)
ctx.datalen = 0
ctx.bitlen(0) = 0
ctx.bitlen(1) = 0
ctx.state(0) = &H6A09E667
ctx.state(1) = &HBB67AE85UI
ctx.state(2) = &H3C6EF372
ctx.state(3) = &HA54FF53AUI
ctx.state(4) = &H510E527F
ctx.state(5) = &H9B05688CUI
ctx.state(6) = &H1F83D9AB
ctx.state(7) = &H5BE0CD19
End Sub
Private Shared Sub SHA256Update(ByRef ctx As SHA256_CTX, data As Byte(), len As UInteger)
For i As UInteger = 0 To len - 1
ctx.data(ctx.datalen) = data(i)
ctx.datalen += 1
If ctx.datalen = 64 Then
SHA256Transform(ctx, ctx.data)
DBL_INT_ADD(ctx.bitlen(0), ctx.bitlen(1), 512)
ctx.datalen = 0
End If
Next
End Sub
Private Shared Sub SHA256Final(ByRef ctx As SHA256_CTX, hash As Byte())
Dim i As UInteger = ctx.datalen
If ctx.datalen < 56 Then
ctx.data(System.Math.Max(i, i - 1)) = &H80
i += 1
While i < 56
ctx.data(System.Math.Max(i, i - 1)) = &H0
i += 1
End While
Else
ctx.data(System.Math.Max(i, i - 1)) = &H80
i += 1
While i < 64
ctx.data(System.Math.Max(i, i - 1)) = &H0
i += 1
End While
SHA256Transform(ctx, ctx.data)
End If
DBL_INT_ADD(ctx.bitlen(0), ctx.bitlen(1), ctx.datalen * 8)
ctx.data(63) = CByte(ctx.bitlen(0))
ctx.data(62) = CByte(ctx.bitlen(0) >> 8)
ctx.data(61) = CByte(ctx.bitlen(0) >> 16)
ctx.data(60) = CByte(ctx.bitlen(0) >> 24)
ctx.data(59) = CByte(ctx.bitlen(1))
ctx.data(58) = CByte(ctx.bitlen(1) >> 8)
ctx.data(57) = CByte(ctx.bitlen(1) >> 16)
ctx.data(56) = CByte(ctx.bitlen(1) >> 24)
SHA256Transform(ctx, ctx.data)
For i = 0 To 3
hash(i) = CByte(((ctx.state(0)) >> CInt(24 - i * 8)) And &HFF)
hash(i + 4) = CByte(((ctx.state(1)) >> CInt(24 - i * 8)) And &HFF)
hash(i + 8) = CByte(((ctx.state(2)) >> CInt(24 - i * 8)) And &HFF)
hash(i + 12) = CByte((ctx.state(3) >> CInt(24 - i * 8)) And &HFF)
hash(i + 16) = CByte((ctx.state(4) >> CInt(24 - i * 8)) And &HFF)
hash(i + 20) = CByte((ctx.state(5) >> CInt(24 - i * 8)) And &HFF)
hash(i + 24) = CByte((ctx.state(6) >> CInt(24 - i * 8)) And &HFF)
hash(i + 28) = CByte((ctx.state(7) >> CInt(24 - i * 8)) And &HFF)
Next
End Sub
Public Shared Function SHA256(data As String) As String
Dim ctx As New SHA256_CTX()
ctx.data = New Byte(63) {}
ctx.bitlen = New UInteger(1) {}
ctx.state = New UInteger(7) {}
Dim hash As Byte() = New Byte(31) {}
Dim hashStr As String = String.Empty
SHA256Init(ctx)
SHA256Update(ctx, Encoding.[Default].GetBytes(data), CUInt(data.Length))
SHA256Final(ctx, hash)
For i As Integer = 0 To 31
hashStr += String.Format("{0:X2}", hash(i))
Next
Return hashStr
End Function
Example
Dim data = "Hello World!"
Dim sha256 = SHA256(data)
Output
7F83B1657FF1FC53B92DC18148A1D65DFC2D4B1FA3D677284ADDD200126D9069