Andreas Software - Source Code - LEA256CTR.PAS

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


unit LEA256CTR;

{
  An implementation of a CTR mode for 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, 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.

[ Source Code ]

In Swedish?
View this page in Swedish