unit HlpSHA3;

{$I HashLib.inc}

interface

uses
{$IFDEF HAS_UNITSCOPE}
  System.SysUtils,
{$ELSE}
  SysUtils,
{$ENDIF HAS_UNITSCOPE}
  HlpBits,
{$IFDEF DELPHI}
  HlpHashBuffer,
  HlpBitConverter,
  HlpHash,
{$ENDIF DELPHI}
  HlpIHashInfo,
  HlpIHash,
  HlpHashResult,
  HlpIHashResult,
  HlpHashCryptoNotBuildIn,
  HlpConverters,
  HlpHashSize,
  HlpHashLibTypes;

resourcestring
  SInvalidHashMode = 'Only "[%s]" HashModes are Supported';
  SInvalidXOFSize = 'XOFSize in Bits must not be Negative and be Divisible by 8.';

type
  TSHA3 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)

  type
{$SCOPEDENUMS ON}
    THashMode = (hmKeccak = $1, hmSHA3 = $6, hmShake = $1F);
{$SCOPEDENUMS OFF}
  strict protected

    Fm_state: THashLibUInt64Array;
    FHashSize, FBlockSize: Int32;
    FHashMode: THashMode;

{$IFNDEF USE_UNROLLED_VARIANT}
{$REGION 'Consts'}

  const

    RC: array [0 .. 23] of UInt64 = (UInt64($0000000000000001),
      UInt64($0000000000008082), UInt64($800000000000808A),
      UInt64($8000000080008000), UInt64($000000000000808B),
      UInt64($0000000080000001), UInt64($8000000080008081),
      UInt64($8000000000008009), UInt64($000000000000008A),
      UInt64($0000000000000088), UInt64($0000000080008009),
      UInt64($000000008000000A), UInt64($000000008000808B),
      UInt64($800000000000008B), UInt64($8000000000008089),
      UInt64($8000000000008003), UInt64($8000000000008002),
      UInt64($8000000000000080), UInt64($000000000000800A),
      UInt64($800000008000000A), UInt64($8000000080008081),
      UInt64($8000000000008080), UInt64($0000000080000001),
      UInt64($8000000080008008));

{$ENDREGION}
{$ENDIF USE_UNROLLED_VARIANT}
    function GetName: String; override;
    constructor Create(a_hash_size: THashSize);

    procedure Finish(); override;
    function GetResult(): THashLibByteArray; override;
    procedure TransformBlock(a_data: PByte; a_data_length: Int32;
      a_index: Int32); override;

  public
    procedure Initialize; override;

  end;

type

  TSHA3_224 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type

  TSHA3_256 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type

  TSHA3_384 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type

  TSHA3_512 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type

  TKeccak_224 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type

  TKeccak_256 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type

  TKeccak_384 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type

  TKeccak_512 = class sealed(TSHA3)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type
  TShake = class abstract(TSHA3, IXOF)
  strict private
  var
    FXOFSize: Int32;
    function GetXOFSize: Int32; inline;
    procedure SetXOFSize(a_xof_size_in_bits: Int32); inline;
  strict protected
    constructor Create(a_hash_size: THashSize);
    function SetXOFOutputSize(a_xof_size_in_bits: Int32): IXOF;
    property XOFSize: Int32 read GetXOFSize write SetXOFSize;

  public
    function GetResult(): THashLibByteArray; override;
    function TransformFinal(): IHashResult; override;
  end;

type
  TShake_128 = class sealed(TShake)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

type
  TShake_256 = class sealed(TShake)

  public

    constructor Create();
    function Clone(): IHash; override;
  end;

implementation

{ TSHA3 }

constructor TSHA3.Create(a_hash_size: THashSize);
begin
  Inherited Create(Int32(a_hash_size), 200 - (Int32(a_hash_size) * 2));

  FHashSize := HashSize;
  FBlockSize := BlockSize;

  System.SetLength(Fm_state, 25);

end;

procedure TSHA3.Finish;
var
  buffer_pos: Int32;
  block: THashLibByteArray;
begin
  buffer_pos := Fm_buffer.Pos;
  block := Fm_buffer.GetBytesZeroPadded();

  block[buffer_pos] := Int32(FHashMode);
  block[FBlockSize - 1] := block[FBlockSize - 1] xor $80;

  TransformBlock(PByte(block), System.Length(block), 0);

{$IFDEF USE_UNROLLED_VARIANT}
  Fm_state[1] := not Fm_state[1];
  Fm_state[2] := not Fm_state[2];
  Fm_state[8] := not Fm_state[8];
  Fm_state[12] := not Fm_state[12];
  Fm_state[17] := not Fm_state[17];
{$ENDIF USE_UNROLLED_VARIANT}
end;

function TSHA3.GetName: String;
begin
  case FHashMode of
    TSHA3.THashMode.hmKeccak:
      Result := Format('%s_%u', ['TKeccak', Self.HashSize * 8]);
    TSHA3.THashMode.hmSHA3:
      Result := Self.ClassName;
    TSHA3.THashMode.hmShake:
      Result := Format('%s_%s_%u', [Self.ClassName, 'XOFSizeInBits',
        (Self as IXOF).XOFSize]);
  else
    begin
      raise EArgumentInvalidHashLibException.CreateResFmt(@SInvalidHashMode,
        ['hmKeccak, hmSHA3, hmShake']);
    end;
  end;
end;

function TSHA3.GetResult: THashLibByteArray;
begin

  System.SetLength(Result, FHashSize);

  TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(Result), 0,
    System.Length(Result));

end;

procedure TSHA3.Initialize;
begin

  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt64),
    UInt64(0));

{$IFDEF USE_UNROLLED_VARIANT}
  Fm_state[1] := System.High(UInt64);
  Fm_state[2] := System.High(UInt64);
  Fm_state[8] := System.High(UInt64);
  Fm_state[12] := System.High(UInt64);
  Fm_state[17] := System.High(UInt64);
  Fm_state[20] := System.High(UInt64);
{$ENDIF USE_UNROLLED_VARIANT}
  Inherited Initialize();

end;

procedure TSHA3.TransformBlock(a_data: PByte; a_data_length: Int32;
  a_index: Int32);
var
  data: array [0 .. 20] of UInt64;
  Ca, Ce, Ci, Co, Cu, De, Di, &Do, Du, Da: UInt64;
  j, upcount: Int32;
{$IFDEF USE_UNROLLED_VARIANT}
  Aba, Abe, Abi, Abo, Abu, Aga, Age, Agi, Ago, Agu, Aka, Ake, Aki, Ako, Aku,
    Ama, Ame, Ami, Amo, Amu, Asa, Ase, Asi, Aso, Asu, Bba, Bbe, Bbi, Bbo, Bbu,
    Bga, Bge, Bgi, Bgo, Bgu, Bka, Bke, Bki, Bko, Bku, Bma, Bme, Bmi, Bmo, Bmu,
    Bsa, Bse, Bsi, Bso, Bsu, Eba, Ebe, Ebi, Ebo, Ebu, Ega, Ege, Egi, Ego, Egu,
    Eka, Eke, Eki, Eko, Eku, Ema, Eme, Emi, Emo, Emu, Esa, Ese, Esi, Eso,
    Esu: UInt64;
{$ELSE}
  temp: array [0 .. 24] of UInt64;
{$ENDIF USE_UNROLLED_VARIANT}
begin
  TConverters.le64_copy(a_data, a_index, @(data[0]), 0, a_data_length);

  j := 0;
  upcount := FBlockSize shr 3;
  while j < upcount do
  begin
    Fm_state[j] := Fm_state[j] xor data[j];
    System.Inc(j);
  end;

{$IFDEF USE_UNROLLED_VARIANT}
  Aba := Fm_state[0];
  Abe := Fm_state[1];
  Abi := Fm_state[2];
  Abo := Fm_state[3];
  Abu := Fm_state[4];
  Aga := Fm_state[5];
  Age := Fm_state[6];
  Agi := Fm_state[7];
  Ago := Fm_state[8];
  Agu := Fm_state[9];
  Aka := Fm_state[10];
  Ake := Fm_state[11];
  Aki := Fm_state[12];
  Ako := Fm_state[13];
  Aku := Fm_state[14];
  Ama := Fm_state[15];
  Ame := Fm_state[16];
  Ami := Fm_state[17];
  Amo := Fm_state[18];
  Amu := Fm_state[19];
  Asa := Fm_state[20];
  Ase := Fm_state[21];
  Asi := Fm_state[22];
  Aso := Fm_state[23];
  Asu := Fm_state[24];

  Ca := Aba xor Aga xor Aka xor Ama xor Asa;
  Ce := Abe xor Age xor Ake xor Ame xor Ase;
  Ci := Abi xor Agi xor Aki xor Ami xor Asi;
  Co := Abo xor Ago xor Ako xor Amo xor Aso;
  Cu := Abu xor Agu xor Aku xor Amu xor Asu;
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[0];
  Eba := Eba xor $0000000000000001;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[1];
  Aba := Aba xor $0000000000008082;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[2];
  Eba := Eba xor $800000000000808A;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[3];
  Aba := Aba xor $8000000080008000;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[4];
  Eba := Eba xor $000000000000808B;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[5];
  Aba := Aba xor $0000000080000001;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[6];
  Eba := Eba xor $8000000080008081;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[7];
  Aba := Aba xor $8000000000008009;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[8];
  Eba := Eba xor $000000000000008A;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[9];
  Aba := Aba xor $0000000000000088;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[10];
  Eba := Eba xor $0000000080008009;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[11];
  Aba := Aba xor $000000008000000A;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[12];
  Eba := Eba xor $000000008000808B;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[13];
  Aba := Aba xor $800000000000008B;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[14];
  Eba := Eba xor $8000000000008089;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[15];
  Aba := Aba xor $8000000000008003;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[16];
  Eba := Eba xor $8000000000008002;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[17];
  Aba := Aba xor $8000000000000080;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[18];
  Eba := Eba xor $000000000000800A;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[19];
  Aba := Aba xor $800000008000000A;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[20];
  Eba := Eba xor $8000000080008081;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[21];
  Aba := Aba xor $8000000000008080;
  Ca := Aba;
  Abe := Bbe xor (not Bbi or Bbo);
  Ce := Abe;
  Abi := Bbi xor (Bbo and Bbu);
  Ci := Abi;
  Abo := Bbo xor (Bbu or Bba);
  Co := Abo;
  Abu := Bbu xor (Bba and Bbe);
  Cu := Abu;
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Ca := Ca xor Aga;
  Age := Bge xor (Bgi and Bgo);
  Ce := Ce xor Age;
  Agi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Agi;
  Ago := Bgo xor (Bgu or Bga);
  Co := Co xor Ago;
  Agu := Bgu xor (Bga and Bge);
  Cu := Cu xor Agu;
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ca := Ca xor Aka;
  Ake := Bke xor (Bki and Bko);
  Ce := Ce xor Ake;
  Aki := Bki xor (not Bko and Bku);
  Ci := Ci xor Aki;
  Ako := (not Bko) xor (Bku or Bka);
  Co := Co xor Ako;
  Aku := Bku xor (Bka and Bke);
  Cu := Cu xor Aku;
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ca := Ca xor Ama;
  Ame := Bme xor (Bmi or Bmo);
  Ce := Ce xor Ame;
  Ami := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Ami;
  Amo := not Bmo xor (Bmu and Bma);
  Co := Co xor Amo;
  Amu := Bmu xor (Bma or Bme);
  Cu := Cu xor Amu;
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Asa;
  Ase := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ase;
  Asi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Asi;
  Aso := Bso xor (Bsu or Bsa);
  Co := Co xor Aso;
  Asu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Asu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Aba := Aba xor De;
  Bba := Aba;
  Age := Age xor Di;
  Bbe := TBits.RotateLeft64(Age, 44);
  Aki := Aki xor &Do;
  Bbi := TBits.RotateLeft64(Aki, 43);
  Amo := Amo xor Du;
  Bbo := TBits.RotateLeft64(Amo, 21);
  Asu := Asu xor Da;
  Bbu := TBits.RotateLeft64(Asu, 14);
  Eba := Bba xor (Bbe or Bbi);
  // Eba := Eba xor RC[22];
  Eba := Eba xor $0000000080000001;
  Ca := Eba;
  Ebe := Bbe xor (not Bbi or Bbo);
  Ce := Ebe;
  Ebi := Bbi xor (Bbo and Bbu);
  Ci := Ebi;
  Ebo := Bbo xor (Bbu or Bba);
  Co := Ebo;
  Ebu := Bbu xor (Bba and Bbe);
  Cu := Ebu;
  Abo := Abo xor Du;
  Bga := TBits.RotateLeft64(Abo, 28);
  Agu := Agu xor Da;
  Bge := TBits.RotateLeft64(Agu, 20);
  Aka := Aka xor De;
  Bgi := TBits.RotateLeft64(Aka, 3);
  Ame := Ame xor Di;
  Bgo := TBits.RotateLeft64(Ame, 45);
  Asi := Asi xor &Do;
  Bgu := TBits.RotateLeft64(Asi, 61);
  Ega := Bga xor (Bge or Bgi);
  Ca := Ca xor Ega;
  Ege := Bge xor (Bgi and Bgo);
  Ce := Ce xor Ege;
  Egi := Bgi xor (Bgo or not Bgu);
  Ci := Ci xor Egi;
  Ego := Bgo xor (Bgu or Bga);
  Co := Co xor Ego;
  Egu := Bgu xor (Bga and Bge);
  Cu := Cu xor Egu;
  Abe := Abe xor Di;
  Bka := TBits.RotateLeft64(Abe, 1);
  Agi := Agi xor &Do;
  Bke := TBits.RotateLeft64(Agi, 6);
  Ako := Ako xor Du;
  Bki := TBits.RotateLeft64(Ako, 25);
  Amu := Amu xor Da;
  Bko := TBits.RotateLeft64(Amu, 8);
  Asa := Asa xor De;
  Bku := TBits.RotateLeft64(Asa, 18);
  Eka := Bka xor (Bke or Bki);
  Ca := Ca xor Eka;
  Eke := Bke xor (Bki and Bko);
  Ce := Ce xor Eke;
  Eki := Bki xor (not Bko and Bku);
  Ci := Ci xor Eki;
  Eko := (not Bko) xor (Bku or Bka);
  Co := Co xor Eko;
  Eku := Bku xor (Bka and Bke);
  Cu := Cu xor Eku;
  Abu := Abu xor Da;
  Bma := TBits.RotateLeft64(Abu, 27);
  Aga := Aga xor De;
  Bme := TBits.RotateLeft64(Aga, 36);
  Ake := Ake xor Di;
  Bmi := TBits.RotateLeft64(Ake, 10);
  Ami := Ami xor &Do;
  Bmo := TBits.RotateLeft64(Ami, 15);
  Aso := Aso xor Du;
  Bmu := TBits.RotateLeft64(Aso, 56);
  Ema := Bma xor (Bme and Bmi);
  Ca := Ca xor Ema;
  Eme := Bme xor (Bmi or Bmo);
  Ce := Ce xor Eme;
  Emi := Bmi xor (not Bmo or Bmu);
  Ci := Ci xor Emi;
  Emo := not Bmo xor (Bmu and Bma);
  Co := Co xor Emo;
  Emu := Bmu xor (Bma or Bme);
  Cu := Cu xor Emu;
  Abi := Abi xor &Do;
  Bsa := TBits.RotateLeft64(Abi, 62);
  Ago := Ago xor Du;
  Bse := TBits.RotateLeft64(Ago, 55);
  Aku := Aku xor Da;
  Bsi := TBits.RotateLeft64(Aku, 39);
  Ama := Ama xor De;
  Bso := TBits.RotateLeft64(Ama, 41);
  Ase := Ase xor Di;
  Bsu := TBits.RotateLeft64(Ase, 2);
  Esa := Bsa xor (not Bse and Bsi);
  Ca := Ca xor Esa;
  Ese := not Bse xor (Bsi or Bso);
  Ce := Ce xor Ese;
  Esi := Bsi xor (Bso and Bsu);
  Ci := Ci xor Esi;
  Eso := Bso xor (Bsu or Bsa);
  Co := Co xor Eso;
  Esu := Bsu xor (Bsa and Bse);
  Cu := Cu xor Esu;
  De := Cu xor TBits.RotateLeft64(Ce, 1);
  Di := Ca xor TBits.RotateLeft64(Ci, 1);
  &Do := Ce xor TBits.RotateLeft64(Co, 1);
  Du := Ci xor TBits.RotateLeft64(Cu, 1);
  Da := Co xor TBits.RotateLeft64(Ca, 1);
  Eba := Eba xor De;
  Bba := Eba;
  Ege := Ege xor Di;
  Bbe := TBits.RotateLeft64(Ege, 44);
  Eki := Eki xor &Do;
  Bbi := TBits.RotateLeft64(Eki, 43);
  Emo := Emo xor Du;
  Bbo := TBits.RotateLeft64(Emo, 21);
  Esu := Esu xor Da;
  Bbu := TBits.RotateLeft64(Esu, 14);
  Aba := Bba xor (Bbe or Bbi);
  // Aba := Aba xor RC[23];
  Aba := Aba xor $8000000080008008;
  Abe := Bbe xor (not Bbi or Bbo);
  Abi := Bbi xor (Bbo and Bbu);
  Abo := Bbo xor (Bbu or Bba);
  Abu := Bbu xor (Bba and Bbe);
  Ebo := Ebo xor Du;
  Bga := TBits.RotateLeft64(Ebo, 28);
  Egu := Egu xor Da;
  Bge := TBits.RotateLeft64(Egu, 20);
  Eka := Eka xor De;
  Bgi := TBits.RotateLeft64(Eka, 3);
  Eme := Eme xor Di;
  Bgo := TBits.RotateLeft64(Eme, 45);
  Esi := Esi xor &Do;
  Bgu := TBits.RotateLeft64(Esi, 61);
  Aga := Bga xor (Bge or Bgi);
  Age := Bge xor (Bgi and Bgo);
  Agi := Bgi xor (Bgo or not Bgu);
  Ago := Bgo xor (Bgu or Bga);
  Agu := Bgu xor (Bga and Bge);
  Ebe := Ebe xor Di;
  Bka := TBits.RotateLeft64(Ebe, 1);
  Egi := Egi xor &Do;
  Bke := TBits.RotateLeft64(Egi, 6);
  Eko := Eko xor Du;
  Bki := TBits.RotateLeft64(Eko, 25);
  Emu := Emu xor Da;
  Bko := TBits.RotateLeft64(Emu, 8);
  Esa := Esa xor De;
  Bku := TBits.RotateLeft64(Esa, 18);
  Aka := Bka xor (Bke or Bki);
  Ake := Bke xor (Bki and Bko);
  Aki := Bki xor (not Bko and Bku);
  Ako := not Bko xor (Bku or Bka);
  Aku := Bku xor (Bka and Bke);
  Ebu := Ebu xor Da;
  Bma := TBits.RotateLeft64(Ebu, 27);
  Ega := Ega xor De;
  Bme := TBits.RotateLeft64(Ega, 36);
  Eke := Eke xor Di;
  Bmi := TBits.RotateLeft64(Eke, 10);
  Emi := Emi xor &Do;
  Bmo := TBits.RotateLeft64(Emi, 15);
  Eso := Eso xor Du;
  Bmu := TBits.RotateLeft64(Eso, 56);
  Ama := Bma xor (Bme and Bmi);
  Ame := Bme xor (Bmi or Bmo);
  Ami := Bmi xor (not Bmo or Bmu);
  Amo := not Bmo xor (Bmu and Bma);
  Amu := Bmu xor (Bma or Bme);
  Ebi := Ebi xor &Do;
  Bsa := TBits.RotateLeft64(Ebi, 62);
  Ego := Ego xor Du;
  Bse := TBits.RotateLeft64(Ego, 55);
  Eku := Eku xor Da;
  Bsi := TBits.RotateLeft64(Eku, 39);
  Ema := Ema xor De;
  Bso := TBits.RotateLeft64(Ema, 41);
  Ese := Ese xor Di;
  Bsu := TBits.RotateLeft64(Ese, 2);
  Asa := Bsa xor (not Bse and Bsi);
  Ase := not Bse xor (Bsi or Bso);
  Asi := Bsi xor (Bso and Bsu);
  Aso := Bso xor (Bsu or Bsa);
  Asu := Bsu xor (Bsa and Bse);

  Fm_state[0] := Aba;
  Fm_state[1] := Abe;
  Fm_state[2] := Abi;
  Fm_state[3] := Abo;
  Fm_state[4] := Abu;
  Fm_state[5] := Aga;
  Fm_state[6] := Age;
  Fm_state[7] := Agi;
  Fm_state[8] := Ago;
  Fm_state[9] := Agu;
  Fm_state[10] := Aka;
  Fm_state[11] := Ake;
  Fm_state[12] := Aki;
  Fm_state[13] := Ako;
  Fm_state[14] := Aku;
  Fm_state[15] := Ama;
  Fm_state[16] := Ame;
  Fm_state[17] := Ami;
  Fm_state[18] := Amo;
  Fm_state[19] := Amu;
  Fm_state[20] := Asa;
  Fm_state[21] := Ase;
  Fm_state[22] := Asi;
  Fm_state[23] := Aso;
  Fm_state[24] := Asu;

{$ELSE}
  for j := 0 to 23 do
  begin
    Ca := Fm_state[00] xor Fm_state[05] xor Fm_state[10] xor Fm_state[15]
      xor Fm_state[20];
    Ce := Fm_state[01] xor Fm_state[06] xor Fm_state[11] xor Fm_state[16]
      xor Fm_state[21];
    Ci := Fm_state[02] xor Fm_state[07] xor Fm_state[12] xor Fm_state[17]
      xor Fm_state[22];
    Co := Fm_state[03] xor Fm_state[08] xor Fm_state[13] xor Fm_state[18]
      xor Fm_state[23];
    Cu := Fm_state[04] xor Fm_state[09] xor Fm_state[14] xor Fm_state[19]
      xor Fm_state[24];
    Da := TBits.RotateLeft64(Ca, 1) xor Co;
    De := TBits.RotateLeft64(Ce, 1) xor Cu;
    Di := TBits.RotateLeft64(Ci, 1) xor Ca;
    &Do := TBits.RotateLeft64(Co, 1) xor Ce;
    Du := TBits.RotateLeft64(Cu, 1) xor Ci;
    temp[00] := Fm_state[00] xor De;
    temp[01] := TBits.RotateLeft64(Fm_state[06] xor Di, 44);
    temp[02] := TBits.RotateLeft64(Fm_state[12] xor &Do, 43);
    temp[03] := TBits.RotateLeft64(Fm_state[18] xor Du, 21);
    temp[04] := TBits.RotateLeft64(Fm_state[24] xor Da, 14);
    temp[05] := TBits.RotateLeft64(Fm_state[03] xor Du, 28);
    temp[06] := TBits.RotateLeft64(Fm_state[09] xor Da, 20);
    temp[07] := TBits.RotateLeft64(Fm_state[10] xor De, 3);
    temp[08] := TBits.RotateLeft64(Fm_state[16] xor Di, 45);
    temp[09] := TBits.RotateLeft64(Fm_state[22] xor &Do, 61);
    temp[10] := TBits.RotateLeft64(Fm_state[01] xor Di, 1);
    temp[11] := TBits.RotateLeft64(Fm_state[07] xor &Do, 6);
    temp[12] := TBits.RotateLeft64(Fm_state[13] xor Du, 25);
    temp[13] := TBits.RotateLeft64(Fm_state[19] xor Da, 8);
    temp[14] := TBits.RotateLeft64(Fm_state[20] xor De, 18);
    temp[15] := TBits.RotateLeft64(Fm_state[04] xor Da, 27);
    temp[16] := TBits.RotateLeft64(Fm_state[05] xor De, 36);
    temp[17] := TBits.RotateLeft64(Fm_state[11] xor Di, 10);
    temp[18] := TBits.RotateLeft64(Fm_state[17] xor &Do, 15);
    temp[19] := TBits.RotateLeft64(Fm_state[23] xor Du, 56);
    temp[20] := TBits.RotateLeft64(Fm_state[02] xor &Do, 62);
    temp[21] := TBits.RotateLeft64(Fm_state[08] xor Du, 55);
    temp[22] := TBits.RotateLeft64(Fm_state[14] xor Da, 39);
    temp[23] := TBits.RotateLeft64(Fm_state[15] xor De, 41);
    temp[24] := TBits.RotateLeft64(Fm_state[21] xor Di, 2);
    Fm_state[00] := temp[00] xor ((not temp[01]) and temp[02]);
    Fm_state[01] := temp[01] xor ((not temp[02]) and temp[03]);
    Fm_state[02] := temp[02] xor ((not temp[03]) and temp[04]);
    Fm_state[03] := temp[03] xor ((not temp[04]) and temp[00]);
    Fm_state[04] := temp[04] xor ((not temp[00]) and temp[01]);
    Fm_state[05] := temp[05] xor ((not temp[06]) and temp[07]);
    Fm_state[06] := temp[06] xor ((not temp[07]) and temp[08]);
    Fm_state[07] := temp[07] xor ((not temp[08]) and temp[09]);
    Fm_state[08] := temp[08] xor ((not temp[09]) and temp[05]);
    Fm_state[09] := temp[09] xor ((not temp[05]) and temp[06]);
    Fm_state[10] := temp[10] xor ((not temp[11]) and temp[12]);
    Fm_state[11] := temp[11] xor ((not temp[12]) and temp[13]);
    Fm_state[12] := temp[12] xor ((not temp[13]) and temp[14]);
    Fm_state[13] := temp[13] xor ((not temp[14]) and temp[10]);
    Fm_state[14] := temp[14] xor ((not temp[10]) and temp[11]);
    Fm_state[15] := temp[15] xor ((not temp[16]) and temp[17]);
    Fm_state[16] := temp[16] xor ((not temp[17]) and temp[18]);
    Fm_state[17] := temp[17] xor ((not temp[18]) and temp[19]);
    Fm_state[18] := temp[18] xor ((not temp[19]) and temp[15]);
    Fm_state[19] := temp[19] xor ((not temp[15]) and temp[16]);
    Fm_state[20] := temp[20] xor ((not temp[21]) and temp[22]);
    Fm_state[21] := temp[21] xor ((not temp[22]) and temp[23]);
    Fm_state[22] := temp[22] xor ((not temp[23]) and temp[24]);
    Fm_state[23] := temp[23] xor ((not temp[24]) and temp[20]);
    Fm_state[24] := temp[24] xor ((not temp[20]) and temp[21]);
    Fm_state[00] := Fm_state[00] xor RC[j];
  end;

  System.FillChar(temp, System.SizeOf(temp), UInt64(0));
{$ENDIF USE_UNROLLED_VARIANT}
  System.FillChar(data, System.SizeOf(data), UInt64(0));
end;

{ TSHA3_224 }

function TSHA3_224.Clone(): IHash;
var
  HashInstance: TSHA3_224;
begin
  HashInstance := TSHA3_224.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TSHA3_224.Create;
begin
  Inherited Create(THashSize.hsHashSize224);
  FHashMode := THashMode.hmSHA3;
end;

{ TSHA3_256 }

function TSHA3_256.Clone(): IHash;
var
  HashInstance: TSHA3_256;
begin
  HashInstance := TSHA3_256.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TSHA3_256.Create;
begin
  Inherited Create(THashSize.hsHashSize256);
  FHashMode := THashMode.hmSHA3;
end;

{ TSHA3_384 }

function TSHA3_384.Clone(): IHash;
var
  HashInstance: TSHA3_384;
begin
  HashInstance := TSHA3_384.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TSHA3_384.Create;
begin
  Inherited Create(THashSize.hsHashSize384);
  FHashMode := THashMode.hmSHA3;
end;

{ TSHA3_512 }

function TSHA3_512.Clone(): IHash;
var
  HashInstance: TSHA3_512;
begin
  HashInstance := TSHA3_512.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TSHA3_512.Create;
begin
  Inherited Create(THashSize.hsHashSize512);
  FHashMode := THashMode.hmSHA3;
end;

{ TKeccak_224 }

function TKeccak_224.Clone(): IHash;
var
  HashInstance: TKeccak_224;
begin
  HashInstance := TKeccak_224.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TKeccak_224.Create;
begin
  Inherited Create(THashSize.hsHashSize224);
  FHashMode := THashMode.hmKeccak;
end;

{ TKeccak_256 }

function TKeccak_256.Clone(): IHash;
var
  HashInstance: TKeccak_256;
begin
  HashInstance := TKeccak_256.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TKeccak_256.Create;
begin
  Inherited Create(THashSize.hsHashSize256);
  FHashMode := THashMode.hmKeccak;
end;

{ TKeccak_384 }

function TKeccak_384.Clone(): IHash;
var
  HashInstance: TKeccak_384;
begin
  HashInstance := TKeccak_384.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TKeccak_384.Create;
begin
  Inherited Create(THashSize.hsHashSize384);
  FHashMode := THashMode.hmKeccak;
end;

{ TKeccak_512 }

function TKeccak_512.Clone(): IHash;
var
  HashInstance: TKeccak_512;
begin
  HashInstance := TKeccak_512.Create();
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TKeccak_512.Create;
begin
  Inherited Create(THashSize.hsHashSize512);
  FHashMode := THashMode.hmKeccak;
end;

{ TShake }

constructor TShake.Create(a_hash_size: THashSize);
begin
  Inherited Create(a_hash_size);
  FHashMode := THashMode.hmShake;
end;

function TShake.GetResult: THashLibByteArray;
var
  buffer_pos, Idx, LXofSize: Int32;
  block: THashLibByteArray;
begin
  buffer_pos := Fm_buffer.Pos;
  block := Fm_buffer.GetBytesZeroPadded();

  LXofSize := FXOFSize shr 3;
  Idx := 0;

  while Idx < LXofSize do
  begin
    if buffer_pos >= FBlockSize then
    begin
      TransformBlock(PByte(block), System.Length(block), 0);
      buffer_pos := 0;
    end;
    System.Inc(Idx);
  end;

  System.SetLength(Result, LXofSize);

  TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(Result), 0,
    System.Length(Result));

end;

function TShake.GetXOFSize: Int32;
begin
  Result := FXOFSize;
end;

function TShake.TransformFinal: IHashResult;
var
  tempresult: THashLibByteArray;
begin
  Finish();
{$IFDEF DEBUG}
  System.Assert(Fm_buffer.IsEmpty);
{$ENDIF DEBUG}
  tempresult := GetResult();
{$IFDEF DEBUG}
  System.Assert(System.Length(tempresult) = (XOFSize shr 3));
{$ENDIF DEBUG}
  Initialize();
  Result := THashResult.Create(tempresult);
end;

function TShake.SetXOFOutputSize(a_xof_size_in_bits: Int32): IXOF;
begin
  If (a_xof_size_in_bits < 0) or ((a_xof_size_in_bits and $7) <> 0) then
  begin
    raise EArgumentInvalidHashLibException.CreateRes(@SInvalidXOFSize);
  end;
  FXOFSize := a_xof_size_in_bits;
  Result := Self;
end;

procedure TShake.SetXOFSize(a_xof_size_in_bits: Int32);
begin
  SetXOFOutputSize(a_xof_size_in_bits);
end;

{ TShake_128 }

function TShake_128.Clone(): IHash;
var
  HashInstance: TShake_128;
begin
  HashInstance := (TShake_128.Create() as IXOF)
    .SetXOFOutputSize((Self as IXOF).XOFSize) as TShake_128;
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TShake_128.Create;
begin
  Inherited Create(THashSize.hsHashSize128);
end;

{ TShake_256 }

function TShake_256.Clone(): IHash;
var
  HashInstance: TShake_256;
begin
  HashInstance := (TShake_256.Create() as IXOF)
    .SetXOFOutputSize((Self as IXOF).XOFSize) as TShake_256;
  HashInstance.Fm_state := System.Copy(Fm_state);
  HashInstance.Fm_buffer := Fm_buffer.Clone();
  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
  Result := HashInstance as IHash;
  Result.BufferSize := BufferSize;
end;

constructor TShake_256.Create;
begin
  Inherited Create(THashSize.hsHashSize256);
end;

end.
