📄 msgcipher.pas
字号:
class procedure TCipher_Blowfish.GetContext(var ABufSize, AKeySize, AUserSize: Integer);
begin
ABufSize := 8;
AKeySize := 56;
AUserSize := SizeOf(Blowfish_Data) + SizeOf(Blowfish_Key);
end;
class function TCipher_Blowfish.TestVector: Pointer;
asm
MOV EAX,OFFSET @Vector
RET
@Vector: DB 019h,071h,0CAh,0CDh,02Bh,09Ch,085h,029h
DB 0DAh,081h,047h,0B7h,0EBh,0CEh,016h,0C6h
DB 091h,00Eh,01Dh,0C8h,040h,012h,03Eh,035h
DB 070h,0EDh,0BCh,096h,04Ch,013h,0D0h,0B8h
end;
type
PBlowfish = ^TBlowfish;
TBlowfish = array[0..3, 0..255] of LongWord;
{$IFDEF UseASM}
{$IFNDEF 486GE} // no Support for <= CPU 386
procedure TCipher_Blowfish.Encode386(Data: Pointer);
asm // specaly for CPU < 486
PUSH EDI
PUSH ESI
PUSH EBX
PUSH EBP
PUSH EDX
MOV ESI,[EAX].TCipher_Blowfish.FUser
MOV EBX,[EDX] // A
MOV EDX,[EDX + 4] // B
XCHG BL,BH // here BSWAP EBX,EDX
XCHG DL,DH
ROL EBX,16
ROL EDX,16
XCHG BL,BH
XCHG DL,DH
XOR EBX,[ESI + 4 * 256 * 4]
XOR EDI,EDI
@@1: MOV EAX,EBX
SHR EBX,16
MOVZX ECX,BH
MOV EBP,[ESI + ECX * 4 + 1024 * 0]
MOVZX ECX,BL
ADD EBP,[ESI + ECX * 4 + 1024 * 1]
MOVZX ECX,AH
XOR EBP,[ESI + ECX * 4 + 1024 * 2]
MOVZX ECX,AL
ADD EBP,[ESI + ECX * 4 + 1024 * 3]
XOR EDX,[ESI + 4 * 256 * 4 + 4 + EDI * 4]
XOR EBP,EDX
MOV EDX,EAX
MOV EBX,EBP
INC EDI
TEST EDI,010h
JZ @@1
POP EAX
XOR EDX,[ESI + 4 * 256 * 4 + 17 * 4]
XCHG BL,BH // here BSWAP EBX,EDX
XCHG DL,DH
ROL EBX,16
ROL EDX,16
XCHG BL,BH
XCHG DL,DH
MOV [EAX],EDX
MOV [EAX + 4],EBX
POP EBP
POP EBX
POP ESI
POP EDI
end;
procedure TCipher_Blowfish.Decode386(Data: Pointer);
asm // specaly for CPU < 486
PUSH EDI
PUSH ESI
PUSH EBX
PUSH EBP
PUSH EDX
MOV ESI,[EAX].TCipher_Blowfish.FUser
MOV EBX,[EDX] // A
MOV EDX,[EDX + 4] // B
XCHG BL,BH
XCHG DL,DH
ROL EBX,16
ROL EDX,16
XCHG BL,BH
XCHG DL,DH
XOR EBX,[ESI + 4 * 256 * 4 + 17 * 4]
MOV EDI,16
@@1: MOV EAX,EBX
SHR EBX,16
MOVZX ECX,BH
MOV EBP,[ESI + ECX * 4 + 1024 * 0]
MOVZX ECX,BL
ADD EBP,[ESI + ECX * 4 + 1024 * 1]
MOVZX ECX,AH
XOR EBP,[ESI + ECX * 4 + 1024 * 2]
MOVZX ECX,AL
ADD EBP,[ESI + ECX * 4 + 1024 * 3]
XOR EDX,[ESI + 4 * 256 * 4 + EDI * 4]
XOR EBP,EDX
MOV EDX,EAX
MOV EBX,EBP
DEC EDI
JNZ @@1
POP EAX
XOR EDX,[ESI + 4 * 256 * 4]
XCHG BL,BH // BSWAP
XCHG DL,DH
ROL EBX,16
ROL EDX,16
XCHG BL,BH
XCHG DL,DH
MOV [EAX],EDX
MOV [EAX + 4],EBX
POP EBP
POP EBX
POP ESI
POP EDI
end;
{$ENDIF} //486GE
{$ENDIF}
procedure TCipher_Blowfish.Encode(Data: Pointer);
{$IFDEF UseASM} // specialy for CPU >= 486
asm
PUSH EDI
PUSH ESI
PUSH EBX
PUSH EBP
PUSH EDX
MOV ESI,[EAX].TCipher_Blowfish.FUser
MOV EBX,[EDX] // A
MOV EBP,[EDX + 4] // B
BSWAP EBX // CPU >= 486
BSWAP EBP
XOR EDI,EDI
XOR EBX,[ESI + 4 * 256 * 4]
// XOR ECX,ECX
@@1:
MOV EAX,EBX
SHR EBX,16
MOVZX ECX,BH // it's faster with AMD Chips,
// MOV CL,BH // it's faster with PII's
MOV EDX,[ESI + ECX * 4 + 1024 * 0]
MOVZX ECX,BL
// MOV CL,BL
ADD EDX,[ESI + ECX * 4 + 1024 * 1]
MOVZX ECX,AH
// MOV CL,AH
XOR EDX,[ESI + ECX * 4 + 1024 * 2]
MOVZX ECX,AL
// MOV CL,AL
ADD EDX,[ESI + ECX * 4 + 1024 * 3]
XOR EBP,[ESI + 4 * 256 * 4 + 4 + EDI * 4]
INC EDI
XOR EDX,EBP
TEST EDI,010h
MOV EBP,EAX
MOV EBX,EDX
JZ @@1
POP EAX
XOR EBP,[ESI + 4 * 256 * 4 + 17 * 4]
BSWAP EBX
BSWAP EBP
MOV [EAX],EBP
MOV [EAX + 4],EBX
POP EBP
POP EBX
POP ESI
POP EDI
end;
{$ELSE}
var
I,A,B: LongWord;
P: PIntArray;
D: PBlowfish;
begin
D := User;
P := Pointer(PChar(User) + SizeOf(Blowfish_Data));
A := SwapInteger(PCipherRec(Data).A) xor P[0]; Inc(PInteger(P));
B := SwapInteger(PCipherRec(Data).B);
for I := 0 to 7 do
begin
B := B xor P[0] xor (D[0, A shr 24 ] +
D[1, A shr 16 and $FF] xor
D[2, A shr 8 and $FF] +
D[3, A and $FF]);
A := A xor P[1] xor (D[0, B shr 24 ] +
D[1, B shr 16 and $FF] xor
D[2, B shr 8 and $FF] +
D[3, B and $FF]);
Inc(PInteger(P), 2);
end;
PCipherRec(Data).A := SwapInteger(B xor P[0]);
PCipherRec(Data).B := SwapInteger(A);
end;
{$ENDIF}
procedure TCipher_Blowfish.Decode(Data: Pointer);
{$IFDEF UseASM}
asm
PUSH EDI
PUSH ESI
PUSH EBX
PUSH EBP
PUSH EDX
MOV ESI,[EAX].TCipher_Blowfish.FUser
MOV EBX,[EDX] // A
MOV EBP,[EDX + 4] // B
BSWAP EBX
BSWAP EBP
XOR EBX,[ESI + 4 * 256 * 4 + 17 * 4]
MOV EDI,16
// XOR ECX,ECX
@@1: MOV EAX,EBX
SHR EBX,16
MOVZX ECX,BH
// MOV CL,BH
MOV EDX,[ESI + ECX * 4 + 1024 * 0]
MOVZX ECX,BL
// MOV CL,BL
ADD EDX,[ESI + ECX * 4 + 1024 * 1]
MOVZX ECX,AH
// MOV CL,AH
XOR EDX,[ESI + ECX * 4 + 1024 * 2]
MOVZX ECX,AL
// MOV CL,AL
ADD EDX,[ESI + ECX * 4 + 1024 * 3]
XOR EBP,[ESI + 4 * 256 * 4 + EDI * 4]
XOR EDX,EBP
DEC EDI
MOV EBP,EAX
MOV EBX,EDX
JNZ @@1
POP EAX
XOR EBP,[ESI + 4 * 256 * 4]
BSWAP EBX
BSWAP EBP
MOV [EAX],EBP
MOV [EAX + 4],EBX
POP EBP
POP EBX
POP ESI
POP EDI
end;
{$ELSE}
var
I,A,B: LongWord;
P: PIntArray;
D: PBlowfish;
begin
D := User;
P := Pointer(PChar(User) + SizeOf(Blowfish_Data) + SizeOf(Blowfish_Key) - SizeOf(Integer));
A := SwapInteger(PCipherRec(Data).A) xor P[0];
B := SwapInteger(PCipherRec(Data).B);
for I := 0 to 7 do
begin
Dec(PInteger(P), 2);
B := B xor P[1] xor (D[0, A shr 24 ] +
D[1, A shr 16 and $FF] xor
D[2, A shr 8 and $FF] +
D[3, A and $FF]);
A := A xor P[0] xor (D[0, B shr 24 ] +
D[1, B shr 16 and $FF] xor
D[2, B shr 8 and $FF] +
D[3, B and $FF]);
end;
Dec(PInteger(P));
PCipherRec(Data).A := SwapInteger(B xor P[0]);
PCipherRec(Data).B := SwapInteger(A);
end;
{$ENDIF}
procedure TCipher_Blowfish.Init(const Key; Size: Integer; IVector: Pointer);
var
I,J: Integer;
B: array[0..7] of Byte;
K: PByteArray;
P: PIntArray;
S: PBlowfish;
begin
InitBegin(Size);
K := @Key;
S := User;
P := Pointer(PChar(User) + SizeOf(Blowfish_Data));
Move(Blowfish_Data, S^, SizeOf(Blowfish_Data));
Move(Blowfish_Key, P^, Sizeof(Blowfish_Key));
J := 0;
for I := 0 to 17 do
begin
P[I] := P[I] xor (K[(J + 0) mod Size] shl 24 +
K[(J + 1) mod Size] shl 16 +
K[(J + 2) mod Size] shl 8 +
K[(J + 3) mod Size]);
J := (J + 4) mod Size;
end;
FillChar(B, SizeOf(B), 0);
for I := 0 to 8 do
begin
Encode(@B);
P[I * 2] := SwapInteger(PCipherRec(@B).A);
P[I * 2 + 1] := SwapInteger(PCipherRec(@B).B);
end;
for I := 0 to 3 do
for J := 0 to 127 do
begin
Encode(@B);
S[I, J * 2] := SwapInteger(PCipherRec(@B).A);
S[I, J * 2 +1] := SwapInteger(PCipherRec(@B).B);
end;
FillChar(B, SizeOf(B), 0);
InitEnd(IVector);
end;
class procedure TCipher_Twofish.GetContext(var ABufSize, AKeySize, AUserSize: Integer);
begin
ABufSize := 16;
AKeySize := 32;
AUserSize := 4256;
end;
class function TCipher_Twofish.TestVector: Pointer;
asm
MOV EAX,OFFSET @Vector
RET
@Vector: DB 0A5h,053h,057h,003h,0EFh,033h,048h,079h
DB 09Fh,022h,0B4h,054h,097h,005h,084h,019h
DB 087h,0BDh,083h,01Ch,04Dh,0AEh,012h,013h
DB 060h,07Ch,07Ch,0D1h,098h,045h,002h,019h
end;
type
PTwofishBox = ^TTwofishBox;
TTwofishBox = array[0..3, 0..255] of Longword;
TLongRec = record
case Integer of
0: (L: Longword);
1: (A,B,C,D: Byte);
end;
procedure TCipher_Twofish.Encode(Data: Pointer);
var
S: PIntArray;
Box: PTwofishBox;
I,X,Y: LongWord;
A,B,C,D: TLongRec;
begin
S := User;
A.L := PIntArray(Data)[0] xor S[0];
B.L := PIntArray(Data)[1] xor S[1];
C.L := PIntArray(Data)[2] xor S[2];
D.L := PIntArray(Data)[3] xor S[3];
S := @PIntArray(User)[8];
Box := @PIntArray(User)[40];
for I := 0 to 7 do
begin
X := Box[0, A.A] xor Box[1, A.B] xor Box[2, A.C] xor Box[3, A.D];
Y := Box[1, B.A] xor Box[2, B.B] xor Box[3, B.C] xor Box[0, B.D];
asm ROL D.L,1 end;
C.L := C.L xor (X + Y + S[0]);
D.L := D.L xor (X + Y shl 1 + S[1]);
asm ROR C.L,1 end;
X := Box[0, C.A] xor Box[1, C.B] xor Box[2, C.C] xor Box[3, C.D];
Y := Box[1, D.A] xor Box[2, D.B] xor Box[3, D.C] xor Box[0, D.D];
asm ROL B.L,1 end;
A.L := A.L xor (X + Y + S[2]);
B.L := B.L xor (X + Y shl 1 + S[3]);
asm ROR A.L,1 end;
Inc(PInteger(S), 4);
end;
S := User;
PIntArray(Data)[0] := C.L xor S[4];
PIntArray(Data)[1] := D.L xor S[5];
PIntArray(Data)[2] := A.L xor S[6];
PIntArray(Data)[3] := B.L xor S[7];
end;
procedure TCipher_Twofish.Decode(Data: Pointer);
var
S: PIntArray;
Box: PTwofishBox;
I,X,Y: LongWord;
A,B,C,D: TLongRec;
begin
S := User;
Box := @PIntArray(User)[40];
C.L := PIntArray(Data)[0] xor S[4];
D.L := PIntArray(Data)[1] xor S[5];
A.L := PIntArray(Data)[2] xor S[6];
B.L := PIntArray(Data)[3] xor S[7];
S := @PIntArray(User)[36];
for I := 0 to 7 do
begin
X := Box[0, C.A] xor Box[1, C.B] xor Box[2, C.C] xor Box[3, C.D];
Y := Box[0, D.D] xor Box[1, D.A] xor Box[2, D.B] xor Box[3, D.C];
asm ROL A.L,1 end;
B.L := B.L xor (X + Y shl 1 + S[3]);
A.L := A.L xor (X + Y + S[2]);
asm ROR B.L,1 end;
X := Box[0, A.A] xor Box[1, A.B] xor Box[2, A.C] xor Box[3, A.D];
Y := Box[0, B.D] xor Box[1, B.A] xor Box[2, B.B] xor Box[3, B.C];
asm ROL C.L,1 end;
D.L := D.L xor (X + Y shl 1 + S[1]);
C.L := C.L xor (X + Y + S[0]);
asm ROR D.L,1 end;
Dec(PByte(S),16);
end;
S := User;
PIntArray(Data)[0] := A.L xor S[0];
PIntArray(Data)[1] := B.L xor S[1];
PIntArray(Data)[2] := C.L xor S[2];
PIntArray(Data)[3] := D.L xor S[3];
end;
procedure TCipher_Twofish.Init(const Key; Size: Integer; IVector: Pointer);
var
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -