?? misty1.pas
字號:
{
***************************************************
* A binary compatible MISTY1 implementation *
* written by Dave Barton (davebarton@bigfoot.com) *
***************************************************
* 64bit block encryption *
* 128bit key size *
***************************************************
}
unit MISTY1;
interface
uses
Sysutils, Tools;
const
NUMROUNDS= 8;
type
TMISTY1Data= record
InitBlock: array[0..7] of byte; { initial IV }
LastBlock: array[0..7] of byte; { current IV }
EK: array[0..31] of DWord;
end;
function MISTY1SelfTest: boolean;
{ performs a self test on this implementation }
procedure MISTY1Init(var Data: TMISTY1Data; Key: pointer; Len: integer; IV: pointer);
{ initializes the TMISTY1Data structure with the key information and IV if applicable }
procedure MISTY1Burn(var Data: TMISTY1Data);
{ erases all information about the key }
procedure MISTY1EncryptECB(var Data: TMISTY1Data; InData, OutData: pointer);
{ encrypts the data in a 64bit block using the ECB mode }
procedure MISTY1EncryptCBC(var Data: TMISTY1Data; InData, OutData: pointer);
{ encrypts the data in a 64bit block using the CBC chaining mode }
procedure MISTY1EncryptOFB(var Data: TMISTY1Data; InData, OutData: pointer);
{ encrypts the data in a 64bit block using the OFB chaining mode }
procedure MISTY1EncryptCFB(var Data: TMISTY1Data; InData, OutData: pointer; Len: integer);
{ encrypts Len bytes of data using the CFB chaining mode }
procedure MISTY1EncryptOFBC(var Data: TMISTY1Data; InData, OutData: pointer; Len: integer);
{ encrypts Len bytes of data using the OFB counter chaining mode }
procedure MISTY1DecryptECB(var Data: TMISTY1Data; InData, OutData: pointer);
{ decrypts the data in a 64bit block using the ECB mode }
procedure MISTY1DecryptCBC(var Data: TMISTY1Data; InData, OutData: pointer);
{ decrypts the data in a 64bit block using the CBC chaining mode }
procedure MISTY1DecryptOFB(var Data: TMISTY1Data; InData, OutData: pointer);
{ decrypts the data in a 64bit block using the OFB chaining mode }
procedure MISTY1DecryptCFB(var Data: TMISTY1Data; InData, OutData: pointer; Len: integer);
{ decrypts Len bytes of data using the CFB chaining mode }
procedure MISTY1DecryptOFBC(var Data: TMISTY1Data; InData, OutData: pointer; Len: integer);
{ decrypts Len bytes of data using the OFB counter chaining mode }
procedure MISTY1Reset(var Data: TMISTY1Data);
{ resets the chaining mode information }
{******************************************************************************}
implementation
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);
function MISTY1SelfTest: boolean;
const
Key: array[0..15] of byte=
($00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff);
InBlock: array[0..1] of DWord=
($01234567, $89abcdef);
OutBlock: array[0..1] of DWord=
($8b1da5f5, $6ab3d07c);
var
Block: array[0..1] of DWord;
Data: TMISTY1Data;
begin
MISTY1Init(Data,@Key,Sizeof(Key),nil);
MISTY1EncryptECB(Data,@InBlock,@Block);
Result:= CompareMem(@Block,@OutBlock,Sizeof(Block)) or not (NUMROUNDS=8);
MISTY1DecryptECB(Data,@Block,@Block);
Result:= Result and CompareMem(@Block,@InBlock,Sizeof(Block));
MISTY1Burn(Data);
end;
function FI(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 FO(Data: TMISTY1Data; FO_IN: DWord; k: integer): DWord;
var
t0, t1: DWord;
begin
t0:= FO_IN shr 16;
t1:= FO_IN and $FFFF;
t0:= t0 xor Data.EK[k];
t0:= FI(t0,Data.EK[((k+5) mod 8) + 8]);
t0:= t0 xor t1;
t1:= t1 xor Data.EK[(k+2) mod 8];
t1:= FI(t1,Data.EK[((k+1) mod 8) + 8]);
t1:= t1 xor t0;
t0:= t0 xor Data.EK[(k+7) mod 8];
t0:= FI(t0,Data.EK[((k+3) mod 8) + 8]);
t0:= t0 xor t1;
t1:= t1 xor Data.EK[(k+4) mod 8];
Result:= (t1 shl 16) or t0;
end;
function FL(Data: TMISTY1Data; FL_IN: DWord; k: integer): 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 Data.EK[((t + 2) mod 8) + 8]);
d0:= d0 xor (d1 or Data.EK[(t + 4) mod 8]);
end
else
begin
t:= k div 2;
d1:= d1 xor (d0 and Data.EK[t]);
d0:= d0 xor (d1 or Data.EK[((t+6) mod 8) + 8]);
end;
Result:= (d0 shl 16) or d1;
end;
function FLINV(Data: TMISTY1Data; FL_IN: DWord; k: integer): 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 Data.EK[(t+4) mod 8]);
d1:= d1 xor (d0 and Data.EK[((t+2) mod 8) + 8]);
end
else
begin
t:= k div 2;
d0:= d0 xor (d1 or Data.EK[((t+6) mod 8) + 8]);
d1:= d1 xor (d0 and Data.EK[t]);
end;
Result:= (d0 shl 16) or d1;
end;
procedure MISTY1Init;
var
KeyW: PByteArray;
i: integer;
begin
if (Len<> 16) then
raise Exception.Create('MISTY1: Invalid key length');
KeyW:= Key;
with Data do
begin
if IV= nil then
begin
FillChar(InitBlock,8,0);
FillChar(LastBlock,8,0);
end
else
begin
Move(IV^,InitBlock,8);
Move(IV^,LastBlock,8);
end;
for i:= 0 to 7 do
EK[i]:= (KeyW[i*2] * 256) + KeyW[i*2+1];
for i:= 0 to 7 do
begin
EK[i+8]:= FI(EK[i],EK[(i+1) mod 8]);
EK[i+16]:= EK[i+8] and $1FF;
EK[i+24]:= EK[i+8] shr 9;
end;
end;
end;
procedure MISTY1Burn;
begin
FillChar(Data,Sizeof(Data),0);
end;
procedure MISTY1EncryptECB;
var
d0, d1: DWord;
i: integer;
begin
Move(InData^,d0,4);
Move(pointer(integer(InData)+4)^,d1,4);
for i:= 0 to NUMROUNDS-1 do
begin
if (i mod 2)= 0 then
begin
d0:= FL(Data,D0,i);
d1:= FL(Data,D1,i+1);
d1:= d1 xor FO(Data,d0,i);
end
else
d0:= d0 xor FO(Data,d1,i);
end;
d0:= FL(Data,d0,NUMROUNDS);
d1:= FL(Data,d1,NUMROUNDS+1);
Move(d1,OutData^,4);
Move(d0,pointer(integer(OutData)+4)^,4);
end;
procedure MISTY1DecryptECB;
var
d0, d1: DWord;
i: integer;
begin
Move(InData^,d1,4);
Move(pointer(integer(InData)+4)^,d0,4);
d1:= FLINV(Data,d1,NUMROUNDS+1);
d0:= FLINV(Data,d0,NUMROUNDS);
for i:= NUMROUNDS-1 downto 0 do
begin
if (i mod 2)= 0 then
begin
d1:= d1 xor FO(Data,d0,i);
d0:= FLINV(Data,D0,i);
d1:= FLINV(Data,D1,i+1);
end
else
d0:= d0 xor FO(Data,d1,i);
end;
Move(d0,OutData^,4);
Move(d1,pointer(integer(OutData)+4)^,4);
end;
procedure MISTY1EncryptCBC;
begin
XorBlock(InData,@Data.LastBlock,OutData,8);
MISTY1EncryptECB(Data,OutData,OutData);
Move(OutData^,Data.LastBlock,8);
end;
procedure MISTY1DecryptCBC;
var
TempBlock: array[0..7] of byte;
begin
Move(InData^,TempBlock,8);
MISTY1DecryptECB(Data,InData,OutData);
XorBlock(OutData,@Data.LastBlock,OutData,8);
Move(TempBlock,Data.LastBlock,8);
end;
procedure MISTY1EncryptCFB;
var
i: integer;
TempBlock: array[0..7] of byte;
begin
for i:= 0 to Len-1 do
begin
MISTY1EncryptECB(Data,@Data.LastBlock,@TempBlock);
PByteArray(OutData)[i]:= PByteArray(InData)[i] xor TempBlock[0];
Move(Data.LastBlock[1],Data.LastBlock[0],7);
Data.LastBlock[7]:= PByteArray(OutData)[i];
end;
end;
procedure MISTY1DecryptCFB;
var
i: integer;
TempBlock: array[0..7] of byte;
b: byte;
begin
for i:= 0 to Len-1 do
begin
b:= PByteArray(InData)[i];
MISTY1EncryptECB(Data,@Data.LastBlock,@TempBlock);
PByteArray(OutData)[i]:= PByteArray(InData)[i] xor TempBlock[0];
Move(Data.LastBlock[1],Data.LastBlock[0],7);
Data.LastBlock[7]:= b;
end;
end;
procedure MISTY1EncryptOFB;
begin
MISTY1EncryptECB(Data,@Data.LastBlock,@Data.LastBlock);
XorBlock(@Data.LastBlock,InData,OutData,8);
end;
procedure MISTY1DecryptOFB;
begin
MISTY1EncryptECB(Data,@Data.LastBlock,@Data.LastBlock);
XorBlock(@Data.LastBlock,InData,OutData,8);
end;
procedure MISTY1EncryptOFBC;
var
i: integer;
TempBlock: array[0..7] of byte;
begin
for i:= 0 to Len-1 do
begin
MISTY1EncryptECB(Data,@Data.LastBlock,@TempBlock);
PByteArray(OutData)[i]:= PByteArray(InData)[i] xor TempBlock[0];
IncBlock(@Data.LastBlock,8);
end;
end;
procedure MISTY1DecryptOFBC;
var
i: integer;
TempBlock: array[0..7] of byte;
begin
for i:= 0 to Len-1 do
begin
MISTY1EncryptECB(Data,@Data.LastBlock,@TempBlock);
PByteArray(OutData)[i]:= PByteArray(InData)[i] xor TempBlock[0];
IncBlock(@Data.LastBlock,8);
end;
end;
procedure MISTY1Reset;
begin
Move(Data.InitBlock,Data.LastBlock,8);
end;
end.
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -