📄 rc_algref.pas
字号:
for j:= 0 to KC-1 do
for i:= 0 to 4-1 do
tk[i][j]:= k[i][j];
{ copy values into round key array }
t:= 0;
j:= 0;
while ((j < KC) and (t < (ROUNDS+1)*BC)) do
begin
for i:= 0 to 4-1 do
W[t div BC][i][t mod BC]:= tk[i][j];
inc(j);
inc(t);
end;
while (t < (ROUNDS+1)*BC) do { while not enough round key material calculated }
begin
{ calculate new values }
for i:= 0 to 4-1 do
tk[i][0]:= tk[i][0] xor S[tk[(i+1) mod 4][KC-1]];
tk[0][0]:= tk[0][0] xor rcon[rconpointer];
inc(rconpointer);
if (KC <> 8) then
begin
for j:= 1 to KC-1 do
for i:= 0 to 4-1 do
tk[i][j]:= tk[i][j] xor tk[i][j-1];
end
else
begin
j:= 1;
while j < KC/2 do
begin
for i:= 0 to 4-1 do
tk[i][j]:= tk[i][j] xor tk[i][j-1];
inc(j);
end;
for i:= 0 to 4-1 do
tk[i][KC div 2]:= tk[i][KC div 2] xor S[tk[i][(KC div 2) - 1]];
j:= (KC div 2) + 1;
while j < KC do
begin
for i:= 0 to 4-1 do
tk[i][j]:= tk[i][j] xor tk[i][j-1];
inc(j);
end;
end;
{ copy values into round key array }
j:= 0;
while ((j < KC) and (t < (ROUNDS+1)*BC)) do
begin
for i:= 0 to 4-1 do
W[t div BC][i][t mod BC]:= tk[i][j];
inc(j);
inc(t);
end;
end;
result:= 0;
end;
function rijndaelEncrypt(var a: TArrayK; keyBits, blockBits: integer; rk: TArrayRK): integer;
{ Encryption of one block. }
var
r, BC, ROUNDS: integer;
begin
case (blockBits) of
128: BC:= 4;
192: BC:= 6;
256: BC:= 8;
else
begin
result:= -2;
exit;
end;
end;
case iif(keyBits >= blockBits, keyBits, blockBits) of
128: ROUNDS:= 10;
192: ROUNDS:= 12;
256: ROUNDS:= 14;
else
begin
result:= -3; { this cannot happen }
exit;
end;
end;
{ begin with a key addition }
KeyAddition(a,addr(rk[0]),BC);
{ ROUNDS-1 ordinary rounds }
for r:= 1 to ROUNDS-1 do
begin
Substitution(a,S,BC);
ShiftRow(a,0,BC);
MixColumn(a,BC);
KeyAddition(a,addr(rk[r]),BC);
end;
{ Last round is special: there is no MixColumn }
Substitution(a,S,BC);
ShiftRow(a,0,BC);
KeyAddition(a,addr(rk[ROUNDS]),BC);
result:= 0;
end;
function rijndaelEncryptRound(var a: TArrayK; keyBits, blockBits: integer;
rk: TArrayRK; var irounds: integer): integer;
{ Encrypt only a certain number of rounds.
Only used in the Intermediate Value Known Answer Test. }
var
r, BC, ROUNDS: integer;
begin
case (blockBits) of
128: BC:= 4;
192: BC:= 6;
256: BC:= 8;
else
begin
result:= -2;
exit;
end;
end;
case iif(keyBits >= blockBits, keyBits, blockBits) of
128: ROUNDS:= 10;
192: ROUNDS:= 12;
256: ROUNDS:= 14;
else
begin
result:= -3; { this cannot happen }
exit;
end;
end;
{ make number of rounds sane }
if (irounds > ROUNDS) then
irounds:= ROUNDS;
{ begin with a key addition }
KeyAddition(a,addr(rk[0]),BC);
{ at most ROUNDS-1 ordinary rounds }
r:= 1;
while (r <= irounds) and (r < ROUNDS) do
begin
Substitution(a,S,BC);
ShiftRow(a,0,BC);
MixColumn(a,BC);
KeyAddition(a,addr(rk[r]),BC);
inc(r);
end;
{ if necessary, do the last, special, round: }
if (irounds = ROUNDS) then
begin
Substitution(a,S,BC);
ShiftRow(a,0,BC);
KeyAddition(a,addr(rk[ROUNDS]),BC);
end;
result:= 0;
end;
function rijndaelDecrypt(var a: TArrayK; keyBits, blockBits: integer; rk: TArrayRK): integer;
var
r, BC, ROUNDS: integer;
begin
case (blockBits) of
128: BC:= 4;
192: BC:= 6;
256: BC:= 8;
else
begin
result:= -2;
exit;
end;
end;
case iif(keyBits >= blockBits, keyBits, blockBits) of
128: ROUNDS:= 10;
192: ROUNDS:= 12;
256: ROUNDS:= 14;
else
begin
result:= -3; { this cannot happen }
exit;
end;
end;
{ To decrypt: apply the inverse operations of the encrypt routine,
in opposite order
(KeyAddition is an involution: it 's equal to its inverse)
(the inverse of Substitution with table S is Substitution with the inverse table of S)
(the inverse of Shiftrow is Shiftrow over a suitable distance) }
{ First the special round:
without InvMixColumn
with extra KeyAddition }
KeyAddition(a,addr(rk[ROUNDS]),BC);
Substitution(a,Si,BC);
ShiftRow(a,1,BC);
{ ROUNDS-1 ordinary rounds }
for r:= ROUNDS-1 downto 0+1 do
begin
KeyAddition(a,addr(rk[r]),BC);
InvMixColumn(a,BC);
Substitution(a,Si,BC);
ShiftRow(a,1,BC);
end;
{ End with the extra key addition }
KeyAddition(a,addr(rk[0]),BC);
result:= 0;
end;
function rijndaelDecryptRound(var a: TArrayK; keyBits, blockBits: integer;
rk: TArrayRK; var irounds: integer): integer;
{ Decrypt only a certain number of rounds.
Only used in the Intermediate Value Known Answer Test.
Operations rearranged such that the intermediate values
of decryption correspond with the intermediate values
of encryption. }
var
r, BC, ROUNDS: integer;
begin
case (blockBits) of
128: BC:= 4;
192: BC:= 6;
256: BC:= 8;
else
begin
result:= -2;
exit;
end;
end;
case iif(keyBits >= blockBits, keyBits, blockBits) of
128: ROUNDS:= 10;
192: ROUNDS:= 12;
256: ROUNDS:= 14;
else
begin
result:= -3; { this cannot happen }
exit;
end;
end;
{ make number of rounds sane }
if (irounds > ROUNDS) then
irounds:= ROUNDS;
{ First the special round:
without InvMixColumn
with extra KeyAddition }
KeyAddition(a,addr(rk[ROUNDS]),BC);
Substitution(a,Si,BC);
ShiftRow(a,1,BC);
{ ROUNDS-1 ordinary rounds }
for r:= ROUNDS-1 downto irounds+1 do
begin
KeyAddition(a,addr(rk[r]),BC);
InvMixColumn(a,BC);
Substitution(a,Si,BC);
ShiftRow(a,1,BC);
end;
if (irounds = 0) then
{ End with the extra key addition }
KeyAddition(a,addr(rk[0]),BC);
result:= 0;
end;
end.
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -