Files
kolmck/Addons/KOLBlockCipher.pas
dkolmck 73c088ce13 formatted source code
git-svn-id: https://svn.code.sf.net/p/kolmck/code@120 91bb2d04-0c0c-4d2d-88a5-bbb6f4c1fa07
2014-12-03 08:46:57 +00:00

8550 lines
345 KiB
ObjectPascal

unit KOLBlockCipher;
{$A1}
interface
uses Windows, KOL;
type
// PBlockCipher64 = ^TBlockCipher64;
TBlockCipher64 = object(TObj)
protected
IV, CV: array[0..7] of byte;
procedure IncCounter;
public
// code
procedure InitKey(const Key; Size: longword); virtual;
procedure Reset;
{ Reset any stored chaining information }
procedure Burn; virtual;
{ Clear all stored key information and chaining information }
procedure SetIV(const Value);
{ Sets the IV to Value and performs a reset }
procedure GetIV(var Value);
{ Returns the current chaining information, not the actual IV }
procedure InitBlockCipher64(const Key; Size: longword; InitVector: pointer);
{ Do key setup based on the data in Key, size is in bits }
procedure EncryptCBC(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CBC method of encryption }
procedure DecryptCBC(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CBC method of decryption }
procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CFB (8 bit) method of encryption }
procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CFB (8 bit) method of decryption }
procedure EncryptCFBblock(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CFB (block) method of encryption }
procedure DecryptCFBblock(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CFB (block) method of decryption }
procedure EncryptOFB(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the OFB method of encryption }
procedure DecryptOFB(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the OFB method of decryption }
procedure EncryptCTR(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CTR method of encryption }
procedure DecryptCTR(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CTR method of decryption }
procedure EncryptECB(const Indata; var Outdata); virtual;
{ Override it! }
procedure DecryptECB(const Indata; var Outdata); virtual;
{ Override it! }
destructor Destroy; virtual;
end;
type
// PBlockCipher128 = ^TBlockCipher128;
TBlockCipher128 = object(TObj)
private
IV, CV: array[0..15] of byte;
procedure IncCounter;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Reset;
{ Reset any stored chaining information }
procedure Burn;
{ Clear all stored key information and chaining information }
procedure SetIV(const Value);
{ Sets the IV to Value and performs a reset }
procedure GetIV(var Value);
{ Returns the current chaining information, not the actual IV }
procedure InitBlockCipher128(const Key; Size: longword; InitVector: pointer);
{ Do key setup based on the data in Key, size is in bits }
procedure EncryptCBC(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CBC method of encryption }
procedure DecryptCBC(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CBC method of decryption }
procedure EncryptCFB8bit(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CFB (8 bit) method of encryption }
procedure DecryptCFB8bit(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CFB (8 bit) method of decryption }
procedure EncryptCFBblock(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CFB (block) method of encryption }
procedure DecryptCFBblock(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CFB (block) method of decryption }
procedure EncryptOFB(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the OFB method of encryption }
procedure DecryptOFB(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the OFB method of decryption }
procedure EncryptCTR(const Indata; var Outdata; Size: longword);
{ Encrypt size bytes of data using the CTR method of encryption }
procedure DecryptCTR(const Indata; var Outdata; Size: longword);
{ Decrypt size bytes of data using the CTR method of decryption }
procedure EncryptECB(const Indata; var Outdata); virtual;
{ Override it! }
procedure DecryptECB(const Indata; var Outdata); virtual;
{ Override it! }
destructor Destroy; virtual;
end;
//Blowfish cipher implementation
const
PBoxOrg: array[0..17] of DWORD = (
$243F6A88, $85A308D3, $13198A2E, $03707344,
$A4093822, $299F31D0, $082EFA98, $EC4E6C89,
$452821E6, $38D01377, $BE5466CF, $34E90C6C,
$C0AC29B7, $C97C50DD, $3F84D5B5, $B5470917,
$9216D5D9, $8979FB1B);
SBoxOrg: array[0..3, 0..255] of DWORD = ((
$D1310BA6, $98DFB5AC, $2FFD72DB, $D01ADFB7,
$B8E1AFED, $6A267E96, $BA7C9045, $F12C7F99,
$24A19947, $B3916CF7, $0801F2E2, $858EFC16,
$636920D8, $71574E69, $A458FEA3, $F4933D7E,
$0D95748F, $728EB658, $718BCD58, $82154AEE,
$7B54A41D, $C25A59B5, $9C30D539, $2AF26013,
$C5D1B023, $286085F0, $CA417918, $B8DB38EF,
$8E79DCB0, $603A180E, $6C9E0E8B, $B01E8A3E,
$D71577C1, $BD314B27, $78AF2FDA, $55605C60,
$E65525F3, $AA55AB94, $57489862, $63E81440,
$55CA396A, $2AAB10B6, $B4CC5C34, $1141E8CE,
$A15486AF, $7C72E993, $B3EE1411, $636FBC2A,
$2BA9C55D, $741831F6, $CE5C3E16, $9B87931E,
$AFD6BA33, $6C24CF5C, $7A325381, $28958677,
$3B8F4898, $6B4BB9AF, $C4BFE81B, $66282193,
$61D809CC, $FB21A991, $487CAC60, $5DEC8032,
$EF845D5D, $E98575B1, $DC262302, $EB651B88,
$23893E81, $D396ACC5, $0F6D6FF3, $83F44239,
$2E0B4482, $A4842004, $69C8F04A, $9E1F9B5E,
$21C66842, $F6E96C9A, $670C9C61, $ABD388F0,
$6A51A0D2, $D8542F68, $960FA728, $AB5133A3,
$6EEF0B6C, $137A3BE4, $BA3BF050, $7EFB2A98,
$A1F1651D, $39AF0176, $66CA593E, $82430E88,
$8CEE8619, $456F9FB4, $7D84A5C3, $3B8B5EBE,
$E06F75D8, $85C12073, $401A449F, $56C16AA6,
$4ED3AA62, $363F7706, $1BFEDF72, $429B023D,
$37D0D724, $D00A1248, $DB0FEAD3, $49F1C09B,
$075372C9, $80991B7B, $25D479D8, $F6E8DEF7,
$E3FE501A, $B6794C3B, $976CE0BD, $04C006BA,
$C1A94FB6, $409F60C4, $5E5C9EC2, $196A2463,
$68FB6FAF, $3E6C53B5, $1339B2EB, $3B52EC6F,
$6DFC511F, $9B30952C, $CC814544, $AF5EBD09,
$BEE3D004, $DE334AFD, $660F2807, $192E4BB3,
$C0CBA857, $45C8740F, $D20B5F39, $B9D3FBDB,
$5579C0BD, $1A60320A, $D6A100C6, $402C7279,
$679F25FE, $FB1FA3CC, $8EA5E9F8, $DB3222F8,
$3C7516DF, $FD616B15, $2F501EC8, $AD0552AB,
$323DB5FA, $FD238760, $53317B48, $3E00DF82,
$9E5C57BB, $CA6F8CA0, $1A87562E, $DF1769DB,
$D542A8F6, $287EFFC3, $AC6732C6, $8C4F5573,
$695B27B0, $BBCA58C8, $E1FFA35D, $B8F011A0,
$10FA3D98, $FD2183B8, $4AFCB56C, $2DD1D35B,
$9A53E479, $B6F84565, $D28E49BC, $4BFB9790,
$E1DDF2DA, $A4CB7E33, $62FB1341, $CEE4C6E8,
$EF20CADA, $36774C01, $D07E9EFE, $2BF11FB4,
$95DBDA4D, $AE909198, $EAAD8E71, $6B93D5A0,
$D08ED1D0, $AFC725E0, $8E3C5B2F, $8E7594B7,
$8FF6E2FB, $F2122B64, $8888B812, $900DF01C,
$4FAD5EA0, $688FC31C, $D1CFF191, $B3A8C1AD,
$2F2F2218, $BE0E1777, $EA752DFE, $8B021FA1,
$E5A0CC0F, $B56F74E8, $18ACF3D6, $CE89E299,
$B4A84FE0, $FD13E0B7, $7CC43B81, $D2ADA8D9,
$165FA266, $80957705, $93CC7314, $211A1477,
$E6AD2065, $77B5FA86, $C75442F5, $FB9D35CF,
$EBCDAF0C, $7B3E89A0, $D6411BD3, $AE1E7E49,
$00250E2D, $2071B35E, $226800BB, $57B8E0AF,
$2464369B, $F009B91E, $5563911D, $59DFA6AA,
$78C14389, $D95A537F, $207D5BA2, $02E5B9C5,
$83260376, $6295CFA9, $11C81968, $4E734A41,
$B3472DCA, $7B14A94A, $1B510052, $9A532915,
$D60F573F, $BC9BC6E4, $2B60A476, $81E67400,
$08BA6FB5, $571BE91F, $F296EC6B, $2A0DD915,
$B6636521, $E7B9F9B6, $FF34052E, $C5855664,
$53B02D5D, $A99F8FA1, $08BA4799, $6E85076A), (
$4B7A70E9, $B5B32944, $DB75092E, $C4192623,
$AD6EA6B0, $49A7DF7D, $9CEE60B8, $8FEDB266,
$ECAA8C71, $699A17FF, $5664526C, $C2B19EE1,
$193602A5, $75094C29, $A0591340, $E4183A3E,
$3F54989A, $5B429D65, $6B8FE4D6, $99F73FD6,
$A1D29C07, $EFE830F5, $4D2D38E6, $F0255DC1,
$4CDD2086, $8470EB26, $6382E9C6, $021ECC5E,
$09686B3F, $3EBAEFC9, $3C971814, $6B6A70A1,
$687F3584, $52A0E286, $B79C5305, $AA500737,
$3E07841C, $7FDEAE5C, $8E7D44EC, $5716F2B8,
$B03ADA37, $F0500C0D, $F01C1F04, $0200B3FF,
$AE0CF51A, $3CB574B2, $25837A58, $DC0921BD,
$D19113F9, $7CA92FF6, $94324773, $22F54701,
$3AE5E581, $37C2DADC, $C8B57634, $9AF3DDA7,
$A9446146, $0FD0030E, $ECC8C73E, $A4751E41,
$E238CD99, $3BEA0E2F, $3280BBA1, $183EB331,
$4E548B38, $4F6DB908, $6F420D03, $F60A04BF,
$2CB81290, $24977C79, $5679B072, $BCAF89AF,
$DE9A771F, $D9930810, $B38BAE12, $DCCF3F2E,
$5512721F, $2E6B7124, $501ADDE6, $9F84CD87,
$7A584718, $7408DA17, $BC9F9ABC, $E94B7D8C,
$EC7AEC3A, $DB851DFA, $63094366, $C464C3D2,
$EF1C1847, $3215D908, $DD433B37, $24C2BA16,
$12A14D43, $2A65C451, $50940002, $133AE4DD,
$71DFF89E, $10314E55, $81AC77D6, $5F11199B,
$043556F1, $D7A3C76B, $3C11183B, $5924A509,
$F28FE6ED, $97F1FBFA, $9EBABF2C, $1E153C6E,
$86E34570, $EAE96FB1, $860E5E0A, $5A3E2AB3,
$771FE71C, $4E3D06FA, $2965DCB9, $99E71D0F,
$803E89D6, $5266C825, $2E4CC978, $9C10B36A,
$C6150EBA, $94E2EA78, $A5FC3C53, $1E0A2DF4,
$F2F74EA7, $361D2B3D, $1939260F, $19C27960,
$5223A708, $F71312B6, $EBADFE6E, $EAC31F66,
$E3BC4595, $A67BC883, $B17F37D1, $018CFF28,
$C332DDEF, $BE6C5AA5, $65582185, $68AB9802,
$EECEA50F, $DB2F953B, $2AEF7DAD, $5B6E2F84,
$1521B628, $29076170, $ECDD4775, $619F1510,
$13CCA830, $EB61BD96, $0334FE1E, $AA0363CF,
$B5735C90, $4C70A239, $D59E9E0B, $CBAADE14,
$EECC86BC, $60622CA7, $9CAB5CAB, $B2F3846E,
$648B1EAF, $19BDF0CA, $A02369B9, $655ABB50,
$40685A32, $3C2AB4B3, $319EE9D5, $C021B8F7,
$9B540B19, $875FA099, $95F7997E, $623D7DA8,
$F837889A, $97E32D77, $11ED935F, $16681281,
$0E358829, $C7E61FD6, $96DEDFA1, $7858BA99,
$57F584A5, $1B227263, $9B83C3FF, $1AC24696,
$CDB30AEB, $532E3054, $8FD948E4, $6DBC3128,
$58EBF2EF, $34C6FFEA, $FE28ED61, $EE7C3C73,
$5D4A14D9, $E864B7E3, $42105D14, $203E13E0,
$45EEE2B6, $A3AAABEA, $DB6C4F15, $FACB4FD0,
$C742F442, $EF6ABBB5, $654F3B1D, $41CD2105,
$D81E799E, $86854DC7, $E44B476A, $3D816250,
$CF62A1F2, $5B8D2646, $FC8883A0, $C1C7B6A3,
$7F1524C3, $69CB7492, $47848A0B, $5692B285,
$095BBF00, $AD19489D, $1462B174, $23820E00,
$58428D2A, $0C55F5EA, $1DADF43E, $233F7061,
$3372F092, $8D937E41, $D65FECF1, $6C223BDB,
$7CDE3759, $CBEE7460, $4085F2A7, $CE77326E,
$A6078084, $19F8509E, $E8EFD855, $61D99735,
$A969A7AA, $C50C06C2, $5A04ABFC, $800BCADC,
$9E447A2E, $C3453484, $FDD56705, $0E1E9EC9,
$DB73DBD3, $105588CD, $675FDA79, $E3674340,
$C5C43465, $713E38D8, $3D28F89E, $F16DFF20,
$153E21E7, $8FB03D4A, $E6E39F2B, $DB83ADF7), (
$E93D5A68, $948140F7, $F64C261C, $94692934,
$411520F7, $7602D4F7, $BCF46B2E, $D4A20068,
$D4082471, $3320F46A, $43B7D4B7, $500061AF,
$1E39F62E, $97244546, $14214F74, $BF8B8840,
$4D95FC1D, $96B591AF, $70F4DDD3, $66A02F45,
$BFBC09EC, $03BD9785, $7FAC6DD0, $31CB8504,
$96EB27B3, $55FD3941, $DA2547E6, $ABCA0A9A,
$28507825, $530429F4, $0A2C86DA, $E9B66DFB,
$68DC1462, $D7486900, $680EC0A4, $27A18DEE,
$4F3FFEA2, $E887AD8C, $B58CE006, $7AF4D6B6,
$AACE1E7C, $D3375FEC, $CE78A399, $406B2A42,
$20FE9E35, $D9F385B9, $EE39D7AB, $3B124E8B,
$1DC9FAF7, $4B6D1856, $26A36631, $EAE397B2,
$3A6EFA74, $DD5B4332, $6841E7F7, $CA7820FB,
$FB0AF54E, $D8FEB397, $454056AC, $BA489527,
$55533A3A, $20838D87, $FE6BA9B7, $D096954B,
$55A867BC, $A1159A58, $CCA92963, $99E1DB33,
$A62A4A56, $3F3125F9, $5EF47E1C, $9029317C,
$FDF8E802, $04272F70, $80BB155C, $05282CE3,
$95C11548, $E4C66D22, $48C1133F, $C70F86DC,
$07F9C9EE, $41041F0F, $404779A4, $5D886E17,
$325F51EB, $D59BC0D1, $F2BCC18F, $41113564,
$257B7834, $602A9C60, $DFF8E8A3, $1F636C1B,
$0E12B4C2, $02E1329E, $AF664FD1, $CAD18115,
$6B2395E0, $333E92E1, $3B240B62, $EEBEB922,
$85B2A20E, $E6BA0D99, $DE720C8C, $2DA2F728,
$D0127845, $95B794FD, $647D0862, $E7CCF5F0,
$5449A36F, $877D48FA, $C39DFD27, $F33E8D1E,
$0A476341, $992EFF74, $3A6F6EAB, $F4F8FD37,
$A812DC60, $A1EBDDF8, $991BE14C, $DB6E6B0D,
$C67B5510, $6D672C37, $2765D43B, $DCD0E804,
$F1290DC7, $CC00FFA3, $B5390F92, $690FED0B,
$667B9FFB, $CEDB7D9C, $A091CF0B, $D9155EA3,
$BB132F88, $515BAD24, $7B9479BF, $763BD6EB,
$37392EB3, $CC115979, $8026E297, $F42E312D,
$6842ADA7, $C66A2B3B, $12754CCC, $782EF11C,
$6A124237, $B79251E7, $06A1BBE6, $4BFB6350,
$1A6B1018, $11CAEDFA, $3D25BDD8, $E2E1C3C9,
$44421659, $0A121386, $D90CEC6E, $D5ABEA2A,
$64AF674E, $DA86A85F, $BEBFE988, $64E4C3FE,
$9DBC8057, $F0F7C086, $60787BF8, $6003604D,
$D1FD8346, $F6381FB0, $7745AE04, $D736FCCC,
$83426B33, $F01EAB71, $B0804187, $3C005E5F,
$77A057BE, $BDE8AE24, $55464299, $BF582E61,
$4E58F48F, $F2DDFDA2, $F474EF38, $8789BDC2,
$5366F9C3, $C8B38E74, $B475F255, $46FCD9B9,
$7AEB2661, $8B1DDF84, $846A0E79, $915F95E2,
$466E598E, $20B45770, $8CD55591, $C902DE4C,
$B90BACE1, $BB8205D0, $11A86248, $7574A99E,
$B77F19B6, $E0A9DC09, $662D09A1, $C4324633,
$E85A1F02, $09F0BE8C, $4A99A025, $1D6EFE10,
$1AB93D1D, $0BA5A4DF, $A186F20F, $2868F169,
$DCB7DA83, $573906FE, $A1E2CE9B, $4FCD7F52,
$50115E01, $A70683FA, $A002B5C4, $0DE6D027,
$9AF88C27, $773F8641, $C3604C06, $61A806B5,
$F0177A28, $C0F586E0, $006058AA, $30DC7D62,
$11E69ED7, $2338EA63, $53C2DD94, $C2C21634,
$BBCBEE56, $90BCB6DE, $EBFC7DA1, $CE591D76,
$6F05E409, $4B7C0188, $39720A3D, $7C927C24,
$86E3725F, $724D9DB9, $1AC15BB4, $D39EB8FC,
$ED545578, $08FCA5B5, $D83D7CD3, $4DAD0FC4,
$1E50EF5E, $B161E6F8, $A28514D9, $6C51133C,
$6FD5C7E7, $56E14EC4, $362ABFCE, $DDC6C837,
$D79A3234, $92638212, $670EFA8E, $406000E0), (
$3A39CE37, $D3FAF5CF, $ABC27737, $5AC52D1B,
$5CB0679E, $4FA33742, $D3822740, $99BC9BBE,
$D5118E9D, $BF0F7315, $D62D1C7E, $C700C47B,
$B78C1B6B, $21A19045, $B26EB1BE, $6A366EB4,
$5748AB2F, $BC946E79, $C6A376D2, $6549C2C8,
$530FF8EE, $468DDE7D, $D5730A1D, $4CD04DC6,
$2939BBDB, $A9BA4650, $AC9526E8, $BE5EE304,
$A1FAD5F0, $6A2D519A, $63EF8CE2, $9A86EE22,
$C089C2B8, $43242EF6, $A51E03AA, $9CF2D0A4,
$83C061BA, $9BE96A4D, $8FE51550, $BA645BD6,
$2826A2F9, $A73A3AE1, $4BA99586, $EF5562E9,
$C72FEFD3, $F752F7DA, $3F046F69, $77FA0A59,
$80E4A915, $87B08601, $9B09E6AD, $3B3EE593,
$E990FD5A, $9E34D797, $2CF0B7D9, $022B8B51,
$96D5AC3A, $017DA67D, $D1CF3ED6, $7C7D2D28,
$1F9F25CF, $ADF2B89B, $5AD6B472, $5A88F54C,
$E029AC71, $E019A5E6, $47B0ACFD, $ED93FA9B,
$E8D3C48D, $283B57CC, $F8D56629, $79132E28,
$785F0191, $ED756055, $F7960E44, $E3D35E8C,
$15056DD4, $88F46DBA, $03A16125, $0564F0BD,
$C3EB9E15, $3C9057A2, $97271AEC, $A93A072A,
$1B3F6D9B, $1E6321F5, $F59C66FB, $26DCF319,
$7533D928, $B155FDF5, $03563482, $8ABA3CBB,
$28517711, $C20AD9F8, $ABCC5167, $CCAD925F,
$4DE81751, $3830DC8E, $379D5862, $9320F991,
$EA7A90C2, $FB3E7BCE, $5121CE64, $774FBE32,
$A8B6E37E, $C3293D46, $48DE5369, $6413E680,
$A2AE0810, $DD6DB224, $69852DFD, $09072166,
$B39A460A, $6445C0DD, $586CDECF, $1C20C8AE,
$5BBEF7DD, $1B588D40, $CCD2017F, $6BB4E3BB,
$DDA26A7E, $3A59FF45, $3E350A44, $BCB4CDD5,
$72EACEA8, $FA6484BB, $8D6612AE, $BF3C6F47,
$D29BE463, $542F5D9E, $AEC2771B, $F64E6370,
$740E0D8D, $E75B1357, $F8721671, $AF537D5D,
$4040CB08, $4EB4E2CC, $34D2466A, $0115AF84,
$E1B00428, $95983A1D, $06B89FB4, $CE6EA048,
$6F3F3B82, $3520AB82, $011A1D4B, $277227F8,
$611560B1, $E7933FDC, $BB3A792B, $344525BD,
$A08839E1, $51CE794B, $2F32C9B7, $A01FBAC9,
$E01CC87E, $BCC7D1F6, $CF0111C3, $A1E8AAC7,
$1A908749, $D44FBD9A, $D0DADECB, $D50ADA38,
$0339C32A, $C6913667, $8DF9317C, $E0B12B4F,
$F79E59B7, $43F5BB3A, $F2D519FF, $27D9459C,
$BF97222C, $15E6FC2A, $0F91FC71, $9B941525,
$FAE59361, $CEB69CEB, $C2A86459, $12BAA8D1,
$B6C1075E, $E3056A0C, $10D25065, $CB03A442,
$E0EC6E0E, $1698DB3B, $4C98A0BE, $3278E964,
$9F1F9532, $E0D392DF, $D3A0342B, $8971F21E,
$1B0A7441, $4BA3348C, $C5BE7120, $C37632D8,
$DF359F8D, $9B992F2E, $E60B6F47, $0FE3F11D,
$E54CDA54, $1EDAD891, $CE6279CF, $CD3E7E6F,
$1618B166, $FD2C1D05, $848FD2C5, $F6FB2299,
$F523F357, $A6327623, $93A83531, $56CCCD02,
$ACF08162, $5A75EBB5, $6E163697, $88D273CC,
$DE966292, $81B949D0, $4C50901B, $71C65614,
$E6C6C7BD, $327A140A, $45E1D006, $C3F27B9A,
$C9AA53FD, $62A80F00, $BB25BFE2, $35BDD2F6,
$71126905, $B2040222, $B6CBCF7C, $CD769C2B,
$53113EC0, $1640E3D3, $38ABBD60, $2547ADF0,
$BA38209C, $F746CE76, $77AFA1C5, $20756060,
$85CBFE4E, $8AE88DD8, $7AAAF9B0, $4CF9AA7E,
$1948C25C, $02FB8A8C, $01C36AE4, $D6EBE1F9,
$90D4F869, $A65CDEA0, $3F09252D, $C208E69F,
$B74E6132, $CE77E25B, $578FDFE3, $3AC372E6));
type
PByteArray = ^TByteArray;
TByteArray = array[0..32767] of byte;
type
PBlowfish = ^TBlowfish;
TBlowfish = object(TBlockCipher64)
protected
SBox: array[0..3, 0..255] of DWORD;
PBox: array[0..17] of DWORD;
public
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//Cast128 cipher implementation
const
cast_sbox1: array[0..255] of DWORD = (
$30FB40D4, $9FA0FF0B, $6BECCD2F, $3F258C7A,
$1E213F2F, $9C004DD3, $6003E540, $CF9FC949,
$BFD4AF27, $88BBBDB5, $E2034090, $98D09675,
$6E63A0E0, $15C361D2, $C2E7661D, $22D4FF8E,
$28683B6F, $C07FD059, $FF2379C8, $775F50E2,
$43C340D3, $DF2F8656, $887CA41A, $A2D2BD2D,
$A1C9E0D6, $346C4819, $61B76D87, $22540F2F,
$2ABE32E1, $AA54166B, $22568E3A, $A2D341D0,
$66DB40C8, $A784392F, $004DFF2F, $2DB9D2DE,
$97943FAC, $4A97C1D8, $527644B7, $B5F437A7,
$B82CBAEF, $D751D159, $6FF7F0ED, $5A097A1F,
$827B68D0, $90ECF52E, $22B0C054, $BC8E5935,
$4B6D2F7F, $50BB64A2, $D2664910, $BEE5812D,
$B7332290, $E93B159F, $B48EE411, $4BFF345D,
$FD45C240, $AD31973F, $C4F6D02E, $55FC8165,
$D5B1CAAD, $A1AC2DAE, $A2D4B76D, $C19B0C50,
$882240F2, $0C6E4F38, $A4E4BFD7, $4F5BA272,
$564C1D2F, $C59C5319, $B949E354, $B04669FE,
$B1B6AB8A, $C71358DD, $6385C545, $110F935D,
$57538AD5, $6A390493, $E63D37E0, $2A54F6B3,
$3A787D5F, $6276A0B5, $19A6FCDF, $7A42206A,
$29F9D4D5, $F61B1891, $BB72275E, $AA508167,
$38901091, $C6B505EB, $84C7CB8C, $2AD75A0F,
$874A1427, $A2D1936B, $2AD286AF, $AA56D291,
$D7894360, $425C750D, $93B39E26, $187184C9,
$6C00B32D, $73E2BB14, $A0BEBC3C, $54623779,
$64459EAB, $3F328B82, $7718CF82, $59A2CEA6,
$04EE002E, $89FE78E6, $3FAB0950, $325FF6C2,
$81383F05, $6963C5C8, $76CB5AD6, $D49974C9,
$CA180DCF, $380782D5, $C7FA5CF6, $8AC31511,
$35E79E13, $47DA91D0, $F40F9086, $A7E2419E,
$31366241, $051EF495, $AA573B04, $4A805D8D,
$548300D0, $00322A3C, $BF64CDDF, $BA57A68E,
$75C6372B, $50AFD341, $A7C13275, $915A0BF5,
$6B54BFAB, $2B0B1426, $AB4CC9D7, $449CCD82,
$F7FBF265, $AB85C5F3, $1B55DB94, $AAD4E324,
$CFA4BD3F, $2DEAA3E2, $9E204D02, $C8BD25AC,
$EADF55B3, $D5BD9E98, $E31231B2, $2AD5AD6C,
$954329DE, $ADBE4528, $D8710F69, $AA51C90F,
$AA786BF6, $22513F1E, $AA51A79B, $2AD344CC,
$7B5A41F0, $D37CFBAD, $1B069505, $41ECE491,
$B4C332E6, $032268D4, $C9600ACC, $CE387E6D,
$BF6BB16C, $6A70FB78, $0D03D9C9, $D4DF39DE,
$E01063DA, $4736F464, $5AD328D8, $B347CC96,
$75BB0FC3, $98511BFB, $4FFBCC35, $B58BCF6A,
$E11F0ABC, $BFC5FE4A, $A70AEC10, $AC39570A,
$3F04442F, $6188B153, $E0397A2E, $5727CB79,
$9CEB418F, $1CACD68D, $2AD37C96, $0175CB9D,
$C69DFF09, $C75B65F0, $D9DB40D8, $EC0E7779,
$4744EAD4, $B11C3274, $DD24CB9E, $7E1C54BD,
$F01144F9, $D2240EB1, $9675B3FD, $A3AC3755,
$D47C27AF, $51C85F4D, $56907596, $A5BB15E6,
$580304F0, $CA042CF1, $011A37EA, $8DBFAADB,
$35BA3E4A, $3526FFA0, $C37B4D09, $BC306ED9,
$98A52666, $5648F725, $FF5E569D, $0CED63D0,
$7C63B2CF, $700B45E1, $D5EA50F1, $85A92872,
$AF1FBDA7, $D4234870, $A7870BF3, $2D3B4D79,
$42E04198, $0CD0EDE7, $26470DB8, $F881814C,
$474D6AD7, $7C0C5E5C, $D1231959, $381B7298,
$F5D2F4DB, $AB838653, $6E2F1E23, $83719C9E,
$BD91E046, $9A56456E, $DC39200C, $20C8C571,
$962BDA1C, $E1E696FF, $B141AB08, $7CCA89B9,
$1A69E783, $02CC4843, $A2F7C579, $429EF47D,
$427B169C, $5AC9F049, $DD8F0F00, $5C8165BF
);
cast_sbox2: array[0..255] of DWORD = (
$1F201094, $EF0BA75B, $69E3CF7E, $393F4380,
$FE61CF7A, $EEC5207A, $55889C94, $72FC0651,
$ADA7EF79, $4E1D7235, $D55A63CE, $DE0436BA,
$99C430EF, $5F0C0794, $18DCDB7D, $A1D6EFF3,
$A0B52F7B, $59E83605, $EE15B094, $E9FFD909,
$DC440086, $EF944459, $BA83CCB3, $E0C3CDFB,
$D1DA4181, $3B092AB1, $F997F1C1, $A5E6CF7B,
$01420DDB, $E4E7EF5B, $25A1FF41, $E180F806,
$1FC41080, $179BEE7A, $D37AC6A9, $FE5830A4,
$98DE8B7F, $77E83F4E, $79929269, $24FA9F7B,
$E113C85B, $ACC40083, $D7503525, $F7EA615F,
$62143154, $0D554B63, $5D681121, $C866C359,
$3D63CF73, $CEE234C0, $D4D87E87, $5C672B21,
$071F6181, $39F7627F, $361E3084, $E4EB573B,
$602F64A4, $D63ACD9C, $1BBC4635, $9E81032D,
$2701F50C, $99847AB4, $A0E3DF79, $BA6CF38C,
$10843094, $2537A95E, $F46F6FFE, $A1FF3B1F,
$208CFB6A, $8F458C74, $D9E0A227, $4EC73A34,
$FC884F69, $3E4DE8DF, $EF0E0088, $3559648D,
$8A45388C, $1D804366, $721D9BFD, $A58684BB,
$E8256333, $844E8212, $128D8098, $FED33FB4,
$CE280AE1, $27E19BA5, $D5A6C252, $E49754BD,
$C5D655DD, $EB667064, $77840B4D, $A1B6A801,
$84DB26A9, $E0B56714, $21F043B7, $E5D05860,
$54F03084, $066FF472, $A31AA153, $DADC4755,
$B5625DBF, $68561BE6, $83CA6B94, $2D6ED23B,
$ECCF01DB, $A6D3D0BA, $B6803D5C, $AF77A709,
$33B4A34C, $397BC8D6, $5EE22B95, $5F0E5304,
$81ED6F61, $20E74364, $B45E1378, $DE18639B,
$881CA122, $B96726D1, $8049A7E8, $22B7DA7B,
$5E552D25, $5272D237, $79D2951C, $C60D894C,
$488CB402, $1BA4FE5B, $A4B09F6B, $1CA815CF,
$A20C3005, $8871DF63, $B9DE2FCB, $0CC6C9E9,
$0BEEFF53, $E3214517, $B4542835, $9F63293C,
$EE41E729, $6E1D2D7C, $50045286, $1E6685F3,
$F33401C6, $30A22C95, $31A70850, $60930F13,
$73F98417, $A1269859, $EC645C44, $52C877A9,
$CDFF33A6, $A02B1741, $7CBAD9A2, $2180036F,
$50D99C08, $CB3F4861, $C26BD765, $64A3F6AB,
$80342676, $25A75E7B, $E4E6D1FC, $20C710E6,
$CDF0B680, $17844D3B, $31EEF84D, $7E0824E4,
$2CCB49EB, $846A3BAE, $8FF77888, $EE5D60F6,
$7AF75673, $2FDD5CDB, $A11631C1, $30F66F43,
$B3FAEC54, $157FD7FA, $EF8579CC, $D152DE58,
$DB2FFD5E, $8F32CE19, $306AF97A, $02F03EF8,
$99319AD5, $C242FA0F, $A7E3EBB0, $C68E4906,
$B8DA230C, $80823028, $DCDEF3C8, $D35FB171,
$088A1BC8, $BEC0C560, $61A3C9E8, $BCA8F54D,
$C72FEFFA, $22822E99, $82C570B4, $D8D94E89,
$8B1C34BC, $301E16E6, $273BE979, $B0FFEAA6,
$61D9B8C6, $00B24869, $B7FFCE3F, $08DC283B,
$43DAF65A, $F7E19798, $7619B72F, $8F1C9BA4,
$DC8637A0, $16A7D3B1, $9FC393B7, $A7136EEB,
$C6BCC63E, $1A513742, $EF6828BC, $520365D6,
$2D6A77AB, $3527ED4B, $821FD216, $095C6E2E,
$DB92F2FB, $5EEA29CB, $145892F5, $91584F7F,
$5483697B, $2667A8CC, $85196048, $8C4BACEA,
$833860D4, $0D23E0F9, $6C387E8A, $0AE6D249,
$B284600C, $D835731D, $DCB1C647, $AC4C56EA,
$3EBD81B3, $230EABB0, $6438BC87, $F0B5B1FA,
$8F5EA2B3, $FC184642, $0A036B7A, $4FB089BD,
$649DA589, $A345415E, $5C038323, $3E5D3BB9,
$43D79572, $7E6DD07C, $06DFDF1E, $6C6CC4EF,
$7160A539, $73BFBE70, $83877605, $4523ECF1
);
cast_sbox3: array[0..255] of DWORD = (
$8DEFC240, $25FA5D9F, $EB903DBF, $E810C907,
$47607FFF, $369FE44B, $8C1FC644, $AECECA90,
$BEB1F9BF, $EEFBCAEA, $E8CF1950, $51DF07AE,
$920E8806, $F0AD0548, $E13C8D83, $927010D5,
$11107D9F, $07647DB9, $B2E3E4D4, $3D4F285E,
$B9AFA820, $FADE82E0, $A067268B, $8272792E,
$553FB2C0, $489AE22B, $D4EF9794, $125E3FBC,
$21FFFCEE, $825B1BFD, $9255C5ED, $1257A240,
$4E1A8302, $BAE07FFF, $528246E7, $8E57140E,
$3373F7BF, $8C9F8188, $A6FC4EE8, $C982B5A5,
$A8C01DB7, $579FC264, $67094F31, $F2BD3F5F,
$40FFF7C1, $1FB78DFC, $8E6BD2C1, $437BE59B,
$99B03DBF, $B5DBC64B, $638DC0E6, $55819D99,
$A197C81C, $4A012D6E, $C5884A28, $CCC36F71,
$B843C213, $6C0743F1, $8309893C, $0FEDDD5F,
$2F7FE850, $D7C07F7E, $02507FBF, $5AFB9A04,
$A747D2D0, $1651192E, $AF70BF3E, $58C31380,
$5F98302E, $727CC3C4, $0A0FB402, $0F7FEF82,
$8C96FDAD, $5D2C2AAE, $8EE99A49, $50DA88B8,
$8427F4A0, $1EAC5790, $796FB449, $8252DC15,
$EFBD7D9B, $A672597D, $ADA840D8, $45F54504,
$FA5D7403, $E83EC305, $4F91751A, $925669C2,
$23EFE941, $A903F12E, $60270DF2, $0276E4B6,
$94FD6574, $927985B2, $8276DBCB, $02778176,
$F8AF918D, $4E48F79E, $8F616DDF, $E29D840E,
$842F7D83, $340CE5C8, $96BBB682, $93B4B148,
$EF303CAB, $984FAF28, $779FAF9B, $92DC560D,
$224D1E20, $8437AA88, $7D29DC96, $2756D3DC,
$8B907CEE, $B51FD240, $E7C07CE3, $E566B4A1,
$C3E9615E, $3CF8209D, $6094D1E3, $CD9CA341,
$5C76460E, $00EA983B, $D4D67881, $FD47572C,
$F76CEDD9, $BDA8229C, $127DADAA, $438A074E,
$1F97C090, $081BDB8A, $93A07EBE, $B938CA15,
$97B03CFF, $3DC2C0F8, $8D1AB2EC, $64380E51,
$68CC7BFB, $D90F2788, $12490181, $5DE5FFD4,
$DD7EF86A, $76A2E214, $B9A40368, $925D958F,
$4B39FFFA, $BA39AEE9, $A4FFD30B, $FAF7933B,
$6D498623, $193CBCFA, $27627545, $825CF47A,
$61BD8BA0, $D11E42D1, $CEAD04F4, $127EA392,
$10428DB7, $8272A972, $9270C4A8, $127DE50B,
$285BA1C8, $3C62F44F, $35C0EAA5, $E805D231,
$428929FB, $B4FCDF82, $4FB66A53, $0E7DC15B,
$1F081FAB, $108618AE, $FCFD086D, $F9FF2889,
$694BCC11, $236A5CAE, $12DECA4D, $2C3F8CC5,
$D2D02DFE, $F8EF5896, $E4CF52DA, $95155B67,
$494A488C, $B9B6A80C, $5C8F82BC, $89D36B45,
$3A609437, $EC00C9A9, $44715253, $0A874B49,
$D773BC40, $7C34671C, $02717EF6, $4FEB5536,
$A2D02FFF, $D2BF60C4, $D43F03C0, $50B4EF6D,
$07478CD1, $006E1888, $A2E53F55, $B9E6D4BC,
$A2048016, $97573833, $D7207D67, $DE0F8F3D,
$72F87B33, $ABCC4F33, $7688C55D, $7B00A6B0,
$947B0001, $570075D2, $F9BB88F8, $8942019E,
$4264A5FF, $856302E0, $72DBD92B, $EE971B69,
$6EA22FDE, $5F08AE2B, $AF7A616D, $E5C98767,
$CF1FEBD2, $61EFC8C2, $F1AC2571, $CC8239C2,
$67214CB8, $B1E583D1, $B7DC3E62, $7F10BDCE,
$F90A5C38, $0FF0443D, $606E6DC6, $60543A49,
$5727C148, $2BE98A1D, $8AB41738, $20E1BE24,
$AF96DA0F, $68458425, $99833BE5, $600D457D,
$282F9350, $8334B362, $D91D1120, $2B6D8DA0,
$642B1E31, $9C305A00, $52BCE688, $1B03588A,
$F7BAEFD5, $4142ED9C, $A4315C11, $83323EC5,
$DFEF4636, $A133C501, $E9D3531C, $EE353783
);
cast_sbox4: array[0..255] of DWORD = (
$9DB30420, $1FB6E9DE, $A7BE7BEF, $D273A298,
$4A4F7BDB, $64AD8C57, $85510443, $FA020ED1,
$7E287AFF, $E60FB663, $095F35A1, $79EBF120,
$FD059D43, $6497B7B1, $F3641F63, $241E4ADF,
$28147F5F, $4FA2B8CD, $C9430040, $0CC32220,
$FDD30B30, $C0A5374F, $1D2D00D9, $24147B15,
$EE4D111A, $0FCA5167, $71FF904C, $2D195FFE,
$1A05645F, $0C13FEFE, $081B08CA, $05170121,
$80530100, $E83E5EFE, $AC9AF4F8, $7FE72701,
$D2B8EE5F, $06DF4261, $BB9E9B8A, $7293EA25,
$CE84FFDF, $F5718801, $3DD64B04, $A26F263B,
$7ED48400, $547EEBE6, $446D4CA0, $6CF3D6F5,
$2649ABDF, $AEA0C7F5, $36338CC1, $503F7E93,
$D3772061, $11B638E1, $72500E03, $F80EB2BB,
$ABE0502E, $EC8D77DE, $57971E81, $E14F6746,
$C9335400, $6920318F, $081DBB99, $FFC304A5,
$4D351805, $7F3D5CE3, $A6C866C6, $5D5BCCA9,
$DAEC6FEA, $9F926F91, $9F46222F, $3991467D,
$A5BF6D8E, $1143C44F, $43958302, $D0214EEB,
$022083B8, $3FB6180C, $18F8931E, $281658E6,
$26486E3E, $8BD78A70, $7477E4C1, $B506E07C,
$F32D0A25, $79098B02, $E4EABB81, $28123B23,
$69DEAD38, $1574CA16, $DF871B62, $211C40B7,
$A51A9EF9, $0014377B, $041E8AC8, $09114003,
$BD59E4D2, $E3D156D5, $4FE876D5, $2F91A340,
$557BE8DE, $00EAE4A7, $0CE5C2EC, $4DB4BBA6,
$E756BDFF, $DD3369AC, $EC17B035, $06572327,
$99AFC8B0, $56C8C391, $6B65811C, $5E146119,
$6E85CB75, $BE07C002, $C2325577, $893FF4EC,
$5BBFC92D, $D0EC3B25, $B7801AB7, $8D6D3B24,
$20C763EF, $C366A5FC, $9C382880, $0ACE3205,
$AAC9548A, $ECA1D7C7, $041AFA32, $1D16625A,
$6701902C, $9B757A54, $31D477F7, $9126B031,
$36CC6FDB, $C70B8B46, $D9E66A48, $56E55A79,
$026A4CEB, $52437EFF, $2F8F76B4, $0DF980A5,
$8674CDE3, $EDDA04EB, $17A9BE04, $2C18F4DF,
$B7747F9D, $AB2AF7B4, $EFC34D20, $2E096B7C,
$1741A254, $E5B6A035, $213D42F6, $2C1C7C26,
$61C2F50F, $6552DAF9, $D2C231F8, $25130F69,
$D8167FA2, $0418F2C8, $001A96A6, $0D1526AB,
$63315C21, $5E0A72EC, $49BAFEFD, $187908D9,
$8D0DBD86, $311170A7, $3E9B640C, $CC3E10D7,
$D5CAD3B6, $0CAEC388, $F73001E1, $6C728AFF,
$71EAE2A1, $1F9AF36E, $CFCBD12F, $C1DE8417,
$AC07BE6B, $CB44A1D8, $8B9B0F56, $013988C3,
$B1C52FCA, $B4BE31CD, $D8782806, $12A3A4E2,
$6F7DE532, $58FD7EB6, $D01EE900, $24ADFFC2,
$F4990FC5, $9711AAC5, $001D7B95, $82E5E7D2,
$109873F6, $00613096, $C32D9521, $ADA121FF,
$29908415, $7FBB977F, $AF9EB3DB, $29C9ED2A,
$5CE2A465, $A730F32C, $D0AA3FE8, $8A5CC091,
$D49E2CE7, $0CE454A9, $D60ACD86, $015F1919,
$77079103, $DEA03AF6, $78A8565E, $DEE356DF,
$21F05CBE, $8B75E387, $B3C50651, $B8A5C3EF,
$D8EEB6D2, $E523BE77, $C2154529, $2F69EFDF,
$AFE67AFB, $F470C4B2, $F3E0EB5B, $D6CC9876,
$39E4460C, $1FDA8538, $1987832F, $CA007367,
$A99144F8, $296B299E, $492FC295, $9266BEAB,
$B5676E69, $9BD3DDDA, $DF7E052F, $DB25701C,
$1B5E51EE, $F65324E6, $6AFCE36C, $0316CC04,
$8644213E, $B7DC59D0, $7965291F, $CCD6FD43,
$41823979, $932BCDF6, $B657C34D, $4EDFD282,
$7AE5290C, $3CB9536B, $851E20FE, $9833557E,
$13ECF0B0, $D3FFB372, $3F85C5C1, $0AEF7ED2
);
cast_sbox5: array[0..255] of DWORD = (
$7EC90C04, $2C6E74B9, $9B0E66DF, $A6337911,
$B86A7FFF, $1DD358F5, $44DD9D44, $1731167F,
$08FBF1FA, $E7F511CC, $D2051B00, $735ABA00,
$2AB722D8, $386381CB, $ACF6243A, $69BEFD7A,
$E6A2E77F, $F0C720CD, $C4494816, $CCF5C180,
$38851640, $15B0A848, $E68B18CB, $4CAADEFF,
$5F480A01, $0412B2AA, $259814FC, $41D0EFE2,
$4E40B48D, $248EB6FB, $8DBA1CFE, $41A99B02,
$1A550A04, $BA8F65CB, $7251F4E7, $95A51725,
$C106ECD7, $97A5980A, $C539B9AA, $4D79FE6A,
$F2F3F763, $68AF8040, $ED0C9E56, $11B4958B,
$E1EB5A88, $8709E6B0, $D7E07156, $4E29FEA7,
$6366E52D, $02D1C000, $C4AC8E05, $9377F571,
$0C05372A, $578535F2, $2261BE02, $D642A0C9,
$DF13A280, $74B55BD2, $682199C0, $D421E5EC,
$53FB3CE8, $C8ADEDB3, $28A87FC9, $3D959981,
$5C1FF900, $FE38D399, $0C4EFF0B, $062407EA,
$AA2F4FB1, $4FB96976, $90C79505, $B0A8A774,
$EF55A1FF, $E59CA2C2, $A6B62D27, $E66A4263,
$DF65001F, $0EC50966, $DFDD55BC, $29DE0655,
$911E739A, $17AF8975, $32C7911C, $89F89468,
$0D01E980, $524755F4, $03B63CC9, $0CC844B2,
$BCF3F0AA, $87AC36E9, $E53A7426, $01B3D82B,
$1A9E7449, $64EE2D7E, $CDDBB1DA, $01C94910,
$B868BF80, $0D26F3FD, $9342EDE7, $04A5C284,
$636737B6, $50F5B616, $F24766E3, $8ECA36C1,
$136E05DB, $FEF18391, $FB887A37, $D6E7F7D4,
$C7FB7DC9, $3063FCDF, $B6F589DE, $EC2941DA,
$26E46695, $B7566419, $F654EFC5, $D08D58B7,
$48925401, $C1BACB7F, $E5FF550F, $B6083049,
$5BB5D0E8, $87D72E5A, $AB6A6EE1, $223A66CE,
$C62BF3CD, $9E0885F9, $68CB3E47, $086C010F,
$A21DE820, $D18B69DE, $F3F65777, $FA02C3F6,
$407EDAC3, $CBB3D550, $1793084D, $B0D70EBA,
$0AB378D5, $D951FB0C, $DED7DA56, $4124BBE4,
$94CA0B56, $0F5755D1, $E0E1E56E, $6184B5BE,
$580A249F, $94F74BC0, $E327888E, $9F7B5561,
$C3DC0280, $05687715, $646C6BD7, $44904DB3,
$66B4F0A3, $C0F1648A, $697ED5AF, $49E92FF6,
$309E374F, $2CB6356A, $85808573, $4991F840,
$76F0AE02, $083BE84D, $28421C9A, $44489406,
$736E4CB8, $C1092910, $8BC95FC6, $7D869CF4,
$134F616F, $2E77118D, $B31B2BE1, $AA90B472,
$3CA5D717, $7D161BBA, $9CAD9010, $AF462BA2,
$9FE459D2, $45D34559, $D9F2DA13, $DBC65487,
$F3E4F94E, $176D486F, $097C13EA, $631DA5C7,
$445F7382, $175683F4, $CDC66A97, $70BE0288,
$B3CDCF72, $6E5DD2F3, $20936079, $459B80A5,
$BE60E2DB, $A9C23101, $EBA5315C, $224E42F2,
$1C5C1572, $F6721B2C, $1AD2FFF3, $8C25404E,
$324ED72F, $4067B7FD, $0523138E, $5CA3BC78,
$DC0FD66E, $75922283, $784D6B17, $58EBB16E,
$44094F85, $3F481D87, $FCFEAE7B, $77B5FF76,
$8C2302BF, $AAF47556, $5F46B02A, $2B092801,
$3D38F5F7, $0CA81F36, $52AF4A8A, $66D5E7C0,
$DF3B0874, $95055110, $1B5AD7A8, $F61ED5AD,
$6CF6E479, $20758184, $D0CEFA65, $88F7BE58,
$4A046826, $0FF6F8F3, $A09C7F70, $5346ABA0,
$5CE96C28, $E176EDA3, $6BAC307F, $376829D2,
$85360FA9, $17E3FE2A, $24B79767, $F5A96B20,
$D6CD2595, $68FF1EBF, $7555442C, $F19F06BE,
$F9E0659A, $EEB9491D, $34010718, $BB30CAB8,
$E822FE15, $88570983, $750E6249, $DA627E55,
$5E76FFA8, $B1534546, $6D47DE08, $EFE9E7D4
);
cast_sbox6: array[0..255] of DWORD = (
$F6FA8F9D, $2CAC6CE1, $4CA34867, $E2337F7C,
$95DB08E7, $016843B4, $ECED5CBC, $325553AC,
$BF9F0960, $DFA1E2ED, $83F0579D, $63ED86B9,
$1AB6A6B8, $DE5EBE39, $F38FF732, $8989B138,
$33F14961, $C01937BD, $F506C6DA, $E4625E7E,
$A308EA99, $4E23E33C, $79CBD7CC, $48A14367,
$A3149619, $FEC94BD5, $A114174A, $EAA01866,
$A084DB2D, $09A8486F, $A888614A, $2900AF98,
$01665991, $E1992863, $C8F30C60, $2E78EF3C,
$D0D51932, $CF0FEC14, $F7CA07D2, $D0A82072,
$FD41197E, $9305A6B0, $E86BE3DA, $74BED3CD,
$372DA53C, $4C7F4448, $DAB5D440, $6DBA0EC3,
$083919A7, $9FBAEED9, $49DBCFB0, $4E670C53,
$5C3D9C01, $64BDB941, $2C0E636A, $BA7DD9CD,
$EA6F7388, $E70BC762, $35F29ADB, $5C4CDD8D,
$F0D48D8C, $B88153E2, $08A19866, $1AE2EAC8,
$284CAF89, $AA928223, $9334BE53, $3B3A21BF,
$16434BE3, $9AEA3906, $EFE8C36E, $F890CDD9,
$80226DAE, $C340A4A3, $DF7E9C09, $A694A807,
$5B7C5ECC, $221DB3A6, $9A69A02F, $68818A54,
$CEB2296F, $53C0843A, $FE893655, $25BFE68A,
$B4628ABC, $CF222EBF, $25AC6F48, $A9A99387,
$53BDDB65, $E76FFBE7, $E967FD78, $0BA93563,
$8E342BC1, $E8A11BE9, $4980740D, $C8087DFC,
$8DE4BF99, $A11101A0, $7FD37975, $DA5A26C0,
$E81F994F, $9528CD89, $FD339FED, $B87834BF,
$5F04456D, $22258698, $C9C4C83B, $2DC156BE,
$4F628DAA, $57F55EC5, $E2220ABE, $D2916EBF,
$4EC75B95, $24F2C3C0, $42D15D99, $CD0D7FA0,
$7B6E27FF, $A8DC8AF0, $7345C106, $F41E232F,
$35162386, $E6EA8926, $3333B094, $157EC6F2,
$372B74AF, $692573E4, $E9A9D848, $F3160289,
$3A62EF1D, $A787E238, $F3A5F676, $74364853,
$20951063, $4576698D, $B6FAD407, $592AF950,
$36F73523, $4CFB6E87, $7DA4CEC0, $6C152DAA,
$CB0396A8, $C50DFE5D, $FCD707AB, $0921C42F,
$89DFF0BB, $5FE2BE78, $448F4F33, $754613C9,
$2B05D08D, $48B9D585, $DC049441, $C8098F9B,
$7DEDE786, $C39A3373, $42410005, $6A091751,
$0EF3C8A6, $890072D6, $28207682, $A9A9F7BE,
$BF32679D, $D45B5B75, $B353FD00, $CBB0E358,
$830F220A, $1F8FB214, $D372CF08, $CC3C4A13,
$8CF63166, $061C87BE, $88C98F88, $6062E397,
$47CF8E7A, $B6C85283, $3CC2ACFB, $3FC06976,
$4E8F0252, $64D8314D, $DA3870E3, $1E665459,
$C10908F0, $513021A5, $6C5B68B7, $822F8AA0,
$3007CD3E, $74719EEF, $DC872681, $073340D4,
$7E432FD9, $0C5EC241, $8809286C, $F592D891,
$08A930F6, $957EF305, $B7FBFFBD, $C266E96F,
$6FE4AC98, $B173ECC0, $BC60B42A, $953498DA,
$FBA1AE12, $2D4BD736, $0F25FAAB, $A4F3FCEB,
$E2969123, $257F0C3D, $9348AF49, $361400BC,
$E8816F4A, $3814F200, $A3F94043, $9C7A54C2,
$BC704F57, $DA41E7F9, $C25AD33A, $54F4A084,
$B17F5505, $59357CBE, $EDBD15C8, $7F97C5AB,
$BA5AC7B5, $B6F6DEAF, $3A479C3A, $5302DA25,
$653D7E6A, $54268D49, $51A477EA, $5017D55B,
$D7D25D88, $44136C76, $0404A8C8, $B8E5A121,
$B81A928A, $60ED5869, $97C55B96, $EAEC991B,
$29935913, $01FDB7F1, $088E8DFA, $9AB6F6F5,
$3B4CBF9F, $4A5DE3AB, $E6051D35, $A0E1D855,
$D36B4CF1, $F544EDEB, $B0E93524, $BEBB8FBD,
$A2D762CF, $49C92F54, $38B5F331, $7128A454,
$48392905, $A65B1DB8, $851C97BD, $D675CF2F
);
cast_sbox7: array[0..255] of DWORD = (
$85E04019, $332BF567, $662DBFFF, $CFC65693,
$2A8D7F6F, $AB9BC912, $DE6008A1, $2028DA1F,
$0227BCE7, $4D642916, $18FAC300, $50F18B82,
$2CB2CB11, $B232E75C, $4B3695F2, $B28707DE,
$A05FBCF6, $CD4181E9, $E150210C, $E24EF1BD,
$B168C381, $FDE4E789, $5C79B0D8, $1E8BFD43,
$4D495001, $38BE4341, $913CEE1D, $92A79C3F,
$089766BE, $BAEEADF4, $1286BECF, $B6EACB19,
$2660C200, $7565BDE4, $64241F7A, $8248DCA9,
$C3B3AD66, $28136086, $0BD8DFA8, $356D1CF2,
$107789BE, $B3B2E9CE, $0502AA8F, $0BC0351E,
$166BF52A, $EB12FF82, $E3486911, $D34D7516,
$4E7B3AFF, $5F43671B, $9CF6E037, $4981AC83,
$334266CE, $8C9341B7, $D0D854C0, $CB3A6C88,
$47BC2829, $4725BA37, $A66AD22B, $7AD61F1E,
$0C5CBAFA, $4437F107, $B6E79962, $42D2D816,
$0A961288, $E1A5C06E, $13749E67, $72FC081A,
$B1D139F7, $F9583745, $CF19DF58, $BEC3F756,
$C06EBA30, $07211B24, $45C28829, $C95E317F,
$BC8EC511, $38BC46E9, $C6E6FA14, $BAE8584A,
$AD4EBC46, $468F508B, $7829435F, $F124183B,
$821DBA9F, $AFF60FF4, $EA2C4E6D, $16E39264,
$92544A8B, $009B4FC3, $ABA68CED, $9AC96F78,
$06A5B79A, $B2856E6E, $1AEC3CA9, $BE838688,
$0E0804E9, $55F1BE56, $E7E5363B, $B3A1F25D,
$F7DEBB85, $61FE033C, $16746233, $3C034C28,
$DA6D0C74, $79AAC56C, $3CE4E1AD, $51F0C802,
$98F8F35A, $1626A49F, $EED82B29, $1D382FE3,
$0C4FB99A, $BB325778, $3EC6D97B, $6E77A6A9,
$CB658B5C, $D45230C7, $2BD1408B, $60C03EB7,
$B9068D78, $A33754F4, $F430C87D, $C8A71302,
$B96D8C32, $EBD4E7BE, $BE8B9D2D, $7979FB06,
$E7225308, $8B75CF77, $11EF8DA4, $E083C858,
$8D6B786F, $5A6317A6, $FA5CF7A0, $5DDA0033,
$F28EBFB0, $F5B9C310, $A0EAC280, $08B9767A,
$A3D9D2B0, $79D34217, $021A718D, $9AC6336A,
$2711FD60, $438050E3, $069908A8, $3D7FEDC4,
$826D2BEF, $4EEB8476, $488DCF25, $36C9D566,
$28E74E41, $C2610ACA, $3D49A9CF, $BAE3B9DF,
$B65F8DE6, $92AEAF64, $3AC7D5E6, $9EA80509,
$F22B017D, $A4173F70, $DD1E16C3, $15E0D7F9,
$50B1B887, $2B9F4FD5, $625ABA82, $6A017962,
$2EC01B9C, $15488AA9, $D716E740, $40055A2C,
$93D29A22, $E32DBF9A, $058745B9, $3453DC1E,
$D699296E, $496CFF6F, $1C9F4986, $DFE2ED07,
$B87242D1, $19DE7EAE, $053E561A, $15AD6F8C,
$66626C1C, $7154C24C, $EA082B2A, $93EB2939,
$17DCB0F0, $58D4F2AE, $9EA294FB, $52CF564C,
$9883FE66, $2EC40581, $763953C3, $01D6692E,
$D3A0C108, $A1E7160E, $E4F2DFA6, $693ED285,
$74904698, $4C2B0EDD, $4F757656, $5D393378,
$A132234F, $3D321C5D, $C3F5E194, $4B269301,
$C79F022F, $3C997E7E, $5E4F9504, $3FFAFBBD,
$76F7AD0E, $296693F4, $3D1FCE6F, $C61E45BE,
$D3B5AB34, $F72BF9B7, $1B0434C0, $4E72B567,
$5592A33D, $B5229301, $CFD2A87F, $60AEB767,
$1814386B, $30BCC33D, $38A0C07D, $FD1606F2,
$C363519B, $589DD390, $5479F8E6, $1CB8D647,
$97FD61A9, $EA7759F4, $2D57539D, $569A58CF,
$E84E63AD, $462E1B78, $6580F87E, $F3817914,
$91DA55F4, $40A230F3, $D1988F35, $B6E318D2,
$3FFA50BC, $3D40F021, $C3C0BDAE, $4958C24C,
$518F36B2, $84B1D370, $0FEDCE83, $878DDADA,
$F2A279C7, $94E01BE8, $90716F4B, $954B8AA3
);
cast_sbox8: array[0..255] of DWORD = (
$E216300D, $BBDDFFFC, $A7EBDABD, $35648095,
$7789F8B7, $E6C1121B, $0E241600, $052CE8B5,
$11A9CFB0, $E5952F11, $ECE7990A, $9386D174,
$2A42931C, $76E38111, $B12DEF3A, $37DDDDFC,
$DE9ADEB1, $0A0CC32C, $BE197029, $84A00940,
$BB243A0F, $B4D137CF, $B44E79F0, $049EEDFD,
$0B15A15D, $480D3168, $8BBBDE5A, $669DED42,
$C7ECE831, $3F8F95E7, $72DF191B, $7580330D,
$94074251, $5C7DCDFA, $ABBE6D63, $AA402164,
$B301D40A, $02E7D1CA, $53571DAE, $7A3182A2,
$12A8DDEC, $FDAA335D, $176F43E8, $71FB46D4,
$38129022, $CE949AD4, $B84769AD, $965BD862,
$82F3D055, $66FB9767, $15B80B4E, $1D5B47A0,
$4CFDE06F, $C28EC4B8, $57E8726E, $647A78FC,
$99865D44, $608BD593, $6C200E03, $39DC5FF6,
$5D0B00A3, $AE63AFF2, $7E8BD632, $70108C0C,
$BBD35049, $2998DF04, $980CF42A, $9B6DF491,
$9E7EDD53, $06918548, $58CB7E07, $3B74EF2E,
$522FFFB1, $D24708CC, $1C7E27CD, $A4EB215B,
$3CF1D2E2, $19B47A38, $424F7618, $35856039,
$9D17DEE7, $27EB35E6, $C9AFF67B, $36BAF5B8,
$09C467CD, $C18910B1, $E11DBF7B, $06CD1AF8,
$7170C608, $2D5E3354, $D4DE495A, $64C6D006,
$BCC0C62C, $3DD00DB3, $708F8F34, $77D51B42,
$264F620F, $24B8D2BF, $15C1B79E, $46A52564,
$F8D7E54E, $3E378160, $7895CDA5, $859C15A5,
$E6459788, $C37BC75F, $DB07BA0C, $0676A3AB,
$7F229B1E, $31842E7B, $24259FD7, $F8BEF472,
$835FFCB8, $6DF4C1F2, $96F5B195, $FD0AF0FC,
$B0FE134C, $E2506D3D, $4F9B12EA, $F215F225,
$A223736F, $9FB4C428, $25D04979, $34C713F8,
$C4618187, $EA7A6E98, $7CD16EFC, $1436876C,
$F1544107, $BEDEEE14, $56E9AF27, $A04AA441,
$3CF7C899, $92ECBAE6, $DD67016D, $151682EB,
$A842EEDF, $FDBA60B4, $F1907B75, $20E3030F,
$24D8C29E, $E139673B, $EFA63FB8, $71873054,
$B6F2CF3B, $9F326442, $CB15A4CC, $B01A4504,
$F1E47D8D, $844A1BE5, $BAE7DFDC, $42CBDA70,
$CD7DAE0A, $57E85B7A, $D53F5AF6, $20CF4D8C,
$CEA4D428, $79D130A4, $3486EBFB, $33D3CDDC,
$77853B53, $37EFFCB5, $C5068778, $E580B3E6,
$4E68B8F4, $C5C8B37E, $0D809EA2, $398FEB7C,
$132A4F94, $43B7950E, $2FEE7D1C, $223613BD,
$DD06CAA2, $37DF932B, $C4248289, $ACF3EBC3,
$5715F6B7, $EF3478DD, $F267616F, $C148CBE4,
$9052815E, $5E410FAB, $B48A2465, $2EDA7FA4,
$E87B40E4, $E98EA084, $5889E9E1, $EFD390FC,
$DD07D35B, $DB485694, $38D7E5B2, $57720101,
$730EDEBC, $5B643113, $94917E4F, $503C2FBA,
$646F1282, $7523D24A, $E0779695, $F9C17A8F,
$7A5B2121, $D187B896, $29263A4D, $BA510CDF,
$81F47C9F, $AD1163ED, $EA7B5965, $1A00726E,
$11403092, $00DA6D77, $4A0CDD61, $AD1F4603,
$605BDFB0, $9EEDC364, $22EBE6A8, $CEE7D28A,
$A0E736A0, $5564A6B9, $10853209, $C7EB8F37,
$2DE705CA, $8951570F, $DF09822B, $BD691A6C,
$AA12E4F2, $87451C0F, $E0F6A27A, $3ADA4819,
$4CF1764F, $0D771C2B, $67CDB156, $350D8384,
$5938FA0F, $42399EF3, $36997B07, $0E84093D,
$4AA93E61, $8360D87B, $1FA98B0C, $1149382C,
$E97625A5, $0614D1B7, $0E25244B, $0C768347,
$589E8D82, $0D2059D1, $A466BB1E, $F8DA0A82,
$04F19130, $BA6E4EC0, $99265164, $1EE7230D,
$50B2AD80, $EAEE6801, $8DB2A283, $EA8BF59E
);
type
PCast128 = ^TCast128;
TCast128 = object(TBlockCipher64)
protected
KeyData: array[0..31] of DWORD;
Rounds: longword;
public
// code
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//Cast256 cipher implementation
const
S1: array[0..255] of DWORD = (
$30FB40D4, $9FA0FF0B, $6BECCD2F, $3F258C7A, $1E213F2F, $9C004DD3,
$6003E540, $CF9FC949, $BFD4AF27, $88BBBDB5, $E2034090, $98D09675,
$6E63A0E0, $15C361D2, $C2E7661D, $22D4FF8E, $28683B6F, $C07FD059,
$FF2379C8, $775F50E2, $43C340D3, $DF2F8656, $887CA41A, $A2D2BD2D,
$A1C9E0D6, $346C4819, $61B76D87, $22540F2F, $2ABE32E1, $AA54166B,
$22568E3A, $A2D341D0, $66DB40C8, $A784392F, $004DFF2F, $2DB9D2DE,
$97943FAC, $4A97C1D8, $527644B7, $B5F437A7, $B82CBAEF, $D751D159,
$6FF7F0ED, $5A097A1F, $827B68D0, $90ECF52E, $22B0C054, $BC8E5935,
$4B6D2F7F, $50BB64A2, $D2664910, $BEE5812D, $B7332290, $E93B159F,
$B48EE411, $4BFF345D, $FD45C240, $AD31973F, $C4F6D02E, $55FC8165,
$D5B1CAAD, $A1AC2DAE, $A2D4B76D, $C19B0C50, $882240F2, $0C6E4F38,
$A4E4BFD7, $4F5BA272, $564C1D2F, $C59C5319, $B949E354, $B04669FE,
$B1B6AB8A, $C71358DD, $6385C545, $110F935D, $57538AD5, $6A390493,
$E63D37E0, $2A54F6B3, $3A787D5F, $6276A0B5, $19A6FCDF, $7A42206A,
$29F9D4D5, $F61B1891, $BB72275E, $AA508167, $38901091, $C6B505EB,
$84C7CB8C, $2AD75A0F, $874A1427, $A2D1936B, $2AD286AF, $AA56D291,
$D7894360, $425C750D, $93B39E26, $187184C9, $6C00B32D, $73E2BB14,
$A0BEBC3C, $54623779, $64459EAB, $3F328B82, $7718CF82, $59A2CEA6,
$04EE002E, $89FE78E6, $3FAB0950, $325FF6C2, $81383F05, $6963C5C8,
$76CB5AD6, $D49974C9, $CA180DCF, $380782D5, $C7FA5CF6, $8AC31511,
$35E79E13, $47DA91D0, $F40F9086, $A7E2419E, $31366241, $051EF495,
$AA573B04, $4A805D8D, $548300D0, $00322A3C, $BF64CDDF, $BA57A68E,
$75C6372B, $50AFD341, $A7C13275, $915A0BF5, $6B54BFAB, $2B0B1426,
$AB4CC9D7, $449CCD82, $F7FBF265, $AB85C5F3, $1B55DB94, $AAD4E324,
$CFA4BD3F, $2DEAA3E2, $9E204D02, $C8BD25AC, $EADF55B3, $D5BD9E98,
$E31231B2, $2AD5AD6C, $954329DE, $ADBE4528, $D8710F69, $AA51C90F,
$AA786BF6, $22513F1E, $AA51A79B, $2AD344CC, $7B5A41F0, $D37CFBAD,
$1B069505, $41ECE491, $B4C332E6, $032268D4, $C9600ACC, $CE387E6D,
$BF6BB16C, $6A70FB78, $0D03D9C9, $D4DF39DE, $E01063DA, $4736F464,
$5AD328D8, $B347CC96, $75BB0FC3, $98511BFB, $4FFBCC35, $B58BCF6A,
$E11F0ABC, $BFC5FE4A, $A70AEC10, $AC39570A, $3F04442F, $6188B153,
$E0397A2E, $5727CB79, $9CEB418F, $1CACD68D, $2AD37C96, $0175CB9D,
$C69DFF09, $C75B65F0, $D9DB40D8, $EC0E7779, $4744EAD4, $B11C3274,
$DD24CB9E, $7E1C54BD, $F01144F9, $D2240EB1, $9675B3FD, $A3AC3755,
$D47C27AF, $51C85F4D, $56907596, $A5BB15E6, $580304F0, $CA042CF1,
$011A37EA, $8DBFAADB, $35BA3E4A, $3526FFA0, $C37B4D09, $BC306ED9,
$98A52666, $5648F725, $FF5E569D, $0CED63D0, $7C63B2CF, $700B45E1,
$D5EA50F1, $85A92872, $AF1FBDA7, $D4234870, $A7870BF3, $2D3B4D79,
$42E04198, $0CD0EDE7, $26470DB8, $F881814C, $474D6AD7, $7C0C5E5C,
$D1231959, $381B7298, $F5D2F4DB, $AB838653, $6E2F1E23, $83719C9E,
$BD91E046, $9A56456E, $DC39200C, $20C8C571, $962BDA1C, $E1E696FF,
$B141AB08, $7CCA89B9, $1A69E783, $02CC4843, $A2F7C579, $429EF47D,
$427B169C, $5AC9F049, $DD8F0F00, $5C8165BF);
S2: array[0..255] of DWORD = (
$1F201094, $EF0BA75B, $69E3CF7E, $393F4380, $FE61CF7A, $EEC5207A,
$55889C94, $72FC0651, $ADA7EF79, $4E1D7235, $D55A63CE, $DE0436BA,
$99C430EF, $5F0C0794, $18DCDB7D, $A1D6EFF3, $A0B52F7B, $59E83605,
$EE15B094, $E9FFD909, $DC440086, $EF944459, $BA83CCB3, $E0C3CDFB,
$D1DA4181, $3B092AB1, $F997F1C1, $A5E6CF7B, $01420DDB, $E4E7EF5B,
$25A1FF41, $E180F806, $1FC41080, $179BEE7A, $D37AC6A9, $FE5830A4,
$98DE8B7F, $77E83F4E, $79929269, $24FA9F7B, $E113C85B, $ACC40083,
$D7503525, $F7EA615F, $62143154, $0D554B63, $5D681121, $C866C359,
$3D63CF73, $CEE234C0, $D4D87E87, $5C672B21, $071F6181, $39F7627F,
$361E3084, $E4EB573B, $602F64A4, $D63ACD9C, $1BBC4635, $9E81032D,
$2701F50C, $99847AB4, $A0E3DF79, $BA6CF38C, $10843094, $2537A95E,
$F46F6FFE, $A1FF3B1F, $208CFB6A, $8F458C74, $D9E0A227, $4EC73A34,
$FC884F69, $3E4DE8DF, $EF0E0088, $3559648D, $8A45388C, $1D804366,
$721D9BFD, $A58684BB, $E8256333, $844E8212, $128D8098, $FED33FB4,
$CE280AE1, $27E19BA5, $D5A6C252, $E49754BD, $C5D655DD, $EB667064,
$77840B4D, $A1B6A801, $84DB26A9, $E0B56714, $21F043B7, $E5D05860,
$54F03084, $066FF472, $A31AA153, $DADC4755, $B5625DBF, $68561BE6,
$83CA6B94, $2D6ED23B, $ECCF01DB, $A6D3D0BA, $B6803D5C, $AF77A709,
$33B4A34C, $397BC8D6, $5EE22B95, $5F0E5304, $81ED6F61, $20E74364,
$B45E1378, $DE18639B, $881CA122, $B96726D1, $8049A7E8, $22B7DA7B,
$5E552D25, $5272D237, $79D2951C, $C60D894C, $488CB402, $1BA4FE5B,
$A4B09F6B, $1CA815CF, $A20C3005, $8871DF63, $B9DE2FCB, $0CC6C9E9,
$0BEEFF53, $E3214517, $B4542835, $9F63293C, $EE41E729, $6E1D2D7C,
$50045286, $1E6685F3, $F33401C6, $30A22C95, $31A70850, $60930F13,
$73F98417, $A1269859, $EC645C44, $52C877A9, $CDFF33A6, $A02B1741,
$7CBAD9A2, $2180036F, $50D99C08, $CB3F4861, $C26BD765, $64A3F6AB,
$80342676, $25A75E7B, $E4E6D1FC, $20C710E6, $CDF0B680, $17844D3B,
$31EEF84D, $7E0824E4, $2CCB49EB, $846A3BAE, $8FF77888, $EE5D60F6,
$7AF75673, $2FDD5CDB, $A11631C1, $30F66F43, $B3FAEC54, $157FD7FA,
$EF8579CC, $D152DE58, $DB2FFD5E, $8F32CE19, $306AF97A, $02F03EF8,
$99319AD5, $C242FA0F, $A7E3EBB0, $C68E4906, $B8DA230C, $80823028,
$DCDEF3C8, $D35FB171, $088A1BC8, $BEC0C560, $61A3C9E8, $BCA8F54D,
$C72FEFFA, $22822E99, $82C570B4, $D8D94E89, $8B1C34BC, $301E16E6,
$273BE979, $B0FFEAA6, $61D9B8C6, $00B24869, $B7FFCE3F, $08DC283B,
$43DAF65A, $F7E19798, $7619B72F, $8F1C9BA4, $DC8637A0, $16A7D3B1,
$9FC393B7, $A7136EEB, $C6BCC63E, $1A513742, $EF6828BC, $520365D6,
$2D6A77AB, $3527ED4B, $821FD216, $095C6E2E, $DB92F2FB, $5EEA29CB,
$145892F5, $91584F7F, $5483697B, $2667A8CC, $85196048, $8C4BACEA,
$833860D4, $0D23E0F9, $6C387E8A, $0AE6D249, $B284600C, $D835731D,
$DCB1C647, $AC4C56EA, $3EBD81B3, $230EABB0, $6438BC87, $F0B5B1FA,
$8F5EA2B3, $FC184642, $0A036B7A, $4FB089BD, $649DA589, $A345415E,
$5C038323, $3E5D3BB9, $43D79572, $7E6DD07C, $06DFDF1E, $6C6CC4EF,
$7160A539, $73BFBE70, $83877605, $4523ECF1);
S3: array[0..255] of DWORD = (
$8DEFC240, $25FA5D9F, $EB903DBF, $E810C907, $47607FFF, $369FE44B,
$8C1FC644, $AECECA90, $BEB1F9BF, $EEFBCAEA, $E8CF1950, $51DF07AE,
$920E8806, $F0AD0548, $E13C8D83, $927010D5, $11107D9F, $07647DB9,
$B2E3E4D4, $3D4F285E, $B9AFA820, $FADE82E0, $A067268B, $8272792E,
$553FB2C0, $489AE22B, $D4EF9794, $125E3FBC, $21FFFCEE, $825B1BFD,
$9255C5ED, $1257A240, $4E1A8302, $BAE07FFF, $528246E7, $8E57140E,
$3373F7BF, $8C9F8188, $A6FC4EE8, $C982B5A5, $A8C01DB7, $579FC264,
$67094F31, $F2BD3F5F, $40FFF7C1, $1FB78DFC, $8E6BD2C1, $437BE59B,
$99B03DBF, $B5DBC64B, $638DC0E6, $55819D99, $A197C81C, $4A012D6E,
$C5884A28, $CCC36F71, $B843C213, $6C0743F1, $8309893C, $0FEDDD5F,
$2F7FE850, $D7C07F7E, $02507FBF, $5AFB9A04, $A747D2D0, $1651192E,
$AF70BF3E, $58C31380, $5F98302E, $727CC3C4, $0A0FB402, $0F7FEF82,
$8C96FDAD, $5D2C2AAE, $8EE99A49, $50DA88B8, $8427F4A0, $1EAC5790,
$796FB449, $8252DC15, $EFBD7D9B, $A672597D, $ADA840D8, $45F54504,
$FA5D7403, $E83EC305, $4F91751A, $925669C2, $23EFE941, $A903F12E,
$60270DF2, $0276E4B6, $94FD6574, $927985B2, $8276DBCB, $02778176,
$F8AF918D, $4E48F79E, $8F616DDF, $E29D840E, $842F7D83, $340CE5C8,
$96BBB682, $93B4B148, $EF303CAB, $984FAF28, $779FAF9B, $92DC560D,
$224D1E20, $8437AA88, $7D29DC96, $2756D3DC, $8B907CEE, $B51FD240,
$E7C07CE3, $E566B4A1, $C3E9615E, $3CF8209D, $6094D1E3, $CD9CA341,
$5C76460E, $00EA983B, $D4D67881, $FD47572C, $F76CEDD9, $BDA8229C,
$127DADAA, $438A074E, $1F97C090, $081BDB8A, $93A07EBE, $B938CA15,
$97B03CFF, $3DC2C0F8, $8D1AB2EC, $64380E51, $68CC7BFB, $D90F2788,
$12490181, $5DE5FFD4, $DD7EF86A, $76A2E214, $B9A40368, $925D958F,
$4B39FFFA, $BA39AEE9, $A4FFD30B, $FAF7933B, $6D498623, $193CBCFA,
$27627545, $825CF47A, $61BD8BA0, $D11E42D1, $CEAD04F4, $127EA392,
$10428DB7, $8272A972, $9270C4A8, $127DE50B, $285BA1C8, $3C62F44F,
$35C0EAA5, $E805D231, $428929FB, $B4FCDF82, $4FB66A53, $0E7DC15B,
$1F081FAB, $108618AE, $FCFD086D, $F9FF2889, $694BCC11, $236A5CAE,
$12DECA4D, $2C3F8CC5, $D2D02DFE, $F8EF5896, $E4CF52DA, $95155B67,
$494A488C, $B9B6A80C, $5C8F82BC, $89D36B45, $3A609437, $EC00C9A9,
$44715253, $0A874B49, $D773BC40, $7C34671C, $02717EF6, $4FEB5536,
$A2D02FFF, $D2BF60C4, $D43F03C0, $50B4EF6D, $07478CD1, $006E1888,
$A2E53F55, $B9E6D4BC, $A2048016, $97573833, $D7207D67, $DE0F8F3D,
$72F87B33, $ABCC4F33, $7688C55D, $7B00A6B0, $947B0001, $570075D2,
$F9BB88F8, $8942019E, $4264A5FF, $856302E0, $72DBD92B, $EE971B69,
$6EA22FDE, $5F08AE2B, $AF7A616D, $E5C98767, $CF1FEBD2, $61EFC8C2,
$F1AC2571, $CC8239C2, $67214CB8, $B1E583D1, $B7DC3E62, $7F10BDCE,
$F90A5C38, $0FF0443D, $606E6DC6, $60543A49, $5727C148, $2BE98A1D,
$8AB41738, $20E1BE24, $AF96DA0F, $68458425, $99833BE5, $600D457D,
$282F9350, $8334B362, $D91D1120, $2B6D8DA0, $642B1E31, $9C305A00,
$52BCE688, $1B03588A, $F7BAEFD5, $4142ED9C, $A4315C11, $83323EC5,
$DFEF4636, $A133C501, $E9D3531C, $EE353783);
S4: array[0..255] of DWORD = (
$9DB30420, $1FB6E9DE, $A7BE7BEF, $D273A298, $4A4F7BDB, $64AD8C57,
$85510443, $FA020ED1, $7E287AFF, $E60FB663, $095F35A1, $79EBF120,
$FD059D43, $6497B7B1, $F3641F63, $241E4ADF, $28147F5F, $4FA2B8CD,
$C9430040, $0CC32220, $FDD30B30, $C0A5374F, $1D2D00D9, $24147B15,
$EE4D111A, $0FCA5167, $71FF904C, $2D195FFE, $1A05645F, $0C13FEFE,
$081B08CA, $05170121, $80530100, $E83E5EFE, $AC9AF4F8, $7FE72701,
$D2B8EE5F, $06DF4261, $BB9E9B8A, $7293EA25, $CE84FFDF, $F5718801,
$3DD64B04, $A26F263B, $7ED48400, $547EEBE6, $446D4CA0, $6CF3D6F5,
$2649ABDF, $AEA0C7F5, $36338CC1, $503F7E93, $D3772061, $11B638E1,
$72500E03, $F80EB2BB, $ABE0502E, $EC8D77DE, $57971E81, $E14F6746,
$C9335400, $6920318F, $081DBB99, $FFC304A5, $4D351805, $7F3D5CE3,
$A6C866C6, $5D5BCCA9, $DAEC6FEA, $9F926F91, $9F46222F, $3991467D,
$A5BF6D8E, $1143C44F, $43958302, $D0214EEB, $022083B8, $3FB6180C,
$18F8931E, $281658E6, $26486E3E, $8BD78A70, $7477E4C1, $B506E07C,
$F32D0A25, $79098B02, $E4EABB81, $28123B23, $69DEAD38, $1574CA16,
$DF871B62, $211C40B7, $A51A9EF9, $0014377B, $041E8AC8, $09114003,
$BD59E4D2, $E3D156D5, $4FE876D5, $2F91A340, $557BE8DE, $00EAE4A7,
$0CE5C2EC, $4DB4BBA6, $E756BDFF, $DD3369AC, $EC17B035, $06572327,
$99AFC8B0, $56C8C391, $6B65811C, $5E146119, $6E85CB75, $BE07C002,
$C2325577, $893FF4EC, $5BBFC92D, $D0EC3B25, $B7801AB7, $8D6D3B24,
$20C763EF, $C366A5FC, $9C382880, $0ACE3205, $AAC9548A, $ECA1D7C7,
$041AFA32, $1D16625A, $6701902C, $9B757A54, $31D477F7, $9126B031,
$36CC6FDB, $C70B8B46, $D9E66A48, $56E55A79, $026A4CEB, $52437EFF,
$2F8F76B4, $0DF980A5, $8674CDE3, $EDDA04EB, $17A9BE04, $2C18F4DF,
$B7747F9D, $AB2AF7B4, $EFC34D20, $2E096B7C, $1741A254, $E5B6A035,
$213D42F6, $2C1C7C26, $61C2F50F, $6552DAF9, $D2C231F8, $25130F69,
$D8167FA2, $0418F2C8, $001A96A6, $0D1526AB, $63315C21, $5E0A72EC,
$49BAFEFD, $187908D9, $8D0DBD86, $311170A7, $3E9B640C, $CC3E10D7,
$D5CAD3B6, $0CAEC388, $F73001E1, $6C728AFF, $71EAE2A1, $1F9AF36E,
$CFCBD12F, $C1DE8417, $AC07BE6B, $CB44A1D8, $8B9B0F56, $013988C3,
$B1C52FCA, $B4BE31CD, $D8782806, $12A3A4E2, $6F7DE532, $58FD7EB6,
$D01EE900, $24ADFFC2, $F4990FC5, $9711AAC5, $001D7B95, $82E5E7D2,
$109873F6, $00613096, $C32D9521, $ADA121FF, $29908415, $7FBB977F,
$AF9EB3DB, $29C9ED2A, $5CE2A465, $A730F32C, $D0AA3FE8, $8A5CC091,
$D49E2CE7, $0CE454A9, $D60ACD86, $015F1919, $77079103, $DEA03AF6,
$78A8565E, $DEE356DF, $21F05CBE, $8B75E387, $B3C50651, $B8A5C3EF,
$D8EEB6D2, $E523BE77, $C2154529, $2F69EFDF, $AFE67AFB, $F470C4B2,
$F3E0EB5B, $D6CC9876, $39E4460C, $1FDA8538, $1987832F, $CA007367,
$A99144F8, $296B299E, $492FC295, $9266BEAB, $B5676E69, $9BD3DDDA,
$DF7E052F, $DB25701C, $1B5E51EE, $F65324E6, $6AFCE36C, $0316CC04,
$8644213E, $B7DC59D0, $7965291F, $CCD6FD43, $41823979, $932BCDF6,
$B657C34D, $4EDFD282, $7AE5290C, $3CB9536B, $851E20FE, $9833557E,
$13ECF0B0, $D3FFB372, $3F85C5C1, $0AEF7ED2);
type
PCast256 = ^TCast256;
TCast256 = object(TBlockCipher128)
protected
Kr, Km: array[0..11, 0..3] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//GOST cipher implementation
const
sTable: array[0..3, 0..255] of DWORD = (
($00072000, $00075000, $00074800, $00071000, $00076800, $00074000, $00070000, $00077000,
$00073000, $00075800, $00070800, $00076000, $00073800, $00077800, $00072800, $00071800,
$0005A000, $0005D000, $0005C800, $00059000, $0005E800, $0005C000, $00058000, $0005F000,
$0005B000, $0005D800, $00058800, $0005E000, $0005B800, $0005F800, $0005A800, $00059800,
$00022000, $00025000, $00024800, $00021000, $00026800, $00024000, $00020000, $00027000,
$00023000, $00025800, $00020800, $00026000, $00023800, $00027800, $00022800, $00021800,
$00062000, $00065000, $00064800, $00061000, $00066800, $00064000, $00060000, $00067000,
$00063000, $00065800, $00060800, $00066000, $00063800, $00067800, $00062800, $00061800,
$00032000, $00035000, $00034800, $00031000, $00036800, $00034000, $00030000, $00037000,
$00033000, $00035800, $00030800, $00036000, $00033800, $00037800, $00032800, $00031800,
$0006A000, $0006D000, $0006C800, $00069000, $0006E800, $0006C000, $00068000, $0006F000,
$0006B000, $0006D800, $00068800, $0006E000, $0006B800, $0006F800, $0006A800, $00069800,
$0007A000, $0007D000, $0007C800, $00079000, $0007E800, $0007C000, $00078000, $0007F000,
$0007B000, $0007D800, $00078800, $0007E000, $0007B800, $0007F800, $0007A800, $00079800,
$00052000, $00055000, $00054800, $00051000, $00056800, $00054000, $00050000, $00057000,
$00053000, $00055800, $00050800, $00056000, $00053800, $00057800, $00052800, $00051800,
$00012000, $00015000, $00014800, $00011000, $00016800, $00014000, $00010000, $00017000,
$00013000, $00015800, $00010800, $00016000, $00013800, $00017800, $00012800, $00011800,
$0001A000, $0001D000, $0001C800, $00019000, $0001E800, $0001C000, $00018000, $0001F000,
$0001B000, $0001D800, $00018800, $0001E000, $0001B800, $0001F800, $0001A800, $00019800,
$00042000, $00045000, $00044800, $00041000, $00046800, $00044000, $00040000, $00047000,
$00043000, $00045800, $00040800, $00046000, $00043800, $00047800, $00042800, $00041800,
$0000A000, $0000D000, $0000C800, $00009000, $0000E800, $0000C000, $00008000, $0000F000,
$0000B000, $0000D800, $00008800, $0000E000, $0000B800, $0000F800, $0000A800, $00009800,
$00002000, $00005000, $00004800, $00001000, $00006800, $00004000, $00000000, $00007000,
$00003000, $00005800, $00000800, $00006000, $00003800, $00007800, $00002800, $00001800,
$0003A000, $0003D000, $0003C800, $00039000, $0003E800, $0003C000, $00038000, $0003F000,
$0003B000, $0003D800, $00038800, $0003E000, $0003B800, $0003F800, $0003A800, $00039800,
$0002A000, $0002D000, $0002C800, $00029000, $0002E800, $0002C000, $00028000, $0002F000,
$0002B000, $0002D800, $00028800, $0002E000, $0002B800, $0002F800, $0002A800, $00029800,
$0004A000, $0004D000, $0004C800, $00049000, $0004E800, $0004C000, $00048000, $0004F000,
$0004B000, $0004D800, $00048800, $0004E000, $0004B800, $0004F800, $0004A800, $00049800),
($03A80000, $03C00000, $03880000, $03E80000, $03D00000, $03980000, $03A00000, $03900000,
$03F00000, $03F80000, $03E00000, $03B80000, $03B00000, $03800000, $03C80000, $03D80000,
$06A80000, $06C00000, $06880000, $06E80000, $06D00000, $06980000, $06A00000, $06900000,
$06F00000, $06F80000, $06E00000, $06B80000, $06B00000, $06800000, $06C80000, $06D80000,
$05280000, $05400000, $05080000, $05680000, $05500000, $05180000, $05200000, $05100000,
$05700000, $05780000, $05600000, $05380000, $05300000, $05000000, $05480000, $05580000,
$00A80000, $00C00000, $00880000, $00E80000, $00D00000, $00980000, $00A00000, $00900000,
$00F00000, $00F80000, $00E00000, $00B80000, $00B00000, $00800000, $00C80000, $00D80000,
$00280000, $00400000, $00080000, $00680000, $00500000, $00180000, $00200000, $00100000,
$00700000, $00780000, $00600000, $00380000, $00300000, $00000000, $00480000, $00580000,
$04280000, $04400000, $04080000, $04680000, $04500000, $04180000, $04200000, $04100000,
$04700000, $04780000, $04600000, $04380000, $04300000, $04000000, $04480000, $04580000,
$04A80000, $04C00000, $04880000, $04E80000, $04D00000, $04980000, $04A00000, $04900000,
$04F00000, $04F80000, $04E00000, $04B80000, $04B00000, $04800000, $04C80000, $04D80000,
$07A80000, $07C00000, $07880000, $07E80000, $07D00000, $07980000, $07A00000, $07900000,
$07F00000, $07F80000, $07E00000, $07B80000, $07B00000, $07800000, $07C80000, $07D80000,
$07280000, $07400000, $07080000, $07680000, $07500000, $07180000, $07200000, $07100000,
$07700000, $07780000, $07600000, $07380000, $07300000, $07000000, $07480000, $07580000,
$02280000, $02400000, $02080000, $02680000, $02500000, $02180000, $02200000, $02100000,
$02700000, $02780000, $02600000, $02380000, $02300000, $02000000, $02480000, $02580000,
$03280000, $03400000, $03080000, $03680000, $03500000, $03180000, $03200000, $03100000,
$03700000, $03780000, $03600000, $03380000, $03300000, $03000000, $03480000, $03580000,
$06280000, $06400000, $06080000, $06680000, $06500000, $06180000, $06200000, $06100000,
$06700000, $06780000, $06600000, $06380000, $06300000, $06000000, $06480000, $06580000,
$05A80000, $05C00000, $05880000, $05E80000, $05D00000, $05980000, $05A00000, $05900000,
$05F00000, $05F80000, $05E00000, $05B80000, $05B00000, $05800000, $05C80000, $05D80000,
$01280000, $01400000, $01080000, $01680000, $01500000, $01180000, $01200000, $01100000,
$01700000, $01780000, $01600000, $01380000, $01300000, $01000000, $01480000, $01580000,
$02A80000, $02C00000, $02880000, $02E80000, $02D00000, $02980000, $02A00000, $02900000,
$02F00000, $02F80000, $02E00000, $02B80000, $02B00000, $02800000, $02C80000, $02D80000,
$01A80000, $01C00000, $01880000, $01E80000, $01D00000, $01980000, $01A00000, $01900000,
$01F00000, $01F80000, $01E00000, $01B80000, $01B00000, $01800000, $01C80000, $01D80000),
($30000002, $60000002, $38000002, $08000002, $28000002, $78000002, $68000002, $40000002,
$20000002, $50000002, $48000002, $70000002, $00000002, $18000002, $58000002, $10000002,
$B0000005, $E0000005, $B8000005, $88000005, $A8000005, $F8000005, $E8000005, $C0000005,
$A0000005, $D0000005, $C8000005, $F0000005, $80000005, $98000005, $D8000005, $90000005,
$30000005, $60000005, $38000005, $08000005, $28000005, $78000005, $68000005, $40000005,
$20000005, $50000005, $48000005, $70000005, $00000005, $18000005, $58000005, $10000005,
$30000000, $60000000, $38000000, $08000000, $28000000, $78000000, $68000000, $40000000,
$20000000, $50000000, $48000000, $70000000, $00000000, $18000000, $58000000, $10000000,
$B0000003, $E0000003, $B8000003, $88000003, $A8000003, $F8000003, $E8000003, $C0000003,
$A0000003, $D0000003, $C8000003, $F0000003, $80000003, $98000003, $D8000003, $90000003,
$30000001, $60000001, $38000001, $08000001, $28000001, $78000001, $68000001, $40000001,
$20000001, $50000001, $48000001, $70000001, $00000001, $18000001, $58000001, $10000001,
$B0000000, $E0000000, $B8000000, $88000000, $A8000000, $F8000000, $E8000000, $C0000000,
$A0000000, $D0000000, $C8000000, $F0000000, $80000000, $98000000, $D8000000, $90000000,
$B0000006, $E0000006, $B8000006, $88000006, $A8000006, $F8000006, $E8000006, $C0000006,
$A0000006, $D0000006, $C8000006, $F0000006, $80000006, $98000006, $D8000006, $90000006,
$B0000001, $E0000001, $B8000001, $88000001, $A8000001, $F8000001, $E8000001, $C0000001,
$A0000001, $D0000001, $C8000001, $F0000001, $80000001, $98000001, $D8000001, $90000001,
$30000003, $60000003, $38000003, $08000003, $28000003, $78000003, $68000003, $40000003,
$20000003, $50000003, $48000003, $70000003, $00000003, $18000003, $58000003, $10000003,
$30000004, $60000004, $38000004, $08000004, $28000004, $78000004, $68000004, $40000004,
$20000004, $50000004, $48000004, $70000004, $00000004, $18000004, $58000004, $10000004,
$B0000002, $E0000002, $B8000002, $88000002, $A8000002, $F8000002, $E8000002, $C0000002,
$A0000002, $D0000002, $C8000002, $F0000002, $80000002, $98000002, $D8000002, $90000002,
$B0000004, $E0000004, $B8000004, $88000004, $A8000004, $F8000004, $E8000004, $C0000004,
$A0000004, $D0000004, $C8000004, $F0000004, $80000004, $98000004, $D8000004, $90000004,
$30000006, $60000006, $38000006, $08000006, $28000006, $78000006, $68000006, $40000006,
$20000006, $50000006, $48000006, $70000006, $00000006, $18000006, $58000006, $10000006,
$B0000007, $E0000007, $B8000007, $88000007, $A8000007, $F8000007, $E8000007, $C0000007,
$A0000007, $D0000007, $C8000007, $F0000007, $80000007, $98000007, $D8000007, $90000007,
$30000007, $60000007, $38000007, $08000007, $28000007, $78000007, $68000007, $40000007,
$20000007, $50000007, $48000007, $70000007, $00000007, $18000007, $58000007, $10000007),
($000000E8, $000000D8, $000000A0, $00000088, $00000098, $000000F8, $000000A8, $000000C8,
$00000080, $000000D0, $000000F0, $000000B8, $000000B0, $000000C0, $00000090, $000000E0,
$000007E8, $000007D8, $000007A0, $00000788, $00000798, $000007F8, $000007A8, $000007C8,
$00000780, $000007D0, $000007F0, $000007B8, $000007B0, $000007C0, $00000790, $000007E0,
$000006E8, $000006D8, $000006A0, $00000688, $00000698, $000006F8, $000006A8, $000006C8,
$00000680, $000006D0, $000006F0, $000006B8, $000006B0, $000006C0, $00000690, $000006E0,
$00000068, $00000058, $00000020, $00000008, $00000018, $00000078, $00000028, $00000048,
$00000000, $00000050, $00000070, $00000038, $00000030, $00000040, $00000010, $00000060,
$000002E8, $000002D8, $000002A0, $00000288, $00000298, $000002F8, $000002A8, $000002C8,
$00000280, $000002D0, $000002F0, $000002B8, $000002B0, $000002C0, $00000290, $000002E0,
$000003E8, $000003D8, $000003A0, $00000388, $00000398, $000003F8, $000003A8, $000003C8,
$00000380, $000003D0, $000003F0, $000003B8, $000003B0, $000003C0, $00000390, $000003E0,
$00000568, $00000558, $00000520, $00000508, $00000518, $00000578, $00000528, $00000548,
$00000500, $00000550, $00000570, $00000538, $00000530, $00000540, $00000510, $00000560,
$00000268, $00000258, $00000220, $00000208, $00000218, $00000278, $00000228, $00000248,
$00000200, $00000250, $00000270, $00000238, $00000230, $00000240, $00000210, $00000260,
$000004E8, $000004D8, $000004A0, $00000488, $00000498, $000004F8, $000004A8, $000004C8,
$00000480, $000004D0, $000004F0, $000004B8, $000004B0, $000004C0, $00000490, $000004E0,
$00000168, $00000158, $00000120, $00000108, $00000118, $00000178, $00000128, $00000148,
$00000100, $00000150, $00000170, $00000138, $00000130, $00000140, $00000110, $00000160,
$000001E8, $000001D8, $000001A0, $00000188, $00000198, $000001F8, $000001A8, $000001C8,
$00000180, $000001D0, $000001F0, $000001B8, $000001B0, $000001C0, $00000190, $000001E0,
$00000768, $00000758, $00000720, $00000708, $00000718, $00000778, $00000728, $00000748,
$00000700, $00000750, $00000770, $00000738, $00000730, $00000740, $00000710, $00000760,
$00000368, $00000358, $00000320, $00000308, $00000318, $00000378, $00000328, $00000348,
$00000300, $00000350, $00000370, $00000338, $00000330, $00000340, $00000310, $00000360,
$000005E8, $000005D8, $000005A0, $00000588, $00000598, $000005F8, $000005A8, $000005C8,
$00000580, $000005D0, $000005F0, $000005B8, $000005B0, $000005C0, $00000590, $000005E0,
$00000468, $00000458, $00000420, $00000408, $00000418, $00000478, $00000428, $00000448,
$00000400, $00000450, $00000470, $00000438, $00000430, $00000440, $00000410, $00000460,
$00000668, $00000658, $00000620, $00000608, $00000618, $00000678, $00000628, $00000648,
$00000600, $00000650, $00000670, $00000638, $00000630, $00000640, $00000610, $00000660));
type
PGOST = ^TGOST;
TGOST = object(TBlockCipher64)
protected
KeyData: array[0..7] of DWORD;
// code
public
// code
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//IDEA cipher implementation
type
PIDEA = ^TIDEA;
TIDEA = object(TBlockCipher64)
protected
EK, DK: array[0..51] of Word;
public
// code
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//Misty1 cipher implementation
const
NUMROUNDSMY1 = 8;
const
S7TABLE: array[0..$7F] of byte = (
$1B, $32, $33, $5A, $3B, $10, $17, $54, $5B, $1A, $72, $73, $6B, $2C, $66, $49,
$1F, $24, $13, $6C, $37, $2E, $3F, $4A, $5D, $0F, $40, $56, $25, $51, $1C, $04,
$0B, $46, $20, $0D, $7B, $35, $44, $42, $2B, $1E, $41, $14, $4B, $79, $15, $6F,
$0E, $55, $09, $36, $74, $0C, $67, $53, $28, $0A, $7E, $38, $02, $07, $60, $29,
$19, $12, $65, $2F, $30, $39, $08, $68, $5F, $78, $2A, $4C, $64, $45, $75, $3D,
$59, $48, $03, $57, $7C, $4F, $62, $3C, $1D, $21, $5E, $27, $6A, $70, $4D, $3A,
$01, $6D, $6E, $63, $18, $77, $23, $05, $26, $76, $00, $31, $2D, $7A, $7F, $61,
$50, $22, $11, $06, $47, $16, $52, $4E, $71, $3E, $69, $43, $34, $5C, $58, $7D);
S9TABLE: array[0..$1FF] of DWORD = (
$1C3, $0CB, $153, $19F, $1E3, $0E9, $0FB, $035, $181, $0B9, $117, $1EB, $133, $009, $02D, $0D3,
$0C7, $14A, $037, $07E, $0EB, $164, $193, $1D8, $0A3, $11E, $055, $02C, $01D, $1A2, $163, $118,
$14B, $152, $1D2, $00F, $02B, $030, $13A, $0E5, $111, $138, $18E, $063, $0E3, $0C8, $1F4, $01B,
$001, $09D, $0F8, $1A0, $16D, $1F3, $01C, $146, $07D, $0D1, $082, $1EA, $183, $12D, $0F4, $19E,
$1D3, $0DD, $1E2, $128, $1E0, $0EC, $059, $091, $011, $12F, $026, $0DC, $0B0, $18C, $10F, $1F7,
$0E7, $16C, $0B6, $0F9, $0D8, $151, $101, $14C, $103, $0B8, $154, $12B, $1AE, $017, $071, $00C,
$047, $058, $07F, $1A4, $134, $129, $084, $15D, $19D, $1B2, $1A3, $048, $07C, $051, $1CA, $023,
$13D, $1A7, $165, $03B, $042, $0DA, $192, $0CE, $0C1, $06B, $09F, $1F1, $12C, $184, $0FA, $196,
$1E1, $169, $17D, $031, $180, $10A, $094, $1DA, $186, $13E, $11C, $060, $175, $1CF, $067, $119,
$065, $068, $099, $150, $008, $007, $17C, $0B7, $024, $019, $0DE, $127, $0DB, $0E4, $1A9, $052,
$109, $090, $19C, $1C1, $028, $1B3, $135, $16A, $176, $0DF, $1E5, $188, $0C5, $16E, $1DE, $1B1,
$0C3, $1DF, $036, $0EE, $1EE, $0F0, $093, $049, $09A, $1B6, $069, $081, $125, $00B, $05E, $0B4,
$149, $1C7, $174, $03E, $13B, $1B7, $08E, $1C6, $0AE, $010, $095, $1EF, $04E, $0F2, $1FD, $085,
$0FD, $0F6, $0A0, $16F, $083, $08A, $156, $09B, $13C, $107, $167, $098, $1D0, $1E9, $003, $1FE,
$0BD, $122, $089, $0D2, $18F, $012, $033, $06A, $142, $0ED, $170, $11B, $0E2, $14F, $158, $131,
$147, $05D, $113, $1CD, $079, $161, $1A5, $179, $09E, $1B4, $0CC, $022, $132, $01A, $0E8, $004,
$187, $1ED, $197, $039, $1BF, $1D7, $027, $18B, $0C6, $09C, $0D0, $14E, $06C, $034, $1F2, $06E,
$0CA, $025, $0BA, $191, $0FE, $013, $106, $02F, $1AD, $172, $1DB, $0C0, $10B, $1D6, $0F5, $1EC,
$10D, $076, $114, $1AB, $075, $10C, $1E4, $159, $054, $11F, $04B, $0C4, $1BE, $0F7, $029, $0A4,
$00E, $1F0, $077, $04D, $17A, $086, $08B, $0B3, $171, $0BF, $10E, $104, $097, $15B, $160, $168,
$0D7, $0BB, $066, $1CE, $0FC, $092, $1C5, $06F, $016, $04A, $0A1, $139, $0AF, $0F1, $190, $00A,
$1AA, $143, $17B, $056, $18D, $166, $0D4, $1FB, $14D, $194, $19A, $087, $1F8, $123, $0A7, $1B8,
$141, $03C, $1F9, $140, $02A, $155, $11A, $1A1, $198, $0D5, $126, $1AF, $061, $12E, $157, $1DC,
$072, $18A, $0AA, $096, $115, $0EF, $045, $07B, $08D, $145, $053, $05F, $178, $0B2, $02E, $020,
$1D5, $03F, $1C9, $1E7, $1AC, $044, $038, $014, $0B1, $16B, $0AB, $0B5, $05A, $182, $1C8, $1D4,
$018, $177, $064, $0CF, $06D, $100, $199, $130, $15A, $005, $120, $1BB, $1BD, $0E0, $04F, $0D6,
$13F, $1C4, $12A, $015, $006, $0FF, $19B, $0A6, $043, $088, $050, $15F, $1E8, $121, $073, $17E,
$0BC, $0C2, $0C9, $173, $189, $1F5, $074, $1CC, $1E6, $1A8, $195, $01F, $041, $00D, $1BA, $032,
$03D, $1D1, $080, $0A8, $057, $1B9, $162, $148, $0D9, $105, $062, $07A, $021, $1FF, $112, $108,
$1C0, $0A9, $11D, $1B0, $1A6, $0CD, $0F3, $05C, $102, $05B, $1D9, $144, $1F6, $0AD, $0A5, $03A,
$1CB, $136, $17F, $046, $0E1, $01E, $1DD, $0E6, $137, $1FA, $185, $08C, $08F, $040, $1B5, $0BE,
$078, $000, $0AC, $110, $15E, $124, $002, $1BC, $0A2, $0EA, $070, $1FC, $116, $15C, $04C, $1C2);
type
PMisty1 = ^TMisty1;
TMisty1 = object(TBlockCipher64)
protected
KeyData: array[0..31] of DWORD;
function FI(const FI_IN, FI_KEY: DWORD): DWORD;
function FO(const FO_IN: DWORD; const k: longword): DWORD;
function FL(const FL_IN: DWORD; const k: longword): DWORD;
function FLINV(const FL_IN: DWORD; const k: longword): DWORD;
public
// code
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//RC2 cipher implementation
const
sBoxRC2: array[0..255] of byte = (
$D9, $78, $F9, $C4, $19, $DD, $B5, $ED, $28, $E9, $FD, $79, $4A, $A0, $D8, $9D,
$C6, $7E, $37, $83, $2B, $76, $53, $8E, $62, $4C, $64, $88, $44, $8B, $FB, $A2,
$17, $9A, $59, $F5, $87, $B3, $4F, $13, $61, $45, $6D, $8D, $09, $81, $7D, $32,
$BD, $8F, $40, $EB, $86, $B7, $7B, $0B, $F0, $95, $21, $22, $5C, $6B, $4E, $82,
$54, $D6, $65, $93, $CE, $60, $B2, $1C, $73, $56, $C0, $14, $A7, $8C, $F1, $DC,
$12, $75, $CA, $1F, $3B, $BE, $E4, $D1, $42, $3D, $D4, $30, $A3, $3C, $B6, $26,
$6F, $BF, $0E, $DA, $46, $69, $07, $57, $27, $F2, $1D, $9B, $BC, $94, $43, $03,
$F8, $11, $C7, $F6, $90, $EF, $3E, $E7, $06, $C3, $D5, $2F, $C8, $66, $1E, $D7,
$08, $E8, $EA, $DE, $80, $52, $EE, $F7, $84, $AA, $72, $AC, $35, $4D, $6A, $2A,
$96, $1A, $D2, $71, $5A, $15, $49, $74, $4B, $9F, $D0, $5E, $04, $18, $A4, $EC,
$C2, $E0, $41, $6E, $0F, $51, $CB, $CC, $24, $91, $AF, $50, $A1, $F4, $70, $39,
$99, $7C, $3A, $85, $23, $B8, $B4, $7A, $FC, $02, $36, $5B, $25, $55, $97, $31,
$2D, $5D, $FA, $98, $E3, $8A, $92, $AE, $05, $DF, $29, $10, $67, $6C, $BA, $C9,
$D3, $00, $E6, $CF, $E1, $9E, $A8, $2C, $63, $16, $01, $3F, $58, $E2, $89, $A9,
$0D, $38, $34, $1B, $AB, $33, $FF, $B0, $BB, $48, $0C, $5F, $B9, $B1, $CD, $2E,
$C5, $F3, $DB, $47, $E5, $A5, $9C, $77, $0A, $A6, $20, $68, $FE, $7F, $C1, $AD);
type
PRC2 = ^TRC2;
TRC2 = object(TBlockCipher64)
protected
KeyData: array[0..63] of Word;
public
// code
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//RC5 cipher implementation
const
NUMROUNDSRC5 = 12; { number of rounds must be between 12-16 }
const
sBoxRC5: array[0..33] of DWORD = (
$B7E15163, $5618CB1C, $F45044D5, $9287BE8E, $30BF3847, $CEF6B200,
$6D2E2BB9, $0B65A572, $A99D1F2B, $47D498E4, $E60C129D, $84438C56,
$227B060F, $C0B27FC8, $5EE9F981, $FD21733A, $9B58ECF3, $399066AC,
$D7C7E065, $75FF5A1E, $1436D3D7, $B26E4D90, $50A5C749, $EEDD4102,
$8D14BABB, $2B4C3474, $C983AE2D, $67BB27E6, $05F2A19F, $A42A1B58,
$42619511, $E0990ECA, $7ED08883, $1D08023C);
type
PRC5 = ^TRC5;
TRC5 = object(TBlockCipher64)
protected
KeyData: array[0..((NUMROUNDSRC5 * 2) + 1)] of DWORD;
public
// code
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//RC6 cipher implementation
const
NUMROUNDSRC6 = 20; { number of rounds must be between 16-24 }
const
sBoxRC6: array[0..51] of DWORD = (
$B7E15163, $5618CB1C, $F45044D5, $9287BE8E, $30BF3847, $CEF6B200,
$6D2E2BB9, $0B65A572, $A99D1F2B, $47D498E4, $E60C129D, $84438C56,
$227B060F, $C0B27FC8, $5EE9F981, $FD21733A, $9B58ECF3, $399066AC,
$D7C7E065, $75FF5A1E, $1436D3D7, $B26E4D90, $50A5C749, $EEDD4102,
$8D14BABB, $2B4C3474, $C983AE2D, $67BB27E6, $05F2A19F, $A42A1B58,
$42619511, $E0990ECA, $7ED08883, $1D08023C, $BB3F7BF5, $5976F5AE,
$F7AE6F67, $95E5E920, $341D62D9, $D254DC92, $708C564B, $0EC3D004,
$ACFB49BD, $4B32C376, $E96A3D2F, $87A1B6E8, $25D930A1, $C410AA5A,
$62482413, $007F9DCC, $9EB71785, $3CEE913E);
type
PRC6 = ^TRC6;
TRC6 = object(TBlockCipher128)
protected
KeyData: array[0..((NUMROUNDSRC6 * 2) + 3)] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
//TEA cipher implementation
const
Delta = $9E3779B9;
Rounds = 32;
type
PTEA = ^TTEA;
TTEA = object(TBlockCipher64)
protected
KeyData: array[0..3] of DWORD;
public
// code
procedure Burn; virtual;
procedure InitKey(const Key; Size: longword); virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
// DES and 3DES cipher implementation
const
shifts2: array[0..15] of byte =
(0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
des_skb: array[0..7, 0..63] of DWORD = (
(
(* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 *)
$00000000, $00000010, $20000000, $20000010,
$00010000, $00010010, $20010000, $20010010,
$00000800, $00000810, $20000800, $20000810,
$00010800, $00010810, $20010800, $20010810,
$00000020, $00000030, $20000020, $20000030,
$00010020, $00010030, $20010020, $20010030,
$00000820, $00000830, $20000820, $20000830,
$00010820, $00010830, $20010820, $20010830,
$00080000, $00080010, $20080000, $20080010,
$00090000, $00090010, $20090000, $20090010,
$00080800, $00080810, $20080800, $20080810,
$00090800, $00090810, $20090800, $20090810,
$00080020, $00080030, $20080020, $20080030,
$00090020, $00090030, $20090020, $20090030,
$00080820, $00080830, $20080820, $20080830,
$00090820, $00090830, $20090820, $20090830
), (
(* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 *)
$00000000, $02000000, $00002000, $02002000,
$00200000, $02200000, $00202000, $02202000,
$00000004, $02000004, $00002004, $02002004,
$00200004, $02200004, $00202004, $02202004,
$00000400, $02000400, $00002400, $02002400,
$00200400, $02200400, $00202400, $02202400,
$00000404, $02000404, $00002404, $02002404,
$00200404, $02200404, $00202404, $02202404,
$10000000, $12000000, $10002000, $12002000,
$10200000, $12200000, $10202000, $12202000,
$10000004, $12000004, $10002004, $12002004,
$10200004, $12200004, $10202004, $12202004,
$10000400, $12000400, $10002400, $12002400,
$10200400, $12200400, $10202400, $12202400,
$10000404, $12000404, $10002404, $12002404,
$10200404, $12200404, $10202404, $12202404
), (
(* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 *)
$00000000, $00000001, $00040000, $00040001,
$01000000, $01000001, $01040000, $01040001,
$00000002, $00000003, $00040002, $00040003,
$01000002, $01000003, $01040002, $01040003,
$00000200, $00000201, $00040200, $00040201,
$01000200, $01000201, $01040200, $01040201,
$00000202, $00000203, $00040202, $00040203,
$01000202, $01000203, $01040202, $01040203,
$08000000, $08000001, $08040000, $08040001,
$09000000, $09000001, $09040000, $09040001,
$08000002, $08000003, $08040002, $08040003,
$09000002, $09000003, $09040002, $09040003,
$08000200, $08000201, $08040200, $08040201,
$09000200, $09000201, $09040200, $09040201,
$08000202, $08000203, $08040202, $08040203,
$09000202, $09000203, $09040202, $09040203
), (
(* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 *)
$00000000, $00100000, $00000100, $00100100,
$00000008, $00100008, $00000108, $00100108,
$00001000, $00101000, $00001100, $00101100,
$00001008, $00101008, $00001108, $00101108,
$04000000, $04100000, $04000100, $04100100,
$04000008, $04100008, $04000108, $04100108,
$04001000, $04101000, $04001100, $04101100,
$04001008, $04101008, $04001108, $04101108,
$00020000, $00120000, $00020100, $00120100,
$00020008, $00120008, $00020108, $00120108,
$00021000, $00121000, $00021100, $00121100,
$00021008, $00121008, $00021108, $00121108,
$04020000, $04120000, $04020100, $04120100,
$04020008, $04120008, $04020108, $04120108,
$04021000, $04121000, $04021100, $04121100,
$04021008, $04121008, $04021108, $04121108
), (
(* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 *)
$00000000, $10000000, $00010000, $10010000,
$00000004, $10000004, $00010004, $10010004,
$20000000, $30000000, $20010000, $30010000,
$20000004, $30000004, $20010004, $30010004,
$00100000, $10100000, $00110000, $10110000,
$00100004, $10100004, $00110004, $10110004,
$20100000, $30100000, $20110000, $30110000,
$20100004, $30100004, $20110004, $30110004,
$00001000, $10001000, $00011000, $10011000,
$00001004, $10001004, $00011004, $10011004,
$20001000, $30001000, $20011000, $30011000,
$20001004, $30001004, $20011004, $30011004,
$00101000, $10101000, $00111000, $10111000,
$00101004, $10101004, $00111004, $10111004,
$20101000, $30101000, $20111000, $30111000,
$20101004, $30101004, $20111004, $30111004
), (
(* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 *)
$00000000, $08000000, $00000008, $08000008,
$00000400, $08000400, $00000408, $08000408,
$00020000, $08020000, $00020008, $08020008,
$00020400, $08020400, $00020408, $08020408,
$00000001, $08000001, $00000009, $08000009,
$00000401, $08000401, $00000409, $08000409,
$00020001, $08020001, $00020009, $08020009,
$00020401, $08020401, $00020409, $08020409,
$02000000, $0A000000, $02000008, $0A000008,
$02000400, $0A000400, $02000408, $0A000408,
$02020000, $0A020000, $02020008, $0A020008,
$02020400, $0A020400, $02020408, $0A020408,
$02000001, $0A000001, $02000009, $0A000009,
$02000401, $0A000401, $02000409, $0A000409,
$02020001, $0A020001, $02020009, $0A020009,
$02020401, $0A020401, $02020409, $0A020409
), (
(* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 *)
$00000000, $00000100, $00080000, $00080100,
$01000000, $01000100, $01080000, $01080100,
$00000010, $00000110, $00080010, $00080110,
$01000010, $01000110, $01080010, $01080110,
$00200000, $00200100, $00280000, $00280100,
$01200000, $01200100, $01280000, $01280100,
$00200010, $00200110, $00280010, $00280110,
$01200010, $01200110, $01280010, $01280110,
$00000200, $00000300, $00080200, $00080300,
$01000200, $01000300, $01080200, $01080300,
$00000210, $00000310, $00080210, $00080310,
$01000210, $01000310, $01080210, $01080310,
$00200200, $00200300, $00280200, $00280300,
$01200200, $01200300, $01280200, $01280300,
$00200210, $00200310, $00280210, $00280310,
$01200210, $01200310, $01280210, $01280310
), (
(* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 *)
$00000000, $04000000, $00040000, $04040000,
$00000002, $04000002, $00040002, $04040002,
$00002000, $04002000, $00042000, $04042000,
$00002002, $04002002, $00042002, $04042002,
$00000020, $04000020, $00040020, $04040020,
$00000022, $04000022, $00040022, $04040022,
$00002020, $04002020, $00042020, $04042020,
$00002022, $04002022, $00042022, $04042022,
$00000800, $04000800, $00040800, $04040800,
$00000802, $04000802, $00040802, $04040802,
$00002800, $04002800, $00042800, $04042800,
$00002802, $04002802, $00042802, $04042802,
$00000820, $04000820, $00040820, $04040820,
$00000822, $04000822, $00040822, $04040822,
$00002820, $04002820, $00042820, $04042820,
$00002822, $04002822, $00042822, $04042822
));
des_sptrans: array[0..7, 0..63] of DWORD = (
(
(* nibble 0 *)
$02080800, $00080000, $02000002, $02080802,
$02000000, $00080802, $00080002, $02000002,
$00080802, $02080800, $02080000, $00000802,
$02000802, $02000000, $00000000, $00080002,
$00080000, $00000002, $02000800, $00080800,
$02080802, $02080000, $00000802, $02000800,
$00000002, $00000800, $00080800, $02080002,
$00000800, $02000802, $02080002, $00000000,
$00000000, $02080802, $02000800, $00080002,
$02080800, $00080000, $00000802, $02000800,
$02080002, $00000800, $00080800, $02000002,
$00080802, $00000002, $02000002, $02080000,
$02080802, $00080800, $02080000, $02000802,
$02000000, $00000802, $00080002, $00000000,
$00080000, $02000000, $02000802, $02080800,
$00000002, $02080002, $00000800, $00080802
), (
(* nibble 1 *)
$40108010, $00000000, $00108000, $40100000,
$40000010, $00008010, $40008000, $00108000,
$00008000, $40100010, $00000010, $40008000,
$00100010, $40108000, $40100000, $00000010,
$00100000, $40008010, $40100010, $00008000,
$00108010, $40000000, $00000000, $00100010,
$40008010, $00108010, $40108000, $40000010,
$40000000, $00100000, $00008010, $40108010,
$00100010, $40108000, $40008000, $00108010,
$40108010, $00100010, $40000010, $00000000,
$40000000, $00008010, $00100000, $40100010,
$00008000, $40000000, $00108010, $40008010,
$40108000, $00008000, $00000000, $40000010,
$00000010, $40108010, $00108000, $40100000,
$40100010, $00100000, $00008010, $40008000,
$40008010, $00000010, $40100000, $00108000
), (
(* nibble 2 *)
$04000001, $04040100, $00000100, $04000101,
$00040001, $04000000, $04000101, $00040100,
$04000100, $00040000, $04040000, $00000001,
$04040101, $00000101, $00000001, $04040001,
$00000000, $00040001, $04040100, $00000100,
$00000101, $04040101, $00040000, $04000001,
$04040001, $04000100, $00040101, $04040000,
$00040100, $00000000, $04000000, $00040101,
$04040100, $00000100, $00000001, $00040000,
$00000101, $00040001, $04040000, $04000101,
$00000000, $04040100, $00040100, $04040001,
$00040001, $04000000, $04040101, $00000001,
$00040101, $04000001, $04000000, $04040101,
$00040000, $04000100, $04000101, $00040100,
$04000100, $00000000, $04040001, $00000101,
$04000001, $00040101, $00000100, $04040000
), (
(* nibble 3 *)
$00401008, $10001000, $00000008, $10401008,
$00000000, $10400000, $10001008, $00400008,
$10401000, $10000008, $10000000, $00001008,
$10000008, $00401008, $00400000, $10000000,
$10400008, $00401000, $00001000, $00000008,
$00401000, $10001008, $10400000, $00001000,
$00001008, $00000000, $00400008, $10401000,
$10001000, $10400008, $10401008, $00400000,
$10400008, $00001008, $00400000, $10000008,
$00401000, $10001000, $00000008, $10400000,
$10001008, $00000000, $00001000, $00400008,
$00000000, $10400008, $10401000, $00001000,
$10000000, $10401008, $00401008, $00400000,
$10401008, $00000008, $10001000, $00401008,
$00400008, $00401000, $10400000, $10001008,
$00001008, $10000000, $10000008, $10401000
), (
(* nibble 4 *)
$08000000, $00010000, $00000400, $08010420,
$08010020, $08000400, $00010420, $08010000,
$00010000, $00000020, $08000020, $00010400,
$08000420, $08010020, $08010400, $00000000,
$00010400, $08000000, $00010020, $00000420,
$08000400, $00010420, $00000000, $08000020,
$00000020, $08000420, $08010420, $00010020,
$08010000, $00000400, $00000420, $08010400,
$08010400, $08000420, $00010020, $08010000,
$00010000, $00000020, $08000020, $08000400,
$08000000, $00010400, $08010420, $00000000,
$00010420, $08000000, $00000400, $00010020,
$08000420, $00000400, $00000000, $08010420,
$08010020, $08010400, $00000420, $00010000,
$00010400, $08010020, $08000400, $00000420,
$00000020, $00010420, $08010000, $08000020
), (
(* nibble 5 *)
$80000040, $00200040, $00000000, $80202000,
$00200040, $00002000, $80002040, $00200000,
$00002040, $80202040, $00202000, $80000000,
$80002000, $80000040, $80200000, $00202040,
$00200000, $80002040, $80200040, $00000000,
$00002000, $00000040, $80202000, $80200040,
$80202040, $80200000, $80000000, $00002040,
$00000040, $00202000, $00202040, $80002000,
$00002040, $80000000, $80002000, $00202040,
$80202000, $00200040, $00000000, $80002000,
$80000000, $00002000, $80200040, $00200000,
$00200040, $80202040, $00202000, $00000040,
$80202040, $00202000, $00200000, $80002040,
$80000040, $80200000, $00202040, $00000000,
$00002000, $80000040, $80002040, $80202000,
$80200000, $00002040, $00000040, $80200040
), (
(* nibble 6 *)
$00004000, $00000200, $01000200, $01000004,
$01004204, $00004004, $00004200, $00000000,
$01000000, $01000204, $00000204, $01004000,
$00000004, $01004200, $01004000, $00000204,
$01000204, $00004000, $00004004, $01004204,
$00000000, $01000200, $01000004, $00004200,
$01004004, $00004204, $01004200, $00000004,
$00004204, $01004004, $00000200, $01000000,
$00004204, $01004000, $01004004, $00000204,
$00004000, $00000200, $01000000, $01004004,
$01000204, $00004204, $00004200, $00000000,
$00000200, $01000004, $00000004, $01000200,
$00000000, $01000204, $01000200, $00004200,
$00000204, $00004000, $01004204, $01000000,
$01004200, $00000004, $00004004, $01004204,
$01000004, $01004200, $01004000, $00004004
), (
(* nibble 7 *)
$20800080, $20820000, $00020080, $00000000,
$20020000, $00800080, $20800000, $20820080,
$00000080, $20000000, $00820000, $00020080,
$00820080, $20020080, $20000080, $20800000,
$00020000, $00820080, $00800080, $20020000,
$20820080, $20000080, $00000000, $00820000,
$20000000, $00800000, $20020080, $20800080,
$00800000, $00020000, $20820000, $00000080,
$00800000, $00020000, $20000080, $20820080,
$00020080, $20000000, $00000000, $00820000,
$20800080, $20020080, $20020000, $00800080,
$20820000, $00000080, $00800080, $20020000,
$20820080, $00800000, $20800000, $20000080,
$00820000, $00020080, $20020080, $20800000,
$00000080, $20820000, $00820080, $00000000,
$20000000, $20800080, $00020000, $00820080
));
// DES and 3DES cipher implementation
type
Pdwordarray = ^Tdwordarray;
Tdwordarray = array[0..8191] of DWORD;
type
TCustomDES = object(TBlockCipher64)
protected
procedure DoInit(KeyB: PByteArray; KeyData: Pdwordarray); virtual;
procedure EncryptBlock(const Indata; var Outdata; KeyData: Pdwordarray);
procedure DecryptBlock(const Indata; var Outdata; KeyData: Pdwordarray);
end;
type
PDES = ^TDES;
TDES = object(TCustomDES)
protected
KeyData: array[0..31] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
type
P3DES = ^T3DES;
T3DES = object(TCustomDES)
protected
KeyData: array[0..2, 0..31] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
type
Pwordarray = ^Twordarray;
Twordarray = array[0..19383] of Word;
// ICE, ICE2 and ThinICE cipher implementation
type
TCustomICE = object(TBlockCipher64)
protected
Rounds: DWORD;
ik_keysched: array[0..31, 0..2] of DWORD;
function f(p, sk: DWORD): DWORD;
procedure key_sched_build(kb: Pwordarray; n: DWORD; keyrot: Pdwordarray);
procedure InitIce(const Key; Size: longword; n: DWORD);
public
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
end;
type
PICE = ^TICE;
TICE = object(TCustomICE)
protected
public
procedure InitKey(const Key; Size: longword); virtual;
destructor Destroy; virtual;
end;
type
PThinIce = ^TThinIce;
TThinIce = object(TCustomICE)
protected
public
procedure InitKey(const Key; Size: longword); virtual;
destructor Destroy; virtual;
end;
type
PICE2 = ^TICE2;
TICE2 = object(TCustomICE)
protected
public
procedure InitKey(const Key; Size: longword); virtual;
destructor Destroy; virtual;
end;
// Mars cipher implementation
const
S_Box: array[0..511] of DWORD = (
$09D0C479, $28C8FFE0, $84AA6C39, $9DAD7287,
$7DFF9BE3, $D4268361, $C96DA1D4, $7974CC93,
$85D0582E, $2A4B5705, $1CA16A62, $C3BD279D,
$0F1F25E5, $5160372F, $C695C1FB, $4D7FF1E4,
$AE5F6BF4, $0D72EE46, $FF23DE8A, $B1CF8E83,
$F14902E2, $3E981E42, $8BF53EB6, $7F4BF8AC,
$83631F83, $25970205, $76AFE784, $3A7931D4,
$4F846450, $5C64C3F6, $210A5F18, $C6986A26,
$28F4E826, $3A60A81C, $D340A664, $7EA820C4,
$526687C5, $7EDDD12B, $32A11D1D, $9C9EF086,
$80F6E831, $AB6F04AD, $56FB9B53, $8B2E095C,
$B68556AE, $D2250B0D, $294A7721, $E21FB253,
$AE136749, $E82AAE86, $93365104, $99404A66,
$78A784DC, $B69BA84B, $04046793, $23DB5C1E,
$46CAE1D6, $2FE28134, $5A223942, $1863CD5B,
$C190C6E3, $07DFB846, $6EB88816, $2D0DCC4A,
$A4CCAE59, $3798670D, $CBFA9493, $4F481D45,
$EAFC8CA8, $DB1129D6, $B0449E20, $0F5407FB,
$6167D9A8, $D1F45763, $4DAA96C3, $3BEC5958,
$ABABA014, $B6CCD201, $38D6279F, $02682215,
$8F376CD5, $092C237E, $BFC56593, $32889D2C,
$854B3E95, $05BB9B43, $7DCD5DCD, $A02E926C,
$FAE527E5, $36A1C330, $3412E1AE, $F257F462,
$3C4F1D71, $30A2E809, $68E5F551, $9C61BA44,
$5DED0AB8, $75CE09C8, $9654F93E, $698C0CCA,
$243CB3E4, $2B062B97, $0F3B8D9E, $00E050DF,
$FC5D6166, $E35F9288, $C079550D, $0591AEE8,
$8E531E74, $75FE3578, $2F6D829A, $F60B21AE,
$95E8EB8D, $6699486B, $901D7D9B, $FD6D6E31,
$1090ACEF, $E0670DD8, $DAB2E692, $CD6D4365,
$E5393514, $3AF345F0, $6241FC4D, $460DA3A3,
$7BCF3729, $8BF1D1E0, $14AAC070, $1587ED55,
$3AFD7D3E, $D2F29E01, $29A9D1F6, $EFB10C53,
$CF3B870F, $B414935C, $664465ED, $024ACAC7,
$59A744C1, $1D2936A7, $DC580AA6, $CF574CA8,
$040A7A10, $6CD81807, $8A98BE4C, $ACCEA063,
$C33E92B5, $D1E0E03D, $B322517E, $2092BD13,
$386B2C4A, $52E8DD58, $58656DFB, $50820371,
$41811896, $E337EF7E, $D39FB119, $C97F0DF6,
$68FEA01B, $A150A6E5, $55258962, $EB6FF41B,
$D7C9CD7A, $A619CD9E, $BCF09576, $2672C073,
$F003FB3C, $4AB7A50B, $1484126A, $487BA9B1,
$A64FC9C6, $F6957D49, $38B06A75, $DD805FCD,
$63D094CF, $F51C999E, $1AA4D343, $B8495294,
$CE9F8E99, $BFFCD770, $C7C275CC, $378453A7,
$7B21BE33, $397F41BD, $4E94D131, $92CC1F98,
$5915EA51, $99F861B7, $C9980A88, $1D74FD5F,
$B0A495F8, $614DEED0, $B5778EEA, $5941792D,
$FA90C1F8, $33F824B4, $C4965372, $3FF6D550,
$4CA5FEC0, $8630E964, $5B3FBBD6, $7DA26A48,
$B203231A, $04297514, $2D639306, $2EB13149,
$16A45272, $532459A0, $8E5F4872, $F966C7D9,
$07128DC0, $0D44DB62, $AFC8D52D, $06316131,
$D838E7CE, $1BC41D00, $3A2E8C0F, $EA83837E,
$B984737D, $13BA4891, $C4F8B949, $A6D6ACB3,
$A215CDCE, $8359838B, $6BD1AA31, $F579DD52,
$21B93F93, $F5176781, $187DFDDE, $E94AEB76,
$2B38FD54, $431DE1DA, $AB394825, $9AD3048F,
$DFEA32AA, $659473E3, $623F7863, $F3346C59,
$AB3AB685, $3346A90B, $6B56443E, $C6DE01F8,
$8D421FC0, $9B0ED10C, $88F1A1E9, $54C1F029,
$7DEAD57B, $8D7BA426, $4CF5178A, $551A7CCA,
$1A9A5F08, $FCD651B9, $25605182, $E11FC6C3,
$B6FD9676, $337B3027, $B7C8EB14, $9E5FD030,
$6B57E354, $AD913CF7, $7E16688D, $58872A69,
$2C2FC7DF, $E389CCC6, $30738DF1, $0824A734,
$E1797A8B, $A4A8D57B, $5B5D193B, $C8A8309B,
$73F9A978, $73398D32, $0F59573E, $E9DF2B03,
$E8A5B6C8, $848D0704, $98DF93C2, $720A1DC3,
$684F259A, $943BA848, $A6370152, $863B5EA3,
$D17B978B, $6D9B58EF, $0A700DD4, $A73D36BF,
$8E6A0829, $8695BC14, $E35B3447, $933AC568,
$8894B022, $2F511C27, $DDFBCC3C, $006662B6,
$117C83FE, $4E12B414, $C2BCA766, $3A2FEC10,
$F4562420, $55792E2A, $46F5D857, $CEDA25CE,
$C3601D3B, $6C00AB46, $EFAC9C28, $B3C35047,
$611DFEE3, $257C3207, $FDD58482, $3B14D84F,
$23BECB64, $A075F3A3, $088F8EAD, $07ADF158,
$7796943C, $FACABF3D, $C09730CD, $F7679969,
$DA44E9ED, $2C854C12, $35935FA3, $2F057D9F,
$690624F8, $1CB0BAFD, $7B0DBDC6, $810F23BB,
$FA929A1A, $6D969A17, $6742979B, $74AC7D05,
$010E65C4, $86A3D963, $F907B5A0, $D0042BD3,
$158D7D03, $287A8255, $BBA8366F, $096EDC33,
$21916A7B, $77B56B86, $951622F9, $A6C5E650,
$8CEA17D1, $CD8C62BC, $A3D63433, $358A68FD,
$0F9B9D3C, $D6AA295B, $FE33384A, $C000738E,
$CD67EB2F, $E2EB6DC2, $97338B02, $06C9F246,
$419CF1AD, $2B83C045, $3723F18A, $CB5B3089,
$160BEAD7, $5D494656, $35F8A74B, $1E4E6C9E,
$000399BD, $67466880, $B4174831, $ACF423B2,
$CA815AB3, $5A6395E7, $302A67C5, $8BDB446B,
$108F8FA4, $10223EDA, $92B8B48B, $7F38D0EE,
$AB2701D4, $0262D415, $AF224A30, $B3D88ABA,
$F8B2C3AF, $DAF7EF70, $CC97D3B7, $E9614B6C,
$2BAEBFF4, $70F687CF, $386C9156, $CE092EE5,
$01E87DA6, $6CE91E6A, $BB7BCC84, $C7922C20,
$9D3B71FD, $060E41C6, $D7590F15, $4E03BB47,
$183C198E, $63EEB240, $2DDBF49A, $6D5CBA54,
$923750AF, $F9E14236, $7838162B, $59726C72,
$81B66760, $BB2926C1, $48A0CE0D, $A6C0496D,
$AD43507B, $718D496A, $9DF057AF, $44B1BDE6,
$054356DC, $DE7CED35, $D51A138B, $62088CC9,
$35830311, $C96EFCA2, $686F86EC, $8E77CB68,
$63E1D6B8, $C80F9778, $79C491FD, $1B4C67F2,
$72698D7D, $5E368C31, $F7D95E2E, $A1D3493F,
$DCD9433E, $896F1552, $4BC4CA7A, $A6D1BAF4,
$A5A96DCC, $0BEF8B46, $A169FDA7, $74DF40B7,
$4E208804, $9A756607, $038E87C8, $20211E44,
$8B7AD4BF, $C6403F35, $1848E36D, $80BDB038,
$1E62891C, $643D2107, $BF04D6F8, $21092C8C,
$F644F389, $0778404E, $7B78ADB8, $A2C52D53,
$42157ABE, $A2253E2E, $7BF3F4AE, $80F594F9,
$953194E7, $77EB92ED, $B3816930, $DA8D9336,
$BF447469, $F26D9483, $EE6FAED5, $71371235,
$DE425F73, $B4E59F43, $7DBE2D4E, $2D37B185,
$49DC9A63, $98C39D98, $1301C9A2, $389B1BBF,
$0C18588D, $A421C1BA, $7AA3865C, $71E08558,
$3C5CFCAA, $7D239CA4, $0297D9DD, $D7DC2830,
$4B37802B, $7428AB54, $AEEE0347, $4B3FBB85,
$692F2F08, $134E578E, $36D9E0BF, $AE8B5FCF,
$EDB93ECF, $2B27248E, $170EB1EF, $7DC57FD6,
$1E760F16, $B1136601, $864E1B9B, $D7EA7319,
$3AB871BD, $CFA4D76F, $E31BD782, $0DBEB469,
$ABB96061, $5370F85D, $FFB07E37, $DA30D0FB,
$EBC977B6, $0B98B40F, $3A4D0FE6, $DF4FC26B,
$159CF22A, $C298D6E2, $2B78EF6A, $61A94AC0,
$AB561187, $14EEA0F0, $DF0D4164, $19AF70EE);
vk: array[0..6] of DWORD = (
$09D0C479, $28C8FFE0, $84AA6C39, $9DAD7287, $7DFF9BE3, $D4268361,
$C96DA1D4);
type
PMars = ^TMars;
TMars = object(TBlockCipher128)
protected
KeyData: array[0..39] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
// Rijndael cipher implementation
const
MAXBC = 8;
MAXKC = 8;
S: array[0..255] of byte = (
99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118,
202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192,
183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21,
4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117,
9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132,
83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207,
208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168,
81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210,
205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115,
96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121,
231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8,
186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138,
112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158,
225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223,
140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22);
T1: array[0..255, 0..3] of byte = (
($C6, $63, $63, $A5), ($F8, $7C, $7C, $84), ($EE, $77, $77, $99), ($F6, $7B, $7B, $8D),
($FF, $F2, $F2, $0D), ($D6, $6B, $6B, $BD), ($DE, $6F, $6F, $B1), ($91, $C5, $C5, $54),
($60, $30, $30, $50), ($02, $01, $01, $03), ($CE, $67, $67, $A9), ($56, $2B, $2B, $7D),
($E7, $FE, $FE, $19), ($B5, $D7, $D7, $62), ($4D, $AB, $AB, $E6), ($EC, $76, $76, $9A),
($8F, $CA, $CA, $45), ($1F, $82, $82, $9D), ($89, $C9, $C9, $40), ($FA, $7D, $7D, $87),
($EF, $FA, $FA, $15), ($B2, $59, $59, $EB), ($8E, $47, $47, $C9), ($FB, $F0, $F0, $0B),
($41, $AD, $AD, $EC), ($B3, $D4, $D4, $67), ($5F, $A2, $A2, $FD), ($45, $AF, $AF, $EA),
($23, $9C, $9C, $BF), ($53, $A4, $A4, $F7), ($E4, $72, $72, $96), ($9B, $C0, $C0, $5B),
($75, $B7, $B7, $C2), ($E1, $FD, $FD, $1C), ($3D, $93, $93, $AE), ($4C, $26, $26, $6A),
($6C, $36, $36, $5A), ($7E, $3F, $3F, $41), ($F5, $F7, $F7, $02), ($83, $CC, $CC, $4F),
($68, $34, $34, $5C), ($51, $A5, $A5, $F4), ($D1, $E5, $E5, $34), ($F9, $F1, $F1, $08),
($E2, $71, $71, $93), ($AB, $D8, $D8, $73), ($62, $31, $31, $53), ($2A, $15, $15, $3F),
($08, $04, $04, $0C), ($95, $C7, $C7, $52), ($46, $23, $23, $65), ($9D, $C3, $C3, $5E),
($30, $18, $18, $28), ($37, $96, $96, $A1), ($0A, $05, $05, $0F), ($2F, $9A, $9A, $B5),
($0E, $07, $07, $09), ($24, $12, $12, $36), ($1B, $80, $80, $9B), ($DF, $E2, $E2, $3D),
($CD, $EB, $EB, $26), ($4E, $27, $27, $69), ($7F, $B2, $B2, $CD), ($EA, $75, $75, $9F),
($12, $09, $09, $1B), ($1D, $83, $83, $9E), ($58, $2C, $2C, $74), ($34, $1A, $1A, $2E),
($36, $1B, $1B, $2D), ($DC, $6E, $6E, $B2), ($B4, $5A, $5A, $EE), ($5B, $A0, $A0, $FB),
($A4, $52, $52, $F6), ($76, $3B, $3B, $4D), ($B7, $D6, $D6, $61), ($7D, $B3, $B3, $CE),
($52, $29, $29, $7B), ($DD, $E3, $E3, $3E), ($5E, $2F, $2F, $71), ($13, $84, $84, $97),
($A6, $53, $53, $F5), ($B9, $D1, $D1, $68), ($00, $00, $00, $00), ($C1, $ED, $ED, $2C),
($40, $20, $20, $60), ($E3, $FC, $FC, $1F), ($79, $B1, $B1, $C8), ($B6, $5B, $5B, $ED),
($D4, $6A, $6A, $BE), ($8D, $CB, $CB, $46), ($67, $BE, $BE, $D9), ($72, $39, $39, $4B),
($94, $4A, $4A, $DE), ($98, $4C, $4C, $D4), ($B0, $58, $58, $E8), ($85, $CF, $CF, $4A),
($BB, $D0, $D0, $6B), ($C5, $EF, $EF, $2A), ($4F, $AA, $AA, $E5), ($ED, $FB, $FB, $16),
($86, $43, $43, $C5), ($9A, $4D, $4D, $D7), ($66, $33, $33, $55), ($11, $85, $85, $94),
($8A, $45, $45, $CF), ($E9, $F9, $F9, $10), ($04, $02, $02, $06), ($FE, $7F, $7F, $81),
($A0, $50, $50, $F0), ($78, $3C, $3C, $44), ($25, $9F, $9F, $BA), ($4B, $A8, $A8, $E3),
($A2, $51, $51, $F3), ($5D, $A3, $A3, $FE), ($80, $40, $40, $C0), ($05, $8F, $8F, $8A),
($3F, $92, $92, $AD), ($21, $9D, $9D, $BC), ($70, $38, $38, $48), ($F1, $F5, $F5, $04),
($63, $BC, $BC, $DF), ($77, $B6, $B6, $C1), ($AF, $DA, $DA, $75), ($42, $21, $21, $63),
($20, $10, $10, $30), ($E5, $FF, $FF, $1A), ($FD, $F3, $F3, $0E), ($BF, $D2, $D2, $6D),
($81, $CD, $CD, $4C), ($18, $0C, $0C, $14), ($26, $13, $13, $35), ($C3, $EC, $EC, $2F),
($BE, $5F, $5F, $E1), ($35, $97, $97, $A2), ($88, $44, $44, $CC), ($2E, $17, $17, $39),
($93, $C4, $C4, $57), ($55, $A7, $A7, $F2), ($FC, $7E, $7E, $82), ($7A, $3D, $3D, $47),
($C8, $64, $64, $AC), ($BA, $5D, $5D, $E7), ($32, $19, $19, $2B), ($E6, $73, $73, $95),
($C0, $60, $60, $A0), ($19, $81, $81, $98), ($9E, $4F, $4F, $D1), ($A3, $DC, $DC, $7F),
($44, $22, $22, $66), ($54, $2A, $2A, $7E), ($3B, $90, $90, $AB), ($0B, $88, $88, $83),
($8C, $46, $46, $CA), ($C7, $EE, $EE, $29), ($6B, $B8, $B8, $D3), ($28, $14, $14, $3C),
($A7, $DE, $DE, $79), ($BC, $5E, $5E, $E2), ($16, $0B, $0B, $1D), ($AD, $DB, $DB, $76),
($DB, $E0, $E0, $3B), ($64, $32, $32, $56), ($74, $3A, $3A, $4E), ($14, $0A, $0A, $1E),
($92, $49, $49, $DB), ($0C, $06, $06, $0A), ($48, $24, $24, $6C), ($B8, $5C, $5C, $E4),
($9F, $C2, $C2, $5D), ($BD, $D3, $D3, $6E), ($43, $AC, $AC, $EF), ($C4, $62, $62, $A6),
($39, $91, $91, $A8), ($31, $95, $95, $A4), ($D3, $E4, $E4, $37), ($F2, $79, $79, $8B),
($D5, $E7, $E7, $32), ($8B, $C8, $C8, $43), ($6E, $37, $37, $59), ($DA, $6D, $6D, $B7),
($01, $8D, $8D, $8C), ($B1, $D5, $D5, $64), ($9C, $4E, $4E, $D2), ($49, $A9, $A9, $E0),
($D8, $6C, $6C, $B4), ($AC, $56, $56, $FA), ($F3, $F4, $F4, $07), ($CF, $EA, $EA, $25),
($CA, $65, $65, $AF), ($F4, $7A, $7A, $8E), ($47, $AE, $AE, $E9), ($10, $08, $08, $18),
($6F, $BA, $BA, $D5), ($F0, $78, $78, $88), ($4A, $25, $25, $6F), ($5C, $2E, $2E, $72),
($38, $1C, $1C, $24), ($57, $A6, $A6, $F1), ($73, $B4, $B4, $C7), ($97, $C6, $C6, $51),
($CB, $E8, $E8, $23), ($A1, $DD, $DD, $7C), ($E8, $74, $74, $9C), ($3E, $1F, $1F, $21),
($96, $4B, $4B, $DD), ($61, $BD, $BD, $DC), ($0D, $8B, $8B, $86), ($0F, $8A, $8A, $85),
($E0, $70, $70, $90), ($7C, $3E, $3E, $42), ($71, $B5, $B5, $C4), ($CC, $66, $66, $AA),
($90, $48, $48, $D8), ($06, $03, $03, $05), ($F7, $F6, $F6, $01), ($1C, $0E, $0E, $12),
($C2, $61, $61, $A3), ($6A, $35, $35, $5F), ($AE, $57, $57, $F9), ($69, $B9, $B9, $D0),
($17, $86, $86, $91), ($99, $C1, $C1, $58), ($3A, $1D, $1D, $27), ($27, $9E, $9E, $B9),
($D9, $E1, $E1, $38), ($EB, $F8, $F8, $13), ($2B, $98, $98, $B3), ($22, $11, $11, $33),
($D2, $69, $69, $BB), ($A9, $D9, $D9, $70), ($07, $8E, $8E, $89), ($33, $94, $94, $A7),
($2D, $9B, $9B, $B6), ($3C, $1E, $1E, $22), ($15, $87, $87, $92), ($C9, $E9, $E9, $20),
($87, $CE, $CE, $49), ($AA, $55, $55, $FF), ($50, $28, $28, $78), ($A5, $DF, $DF, $7A),
($03, $8C, $8C, $8F), ($59, $A1, $A1, $F8), ($09, $89, $89, $80), ($1A, $0D, $0D, $17),
($65, $BF, $BF, $DA), ($D7, $E6, $E6, $31), ($84, $42, $42, $C6), ($D0, $68, $68, $B8),
($82, $41, $41, $C3), ($29, $99, $99, $B0), ($5A, $2D, $2D, $77), ($1E, $0F, $0F, $11),
($7B, $B0, $B0, $CB), ($A8, $54, $54, $FC), ($6D, $BB, $BB, $D6), ($2C, $16, $16, $3A));
T2: array[0..255, 0..3] of byte = (
($A5, $C6, $63, $63), ($84, $F8, $7C, $7C), ($99, $EE, $77, $77), ($8D, $F6, $7B, $7B),
($0D, $FF, $F2, $F2), ($BD, $D6, $6B, $6B), ($B1, $DE, $6F, $6F), ($54, $91, $C5, $C5),
($50, $60, $30, $30), ($03, $02, $01, $01), ($A9, $CE, $67, $67), ($7D, $56, $2B, $2B),
($19, $E7, $FE, $FE), ($62, $B5, $D7, $D7), ($E6, $4D, $AB, $AB), ($9A, $EC, $76, $76),
($45, $8F, $CA, $CA), ($9D, $1F, $82, $82), ($40, $89, $C9, $C9), ($87, $FA, $7D, $7D),
($15, $EF, $FA, $FA), ($EB, $B2, $59, $59), ($C9, $8E, $47, $47), ($0B, $FB, $F0, $F0),
($EC, $41, $AD, $AD), ($67, $B3, $D4, $D4), ($FD, $5F, $A2, $A2), ($EA, $45, $AF, $AF),
($BF, $23, $9C, $9C), ($F7, $53, $A4, $A4), ($96, $E4, $72, $72), ($5B, $9B, $C0, $C0),
($C2, $75, $B7, $B7), ($1C, $E1, $FD, $FD), ($AE, $3D, $93, $93), ($6A, $4C, $26, $26),
($5A, $6C, $36, $36), ($41, $7E, $3F, $3F), ($02, $F5, $F7, $F7), ($4F, $83, $CC, $CC),
($5C, $68, $34, $34), ($F4, $51, $A5, $A5), ($34, $D1, $E5, $E5), ($08, $F9, $F1, $F1),
($93, $E2, $71, $71), ($73, $AB, $D8, $D8), ($53, $62, $31, $31), ($3F, $2A, $15, $15),
($0C, $08, $04, $04), ($52, $95, $C7, $C7), ($65, $46, $23, $23), ($5E, $9D, $C3, $C3),
($28, $30, $18, $18), ($A1, $37, $96, $96), ($0F, $0A, $05, $05), ($B5, $2F, $9A, $9A),
($09, $0E, $07, $07), ($36, $24, $12, $12), ($9B, $1B, $80, $80), ($3D, $DF, $E2, $E2),
($26, $CD, $EB, $EB), ($69, $4E, $27, $27), ($CD, $7F, $B2, $B2), ($9F, $EA, $75, $75),
($1B, $12, $09, $09), ($9E, $1D, $83, $83), ($74, $58, $2C, $2C), ($2E, $34, $1A, $1A),
($2D, $36, $1B, $1B), ($B2, $DC, $6E, $6E), ($EE, $B4, $5A, $5A), ($FB, $5B, $A0, $A0),
($F6, $A4, $52, $52), ($4D, $76, $3B, $3B), ($61, $B7, $D6, $D6), ($CE, $7D, $B3, $B3),
($7B, $52, $29, $29), ($3E, $DD, $E3, $E3), ($71, $5E, $2F, $2F), ($97, $13, $84, $84),
($F5, $A6, $53, $53), ($68, $B9, $D1, $D1), ($00, $00, $00, $00), ($2C, $C1, $ED, $ED),
($60, $40, $20, $20), ($1F, $E3, $FC, $FC), ($C8, $79, $B1, $B1), ($ED, $B6, $5B, $5B),
($BE, $D4, $6A, $6A), ($46, $8D, $CB, $CB), ($D9, $67, $BE, $BE), ($4B, $72, $39, $39),
($DE, $94, $4A, $4A), ($D4, $98, $4C, $4C), ($E8, $B0, $58, $58), ($4A, $85, $CF, $CF),
($6B, $BB, $D0, $D0), ($2A, $C5, $EF, $EF), ($E5, $4F, $AA, $AA), ($16, $ED, $FB, $FB),
($C5, $86, $43, $43), ($D7, $9A, $4D, $4D), ($55, $66, $33, $33), ($94, $11, $85, $85),
($CF, $8A, $45, $45), ($10, $E9, $F9, $F9), ($06, $04, $02, $02), ($81, $FE, $7F, $7F),
($F0, $A0, $50, $50), ($44, $78, $3C, $3C), ($BA, $25, $9F, $9F), ($E3, $4B, $A8, $A8),
($F3, $A2, $51, $51), ($FE, $5D, $A3, $A3), ($C0, $80, $40, $40), ($8A, $05, $8F, $8F),
($AD, $3F, $92, $92), ($BC, $21, $9D, $9D), ($48, $70, $38, $38), ($04, $F1, $F5, $F5),
($DF, $63, $BC, $BC), ($C1, $77, $B6, $B6), ($75, $AF, $DA, $DA), ($63, $42, $21, $21),
($30, $20, $10, $10), ($1A, $E5, $FF, $FF), ($0E, $FD, $F3, $F3), ($6D, $BF, $D2, $D2),
($4C, $81, $CD, $CD), ($14, $18, $0C, $0C), ($35, $26, $13, $13), ($2F, $C3, $EC, $EC),
($E1, $BE, $5F, $5F), ($A2, $35, $97, $97), ($CC, $88, $44, $44), ($39, $2E, $17, $17),
($57, $93, $C4, $C4), ($F2, $55, $A7, $A7), ($82, $FC, $7E, $7E), ($47, $7A, $3D, $3D),
($AC, $C8, $64, $64), ($E7, $BA, $5D, $5D), ($2B, $32, $19, $19), ($95, $E6, $73, $73),
($A0, $C0, $60, $60), ($98, $19, $81, $81), ($D1, $9E, $4F, $4F), ($7F, $A3, $DC, $DC),
($66, $44, $22, $22), ($7E, $54, $2A, $2A), ($AB, $3B, $90, $90), ($83, $0B, $88, $88),
($CA, $8C, $46, $46), ($29, $C7, $EE, $EE), ($D3, $6B, $B8, $B8), ($3C, $28, $14, $14),
($79, $A7, $DE, $DE), ($E2, $BC, $5E, $5E), ($1D, $16, $0B, $0B), ($76, $AD, $DB, $DB),
($3B, $DB, $E0, $E0), ($56, $64, $32, $32), ($4E, $74, $3A, $3A), ($1E, $14, $0A, $0A),
($DB, $92, $49, $49), ($0A, $0C, $06, $06), ($6C, $48, $24, $24), ($E4, $B8, $5C, $5C),
($5D, $9F, $C2, $C2), ($6E, $BD, $D3, $D3), ($EF, $43, $AC, $AC), ($A6, $C4, $62, $62),
($A8, $39, $91, $91), ($A4, $31, $95, $95), ($37, $D3, $E4, $E4), ($8B, $F2, $79, $79),
($32, $D5, $E7, $E7), ($43, $8B, $C8, $C8), ($59, $6E, $37, $37), ($B7, $DA, $6D, $6D),
($8C, $01, $8D, $8D), ($64, $B1, $D5, $D5), ($D2, $9C, $4E, $4E), ($E0, $49, $A9, $A9),
($B4, $D8, $6C, $6C), ($FA, $AC, $56, $56), ($07, $F3, $F4, $F4), ($25, $CF, $EA, $EA),
($AF, $CA, $65, $65), ($8E, $F4, $7A, $7A), ($E9, $47, $AE, $AE), ($18, $10, $08, $08),
($D5, $6F, $BA, $BA), ($88, $F0, $78, $78), ($6F, $4A, $25, $25), ($72, $5C, $2E, $2E),
($24, $38, $1C, $1C), ($F1, $57, $A6, $A6), ($C7, $73, $B4, $B4), ($51, $97, $C6, $C6),
($23, $CB, $E8, $E8), ($7C, $A1, $DD, $DD), ($9C, $E8, $74, $74), ($21, $3E, $1F, $1F),
($DD, $96, $4B, $4B), ($DC, $61, $BD, $BD), ($86, $0D, $8B, $8B), ($85, $0F, $8A, $8A),
($90, $E0, $70, $70), ($42, $7C, $3E, $3E), ($C4, $71, $B5, $B5), ($AA, $CC, $66, $66),
($D8, $90, $48, $48), ($05, $06, $03, $03), ($01, $F7, $F6, $F6), ($12, $1C, $0E, $0E),
($A3, $C2, $61, $61), ($5F, $6A, $35, $35), ($F9, $AE, $57, $57), ($D0, $69, $B9, $B9),
($91, $17, $86, $86), ($58, $99, $C1, $C1), ($27, $3A, $1D, $1D), ($B9, $27, $9E, $9E),
($38, $D9, $E1, $E1), ($13, $EB, $F8, $F8), ($B3, $2B, $98, $98), ($33, $22, $11, $11),
($BB, $D2, $69, $69), ($70, $A9, $D9, $D9), ($89, $07, $8E, $8E), ($A7, $33, $94, $94),
($B6, $2D, $9B, $9B), ($22, $3C, $1E, $1E), ($92, $15, $87, $87), ($20, $C9, $E9, $E9),
($49, $87, $CE, $CE), ($FF, $AA, $55, $55), ($78, $50, $28, $28), ($7A, $A5, $DF, $DF),
($8F, $03, $8C, $8C), ($F8, $59, $A1, $A1), ($80, $09, $89, $89), ($17, $1A, $0D, $0D),
($DA, $65, $BF, $BF), ($31, $D7, $E6, $E6), ($C6, $84, $42, $42), ($B8, $D0, $68, $68),
($C3, $82, $41, $41), ($B0, $29, $99, $99), ($77, $5A, $2D, $2D), ($11, $1E, $0F, $0F),
($CB, $7B, $B0, $B0), ($FC, $A8, $54, $54), ($D6, $6D, $BB, $BB), ($3A, $2C, $16, $16));
T3: array[0..255, 0..3] of byte = (
($63, $A5, $C6, $63), ($7C, $84, $F8, $7C), ($77, $99, $EE, $77), ($7B, $8D, $F6, $7B),
($F2, $0D, $FF, $F2), ($6B, $BD, $D6, $6B), ($6F, $B1, $DE, $6F), ($C5, $54, $91, $C5),
($30, $50, $60, $30), ($01, $03, $02, $01), ($67, $A9, $CE, $67), ($2B, $7D, $56, $2B),
($FE, $19, $E7, $FE), ($D7, $62, $B5, $D7), ($AB, $E6, $4D, $AB), ($76, $9A, $EC, $76),
($CA, $45, $8F, $CA), ($82, $9D, $1F, $82), ($C9, $40, $89, $C9), ($7D, $87, $FA, $7D),
($FA, $15, $EF, $FA), ($59, $EB, $B2, $59), ($47, $C9, $8E, $47), ($F0, $0B, $FB, $F0),
($AD, $EC, $41, $AD), ($D4, $67, $B3, $D4), ($A2, $FD, $5F, $A2), ($AF, $EA, $45, $AF),
($9C, $BF, $23, $9C), ($A4, $F7, $53, $A4), ($72, $96, $E4, $72), ($C0, $5B, $9B, $C0),
($B7, $C2, $75, $B7), ($FD, $1C, $E1, $FD), ($93, $AE, $3D, $93), ($26, $6A, $4C, $26),
($36, $5A, $6C, $36), ($3F, $41, $7E, $3F), ($F7, $02, $F5, $F7), ($CC, $4F, $83, $CC),
($34, $5C, $68, $34), ($A5, $F4, $51, $A5), ($E5, $34, $D1, $E5), ($F1, $08, $F9, $F1),
($71, $93, $E2, $71), ($D8, $73, $AB, $D8), ($31, $53, $62, $31), ($15, $3F, $2A, $15),
($04, $0C, $08, $04), ($C7, $52, $95, $C7), ($23, $65, $46, $23), ($C3, $5E, $9D, $C3),
($18, $28, $30, $18), ($96, $A1, $37, $96), ($05, $0F, $0A, $05), ($9A, $B5, $2F, $9A),
($07, $09, $0E, $07), ($12, $36, $24, $12), ($80, $9B, $1B, $80), ($E2, $3D, $DF, $E2),
($EB, $26, $CD, $EB), ($27, $69, $4E, $27), ($B2, $CD, $7F, $B2), ($75, $9F, $EA, $75),
($09, $1B, $12, $09), ($83, $9E, $1D, $83), ($2C, $74, $58, $2C), ($1A, $2E, $34, $1A),
($1B, $2D, $36, $1B), ($6E, $B2, $DC, $6E), ($5A, $EE, $B4, $5A), ($A0, $FB, $5B, $A0),
($52, $F6, $A4, $52), ($3B, $4D, $76, $3B), ($D6, $61, $B7, $D6), ($B3, $CE, $7D, $B3),
($29, $7B, $52, $29), ($E3, $3E, $DD, $E3), ($2F, $71, $5E, $2F), ($84, $97, $13, $84),
($53, $F5, $A6, $53), ($D1, $68, $B9, $D1), ($00, $00, $00, $00), ($ED, $2C, $C1, $ED),
($20, $60, $40, $20), ($FC, $1F, $E3, $FC), ($B1, $C8, $79, $B1), ($5B, $ED, $B6, $5B),
($6A, $BE, $D4, $6A), ($CB, $46, $8D, $CB), ($BE, $D9, $67, $BE), ($39, $4B, $72, $39),
($4A, $DE, $94, $4A), ($4C, $D4, $98, $4C), ($58, $E8, $B0, $58), ($CF, $4A, $85, $CF),
($D0, $6B, $BB, $D0), ($EF, $2A, $C5, $EF), ($AA, $E5, $4F, $AA), ($FB, $16, $ED, $FB),
($43, $C5, $86, $43), ($4D, $D7, $9A, $4D), ($33, $55, $66, $33), ($85, $94, $11, $85),
($45, $CF, $8A, $45), ($F9, $10, $E9, $F9), ($02, $06, $04, $02), ($7F, $81, $FE, $7F),
($50, $F0, $A0, $50), ($3C, $44, $78, $3C), ($9F, $BA, $25, $9F), ($A8, $E3, $4B, $A8),
($51, $F3, $A2, $51), ($A3, $FE, $5D, $A3), ($40, $C0, $80, $40), ($8F, $8A, $05, $8F),
($92, $AD, $3F, $92), ($9D, $BC, $21, $9D), ($38, $48, $70, $38), ($F5, $04, $F1, $F5),
($BC, $DF, $63, $BC), ($B6, $C1, $77, $B6), ($DA, $75, $AF, $DA), ($21, $63, $42, $21),
($10, $30, $20, $10), ($FF, $1A, $E5, $FF), ($F3, $0E, $FD, $F3), ($D2, $6D, $BF, $D2),
($CD, $4C, $81, $CD), ($0C, $14, $18, $0C), ($13, $35, $26, $13), ($EC, $2F, $C3, $EC),
($5F, $E1, $BE, $5F), ($97, $A2, $35, $97), ($44, $CC, $88, $44), ($17, $39, $2E, $17),
($C4, $57, $93, $C4), ($A7, $F2, $55, $A7), ($7E, $82, $FC, $7E), ($3D, $47, $7A, $3D),
($64, $AC, $C8, $64), ($5D, $E7, $BA, $5D), ($19, $2B, $32, $19), ($73, $95, $E6, $73),
($60, $A0, $C0, $60), ($81, $98, $19, $81), ($4F, $D1, $9E, $4F), ($DC, $7F, $A3, $DC),
($22, $66, $44, $22), ($2A, $7E, $54, $2A), ($90, $AB, $3B, $90), ($88, $83, $0B, $88),
($46, $CA, $8C, $46), ($EE, $29, $C7, $EE), ($B8, $D3, $6B, $B8), ($14, $3C, $28, $14),
($DE, $79, $A7, $DE), ($5E, $E2, $BC, $5E), ($0B, $1D, $16, $0B), ($DB, $76, $AD, $DB),
($E0, $3B, $DB, $E0), ($32, $56, $64, $32), ($3A, $4E, $74, $3A), ($0A, $1E, $14, $0A),
($49, $DB, $92, $49), ($06, $0A, $0C, $06), ($24, $6C, $48, $24), ($5C, $E4, $B8, $5C),
($C2, $5D, $9F, $C2), ($D3, $6E, $BD, $D3), ($AC, $EF, $43, $AC), ($62, $A6, $C4, $62),
($91, $A8, $39, $91), ($95, $A4, $31, $95), ($E4, $37, $D3, $E4), ($79, $8B, $F2, $79),
($E7, $32, $D5, $E7), ($C8, $43, $8B, $C8), ($37, $59, $6E, $37), ($6D, $B7, $DA, $6D),
($8D, $8C, $01, $8D), ($D5, $64, $B1, $D5), ($4E, $D2, $9C, $4E), ($A9, $E0, $49, $A9),
($6C, $B4, $D8, $6C), ($56, $FA, $AC, $56), ($F4, $07, $F3, $F4), ($EA, $25, $CF, $EA),
($65, $AF, $CA, $65), ($7A, $8E, $F4, $7A), ($AE, $E9, $47, $AE), ($08, $18, $10, $08),
($BA, $D5, $6F, $BA), ($78, $88, $F0, $78), ($25, $6F, $4A, $25), ($2E, $72, $5C, $2E),
($1C, $24, $38, $1C), ($A6, $F1, $57, $A6), ($B4, $C7, $73, $B4), ($C6, $51, $97, $C6),
($E8, $23, $CB, $E8), ($DD, $7C, $A1, $DD), ($74, $9C, $E8, $74), ($1F, $21, $3E, $1F),
($4B, $DD, $96, $4B), ($BD, $DC, $61, $BD), ($8B, $86, $0D, $8B), ($8A, $85, $0F, $8A),
($70, $90, $E0, $70), ($3E, $42, $7C, $3E), ($B5, $C4, $71, $B5), ($66, $AA, $CC, $66),
($48, $D8, $90, $48), ($03, $05, $06, $03), ($F6, $01, $F7, $F6), ($0E, $12, $1C, $0E),
($61, $A3, $C2, $61), ($35, $5F, $6A, $35), ($57, $F9, $AE, $57), ($B9, $D0, $69, $B9),
($86, $91, $17, $86), ($C1, $58, $99, $C1), ($1D, $27, $3A, $1D), ($9E, $B9, $27, $9E),
($E1, $38, $D9, $E1), ($F8, $13, $EB, $F8), ($98, $B3, $2B, $98), ($11, $33, $22, $11),
($69, $BB, $D2, $69), ($D9, $70, $A9, $D9), ($8E, $89, $07, $8E), ($94, $A7, $33, $94),
($9B, $B6, $2D, $9B), ($1E, $22, $3C, $1E), ($87, $92, $15, $87), ($E9, $20, $C9, $E9),
($CE, $49, $87, $CE), ($55, $FF, $AA, $55), ($28, $78, $50, $28), ($DF, $7A, $A5, $DF),
($8C, $8F, $03, $8C), ($A1, $F8, $59, $A1), ($89, $80, $09, $89), ($0D, $17, $1A, $0D),
($BF, $DA, $65, $BF), ($E6, $31, $D7, $E6), ($42, $C6, $84, $42), ($68, $B8, $D0, $68),
($41, $C3, $82, $41), ($99, $B0, $29, $99), ($2D, $77, $5A, $2D), ($0F, $11, $1E, $0F),
($B0, $CB, $7B, $B0), ($54, $FC, $A8, $54), ($BB, $D6, $6D, $BB), ($16, $3A, $2C, $16));
T4: array[0..255, 0..3] of byte = (
($63, $63, $A5, $C6), ($7C, $7C, $84, $F8), ($77, $77, $99, $EE), ($7B, $7B, $8D, $F6),
($F2, $F2, $0D, $FF), ($6B, $6B, $BD, $D6), ($6F, $6F, $B1, $DE), ($C5, $C5, $54, $91),
($30, $30, $50, $60), ($01, $01, $03, $02), ($67, $67, $A9, $CE), ($2B, $2B, $7D, $56),
($FE, $FE, $19, $E7), ($D7, $D7, $62, $B5), ($AB, $AB, $E6, $4D), ($76, $76, $9A, $EC),
($CA, $CA, $45, $8F), ($82, $82, $9D, $1F), ($C9, $C9, $40, $89), ($7D, $7D, $87, $FA),
($FA, $FA, $15, $EF), ($59, $59, $EB, $B2), ($47, $47, $C9, $8E), ($F0, $F0, $0B, $FB),
($AD, $AD, $EC, $41), ($D4, $D4, $67, $B3), ($A2, $A2, $FD, $5F), ($AF, $AF, $EA, $45),
($9C, $9C, $BF, $23), ($A4, $A4, $F7, $53), ($72, $72, $96, $E4), ($C0, $C0, $5B, $9B),
($B7, $B7, $C2, $75), ($FD, $FD, $1C, $E1), ($93, $93, $AE, $3D), ($26, $26, $6A, $4C),
($36, $36, $5A, $6C), ($3F, $3F, $41, $7E), ($F7, $F7, $02, $F5), ($CC, $CC, $4F, $83),
($34, $34, $5C, $68), ($A5, $A5, $F4, $51), ($E5, $E5, $34, $D1), ($F1, $F1, $08, $F9),
($71, $71, $93, $E2), ($D8, $D8, $73, $AB), ($31, $31, $53, $62), ($15, $15, $3F, $2A),
($04, $04, $0C, $08), ($C7, $C7, $52, $95), ($23, $23, $65, $46), ($C3, $C3, $5E, $9D),
($18, $18, $28, $30), ($96, $96, $A1, $37), ($05, $05, $0F, $0A), ($9A, $9A, $B5, $2F),
($07, $07, $09, $0E), ($12, $12, $36, $24), ($80, $80, $9B, $1B), ($E2, $E2, $3D, $DF),
($EB, $EB, $26, $CD), ($27, $27, $69, $4E), ($B2, $B2, $CD, $7F), ($75, $75, $9F, $EA),
($09, $09, $1B, $12), ($83, $83, $9E, $1D), ($2C, $2C, $74, $58), ($1A, $1A, $2E, $34),
($1B, $1B, $2D, $36), ($6E, $6E, $B2, $DC), ($5A, $5A, $EE, $B4), ($A0, $A0, $FB, $5B),
($52, $52, $F6, $A4), ($3B, $3B, $4D, $76), ($D6, $D6, $61, $B7), ($B3, $B3, $CE, $7D),
($29, $29, $7B, $52), ($E3, $E3, $3E, $DD), ($2F, $2F, $71, $5E), ($84, $84, $97, $13),
($53, $53, $F5, $A6), ($D1, $D1, $68, $B9), ($00, $00, $00, $00), ($ED, $ED, $2C, $C1),
($20, $20, $60, $40), ($FC, $FC, $1F, $E3), ($B1, $B1, $C8, $79), ($5B, $5B, $ED, $B6),
($6A, $6A, $BE, $D4), ($CB, $CB, $46, $8D), ($BE, $BE, $D9, $67), ($39, $39, $4B, $72),
($4A, $4A, $DE, $94), ($4C, $4C, $D4, $98), ($58, $58, $E8, $B0), ($CF, $CF, $4A, $85),
($D0, $D0, $6B, $BB), ($EF, $EF, $2A, $C5), ($AA, $AA, $E5, $4F), ($FB, $FB, $16, $ED),
($43, $43, $C5, $86), ($4D, $4D, $D7, $9A), ($33, $33, $55, $66), ($85, $85, $94, $11),
($45, $45, $CF, $8A), ($F9, $F9, $10, $E9), ($02, $02, $06, $04), ($7F, $7F, $81, $FE),
($50, $50, $F0, $A0), ($3C, $3C, $44, $78), ($9F, $9F, $BA, $25), ($A8, $A8, $E3, $4B),
($51, $51, $F3, $A2), ($A3, $A3, $FE, $5D), ($40, $40, $C0, $80), ($8F, $8F, $8A, $05),
($92, $92, $AD, $3F), ($9D, $9D, $BC, $21), ($38, $38, $48, $70), ($F5, $F5, $04, $F1),
($BC, $BC, $DF, $63), ($B6, $B6, $C1, $77), ($DA, $DA, $75, $AF), ($21, $21, $63, $42),
($10, $10, $30, $20), ($FF, $FF, $1A, $E5), ($F3, $F3, $0E, $FD), ($D2, $D2, $6D, $BF),
($CD, $CD, $4C, $81), ($0C, $0C, $14, $18), ($13, $13, $35, $26), ($EC, $EC, $2F, $C3),
($5F, $5F, $E1, $BE), ($97, $97, $A2, $35), ($44, $44, $CC, $88), ($17, $17, $39, $2E),
($C4, $C4, $57, $93), ($A7, $A7, $F2, $55), ($7E, $7E, $82, $FC), ($3D, $3D, $47, $7A),
($64, $64, $AC, $C8), ($5D, $5D, $E7, $BA), ($19, $19, $2B, $32), ($73, $73, $95, $E6),
($60, $60, $A0, $C0), ($81, $81, $98, $19), ($4F, $4F, $D1, $9E), ($DC, $DC, $7F, $A3),
($22, $22, $66, $44), ($2A, $2A, $7E, $54), ($90, $90, $AB, $3B), ($88, $88, $83, $0B),
($46, $46, $CA, $8C), ($EE, $EE, $29, $C7), ($B8, $B8, $D3, $6B), ($14, $14, $3C, $28),
($DE, $DE, $79, $A7), ($5E, $5E, $E2, $BC), ($0B, $0B, $1D, $16), ($DB, $DB, $76, $AD),
($E0, $E0, $3B, $DB), ($32, $32, $56, $64), ($3A, $3A, $4E, $74), ($0A, $0A, $1E, $14),
($49, $49, $DB, $92), ($06, $06, $0A, $0C), ($24, $24, $6C, $48), ($5C, $5C, $E4, $B8),
($C2, $C2, $5D, $9F), ($D3, $D3, $6E, $BD), ($AC, $AC, $EF, $43), ($62, $62, $A6, $C4),
($91, $91, $A8, $39), ($95, $95, $A4, $31), ($E4, $E4, $37, $D3), ($79, $79, $8B, $F2),
($E7, $E7, $32, $D5), ($C8, $C8, $43, $8B), ($37, $37, $59, $6E), ($6D, $6D, $B7, $DA),
($8D, $8D, $8C, $01), ($D5, $D5, $64, $B1), ($4E, $4E, $D2, $9C), ($A9, $A9, $E0, $49),
($6C, $6C, $B4, $D8), ($56, $56, $FA, $AC), ($F4, $F4, $07, $F3), ($EA, $EA, $25, $CF),
($65, $65, $AF, $CA), ($7A, $7A, $8E, $F4), ($AE, $AE, $E9, $47), ($08, $08, $18, $10),
($BA, $BA, $D5, $6F), ($78, $78, $88, $F0), ($25, $25, $6F, $4A), ($2E, $2E, $72, $5C),
($1C, $1C, $24, $38), ($A6, $A6, $F1, $57), ($B4, $B4, $C7, $73), ($C6, $C6, $51, $97),
($E8, $E8, $23, $CB), ($DD, $DD, $7C, $A1), ($74, $74, $9C, $E8), ($1F, $1F, $21, $3E),
($4B, $4B, $DD, $96), ($BD, $BD, $DC, $61), ($8B, $8B, $86, $0D), ($8A, $8A, $85, $0F),
($70, $70, $90, $E0), ($3E, $3E, $42, $7C), ($B5, $B5, $C4, $71), ($66, $66, $AA, $CC),
($48, $48, $D8, $90), ($03, $03, $05, $06), ($F6, $F6, $01, $F7), ($0E, $0E, $12, $1C),
($61, $61, $A3, $C2), ($35, $35, $5F, $6A), ($57, $57, $F9, $AE), ($B9, $B9, $D0, $69),
($86, $86, $91, $17), ($C1, $C1, $58, $99), ($1D, $1D, $27, $3A), ($9E, $9E, $B9, $27),
($E1, $E1, $38, $D9), ($F8, $F8, $13, $EB), ($98, $98, $B3, $2B), ($11, $11, $33, $22),
($69, $69, $BB, $D2), ($D9, $D9, $70, $A9), ($8E, $8E, $89, $07), ($94, $94, $A7, $33),
($9B, $9B, $B6, $2D), ($1E, $1E, $22, $3C), ($87, $87, $92, $15), ($E9, $E9, $20, $C9),
($CE, $CE, $49, $87), ($55, $55, $FF, $AA), ($28, $28, $78, $50), ($DF, $DF, $7A, $A5),
($8C, $8C, $8F, $03), ($A1, $A1, $F8, $59), ($89, $89, $80, $09), ($0D, $0D, $17, $1A),
($BF, $BF, $DA, $65), ($E6, $E6, $31, $D7), ($42, $42, $C6, $84), ($68, $68, $B8, $D0),
($41, $41, $C3, $82), ($99, $99, $B0, $29), ($2D, $2D, $77, $5A), ($0F, $0F, $11, $1E),
($B0, $B0, $CB, $7B), ($54, $54, $FC, $A8), ($BB, $BB, $D6, $6D), ($16, $16, $3A, $2C));
T5: array[0..255, 0..3] of byte = (
($51, $F4, $A7, $50), ($7E, $41, $65, $53), ($1A, $17, $A4, $C3), ($3A, $27, $5E, $96),
($3B, $AB, $6B, $CB), ($1F, $9D, $45, $F1), ($AC, $FA, $58, $AB), ($4B, $E3, $03, $93),
($20, $30, $FA, $55), ($AD, $76, $6D, $F6), ($88, $CC, $76, $91), ($F5, $02, $4C, $25),
($4F, $E5, $D7, $FC), ($C5, $2A, $CB, $D7), ($26, $35, $44, $80), ($B5, $62, $A3, $8F),
($DE, $B1, $5A, $49), ($25, $BA, $1B, $67), ($45, $EA, $0E, $98), ($5D, $FE, $C0, $E1),
($C3, $2F, $75, $02), ($81, $4C, $F0, $12), ($8D, $46, $97, $A3), ($6B, $D3, $F9, $C6),
($03, $8F, $5F, $E7), ($15, $92, $9C, $95), ($BF, $6D, $7A, $EB), ($95, $52, $59, $DA),
($D4, $BE, $83, $2D), ($58, $74, $21, $D3), ($49, $E0, $69, $29), ($8E, $C9, $C8, $44),
($75, $C2, $89, $6A), ($F4, $8E, $79, $78), ($99, $58, $3E, $6B), ($27, $B9, $71, $DD),
($BE, $E1, $4F, $B6), ($F0, $88, $AD, $17), ($C9, $20, $AC, $66), ($7D, $CE, $3A, $B4),
($63, $DF, $4A, $18), ($E5, $1A, $31, $82), ($97, $51, $33, $60), ($62, $53, $7F, $45),
($B1, $64, $77, $E0), ($BB, $6B, $AE, $84), ($FE, $81, $A0, $1C), ($F9, $08, $2B, $94),
($70, $48, $68, $58), ($8F, $45, $FD, $19), ($94, $DE, $6C, $87), ($52, $7B, $F8, $B7),
($AB, $73, $D3, $23), ($72, $4B, $02, $E2), ($E3, $1F, $8F, $57), ($66, $55, $AB, $2A),
($B2, $EB, $28, $07), ($2F, $B5, $C2, $03), ($86, $C5, $7B, $9A), ($D3, $37, $08, $A5),
($30, $28, $87, $F2), ($23, $BF, $A5, $B2), ($02, $03, $6A, $BA), ($ED, $16, $82, $5C),
($8A, $CF, $1C, $2B), ($A7, $79, $B4, $92), ($F3, $07, $F2, $F0), ($4E, $69, $E2, $A1),
($65, $DA, $F4, $CD), ($06, $05, $BE, $D5), ($D1, $34, $62, $1F), ($C4, $A6, $FE, $8A),
($34, $2E, $53, $9D), ($A2, $F3, $55, $A0), ($05, $8A, $E1, $32), ($A4, $F6, $EB, $75),
($0B, $83, $EC, $39), ($40, $60, $EF, $AA), ($5E, $71, $9F, $06), ($BD, $6E, $10, $51),
($3E, $21, $8A, $F9), ($96, $DD, $06, $3D), ($DD, $3E, $05, $AE), ($4D, $E6, $BD, $46),
($91, $54, $8D, $B5), ($71, $C4, $5D, $05), ($04, $06, $D4, $6F), ($60, $50, $15, $FF),
($19, $98, $FB, $24), ($D6, $BD, $E9, $97), ($89, $40, $43, $CC), ($67, $D9, $9E, $77),
($B0, $E8, $42, $BD), ($07, $89, $8B, $88), ($E7, $19, $5B, $38), ($79, $C8, $EE, $DB),
($A1, $7C, $0A, $47), ($7C, $42, $0F, $E9), ($F8, $84, $1E, $C9), ($00, $00, $00, $00),
($09, $80, $86, $83), ($32, $2B, $ED, $48), ($1E, $11, $70, $AC), ($6C, $5A, $72, $4E),
($FD, $0E, $FF, $FB), ($0F, $85, $38, $56), ($3D, $AE, $D5, $1E), ($36, $2D, $39, $27),
($0A, $0F, $D9, $64), ($68, $5C, $A6, $21), ($9B, $5B, $54, $D1), ($24, $36, $2E, $3A),
($0C, $0A, $67, $B1), ($93, $57, $E7, $0F), ($B4, $EE, $96, $D2), ($1B, $9B, $91, $9E),
($80, $C0, $C5, $4F), ($61, $DC, $20, $A2), ($5A, $77, $4B, $69), ($1C, $12, $1A, $16),
($E2, $93, $BA, $0A), ($C0, $A0, $2A, $E5), ($3C, $22, $E0, $43), ($12, $1B, $17, $1D),
($0E, $09, $0D, $0B), ($F2, $8B, $C7, $AD), ($2D, $B6, $A8, $B9), ($14, $1E, $A9, $C8),
($57, $F1, $19, $85), ($AF, $75, $07, $4C), ($EE, $99, $DD, $BB), ($A3, $7F, $60, $FD),
($F7, $01, $26, $9F), ($5C, $72, $F5, $BC), ($44, $66, $3B, $C5), ($5B, $FB, $7E, $34),
($8B, $43, $29, $76), ($CB, $23, $C6, $DC), ($B6, $ED, $FC, $68), ($B8, $E4, $F1, $63),
($D7, $31, $DC, $CA), ($42, $63, $85, $10), ($13, $97, $22, $40), ($84, $C6, $11, $20),
($85, $4A, $24, $7D), ($D2, $BB, $3D, $F8), ($AE, $F9, $32, $11), ($C7, $29, $A1, $6D),
($1D, $9E, $2F, $4B), ($DC, $B2, $30, $F3), ($0D, $86, $52, $EC), ($77, $C1, $E3, $D0),
($2B, $B3, $16, $6C), ($A9, $70, $B9, $99), ($11, $94, $48, $FA), ($47, $E9, $64, $22),
($A8, $FC, $8C, $C4), ($A0, $F0, $3F, $1A), ($56, $7D, $2C, $D8), ($22, $33, $90, $EF),
($87, $49, $4E, $C7), ($D9, $38, $D1, $C1), ($8C, $CA, $A2, $FE), ($98, $D4, $0B, $36),
($A6, $F5, $81, $CF), ($A5, $7A, $DE, $28), ($DA, $B7, $8E, $26), ($3F, $AD, $BF, $A4),
($2C, $3A, $9D, $E4), ($50, $78, $92, $0D), ($6A, $5F, $CC, $9B), ($54, $7E, $46, $62),
($F6, $8D, $13, $C2), ($90, $D8, $B8, $E8), ($2E, $39, $F7, $5E), ($82, $C3, $AF, $F5),
($9F, $5D, $80, $BE), ($69, $D0, $93, $7C), ($6F, $D5, $2D, $A9), ($CF, $25, $12, $B3),
($C8, $AC, $99, $3B), ($10, $18, $7D, $A7), ($E8, $9C, $63, $6E), ($DB, $3B, $BB, $7B),
($CD, $26, $78, $09), ($6E, $59, $18, $F4), ($EC, $9A, $B7, $01), ($83, $4F, $9A, $A8),
($E6, $95, $6E, $65), ($AA, $FF, $E6, $7E), ($21, $BC, $CF, $08), ($EF, $15, $E8, $E6),
($BA, $E7, $9B, $D9), ($4A, $6F, $36, $CE), ($EA, $9F, $09, $D4), ($29, $B0, $7C, $D6),
($31, $A4, $B2, $AF), ($2A, $3F, $23, $31), ($C6, $A5, $94, $30), ($35, $A2, $66, $C0),
($74, $4E, $BC, $37), ($FC, $82, $CA, $A6), ($E0, $90, $D0, $B0), ($33, $A7, $D8, $15),
($F1, $04, $98, $4A), ($41, $EC, $DA, $F7), ($7F, $CD, $50, $0E), ($17, $91, $F6, $2F),
($76, $4D, $D6, $8D), ($43, $EF, $B0, $4D), ($CC, $AA, $4D, $54), ($E4, $96, $04, $DF),
($9E, $D1, $B5, $E3), ($4C, $6A, $88, $1B), ($C1, $2C, $1F, $B8), ($46, $65, $51, $7F),
($9D, $5E, $EA, $04), ($01, $8C, $35, $5D), ($FA, $87, $74, $73), ($FB, $0B, $41, $2E),
($B3, $67, $1D, $5A), ($92, $DB, $D2, $52), ($E9, $10, $56, $33), ($6D, $D6, $47, $13),
($9A, $D7, $61, $8C), ($37, $A1, $0C, $7A), ($59, $F8, $14, $8E), ($EB, $13, $3C, $89),
($CE, $A9, $27, $EE), ($B7, $61, $C9, $35), ($E1, $1C, $E5, $ED), ($7A, $47, $B1, $3C),
($9C, $D2, $DF, $59), ($55, $F2, $73, $3F), ($18, $14, $CE, $79), ($73, $C7, $37, $BF),
($53, $F7, $CD, $EA), ($5F, $FD, $AA, $5B), ($DF, $3D, $6F, $14), ($78, $44, $DB, $86),
($CA, $AF, $F3, $81), ($B9, $68, $C4, $3E), ($38, $24, $34, $2C), ($C2, $A3, $40, $5F),
($16, $1D, $C3, $72), ($BC, $E2, $25, $0C), ($28, $3C, $49, $8B), ($FF, $0D, $95, $41),
($39, $A8, $01, $71), ($08, $0C, $B3, $DE), ($D8, $B4, $E4, $9C), ($64, $56, $C1, $90),
($7B, $CB, $84, $61), ($D5, $32, $B6, $70), ($48, $6C, $5C, $74), ($D0, $B8, $57, $42));
T6: array[0..255, 0..3] of byte = (
($50, $51, $F4, $A7), ($53, $7E, $41, $65), ($C3, $1A, $17, $A4), ($96, $3A, $27, $5E),
($CB, $3B, $AB, $6B), ($F1, $1F, $9D, $45), ($AB, $AC, $FA, $58), ($93, $4B, $E3, $03),
($55, $20, $30, $FA), ($F6, $AD, $76, $6D), ($91, $88, $CC, $76), ($25, $F5, $02, $4C),
($FC, $4F, $E5, $D7), ($D7, $C5, $2A, $CB), ($80, $26, $35, $44), ($8F, $B5, $62, $A3),
($49, $DE, $B1, $5A), ($67, $25, $BA, $1B), ($98, $45, $EA, $0E), ($E1, $5D, $FE, $C0),
($02, $C3, $2F, $75), ($12, $81, $4C, $F0), ($A3, $8D, $46, $97), ($C6, $6B, $D3, $F9),
($E7, $03, $8F, $5F), ($95, $15, $92, $9C), ($EB, $BF, $6D, $7A), ($DA, $95, $52, $59),
($2D, $D4, $BE, $83), ($D3, $58, $74, $21), ($29, $49, $E0, $69), ($44, $8E, $C9, $C8),
($6A, $75, $C2, $89), ($78, $F4, $8E, $79), ($6B, $99, $58, $3E), ($DD, $27, $B9, $71),
($B6, $BE, $E1, $4F), ($17, $F0, $88, $AD), ($66, $C9, $20, $AC), ($B4, $7D, $CE, $3A),
($18, $63, $DF, $4A), ($82, $E5, $1A, $31), ($60, $97, $51, $33), ($45, $62, $53, $7F),
($E0, $B1, $64, $77), ($84, $BB, $6B, $AE), ($1C, $FE, $81, $A0), ($94, $F9, $08, $2B),
($58, $70, $48, $68), ($19, $8F, $45, $FD), ($87, $94, $DE, $6C), ($B7, $52, $7B, $F8),
($23, $AB, $73, $D3), ($E2, $72, $4B, $02), ($57, $E3, $1F, $8F), ($2A, $66, $55, $AB),
($07, $B2, $EB, $28), ($03, $2F, $B5, $C2), ($9A, $86, $C5, $7B), ($A5, $D3, $37, $08),
($F2, $30, $28, $87), ($B2, $23, $BF, $A5), ($BA, $02, $03, $6A), ($5C, $ED, $16, $82),
($2B, $8A, $CF, $1C), ($92, $A7, $79, $B4), ($F0, $F3, $07, $F2), ($A1, $4E, $69, $E2),
($CD, $65, $DA, $F4), ($D5, $06, $05, $BE), ($1F, $D1, $34, $62), ($8A, $C4, $A6, $FE),
($9D, $34, $2E, $53), ($A0, $A2, $F3, $55), ($32, $05, $8A, $E1), ($75, $A4, $F6, $EB),
($39, $0B, $83, $EC), ($AA, $40, $60, $EF), ($06, $5E, $71, $9F), ($51, $BD, $6E, $10),
($F9, $3E, $21, $8A), ($3D, $96, $DD, $06), ($AE, $DD, $3E, $05), ($46, $4D, $E6, $BD),
($B5, $91, $54, $8D), ($05, $71, $C4, $5D), ($6F, $04, $06, $D4), ($FF, $60, $50, $15),
($24, $19, $98, $FB), ($97, $D6, $BD, $E9), ($CC, $89, $40, $43), ($77, $67, $D9, $9E),
($BD, $B0, $E8, $42), ($88, $07, $89, $8B), ($38, $E7, $19, $5B), ($DB, $79, $C8, $EE),
($47, $A1, $7C, $0A), ($E9, $7C, $42, $0F), ($C9, $F8, $84, $1E), ($00, $00, $00, $00),
($83, $09, $80, $86), ($48, $32, $2B, $ED), ($AC, $1E, $11, $70), ($4E, $6C, $5A, $72),
($FB, $FD, $0E, $FF), ($56, $0F, $85, $38), ($1E, $3D, $AE, $D5), ($27, $36, $2D, $39),
($64, $0A, $0F, $D9), ($21, $68, $5C, $A6), ($D1, $9B, $5B, $54), ($3A, $24, $36, $2E),
($B1, $0C, $0A, $67), ($0F, $93, $57, $E7), ($D2, $B4, $EE, $96), ($9E, $1B, $9B, $91),
($4F, $80, $C0, $C5), ($A2, $61, $DC, $20), ($69, $5A, $77, $4B), ($16, $1C, $12, $1A),
($0A, $E2, $93, $BA), ($E5, $C0, $A0, $2A), ($43, $3C, $22, $E0), ($1D, $12, $1B, $17),
($0B, $0E, $09, $0D), ($AD, $F2, $8B, $C7), ($B9, $2D, $B6, $A8), ($C8, $14, $1E, $A9),
($85, $57, $F1, $19), ($4C, $AF, $75, $07), ($BB, $EE, $99, $DD), ($FD, $A3, $7F, $60),
($9F, $F7, $01, $26), ($BC, $5C, $72, $F5), ($C5, $44, $66, $3B), ($34, $5B, $FB, $7E),
($76, $8B, $43, $29), ($DC, $CB, $23, $C6), ($68, $B6, $ED, $FC), ($63, $B8, $E4, $F1),
($CA, $D7, $31, $DC), ($10, $42, $63, $85), ($40, $13, $97, $22), ($20, $84, $C6, $11),
($7D, $85, $4A, $24), ($F8, $D2, $BB, $3D), ($11, $AE, $F9, $32), ($6D, $C7, $29, $A1),
($4B, $1D, $9E, $2F), ($F3, $DC, $B2, $30), ($EC, $0D, $86, $52), ($D0, $77, $C1, $E3),
($6C, $2B, $B3, $16), ($99, $A9, $70, $B9), ($FA, $11, $94, $48), ($22, $47, $E9, $64),
($C4, $A8, $FC, $8C), ($1A, $A0, $F0, $3F), ($D8, $56, $7D, $2C), ($EF, $22, $33, $90),
($C7, $87, $49, $4E), ($C1, $D9, $38, $D1), ($FE, $8C, $CA, $A2), ($36, $98, $D4, $0B),
($CF, $A6, $F5, $81), ($28, $A5, $7A, $DE), ($26, $DA, $B7, $8E), ($A4, $3F, $AD, $BF),
($E4, $2C, $3A, $9D), ($0D, $50, $78, $92), ($9B, $6A, $5F, $CC), ($62, $54, $7E, $46),
($C2, $F6, $8D, $13), ($E8, $90, $D8, $B8), ($5E, $2E, $39, $F7), ($F5, $82, $C3, $AF),
($BE, $9F, $5D, $80), ($7C, $69, $D0, $93), ($A9, $6F, $D5, $2D), ($B3, $CF, $25, $12),
($3B, $C8, $AC, $99), ($A7, $10, $18, $7D), ($6E, $E8, $9C, $63), ($7B, $DB, $3B, $BB),
($09, $CD, $26, $78), ($F4, $6E, $59, $18), ($01, $EC, $9A, $B7), ($A8, $83, $4F, $9A),
($65, $E6, $95, $6E), ($7E, $AA, $FF, $E6), ($08, $21, $BC, $CF), ($E6, $EF, $15, $E8),
($D9, $BA, $E7, $9B), ($CE, $4A, $6F, $36), ($D4, $EA, $9F, $09), ($D6, $29, $B0, $7C),
($AF, $31, $A4, $B2), ($31, $2A, $3F, $23), ($30, $C6, $A5, $94), ($C0, $35, $A2, $66),
($37, $74, $4E, $BC), ($A6, $FC, $82, $CA), ($B0, $E0, $90, $D0), ($15, $33, $A7, $D8),
($4A, $F1, $04, $98), ($F7, $41, $EC, $DA), ($0E, $7F, $CD, $50), ($2F, $17, $91, $F6),
($8D, $76, $4D, $D6), ($4D, $43, $EF, $B0), ($54, $CC, $AA, $4D), ($DF, $E4, $96, $04),
($E3, $9E, $D1, $B5), ($1B, $4C, $6A, $88), ($B8, $C1, $2C, $1F), ($7F, $46, $65, $51),
($04, $9D, $5E, $EA), ($5D, $01, $8C, $35), ($73, $FA, $87, $74), ($2E, $FB, $0B, $41),
($5A, $B3, $67, $1D), ($52, $92, $DB, $D2), ($33, $E9, $10, $56), ($13, $6D, $D6, $47),
($8C, $9A, $D7, $61), ($7A, $37, $A1, $0C), ($8E, $59, $F8, $14), ($89, $EB, $13, $3C),
($EE, $CE, $A9, $27), ($35, $B7, $61, $C9), ($ED, $E1, $1C, $E5), ($3C, $7A, $47, $B1),
($59, $9C, $D2, $DF), ($3F, $55, $F2, $73), ($79, $18, $14, $CE), ($BF, $73, $C7, $37),
($EA, $53, $F7, $CD), ($5B, $5F, $FD, $AA), ($14, $DF, $3D, $6F), ($86, $78, $44, $DB),
($81, $CA, $AF, $F3), ($3E, $B9, $68, $C4), ($2C, $38, $24, $34), ($5F, $C2, $A3, $40),
($72, $16, $1D, $C3), ($0C, $BC, $E2, $25), ($8B, $28, $3C, $49), ($41, $FF, $0D, $95),
($71, $39, $A8, $01), ($DE, $08, $0C, $B3), ($9C, $D8, $B4, $E4), ($90, $64, $56, $C1),
($61, $7B, $CB, $84), ($70, $D5, $32, $B6), ($74, $48, $6C, $5C), ($42, $D0, $B8, $57));
T7: array[0..255, 0..3] of byte = (
($A7, $50, $51, $F4), ($65, $53, $7E, $41), ($A4, $C3, $1A, $17), ($5E, $96, $3A, $27),
($6B, $CB, $3B, $AB), ($45, $F1, $1F, $9D), ($58, $AB, $AC, $FA), ($03, $93, $4B, $E3),
($FA, $55, $20, $30), ($6D, $F6, $AD, $76), ($76, $91, $88, $CC), ($4C, $25, $F5, $02),
($D7, $FC, $4F, $E5), ($CB, $D7, $C5, $2A), ($44, $80, $26, $35), ($A3, $8F, $B5, $62),
($5A, $49, $DE, $B1), ($1B, $67, $25, $BA), ($0E, $98, $45, $EA), ($C0, $E1, $5D, $FE),
($75, $02, $C3, $2F), ($F0, $12, $81, $4C), ($97, $A3, $8D, $46), ($F9, $C6, $6B, $D3),
($5F, $E7, $03, $8F), ($9C, $95, $15, $92), ($7A, $EB, $BF, $6D), ($59, $DA, $95, $52),
($83, $2D, $D4, $BE), ($21, $D3, $58, $74), ($69, $29, $49, $E0), ($C8, $44, $8E, $C9),
($89, $6A, $75, $C2), ($79, $78, $F4, $8E), ($3E, $6B, $99, $58), ($71, $DD, $27, $B9),
($4F, $B6, $BE, $E1), ($AD, $17, $F0, $88), ($AC, $66, $C9, $20), ($3A, $B4, $7D, $CE),
($4A, $18, $63, $DF), ($31, $82, $E5, $1A), ($33, $60, $97, $51), ($7F, $45, $62, $53),
($77, $E0, $B1, $64), ($AE, $84, $BB, $6B), ($A0, $1C, $FE, $81), ($2B, $94, $F9, $08),
($68, $58, $70, $48), ($FD, $19, $8F, $45), ($6C, $87, $94, $DE), ($F8, $B7, $52, $7B),
($D3, $23, $AB, $73), ($02, $E2, $72, $4B), ($8F, $57, $E3, $1F), ($AB, $2A, $66, $55),
($28, $07, $B2, $EB), ($C2, $03, $2F, $B5), ($7B, $9A, $86, $C5), ($08, $A5, $D3, $37),
($87, $F2, $30, $28), ($A5, $B2, $23, $BF), ($6A, $BA, $02, $03), ($82, $5C, $ED, $16),
($1C, $2B, $8A, $CF), ($B4, $92, $A7, $79), ($F2, $F0, $F3, $07), ($E2, $A1, $4E, $69),
($F4, $CD, $65, $DA), ($BE, $D5, $06, $05), ($62, $1F, $D1, $34), ($FE, $8A, $C4, $A6),
($53, $9D, $34, $2E), ($55, $A0, $A2, $F3), ($E1, $32, $05, $8A), ($EB, $75, $A4, $F6),
($EC, $39, $0B, $83), ($EF, $AA, $40, $60), ($9F, $06, $5E, $71), ($10, $51, $BD, $6E),
($8A, $F9, $3E, $21), ($06, $3D, $96, $DD), ($05, $AE, $DD, $3E), ($BD, $46, $4D, $E6),
($8D, $B5, $91, $54), ($5D, $05, $71, $C4), ($D4, $6F, $04, $06), ($15, $FF, $60, $50),
($FB, $24, $19, $98), ($E9, $97, $D6, $BD), ($43, $CC, $89, $40), ($9E, $77, $67, $D9),
($42, $BD, $B0, $E8), ($8B, $88, $07, $89), ($5B, $38, $E7, $19), ($EE, $DB, $79, $C8),
($0A, $47, $A1, $7C), ($0F, $E9, $7C, $42), ($1E, $C9, $F8, $84), ($00, $00, $00, $00),
($86, $83, $09, $80), ($ED, $48, $32, $2B), ($70, $AC, $1E, $11), ($72, $4E, $6C, $5A),
($FF, $FB, $FD, $0E), ($38, $56, $0F, $85), ($D5, $1E, $3D, $AE), ($39, $27, $36, $2D),
($D9, $64, $0A, $0F), ($A6, $21, $68, $5C), ($54, $D1, $9B, $5B), ($2E, $3A, $24, $36),
($67, $B1, $0C, $0A), ($E7, $0F, $93, $57), ($96, $D2, $B4, $EE), ($91, $9E, $1B, $9B),
($C5, $4F, $80, $C0), ($20, $A2, $61, $DC), ($4B, $69, $5A, $77), ($1A, $16, $1C, $12),
($BA, $0A, $E2, $93), ($2A, $E5, $C0, $A0), ($E0, $43, $3C, $22), ($17, $1D, $12, $1B),
($0D, $0B, $0E, $09), ($C7, $AD, $F2, $8B), ($A8, $B9, $2D, $B6), ($A9, $C8, $14, $1E),
($19, $85, $57, $F1), ($07, $4C, $AF, $75), ($DD, $BB, $EE, $99), ($60, $FD, $A3, $7F),
($26, $9F, $F7, $01), ($F5, $BC, $5C, $72), ($3B, $C5, $44, $66), ($7E, $34, $5B, $FB),
($29, $76, $8B, $43), ($C6, $DC, $CB, $23), ($FC, $68, $B6, $ED), ($F1, $63, $B8, $E4),
($DC, $CA, $D7, $31), ($85, $10, $42, $63), ($22, $40, $13, $97), ($11, $20, $84, $C6),
($24, $7D, $85, $4A), ($3D, $F8, $D2, $BB), ($32, $11, $AE, $F9), ($A1, $6D, $C7, $29),
($2F, $4B, $1D, $9E), ($30, $F3, $DC, $B2), ($52, $EC, $0D, $86), ($E3, $D0, $77, $C1),
($16, $6C, $2B, $B3), ($B9, $99, $A9, $70), ($48, $FA, $11, $94), ($64, $22, $47, $E9),
($8C, $C4, $A8, $FC), ($3F, $1A, $A0, $F0), ($2C, $D8, $56, $7D), ($90, $EF, $22, $33),
($4E, $C7, $87, $49), ($D1, $C1, $D9, $38), ($A2, $FE, $8C, $CA), ($0B, $36, $98, $D4),
($81, $CF, $A6, $F5), ($DE, $28, $A5, $7A), ($8E, $26, $DA, $B7), ($BF, $A4, $3F, $AD),
($9D, $E4, $2C, $3A), ($92, $0D, $50, $78), ($CC, $9B, $6A, $5F), ($46, $62, $54, $7E),
($13, $C2, $F6, $8D), ($B8, $E8, $90, $D8), ($F7, $5E, $2E, $39), ($AF, $F5, $82, $C3),
($80, $BE, $9F, $5D), ($93, $7C, $69, $D0), ($2D, $A9, $6F, $D5), ($12, $B3, $CF, $25),
($99, $3B, $C8, $AC), ($7D, $A7, $10, $18), ($63, $6E, $E8, $9C), ($BB, $7B, $DB, $3B),
($78, $09, $CD, $26), ($18, $F4, $6E, $59), ($B7, $01, $EC, $9A), ($9A, $A8, $83, $4F),
($6E, $65, $E6, $95), ($E6, $7E, $AA, $FF), ($CF, $08, $21, $BC), ($E8, $E6, $EF, $15),
($9B, $D9, $BA, $E7), ($36, $CE, $4A, $6F), ($09, $D4, $EA, $9F), ($7C, $D6, $29, $B0),
($B2, $AF, $31, $A4), ($23, $31, $2A, $3F), ($94, $30, $C6, $A5), ($66, $C0, $35, $A2),
($BC, $37, $74, $4E), ($CA, $A6, $FC, $82), ($D0, $B0, $E0, $90), ($D8, $15, $33, $A7),
($98, $4A, $F1, $04), ($DA, $F7, $41, $EC), ($50, $0E, $7F, $CD), ($F6, $2F, $17, $91),
($D6, $8D, $76, $4D), ($B0, $4D, $43, $EF), ($4D, $54, $CC, $AA), ($04, $DF, $E4, $96),
($B5, $E3, $9E, $D1), ($88, $1B, $4C, $6A), ($1F, $B8, $C1, $2C), ($51, $7F, $46, $65),
($EA, $04, $9D, $5E), ($35, $5D, $01, $8C), ($74, $73, $FA, $87), ($41, $2E, $FB, $0B),
($1D, $5A, $B3, $67), ($D2, $52, $92, $DB), ($56, $33, $E9, $10), ($47, $13, $6D, $D6),
($61, $8C, $9A, $D7), ($0C, $7A, $37, $A1), ($14, $8E, $59, $F8), ($3C, $89, $EB, $13),
($27, $EE, $CE, $A9), ($C9, $35, $B7, $61), ($E5, $ED, $E1, $1C), ($B1, $3C, $7A, $47),
($DF, $59, $9C, $D2), ($73, $3F, $55, $F2), ($CE, $79, $18, $14), ($37, $BF, $73, $C7),
($CD, $EA, $53, $F7), ($AA, $5B, $5F, $FD), ($6F, $14, $DF, $3D), ($DB, $86, $78, $44),
($F3, $81, $CA, $AF), ($C4, $3E, $B9, $68), ($34, $2C, $38, $24), ($40, $5F, $C2, $A3),
($C3, $72, $16, $1D), ($25, $0C, $BC, $E2), ($49, $8B, $28, $3C), ($95, $41, $FF, $0D),
($01, $71, $39, $A8), ($B3, $DE, $08, $0C), ($E4, $9C, $D8, $B4), ($C1, $90, $64, $56),
($84, $61, $7B, $CB), ($B6, $70, $D5, $32), ($5C, $74, $48, $6C), ($57, $42, $D0, $B8));
T8: array[0..255, 0..3] of byte = (
($F4, $A7, $50, $51), ($41, $65, $53, $7E), ($17, $A4, $C3, $1A), ($27, $5E, $96, $3A),
($AB, $6B, $CB, $3B), ($9D, $45, $F1, $1F), ($FA, $58, $AB, $AC), ($E3, $03, $93, $4B),
($30, $FA, $55, $20), ($76, $6D, $F6, $AD), ($CC, $76, $91, $88), ($02, $4C, $25, $F5),
($E5, $D7, $FC, $4F), ($2A, $CB, $D7, $C5), ($35, $44, $80, $26), ($62, $A3, $8F, $B5),
($B1, $5A, $49, $DE), ($BA, $1B, $67, $25), ($EA, $0E, $98, $45), ($FE, $C0, $E1, $5D),
($2F, $75, $02, $C3), ($4C, $F0, $12, $81), ($46, $97, $A3, $8D), ($D3, $F9, $C6, $6B),
($8F, $5F, $E7, $03), ($92, $9C, $95, $15), ($6D, $7A, $EB, $BF), ($52, $59, $DA, $95),
($BE, $83, $2D, $D4), ($74, $21, $D3, $58), ($E0, $69, $29, $49), ($C9, $C8, $44, $8E),
($C2, $89, $6A, $75), ($8E, $79, $78, $F4), ($58, $3E, $6B, $99), ($B9, $71, $DD, $27),
($E1, $4F, $B6, $BE), ($88, $AD, $17, $F0), ($20, $AC, $66, $C9), ($CE, $3A, $B4, $7D),
($DF, $4A, $18, $63), ($1A, $31, $82, $E5), ($51, $33, $60, $97), ($53, $7F, $45, $62),
($64, $77, $E0, $B1), ($6B, $AE, $84, $BB), ($81, $A0, $1C, $FE), ($08, $2B, $94, $F9),
($48, $68, $58, $70), ($45, $FD, $19, $8F), ($DE, $6C, $87, $94), ($7B, $F8, $B7, $52),
($73, $D3, $23, $AB), ($4B, $02, $E2, $72), ($1F, $8F, $57, $E3), ($55, $AB, $2A, $66),
($EB, $28, $07, $B2), ($B5, $C2, $03, $2F), ($C5, $7B, $9A, $86), ($37, $08, $A5, $D3),
($28, $87, $F2, $30), ($BF, $A5, $B2, $23), ($03, $6A, $BA, $02), ($16, $82, $5C, $ED),
($CF, $1C, $2B, $8A), ($79, $B4, $92, $A7), ($07, $F2, $F0, $F3), ($69, $E2, $A1, $4E),
($DA, $F4, $CD, $65), ($05, $BE, $D5, $06), ($34, $62, $1F, $D1), ($A6, $FE, $8A, $C4),
($2E, $53, $9D, $34), ($F3, $55, $A0, $A2), ($8A, $E1, $32, $05), ($F6, $EB, $75, $A4),
($83, $EC, $39, $0B), ($60, $EF, $AA, $40), ($71, $9F, $06, $5E), ($6E, $10, $51, $BD),
($21, $8A, $F9, $3E), ($DD, $06, $3D, $96), ($3E, $05, $AE, $DD), ($E6, $BD, $46, $4D),
($54, $8D, $B5, $91), ($C4, $5D, $05, $71), ($06, $D4, $6F, $04), ($50, $15, $FF, $60),
($98, $FB, $24, $19), ($BD, $E9, $97, $D6), ($40, $43, $CC, $89), ($D9, $9E, $77, $67),
($E8, $42, $BD, $B0), ($89, $8B, $88, $07), ($19, $5B, $38, $E7), ($C8, $EE, $DB, $79),
($7C, $0A, $47, $A1), ($42, $0F, $E9, $7C), ($84, $1E, $C9, $F8), ($00, $00, $00, $00),
($80, $86, $83, $09), ($2B, $ED, $48, $32), ($11, $70, $AC, $1E), ($5A, $72, $4E, $6C),
($0E, $FF, $FB, $FD), ($85, $38, $56, $0F), ($AE, $D5, $1E, $3D), ($2D, $39, $27, $36),
($0F, $D9, $64, $0A), ($5C, $A6, $21, $68), ($5B, $54, $D1, $9B), ($36, $2E, $3A, $24),
($0A, $67, $B1, $0C), ($57, $E7, $0F, $93), ($EE, $96, $D2, $B4), ($9B, $91, $9E, $1B),
($C0, $C5, $4F, $80), ($DC, $20, $A2, $61), ($77, $4B, $69, $5A), ($12, $1A, $16, $1C),
($93, $BA, $0A, $E2), ($A0, $2A, $E5, $C0), ($22, $E0, $43, $3C), ($1B, $17, $1D, $12),
($09, $0D, $0B, $0E), ($8B, $C7, $AD, $F2), ($B6, $A8, $B9, $2D), ($1E, $A9, $C8, $14),
($F1, $19, $85, $57), ($75, $07, $4C, $AF), ($99, $DD, $BB, $EE), ($7F, $60, $FD, $A3),
($01, $26, $9F, $F7), ($72, $F5, $BC, $5C), ($66, $3B, $C5, $44), ($FB, $7E, $34, $5B),
($43, $29, $76, $8B), ($23, $C6, $DC, $CB), ($ED, $FC, $68, $B6), ($E4, $F1, $63, $B8),
($31, $DC, $CA, $D7), ($63, $85, $10, $42), ($97, $22, $40, $13), ($C6, $11, $20, $84),
($4A, $24, $7D, $85), ($BB, $3D, $F8, $D2), ($F9, $32, $11, $AE), ($29, $A1, $6D, $C7),
($9E, $2F, $4B, $1D), ($B2, $30, $F3, $DC), ($86, $52, $EC, $0D), ($C1, $E3, $D0, $77),
($B3, $16, $6C, $2B), ($70, $B9, $99, $A9), ($94, $48, $FA, $11), ($E9, $64, $22, $47),
($FC, $8C, $C4, $A8), ($F0, $3F, $1A, $A0), ($7D, $2C, $D8, $56), ($33, $90, $EF, $22),
($49, $4E, $C7, $87), ($38, $D1, $C1, $D9), ($CA, $A2, $FE, $8C), ($D4, $0B, $36, $98),
($F5, $81, $CF, $A6), ($7A, $DE, $28, $A5), ($B7, $8E, $26, $DA), ($AD, $BF, $A4, $3F),
($3A, $9D, $E4, $2C), ($78, $92, $0D, $50), ($5F, $CC, $9B, $6A), ($7E, $46, $62, $54),
($8D, $13, $C2, $F6), ($D8, $B8, $E8, $90), ($39, $F7, $5E, $2E), ($C3, $AF, $F5, $82),
($5D, $80, $BE, $9F), ($D0, $93, $7C, $69), ($D5, $2D, $A9, $6F), ($25, $12, $B3, $CF),
($AC, $99, $3B, $C8), ($18, $7D, $A7, $10), ($9C, $63, $6E, $E8), ($3B, $BB, $7B, $DB),
($26, $78, $09, $CD), ($59, $18, $F4, $6E), ($9A, $B7, $01, $EC), ($4F, $9A, $A8, $83),
($95, $6E, $65, $E6), ($FF, $E6, $7E, $AA), ($BC, $CF, $08, $21), ($15, $E8, $E6, $EF),
($E7, $9B, $D9, $BA), ($6F, $36, $CE, $4A), ($9F, $09, $D4, $EA), ($B0, $7C, $D6, $29),
($A4, $B2, $AF, $31), ($3F, $23, $31, $2A), ($A5, $94, $30, $C6), ($A2, $66, $C0, $35),
($4E, $BC, $37, $74), ($82, $CA, $A6, $FC), ($90, $D0, $B0, $E0), ($A7, $D8, $15, $33),
($04, $98, $4A, $F1), ($EC, $DA, $F7, $41), ($CD, $50, $0E, $7F), ($91, $F6, $2F, $17),
($4D, $D6, $8D, $76), ($EF, $B0, $4D, $43), ($AA, $4D, $54, $CC), ($96, $04, $DF, $E4),
($D1, $B5, $E3, $9E), ($6A, $88, $1B, $4C), ($2C, $1F, $B8, $C1), ($65, $51, $7F, $46),
($5E, $EA, $04, $9D), ($8C, $35, $5D, $01), ($87, $74, $73, $FA), ($0B, $41, $2E, $FB),
($67, $1D, $5A, $B3), ($DB, $D2, $52, $92), ($10, $56, $33, $E9), ($D6, $47, $13, $6D),
($D7, $61, $8C, $9A), ($A1, $0C, $7A, $37), ($F8, $14, $8E, $59), ($13, $3C, $89, $EB),
($A9, $27, $EE, $CE), ($61, $C9, $35, $B7), ($1C, $E5, $ED, $E1), ($47, $B1, $3C, $7A),
($D2, $DF, $59, $9C), ($F2, $73, $3F, $55), ($14, $CE, $79, $18), ($C7, $37, $BF, $73),
($F7, $CD, $EA, $53), ($FD, $AA, $5B, $5F), ($3D, $6F, $14, $DF), ($44, $DB, $86, $78),
($AF, $F3, $81, $CA), ($68, $C4, $3E, $B9), ($24, $34, $2C, $38), ($A3, $40, $5F, $C2),
($1D, $C3, $72, $16), ($E2, $25, $0C, $BC), ($3C, $49, $8B, $28), ($0D, $95, $41, $FF),
($A8, $01, $71, $39), ($0C, $B3, $DE, $08), ($B4, $E4, $9C, $D8), ($56, $C1, $90, $64),
($CB, $84, $61, $7B), ($32, $B6, $70, $D5), ($6C, $5C, $74, $48), ($B8, $57, $42, $D0));
S5: array[0..255] of byte = (
$52, $09, $6A, $D5,
$30, $36, $A5, $38,
$BF, $40, $A3, $9E,
$81, $F3, $D7, $FB,
$7C, $E3, $39, $82,
$9B, $2F, $FF, $87,
$34, $8E, $43, $44,
$C4, $DE, $E9, $CB,
$54, $7B, $94, $32,
$A6, $C2, $23, $3D,
$EE, $4C, $95, $0B,
$42, $FA, $C3, $4E,
$08, $2E, $A1, $66,
$28, $D9, $24, $B2,
$76, $5B, $A2, $49,
$6D, $8B, $D1, $25,
$72, $F8, $F6, $64,
$86, $68, $98, $16,
$D4, $A4, $5C, $CC,
$5D, $65, $B6, $92,
$6C, $70, $48, $50,
$FD, $ED, $B9, $DA,
$5E, $15, $46, $57,
$A7, $8D, $9D, $84,
$90, $D8, $AB, $00,
$8C, $BC, $D3, $0A,
$F7, $E4, $58, $05,
$B8, $B3, $45, $06,
$D0, $2C, $1E, $8F,
$CA, $3F, $0F, $02,
$C1, $AF, $BD, $03,
$01, $13, $8A, $6B,
$3A, $91, $11, $41,
$4F, $67, $DC, $EA,
$97, $F2, $CF, $CE,
$F0, $B4, $E6, $73,
$96, $AC, $74, $22,
$E7, $AD, $35, $85,
$E2, $F9, $37, $E8,
$1C, $75, $DF, $6E,
$47, $F1, $1A, $71,
$1D, $29, $C5, $89,
$6F, $B7, $62, $0E,
$AA, $18, $BE, $1B,
$FC, $56, $3E, $4B,
$C6, $D2, $79, $20,
$9A, $DB, $C0, $FE,
$78, $CD, $5A, $F4,
$1F, $DD, $A8, $33,
$88, $07, $C7, $31,
$B1, $12, $10, $59,
$27, $80, $EC, $5F,
$60, $51, $7F, $A9,
$19, $B5, $4A, $0D,
$2D, $E5, $7A, $9F,
$93, $C9, $9C, $EF,
$A0, $E0, $3B, $4D,
$AE, $2A, $F5, $B0,
$C8, $EB, $BB, $3C,
$83, $53, $99, $61,
$17, $2B, $04, $7E,
$BA, $77, $D6, $26,
$E1, $69, $14, $63,
$55, $21, $0C, $7D);
U1: array[0..255, 0..3] of byte = (
($00, $00, $00, $00), ($0E, $09, $0D, $0B), ($1C, $12, $1A, $16), ($12, $1B, $17, $1D),
($38, $24, $34, $2C), ($36, $2D, $39, $27), ($24, $36, $2E, $3A), ($2A, $3F, $23, $31),
($70, $48, $68, $58), ($7E, $41, $65, $53), ($6C, $5A, $72, $4E), ($62, $53, $7F, $45),
($48, $6C, $5C, $74), ($46, $65, $51, $7F), ($54, $7E, $46, $62), ($5A, $77, $4B, $69),
($E0, $90, $D0, $B0), ($EE, $99, $DD, $BB), ($FC, $82, $CA, $A6), ($F2, $8B, $C7, $AD),
($D8, $B4, $E4, $9C), ($D6, $BD, $E9, $97), ($C4, $A6, $FE, $8A), ($CA, $AF, $F3, $81),
($90, $D8, $B8, $E8), ($9E, $D1, $B5, $E3), ($8C, $CA, $A2, $FE), ($82, $C3, $AF, $F5),
($A8, $FC, $8C, $C4), ($A6, $F5, $81, $CF), ($B4, $EE, $96, $D2), ($BA, $E7, $9B, $D9),
($DB, $3B, $BB, $7B), ($D5, $32, $B6, $70), ($C7, $29, $A1, $6D), ($C9, $20, $AC, $66),
($E3, $1F, $8F, $57), ($ED, $16, $82, $5C), ($FF, $0D, $95, $41), ($F1, $04, $98, $4A),
($AB, $73, $D3, $23), ($A5, $7A, $DE, $28), ($B7, $61, $C9, $35), ($B9, $68, $C4, $3E),
($93, $57, $E7, $0F), ($9D, $5E, $EA, $04), ($8F, $45, $FD, $19), ($81, $4C, $F0, $12),
($3B, $AB, $6B, $CB), ($35, $A2, $66, $C0), ($27, $B9, $71, $DD), ($29, $B0, $7C, $D6),
($03, $8F, $5F, $E7), ($0D, $86, $52, $EC), ($1F, $9D, $45, $F1), ($11, $94, $48, $FA),
($4B, $E3, $03, $93), ($45, $EA, $0E, $98), ($57, $F1, $19, $85), ($59, $F8, $14, $8E),
($73, $C7, $37, $BF), ($7D, $CE, $3A, $B4), ($6F, $D5, $2D, $A9), ($61, $DC, $20, $A2),
($AD, $76, $6D, $F6), ($A3, $7F, $60, $FD), ($B1, $64, $77, $E0), ($BF, $6D, $7A, $EB),
($95, $52, $59, $DA), ($9B, $5B, $54, $D1), ($89, $40, $43, $CC), ($87, $49, $4E, $C7),
($DD, $3E, $05, $AE), ($D3, $37, $08, $A5), ($C1, $2C, $1F, $B8), ($CF, $25, $12, $B3),
($E5, $1A, $31, $82), ($EB, $13, $3C, $89), ($F9, $08, $2B, $94), ($F7, $01, $26, $9F),
($4D, $E6, $BD, $46), ($43, $EF, $B0, $4D), ($51, $F4, $A7, $50), ($5F, $FD, $AA, $5B),
($75, $C2, $89, $6A), ($7B, $CB, $84, $61), ($69, $D0, $93, $7C), ($67, $D9, $9E, $77),
($3D, $AE, $D5, $1E), ($33, $A7, $D8, $15), ($21, $BC, $CF, $08), ($2F, $B5, $C2, $03),
($05, $8A, $E1, $32), ($0B, $83, $EC, $39), ($19, $98, $FB, $24), ($17, $91, $F6, $2F),
($76, $4D, $D6, $8D), ($78, $44, $DB, $86), ($6A, $5F, $CC, $9B), ($64, $56, $C1, $90),
($4E, $69, $E2, $A1), ($40, $60, $EF, $AA), ($52, $7B, $F8, $B7), ($5C, $72, $F5, $BC),
($06, $05, $BE, $D5), ($08, $0C, $B3, $DE), ($1A, $17, $A4, $C3), ($14, $1E, $A9, $C8),
($3E, $21, $8A, $F9), ($30, $28, $87, $F2), ($22, $33, $90, $EF), ($2C, $3A, $9D, $E4),
($96, $DD, $06, $3D), ($98, $D4, $0B, $36), ($8A, $CF, $1C, $2B), ($84, $C6, $11, $20),
($AE, $F9, $32, $11), ($A0, $F0, $3F, $1A), ($B2, $EB, $28, $07), ($BC, $E2, $25, $0C),
($E6, $95, $6E, $65), ($E8, $9C, $63, $6E), ($FA, $87, $74, $73), ($F4, $8E, $79, $78),
($DE, $B1, $5A, $49), ($D0, $B8, $57, $42), ($C2, $A3, $40, $5F), ($CC, $AA, $4D, $54),
($41, $EC, $DA, $F7), ($4F, $E5, $D7, $FC), ($5D, $FE, $C0, $E1), ($53, $F7, $CD, $EA),
($79, $C8, $EE, $DB), ($77, $C1, $E3, $D0), ($65, $DA, $F4, $CD), ($6B, $D3, $F9, $C6),
($31, $A4, $B2, $AF), ($3F, $AD, $BF, $A4), ($2D, $B6, $A8, $B9), ($23, $BF, $A5, $B2),
($09, $80, $86, $83), ($07, $89, $8B, $88), ($15, $92, $9C, $95), ($1B, $9B, $91, $9E),
($A1, $7C, $0A, $47), ($AF, $75, $07, $4C), ($BD, $6E, $10, $51), ($B3, $67, $1D, $5A),
($99, $58, $3E, $6B), ($97, $51, $33, $60), ($85, $4A, $24, $7D), ($8B, $43, $29, $76),
($D1, $34, $62, $1F), ($DF, $3D, $6F, $14), ($CD, $26, $78, $09), ($C3, $2F, $75, $02),
($E9, $10, $56, $33), ($E7, $19, $5B, $38), ($F5, $02, $4C, $25), ($FB, $0B, $41, $2E),
($9A, $D7, $61, $8C), ($94, $DE, $6C, $87), ($86, $C5, $7B, $9A), ($88, $CC, $76, $91),
($A2, $F3, $55, $A0), ($AC, $FA, $58, $AB), ($BE, $E1, $4F, $B6), ($B0, $E8, $42, $BD),
($EA, $9F, $09, $D4), ($E4, $96, $04, $DF), ($F6, $8D, $13, $C2), ($F8, $84, $1E, $C9),
($D2, $BB, $3D, $F8), ($DC, $B2, $30, $F3), ($CE, $A9, $27, $EE), ($C0, $A0, $2A, $E5),
($7A, $47, $B1, $3C), ($74, $4E, $BC, $37), ($66, $55, $AB, $2A), ($68, $5C, $A6, $21),
($42, $63, $85, $10), ($4C, $6A, $88, $1B), ($5E, $71, $9F, $06), ($50, $78, $92, $0D),
($0A, $0F, $D9, $64), ($04, $06, $D4, $6F), ($16, $1D, $C3, $72), ($18, $14, $CE, $79),
($32, $2B, $ED, $48), ($3C, $22, $E0, $43), ($2E, $39, $F7, $5E), ($20, $30, $FA, $55),
($EC, $9A, $B7, $01), ($E2, $93, $BA, $0A), ($F0, $88, $AD, $17), ($FE, $81, $A0, $1C),
($D4, $BE, $83, $2D), ($DA, $B7, $8E, $26), ($C8, $AC, $99, $3B), ($C6, $A5, $94, $30),
($9C, $D2, $DF, $59), ($92, $DB, $D2, $52), ($80, $C0, $C5, $4F), ($8E, $C9, $C8, $44),
($A4, $F6, $EB, $75), ($AA, $FF, $E6, $7E), ($B8, $E4, $F1, $63), ($B6, $ED, $FC, $68),
($0C, $0A, $67, $B1), ($02, $03, $6A, $BA), ($10, $18, $7D, $A7), ($1E, $11, $70, $AC),
($34, $2E, $53, $9D), ($3A, $27, $5E, $96), ($28, $3C, $49, $8B), ($26, $35, $44, $80),
($7C, $42, $0F, $E9), ($72, $4B, $02, $E2), ($60, $50, $15, $FF), ($6E, $59, $18, $F4),
($44, $66, $3B, $C5), ($4A, $6F, $36, $CE), ($58, $74, $21, $D3), ($56, $7D, $2C, $D8),
($37, $A1, $0C, $7A), ($39, $A8, $01, $71), ($2B, $B3, $16, $6C), ($25, $BA, $1B, $67),
($0F, $85, $38, $56), ($01, $8C, $35, $5D), ($13, $97, $22, $40), ($1D, $9E, $2F, $4B),
($47, $E9, $64, $22), ($49, $E0, $69, $29), ($5B, $FB, $7E, $34), ($55, $F2, $73, $3F),
($7F, $CD, $50, $0E), ($71, $C4, $5D, $05), ($63, $DF, $4A, $18), ($6D, $D6, $47, $13),
($D7, $31, $DC, $CA), ($D9, $38, $D1, $C1), ($CB, $23, $C6, $DC), ($C5, $2A, $CB, $D7),
($EF, $15, $E8, $E6), ($E1, $1C, $E5, $ED), ($F3, $07, $F2, $F0), ($FD, $0E, $FF, $FB),
($A7, $79, $B4, $92), ($A9, $70, $B9, $99), ($BB, $6B, $AE, $84), ($B5, $62, $A3, $8F),
($9F, $5D, $80, $BE), ($91, $54, $8D, $B5), ($83, $4F, $9A, $A8), ($8D, $46, $97, $A3));
U2: array[0..255, 0..3] of byte = (
($00, $00, $00, $00), ($0B, $0E, $09, $0D), ($16, $1C, $12, $1A), ($1D, $12, $1B, $17),
($2C, $38, $24, $34), ($27, $36, $2D, $39), ($3A, $24, $36, $2E), ($31, $2A, $3F, $23),
($58, $70, $48, $68), ($53, $7E, $41, $65), ($4E, $6C, $5A, $72), ($45, $62, $53, $7F),
($74, $48, $6C, $5C), ($7F, $46, $65, $51), ($62, $54, $7E, $46), ($69, $5A, $77, $4B),
($B0, $E0, $90, $D0), ($BB, $EE, $99, $DD), ($A6, $FC, $82, $CA), ($AD, $F2, $8B, $C7),
($9C, $D8, $B4, $E4), ($97, $D6, $BD, $E9), ($8A, $C4, $A6, $FE), ($81, $CA, $AF, $F3),
($E8, $90, $D8, $B8), ($E3, $9E, $D1, $B5), ($FE, $8C, $CA, $A2), ($F5, $82, $C3, $AF),
($C4, $A8, $FC, $8C), ($CF, $A6, $F5, $81), ($D2, $B4, $EE, $96), ($D9, $BA, $E7, $9B),
($7B, $DB, $3B, $BB), ($70, $D5, $32, $B6), ($6D, $C7, $29, $A1), ($66, $C9, $20, $AC),
($57, $E3, $1F, $8F), ($5C, $ED, $16, $82), ($41, $FF, $0D, $95), ($4A, $F1, $04, $98),
($23, $AB, $73, $D3), ($28, $A5, $7A, $DE), ($35, $B7, $61, $C9), ($3E, $B9, $68, $C4),
($0F, $93, $57, $E7), ($04, $9D, $5E, $EA), ($19, $8F, $45, $FD), ($12, $81, $4C, $F0),
($CB, $3B, $AB, $6B), ($C0, $35, $A2, $66), ($DD, $27, $B9, $71), ($D6, $29, $B0, $7C),
($E7, $03, $8F, $5F), ($EC, $0D, $86, $52), ($F1, $1F, $9D, $45), ($FA, $11, $94, $48),
($93, $4B, $E3, $03), ($98, $45, $EA, $0E), ($85, $57, $F1, $19), ($8E, $59, $F8, $14),
($BF, $73, $C7, $37), ($B4, $7D, $CE, $3A), ($A9, $6F, $D5, $2D), ($A2, $61, $DC, $20),
($F6, $AD, $76, $6D), ($FD, $A3, $7F, $60), ($E0, $B1, $64, $77), ($EB, $BF, $6D, $7A),
($DA, $95, $52, $59), ($D1, $9B, $5B, $54), ($CC, $89, $40, $43), ($C7, $87, $49, $4E),
($AE, $DD, $3E, $05), ($A5, $D3, $37, $08), ($B8, $C1, $2C, $1F), ($B3, $CF, $25, $12),
($82, $E5, $1A, $31), ($89, $EB, $13, $3C), ($94, $F9, $08, $2B), ($9F, $F7, $01, $26),
($46, $4D, $E6, $BD), ($4D, $43, $EF, $B0), ($50, $51, $F4, $A7), ($5B, $5F, $FD, $AA),
($6A, $75, $C2, $89), ($61, $7B, $CB, $84), ($7C, $69, $D0, $93), ($77, $67, $D9, $9E),
($1E, $3D, $AE, $D5), ($15, $33, $A7, $D8), ($08, $21, $BC, $CF), ($03, $2F, $B5, $C2),
($32, $05, $8A, $E1), ($39, $0B, $83, $EC), ($24, $19, $98, $FB), ($2F, $17, $91, $F6),
($8D, $76, $4D, $D6), ($86, $78, $44, $DB), ($9B, $6A, $5F, $CC), ($90, $64, $56, $C1),
($A1, $4E, $69, $E2), ($AA, $40, $60, $EF), ($B7, $52, $7B, $F8), ($BC, $5C, $72, $F5),
($D5, $06, $05, $BE), ($DE, $08, $0C, $B3), ($C3, $1A, $17, $A4), ($C8, $14, $1E, $A9),
($F9, $3E, $21, $8A), ($F2, $30, $28, $87), ($EF, $22, $33, $90), ($E4, $2C, $3A, $9D),
($3D, $96, $DD, $06), ($36, $98, $D4, $0B), ($2B, $8A, $CF, $1C), ($20, $84, $C6, $11),
($11, $AE, $F9, $32), ($1A, $A0, $F0, $3F), ($07, $B2, $EB, $28), ($0C, $BC, $E2, $25),
($65, $E6, $95, $6E), ($6E, $E8, $9C, $63), ($73, $FA, $87, $74), ($78, $F4, $8E, $79),
($49, $DE, $B1, $5A), ($42, $D0, $B8, $57), ($5F, $C2, $A3, $40), ($54, $CC, $AA, $4D),
($F7, $41, $EC, $DA), ($FC, $4F, $E5, $D7), ($E1, $5D, $FE, $C0), ($EA, $53, $F7, $CD),
($DB, $79, $C8, $EE), ($D0, $77, $C1, $E3), ($CD, $65, $DA, $F4), ($C6, $6B, $D3, $F9),
($AF, $31, $A4, $B2), ($A4, $3F, $AD, $BF), ($B9, $2D, $B6, $A8), ($B2, $23, $BF, $A5),
($83, $09, $80, $86), ($88, $07, $89, $8B), ($95, $15, $92, $9C), ($9E, $1B, $9B, $91),
($47, $A1, $7C, $0A), ($4C, $AF, $75, $07), ($51, $BD, $6E, $10), ($5A, $B3, $67, $1D),
($6B, $99, $58, $3E), ($60, $97, $51, $33), ($7D, $85, $4A, $24), ($76, $8B, $43, $29),
($1F, $D1, $34, $62), ($14, $DF, $3D, $6F), ($09, $CD, $26, $78), ($02, $C3, $2F, $75),
($33, $E9, $10, $56), ($38, $E7, $19, $5B), ($25, $F5, $02, $4C), ($2E, $FB, $0B, $41),
($8C, $9A, $D7, $61), ($87, $94, $DE, $6C), ($9A, $86, $C5, $7B), ($91, $88, $CC, $76),
($A0, $A2, $F3, $55), ($AB, $AC, $FA, $58), ($B6, $BE, $E1, $4F), ($BD, $B0, $E8, $42),
($D4, $EA, $9F, $09), ($DF, $E4, $96, $04), ($C2, $F6, $8D, $13), ($C9, $F8, $84, $1E),
($F8, $D2, $BB, $3D), ($F3, $DC, $B2, $30), ($EE, $CE, $A9, $27), ($E5, $C0, $A0, $2A),
($3C, $7A, $47, $B1), ($37, $74, $4E, $BC), ($2A, $66, $55, $AB), ($21, $68, $5C, $A6),
($10, $42, $63, $85), ($1B, $4C, $6A, $88), ($06, $5E, $71, $9F), ($0D, $50, $78, $92),
($64, $0A, $0F, $D9), ($6F, $04, $06, $D4), ($72, $16, $1D, $C3), ($79, $18, $14, $CE),
($48, $32, $2B, $ED), ($43, $3C, $22, $E0), ($5E, $2E, $39, $F7), ($55, $20, $30, $FA),
($01, $EC, $9A, $B7), ($0A, $E2, $93, $BA), ($17, $F0, $88, $AD), ($1C, $FE, $81, $A0),
($2D, $D4, $BE, $83), ($26, $DA, $B7, $8E), ($3B, $C8, $AC, $99), ($30, $C6, $A5, $94),
($59, $9C, $D2, $DF), ($52, $92, $DB, $D2), ($4F, $80, $C0, $C5), ($44, $8E, $C9, $C8),
($75, $A4, $F6, $EB), ($7E, $AA, $FF, $E6), ($63, $B8, $E4, $F1), ($68, $B6, $ED, $FC),
($B1, $0C, $0A, $67), ($BA, $02, $03, $6A), ($A7, $10, $18, $7D), ($AC, $1E, $11, $70),
($9D, $34, $2E, $53), ($96, $3A, $27, $5E), ($8B, $28, $3C, $49), ($80, $26, $35, $44),
($E9, $7C, $42, $0F), ($E2, $72, $4B, $02), ($FF, $60, $50, $15), ($F4, $6E, $59, $18),
($C5, $44, $66, $3B), ($CE, $4A, $6F, $36), ($D3, $58, $74, $21), ($D8, $56, $7D, $2C),
($7A, $37, $A1, $0C), ($71, $39, $A8, $01), ($6C, $2B, $B3, $16), ($67, $25, $BA, $1B),
($56, $0F, $85, $38), ($5D, $01, $8C, $35), ($40, $13, $97, $22), ($4B, $1D, $9E, $2F),
($22, $47, $E9, $64), ($29, $49, $E0, $69), ($34, $5B, $FB, $7E), ($3F, $55, $F2, $73),
($0E, $7F, $CD, $50), ($05, $71, $C4, $5D), ($18, $63, $DF, $4A), ($13, $6D, $D6, $47),
($CA, $D7, $31, $DC), ($C1, $D9, $38, $D1), ($DC, $CB, $23, $C6), ($D7, $C5, $2A, $CB),
($E6, $EF, $15, $E8), ($ED, $E1, $1C, $E5), ($F0, $F3, $07, $F2), ($FB, $FD, $0E, $FF),
($92, $A7, $79, $B4), ($99, $A9, $70, $B9), ($84, $BB, $6B, $AE), ($8F, $B5, $62, $A3),
($BE, $9F, $5D, $80), ($B5, $91, $54, $8D), ($A8, $83, $4F, $9A), ($A3, $8D, $46, $97));
U3: array[0..255, 0..3] of byte = (
($00, $00, $00, $00), ($0D, $0B, $0E, $09), ($1A, $16, $1C, $12), ($17, $1D, $12, $1B),
($34, $2C, $38, $24), ($39, $27, $36, $2D), ($2E, $3A, $24, $36), ($23, $31, $2A, $3F),
($68, $58, $70, $48), ($65, $53, $7E, $41), ($72, $4E, $6C, $5A), ($7F, $45, $62, $53),
($5C, $74, $48, $6C), ($51, $7F, $46, $65), ($46, $62, $54, $7E), ($4B, $69, $5A, $77),
($D0, $B0, $E0, $90), ($DD, $BB, $EE, $99), ($CA, $A6, $FC, $82), ($C7, $AD, $F2, $8B),
($E4, $9C, $D8, $B4), ($E9, $97, $D6, $BD), ($FE, $8A, $C4, $A6), ($F3, $81, $CA, $AF),
($B8, $E8, $90, $D8), ($B5, $E3, $9E, $D1), ($A2, $FE, $8C, $CA), ($AF, $F5, $82, $C3),
($8C, $C4, $A8, $FC), ($81, $CF, $A6, $F5), ($96, $D2, $B4, $EE), ($9B, $D9, $BA, $E7),
($BB, $7B, $DB, $3B), ($B6, $70, $D5, $32), ($A1, $6D, $C7, $29), ($AC, $66, $C9, $20),
($8F, $57, $E3, $1F), ($82, $5C, $ED, $16), ($95, $41, $FF, $0D), ($98, $4A, $F1, $04),
($D3, $23, $AB, $73), ($DE, $28, $A5, $7A), ($C9, $35, $B7, $61), ($C4, $3E, $B9, $68),
($E7, $0F, $93, $57), ($EA, $04, $9D, $5E), ($FD, $19, $8F, $45), ($F0, $12, $81, $4C),
($6B, $CB, $3B, $AB), ($66, $C0, $35, $A2), ($71, $DD, $27, $B9), ($7C, $D6, $29, $B0),
($5F, $E7, $03, $8F), ($52, $EC, $0D, $86), ($45, $F1, $1F, $9D), ($48, $FA, $11, $94),
($03, $93, $4B, $E3), ($0E, $98, $45, $EA), ($19, $85, $57, $F1), ($14, $8E, $59, $F8),
($37, $BF, $73, $C7), ($3A, $B4, $7D, $CE), ($2D, $A9, $6F, $D5), ($20, $A2, $61, $DC),
($6D, $F6, $AD, $76), ($60, $FD, $A3, $7F), ($77, $E0, $B1, $64), ($7A, $EB, $BF, $6D),
($59, $DA, $95, $52), ($54, $D1, $9B, $5B), ($43, $CC, $89, $40), ($4E, $C7, $87, $49),
($05, $AE, $DD, $3E), ($08, $A5, $D3, $37), ($1F, $B8, $C1, $2C), ($12, $B3, $CF, $25),
($31, $82, $E5, $1A), ($3C, $89, $EB, $13), ($2B, $94, $F9, $08), ($26, $9F, $F7, $01),
($BD, $46, $4D, $E6), ($B0, $4D, $43, $EF), ($A7, $50, $51, $F4), ($AA, $5B, $5F, $FD),
($89, $6A, $75, $C2), ($84, $61, $7B, $CB), ($93, $7C, $69, $D0), ($9E, $77, $67, $D9),
($D5, $1E, $3D, $AE), ($D8, $15, $33, $A7), ($CF, $08, $21, $BC), ($C2, $03, $2F, $B5),
($E1, $32, $05, $8A), ($EC, $39, $0B, $83), ($FB, $24, $19, $98), ($F6, $2F, $17, $91),
($D6, $8D, $76, $4D), ($DB, $86, $78, $44), ($CC, $9B, $6A, $5F), ($C1, $90, $64, $56),
($E2, $A1, $4E, $69), ($EF, $AA, $40, $60), ($F8, $B7, $52, $7B), ($F5, $BC, $5C, $72),
($BE, $D5, $06, $05), ($B3, $DE, $08, $0C), ($A4, $C3, $1A, $17), ($A9, $C8, $14, $1E),
($8A, $F9, $3E, $21), ($87, $F2, $30, $28), ($90, $EF, $22, $33), ($9D, $E4, $2C, $3A),
($06, $3D, $96, $DD), ($0B, $36, $98, $D4), ($1C, $2B, $8A, $CF), ($11, $20, $84, $C6),
($32, $11, $AE, $F9), ($3F, $1A, $A0, $F0), ($28, $07, $B2, $EB), ($25, $0C, $BC, $E2),
($6E, $65, $E6, $95), ($63, $6E, $E8, $9C), ($74, $73, $FA, $87), ($79, $78, $F4, $8E),
($5A, $49, $DE, $B1), ($57, $42, $D0, $B8), ($40, $5F, $C2, $A3), ($4D, $54, $CC, $AA),
($DA, $F7, $41, $EC), ($D7, $FC, $4F, $E5), ($C0, $E1, $5D, $FE), ($CD, $EA, $53, $F7),
($EE, $DB, $79, $C8), ($E3, $D0, $77, $C1), ($F4, $CD, $65, $DA), ($F9, $C6, $6B, $D3),
($B2, $AF, $31, $A4), ($BF, $A4, $3F, $AD), ($A8, $B9, $2D, $B6), ($A5, $B2, $23, $BF),
($86, $83, $09, $80), ($8B, $88, $07, $89), ($9C, $95, $15, $92), ($91, $9E, $1B, $9B),
($0A, $47, $A1, $7C), ($07, $4C, $AF, $75), ($10, $51, $BD, $6E), ($1D, $5A, $B3, $67),
($3E, $6B, $99, $58), ($33, $60, $97, $51), ($24, $7D, $85, $4A), ($29, $76, $8B, $43),
($62, $1F, $D1, $34), ($6F, $14, $DF, $3D), ($78, $09, $CD, $26), ($75, $02, $C3, $2F),
($56, $33, $E9, $10), ($5B, $38, $E7, $19), ($4C, $25, $F5, $02), ($41, $2E, $FB, $0B),
($61, $8C, $9A, $D7), ($6C, $87, $94, $DE), ($7B, $9A, $86, $C5), ($76, $91, $88, $CC),
($55, $A0, $A2, $F3), ($58, $AB, $AC, $FA), ($4F, $B6, $BE, $E1), ($42, $BD, $B0, $E8),
($09, $D4, $EA, $9F), ($04, $DF, $E4, $96), ($13, $C2, $F6, $8D), ($1E, $C9, $F8, $84),
($3D, $F8, $D2, $BB), ($30, $F3, $DC, $B2), ($27, $EE, $CE, $A9), ($2A, $E5, $C0, $A0),
($B1, $3C, $7A, $47), ($BC, $37, $74, $4E), ($AB, $2A, $66, $55), ($A6, $21, $68, $5C),
($85, $10, $42, $63), ($88, $1B, $4C, $6A), ($9F, $06, $5E, $71), ($92, $0D, $50, $78),
($D9, $64, $0A, $0F), ($D4, $6F, $04, $06), ($C3, $72, $16, $1D), ($CE, $79, $18, $14),
($ED, $48, $32, $2B), ($E0, $43, $3C, $22), ($F7, $5E, $2E, $39), ($FA, $55, $20, $30),
($B7, $01, $EC, $9A), ($BA, $0A, $E2, $93), ($AD, $17, $F0, $88), ($A0, $1C, $FE, $81),
($83, $2D, $D4, $BE), ($8E, $26, $DA, $B7), ($99, $3B, $C8, $AC), ($94, $30, $C6, $A5),
($DF, $59, $9C, $D2), ($D2, $52, $92, $DB), ($C5, $4F, $80, $C0), ($C8, $44, $8E, $C9),
($EB, $75, $A4, $F6), ($E6, $7E, $AA, $FF), ($F1, $63, $B8, $E4), ($FC, $68, $B6, $ED),
($67, $B1, $0C, $0A), ($6A, $BA, $02, $03), ($7D, $A7, $10, $18), ($70, $AC, $1E, $11),
($53, $9D, $34, $2E), ($5E, $96, $3A, $27), ($49, $8B, $28, $3C), ($44, $80, $26, $35),
($0F, $E9, $7C, $42), ($02, $E2, $72, $4B), ($15, $FF, $60, $50), ($18, $F4, $6E, $59),
($3B, $C5, $44, $66), ($36, $CE, $4A, $6F), ($21, $D3, $58, $74), ($2C, $D8, $56, $7D),
($0C, $7A, $37, $A1), ($01, $71, $39, $A8), ($16, $6C, $2B, $B3), ($1B, $67, $25, $BA),
($38, $56, $0F, $85), ($35, $5D, $01, $8C), ($22, $40, $13, $97), ($2F, $4B, $1D, $9E),
($64, $22, $47, $E9), ($69, $29, $49, $E0), ($7E, $34, $5B, $FB), ($73, $3F, $55, $F2),
($50, $0E, $7F, $CD), ($5D, $05, $71, $C4), ($4A, $18, $63, $DF), ($47, $13, $6D, $D6),
($DC, $CA, $D7, $31), ($D1, $C1, $D9, $38), ($C6, $DC, $CB, $23), ($CB, $D7, $C5, $2A),
($E8, $E6, $EF, $15), ($E5, $ED, $E1, $1C), ($F2, $F0, $F3, $07), ($FF, $FB, $FD, $0E),
($B4, $92, $A7, $79), ($B9, $99, $A9, $70), ($AE, $84, $BB, $6B), ($A3, $8F, $B5, $62),
($80, $BE, $9F, $5D), ($8D, $B5, $91, $54), ($9A, $A8, $83, $4F), ($97, $A3, $8D, $46));
U4: array[0..255, 0..3] of byte = (
($00, $00, $00, $00), ($09, $0D, $0B, $0E), ($12, $1A, $16, $1C), ($1B, $17, $1D, $12),
($24, $34, $2C, $38), ($2D, $39, $27, $36), ($36, $2E, $3A, $24), ($3F, $23, $31, $2A),
($48, $68, $58, $70), ($41, $65, $53, $7E), ($5A, $72, $4E, $6C), ($53, $7F, $45, $62),
($6C, $5C, $74, $48), ($65, $51, $7F, $46), ($7E, $46, $62, $54), ($77, $4B, $69, $5A),
($90, $D0, $B0, $E0), ($99, $DD, $BB, $EE), ($82, $CA, $A6, $FC), ($8B, $C7, $AD, $F2),
($B4, $E4, $9C, $D8), ($BD, $E9, $97, $D6), ($A6, $FE, $8A, $C4), ($AF, $F3, $81, $CA),
($D8, $B8, $E8, $90), ($D1, $B5, $E3, $9E), ($CA, $A2, $FE, $8C), ($C3, $AF, $F5, $82),
($FC, $8C, $C4, $A8), ($F5, $81, $CF, $A6), ($EE, $96, $D2, $B4), ($E7, $9B, $D9, $BA),
($3B, $BB, $7B, $DB), ($32, $B6, $70, $D5), ($29, $A1, $6D, $C7), ($20, $AC, $66, $C9),
($1F, $8F, $57, $E3), ($16, $82, $5C, $ED), ($0D, $95, $41, $FF), ($04, $98, $4A, $F1),
($73, $D3, $23, $AB), ($7A, $DE, $28, $A5), ($61, $C9, $35, $B7), ($68, $C4, $3E, $B9),
($57, $E7, $0F, $93), ($5E, $EA, $04, $9D), ($45, $FD, $19, $8F), ($4C, $F0, $12, $81),
($AB, $6B, $CB, $3B), ($A2, $66, $C0, $35), ($B9, $71, $DD, $27), ($B0, $7C, $D6, $29),
($8F, $5F, $E7, $03), ($86, $52, $EC, $0D), ($9D, $45, $F1, $1F), ($94, $48, $FA, $11),
($E3, $03, $93, $4B), ($EA, $0E, $98, $45), ($F1, $19, $85, $57), ($F8, $14, $8E, $59),
($C7, $37, $BF, $73), ($CE, $3A, $B4, $7D), ($D5, $2D, $A9, $6F), ($DC, $20, $A2, $61),
($76, $6D, $F6, $AD), ($7F, $60, $FD, $A3), ($64, $77, $E0, $B1), ($6D, $7A, $EB, $BF),
($52, $59, $DA, $95), ($5B, $54, $D1, $9B), ($40, $43, $CC, $89), ($49, $4E, $C7, $87),
($3E, $05, $AE, $DD), ($37, $08, $A5, $D3), ($2C, $1F, $B8, $C1), ($25, $12, $B3, $CF),
($1A, $31, $82, $E5), ($13, $3C, $89, $EB), ($08, $2B, $94, $F9), ($01, $26, $9F, $F7),
($E6, $BD, $46, $4D), ($EF, $B0, $4D, $43), ($F4, $A7, $50, $51), ($FD, $AA, $5B, $5F),
($C2, $89, $6A, $75), ($CB, $84, $61, $7B), ($D0, $93, $7C, $69), ($D9, $9E, $77, $67),
($AE, $D5, $1E, $3D), ($A7, $D8, $15, $33), ($BC, $CF, $08, $21), ($B5, $C2, $03, $2F),
($8A, $E1, $32, $05), ($83, $EC, $39, $0B), ($98, $FB, $24, $19), ($91, $F6, $2F, $17),
($4D, $D6, $8D, $76), ($44, $DB, $86, $78), ($5F, $CC, $9B, $6A), ($56, $C1, $90, $64),
($69, $E2, $A1, $4E), ($60, $EF, $AA, $40), ($7B, $F8, $B7, $52), ($72, $F5, $BC, $5C),
($05, $BE, $D5, $06), ($0C, $B3, $DE, $08), ($17, $A4, $C3, $1A), ($1E, $A9, $C8, $14),
($21, $8A, $F9, $3E), ($28, $87, $F2, $30), ($33, $90, $EF, $22), ($3A, $9D, $E4, $2C),
($DD, $06, $3D, $96), ($D4, $0B, $36, $98), ($CF, $1C, $2B, $8A), ($C6, $11, $20, $84),
($F9, $32, $11, $AE), ($F0, $3F, $1A, $A0), ($EB, $28, $07, $B2), ($E2, $25, $0C, $BC),
($95, $6E, $65, $E6), ($9C, $63, $6E, $E8), ($87, $74, $73, $FA), ($8E, $79, $78, $F4),
($B1, $5A, $49, $DE), ($B8, $57, $42, $D0), ($A3, $40, $5F, $C2), ($AA, $4D, $54, $CC),
($EC, $DA, $F7, $41), ($E5, $D7, $FC, $4F), ($FE, $C0, $E1, $5D), ($F7, $CD, $EA, $53),
($C8, $EE, $DB, $79), ($C1, $E3, $D0, $77), ($DA, $F4, $CD, $65), ($D3, $F9, $C6, $6B),
($A4, $B2, $AF, $31), ($AD, $BF, $A4, $3F), ($B6, $A8, $B9, $2D), ($BF, $A5, $B2, $23),
($80, $86, $83, $09), ($89, $8B, $88, $07), ($92, $9C, $95, $15), ($9B, $91, $9E, $1B),
($7C, $0A, $47, $A1), ($75, $07, $4C, $AF), ($6E, $10, $51, $BD), ($67, $1D, $5A, $B3),
($58, $3E, $6B, $99), ($51, $33, $60, $97), ($4A, $24, $7D, $85), ($43, $29, $76, $8B),
($34, $62, $1F, $D1), ($3D, $6F, $14, $DF), ($26, $78, $09, $CD), ($2F, $75, $02, $C3),
($10, $56, $33, $E9), ($19, $5B, $38, $E7), ($02, $4C, $25, $F5), ($0B, $41, $2E, $FB),
($D7, $61, $8C, $9A), ($DE, $6C, $87, $94), ($C5, $7B, $9A, $86), ($CC, $76, $91, $88),
($F3, $55, $A0, $A2), ($FA, $58, $AB, $AC), ($E1, $4F, $B6, $BE), ($E8, $42, $BD, $B0),
($9F, $09, $D4, $EA), ($96, $04, $DF, $E4), ($8D, $13, $C2, $F6), ($84, $1E, $C9, $F8),
($BB, $3D, $F8, $D2), ($B2, $30, $F3, $DC), ($A9, $27, $EE, $CE), ($A0, $2A, $E5, $C0),
($47, $B1, $3C, $7A), ($4E, $BC, $37, $74), ($55, $AB, $2A, $66), ($5C, $A6, $21, $68),
($63, $85, $10, $42), ($6A, $88, $1B, $4C), ($71, $9F, $06, $5E), ($78, $92, $0D, $50),
($0F, $D9, $64, $0A), ($06, $D4, $6F, $04), ($1D, $C3, $72, $16), ($14, $CE, $79, $18),
($2B, $ED, $48, $32), ($22, $E0, $43, $3C), ($39, $F7, $5E, $2E), ($30, $FA, $55, $20),
($9A, $B7, $01, $EC), ($93, $BA, $0A, $E2), ($88, $AD, $17, $F0), ($81, $A0, $1C, $FE),
($BE, $83, $2D, $D4), ($B7, $8E, $26, $DA), ($AC, $99, $3B, $C8), ($A5, $94, $30, $C6),
($D2, $DF, $59, $9C), ($DB, $D2, $52, $92), ($C0, $C5, $4F, $80), ($C9, $C8, $44, $8E),
($F6, $EB, $75, $A4), ($FF, $E6, $7E, $AA), ($E4, $F1, $63, $B8), ($ED, $FC, $68, $B6),
($0A, $67, $B1, $0C), ($03, $6A, $BA, $02), ($18, $7D, $A7, $10), ($11, $70, $AC, $1E),
($2E, $53, $9D, $34), ($27, $5E, $96, $3A), ($3C, $49, $8B, $28), ($35, $44, $80, $26),
($42, $0F, $E9, $7C), ($4B, $02, $E2, $72), ($50, $15, $FF, $60), ($59, $18, $F4, $6E),
($66, $3B, $C5, $44), ($6F, $36, $CE, $4A), ($74, $21, $D3, $58), ($7D, $2C, $D8, $56),
($A1, $0C, $7A, $37), ($A8, $01, $71, $39), ($B3, $16, $6C, $2B), ($BA, $1B, $67, $25),
($85, $38, $56, $0F), ($8C, $35, $5D, $01), ($97, $22, $40, $13), ($9E, $2F, $4B, $1D),
($E9, $64, $22, $47), ($E0, $69, $29, $49), ($FB, $7E, $34, $5B), ($F2, $73, $3F, $55),
($CD, $50, $0E, $7F), ($C4, $5D, $05, $71), ($DF, $4A, $18, $63), ($D6, $47, $13, $6D),
($31, $DC, $CA, $D7), ($38, $D1, $C1, $D9), ($23, $C6, $DC, $CB), ($2A, $CB, $D7, $C5),
($15, $E8, $E6, $EF), ($1C, $E5, $ED, $E1), ($07, $F2, $F0, $F3), ($0E, $FF, $FB, $FD),
($79, $B4, $92, $A7), ($70, $B9, $99, $A9), ($6B, $AE, $84, $BB), ($62, $A3, $8F, $B5),
($5D, $80, $BE, $9F), ($54, $8D, $B5, $91), ($4F, $9A, $A8, $83), ($46, $97, $A3, $8D));
rcon: array[0..29] of Cardinal = (
$01, $02, $04, $08, $10, $20, $40, $80, $1B, $36, $6C, $D8, $AB, $4D, $9A,
$2F, $5E, $BC, $63, $C6, $97, $35, $6A, $D4, $B3, $7D, $FA, $EF, $C5, $91);
const
BCRJ = 4;
MAXROUNDSRJ = 14;
type
PRijndael = ^TRijndael;
TRijndael = object(TBlockCipher128)
protected
numrounds: longword;
rk, drk: array[0..MAXROUNDSRJ, 0..7] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
// Serpent cipher implementation
type
PSerpent = ^TSerpent;
TSerpent = object(TBlockCipher128)
protected
l_key: array[0..131] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
// TwoFish cipher implementation
const
p8x8: array[0..1, 0..255] of byte = ((
$A9, $67, $B3, $E8, $04, $FD, $A3, $76,
$9A, $92, $80, $78, $E4, $DD, $D1, $38,
$0D, $C6, $35, $98, $18, $F7, $EC, $6C,
$43, $75, $37, $26, $FA, $13, $94, $48,
$F2, $D0, $8B, $30, $84, $54, $DF, $23,
$19, $5B, $3D, $59, $F3, $AE, $A2, $82,
$63, $01, $83, $2E, $D9, $51, $9B, $7C,
$A6, $EB, $A5, $BE, $16, $0C, $E3, $61,
$C0, $8C, $3A, $F5, $73, $2C, $25, $0B,
$BB, $4E, $89, $6B, $53, $6A, $B4, $F1,
$E1, $E6, $BD, $45, $E2, $F4, $B6, $66,
$CC, $95, $03, $56, $D4, $1C, $1E, $D7,
$FB, $C3, $8E, $B5, $E9, $CF, $BF, $BA,
$EA, $77, $39, $AF, $33, $C9, $62, $71,
$81, $79, $09, $AD, $24, $CD, $F9, $D8,
$E5, $C5, $B9, $4D, $44, $08, $86, $E7,
$A1, $1D, $AA, $ED, $06, $70, $B2, $D2,
$41, $7B, $A0, $11, $31, $C2, $27, $90,
$20, $F6, $60, $FF, $96, $5C, $B1, $AB,
$9E, $9C, $52, $1B, $5F, $93, $0A, $EF,
$91, $85, $49, $EE, $2D, $4F, $8F, $3B,
$47, $87, $6D, $46, $D6, $3E, $69, $64,
$2A, $CE, $CB, $2F, $FC, $97, $05, $7A,
$AC, $7F, $D5, $1A, $4B, $0E, $A7, $5A,
$28, $14, $3F, $29, $88, $3C, $4C, $02,
$B8, $DA, $B0, $17, $55, $1F, $8A, $7D,
$57, $C7, $8D, $74, $B7, $C4, $9F, $72,
$7E, $15, $22, $12, $58, $07, $99, $34,
$6E, $50, $DE, $68, $65, $BC, $DB, $F8,
$C8, $A8, $2B, $40, $DC, $FE, $32, $A4,
$CA, $10, $21, $F0, $D3, $5D, $0F, $00,
$6F, $9D, $36, $42, $4A, $5E, $C1, $E0), (
$75, $F3, $C6, $F4, $DB, $7B, $FB, $C8,
$4A, $D3, $E6, $6B, $45, $7D, $E8, $4B,
$D6, $32, $D8, $FD, $37, $71, $F1, $E1,
$30, $0F, $F8, $1B, $87, $FA, $06, $3F,
$5E, $BA, $AE, $5B, $8A, $00, $BC, $9D,
$6D, $C1, $B1, $0E, $80, $5D, $D2, $D5,
$A0, $84, $07, $14, $B5, $90, $2C, $A3,
$B2, $73, $4C, $54, $92, $74, $36, $51,
$38, $B0, $BD, $5A, $FC, $60, $62, $96,
$6C, $42, $F7, $10, $7C, $28, $27, $8C,
$13, $95, $9C, $C7, $24, $46, $3B, $70,
$CA, $E3, $85, $CB, $11, $D0, $93, $B8,
$A6, $83, $20, $FF, $9F, $77, $C3, $CC,
$03, $6F, $08, $BF, $40, $E7, $2B, $E2,
$79, $0C, $AA, $82, $41, $3A, $EA, $B9,
$E4, $9A, $A4, $97, $7E, $DA, $7A, $17,
$66, $94, $A1, $1D, $3D, $F0, $DE, $B3,
$0B, $72, $A7, $1C, $EF, $D1, $53, $3E,
$8F, $33, $26, $5F, $EC, $76, $2A, $49,
$81, $88, $EE, $21, $C4, $1A, $EB, $D9,
$C5, $39, $99, $CD, $AD, $31, $8B, $01,
$18, $23, $DD, $1F, $4E, $2D, $F9, $48,
$4F, $F2, $65, $8E, $78, $5C, $58, $19,
$8D, $E5, $98, $57, $67, $7F, $05, $64,
$AF, $63, $B6, $FE, $F5, $B7, $3C, $A5,
$CE, $E9, $68, $44, $E0, $4D, $43, $69,
$29, $2E, $AC, $15, $59, $A8, $0A, $9E,
$6E, $47, $DF, $34, $35, $6A, $CF, $DC,
$22, $C9, $C0, $9B, $89, $D4, $ED, $AB,
$12, $A2, $0D, $52, $BB, $02, $2F, $A9,
$D7, $61, $1E, $B4, $50, $04, $F6, $C2,
$16, $25, $86, $56, $55, $09, $BE, $91));
const
INPUTWHITEN = 0;
OUTPUTWHITEN = 4;
NUMROUNDSTF = 16;
ROUNDSUBKEYS = (OUTPUTWHITEN + 4);
TOTALSUBKEYS = (ROUNDSUBKEYS + NUMROUNDSTF * 2);
RS_GF_FDBK = $14D;
MDS_GF_FDBK = $169;
SK_STEP = $02020202;
SK_BUMP = $01010101;
SK_ROTL = 9;
type
PTwoFish = ^TTwoFish;
TTwoFish = object(TBlockCipher128)
protected
SubKeys: array[0..TOTALSUBKEYS - 1] of DWORD;
SBox: array[0..3, 0..255] of DWORD;
public
procedure InitKey(const Key; Size: longword); virtual;
procedure Burn; virtual;
procedure EncryptECB(const Indata; var Outdata); virtual;
procedure DecryptECB(const Indata; var Outdata); virtual;
destructor Destroy; virtual;
end;
type
PRC4 = ^TRC4;
TRC4 = object(TObj)
protected
KeyData, KeyOrg: array[0..255] of byte;
public
procedure InitKey(const Key; Size: longword; InitVector: pointer);
procedure Reset;
procedure Burn;
procedure Encrypt(const Indata; var Outdata; Size: longword);
procedure Decrypt(const Indata; var Outdata; Size: longword);
destructor Destroy; virtual;
end;
TKOLRijndael = PRijndael;
TKOLMars = PMars;
TKOLICE = PICE;
TKOLICE2 = PICE2;
TKOLThinICE = PThinIce;
TKOLDES = PDES;
TKOL3DES = P3DES;
TKOLTEA = PTEA;
TKOLRC2 = PRC2;
TKOLRC4 = PRC4;
TKOLRC5 = PRC5;
TKOLRC6 = PRC6;
TKOLMisty1 = PMisty1;
TKOLIDEA = PIDEA;
TKOLGOST = PGOST;
TKOLCast128 = PCast128;
TKOLCast256 = PCast256;
TKOLBlowfish = PBlowfish;
TKOLTwofish = PTwoFish;
TKOLSerpent = PSerpent;
// TKOLBlockCipher64 = PBlockCipher64;
// TKOLBlockCipher128 = PBlockCipher128;
function NewSerpent: PSerpent;
function NewRijndael: PRijndael;
function NewICE: PICE;
function NewICE2: PICE2;
function NewThinICE: PThinIce;
function New3DES: P3DES;
function NewDES: PDES;
function NewTEA: PTEA;
function NewRC2: PRC2;
function NewRC4: PRC4;
function NewRC5: PRC5;
function NewRC6: PRC6;
function NewMisty1: PMisty1;
function NewIDEA: PIDEA;
function NewGOST: PGOST;
function NewCast256: PCast256;
function NewCast128: PCast128;
function NewBlowfish: PBlowfish;
function NewTwofish: PTwoFish;
function NewMars: PMars;
//function NewBlockCipher64: PBlockCipher64;
//function NewBlockCipher128: PBlockCipher128;
implementation
// uses CommCtrl, ShellApi;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TBlockCipher64.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
//function NewBlockCipher64;
//begin
//New(Result, Create);
// code
//end;
////////////////////////////////////////////////////////////////////////////////
destructor TBlockCipher128.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
//function NewBlockCipher128;
//begin
//New(Result, Create);
// code
//end;
////////////////////////////////////////////////////////////////////////////////
procedure XorBlock(var InData1, InData2; Size: longword);
var
i: longword;
begin
for i := 1 to Size do
Pbyte(longword(@InData1) + i - 1)^ := Pbyte(longword(@InData1) + i - 1)^ xor Pbyte(longword(@InData2) + i - 1)^;
end;
procedure TBlockCipher64.EncryptECB(const Indata; var Outdata);
begin
end;
procedure TBlockCipher64.DecryptECB(const Indata; var Outdata);
begin
end;
procedure TBlockCipher64.InitKey(const Key; Size: longword);
begin
end;
procedure TBlockCipher128.EncryptECB(const Indata; var Outdata);
begin
end;
procedure TBlockCipher128.DecryptECB(const Indata; var Outdata);
begin
end;
procedure TBlockCipher128.InitKey(const Key; Size: longword);
begin
end;
procedure TBlockCipher64.IncCounter;
var
i: Integer;
begin
Inc(CV[7]);
i := 7;
while (i > 0) and (CV[i] = 0) do begin
Inc(CV[i - 1]);
Dec(i);
end;
end;
procedure TBlockCipher64.InitBlockCipher64(const Key; Size: longword; InitVector: pointer);
begin
{inherited}
//Init(Key,Size,InitVector);
InitKey(Key, Size);
if InitVector = nil then begin
FillChar(IV, 8, 0);
EncryptECB(IV, IV);
Reset;
end
else begin
Move(InitVector^, IV, 8);
Reset;
end;
end;
procedure TBlockCipher64.SetIV(const Value);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Move(Value, IV, 8);
Reset;
end;
procedure TBlockCipher64.GetIV(var Value);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Move(CV, Value, 8);
end;
procedure TBlockCipher64.Reset;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized')
// else
Move(IV, CV, 8);
end;
procedure TBlockCipher64.Burn;
begin
FillChar(IV, 8, $FF);
FillChar(CV, 8, $FF);
// inherited Burn;
end;
procedure TBlockCipher64.EncryptCBC(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
Move(p1^, p2^, 8);
XorBlock(p2^, CV, 8);
EncryptECB(p2^, p2^);
Move(p2^, CV, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, CV, Size mod 8);
end;
end;
procedure TBlockCipher64.DecryptCBC(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
Temp: array[0..7] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
Move(p1^, p2^, 8);
Move(p1^, Temp, 8);
DecryptECB(p2^, p2^);
XorBlock(p2^, CV, 8);
Move(Temp, CV, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, CV, Size mod 8);
end;
end;
procedure TBlockCipher64.EncryptCFB8bit(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
Temp: array[0..7] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to Size do begin
EncryptECB(CV, Temp);
p2^ := p1^ xor Temp[0];
Move(CV[1], CV[0], 8 - 1);
CV[7] := p2^;
Inc(p1);
Inc(p2);
end;
end;
procedure TBlockCipher64.DecryptCFB8bit(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
TempByte: byte;
Temp: array[0..7] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to Size do begin
TempByte := p1^;
EncryptECB(CV, Temp);
p2^ := p1^ xor Temp[0];
Move(CV[1], CV[0], 8 - 1);
CV[7] := TempByte;
Inc(p1);
Inc(p2);
end;
end;
procedure TBlockCipher64.EncryptCFBblock(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
EncryptECB(CV, CV);
Move(p1^, p2^, 8);
XorBlock(p2^, CV, 8);
Move(p2^, CV, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, CV, Size mod 8);
end;
end;
procedure TBlockCipher64.DecryptCFBblock(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
Temp: array[0..7] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
Move(p1^, Temp, 8);
EncryptECB(CV, CV);
Move(p1^, p2^, 8);
XorBlock(p2^, CV, 8);
Move(Temp, CV, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, CV, Size mod 8);
end;
end;
procedure TBlockCipher64.EncryptOFB(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
EncryptECB(CV, CV);
Move(p1^, p2^, 8);
XorBlock(p2^, CV, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, CV, Size mod 8);
end;
end;
procedure TBlockCipher64.DecryptOFB(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
EncryptECB(CV, CV);
Move(p1^, p2^, 8);
XorBlock(p2^, CV, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, CV, Size mod 8);
end;
end;
procedure TBlockCipher64.EncryptCTR(const Indata; var Outdata; Size: longword);
var
Temp: array[0..7] of byte;
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, 8);
XorBlock(p2^, Temp, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, Temp, Size mod 8);
end;
end;
procedure TBlockCipher64.DecryptCTR(const Indata; var Outdata; Size: longword);
var
Temp: array[0..7] of byte;
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 8) do begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, 8);
XorBlock(p2^, Temp, 8);
p1 := pointer(longword(p1) + 8);
p2 := pointer(longword(p2) + 8);
end;
if (Size mod 8) <> 0 then begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, Size mod 8);
XorBlock(p2^, Temp, Size mod 8);
end;
end;
{** TBlockCipher128 ********************************************************}
procedure TBlockCipher128.IncCounter;
var
i: Integer;
begin
Inc(CV[15]);
i := 15;
while (i > 0) and (CV[i] = 0) do begin
Inc(CV[i - 1]);
Dec(i);
end;
end;
procedure TBlockCipher128.InitBlockCipher128(const Key; Size: longword; InitVector: pointer);
begin
// inherited Init(Key,Size,InitVector);
InitKey(Key, Size);
if InitVector = nil then begin
FillChar(IV, 16, 0);
EncryptECB(IV, IV);
Reset;
end
else begin
Move(InitVector^, IV, 16);
Reset;
end;
end;
procedure TBlockCipher128.SetIV(const Value);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Move(Value, IV, 16);
Reset;
end;
procedure TBlockCipher128.GetIV(var Value);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Move(CV, Value, 16);
end;
procedure TBlockCipher128.Reset;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized')
// else
Move(IV, CV, 16);
end;
procedure TBlockCipher128.Burn;
begin
FillChar(IV, 16, $FF);
FillChar(CV, 16, $FF);
// inherited Burn;
end;
procedure TBlockCipher128.EncryptCBC(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
Move(p1^, p2^, 16);
XorBlock(p2^, CV, 16);
EncryptECB(p2^, p2^);
Move(p2^, CV, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, CV, Size mod 16);
end;
end;
procedure TBlockCipher128.DecryptCBC(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
Temp: array[0..15] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
Move(p1^, p2^, 16);
Move(p1^, Temp, 16);
DecryptECB(p2^, p2^);
XorBlock(p2^, CV, 16);
Move(Temp, CV, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, CV, Size mod 16);
end;
end;
procedure TBlockCipher128.EncryptCFB8bit(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
Temp: array[0..15] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to Size do begin
EncryptECB(CV, Temp);
p2^ := p1^ xor Temp[0];
Move(CV[1], CV[0], 15);
CV[15] := p2^;
Inc(p1);
Inc(p2);
end;
end;
procedure TBlockCipher128.DecryptCFB8bit(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
TempByte: byte;
Temp: array[0..15] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to Size do begin
TempByte := p1^;
EncryptECB(CV, Temp);
p2^ := p1^ xor Temp[0];
Move(CV[1], CV[0], 15);
CV[15] := TempByte;
Inc(p1);
Inc(p2);
end;
end;
procedure TBlockCipher128.EncryptCFBblock(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
EncryptECB(CV, CV);
Move(p1^, p2^, 16);
XorBlock(p2^, CV, 16);
Move(p2^, CV, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, CV, Size mod 16);
end;
end;
procedure TBlockCipher128.DecryptCFBblock(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: Pbyte;
Temp: array[0..15] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
Move(p1^, Temp, 16);
EncryptECB(CV, CV);
Move(p1^, p2^, 16);
XorBlock(p2^, CV, 16);
Move(Temp, CV, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, CV, Size mod 16);
end;
end;
procedure TBlockCipher128.EncryptOFB(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
EncryptECB(CV, CV);
Move(p1^, p2^, 16);
XorBlock(p2^, CV, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, CV, Size mod 16);
end;
end;
procedure TBlockCipher128.DecryptOFB(const Indata; var Outdata; Size: longword);
var
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
EncryptECB(CV, CV);
Move(p1^, p2^, 16);
XorBlock(p2^, CV, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, CV);
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, CV, Size mod 16);
end;
end;
procedure TBlockCipher128.EncryptCTR(const Indata; var Outdata; Size: longword);
var
Temp: array[0..15] of byte;
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, 16);
XorBlock(p2^, Temp, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, Temp, Size mod 16);
end;
end;
procedure TBlockCipher128.DecryptCTR(const Indata; var Outdata; Size: longword);
var
Temp: array[0..15] of byte;
i: longword;
p1, p2: pointer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
p1 := @Indata;
p2 := @Outdata;
for i := 1 to (Size div 16) do begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, 16);
XorBlock(p2^, Temp, 16);
p1 := pointer(longword(p1) + 16);
p2 := pointer(longword(p2) + 16);
end;
if (Size mod 16) <> 0 then begin
EncryptECB(CV, Temp);
IncCounter;
Move(p1^, p2^, Size mod 16);
XorBlock(p2^, Temp, Size mod 16);
end;
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TBlowfish.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewBlowfish;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
{$R-}{$Q-}
//{$I DCPblowfish.inc}
procedure TBlowfish.InitKey(const Key; Size: longword);
var
i, k: longword;
A: DWORD;
KeyB: PByteArray;
Block: array[0..7] of byte;
begin
Burn;
Size := Size div 8;
KeyB := @Key;
Move(SBoxOrg, SBox, Sizeof(SBox));
Move(PBoxOrg, PBox, Sizeof(PBox));
k := 0;
for i := 0 to 17 do begin
A := DWORD(KeyB^[(k + 3) mod Size]);
A := A + (DWORD(KeyB^[(k + 2) mod Size]) shl 8);
A := A + (DWORD(KeyB^[(k + 1) mod Size]) shl 16);
A := A + (DWORD(KeyB^[k]) shl 24);
PBox[i] := PBox[i] xor A;
k := (k + 4) mod Size;
end;
FillChar(Block, Sizeof(Block), 0);
for i := 0 to 8 do begin
EncryptECB(Block, Block);
PBox[i * 2] := DWORD(Block[3]) + (DWORD(Block[2]) shl 8) + (DWORD(Block[1]) shl 16) + (DWORD(Block[0]) shl 24);
PBox[i * 2 + 1] := DWORD(Block[7]) + (DWORD(Block[6]) shl 8) + (DWORD(Block[5]) shl 16) + (DWORD(Block[4]) shl 24);
end;
for k := 0 to 3 do begin
for i := 0 to 127 do begin
EncryptECB(Block, Block);
SBox[k, i * 2] := DWORD(Block[3]) + (DWORD(Block[2]) shl 8) + (DWORD(Block[1]) shl 16) + (DWORD(Block[0]) shl 24);
SBox[k, i * 2 + 1] := DWORD(Block[7]) + (DWORD(Block[6]) shl 8) + (DWORD(Block[5]) shl 16) + (DWORD(Block[4]) shl 24);
end;
end;
end;
procedure TBlowfish.Burn;
begin
FillChar(SBox, Sizeof(SBox), $FF);
FillChar(PBox, Sizeof(PBox), $FF);
inherited Burn;
end;
procedure TBlowfish.EncryptECB(const Indata; var Outdata);
var
xL, xR: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
xL := Pdword(@Indata)^;
xR := Pdword(longword(@Indata) + 4)^;
xL := ((xL and $FF) shl 24) or ((xL and $FF00) shl 8) or ((xL and $FF0000) shr 8) or ((xL and $FF000000) shr 24);
xR := ((xR and $FF) shl 24) or ((xR and $FF00) shl 8) or ((xR and $FF0000) shr 8) or ((xR and $FF000000) shr 24);
xL := xL xor PBox[0];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[1];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[2];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[3];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[4];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[5];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[6];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[7];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[8];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[9];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[10];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[11];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[12];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[13];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[14];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[15];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[16];
xR := xR xor PBox[17];
xL := ((xL and $FF) shl 24) or ((xL and $FF00) shl 8) or ((xL and $FF0000) shr 8) or ((xL and $FF000000) shr 24);
xR := ((xR and $FF) shl 24) or ((xR and $FF00) shl 8) or ((xR and $FF0000) shr 8) or ((xR and $FF000000) shr 24);
Pdword(@Outdata)^ := xR;
Pdword(longword(@Outdata) + 4)^ := xL;
end;
procedure TBlowfish.DecryptECB(const Indata; var Outdata);
var
xL, xR: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
xL := Pdword(@Indata)^;
xR := Pdword(longword(@Indata) + 4)^;
xL := (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
xR := (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
xL := xL xor PBox[17];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[16];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[15];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[14];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[13];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[12];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[11];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[10];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[9];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[8];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[7];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[6];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[5];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[4];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[3];
xR := xR xor (((SBox[0, (xL shr 24) and $FF] + SBox[1, (xL shr 16) and $FF]) xor
SBox[2, (xL shr 8) and $FF]) + SBox[3, xL and $FF]) xor PBox[2];
xL := xL xor (((SBox[0, (xR shr 24) and $FF] + SBox[1, (xR shr 16) and $FF]) xor
SBox[2, (xR shr 8) and $FF]) + SBox[3, xR and $FF]) xor PBox[1];
xR := xR xor PBox[0];
xL := (xL shr 24) or ((xL shr 8) and $FF00) or ((xL shl 8) and $FF0000) or (xL shl 24);
xR := (xR shr 24) or ((xR shr 8) and $FF00) or ((xR shl 8) and $FF0000) or (xR shl 24);
Pdword(@Outdata)^ := xR;
Pdword(longword(@Outdata) + 4)^ := xL;
end;
{$R-}{$Q-}
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TCast128.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewCast128;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
function LRot32(A, n: DWORD): DWORD;
begin
Result := (A shl n) or (A shr (32 - n));
end;
procedure TCast128.InitKey(const Key; Size: longword);
var
x, t, z: array[0..3] of DWORD;
i: longword;
begin
Burn;
Size := Size div 8;
if Size <= 10 then
Rounds := 12
else
Rounds := 16;
FillChar(x, Sizeof(x), 0);
Move(Key, x, Size);
x[0] := (x[0] shr 24) or ((x[0] shr 8) and $FF00) or ((x[0] shl 8) and $FF0000) or (x[0] shl 24);
x[1] := (x[1] shr 24) or ((x[1] shr 8) and $FF00) or ((x[1] shl 8) and $FF0000) or (x[1] shl 24);
x[2] := (x[2] shr 24) or ((x[2] shr 8) and $FF00) or ((x[2] shl 8) and $FF0000) or (x[2] shl 24);
x[3] := (x[3] shr 24) or ((x[3] shr 8) and $FF00) or ((x[3] shl 8) and $FF0000) or (x[3] shl 24);
i := 0;
while i < 32 do begin
case (i and 4) of
0: begin
z[0] := x[0] xor cast_sbox5[(x[3] shr 16) and $FF] xor
cast_sbox6[x[3] and $FF] xor cast_sbox7[x[3] shr 24] xor
cast_sbox8[(x[3] shr 8) and $FF] xor cast_sbox7[x[2] shr 24];
t[0] := z[0];
z[1] := x[2] xor cast_sbox5[z[0] shr 24] xor
cast_sbox6[(z[0] shr 8) and $FF] xor cast_sbox7[(z[0] shr 16) and $FF] xor
cast_sbox8[z[0] and $FF] xor cast_sbox8[(x[2] shr 8) and $FF];
t[1] := z[1];
z[2] := x[3] xor cast_sbox5[z[1] and $FF] xor
cast_sbox6[(z[1] shr 8) and $FF] xor cast_sbox7[(z[1] shr 16) and $FF] xor
cast_sbox8[z[1] shr 24] xor cast_sbox5[(x[2] shr 16) and $FF];
t[2] := z[2];
z[3] := x[1] xor cast_sbox5[(z[2] shr 8) and $FF] xor
cast_sbox6[(z[2] shr 16) and $FF] xor cast_sbox7[z[2] and $FF] xor
cast_sbox8[z[2] shr 24] xor cast_sbox6[x[2] and $FF];
t[3] := z[3];
end;
4: begin
x[0] := z[2] xor cast_sbox5[(z[1] shr 16) and $FF] xor
cast_sbox6[z[1] and $FF] xor cast_sbox7[z[1] shr 24] xor
cast_sbox8[(z[1] shr 8) and $FF] xor cast_sbox7[z[0] shr 24];
t[0] := x[0];
x[1] := z[0] xor cast_sbox5[x[0] shr 24] xor
cast_sbox6[(x[0] shr 8) and $FF] xor cast_sbox7[(x[0] shr 16) and $FF] xor
cast_sbox8[x[0] and $FF] xor cast_sbox8[(z[0] shr 8) and $FF];
t[1] := x[1];
x[2] := z[1] xor cast_sbox5[x[1] and $FF] xor
cast_sbox6[(x[1] shr 8) and $FF] xor cast_sbox7[(x[1] shr 16) and $FF] xor
cast_sbox8[x[1] shr 24] xor cast_sbox5[(z[0] shr 16) and $FF];
t[2] := x[2];
x[3] := z[3] xor cast_sbox5[(x[2] shr 8) and $FF] xor
cast_sbox6[(x[2] shr 16) and $FF] xor cast_sbox7[x[2] and $FF] xor
cast_sbox8[x[2] shr 24] xor cast_sbox6[z[0] and $FF];
t[3] := x[3];
end;
end;
case (i and 12) of
0, 12: begin
KeyData[i + 0] := cast_sbox5[t[2] shr 24] xor cast_sbox6[(t[2] shr 16) and $FF] xor
cast_sbox7[t[1] and $FF] xor cast_sbox8[(t[1] shr 8) and $FF];
KeyData[i + 1] := cast_sbox5[(t[2] shr 8) and $FF] xor cast_sbox6[t[2] and $FF] xor
cast_sbox7[(t[1] shr 16) and $FF] xor cast_sbox8[t[1] shr 24];
KeyData[i + 2] := cast_sbox5[t[3] shr 24] xor cast_sbox6[(t[3] shr 16) and $FF] xor
cast_sbox7[t[0] and $FF] xor cast_sbox8[(t[0] shr 8) and $FF];
KeyData[i + 3] := cast_sbox5[(t[3] shr 8) and $FF] xor cast_sbox6[t[3] and $FF] xor
cast_sbox7[(t[0] shr 16) and $FF] xor cast_sbox8[t[0] shr 24];
end;
4, 8: begin
KeyData[i + 0] := cast_sbox5[t[0] and $FF] xor cast_sbox6[(t[0] shr 8) and $FF] xor
cast_sbox7[t[3] shr 24] xor cast_sbox8[(t[3] shr 16) and $FF];
KeyData[i + 1] := cast_sbox5[(t[0] shr 16) and $FF] xor cast_sbox6[t[0] shr 24] xor
cast_sbox7[(t[3] shr 8) and $FF] xor cast_sbox8[t[3] and $FF];
KeyData[i + 2] := cast_sbox5[t[1] and $FF] xor cast_sbox6[(t[1] shr 8) and $FF] xor
cast_sbox7[t[2] shr 24] xor cast_sbox8[(t[2] shr 16) and $FF];
KeyData[i + 3] := cast_sbox5[(t[1] shr 16) and $FF] xor cast_sbox6[t[1] shr 24] xor
cast_sbox7[(t[2] shr 8) and $FF] xor cast_sbox8[t[2] and $FF];
end;
end;
case (i and 12) of
0: begin
KeyData[i + 0] := KeyData[i + 0] xor cast_sbox5[(z[0] shr 8) and $FF];
KeyData[i + 1] := KeyData[i + 1] xor cast_sbox6[(z[1] shr 8) and $FF];
KeyData[i + 2] := KeyData[i + 2] xor cast_sbox7[(z[2] shr 16) and $FF];
KeyData[i + 3] := KeyData[i + 3] xor cast_sbox8[z[3] shr 24];
end;
4: begin
KeyData[i + 0] := KeyData[i + 0] xor cast_sbox5[x[2] shr 24];
KeyData[i + 1] := KeyData[i + 1] xor cast_sbox6[(x[3] shr 16) and $FF];
KeyData[i + 2] := KeyData[i + 2] xor cast_sbox7[x[0] and $FF];
KeyData[i + 3] := KeyData[i + 3] xor cast_sbox8[x[1] and $FF];
end;
8: begin
KeyData[i + 0] := KeyData[i + 0] xor cast_sbox5[(z[2] shr 16) and $FF];
KeyData[i + 1] := KeyData[i + 1] xor cast_sbox6[z[3] shr 24];
KeyData[i + 2] := KeyData[i + 2] xor cast_sbox7[(z[0] shr 8) and $FF];
KeyData[i + 3] := KeyData[i + 3] xor cast_sbox8[(z[1] shr 8) and $FF];
end;
12: begin
KeyData[i + 0] := KeyData[i + 0] xor cast_sbox5[x[0] and $FF];
KeyData[i + 1] := KeyData[i + 1] xor cast_sbox6[x[1] and $FF];
KeyData[i + 2] := KeyData[i + 2] xor cast_sbox7[x[2] shr 24];
KeyData[i + 3] := KeyData[i + 3] xor cast_sbox8[(x[3] shr 16) and $FF];
end;
end;
if (i >= 16) then begin
KeyData[i + 0] := KeyData[i + 0] and 31;
KeyData[i + 1] := KeyData[i + 1] and 31;
KeyData[i + 2] := KeyData[i + 2] and 31;
KeyData[i + 3] := KeyData[i + 3] and 31;
end;
Inc(i, 4);
end;
end;
procedure TCast128.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), $FF);
Rounds := 0;
inherited Burn;
end;
procedure TCast128.EncryptECB(const Indata; var Outdata);
var
t, l, r: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
l := Pdword(@Indata)^;
r := Pdword(longword(@Indata) + 4)^;
l := (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
r := (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
t := LRot32(KeyData[0] + r, KeyData[0 + 16]);
l := l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[1] xor l, KeyData[1 + 16]);
r := r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[2] - r, KeyData[2 + 16]);
l := l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[3] + l, KeyData[3 + 16]);
r := r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[4] xor r, KeyData[4 + 16]);
l := l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[5] - l, KeyData[5 + 16]);
r := r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[6] + r, KeyData[6 + 16]);
l := l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[7] xor l, KeyData[7 + 16]);
r := r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[8] - r, KeyData[8 + 16]);
l := l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[9] + l, KeyData[9 + 16]);
r := r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[10] xor r, KeyData[10 + 16]);
l := l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[11] - l, KeyData[11 + 16]);
r := r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
if Rounds > 12 then begin
t := LRot32(KeyData[12] + r, KeyData[12 + 16]);
l := l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[13] xor l, KeyData[13 + 16]);
r := r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[14] - r, KeyData[14 + 16]);
l := l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[15] + l, KeyData[15 + 16]);
r := r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
end;
l := (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
r := (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
Pdword(@Outdata)^ := r;
Pdword(longword(@Outdata) + 4)^ := l;
end;
procedure TCast128.DecryptECB(const Indata; var Outdata);
var
t, l, r: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
r := Pdword(@Indata)^;
l := Pdword(longword(@Indata) + 4)^;
l := (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
r := (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
if Rounds > 12 then begin
t := LRot32(KeyData[15] + l, KeyData[15 + 16]);
r := r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[14] - r, KeyData[14 + 16]);
l := l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[13] xor l, KeyData[13 + 16]);
r := r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[12] + r, KeyData[12 + 16]);
l := l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
end;
t := LRot32(KeyData[11] - l, KeyData[11 + 16]);
r := r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[10] xor r, KeyData[10 + 16]);
l := l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[9] + l, KeyData[9 + 16]);
r := r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[8] - r, KeyData[8 + 16]);
l := l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[7] xor l, KeyData[7 + 16]);
r := r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[6] + r, KeyData[6 + 16]);
l := l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[5] - l, KeyData[5 + 16]);
r := r xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[4] xor r, KeyData[4 + 16]);
l := l xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[3] + l, KeyData[3 + 16]);
r := r xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
t := LRot32(KeyData[2] - r, KeyData[2 + 16]);
l := l xor (((cast_sbox1[t shr 24] + cast_sbox2[(t shr 16) and $FF]) xor
cast_sbox3[(t shr 8) and $FF]) - cast_sbox4[t and $FF]);
t := LRot32(KeyData[1] xor l, KeyData[1 + 16]);
r := r xor (((cast_sbox1[t shr 24] - cast_sbox2[(t shr 16) and $FF]) +
cast_sbox3[(t shr 8) and $FF]) xor cast_sbox4[t and $FF]);
t := LRot32(KeyData[0] + r, KeyData[0 + 16]);
l := l xor (((cast_sbox1[t shr 24] xor cast_sbox2[(t shr 16) and $FF]) -
cast_sbox3[(t shr 8) and $FF]) + cast_sbox4[t and $FF]);
l := (l shr 24) or ((l shr 8) and $FF00) or ((l shl 8) and $FF0000) or (l shl 24);
r := (r shr 24) or ((r shr 8) and $FF00) or ((r shl 8) and $FF0000) or (r shl 24);
Pdword(@Outdata)^ := l;
Pdword(longword(@Outdata) + 4)^ := r;
end;
destructor TGOST.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewGOST;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
{$R-}{$Q-}
//{$I DCPgost.inc}
procedure TGOST.InitKey(const Key; Size: longword);
var
i: longword;
userkey: array[0..31] of byte;
begin
Burn;
Size := Size div 8;
FillChar(userkey, Sizeof(userkey), 0);
Move(Key, userkey, Size);
for i := 0 to 7 do
KeyData[i] := (DWORD(userkey[4 * i + 3]) shl 24) or (DWORD(userkey[4 * i + 2]) shl 16) or
(DWORD(userkey[4 * i + 1]) shl 8) or (DWORD(userkey[4 * i + 0]));
end;
procedure TGOST.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), 0);
inherited Burn;
end;
procedure TGOST.EncryptECB(const Indata; var Outdata);
var
n1, n2: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
n1 := Pdword(@Indata)^;
n2 := Pdword(DWORD(@Indata) + 4)^;
for i := 0 to 2 do begin
n2 := n2 xor (sTable[3, (n1 + KeyData[0]) shr 24] xor sTable[2, ((n1 + KeyData[0]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[0]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[0]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[1]) shr 24] xor sTable[2, ((n2 + KeyData[1]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[1]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[1]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[2]) shr 24] xor sTable[2, ((n1 + KeyData[2]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[2]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[2]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[3]) shr 24] xor sTable[2, ((n2 + KeyData[3]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[3]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[3]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[4]) shr 24] xor sTable[2, ((n1 + KeyData[4]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[4]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[4]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[5]) shr 24] xor sTable[2, ((n2 + KeyData[5]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[5]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[5]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[6]) shr 24] xor sTable[2, ((n1 + KeyData[6]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[6]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[6]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[7]) shr 24] xor sTable[2, ((n2 + KeyData[7]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[7]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[7]) and $FF]);
end;
n2 := n2 xor (sTable[3, (n1 + KeyData[7]) shr 24] xor sTable[2, ((n1 + KeyData[7]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[7]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[7]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[6]) shr 24] xor sTable[2, ((n2 + KeyData[6]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[6]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[6]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[5]) shr 24] xor sTable[2, ((n1 + KeyData[5]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[5]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[5]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[4]) shr 24] xor sTable[2, ((n2 + KeyData[4]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[4]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[4]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[3]) shr 24] xor sTable[2, ((n1 + KeyData[3]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[3]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[3]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[2]) shr 24] xor sTable[2, ((n2 + KeyData[2]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[2]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[2]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[1]) shr 24] xor sTable[2, ((n1 + KeyData[1]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[1]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[1]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[0]) shr 24] xor sTable[2, ((n2 + KeyData[0]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[0]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[0]) and $FF]);
Pdword(@Outdata)^ := n2;
Pdword(DWORD(@Outdata) + 4)^ := n1;
end;
procedure TGOST.DecryptECB(const Indata; var Outdata);
var
n1, n2: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
n1 := Pdword(@Indata)^;
n2 := Pdword(DWORD(@Indata) + 4)^;
n2 := n2 xor (sTable[3, (n1 + KeyData[0]) shr 24] xor sTable[2, ((n1 + KeyData[0]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[0]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[0]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[1]) shr 24] xor sTable[2, ((n2 + KeyData[1]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[1]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[1]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[2]) shr 24] xor sTable[2, ((n1 + KeyData[2]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[2]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[2]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[3]) shr 24] xor sTable[2, ((n2 + KeyData[3]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[3]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[3]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[4]) shr 24] xor sTable[2, ((n1 + KeyData[4]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[4]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[4]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[5]) shr 24] xor sTable[2, ((n2 + KeyData[5]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[5]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[5]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[6]) shr 24] xor sTable[2, ((n1 + KeyData[6]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[6]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[6]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[7]) shr 24] xor sTable[2, ((n2 + KeyData[7]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[7]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[7]) and $FF]);
for i := 0 to 2 do begin
n2 := n2 xor (sTable[3, (n1 + KeyData[7]) shr 24] xor sTable[2, ((n1 + KeyData[7]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[7]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[7]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[6]) shr 24] xor sTable[2, ((n2 + KeyData[6]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[6]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[6]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[5]) shr 24] xor sTable[2, ((n1 + KeyData[5]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[5]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[5]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[4]) shr 24] xor sTable[2, ((n2 + KeyData[4]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[4]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[4]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[3]) shr 24] xor sTable[2, ((n1 + KeyData[3]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[3]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[3]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[2]) shr 24] xor sTable[2, ((n2 + KeyData[2]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[2]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[2]) and $FF]);
n2 := n2 xor (sTable[3, (n1 + KeyData[1]) shr 24] xor sTable[2, ((n1 + KeyData[1]) shr 16) and $FF]
xor sTable[1, ((n1 + KeyData[1]) shr 8) and $FF] xor sTable[0, (n1 + KeyData[1]) and $FF]);
n1 := n1 xor (sTable[3, (n2 + KeyData[0]) shr 24] xor sTable[2, ((n2 + KeyData[0]) shr 16) and $FF]
xor sTable[1, ((n2 + KeyData[0]) shr 8) and $FF] xor sTable[0, (n2 + KeyData[0]) and $FF]);
end;
Pdword(@Outdata)^ := n2;
Pdword(DWORD(@Outdata) + 4)^ := n1;
end;
destructor TIDEA.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewIDEA;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
{$R-}{$Q-}
function MulInv(x: Word): Word;
var
t0, T1, q, y: Word;
begin
if x <= 1 then begin
Result := x;
Exit;
end;
T1 := DWORD($10001) div x;
y := DWORD($10001) mod x;
if y = 1 then begin
Result := (1 - T1) and $FFFF;
Exit;
end;
t0 := 1;
repeat
q := x div y;
x := x mod y;
t0 := t0 + (q * T1);
if x = 1 then begin
Result := t0;
Exit;
end;
q := y div x;
y := y mod x;
T1 := T1 + (q * t0);
until y = 1;
Result := (1 - T1) and $FFFF;
end;
procedure TIDEA.InitKey(const Key; Size: longword);
var
i: Integer;
begin
Burn;
Size := Size div 8;
FillChar(EK, Sizeof(EK), 0);
Move(Key, EK, Size);
for i := 0 to 7 do
EK[i] := (EK[i] shl 8) or (EK[i] shr 8);
for i := 1 to 5 do begin
EK[(i * 8) + 0] := (EK[((i - 1) * 8) + 1] shl 9) or (EK[((i - 1) * 8) + 2] shr 7);
EK[(i * 8) + 1] := (EK[((i - 1) * 8) + 2] shl 9) or (EK[((i - 1) * 8) + 3] shr 7);
EK[(i * 8) + 2] := (EK[((i - 1) * 8) + 3] shl 9) or (EK[((i - 1) * 8) + 4] shr 7);
EK[(i * 8) + 3] := (EK[((i - 1) * 8) + 4] shl 9) or (EK[((i - 1) * 8) + 5] shr 7);
EK[(i * 8) + 4] := (EK[((i - 1) * 8) + 5] shl 9) or (EK[((i - 1) * 8) + 6] shr 7);
EK[(i * 8) + 5] := (EK[((i - 1) * 8) + 6] shl 9) or (EK[((i - 1) * 8) + 7] shr 7);
EK[(i * 8) + 6] := (EK[((i - 1) * 8) + 7] shl 9) or (EK[((i - 1) * 8) + 0] shr 7);
EK[(i * 8) + 7] := (EK[((i - 1) * 8) + 0] shl 9) or (EK[((i - 1) * 8) + 1] shr 7);
end;
EK[48] := (EK[41] shl 9) or (EK[42] shr 7);
EK[49] := (EK[42] shl 9) or (EK[43] shr 7);
EK[50] := (EK[43] shl 9) or (EK[44] shr 7);
EK[51] := (EK[44] shl 9) or (EK[45] shr 7);
DK[51] := MulInv(EK[3]);
DK[50] := -EK[2];
DK[49] := -EK[1];
DK[48] := MulInv(EK[0]);
for i := 0 to 6 do begin
DK[47 - i * 6] := EK[i * 6 + 5];
DK[46 - i * 6] := EK[i * 6 + 4];
DK[45 - i * 6] := MulInv(EK[i * 6 + 9]);
DK[44 - i * 6] := -EK[i * 6 + 7];
DK[43 - i * 6] := -EK[i * 6 + 8];
DK[42 - i * 6] := MulInv(EK[i * 6 + 6]);
end;
DK[5] := EK[47];
DK[4] := EK[46];
DK[3] := MulInv(EK[51]);
DK[2] := -EK[50];
DK[1] := -EK[49];
DK[0] := MulInv(EK[48]);
end;
procedure TIDEA.Burn;
begin
FillChar(EK, Sizeof(EK), 0);
FillChar(DK, Sizeof(DK), 0);
inherited Burn;
end;
procedure Mul(var x: Word; const y: Word);
var
p: DWORD;
t16: Word;
begin
p := DWORD(x) * y;
if p = 0 then
x := 1 - x - y
else begin
x := p shr 16;
t16 := p and $FFFF;
x := t16 - x;
if (t16 < x) then
Inc(x);
end;
end;
procedure TIDEA.EncryptECB(const Indata; var Outdata);
var
x: array[1..4] of Word;
S3, S2: Word;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Pdword(@x[1])^ := Pdword(@Indata)^;
Pdword(@x[3])^ := Pdword(DWORD(@Indata) + 4)^;
for i := 1 to 4 do
x[i] := (x[i] shl 8) or (x[i] shr 8);
for i := 0 to 7 do begin
Mul(x[1], EK[(i * 6) + 0]);
Inc(x[2], EK[(i * 6) + 1]);
Inc(x[3], EK[(i * 6) + 2]);
Mul(x[4], EK[(i * 6) + 3]);
S3 := x[3];
x[3] := x[3] xor x[1];
Mul(x[3], EK[(i * 6) + 4]);
S2 := x[2];
x[2] := x[2] xor x[4];
Inc(x[2], x[3]);
Mul(x[2], EK[(i * 6) + 5]);
Inc(x[3], x[2]);
x[1] := x[1] xor x[2];
x[4] := x[4] xor x[3];
x[2] := x[2] xor S3;
x[3] := x[3] xor S2;
end;
Mul(x[1], EK[48]);
Inc(x[3], EK[49]);
Inc(x[2], EK[50]);
Mul(x[4], EK[51]);
x[1] := (x[1] shl 8) or (x[1] shr 8);
S2 := (x[3] shl 8) or (x[3] shr 8);
x[3] := (x[2] shl 8) or (x[2] shr 8);
x[4] := (x[4] shl 8) or (x[4] shr 8);
x[2] := S2;
Pdword(@Outdata)^ := Pdword(@x[1])^;
Pdword(DWORD(@Outdata) + 4)^ := Pdword(@x[3])^;
end;
procedure TIDEA.DecryptECB(const Indata; var Outdata);
var
x: array[1..4] of Word;
S3, S2: Word;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Pdword(@x[1])^ := Pdword(@Indata)^;
Pdword(@x[3])^ := Pdword(DWORD(@Indata) + 4)^;
for i := 1 to 4 do
x[i] := (x[i] shl 8) or (x[i] shr 8);
for i := 0 to 7 do begin
Mul(x[1], DK[(i * 6) + 0]);
Inc(x[2], DK[(i * 6) + 1]);
Inc(x[3], DK[(i * 6) + 2]);
Mul(x[4], DK[(i * 6) + 3]);
S3 := x[3];
x[3] := x[3] xor x[1];
Mul(x[3], DK[(i * 6) + 4]);
S2 := x[2];
x[2] := x[2] xor x[4];
Inc(x[2], x[3]);
Mul(x[2], DK[(i * 6) + 5]);
Inc(x[3], x[2]);
x[1] := x[1] xor x[2];
x[4] := x[4] xor x[3];
x[2] := x[2] xor S3;
x[3] := x[3] xor S2;
end;
Mul(x[1], DK[48]);
Inc(x[3], DK[49]);
Inc(x[2], DK[50]);
Mul(x[4], DK[51]);
x[1] := (x[1] shl 8) or (x[1] shr 8);
S2 := (x[3] shl 8) or (x[3] shr 8);
x[3] := (x[2] shl 8) or (x[2] shr 8);
x[4] := (x[4] shl 8) or (x[4] shr 8);
x[2] := S2;
Pdword(@Outdata)^ := Pdword(@x[1])^;
Pdword(DWORD(@Outdata) + 4)^ := Pdword(@x[3])^;
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TMisty1.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewMisty1;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
//{$I DCPmisty1.inc}
function SwapDword(A: DWORD): DWORD;
begin
Result := ((A and $FF) shl 24) or ((A and $FF00) shl 8) or ((A and $FF0000) shr 8) or ((A and $FF000000) shr 24);
end;
function TMisty1.FI(const FI_IN, FI_KEY: DWORD): DWORD;
var
d7, d9: DWORD;
begin
d9 := (FI_IN shr 7) and $1FF;
d7 := FI_IN and $7F;
d9 := S9TABLE[d9] xor d7;
d7 := (S7TABLE[d7] xor d9) and $7F;
d7 := d7 xor ((FI_KEY shr 9) and $7F);
d9 := d9 xor (FI_KEY and $1FF);
d9 := S9TABLE[d9] xor d7;
Result := (d7 shl 9) or d9;
end;
function TMisty1.FO(const FO_IN: DWORD; const k: longword): DWORD;
var
t0, T1: DWORD;
begin
t0 := FO_IN shr 16;
T1 := FO_IN and $FFFF;
t0 := t0 xor KeyData[k];
t0 := FI(t0, KeyData[((k + 5) mod 8) + 8]);
t0 := t0 xor T1;
T1 := T1 xor KeyData[(k + 2) mod 8];
T1 := FI(T1, KeyData[((k + 1) mod 8) + 8]);
T1 := T1 xor t0;
t0 := t0 xor KeyData[(k + 7) mod 8];
t0 := FI(t0, KeyData[((k + 3) mod 8) + 8]);
t0 := t0 xor T1;
T1 := T1 xor KeyData[(k + 4) mod 8];
Result := (T1 shl 16) or t0;
end;
function TMisty1.FL(const FL_IN: DWORD; const k: longword): DWORD;
var
d0, d1: DWORD;
t: byte;
begin
d0 := FL_IN shr 16;
d1 := FL_IN and $FFFF;
if (k mod 2) <> 0 then begin
t := (k - 1) div 2;
d1 := d1 xor (d0 and KeyData[((t + 2) mod 8) + 8]);
d0 := d0 xor (d1 or KeyData[(t + 4) mod 8]);
end
else begin
t := k div 2;
d1 := d1 xor (d0 and KeyData[t]);
d0 := d0 xor (d1 or KeyData[((t + 6) mod 8) + 8]);
end;
Result := (d0 shl 16) or d1;
end;
function TMisty1.FLINV(const FL_IN: DWORD; const k: longword): DWORD;
var
d0, d1: DWORD;
t: byte;
begin
d0 := FL_IN shr 16;
d1 := FL_IN and $FFFF;
if (k mod 2) <> 0 then begin
t := (k - 1) div 2;
d0 := d0 xor (d1 or KeyData[(t + 4) mod 8]);
d1 := d1 xor (d0 and KeyData[((t + 2) mod 8) + 8]);
end
else begin
t := k div 2;
d0 := d0 xor (d1 or KeyData[((t + 6) mod 8) + 8]);
d1 := d1 xor (d0 and KeyData[t]);
end;
Result := (d0 shl 16) or d1;
end;
procedure TMisty1.InitKey(const Key; Size: longword);
var
KeyB: array[0..15] of byte;
i: longword;
begin
Burn;
FillChar(KeyB, Sizeof(KeyB), 0);
Move(Key, KeyB, Size div 8);
for i := 0 to 7 do
KeyData[i] := (KeyB[i * 2] * 256) + KeyB[i * 2 + 1];
for i := 0 to 7 do begin
KeyData[i + 8] := FI(KeyData[i], KeyData[(i + 1) mod 8]);
KeyData[i + 16] := KeyData[i + 8] and $1FF;
KeyData[i + 24] := KeyData[i + 8] shr 9;
end;
end;
procedure TMisty1.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), 0);
inherited Burn;
end;
procedure TMisty1.EncryptECB(const Indata; var Outdata);
var
d0, d1: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
d0 := SwapDword(Pdword(@Indata)^);
d1 := SwapDword(Pdword(longword(@Indata) + 4)^);
for i := 0 to NUMROUNDSMY1 - 1 do begin
if (i mod 2) = 0 then begin
d0 := FL(d0, i);
d1 := FL(d1, i + 1);
d1 := d1 xor FO(d0, i);
end
else
d0 := d0 xor FO(d1, i);
end;
d0 := FL(d0, NUMROUNDSMY1);
d1 := FL(d1, NUMROUNDSMY1 + 1);
Pdword(@Outdata)^ := SwapDword(d1);
Pdword(longword(@Outdata) + 4)^ := SwapDword(d0);
end;
procedure TMisty1.DecryptECB(const Indata; var Outdata);
var
d0, d1: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
d1 := SwapDword(Pdword(@Indata)^);
d0 := SwapDword(Pdword(longword(@Indata) + 4)^);
d1 := FLINV(d1, NUMROUNDSMY1 + 1);
d0 := FLINV(d0, NUMROUNDSMY1);
for i := NUMROUNDSMY1 - 1 downto 0 do begin
if (i mod 2) = 0 then begin
d1 := d1 xor FO(d0, i);
d0 := FLINV(d0, i);
d1 := FLINV(d1, i + 1);
end
else
d0 := d0 xor FO(d1, i);
end;
Pdword(@Outdata)^ := SwapDword(d0);
Pdword(longword(@Outdata) + 4)^ := SwapDword(d1);
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TRC2.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewRC2;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
function LRot16(A, n: Word): Word;
begin
Result := (A shl n) or (A shr (16 - n));
end;
function RRot16(A, n: Word): Word;
begin
Result := (A shr n) or (A shl (16 - n));
end;
procedure TRC2.InitKey(const Key; Size: longword);
var
i: longword;
KeyB: array[0..127] of byte;
begin
Burn;
Move(Key, KeyB, Size div 8);
for i := (Size div 8) to 127 do
KeyB[i] := sBoxRC2[(KeyB[i - (Size div 8)] + KeyB[i - 1]) and $FF];
KeyB[0] := sBoxRC2[KeyB[0]];
Move(KeyB, KeyData, Sizeof(KeyData));
end;
procedure TRC2.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), 0);
inherited Burn;
end;
procedure TRC2.EncryptECB(const Indata; var Outdata);
var
i, j: longword;
w: array[0..3] of Word;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Pdword(@w[0])^ := Pdword(@Indata)^;
Pdword(@w[2])^ := Pdword(longword(@Indata) + 4)^;
for i := 0 to 15 do begin
j := i * 4;
w[0] := LRot16((w[0] + (w[1] and (not w[3])) + (w[2] and w[3]) + KeyData[j + 0]), 1);
w[1] := LRot16((w[1] + (w[2] and (not w[0])) + (w[3] and w[0]) + KeyData[j + 1]), 2);
w[2] := LRot16((w[2] + (w[3] and (not w[1])) + (w[0] and w[1]) + KeyData[j + 2]), 3);
w[3] := LRot16((w[3] + (w[0] and (not w[2])) + (w[1] and w[2]) + KeyData[j + 3]), 5);
if (i = 4) or (i = 10) then begin
w[0] := w[0] + KeyData[w[3] and 63];
w[1] := w[1] + KeyData[w[0] and 63];
w[2] := w[2] + KeyData[w[1] and 63];
w[3] := w[3] + KeyData[w[2] and 63];
end;
end;
Pdword(@Outdata)^ := Pdword(@w[0])^;
Pdword(longword(@Outdata) + 4)^ := Pdword(@w[2])^;
end;
procedure TRC2.DecryptECB(const Indata; var Outdata);
var
i, j: longword;
w: array[0..3] of Word;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Pdword(@w[0])^ := Pdword(@Indata)^;
Pdword(@w[2])^ := Pdword(longword(@Indata) + 4)^;
for i := 15 downto 0 do begin
j := i * 4;
w[3] := RRot16(w[3], 5) - (w[0] and (not w[2])) - (w[1] and w[2]) - KeyData[j + 3];
w[2] := RRot16(w[2], 3) - (w[3] and (not w[1])) - (w[0] and w[1]) - KeyData[j + 2];
w[1] := RRot16(w[1], 2) - (w[2] and (not w[0])) - (w[3] and w[0]) - KeyData[j + 1];
w[0] := RRot16(w[0], 1) - (w[1] and (not w[3])) - (w[2] and w[3]) - KeyData[j + 0];
if (i = 5) or (i = 11) then begin
w[3] := w[3] - KeyData[w[2] and 63];
w[2] := w[2] - KeyData[w[1] and 63];
w[1] := w[1] - KeyData[w[0] and 63];
w[0] := w[0] - KeyData[w[3] and 63];
end;
end;
Pdword(@Outdata)^ := Pdword(@w[0])^;
Pdword(longword(@Outdata) + 4)^ := Pdword(@w[2])^;
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TRC4.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewRC4;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure TRC4.InitKey(const Key; Size: longword; InitVector: pointer);
var
i, j, t: longword;
xKey: array[0..255] of byte;
begin
// if fInitialized then
Burn;
// inherited Init(Key,Size,nil);
Size := Size div 8;
i := 0;
while i < 255 do begin
KeyData[i] := i;
xKey[i] := Pbyte(longword(@Key) + (i mod Size))^;
KeyData[i + 1] := i + 1;
xKey[i + 1] := Pbyte(longword(@Key) + ((i + 1) mod Size))^;
KeyData[i + 2] := i + 2;
xKey[i + 2] := Pbyte(longword(@Key) + ((i + 2) mod Size))^;
KeyData[i + 3] := i + 3;
xKey[i + 3] := Pbyte(longword(@Key) + ((i + 3) mod Size))^;
KeyData[i + 4] := i + 4;
xKey[i + 4] := Pbyte(longword(@Key) + ((i + 4) mod Size))^;
KeyData[i + 5] := i + 5;
xKey[i + 5] := Pbyte(longword(@Key) + ((i + 5) mod Size))^;
KeyData[i + 6] := i + 6;
xKey[i + 6] := Pbyte(longword(@Key) + ((i + 6) mod Size))^;
KeyData[i + 7] := i + 7;
xKey[i + 7] := Pbyte(longword(@Key) + ((i + 7) mod Size))^;
Inc(i, 8);
end;
j := 0;
i := 0;
while i < 255 do begin
j := (j + KeyData[i] + xKey[i]) and $FF;
t := KeyData[i];
KeyData[i] := KeyData[j];
KeyData[j] := t;
j := (j + KeyData[i + 1] + xKey[i + 1]) and $FF;
t := KeyData[i + 1];
KeyData[i + 1] := KeyData[j];
KeyData[j] := t;
j := (j + KeyData[i + 2] + xKey[i + 2]) and $FF;
t := KeyData[i + 2];
KeyData[i + 2] := KeyData[j];
KeyData[j] := t;
j := (j + KeyData[i + 3] + xKey[i + 3]) and $FF;
t := KeyData[i + 3];
KeyData[i + 3] := KeyData[j];
KeyData[j] := t;
j := (j + KeyData[i + 4] + xKey[i + 4]) and $FF;
t := KeyData[i + 4];
KeyData[i + 4] := KeyData[j];
KeyData[j] := t;
j := (j + KeyData[i + 5] + xKey[i + 5]) and $FF;
t := KeyData[i + 5];
KeyData[i + 5] := KeyData[j];
KeyData[j] := t;
j := (j + KeyData[i + 6] + xKey[i + 6]) and $FF;
t := KeyData[i + 6];
KeyData[i + 6] := KeyData[j];
KeyData[j] := t;
j := (j + KeyData[i + 7] + xKey[i + 7]) and $FF;
t := KeyData[i + 7];
KeyData[i + 7] := KeyData[j];
KeyData[j] := t;
Inc(i, 8);
end;
Move(KeyData, KeyOrg, Sizeof(KeyOrg));
end;
procedure TRC4.Reset;
begin
Move(KeyOrg, KeyData, Sizeof(KeyData));
end;
procedure TRC4.Burn;
begin
FillChar(KeyOrg, Sizeof(KeyOrg), $FF);
FillChar(KeyData, Sizeof(KeyData), $FF);
// inherited Burn;
end;
procedure TRC4.Encrypt(const Indata; var Outdata; Size: longword);
var
i, j, t, k: longword;
begin
// if not fInitialized then
// raise EDCP_cipher.Create('Cipher not initialized');
i := 0;
j := 0;
for k := 0 to Size - 1 do begin
i := (i + 1) and $FF;
t := KeyData[i];
j := (j + t) and $FF;
KeyData[i] := KeyData[j];
KeyData[j] := t;
t := (t + KeyData[i]) and $FF;
PByteArray(@Outdata)^[k] := PByteArray(@Indata)^[k] xor KeyData[t];
end;
end;
procedure TRC4.Decrypt(const Indata; var Outdata; Size: longword);
var
i, j, t, k: longword;
begin
// if not fInitialized then
// raise EDCP_cipher.Create('Cipher not initialized');
i := 0;
j := 0;
for k := 0 to Size - 1 do begin
i := (i + 1) and $FF;
t := KeyData[i];
j := (j + t) and $FF;
KeyData[i] := KeyData[j];
KeyData[j] := t;
t := (t + KeyData[i]) and $FF;
PByteArray(@Outdata)^[k] := PByteArray(@Indata)^[k] xor KeyData[t];
end;
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TRC5.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewRC5;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
function RRot32(A, b: longword): longword;
begin
Result := (A shr b) or (A shl (32 - b));
end;
procedure TRC5.InitKey(const Key; Size: longword);
var
xKeyD: array[0..63] of DWORD;
i, j, k, xKeyLen: longword;
A, b: DWORD;
begin
Burn;
FillChar(xKeyD, Sizeof(xKeyD), 0);
Size := Size div 8;
Move(Key, xKeyD, Size);
xKeyLen := Size div 4;
if (Size mod 4) <> 0 then
Inc(xKeyLen);
Move(sBoxRC5, KeyData, (NUMROUNDSRC5 + 1) * 8);
i := 0;
j := 0;
A := 0;
b := 0;
if xKeyLen > ((NUMROUNDSRC5 + 1) * 2) then
k := xKeyLen * 3
else
k := (NUMROUNDSRC5 + 1) * 6;
for k := k downto 1 do begin
A := LRot32(KeyData[i] + A + b, 3);
KeyData[i] := A;
b := LRot32(xKeyD[j] + A + b, A + b);
xKeyD[j] := b;
i := (i + 1) mod ((NUMROUNDSRC5 + 1) * 2);
j := (j + 1) mod xKeyLen;
end;
FillChar(xKeyD, Sizeof(xKeyD), 0);
end;
procedure TRC5.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), $FF);
inherited Burn;
end;
procedure TRC5.EncryptECB(const Indata; var Outdata);
var
A, b: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
A := Pdword(@Indata)^ + KeyData[0];
b := Pdword(longword(@Indata) + 4)^ + KeyData[1];
for i := 1 to NUMROUNDSRC5 do begin
A := A xor b;
A := LRot32(A, b) + KeyData[2 * i];
b := b xor A;
b := LRot32(b, A) + KeyData[(2 * i) + 1];
end;
Pdword(@Outdata)^ := A;
Pdword(longword(@Outdata) + 4)^ := b;
end;
procedure TRC5.DecryptECB(const Indata; var Outdata);
var
A, b: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
A := Pdword(@Indata)^;
b := Pdword(longword(@Indata) + 4)^;
for i := NUMROUNDSRC5 downto 1 do begin
b := RRot32(b - KeyData[(2 * i) + 1], A);
b := b xor A;
A := RRot32(A - KeyData[2 * i], b);
A := A xor b;
end;
Pdword(@Outdata)^ := A - KeyData[0];
Pdword(longword(@Outdata) + 4)^ := b - KeyData[1];
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TTEA.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewTEA;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure TTEA.InitKey(const Key; Size: longword);
begin
Burn;
FillChar(KeyData, Sizeof(KeyData), 0);
Move(Key, KeyData, Size div 8);
KeyData[0] := SwapDword(KeyData[0]);
KeyData[1] := SwapDword(KeyData[1]);
KeyData[2] := SwapDword(KeyData[2]);
KeyData[3] := SwapDword(KeyData[3]);
end;
procedure TTEA.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), 0);
inherited Burn;
end;
procedure TTEA.EncryptECB(const Indata; var Outdata);
var
A, b, c, d, x, y, n, sum: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
x := SwapDword(Pdword(@Indata)^);
y := SwapDword(Pdword(longword(@Indata) + 4)^);
sum := 0;
A := KeyData[0];
b := KeyData[1];
c := KeyData[2];
d := KeyData[3];
for n := 1 to Rounds do begin
Inc(sum, Delta);
Inc(x, (y shl 4) + (A xor y) + (sum xor (y shr 5)) + b);
Inc(y, (x shl 4) + (c xor x) + (sum xor (x shr 5)) + d);
end;
Pdword(@Outdata)^ := SwapDword(x);
Pdword(longword(@Outdata) + 4)^ := SwapDword(y);
end;
procedure TTEA.DecryptECB(const Indata; var Outdata);
var
A, b, c, d, x, y, n, sum: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
x := SwapDword(Pdword(@Indata)^);
y := SwapDword(Pdword(longword(@Indata) + 4)^);
sum := Delta shl 5;
A := KeyData[0];
b := KeyData[1];
c := KeyData[2];
d := KeyData[3];
for n := 1 to Rounds do begin
Dec(y, (x shl 4) + (c xor x) + (sum xor (x shr 5)) + d);
Dec(x, (y shl 4) + (A xor y) + (sum xor (y shr 5)) + b);
Dec(sum, Delta);
end;
Pdword(@Outdata)^ := SwapDword(x);
Pdword(longword(@Outdata) + 4)^ := SwapDword(y);
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TDES.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewDES;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure hperm_op(var A, t: DWORD; n, m: DWORD);
begin
t := ((A shl (16 - n)) xor A) and m;
A := A xor t xor (t shr (16 - n));
end;
procedure perm_op(var A, b, t: DWORD; n, m: DWORD);
begin
t := ((A shr n) xor b) and m;
b := b xor t;
A := A xor (t shl n);
end;
procedure TCustomDES.DoInit(KeyB: PByteArray; KeyData: Pdwordarray);
var
c, d, t, S, T2, i: DWORD;
begin
c := KeyB^[0] or (KeyB^[1] shl 8) or (KeyB^[2] shl 16) or (KeyB^[3] shl 24);
d := KeyB^[4] or (KeyB^[5] shl 8) or (KeyB^[6] shl 16) or (KeyB^[7] shl 24);
perm_op(d, c, t, 4, $0F0F0F0F);
hperm_op(c, t, DWORD(-2), $CCCC0000);
hperm_op(d, t, DWORD(-2), $CCCC0000);
perm_op(d, c, t, 1, $55555555);
perm_op(c, d, t, 8, $00FF00FF);
perm_op(d, c, t, 1, $55555555);
d := ((d and $FF) shl 16) or (d and $FF00) or ((d and $FF0000) shr 16) or
((c and $F0000000) shr 4);
c := c and $FFFFFFF;
for i := 0 to 15 do begin
if shifts2[i] <> 0 then begin
c := ((c shr 2) or (c shl 26));
d := ((d shr 2) or (d shl 26));
end
else begin
c := ((c shr 1) or (c shl 27));
d := ((d shr 1) or (d shl 27));
end;
c := c and $FFFFFFF;
d := d and $FFFFFFF;
S := des_skb[0, c and $3F] or
des_skb[1, ((c shr 6) and $03) or ((c shr 7) and $3C)] or
des_skb[2, ((c shr 13) and $0F) or ((c shr 14) and $30)] or
des_skb[3, ((c shr 20) and $01) or ((c shr 21) and $06) or ((c shr 22) and $38)];
t := des_skb[4, d and $3F] or
des_skb[5, ((d shr 7) and $03) or ((d shr 8) and $3C)] or
des_skb[6, (d shr 15) and $3F] or
des_skb[7, ((d shr 21) and $0F) or ((d shr 22) and $30)];
T2 := ((t shl 16) or (S and $FFFF));
KeyData^[(i shl 1)] := ((T2 shl 2) or (T2 shr 30));
T2 := ((S shr 16) or (t and $FFFF0000));
KeyData^[(i shl 1) + 1] := ((T2 shl 6) or (T2 shr 26));
end;
end;
procedure TCustomDES.EncryptBlock(const Indata; var Outdata; KeyData: Pdwordarray);
var
l, r, t, u: DWORD;
i: longint;
begin
r := Pdword(@Indata)^;
l := Pdword(DWORD(@Indata) + 4)^;
t := ((l shr 4) xor r) and $0F0F0F0F;
r := r xor t;
l := l xor (t shl 4);
t := ((r shr 16) xor l) and $0000FFFF;
l := l xor t;
r := r xor (t shl 16);
t := ((l shr 2) xor r) and $33333333;
r := r xor t;
l := l xor (t shl 2);
t := ((r shr 8) xor l) and $00FF00FF;
l := l xor t;
r := r xor (t shl 8);
t := ((l shr 1) xor r) and $55555555;
r := r xor t;
l := l xor (t shl 1);
r := (r shr 29) or (r shl 3);
l := (l shr 29) or (l shl 3);
i := 0;
while i < 32 do begin
u := r xor KeyData^[i];
t := r xor KeyData^[i + 1];
t := (t shr 4) or (t shl 28);
l := l xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
u := l xor KeyData^[i + 2];
t := l xor KeyData^[i + 3];
t := (t shr 4) or (t shl 28);
r := r xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
u := r xor KeyData^[i + 4];
t := r xor KeyData^[i + 5];
t := (t shr 4) or (t shl 28);
l := l xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
u := l xor KeyData^[i + 6];
t := l xor KeyData^[i + 7];
t := (t shr 4) or (t shl 28);
r := r xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
Inc(i, 8);
end;
r := (r shr 3) or (r shl 29);
l := (l shr 3) or (l shl 29);
t := ((r shr 1) xor l) and $55555555;
l := l xor t;
r := r xor (t shl 1);
t := ((l shr 8) xor r) and $00FF00FF;
r := r xor t;
l := l xor (t shl 8);
t := ((r shr 2) xor l) and $33333333;
l := l xor t;
r := r xor (t shl 2);
t := ((l shr 16) xor r) and $0000FFFF;
r := r xor t;
l := l xor (t shl 16);
t := ((r shr 4) xor l) and $0F0F0F0F;
l := l xor t;
r := r xor (t shl 4);
Pdword(@Outdata)^ := l;
Pdword(DWORD(@Outdata) + 4)^ := r;
end;
procedure TCustomDES.DecryptBlock(const Indata; var Outdata; KeyData: Pdwordarray);
var
l, r, t, u: DWORD;
i: longint;
begin
r := Pdword(@Indata)^;
l := Pdword(DWORD(@Indata) + 4)^;
t := ((l shr 4) xor r) and $0F0F0F0F;
r := r xor t;
l := l xor (t shl 4);
t := ((r shr 16) xor l) and $0000FFFF;
l := l xor t;
r := r xor (t shl 16);
t := ((l shr 2) xor r) and $33333333;
r := r xor t;
l := l xor (t shl 2);
t := ((r shr 8) xor l) and $00FF00FF;
l := l xor t;
r := r xor (t shl 8);
t := ((l shr 1) xor r) and $55555555;
r := r xor t;
l := l xor (t shl 1);
r := (r shr 29) or (r shl 3);
l := (l shr 29) or (l shl 3);
i := 30;
while i > 0 do begin
u := r xor KeyData^[i];
t := r xor KeyData^[i + 1];
t := (t shr 4) or (t shl 28);
l := l xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
u := l xor KeyData^[i - 2];
t := l xor KeyData^[i - 1];
t := (t shr 4) or (t shl 28);
r := r xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
u := r xor KeyData^[i - 4];
t := r xor KeyData^[i - 3];
t := (t shr 4) or (t shl 28);
l := l xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
u := l xor KeyData^[i - 6];
t := l xor KeyData^[i - 5];
t := (t shr 4) or (t shl 28);
r := r xor des_sptrans[0, (u shr 2) and $3F] xor
des_sptrans[2, (u shr 10) and $3F] xor
des_sptrans[4, (u shr 18) and $3F] xor
des_sptrans[6, (u shr 26) and $3F] xor
des_sptrans[1, (t shr 2) and $3F] xor
des_sptrans[3, (t shr 10) and $3F] xor
des_sptrans[5, (t shr 18) and $3F] xor
des_sptrans[7, (t shr 26) and $3F];
Dec(i, 8);
end;
r := (r shr 3) or (r shl 29);
l := (l shr 3) or (l shl 29);
t := ((r shr 1) xor l) and $55555555;
l := l xor t;
r := r xor (t shl 1);
t := ((l shr 8) xor r) and $00FF00FF;
r := r xor t;
l := l xor (t shl 8);
t := ((r shr 2) xor l) and $33333333;
l := l xor t;
r := r xor (t shl 2);
t := ((l shr 16) xor r) and $0000FFFF;
r := r xor t;
l := l xor (t shl 16);
t := ((r shr 4) xor l) and $0F0F0F0F;
l := l xor t;
r := r xor (t shl 4);
Pdword(@Outdata)^ := l;
Pdword(DWORD(@Outdata) + 4)^ := r;
end;
procedure TDES.InitKey(const Key; Size: longword);
var
KeyB: array[0..7] of byte;
begin
Burn;
FillChar(KeyB, Sizeof(KeyB), 0);
Move(Key, KeyB, Size div 8);
DoInit(@KeyB, @KeyData);
end;
procedure TDES.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), 0);
inherited Burn;
end;
procedure TDES.EncryptECB(const Indata; var Outdata);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
EncryptBlock(Indata, Outdata, @KeyData);
end;
procedure TDES.DecryptECB(const Indata; var Outdata);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
DecryptBlock(Indata, Outdata, @KeyData);
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor T3DES.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function New3DES;
begin
New(Result, Create);
//burn;
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure T3DES.InitKey(const Key; Size: longword);
var
KeyB: array[0..2, 0..7] of byte;
begin
Burn;
FillChar(KeyB, Sizeof(KeyB), 0);
Move(Key, KeyB, Size div 8);
DoInit(@KeyB[0], @KeyData[0]);
DoInit(@KeyB[1], @KeyData[1]);
if Size > 128 then
DoInit(@KeyB[2], @KeyData[2])
else
Move(KeyData[0], KeyData[2], 128);
end;
procedure T3DES.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), 0);
inherited Burn;
end;
procedure T3DES.EncryptECB(const Indata; var Outdata);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
EncryptBlock(Indata, Outdata, @KeyData[0]);
DecryptBlock(Outdata, Outdata, @KeyData[1]);
EncryptBlock(Outdata, Outdata, @KeyData[2]);
end;
procedure T3DES.DecryptECB(const Indata; var Outdata);
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
DecryptBlock(Indata, Outdata, @KeyData[2]);
EncryptBlock(Outdata, Outdata, @KeyData[1]);
DecryptBlock(Outdata, Outdata, @KeyData[0]);
end;
var
ice_sbox: array[0..3, 0..1023] of DWORD;
ice_sboxdone: Boolean;
const
ice_smod: array[0..3, 0..3] of DWORD = (
(333, 313, 505, 369),
(379, 375, 319, 391),
(361, 445, 451, 397),
(397, 425, 395, 505));
ice_sxor: array[0..3, 0..3] of DWORD = (
($83, $85, $9B, $CD),
($CC, $A7, $AD, $41),
($4B, $2E, $D4, $33),
($EA, $CB, $2E, $04));
ice_keyrot: array[0..15] of DWORD = (
0, 1, 2, 3, 2, 1, 3, 0,
1, 3, 2, 0, 3, 1, 0, 2);
ice_pbox: array[0..31] of DWORD = (
$00000001, $00000080, $00000400, $00002000,
$00080000, $00200000, $01000000, $40000000,
$00000008, $00000020, $00000100, $00004000,
$00010000, $00800000, $04000000, $20000000,
$00000004, $00000010, $00000200, $00008000,
$00020000, $00400000, $08000000, $10000000,
$00000002, $00000040, $00000800, $00001000,
$00040000, $00100000, $02000000, $80000000);
{******************************************************************************}
function gf_mult(A, b, m: DWORD): DWORD;
var
res: DWORD;
begin
res := 0;
while b <> 0 do begin
if (b and 1) <> 0 then
res := res xor A;
A := A shl 1;
b := b shr 1;
if A >= 256 then
A := A xor m;
end;
Result := res;
end;
function gf_exp7(b, m: DWORD): DWORD;
var
x: DWORD;
begin
if b = 0 then
Result := 0
else begin
x := gf_mult(b, b, m);
x := gf_mult(b, x, m);
x := gf_mult(x, x, m);
Result := gf_mult(b, x, m);
end;
end;
function ice_perm32(x: DWORD): DWORD;
var
res: DWORD;
PBox: Pdword;
begin
res := 0;
PBox := @ice_pbox;
while x <> 0 do begin
if (x and 1) <> 0 then
res := res or PBox^;
Inc(PBox);
x := x shr 1;
end;
Result := res;
end;
procedure ice_sboxes_init;
var
i, col, row: DWORD;
x: DWORD;
begin
for i := 0 to 1023 do begin
col := (i shr 1) and $FF;
row := (i and 1) or ((i and $200) shr 8);
x := gf_exp7(col xor ice_sxor[0, row], ice_smod[0, row]) shl 24;
ice_sbox[0, i] := ice_perm32(x);
x := gf_exp7(col xor ice_sxor[1, row], ice_smod[1, row]) shl 16;
ice_sbox[1, i] := ice_perm32(x);
x := gf_exp7(col xor ice_sxor[2, row], ice_smod[2, row]) shl 8;
ice_sbox[2, i] := ice_perm32(x);
x := gf_exp7(col xor ice_sxor[3, row], ice_smod[3, row]);
ice_sbox[3, i] := ice_perm32(x);
end;
end;
function TCustomICE.f(p, sk: DWORD): DWORD;
var
tl, tr, al, ar: DWORD;
begin
tl := ((p shr 16) and $3FF) or (((p shr 14) or (p shl 18)) and $FFC00);
tr := (p and $3FF) or ((p shl 2) and $FFC00);
al := ik_keysched[sk, 2] and (tl xor tr);
ar := al xor tr;
al := al xor tl;
al := al xor ik_keysched[sk, 0];
ar := ar xor ik_keysched[sk, 1];
Result := ice_sbox[0, al shr 10] or ice_sbox[1, al and $3FF] or
ice_sbox[2, ar shr 10] or ice_sbox[3, ar and $3FF];
end;
procedure TCustomICE.key_sched_build(kb: Pwordarray; n: DWORD; keyrot: Pdwordarray);
var
i, j, k, Kr: DWORD;
keys: Pdwordarray;
currentsk: Pdword;
currentkb: pword;
bit: DWORD;
begin
for i := 0 to 7 do begin
Kr := keyrot^[i];
keys := @ik_keysched[n + i];
for j := 0 to 2 do
keys^[j] := 0;
for j := 0 to 14 do begin
currentsk := @keys^[j mod 3];
for k := 0 to 3 do begin
currentkb := @kb^[(Kr + k) and 3];
bit := currentkb^ and 1;
currentsk^ := (currentsk^ shl 1) or bit;
currentkb^ := (currentkb^ shr 1) or ((bit xor 1) shl 15);
end;
end;
end;
end;
procedure TCustomICE.InitIce(const Key; Size: longword; n: DWORD);
var
i, j: DWORD;
kb: array[0..3] of Word;
KeyB: array[0..15] of byte;
begin
FillChar(KeyB, Sizeof(KeyB), 0);
Move(Key, KeyB, Size div 8);
if n > 0 then
Rounds := 16 * n
else
Rounds := 8;
if Rounds = 8 then begin
for i := 0 to 4 do
kb[3 - i] := (KeyB[i * 2] shl 8) or KeyB[i * 2 + 1];
key_sched_build(@kb, 0, @ice_keyrot);
end
else begin
for i := 0 to (n - 1) do begin
for j := 0 to 3 do
kb[3 - j] := (KeyB[i * 8 + j * 2] shl 8) or KeyB[i * 8 + j * 2 + 1];
key_sched_build(@kb, i * 8, @ice_keyrot);
key_sched_build(@kb, Rounds - 8 - i * 8, @ice_keyrot[8]);
end;
end;
end;
procedure TCustomICE.Burn;
begin
FillChar(ik_keysched, Sizeof(ik_keysched), 0);
Rounds := 0;
inherited Burn;
end;
procedure TCustomICE.EncryptECB(const Indata; var Outdata);
var
i, l, r: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
l := SwapDword(Pdword(@Indata)^);
r := SwapDword(Pdword(longword(@Indata) + 4)^);
i := 0;
while i < Rounds do begin
l := l xor f(r, i);
r := r xor f(l, i + 1);
Inc(i, 2);
end;
Pdword(@Outdata)^ := SwapDword(r);
Pdword(longword(@Outdata) + 4)^ := SwapDword(l);
end;
procedure TCustomICE.DecryptECB(const Indata; var Outdata);
var
l, r: DWORD;
i: Integer;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
l := SwapDword(Pdword(@Indata)^);
r := SwapDword(Pdword(longword(@Indata) + 4)^);
i := Rounds - 1;
while i > 0 do begin
l := l xor f(r, i);
r := r xor f(l, i - 1);
Dec(i, 2);
end;
Pdword(@Outdata)^ := SwapDword(r);
Pdword(longword(@Outdata) + 4)^ := SwapDword(l);
end;
destructor TICE.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewICE;
begin
New(Result, Create);
if not ice_sboxdone then begin
ice_sboxes_init;
ice_sboxdone := True;
end;
// code
end;
destructor TICE2.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TICE.InitKey(const Key; Size: longword);
begin
Burn;
InitIce(Key, Size, 1);
end;
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewICE2;
begin
New(Result, Create);
if not ice_sboxdone then begin
ice_sboxes_init;
ice_sboxdone := True;
end;
// code
end;
destructor TThinIce.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
procedure TICE2.InitKey(const Key; Size: longword);
begin
Burn;
InitIce(Key, Size, 2);
end;
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewThinICE;
begin
New(Result, Create);
if not ice_sboxdone then begin
ice_sboxes_init;
ice_sboxdone := True;
end;
// code
end;
procedure TThinIce.InitKey(const Key; Size: longword);
begin
Burn;
InitIce(Key, Size, 0);
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TCast256.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewCast256;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
function F1(A, rk, mk: DWORD): DWORD;
var
t: DWORD;
begin
t := LRot32(mk + A, rk);
Result := ((S1[t shr 24] xor S2[(t shr 16) and $FF]) - S3[(t shr 8) and $FF]) + S4[t and $FF];
end;
function F2(A, rk, mk: DWORD): DWORD;
var
t: DWORD;
begin
t := LRot32(mk xor A, rk);
Result := ((S1[t shr 24] - S2[(t shr 16) and $FF]) + S3[(t shr 8) and $FF]) xor S4[t and $FF];
end;
function F3(A, rk, mk: DWORD): DWORD;
var
t: DWORD;
begin
t := LRot32(mk - A, rk);
Result := ((S1[t shr 24] + S2[(t shr 16) and $FF]) xor S3[(t shr 8) and $FF]) - S4[t and $FF];
end;
procedure TCast256.InitKey(const Key; Size: longword);
var
x: array[0..7] of DWORD;
cm, cr: DWORD;
i, j: longword;
tr, tm: array[0..7] of DWORD;
begin
Burn;
Size := Size div 8;
FillChar(x, Sizeof(x), 0);
Move(Key, x, Size);
cm := $5A827999;
cr := 19;
for i := 0 to 7 do
x[i] := (x[i] shl 24) or ((x[i] shl 8) and $FF0000) or ((x[i] shr 8) and $FF00) or (x[i] shr 24);
for i := 0 to 11 do begin
for j := 0 to 7 do begin
tm[j] := cm;
Inc(cm, $6ED9EBA1);
tr[j] := cr;
Inc(cr, 17);
end;
x[6] := x[6] xor F1(x[7], tr[0], tm[0]);
x[5] := x[5] xor F2(x[6], tr[1], tm[1]);
x[4] := x[4] xor F3(x[5], tr[2], tm[2]);
x[3] := x[3] xor F1(x[4], tr[3], tm[3]);
x[2] := x[2] xor F2(x[3], tr[4], tm[4]);
x[1] := x[1] xor F3(x[2], tr[5], tm[5]);
x[0] := x[0] xor F1(x[1], tr[6], tm[6]);
x[7] := x[7] xor F2(x[0], tr[7], tm[7]);
for j := 0 to 7 do begin
tm[j] := cm;
Inc(cm, $6ED9EBA1);
tr[j] := cr;
Inc(cr, 17);
end;
x[6] := x[6] xor F1(x[7], tr[0], tm[0]);
x[5] := x[5] xor F2(x[6], tr[1], tm[1]);
x[4] := x[4] xor F3(x[5], tr[2], tm[2]);
x[3] := x[3] xor F1(x[4], tr[3], tm[3]);
x[2] := x[2] xor F2(x[3], tr[4], tm[4]);
x[1] := x[1] xor F3(x[2], tr[5], tm[5]);
x[0] := x[0] xor F1(x[1], tr[6], tm[6]);
x[7] := x[7] xor F2(x[0], tr[7], tm[7]);
Kr[i, 0] := x[0] and 31;
Kr[i, 1] := x[2] and 31;
Kr[i, 2] := x[4] and 31;
Kr[i, 3] := x[6] and 31;
Km[i, 0] := x[7];
Km[i, 1] := x[5];
Km[i, 2] := x[3];
Km[i, 3] := x[1];
end;
FillChar(x, Sizeof(x), $FF);
end;
procedure TCast256.Burn;
begin
FillChar(Kr, Sizeof(Kr), $FF);
FillChar(Km, Sizeof(Km), $FF);
inherited Burn;
end;
procedure TCast256.EncryptECB(const Indata; var Outdata);
var
A: array[0..3] of DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
A[0] := Pdword(@Indata)^;
A[1] := Pdword(longword(@Indata) + 4)^;
A[2] := Pdword(longword(@Indata) + 8)^;
A[3] := Pdword(longword(@Indata) + 12)^;
A[0] := SwapDword(A[0]);
A[1] := SwapDword(A[1]);
A[2] := SwapDword(A[2]);
A[3] := SwapDword(A[3]);
A[2] := A[2] xor F1(A[3], Kr[0, 0], Km[0, 0]);
A[1] := A[1] xor F2(A[2], Kr[0, 1], Km[0, 1]);
A[0] := A[0] xor F3(A[1], Kr[0, 2], Km[0, 2]);
A[3] := A[3] xor F1(A[0], Kr[0, 3], Km[0, 3]);
A[2] := A[2] xor F1(A[3], Kr[1, 0], Km[1, 0]);
A[1] := A[1] xor F2(A[2], Kr[1, 1], Km[1, 1]);
A[0] := A[0] xor F3(A[1], Kr[1, 2], Km[1, 2]);
A[3] := A[3] xor F1(A[0], Kr[1, 3], Km[1, 3]);
A[2] := A[2] xor F1(A[3], Kr[2, 0], Km[2, 0]);
A[1] := A[1] xor F2(A[2], Kr[2, 1], Km[2, 1]);
A[0] := A[0] xor F3(A[1], Kr[2, 2], Km[2, 2]);
A[3] := A[3] xor F1(A[0], Kr[2, 3], Km[2, 3]);
A[2] := A[2] xor F1(A[3], Kr[3, 0], Km[3, 0]);
A[1] := A[1] xor F2(A[2], Kr[3, 1], Km[3, 1]);
A[0] := A[0] xor F3(A[1], Kr[3, 2], Km[3, 2]);
A[3] := A[3] xor F1(A[0], Kr[3, 3], Km[3, 3]);
A[2] := A[2] xor F1(A[3], Kr[4, 0], Km[4, 0]);
A[1] := A[1] xor F2(A[2], Kr[4, 1], Km[4, 1]);
A[0] := A[0] xor F3(A[1], Kr[4, 2], Km[4, 2]);
A[3] := A[3] xor F1(A[0], Kr[4, 3], Km[4, 3]);
A[2] := A[2] xor F1(A[3], Kr[5, 0], Km[5, 0]);
A[1] := A[1] xor F2(A[2], Kr[5, 1], Km[5, 1]);
A[0] := A[0] xor F3(A[1], Kr[5, 2], Km[5, 2]);
A[3] := A[3] xor F1(A[0], Kr[5, 3], Km[5, 3]);
A[3] := A[3] xor F1(A[0], Kr[6, 3], Km[6, 3]);
A[0] := A[0] xor F3(A[1], Kr[6, 2], Km[6, 2]);
A[1] := A[1] xor F2(A[2], Kr[6, 1], Km[6, 1]);
A[2] := A[2] xor F1(A[3], Kr[6, 0], Km[6, 0]);
A[3] := A[3] xor F1(A[0], Kr[7, 3], Km[7, 3]);
A[0] := A[0] xor F3(A[1], Kr[7, 2], Km[7, 2]);
A[1] := A[1] xor F2(A[2], Kr[7, 1], Km[7, 1]);
A[2] := A[2] xor F1(A[3], Kr[7, 0], Km[7, 0]);
A[3] := A[3] xor F1(A[0], Kr[8, 3], Km[8, 3]);
A[0] := A[0] xor F3(A[1], Kr[8, 2], Km[8, 2]);
A[1] := A[1] xor F2(A[2], Kr[8, 1], Km[8, 1]);
A[2] := A[2] xor F1(A[3], Kr[8, 0], Km[8, 0]);
A[3] := A[3] xor F1(A[0], Kr[9, 3], Km[9, 3]);
A[0] := A[0] xor F3(A[1], Kr[9, 2], Km[9, 2]);
A[1] := A[1] xor F2(A[2], Kr[9, 1], Km[9, 1]);
A[2] := A[2] xor F1(A[3], Kr[9, 0], Km[9, 0]);
A[3] := A[3] xor F1(A[0], Kr[10, 3], Km[10, 3]);
A[0] := A[0] xor F3(A[1], Kr[10, 2], Km[10, 2]);
A[1] := A[1] xor F2(A[2], Kr[10, 1], Km[10, 1]);
A[2] := A[2] xor F1(A[3], Kr[10, 0], Km[10, 0]);
A[3] := A[3] xor F1(A[0], Kr[11, 3], Km[11, 3]);
A[0] := A[0] xor F3(A[1], Kr[11, 2], Km[11, 2]);
A[1] := A[1] xor F2(A[2], Kr[11, 1], Km[11, 1]);
A[2] := A[2] xor F1(A[3], Kr[11, 0], Km[11, 0]);
A[0] := SwapDword(A[0]);
A[1] := SwapDword(A[1]);
A[2] := SwapDword(A[2]);
A[3] := SwapDword(A[3]);
Pdword(@Outdata)^ := A[0];
Pdword(longword(@Outdata) + 4)^ := A[1];
Pdword(longword(@Outdata) + 8)^ := A[2];
Pdword(longword(@Outdata) + 12)^ := A[3];
end;
procedure TCast256.DecryptECB(const Indata; var Outdata);
var
A: array[0..3] of DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
A[0] := Pdword(@Indata)^;
A[1] := Pdword(longword(@Indata) + 4)^;
A[2] := Pdword(longword(@Indata) + 8)^;
A[3] := Pdword(longword(@Indata) + 12)^;
A[0] := SwapDword(A[0]);
A[1] := SwapDword(A[1]);
A[2] := SwapDword(A[2]);
A[3] := SwapDword(A[3]);
A[2] := A[2] xor F1(A[3], Kr[11, 0], Km[11, 0]);
A[1] := A[1] xor F2(A[2], Kr[11, 1], Km[11, 1]);
A[0] := A[0] xor F3(A[1], Kr[11, 2], Km[11, 2]);
A[3] := A[3] xor F1(A[0], Kr[11, 3], Km[11, 3]);
A[2] := A[2] xor F1(A[3], Kr[10, 0], Km[10, 0]);
A[1] := A[1] xor F2(A[2], Kr[10, 1], Km[10, 1]);
A[0] := A[0] xor F3(A[1], Kr[10, 2], Km[10, 2]);
A[3] := A[3] xor F1(A[0], Kr[10, 3], Km[10, 3]);
A[2] := A[2] xor F1(A[3], Kr[9, 0], Km[9, 0]);
A[1] := A[1] xor F2(A[2], Kr[9, 1], Km[9, 1]);
A[0] := A[0] xor F3(A[1], Kr[9, 2], Km[9, 2]);
A[3] := A[3] xor F1(A[0], Kr[9, 3], Km[9, 3]);
A[2] := A[2] xor F1(A[3], Kr[8, 0], Km[8, 0]);
A[1] := A[1] xor F2(A[2], Kr[8, 1], Km[8, 1]);
A[0] := A[0] xor F3(A[1], Kr[8, 2], Km[8, 2]);
A[3] := A[3] xor F1(A[0], Kr[8, 3], Km[8, 3]);
A[2] := A[2] xor F1(A[3], Kr[7, 0], Km[7, 0]);
A[1] := A[1] xor F2(A[2], Kr[7, 1], Km[7, 1]);
A[0] := A[0] xor F3(A[1], Kr[7, 2], Km[7, 2]);
A[3] := A[3] xor F1(A[0], Kr[7, 3], Km[7, 3]);
A[2] := A[2] xor F1(A[3], Kr[6, 0], Km[6, 0]);
A[1] := A[1] xor F2(A[2], Kr[6, 1], Km[6, 1]);
A[0] := A[0] xor F3(A[1], Kr[6, 2], Km[6, 2]);
A[3] := A[3] xor F1(A[0], Kr[6, 3], Km[6, 3]);
A[3] := A[3] xor F1(A[0], Kr[5, 3], Km[5, 3]);
A[0] := A[0] xor F3(A[1], Kr[5, 2], Km[5, 2]);
A[1] := A[1] xor F2(A[2], Kr[5, 1], Km[5, 1]);
A[2] := A[2] xor F1(A[3], Kr[5, 0], Km[5, 0]);
A[3] := A[3] xor F1(A[0], Kr[4, 3], Km[4, 3]);
A[0] := A[0] xor F3(A[1], Kr[4, 2], Km[4, 2]);
A[1] := A[1] xor F2(A[2], Kr[4, 1], Km[4, 1]);
A[2] := A[2] xor F1(A[3], Kr[4, 0], Km[4, 0]);
A[3] := A[3] xor F1(A[0], Kr[3, 3], Km[3, 3]);
A[0] := A[0] xor F3(A[1], Kr[3, 2], Km[3, 2]);
A[1] := A[1] xor F2(A[2], Kr[3, 1], Km[3, 1]);
A[2] := A[2] xor F1(A[3], Kr[3, 0], Km[3, 0]);
A[3] := A[3] xor F1(A[0], Kr[2, 3], Km[2, 3]);
A[0] := A[0] xor F3(A[1], Kr[2, 2], Km[2, 2]);
A[1] := A[1] xor F2(A[2], Kr[2, 1], Km[2, 1]);
A[2] := A[2] xor F1(A[3], Kr[2, 0], Km[2, 0]);
A[3] := A[3] xor F1(A[0], Kr[1, 3], Km[1, 3]);
A[0] := A[0] xor F3(A[1], Kr[1, 2], Km[1, 2]);
A[1] := A[1] xor F2(A[2], Kr[1, 1], Km[1, 1]);
A[2] := A[2] xor F1(A[3], Kr[1, 0], Km[1, 0]);
A[3] := A[3] xor F1(A[0], Kr[0, 3], Km[0, 3]);
A[0] := A[0] xor F3(A[1], Kr[0, 2], Km[0, 2]);
A[1] := A[1] xor F2(A[2], Kr[0, 1], Km[0, 1]);
A[2] := A[2] xor F1(A[3], Kr[0, 0], Km[0, 0]);
A[0] := SwapDword(A[0]);
A[1] := SwapDword(A[1]);
A[2] := SwapDword(A[2]);
A[3] := SwapDword(A[3]);
Pdword(@Outdata)^ := A[0];
Pdword(longword(@Outdata) + 4)^ := A[1];
Pdword(longword(@Outdata) + 8)^ := A[2];
Pdword(longword(@Outdata) + 12)^ := A[3];
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TMars.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewMars;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure gen_mask(var x, m: DWORD);
var
u: DWORD;
begin
u := x and (x shr 1);
u := u and (u shr 2);
u := u and (u shr 4);
u := u and (u shr 1) and (u shr 2);
m := u;
u := (x xor $FFFFFFFF) and ((x xor $FFFFFFFF) shr 1);
u := u and (u shr 2);
u := u and (u shr 4);
u := u and (u shr 1) and (u shr 2);
u := u or m;
m := (u shl 1) or (u shl 2) or (u shl 3)
or (u shl 4) or (u shl 5) or (u shl 6)
or (u shl 7) or (u shl 8);
m := (m or u or (u shl 9)) and ((x xor $FFFFFFFF) xor (x shl 1)) and ((x xor $FFFFFFFF) xor (x shr 1));
m := m and $FFFFFFFC;
end;
procedure TMars.InitKey(const Key; Size: longword);
var
i, j, m, u, w: DWORD;
t: array[-7..39] of DWORD;
KeyB: array[0..39] of DWORD;
begin
Burn;
Size := Size div 8;
FillChar(KeyB, Sizeof(KeyB), 0);
Move(Key, KeyB, Size);
Size := Size div 4;
Move(vk, t, Sizeof(vk));
for i := 0 to 38 do begin
u := t[i - 7] xor t[i - 2];
t[i] := LRot32(u, 3) xor KeyB[i mod DWORD(Size)] xor i;
end;
t[39] := Size;
for j := 0 to 6 do begin
for i := 1 to 39 do begin
u := t[i] + S_Box[t[i - 1] and $1FF];
t[i] := LRot32(u, 9);
end;
u := t[0] + S_Box[t[39] and $1FF];
t[0] := LRot32(u, 9);
end;
for i := 0 to 39 do
KeyData[(7 * i) mod 40] := t[i];
i := 5;
repeat
u := S_Box[265 + (KeyData[i] and $3)];
j := KeyData[i + 3] and $1F;
w := KeyData[i] or $3;
gen_mask(w, m);
KeyData[i] := w xor (LRot32(u, j) and m);
Inc(i, 2);
until i >= 37;
end;
procedure TMars.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), $FF);
inherited Burn;
end;
procedure TMars.EncryptECB(const Indata; var Outdata);
var
l, m, r, t: DWORD;
blk: array[0..3] of DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
blk[0] := Pdword(@Indata)^;
blk[1] := Pdword(longword(@Indata) + 4)^;
blk[2] := Pdword(longword(@Indata) + 8)^;
blk[3] := Pdword(longword(@Indata) + 12)^;
blk[0] := blk[0] + KeyData[0];
blk[1] := blk[1] + KeyData[1];
blk[2] := blk[2] + KeyData[2];
blk[3] := blk[3] + KeyData[3];
blk[1] := blk[1] xor S_Box[blk[0] and $FF];
blk[1] := blk[1] + S_Box[((blk[0] shr 8) and $FF) + 256];
blk[2] := blk[2] + S_Box[(blk[0] shr 16) and $FF];
blk[3] := blk[3] xor S_Box[((blk[0] shr 24) and $FF) + 256];
blk[0] := RRot32(blk[0], 24);
blk[0] := blk[0] + blk[3];
blk[2] := blk[2] xor S_Box[blk[1] and $FF];
blk[2] := blk[2] + S_Box[((blk[1] shr 8) and $FF) + 256];
blk[3] := blk[3] + S_Box[(blk[1] shr 16) and $FF];
blk[0] := blk[0] xor S_Box[((blk[1] shr 24) and $FF) + 256];
blk[1] := RRot32(blk[1], 24);
blk[1] := blk[1] + blk[2];
blk[3] := blk[3] xor S_Box[blk[2] and $FF];
blk[3] := blk[3] + S_Box[((blk[2] shr 8) and $FF) + 256];
blk[0] := blk[0] + S_Box[(blk[2] shr 16) and $FF];
blk[1] := blk[1] xor S_Box[((blk[2] shr 24) and $FF) + 256];
blk[2] := RRot32(blk[2], 24);
blk[0] := blk[0] xor S_Box[blk[3] and $FF];
blk[0] := blk[0] + S_Box[((blk[3] shr 8) and $FF) + 256];
blk[1] := blk[1] + S_Box[(blk[3] shr 16) and $FF];
blk[2] := blk[2] xor S_Box[((blk[3] shr 24) and $FF) + 256];
blk[3] := RRot32(blk[3], 24);
blk[1] := blk[1] xor S_Box[blk[0] and $FF];
blk[1] := blk[1] + S_Box[((blk[0] shr 8) and $FF) + 256];
blk[2] := blk[2] + S_Box[(blk[0] shr 16) and $FF];
blk[3] := blk[3] xor S_Box[((blk[0] shr 24) and $FF) + 256];
blk[0] := RRot32(blk[0], 24);
blk[0] := blk[0] + blk[3];
blk[2] := blk[2] xor S_Box[blk[1] and $FF];
blk[2] := blk[2] + S_Box[((blk[1] shr 8) and $FF) + 256];
blk[3] := blk[3] + S_Box[(blk[1] shr 16) and $FF];
blk[0] := blk[0] xor S_Box[((blk[1] shr 24) and $FF) + 256];
blk[1] := RRot32(blk[1], 24);
blk[1] := blk[1] + blk[2];
blk[3] := blk[3] xor S_Box[blk[2] and $FF];
blk[3] := blk[3] + S_Box[((blk[2] shr 8) and $FF) + 256];
blk[0] := blk[0] + S_Box[(blk[2] shr 16) and $FF];
blk[1] := blk[1] xor S_Box[((blk[2] shr 24) and $FF) + 256];
blk[2] := RRot32(blk[2], 24);
blk[0] := blk[0] xor S_Box[blk[3] and $FF];
blk[0] := blk[0] + S_Box[((blk[3] shr 8) and $FF) + 256];
blk[1] := blk[1] + S_Box[(blk[3] shr 16) and $FF];
blk[2] := blk[2] xor S_Box[((blk[3] shr 24) and $FF) + 256];
blk[3] := RRot32(blk[3], 24);
m := blk[0] + KeyData[4];
r := LRot32(blk[0], 13) * KeyData[5];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := LRot32(blk[0], 13);
blk[1] := blk[1] + l;
blk[2] := blk[2] + m;
blk[3] := blk[3] xor r;
m := blk[1] + KeyData[6];
r := LRot32(blk[1], 13) * KeyData[7];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := LRot32(blk[1], 13);
blk[2] := blk[2] + l;
blk[3] := blk[3] + m;
blk[0] := blk[0] xor r;
m := blk[2] + KeyData[8];
r := LRot32(blk[2], 13) * KeyData[9];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := LRot32(blk[2], 13);
blk[3] := blk[3] + l;
blk[0] := blk[0] + m;
blk[1] := blk[1] xor r;
m := blk[3] + KeyData[10];
r := LRot32(blk[3], 13) * KeyData[11];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := LRot32(blk[3], 13);
blk[0] := blk[0] + l;
blk[1] := blk[1] + m;
blk[2] := blk[2] xor r;
m := blk[0] + KeyData[12];
r := LRot32(blk[0], 13) * KeyData[13];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := LRot32(blk[0], 13);
blk[1] := blk[1] + l;
blk[2] := blk[2] + m;
blk[3] := blk[3] xor r;
m := blk[1] + KeyData[14];
r := LRot32(blk[1], 13) * KeyData[15];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := LRot32(blk[1], 13);
blk[2] := blk[2] + l;
blk[3] := blk[3] + m;
blk[0] := blk[0] xor r;
m := blk[2] + KeyData[16];
r := LRot32(blk[2], 13) * KeyData[17];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := LRot32(blk[2], 13);
blk[3] := blk[3] + l;
blk[0] := blk[0] + m;
blk[1] := blk[1] xor r;
m := blk[3] + KeyData[18];
r := LRot32(blk[3], 13) * KeyData[19];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := LRot32(blk[3], 13);
blk[0] := blk[0] + l;
blk[1] := blk[1] + m;
blk[2] := blk[2] xor r;
m := blk[0] + KeyData[20];
r := LRot32(blk[0], 13) * KeyData[21];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := LRot32(blk[0], 13);
blk[3] := blk[3] + l;
blk[2] := blk[2] + m;
blk[1] := blk[1] xor r;
m := blk[1] + KeyData[22];
r := LRot32(blk[1], 13) * KeyData[23];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := LRot32(blk[1], 13);
blk[0] := blk[0] + l;
blk[3] := blk[3] + m;
blk[2] := blk[2] xor r;
m := blk[2] + KeyData[24];
r := LRot32(blk[2], 13) * KeyData[25];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := LRot32(blk[2], 13);
blk[1] := blk[1] + l;
blk[0] := blk[0] + m;
blk[3] := blk[3] xor r;
m := blk[3] + KeyData[26];
r := LRot32(blk[3], 13) * KeyData[27];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := LRot32(blk[3], 13);
blk[2] := blk[2] + l;
blk[1] := blk[1] + m;
blk[0] := blk[0] xor r;
m := blk[0] + KeyData[28];
r := LRot32(blk[0], 13) * KeyData[29];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := LRot32(blk[0], 13);
blk[3] := blk[3] + l;
blk[2] := blk[2] + m;
blk[1] := blk[1] xor r;
m := blk[1] + KeyData[30];
r := LRot32(blk[1], 13) * KeyData[31];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := LRot32(blk[1], 13);
blk[0] := blk[0] + l;
blk[3] := blk[3] + m;
blk[2] := blk[2] xor r;
m := blk[2] + KeyData[32];
r := LRot32(blk[2], 13) * KeyData[33];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := LRot32(blk[2], 13);
blk[1] := blk[1] + l;
blk[0] := blk[0] + m;
blk[3] := blk[3] xor r;
m := blk[3] + KeyData[34];
r := LRot32(blk[3], 13) * KeyData[35];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := LRot32(blk[3], 13);
blk[2] := blk[2] + l;
blk[1] := blk[1] + m;
blk[0] := blk[0] xor r;
blk[1] := blk[1] xor S_Box[(blk[0] and $FF) + 256];
blk[2] := blk[2] - S_Box[(blk[0] shr 24) and $FF];
blk[3] := blk[3] - S_Box[((blk[0] shr 16) and $FF) + 256];
blk[3] := blk[3] xor S_Box[(blk[0] shr 8) and $FF];
blk[0] := LRot32(blk[0], 24);
blk[2] := blk[2] xor S_Box[(blk[1] and $FF) + 256];
blk[3] := blk[3] - S_Box[(blk[1] shr 24) and $FF];
blk[0] := blk[0] - S_Box[((blk[1] shr 16) and $FF) + 256];
blk[0] := blk[0] xor S_Box[(blk[1] shr 8) and $FF];
blk[1] := LRot32(blk[1], 24);
blk[2] := blk[2] - blk[1];
blk[3] := blk[3] xor S_Box[(blk[2] and $FF) + 256];
blk[0] := blk[0] - S_Box[(blk[2] shr 24) and $FF];
blk[1] := blk[1] - S_Box[((blk[2] shr 16) and $FF) + 256];
blk[1] := blk[1] xor S_Box[(blk[2] shr 8) and $FF];
blk[2] := LRot32(blk[2], 24);
blk[3] := blk[3] - blk[0];
blk[0] := blk[0] xor S_Box[(blk[3] and $FF) + 256];
blk[1] := blk[1] - S_Box[(blk[3] shr 24) and $FF];
blk[2] := blk[2] - S_Box[((blk[3] shr 16) and $FF) + 256];
blk[2] := blk[2] xor S_Box[(blk[3] shr 8) and $FF];
blk[3] := LRot32(blk[3], 24);
blk[1] := blk[1] xor S_Box[(blk[0] and $FF) + 256];
blk[2] := blk[2] - S_Box[(blk[0] shr 24) and $FF];
blk[3] := blk[3] - S_Box[((blk[0] shr 16) and $FF) + 256];
blk[3] := blk[3] xor S_Box[(blk[0] shr 8) and $FF];
blk[0] := LRot32(blk[0], 24);
blk[2] := blk[2] xor S_Box[(blk[1] and $FF) + 256];
blk[3] := blk[3] - S_Box[(blk[1] shr 24) and $FF];
blk[0] := blk[0] - S_Box[((blk[1] shr 16) and $FF) + 256];
blk[0] := blk[0] xor S_Box[(blk[1] shr 8) and $FF];
blk[1] := LRot32(blk[1], 24);
blk[2] := blk[2] - blk[1];
blk[3] := blk[3] xor S_Box[(blk[2] and $FF) + 256];
blk[0] := blk[0] - S_Box[(blk[2] shr 24) and $FF];
blk[1] := blk[1] - S_Box[((blk[2] shr 16) and $FF) + 256];
blk[1] := blk[1] xor S_Box[(blk[2] shr 8) and $FF];
blk[2] := LRot32(blk[2], 24);
blk[3] := blk[3] - blk[0];
blk[0] := blk[0] xor S_Box[(blk[3] and $FF) + 256];
blk[1] := blk[1] - S_Box[(blk[3] shr 24) and $FF];
blk[2] := blk[2] - S_Box[((blk[3] shr 16) and $FF) + 256];
blk[2] := blk[2] xor S_Box[(blk[3] shr 8) and $FF];
blk[3] := LRot32(blk[3], 24);
blk[0] := blk[0] - KeyData[36];
blk[1] := blk[1] - KeyData[37];
blk[2] := blk[2] - KeyData[38];
blk[3] := blk[3] - KeyData[39];
Pdword(@Outdata)^ := blk[0];
Pdword(longword(@Outdata) + 4)^ := blk[1];
Pdword(longword(@Outdata) + 8)^ := blk[2];
Pdword(longword(@Outdata) + 12)^ := blk[3];
end;
procedure TMars.DecryptECB(const Indata; var Outdata);
var
l, m, r, t: DWORD;
blk: array[0..3] of DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
blk[0] := Pdword(@Indata)^;
blk[1] := Pdword(longword(@Indata) + 4)^;
blk[2] := Pdword(longword(@Indata) + 8)^;
blk[3] := Pdword(longword(@Indata) + 12)^;
blk[0] := blk[0] + KeyData[36];
blk[1] := blk[1] + KeyData[37];
blk[2] := blk[2] + KeyData[38];
blk[3] := blk[3] + KeyData[39];
blk[3] := RRot32(blk[3], 24);
blk[2] := blk[2] xor S_Box[(blk[3] shr 8) and $FF];
blk[2] := blk[2] + S_Box[((blk[3] shr 16) and $FF) + 256];
blk[1] := blk[1] + S_Box[(blk[3] shr 24) and $FF];
blk[0] := blk[0] xor S_Box[(blk[3] and $FF) + 256];
blk[3] := blk[3] + blk[0];
blk[2] := RRot32(blk[2], 24);
blk[1] := blk[1] xor S_Box[(blk[2] shr 8) and $FF];
blk[1] := blk[1] + S_Box[((blk[2] shr 16) and $FF) + 256];
blk[0] := blk[0] + S_Box[(blk[2] shr 24) and $FF];
blk[3] := blk[3] xor S_Box[(blk[2] and $FF) + 256];
blk[2] := blk[2] + blk[1];
blk[1] := RRot32(blk[1], 24);
blk[0] := blk[0] xor S_Box[(blk[1] shr 8) and $FF];
blk[0] := blk[0] + S_Box[((blk[1] shr 16) and $FF) + 256];
blk[3] := blk[3] + S_Box[(blk[1] shr 24) and $FF];
blk[2] := blk[2] xor S_Box[(blk[1] and $FF) + 256];
blk[0] := RRot32(blk[0], 24);
blk[3] := blk[3] xor S_Box[(blk[0] shr 8) and $FF];
blk[3] := blk[3] + S_Box[((blk[0] shr 16) and $FF) + 256];
blk[2] := blk[2] + S_Box[(blk[0] shr 24) and $FF];
blk[1] := blk[1] xor S_Box[(blk[0] and $FF) + 256];
blk[3] := RRot32(blk[3], 24);
blk[2] := blk[2] xor S_Box[(blk[3] shr 8) and $FF];
blk[2] := blk[2] + S_Box[((blk[3] shr 16) and $FF) + 256];
blk[1] := blk[1] + S_Box[(blk[3] shr 24) and $FF];
blk[0] := blk[0] xor S_Box[(blk[3] and $FF) + 256];
blk[3] := blk[3] + blk[0];
blk[2] := RRot32(blk[2], 24);
blk[1] := blk[1] xor S_Box[(blk[2] shr 8) and $FF];
blk[1] := blk[1] + S_Box[((blk[2] shr 16) and $FF) + 256];
blk[0] := blk[0] + S_Box[(blk[2] shr 24) and $FF];
blk[3] := blk[3] xor S_Box[(blk[2] and $FF) + 256];
blk[2] := blk[2] + blk[1];
blk[1] := RRot32(blk[1], 24);
blk[0] := blk[0] xor S_Box[(blk[1] shr 8) and $FF];
blk[0] := blk[0] + S_Box[((blk[1] shr 16) and $FF) + 256];
blk[3] := blk[3] + S_Box[(blk[1] shr 24) and $FF];
blk[2] := blk[2] xor S_Box[(blk[1] and $FF) + 256];
blk[0] := RRot32(blk[0], 24);
blk[3] := blk[3] xor S_Box[(blk[0] shr 8) and $FF];
blk[3] := blk[3] + S_Box[((blk[0] shr 16) and $FF) + 256];
blk[2] := blk[2] + S_Box[(blk[0] shr 24) and $FF];
blk[1] := blk[1] xor S_Box[(blk[0] and $FF) + 256];
blk[3] := RRot32(blk[3], 13);
m := blk[3] + KeyData[34];
r := LRot32(blk[3], 13) * KeyData[35];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := blk[2] - l;
blk[1] := blk[1] - m;
blk[0] := blk[0] xor r;
blk[2] := RRot32(blk[2], 13);
m := blk[2] + KeyData[32];
r := LRot32(blk[2], 13) * KeyData[33];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := blk[1] - l;
blk[0] := blk[0] - m;
blk[3] := blk[3] xor r;
blk[1] := RRot32(blk[1], 13);
m := blk[1] + KeyData[30];
r := LRot32(blk[1], 13) * KeyData[31];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := blk[0] - l;
blk[3] := blk[3] - m;
blk[2] := blk[2] xor r;
blk[0] := RRot32(blk[0], 13);
m := blk[0] + KeyData[28];
r := LRot32(blk[0], 13) * KeyData[29];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := blk[3] - l;
blk[2] := blk[2] - m;
blk[1] := blk[1] xor r;
blk[3] := RRot32(blk[3], 13);
m := blk[3] + KeyData[26];
r := LRot32(blk[3], 13) * KeyData[27];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := blk[2] - l;
blk[1] := blk[1] - m;
blk[0] := blk[0] xor r;
blk[2] := RRot32(blk[2], 13);
m := blk[2] + KeyData[24];
r := LRot32(blk[2], 13) * KeyData[25];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := blk[1] - l;
blk[0] := blk[0] - m;
blk[3] := blk[3] xor r;
blk[1] := RRot32(blk[1], 13);
m := blk[1] + KeyData[22];
r := LRot32(blk[1], 13) * KeyData[23];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := blk[0] - l;
blk[3] := blk[3] - m;
blk[2] := blk[2] xor r;
blk[0] := RRot32(blk[0], 13);
m := blk[0] + KeyData[20];
r := LRot32(blk[0], 13) * KeyData[21];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := blk[3] - l;
blk[2] := blk[2] - m;
blk[1] := blk[1] xor r;
blk[3] := RRot32(blk[3], 13);
m := blk[3] + KeyData[18];
r := LRot32(blk[3], 13) * KeyData[19];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := blk[0] - l;
blk[1] := blk[1] - m;
blk[2] := blk[2] xor r;
blk[2] := RRot32(blk[2], 13);
m := blk[2] + KeyData[16];
r := LRot32(blk[2], 13) * KeyData[17];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := blk[3] - l;
blk[0] := blk[0] - m;
blk[1] := blk[1] xor r;
blk[1] := RRot32(blk[1], 13);
m := blk[1] + KeyData[14];
r := LRot32(blk[1], 13) * KeyData[15];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := blk[2] - l;
blk[3] := blk[3] - m;
blk[0] := blk[0] xor r;
blk[0] := RRot32(blk[0], 13);
m := blk[0] + KeyData[12];
r := LRot32(blk[0], 13) * KeyData[13];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := blk[1] - l;
blk[2] := blk[2] - m;
blk[3] := blk[3] xor r;
blk[3] := RRot32(blk[3], 13);
m := blk[3] + KeyData[10];
r := LRot32(blk[3], 13) * KeyData[11];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[0] := blk[0] - l;
blk[1] := blk[1] - m;
blk[2] := blk[2] xor r;
blk[2] := RRot32(blk[2], 13);
m := blk[2] + KeyData[8];
r := LRot32(blk[2], 13) * KeyData[9];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[3] := blk[3] - l;
blk[0] := blk[0] - m;
blk[1] := blk[1] xor r;
blk[1] := RRot32(blk[1], 13);
m := blk[1] + KeyData[6];
r := LRot32(blk[1], 13) * KeyData[7];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[2] := blk[2] - l;
blk[3] := blk[3] - m;
blk[0] := blk[0] xor r;
blk[0] := RRot32(blk[0], 13);
m := blk[0] + KeyData[4];
r := LRot32(blk[0], 13) * KeyData[5];
l := S_Box[m and $1FF];
r := LRot32(r, 5);
t := r and $1F;
m := LRot32(m, t);
l := l xor r;
r := LRot32(r, 5);
l := l xor r;
t := r and $1F;
l := LRot32(l, t);
blk[1] := blk[1] - l;
blk[2] := blk[2] - m;
blk[3] := blk[3] xor r;
blk[3] := LRot32(blk[3], 24);
blk[2] := blk[2] xor S_Box[((blk[3] shr 24) and $FF) + 256];
blk[1] := blk[1] - S_Box[(blk[3] shr 16) and $FF];
blk[0] := blk[0] - S_Box[((blk[3] shr 8) and $FF) + 256];
blk[0] := blk[0] xor S_Box[blk[3] and $FF];
blk[2] := LRot32(blk[2], 24);
blk[1] := blk[1] xor S_Box[((blk[2] shr 24) and $FF) + 256];
blk[0] := blk[0] - S_Box[(blk[2] shr 16) and $FF];
blk[3] := blk[3] - S_Box[((blk[2] shr 8) and $FF) + 256];
blk[3] := blk[3] xor S_Box[blk[2] and $FF];
blk[1] := blk[1] - blk[2];
blk[1] := LRot32(blk[1], 24);
blk[0] := blk[0] xor S_Box[((blk[1] shr 24) and $FF) + 256];
blk[3] := blk[3] - S_Box[(blk[1] shr 16) and $FF];
blk[2] := blk[2] - S_Box[((blk[1] shr 8) and $FF) + 256];
blk[2] := blk[2] xor S_Box[blk[1] and $FF];
blk[0] := blk[0] - blk[3];
blk[0] := LRot32(blk[0], 24);
blk[3] := blk[3] xor S_Box[((blk[0] shr 24) and $FF) + 256];
blk[2] := blk[2] - S_Box[(blk[0] shr 16) and $FF];
blk[1] := blk[1] - S_Box[((blk[0] shr 8) and $FF) + 256];
blk[1] := blk[1] xor S_Box[blk[0] and $FF];
blk[3] := LRot32(blk[3], 24);
blk[2] := blk[2] xor S_Box[((blk[3] shr 24) and $FF) + 256];
blk[1] := blk[1] - S_Box[(blk[3] shr 16) and $FF];
blk[0] := blk[0] - S_Box[((blk[3] shr 8) and $FF) + 256];
blk[0] := blk[0] xor S_Box[blk[3] and $FF];
blk[2] := LRot32(blk[2], 24);
blk[1] := blk[1] xor S_Box[((blk[2] shr 24) and $FF) + 256];
blk[0] := blk[0] - S_Box[(blk[2] shr 16) and $FF];
blk[3] := blk[3] - S_Box[((blk[2] shr 8) and $FF) + 256];
blk[3] := blk[3] xor S_Box[blk[2] and $FF];
blk[1] := blk[1] - blk[2];
blk[1] := LRot32(blk[1], 24);
blk[0] := blk[0] xor S_Box[((blk[1] shr 24) and $FF) + 256];
blk[3] := blk[3] - S_Box[(blk[1] shr 16) and $FF];
blk[2] := blk[2] - S_Box[((blk[1] shr 8) and $FF) + 256];
blk[2] := blk[2] xor S_Box[blk[1] and $FF];
blk[0] := blk[0] - blk[3];
blk[0] := LRot32(blk[0], 24);
blk[3] := blk[3] xor S_Box[((blk[0] shr 24) and $FF) + 256];
blk[2] := blk[2] - S_Box[(blk[0] shr 16) and $FF];
blk[1] := blk[1] - S_Box[((blk[0] shr 8) and $FF) + 256];
blk[1] := blk[1] xor S_Box[blk[0] and $FF];
blk[0] := blk[0] - KeyData[0];
blk[1] := blk[1] - KeyData[1];
blk[2] := blk[2] - KeyData[2];
blk[3] := blk[3] - KeyData[3];
Pdword(@Outdata)^ := blk[0];
Pdword(longword(@Outdata) + 4)^ := blk[1];
Pdword(longword(@Outdata) + 8)^ := blk[2];
Pdword(longword(@Outdata) + 12)^ := blk[3];
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TRC6.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewRC6;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure TRC6.InitKey(const Key; Size: longword);
var
xKeyD: array[0..63] of DWORD;
i, j, k, xKeyLen: longword;
A, b: DWORD;
begin
Burn;
Size := Size div 8;
FillChar(xKeyD, Sizeof(xKeyD), 0);
Move(Key, xKeyD, Size);
xKeyLen := Size div 4;
if (Size mod 4) <> 0 then
Inc(xKeyLen);
Move(sBoxRC6, KeyData, ((NUMROUNDSRC6 * 2) + 4) * 4);
i := 0;
j := 0;
A := 0;
b := 0;
if xKeyLen > ((NUMROUNDSRC6 * 2) + 4) then
k := xKeyLen * 3
else
k := ((NUMROUNDSRC6 * 2) + 4) * 3;
for k := 1 to k do begin
A := LRot32(KeyData[i] + A + b, 3);
KeyData[i] := A;
b := LRot32(xKeyD[j] + A + b, A + b);
xKeyD[j] := b;
i := (i + 1) mod ((NUMROUNDSRC6 * 2) + 4);
j := (j + 1) mod xKeyLen;
end;
FillChar(xKeyD, Sizeof(xKeyD), 0);
end;
procedure TRC6.Burn;
begin
FillChar(KeyData, Sizeof(KeyData), $FF);
inherited Burn;
end;
procedure TRC6.EncryptECB(const Indata; var Outdata);
var
x0, x1, x2, x3: DWORD;
u, t: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
x0 := Pdword(@Indata)^;
x1 := Pdword(longword(@Indata) + 4)^;
x2 := Pdword(longword(@Indata) + 8)^;
x3 := Pdword(longword(@Indata) + 12)^;
x1 := x1 + KeyData[0];
x3 := x3 + KeyData[1];
for i := 1 to NUMROUNDSRC6 do begin
t := LRot32(x1 * (2 * x1 + 1), 5);
u := LRot32(x3 * (2 * x3 + 1), 5);
x0 := LRot32(x0 xor t, u) + KeyData[2 * i];
x2 := LRot32(x2 xor u, t) + KeyData[2 * i + 1];
t := x0;
x0 := x1;
x1 := x2;
x2 := x3;
x3 := t;
end;
x0 := x0 + KeyData[(2 * NUMROUNDSRC6) + 2];
x2 := x2 + KeyData[(2 * NUMROUNDSRC6) + 3];
Pdword(@Outdata)^ := x0;
Pdword(longword(@Outdata) + 4)^ := x1;
Pdword(longword(@Outdata) + 8)^ := x2;
Pdword(longword(@Outdata) + 12)^ := x3;
end;
procedure TRC6.DecryptECB(const Indata; var Outdata);
var
x0, x1, x2, x3: DWORD;
u, t: DWORD;
i: longword;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
x0 := Pdword(@Indata)^;
x1 := Pdword(longword(@Indata) + 4)^;
x2 := Pdword(longword(@Indata) + 8)^;
x3 := Pdword(longword(@Indata) + 12)^;
x2 := x2 - KeyData[(2 * NUMROUNDSRC6) + 3];
x0 := x0 - KeyData[(2 * NUMROUNDSRC6) + 2];
for i := NUMROUNDSRC6 downto 1 do begin
t := x0;
x0 := x3;
x3 := x2;
x2 := x1;
x1 := t;
u := LRot32(x3 * (2 * x3 + 1), 5);
t := LRot32(x1 * (2 * x1 + 1), 5);
x2 := RRot32(x2 - KeyData[2 * i + 1], t) xor u;
x0 := RRot32(x0 - KeyData[2 * i], u) xor t;
end;
x3 := x3 - KeyData[1];
x1 := x1 - KeyData[0];
Pdword(@Outdata)^ := x0;
Pdword(longword(@Outdata) + 4)^ := x1;
Pdword(longword(@Outdata) + 8)^ := x2;
Pdword(longword(@Outdata) + 12)^ := x3;
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TRijndael.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewRijndael;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure InvMixColumn(A: PByteArray; BC: byte);
var
j: longword;
begin
for j := 0 to (BC - 1) do
Pdword(@(A^[j * 4]))^ := Pdword(@U1[A^[j * 4 + 0]])^ xor
Pdword(@U2[A^[j * 4 + 1]])^ xor
Pdword(@U3[A^[j * 4 + 2]])^ xor
Pdword(@U4[A^[j * 4 + 3]])^;
end;
procedure TRijndael.InitKey(const Key; Size: longword);
var
KC, Rounds, j, r, t, rconpointer: longword;
tk: array[0..MAXKC - 1, 0..3] of byte;
begin
Burn;
Size := Size div 8;
FillChar(tk, Sizeof(tk), 0);
Move(Key, tk, Size);
if Size <= 16 then begin
KC := 4;
Rounds := 10;
end
else if Size <= 24 then begin
KC := 6;
Rounds := 12;
end
else begin
KC := 8;
Rounds := 14;
end;
numrounds := Rounds;
r := 0;
t := 0;
j := 0;
while (j < KC) and (r < (Rounds + 1)) do begin
while (j < KC) and (t < BCRJ) do begin
rk[r, t] := Pdword(@tk[j])^;
Inc(j);
Inc(t);
end;
if t = BCRJ then begin
t := 0;
Inc(r);
end;
end;
rconpointer := 0;
while (r < (Rounds + 1)) do begin
tk[0, 0] := tk[0, 0] xor S[tk[KC - 1, 1]];
tk[0, 1] := tk[0, 1] xor S[tk[KC - 1, 2]];
tk[0, 2] := tk[0, 2] xor S[tk[KC - 1, 3]];
tk[0, 3] := tk[0, 3] xor S[tk[KC - 1, 0]];
tk[0, 0] := tk[0, 0] xor rcon[rconpointer];
Inc(rconpointer);
if KC <> 8 then begin
for j := 1 to (KC - 1) do
Pdword(@tk[j])^ := Pdword(@tk[j])^ xor Pdword(@tk[j - 1])^;
end
else begin
for j := 1 to ((KC div 2) - 1) do
Pdword(@tk[j])^ := Pdword(@tk[j])^ xor Pdword(@tk[j - 1])^;
tk[KC div 2, 0] := tk[KC div 2, 0] xor S[tk[KC div 2 - 1, 0]];
tk[KC div 2, 1] := tk[KC div 2, 1] xor S[tk[KC div 2 - 1, 1]];
tk[KC div 2, 2] := tk[KC div 2, 2] xor S[tk[KC div 2 - 1, 2]];
tk[KC div 2, 3] := tk[KC div 2, 3] xor S[tk[KC div 2 - 1, 3]];
for j := ((KC div 2) + 1) to (KC - 1) do
Pdword(@tk[j])^ := Pdword(@tk[j])^ xor Pdword(@tk[j - 1])^;
end;
j := 0;
while (j < KC) and (r < (Rounds + 1)) do begin
while (j < KC) and (t < BCRJ) do begin
rk[r, t] := Pdword(@tk[j])^;
Inc(j);
Inc(t);
end;
if t = BCRJ then begin
Inc(r);
t := 0;
end;
end;
end;
Move(rk, drk, Sizeof(rk));
for r := 1 to (numrounds - 1) do
InvMixColumn(@drk[r], BCRJ);
end;
procedure TRijndael.Burn;
begin
numrounds := 0;
FillChar(rk, Sizeof(rk), 0);
FillChar(drk, Sizeof(drk), 0);
inherited Burn;
end;
procedure TRijndael.EncryptECB(const Indata; var Outdata);
var
r: longword;
tempb: array[0..MAXBC - 1, 0..3] of byte;
A: array[0..MAXBC, 0..3] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Pdword(@A[0, 0])^ := Pdword(@Indata)^;
Pdword(@A[1, 0])^ := Pdword(DWORD(@Indata) + 4)^;
Pdword(@A[2, 0])^ := Pdword(DWORD(@Indata) + 8)^;
Pdword(@A[3, 0])^ := Pdword(DWORD(@Indata) + 12)^;
for r := 0 to (numrounds - 2) do begin
Pdword(@tempb[0])^ := Pdword(@A[0])^ xor rk[r, 0];
Pdword(@tempb[1])^ := Pdword(@A[1])^ xor rk[r, 1];
Pdword(@tempb[2])^ := Pdword(@A[2])^ xor rk[r, 2];
Pdword(@tempb[3])^ := Pdword(@A[3])^ xor rk[r, 3];
Pdword(@A[0])^ := Pdword(@T1[tempb[0, 0]])^ xor
Pdword(@T2[tempb[1, 1]])^ xor
Pdword(@T3[tempb[2, 2]])^ xor
Pdword(@T4[tempb[3, 3]])^;
Pdword(@A[1])^ := Pdword(@T1[tempb[1, 0]])^ xor
Pdword(@T2[tempb[2, 1]])^ xor
Pdword(@T3[tempb[3, 2]])^ xor
Pdword(@T4[tempb[0, 3]])^;
Pdword(@A[2])^ := Pdword(@T1[tempb[2, 0]])^ xor
Pdword(@T2[tempb[3, 1]])^ xor
Pdword(@T3[tempb[0, 2]])^ xor
Pdword(@T4[tempb[1, 3]])^;
Pdword(@A[3])^ := Pdword(@T1[tempb[3, 0]])^ xor
Pdword(@T2[tempb[0, 1]])^ xor
Pdword(@T3[tempb[1, 2]])^ xor
Pdword(@T4[tempb[2, 3]])^;
end;
Pdword(@tempb[0])^ := Pdword(@A[0])^ xor rk[numrounds - 1, 0];
Pdword(@tempb[1])^ := Pdword(@A[1])^ xor rk[numrounds - 1, 1];
Pdword(@tempb[2])^ := Pdword(@A[2])^ xor rk[numrounds - 1, 2];
Pdword(@tempb[3])^ := Pdword(@A[3])^ xor rk[numrounds - 1, 3];
A[0, 0] := T1[tempb[0, 0], 1];
A[0, 1] := T1[tempb[1, 1], 1];
A[0, 2] := T1[tempb[2, 2], 1];
A[0, 3] := T1[tempb[3, 3], 1];
A[1, 0] := T1[tempb[1, 0], 1];
A[1, 1] := T1[tempb[2, 1], 1];
A[1, 2] := T1[tempb[3, 2], 1];
A[1, 3] := T1[tempb[0, 3], 1];
A[2, 0] := T1[tempb[2, 0], 1];
A[2, 1] := T1[tempb[3, 1], 1];
A[2, 2] := T1[tempb[0, 2], 1];
A[2, 3] := T1[tempb[1, 3], 1];
A[3, 0] := T1[tempb[3, 0], 1];
A[3, 1] := T1[tempb[0, 1], 1];
A[3, 2] := T1[tempb[1, 2], 1];
A[3, 3] := T1[tempb[2, 3], 1];
Pdword(@A[0])^ := Pdword(@A[0])^ xor rk[numrounds, 0];
Pdword(@A[1])^ := Pdword(@A[1])^ xor rk[numrounds, 1];
Pdword(@A[2])^ := Pdword(@A[2])^ xor rk[numrounds, 2];
Pdword(@A[3])^ := Pdword(@A[3])^ xor rk[numrounds, 3];
Pdword(@Outdata)^ := Pdword(@A[0, 0])^;
Pdword(DWORD(@Outdata) + 4)^ := Pdword(@A[1, 0])^;
Pdword(DWORD(@Outdata) + 8)^ := Pdword(@A[2, 0])^;
Pdword(DWORD(@Outdata) + 12)^ := Pdword(@A[3, 0])^;
end;
procedure TRijndael.DecryptECB(const Indata; var Outdata);
var
r: longword;
tempb: array[0..MAXBC - 1, 0..3] of byte;
A: array[0..MAXBC, 0..3] of byte;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
Pdword(@A[0, 0])^ := Pdword(@Indata)^;
Pdword(@A[1, 0])^ := Pdword(DWORD(@Indata) + 4)^;
Pdword(@A[2, 0])^ := Pdword(DWORD(@Indata) + 8)^;
Pdword(@A[3, 0])^ := Pdword(DWORD(@Indata) + 12)^;
for r := numrounds downto 2 do begin
Pdword(@tempb[0])^ := Pdword(@A[0])^ xor drk[r, 0];
Pdword(@tempb[1])^ := Pdword(@A[1])^ xor drk[r, 1];
Pdword(@tempb[2])^ := Pdword(@A[2])^ xor drk[r, 2];
Pdword(@tempb[3])^ := Pdword(@A[3])^ xor drk[r, 3];
Pdword(@A[0])^ := Pdword(@T5[tempb[0, 0]])^ xor
Pdword(@T6[tempb[3, 1]])^ xor
Pdword(@T7[tempb[2, 2]])^ xor
Pdword(@T8[tempb[1, 3]])^;
Pdword(@A[1])^ := Pdword(@T5[tempb[1, 0]])^ xor
Pdword(@T6[tempb[0, 1]])^ xor
Pdword(@T7[tempb[3, 2]])^ xor
Pdword(@T8[tempb[2, 3]])^;
Pdword(@A[2])^ := Pdword(@T5[tempb[2, 0]])^ xor
Pdword(@T6[tempb[1, 1]])^ xor
Pdword(@T7[tempb[0, 2]])^ xor
Pdword(@T8[tempb[3, 3]])^;
Pdword(@A[3])^ := Pdword(@T5[tempb[3, 0]])^ xor
Pdword(@T6[tempb[2, 1]])^ xor
Pdword(@T7[tempb[1, 2]])^ xor
Pdword(@T8[tempb[0, 3]])^;
end;
Pdword(@tempb[0])^ := Pdword(@A[0])^ xor drk[1, 0];
Pdword(@tempb[1])^ := Pdword(@A[1])^ xor drk[1, 1];
Pdword(@tempb[2])^ := Pdword(@A[2])^ xor drk[1, 2];
Pdword(@tempb[3])^ := Pdword(@A[3])^ xor drk[1, 3];
A[0, 0] := S5[tempb[0, 0]];
A[0, 1] := S5[tempb[3, 1]];
A[0, 2] := S5[tempb[2, 2]];
A[0, 3] := S5[tempb[1, 3]];
A[1, 0] := S5[tempb[1, 0]];
A[1, 1] := S5[tempb[0, 1]];
A[1, 2] := S5[tempb[3, 2]];
A[1, 3] := S5[tempb[2, 3]];
A[2, 0] := S5[tempb[2, 0]];
A[2, 1] := S5[tempb[1, 1]];
A[2, 2] := S5[tempb[0, 2]];
A[2, 3] := S5[tempb[3, 3]];
A[3, 0] := S5[tempb[3, 0]];
A[3, 1] := S5[tempb[2, 1]];
A[3, 2] := S5[tempb[1, 2]];
A[3, 3] := S5[tempb[0, 3]];
Pdword(@A[0])^ := Pdword(@A[0])^ xor drk[0, 0];
Pdword(@A[1])^ := Pdword(@A[1])^ xor drk[0, 1];
Pdword(@A[2])^ := Pdword(@A[2])^ xor drk[0, 2];
Pdword(@A[3])^ := Pdword(@A[3])^ xor drk[0, 3];
Pdword(@Outdata)^ := Pdword(@A[0, 0])^;
Pdword(DWORD(@Outdata) + 4)^ := Pdword(@A[1, 0])^;
Pdword(DWORD(@Outdata) + 8)^ := Pdword(@A[2, 0])^;
Pdword(DWORD(@Outdata) + 12)^ := Pdword(@A[3, 0])^;
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TSerpent.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewSerpent;
begin
New(Result, Create);
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure TSerpent.InitKey(const Key; Size: longword);
var
kp: array[0..139] of DWORD;
i, n: Integer;
t, T1, T2, T3, T4, T5, T6, T7, T8, t9, t10, t11, t12, t13, t14, t15, t16, t17: DWORD;
A, b, c, d: DWORD;
begin
Burn;
FillChar(kp, 256 div 8, 0);
Move(Key, kp, Size div 8);
if Size < 256 then begin
i := Size div 32;
t := 1 shl (Size mod 32);
kp[i] := (kp[i] and (t - 1)) or t;
end;
for i := 8 to 139 do begin
t := kp[i - 8] xor kp[i - 5] xor kp[i - 3] xor kp[i - 1] xor $9E3779B9 xor longword(i - 8);
kp[i] := (t shl 11) or (t shr 21);
end;
for i := 0 to 3 do begin
n := i * 32;
A := kp[n + 4 * 0 + 8];
b := kp[n + 4 * 0 + 9];
c := kp[n + 4 * 0 + 10];
d := kp[n + 4 * 0 + 11];
T1 := A xor c;
T2 := A or d;
T3 := A and b;
T4 := A and d;
T5 := b or T4;
T6 := T1 and T2;
kp[9 + n] := T5 xor T6;
T8 := b xor d;
t9 := c or T3;
t10 := T6 xor T8;
kp[11 + n] := t9 xor t10;
t12 := c xor T3;
t13 := T2 and kp[11 + n];
kp[10 + n] := t12 xor t13;
t15 := not kp[10 + n];
t16 := T2 xor T3;
t17 := kp[9 + n] and t15;
kp[8 + n] := t16 xor t17;
A := kp[n + 4 * 1 + 8];
b := kp[n + 4 * 1 + 9];
c := kp[n + 4 * 1 + 10];
d := kp[n + 4 * 1 + 11];
T1 := not A;
T2 := b xor d;
T3 := c and T1;
kp[12 + n] := T2 xor T3;
T5 := c xor T1;
T6 := c xor kp[12 + n];
T7 := b and T6;
kp[15 + n] := T5 xor T7;
t9 := d or T7;
t10 := kp[12 + n] or T5;
t11 := t9 and t10;
kp[14 + n] := A xor t11;
t13 := d or T1;
t14 := T2 xor kp[15 + n];
t15 := kp[14 + n] xor t13;
kp[13 + n] := t14 xor t15;
A := kp[n + 4 * 2 + 8];
b := kp[n + 4 * 2 + 9];
c := kp[n + 4 * 2 + 10];
d := kp[n + 4 * 2 + 11];
T1 := A xor d;
T2 := b xor d;
T3 := A and b;
T4 := not c;
T5 := T2 xor T3;
kp[18 + n] := T4 xor T5;
T7 := A xor T2;
T8 := b or T4;
t9 := d or kp[18 + n];
t10 := T7 and t9;
kp[17 + n] := T8 xor t10;
t12 := c xor d;
t13 := T1 or T2;
t14 := kp[17 + n] xor t12;
kp[19 + n] := t13 xor t14;
t16 := T1 or kp[18 + n];
t17 := T8 xor t14;
kp[16 + n] := t16 xor t17;
A := kp[n + 4 * 3 + 8];
b := kp[n + 4 * 3 + 9];
c := kp[n + 4 * 3 + 10];
d := kp[n + 4 * 3 + 11];
T1 := b xor d;
T2 := not T1;
T3 := A or d;
T4 := b xor c;
kp[23 + n] := T3 xor T4;
T6 := A xor b;
T7 := A or T4;
T8 := c and T6;
t9 := T2 or T8;
kp[20 + n] := T7 xor t9;
t11 := A xor kp[23 + n];
t12 := T1 and T6;
t13 := kp[20 + n] xor t11;
kp[21 + n] := t12 xor t13;
t15 := kp[20 + n] or kp[21 + n];
t16 := T3 and t15;
kp[22 + n] := b xor t16;
A := kp[n + 4 * 4 + 8];
b := kp[n + 4 * 4 + 9];
c := kp[n + 4 * 4 + 10];
d := kp[n + 4 * 4 + 11];
T1 := not c;
T2 := b xor c;
T3 := b or T1;
T4 := d xor T3;
T5 := A and T4;
kp[27 + n] := T2 xor T5;
T7 := A xor d;
T8 := b xor T5;
t9 := T2 or T8;
kp[25 + n] := T7 xor t9;
t11 := d and T3;
t12 := T5 xor kp[25 + n];
t13 := kp[27 + n] and t12;
kp[26 + n] := t11 xor t13;
t15 := T1 or T4;
t16 := t12 xor kp[26 + n];
kp[24 + n] := t15 xor t16;
A := kp[n + 4 * 5 + 8];
b := kp[n + 4 * 5 + 9];
c := kp[n + 4 * 5 + 10];
d := kp[n + 4 * 5 + 11];
T1 := A xor c;
T2 := b or d;
T3 := b xor c;
T4 := not T3;
T5 := A and d;
kp[29 + n] := T4 xor T5;
T7 := b or c;
T8 := d xor T1;
t9 := T7 and T8;
kp[31 + n] := T2 xor t9;
t11 := T1 and T7;
t12 := T4 xor T8;
t13 := kp[31 + n] and t11;
kp[28 + n] := t12 xor t13;
t15 := T3 xor t11;
t16 := kp[31 + n] or t15;
kp[30 + n] := t12 xor t16;
A := kp[n + 4 * 6 + 8];
b := kp[n + 4 * 6 + 9];
c := kp[n + 4 * 6 + 10];
d := kp[n + 4 * 6 + 11];
T1 := not A;
T2 := A xor b;
T3 := A xor d;
T4 := c xor T1;
T5 := T2 or T3;
kp[32 + n] := T4 xor T5;
T7 := not d;
T8 := kp[32 + n] and T7;
kp[33 + n] := T2 xor T8;
t10 := b or kp[33 + n];
t11 := c or kp[32 + n];
t12 := T7 xor t10;
kp[35 + n] := t11 xor t12;
t14 := d or kp[33 + n];
t15 := T1 xor t14;
t16 := kp[32 + n] or kp[35 + n];
kp[34 + n] := t15 xor t16;
A := kp[n + 4 * 7 + 8];
b := kp[n + 4 * 7 + 9];
c := kp[n + 4 * 7 + 10];
d := kp[n + 4 * 7 + 11];
T1 := not A;
T2 := A xor d;
T3 := A xor b;
T4 := c xor T1;
T5 := T2 or T3;
kp[36 + n] := T4 xor T5;
T7 := not kp[36 + n];
T8 := b or T7;
kp[39 + n] := T2 xor T8;
t10 := A and kp[36 + n];
t11 := b xor kp[39 + n];
t12 := T8 and t11;
kp[38 + n] := t10 xor t12;
t14 := A or T7;
t15 := T3 xor t14;
t16 := kp[39 + n] and kp[38 + n];
kp[37 + n] := t15 xor t16;
end;
A := kp[136];
b := kp[137];
c := kp[138];
d := kp[139];
T1 := A xor c;
T2 := A or d;
T3 := A and b;
T4 := A and d;
T5 := b or T4;
T6 := T1 and T2;
kp[137] := T5 xor T6;
T8 := b xor d;
t9 := c or T3;
t10 := T6 xor T8;
kp[139] := t9 xor t10;
t12 := c xor T3;
t13 := T2 and kp[139];
kp[138] := t12 xor t13;
t15 := not kp[138];
t16 := T2 xor T3;
t17 := kp[137] and t15;
kp[136] := t16 xor t17;
Move(kp[8], l_key, Sizeof(l_key));
FillChar(kp, Sizeof(kp), 0);
end;
procedure TSerpent.Burn;
begin
FillChar(l_key, Sizeof(l_key), 0);
inherited Burn;
end;
procedure TSerpent.EncryptECB(const Indata; var Outdata);
var
i: Integer;
A, b, c, d, e, f, g, h: DWORD;
T1, T2, T3, T4, T5, T6, T7, T8, t9, t10, t11, t12, t13, t14, t15, t16, t17: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
A := Pdword(@Indata)^;
b := Pdword(longword(@Indata) + 4)^;
c := Pdword(longword(@Indata) + 8)^;
d := Pdword(longword(@Indata) + 12)^;
i := 0;
while i < 32 do begin
A := A xor l_key[4 * (i)];
b := b xor l_key[4 * (i) + 1];
c := c xor l_key[4 * (i) + 2];
d := d xor l_key[4 * (i) + 3];
T1 := b xor d;
T2 := not T1;
T3 := A or d;
T4 := b xor c;
h := T3 xor T4;
T6 := A xor b;
T7 := A or T4;
T8 := c and T6;
t9 := T2 or T8;
e := T7 xor t9;
t11 := A xor h;
t12 := T1 and T6;
t13 := e xor t11;
f := t12 xor t13;
t15 := e or f;
t16 := T3 and t15;
g := b xor t16;
e := (e shl 13) or (e shr 19);
g := (g shl 3) or (g shr 29);
f := f xor e xor g;
h := h xor g xor (e shl 3);
f := (f shl 1) or (f shr 31);
h := (h shl 7) or (h shr 25);
e := e xor f xor h;
g := g xor h xor (f shl 7);
e := (e shl 5) or (e shr 27);
g := (g shl 22) or (g shr 10);
e := e xor l_key[4 * (i + 1)];
f := f xor l_key[4 * (i + 1) + 1];
g := g xor l_key[4 * (i + 1) + 2];
h := h xor l_key[4 * (i + 1) + 3];
T1 := e xor h;
T2 := f xor h;
T3 := e and f;
T4 := not g;
T5 := T2 xor T3;
c := T4 xor T5;
T7 := e xor T2;
T8 := f or T4;
t9 := h or c;
t10 := T7 and t9;
b := T8 xor t10;
t12 := g xor h;
t13 := T1 or T2;
t14 := b xor t12;
d := t13 xor t14;
t16 := T1 or c;
t17 := T8 xor t14;
A := t16 xor t17;
A := (A shl 13) or (A shr 19);
c := (c shl 3) or (c shr 29);
b := b xor A xor c;
d := d xor c xor (A shl 3);
b := (b shl 1) or (b shr 31);
d := (d shl 7) or (d shr 25);
A := A xor b xor d;
c := c xor d xor (b shl 7);
A := (A shl 5) or (A shr 27);
c := (c shl 22) or (c shr 10);
A := A xor l_key[4 * (i + 2)];
b := b xor l_key[4 * (i + 2) + 1];
c := c xor l_key[4 * (i + 2) + 2];
d := d xor l_key[4 * (i + 2) + 3];
T1 := not A;
T2 := b xor d;
T3 := c and T1;
e := T2 xor T3;
T5 := c xor T1;
T6 := c xor e;
T7 := b and T6;
h := T5 xor T7;
t9 := d or T7;
t10 := e or T5;
t11 := t9 and t10;
g := A xor t11;
t13 := d or T1;
t14 := T2 xor h;
t15 := g xor t13;
f := t14 xor t15;
e := (e shl 13) or (e shr 19);
g := (g shl 3) or (g shr 29);
f := f xor e xor g;
h := h xor g xor (e shl 3);
f := (f shl 1) or (f shr 31);
h := (h shl 7) or (h shr 25);
e := e xor f xor h;
g := g xor h xor (f shl 7);
e := (e shl 5) or (e shr 27);
g := (g shl 22) or (g shr 10);
e := e xor l_key[4 * (i + 3)];
f := f xor l_key[4 * (i + 3) + 1];
g := g xor l_key[4 * (i + 3) + 2];
h := h xor l_key[4 * (i + 3) + 3];
T1 := e xor g;
T2 := e or h;
T3 := e and f;
T4 := e and h;
T5 := f or T4;
T6 := T1 and T2;
b := T5 xor T6;
T8 := f xor h;
t9 := g or T3;
t10 := T6 xor T8;
d := t9 xor t10;
t12 := g xor T3;
t13 := T2 and d;
c := t12 xor t13;
t15 := not c;
t16 := T2 xor T3;
t17 := b and t15;
A := t16 xor t17;
A := (A shl 13) or (A shr 19);
c := (c shl 3) or (c shr 29);
b := b xor A xor c;
d := d xor c xor (A shl 3);
b := (b shl 1) or (b shr 31);
d := (d shl 7) or (d shr 25);
A := A xor b xor d;
c := c xor d xor (b shl 7);
A := (A shl 5) or (A shr 27);
c := (c shl 22) or (c shr 10);
A := A xor l_key[4 * (i + 4)];
b := b xor l_key[4 * (i + 4) + 1];
c := c xor l_key[4 * (i + 4) + 2];
d := d xor l_key[4 * (i + 4) + 3];
T1 := not A;
T2 := A xor d;
T3 := A xor b;
T4 := c xor T1;
T5 := T2 or T3;
e := T4 xor T5;
T7 := not e;
T8 := b or T7;
h := T2 xor T8;
t10 := A and e;
t11 := b xor h;
t12 := T8 and t11;
g := t10 xor t12;
t14 := A or T7;
t15 := T3 xor t14;
t16 := h and g;
f := t15 xor t16;
e := (e shl 13) or (e shr 19);
g := (g shl 3) or (g shr 29);
f := f xor e xor g;
h := h xor g xor (e shl 3);
f := (f shl 1) or (f shr 31);
h := (h shl 7) or (h shr 25);
e := e xor f xor h;
g := g xor h xor (f shl 7);
e := (e shl 5) or (e shr 27);
g := (g shl 22) or (g shr 10);
e := e xor l_key[4 * (i + 5)];
f := f xor l_key[4 * (i + 5) + 1];
g := g xor l_key[4 * (i + 5) + 2];
h := h xor l_key[4 * (i + 5) + 3];
T1 := not e;
T2 := e xor f;
T3 := e xor h;
T4 := g xor T1;
T5 := T2 or T3;
A := T4 xor T5;
T7 := not h;
T8 := A and T7;
b := T2 xor T8;
t10 := f or b;
t11 := g or A;
t12 := T7 xor t10;
d := t11 xor t12;
t14 := h or b;
t15 := T1 xor t14;
t16 := A or d;
c := t15 xor t16;
A := (A shl 13) or (A shr 19);
c := (c shl 3) or (c shr 29);
b := b xor A xor c;
d := d xor c xor (A shl 3);
b := (b shl 1) or (b shr 31);
d := (d shl 7) or (d shr 25);
A := A xor b xor d;
c := c xor d xor (b shl 7);
A := (A shl 5) or (A shr 27);
c := (c shl 22) or (c shr 10);
A := A xor l_key[4 * (i + 6)];
b := b xor l_key[4 * (i + 6) + 1];
c := c xor l_key[4 * (i + 6) + 2];
d := d xor l_key[4 * (i + 6) + 3];
T1 := A xor c;
T2 := b or d;
T3 := b xor c;
T4 := not T3;
T5 := A and d;
f := T4 xor T5;
T7 := b or c;
T8 := d xor T1;
t9 := T7 and T8;
h := T2 xor t9;
t11 := T1 and T7;
t12 := T4 xor T8;
t13 := h and t11;
e := t12 xor t13;
t15 := T3 xor t11;
t16 := h or t15;
g := t12 xor t16;
e := (e shl 13) or (e shr 19);
g := (g shl 3) or (g shr 29);
f := f xor e xor g;
h := h xor g xor (e shl 3);
f := (f shl 1) or (f shr 31);
h := (h shl 7) or (h shr 25);
e := e xor f xor h;
g := g xor h xor (f shl 7);
e := (e shl 5) or (e shr 27);
g := (g shl 22) or (g shr 10);
e := e xor l_key[4 * (i + 7)];
f := f xor l_key[4 * (i + 7) + 1];
g := g xor l_key[4 * (i + 7) + 2];
h := h xor l_key[4 * (i + 7) + 3];
T1 := not g;
T2 := f xor g;
T3 := f or T1;
T4 := h xor T3;
T5 := e and T4;
d := T2 xor T5;
T7 := e xor h;
T8 := f xor T5;
t9 := T2 or T8;
b := T7 xor t9;
t11 := h and T3;
t12 := T5 xor b;
t13 := d and t12;
c := t11 xor t13;
t15 := T1 or T4;
t16 := t12 xor c;
A := t15 xor t16;
Inc(i, 8);
if i < 32 then begin
A := (A shl 13) or (A shr 19);
c := (c shl 3) or (c shr 29);
b := b xor A xor c;
d := d xor c xor (A shl 3);
b := (b shl 1) or (b shr 31);
d := (d shl 7) or (d shr 25);
A := A xor b xor d;
c := c xor d xor (b shl 7);
A := (A shl 5) or (A shr 27);
c := (c shl 22) or (c shr 10);
end;
end;
A := A xor l_key[128];
b := b xor l_key[128 + 1];
c := c xor l_key[128 + 2];
d := d xor l_key[128 + 3];
Pdword(longword(@Outdata) + 0)^ := A;
Pdword(longword(@Outdata) + 4)^ := b;
Pdword(longword(@Outdata) + 8)^ := c;
Pdword(longword(@Outdata) + 12)^ := d;
end;
procedure TSerpent.DecryptECB(const Indata; var Outdata);
var
i: Integer;
A, b, c, d, e, f, g, h: DWORD;
T1, T2, T3, T4, T5, T6, T7, T8, t9, t10, t11, t12, t13, t14, t15, t16: DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
A := Pdword(@Indata)^;
b := Pdword(longword(@Indata) + 4)^;
c := Pdword(longword(@Indata) + 8)^;
d := Pdword(longword(@Indata) + 12)^;
i := 32;
A := A xor l_key[4 * 32];
b := b xor l_key[4 * 32 + 1];
c := c xor l_key[4 * 32 + 2];
d := d xor l_key[4 * 32 + 3];
while i > 0 do begin
if i < 32 then begin
c := (c shr 22) or (c shl 10);
A := (A shr 5) or (A shl 27);
c := c xor d xor (b shl 7);
A := A xor b xor d;
d := (d shr 7) or (d shl 25);
b := (b shr 1) or (b shl 31);
d := d xor c xor (A shl 3);
b := b xor A xor c;
c := (c shr 3) or (c shl 29);
A := (A shr 13) or (A shl 19);
end;
T1 := A and b;
T2 := A or b;
T3 := c or T1;
T4 := d and T2;
h := T3 xor T4;
T6 := not d;
T7 := b xor T4;
T8 := h xor T6;
t9 := T7 or T8;
f := A xor t9;
t11 := c xor T7;
t12 := d or f;
e := t11 xor t12;
t14 := A and h;
t15 := T3 xor f;
t16 := e xor t14;
g := t15 xor t16;
e := e xor l_key[4 * (i - 1)];
f := f xor l_key[4 * (i - 1) + 1];
g := g xor l_key[4 * (i - 1) + 2];
h := h xor l_key[4 * (i - 1) + 3];
g := (g shr 22) or (g shl 10);
e := (e shr 5) or (e shl 27);
g := g xor h xor (f shl 7);
e := e xor f xor h;
h := (h shr 7) or (h shl 25);
f := (f shr 1) or (f shl 31);
h := h xor g xor (e shl 3);
f := f xor e xor g;
g := (g shr 3) or (g shl 29);
e := (e shr 13) or (e shl 19);
T1 := not g;
T2 := e xor g;
T3 := f xor h;
T4 := e or T1;
b := T3 xor T4;
T6 := e or f;
T7 := f and T2;
T8 := b xor T6;
t9 := T7 or T8;
A := g xor t9;
t11 := not b;
t12 := h or T2;
t13 := t9 xor t11;
d := t12 xor t13;
t15 := f xor t11;
t16 := A and d;
c := t15 xor t16;
A := A xor l_key[4 * (i - 2)];
b := b xor l_key[4 * (i - 2) + 1];
c := c xor l_key[4 * (i - 2) + 2];
d := d xor l_key[4 * (i - 2) + 3];
c := (c shr 22) or (c shl 10);
A := (A shr 5) or (A shl 27);
c := c xor d xor (b shl 7);
A := A xor b xor d;
d := (d shr 7) or (d shl 25);
b := (b shr 1) or (b shl 31);
d := d xor c xor (A shl 3);
b := b xor A xor c;
c := (c shr 3) or (c shl 29);
A := (A shr 13) or (A shl 19);
T1 := not c;
T2 := b and T1;
T3 := d xor T2;
T4 := A and T3;
T5 := b xor T1;
h := T4 xor T5;
T7 := b or h;
T8 := A and T7;
f := T3 xor T8;
t10 := A or d;
t11 := T1 xor T7;
e := t10 xor t11;
t13 := A xor c;
t14 := b and t10;
t15 := T4 or t13;
g := t14 xor t15;
e := e xor l_key[4 * (i - 3)];
f := f xor l_key[4 * (i - 3) + 1];
g := g xor l_key[4 * (i - 3) + 2];
h := h xor l_key[4 * (i - 3) + 3];
g := (g shr 22) or (g shl 10);
e := (e shr 5) or (e shl 27);
g := g xor h xor (f shl 7);
e := e xor f xor h;
h := (h shr 7) or (h shl 25);
f := (f shr 1) or (f shl 31);
h := h xor g xor (e shl 3);
f := f xor e xor g;
g := (g shr 3) or (g shl 29);
e := (e shr 13) or (e shl 19);
T1 := g xor h;
T2 := g or h;
T3 := f xor T2;
T4 := e and T3;
b := T1 xor T4;
T6 := e xor h;
T7 := f or h;
T8 := T6 and T7;
d := T3 xor T8;
t10 := not e;
t11 := g xor d;
t12 := t10 or t11;
A := T3 xor t12;
t14 := g or T4;
t15 := T7 xor t14;
t16 := d or t10;
c := t15 xor t16;
A := A xor l_key[4 * (i - 4)];
b := b xor l_key[4 * (i - 4) + 1];
c := c xor l_key[4 * (i - 4) + 2];
d := d xor l_key[4 * (i - 4) + 3];
c := (c shr 22) or (c shl 10);
A := (A shr 5) or (A shl 27);
c := c xor d xor (b shl 7);
A := A xor b xor d;
d := (d shr 7) or (d shl 25);
b := (b shr 1) or (b shl 31);
d := d xor c xor (A shl 3);
b := b xor A xor c;
c := (c shr 3) or (c shl 29);
A := (A shr 13) or (A shl 19);
T1 := b xor c;
T2 := b or c;
T3 := A xor c;
T4 := T2 xor T3;
T5 := d or T4;
e := T1 xor T5;
T7 := A xor d;
T8 := T1 or T5;
t9 := T2 xor T7;
g := T8 xor t9;
t11 := A and T4;
t12 := e or t9;
f := t11 xor t12;
t14 := A and g;
t15 := T2 xor t14;
t16 := e and t15;
h := T4 xor t16;
e := e xor l_key[4 * (i - 5)];
f := f xor l_key[4 * (i - 5) + 1];
g := g xor l_key[4 * (i - 5) + 2];
h := h xor l_key[4 * (i - 5) + 3];
g := (g shr 22) or (g shl 10);
e := (e shr 5) or (e shl 27);
g := g xor h xor (f shl 7);
e := e xor f xor h;
h := (h shr 7) or (h shl 25);
f := (f shr 1) or (f shl 31);
h := h xor g xor (e shl 3);
f := f xor e xor g;
g := (g shr 3) or (g shl 29);
e := (e shr 13) or (e shl 19);
T1 := f xor h;
T2 := not T1;
T3 := e xor g;
T4 := g xor T1;
T5 := f and T4;
A := T3 xor T5;
T7 := e or T2;
T8 := h xor T7;
t9 := T3 or T8;
d := T1 xor t9;
t11 := not T4;
t12 := A or d;
b := t11 xor t12;
t14 := h and t11;
t15 := T3 xor t12;
c := t14 xor t15;
A := A xor l_key[4 * (i - 6)];
b := b xor l_key[4 * (i - 6) + 1];
c := c xor l_key[4 * (i - 6) + 2];
d := d xor l_key[4 * (i - 6) + 3];
c := (c shr 22) or (c shl 10);
A := (A shr 5) or (A shl 27);
c := c xor d xor (b shl 7);
A := A xor b xor d;
d := (d shr 7) or (d shl 25);
b := (b shr 1) or (b shl 31);
d := d xor c xor (A shl 3);
b := b xor A xor c;
c := (c shr 3) or (c shl 29);
A := (A shr 13) or (A shl 19);
T1 := A xor d;
T2 := A and b;
T3 := b xor c;
T4 := A xor T3;
T5 := b or d;
h := T4 xor T5;
T7 := c or T1;
T8 := b xor T7;
t9 := T4 and T8;
f := T1 xor t9;
t11 := not T2;
t12 := h and f;
t13 := t9 xor t11;
g := t12 xor t13;
t15 := A and d;
t16 := c xor t13;
e := t15 xor t16;
e := e xor l_key[4 * (i - 7)];
f := f xor l_key[4 * (i - 7) + 1];
g := g xor l_key[4 * (i - 7) + 2];
h := h xor l_key[4 * (i - 7) + 3];
g := (g shr 22) or (g shl 10);
e := (e shr 5) or (e shl 27);
g := g xor h xor (f shl 7);
e := e xor f xor h;
h := (h shr 7) or (h shl 25);
f := (f shr 1) or (f shl 31);
h := h xor g xor (e shl 3);
f := f xor e xor g;
g := (g shr 3) or (g shl 29);
e := (e shr 13) or (e shl 19);
T1 := e xor h;
T2 := g xor h;
T3 := not T2;
T4 := e or f;
c := T3 xor T4;
T6 := f xor T1;
T7 := g or T6;
T8 := e xor T7;
t9 := T2 and T8;
b := T6 xor t9;
t11 := not T8;
t12 := f and h;
t13 := b or t12;
d := t11 xor t13;
t15 := T2 xor t12;
t16 := b or d;
A := t15 xor t16;
A := A xor l_key[4 * (i - 8)];
b := b xor l_key[4 * (i - 8) + 1];
c := c xor l_key[4 * (i - 8) + 2];
d := d xor l_key[4 * (i - 8) + 3];
Dec(i, 8);
end;
Pdword(longword(@Outdata) + 0)^ := A;
Pdword(longword(@Outdata) + 4)^ := b;
Pdword(longword(@Outdata) + 8)^ := c;
Pdword(longword(@Outdata) + 12)^ := d;
end;
var
MDS: array[0..3, 0..255] of DWORD;
MDSDone: Boolean;
function LFSR1(x: DWORD): DWORD;
begin
if (x and 1) <> 0 then
Result := (x shr 1) xor (MDS_GF_FDBK div 2)
else
Result := (x shr 1);
end;
function LFSR2(x: DWORD): DWORD;
begin
if (x and 2) <> 0 then
if (x and 1) <> 0 then
Result := (x shr 2) xor (MDS_GF_FDBK div 2) xor (MDS_GF_FDBK div 4)
else
Result := (x shr 2) xor (MDS_GF_FDBK div 2)
else if (x and 1) <> 0 then
Result := (x shr 2) xor (MDS_GF_FDBK div 4)
else
Result := (x shr 2);
end;
function Mul_X(x: DWORD): DWORD;
begin
Result := x xor LFSR2(x);
end;
function Mul_Y(x: DWORD): DWORD;
begin
Result := x xor LFSR1(x) xor LFSR2(x);
end;
function RS_MDS_Encode(lK0, lK1: DWORD): DWORD;
var
lR, nJ, lG2, lG3: DWORD;
bB: byte;
begin
lR := lK1;
for nJ := 0 to 3 do begin
bB := lR shr 24;
if (bB and $80) <> 0 then
lG2 := ((bB shl 1) xor RS_GF_FDBK) and $FF
else
lG2 := (bB shl 1) and $FF;
if (bB and 1) <> 0 then
lG3 := ((bB shr 1) and $7F) xor (RS_GF_FDBK shr 1) xor lG2
else
lG3 := ((bB shr 1) and $7F) xor lG2;
lR := (lR shl 8) xor (lG3 shl 24) xor (lG2 shl 16) xor (lG3 shl 8) xor bB;
end;
lR := lR xor lK0;
for nJ := 0 to 3 do begin
bB := lR shr 24;
if (bB and $80) <> 0 then
lG2 := ((bB shl 1) xor RS_GF_FDBK) and $FF
else
lG2 := (bB shl 1) and $FF;
if (bB and 1) <> 0 then
lG3 := ((bB shr 1) and $7F) xor (RS_GF_FDBK shr 1) xor lG2
else
lG3 := ((bB shr 1) and $7F) xor lG2;
lR := (lR shl 8) xor (lG3 shl 24) xor (lG2 shl 16) xor (lG3 shl 8) xor bB;
end;
Result := lR;
end;
function f32(x: DWORD; K32: Pdwordarray; Len: DWORD): DWORD;
var
t0, T1, T2, T3: DWORD;
begin
t0 := x and $FF;
T1 := (x shr 8) and $FF;
T2 := (x shr 16) and $FF;
T3 := x shr 24;
if Len = 256 then begin
t0 := p8x8[1, t0] xor ((K32^[3]) and $FF);
T1 := p8x8[0, T1] xor ((K32^[3] shr 8) and $FF);
T2 := p8x8[0, T2] xor ((K32^[3] shr 16) and $FF);
T3 := p8x8[1, T3] xor ((K32^[3] shr 24));
end;
if Len >= 192 then begin
t0 := p8x8[1, t0] xor ((K32^[2]) and $FF);
T1 := p8x8[1, T1] xor ((K32^[2] shr 8) and $FF);
T2 := p8x8[0, T2] xor ((K32^[2] shr 16) and $FF);
T3 := p8x8[0, T3] xor ((K32^[2] shr 24));
end;
Result := MDS[0, p8x8[0, p8x8[0, t0] xor ((K32^[1]) and $FF)] xor ((K32^[0]) and $FF)] xor
MDS[1, p8x8[0, p8x8[1, T1] xor ((K32^[1] shr 8) and $FF)] xor ((K32^[0] shr 8) and $FF)] xor
MDS[2, p8x8[1, p8x8[0, T2] xor ((K32^[1] shr 16) and $FF)] xor ((K32^[0] shr 16) and $FF)] xor
MDS[3, p8x8[1, p8x8[1, T3] xor ((K32^[1] shr 24))] xor ((K32^[0] shr 24))];
end;
procedure Xor256(Dst, Src: Pdwordarray; v: byte);
var
i, j: DWORD;
begin
i := 0;
j := v * $01010101;
while i < 64 do begin
Dst^[i] := Src^[i] xor j;
Dst^[i + 1] := Src^[i + 1] xor j;
Dst^[i + 2] := Src^[i + 2] xor j;
Dst^[i + 3] := Src^[i + 3] xor j;
Inc(i, 4);
end;
end;
procedure PreCompMDS;
var
m1, mx, my: array[0..1] of DWORD;
nI: longword;
begin
for nI := 0 to 255 do begin
m1[0] := p8x8[0, nI];
mx[0] := Mul_X(m1[0]);
my[0] := Mul_Y(m1[0]);
m1[1] := p8x8[1, nI];
mx[1] := Mul_X(m1[1]);
my[1] := Mul_Y(m1[1]);
MDS[0, nI] := (m1[1] shl 0) or
(mx[1] shl 8) or
(my[1] shl 16) or
(my[1] shl 24);
MDS[1, nI] := (my[0] shl 0) or
(my[0] shl 8) or
(mx[0] shl 16) or
(m1[0] shl 24);
MDS[2, nI] := (mx[1] shl 0) or
(my[1] shl 8) or
(m1[1] shl 16) or
(my[1] shl 24);
MDS[3, nI] := (mx[0] shl 0) or
(m1[0] shl 8) or
(my[0] shl 16) or
(mx[0] shl 24);
end;
end;
{--------------------}
{ Destructor ������� }
{--------------------}
destructor TTwoFish.Destroy;
begin
// All Strings := '';
// Free_And_Nil(All PObj);
inherited;
end;
////////////////////////////////////////////////////////////////////////////////
{-----------------------------}
{ ����������� ��� KOL ������� }
{-----------------------------}
function NewTwofish;
begin
New(Result, Create);
if not MDSDone then begin
PreCompMDS;
MDSDone := True;
end;
// code
end;
////////////////////////////////////////////////////////////////////////////////
procedure TTwoFish.InitKey(const Key; Size: longword);
const
subkeyCnt = ROUNDSUBKEYS + 2 * NUMROUNDSTF;
var
key32: array[0..7] of DWORD;
k32e, k32o, sboxkeys: array[0..3] of DWORD;
k64Cnt, i, j, A, b, q: DWORD;
L0, L1: array[0..255] of byte;
begin
Burn;
FillChar(key32, Sizeof(key32), 0);
Move(Key, key32, Size div 8);
if Size <= 128 then { pad the key to either 128bit, 192bit or 256bit}
Size := 128
else if Size <= 192 then
Size := 192
else
Size := 256;
k64Cnt := Size div 64;
j := k64Cnt - 1;
for i := 0 to j do begin
k32e[i] := key32[2 * i];
k32o[i] := key32[2 * i + 1];
sboxkeys[j] := RS_MDS_Encode(k32e[i], k32o[i]);
Dec(j);
end;
q := 0;
for i := 0 to ((subkeyCnt div 2) - 1) do begin
A := f32(q, @k32e, Size);
b := f32(q + SK_BUMP, @k32o, Size);
b := (b shl 8) or (b shr 24);
SubKeys[2 * i] := A + b;
b := A + 2 * b;
SubKeys[2 * i + 1] := (b shl SK_ROTL) or (b shr (32 - SK_ROTL));
Inc(q, SK_STEP);
end;
case Size of
128: begin
Xor256(@L0, @p8x8[0], (sboxkeys[1] and $FF));
A := (sboxkeys[0] and $FF);
i := 0;
while i < 256 do begin
SBox[0 and 2, 2 * i + (0 and 1)] := MDS[0, p8x8[0, L0[i]] xor A];
SBox[0 and 2, 2 * i + (0 and 1) + 2] := MDS[0, p8x8[0, L0[i + 1]] xor A];
Inc(i, 2);
end;
Xor256(@L0, @p8x8[1], (sboxkeys[1] shr 8) and $FF);
A := (sboxkeys[0] shr 8) and $FF;
i := 0;
while i < 256 do begin
SBox[1 and 2, 2 * i + (1 and 1)] := MDS[1, p8x8[0, L0[i]] xor A];
SBox[1 and 2, 2 * i + (1 and 1) + 2] := MDS[1, p8x8[0, L0[i + 1]] xor A];
Inc(i, 2);
end;
Xor256(@L0, @p8x8[0], (sboxkeys[1] shr 16) and $FF);
A := (sboxkeys[0] shr 16) and $FF;
i := 0;
while i < 256 do begin
SBox[2 and 2, 2 * i + (2 and 1)] := MDS[2, p8x8[1, L0[i]] xor A];
SBox[2 and 2, 2 * i + (2 and 1) + 2] := MDS[2, p8x8[1, L0[i + 1]] xor A];
Inc(i, 2);
end;
Xor256(@L0, @p8x8[1], (sboxkeys[1] shr 24));
A := (sboxkeys[0] shr 24);
i := 0;
while i < 256 do begin
SBox[3 and 2, 2 * i + (3 and 1)] := MDS[3, p8x8[1, L0[i]] xor A];
SBox[3 and 2, 2 * i + (3 and 1) + 2] := MDS[3, p8x8[1, L0[i + 1]] xor A];
Inc(i, 2);
end;
end;
192: begin
Xor256(@L0, @p8x8[1], sboxkeys[2] and $FF);
A := sboxkeys[0] and $FF;
b := sboxkeys[1] and $FF;
i := 0;
while i < 256 do begin
SBox[0 and 2, 2 * i + (0 and 1)] := MDS[0, p8x8[0, p8x8[0, L0[i]] xor b] xor A];
SBox[0 and 2, 2 * i + (0 and 1) + 2] := MDS[0, p8x8[0, p8x8[0, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
Xor256(@L0, @p8x8[1], (sboxkeys[2] shr 8) and $FF);
A := (sboxkeys[0] shr 8) and $FF;
b := (sboxkeys[1] shr 8) and $FF;
i := 0;
while i < 256 do begin
SBox[1 and 2, 2 * i + (1 and 1)] := MDS[1, p8x8[0, p8x8[1, L0[i]] xor b] xor A];
SBox[1 and 2, 2 * i + (1 and 1) + 2] := MDS[1, p8x8[0, p8x8[1, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
Xor256(@L0, @p8x8[0], (sboxkeys[2] shr 16) and $FF);
A := (sboxkeys[0] shr 16) and $FF;
b := (sboxkeys[1] shr 16) and $FF;
i := 0;
while i < 256 do begin
SBox[2 and 2, 2 * i + (2 and 1)] := MDS[2, p8x8[1, p8x8[0, L0[i]] xor b] xor A];
SBox[2 and 2, 2 * i + (2 and 1) + 2] := MDS[2, p8x8[1, p8x8[0, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
Xor256(@L0, @p8x8[0], (sboxkeys[2] shr 24));
A := (sboxkeys[0] shr 24);
b := (sboxkeys[1] shr 24);
i := 0;
while i < 256 do begin
SBox[3 and 2, 2 * i + (3 and 1)] := MDS[3, p8x8[1, p8x8[1, L0[i]] xor b] xor A];
SBox[3 and 2, 2 * i + (3 and 1) + 2] := MDS[3, p8x8[1, p8x8[1, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
end;
256: begin
Xor256(@L1, @p8x8[1], (sboxkeys[3]) and $FF);
i := 0;
while i < 256 do begin
L0[i] := p8x8[1, L1[i]];
L0[i + 1] := p8x8[1, L1[i + 1]];
Inc(i, 2);
end;
Xor256(@L0, @L0, (sboxkeys[2]) and $FF);
A := (sboxkeys[0]) and $FF;
b := (sboxkeys[1]) and $FF;
i := 0;
while i < 256 do begin
SBox[0 and 2, 2 * i + (0 and 1)] := MDS[0, p8x8[0, p8x8[0, L0[i]] xor b] xor A];
SBox[0 and 2, 2 * i + (0 and 1) + 2] := MDS[0, p8x8[0, p8x8[0, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
Xor256(@L1, @p8x8[0], (sboxkeys[3] shr 8) and $FF);
i := 0;
while i < 256 do begin
L0[i] := p8x8[1, L1[i]];
L0[i + 1] := p8x8[1, L1[i + 1]];
Inc(i, 2);
end;
Xor256(@L0, @L0, (sboxkeys[2] shr 8) and $FF);
A := (sboxkeys[0] shr 8) and $FF;
b := (sboxkeys[1] shr 8) and $FF;
i := 0;
while i < 256 do begin
SBox[1 and 2, 2 * i + (1 and 1)] := MDS[1, p8x8[0, p8x8[1, L0[i]] xor b] xor A];
SBox[1 and 2, 2 * i + (1 and 1) + 2] := MDS[1, p8x8[0, p8x8[1, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
Xor256(@L1, @p8x8[0], (sboxkeys[3] shr 16) and $FF);
i := 0;
while i < 256 do begin
L0[i] := p8x8[0, L1[i]];
L0[i + 1] := p8x8[0, L1[i + 1]];
Inc(i, 2);
end;
Xor256(@L0, @L0, (sboxkeys[2] shr 16) and $FF);
A := (sboxkeys[0] shr 16) and $FF;
b := (sboxkeys[1] shr 16) and $FF;
i := 0;
while i < 256 do begin
SBox[2 and 2, 2 * i + (2 and 1)] := MDS[2, p8x8[1, p8x8[0, L0[i]] xor b] xor A];
SBox[2 and 2, 2 * i + (2 and 1) + 2] := MDS[2, p8x8[1, p8x8[0, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
Xor256(@L1, @p8x8[1], (sboxkeys[3] shr 24));
i := 0;
while i < 256 do begin
L0[i] := p8x8[0, L1[i]];
L0[i + 1] := p8x8[0, L1[i + 1]];
Inc(i, 2);
end;
Xor256(@L0, @L0, (sboxkeys[2] shr 24));
A := (sboxkeys[0] shr 24);
b := (sboxkeys[1] shr 24);
i := 0;
while i < 256 do begin
SBox[3 and 2, 2 * i + (3 and 1)] := MDS[3, p8x8[1, p8x8[1, L0[i]] xor b] xor A];
SBox[3 and 2, 2 * i + (3 and 1) + 2] := MDS[3, p8x8[1, p8x8[1, L0[i + 1]] xor b] xor A];
Inc(i, 2);
end;
end;
end;
end;
procedure TTwoFish.Burn;
begin
FillChar(SBox, Sizeof(SBox), $FF);
FillChar(SubKeys, Sizeof(SubKeys), $FF);
inherited Burn;
end;
procedure TTwoFish.EncryptECB(const Indata; var Outdata);
var
i: longword;
t0, T1: DWORD;
x: array[0..3] of DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
x[0] := Pdword(@Indata)^ xor SubKeys[INPUTWHITEN];
x[1] := Pdword(longword(@Indata) + 4)^ xor SubKeys[INPUTWHITEN + 1];
x[2] := Pdword(longword(@Indata) + 8)^ xor SubKeys[INPUTWHITEN + 2];
x[3] := Pdword(longword(@Indata) + 12)^ xor SubKeys[INPUTWHITEN + 3];
i := 0;
while i <= NUMROUNDSTF - 2 do begin
t0 := SBox[0, (x[0] shl 1) and $1FE] xor SBox[0, ((x[0] shr 7) and $1FE) + 1]
xor SBox[2, (x[0] shr 15) and $1FE] xor SBox[2, ((x[0] shr 23) and $1FE) + 1];
T1 := SBox[0, ((x[1] shr 23) and $1FE)] xor SBox[0, ((x[1] shl 1) and $1FE) + 1]
xor SBox[2, ((x[1] shr 7) and $1FE)] xor SBox[2, ((x[1] shr 15) and $1FE) + 1];
x[3] := (x[3] shl 1) or (x[3] shr 31);
x[2] := x[2] xor (t0 + T1 + SubKeys[ROUNDSUBKEYS + 2 * i]);
x[3] := x[3] xor (t0 + 2 * T1 + SubKeys[ROUNDSUBKEYS + 2 * i + 1]);
x[2] := (x[2] shr 1) or (x[2] shl 31);
t0 := SBox[0, (x[2] shl 1) and $1FE] xor SBox[0, ((x[2] shr 7) and $1FE) + 1]
xor SBox[2, ((x[2] shr 15) and $1FE)] xor SBox[2, ((x[2] shr 23) and $1FE) + 1];
T1 := SBox[0, ((x[3] shr 23) and $1FE)] xor SBox[0, ((x[3] shl 1) and $1FE) + 1]
xor SBox[2, ((x[3] shr 7) and $1FE)] xor SBox[2, ((x[3] shr 15) and $1FE) + 1];
x[1] := (x[1] shl 1) or (x[1] shr 31);
x[0] := x[0] xor (t0 + T1 + SubKeys[ROUNDSUBKEYS + 2 * (i + 1)]);
x[1] := x[1] xor (t0 + 2 * T1 + SubKeys[ROUNDSUBKEYS + 2 * (i + 1) + 1]);
x[0] := (x[0] shr 1) or (x[0] shl 31);
Inc(i, 2);
end;
Pdword(longword(@Outdata) + 0)^ := x[2] xor SubKeys[OUTPUTWHITEN];
Pdword(longword(@Outdata) + 4)^ := x[3] xor SubKeys[OUTPUTWHITEN + 1];
Pdword(longword(@Outdata) + 8)^ := x[0] xor SubKeys[OUTPUTWHITEN + 2];
Pdword(longword(@Outdata) + 12)^ := x[1] xor SubKeys[OUTPUTWHITEN + 3];
end;
procedure TTwoFish.DecryptECB(const Indata; var Outdata);
var
i: Integer;
t0, T1: DWORD;
x: array[0..3] of DWORD;
begin
// if not fInitialized then
// raise EDCP_blockcipher.Create('Cipher not initialized');
x[2] := Pdword(@Indata)^ xor SubKeys[OUTPUTWHITEN];
x[3] := Pdword(longword(@Indata) + 4)^ xor SubKeys[OUTPUTWHITEN + 1];
x[0] := Pdword(longword(@Indata) + 8)^ xor SubKeys[OUTPUTWHITEN + 2];
x[1] := Pdword(longword(@Indata) + 12)^ xor SubKeys[OUTPUTWHITEN + 3];
i := NUMROUNDSTF - 2;
while i >= 0 do begin
t0 := SBox[0, (x[2] shl 1) and $1FE] xor SBox[0, ((x[2] shr 7) and $1FE) + 1]
xor SBox[2, ((x[2] shr 15) and $1FE)] xor SBox[2, ((x[2] shr 23) and $1FE) + 1];
T1 := SBox[0, ((x[3] shr 23) and $1FE)] xor SBox[0, ((x[3] shl 1) and $1FE) + 1]
xor SBox[2, ((x[3] shr 7) and $1FE)] xor SBox[2, ((x[3] shr 15) and $1FE) + 1];
x[0] := (x[0] shl 1) or (x[0] shr 31);
x[0] := x[0] xor (t0 + T1 + SubKeys[ROUNDSUBKEYS + 2 * (i + 1)]);
x[1] := x[1] xor (t0 + 2 * T1 + SubKeys[ROUNDSUBKEYS + 2 * (i + 1) + 1]);
x[1] := (x[1] shr 1) or (x[1] shl 31);
t0 := SBox[0, (x[0] shl 1) and $1FE] xor SBox[0, ((x[0] shr 7) and $1FE) + 1]
xor SBox[2, (x[0] shr 15) and $1FE] xor SBox[2, ((x[0] shr 23) and $1FE) + 1];
T1 := SBox[0, ((x[1] shr 23) and $1FE)] xor SBox[0, ((x[1] shl 1) and $1FE) + 1]
xor SBox[2, ((x[1] shr 7) and $1FE)] xor SBox[2, ((x[1] shr 15) and $1FE) + 1];
x[2] := (x[2] shl 1) or (x[2] shr 31);
x[2] := x[2] xor (t0 + T1 + SubKeys[ROUNDSUBKEYS + 2 * i]);
x[3] := x[3] xor (t0 + 2 * T1 + SubKeys[ROUNDSUBKEYS + 2 * i + 1]);
x[3] := (x[3] shr 1) or (x[3] shl 31);
Dec(i, 2);
end;
Pdword(longword(@Outdata) + 0)^ := x[0] xor SubKeys[INPUTWHITEN];
Pdword(longword(@Outdata) + 4)^ := x[1] xor SubKeys[INPUTWHITEN + 1];
Pdword(longword(@Outdata) + 8)^ := x[2] xor SubKeys[INPUTWHITEN + 2];
Pdword(longword(@Outdata) + 12)^ := x[3] xor SubKeys[INPUTWHITEN + 3];
end;
initialization
ice_sboxdone := False;
MDSDone := False;
end.