📄 abscipher.pas
字号:
B := F;
F := S;
Inc(D, FBufSize);
Dec(DataSize, FBufSize);
end;
if F <> FFeedback then Move(F^, FFeedback^, FBufSize);
if DataSize > 0 then
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
XORBuffers(D, FBuffer, DataSize, D);
XORBuffers(FBuffer, FFeedback, FBufSize, FFeedback);
end;
end;
cmCFB:
while DataSize > 0 do
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
Move(PByteArray(FFeedback)[1], FFeedback^, FBufSize-1);
PByteArray(FFeedback)[FBufSize-1] := S^;
D^ := S^ xor PByte(FBuffer)^;
Inc(D);
Inc(S);
Dec(DataSize);
end;
cmOFB:
while DataSize > 0 do
begin
Move(FFeedback^, FBuffer^, FBufSize);
Encode(FBuffer);
D^ := S^ xor PByte(FBuffer)^;
Move(PByteArray(FFeedback)[1], FFeedback^, FBufSize-1);
PByteArray(FFeedback)[FBufSize-1] := PByte(FBuffer)^;
Inc(D);
Inc(S);
Dec(DataSize);
end;
cmCTSMAC, cmCBCMAC, cmCFBMAC:
begin
EncodeBuffer(Source, Dest, DataSize);
Exit;
end;
end;
end;
procedure TCipher.CodeInit(Action: TPAction);
begin
if not Initialized then
RaiseCipherException(errNotInitialized, Format(sNotInitialized, [ClassName]));
{ if (Mode in [cmCBCMAC, cmCTSMAC, cmCFBMAC]) <> (Action = paCalc) then
RaiseCipherException(errCantCalc, Format(sCantCalc, [ClassName]));}
if Action <> paCalc then
if Action <> paWipe then Done
else RndXORBuffer(RndTimeSeed, FFeedback^, FBufSize);
inherited CodeInit(Action);
end;
procedure TCipher.CodeDone(Action: TPAction);
begin
inherited CodeDone(Action);
if Action <> paCalc then
if Action <> paWipe then Done
else RndXORBuffer(RndTimeSeed, FFeedback^, FBufSize);
end;
procedure TCipher.CodeBuf(var Buffer; const BufferSize: Integer; Action: TPAction);
begin
if Action = paDecode then
begin
if Action in Actions then
DecodeBuffer(Buffer, Buffer, BufferSize);
inherited CodeBuf(Buffer, BufferSize, Action);
end else
begin
inherited CodeBuf(Buffer, BufferSize, Action);
if Action in Actions then
EncodeBuffer(Buffer, Buffer, BufferSize);
end;
end;
type
PCipherRec = ^TCipherRec;
TCipherRec = packed record
case Integer of
0: (X: array[0..7] of Byte);
1: (A, B: LongWord);
end;
{$IFDEF VER_D3H}
procedure ModuleUnload(Module: Integer);
var
I: Integer;
begin
if IsObject(FCipherList, TStringList) then
for I := FCipherList.Count-1 downto 0 do
if FindClassHInstance(TClass(FCipherList.Objects[I])) = LongWord(Module) then
FCipherList.Delete(I);
end;
{$ENDIF}
// ------- from cipher1 -----------------
const
{don't change this}
Rijndael_Blocks = 4;
Rijndael_Rounds = 14;
class procedure TCipher_Rijndael.GetContext(var ABufSize, AKeySize, AUserSize: Integer);
begin
ABufSize := Rijndael_Blocks * 4;
AKeySize := 32;
AUserSize := (Rijndael_Rounds + 1) * Rijndael_Blocks * SizeOf(Integer) * 2;
end;
class function TCipher_Rijndael.TestVector: Pointer;
asm
MOV EAX,OFFSET @Vector
RET
@Vector: DB 094h,06Dh,02Bh,05Eh,0E0h,0ADh,01Bh,05Ch
DB 0A5h,023h,0A5h,013h,095h,08Bh,03Dh,02Dh
DB 093h,087h,0F3h,037h,045h,051h,0F6h,058h
DB 09Bh,0E7h,090h,01Bh,036h,087h,0F9h,0A9h
end;
procedure TCipher_Rijndael.Encode(Data: Pointer);
var
P,K: PInteger;
I,A,B,C,D: Integer;
begin
P := User;
K := Data;
for I := 2 to FRounds do
begin
A := K^ xor P^; Inc(P); Inc(K);
B := K^ xor P^; Inc(P); Inc(K);
C := K^ xor P^; Inc(P); Inc(K);
D := K^ xor P^; Inc(P);
K^ := Rijndael_T[0, D and $FF] xor
Rijndael_T[1, A shr 8 and $FF] xor
Rijndael_T[2, B shr 16 and $FF] xor
Rijndael_T[3, C shr 24]; Dec(K);
K^ := Rijndael_T[0, C and $FF] xor
Rijndael_T[1, D shr 8 and $FF] xor
Rijndael_T[2, A shr 16 and $FF] xor
Rijndael_T[3, B shr 24]; Dec(K);
K^ := Rijndael_T[0, B and $FF] xor
Rijndael_T[1, C shr 8 and $FF] xor
Rijndael_T[2, D shr 16 and $FF] xor
Rijndael_T[3, A shr 24]; Dec(K);
K^ := Rijndael_T[0, A and $FF] xor
Rijndael_T[1, B shr 8 and $FF] xor
Rijndael_T[2, C shr 16 and $FF] xor
Rijndael_T[3, D shr 24];
end;
A := K^ xor P^; Inc(P); Inc(K);
B := K^ xor P^; Inc(P); Inc(K);
C := K^ xor P^; Inc(P); Inc(K);
D := K^ xor P^; Inc(P);
K^ := Rijndael_S[0, D and $FF] or
Rijndael_S[0, A shr 8 and $FF] shl 8 or
Rijndael_S[0, B shr 16 and $FF] shl 16 or
Rijndael_S[0, C shr 24] shl 24; Dec(K);
K^ := Rijndael_S[0, C and $FF] or
Rijndael_S[0, D shr 8 and $FF] shl 8 or
Rijndael_S[0, A shr 16 and $FF] shl 16 or
Rijndael_S[0, B shr 24] shl 24; Dec(K);
K^ := Rijndael_S[0, B and $FF] or
Rijndael_S[0, C shr 8 and $FF] shl 8 or
Rijndael_S[0, D shr 16 and $FF] shl 16 or
Rijndael_S[0, A shr 24] shl 24; Dec(K);
K^ := Rijndael_S[0, A and $FF] or
Rijndael_S[0, B shr 8 and $FF] shl 8 or
Rijndael_S[0, C shr 16 and $FF] shl 16 or
Rijndael_S[0, D shr 24] shl 24;
for I := 1 to Rijndael_Blocks do
begin
K^ := K^ xor P^;
Inc(P);
Inc(K);
end;
end;
procedure TCipher_Rijndael.Decode(Data: Pointer);
var
P,K: PInteger;
I,A,B,C,D: Integer;
begin
P := Pointer(PChar(User) + UserSize shr 1);
Inc(P, FRounds * 4 +3);
K := Pointer(PChar(Data) + 12);
for I := 2 to FRounds do
begin
D := K^ xor P^; Dec(P); Dec(K);
C := K^ xor P^; Dec(P); Dec(K);
B := K^ xor P^; Dec(P); Dec(K);
A := K^ xor P^; Dec(P);
K^ := Rijndael_T[4, A and $FF] xor
Rijndael_T[5, D shr 8 and $FF] xor
Rijndael_T[6, C shr 16 and $FF] xor
Rijndael_T[7, B shr 24]; Inc(K);
K^ := Rijndael_T[4, B and $FF] xor
Rijndael_T[5, A shr 8 and $FF] xor
Rijndael_T[6, D shr 16 and $FF] xor
Rijndael_T[7, C shr 24]; Inc(K);
K^ := Rijndael_T[4, C and $FF] xor
Rijndael_T[5, B shr 8 and $FF] xor
Rijndael_T[6, A shr 16 and $FF] xor
Rijndael_T[7, D shr 24]; Inc(K);
K^ := Rijndael_T[4, D and $FF] xor
Rijndael_T[5, C shr 8 and $FF] xor
Rijndael_T[6, B shr 16 and $FF] xor
Rijndael_T[7, A shr 24];
end;
D := K^ xor P^; Dec(P); Dec(K);
C := K^ xor P^; Dec(P); Dec(K);
B := K^ xor P^; Dec(P); Dec(K);
A := K^ xor P^; Dec(P);
K^ := Rijndael_S[1, A and $FF] or
Rijndael_S[1, D shr 8 and $FF] shl 8 or
Rijndael_S[1, C shr 16 and $FF] shl 16 or
Rijndael_S[1, B shr 24] shl 24; Inc(K);
K^ := Rijndael_S[1, B and $FF] or
Rijndael_S[1, A shr 8 and $FF] shl 8 or
Rijndael_S[1, D shr 16 and $FF] shl 16 or
Rijndael_S[1, C shr 24] shl 24; Inc(K);
K^ := Rijndael_S[1, C and $FF] or
Rijndael_S[1, B shr 8 and $FF] shl 8 or
Rijndael_S[1, A shr 16 and $FF] shl 16 or
Rijndael_S[1, D shr 24] shl 24; Inc(K);
K^ := Rijndael_S[1, D and $FF] or
Rijndael_S[1, C shr 8 and $FF] shl 8 or
Rijndael_S[1, B shr 16 and $FF] shl 16 or
Rijndael_S[1, A shr 24] shl 24;
for I := 0 to 3 do
begin
K^ := K^ xor P^;
Dec(P);
Dec(K);
end;
end;
procedure TCipher_Rijndael.Init(const Key; Size: Integer; IVector: Pointer);
var
K: array[0..7] of Integer;
procedure BuildEncodeKey;
const
RND_Data: array[0..29] of Byte = (
$01,$02,$04,$08,$10,$20,$40,$80,$1B,$36,$6C,$D8,$AB,$4D,$9A,
$2F,$5E,$BC,$63,$C6,$97,$35,$6A,$D4,$B3,$7D,$FA,$EF,$C5,$91);
var
T,R: Integer;
procedure NextRounds;
var
J: Integer;
begin
J := 0;
while (J < FRounds-6) and (R <= FRounds) do
begin
while (J < FRounds-6) and (T < Rijndael_Blocks) do
begin
PIntArray(User)[R * Rijndael_Blocks + T] := K[J];
Inc(J);
Inc(T);
end;
if T = Rijndael_Blocks then
begin
T := 0;
Inc(R);
end;
end;
end;
var
RND: PByte;
B: PByte;
I: Integer;
begin
R := 0;
T := 0;
RND := @RND_Data;
NextRounds;
while R <= FRounds do
begin
B := @K;
B^ := B^ xor Rijndael_S[0, K[FRounds -7] shr 8 and $FF] xor RND^; Inc(B);
B^ := B^ xor Rijndael_S[0, K[FRounds -7] shr 16 and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[FRounds -7] shr 24]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[FRounds -7] and $FF];
Inc(RND);
if FRounds = 14 then
begin
for I := 1 to 7 do K[I] := K[I] xor K[I -1];
B := @K[4];
B^ := B^ xor Rijndael_S[0, K[3] and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[3] shr 8 and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[3] shr 16 and $FF]; Inc(B);
B^ := B^ xor Rijndael_S[0, K[3] shr 24];
for I := 5 to 7 do K[I] := K[I] xor K[I -1];
end else
for I := 1 to FRounds -7 do K[I] := K[I] xor K[I -1];
NextRounds;
end;
end;
procedure BuildDecodeKey;
var
I: Integer;
D: PInteger;
begin
D := Pointer(PChar(User) + UserSize shr 1);
Move(User^, D^, UserSize shr 1);
Inc(D, 4);
for I := 0 to FRounds * 4 - 5 do
begin
D^ := Rijndael_Key[D^ and $FF] xor
ROL(Rijndael_Key[D^ shr 8 and $FF], 8) xor
ROL(Rijndael_Key[D^ shr 16 and $FF], 16) xor
ROL(Rijndael_Key[D^ shr 24], 24);
Inc(D);
end;
end;
begin
InitBegin(Size);
if Size <= 16 then FRounds := 10 else
if Size <= 24 then FRounds := 12 else FRounds := 14;
FillChar(K, SizeOf(K), 0);
Move(Key, K, Size);
BuildEncodeKey;
BuildDecodeKey;
FillChar(K, SizeOf(K), 0);
InitEnd(IVector);
end;
// blowfish
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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -