DELPHI 语言AES CBC模式加解密数据实现

 在多可文档系统中文件接口需要和其他系统实现用户统一登录,其他数据加密传输,要保障算法和数据的一致性    对系统接口使用有很大帮助。系统选择使用AES加密算法的CBC模式(128位密钥),实现各系统间加密数据的传输。多可提供各种语言的算法实现,以下是DELPHI 语言的具体算法实现(其他语言参考博主相关文章):
   加解密文本用16进制字符串表示,如果您需要base64编码请修改编码和解密部分即可。

(* ************************************************ *)
 AES 加解密单元
(* ************************************************ *)

unit ElAES;

interface

uses
    SysUtils, Windows, Classes;

resourcestring
    SInvalidInBufSize = 'Wrong decrypting data block';
    // 'Invalid buffer size for decryption';
    SReadError = 'Data read error';
    SWriteError = 'Data write error';
    SDecryptError = 'Data error while decrypting';
    SHeadInfoError = 'Data error while decrypting';
    SPassWordEffError = 'Secret password verification error';

type
    EAESError = class(Exception);

    PInteger = ^Integer;
    PLongWord = ^longword;

    TAESBuffer = array [0 .. 15] of Byte;
    TAESKey128 = array [0 .. 15] of Byte;
    TAESKey192 = array [0 .. 23] of Byte;
    TAESKey256 = array [0 .. 31] of Byte;
    TAESExpandedKey128 = array [0 .. 43] of longword;
    TAESExpandedKey192 = array [0 .. 53] of longword;
    TAESExpandedKey256 = array [0 .. 63] of longword;

    PAESBuffer = ^TAESBuffer;
    PAESKey128 = ^TAESKey128;
    PAESKey192 = ^TAESKey192;
    PAESKey256 = ^TAESKey256;
    PAESExpandedKey128 = ^TAESExpandedKey128;
    PAESExpandedKey192 = ^TAESExpandedKey192;
    PAESExpandedKey256 = ^TAESExpandedKey256;

    TKeyBit = (KB128 = 1, KB192 = 2, KB256 = 3, KB512 = 7, KB1024 = 15);

    TDoAesBuffer = procedure(Obj: TObject; const Buffer; const BufferLen: Longint) of object;
    TDoReadAesBuffer = procedure(Obj: TObject; var Buffer; var BufferLen: Longint) of object;

    TAES = class(TObject)
    private
        // FKeyType: TKeyBit;

        function Min(A, B: Integer): Integer;
        function StrToHex(Value: Ansistring): string;
        function HexToStr(Value: string): Ansistring;
        // function GetEff(S: string): Word;

        // Key expansion routines for encryption
        procedure ExpandAESKeyForEncryption(const Key: TAESKey128; var ExpandedKey: TAESExpandedKey128); overload;
        procedure ExpandAESKeyForEncryption(const Key: TAESKey192; var ExpandedKey: TAESExpandedKey192); overload;
        procedure ExpandAESKeyForEncryption(const Key: TAESKey256; var ExpandedKey: TAESExpandedKey256); overload;

        // Block encryption routines
        procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128; var OutBuf: TAESBuffer); overload;
        procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192; var OutBuf: TAESBuffer); overload;
        procedure EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256; var OutBuf: TAESBuffer); overload;

        // Key transformation routines for decryption
        procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey128); overload;
        procedure ExpandAESKeyForDecryption(const Key: TAESKey128; var ExpandedKey: TAESExpandedKey128); overload;

        procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey192); overload;
        procedure ExpandAESKeyForDecryption(const Key: TAESKey192; var ExpandedKey: TAESExpandedKey192); overload;

        procedure ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey256); overload;
        procedure ExpandAESKeyForDecryption(const Key: TAESKey256; var ExpandedKey: TAESExpandedKey256); overload;

        procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128; var OutBuf: TAESBuffer); overload;
        procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192; var OutBuf: TAESBuffer); overload;
        procedure DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256; var OutBuf: TAESBuffer); overload;

        procedure FormatKey_Encrypt(const Key: Ansistring; const KeyBit: TKeyBit; AESKey128: TAESKey128;
          AESKey192: TAESKey192; AESKey256: TAESKey256; var ExpandedKey128: TAESExpandedKey128;
          var ExpandedKey192: TAESExpandedKey192; var ExpandedKey256: TAESExpandedKey256);
        procedure FormatKey_Decrypt(const Key: Ansistring; const KeyBit: TKeyBit; AESKey128: TAESKey128;
          AESKey192: TAESKey192; AESKey256: TAESKey256; var ExpandedKey128: TAESExpandedKey128;
          var ExpandedKey192: TAESExpandedKey192; var ExpandedKey256: TAESExpandedKey256);
    public
        procedure AfterConstruction(); override;

        // 流加解密
        procedure EncryptAESStreamCBC(Source, Dest: TStream; Count: Int64; const InitVector: TAESBuffer;
          Key: Ansistring; KeyBit: TKeyBit = KB128);
        procedure DecryptAESStreamCBC(Source, Dest: TStream; Count: Int64; const InitVector: TAESBuffer;
          Key: Ansistring; KeyBit: TKeyBit = KB128);

    end;

    // IsUtf8Encode 是否对输入字符串进行 Utf8 转码
function EncryptStr_CBC(Value, Key: string; InitVector: TAESBuffer; KeyBit: TKeyBit = KB256;
  IsUtf8Encode: Boolean = False): string;
function DecryptStr_CBC(Value, Key: string; InitVector: TAESBuffer; KeyBit: TKeyBit = KB256;
  IsUtf8Decode: Boolean = False): string;

implementation

const
    // 版本号
    AesEdition_1_0 = 1;

    Rcon: array [1 .. 30] of longword = ($00000001, $00000002, $00000004, $00000008, $00000010, $00000020, $00000040,
      $00000080, $0000001B, $00000036, $0000006C, $000000D8, $000000AB, $0000004D, $0000009A, $0000002F, $0000005E,
      $000000BC, $00000063, $000000C6, $00000097, $00000035, $0000006A, $000000D4, $000000B3, $0000007D, $000000FA,
      $000000EF, $000000C5, $00000091);

    ForwardTable: array [0 .. 255] of longword = ($A56363C6, $847C7CF8, $997777EE, $8D7B7BF6, $0DF2F2FF, $BD6B6BD6,
      $B16F6FDE, $54C5C591, $50303060, $03010102, $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D, $9A7676EC,
      $45CACA8F, $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF, $EB5959B2, $C947478E, $0BF0F0FB, $ECADAD41, $67D4D4B3,
      $FDA2A25F, $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4, $5BC0C09B, $C2B7B775, $1CFDFDE1, $AE93933D, $6A26264C,
      $5A36366C, $413F3F7E, $02F7F7F5, $4FCCCC83, $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2, $73D8D8AB,
      $53313162, $3F15152A, $0C040408, $52C7C795, $65232346, $5EC3C39D, $28181830, $A1969637, $0F05050A, $B59A9A2F,
      $0907070E, $36121224, $9B80801B, $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F, $9F7575EA, $1B090912, $9E83831D,
      $742C2C58, $2E1A1A34, $2D1B1B36, $B26E6EDC, $EE5A5AB4, $FBA0A05B, $F65252A4, $4D3B3B76, $61D6D6B7, $CEB3B37D,
      $7B292952, $3EE3E3DD, $712F2F5E, $97848413, $F55353A6, $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3,
      $C8B1B179, $ED5B5BB6, $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94, $D44C4C98, $E85858B0, $4ACFCF85,
      $6BD0D0BB, $2AEFEFC5, $E5AAAA4F, $16FBFBED, $C5434386, $D74D4D9A, $55333366, $94858511, $CF45458A, $10F9F9E9,
      $06020204, $817F7FFE, $F05050A0, $443C3C78, $BA9F9F25, $E3A8A84B, $F35151A2, $FEA3A35D, $C0404080, $8A8F8F05,
      $AD92923F, $BC9D9D21, $48383870, $04F5F5F1, $DFBCBC63, $C1B6B677, $75DADAAF, $63212142, $30101020, $1AFFFFE5,
      $0EF3F3FD, $6DD2D2BF, $4CCDCD81, $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488, $3917172E,
      $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8, $E75D5DBA, $2B191932, $957373E6, $A06060C0, $98818119,
      $D14F4F9E, $7FDCDCA3, $66222244, $7E2A2A54, $AB90903B, $8388880B, $CA46468C, $29EEEEC7, $D3B8B86B, $3C141428,
      $79DEDEA7, $E25E5EBC, $1D0B0B16, $76DBDBAD, $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14, $DB494992, $0A06060C,
      $6C242448, $E45C5CB8, $5DC2C29F, $6ED3D3BD, $EFACAC43, $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2,
      $32E7E7D5, $43C8C88B, $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C, $E0A9A949, $B46C6CD8, $FA5656AC,
      $07F4F4F3, $25EAEACF, $AF6565CA, $8E7A7AF4, $E9AEAE47, $18080810, $D5BABA6F, $887878F0, $6F25254A, $722E2E5C,
      $241C1C38, $F1A6A657, $C7B4B473, $51C6C697, $23E8E8CB, $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61,
      $868B8B0D, $858A8A0F, $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890, $05030306, $01F6F6F7, $120E0E1C,
      $A36161C2, $5F35356A, $F95757AE, $D0B9B969, $91868617, $58C1C199, $271D1D3A, $B99E9E27, $38E1E1D9, $13F8F8EB,
      $B398982B, $33111122, $BB6969D2, $70D9D9A9, $898E8E07, $A7949433, $B69B9B2D, $221E1E3C, $92878715, $20E9E9C9,
      $49CECE87, $FF5555AA, $78282850, $7ADFDFA5, $8F8C8C03, $F8A1A159, $80898909, $170D0D1A, $DABFBF65, $31E6E6D7,
      $C6424284, $B86868D0, $C3414182, $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D, $3A16162C);

    LastForwardTable: array [0 .. 255] of longword = ($00000063, $0000007C, $00000077, $0000007B, $000000F2, $0000006B,
      $0000006F, $000000C5, $00000030, $00000001, $00000067, $0000002B, $000000FE, $000000D7, $000000AB, $00000076,
      $000000CA, $00000082, $000000C9, $0000007D, $000000FA, $00000059, $00000047, $000000F0, $000000AD, $000000D4,
      $000000A2, $000000AF, $0000009C, $000000A4, $00000072, $000000C0, $000000B7, $000000FD, $00000093, $00000026,
      $00000036, $0000003F, $000000F7, $000000CC, $00000034, $000000A5, $000000E5, $000000F1, $00000071, $000000D8,
      $00000031, $00000015, $00000004, $000000C7, $00000023, $000000C3, $00000018, $00000096, $00000005, $0000009A,
      $00000007, $00000012, $00000080, $000000E2, $000000EB, $00000027, $000000B2, $00000075, $00000009, $00000083,
      $0000002C, $0000001A, $0000001B, $0000006E, $0000005A, $000000A0, $00000052, $0000003B, $000000D6, $000000B3,
      $00000029, $000000E3, $0000002F, $00000084, $00000053, $000000D1, $00000000, $000000ED, $00000020, $000000FC,
      $000000B1, $0000005B, $0000006A, $000000CB, $000000BE, $00000039, $0000004A, $0000004C, $00000058, $000000CF,
      $000000D0, $000000EF, $000000AA, $000000FB, $00000043, $0000004D, $00000033, $00000085, $00000045, $000000F9,
      $00000002, $0000007F, $00000050, $0000003C, $0000009F, $000000A8, $00000051, $000000A3, $00000040, $0000008F,
      $00000092, $0000009D, $00000038, $000000F5, $000000BC, $000000B6, $000000DA, $00000021, $00000010, $000000FF,
      $000000F3, $000000D2, $000000CD, $0000000C, $00000013, $000000EC, $0000005F, $00000097, $00000044, $00000017,
      $000000C4, $000000A7, $0000007E, $0000003D, $00000064, $0000005D, $00000019, $00000073, $00000060, $00000081,
      $0000004F, $000000DC, $00000022, $0000002A, $00000090, $00000088, $00000046, $000000EE, $000000B8, $00000014,
      $000000DE, $0000005E, $0000000B, $000000DB, $000000E0, $00000032, $0000003A, $0000000A, $00000049, $00000006,
      $00000024, $0000005C, $000000C2, $000000D3, $000000AC, $00000062, $00000091, $00000095, $000000E4, $00000079,
      $000000E7, $000000C8, $00000037, $0000006D, $0000008D, $000000D5, $0000004E, $000000A9, $0000006C, $00000056,
      $000000F4, $000000EA, $00000065, $0000007A, $000000AE, $00000008, $000000BA, $00000078, $00000025, $0000002E,
      $0000001C, $000000A6, $000000B4, $000000C6, $000000E8, $000000DD, $00000074, $0000001F, $0000004B, $000000BD,
      $0000008B, $0000008A, $00000070, $0000003E, $000000B5, $00000066, $00000048, $00000003, $000000F6, $0000000E,
      $00000061, $00000035, $00000057, $000000B9, $00000086, $000000C1, $0000001D, $0000009E, $000000E1, $000000F8,
      $00000098, $00000011, $00000069, $000000D9, $0000008E, $00000094, $0000009B, $0000001E, $00000087, $000000E9,
      $000000CE, $00000055, $00000028, $000000DF, $0000008C, $000000A1, $00000089, $0000000D, $000000BF, $000000E6,
      $00000042, $00000068, $00000041, $00000099, $0000002D, $0000000F, $000000B0, $00000054, $000000BB, $00000016);

    InverseTable: array [0 .. 255] of longword = ($50A7F451, $5365417E, $C3A4171A, $965E273A, $CB6BAB3B, $F1459D1F,
      $AB58FAAC, $9303E34B, $55FA3020, $F66D76AD, $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526, $8FA362B5,
      $495AB1DE, $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3, $12F04C81, $A397468D, $C6F9D36B, $E75F8F03, $959C9215,
      $EB7A6DBF, $DA595295, $2D83BED4, $D3217458, $2969E049, $44C8C98E, $6A89C275, $78798EF4, $6B3E5899, $DD71B927,
      $B64FE1BE, $17AD88F0, $66AC20C9, $B43ACE7D, $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1, $84AE6BBB,
      $1CA081FE, $942B08F9, $58684870, $19FD458F, $876CDE94, $B7F87B52, $23D373AB, $E2024B72, $578F1FE3, $2AAB5566,
      $0728EBB2, $03C2B52F, $9A7BC586, $A50837D3, $F2872830, $B2A5BF23, $BA6A0302, $5C8216ED, $2B1CCF8A, $92B479A7,
      $F0F207F3, $A1E2694E, $CDF4DA65, $D5BE0506, $1F6234D1, $8AFEA6C4, $9D532E34, $A055F3A2, $32E18A05, $75EBF6A4,
      $39EC830B, $AAEF6040, $069F715E, $51106EBD, $F98A213E, $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471,
      $6FD40604, $FF155060, $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0, $888B8907, $385B19E7, $DBEEC879,
      $470A7CA1, $E90F427C, $C91E84F8, $00000000, $83868009, $48ED2B32, $AC70111E, $4E725A6C, $FBFF0EFD, $5638850F,
      $1ED5AE3D, $27392D36, $64D90F0A, $21A65C68, $D1545B9B, $3A2E3624, $B1670A0C, $0FE75793, $D296EEB4, $9E919B1B,
      $4FC5C080, $A220DC61, $694B775A, $161A121C, $0ABA93E2, $E52AA0C0, $43E0223C, $1D171B12, $0B0D090E, $ADC78BF2,
      $B9A8B62D, $C8A91E14, $8519F157, $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644, $347EFB5B,
      $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7, $10856342, $40229713, $2011C684, $7D244A85, $F83DBBD2,
      $1132F9AE, $6DA129C7, $4B2F9E1D, $F330B2DC, $EC52860D, $D0E3C177, $6C16B32B, $99B970A9, $FA489411, $2264E947,
      $C48CFCA8, $1A3FF0A0, $D82C7D56, $EF903322, $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498, $CF81F5A6, $28DE7AA5,
      $268EB7DA, $A4BFAD3F, $E49D3A2C, $0D927850, $9BCC5F6A, $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382,
      $BE805D9F, $7C93D069, $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8, $7BBB3BDB, $097826CD, $F418596E,
      $01B79AEC, $A89A4F83, $656E95E6, $7EE6FFAA, $08CFBC21, $E6E815EF, $D99BE7BA, $CE366F4A, $D4099FEA, $D67CB029,
      $AFB2A431, $31233F2A, $3094A5C6, $C066A235, $37BC4E74, $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41,
      $0E50CD7F, $2FF69117, $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E, $1B886A4C, $B81F2CC1, $7F516546,
      $04EA5E9D, $5D358C01, $737487FA, $2E410BFB, $5A1D67B3, $52D2DB92, $335610E9, $1347D66D, $8C61D79A, $7A0CA137,
      $8E14F859, $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1, $3CB1477A, $59DFD29C, $3F73F255, $79CE1418, $BF37C773,
      $EACDF753, $5BAAFD5F, $146F3DDF, $86DB4478, $81F3AFCA, $3EC468B9, $2C342438, $5F40A3C2, $72C31D16, $0C25E2BC,
      $8B493C28, $41950DFF, $7101A839, $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48, $4257B8D0);

    LastInverseTable: array [0 .. 255] of longword = ($00000052, $00000009, $0000006A, $000000D5, $00000030, $00000036,
      $000000A5, $00000038, $000000BF, $00000040, $000000A3, $0000009E, $00000081, $000000F3, $000000D7, $000000FB,
      $0000007C, $000000E3, $00000039, $00000082, $0000009B, $0000002F, $000000FF, $00000087, $00000034, $0000008E,
      $00000043, $00000044, $000000C4, $000000DE, $000000E9, $000000CB, $00000054, $0000007B, $00000094, $00000032,
      $000000A6, $000000C2, $00000023, $0000003D, $000000EE, $0000004C, $00000095, $0000000B, $00000042, $000000FA,
      $000000C3, $0000004E, $00000008, $0000002E, $000000A1, $00000066, $00000028, $000000D9, $00000024, $000000B2,
      $00000076, $0000005B, $000000A2, $00000049, $0000006D, $0000008B, $000000D1, $00000025, $00000072, $000000F8,
      $000000F6, $00000064, $00000086, $00000068, $00000098, $00000016, $000000D4, $000000A4, $0000005C, $000000CC,
      $0000005D, $00000065, $000000B6, $00000092, $0000006C, $00000070, $00000048, $00000050, $000000FD, $000000ED,
      $000000B9, $000000DA, $0000005E, $00000015, $00000046, $00000057, $000000A7, $0000008D, $0000009D, $00000084,
      $00000090, $000000D8, $000000AB, $00000000, $0000008C, $000000BC, $000000D3, $0000000A, $000000F7, $000000E4,
      $00000058, $00000005, $000000B8, $000000B3, $00000045, $00000006, $000000D0, $0000002C, $0000001E, $0000008F,
      $000000CA, $0000003F, $0000000F, $00000002, $000000C1, $000000AF, $000000BD, $00000003, $00000001, $00000013,
      $0000008A, $0000006B, $0000003A, $00000091, $00000011, $00000041, $0000004F, $00000067, $000000DC, $000000EA,
      $00000097, $000000F2, $000000CF, $000000CE, $000000F0, $000000B4, $000000E6, $00000073, $00000096, $000000AC,
      $00000074, $00000022, $000000E7, $000000AD, $00000035, $00000085, $000000E2, $000000F9, $00000037, $000000E8,
      $0000001C, $00000075, $000000DF, $0000006E, $00000047, $000000F1, $0000001A, $00000071, $0000001D, $00000029,
      $000000C5, $00000089, $0000006F, $000000B7, $00000062, $0000000E, $000000AA, $00000018, $000000BE, $0000001B,
      $000000FC, $00000056, $0000003E, $0000004B, $000000C6, $000000D2, $00000079, $00000020, $0000009A, $000000DB,
      $000000C0, $000000FE, $00000078, $000000CD, $0000005A, $000000F4, $0000001F, $000000DD, $000000A8, $00000033,
      $00000088, $00000007, $000000C7, $00000031, $000000B1, $00000012, $00000010, $00000059, $00000027, $00000080,
      $000000EC, $0000005F, $00000060, $00000051, $0000007F, $000000A9, $00000019, $000000B5, $0000004A, $0000000D,
      $0000002D, $000000E5, $0000007A, $0000009F, $00000093, $000000C9, $0000009C, $000000EF, $000000A0, $000000E0,
      $0000003B, $0000004D, $000000AE, $0000002A, $000000F5, $000000B0, $000000C8, $000000EB, $000000BB, $0000003C,
      $00000083, $00000053, $00000099, $00000061, $00000017, $0000002B, $00000004, $0000007E, $000000BA, $00000077,
      $000000D6, $00000026, $000000E1, $00000069, $00000014, $00000063, $00000055, $00000021, $0000000C, $0000007D);

procedure TAES.AfterConstruction();
begin
    inherited;
    // FKeyType := kb128;
end;

function TAES.Min(A, B: Integer): Integer;
begin
    if A < B then
        Result := A
    else
        Result := B;
end;

procedure TAES.ExpandAESKeyForEncryption(const Key: TAESKey128; var ExpandedKey: TAESExpandedKey128);
var
    I, J: Integer;
    T: longword;
    W0, W1, W2, W3: longword;
begin
    ExpandedKey[0] := PLongWord(@Key[0])^;
    ExpandedKey[1] := PLongWord(@Key[4])^;
    ExpandedKey[2] := PLongWord(@Key[8])^;
    ExpandedKey[3] := PLongWord(@Key[12])^;
    I := 0;
    J := 1;
    repeat
        T := (ExpandedKey[I + 3] shl 24) or (ExpandedKey[I + 3] shr 8);
        W0 := LastForwardTable[Byte(T)];
        W1 := LastForwardTable[Byte(T shr 8)];
        W2 := LastForwardTable[Byte(T shr 16)];
        W3 := LastForwardTable[Byte(T shr 24)];

        ExpandedKey[I + 4] := ExpandedKey[I] xor (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
          xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J];
        Inc(J);
        ExpandedKey[I + 5] := ExpandedKey[I + 1] xor ExpandedKey[I + 4];
        ExpandedKey[I + 6] := ExpandedKey[I + 2] xor ExpandedKey[I + 5];
        ExpandedKey[I + 7] := ExpandedKey[I + 3] xor ExpandedKey[I + 6];
        Inc(I, 4);
    until I >= 40;
end;

procedure TAES.ExpandAESKeyForEncryption(const Key: TAESKey192; var ExpandedKey: TAESExpandedKey192);
var
    I, J: Integer;
    T: longword;
    W0, W1, W2, W3: longword;
begin
    ExpandedKey[0] := PLongWord(@Key[0])^;
    ExpandedKey[1] := PLongWord(@Key[4])^;
    ExpandedKey[2] := PLongWord(@Key[8])^;
    ExpandedKey[3] := PLongWord(@Key[12])^;
    ExpandedKey[4] := PLongWord(@Key[16])^;
    ExpandedKey[5] := PLongWord(@Key[20])^;
    I := 0;
    J := 1;
    repeat
        T := (ExpandedKey[I + 5] shl 24) or (ExpandedKey[I + 5] shr 8);
        W0 := LastForwardTable[Byte(T)];
        W1 := LastForwardTable[Byte(T shr 8)];
        W2 := LastForwardTable[Byte(T shr 16)];
        W3 := LastForwardTable[Byte(T shr 24)];
        ExpandedKey[I + 6] := ExpandedKey[I] xor (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
          xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J];
        Inc(J);
        ExpandedKey[I + 7] := ExpandedKey[I + 1] xor ExpandedKey[I + 6];
        ExpandedKey[I + 8] := ExpandedKey[I + 2] xor ExpandedKey[I + 7];
        ExpandedKey[I + 9] := ExpandedKey[I + 3] xor ExpandedKey[I + 8];
        ExpandedKey[I + 10] := ExpandedKey[I + 4] xor ExpandedKey[I + 9];
        ExpandedKey[I + 11] := ExpandedKey[I + 5] xor ExpandedKey[I + 10];
        Inc(I, 6);
    until I >= 46;
end;

procedure TAES.ExpandAESKeyForEncryption(const Key: TAESKey256; var ExpandedKey: TAESExpandedKey256);
var
    I, J: Integer;
    T: longword;
    W0, W1, W2, W3: longword;
begin
    ExpandedKey[0] := PLongWord(@Key[0])^;
    ExpandedKey[1] := PLongWord(@Key[4])^;
    ExpandedKey[2] := PLongWord(@Key[8])^;
    ExpandedKey[3] := PLongWord(@Key[12])^;
    ExpandedKey[4] := PLongWord(@Key[16])^;
    ExpandedKey[5] := PLongWord(@Key[20])^;
    ExpandedKey[6] := PLongWord(@Key[24])^;
    ExpandedKey[7] := PLongWord(@Key[28])^;
    I := 0;
    J := 1;
    repeat
        T := (ExpandedKey[I + 7] shl 24) or (ExpandedKey[I + 7] shr 8);
        W0 := LastForwardTable[Byte(T)];
        W1 := LastForwardTable[Byte(T shr 8)];
        W2 := LastForwardTable[Byte(T shr 16)];
        W3 := LastForwardTable[Byte(T shr 24)];
        ExpandedKey[I + 8] := ExpandedKey[I] xor (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16))
          xor ((W3 shl 24) or (W3 shr 8))) xor Rcon[J];
        Inc(J);
        ExpandedKey[I + 9] := ExpandedKey[I + 1] xor ExpandedKey[I + 8];
        ExpandedKey[I + 10] := ExpandedKey[I + 2] xor ExpandedKey[I + 9];
        ExpandedKey[I + 11] := ExpandedKey[I + 3] xor ExpandedKey[I + 10];
        W0 := LastForwardTable[Byte(ExpandedKey[I + 11])];
        W1 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 8)];
        W2 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 16)];
        W3 := LastForwardTable[Byte(ExpandedKey[I + 11] shr 24)];
        ExpandedKey[I + 12] := ExpandedKey[I + 4] xor (W0 xor ((W1 shl 8) or (W1 shr 24))
          xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)));
        ExpandedKey[I + 13] := ExpandedKey[I + 5] xor ExpandedKey[I + 12];
        ExpandedKey[I + 14] := ExpandedKey[I + 6] xor ExpandedKey[I + 13];
        ExpandedKey[I + 15] := ExpandedKey[I + 7] xor ExpandedKey[I + 14];
        Inc(I, 8);
    until I >= 52;
end;

procedure TAES.EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128; var OutBuf: TAESBuffer);
var
    T0, T1: array [0 .. 3] of longword;
    W0, W1, W2, W3: longword;
begin
    // initializing
    T0[0] := PLongWord(@InBuf[0])^ xor Key[0];
    T0[1] := PLongWord(@InBuf[4])^ xor Key[1];
    T0[2] := PLongWord(@InBuf[8])^ xor Key[2];
    T0[3] := PLongWord(@InBuf[12])^ xor Key[3];
    // performing transformation 9 times
    // round 1
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[4];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[5];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[6];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[7];
    // round 2
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[8];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[9];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[10];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[11];
    // round 3
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[12];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[13];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[14];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[15];
    // round 4
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[16];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[17];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[18];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[19];
    // round 5
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[20];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[21];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[22];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[23];
    // round 6
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[24];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[25];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[26];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[27];
    // round 7
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[28];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[29];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[30];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[31];
    // round 8
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[32];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[33];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[34];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[35];
    // round 9
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[36];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[37];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[38];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[39];
    // last round of transformations
    W0 := LastForwardTable[Byte(T1[0])];
    W1 := LastForwardTable[Byte(T1[1] shr 8)];
    W2 := LastForwardTable[Byte(T1[2] shr 16)];
    W3 := LastForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[40];
    W0 := LastForwardTable[Byte(T1[1])];
    W1 := LastForwardTable[Byte(T1[2] shr 8)];
    W2 := LastForwardTable[Byte(T1[3] shr 16)];
    W3 := LastForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[41];
    W0 := LastForwardTable[Byte(T1[2])];
    W1 := LastForwardTable[Byte(T1[3] shr 8)];
    W2 := LastForwardTable[Byte(T1[0] shr 16)];
    W3 := LastForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[42];
    W0 := LastForwardTable[Byte(T1[3])];
    W1 := LastForwardTable[Byte(T1[0] shr 8)];
    W2 := LastForwardTable[Byte(T1[1] shr 16)];
    W3 := LastForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[43];
    // finalizing
    PLongWord(@OutBuf[0])^ := T0[0];
    PLongWord(@OutBuf[4])^ := T0[1];
    PLongWord(@OutBuf[8])^ := T0[2];
    PLongWord(@OutBuf[12])^ := T0[3];
end;

procedure TAES.EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192; var OutBuf: TAESBuffer);
var
    T0, T1: array [0 .. 3] of longword;
    W0, W1, W2, W3: longword;
begin
    // initializing
    T0[0] := PLongWord(@InBuf[0])^ xor Key[0];
    T0[1] := PLongWord(@InBuf[4])^ xor Key[1];
    T0[2] := PLongWord(@InBuf[8])^ xor Key[2];
    T0[3] := PLongWord(@InBuf[12])^ xor Key[3];
    // performing transformation 11 times
    // round 1
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[4];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[5];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[6];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[7];
    // round 2
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[8];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[9];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[10];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[11];
    // round 3
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[12];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[13];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[14];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[15];
    // round 4
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[16];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[17];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[18];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[19];
    // round 5
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[20];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[21];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[22];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[23];
    // round 6
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[24];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[25];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[26];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[27];
    // round 7
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[28];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[29];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[30];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[31];
    // round 8
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[32];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[33];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[34];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[35];
    // round 9
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[36];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[37];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[38];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[39];
    // round 10
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[40];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[41];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[42];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[43];
    // round 11
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[44];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[45];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[46];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[47];
    // last round of transformations
    W0 := LastForwardTable[Byte(T1[0])];
    W1 := LastForwardTable[Byte(T1[1] shr 8)];
    W2 := LastForwardTable[Byte(T1[2] shr 16)];
    W3 := LastForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[48];
    W0 := LastForwardTable[Byte(T1[1])];
    W1 := LastForwardTable[Byte(T1[2] shr 8)];
    W2 := LastForwardTable[Byte(T1[3] shr 16)];
    W3 := LastForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[49];
    W0 := LastForwardTable[Byte(T1[2])];
    W1 := LastForwardTable[Byte(T1[3] shr 8)];
    W2 := LastForwardTable[Byte(T1[0] shr 16)];
    W3 := LastForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[50];
    W0 := LastForwardTable[Byte(T1[3])];
    W1 := LastForwardTable[Byte(T1[0] shr 8)];
    W2 := LastForwardTable[Byte(T1[1] shr 16)];
    W3 := LastForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[51];
    // finalizing
    PLongWord(@OutBuf[0])^ := T0[0];
    PLongWord(@OutBuf[4])^ := T0[1];
    PLongWord(@OutBuf[8])^ := T0[2];
    PLongWord(@OutBuf[12])^ := T0[3];
end;

procedure TAES.EncryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256; var OutBuf: TAESBuffer);
var
    T0, T1: array [0 .. 3] of longword;
    W0, W1, W2, W3: longword;
begin
    // initializing
    T0[0] := PLongWord(@InBuf[0])^ xor Key[0];
    T0[1] := PLongWord(@InBuf[4])^ xor Key[1];
    T0[2] := PLongWord(@InBuf[8])^ xor Key[2];
    T0[3] := PLongWord(@InBuf[12])^ xor Key[3];
    // performing transformation 13 times
    // round 1
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[4];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[5];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[6];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[7];
    // round 2
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[8];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[9];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[10];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[11];
    // round 3
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[12];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[13];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[14];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[15];
    // round 4
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[16];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[17];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[18];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[19];
    // round 5
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[20];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[21];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[22];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[23];
    // round 6
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[24];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[25];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[26];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[27];
    // round 7
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[28];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[29];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[30];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[31];
    // round 8
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[32];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[33];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[34];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[35];
    // round 9
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[36];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[37];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[38];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[39];
    // round 10
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[40];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[41];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[42];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[43];
    // round 11
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[44];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[45];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[46];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[47];
    // round 12
    W0 := ForwardTable[Byte(T1[0])];
    W1 := ForwardTable[Byte(T1[1] shr 8)];
    W2 := ForwardTable[Byte(T1[2] shr 16)];
    W3 := ForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[48];
    W0 := ForwardTable[Byte(T1[1])];
    W1 := ForwardTable[Byte(T1[2] shr 8)];
    W2 := ForwardTable[Byte(T1[3] shr 16)];
    W3 := ForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[49];
    W0 := ForwardTable[Byte(T1[2])];
    W1 := ForwardTable[Byte(T1[3] shr 8)];
    W2 := ForwardTable[Byte(T1[0] shr 16)];
    W3 := ForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[50];
    W0 := ForwardTable[Byte(T1[3])];
    W1 := ForwardTable[Byte(T1[0] shr 8)];
    W2 := ForwardTable[Byte(T1[1] shr 16)];
    W3 := ForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[51];
    // round 13
    W0 := ForwardTable[Byte(T0[0])];
    W1 := ForwardTable[Byte(T0[1] shr 8)];
    W2 := ForwardTable[Byte(T0[2] shr 16)];
    W3 := ForwardTable[Byte(T0[3] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[52];
    W0 := ForwardTable[Byte(T0[1])];
    W1 := ForwardTable[Byte(T0[2] shr 8)];
    W2 := ForwardTable[Byte(T0[3] shr 16)];
    W3 := ForwardTable[Byte(T0[0] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[53];
    W0 := ForwardTable[Byte(T0[2])];
    W1 := ForwardTable[Byte(T0[3] shr 8)];
    W2 := ForwardTable[Byte(T0[0] shr 16)];
    W3 := ForwardTable[Byte(T0[1] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[54];
    W0 := ForwardTable[Byte(T0[3])];
    W1 := ForwardTable[Byte(T0[0] shr 8)];
    W2 := ForwardTable[Byte(T0[1] shr 16)];
    W3 := ForwardTable[Byte(T0[2] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[55];
    // last round of transformations
    W0 := LastForwardTable[Byte(T1[0])];
    W1 := LastForwardTable[Byte(T1[1] shr 8)];
    W2 := LastForwardTable[Byte(T1[2] shr 16)];
    W3 := LastForwardTable[Byte(T1[3] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[56];
    W0 := LastForwardTable[Byte(T1[1])];
    W1 := LastForwardTable[Byte(T1[2] shr 8)];
    W2 := LastForwardTable[Byte(T1[3] shr 16)];
    W3 := LastForwardTable[Byte(T1[0] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[57];
    W0 := LastForwardTable[Byte(T1[2])];
    W1 := LastForwardTable[Byte(T1[3] shr 8)];
    W2 := LastForwardTable[Byte(T1[0] shr 16)];
    W3 := LastForwardTable[Byte(T1[1] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[58];
    W0 := LastForwardTable[Byte(T1[3])];
    W1 := LastForwardTable[Byte(T1[0] shr 8)];
    W2 := LastForwardTable[Byte(T1[1] shr 16)];
    W3 := LastForwardTable[Byte(T1[2] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[59];
    // finalizing
    PLongWord(@OutBuf[0])^ := T0[0];
    PLongWord(@OutBuf[4])^ := T0[1];
    PLongWord(@OutBuf[8])^ := T0[2];
    PLongWord(@OutBuf[12])^ := T0[3];
end;

procedure TAES.ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey128);
var
    I: Integer;
    U, F2, F4, F8, F9: longword;
begin
    for I := 1 to 9 do begin
        F9 := ExpandedKey[I * 4];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 1];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 2];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 3];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
    end;
end;

procedure TAES.ExpandAESKeyForDecryption(const Key: TAESKey128; var ExpandedKey: TAESExpandedKey128);
begin
    ExpandAESKeyForEncryption(Key, ExpandedKey);
    ExpandAESKeyForDecryption(ExpandedKey);
end;

procedure TAES.ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey192);
var
    I: Integer;
    U, F2, F4, F8, F9: longword;
begin
    for I := 1 to 11 do begin
        F9 := ExpandedKey[I * 4];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 1];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 2];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 3];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
    end;
end;

procedure TAES.ExpandAESKeyForDecryption(const Key: TAESKey192; var ExpandedKey: TAESExpandedKey192);
begin
    ExpandAESKeyForEncryption(Key, ExpandedKey);
    ExpandAESKeyForDecryption(ExpandedKey);
end;

procedure TAES.ExpandAESKeyForDecryption(var ExpandedKey: TAESExpandedKey256);
var
    I: Integer;
    U, F2, F4, F8, F9: longword;
begin
    for I := 1 to 13 do begin
        F9 := ExpandedKey[I * 4];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 1];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 1] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 2];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 2] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
        F9 := ExpandedKey[I * 4 + 3];
        U := F9 and $80808080;
        F2 := ((F9 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F2 and $80808080;
        F4 := ((F2 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        U := F4 and $80808080;
        F8 := ((F4 and $7F7F7F7F) shl 1) xor ((U - (U shr 7)) and $1B1B1B1B);
        F9 := F9 xor F8;
        ExpandedKey[I * 4 + 3] := F2 xor F4 xor F8 xor (((F2 xor F9) shl 24) or ((F2 xor F9) shr 8))
          xor (((F4 xor F9) shl 16) or ((F4 xor F9) shr 16)) xor ((F9 shl 8) or (F9 shr 24));
    end;
end;

procedure TAES.ExpandAESKeyForDecryption(const Key: TAESKey256; var ExpandedKey: TAESExpandedKey256);
begin
    ExpandAESKeyForEncryption(Key, ExpandedKey);
    ExpandAESKeyForDecryption(ExpandedKey);
end;

procedure TAES.DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey128; var OutBuf: TAESBuffer);
var
    T0, T1: array [0 .. 3] of longword;
    W0, W1, W2, W3: longword;
begin
    // initializing
    T0[0] := PLongWord(@InBuf[0])^ xor Key[40];
    T0[1] := PLongWord(@InBuf[4])^ xor Key[41];
    T0[2] := PLongWord(@InBuf[8])^ xor Key[42];
    T0[3] := PLongWord(@InBuf[12])^ xor Key[43];
    // performing transformations 9 times
    // round 1
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[36];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[37];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[38];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[39];
    // round 2
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[32];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[33];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[34];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[35];
    // round 3
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[28];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[29];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[30];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[31];
    // round 4
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[24];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[25];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[26];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[27];
    // round 5
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[20];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[21];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[22];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[23];
    // round 6
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[16];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[17];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[18];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[19];
    // round 7
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[12];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[13];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[14];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[15];
    // round 8
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[8];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[9];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[10];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[11];
    // round 9
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[4];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[5];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[6];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[7];
    // last round of transformations
    W0 := LastInverseTable[Byte(T1[0])];
    W1 := LastInverseTable[Byte(T1[3] shr 8)];
    W2 := LastInverseTable[Byte(T1[2] shr 16)];
    W3 := LastInverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[0];
    W0 := LastInverseTable[Byte(T1[1])];
    W1 := LastInverseTable[Byte(T1[0] shr 8)];
    W2 := LastInverseTable[Byte(T1[3] shr 16)];
    W3 := LastInverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[1];
    W0 := LastInverseTable[Byte(T1[2])];
    W1 := LastInverseTable[Byte(T1[1] shr 8)];
    W2 := LastInverseTable[Byte(T1[0] shr 16)];
    W3 := LastInverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[2];
    W0 := LastInverseTable[Byte(T1[3])];
    W1 := LastInverseTable[Byte(T1[2] shr 8)];
    W2 := LastInverseTable[Byte(T1[1] shr 16)];
    W3 := LastInverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[3];
    // finalizing
    PLongWord(@OutBuf[0])^ := T0[0];
    PLongWord(@OutBuf[4])^ := T0[1];
    PLongWord(@OutBuf[8])^ := T0[2];
    PLongWord(@OutBuf[12])^ := T0[3];
end;

procedure TAES.DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey192; var OutBuf: TAESBuffer);
var
    T0, T1: array [0 .. 3] of longword;
    W0, W1, W2, W3: longword;
begin
    // initializing
    T0[0] := PLongWord(@InBuf[0])^ xor Key[48];
    T0[1] := PLongWord(@InBuf[4])^ xor Key[49];
    T0[2] := PLongWord(@InBuf[8])^ xor Key[50];
    T0[3] := PLongWord(@InBuf[12])^ xor Key[51];
    // performing transformations 11 times
    // round 1
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[44];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[45];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[46];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[47];
    // round 2
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[40];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[41];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[42];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[43];
    // round 3
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[36];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[37];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[38];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[39];
    // round 4
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[32];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[33];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[34];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[35];
    // round 5
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[28];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[29];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[30];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[31];
    // round 6
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[24];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[25];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[26];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[27];
    // round 7
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[20];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[21];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[22];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[23];
    // round 8
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[16];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[17];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[18];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[19];
    // round 9
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[12];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[13];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[14];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[15];
    // round 10
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[8];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[9];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[10];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[11];
    // round 11
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[4];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[5];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[6];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[7];
    // last round of transformations
    W0 := LastInverseTable[Byte(T1[0])];
    W1 := LastInverseTable[Byte(T1[3] shr 8)];
    W2 := LastInverseTable[Byte(T1[2] shr 16)];
    W3 := LastInverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[0];
    W0 := LastInverseTable[Byte(T1[1])];
    W1 := LastInverseTable[Byte(T1[0] shr 8)];
    W2 := LastInverseTable[Byte(T1[3] shr 16)];
    W3 := LastInverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[1];
    W0 := LastInverseTable[Byte(T1[2])];
    W1 := LastInverseTable[Byte(T1[1] shr 8)];
    W2 := LastInverseTable[Byte(T1[0] shr 16)];
    W3 := LastInverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[2];
    W0 := LastInverseTable[Byte(T1[3])];
    W1 := LastInverseTable[Byte(T1[2] shr 8)];
    W2 := LastInverseTable[Byte(T1[1] shr 16)];
    W3 := LastInverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[3];
    // finalizing
    PLongWord(@OutBuf[0])^ := T0[0];
    PLongWord(@OutBuf[4])^ := T0[1];
    PLongWord(@OutBuf[8])^ := T0[2];
    PLongWord(@OutBuf[12])^ := T0[3];
end;

procedure TAES.DecryptAES(const InBuf: TAESBuffer; const Key: TAESExpandedKey256; var OutBuf: TAESBuffer);
var
    T0, T1: array [0 .. 3] of longword;
    W0, W1, W2, W3: longword;
begin
    // initializing
    T0[0] := PLongWord(@InBuf[0])^ xor Key[56];
    T0[1] := PLongWord(@InBuf[4])^ xor Key[57];
    T0[2] := PLongWord(@InBuf[8])^ xor Key[58];
    T0[3] := PLongWord(@InBuf[12])^ xor Key[59];
    // performing transformations 13 times
    // round 1
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[52];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[53];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[54];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[55];
    // round 2
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[48];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[49];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[50];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[51];
    // round 3
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[44];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[45];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[46];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[47];
    // round 4
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[40];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[41];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[42];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[43];
    // round 5
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[36];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[37];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[38];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[39];
    // round 6
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[32];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[33];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[34];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[35];
    // round 7
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[28];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[29];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[30];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[31];
    // round 8
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[24];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[25];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[26];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[27];
    // round 9
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[20];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[21];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[22];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[23];
    // round 10
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[16];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[17];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[18];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[19];
    // round 11
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[12];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[13];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[14];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[15];
    // round 12
    W0 := InverseTable[Byte(T1[0])];
    W1 := InverseTable[Byte(T1[3] shr 8)];
    W2 := InverseTable[Byte(T1[2] shr 16)];
    W3 := InverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[8];
    W0 := InverseTable[Byte(T1[1])];
    W1 := InverseTable[Byte(T1[0] shr 8)];
    W2 := InverseTable[Byte(T1[3] shr 16)];
    W3 := InverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[9];
    W0 := InverseTable[Byte(T1[2])];
    W1 := InverseTable[Byte(T1[1] shr 8)];
    W2 := InverseTable[Byte(T1[0] shr 16)];
    W3 := InverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[10];
    W0 := InverseTable[Byte(T1[3])];
    W1 := InverseTable[Byte(T1[2] shr 8)];
    W2 := InverseTable[Byte(T1[1] shr 16)];
    W3 := InverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[11];
    // round 13
    W0 := InverseTable[Byte(T0[0])];
    W1 := InverseTable[Byte(T0[3] shr 8)];
    W2 := InverseTable[Byte(T0[2] shr 16)];
    W3 := InverseTable[Byte(T0[1] shr 24)];
    T1[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[4];
    W0 := InverseTable[Byte(T0[1])];
    W1 := InverseTable[Byte(T0[0] shr 8)];
    W2 := InverseTable[Byte(T0[3] shr 16)];
    W3 := InverseTable[Byte(T0[2] shr 24)];
    T1[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[5];
    W0 := InverseTable[Byte(T0[2])];
    W1 := InverseTable[Byte(T0[1] shr 8)];
    W2 := InverseTable[Byte(T0[0] shr 16)];
    W3 := InverseTable[Byte(T0[3] shr 24)];
    T1[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[6];
    W0 := InverseTable[Byte(T0[3])];
    W1 := InverseTable[Byte(T0[2] shr 8)];
    W2 := InverseTable[Byte(T0[1] shr 16)];
    W3 := InverseTable[Byte(T0[0] shr 24)];
    T1[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[7];
    // last round of transformations
    W0 := LastInverseTable[Byte(T1[0])];
    W1 := LastInverseTable[Byte(T1[3] shr 8)];
    W2 := LastInverseTable[Byte(T1[2] shr 16)];
    W3 := LastInverseTable[Byte(T1[1] shr 24)];
    T0[0] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[0];
    W0 := LastInverseTable[Byte(T1[1])];
    W1 := LastInverseTable[Byte(T1[0] shr 8)];
    W2 := LastInverseTable[Byte(T1[3] shr 16)];
    W3 := LastInverseTable[Byte(T1[2] shr 24)];
    T0[1] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[1];
    W0 := LastInverseTable[Byte(T1[2])];
    W1 := LastInverseTable[Byte(T1[1] shr 8)];
    W2 := LastInverseTable[Byte(T1[0] shr 16)];
    W3 := LastInverseTable[Byte(T1[3] shr 24)];
    T0[2] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[2];
    W0 := LastInverseTable[Byte(T1[3])];
    W1 := LastInverseTable[Byte(T1[2] shr 8)];
    W2 := LastInverseTable[Byte(T1[1] shr 16)];
    W3 := LastInverseTable[Byte(T1[0] shr 24)];
    T0[3] := (W0 xor ((W1 shl 8) or (W1 shr 24)) xor ((W2 shl 16) or (W2 shr 16)) xor ((W3 shl 24) or (W3 shr 8)))
      xor Key[3];
    // finalizing
    PLongWord(@OutBuf[0])^ := T0[0];
    PLongWord(@OutBuf[4])^ := T0[1];
    PLongWord(@OutBuf[8])^ := T0[2];
    PLongWord(@OutBuf[12])^ := T0[3];
end;

procedure TAES.FormatKey_Encrypt(const Key: Ansistring; const KeyBit: TKeyBit; AESKey128: TAESKey128;
  AESKey192: TAESKey192; AESKey256: TAESKey256; var ExpandedKey128: TAESExpandedKey128;
  var ExpandedKey192: TAESExpandedKey192; var ExpandedKey256: TAESExpandedKey256);
begin
    // kb128, kb192, kb256
    if KeyBit = KB128 then begin
        FillChar(AESKey128, SizeOf(AESKey128), 0);
        Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
        ExpandAESKeyForEncryption(AESKey128, ExpandedKey128);
    end;

    if KeyBit = KB192 then begin
        FillChar(AESKey192, SizeOf(AESKey192), 0);
        Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
        ExpandAESKeyForEncryption(AESKey192, ExpandedKey192);
    end;

    if KeyBit = KB256 then begin
        FillChar(AESKey256, SizeOf(AESKey256), 0);
        Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
        ExpandAESKeyForEncryption(AESKey256, ExpandedKey256);
    end;
end;

procedure TAES.FormatKey_Decrypt(const Key: Ansistring; const KeyBit: TKeyBit; AESKey128: TAESKey128;
  AESKey192: TAESKey192; AESKey256: TAESKey256; var ExpandedKey128: TAESExpandedKey128;
  var ExpandedKey192: TAESExpandedKey192; var ExpandedKey256: TAESExpandedKey256);
begin
    // kb128, kb192, kb256
    if KeyBit = KB128 then begin
        FillChar(AESKey128, SizeOf(AESKey128), 0);
        Move(PAnsiChar(Key)^, AESKey128, Min(SizeOf(AESKey128), Length(Key)));
        ExpandAESKeyForDecryption(AESKey128, ExpandedKey128);
    end;

    if KeyBit = KB192 then begin
        FillChar(AESKey192, SizeOf(AESKey192), 0);
        Move(PAnsiChar(Key)^, AESKey192, Min(SizeOf(AESKey192), Length(Key)));
        ExpandAESKeyForDecryption(AESKey192, ExpandedKey192);
    end;

    if KeyBit = KB256 then begin
        FillChar(AESKey256, SizeOf(AESKey256), 0);
        Move(PAnsiChar(Key)^, AESKey256, Min(SizeOf(AESKey256), Length(Key)));
        ExpandAESKeyForDecryption(AESKey256, ExpandedKey256);
    end;
end;

procedure TAES.EncryptAESStreamCBC(Source, Dest: TStream; Count: Int64; const InitVector: TAESBuffer; Key: Ansistring;
  KeyBit: TKeyBit = KB128);
var
    AESKey128: TAESKey128;
    AESKey192: TAESKey192;
    AESKey256: TAESKey256;

    ExpandedKey128: TAESExpandedKey128;
    ExpandedKey192: TAESExpandedKey192;
    ExpandedKey256: TAESExpandedKey256;

    TempIn, TempOut, Vector: TAESBuffer;
    Done: Int64;
begin
    if Count = 0 then
        Count := Source.Size - Source.Position;
    if (Count = 0) or (Count > Source.Size - Source.Position) then
        Exit;
    Vector := InitVector;

    // kb128, kb192, kb256
    FormatKey_Encrypt(Key, KeyBit, AESKey128, AESKey192, AESKey256, ExpandedKey128, ExpandedKey192, ExpandedKey256);

    while Count >= SizeOf(TAESBuffer) do begin
        Done := Source.Read(TempIn[0], SizeOf(TempIn));
        if Done < SizeOf(TempIn) then
            raise EStreamError.Create(SReadError);
        PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
        PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
        PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
        PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;

        if KeyBit = KB128 then
            EncryptAES(TempIn, ExpandedKey128, TempOut);
        if KeyBit = KB192 then
            EncryptAES(TempIn, ExpandedKey192, TempOut);
        if KeyBit = KB256 then
            EncryptAES(TempIn, ExpandedKey256, TempOut);

        Done := Dest.Write(TempOut, SizeOf(TempOut));
        if Done < SizeOf(TempOut) then
            raise EStreamError.Create(SWriteError);
        Vector := TempOut;
        Dec(Count, SizeOf(TAESBuffer));
    end;

    if Count > 0 then begin
        Done := Source.Read(TempIn, Count);
        if Done < Count then
            raise EStreamError.Create(SReadError);
        FillChar(TempIn[Count], SizeOf(TAESBuffer) - Count, 0);
        PLongWord(@TempIn[0])^ := PLongWord(@TempIn[0])^ xor PLongWord(@Vector[0])^;
        PLongWord(@TempIn[4])^ := PLongWord(@TempIn[4])^ xor PLongWord(@Vector[4])^;
        PLongWord(@TempIn[8])^ := PLongWord(@TempIn[8])^ xor PLongWord(@Vector[8])^;
        PLongWord(@TempIn[12])^ := PLongWord(@TempIn[12])^ xor PLongWord(@Vector[12])^;

        if KeyBit = KB128 then
            EncryptAES(TempIn, ExpandedKey128, TempOut);
        if KeyBit = KB192 then
            EncryptAES(TempIn, ExpandedKey192, TempOut);
        if KeyBit = KB256 then
            EncryptAES(TempIn, ExpandedKey256, TempOut);

        Done := Dest.Write(TempOut[0], SizeOf(TempOut));
        if Done < SizeOf(TempOut) then
            raise EStreamError.Create(SWriteError);
    end;
end;

procedure TAES.DecryptAESStreamCBC(Source, Dest: TStream; Count: Int64; const InitVector: TAESBuffer; Key: Ansistring;
  KeyBit: TKeyBit = KB128);
var
    AESKey128: TAESKey128;
    AESKey192: TAESKey192;
    AESKey256: TAESKey256;

    ExpandedKey128: TAESExpandedKey128;
    ExpandedKey192: TAESExpandedKey192;
    ExpandedKey256: TAESExpandedKey256;

    TempIn, TempOut: TAESBuffer;
    Vector1, Vector2: TAESBuffer;
    Done: Int64;
begin
    if Count = 0 then
        Count := Source.Size - Source.Position;
    if (Count = 0) or (Count > Source.Size - Source.Position) then
        Exit;
    if (Count mod SizeOf(TAESBuffer)) > 0 then
        raise EAESError.Create(SInvalidInBufSize);

    FormatKey_Decrypt(Key, KeyBit, AESKey128, AESKey192, AESKey256, ExpandedKey128, ExpandedKey192, ExpandedKey256);

    Vector1 := InitVector;
    while Count >= SizeOf(TAESBuffer) do begin
        Done := Source.Read(TempIn[0], SizeOf(TempIn));
        if Done < SizeOf(TempIn) then
            raise EStreamError(SReadError);
        Vector2 := TempIn;

        if KeyBit = KB128 then
            DecryptAES(TempIn, ExpandedKey128, TempOut);
        if KeyBit = KB192 then
            DecryptAES(TempIn, ExpandedKey192, TempOut);
        if KeyBit = KB256 then
            DecryptAES(TempIn, ExpandedKey256, TempOut);

        PLongWord(@TempOut[0])^ := PLongWord(@TempOut[0])^ xor PLongWord(@Vector1[0])^;
        PLongWord(@TempOut[4])^ := PLongWord(@TempOut[4])^ xor PLongWord(@Vector1[4])^;
        PLongWord(@TempOut[8])^ := PLongWord(@TempOut[8])^ xor PLongWord(@Vector1[8])^;
        PLongWord(@TempOut[12])^ := PLongWord(@TempOut[12])^ xor PLongWord(@Vector1[12])^;
        Done := Dest.Write(TempOut[0], SizeOf(TempOut));
        if Done < SizeOf(TempOut) then
            raise EStreamError(SWriteError);
        Vector1 := Vector2;
        Dec(Count, SizeOf(TAESBuffer));
    end;
end;

function TAES.StrToHex(Value: Ansistring): string;
begin
    SetLength(Result, 2 * Length(Value));
    BinToHex(PAnsiChar(Value), PChar(Result), Length(Value));
end;

function TAES.HexToStr(Value: string): Ansistring;
begin
    SetLength(Result, Length(Value) div 2);
    HexToBin(PChar(Value), PAnsiChar(Result), Length(Value));
end;

function EncryptStr_CBC(Value, Key: string; InitVector: TAESBuffer; KeyBit: TKeyBit = KB256;
  IsUtf8Encode: Boolean = False): string;

const
    Convert: array [0 .. 15] of WideChar = '0123456789ABCDEF';
var
    Source, Dest: TBytesStream;
    Aes: TAES;
    I: Integer;
    P: PAnsiChar;
    Bt: Byte;
    KeyBytes, InRaws: Ansistring;

begin
    Result := '';
    if Value = '' then
        Exit;

    Source := TBytesStream.Create();
    Dest := TBytesStream.Create();
    Aes := TAES.Create();
    try
        // utf8 编码
        if IsUtf8Encode then begin
            InRaws := Utf8Encode(Value);
            KeyBytes := Utf8Encode(Key);
        end
        else begin
            InRaws := Ansistring(Value);
            KeyBytes := Ansistring(Key);
        end;
        //
        Source.Write(InRaws[1], Length(InRaws));
        Source.Position := 0;
        try
            Aes.EncryptAESStreamCBC(Source, Dest, Source.Size, InitVector, KeyBytes, KeyBit);
            //
            Dest.Position := 0;
            P := PAnsiChar(Dest.Memory);
            //
            SetLength(Result, 2 * Dest.Size);
            for I := 0 to Dest.Size - 1 do begin
                Bt := Byte(P^);
                Result[I * 2 + 1] := Convert[Bt shr 4];
                Result[I * 2 + 2] := Convert[Bt and $F];
                Inc(P);
            end;
        except
        end;
    finally
        Aes.Free();
        Dest.Free();
        Source.Free();
    end;
end;

//
function DecryptStr_CBC(Value, Key: string; InitVector: TAESBuffer; KeyBit: TKeyBit = KB256;
  IsUtf8Decode: Boolean = False): string;
var
    Source, Dest: TStream;
    Aes: TAES;
    S: Ansistring;
    OutRaws, KeyBytes: Ansistring;

begin
    Result := '';
    if Value = '' then
        Exit;

    Source := TMemoryStream.Create();
    Dest := TMemoryStream.Create();
    Aes := TAES.Create();
    try
        KeyBytes := Utf8Encode(Key);
        if IsUtf8Decode then
            KeyBytes := Utf8Encode(Key)
        else
            KeyBytes := Ansistring(Key);

        //
        SetLength(S, Length(Value) div 2);
        HexToBin(PChar(Value), PAnsiChar(S), Length(Value));
        //
        Source.Write(S[1], Length(S));
        Source.Position := 0;
        try
            Aes.DecryptAESStreamCBC(Source, Dest, Source.Size, InitVector, KeyBytes, KeyBit);
            //
            Dest.Position := 0;
            SetLength(OutRaws, Dest.Size);
            Dest.Read(OutRaws[1], Dest.Size);
            //
            if IsUtf8Decode then
                Result := Utf8ToWideString(OutRaws)
            else
                Result := string(OutRaws);
        except
        end;
    finally
        Aes.Free();
        Dest.Free();
        Source.Free();
    end;
end;

end.
 

//工程调用代码如下:
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
    System.SysUtils,
    ElAES in 'ElAES.pas';

const
    // 初始化向量  = 1234567890ABCDEF
    InitVector: TAESBuffer = (49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 65, 66, 67, 68, 69, 70);

procedure Test();
var
    S, S2: string;
begin
    // 加密
    S := EncryptStr_CBC('多可文档管理系统', '2018201820182018', InitVector, KB128, True);
    Writeln(S);
    // 解密
    S2 := DecryptStr_CBC(S, '2018201820182018', InitVector, KB128, True);
    Writeln(S2);
end;

begin
    try
        Test();
    except
        on E: Exception do
            Writeln(E.ClassName, ': ', E.Message);
    end;
end.

Delphi 7和Java是两种不同的编程语言,它们具有不同的工作原理和语法,因此在进行AES加密解密和相互转换时需要特定的步骤。 1. Delphi 7的AES加密解密: - Delphi 7可以使用第三方库来实现AES加密解密,例如DCPCrypt或DelphiEncryptionCompendium等。 - 使用这些库,你可以在Delphi 7中调用AES加密和解密方法来处理需要加密或解密的数据。 - 对于加密操作,你需要提供明文,密钥和加密模式等参数。对于解密操作,你需要提供密文,密钥和解密模式等参数。 2. Delphi 7到Java的转换: - 在将Delphi 7中的AES加密解密逻辑转换到Java时,你需要使用Java的加密类库,例如Java Cryptography Extension(JCE)。 - 在Java中,你可以使用javax.crypto包中的Cipher类来实现AES加密解密操作。 - 你需要提供相应的参数,例如密钥,加密算法和填充模式等来执行加密和解密操作。 3. Java到Delphi 7的转换: - 在将Java中的AES加密解密逻辑转换到Delphi 7时,你需要使用Delphi 7的加密类库,如前面提到的DCPCrypt或DelphiEncryptionCompendium等。 - 你可以使用对应的加密方法和相应的参数(如密钥和加密算法等)来执行加密解密操作。 - 确保在转换时,密钥和其他相关参数的格式和类型是一致的,以便正确处理数据。 总之,要在Delphi 7和Java之间实现AES加密解密的互转,你需要使用每种语言中的加密库并提供相应的参数。这样可以确保在两种语言之间正确执行加密解密操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值