Robert Kosek

10-03-2006, 11:01 PM

For a simple overview and pseudocode on XTea, you can wiki-it (http://en.wikipedia.org/wiki/XTEA).

XTea is supposed to be a simple encryption algorithm, and it is mathematically. But my implementation is going wrong somewhere in the encryption and possibly decryption phases. Very wrong. Like it could simply crash silently on me, or the encryption "halts" part way through. It seems to be something in relation to password length and content length. It might work with a 16 character password, and a short paragraph, but change either around and it'll go screwy in no time flat!

As you can guess it's got me fairly confused. :oops: I have to thank Lifepower a lot just for helping me this far along! Any further help from ya'll will really be appreciated. I'll be trying to juggle the discussion here and at Afterwarp, so just know that unless you check the thread there (http://www.afterwarp.net/forum/showthread.php?p=2694#post2694), you might not be up to date on the problem.

Here's the source. To use it just make a TXTea object, create it, Init the key, Encrypt/Decrypt then burn it.

(************************************************* *****************************)

(* Translated from C into Object Pascal by Robert Kosek with much help from *)

(* Yuriy Kotsarenko. Please leave this header in any subsequent distribution *)

(* and maybe mention us in the credits of whatever uses this. Especially *)

(* Yuriy, he did the majority of the work in the end. ;-) *)

(* *)

(* My only stipulation to this is that if you use it, adapt it or change it, *)

(* please let us know and post your changes here: *)

(* http://www.afterwarp.net/forum/thread460.html *)

(************************************************* *****************************)

(* Original code taken from: *)

(* http://en.wikipedia.org/wiki/XTEA *)

(* http://www.irnis.net/soft/xted/ *)

(* *)

(* Our Sites: *)

(* http://afterwarp.net/ *)

(* http://thewickedflea.com/ *)

(************************************************* *****************************)

unit xtea;

interface

uses SysUtils;

type

PKey128 = ^TKey128;

TKey128 = array [0..3] of longword;

PBlock64 = ^TBlock64;

TBlock64 = array [0..1] of longword;

TXTea = class(TObject)

private

FKey: TKey128;

FInitialized: Boolean;

public

property Initialized: boolean read FInitialized default false;

procedure Burn;

procedure InitKey(const Key: string);

function Encrypt(const Input: string): string;

function Decrypt(const Input: string): string;

destructor Destroy; override;

constructor Create;

end;

const

DELTA = $9e3779b9;

XTEA_BLANK: TBlock64 = (0,0);

XTEA_BURN: TKey128 =(0,0,0,0);

implementation

destructor TXTea.Destroy;

begin

Burn;

inherited Destroy;

end;

constructor TXTea.Create;

begin

inherited Create;

Burn;

end;

procedure TXTea.Burn;

begin

FKey := XTEA_BURN;

FInitialized := False;

end;

procedure TXTea.InitKey(const Key: string);

var L: integer;

begin

if Length(Key) <= SizeOf(FKey) then

L := Length(Key)

else

L := SizeOf(FKey);

Move(Key[1],FKey[0],L);

FInitialized := True;

end;

function TXTea.Encrypt(const Input: string): string;

var i,l,n,b: integer;

v: TBlock64;

procedure CipherXTea(v: PBlock64; key: PKey128);

var sum: longword;

i: integer;

begin

Sum:= 0;

for i:= 0 to 31 do

begin

Inc(v[0], ((v[1] shl 4 xor v[1] shr 5) + v[1]) xor (Sum + Key[Sum and 3]));

Inc(Sum, Delta);

Inc(v[1], ((v[0] shl 4 xor v[0] shr 5) + v[0]) xor (Sum + Key[Sum shr 11 and 3]));

end;

end;

begin

if not Initialized then

raise Exception.Create('Error: You must define a password.');

b := SizeOf(v);

l := Length(Input);

SetLength(Result,l);

i := 1;

while i < l do

try

v := XTEA_BLANK;

n := l - (i-1);

if n > b then

Move(Input[i],v[0],b)

else

Move(Input[i],v[0],n);

CipherXTea(@v,@FKey);

Move(v[0],Result[i],b);

inc(i,8);

except

raise;

end;

end;

function TXTea.Decrypt(const Input: string): string;

var i,l,n,b: integer;

v: TBlock64;

procedure DecipherXTea(v: PBlock64; Key: PKey128);

var

i: Integer;

Sum: Longword;

begin

Sum:= $C6EF3720;

for i:= 0 to 31 do

begin

Dec(v[1], ((v[0] shl 4 xor v[0] shr 5) + v[0]) xor (Sum + Key[Sum shr 11 and 3]));

Dec(Sum, Delta);

Dec(v[0], ((v[1] shl 4 xor v[1] shr 5) + v[1]) xor (Sum + Key[Sum and 3]));

end;

end;

begin

if not Initialized then

raise Exception.Create('Error: You must define a password.');

b := SizeOf(v);

l := Length(Input);

SetLength(Result,l);

i := 1;

while i < l do

try

v := XTEA_BLANK;

n := l - (i-1);

if n > b then

Move(Input[i],v[0],b)

else

Move(Input[i],v[0],n);

DecipherXTea(@v,@FKey);

Move(v[0],Result[i],b);

inc(i,8);

except

raise;

end;

end;

end.

XTea is supposed to be a simple encryption algorithm, and it is mathematically. But my implementation is going wrong somewhere in the encryption and possibly decryption phases. Very wrong. Like it could simply crash silently on me, or the encryption "halts" part way through. It seems to be something in relation to password length and content length. It might work with a 16 character password, and a short paragraph, but change either around and it'll go screwy in no time flat!

As you can guess it's got me fairly confused. :oops: I have to thank Lifepower a lot just for helping me this far along! Any further help from ya'll will really be appreciated. I'll be trying to juggle the discussion here and at Afterwarp, so just know that unless you check the thread there (http://www.afterwarp.net/forum/showthread.php?p=2694#post2694), you might not be up to date on the problem.

Here's the source. To use it just make a TXTea object, create it, Init the key, Encrypt/Decrypt then burn it.

(************************************************* *****************************)

(* Translated from C into Object Pascal by Robert Kosek with much help from *)

(* Yuriy Kotsarenko. Please leave this header in any subsequent distribution *)

(* and maybe mention us in the credits of whatever uses this. Especially *)

(* Yuriy, he did the majority of the work in the end. ;-) *)

(* *)

(* My only stipulation to this is that if you use it, adapt it or change it, *)

(* please let us know and post your changes here: *)

(* http://www.afterwarp.net/forum/thread460.html *)

(************************************************* *****************************)

(* Original code taken from: *)

(* http://en.wikipedia.org/wiki/XTEA *)

(* http://www.irnis.net/soft/xted/ *)

(* *)

(* Our Sites: *)

(* http://afterwarp.net/ *)

(* http://thewickedflea.com/ *)

(************************************************* *****************************)

unit xtea;

interface

uses SysUtils;

type

PKey128 = ^TKey128;

TKey128 = array [0..3] of longword;

PBlock64 = ^TBlock64;

TBlock64 = array [0..1] of longword;

TXTea = class(TObject)

private

FKey: TKey128;

FInitialized: Boolean;

public

property Initialized: boolean read FInitialized default false;

procedure Burn;

procedure InitKey(const Key: string);

function Encrypt(const Input: string): string;

function Decrypt(const Input: string): string;

destructor Destroy; override;

constructor Create;

end;

const

DELTA = $9e3779b9;

XTEA_BLANK: TBlock64 = (0,0);

XTEA_BURN: TKey128 =(0,0,0,0);

implementation

destructor TXTea.Destroy;

begin

Burn;

inherited Destroy;

end;

constructor TXTea.Create;

begin

inherited Create;

Burn;

end;

procedure TXTea.Burn;

begin

FKey := XTEA_BURN;

FInitialized := False;

end;

procedure TXTea.InitKey(const Key: string);

var L: integer;

begin

if Length(Key) <= SizeOf(FKey) then

L := Length(Key)

else

L := SizeOf(FKey);

Move(Key[1],FKey[0],L);

FInitialized := True;

end;

function TXTea.Encrypt(const Input: string): string;

var i,l,n,b: integer;

v: TBlock64;

procedure CipherXTea(v: PBlock64; key: PKey128);

var sum: longword;

i: integer;

begin

Sum:= 0;

for i:= 0 to 31 do

begin

Inc(v[0], ((v[1] shl 4 xor v[1] shr 5) + v[1]) xor (Sum + Key[Sum and 3]));

Inc(Sum, Delta);

Inc(v[1], ((v[0] shl 4 xor v[0] shr 5) + v[0]) xor (Sum + Key[Sum shr 11 and 3]));

end;

end;

begin

if not Initialized then

raise Exception.Create('Error: You must define a password.');

b := SizeOf(v);

l := Length(Input);

SetLength(Result,l);

i := 1;

while i < l do

try

v := XTEA_BLANK;

n := l - (i-1);

if n > b then

Move(Input[i],v[0],b)

else

Move(Input[i],v[0],n);

CipherXTea(@v,@FKey);

Move(v[0],Result[i],b);

inc(i,8);

except

raise;

end;

end;

function TXTea.Decrypt(const Input: string): string;

var i,l,n,b: integer;

v: TBlock64;

procedure DecipherXTea(v: PBlock64; Key: PKey128);

var

i: Integer;

Sum: Longword;

begin

Sum:= $C6EF3720;

for i:= 0 to 31 do

begin

Dec(v[1], ((v[0] shl 4 xor v[0] shr 5) + v[0]) xor (Sum + Key[Sum shr 11 and 3]));

Dec(Sum, Delta);

Dec(v[0], ((v[1] shl 4 xor v[1] shr 5) + v[1]) xor (Sum + Key[Sum and 3]));

end;

end;

begin

if not Initialized then

raise Exception.Create('Error: You must define a password.');

b := SizeOf(v);

l := Length(Input);

SetLength(Result,l);

i := 1;

while i < l do

try

v := XTEA_BLANK;

n := l - (i-1);

if n > b then

Move(Input[i],v[0],b)

else

Move(Input[i],v[0],n);

DecipherXTea(@v,@FKey);

Move(v[0],Result[i],b);

inc(i,8);

except

raise;

end;

end;

end.