I get a curious behavior with the TEA-Functions, when using AHKL and a long password.
Code:
;-------------------------------------------------------------------------------
;
; TEA Encryption Library 0.10
; String and File Encruption Library for AutoHotkey
;
; - Original Encryption Functions By Laszlo
; - Library Modifications by Danny Ben Shitrit (aka Icarus)
;
; - Forum: http://www.autohotkey.com/forum/viewtopic.php?p=27017#27017
;
; FUNCTIONS IN THIS LIBRARY:
; EncryptFile( inputFile, password, outputFile="" ) ; rewrite to inputFile if
; DecryptFile( inputFile, password, outputFile="" ) ; outputFile is empty.
;
; NewString := EncryptString( inputString, password )
; NewString := DecryptString( inputString, password )
;
; Revision History at the end of the file
;
;-------------------------------------------------------------------------------
; TESTER - Delete or comment out when including the file
;-------------------------------------------------------------------------------
; File Encryption / Decryption
; EncryptFile( A_ScriptFullPath , "myNicePassword" , "encrypted.txt" )
; DecryptFile( "encrypted.txt" , "myNicePassword" , "decrypted.txt" )
; String Encryption / Decryption
MyString := "Hello world, I am a nice readable string mit ö, ü,ä,ß" ; Encrypted := TEA_EncryptString( MyString , "aSimplePassword" )
; Decrypted := TEA_DecryptString( Encrypted, "aSimplePassword" )
Encrypted := TEA_EncryptString( MyString , "aüopjkoeiop<sekJKHIU34u9ß8s5zjhikmydrojilgoöyeuprj@akll€" )
Decrypted := TEA_DecryptString( Encrypted, "aüopjkoeiop<sekJKHIU34u9ß8s5zjhikmydrojilgoöyeuprj@akll€" )
Msgbox Original:`t`t[%MyString%]`nEncrypted:`t[%Encrypted%]`nDecrypted:`t[%Decrypted%]
;-------------------------------------------------------------------------------
; END OF TESTER
;-------------------------------------------------------------------------------
; INTERFACE
;-------------------------------------------------------------------------------
TEA_EncryptFile( inputFile, password, outputFile="" ) {
; Reads a file, encrypts its contents and write it back to itself or
; to a new file.
;_____________________________________________________________________________
If( outputFile = "" )
outputFile .= inputFile . ".enc"
FileRead FileString, %inputFile%
FileDelete %outputFile%
FileAppend % TEA_EncryptString( FileString, password ), %outputFile%
}
TEA_DecryptFile( inputFile, password, outputFile="" ) {
; Reads a file, decrypts its contents and write it back to itself or
; to a new file.
;_____________________________________________________________________________
If( outputFile = "" )
outputFile .= inputFile . ".dec"
FileRead FileString, %inputFile%
FileDelete %outputFile%
FileAppend % TEA_DecryptString( FileString, password ), %outputFile%
}
TEA_EncryptFileLine( inputFile, password, outputFile="" ) {
; Reads a file line-by-line, encrypts its contents and write it back to itself or
; to a new file.
;_____________________________________________________________________________
If( outputFile = "" )
outputFile := inputFile . ".enc"
FileDelete %outputFile%
Loop, Read, %InputFile%, %outputFile%
{
FileAppend % TEA_EncryptString( A_LoopReadLine , password ) . "`r`n"
; ToolTip,%A_Index%,400,1
}
}
TEA_DecryptFileLine( inputFile, password, outputFile="" ) {
; Reads a file line-by-line, decrypts its contents and write it back to itself or
; to a new file.
;_____________________________________________________________________________
If( outputFile = "" )
outputFile := inputFile . ".dec"
FileDelete %outputFile%
Loop, Read, %InputFile%, %outputFile%
{
FileAppend % TEA_DecryptString( A_LoopReadLine , password ) . "`r`n"
ToolTip,%A_Index%,400,1
}
}
TEA_EncryptString( inputString, password ) {
; Gets a plain string and returns the encrypted string.
;_____________________________________________________________________________
TEA_Pwd2Key( password, k1,k2,k3,k4,k5 )
i := 9 ; pad-index, force restart
p := 0 ; counter to be encrypted
OutString := ""
Loop Parse, inputString, `n,`r
{
ThisLine := A_LoopField
L := "" ; processed line
Loop % StrLen( ThisLine )
{
i++
IfGreater i,8, { ; all 9 pad values exhausted
u := p
v := k5 ; another secret
p++ ; increment counter
TEA_TEA(u,v, k1,k2,k3,k4)
TEA_Stream9(u,v) ; 9 pads from encrypted counter
i = 0
}
StringMid c, ThisLine, A_Index, 1
a := Asc(c)
if a between 32 and 126
{ ; chars > 126 or < 31 unchanged
a += s%i%
IfGreater a, 126, SetEnv, a, % a-95
c := Chr(a)
}
L := L . c ; attach encrypted character
}
OutString .= L . "`n"
}
StringTrimRight OutString, OutString, 1
Return OutString
}
TEA_DecryptString( inputString, password ) {
; Gets an encrypted string and returns the plain string.
;_____________________________________________________________________________
TEA_Pwd2Key( password, k1,k2,k3,k4,k5 )
i := 9 ; pad-index, force restart
p := 0 ; counter to be encrypted
OutString := ""
Loop Parse, inputString, `n,`r
{
ThisLine := A_LoopField
L := "" ; processed line
Loop % StrLen( ThisLine )
{
i++
IfGreater i,8, { ; all 9 pad values exhausted
u := p
v := k5 ; another secret
p++ ; increment counter
TEA_TEA(u,v, k1,k2,k3,k4)
TEA_Stream9(u,v) ; 9 pads from encrypted counter
i = 0
}
StringMid c, ThisLine, A_Index, 1
a := Asc(c)
if a between 32 and 126
{ ; chars > 126 or < 31 unchanged
a -= s%i%
IfLess a, 32, SetEnv, a, % a+95
c := Chr(a)
}
L := L . c ; attach encrypted character
}
OutString .= "`n" . L
}
Return SubStr(OutString,2)
}
;-------------------------------------------------------------------------------
; INTERNAL ENCRYPTION FUNCTIONS
;-------------------------------------------------------------------------------
TEA_PWD2Key(PW, ByRef k1, ByRef k2, ByRef k3, ByRef k4, ByRef k5) {
TEA_CBC(k1,k2, PW, 1,2,3,4)
TEA_CBC(k3,k4, PW, 4,3,2,1)
k5 := k1^k2^k3^k4
}
TEA_CBC(ByRef u, ByRef v, x, k0,k1,k2,k3) {
u = 0
v = 0
Loop % Ceil(StrLen(x)/8)
{
p = 0
StringLeft c, x, 4
Loop Parse, c
p := (p<<8) + Asc(A_LoopField)
u := u ^ p
p = 0
StringMid c, x, 5, 4
Loop Parse, c
p := (p<<8) + Asc(A_LoopField)
v := v ^ p
TEA_TEA(u,v,k0,k1,k2,k3)
StringTrimLeft x, x, 8
}
}
TEA_TEA(ByRef y,ByRef z,k0,k1,k2,k3) { ; (y,z) = 64-bit I/0 block
; (k0,k1,k2,k3) = 128-bit key
IntFormat = %A_FormatInteger%
SetFormat Integer, D ; needed for decimal indices
s := 0
d := 0x9E3779B9
Loop 32
{
k := "k" . s & 3 ; indexing the key
y := 0xFFFFFFFF & (y + ((z << 4 ^ z >> 5) + z ^ s + %k%))
s := 0xFFFFFFFF & (s + d) ; simulate 32 bit operations
k := "k" . s >> 11 & 3
z := 0xFFFFFFFF & (z + ((y << 4 ^ y >> 5) + y ^ s + %k%))
}
SetFormat Integer, %IntFormat%
y += 0
z += 0 ; Convert to original ineger format
}
TEA_Stream9(x,y) { ; Convert 2 32-bit words to 9 pad values
; 0 <= s0, s1, ... s8 <= 94
Local z ; makes all s%i% global
s0 := Floor(x*0.000000022118911147) ; 95/2**32
Loop 8
{
z := (y << 25) + (x >> 7) & 0xFFFFFFFF
y := (x << 25) + (y >> 7) & 0xFFFFFFFF
x = %z%
s%A_Index% := Floor(x*0.000000022118911147)
}
}
The code is utf-8 and compiled with the latest version of Lexikos' AutoHotkeySC.bin. The misterious: when running as script, the code produces the same encrypted string as in AHK basic. When running compiled, it produces a totally different string, which is bad for testing and which is worse with old AHKbasic-encrypted files, that can't get decrypted by the AHK_L-exe.
Edit: It was my fault, because I got lost between the different versions of AHK.exe and AHKSC.bin. But I still have the problem, that I get different results witk AHKbasic and AHK_L, so that the already existing keyfiles don't match any longer.
Quote:
---------------------------
TEA.ahkl
---------------------------
Original: [Hello world, I am a nice readable string mit ö, ü,ä,ß]
Encrypted: [9Gr+P$KjqC_zh.UB<UD #n>ide/Gj[.>X,MKoIv\wehILö>1ücä%ß]
Decrypted: [Hello world, I am a nice readable string mit ö, ü,ä,ß]
---------------------------
OK
---------------------------
Quote:
---------------------------
TEA.ahk
---------------------------
Original: [Hello world, I am a nice readable string mit ö, ü,ä,ß]
Encrypted: [w\7M)rrE@ }#d^TbJe.KuPHT$R8m-_n*%#(i*9bhkBJ*?önhü_ätß]
Decrypted: [Hello world, I am a nice readable string mit ö, ü,ä,ß]
---------------------------
OK
---------------------------