Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Small and fast Text File Encryptor


  • Please log in to reply
55 replies to this topic
Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Here is a relatively small script for encrypting and decrypting text files. The ciphertext is also a text file. Characters with code less than 32 or larger than 126 are left unencrypted. The line structure of the original file is preserved. If this is undesirable, the original lines could be padded with a random number of space characters or to the same lengths.

If you share a secret key with your friends, you can easily encrypt emails or chat messages on the fly. Instead of reading letters from a text file use the Input command to intercept, and then Send the encrypted character. Having received an encrypted message, you can highlight it and a Hotkey activated function pops up a MsgBox with the decrypted text. In this application the message should be preceded with a random nonce, the counter initialization value, to avoid synchronization problems. This script is the basic tool, having many applications.

Processing a 150 line text file takes less than 1 second on my 2 GHz laptop, but still, it is not a good idea to use this script for gigabyte files. AHK is too slow for that with its interpreted scripts and text based, simulated 32-bit arithmetic.

The encryption algorithm is TEA, the smallest secure cipher known. It is used in counter mode to generate a stream of random looking numbers, which are added to the codes of the letters in the text file, folding (modulo) the result back to the range of 32...126. Decryption is similar, the same stream is generated, but this time it gets subtracted from the ciphertext characters, folding the result back to the allowed range.

This algorithm is fast and secure, but being a stream cipher, it is malleable. In this case it means, adding a constant to the ciphertext codes produces a plaintext after decrypting, with character codes also increased by the same constant. If an attacker knows the structure of the plaintext, he can modify the ciphertext to produce a falsified message. Normally, we assume that the structure of our plaintext is unknown to the attacker, so this is not a real threat. If this assumption does not hold, we have to add a message authentication code. It can also be computed with the presented TEA function.

I plan to extend this script to handle binary files, when AHK will provide easy tools for that.

This is version 1, so there could be some bugs. Please tell if something sucks.
/*
AutoHotkey Version: 1.0.35+
Language:  English
Platform:  Win2000/XP
Author:    Laszlo Hars <www.Hars.US>

Script to en/decrypt text files to text files

Plus-minus Counter Mode: stream cipher using add/subtract with reduced range
   (32...126). Characters outside remain unchanged (TAB, CR, LF, ...).
   Lines will remain of the same length. If it leaks information, pad!

The underlying cipher is TEA, the Tiny Encryption Algorithm
http://www.simonshepherd.supanet.com/tea.htm It is one of the fastest and most
efficient cryptographic algorithms. It was developed by David Wheeler and Roger
Needham at the Computer Laboratory of Cambridge University. It is a Feistel
cipher, which uses operations from mixed (orthogonal) algebraic groups - XOR,
ADD and SHIFT in this case. It encrypts 64 data bits at a time using a 128-bit
key. It seems highly resistant to differential cryptanalysis, and achieves
complete diffusion (where a one bit difference in the plaintext will cause
approximately 32 bit differences in the ciphertext) after only six rounds.

As a test, the script reads its source file and saves the ciphertext with
   extension .enc to the same directory.
If it exists, the decrypted file is saved with extension .dec instead

Version:   1.0  2005.07.08  First created
*/

SetBatchLines -1
StringCaseSense Off
AutoTrim Off

k1 := 0x11111111                 ; 128-bit secret key
k2 := 0x22222222
k3 := 0x33333333                 ; choose wisely!
k4 := 0x44444444
k5 := 0x12345678                 ; starting counter value

StringTrimRight ScriptFile, A_ScriptFullPath, 4
EncFile = %ScriptFile%.enc       ; EncFile = {script-name}.enc
DecFile = %ScriptFile%.dec       ; DecFile = {script-name}.dec

IfExist %EncFile%
   GoSub DECRYPT
Else
   GoSub ENCRYPT
ExitApp

ENCRYPT:
   i = 9                         ; pad-index, force restart
   p = 0                         ; counter to be encrypted
   Loop Read, %A_ScriptFullPath%, %EncFile%
   {
      L =                        ; processed line
      Loop % StrLen(A_LoopReadLine)
      {
         i++
         IfGreater i,8, {        ; all 9 pad values exhausted
            u := p
            v := k5              ; another secret
            p++                  ; increment counter
            TEA(u,v, k1,k2,k3,k4)
            Stream9(u,v)         ; 9 pads from encrypted counter
            i = 0
         }
         StringMid c, A_LoopReadLine, 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
      }
      FileAppend %L%`n
   }
Return

DECRYPT:
   FileDelete %DecFile%
   i = 9                         ; pad-index, force restart
   p = 0                         ; counter to be encrypted
   Loop Read, %EncFile%, %DecFile%
   {
      L =                        ; processed line
      Loop % StrLen(A_LoopReadLine)
      {
         i++
         IfGreater i,8, {        ; all 9 pad values exhausted
            u := p
            v := k5              ; another secret
            p++                  ; increment counter
            TEA(u,v, k1,k2,k3,k4)
            Stream9(u,v)         ; 9 pads from encrypted counter
            i = 0
         }
         StringMid c, A_LoopReadLine, 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
      }
      FileAppend %L%`n
   }
Return


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
}

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)
   }
}


Chris
  • Administrators
  • 10727 posts
  • Last active:
  • Joined: 02 Mar 2004
I learned a little about the art of encryption and decryption just from reading your description. Thanks for sharing this well-documented script.

Atomhrt
  • Members
  • 124 posts
  • Last active: Nov 13 2006 09:18 PM
  • Joined: 02 Sep 2004
Thanks for the code! I have written a few encryption tools myself in the past. I will test as soon as I get some time.
I am he of whom he speaks!

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004
nice work Laszlo. if direct support for the chars other than 32-126 is difficult in this algorithm, i'm posting my hex & asc functions using which u can extend it to support full charset.

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Thanks, Rajat. I will look at your functions. There are problems with binary data, or the full ANSI char set. The first difficulty is with the NULL char, which interferes with the string and I/O functions. Second, the invisible chars: codes 0...31, 127...144 and 147...160. Many editors remove or replace them with something else (like the CR/LF problems or TAB is replaced with spaces, etc.). Accordingly, the ciphertext must not contain any of them, not present in the original. We want a one-to-one mapping, so the same many character must be allowed in the plaintext and in the ciphertext, which would necessitate these gaps also in the plaintext. This non-contiguous code set makes the script slower and more complicated.

Thirdly, some email or Internet chat programs code the ANSI characters above the code 127 as Unicodes or other ways, which prevents decryption. In a random looking letter soup we encounter occasionally these special code symbol markers, which would cause a complete mess. It looked like the only safe way is to restrict the transcoded character set to 32...126.

Of course, we can convert any data to its hex representation (or base 64, or whatever you like) and encrypt the hex digits. It doubles the size, though. The necessary functions are also in my list manipulation package, but the file I/O difficulties remain. Let's just hope that Chris implements binary file handling soon, so we don’t have to bend backwards for a universal crypto function.

Rajat
  • Members
  • 1904 posts
  • Last active: Jul 17 2015 07:45 AM
  • Joined: 28 Mar 2004

Of course, we can convert any data to its hex representation (or base 64, or whatever you like) and encrypt the hex digits. It doubles the size, though.

that's true. anybody knows of a string compression function?

Let's just hope that Chris implements binary file handling soon, so we don’t have to bend backwards for a universal crypto function.

Amen.

MIA

CleanNews.in : Bite sized latest news headlines from India with zero bloat


twhyman
  • Members
  • 348 posts
  • Last active: Sep 17 2014 01:55 AM
  • Joined: 07 Dec 2005
hi,

iam new to all this, how do i pass the passwaord that the user entered
to the encryption sysytem?

and how do i get the encrypted pass decrypted?

iam working with an ini file
thanks
twhyman

; Generated using SmartGUI Creator 3.5.1 
IniRead, SUN, E:\Documents and Settings\admin\Desktop\test.ini, username, user ;Read User Name From ini 
IniRead, SUP, E:\Documents and Settings\admin\Desktop\test.ini, pass, password ;Read Password From ini 
Gui, Show, x182 y47 h149 w344, Password Encryption Test 

Gui, Add, Text, x46 y37 w110 h20,User 
Gui, Add, Edit, x176 y37 w130 h20 vGsUser, %SUN% 
Gui, Add, Text, x46 y67 w110 h20,Password 
Gui, Add, Edit, x176 y67 w130 h20 vGsPass, %SUP% 
Gui, Add, Button, x126 y107 w110 h20 gSubmit,Submit 
Return 

Submit: 
Gui, Submit, NoHide 



GuiClose: 
IniWrite, %GsUser%, E:\Documents and Settings\admin\Desktop\test.ini, username, user ;Writes UserName to ini 
IniWrite, %Result%, E:\Documents and Settings\admin\Desktop\test.ini, pass, password ;Writes Password to ini 
ExitApp 



Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
The key consists of five 32-bit numbers, stored in the variables k1...k5. If you have a text password you have to convert it to 5 numbers.

The password is not encrypted, but used to generate the key, which affects the encryption. The same password has to be given to decrypt the encrypted file. If a wrong one is given the decryption yields gibberish.

Below is a fully functional script. It encrypts a file using the password input by the user, and writes the encrypted file to disk. After that it decrypts this file with the same key – to see if everything works as expected. It was meant for demonstration of the concept, you have to ask the user, if encryption or decryption is needed, and perform only that action. The file names could be selected with FileSelectFile or some other nice GUI, it is up to you.
SetBatchLines -1
StringCaseSense Off
AutoTrim Off

InputBox pwd, PassPhrase, Enter your PassPhrase, HIDE, 400, 160
IfNotEqual ErrorLevel,0, ExitApp
PWD2Key(pwd, k1,k2,k3,k4,k5)

InputBox InpFile, Input, Enter the input file,, 400, 160,,,,,%A_ScriptFullPath%
IfNotEqual ErrorLevel,0, ExitApp
StringTrimRight File, InpFile, 4

InputBox EncFile, Encrypted file, Enter a name for the encrypted file,, 400, 160,,,,,%File%.enc
IfNotEqual ErrorLevel,0, ExitApp

InputBox DecFile, Decrypted file, Enter a name for the decrypted file,, 400, 160,,,,,%File%.dec
IfNotEqual ErrorLevel,0, ExitApp

ENCRYPT(EncFile,InpFile,k1,k2,k3,k4,k5)   ; only one of it is needed at once
DECRYPT(DecFile,EncFile,k1,k2,k3,k4,k5)
ExitApp

PWD2Key(PW, ByRef k1, ByRef k2, ByRef k3, ByRef k4, ByRef k5)
{
   CBC(k1,k2, PW, 1,2,3,4)
   CBC(k3,k4, PW, 4,3,2,1)
   k5 := k1^k2^k3^k4
}

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(u,v,k0,k1,k2,k3)
      StringTrimLeft x, x, 8
   }
}

ENCRYPT(EncFile,InpFile,k1=0,k2=0,k3=0,k4=0,k5=0) ; encrypt InpFile to EncFile with key k1..k5
{
   i = 9                         ; pad-index, force restart
   p = 0                         ; counter to be encrypted
   Loop Read, %InpFile%, %EncFile%
   {
      L =                        ; processed line
      Loop % StrLen(A_LoopReadLine)
      {
         i++
         IfGreater i,8, {        ; all 9 pad values exhausted
            u := p
            v := k5              ; another secret
            p++                  ; increment counter
            TEA(u,v, k1,k2,k3,k4)
            Stream9(u,v)         ; 9 pads from encrypted counter
            i = 0
         }
         StringMid c, A_LoopReadLine, 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
      }
      FileAppend %L%`n
   }
}

DECRYPT(DecFile,EncFile,k1=0,k2=0,k3=0,k4=0,k5=0) ; decrypt EncFile to DecFile with key k1..k5
{
   FileDelete %DecFile%
   i = 9                         ; pad-index, force restart
   p = 0                         ; counter to be encrypted
   Loop Read, %EncFile%, %DecFile%
   {
      L =                        ; processed line
      Loop % StrLen(A_LoopReadLine)
      {
         i++
         IfGreater i,8, {        ; all 9 pad values exhausted
            u := p
            v := k5              ; another secret
            p++                  ; increment counter
            TEA(u,v, k1,k2,k3,k4)
            Stream9(u,v)         ; 9 pads from encrypted counter
            i = 0
         }
         StringMid c, A_LoopReadLine, 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
      }
      FileAppend %L%`n
   }
}


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
}

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)
   }
}
Edit: fixed CBC (ceil instead of floor, shorter code)

twhyman
  • Members
  • 348 posts
  • Last active: Sep 17 2014 01:55 AM
  • Joined: 07 Dec 2005
hi laszlo,

with the script u posted above, can i input a password in a gui field and then the script will save it encrypted to a file? and then retrive it Decrypted?

cause all i wanna do is save a passoword to ini, and make the password encrypted in the ini so if u look at the ini u see gibrish...

and then retrive the encrypted password and display it Decrypted in the gui.

thanks
twhyman

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
This is a file-to-file encryption, so you have to modify it to make it variable-to-variable. Maybe this is closer what you want to do, but the appended IV values might disturb.

In any case, first you need to establish the keys, than call the modified ENCRYPT or DECRYPT functions, which don't read/write files but get/append characters to variables.

If you don't want to write code, the closest thing is this. It should not bother you that the encrypted text is in hex, it just makes it a little longer.

twhyman
  • Members
  • 348 posts
  • Last active: Sep 17 2014 01:55 AM
  • Joined: 07 Dec 2005
thanks for the post,but iam all new to AHK and coding at all ,
i still can figure out what are those codes in the posts u gave me
all i know is how to get a variable from the edit field and write it to ini
same for reading it from the ini....

thanks anyway for the help but its too complicated to me :(
i just cant figure this out...

twhyman

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
It is not a good idea to have the password in the ini file. It has to be secret, so you have to ask the user to supply it, for example, typing it in an InputBox.
InputBox Pass_phrase, PassPhrase Input, Enter your PassPhrase below, HIDE, 400, 160
Or, read it from another file.

What do you want to do with your script? Someone might be able to assist you if you tell. Still, I think it is simpler to use RC4: http://www.autohotke...opic.php?t=6804
encrypted_text := RC4txt2hex(unencrypted_text,Pass_phrase)
gives you the encrypted_text, which you can write to the ini file. When you read the encrypted text, you call the decryption function
unencrypted_text := RC4hex2txt(encrypted_text,Pass_phrase)
to get back the original.

twhyman
  • Members
  • 348 posts
  • Last active: Sep 17 2014 01:55 AM
  • Joined: 07 Dec 2005
hi Laszlo,

what iam doing is a game launcher i am buiiding a cmd from edit boxes
like:

run c:\games\game.exe %user% %password%

the user name and password are saved in a ini file
and i want the password the be saved encrypted.
and when the applaication is loaded again i want the password
to be decrypted so the user just can click on "launch game"
and the game "run" cmd will have Decrypted password in it.

hope this explians all my questions so far :oops:

twhyman

Laszlo
  • Moderators
  • 4713 posts
  • Last active: Mar 31 2012 03:17 AM
  • Joined: 14 Feb 2005
Here is a primitive version of the game launcher. You could add a nice GUI, error check, etc.

First you create an ini file (as an example I used a.ini in the AHK working directory). It contains the names of the games you want to launch, as section names in square brackets. In each section you need 3 keys, the executable of the game, the username and the password for that game:
[Game1]
run = game1.exe
user = username1
password = password1

[Game2]
run = game2.exe
user = username2
password = password2
Then you run the script. It will ask for a password to encrypt the ini file, deletes the old encrypted file if there was one, encrypts the ini file and deletes the original. Now you only have the encrypted ini file (a.enc, during the development of the script you want to keep a backup copy, to be deleted when everything runs OK).

If you run the script again, it asks for the ini password, but will not find the ini file, so it decrypts the encrypted ini file (a.enc) to the original name (a.ini) and asks, which game you want to play. It reads the executable, the game user and its password from the ini file, then deletes it. Finally it runs the game. Two hotkeys Ctrl-Alt-N and Ctrl-Alt-P are defined, which will send the username and password respectively.
StringCaseSense Off
AutoTrim Off

IniFile = a.ini      ; the original ini file
EncFile = a.enc      ; encrypted file

InputBox pwd, PassPhrase, Enter your PassPhrase, HIDE, 400, 160
IfNotEqual ErrorLevel,0, ExitApp
PWD2Key(pwd, k1,k2,k3,k4,k5)

IfExist %IniFile%
{
   FileDelete %EncFile%
   ENCRYPT(EncFile,IniFile,k1,k2,k3,k4,k5)
   FileDelete %IniFile%
   ExitApp
}

InputBox Game, Which Game?, Type the name of the game,, 400, 160
IfNotEqual ErrorLevel,0, ExitApp
DECRYPT(IniFile,EncFile,k1,k2,k3,k4,k5)
IniRead Run, %IniFile%, %Game%, run
IniRead user,%IniFile%, %Game%, user
IniRead password, %IniFile%, %Game%, password
FileDelete %IniFile%
Run %game%
Return

^!n::SendRaw %user%     ; Ctrl-Alt-n for sending userName
^!p::SendRaw %password% ; Ctrl-Alt-p for sending Password

PWD2Key(PW, ByRef k1, ByRef k2, ByRef k3, ByRef k4, ByRef k5)
{
   CBC(k1,k2, PW, 1,2,3,4)
   CBC(k3,k4, PW, 4,3,2,1)
   k5 := k1^k2^k3^k4
}

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(u,v,k0,k1,k2,k3)
      StringTrimLeft x, x, 8
   }
}

ENCRYPT(EncFile,InpFile,k1=0,k2=0,k3=0,k4=0,k5=0) ; encrypt InpFile to EncFile with key k1..k5
{
   i = 9                         ; pad-index, force restart
   p = 0                         ; counter to be encrypted
   Loop Read, %InpFile%, %EncFile%
   {
      L =                        ; processed line
      Loop % StrLen(A_LoopReadLine)
      {
         i++
         IfGreater i,8, {        ; all 9 pad values exhausted
            u := p
            v := k5              ; another secret
            p++                  ; increment counter
            TEA(u,v, k1,k2,k3,k4)
            Stream9(u,v)         ; 9 pads from encrypted counter
            i = 0
         }
         StringMid c, A_LoopReadLine, 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
      }
      FileAppend %L%`n
   }
}

DECRYPT(DecFile,EncFile,k1=0,k2=0,k3=0,k4=0,k5=0) ; decrypt EncFile to DecFile with key k1..k5
{
   FileDelete %DecFile%
   i = 9                         ; pad-index, force restart
   p = 0                         ; counter to be encrypted
   Loop Read, %EncFile%, %DecFile%
   {
      L =                        ; processed line
      Loop % StrLen(A_LoopReadLine)
      {
         i++
         IfGreater i,8, {        ; all 9 pad values exhausted
            u := p
            v := k5              ; another secret
            p++                  ; increment counter
            TEA(u,v, k1,k2,k3,k4)
            Stream9(u,v)         ; 9 pads from encrypted counter
            i = 0
         }
         StringMid c, A_LoopReadLine, 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
      }
      FileAppend %L%`n
   }
}


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
}

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)
   }
}


tic
  • Members
  • 1934 posts
  • Last active: May 30 2018 08:13 PM
  • Joined: 22 Apr 2007
thought id just make this as i find it more useful that encoding/decoding files. It will give you a gui that will decode/encode text put into it. thanks for making such cool stuff laszlo:



SetBatchLines -1
StringCaseSense Off
AutoTrim Off

k1 := 0x11111111                 ; 128-bit secret key
k2 := 0x22222222
k3 := 0x33333333                 ; choose wisely!
k4 := 0x44444444
k5 := 0x12345678                 ; starting counter value

Gui, 1: Add, Edit, x10 y10 w280 r8 vEncDec
Gui, 1: Add, Button, x10 y150 w75 gENCRYPT, Encode
Gui, 1: Add, Button, x215 y150 w75 gDECRYPT, Decode
Gui, 1: Show, w300 h200, XTEA
Return

;#############################################################################################################

ENCRYPT:
encrypt = 1
decrypt = 0
GoSub, EncryptDecrypt
Return

DECRYPT:
decrypt = 1
encrypt = 0
GoSub, EncryptDecrypt
Return

;#############################################################################################################

EncryptDecrypt:
Gui, 1: Submit, NoHide

i = 9
p = 0
L =
   
Loop % StrLen(EncDec)
{
    i++
    If i > 8
	{
		u := p
		v := k5
		p++
		TEA(u,v, k1,k2,k3,k4)
		Stream9(u,v)
		i = 0
	}
		
    StringMid c, EncDec, A_Index, 1
    a := Asc(c)
	
    If a between 32 and 126
    {
		If encrypt = 1
		{
			a += s%i%
			IfGreater a, 126, SetEnv, a, % a-95
			c := Chr(a)
		}
		If decrypt = 1	
		{
			a -= s%i%
			IfLess a, 32, SetEnv, a, % a+95
			c := Chr(a)
		}
    }
		
	L = %L%%c% 
}
GuiControl,, EncDec, %L%
Return

;#############################################################################################################

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
}

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)
   }
}