📄 rc5unit.pas
字号:
FRounds := 8;
FSubKeyLen := (FRounds * 2) + 2; {calculate new subkeylen}
GetMem(FpKey, FSubKeyLen * 4); {get mem for new subkeys}
FIVTemp := nil;
end;{Create}
{$IFDEF DELPHI}
destructor TRC5.Destroy;
{$ENDIF}
{$IFDEF BP7}
destructor TRC5.Done;
{$ENDIF}
begin
If FpKey <> nil then FreeMem(FpKey, (FSubKeyLen * 4));
{$IFDEF DELPHI}
inherited Destroy;
{$ENDIF}
end;{TRC5.Destroy;}
Procedure TRC5.SetKeys;
{------------------------------------------------------------------------------
Generating the subkeys:
Copy user key in an array L, of c 32bit words, padding final word with
zeros if necessary. Then
S0 = P
for i = 1 to 2(r +1) - 1
Si = (S(i-1) + Q) Mod 2tothe32
where P=$b7e15163 Q=$9e3779b9
then
i=j=0
A=B=0
do 3*n times(where n is the maximum of 2(r + 1) and c)
A = Si =(Si + A + B) <<< 3
B = Lj =(Lj + A + B) <<< (A + B)
i=(i+1) mod 2(r +1)
j=(j+1) mod c
-------------------------------------------------------------------------------}
var
userKeyLen,SubkeyLen, paddedLen, i, j, n, maxtimes : WORD;
L: PLArray; {array of bytes}
A, B: LongInt;
{$IFDEF ORDER_ABCD}
plittleL: Paword;
bigL: aword;
{$ENDIF}
begin
{$IFDEF TEST}
FKey := #$91 + #$5F + #$46 + #$19 + #$BE + #$41 + #$B2 + #$51 + #$63 + #$55
+ #$A5 + #$01 + #$10 + #$A9 + #$CE + #$91;
FRounds := 12;
{$ENDIF}
userKeyLen := Length(FKey);
{If UserKeyLen <= 0 then Signal Error..}
SubKeyLen := (FRounds * 2) + 2; {calculate new subkeylen}
FreeMem(FpKey, FSubKeyLen * 4); {free old subkey mem}
GetMem(FpKey, SubKeyLen * 4); {get mem for new subkeys}
FSubKeyLen := SubKeyLen; {save old length}
paddedLen := userKeyLen DIV 4;
if (userKeyLen MOD 4) <> 0 then Inc(paddedLen);
{get some memory for temp array L}
GetMem(L, paddedLen * 4);
{if L = nil then error}
FillChar(L^, paddedLen * 4, #0);{initialize with zeros}
{copy users key into L, L is array of UWORD32, so on BigEndian we need
to make sure that the bytes get in the right places, RC5 assumes LittleEnd}
Move(FKey[1], L^, userKeyLen);
{$IFDEF ORDER_ABCD}
pbigL := L;
For i := 1 to (paddedLen) do begin
bigL := plittleL^;
plittleL^.w.Byte3 := bigL.w.Byte0;
plittleL^.w.Byte2 := bigL.w.Byte1;
plittleL^.w.Byte1 := bigL.w.Byte2;
plittleL^.w.Byte0 := bigL.w.Byte3;
Inc(plittleL);
end;{for}
{$ENDIF}
{Initialize SubKeys}
FpKey^[0] := P;
For i:= 1 to (SubKeyLen - 1) do begin
FpKey^[i] := FpKey^[i - 1] + Q;
end;{for}
i := 0; j := 0; n := 0; A := 0; B := 0;
if paddedLen > SubKeyLen then
maxtimes := 3*paddedLen
else
maxtimes := 3*SubKeyLen;
{calculate SubKeys}
repeat
inc(n);
FpKey^[i] := FpKey^[i] + A + B;
{$IFDEF ORDER_DCBA} {Intel, use inline asm functions}
FpKey^[i] := ROL(FpKey^[i], 3);
{$ELSE}
FpKey^[i] := (FpKey^[i] SHL 3) Or (FpKey^[i] SHR (32 - 3));
{$ENDIF}
A := FpKey^[i];
L^[j] := L^[j] + A + B;
{$IFDEF ORDER_DCBA} {Intel, use inline asm functions}
L^[j] := ROL(L^[j], ((A + B) AND 31));
{$ELSE}
L^[j] := (L^[j] SHL ((A + B) AND 31)) Or (L^[j] SHR (32 - ((A + B) AND 31)));
{$ENDIF}
B := L^[j];
i := (i + 1) MOD SubKeyLen;
j := (j + 1) MOD paddedLen;
until n = maxtimes;
FillChar(L^, paddedLen * 4, #0);
FreeMem(L,paddedLen * 4);
end;{TRC5.SetKeys}
Procedure TRC5.EncipherBLOCK;
{------------------------------------------------------------------------------
Enciphers a 64bit block, two 32bit halfs, A & B
Encryption uses 2r + r(r = rounds) key dependent 32bit words(S0..S31).
To encrypt first divide the plaintext block into two 32 bit words: A & B.
Then:
A = A + S0
B = B + S1
For i = 1 to r
A = ((A Xor B) <<< B) + S2i
B = ((B Xor A) <<< A) + S(2i + 1)
The output is A & B
-------------------------------------------------------------------------------}
var
i, j : WORD;
{$IFDEF ORDER_ABCD}
bigL: aword;
{$ENDIF}
begin
{$IFDEF TEST}
FpA^ := $EEDBA521;
FpB^ := $6D8F4B15;
{$ENDIF}
{Flip bytes here on Mac}
{$IFDEF ORDER_ABCD}
pbigL := Paword(FpA)^;
Paword(FpA)^.w.Byte3 := bigL.w.Byte0;
Paword(FpA)^.w.Byte2 := bigL.w.Byte1;
Paword(FpA)^.w.Byte1 := bigL.w.Byte2;
Paword(FpA)^.w.Byte0 := bigL.w.Byte3;
pbigL := Paword(FpB)^;
Paword(FpB)^.w.Byte3 := bigL.w.Byte0;
Paword(FpB)^.w.Byte2 := bigL.w.Byte1;
Paword(FpB)^.w.Byte1 := bigL.w.Byte2;
Paword(FpB)^.w.Byte0 := bigL.w.Byte3;
{$ENDIF}
Inc(FpA^, FpKey^[0]);
Inc(FpB^, FpKey^[1]);
For i:= 1 to FRounds do begin
j := 2 * i;
{$IFDEF ORDER_DCBA} {Intel, use asm functions}
FpA^ := ROL((FpA^ Xor FpB^), (FpB^ AND 31)) + FpKey^[j];
FpB^ := ROL((FpB^ Xor FpA^), (FpA^ AND 31)) + FpKey^[j + 1];
{$ELSE}
FpA^ := FpA^ Xor FpB^;
FpA^ := ((FpA^ SHL (FpB^ AND 31)) Or (FpA^ SHR (32 - (FpB^ AND 31)))) + FpKey^[j];
FpB^ := FpB^ Xor FpA^;
FpB^ := ((FpB^ SHL (FpA^ AND 31)) Or (FpB^ SHR (32 - (FpA^ AND 31)))) + FpKey^[j + 1];
{$ENDIF}
end;{for}
{Flip Bytes here on Mac}
{$IFDEF ORDER_ABCD}
pbigL := Paword(FpA)^;
Paword(FpA)^.w.Byte3 := bigL.w.Byte0;
Paword(FpA)^.w.Byte2 := bigL.w.Byte1;
Paword(FpA)^.w.Byte1 := bigL.w.Byte2;
Paword(FpA)^.w.Byte0 := bigL.w.Byte3;
pbigL := Paword(FpB)^;
Paword(FpB)^.w.Byte3 := bigL.w.Byte0;
Paword(FpB)^.w.Byte2 := bigL.w.Byte1;
Paword(FpB)^.w.Byte1 := bigL.w.Byte2;
Paword(FpB)^.w.Byte0 := bigL.w.Byte3;
{$ENDIF}
{If you were testing, then FpA^ should = $AC13C0F7 and FpB^ should = $52892B5B}
end;{TRC5.EncipherBLOCK}
Procedure TRC5.DecipherBLOCK;
{------------------------------------------------------------------------------
Decryption
For i = r down to 1
B = ((B - S(2i +1)) >>> A) Xor A
B = ((A - S2i)>>>B) Xor B
B = B - S1
A = A - S0
------------------------------------------------------------------------------}
var
i, j: WORD;
{$IFDEF ORDER_ABCD}
bigL: aword;
{$ENDIF}
begin
{Flip bytes here on Mac}
{$IFDEF ORDER_ABCD}
pbigL := Paword(FpA)^;
Paword(FpA)^.w.Byte3 := bigL.w.Byte0;
Paword(FpA)^.w.Byte2 := bigL.w.Byte1;
Paword(FpA)^.w.Byte1 := bigL.w.Byte2;
Paword(FpA)^.w.Byte0 := bigL.w.Byte3;
pbigL := Paword(FpB)^;
Paword(FpB)^.w.Byte3 := bigL.w.Byte0;
Paword(FpB)^.w.Byte2 := bigL.w.Byte1;
Paword(FpB)^.w.Byte1 := bigL.w.Byte2;
Paword(FpB)^.w.Byte0 := bigL.w.Byte3;
{$ENDIF}
For i:= FRounds downto 1 do begin
j := i * 2;
{$IFDEF ORDER_DCBA}
FpB^ := ROR((FpB^ - FpKey^[j + 1]), (FpA^ AND 31)) Xor FpA^;
FpA^ := ROR((FpA^ - FpKey^[j]), (FpB^ AND 31)) Xor FpB^;
{$ELSE}
FpB^ := FpB^ - FpKey^[j + 1];
FpB^ := ((FpB^ SHR (FpA^ AND 31)) Or (FpB^ SHL (32 - (FpA^ AND 31)))) Xor FpA^;
FpA^ := FpA^ - FpKey^[j];
FpA^ := ((FpA^ SHR (FpB^ AND 31)) Or (FpA^ SHL (32 - (FpB^ AND 31)))) Xor FpB^;
{$ENDIF}
end;{for}
Dec(FpB^, FpKey^[1]);
Dec(FpA^, FpKey^[0]);
{$IFDEF ORDER_ABCD}
pbigL := Paword(FpA)^;
Paword(FpA)^.w.Byte3 := bigL.w.Byte0;
Paword(FpA)^.w.Byte2 := bigL.w.Byte1;
Paword(FpA)^.w.Byte1 := bigL.w.Byte2;
Paword(FpA)^.w.Byte0 := bigL.w.Byte3;
pbigL := Paword(FpB)^;
Paword(FpB)^.w.Byte3 := bigL.w.Byte0;
Paword(FpB)^.w.Byte2 := bigL.w.Byte1;
Paword(FpB)^.w.Byte1 := bigL.w.Byte2;
Paword(FpB)^.w.Byte0 := bigL.w.Byte3;
{$ENDIF}
end;{TRC5.DecipherBLOCK}
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -