📄 skipjack.pas
字号:
unit Skipjack; //Key must over 8 bits, use CRC deal it
interface
uses
Windows, Sysutils;
type
TSkipjackData = record
InitBlock: array[0..7] of Byte; //Initial IV
LastBlock: array[0..7] of Byte; //Current IV
XKey: array[0..9, 0..255] of Byte;
end;
procedure SkipjackInit(var Data: TSkipjackData; Key: Pointer;
Len: Integer; IV: Pointer);
procedure SkipjackBurn(var Data: TSkipjackData);
procedure SkipjackReset(var Data: TSkipjackData);
procedure SkipjackEncryptECB(var Data: TSkipjackData;
InData, OutData: Pointer);
procedure SkipjackEncryptCBC(var Data: TSkipjackData;
InData, OutData: Pointer);
procedure SkipjackDecryptECB(var Data: TSkipjackData;
InData, OutData: Pointer);
procedure SkipjackDecryptCBC(var Data: TSkipjackData;
InData, OutData: Pointer);
procedure SkipjackEncrypt(Data: Pointer; Len: Integer; Key: string);
procedure SkipjackDecrypt(Data: Pointer; Len: Integer; Key: string);
implementation
type
PXKey = ^TXKey;
TXKey = array[0..9, 0..255] of Byte;
const
fTable: array[0..255] of Byte= (
$a3,$d7,$09,$83,$f8,$48,$f6,$f4,$b3,$21,$15,$78,$99,$b1,$af,$f9,
$e7,$2d,$4d,$8a,$ce,$4c,$ca,$2e,$52,$95,$d9,$1e,$4e,$38,$44,$28,
$0a,$df,$02,$a0,$17,$f1,$60,$68,$12,$b7,$7a,$c3,$e9,$fa,$3d,$53,
$96,$84,$6b,$ba,$f2,$63,$9a,$19,$7c,$ae,$e5,$f5,$f7,$16,$6a,$a2,
$39,$b6,$7b,$0f,$c1,$93,$81,$1b,$ee,$b4,$1a,$ea,$d0,$91,$2f,$b8,
$55,$b9,$da,$85,$3f,$41,$bf,$e0,$5a,$58,$80,$5f,$66,$0b,$d8,$90,
$35,$d5,$c0,$a7,$33,$06,$65,$69,$45,$00,$94,$56,$6d,$98,$9b,$76,
$97,$fc,$b2,$c2,$b0,$fe,$db,$20,$e1,$eb,$d6,$e4,$dd,$47,$4a,$1d,
$42,$ed,$9e,$6e,$49,$3c,$cd,$43,$27,$d2,$07,$d4,$de,$c7,$67,$18,
$89,$cb,$30,$1f,$8d,$c6,$8f,$aa,$c8,$74,$dc,$c9,$5d,$5c,$31,$a4,
$70,$88,$61,$2c,$9f,$0d,$2b,$87,$50,$82,$54,$64,$26,$7d,$03,$40,
$34,$4b,$1c,$73,$d1,$c4,$fd,$3b,$cc,$fb,$7f,$ab,$e6,$3e,$5b,$a5,
$ad,$04,$23,$9c,$14,$51,$22,$f0,$29,$79,$71,$7e,$ff,$8c,$0e,$e2,
$0c,$ef,$bc,$72,$75,$6f,$37,$a1,$ec,$d3,$8e,$62,$8b,$86,$10,$e8,
$08,$77,$11,$be,$92,$4f,$24,$c5,$32,$36,$9d,$cf,$f3,$a6,$bb,$ac,
$5e,$6c,$a9,$13,$57,$25,$b5,$e3,$bd,$a8,$3a,$01,$05,$59,$2a,$46);
procedure XorBlock(I1, I2, O1: PByteArray; Len: Integer);
var
i: Integer;
begin
for i := 0 to Len - 1 do
O1[i] := I1[i] xor I2[i];
end;
procedure SkipjackInit(var Data: TSkipjackData; Key: Pointer;
Len: Integer; IV: Pointer);
var
i, j: Integer;
KeyB: PByteArray;
begin
{if (Len<= 0) or (Len> 128) then
raise Exception.Create('Skipjack: Invalid key length');}
KeyB := 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 9 do
for j := 0 to 255 do
XKey[i, j] := fTable[j xor KeyB[i]];
end;
end;
procedure SkipjackBurn(var Data: TSkipjackData);
begin
FillChar(Data, Sizeof(Data), 0);
end;
procedure G(Tab: PXKey; var W: Word; i, j, k, l: Byte);
begin
W := W xor (Integer(Tab[i, W and $FF]) shl 8);
W := W xor Integer(Tab[j, W shr 8]);
W := W xor (Integer(Tab[k, W and $FF]) shl 8);
W := W xor Integer(Tab[l, W shr 8]);
end;
procedure G0(Tab: PXKey; var W: Word);
begin
G(Tab, W, 0, 1, 2, 3);
end;
procedure G1(Tab: PXKey; var W: Word);
begin
G(Tab, W, 4, 5, 6, 7);
end;
procedure G2(Tab: PXKey; var W: Word);
begin
G(Tab, W, 8, 9, 0, 1);
end;
procedure G3(Tab: PXKey; var W: Word);
begin
G(Tab, W, 2, 3, 4, 5);
end;
procedure G4(Tab: PXKey; var W: Word);
begin
G(Tab, W, 6, 7, 8, 9);
end;
procedure H(Tab: PXKey; var W: Word; i, j, k, l: Byte);
begin
W := W xor Word(Tab[l, W shr 8]);
W := W xor (Word(Tab[k, W and $FF]) shl 8);
W := W xor Word(Tab[j, W shr 8]);
W := W xor (Word(Tab[i, W and $FF]) shl 8);
end;
procedure H0(Tab: PXKey; var W: Word);
begin
H(Tab, W, 0, 1, 2, 3);
end;
procedure H1(Tab: PXKey; var W: Word);
begin
H(Tab, W, 4, 5, 6, 7);
end;
procedure H2(Tab: PXKey; var W: Word);
begin
H(Tab, W, 8, 9, 0, 1);
end;
procedure H3(Tab: PXKey; var W: Word);
begin
H(Tab, W, 2, 3, 4, 5);
end;
procedure H4(Tab: PXKey; var W: Word);
begin
H(Tab, W, 6, 7, 8, 9);
end;
procedure SkipjackEncryptECB(var Data: TSkipjackData;
InData, OutData: Pointer);
var
w1, w2, w3, w4: Word;
begin
Move(InData^, w1, 2);
Move(pointer(Integer(InData) + 2)^, w2, 2);
Move(pointer(Integer(InData) + 4)^, w3, 2);
Move(pointer(Integer(InData) + 6)^, w4, 2);
w1 := (w1 shl 8) or (w1 shr 8);
w2 := (w2 shl 8) or (w2 shr 8);
w3 := (w3 shl 8) or (w3 shr 8);
w4 := (w4 shl 8) or (w4 shr 8);
G0(@Data.XKey, w1);
w4 := w4 xor w1 xor 1;
G1(@Data.XKey, w4);
w3 := w3 xor w4 xor 2;
G2(@Data.XKey, w3);
w2 := w2 xor w3 xor 3;
G3(@Data.XKey, w2);
w1 := w1 xor w2 xor 4;
G4(@Data.XKey, w1);
w4 := w4 xor w1 xor 5;
G0(@Data.XKey, w4);
w3 := w3 xor w4 xor 6;
G1(@Data.XKey, w3);
w2 := w2 xor w3 xor 7;
G2(@Data.XKey, w2);
w1 := w1 xor w2 xor 8;
w2 := w2 xor w1 xor 9;
G3(@Data.XKey, w1);
w1 := w1 xor w4 xor 10;
G4(@Data.XKey, w4);
w4 := w4 xor w3 xor 11;
G0(@Data.XKey, w3);
w3 := w3 xor w2 xor 12;
G1(@Data.XKey, w2);
w2 := w2 xor w1 xor 13;
G2(@Data.XKey, w1);
w1 := w1 xor w4 xor 14;
G3(@Data.XKey, w4);
w4 := w4 xor w3 xor 15;
G4(@Data.XKey, w3);
w3 := w3 xor w2 xor 16;
G0(@Data.XKey, w2);
G1(@Data.XKey, w1);
w4 := w4 xor w1 xor 17;
G2(@Data.XKey, w4);
w3 := w3 xor w4 xor 18;
G3(@Data.XKey, w3);
w2 := w2 xor w3 xor 19;
G4(@Data.XKey, w2);
w1 := w1 xor w2 xor 20;
G0(@Data.XKey, w1);
w4 := w4 xor w1 xor 21;
G1(@Data.XKey, w4);
w3 := w3 xor w4 xor 22;
G2(@Data.XKey, w3);
w2 := w2 xor w3 xor 23;
G3(@Data.XKey, w2);
w1 := w1 xor w2 xor 24;
w2 := w2 xor w1 xor 25;
G4(@Data.XKey, w1);
w1 := w1 xor w4 xor 26;
G0(@Data.XKey, w4);
w4 := w4 xor w3 xor 27;
G1(@Data.XKey, w3);
w3 := w3 xor w2 xor 28;
G2(@Data.XKey, w2);
w2 := w2 xor w1 xor 29;
G3(@Data.XKey, w1);
w1 := w1 xor w4 xor 30;
G4(@Data.XKey, w4);
w4 := w4 xor w3 xor 31;
G0(@Data.XKey, w3);
w3 := w3 xor w2 xor 32;
G1(@Data.XKey, w2);
w1 := (w1 shl 8) or (w1 shr 8);
w2 := (w2 shl 8) or (w2 shr 8);
w3 := (w3 shl 8) or (w3 shr 8);
w4 := (w4 shl 8) or (w4 shr 8);
Move(w1, OutData^, 2);
Move(w2, pointer(Integer(OutData) + 2)^, 2);
Move(w3, pointer(Integer(OutData) + 4)^, 2);
Move(w4, pointer(Integer(OutData) + 6)^, 2);
end;
procedure SkipjackDecryptECB(var Data: TSkipjackData;
InData, OutData: Pointer);
var
w1, w2, w3, w4: Word;
begin
Move(InData^, w1, 2);
Move(pointer(Integer(InData) + 2)^, w2, 2);
Move(pointer(Integer(InData) + 4)^, w3, 2);
Move(pointer(Integer(InData) + 6)^, w4, 2);
w1 := (w1 shl 8) or (w1 shr 8);
w2 := (w2 shl 8) or (w2 shr 8);
w3 := (w3 shl 8) or (w3 shr 8);
w4 := (w4 shl 8) or (w4 shr 8);
H1(@Data.XKey, w2);
w3 := w3 xor w2 xor 32;
H0(@Data.XKey, w3);
w4 := w4 xor w3 xor 31;
H4(@Data.XKey, w4);
w1 := w1 xor w4 xor 30;
H3(@Data.XKey, w1);
w2 := w2 xor w1 xor 29;
H2(@Data.XKey, w2);
w3 := w3 xor w2 xor 28;
H1(@Data.XKey, w3);
w4 := w4 xor w3 xor 27;
H0(@Data.XKey, w4);
w1 := w1 xor w4 xor 26;
H4(@Data.XKey, w1);
w2 := w2 xor w1 xor 25;
w1 := w1 xor w2 xor 24;
H3(@Data.XKey, w2);
w2 := w2 xor w3 xor 23;
H2(@Data.XKey, w3);
w3 := w3 xor w4 xor 22;
H1(@Data.XKey, w4);
w4 := w4 xor w1 xor 21;
H0(@Data.XKey, w1);
w1 := w1 xor w2 xor 20;
H4(@Data.XKey, w2);
w2 := w2 xor w3 xor 19;
H3(@Data.XKey, w3);
w3 := w3 xor w4 xor 18;
H2(@Data.XKey, w4);
w4 := w4 xor w1 xor 17;
H1(@Data.XKey, w1);
H0(@Data.XKey, w2);
w3 := w3 xor w2 xor 16;
H4(@Data.XKey, w3);
w4 := w4 xor w3 xor 15;
H3(@Data.XKey, w4);
w1 := w1 xor w4 xor 14;
H2(@Data.XKey, w1);
w2 := w2 xor w1 xor 13;
H1(@Data.XKey, w2);
w3 := w3 xor w2 xor 12;
H0(@Data.XKey, w3);
w4 := w4 xor w3 xor 11;
H4(@Data.XKey, w4);
w1 := w1 xor w4 xor 10;
H3(@Data.XKey, w1);
w2 := w2 xor w1 xor 9;
w1 := w1 xor w2 xor 8;
H2(@Data.XKey, w2);
w2 := w2 xor w3 xor 7;
H1(@Data.XKey, w3);
w3 := w3 xor w4 xor 6;
H0(@Data.XKey, w4);
w4 := w4 xor w1 xor 5;
H4(@Data.XKey, w1);
w1 := w1 xor w2 xor 4;
H3(@Data.XKey, w2);
w2 := w2 xor w3 xor 3;
H2(@Data.XKey, w3);
w3 := w3 xor w4 xor 2;
H1(@Data.XKey, w4);
w4 := w4 xor w1 xor 1;
H0(@Data.XKey, w1);
w1 := (w1 shl 8) or (w1 shr 8);
w2 := (w2 shl 8) or (w2 shr 8);
w3 := (w3 shl 8) or (w3 shr 8);
w4 := (w4 shl 8) or (w4 shr 8);
Move(w1, OutData^, 2);
Move(w2, pointer(Integer(OutData) + 2)^, 2);
Move(w3, pointer(Integer(OutData) + 4)^, 2);
Move(w4, pointer(Integer(OutData) + 6)^, 2);
end;
procedure SkipjackEncryptCBC(var Data: TSkipjackData;
InData, OutData: Pointer);
begin
XorBlock(InData, @Data.LastBlock, OutData, 8);
SkipjackEncryptECB(Data, OutData, OutData);
Move(OutData^, Data.LastBlock, 8);
end;
procedure SkipjackDecryptCBC(var Data: TSkipjackData;
InData, OutData: Pointer);
var
TempBlock: array[0..7] of Byte;
begin
Move(InData^, TempBlock, 8);
SkipjackDecryptECB(Data, InData, OutData);
XorBlock(OutData, @Data.LastBlock, OutData, 8);
Move(TempBlock, Data.LastBlock, 8);
end;
procedure SkipjackReset(var Data: TSkipjackData);
begin
Move(Data.InitBlock, Data.LastBlock, 8);
end;
procedure SkipjackEncrypt(Data: Pointer; Len: Integer; Key: string);
var
i, Time: LongInt;
KeyData: TSkipjackData;
P: Pointer;
begin
SkipjackBurn(KeyData);
SkipjackInit(KeyData, PChar(Key), Length(Key), PChar(Key));
Time := Len div 8 - 1;
for i := 0 to Time do
begin
P := Ptr(LongInt(Data) + i * 8);
SkipjackEncryptCBC(KeyData, P, P);
end;
SkipjackBurn(KeyData);
end;
procedure SkipjackDecrypt(Data: Pointer; Len: Integer; Key: string);
var
i, Time: LongInt;
KeyData: TSkipjackData;
P: Pointer;
begin
SkipjackBurn(KeyData);
SkipjackInit(KeyData, PChar(Key), Length(Key), PChar(Key));
Time := Len div 8 - 1;
for i := 0 to Time do
begin
P := Ptr(LongInt(Data) + i * 8);
SkipjackDecryptCBC(KeyData, P, P);
end;
SkipjackBurn(KeyData);
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -