Andreas Software - Source Code - LEA256.PAS

An implementation of the block cipher LEA-256 for Embarcadero Delphi


unit LEA256;

{
  An implementation of the block cipher LEA-256 for Embarcadero Delphi.

  Original Author: Andreas Jonsson. (www.andreas-software.com)

  Written: 2020-10-01.

  Published: 2020-10-01.

  Modified By: Your Name. (Your Website)

  |------------------------------------------------------|
  |                                                      |
  |    YOU MAY USE AND MODIFY THIS SOURCE CODE FREELY    |
  |    THE ONLY REQUIREMENT IS THAT THE COMMENT ABOUT    |
  |    THE ORIGINAL AUTHOR AND THIS NOTICE REMAINS IN    |
  |    THE SOURCE CODE                                   |
  |                                                      |
  |------------------------------------------------------|
}

interface

uses
  System.SysUtils, System.Variants, System.Classes;

type
  TLEA256Constants = array[0..7] of Cardinal;

const LEA256Constants: TLEA256Constants = ($C3EFE9DB, $44626B02, $79E27C8A, $78DF30EC, $715EA49E, $C785DA0A, $E04EF22A, $E5C40957);

type
  TLEA256Keys = array[0..7] of Cardinal;

type
  TLEA256RoundKeys = array[0..31] of array[0..5] of Cardinal;

type
  TLEA256Block = array[0..3] of Cardinal;

type
  TLEA256Context = record
    RoundKeys: TLEA256RoundKeys;
  end;

function ROL32(Value: Cardinal; N: Cardinal): Cardinal; inline;
function ROR32(Value: Cardinal; N: Cardinal): Cardinal; inline;

procedure LEA256_KeySchedule(var Context: TLEA256Context; Keys: TLEA256Keys);

procedure LEA256_Initialize(var Context: TLEA256Context; Keys: TLEA256Keys);
procedure LEA256_Burn(var Context: TLEA256Context);

procedure LEA256_Encrypt(var Context: TLEA256Context; var Block: TLEA256Block);
procedure LEA256_Decrypt(var Context: TLEA256Context; var Block: TLEA256Block);

implementation

function ROL32(Value: Cardinal; N: Cardinal): Cardinal; inline;
begin
  Result := ((Value shl N) or (Value shr (32 - N)));
end;

function ROR32(Value: Cardinal; N: Cardinal): Cardinal; inline;
begin
  Result := ((Value shr N) or (Value shl (32 - N)));
end;

procedure LEA256_KeySchedule(var Context: TLEA256Context; Keys: TLEA256Keys);
var T: TLEA256Keys;
var I: Integer;
var Temp: Cardinal;
begin
  T := Keys;
  for I := 0 to 31 do begin
    Temp := ROL32(LEA256Constants[I and 7], I and $1F);
    T[((I * 6) + 0) and 7] := ROL32(T[((I * 6) + 0) and 7] +       Temp    ,  1);
    T[((I * 6) + 1) and 7] := ROL32(T[((I * 6) + 1) and 7] + ROL32(Temp, 1),  3);
    T[((I * 6) + 2) and 7] := ROL32(T[((I * 6) + 2) and 7] + ROL32(Temp, 2),  6);
    T[((I * 6) + 3) and 7] := ROL32(T[((I * 6) + 3) and 7] + ROL32(Temp, 3), 11);
    T[((I * 6) + 4) and 7] := ROL32(T[((I * 6) + 4) and 7] + ROL32(Temp, 4), 13);
    T[((I * 6) + 5) and 7] := ROL32(T[((I * 6) + 5) and 7] + ROL32(Temp, 5), 17);
    Context.RoundKeys[I][0] := T[((I * 6) + 0) and 7];
    Context.RoundKeys[I][1] := T[((I * 6) + 1) and 7];
    Context.RoundKeys[I][2] := T[((I * 6) + 2) and 7];
    Context.RoundKeys[I][3] := T[((I * 6) + 3) and 7];
    Context.RoundKeys[I][4] := T[((I * 6) + 4) and 7];
    Context.RoundKeys[I][5] := T[((I * 6) + 5) and 7];
  end;
end;

procedure LEA256_Initialize(var Context: TLEA256Context; Keys: TLEA256Keys);
begin
  LEA256_KeySchedule(Context, Keys);
end;

procedure LEA256_Burn(var Context: TLEA256Context);
var I: Integer;
var J: Integer;
begin
  for I := 0 to 31 do begin
    for J := 0 to 5 do begin
      Context.RoundKeys[I][J] := 0;
    end;
  end;
end;

procedure LEA256_Encrypt(var Context: TLEA256Context; var Block: TLEA256Block);
var I: Integer;
begin
  I := -1;
  repeat
    I := I + 1;
    Block[3] := ROR32((Block[2] xor Context.RoundKeys[I][4]) + (Block[3] xor Context.RoundKeys[I][5]), 3);
    Block[2] := ROR32((Block[1] xor Context.RoundKeys[I][2]) + (Block[2] xor Context.RoundKeys[I][3]), 5);
    Block[1] := ROL32((Block[0] xor Context.RoundKeys[I][0]) + (Block[1] xor Context.RoundKeys[I][1]), 9);
    I := I + 1;
    Block[0] := ROR32((Block[3] xor Context.RoundKeys[I][4]) + (Block[0] xor Context.RoundKeys[I][5]), 3);
    Block[3] := ROR32((Block[2] xor Context.RoundKeys[I][2]) + (Block[3] xor Context.RoundKeys[I][3]), 5);
    Block[2] := ROL32((Block[1] xor Context.RoundKeys[I][0]) + (Block[2] xor Context.RoundKeys[I][1]), 9);
    I := I + 1;
    Block[1] := ROR32((Block[0] xor Context.RoundKeys[I][4]) + (Block[1] xor Context.RoundKeys[I][5]), 3);
    Block[0] := ROR32((Block[3] xor Context.RoundKeys[I][2]) + (Block[0] xor Context.RoundKeys[I][3]), 5);
    Block[3] := ROL32((Block[2] xor Context.RoundKeys[I][0]) + (Block[3] xor Context.RoundKeys[I][1]), 9);
    I := I + 1;
    Block[2] := ROR32((Block[1] xor Context.RoundKeys[I][4]) + (Block[2] xor Context.RoundKeys[I][5]), 3);
    Block[1] := ROR32((Block[0] xor Context.RoundKeys[I][2]) + (Block[1] xor Context.RoundKeys[I][3]), 5);
    Block[0] := ROL32((Block[3] xor Context.RoundKeys[I][0]) + (Block[0] xor Context.RoundKeys[I][1]), 9);
  until (I = 31);
end;

procedure LEA256_Decrypt(var Context: TLEA256Context; var Block: TLEA256Block);
var I: Integer;
begin
  I := 31;
  repeat
    Block[0] := (ROR32(Block[0], 9) - (Block[3] xor Context.RoundKeys[I][0])) xor Context.RoundKeys[I][1];
    Block[1] := (ROL32(Block[1], 5) - (Block[0] xor Context.RoundKeys[I][2])) xor Context.RoundKeys[I][3];
    Block[2] := (ROL32(Block[2], 3) - (Block[1] xor Context.RoundKeys[I][4])) xor Context.RoundKeys[I][5];
    I := I - 1;
    Block[3] := (ROR32(Block[3], 9) - (Block[2] xor Context.RoundKeys[I][0])) xor Context.RoundKeys[I][1];
    Block[0] := (ROL32(Block[0], 5) - (Block[3] xor Context.RoundKeys[I][2])) xor Context.RoundKeys[I][3];
    Block[1] := (ROL32(Block[1], 3) - (Block[0] xor Context.RoundKeys[I][4])) xor Context.RoundKeys[I][5];
    I := I - 1;
    Block[2] := (ROR32(Block[2], 9) - (Block[1] xor Context.RoundKeys[I][0])) xor Context.RoundKeys[I][1];
    Block[3] := (ROL32(Block[3], 5) - (Block[2] xor Context.RoundKeys[I][2])) xor Context.RoundKeys[I][3];
    Block[0] := (ROL32(Block[0], 3) - (Block[3] xor Context.RoundKeys[I][4])) xor Context.RoundKeys[I][5];
    I := I - 1;
    Block[1] := (ROR32(Block[1], 9) - (Block[0] xor Context.RoundKeys[I][0])) xor Context.RoundKeys[I][1];
    Block[2] := (ROL32(Block[2], 5) - (Block[1] xor Context.RoundKeys[I][2])) xor Context.RoundKeys[I][3];
    Block[3] := (ROL32(Block[3], 3) - (Block[2] xor Context.RoundKeys[I][4])) xor Context.RoundKeys[I][5];
    I := I - 1;
  until (I = -1);
end;

end.

[ Source Code ]

In Swedish?
View this page in Swedish