📄 blowfish.~pas
字号:
var
i: longint;
j: longint;
s: string;
InputTemp: string;
begin
// check that we have a keys and IV
CheckKeys;
// initialise the output string
Output := '';
// check for zero length strings
if Length(Input) = 0 then
begin
// don't need to do anything
Exit;
end;
// decode the string if required
if FStringMode = smEncode then
begin
InputTemp := DecodeString(Input);
end
else
begin
InputTemp := Input;
end;
// check that the input is long enough
if Length(InputTemp) < BLOCKSIZE then
begin
raise EInputError.Create(LIT_INPUT_LENGTH);
end; {if Length}
// initialise the working string
s := '';
// preset the length of the 磜orking string
SetLength(s, Length(InputTemp));
// initialise the counters
i := 1;
j := 1;
// and step through the string
while i < (Length(InputTemp)) do
begin
// copy the next bytes into the context block buffer
Move(InputTemp[j], FBlowCore.ctx.ByteBuffer, BLOCKSIZE);
Inc(j, BLOCKSIZE);
// perform the decryption of the context
DecryptBlockMode;
// copy the block into the output string
Move(FBlowCore.ctx.ByteBuffer, s[i], BLOCKSIZE);
Inc(i, BLOCKSIZE);
end; {while i}
// Unpad Plain Text string
// Last byte is number of pad bytes
i := ord(s[Length(s)]);
if (i > 0) and (i <= BLOCKSIZE) then
begin
Output := Copy(s, 1,Length(s) - i);
end
else
begin
Output := Copy(s, 1,Length(s) - 1);
end; {if (i>0) and}
end; {DecString}
procedure TBlowfish.SetCipherMode(const Value: TCipherMode);
begin
FCipherMode := Value;
end; {TBlowfish.SetCipherMode}
procedure TBlowfish.SetStringMode(const Value: TStringMode);
begin
FStringMode := Value;
end; {TBlowfish.SetStringMode}
function TBlowfish.GetCipherMode: TCipherMode;
begin
Result := FCipherMode;
end; {TBlowfish.GetCipherMode}
function TBlowfish.GetStringMode: TStringMode;
begin
Result := FStringMode;
end; {TBlowfish.GetStringMode}
procedure TBlowfish.Burn;
begin
FillChar(FBlowCore.ctx, SizeOf(FBlowCore.ctx), #0);
ctx.KeyInit := False;
ctx.IVInit := False;
end;
procedure TBlowfish.EncryptBlockMode;
var
i:integer;
begin
FBlowCore.FPtrL := @FBlowCore.ctx.Longbuffer[0];
FBlowCore.FPtrR := @FBlowCore.ctx.Longbuffer[1];
case FCipherMode of
ECB:EndianEncBlock;
end;
end;
procedure TBlowfish.DecryptBlockMode;
var
i:integer;
begin
FBlowCore.FPtrL := @FBlowCore.ctx.Longbuffer[0];
FBlowCore.FPtrR := @FBlowCore.ctx.Longbuffer[1];
case FCipherMode of
ECB:EndianDecBlock;
end;
end;
procedure TBlowfish.CheckKeys;
begin
if not ctx.KeyInit then
begin
raise EKeyError.Create(LIT_KEY_NOT_SET);
Exit;
end;
if FCipherMode <> ECB then
begin
if not ctx.IVInit then
begin
raise EKeyError.Create(LIT_IV_NOT_SET);
Exit;
end;
end;
end;
procedure TBlowfish.InitArray;
begin
FBlowCore.ctx.P := TempP;
FBlowCore.ctx.S1 := TempS1;
FBlowCore.ctx.S2 := TempS2;
FBlowCore.ctx.S3 := TempS3;
FBlowCore.ctx.S4 := TempS4;
end;
procedure TBlowfish.EndianEncBlock;
var
TempLong: DoublWord;
begin
// flip the oder of the bytes
// we only need to do this because of the endianness of Intel
TempLong := FBlowCore.FPtrL^;
FBlowCore.FPtrL^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrL^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrL^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrL^.w.byte0 := TempLong.w.byte3;
TempLong := FBlowCore.FPtrR^;
FBlowCore.FPtrR^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrR^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrR^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrR^.w.byte0 := TempLong.w.byte3;
// perform the encryption
FBlowCore.Blowfish_Core_Block_Encrypt;
// flip the order of the bytes back
TempLong := FBlowCore.FPtrL^;
FBlowCore.FPtrL^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrL^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrL^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrL^.w.byte0 := TempLong.w.byte3;
TempLong := FBlowCore.FPtrR^;
FBlowCore.FPtrR^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrR^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrR^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrR^.w.byte0 := TempLong.w.byte3;
end;{EndianEncBlock}
procedure TBlowfish.EndianDecBlock;
var
TempLong: DoublWord;
begin
TempLong := FBlowCore.FPtrL^;
FBlowCore.FPtrL^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrL^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrL^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrL^.w.byte0 := TempLong.w.byte3;
TempLong := FBlowCore.FPtrR^;
FBlowCore.FPtrR^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrR^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrR^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrR^.w.byte0 := TempLong.w.byte3;
FBlowCore.Blowfish_Core_Block_Decrypt;
TempLong := FBlowCore.FPtrL^;
FBlowCore.FPtrL^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrL^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrL^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrL^.w.byte0 := TempLong.w.byte3;
TempLong := FBlowCore.FPtrR^;
FBlowCore.FPtrR^.w.byte3 := TempLong.w.byte0;
FBlowCore.FPtrR^.w.byte2 := TempLong.w.byte1;
FBlowCore.FPtrR^.w.byte1 := TempLong.w.byte2;
FBlowCore.FPtrR^.w.byte0 := TempLong.w.byte3;
end;{EndianDecBlock}
procedure TBlowCore.Blowfish_Core_Block_Encrypt;
var
Xl:DoublWord;
Xr:DoublWord;
begin
Xl := FPtrL^;
Xr := FPtrR^;
Xl.LWord := Xl.LWord xor ctx.P[0];
{第1轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[1];
{第2轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[2];
{第3轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[3];
{第4轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[4];
{第5轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[5];
{第6轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[6];
{第7轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[7];
{第8轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[8];
{第9轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[9];
{第10轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[10];
{第11轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[11];
{第12轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[12];
{第13轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[13];
{第14轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[14];
{第15轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[15];
{第16轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[16];
Xr.LWord := Xr.LWord xor ctx.P[17];
FPtrL^ := Xr;
FPtrR^ := Xl;
end;
procedure TBlowCore.Blowfish_Core_Block_Decrypt;
var
Xl: DoublWord;
Xr: DoublWord;
begin
Xl := FPtrL^;
Xr := FPtrR^;
Xl.Lword := Xl.Lword xor ctx.P[17];
{第16轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[16];
{第15轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[15];
{第14轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[14];
{第13轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[13];
{第12轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[12];
{第11轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[11];
{第10轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[10];
{第9轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[9];
{第8轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[8];
{第7轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[7];
{第6轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[6];
{第5轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[5];
{第4轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[4];
{第3轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[3];
{第2轮}
Xr.LWord := Xr.LWord xor (((ctx.S1[Xl.w.byte0] + ctx.S2[Xl.w.byte1]) xor
ctx.S3[Xl.w.byte2]) + ctx.S4[Xl.w.byte3]) xor ctx.P[2];
{第1轮}
Xl.LWord := Xl.LWord xor (((ctx.S1[Xr.w.byte0] + ctx.S2[Xr.w.byte1]) xor
ctx.S3[Xr.w.byte2]) + ctx.S4[Xr.w.byte3]) xor ctx.P[1];
Xr.Lword := Xr.Lword xor ctx.P[0];
FPtrL^ := Xr;
FPtrR^ := Xl;
end;
procedure TBlowfish.Blowfish_Core_Key_Setup(KeyArray: array of Byte; const KeyLength: integer);
var
i,j:integer;
data: Longint;
datal:Longint;
datar:Longint;
begin
InitArray;
j := 0;
//18个32位子密钥
for i:= 0 to 17 do
begin
Data := KeyArray[(j+3) mod KeyLength];
Data:= Data + (KeyArray[(j+2) mod KeyLength] shl 8);
Data:= Data + (KeyArray[(j+1) mod KeyLength] shl 16);
Data:= Data + (KeyArray[j] shl 24);
FBlowCore.ctx.P[i] := FBlowCore.ctx.P[i] xor data;
j:= (j+4) mod KeyLength;
end;{for i}
datal := 0;
FBlowCore.FPtrL := @datal;
datar := 0;
FBlowCore.FPtrR := @datar;
i:= 0;
while (i < (16 + 2)) do
begin
FBlowCore.Blowfish_Core_Block_Encrypt;
FBlowCore.ctx.P[i] := datal;
FBlowCore.ctx.P[i + 1] := datar;
Inc(i, 2);
end; {while i}
j:=0;
//第一个32位的S盒
while (j < 256) do
begin
FBlowCore.Blowfish_Core_Block_Encrypt;
FBlowCore.ctx.S1[j] := datal;
FBlowCore.ctx.S1[j + 1] := datar;
Inc(j, 2);
end;{while j}
j := 0;
//第二个32位的S盒
while (j < 256) do
begin
FBlowCore.Blowfish_Core_Block_Encrypt;
FBlowCore.ctx.S2[j] := datal;
FBlowCore.ctx.S2[j + 1] := datar;
Inc(j, 2);
end;{while j}
j := 0;
//第三个32位的S盒
while (j < 256) do
begin
FBlowCore.Blowfish_Core_Block_Encrypt;
FBlowCore.ctx.S3[j] := datal;
FBlowCore.ctx.S3[j + 1] := datar;
Inc(j, 2);
end;{while j}
j := 0;
//第四个32位的S盒
while (j < 256) do
begin
FBlowCore.Blowfish_Core_Block_Encrypt;
FBlowCore.ctx.S4[j] := datal;
FBlowCore.ctx.S4[j + 1] := datar;
Inc(j, 2);
end;
end;
constructor TBlowfish.Create;
begin
FBlowCore := TBlowCore.Create;
end;
destructor TBlowfish.Destroy;
begin
FBLowCore.Free;
inherited Destroy;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -