⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 skipjack.pas

📁 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 + -