An implementation of a CTR mode for the block cipher LEA-256 for Embarcadero Delphi
unit LEA256CTR;
{
An implementation of a CTR mode (with a 128-bit nonce and a 64-bit counter) for the block cipher LEA-256 (Lightweight Encryption Algorithm 256-bit) for Embarcadero Delphi. Keep in mind that the nonce should be randomly selected as we are adding together the nonce and the counter values.
Original Author: Andreas Jonsson. (www.andreas-software.com)
NOTICE: 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, LEA256;
type
TLEA256CTRKeys = array[0..7] of Cardinal;
type
TLEA256CTRNumbersOnce = array[0..3] of Cardinal;
type
TLEA256CTRSerializedBlock = array[0..15] of Byte;
type
TLEA256CTRContext = record
LEA256Context: TLEA256Context;
NumbersOnce: TLEA256CTRNumbersOnce;
Counter: UInt64;
ByteCounter: Byte;
LastBlock: TLEA256CTRSerializedBlock;
end;
function Hi32(U: UInt64): Cardinal; inline;
function Lo32(U: UInt64): Cardinal; inline;
procedure LEA256CTR_Block(var Context: TLEA256CTRContext);
procedure LEA256CTR_Initialize(var Context: TLEA256CTRContext; Keys: TLEA256CTRKeys; NumbersOnce: TLEA256CTRNumbersOnce);
function LEA256CTR_GenerateByte(var Context: TLEA256CTRContext): Byte; inline;
procedure LEA256CTR_Burn(var Context: TLEA256CTRContext);
function LEA256CTR_GenerateWord(var Context: TLEA256CTRContext): Word;
function LEA256CTR_GenerateCardinal(var Context: TLEA256CTRContext): Cardinal;
function LEA256CTR_GenerateUInt64(var Context: TLEA256CTRContext): UInt64;
implementation
function Hi32(U: UInt64): Cardinal; inline;
begin
Result := ((U and $FFFFFFFF00000000) shr 32);
end;
function Lo32(U: UInt64): Cardinal; inline;
begin
Result := ( U and $00000000FFFFFFFF);
end;
procedure LEA256CTR_Block(var Context: TLEA256CTRContext);
var CounterHi: Cardinal;
var CounterLo: Cardinal;
var Block: TLEA256Block;
begin
CounterHi := Hi32(Context.Counter);
CounterLo := Lo32(Context.Counter);
Block[0] := Context.NumbersOnce[0] + CounterHi;
Block[1] := Context.NumbersOnce[1] + CounterLo;
Block[2] := Context.NumbersOnce[2] + CounterHi;
Block[3] := Context.NumbersOnce[3] + CounterLo;
LEA256_Encrypt(Context.LEA256Context, Block);
Move(Block, Context.LastBlock, 16);
end;
procedure LEA256CTR_Initialize(var Context: TLEA256CTRContext; Keys: TLEA256CTRKeys; NumbersOnce: TLEA256CTRNumbersOnce);
begin
LEA256_Initialize(Context.LEA256Context, TLEA256Keys(Keys));
Context.NumbersOnce := NumbersOnce;
Context.Counter := 0;
Context.ByteCounter := 0;
end;
function LEA256CTR_GenerateByte(var Context: TLEA256CTRContext): Byte; inline;
begin
if Context.ByteCounter = 0 then begin
LEA256CTR_Block(Context);
end;
Result := Context.LastBlock[Context.ByteCounter];
if Context.ByteCounter = 15 then begin
Context.Counter := Context.Counter + 1;
Context.ByteCounter := 0;
end
else begin
Context.ByteCounter := Context.ByteCounter + 1;
end;
end;
procedure LEA256CTR_Burn(var Context: TLEA256CTRContext);
var I: Integer;
begin
LEA256_Burn(Context.LEA256Context);
for I := 0 to 3 do begin
Context.NumbersOnce[I] := 0;
end;
Context.Counter := 0;
Context.ByteCounter := 0;
for I := 0 to 15 do begin
Context.LastBlock[I] := 0;
end;
end;
function LEA256CTR_GenerateWord(var Context: TLEA256CTRContext): Word;
var ByteArray: array[0..1] of Byte;
begin
ByteArray[0] := LEA256CTR_GenerateByte(Context);
ByteArray[1] := LEA256CTR_GenerateByte(Context);
Move(ByteArray, Result, 2);
end;
function LEA256CTR_GenerateCardinal(var Context: TLEA256CTRContext): Cardinal;
var ByteArray: array[0..3] of Byte;
begin
ByteArray[0] := LEA256CTR_GenerateByte(Context);
ByteArray[1] := LEA256CTR_GenerateByte(Context);
ByteArray[2] := LEA256CTR_GenerateByte(Context);
ByteArray[3] := LEA256CTR_GenerateByte(Context);
Move(ByteArray, Result, 4);
end;
function LEA256CTR_GenerateUInt64(var Context: TLEA256CTRContext): UInt64;
var ByteArray: array[0..7] of Byte;
begin
ByteArray[0] := LEA256CTR_GenerateByte(Context);
ByteArray[1] := LEA256CTR_GenerateByte(Context);
ByteArray[2] := LEA256CTR_GenerateByte(Context);
ByteArray[3] := LEA256CTR_GenerateByte(Context);
ByteArray[4] := LEA256CTR_GenerateByte(Context);
ByteArray[5] := LEA256CTR_GenerateByte(Context);
ByteArray[6] := LEA256CTR_GenerateByte(Context);
ByteArray[7] := LEA256CTR_GenerateByte(Context);
Move(ByteArray, Result, 8);
end;
end.