码迷,mamicode.com
首页 > 其他好文 > 详细

可逆加密解密单元文件和调用方法

时间:2015-04-10 19:51:45      阅读:264      评论:0      收藏:0      [点我收藏+]

标签:

技术分享
  1 (**************************************************)
  2 (*                                                *)
  3 (*     Advanced Encryption Standard (AES)         *)
  4 (*     Interface Unit v1.3                        *)
  5 (*                                                *)
  6 (*                                                *)
  7 (*     Copyright (c) 2002 Jorlen Young            *)
  8 (*                                                *)
  9 (*                                                *)
 10 (*                                                *)
 11 (*说明:                                          *)
 12 (*                                                *)
 13 (*   基于 ElASE.pas 单元封装                      *)
 14 (*                                                *)
 15 (*   这是一个 AES 加密算法的标准接口。            *)
 16 (*                                                *)
 17 (*                                                *)
 18 (*         
 19 (*                                                *)
 20 (*   支持 128 / 192 / 256 位的密匙                *)                
 21 (*   默认情况下按照 128 位密匙操作                *)
 22 (*                                                *)
 23 (**************************************************)
 24 
 25 unit AES;                  
 26 
 27 interface
 28 
 29 uses
 30   SysUtils, Classes, Math, ElAES;
 31 
 32 type
 33   TKeyBit = (kb128, kb192, kb256);
 34 
 35 function StrToHex(Value: string): string;
 36 function HexToStr(Value: string): string;
 37 function EncryptString(Value: string; Key: string;
 38   KeyBit: TKeyBit = kb128): string;
 39 function DecryptString(Value: string; Key: string;
 40   KeyBit: TKeyBit = kb128): string;
 41 function EncryptStream(Stream: TStream; Key: string;
 42   KeyBit: TKeyBit = kb128): TStream;
 43 function DecryptStream(Stream: TStream; Key: string;
 44   KeyBit: TKeyBit = kb128): TStream;
 45 procedure EncryptFile(SourceFile, DestFile: string;
 46   Key: string; KeyBit: TKeyBit = kb128);
 47 procedure DecryptFile(SourceFile, DestFile: string;
 48   Key: string; KeyBit: TKeyBit = kb128);
 49   
 50 implementation
 51 
 52 function StrToHex(Value: string): string;
 53 var
 54   I: Integer;
 55 begin
 56   Result := ‘‘;
 57   for I := 1 to Length(Value) do
 58     Result := Result + IntToHex(Ord(Value[I]), 2);
 59 end;
 60 
 61 function HexToStr(Value: string): string;
 62 var
 63   I: Integer;
 64 begin
 65   Result := ‘‘;
 66   for I := 1 to Length(Value) do
 67   begin
 68     if ((I mod 2) = 1) then
 69       Result := Result + Chr(StrToInt(0x+ Copy(Value, I, 2)));
 70   end;
 71 end;
 72 
 73 {  --  字符串加密函数 默认按照 128 位密匙加密 --  }
 74 function EncryptString(Value: string; Key: string;
 75   KeyBit: TKeyBit = kb128): string;
 76 var
 77   SS, DS: TStringStream;
 78   Size: Int64;
 79   AESKey128: TAESKey128;
 80   AESKey192: TAESKey192;
 81   AESKey256: TAESKey256;
 82 begin
 83   Result := ‘‘;
 84   if Value = ‘‘ then Exit;
 85   SS := TStringStream.Create(Value);
 86   DS := TStringStream.Create(‘‘);
 87   try
 88     Size := SS.Size;
 89     DS.WriteBuffer(Size, SizeOf(Size));
 90     {  --  128 位密匙最大长度为 16 个字符 --  }
 91     if KeyBit = kb128 then
 92     begin
 93       FillChar(AESKey128, SizeOf(AESKey128), 0 );
 94       Move(PChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
 95       EncryptAESStreamECB(SS, 0, AESKey128, DS);
 96     end;
 97     {  --  192 位密匙最大长度为 24 个字符 --  }
 98     if KeyBit = kb192 then
 99     begin
100       FillChar(AESKey192, SizeOf(AESKey192), 0 );
101       Move(PChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
102       EncryptAESStreamECB(SS, 0, AESKey192, DS);
103     end;
104     {  --  256 位密匙最大长度为 32 个字符 --  }
105     if KeyBit = kb256 then
106     begin
107       FillChar(AESKey256, SizeOf(AESKey256), 0 );
108       Move(PChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
109       EncryptAESStreamECB(SS, 0, AESKey256, DS);
110     end;
111     Result := StrToHex(DS.DataString);
112   finally
113     SS.Free;
114     DS.Free;
115   end;
116 end;
117 
118 {  --  字符串解密函数 默认按照 128 位密匙解密 --  }
119 function DecryptString(Value: string; Key: string;
120   KeyBit: TKeyBit = kb128): string;
121 var
122   SS, DS: TStringStream;
123   Size: Int64;
124   AESKey128: TAESKey128;
125   AESKey192: TAESKey192;
126   AESKey256: TAESKey256;
127 begin
128   Result := ‘‘;
129   if Value = ‘‘ then Exit;
130   SS := TStringStream.Create(HexToStr(Value));
131   DS := TStringStream.Create(‘‘);
132   try
133     Size := SS.Size;
134     SS.ReadBuffer(Size, SizeOf(Size));
135     {  --  128 位密匙最大长度为 16 个字符 --  }
136     if KeyBit = kb128 then
137     begin
138       FillChar(AESKey128, SizeOf(AESKey128), 0 );
139       Move(PChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
140       DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey128, DS);
141     end;
142     {  --  192 位密匙最大长度为 24 个字符 --  }
143     if KeyBit = kb192 then
144     begin
145       FillChar(AESKey192, SizeOf(AESKey192), 0 );
146       Move(PChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
147       DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey192, DS);
148     end;
149     {  --  256 位密匙最大长度为 32 个字符 --  }
150     if KeyBit = kb256 then
151     begin
152       FillChar(AESKey256, SizeOf(AESKey256), 0 );
153       Move(PChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
154       DecryptAESStreamECB(SS, SS.Size - SS.Position, AESKey256, DS);
155     end;
156     Result := DS.DataString;
157   finally
158     SS.Free;
159     DS.Free;
160   end;
161 end;
162 
163 {  --  流加密函数 默认按照 128 位密匙解密 --  }
164 function EncryptStream(Stream: TStream; Key: string;
165   KeyBit: TKeyBit = kb128): TStream;
166 var
167   Count: Int64;
168   OutStrm: TStream;
169   AESKey128: TAESKey128;
170   AESKey192: TAESKey192;
171   AESKey256: TAESKey256;
172 begin
173   OutStrm := TStream.Create;
174   Stream.Position := 0;
175   Count := Stream.Size;
176   OutStrm.Write(Count, SizeOf(Count));
177   try
178     {  --  128 位密匙最大长度为 16 个字符 --  }
179     if KeyBit = kb128 then
180     begin
181       FillChar(AESKey128, SizeOf(AESKey128), 0 );
182       Move(PChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
183       EncryptAESStreamECB(Stream, 0, AESKey128, OutStrm);
184     end;
185     {  --  192 位密匙最大长度为 24 个字符 --  }
186     if KeyBit = kb192 then
187     begin
188       FillChar(AESKey192, SizeOf(AESKey192), 0 );
189       Move(PChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
190       EncryptAESStreamECB(Stream, 0, AESKey192, OutStrm);
191     end;
192     {  --  256 位密匙最大长度为 32 个字符 --  }
193     if KeyBit = kb256 then
194     begin
195       FillChar(AESKey256, SizeOf(AESKey256), 0 );
196       Move(PChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
197       EncryptAESStreamECB(Stream, 0, AESKey256, OutStrm);
198     end;
199     Result := OutStrm;
200   finally
201     OutStrm.Free;
202   end;
203 end;
204 
205 {  --  流解密函数 默认按照 128 位密匙解密 --  }
206 function DecryptStream(Stream: TStream; Key: string;
207   KeyBit: TKeyBit = kb128): TStream;
208 var
209   Count, OutPos: Int64;
210   OutStrm: TStream;
211   AESKey128: TAESKey128;
212   AESKey192: TAESKey192;
213   AESKey256: TAESKey256;
214 begin
215   OutStrm := TStream.Create;
216   Stream.Position := 0;
217   OutPos :=OutStrm.Position;
218   Stream.ReadBuffer(Count, SizeOf(Count));
219   try
220     {  --  128 位密匙最大长度为 16 个字符 --  }
221     if KeyBit = kb128 then
222     begin
223       FillChar(AESKey128, SizeOf(AESKey128), 0 );
224       Move(PChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
225       DecryptAESStreamECB(Stream, Stream.Size - Stream.Position,
226         AESKey128, OutStrm);
227     end;
228     {  --  192 位密匙最大长度为 24 个字符 --  }
229     if KeyBit = kb192 then
230     begin
231       FillChar(AESKey192, SizeOf(AESKey192), 0 );
232       Move(PChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
233       DecryptAESStreamECB(Stream, Stream.Size - Stream.Position,
234         AESKey192, OutStrm);
235     end;
236     {  --  256 位密匙最大长度为 32 个字符 --  }
237     if KeyBit = kb256 then
238     begin
239       FillChar(AESKey256, SizeOf(AESKey256), 0 );
240       Move(PChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
241       DecryptAESStreamECB(Stream, Stream.Size - Stream.Position,
242         AESKey256, OutStrm);
243     end;
244     OutStrm.Size := OutPos + Count;
245     OutStrm.Position := OutPos;
246     Result := OutStrm;
247   finally
248     OutStrm.Free;
249   end;
250 end;
251 
252 {  --  文件加密函数 默认按照 128 位密匙解密 --  }
253 procedure EncryptFile(SourceFile, DestFile: string;
254   Key: string; KeyBit: TKeyBit = kb128);
255 var
256   SFS, DFS: TFileStream;
257   Size: Int64;
258   AESKey128: TAESKey128;
259   AESKey192: TAESKey192;
260   AESKey256: TAESKey256;
261 begin
262   SFS := TFileStream.Create(SourceFile, fmOpenRead);
263   try
264     DFS := TFileStream.Create(DestFile, fmCreate);
265     try
266       Size := SFS.Size;
267       DFS.WriteBuffer(Size, SizeOf(Size));
268       {  --  128 位密匙最大长度为 16 个字符 --  }
269       if KeyBit = kb128 then
270       begin
271         FillChar(AESKey128, SizeOf(AESKey128), 0 );
272         Move(PChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
273         EncryptAESStreamECB(SFS, 0, AESKey128, DFS);
274       end;
275       {  --  192 位密匙最大长度为 24 个字符 --  }
276       if KeyBit = kb192 then
277       begin
278         FillChar(AESKey192, SizeOf(AESKey192), 0 );
279         Move(PChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
280         EncryptAESStreamECB(SFS, 0, AESKey192, DFS);
281       end;
282       {  --  256 位密匙最大长度为 32 个字符 --  }
283       if KeyBit = kb256 then
284       begin
285         FillChar(AESKey256, SizeOf(AESKey256), 0 );
286         Move(PChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
287         EncryptAESStreamECB(SFS, 0, AESKey256, DFS);
288       end;
289     finally
290       DFS.Free;
291     end;
292   finally
293     SFS.Free;
294   end;
295 end;
296 
297 {  --  文件解密函数 默认按照 128 位密匙解密 --  }
298 procedure DecryptFile(SourceFile, DestFile: string;
299   Key: string; KeyBit: TKeyBit = kb128);
300 var
301   SFS, DFS: TFileStream;
302   Size: Int64;
303   AESKey128: TAESKey128;
304   AESKey192: TAESKey192;
305   AESKey256: TAESKey256;
306 begin
307   SFS := TFileStream.Create(SourceFile, fmOpenRead);
308   try
309     SFS.ReadBuffer(Size, SizeOf(Size));
310     DFS := TFileStream.Create(DestFile, fmCreate);
311     try
312       {  --  128 位密匙最大长度为 16 个字符 --  }
313       if KeyBit = kb128 then
314       begin
315         FillChar(AESKey128, SizeOf(AESKey128), 0 );
316         Move(PChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
317         DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey128, DFS);
318       end;
319       {  --  192 位密匙最大长度为 24 个字符 --  }
320       if KeyBit = kb192 then
321       begin
322         FillChar(AESKey192, SizeOf(AESKey192), 0 );
323         Move(PChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
324         DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey192, DFS);
325       end;
326       {  --  256 位密匙最大长度为 32 个字符 --  }
327       if KeyBit = kb256 then
328       begin
329         FillChar(AESKey256, SizeOf(AESKey256), 0 );
330         Move(PChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
331         DecryptAESStreamECB(SFS, SFS.Size - SFS.Position, AESKey256, DFS);
332       end;
333       DFS.Size := Size;
334     finally
335       DFS.Free;
336     end;
337   finally
338     SFS.Free;
339   end;
340 end;
341 end.
AES.pas单元文件
技术分享
   1 (**************************************************)
   2 (*                                                *)
   3 (*     Advanced Encryption Standard (AES)         *)
   4 (*                                                *)
   5 (*     Copyright (c) 1998-2001                    *)
   6 (*     EldoS, Alexander Ionov                     *)
   7 (*                                                *)
   8 (**************************************************)
   9 
  10 unit ElAES;
  11 
  12 interface
  13 
  14 uses
  15   Classes, SysUtils;
  16 
  17 type
  18   EAESError = class(Exception);
  19 
  20   PInteger  = ^Integer;
  21 
  22   TAESBuffer = array [0..15] of byte;
  23   TAESKey128 = array [0..15] of byte;
  24   TAESKey192 = array [0..23] of byte;
  25   TAESKey256 = array [0..31] of byte;
  26   TAESExpandedKey128 = array [0..43] of longword;
  27   TAESExpandedKey192 = array [0..53] of longword;
  28   TAESExpandedKey256 = array [0..63] of longword;
  29 
  30   PAESBuffer =^TAESBuffer;
  31   PAESKey128 =^TAESKey128;
  32   PAESKey192 =^TAESKey192;
  33   PAESKey256 =^TAESKey256;
  34   PAESExpandedKey128 =^TAESExpandedKey128;
  35   PAESExpandedKey192 =^TAESExpandedKey192;
  36   PAESExpandedKey256 =^TAESExpandedKey256;
  37 
  38 // Key expansion routines for encryption  
  39 
  40 procedure ExpandAESKeyForEncryption(const Key: TAESKey128;
  41   var ExpandedKey: TAESExpandedKey128); overload;
  42 procedure ExpandAESKeyForEncryption(const Key: TAESKey192;
  43   var ExpandedKey: TAESExpandedKey192); overload;
  44 procedure ExpandAESKeyForEncryption(const Key: TAESKey256;
  45   var ExpandedKey: TAESExpandedKey256); overload;
  46 
  47 // Block encryption routines
  48 
  49 procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128;
  50   var OutBuf: TAESBuffer); overload;
  51 procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192;
  52   var OutBuf: TAESBuffer); overload;
  53 procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256;
  54   var OutBuf: TAESBuffer); overload;
  55 
  56 // Stream encryption routines (ECB mode)
  57 
  58 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
  59   const Key: TAESKey128; Dest: TStream); overload;
  60 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
  61   const ExpandedKey: TAESExpandedKey128; Dest: TStream); overload;
  62 
  63 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
  64   const Key: TAESKey192; Dest: TStream); overload;
  65 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
  66   const ExpandedKey: TAESExpandedKey192; Dest: TStream); overload;
  67 
  68 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
  69   const Key: TAESKey256; Dest: TStream); overload;
  70 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
  71   const ExpandedKey: TAESExpandedKey256; Dest: TStream); overload;
  72 
  73 // Stream encryption routines (CBC mode)
  74 
  75 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
  76   const Key: TAESKey128; const InitVector: TAESBuffer; Dest: TStream); overload;
  77 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
  78   const ExpandedKey: TAESExpandedKey128;  const InitVector: TAESBuffer;
  79   Dest: TStream); overload;
  80 
  81 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
  82   const Key: TAESKey192; const InitVector: TAESBuffer; Dest: TStream); overload;
  83 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
  84   const ExpandedKey: TAESExpandedKey192;  const InitVector: TAESBuffer;
  85   Dest: TStream); overload;
  86 
  87 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
  88   const Key: TAESKey256; const InitVector: TAESBuffer; Dest: TStream); overload;
  89 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
  90   const ExpandedKey: TAESExpandedKey256;  const InitVector: TAESBuffer;
  91   Dest: TStream); overload;
  92 
  93 // Key transformation routines for decryption
  94 
  95 procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey128); overload;
  96 procedure ExpandAESKeyForDecryption(const Key: TAESKey128;
  97   var ExpandedKey: TAESExpandedKey128); overload;
  98 
  99 procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey192); overload;
 100 procedure ExpandAESKeyForDecryption(const Key: TAESKey192;
 101   var ExpandedKey: TAESExpandedKey192); overload;
 102 
 103 procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey256); overload;
 104 procedure ExpandAESKeyForDecryption(const Key: TAESKey256;
 105   var ExpandedKey: TAESExpandedKey256); overload;
 106 
 107 // Block decryption routines
 108 
 109 procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128;
 110   var OutBuf: TAESBuffer); overload;
 111 procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192;
 112   var OutBuf: TAESBuffer); overload;
 113 procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256;
 114   var OutBuf: TAESBuffer); overload;
 115 
 116 // Stream decryption routines (ECB mode)
 117 
 118 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
 119   const Key: TAESKey128; Dest: TStream); overload;
 120 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
 121   const ExpandedKey: TAESExpandedKey128; Dest: TStream); overload;
 122 
 123 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
 124   const Key: TAESKey192; Dest: TStream); overload;
 125 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
 126   const ExpandedKey: TAESExpandedKey192; Dest: TStream); overload;
 127 
 128 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
 129   const Key: TAESKey256; Dest: TStream); overload;
 130 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
 131   const ExpandedKey: TAESExpandedKey256; Dest: TStream); overload;
 132 
 133 // Stream decryption routines (CBC mode)
 134 
 135 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
 136   const Key: TAESKey128; const InitVector: TAESBuffer; Dest: TStream); overload;
 137 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
 138   const ExpandedKey: TAESExpandedKey128;  const InitVector: TAESBuffer;
 139   Dest: TStream); overload;
 140 
 141 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
 142   const Key: TAESKey192; const InitVector: TAESBuffer; Dest: TStream); overload;
 143 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
 144   const ExpandedKey: TAESExpandedKey192;  const InitVector: TAESBuffer;
 145   Dest: TStream); overload;
 146 
 147 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
 148   const Key: TAESKey256; const InitVector: TAESBuffer; Dest: TStream); overload;
 149 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
 150   const ExpandedKey: TAESExpandedKey256;  const InitVector: TAESBuffer;
 151   Dest: TStream); overload;
 152 
 153 resourcestring
 154   SInvalidInBufSize = Invalid buffer size for decryption;
 155   SReadError = Stream read error;
 156   SWriteError = Stream write error;
 157 
 158 implementation
 159 
 160 type
 161   PLongWord = ^LongWord;
 162 
 163 function Min(A, B: integer): integer;
 164 begin
 165   if A < B then
 166     Result := A
 167   else
 168     Result := B;
 169 end;
 170 
 171 const
 172   Rcon: array [1..30] of longword = (
 173     $00000001, $00000002, $00000004, $00000008, $00000010, $00000020,
 174     $00000040, $00000080, $0000001B, $00000036, $0000006C, $000000D8,
 175     $000000AB, $0000004D, $0000009A, $0000002F, $0000005E, $000000BC,
 176     $00000063, $000000C6, $00000097, $00000035, $0000006A, $000000D4,
 177     $000000B3, $0000007D, $000000FA, $000000EF, $000000C5, $00000091
 178   );
 179 
 180   ForwardTable: array [0..255] of longword = (
 181     $A56363C6, $847C7CF8, $997777EE, $8D7B7BF6, $0DF2F2FF, $BD6B6BD6, $B16F6FDE, $54C5C591,
 182     $50303060, $03010102, $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D, $9A7676EC,
 183     $45CACA8F, $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF, $EB5959B2, $C947478E, $0BF0F0FB,
 184     $ECADAD41, $67D4D4B3, $FDA2A25F, $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4, $5BC0C09B,
 185     $C2B7B775, $1CFDFDE1, $AE93933D, $6A26264C, $5A36366C, $413F3F7E, $02F7F7F5, $4FCCCC83,
 186     $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2, $73D8D8AB, $53313162, $3F15152A,
 187     $0C040408, $52C7C795, $65232346, $5EC3C39D, $28181830, $A1969637, $0F05050A, $B59A9A2F,
 188     $0907070E, $36121224, $9B80801B, $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F, $9F7575EA,
 189     $1B090912, $9E83831D, $742C2C58, $2E1A1A34, $2D1B1B36, $B26E6EDC, $EE5A5AB4, $FBA0A05B,
 190     $F65252A4, $4D3B3B76, $61D6D6B7, $CEB3B37D, $7B292952, $3EE3E3DD, $712F2F5E, $97848413,
 191     $F55353A6, $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3, $C8B1B179, $ED5B5BB6,
 192     $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94, $D44C4C98, $E85858B0, $4ACFCF85,
 193     $6BD0D0BB, $2AEFEFC5, $E5AAAA4F, $16FBFBED, $C5434386, $D74D4D9A, $55333366, $94858511,
 194     $CF45458A, $10F9F9E9, $06020204, $817F7FFE, $F05050A0, $443C3C78, $BA9F9F25, $E3A8A84B,
 195     $F35151A2, $FEA3A35D, $C0404080, $8A8F8F05, $AD92923F, $BC9D9D21, $48383870, $04F5F5F1,
 196     $DFBCBC63, $C1B6B677, $75DADAAF, $63212142, $30101020, $1AFFFFE5, $0EF3F3FD, $6DD2D2BF,
 197     $4CCDCD81, $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488, $3917172E,
 198     $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8, $E75D5DBA, $2B191932, $957373E6,
 199     $A06060C0, $98818119, $D14F4F9E, $7FDCDCA3, $66222244, $7E2A2A54, $AB90903B, $8388880B,
 200     $CA46468C, $29EEEEC7, $D3B8B86B, $3C141428, $79DEDEA7, $E25E5EBC, $1D0B0B16, $76DBDBAD,
 201     $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14, $DB494992, $0A06060C, $6C242448, $E45C5CB8,
 202     $5DC2C29F, $6ED3D3BD, $EFACAC43, $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2,
 203     $32E7E7D5, $43C8C88B, $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C, $E0A9A949,
 204     $B46C6CD8, $FA5656AC, $07F4F4F3, $25EAEACF, $AF6565CA, $8E7A7AF4, $E9AEAE47, $18080810,
 205     $D5BABA6F, $887878F0, $6F25254A, $722E2E5C, $241C1C38, $F1A6A657, $C7B4B473, $51C6C697,
 206     $23E8E8CB, $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61, $868B8B0D, $858A8A0F,
 207     $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890, $05030306, $01F6F6F7, $120E0E1C,
 208     $A36161C2, $5F35356A, $F95757AE, $D0B9B969, $91868617, $58C1C199, $271D1D3A, $B99E9E27,
 209     $38E1E1D9, $13F8F8EB, $B398982B, $33111122, $BB6969D2, $70D9D9A9, $898E8E07, $A7949433,
 210     $B69B9B2D, $221E1E3C, $92878715, $20E9E9C9, $49CECE87, $FF5555AA, $78282850, $7ADFDFA5,
 211     $8F8C8C03, $F8A1A159, $80898909, $170D0D1A, $DABFBF65, $31E6E6D7, $C6424284, $B86868D0,
 212     $C3414182, $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D, $3A16162C
 213   );
 214 
 215   LastForwardTable: array [0..255] of longword = (
 216     $00000063, $0000007C, $00000077, $0000007B, $000000F2, $0000006B, $0000006F, $000000C5,
 217     $00000030, $00000001, $00000067, $0000002B, $000000FE, $000000D7, $000000AB, $00000076,
 218     $000000CA, $00000082, $000000C9, $0000007D, $000000FA, $00000059, $00000047, $000000F0,
 219     $000000AD, $000000D4, $000000A2, $000000AF, $0000009C, $000000A4, $00000072, $000000C0,
 220     $000000B7, $000000FD, $00000093, $00000026, $00000036, $0000003F, $000000F7, $000000CC,
 221     $00000034, $000000A5, $000000E5, $000000F1, $00000071, $000000D8, $00000031, $00000015,
 222     $00000004, $000000C7, $00000023, $000000C3, $00000018, $00000096, $00000005, $0000009A,
 223     $00000007, $00000012, $00000080, $000000E2, $000000EB, $00000027, $000000B2, $00000075,
 224     $00000009, $00000083, $0000002C, $0000001A, $0000001B, $0000006E, $0000005A, $000000A0,
 225     $00000052, $0000003B, $000000D6, $000000B3, $00000029, $000000E3, $0000002F, $00000084,
 226     $00000053, $000000D1, $00000000, $000000ED, $00000020, $000000FC, $000000B1, $0000005B,
 227     $0000006A, $000000CB, $000000BE, $00000039, $0000004A, $0000004C, $00000058, $000000CF,
 228     $000000D0, $000000EF, $000000AA, $000000FB, $00000043, $0000004D, $00000033, $00000085,
 229     $00000045, $000000F9, $00000002, $0000007F, $00000050, $0000003C, $0000009F, $000000A8,
 230     $00000051, $000000A3, $00000040, $0000008F, $00000092, $0000009D, $00000038, $000000F5,
 231     $000000BC, $000000B6, $000000DA, $00000021, $00000010, $000000FF, $000000F3, $000000D2,
 232     $000000CD, $0000000C, $00000013, $000000EC, $0000005F, $00000097, $00000044, $00000017,
 233     $000000C4, $000000A7, $0000007E, $0000003D, $00000064, $0000005D, $00000019, $00000073,
 234     $00000060, $00000081, $0000004F, $000000DC, $00000022, $0000002A, $00000090, $00000088,
 235     $00000046, $000000EE, $000000B8, $00000014, $000000DE, $0000005E, $0000000B, $000000DB,
 236     $000000E0, $00000032, $0000003A, $0000000A, $00000049, $00000006, $00000024, $0000005C,
 237     $000000C2, $000000D3, $000000AC, $00000062, $00000091, $00000095, $000000E4, $00000079,
 238     $000000E7, $000000C8, $00000037, $0000006D, $0000008D, $000000D5, $0000004E, $000000A9,
 239     $0000006C, $00000056, $000000F4, $000000EA, $00000065, $0000007A, $000000AE, $00000008,
 240     $000000BA, $00000078, $00000025, $0000002E, $0000001C, $000000A6, $000000B4, $000000C6,
 241     $000000E8, $000000DD, $00000074, $0000001F, $0000004B, $000000BD, $0000008B, $0000008A,
 242     $00000070, $0000003E, $000000B5, $00000066, $00000048, $00000003, $000000F6, $0000000E,
 243     $00000061, $00000035, $00000057, $000000B9, $00000086, $000000C1, $0000001D, $0000009E,
 244     $000000E1, $000000F8, $00000098, $00000011, $00000069, $000000D9, $0000008E, $00000094,
 245     $0000009B, $0000001E, $00000087, $000000E9, $000000CE, $00000055, $00000028, $000000DF,
 246     $0000008C, $000000A1, $00000089, $0000000D, $000000BF, $000000E6, $00000042, $00000068,
 247     $00000041, $00000099, $0000002D, $0000000F, $000000B0, $00000054, $000000BB, $00000016
 248   );
 249 
 250   InverseTable: array [0..255] of longword = (
 251     $50A7F451, $5365417E, $C3A4171A, $965E273A, $CB6BAB3B, $F1459D1F, $AB58FAAC, $9303E34B,
 252     $55FA3020, $F66D76AD, $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526, $8FA362B5,
 253     $495AB1DE, $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3, $12F04C81, $A397468D, $C6F9D36B,
 254     $E75F8F03, $959C9215, $EB7A6DBF, $DA595295, $2D83BED4, $D3217458, $2969E049, $44C8C98E,
 255     $6A89C275, $78798EF4, $6B3E5899, $DD71B927, $B64FE1BE, $17AD88F0, $66AC20C9, $B43ACE7D,
 256     $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1, $84AE6BBB, $1CA081FE, $942B08F9,
 257     $58684870, $19FD458F, $876CDE94, $B7F87B52, $23D373AB, $E2024B72, $578F1FE3, $2AAB5566,
 258     $0728EBB2, $03C2B52F, $9A7BC586, $A50837D3, $F2872830, $B2A5BF23, $BA6A0302, $5C8216ED,
 259     $2B1CCF8A, $92B479A7, $F0F207F3, $A1E2694E, $CDF4DA65, $D5BE0506, $1F6234D1, $8AFEA6C4,
 260     $9D532E34, $A055F3A2, $32E18A05, $75EBF6A4, $39EC830B, $AAEF6040, $069F715E, $51106EBD,
 261     $F98A213E, $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471, $6FD40604, $FF155060,
 262     $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0, $888B8907, $385B19E7, $DBEEC879,
 263     $470A7CA1, $E90F427C, $C91E84F8, $00000000, $83868009, $48ED2B32, $AC70111E, $4E725A6C,
 264     $FBFF0EFD, $5638850F, $1ED5AE3D, $27392D36, $64D90F0A, $21A65C68, $D1545B9B, $3A2E3624,
 265     $B1670A0C, $0FE75793, $D296EEB4, $9E919B1B, $4FC5C080, $A220DC61, $694B775A, $161A121C,
 266     $0ABA93E2, $E52AA0C0, $43E0223C, $1D171B12, $0B0D090E, $ADC78BF2, $B9A8B62D, $C8A91E14,
 267     $8519F157, $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644, $347EFB5B,
 268     $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7, $10856342, $40229713, $2011C684,
 269     $7D244A85, $F83DBBD2, $1132F9AE, $6DA129C7, $4B2F9E1D, $F330B2DC, $EC52860D, $D0E3C177,
 270     $6C16B32B, $99B970A9, $FA489411, $2264E947, $C48CFCA8, $1A3FF0A0, $D82C7D56, $EF903322,
 271     $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498, $CF81F5A6, $28DE7AA5, $268EB7DA, $A4BFAD3F,
 272     $E49D3A2C, $0D927850, $9BCC5F6A, $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382,
 273     $BE805D9F, $7C93D069, $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8, $7BBB3BDB,
 274     $097826CD, $F418596E, $01B79AEC, $A89A4F83, $656E95E6, $7EE6FFAA, $08CFBC21, $E6E815EF,
 275     $D99BE7BA, $CE366F4A, $D4099FEA, $D67CB029, $AFB2A431, $31233F2A, $3094A5C6, $C066A235,
 276     $37BC4E74, $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41, $0E50CD7F, $2FF69117,
 277     $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E, $1B886A4C, $B81F2CC1, $7F516546,
 278     $04EA5E9D, $5D358C01, $737487FA, $2E410BFB, $5A1D67B3, $52D2DB92, $335610E9, $1347D66D,
 279     $8C61D79A, $7A0CA137, $8E14F859, $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1, $3CB1477A,
 280     $59DFD29C, $3F73F255, $79CE1418, $BF37C773, $EACDF753, $5BAAFD5F, $146F3DDF, $86DB4478,
 281     $81F3AFCA, $3EC468B9, $2C342438, $5F40A3C2, $72C31D16, $0C25E2BC, $8B493C28, $41950DFF,
 282     $7101A839, $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48, $4257B8D0
 283   );
 284 
 285   LastInverseTable: array [0..255] of longword = (
 286     $00000052, $00000009, $0000006A, $000000D5, $00000030, $00000036, $000000A5, $00000038,
 287     $000000BF, $00000040, $000000A3, $0000009E, $00000081, $000000F3, $000000D7, $000000FB,
 288     $0000007C, $000000E3, $00000039, $00000082, $0000009B, $0000002F, $000000FF, $00000087,
 289     $00000034, $0000008E, $00000043, $00000044, $000000C4, $000000DE, $000000E9, $000000CB,
 290     $00000054, $0000007B, $00000094, $00000032, $000000A6, $000000C2, $00000023, $0000003D,
 291     $000000EE, $0000004C, $00000095, $0000000B, $00000042, $000000FA, $000000C3, $0000004E,
 292     $00000008, $0000002E, $000000A1, $00000066, $00000028, $000000D9, $00000024, $000000B2,
 293     $00000076, $0000005B, $000000A2, $00000049, $0000006D, $0000008B, $000000D1, $00000025,
 294     $00000072, $000000F8, $000000F6, $00000064, $00000086, $00000068, $00000098, $00000016,
 295     $000000D4, $000000A4, $0000005C, $000000CC, $0000005D, $00000065, $000000B6, $00000092,
 296     $0000006C, $00000070, $00000048, $00000050, $000000FD, $000000ED, $000000B9, $000000DA,
 297     $0000005E, $00000015, $00000046, $00000057, $000000A7, $0000008D, $0000009D, $00000084,
 298     $00000090, $000000D8, $000000AB, $00000000, $0000008C, $000000BC, $000000D3, $0000000A,
 299     $000000F7, $000000E4, $00000058, $00000005, $000000B8, $000000B3, $00000045, $00000006,
 300     $000000D0, $0000002C, $0000001E, $0000008F, $000000CA, $0000003F, $0000000F, $00000002,
 301     $000000C1, $000000AF, $000000BD, $00000003, $00000001, $00000013, $0000008A, $0000006B,
 302     $0000003A, $00000091, $00000011, $00000041, $0000004F, $00000067, $000000DC, $000000EA,
 303     $00000097, $000000F2, $000000CF, $000000CE, $000000F0, $000000B4, $000000E6, $00000073,
 304     $00000096, $000000AC, $00000074, $00000022, $000000E7, $000000AD, $00000035, $00000085,
 305     $000000E2, $000000F9, $00000037, $000000E8, $0000001C, $00000075, $000000DF, $0000006E,
 306     $00000047, $000000F1, $0000001A, $00000071, $0000001D, $00000029, $000000C5, $00000089,
 307     $0000006F, $000000B7, $00000062, $0000000E, $000000AA, $00000018, $000000BE, $0000001B,
 308     $000000FC, $00000056, $0000003E, $0000004B, $000000C6, $000000D2, $00000079, $00000020,
 309     $0000009A, $000000DB, $000000C0, $000000FE, $00000078, $000000CD, $0000005A, $000000F4,
 310     $0000001F, $000000DD, $000000A8, $00000033, $00000088, $00000007, $000000C7, $00000031,
 311     $000000B1, $00000012, $00000010, $00000059, $00000027, $00000080, $000000EC, $0000005F,
 312     $00000060, $00000051, $0000007F, $000000A9, $00000019, $000000B5, $0000004A, $0000000D,
 313     $0000002D, $000000E5, $0000007A, $0000009F, $00000093, $000000C9, $0000009C, $000000EF,
 314     $000000A0, $000000E0, $0000003B, $0000004D, $000000AE, $0000002A, $000000F5, $000000B0,
 315     $000000C8, $000000EB, $000000BB, $0000003C, $00000083, $00000053, $00000099, $00000061,
 316     $00000017, $0000002B, $00000004, $0000007E, $000000BA, $00000077, $000000D6, $00000026,
 317     $000000E1, $00000069, $00000014, $00000063, $00000055, $00000021, $0000000C, $0000007D
 318   );
 319 
 320 procedure ExpandAESKeyForEncryption(const Key: TAESKey128; var ExpandedKey: TAESExpandedKey128);
 321 var
 322   I, J: integer;
 323   T: longword;
 324   W0, W1, W2, W3: longword;
 325 begin
 326   ExpandedKey[0] := PLongWord(@Key[0])^;
 327   ExpandedKey[1] := PLongWord(@Key[4])^;
 328   ExpandedKey[2] := PLongWord(@Key[8])^;
 329   ExpandedKey[3] := PLongWord(@Key[12])^;
 330   I := 0; J := 1;
 331   repeat
 332     T := (ExpandedKey[I + 3] shl 24) or (ExpandedKey[I + 3] shr 8);
 333     W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)];
 334     W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)];
 335     ExpandedKey[I + 4] := ExpandedKey[I] xor
 336       (W0 xor ((W1 shl 8) or (W1 shr 24)) xor
 337       ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J];
 338     Inc(J);
 339     ExpandedKey[I + 5] := ExpandedKey[I + 1] xor ExpandedKey[I + 4];
 340     ExpandedKey[I + 6] := ExpandedKey[I + 2] xor ExpandedKey[I + 5];
 341     ExpandedKey[I + 7] := ExpandedKey[I + 3] xor ExpandedKey[I + 6];
 342     Inc(I, 4);
 343   until I >= 40;
 344 end;
 345 
 346 procedure ExpandAESKeyForEncryption(const Key: TAESKey192; var ExpandedKey: TAESExpandedKey192); overload;
 347 var
 348   I, J: integer;
 349   T: longword;
 350   W0, W1, W2, W3: longword;
 351 begin
 352   ExpandedKey[0] := PLongWord(@Key[0])^;
 353   ExpandedKey[1] := PLongWord(@Key[4])^;
 354   ExpandedKey[2] := PLongWord(@Key[8])^;
 355   ExpandedKey[3] := PLongWord(@Key[12])^;
 356   ExpandedKey[4] := PLongWord(@Key[16])^;
 357   ExpandedKey[5] := PLongWord(@Key[20])^;
 358   I := 0; J := 1;
 359   repeat
 360     T := (ExpandedKey[I + 5] shl 24) or (ExpandedKey[I + 5] shr 8);
 361     W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)];
 362     W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)];
 363     ExpandedKey[I + 6] := ExpandedKey[I] xor
 364       (W0 xor ((W1 shl 8) or (W1 shr 24)) xor
 365       ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J];
 366     Inc(J);
 367     ExpandedKey[I + 7] := ExpandedKey[I + 1] xor ExpandedKey[I + 6];
 368     ExpandedKey[I + 8] := ExpandedKey[I + 2] xor ExpandedKey[I + 7];
 369     ExpandedKey[I + 9] := ExpandedKey[I + 3] xor ExpandedKey[I + 8];
 370     ExpandedKey[I + 10] := ExpandedKey[I + 4] xor ExpandedKey[I + 9];
 371     ExpandedKey[I + 11] := ExpandedKey[I + 5] xor ExpandedKey[I + 10];
 372     Inc(I, 6);
 373   until I >= 46;
 374 end;
 375 
 376 procedure ExpandAESKeyForEncryption(const Key: TAESKey256; var ExpandedKey: TAESExpandedKey256); overload;
 377 var
 378   I, J: integer;
 379   T: longword;
 380   W0, W1, W2, W3: longword;
 381 begin
 382   ExpandedKey[0] := PLongWord(@Key[0])^;
 383   ExpandedKey[1] := PLongWord(@Key[4])^;
 384   ExpandedKey[2] := PLongWord(@Key[8])^;
 385   ExpandedKey[3] := PLongWord(@Key[12])^;
 386   ExpandedKey[4] := PLongWord(@Key[16])^;
 387   ExpandedKey[5] := PLongWord(@Key[20])^;
 388   ExpandedKey[6] := PLongWord(@Key[24])^;
 389   ExpandedKey[7] := PLongWord(@Key[28])^;
 390   I := 0; J := 1;
 391   repeat
 392     T := (ExpandedKey[I + 7] shl 24) or (ExpandedKey[I + 7] shr 8);
 393     W0 := LastForwardTable[Byte(T)]; W1 := LastForwardTable[Byte(T shr 8)];
 394     W2 := LastForwardTable[Byte(T shr 16)]; W3 := LastForwardTable[Byte(T shr 24)];
 395     ExpandedKey[I + 8] := ExpandedKey[I] xor
 396       (W0 xor ((W1 shl 8) or (W1 shr 24)) xor
 397       ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J];
 398     Inc(J);
 399     ExpandedKey[I + 9] := ExpandedKey[I + 1] xor ExpandedKey[I + 8];
 400     ExpandedKey[I + 10] := ExpandedKey[I + 2] xor ExpandedKey[I + 9];
 401     ExpandedKey[I + 11] := ExpandedKey[I + 3] xor ExpandedKey[I + 10];
 402     W0 := LastForwardTable[Byte(ExpandedKey[I + 11])];
 403     W1 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 8)];
 404     W2 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 16)];
 405     W3 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 24)];
 406     ExpandedKey[I + 12] := ExpandedKey[I + 4] xor
 407       (W0 xor ((W1 shl 8) or (W1 shr 24)) xor
 408       ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)));
 409     ExpandedKey[I + 13] := ExpandedKey[I + 5] xor ExpandedKey[I + 12];
 410     ExpandedKey[I + 14] := ExpandedKey[I + 6] xor ExpandedKey[I + 13];
 411     ExpandedKey[I + 15] := ExpandedKey[I + 7] xor ExpandedKey[I + 14];
 412     Inc(I, 8);
 413   until I >= 52;
 414 end;
 415 
 416 procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128;
 417   var OutBuf: TAESBuffer); 
 418 var
 419   T0, T1: array [0..3] of longword;
 420   W0, W1, W2, W3: longword;
 421 begin
 422   // initializing
 423   T0[0] := PLongWord(@InBuf[0])^ xor Key[0];
 424   T0[1] := PLongWord(@InBuf[4])^ xor Key[1];
 425   T0[2] := PLongWord(@InBuf[8])^ xor Key[2];
 426   T0[3] := PLongWord(@InBuf[12])^ xor Key[3];
 427   // performing transformation 9 times
 428   // round 1
 429   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 430   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 431   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 432     xor ((W3 shl 24) or (W3 shr 8))) xor Key[4];
 433   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 434   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 435   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 436     xor ((W3 shl 24) or (W3 shr 8))) xor Key[5];
 437   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 438   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 439   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 440     xor ((W3 shl 24) or (W3 shr 8))) xor Key[6];
 441   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 442   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 443   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 444     xor ((W3 shl 24) or (W3 shr 8))) xor Key[7];
 445   // round 2
 446   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 447   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 448   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 449     xor ((W3 shl 24) or (W3 shr 8))) xor Key[8];
 450   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 451   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 452   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 453     xor ((W3 shl 24) or (W3 shr 8))) xor Key[9];
 454   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 455   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 456   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 457     xor ((W3 shl 24) or (W3 shr 8))) xor Key[10];
 458   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 459   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 460   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 461     xor ((W3 shl 24) or (W3 shr 8))) xor Key[11];
 462   // round 3
 463   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 464   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 465   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 466     xor ((W3 shl 24) or (W3 shr 8))) xor Key[12];
 467   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 468   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 469   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 470     xor ((W3 shl 24) or (W3 shr 8))) xor Key[13];
 471   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 472   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 473   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 474     xor ((W3 shl 24) or (W3 shr 8))) xor Key[14];
 475   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 476   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 477   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 478     xor ((W3 shl 24) or (W3 shr 8))) xor Key[15];
 479   // round 4
 480   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 481   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 482   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 483     xor ((W3 shl 24) or (W3 shr 8))) xor Key[16];
 484   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 485   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 486   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 487     xor ((W3 shl 24) or (W3 shr 8))) xor Key[17];
 488   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 489   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 490   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 491     xor ((W3 shl 24) or (W3 shr 8))) xor Key[18];
 492   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 493   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 494   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 495     xor ((W3 shl 24) or (W3 shr 8))) xor Key[19];
 496   // round 5
 497   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 498   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 499   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 500     xor ((W3 shl 24) or (W3 shr 8))) xor Key[20];
 501   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 502   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 503   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 504     xor ((W3 shl 24) or (W3 shr 8))) xor Key[21];
 505   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 506   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 507   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 508     xor ((W3 shl 24) or (W3 shr 8))) xor Key[22];
 509   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 510   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 511   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 512     xor ((W3 shl 24) or (W3 shr 8))) xor Key[23];
 513   // round 6
 514   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 515   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 516   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 517     xor ((W3 shl 24) or (W3 shr 8))) xor Key[24];
 518   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 519   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 520   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 521     xor ((W3 shl 24) or (W3 shr 8))) xor Key[25];
 522   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 523   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 524   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 525     xor ((W3 shl 24) or (W3 shr 8))) xor Key[26];
 526   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 527   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 528   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 529     xor ((W3 shl 24) or (W3 shr 8))) xor Key[27];
 530   // round 7
 531   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 532   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 533   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 534     xor ((W3 shl 24) or (W3 shr 8))) xor Key[28];
 535   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 536   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 537   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 538     xor ((W3 shl 24) or (W3 shr 8))) xor Key[29];
 539   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 540   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 541   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 542     xor ((W3 shl 24) or (W3 shr 8))) xor Key[30];
 543   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 544   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 545   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 546     xor ((W3 shl 24) or (W3 shr 8))) xor Key[31];
 547   // round 8
 548   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 549   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 550   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 551     xor ((W3 shl 24) or (W3 shr 8))) xor Key[32];
 552   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 553   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 554   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 555     xor ((W3 shl 24) or (W3 shr 8))) xor Key[33];
 556   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 557   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 558   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 559     xor ((W3 shl 24) or (W3 shr 8))) xor Key[34];
 560   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 561   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 562   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 563     xor ((W3 shl 24) or (W3 shr 8))) xor Key[35];
 564   // round 9
 565   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 566   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 567   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 568     xor ((W3 shl 24) or (W3 shr 8))) xor Key[36];
 569   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 570   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 571   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 572     xor ((W3 shl 24) or (W3 shr 8))) xor Key[37];
 573   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 574   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 575   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 576     xor ((W3 shl 24) or (W3 shr 8))) xor Key[38];
 577   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 578   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 579   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 580     xor ((W3 shl 24) or (W3 shr 8))) xor Key[39];
 581   // last round of transformations
 582   W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)];
 583   W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)];
 584   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 585     xor ((W3 shl 24) or (W3 shr 8))) xor Key[40];
 586   W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)];
 587   W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)];
 588   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 589     xor ((W3 shl 24) or (W3 shr 8))) xor Key[41];
 590   W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)];
 591   W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)];
 592   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 593     xor ((W3 shl 24) or (W3 shr 8))) xor Key[42];
 594   W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)];
 595   W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)];
 596   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 597     xor ((W3 shl 24) or (W3 shr 8))) xor Key[43];
 598   // finalizing
 599   PLongWord(@OutBuf[0])^ := T0[0]; PLongWord(@OutBuf[4])^ := T0[1];
 600   PLongWord(@OutBuf[8])^ := T0[2]; PLongWord(@OutBuf[12])^ := T0[3];
 601 end;
 602 
 603 procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192;
 604   var OutBuf: TAESBuffer);
 605 var
 606   T0, T1: array [0..3] of longword;
 607   W0, W1, W2, W3: longword;
 608 begin
 609   // initializing
 610   T0[0] := PLongWord(@InBuf[0])^ xor Key[0];
 611   T0[1] := PLongWord(@InBuf[4])^ xor Key[1];
 612   T0[2] := PLongWord(@InBuf[8])^ xor Key[2];
 613   T0[3] := PLongWord(@InBuf[12])^ xor Key[3];
 614   // performing transformation 11 times
 615   // round 1
 616   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 617   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 618   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 619     xor ((W3 shl 24) or (W3 shr 8))) xor Key[4];
 620   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 621   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 622   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 623     xor ((W3 shl 24) or (W3 shr 8))) xor Key[5];
 624   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 625   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 626   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 627     xor ((W3 shl 24) or (W3 shr 8))) xor Key[6];
 628   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 629   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 630   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 631     xor ((W3 shl 24) or (W3 shr 8))) xor Key[7];
 632   // round 2
 633   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 634   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 635   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 636     xor ((W3 shl 24) or (W3 shr 8))) xor Key[8];
 637   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 638   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 639   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 640     xor ((W3 shl 24) or (W3 shr 8))) xor Key[9];
 641   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 642   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 643   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 644     xor ((W3 shl 24) or (W3 shr 8))) xor Key[10];
 645   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 646   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 647   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 648     xor ((W3 shl 24) or (W3 shr 8))) xor Key[11];
 649   // round 3
 650   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 651   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 652   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 653     xor ((W3 shl 24) or (W3 shr 8))) xor Key[12];
 654   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 655   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 656   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 657     xor ((W3 shl 24) or (W3 shr 8))) xor Key[13];
 658   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 659   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 660   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 661     xor ((W3 shl 24) or (W3 shr 8))) xor Key[14];
 662   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 663   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 664   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 665     xor ((W3 shl 24) or (W3 shr 8))) xor Key[15];
 666   // round 4
 667   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 668   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 669   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 670     xor ((W3 shl 24) or (W3 shr 8))) xor Key[16];
 671   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 672   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 673   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 674     xor ((W3 shl 24) or (W3 shr 8))) xor Key[17];
 675   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 676   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 677   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 678     xor ((W3 shl 24) or (W3 shr 8))) xor Key[18];
 679   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 680   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 681   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 682     xor ((W3 shl 24) or (W3 shr 8))) xor Key[19];
 683   // round 5
 684   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 685   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 686   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 687     xor ((W3 shl 24) or (W3 shr 8))) xor Key[20];
 688   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 689   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 690   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 691     xor ((W3 shl 24) or (W3 shr 8))) xor Key[21];
 692   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 693   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 694   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 695     xor ((W3 shl 24) or (W3 shr 8))) xor Key[22];
 696   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 697   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 698   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 699     xor ((W3 shl 24) or (W3 shr 8))) xor Key[23];
 700   // round 6
 701   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 702   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 703   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 704     xor ((W3 shl 24) or (W3 shr 8))) xor Key[24];
 705   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 706   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 707   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 708     xor ((W3 shl 24) or (W3 shr 8))) xor Key[25];
 709   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 710   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 711   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 712     xor ((W3 shl 24) or (W3 shr 8))) xor Key[26];
 713   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 714   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 715   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 716     xor ((W3 shl 24) or (W3 shr 8))) xor Key[27];
 717   // round 7
 718   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 719   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 720   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 721     xor ((W3 shl 24) or (W3 shr 8))) xor Key[28];
 722   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 723   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 724   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 725     xor ((W3 shl 24) or (W3 shr 8))) xor Key[29];
 726   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 727   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 728   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 729     xor ((W3 shl 24) or (W3 shr 8))) xor Key[30];
 730   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 731   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 732   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 733     xor ((W3 shl 24) or (W3 shr 8))) xor Key[31];
 734   // round 8
 735   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 736   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 737   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 738     xor ((W3 shl 24) or (W3 shr 8))) xor Key[32];
 739   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 740   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 741   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 742     xor ((W3 shl 24) or (W3 shr 8))) xor Key[33];
 743   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 744   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 745   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 746     xor ((W3 shl 24) or (W3 shr 8))) xor Key[34];
 747   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 748   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 749   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 750     xor ((W3 shl 24) or (W3 shr 8))) xor Key[35];
 751   // round 9
 752   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 753   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 754   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 755     xor ((W3 shl 24) or (W3 shr 8))) xor Key[36];
 756   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 757   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 758   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 759     xor ((W3 shl 24) or (W3 shr 8))) xor Key[37];
 760   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 761   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 762   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 763     xor ((W3 shl 24) or (W3 shr 8))) xor Key[38];
 764   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 765   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 766   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 767     xor ((W3 shl 24) or (W3 shr 8))) xor Key[39];
 768   // round 10
 769   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 770   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 771   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 772     xor ((W3 shl 24) or (W3 shr 8))) xor Key[40];
 773   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 774   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 775   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 776     xor ((W3 shl 24) or (W3 shr 8))) xor Key[41];
 777   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 778   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 779   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 780     xor ((W3 shl 24) or (W3 shr 8))) xor Key[42];
 781   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 782   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 783   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 784     xor ((W3 shl 24) or (W3 shr 8))) xor Key[43];
 785   // round 11
 786   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 787   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 788   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 789     xor ((W3 shl 24) or (W3 shr 8))) xor Key[44];
 790   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 791   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 792   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 793     xor ((W3 shl 24) or (W3 shr 8))) xor Key[45];
 794   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 795   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 796   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 797     xor ((W3 shl 24) or (W3 shr 8))) xor Key[46];
 798   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 799   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 800   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 801     xor ((W3 shl 24) or (W3 shr 8))) xor Key[47];
 802   // last round of transformations
 803   W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)];
 804   W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)];
 805   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 806     xor ((W3 shl 24) or (W3 shr 8))) xor Key[48];
 807   W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)];
 808   W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)];
 809   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 810     xor ((W3 shl 24) or (W3 shr 8))) xor Key[49];
 811   W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)];
 812   W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)];
 813   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 814     xor ((W3 shl 24) or (W3 shr 8))) xor Key[50];
 815   W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)];
 816   W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)];
 817   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 818     xor ((W3 shl 24) or (W3 shr 8))) xor Key[51];
 819   // finalizing
 820   PLongWord(@OutBuf[0])^ := T0[0]; PLongWord(@OutBuf[4])^ := T0[1];
 821   PLongWord(@OutBuf[8])^ := T0[2]; PLongWord(@OutBuf[12])^ := T0[3];
 822 end;
 823 
 824 procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256;
 825   var OutBuf: TAESBuffer);
 826 var
 827   T0, T1: array [0..3] of longword;
 828   W0, W1, W2, W3: longword;
 829 begin
 830   // initializing
 831   T0[0] := PLongWord(@InBuf[0])^ xor Key[0];
 832   T0[1] := PLongWord(@InBuf[4])^ xor Key[1];
 833   T0[2] := PLongWord(@InBuf[8])^ xor Key[2];
 834   T0[3] := PLongWord(@InBuf[12])^ xor Key[3];
 835   // performing transformation 13 times
 836   // round 1
 837   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 838   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 839   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 840     xor ((W3 shl 24) or (W3 shr 8))) xor Key[4];
 841   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 842   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 843   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 844     xor ((W3 shl 24) or (W3 shr 8))) xor Key[5];
 845   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 846   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 847   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 848     xor ((W3 shl 24) or (W3 shr 8))) xor Key[6];
 849   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 850   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 851   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 852     xor ((W3 shl 24) or (W3 shr 8))) xor Key[7];
 853   // round 2
 854   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 855   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 856   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 857     xor ((W3 shl 24) or (W3 shr 8))) xor Key[8];
 858   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 859   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 860   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 861     xor ((W3 shl 24) or (W3 shr 8))) xor Key[9];
 862   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 863   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 864   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 865     xor ((W3 shl 24) or (W3 shr 8))) xor Key[10];
 866   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 867   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 868   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 869     xor ((W3 shl 24) or (W3 shr 8))) xor Key[11];
 870   // round 3
 871   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 872   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 873   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 874     xor ((W3 shl 24) or (W3 shr 8))) xor Key[12];
 875   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 876   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 877   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 878     xor ((W3 shl 24) or (W3 shr 8))) xor Key[13];
 879   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 880   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 881   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 882     xor ((W3 shl 24) or (W3 shr 8))) xor Key[14];
 883   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 884   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 885   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 886     xor ((W3 shl 24) or (W3 shr 8))) xor Key[15];
 887   // round 4
 888   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 889   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 890   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 891     xor ((W3 shl 24) or (W3 shr 8))) xor Key[16];
 892   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 893   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 894   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 895     xor ((W3 shl 24) or (W3 shr 8))) xor Key[17];
 896   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 897   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 898   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 899     xor ((W3 shl 24) or (W3 shr 8))) xor Key[18];
 900   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 901   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 902   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 903     xor ((W3 shl 24) or (W3 shr 8))) xor Key[19];
 904   // round 5
 905   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 906   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 907   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 908     xor ((W3 shl 24) or (W3 shr 8))) xor Key[20];
 909   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 910   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 911   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 912     xor ((W3 shl 24) or (W3 shr 8))) xor Key[21];
 913   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 914   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 915   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 916     xor ((W3 shl 24) or (W3 shr 8))) xor Key[22];
 917   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 918   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 919   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 920     xor ((W3 shl 24) or (W3 shr 8))) xor Key[23];
 921   // round 6
 922   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 923   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 924   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 925     xor ((W3 shl 24) or (W3 shr 8))) xor Key[24];
 926   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 927   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 928   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 929     xor ((W3 shl 24) or (W3 shr 8))) xor Key[25];
 930   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 931   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 932   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 933     xor ((W3 shl 24) or (W3 shr 8))) xor Key[26];
 934   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 935   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 936   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 937     xor ((W3 shl 24) or (W3 shr 8))) xor Key[27];
 938   // round 7
 939   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 940   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 941   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 942     xor ((W3 shl 24) or (W3 shr 8))) xor Key[28];
 943   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 944   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 945   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 946     xor ((W3 shl 24) or (W3 shr 8))) xor Key[29];
 947   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 948   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 949   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 950     xor ((W3 shl 24) or (W3 shr 8))) xor Key[30];
 951   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 952   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 953   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 954     xor ((W3 shl 24) or (W3 shr 8))) xor Key[31];
 955   // round 8
 956   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 957   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 958   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 959     xor ((W3 shl 24) or (W3 shr 8))) xor Key[32];
 960   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 961   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 962   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 963     xor ((W3 shl 24) or (W3 shr 8))) xor Key[33];
 964   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 965   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
 966   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 967     xor ((W3 shl 24) or (W3 shr 8))) xor Key[34];
 968   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
 969   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
 970   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 971     xor ((W3 shl 24) or (W3 shr 8))) xor Key[35];
 972   // round 9
 973   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
 974   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
 975   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 976     xor ((W3 shl 24) or (W3 shr 8))) xor Key[36];
 977   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
 978   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
 979   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 980     xor ((W3 shl 24) or (W3 shr 8))) xor Key[37];
 981   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
 982   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
 983   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 984     xor ((W3 shl 24) or (W3 shr 8))) xor Key[38];
 985   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
 986   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
 987   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 988     xor ((W3 shl 24) or (W3 shr 8))) xor Key[39];
 989   // round 10
 990   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
 991   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
 992   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 993     xor ((W3 shl 24) or (W3 shr 8))) xor Key[40];
 994   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
 995   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
 996   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
 997     xor ((W3 shl 24) or (W3 shr 8))) xor Key[41];
 998   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
 999   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
1000   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1001     xor ((W3 shl 24) or (W3 shr 8))) xor Key[42];
1002   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
1003   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
1004   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1005     xor ((W3 shl 24) or (W3 shr 8))) xor Key[43];
1006   // round 11
1007   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
1008   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
1009   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1010     xor ((W3 shl 24) or (W3 shr 8))) xor Key[44];
1011   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
1012   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
1013   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1014     xor ((W3 shl 24) or (W3 shr 8))) xor Key[45];
1015   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
1016   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
1017   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1018     xor ((W3 shl 24) or (W3 shr 8))) xor Key[46];
1019   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
1020   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
1021   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1022     xor ((W3 shl 24) or (W3 shr 8))) xor Key[47];
1023   // round 12
1024   W0 := ForwardTable[Byte(T1[0])]; W1 := ForwardTable[Byte(T1[1] shr 8)];
1025   W2 := ForwardTable[Byte(T1[2] shr 16)]; W3 := ForwardTable[Byte(T1[3] shr 24)];
1026   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1027     xor ((W3 shl 24) or (W3 shr 8))) xor Key[48];
1028   W0 := ForwardTable[Byte(T1[1])]; W1 := ForwardTable[Byte(T1[2] shr 8)];
1029   W2 := ForwardTable[Byte(T1[3] shr 16)]; W3 := ForwardTable[Byte(T1[0] shr 24)];
1030   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1031     xor ((W3 shl 24) or (W3 shr 8))) xor Key[49];
1032   W0 := ForwardTable[Byte(T1[2])]; W1 := ForwardTable[Byte(T1[3] shr 8)];
1033   W2 := ForwardTable[Byte(T1[0] shr 16)]; W3 := ForwardTable[Byte(T1[1] shr 24)];
1034   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1035     xor ((W3 shl 24) or (W3 shr 8))) xor Key[50];
1036   W0 := ForwardTable[Byte(T1[3])]; W1 := ForwardTable[Byte(T1[0] shr 8)];
1037   W2 := ForwardTable[Byte(T1[1] shr 16)]; W3 := ForwardTable[Byte(T1[2] shr 24)];
1038   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1039     xor ((W3 shl 24) or (W3 shr 8))) xor Key[51];
1040   // round 13
1041   W0 := ForwardTable[Byte(T0[0])]; W1 := ForwardTable[Byte(T0[1] shr 8)];
1042   W2 := ForwardTable[Byte(T0[2] shr 16)]; W3 := ForwardTable[Byte(T0[3] shr 24)];
1043   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1044     xor ((W3 shl 24) or (W3 shr 8))) xor Key[52];
1045   W0 := ForwardTable[Byte(T0[1])]; W1 := ForwardTable[Byte(T0[2] shr 8)];
1046   W2 := ForwardTable[Byte(T0[3] shr 16)]; W3 := ForwardTable[Byte(T0[0] shr 24)];
1047   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1048     xor ((W3 shl 24) or (W3 shr 8))) xor Key[53];
1049   W0 := ForwardTable[Byte(T0[2])]; W1 := ForwardTable[Byte(T0[3] shr 8)];
1050   W2 := ForwardTable[Byte(T0[0] shr 16)]; W3 := ForwardTable[Byte(T0[1] shr 24)];
1051   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1052     xor ((W3 shl 24) or (W3 shr 8))) xor Key[54];
1053   W0 := ForwardTable[Byte(T0[3])]; W1 := ForwardTable[Byte(T0[0] shr 8)];
1054   W2 := ForwardTable[Byte(T0[1] shr 16)]; W3 := ForwardTable[Byte(T0[2] shr 24)];
1055   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1056     xor ((W3 shl 24) or (W3 shr 8))) xor Key[55];
1057   // last round of transformations
1058   W0 := LastForwardTable[Byte(T1[0])]; W1 := LastForwardTable[Byte(T1[1] shr 8)];
1059   W2 := LastForwardTable[Byte(T1[2] shr 16)]; W3 := LastForwardTable[Byte(T1[3] shr 24)];
1060   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1061     xor ((W3 shl 24) or (W3 shr 8))) xor Key[56];
1062   W0 := LastForwardTable[Byte(T1[1])]; W1 := LastForwardTable[Byte(T1[2] shr 8)];
1063   W2 := LastForwardTable[Byte(T1[3] shr 16)]; W3 := LastForwardTable[Byte(T1[0] shr 24)];
1064   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1065     xor ((W3 shl 24) or (W3 shr 8))) xor Key[57];
1066   W0 := LastForwardTable[Byte(T1[2])]; W1 := LastForwardTable[Byte(T1[3] shr 8)];
1067   W2 := LastForwardTable[Byte(T1[0] shr 16)]; W3 := LastForwardTable[Byte(T1[1] shr 24)];
1068   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1069     xor ((W3 shl 24) or (W3 shr 8))) xor Key[58];
1070   W0 := LastForwardTable[Byte(T1[3])]; W1 := LastForwardTable[Byte(T1[0] shr 8)];
1071   W2 := LastForwardTable[Byte(T1[1] shr 16)]; W3 := LastForwardTable[Byte(T1[2] shr 24)];
1072   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1073     xor ((W3 shl 24) or (W3 shr 8))) xor Key[59];
1074   // finalizing
1075   PLongWord(@OutBuf[0])^ := T0[0]; PLongWord(@OutBuf[4])^ := T0[1];
1076   PLongWord(@OutBuf[8])^ := T0[2]; PLongWord(@OutBuf[12])^ := T0[3];
1077 end;
1078 
1079 procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey128);
1080 var
1081   I: integer;
1082   U, F2, F4, F8, F9: longword;
1083 begin
1084   for I := 1 to 9 do
1085   begin
1086     F9 := ExpandedKey[I * 4];
1087     U := F9 and $80808080;
1088     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1089     U := F2 and $80808080;
1090     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1091     U := F4 and $80808080;
1092     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1093     F9 := F9 xor F8;
1094     ExpandedKey[I * 4] := F2 xor F4 xor F8 xor
1095       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1096       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1097     F9 := ExpandedKey[I * 4 + 1];
1098     U := F9 and $80808080;
1099     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1100     U := F2 and $80808080;
1101     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1102     U := F4 and $80808080;
1103     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1104     F9 := F9 xor F8;
1105     ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor
1106       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1107       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1108     F9 := ExpandedKey[I * 4 + 2];
1109     U := F9 and $80808080;
1110     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1111     U := F2 and $80808080;
1112     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1113     U := F4 and $80808080;
1114     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1115     F9 := F9 xor F8;
1116     ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor
1117       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1118       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1119     F9 := ExpandedKey[I * 4 + 3];
1120     U := F9 and $80808080;
1121     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1122     U := F2 and $80808080;
1123     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1124     U := F4 and $80808080;
1125     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1126     F9 := F9 xor F8;
1127     ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor
1128       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1129       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1130   end;
1131 end;
1132 
1133 procedure ExpandAESKeyForDecryption(const Key: TAESKey128; var ExpandedKey: TAESExpandedKey128);
1134 begin
1135   ExpandAESKeyForEncryption(Key, ExpandedKey);
1136   ExpandAESKeyForDecryption(ExpandedKey);
1137 end;
1138 
1139 procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey192);
1140 var
1141   I: integer;
1142   U, F2, F4, F8, F9: longword;
1143 begin
1144   for I := 1 to 11 do
1145   begin
1146     F9 := ExpandedKey[I * 4];
1147     U := F9 and $80808080;
1148     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1149     U := F2 and $80808080;
1150     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1151     U := F4 and $80808080;
1152     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1153     F9 := F9 xor F8;
1154     ExpandedKey[I * 4] := F2 xor F4 xor F8 xor
1155       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1156       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1157     F9 := ExpandedKey[I * 4 + 1];
1158     U := F9 and $80808080;
1159     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1160     U := F2 and $80808080;
1161     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1162     U := F4 and $80808080;
1163     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1164     F9 := F9 xor F8;
1165     ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor
1166       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1167       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1168     F9 := ExpandedKey[I * 4 + 2];
1169     U := F9 and $80808080;
1170     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1171     U := F2 and $80808080;
1172     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1173     U := F4 and $80808080;
1174     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1175     F9 := F9 xor F8;
1176     ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor
1177       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1178       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1179     F9 := ExpandedKey[I * 4 + 3];
1180     U := F9 and $80808080;
1181     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1182     U := F2 and $80808080;
1183     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1184     U := F4 and $80808080;
1185     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1186     F9 := F9 xor F8;
1187     ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor
1188       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1189       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1190   end;
1191 end;
1192 
1193 procedure ExpandAESKeyForDecryption(const Key: TAESKey192; var ExpandedKey: TAESExpandedKey192);
1194 begin
1195   ExpandAESKeyForEncryption(Key, ExpandedKey);
1196   ExpandAESKeyForDecryption(ExpandedKey);
1197 end;
1198 
1199 procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey256);
1200 var
1201   I: integer;
1202   U, F2, F4, F8, F9: longword;
1203 begin
1204   for I := 1 to 13 do
1205   begin
1206     F9 := ExpandedKey[I * 4];
1207     U := F9 and $80808080;
1208     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1209     U := F2 and $80808080;
1210     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1211     U := F4 and $80808080;
1212     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1213     F9 := F9 xor F8;
1214     ExpandedKey[I * 4] := F2 xor F4 xor F8 xor
1215       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1216       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1217     F9 := ExpandedKey[I * 4 + 1];
1218     U := F9 and $80808080;
1219     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1220     U := F2 and $80808080;
1221     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1222     U := F4 and $80808080;
1223     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1224     F9 := F9 xor F8;
1225     ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor
1226       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1227       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1228     F9 := ExpandedKey[I * 4 + 2];
1229     U := F9 and $80808080;
1230     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1231     U := F2 and $80808080;
1232     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1233     U := F4 and $80808080;
1234     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1235     F9 := F9 xor F8;
1236     ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor
1237       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1238       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1239     F9 := ExpandedKey[I * 4 + 3];
1240     U := F9 and $80808080;
1241     F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1242     U := F2 and $80808080;
1243     F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1244     U := F4 and $80808080;
1245     F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
1246     F9 := F9 xor F8;
1247     ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor
1248       (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8)) xor
1249       (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
1250   end;
1251 end;
1252 
1253 procedure ExpandAESKeyForDecryption(const Key: TAESKey256; var ExpandedKey: TAESExpandedKey256);
1254 begin
1255   ExpandAESKeyForEncryption(Key, ExpandedKey);
1256   ExpandAESKeyForDecryption(ExpandedKey);
1257 end;
1258 
1259 procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128;
1260   var OutBuf: TAESBuffer);
1261 var
1262   T0, T1: array [0..3] of longword;
1263   W0, W1, W2, W3: longword;
1264 begin
1265   // initializing
1266   T0[0] := PLongWord(@InBuf[0])^ xor Key[40];
1267   T0[1] := PLongWord(@InBuf[4])^ xor Key[41];
1268   T0[2] := PLongWord(@InBuf[8])^ xor Key[42];
1269   T0[3] := PLongWord(@InBuf[12])^ xor Key[43];
1270   // performing transformations 9 times
1271   // round 1
1272   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1273   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1274   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1275     xor ((W3 shl 24) or (W3 shr 8))) xor Key[36];
1276   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1277   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1278   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1279     xor ((W3 shl 24) or (W3 shr 8))) xor Key[37];
1280   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1281   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1282   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1283     xor ((W3 shl 24) or (W3 shr 8))) xor Key[38];
1284   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1285   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1286   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1287     xor ((W3 shl 24) or (W3 shr 8))) xor Key[39];
1288   // round 2
1289   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1290   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1291   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1292     xor ((W3 shl 24) or (W3 shr 8))) xor Key[32];
1293   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1294   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1295   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1296     xor ((W3 shl 24) or (W3 shr 8))) xor Key[33];
1297   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1298   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1299   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1300     xor ((W3 shl 24) or (W3 shr 8))) xor Key[34];
1301   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1302   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1303   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1304     xor ((W3 shl 24) or (W3 shr 8))) xor Key[35];
1305   // round 3
1306   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1307   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1308   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1309     xor ((W3 shl 24) or (W3 shr 8))) xor Key[28];
1310   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1311   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1312   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1313     xor ((W3 shl 24) or (W3 shr 8))) xor Key[29];
1314   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1315   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1316   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1317     xor ((W3 shl 24) or (W3 shr 8))) xor Key[30];
1318   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1319   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1320   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1321     xor ((W3 shl 24) or (W3 shr 8))) xor Key[31];
1322   // round 4
1323   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1324   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1325   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1326     xor ((W3 shl 24) or (W3 shr 8))) xor Key[24];
1327   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1328   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1329   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1330     xor ((W3 shl 24) or (W3 shr 8))) xor Key[25];
1331   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1332   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1333   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1334     xor ((W3 shl 24) or (W3 shr 8))) xor Key[26];
1335   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1336   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1337   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1338     xor ((W3 shl 24) or (W3 shr 8))) xor Key[27];
1339   // round 5
1340   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1341   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1342   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1343     xor ((W3 shl 24) or (W3 shr 8))) xor Key[20];
1344   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1345   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1346   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1347     xor ((W3 shl 24) or (W3 shr 8))) xor Key[21];
1348   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1349   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1350   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1351     xor ((W3 shl 24) or (W3 shr 8))) xor Key[22];
1352   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1353   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1354   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1355     xor ((W3 shl 24) or (W3 shr 8))) xor Key[23];
1356   // round 6
1357   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1358   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1359   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1360     xor ((W3 shl 24) or (W3 shr 8))) xor Key[16];
1361   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1362   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1363   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1364     xor ((W3 shl 24) or (W3 shr 8))) xor Key[17];
1365   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1366   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1367   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1368     xor ((W3 shl 24) or (W3 shr 8))) xor Key[18];
1369   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1370   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1371   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1372     xor ((W3 shl 24) or (W3 shr 8))) xor Key[19];
1373   // round 7
1374   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1375   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1376   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1377     xor ((W3 shl 24) or (W3 shr 8))) xor Key[12];
1378   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1379   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1380   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1381     xor ((W3 shl 24) or (W3 shr 8))) xor Key[13];
1382   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1383   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1384   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1385     xor ((W3 shl 24) or (W3 shr 8))) xor Key[14];
1386   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1387   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1388   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1389     xor ((W3 shl 24) or (W3 shr 8))) xor Key[15];
1390   // round 8
1391   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1392   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1393   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1394     xor ((W3 shl 24) or (W3 shr 8))) xor Key[8];
1395   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1396   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1397   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1398     xor ((W3 shl 24) or (W3 shr 8))) xor Key[9];
1399   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1400   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1401   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1402     xor ((W3 shl 24) or (W3 shr 8))) xor Key[10];
1403   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1404   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1405   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1406     xor ((W3 shl 24) or (W3 shr 8))) xor Key[11];
1407   // round 9
1408   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1409   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1410   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1411     xor ((W3 shl 24) or (W3 shr 8))) xor Key[4];
1412   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1413   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1414   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1415     xor ((W3 shl 24) or (W3 shr 8))) xor Key[5];
1416   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1417   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1418   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1419     xor ((W3 shl 24) or (W3 shr 8))) xor Key[6];
1420   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1421   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1422   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1423     xor ((W3 shl 24) or (W3 shr 8))) xor Key[7];
1424   // last round of transformations
1425   W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)];
1426   W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)];
1427   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1428     xor ((W3 shl 24) or (W3 shr 8))) xor Key[0];
1429   W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)];
1430   W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)];
1431   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1432     xor ((W3 shl 24) or (W3 shr 8))) xor Key[1];
1433   W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)];
1434   W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)];
1435   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1436     xor ((W3 shl 24) or (W3 shr 8))) xor Key[2];
1437   W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)];
1438   W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)];
1439   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1440     xor ((W3 shl 24) or (W3 shr 8))) xor Key[3];
1441   // finalizing
1442   PLongWord(@OutBuf[0])^ := T0[0]; PLongWord(@OutBuf[4])^ := T0[1];
1443   PLongWord(@OutBuf[8])^ := T0[2]; PLongWord(@OutBuf[12])^ := T0[3];
1444 end;
1445 
1446 procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192;
1447   var OutBuf: TAESBuffer);
1448 var
1449   T0, T1: array [0..3] of longword;
1450   W0, W1, W2, W3: longword;
1451 begin
1452   // initializing
1453   T0[0] := PLongWord(@InBuf[0])^ xor Key[48];
1454   T0[1] := PLongWord(@InBuf[4])^ xor Key[49];
1455   T0[2] := PLongWord(@InBuf[8])^ xor Key[50];
1456   T0[3] := PLongWord(@InBuf[12])^ xor Key[51];
1457   // performing transformations 11 times
1458   // round 1
1459   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1460   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1461   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1462     xor ((W3 shl 24) or (W3 shr 8))) xor Key[44];
1463   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1464   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1465   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1466     xor ((W3 shl 24) or (W3 shr 8))) xor Key[45];
1467   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1468   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1469   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1470     xor ((W3 shl 24) or (W3 shr 8))) xor Key[46];
1471   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1472   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1473   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1474     xor ((W3 shl 24) or (W3 shr 8))) xor Key[47];
1475   // round 2
1476   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1477   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1478   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1479     xor ((W3 shl 24) or (W3 shr 8))) xor Key[40];
1480   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1481   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1482   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1483     xor ((W3 shl 24) or (W3 shr 8))) xor Key[41];
1484   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1485   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1486   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1487     xor ((W3 shl 24) or (W3 shr 8))) xor Key[42];
1488   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1489   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1490   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1491     xor ((W3 shl 24) or (W3 shr 8))) xor Key[43];
1492   // round 3
1493   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1494   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1495   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1496     xor ((W3 shl 24) or (W3 shr 8))) xor Key[36];
1497   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1498   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1499   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1500     xor ((W3 shl 24) or (W3 shr 8))) xor Key[37];
1501   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1502   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1503   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1504     xor ((W3 shl 24) or (W3 shr 8))) xor Key[38];
1505   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1506   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1507   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1508     xor ((W3 shl 24) or (W3 shr 8))) xor Key[39];
1509   // round 4
1510   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1511   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1512   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1513     xor ((W3 shl 24) or (W3 shr 8))) xor Key[32];
1514   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1515   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1516   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1517     xor ((W3 shl 24) or (W3 shr 8))) xor Key[33];
1518   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1519   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1520   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1521     xor ((W3 shl 24) or (W3 shr 8))) xor Key[34];
1522   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1523   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1524   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1525     xor ((W3 shl 24) or (W3 shr 8))) xor Key[35];
1526   // round 5
1527   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1528   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1529   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1530     xor ((W3 shl 24) or (W3 shr 8))) xor Key[28];
1531   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1532   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1533   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1534     xor ((W3 shl 24) or (W3 shr 8))) xor Key[29];
1535   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1536   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1537   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1538     xor ((W3 shl 24) or (W3 shr 8))) xor Key[30];
1539   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1540   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1541   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1542     xor ((W3 shl 24) or (W3 shr 8))) xor Key[31];
1543   // round 6
1544   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1545   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1546   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1547     xor ((W3 shl 24) or (W3 shr 8))) xor Key[24];
1548   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1549   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1550   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1551     xor ((W3 shl 24) or (W3 shr 8))) xor Key[25];
1552   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1553   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1554   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1555     xor ((W3 shl 24) or (W3 shr 8))) xor Key[26];
1556   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1557   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1558   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1559     xor ((W3 shl 24) or (W3 shr 8))) xor Key[27];
1560   // round 7
1561   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1562   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1563   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1564     xor ((W3 shl 24) or (W3 shr 8))) xor Key[20];
1565   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1566   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1567   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1568     xor ((W3 shl 24) or (W3 shr 8))) xor Key[21];
1569   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1570   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1571   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1572     xor ((W3 shl 24) or (W3 shr 8))) xor Key[22];
1573   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1574   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1575   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1576     xor ((W3 shl 24) or (W3 shr 8))) xor Key[23];
1577   // round 8
1578   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1579   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1580   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1581     xor ((W3 shl 24) or (W3 shr 8))) xor Key[16];
1582   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1583   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1584   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1585     xor ((W3 shl 24) or (W3 shr 8))) xor Key[17];
1586   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1587   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1588   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1589     xor ((W3 shl 24) or (W3 shr 8))) xor Key[18];
1590   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1591   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1592   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1593     xor ((W3 shl 24) or (W3 shr 8))) xor Key[19];
1594   // round 9
1595   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1596   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1597   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1598     xor ((W3 shl 24) or (W3 shr 8))) xor Key[12];
1599   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1600   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1601   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1602     xor ((W3 shl 24) or (W3 shr 8))) xor Key[13];
1603   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1604   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1605   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1606     xor ((W3 shl 24) or (W3 shr 8))) xor Key[14];
1607   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1608   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1609   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1610     xor ((W3 shl 24) or (W3 shr 8))) xor Key[15];
1611   // round 10
1612   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1613   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1614   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1615     xor ((W3 shl 24) or (W3 shr 8))) xor Key[8];
1616   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1617   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1618   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1619     xor ((W3 shl 24) or (W3 shr 8))) xor Key[9];
1620   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1621   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1622   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1623     xor ((W3 shl 24) or (W3 shr 8))) xor Key[10];
1624   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1625   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1626   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1627     xor ((W3 shl 24) or (W3 shr 8))) xor Key[11];
1628   // round 11
1629   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1630   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1631   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1632     xor ((W3 shl 24) or (W3 shr 8))) xor Key[4];
1633   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1634   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1635   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1636     xor ((W3 shl 24) or (W3 shr 8))) xor Key[5];
1637   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1638   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1639   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1640     xor ((W3 shl 24) or (W3 shr 8))) xor Key[6];
1641   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1642   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1643   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1644     xor ((W3 shl 24) or (W3 shr 8))) xor Key[7];
1645   // last round of transformations
1646   W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)];
1647   W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)];
1648   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1649     xor ((W3 shl 24) or (W3 shr 8))) xor Key[0];
1650   W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)];
1651   W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)];
1652   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1653     xor ((W3 shl 24) or (W3 shr 8))) xor Key[1];
1654   W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)];
1655   W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)];
1656   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1657     xor ((W3 shl 24) or (W3 shr 8))) xor Key[2];
1658   W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)];
1659   W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)];
1660   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1661     xor ((W3 shl 24) or (W3 shr 8))) xor Key[3];
1662   // finalizing
1663   PLongWord(@OutBuf[0])^ := T0[0]; PLongWord(@OutBuf[4])^ := T0[1];
1664   PLongWord(@OutBuf[8])^ := T0[2]; PLongWord(@OutBuf[12])^ := T0[3];
1665 end;
1666 
1667 procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256;
1668   var OutBuf: TAESBuffer);
1669 var
1670   T0, T1: array [0..3] of longword;
1671   W0, W1, W2, W3: longword;
1672 begin
1673   // initializing
1674   T0[0] := PLongWord(@InBuf[0])^ xor Key[56];
1675   T0[1] := PLongWord(@InBuf[4])^ xor Key[57];
1676   T0[2] := PLongWord(@InBuf[8])^ xor Key[58];
1677   T0[3] := PLongWord(@InBuf[12])^ xor Key[59];
1678   // performing transformations 13 times
1679   // round 1
1680   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1681   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1682   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1683     xor ((W3 shl 24) or (W3 shr 8))) xor Key[52];
1684   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1685   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1686   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1687     xor ((W3 shl 24) or (W3 shr 8))) xor Key[53];
1688   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1689   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1690   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1691     xor ((W3 shl 24) or (W3 shr 8))) xor Key[54];
1692   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1693   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1694   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1695     xor ((W3 shl 24) or (W3 shr 8))) xor Key[55];
1696   // round 2
1697   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1698   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1699   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1700     xor ((W3 shl 24) or (W3 shr 8))) xor Key[48];
1701   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1702   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1703   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1704     xor ((W3 shl 24) or (W3 shr 8))) xor Key[49];
1705   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1706   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1707   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1708     xor ((W3 shl 24) or (W3 shr 8))) xor Key[50];
1709   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1710   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1711   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1712     xor ((W3 shl 24) or (W3 shr 8))) xor Key[51];
1713   // round 3
1714   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1715   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1716   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1717     xor ((W3 shl 24) or (W3 shr 8))) xor Key[44];
1718   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1719   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1720   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1721     xor ((W3 shl 24) or (W3 shr 8))) xor Key[45];
1722   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1723   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1724   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1725     xor ((W3 shl 24) or (W3 shr 8))) xor Key[46];
1726   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1727   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1728   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1729     xor ((W3 shl 24) or (W3 shr 8))) xor Key[47];
1730   // round 4
1731   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1732   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1733   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1734     xor ((W3 shl 24) or (W3 shr 8))) xor Key[40];
1735   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1736   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1737   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1738     xor ((W3 shl 24) or (W3 shr 8))) xor Key[41];
1739   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1740   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1741   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1742     xor ((W3 shl 24) or (W3 shr 8))) xor Key[42];
1743   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1744   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1745   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1746     xor ((W3 shl 24) or (W3 shr 8))) xor Key[43];
1747   // round 5
1748   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1749   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1750   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1751     xor ((W3 shl 24) or (W3 shr 8))) xor Key[36];
1752   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1753   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1754   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1755     xor ((W3 shl 24) or (W3 shr 8))) xor Key[37];
1756   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1757   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1758   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1759     xor ((W3 shl 24) or (W3 shr 8))) xor Key[38];
1760   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1761   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1762   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1763     xor ((W3 shl 24) or (W3 shr 8))) xor Key[39];
1764   // round 6
1765   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1766   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1767   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1768     xor ((W3 shl 24) or (W3 shr 8))) xor Key[32];
1769   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1770   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1771   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1772     xor ((W3 shl 24) or (W3 shr 8))) xor Key[33];
1773   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1774   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1775   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1776     xor ((W3 shl 24) or (W3 shr 8))) xor Key[34];
1777   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1778   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1779   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1780     xor ((W3 shl 24) or (W3 shr 8))) xor Key[35];
1781   // round 7
1782   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1783   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1784   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1785     xor ((W3 shl 24) or (W3 shr 8))) xor Key[28];
1786   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1787   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1788   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1789     xor ((W3 shl 24) or (W3 shr 8))) xor Key[29];
1790   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1791   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1792   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1793     xor ((W3 shl 24) or (W3 shr 8))) xor Key[30];
1794   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1795   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1796   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1797     xor ((W3 shl 24) or (W3 shr 8))) xor Key[31];
1798   // round 8
1799   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1800   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1801   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1802     xor ((W3 shl 24) or (W3 shr 8))) xor Key[24];
1803   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1804   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1805   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1806     xor ((W3 shl 24) or (W3 shr 8))) xor Key[25];
1807   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1808   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1809   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1810     xor ((W3 shl 24) or (W3 shr 8))) xor Key[26];
1811   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1812   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1813   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1814     xor ((W3 shl 24) or (W3 shr 8))) xor Key[27];
1815   // round 9
1816   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1817   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1818   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1819     xor ((W3 shl 24) or (W3 shr 8))) xor Key[20];
1820   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1821   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1822   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1823     xor ((W3 shl 24) or (W3 shr 8))) xor Key[21];
1824   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1825   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1826   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1827     xor ((W3 shl 24) or (W3 shr 8))) xor Key[22];
1828   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1829   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1830   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1831     xor ((W3 shl 24) or (W3 shr 8))) xor Key[23];
1832   // round 10
1833   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1834   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1835   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1836     xor ((W3 shl 24) or (W3 shr 8))) xor Key[16];
1837   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1838   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1839   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1840     xor ((W3 shl 24) or (W3 shr 8))) xor Key[17];
1841   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1842   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1843   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1844     xor ((W3 shl 24) or (W3 shr 8))) xor Key[18];
1845   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1846   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1847   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1848     xor ((W3 shl 24) or (W3 shr 8))) xor Key[19];
1849   // round 11
1850   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1851   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1852   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1853     xor ((W3 shl 24) or (W3 shr 8))) xor Key[12];
1854   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1855   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1856   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1857     xor ((W3 shl 24) or (W3 shr 8))) xor Key[13];
1858   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1859   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1860   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1861     xor ((W3 shl 24) or (W3 shr 8))) xor Key[14];
1862   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1863   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1864   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1865     xor ((W3 shl 24) or (W3 shr 8))) xor Key[15];
1866   // round 12
1867   W0 := InverseTable[Byte(T1[0])]; W1 := InverseTable[Byte(T1[3] shr 8)];
1868   W2 := InverseTable[Byte(T1[2] shr 16)]; W3 := InverseTable[Byte(T1[1] shr 24)];
1869   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1870     xor ((W3 shl 24) or (W3 shr 8))) xor Key[8];
1871   W0 := InverseTable[Byte(T1[1])]; W1 := InverseTable[Byte(T1[0] shr 8)];
1872   W2 := InverseTable[Byte(T1[3] shr 16)]; W3 := InverseTable[Byte(T1[2] shr 24)];
1873   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1874     xor ((W3 shl 24) or (W3 shr 8))) xor Key[9];
1875   W0 := InverseTable[Byte(T1[2])]; W1 := InverseTable[Byte(T1[1] shr 8)];
1876   W2 := InverseTable[Byte(T1[0] shr 16)]; W3 := InverseTable[Byte(T1[3] shr 24)];
1877   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1878     xor ((W3 shl 24) or (W3 shr 8))) xor Key[10];
1879   W0 := InverseTable[Byte(T1[3])]; W1 := InverseTable[Byte(T1[2] shr 8)];
1880   W2 := InverseTable[Byte(T1[1] shr 16)]; W3 := InverseTable[Byte(T1[0] shr 24)];
1881   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1882     xor ((W3 shl 24) or (W3 shr 8))) xor Key[11];
1883   // round 13
1884   W0 := InverseTable[Byte(T0[0])]; W1 := InverseTable[Byte(T0[3] shr 8)];
1885   W2 := InverseTable[Byte(T0[2] shr 16)]; W3 := InverseTable[Byte(T0[1] shr 24)];
1886   T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1887     xor ((W3 shl 24) or (W3 shr 8))) xor Key[4];
1888   W0 := InverseTable[Byte(T0[1])]; W1 := InverseTable[Byte(T0[0] shr 8)];
1889   W2 := InverseTable[Byte(T0[3] shr 16)]; W3 := InverseTable[Byte(T0[2] shr 24)];
1890   T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1891     xor ((W3 shl 24) or (W3 shr 8))) xor Key[5];
1892   W0 := InverseTable[Byte(T0[2])]; W1 := InverseTable[Byte(T0[1] shr 8)];
1893   W2 := InverseTable[Byte(T0[0] shr 16)]; W3 := InverseTable[Byte(T0[3] shr 24)];
1894   T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1895     xor ((W3 shl 24) or (W3 shr 8))) xor Key[6];
1896   W0 := InverseTable[Byte(T0[3])]; W1 := InverseTable[Byte(T0[2] shr 8)];
1897   W2 := InverseTable[Byte(T0[1] shr 16)]; W3 := InverseTable[Byte(T0[0] shr 24)];
1898   T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1899     xor ((W3 shl 24) or (W3 shr 8))) xor Key[7];
1900   // last round of transformations
1901   W0 := LastInverseTable[Byte(T1[0])]; W1 := LastInverseTable[Byte(T1[3] shr 8)];
1902   W2 := LastInverseTable[Byte(T1[2] shr 16)]; W3 := LastInverseTable[Byte(T1[1] shr 24)];
1903   T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1904     xor ((W3 shl 24) or (W3 shr 8))) xor Key[0];
1905   W0 := LastInverseTable[Byte(T1[1])]; W1 := LastInverseTable[Byte(T1[0] shr 8)];
1906   W2 := LastInverseTable[Byte(T1[3] shr 16)]; W3 := LastInverseTable[Byte(T1[2] shr 24)];
1907   T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1908     xor ((W3 shl 24) or (W3 shr 8))) xor Key[1];
1909   W0 := LastInverseTable[Byte(T1[2])]; W1 := LastInverseTable[Byte(T1[1] shr 8)];
1910   W2 := LastInverseTable[Byte(T1[0] shr 16)]; W3 := LastInverseTable[Byte(T1[3] shr 24)];
1911   T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1912     xor ((W3 shl 24) or (W3 shr 8))) xor Key[2];
1913   W0 := LastInverseTable[Byte(T1[3])]; W1 := LastInverseTable[Byte(T1[2] shr 8)];
1914   W2 := LastInverseTable[Byte(T1[1] shr 16)]; W3 := LastInverseTable[Byte(T1[0] shr 24)];
1915   T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
1916     xor ((W3 shl 24) or (W3 shr 8))) xor Key[3];
1917   // finalizing
1918   PLongWord(@OutBuf[0])^ := T0[0]; PLongWord(@OutBuf[4])^ := T0[1];
1919   PLongWord(@OutBuf[8])^ := T0[2]; PLongWord(@OutBuf[12])^ := T0[3];
1920 end;
1921 
1922 // Stream encryption routines (ECB mode)
1923 
1924 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
1925   const Key: TAESKey128; Dest: TStream);
1926 var
1927   ExpandedKey: TAESExpandedKey128;
1928 begin
1929   ExpandAESKeyForEncryption(Key, ExpandedKey);
1930   EncryptAESStreamECB(Source, Count, ExpandedKey, Dest);
1931 end;
1932 
1933 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
1934   const Key: TAESKey192; Dest: TStream);
1935 var
1936   ExpandedKey: TAESExpandedKey192;
1937 begin
1938   ExpandAESKeyForEncryption(Key, ExpandedKey);
1939   EncryptAESStreamECB(Source, Count, ExpandedKey, Dest);
1940 end;
1941 
1942 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
1943   const Key: TAESKey256; Dest: TStream);
1944 var
1945   ExpandedKey: TAESExpandedKey256;
1946 begin
1947   ExpandAESKeyForEncryption(Key, ExpandedKey);
1948   EncryptAESStreamECB(Source, Count, ExpandedKey, Dest);
1949 end;
1950 
1951 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
1952   const ExpandedKey: TAESExpandedKey128; Dest: TStream);
1953 var
1954   TempIn, TempOut: TAESBuffer;
1955   Done: cardinal;
1956 begin
1957   if Count = 0 then
1958   begin
1959     Source.Position := 0;
1960     Count := Source.Size;
1961   end
1962   else Count := Min(Count, Source.Size - Source.Position);
1963   if Count = 0 then exit;
1964   while Count >= SizeOf(TAESBuffer) do
1965   begin
1966     Done := Source.Read(TempIn, SizeOf(TempIn));
1967     if Done < SizeOf(TempIn) then
1968       raise EStreamError.Create(SReadError);
1969     EncryptAES(TempIn, ExpandedKey, TempOut);
1970     Done := Dest.Write(TempOut, SizeOf(TempOut));
1971     if Done < SizeOf(TempOut) then
1972       raise EStreamError.Create(SWriteError);
1973     Dec(Count, SizeOf(TAESBuffer));
1974   end;
1975   if Count > 0 then
1976   begin
1977     Done := Source.Read(TempIn, Count);
1978     if Done < Count then
1979       raise EStreamError.Create(SReadError);
1980     FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0);
1981     EncryptAES(TempIn, ExpandedKey, TempOut);
1982     Done := Dest.Write(TempOut, SizeOf(TempOut));
1983     if Done < SizeOf(TempOut) then
1984       raise EStreamError.Create(SWriteError);
1985   end;
1986 end;
1987 
1988 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
1989   const ExpandedKey: TAESExpandedKey192; Dest: TStream);
1990 var
1991   TempIn, TempOut: TAESBuffer;
1992   Done: cardinal;
1993 begin
1994   if Count = 0 then
1995   begin
1996     Source.Position := 0;
1997     Count := Source.Size;
1998   end
1999   else Count := Min(Count, Source.Size - Source.Position);
2000   if Count = 0 then exit;
2001   while Count >= SizeOf(TAESBuffer) do
2002   begin
2003     Done := Source.Read(TempIn, SizeOf(TempIn));
2004     if Done < SizeOf(TempIn) then
2005       raise EStreamError.Create(SReadError);
2006     EncryptAES(TempIn, ExpandedKey, TempOut);
2007     Done := Dest.Write(TempOut, SizeOf(TempOut));
2008     if Done < SizeOf(TempOut) then
2009       raise EStreamError.Create(SWriteError);
2010     Dec(Count, SizeOf(TAESBuffer));
2011   end;
2012   if Count > 0 then
2013   begin
2014     Done := Source.Read(TempIn, Count);
2015     if Done < Count then
2016       raise EStreamError.Create(SReadError);
2017     FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0);
2018     EncryptAES(TempIn, ExpandedKey, TempOut);
2019     Done := Dest.Write(TempOut, SizeOf(TempOut));
2020     if Done < SizeOf(TempOut) then
2021       raise EStreamError.Create(SWriteError);
2022   end;
2023 end;
2024 
2025 procedure EncryptAESStreamECB(Source: TStream; Count: cardinal;
2026   const ExpandedKey: TAESExpandedKey256; Dest: TStream);
2027 var
2028   TempIn, TempOut: TAESBuffer;
2029   Done: cardinal;
2030 begin
2031   if Count = 0 then
2032   begin
2033     Source.Position := 0;
2034     Count := Source.Size;
2035   end
2036   else Count := Min(Count, Source.Size - Source.Position);
2037   if Count = 0 then exit;
2038   while Count >= SizeOf(TAESBuffer) do
2039   begin
2040     Done := Source.Read(TempIn, SizeOf(TempIn));
2041     if Done < SizeOf(TempIn) then
2042       raise EStreamError.Create(SReadError);
2043     EncryptAES(TempIn, ExpandedKey, TempOut);
2044     Done := Dest.Write(TempOut, SizeOf(TempOut));
2045     if Done < SizeOf(TempOut) then
2046       raise EStreamError.Create(SWriteError);
2047     Dec(Count, SizeOf(TAESBuffer));
2048   end;
2049   if Count > 0 then
2050   begin
2051     Done := Source.Read(TempIn, Count);
2052     if Done < Count then
2053       raise EStreamError.Create(SReadError);
2054     FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0);
2055     EncryptAES(TempIn, ExpandedKey, TempOut);
2056     Done := Dest.Write(TempOut, SizeOf(TempOut));
2057     if Done < SizeOf(TempOut) then
2058       raise EStreamError.Create(SWriteError);
2059   end;
2060 end;
2061 
2062 // Stream decryption routines (ECB mode)
2063 
2064 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
2065   const Key: TAESKey128; Dest: TStream);
2066 var
2067   ExpandedKey: TAESExpandedKey128;
2068 begin
2069   ExpandAESKeyForDecryption(Key, ExpandedKey);
2070   DecryptAESStreamECB(Source, Count, ExpandedKey, Dest);
2071 end;
2072 
2073 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
2074   const ExpandedKey: TAESExpandedKey128; Dest: TStream);
2075 var
2076   TempIn, TempOut: TAESBuffer;
2077   Done: cardinal;
2078 begin
2079   if Count = 0 then
2080   begin
2081     Source.Position := 0;
2082     Count := Source.Size;
2083   end
2084   else Count := Min(Count, Source.Size - Source.Position);
2085   if Count = 0 then exit;
2086   if (Count mod SizeOf(TAESBuffer)) > 0 then
2087     raise EAESError.Create(SInvalidInBufSize);
2088   while Count >= SizeOf(TAESBuffer) do
2089   begin
2090     Done := Source.Read(TempIn, SizeOf(TempIn));
2091     if Done < SizeOf(TempIn) then
2092       raise EStreamError.Create(SReadError);
2093     DecryptAES(TempIn, ExpandedKey, TempOut);
2094     Done := Dest.Write(TempOut, SizeOf(TempOut));
2095     if Done < SizeOf(TempOut) then
2096       raise EStreamError.Create(SWriteError);
2097     Dec(Count, SizeOf(TAESBuffer));
2098   end;
2099 end;
2100 
2101 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
2102   const Key: TAESKey192; Dest: TStream);
2103 var
2104   ExpandedKey: TAESExpandedKey192;
2105 begin
2106   ExpandAESKeyForDecryption(Key, ExpandedKey);
2107   DecryptAESStreamECB(Source, Count, ExpandedKey, Dest);
2108 end;
2109 
2110 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
2111   const ExpandedKey: TAESExpandedKey192; Dest: TStream);
2112 var
2113   TempIn, TempOut: TAESBuffer;
2114   Done: cardinal;
2115 begin
2116   if Count = 0 then
2117   begin
2118     Source.Position := 0;
2119     Count := Source.Size;
2120   end
2121   else Count := Min(Count, Source.Size - Source.Position);
2122   if Count = 0 then exit;
2123   if (Count mod SizeOf(TAESBuffer)) > 0 then
2124     raise EAESError.Create(SInvalidInBufSize);
2125   while Count >= SizeOf(TAESBuffer) do
2126   begin
2127     Done := Source.Read(TempIn, SizeOf(TempIn));
2128     if Done < SizeOf(TempIn) then
2129       raise EStreamError.Create(SReadError);
2130     DecryptAES(TempIn, ExpandedKey, TempOut);
2131     Done := Dest.Write(TempOut, SizeOf(TempOut));
2132     if Done < SizeOf(TempOut) then
2133       raise EStreamError.Create(SWriteError);
2134     Dec(Count, SizeOf(TAESBuffer));
2135   end;
2136 end;
2137 
2138 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
2139   const Key: TAESKey256; Dest: TStream);
2140 var
2141   ExpandedKey: TAESExpandedKey256;
2142 begin
2143   ExpandAESKeyForDecryption(Key, ExpandedKey);
2144   DecryptAESStreamECB(Source, Count, ExpandedKey, Dest);
2145 end;
2146 
2147 procedure DecryptAESStreamECB(Source: TStream; Count: cardinal;
2148   const ExpandedKey: TAESExpandedKey256; Dest: TStream);
2149 var
2150   TempIn, TempOut: TAESBuffer;
2151   Done: cardinal;
2152 begin
2153   if Count = 0 then
2154   begin
2155     Source.Position := 0;
2156     Count := Source.Size;
2157   end
2158   else Count := Min(Count, Source.Size - Source.Position);
2159   if Count = 0 then exit;
2160   if (Count mod SizeOf(TAESBuffer)) > 0 then
2161     raise EAESError.Create(SInvalidInBufSize);
2162   while Count >= SizeOf(TAESBuffer) do
2163   begin
2164     Done := Source.Read(TempIn, SizeOf(TempIn));
2165     if Done < SizeOf(TempIn) then
2166       raise EStreamError.Create(SReadError);
2167     DecryptAES(TempIn, ExpandedKey, TempOut);
2168     Done := Dest.Write(TempOut, SizeOf(TempOut));
2169     if Done < SizeOf(TempOut) then
2170       raise EStreamError.Create(SWriteError);
2171     Dec(Count, SizeOf(TAESBuffer));
2172   end;
2173 end;
2174 
2175 // Stream encryption routines (CBC mode)
2176 
2177 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
2178   const Key: TAESKey128; const InitVector: TAESBuffer; Dest: TStream);
2179 var
2180   ExpandedKey: TAESExpandedKey128;
2181 begin
2182   ExpandAESKeyForEncryption(Key, ExpandedKey);
2183   EncryptAESStreamCBC(Source, Count, ExpandedKey, InitVector, Dest);
2184 end;
2185 
2186 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
2187   const ExpandedKey: TAESExpandedKey128;  const InitVector: TAESBuffer;
2188   Dest: TStream);
2189 var
2190   TempIn, TempOut, Vector: TAESBuffer;
2191   Done: cardinal;
2192 begin
2193   if Count = 0 then
2194   begin
2195     Source.Position := 0;
2196     Count := Source.Size;
2197   end
2198   else Count := Min(Count, Source.Size - Source.Position);
2199   if Count = 0 then exit;
2200   Vector := InitVector;
2201   while Count >= SizeOf(TAESBuffer) do
2202   begin
2203     Done := Source.Read(TempIn, SizeOf(TempIn));
2204     if Done < SizeOf(TempIn) then
2205       raise EStreamError.Create(SReadError);
2206     PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
2207     PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
2208     PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
2209     PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;
2210     EncryptAES(TempIn, ExpandedKey, TempOut);
2211     Done := Dest.Write(TempOut, SizeOf(TempOut));
2212     if Done < SizeOf(TempOut) then
2213       raise EStreamError.Create(SWriteError);
2214     Vector := TempOut;
2215     Dec(Count, SizeOf(TAESBuffer));
2216   end;
2217   if Count > 0 then
2218   begin
2219     Done := Source.Read(TempIn, Count);
2220     if Done < Count then
2221       raise EStreamError.Create(SReadError);
2222     FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0);
2223     PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
2224     PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
2225     PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
2226     PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;
2227     EncryptAES(TempIn, ExpandedKey, TempOut);
2228     Done := Dest.Write(TempOut, SizeOf(TempOut));
2229     if Done < SizeOf(TempOut) then
2230       raise EStreamError.Create(SWriteError);
2231   end;
2232 end;
2233 
2234 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
2235   const Key: TAESKey192; const InitVector: TAESBuffer; Dest: TStream);
2236 var
2237   ExpandedKey: TAESExpandedKey192;
2238 begin
2239   ExpandAESKeyForEncryption(Key, ExpandedKey);
2240   EncryptAESStreamCBC(Source, Count, ExpandedKey, InitVector, Dest);
2241 end;
2242 
2243 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
2244   const ExpandedKey: TAESExpandedKey192;  const InitVector: TAESBuffer;
2245   Dest: TStream);
2246 var
2247   TempIn, TempOut, Vector: TAESBuffer;
2248   Done: cardinal;
2249 begin
2250   if Count = 0 then
2251   begin
2252     Source.Position := 0;
2253     Count := Source.Size;
2254   end
2255   else Count := Min(Count, Source.Size - Source.Position);
2256   if Count = 0 then exit;
2257   Vector := InitVector;
2258   while Count >= SizeOf(TAESBuffer) do
2259   begin
2260     Done := Source.Read(TempIn, SizeOf(TempIn));
2261     if Done < SizeOf(TempIn) then
2262       raise EStreamError.Create(SReadError);
2263     PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
2264     PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
2265     PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
2266     PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;
2267     EncryptAES(TempIn, ExpandedKey, TempOut);
2268     Done := Dest.Write(TempOut, SizeOf(TempOut));
2269     if Done < SizeOf(TempOut) then
2270       raise EStreamError.Create(SWriteError);
2271     Vector := TempOut;
2272     Dec(Count, SizeOf(TAESBuffer));
2273   end;
2274   if Count > 0 then
2275   begin
2276     Done := Source.Read(TempIn, Count);
2277     if Done < Count then
2278       raise EStreamError.Create(SReadError);
2279     FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0);
2280     PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
2281     PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
2282     PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
2283     PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;
2284     EncryptAES(TempIn, ExpandedKey, TempOut);
2285     Done := Dest.Write(TempOut, SizeOf(TempOut));
2286     if Done < SizeOf(TempOut) then
2287       raise EStreamError.Create(SWriteError);
2288   end;
2289 end;
2290 
2291 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
2292   const Key: TAESKey256; const InitVector: TAESBuffer; Dest: TStream);
2293 var
2294   ExpandedKey: TAESExpandedKey256;
2295 begin
2296   ExpandAESKeyForEncryption(Key, ExpandedKey);
2297   EncryptAESStreamCBC(Source, Count, ExpandedKey, InitVector, Dest);
2298 end;
2299 
2300 procedure EncryptAESStreamCBC(Source: TStream; Count: cardinal;
2301   const ExpandedKey: TAESExpandedKey256;  const InitVector: TAESBuffer;
2302   Dest: TStream);
2303 var
2304   TempIn, TempOut, Vector: TAESBuffer;
2305   Done: cardinal;
2306 begin
2307   if Count = 0 then
2308   begin
2309     Source.Position := 0;
2310     Count := Source.Size;
2311   end
2312   else Count := Min(Count, Source.Size - Source.Position);
2313   if Count = 0 then exit;
2314   Vector := InitVector;
2315   while Count >= SizeOf(TAESBuffer) do
2316   begin
2317     Done := Source.Read(TempIn, SizeOf(TempIn));
2318     if Done < SizeOf(TempIn) then
2319       raise EStreamError.Create(SReadError);
2320     PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
2321     PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
2322     PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
2323     PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;
2324     EncryptAES(TempIn, ExpandedKey, TempOut);
2325     Done := Dest.Write(TempOut, SizeOf(TempOut));
2326     if Done < SizeOf(TempOut) then
2327       raise EStreamError.Create(SWriteError);
2328     Vector := TempOut;
2329     Dec(Count, SizeOf(TAESBuffer));
2330   end;
2331   if Count > 0 then
2332   begin
2333     Done := Source.Read(TempIn, Count);
2334     if Done < Count then
2335       raise EStreamError.Create(SReadError);
2336     FillChar(TempIn[Count], SizeOf(TempIn) - Count, 0);
2337     PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
2338     PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
2339     PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
2340     PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;
2341     EncryptAES(TempIn, ExpandedKey, TempOut);
2342     Done := Dest.Write(TempOut, SizeOf(TempOut));
2343     if Done < SizeOf(TempOut) then
2344       raise EStreamError.Create(SWriteError);
2345   end;
2346 end;
2347 
2348 // Stream decryption routines (CBC mode)
2349 
2350 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
2351   const Key: TAESKey128; const InitVector: TAESBuffer; Dest: TStream);
2352 var
2353   ExpandedKey: TAESExpandedKey128;
2354 begin
2355   ExpandAESKeyForDecryption(Key, ExpandedKey);
2356   DecryptAESStreamCBC(Source, Count, ExpandedKey, InitVector, Dest);
2357 end;
2358 
2359 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
2360   const ExpandedKey: TAESExpandedKey128;  const InitVector: TAESBuffer;
2361   Dest: TStream);
2362 var
2363   TempIn, TempOut: TAESBuffer;
2364   Vector1, Vector2: TAESBuffer;
2365   Done: cardinal;
2366 begin
2367   if Count = 0 then
2368   begin
2369     Source.Position := 0;
2370     Count := Source.Size;
2371   end
2372   else Count := Min(Count, Source.Size - Source.Position);
2373   if Count = 0 then exit;
2374   if (Count mod SizeOf(TAESBuffer)) > 0 then
2375     raise EAESError.Create(SInvalidInBufSize);
2376   Vector1 := InitVector;
2377   while Count >= SizeOf(TAESBuffer) do
2378   begin
2379     Done := Source.Read(TempIn, SizeOf(TempIn));
2380     if Done < SizeOf(TempIn) then
2381       raise EStreamError(SReadError);
2382     Vector2 := TempIn;
2383     DecryptAES(TempIn, ExpandedKey, TempOut);
2384     PLongWord(@TempOut[0])^ := PLongWord(@TempOut[0])^ xor PLongWord(@Vector1[0])^;
2385     PLongWord(@TempOut[4])^ := PLongWord(@TempOut[4])^ xor PLongWord(@Vector1[4])^;
2386     PLongWord(@TempOut[8])^ := PLongWord(@TempOut[8])^ xor PLongWord(@Vector1[8])^;
2387     PLongWord(@TempOut[12])^ := PLongWord(@TempOut[12])^ xor PLongWord(@Vector1[12])^;
2388     Done := Dest.Write(TempOut, SizeOf(TempOut));
2389     if Done < SizeOf(TempOut) then
2390       raise EStreamError(SWriteError);
2391     Vector1 := Vector2;
2392     Dec(Count, SizeOf(TAESBuffer));
2393   end;
2394 end;
2395 
2396 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
2397   const Key: TAESKey192; const InitVector: TAESBuffer; Dest: TStream);
2398 var
2399   ExpandedKey: TAESExpandedKey192;
2400 begin
2401   ExpandAESKeyForDecryption(Key, ExpandedKey);
2402   DecryptAESStreamCBC(Source, Count, ExpandedKey, InitVector, Dest);
2403 end;
2404 
2405 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
2406   const ExpandedKey: TAESExpandedKey192;  const InitVector: TAESBuffer;
2407   Dest: TStream);
2408 var
2409   TempIn, TempOut: TAESBuffer;
2410   Vector1, Vector2: TAESBuffer;
2411   Done: cardinal;
2412 begin
2413   if Count = 0 then
2414   begin
2415     Source.Position := 0;
2416     Count := Source.Size;
2417   end
2418   else Count := Min(Count, Source.Size - Source.Position);
2419   if Count = 0 then exit;
2420   if (Count mod SizeOf(TAESBuffer)) > 0 then
2421     raise EAESError.Create(SInvalidInBufSize);
2422   Vector1 := InitVector;
2423   while Count >= SizeOf(TAESBuffer) do
2424   begin
2425     Done := Source.Read(TempIn, SizeOf(TempIn));
2426     if Done < SizeOf(TempIn) then
2427       raise EStreamError(SReadError);
2428     Vector2 := TempIn;
2429     DecryptAES(TempIn, ExpandedKey, TempOut);
2430     PLongWord(@TempOut[0])^ := PLongWord(@TempOut[0])^ xor PLongWord(@Vector1[0])^;
2431     PLongWord(@TempOut[4])^ := PLongWord(@TempOut[4])^ xor PLongWord(@Vector1[4])^;
2432     PLongWord(@TempOut[8])^ := PLongWord(@TempOut[8])^ xor PLongWord(@Vector1[8])^;
2433     PLongWord(@TempOut[12])^ := PLongWord(@TempOut[12])^ xor PLongWord(@Vector1[12])^;
2434     Done := Dest.Write(TempOut, SizeOf(TempOut));
2435     if Done < SizeOf(TempOut) then
2436       raise EStreamError(SWriteError);
2437     Vector1 := Vector2;
2438     Dec(Count, SizeOf(TAESBuffer));
2439   end;
2440 end;
2441 
2442 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
2443   const Key: TAESKey256; const InitVector: TAESBuffer; Dest: TStream);
2444 var
2445   ExpandedKey: TAESExpandedKey256;
2446 begin
2447   ExpandAESKeyForDecryption(Key, ExpandedKey);
2448   DecryptAESStreamCBC(Source, Count, ExpandedKey, InitVector, Dest);
2449 end;
2450 
2451 procedure DecryptAESStreamCBC(Source: TStream; Count: cardinal;
2452   const ExpandedKey: TAESExpandedKey256;  const InitVector: TAESBuffer;
2453   Dest: TStream);
2454 var
2455   TempIn, TempOut: TAESBuffer;
2456   Vector1, Vector2: TAESBuffer;
2457   Done: cardinal;
2458 begin
2459   if Count = 0 then
2460   begin
2461     Source.Position := 0;
2462     Count := Source.Size;
2463   end
2464   else Count := Min(Count, Source.Size - Source.Position);
2465   if Count = 0 then exit;
2466   if (Count mod SizeOf(TAESBuffer)) > 0 then
2467     raise EAESError.Create(SInvalidInBufSize);
2468   Vector1 := InitVector;
2469   while Count >= SizeOf(TAESBuffer) do
2470   begin
2471     Done := Source.Read(TempIn, SizeOf(TempIn));
2472     if Done < SizeOf(TempIn) then
2473       raise EStreamError(SReadError);
2474     Vector2 := TempIn;
2475     DecryptAES(TempIn, ExpandedKey, TempOut);
2476     PLongWord(@TempOut[0])^ := PLongWord(@TempOut[0])^ xor PLongWord(@Vector1[0])^;
2477     PLongWord(@TempOut[4])^ := PLongWord(@TempOut[4])^ xor PLongWord(@Vector1[4])^;
2478     PLongWord(@TempOut[8])^ := PLongWord(@TempOut[8])^ xor PLongWord(@Vector1[8])^;
2479     PLongWord(@TempOut[12])^ := PLongWord(@TempOut[12])^ xor PLongWord(@Vector1[12])^;
2480     Done := Dest.Write(TempOut, SizeOf(TempOut));
2481     if Done < SizeOf(TempOut) then
2482       raise EStreamError(SWriteError);
2483     Vector1 := Vector2;
2484     Dec(Count, SizeOf(TAESBuffer));
2485   end;
2486 end;
2487 
2488 end.
ElAES.pas单元文件

function EncryptString(Value: string; Key: string;KeyBit: TKeyBit = kb128): string; //加密
function DecryptString(Value: string; Key: string;KeyBit: TKeyBit = kb128): string;//解密

Pub_SysDBConStr := DecryptString( Trim(Pub_IniFile.ReadString(‘Setup‘, ‘SysDB‘, ‘‘)), Pub_SVR_EncryptionConnectionKey, kb256 );//例子

可逆加密解密单元文件和调用方法

标签:

原文地址:http://www.cnblogs.com/rogge7/p/4415175.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!