#include once "window9.bi"

' AES Encryption Implementation by: Chris Brown(2007) aka Zamaster
'
' -Takes plain text and converts it to encrypted ASCII
' -Keys must be 128 bits in size, or 32 hex places/16 char places
' -Set ed in RIJNDAEL_Encrypt to 2 for decryption, 1 for encryption
'
Sub RIJNDAEL_ConvertEXPtoKey(byval index As Long, ekey() As Ubyte, tkey() As Ubyte)
	Dim As Ubyte x,y,b
	b = (index-1)*4
	For y = 1 To 4
		For x = 1 To 4
			tkey(x,y) = ekey(b+x,y)
		Next x
	Next y
End Sub


Function RIJNDAEL_InverseS(byval v As Ubyte) As Ubyte
	Static As Ubyte RSBOX(0 To 255) = {_
	&H52, &H09, &H6A, &HD5, &H30, &H36, &HA5, &H38, &HBF, &H40, &HA3, &H9E, &H81, &HF3, &HD7, &HFB, _
	&H7C, &HE3, &H39, &H82, &H9B, &H2F, &HFF, &H87, &H34, &H8E, &H43, &H44, &HC4, &HDE, &HE9, &HCB, _
	&H54, &H7B, &H94, &H32, &HA6, &HC2, &H23, &H3D, &HEE, &H4C, &H95, &H0B, &H42, &HFA, &HC3, &H4E, _
	&H08, &H2E, &HA1, &H66, &H28, &HD9, &H24, &HB2, &H76, &H5B, &HA2, &H49, &H6D, &H8B, &HD1, &H25, _
	&H72, &HF8, &HF6, &H64, &H86, &H68, &H98, &H16, &HD4, &HA4, &H5C, &HCC, &H5D, &H65, &HB6, &H92, _
	&H6C, &H70, &H48, &H50, &HFD, &HED, &HB9, &HDA, &H5E, &H15, &H46, &H57, &HA7, &H8D, &H9D, &H84, _
	&H90, &HD8, &HAB, &H00, &H8C, &HBC, &HD3, &H0A, &HF7, &HE4, &H58, &H05, &HB8, &HB3, &H45, &H06, _
	&HD0, &H2C, &H1E, &H8F, &HCA, &H3F, &H0F, &H02, &HC1, &HAF, &HBD, &H03, &H01, &H13, &H8A, &H6B, _
	&H3A, &H91, &H11, &H41, &H4F, &H67, &HDC, &HEA, &H97, &HF2, &HCF, &HCE, &HF0, &HB4, &HE6, &H73, _
	&H96, &HAC, &H74, &H22, &HE7, &HAD, &H35, &H85, &HE2, &HF9, &H37, &HE8, &H1C, &H75, &HDF, &H6E, _
	&H47, &HF1, &H1A, &H71, &H1D, &H29, &HC5, &H89, &H6F, &HB7, &H62, &H0E, &HAA, &H18, &HBE, &H1B, _
	&HFC, &H56, &H3E, &H4B, &HC6, &HD2, &H79, &H20, &H9A, &HDB, &HC0, &HFE, &H78, &HCD, &H5A, &HF4, _
	&H1F, &HDD, &HA8, &H33, &H88, &H07, &HC7, &H31, &HB1, &H12, &H10, &H59, &H27, &H80, &HEC, &H5F, _
	&H60, &H51, &H7F, &HA9, &H19, &HB5, &H4A, &H0D, &H2D, &HE5, &H7A, &H9F, &H93, &HC9, &H9C, &HEF, _
	&HA0, &HE0, &H3B, &H4D, &HAE, &H2A, &HF5, &HB0, &HC8, &HEB, &HBB, &H3C, &H83, &H53, &H99, &H61, _
	&H17, &H2B, &H04, &H7E, &HBA, &H77, &HD6, &H26, &HE1, &H69, &H14, &H63, &H55, &H21, &H0C, &H7D}
	Dim As Long x
	x = RSBOX((v And &HF0) + (v And &HF))
	Return x
End Function

Function RIJNDAEL_S(byval v As Ubyte) As Ubyte
	Static As Ubyte RSBOX(0 To 255) = {_
	&H63, &H7C, &H77, &H7B, &HF2, &H6B, &H6F, &HC5, &H30, &H01, &H67, &H2B, &HFE, &HD7, &HAB, &H76, _
	&HCA, &H82, &HC9, &H7D, &HFA, &H59, &H47, &HF0, &HAD, &HD4, &HA2, &HAF, &H9C, &HA4, &H72, &HC0, _
	&HB7, &HFD, &H93, &H26, &H36, &H3F, &HF7, &HCC, &H34, &HA5, &HE5, &HF1, &H71, &HD8, &H31, &H15, _
	&H04, &HC7, &H23, &HC3, &H18, &H96, &H05, &H9A, &H07, &H12, &H80, &HE2, &HEB, &H27, &HB2, &H75, _
	&H09, &H83, &H2C, &H1A, &H1B, &H6E, &H5A, &HA0, &H52, &H3B, &HD6, &HB3, &H29, &HE3, &H2F, &H84, _
	&H53, &HD1, &H00, &HED, &H20, &HFC, &HB1, &H5B, &H6A, &HCB, &HBE, &H39, &H4A, &H4C, &H58, &HCF, _
	&HD0, &HEF, &HAA, &HFB, &H43, &H4D, &H33, &H85, &H45, &HF9, &H02, &H7F, &H50, &H3C, &H9F, &HA8, _
	&H51, &HA3, &H40, &H8F, &H92, &H9D, &H38, &HF5, &HBC, &HB6, &HDA, &H21, &H10, &HFF, &HF3, &HD2, _
	&HCD, &H0C, &H13, &HEC, &H5F, &H97, &H44, &H17, &HC4, &HA7, &H7E, &H3D, &H64, &H5D, &H19, &H73, _
	&H60, &H81, &H4F, &HDC, &H22, &H2A, &H90, &H88, &H46, &HEE, &HB8, &H14, &HDE, &H5E, &H0B, &HDB, _
	&HE0, &H32, &H3A, &H0A, &H49, &H06, &H24, &H5C, &HC2, &HD3, &HAC, &H62, &H91, &H95, &HE4, &H79, _
	&HE7, &HC8, &H37, &H6D, &H8D, &HD5, &H4E, &HA9, &H6C, &H56, &HF4, &HEA, &H65, &H7A, &HAE, &H08, _
	&HBA, &H78, &H25, &H2E, &H1C, &HA6, &HB4, &HC6, &HE8, &HDD, &H74, &H1F, &H4B, &HBD, &H8B, &H8A, _
	&H70, &H3E, &HB5, &H66, &H48, &H03, &HF6, &H0E, &H61, &H35, &H57, &HB9, &H86, &HC1, &H1D, &H9E, _
	&HE1, &HF8, &H98, &H11, &H69, &HD9, &H8E, &H94, &H9B, &H1E, &H87, &HE9, &HCE, &H55, &H28, &HDF, _
	&H8C, &HA1, &H89, &H0D, &HBF, &HE6, &H42, &H68, &H41, &H99, &H2D, &H0F, &HB0, &H54, &HBB, &H16}
	Dim As Long x
	x = RSBOX((v And &HF0) + (v And &HF))
	Return x
End Function


Sub RIJNDAEL_SubBytes(T() As Ubyte)
	Dim As Ubyte x,y, temp
	For y = 1 To 4
		For x = 1 To 4
			temp = T(x,y)
			T(x,y) = RIJNDAEL_S(temp)
		Next x
	Next y
End Sub

Sub RIJNDAEL_InverseSubBytes(T() As Ubyte)
	Dim As Ubyte x,y, temp
	For y = 1 To 4
		For x = 1 To 4
			temp = T(x,y)
			T(x,y) = RIJNDAEL_InverseS(temp)
		Next x
	Next y
End Sub


Sub RIJNDAEL_ShiftRows(T() As Ubyte)
	Swap T(1,2), T(4,2)
	Swap T(2,2), T(1,2)
	Swap T(3,2), T(2,2)
	Swap T(1,3), T(3,3)
	Swap T(2,3), T(4,3)
	Swap T(1,4), T(2,4)
	Swap T(3,4), T(4,4)
	Swap T(1,4), T(3,4)
End Sub

Sub RIJNDAEL_InverseShiftRows(T() As Ubyte)
	Swap T(1,2), T(2,2)
	Swap T(1,2), T(4,2)
	Swap T(3,2), T(4,2)
	Swap T(1,3), T(3,3)
	Swap T(2,3), T(4,3)
	Swap T(1,4), T(2,4)
	Swap T(2,4), T(3,4)
	Swap T(3,4), T(4,4)
End Sub



Function RIJNDAEL_Gmul(Byval a As Ubyte, Byval b As Ubyte) As Ubyte
	Dim As Ubyte p, i, hi
	For i = 1 To 8
		If (b And 1) = &H01 Then p = p Xor a
		hi = a And &H80
		a = a Shl 1
		If hi = &H80 Then a = a Xor &H1B
		b = b Shr 1
	Next i
	Return p
End Function


Sub RIJNDAEL_MixCollums(T() As Ubyte)
	Dim As Ubyte a(1 To 4), b(1 To 4), i, q, hb
	For q = 1 To 4
		For i = 1 To 4
			a(i) = T(q,i)
			hb = T(q,i) And &H80
			b(i) = a(i) Shl 1
			If hb = &h80 Then b(i) = b(i) Xor &H1B
		Next i
		T(q,1) = b(1) Xor a(4) Xor a(3) Xor b(2) Xor a(2)
		T(q,2) = b(2) Xor a(1) Xor a(4) Xor b(3) Xor a(3)
		T(q,3) = b(3) Xor a(2) Xor a(1) Xor b(4) Xor a(4)
		T(q,4) = b(4) Xor a(3) Xor a(2) Xor b(1) Xor a(1)
	Next q
End Sub

Sub RIJNDAEL_InverseMixCollums(T() As Ubyte)
	Dim As Ubyte a(1 To 4), q, i
	For q = 1 To 4
		For i = 1 To 4
			a(i) = T(q,i)
		Next
		T(q,1) = RIJNDAEL_Gmul(a(1),&HE) Xor RIJNDAEL_Gmul(a(2),&HB) Xor RIJNDAEL_Gmul(a(3),&HD) Xor RIJNDAEL_Gmul(a(4),&H9)
		T(q,2) = RIJNDAEL_Gmul(a(1),&H9) Xor RIJNDAEL_Gmul(a(2),&HE) Xor RIJNDAEL_Gmul(a(3),&HB) Xor RIJNDAEL_Gmul(a(4),&HD)
		T(q,3) = RIJNDAEL_Gmul(a(1),&HD) Xor RIJNDAEL_Gmul(a(2),&H9) Xor RIJNDAEL_Gmul(a(3),&HE) Xor RIJNDAEL_Gmul(a(4),&HB)
		T(q,4) = RIJNDAEL_Gmul(a(1),&HB) Xor RIJNDAEL_Gmul(a(2),&HD) Xor RIJNDAEL_Gmul(a(3),&H9) Xor RIJNDAEL_Gmul(a(4),&HE)
	Next q
End Sub


Sub RIJNDAEL_AddKey(T() As Ubyte, K() As Ubyte)
	Dim As Ubyte x,y
	For y = 1 To 4
		For x = 1 To 4
			T(x,y) = T(x,y) Xor K(x,y)
		Next x
	Next y
End Sub


Sub RIJNDAEL_ExpandKey(K1() As Ubyte, K2() As Ubyte)
	Static As Ubyte RCON(1 To 10) = {&H01, &H02, &H04, &H08, &H10, &H20, &H40, &H80, &H1B, &H36}
	Dim As Long i, q, a, opt4, opt4m1, opt4m4, o4, om1, om4
	K2(1,1) = K1(1,1) Xor RIJNDAEL_S(K1(4,2)) Xor RCON(1)
	K2(1,2) = K1(1,2) Xor RIJNDAEL_S(K1(4,3))
	K2(1,3) = K1(1,3) Xor RIJNDAEL_S(K1(4,4))
	K2(1,4) = K1(1,4) Xor RIJNDAEL_S(K1(4,1))
	For i = 2 To 4
		For q = 1 To 4
			K2(i,q) = K2(i-1,q) Xor K1(i,q)
		Next q
	Next i
	
	For i = 2 To 10
		opt4 = ((i-1) Shl 2) + 1
		opt4m1 = opt4 - 1
		opt4m4 = opt4 - 4
		K2(opt4,1) = K2(opt4m4,1) Xor RIJNDAEL_S(K2(opt4m1,2)) Xor RCON(i)
		K2(opt4,2) = K2(opt4m4,2) Xor RIJNDAEL_S(K2(opt4m1,3))
		K2(opt4,3) = K2(opt4m4,3) Xor RIJNDAEL_S(K2(opt4m1,4))
		K2(opt4,4) = K2(opt4m4,4) Xor RIJNDAEL_S(K2(opt4m1,1))
		For q = 2 To 4
			o4 = opt4m1 + q
			om1 = o4-1
			om4 = o4-4
			For a = 1 To 4
				K2(o4,a) = K2(om1,a) Xor K2(om4,a)
			Next a
		Next q
	Next i
End Sub


Sub RIJNDAEL_TextToState(Byref texts As String, T() As Ubyte, byval dirc As Long)
	Dim As String text
	text = texts
	Dim As Ubyte x,y
	If dirc = 1 Then
		For y = 1 To 4
			For x = 1 To 4
				T(x,y) = Asc(Mid(text,(((y-1) Shl 2) + x),1))
			Next x
		Next y
	Else
		For y = 1 To 4
			For x = 1 To 4
				T(y,x) = Asc(Mid(text,(((y-1) Shl 2) + x),1))
			Next x
		Next y
	Endif
End Sub

Sub RIJNDAEL_Rotate(K() As Ubyte)
	Swap K(1,2), K(2,1)
	Swap K(1,3), K(3,1)
	Swap K(1,4), K(4,1)
	Swap K(2,4), K(4,2)
	Swap K(3,4), K(4,3)
	Swap K(2,3), K(3,2)
End Sub

Function RIJNDAEL_StateToText(T() As Ubyte) As String
	Dim As String s
	Dim As Long x,y
	For y = 1 To 4
		For x = 1 To 4
			s += Chr(T(x,y))
		Next x
	Next y
	Return s
End Function

Function RIJNDAEL_StrToHex (Byref s As String) As String
	Dim As String convstr
	convstr = s
	Dim As Long i
	Dim As String ftext
	For i = 1 To Len(convstr)
		ftext += Hex(Asc(Mid(convstr,i,1)),2)
	Next i
	Return ftext
End Function

Function RIJNDAEL_HexToStr (Byref s As String) As String
	Dim As String convstr
	convstr = s
	If Len(convstr) Mod 2 = 1 Then convstr += "0"
	Dim As Long i
	Dim As String   f
	For i = 1 To Len(convstr) Step 2
		f += Chr(Val("&H"+Mid(convstr,i,2)))
	Next i
	Return f
End Function


Sub RIJNDAEL_BlockEncrypt(T() As Ubyte, K1() As Ubyte, K2() As Ubyte)
	Dim As Long i
	Dim As Ubyte TempKey(1 To 4, 1 To 4)
	RIJNDAEL_AddKey T(), K1()
	RIJNDAEL_Rotate T()
	For i = 1 To 9
		RIJNDAEL_SubBytes T()
		RIJNDAEL_ShiftRows T()
		RIJNDAEL_MixCollums T()
		RIJNDAEL_ConvertEXPtoKey i, K2(), TempKey()
		RIJNDAEL_AddKey T(), TempKey()
	Next i
	RIJNDAEL_SubBytes T()
	RIJNDAEL_ShiftRows T()
	RIJNDAEL_ConvertEXPtoKey 10, K2(), TempKey()
	RIJNDAEL_AddKey T(), TempKey()
End Sub


Sub RIJNDAEL_BlockDecrypt(T() As Ubyte, K1() As Ubyte, K2() As Ubyte)
	Dim As Long i
	Dim As Ubyte TempKey(1 To 4, 1 To 4)
	RIJNDAEL_ConvertEXPtoKey 10, K2(), TempKey()
	RIJNDAEL_AddKey T(), TempKey()
	For i = 9 To 1 Step -1
		RIJNDAEL_InverseShiftRows T()
		RIJNDAEL_InverseSubBytes T()
		RIJNDAEL_ConvertEXPtoKey i, K2(), TempKey()
		RIJNDAEL_AddKey T(), TempKey()
		RIJNDAEL_InverseMixCollums T()
	Next i
	RIJNDAEL_InverseShiftRows T()
	RIJNDAEL_InverseSubBytes T()
	RIJNDAEL_AddKey T(), K1()
End Sub


Function RIJNDAEL_Encrypt(Byref pptext As String, Byref Key As String, byval ed As Long) As String
	If ed < 1 Or ed > 2 Then
		Beep
		Return "ERROR - NO SUCH ENCRYPTION MODE"
	Endif
	Dim As String ptext, ctext, mtext
	ptext = pptext
	Dim As Long lt
	lt = Len(Key)
	If (lt Mod 16 <> 0) Or (lt Shr 4 <> 1) Then
		Return "ERROR - INVALID KEY"
	Endif
	Dim As Long pmod, i
	lt = Len(ptext)
	pmod = lt Mod 16
	If pmod <> 0 Or lt < 1 Then
		pmod = 16 - pmod
		For i = 1 To pmod
			ptext += Chr(0)
		Next i
	Endif
	lt = Len(ptext)
	lt = lt Shr 4
	Dim As Ubyte State(1 To 4, 1 To 4), KeyT(1 To 4, 1 To 4), EXPKey(1 To 40, 1 To 4)
	RIJNDAEL_TextToState Key, KeyT(), 2
	RIJNDAEL_ExpandKey KeyT(), EXPKey()
	Select Case ed
		Case 1
			For i = 1 To lt
				mtext = Mid(ptext, ((i-1) Shl 4) + 1, 16)
				RIJNDAEL_TextToState mtext, State(), 1
				RIJNDAEL_BlockEncrypt State(), KeyT(), EXPKey()
				ctext += RIJNDAEL_StateToText(State())
			Next i
		Case 2
			RIJNDAEL_Rotate KeyT()
			For i = 1 To lt
				mtext = Mid(ptext, ((i-1) Shl 4) + 1, 16)
				RIJNDAEL_TextToState mtext, State(), 1
				RIJNDAEL_BlockDecrypt State(), KeyT(), EXPKey()
				RIJNDAEL_Rotate State()
				ctext += RIJNDAEL_StateToText(State())
			Next i
	End Select
	Return ctext
End Function

Function AddCryptLenKey(ByRef key As String) As String
	Dim As Long lenkey=Len(key)
	If  lenkey<16 Then
		For a As Long=lenkey To 15
			key+="1"
		Next
	ElseIf lenkey>16 Then
		key=Mid(key,1,16)
	EndIf
	Return key
End Function

function AESEncoder(byref Text as Ustring, byref Key as Ustring) as UString Export
	dim as string sKey , sText
	sKey = Key
	sText = Text
	sKey=AddCryptLenKey(sKey)
	return RIJNDAEL_Encrypt(sText, sKey, 1)
End function

function AESDecoder(byref Text as Ustring, byref Key as Ustring) as UString Export
	dim as string sKey , sText
	sKey = Key
	sText = Text  
	sKey=AddCryptLenKey(sKey)
	#ifdef UNICODE
		return Rtrim(RIJNDAEL_Encrypt(sText, sKey, 2), Wchr(0))
	#else
		return Rtrim(RIJNDAEL_Encrypt(sText, sKey, 2), chr(0))
	#EndIf
End Function


