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