>
UNIT SSC

Unit Ssc;

Interface

Var
DA,DB,DC,DD: Byte;
S0,S1:Array[0..255]Of Byte;

Function Encrypted(Const IB:Byte):Byte;
Function Decrypted(Const IB:Byte):Byte;

Procedure BufEnc(Var Data; Const Size:Word);
Procedure BufDec(Var Data; Const Size:Word);
Procedure BufMut(Const Data; Const Size:Word);

Procedure DataInit(Const Data; Const Size:Word; Const Rounds:Longint; Const Mode:Boolean);
Procedure PassInit(Const Key : String; Const Rounds:Longint; Const Mode:Boolean);
Procedure DataKSA(Const Key; Const KeySize:Word; Const Vec; Const VecSize:Word; Const Rounds:Longint);
Procedure PassKSA(Const Key:String; Const Vec; Const VecSize:Word; Const Rounds:Longint);

Procedure SetMAC(Var MAC; Const MACSize:Word);
Function CheckKey:Boolean;
Procedure SetKeys;
Procedure KeyMut;
Procedure Burn;

Implementation

Type ByteArray = Array[0..0] Of Byte;


Procedure NextState;

Procedure SWAB(Var A,B: Byte); { Swaps two bytes }
Var C : Byte;
Begin
C := A; A := B; B := C;
End;

Begin
Inc(DD); DC := S0[S0[(S0[(S0[(S0[DD]+DC) And $FF]+DB) And $FF]+DA) And $FF]];
SWAB(S0[DA],S0[DD]); S1[S0[DA]]:=DA; S1[S0[DD]]:=DD;
SWAB(S0[DB],S0[DC]); S1[S0[DB]]:=DB; S1[S0[DC]]:=DC;
End;

Function Encrypted(Const IB:Byte):Byte;
Begin
DA := S0[Succ(S0[Pred(S0[IB Xor S0[Pred(S0[Succ(S0[DC])])]])])];
DB := S0[Pred(S0[Succ(S0[DA Xor S0[Succ(S0[Pred(S0[DD])])]])])];
Encrypted := S0[Succ(S0[Pred(S0[Succ(S0[Pred(S0[DB])])])])];
NextState;
End;

Function Decrypted(Const IB:Byte):Byte;
Begin
DB := S1[Succ(S1[Pred(S1[Succ(S1[Pred(S1[IB])])])])];
DA := S1[Pred(S1[Succ(S1[DB])])] Xor S0[Succ(S0[Pred(S0[DD])])];
Decrypted := S1[Succ(S1[Pred(S1[DA])])] Xor S0[Pred(S0[Succ(S0[DC])])];
NextState;
End;

Procedure BufEnc(Var Data; Const Size:Word);
Var IC:Word;
Buf:ByteArray Absolute Data;
Begin
For IC := 0 To Size-1 Do Buf[IC] := Encrypted(Buf[IC]);
End;

Procedure BufDec(Var Data; Const Size:Word);
Var IC:Word;
Buf:ByteArray Absolute Data;
Begin
For IC := 0 To Size-1 Do Buf[IC] := Decrypted(Buf[IC]);
End;

Procedure BufMut(Const Data; Const Size:Word);
Var IC:Word;
Buf:ByteArray Absolute Data;
Begin
For IC := 0 To Size-1 Do Encrypted(Buf[IC]);
End;

Procedure DataInit(Const Data; Const Size:Word; Const Rounds:Longint; Const Mode:Boolean);
Var IC:Longint;
Begin
If Mode Then SetKeys;
For IC := 0 To Rounds-1 Do Begin
BufMut(Data,Size);
KeyMut;
End;
End;

Procedure PassInit(Const Key : String; Const Rounds:Longint; Const Mode:Boolean);
Begin
DataInit(Key[1],Byte(Key[0]),Rounds,Mode);
End;

Procedure DataKSA(Const Key; Const KeySize:Word; Const Vec; Const VecSize:Word; Const Rounds:Longint);
Var IC:Longint;
Begin
SetKeys;
For IC := 0 To Rounds-1 Do Begin
BufMut(Key,KeySize); KeyMut;
BufMut(Vec,VecSize); KeyMut;
BufMut(Key,KeySize); KeyMut;
End;
End;

Procedure PassKSA(Const Key:String; Const Vec; Const VecSize:Word; Const Rounds:Longint);
Begin
DataKSA(Key[1], Byte(Key[0]), Vec, VecSize, Rounds);
End;

Function CheckKey:Boolean;
Var IC : Byte;
Begin
CheckKey:=True;
For IC := 0 To 255 Do S1[IC]:=0;
For IC := 0 To 255 Do Inc(S1[S0[IC]]);
For IC := 0 To 255 Do If S1[IC]<>1 Then CheckKey:=False;
End;

Procedure SetKeys;
Var IC:Byte;
Begin
For IC := 0 To 255 Do S0[IC] := IC;
For IC := 0 To 255 Do S1[S0[IC]] := IC;
DC := 0;
DD := 255;
End;

Procedure KeyMut;
Var IC : Byte;
Begin
For IC := 0 To 255 Do Encrypted(Encrypted(Encrypted(Encrypted(S0[IC]))));
End;

Procedure SetMAC(Var MAC; Const MACSize:Word);
Var
C:Word;
Buf:ByteArray Absolute MAC;
Begin
For C := 0 To MACSize-1 Do Encrypted(C);
KeyMut;
For C := 0 To MACSize-1 Do Buf[C] := Encrypted(C);
End;

Procedure Burn;
Begin
FillChar(S0,256,0);
FillChar(S1,256,0);
DA := 0;
DB := 0;
DC := 0;
DD := 0;
End;

End.