Browse Source

add support for SPECK Cipher Algorithm

Ugochukwu Mmaduekwe 6 years ago
parent
commit
a716cf691a

+ 4 - 2
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -209,7 +209,7 @@ uses
   ClpDsaKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaKeyPairGenerator.pas',
   ClpIDsaKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaKeyPairGenerator.pas',
   ClpDsaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpDsaSigner.pas',
-  ClpEncoders in '..\..\cryptolib\src\utils\encoders\ClpEncoders.pas',
+  ClpEncoders in '..\..\CryptoLib\src\Utils\Encoders\ClpEncoders.pas',
   ClpIDsaSigner in '..\..\CryptoLib\src\Interfaces\ClpIDsaSigner.pas',
   ClpDigest in '..\..\CryptoLib\src\Crypto\Digests\ClpDigest.pas',
   ClpECDHCBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHCBasicAgreement.pas',
@@ -240,7 +240,7 @@ uses
   ClpNat512 in '..\..\CryptoLib\src\Math\Raw\ClpNat512.pas',
   ClpInterleave in '..\..\CryptoLib\src\Math\Raw\ClpInterleave.pas',
   ClpIDsaExt in '..\..\CryptoLib\src\Interfaces\ClpIDsaExt.pas',
-  ClpISignersEncodings in '..\..\cryptolib\src\interfaces\ClpISignersEncodings.pas',
+  ClpISignersEncodings in '..\..\CryptoLib\src\Interfaces\ClpISignersEncodings.pas',
   ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
   ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
   ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
@@ -251,6 +251,8 @@ uses
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
   ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas',
+  ClpSpeckEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpSpeckEngine.pas',
+  ClpISpeckEngine in '..\..\CryptoLib\src\Interfaces\ClpISpeckEngine.pas',
   ClpSecP256R1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Custom.pas',
   ClpISecP256R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Custom.pas',
   ClpSecP256K1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas',

+ 4 - 0
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.TestInsight.dpr

@@ -261,6 +261,8 @@ uses
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
   ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas',
+  ClpSpeckEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpSpeckEngine.pas',
+  ClpISpeckEngine in '..\..\CryptoLib\src\Interfaces\ClpISpeckEngine.pas',
   ClpSecP256R1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Custom.pas',
   ClpISecP256R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Custom.pas',
   ClpSecP256K1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas',
@@ -286,6 +288,7 @@ uses
   BlowfishTestVectors in '..\src\Crypto\BlowfishTestVectors.pas',
   BlockCipherVectorTests in '..\src\Crypto\BlockCipherVectorTests.pas',
   AESTestVectors in '..\src\Crypto\AESTestVectors.pas',
+  SpeckTestVectors in '..\src\Crypto\SpeckTestVectors.pas',
   OIDTests in '..\src\Asn1\OIDTests.pas',
   SecureRandomTests in '..\src\Security\SecureRandomTests.pas',
   EqualsAndHashCodeTests in '..\src\Asn1\EqualsAndHashCodeTests.pas',
@@ -305,6 +308,7 @@ uses
   AESTests in '..\src\Crypto\AESTests.pas',
   IESCipherTests in '..\src\Math\IESCipherTests.pas',
   AESSICTests in '..\src\Crypto\AESSICTests.pas',
+  SPECKTests in '..\src\Crypto\SPECKTests.pas',
   Pkcs5Tests in '..\src\Crypto\Pkcs5Tests.pas',
   HkdfGeneratorTests in '..\src\Crypto\HkdfGeneratorTests.pas',
   ECIESTests in '..\src\Math\ECIESTests.pas',

+ 4 - 0
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -264,6 +264,8 @@ uses
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
   ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas',
+  ClpSpeckEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpSpeckEngine.pas',
+  ClpISpeckEngine in '..\..\CryptoLib\src\Interfaces\ClpISpeckEngine.pas',
   ClpSecP256R1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Custom.pas',
   ClpISecP256R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Custom.pas',
   ClpSecP256K1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas',
@@ -289,6 +291,7 @@ uses
   BlowfishTestVectors in '..\src\Crypto\BlowfishTestVectors.pas',
   BlockCipherVectorTests in '..\src\Crypto\BlockCipherVectorTests.pas',
   AESTestVectors in '..\src\Crypto\AESTestVectors.pas',
+  SpeckTestVectors in '..\src\Crypto\SpeckTestVectors.pas',
   OIDTests in '..\src\Asn1\OIDTests.pas',
   SecureRandomTests in '..\src\Security\SecureRandomTests.pas',
   EqualsAndHashCodeTests in '..\src\Asn1\EqualsAndHashCodeTests.pas',
@@ -308,6 +311,7 @@ uses
   AESTests in '..\src\Crypto\AESTests.pas',
   IESCipherTests in '..\src\Math\IESCipherTests.pas',
   AESSICTests in '..\src\Crypto\AESSICTests.pas',
+  SPECKTests in '..\src\Crypto\SPECKTests.pas',
   Pkcs5Tests in '..\src\Crypto\Pkcs5Tests.pas',
   HkdfGeneratorTests in '..\src\Crypto\HkdfGeneratorTests.pas',
   ECIESTests in '..\src\Math\ECIESTests.pas',

+ 13 - 6
CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <CONFIG>
   <ProjectOptions>
-    <Version Value="11"/>
+    <Version Value="10"/>
     <PathDelim Value="\"/>
     <General>
       <SessionStorage Value="InProjectDir"/>
@@ -17,10 +17,9 @@
       <Version Value="2"/>
     </PublishOptions>
     <RunParams>
-      <FormatVersion Value="2"/>
-      <Modes Count="1">
-        <Mode0 Name="default"/>
-      </Modes>
+      <local>
+        <FormatVersion Value="1"/>
+      </local>
     </RunParams>
     <RequiredPackages Count="4">
       <Item1>
@@ -36,7 +35,7 @@
         <PackageName Value="FCL"/>
       </Item4>
     </RequiredPackages>
-    <Units Count="48">
+    <Units Count="50">
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -230,6 +229,14 @@
         <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit47>
+      <Unit48>
+        <Filename Value="..\src\Crypto\SpeckTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit48>
+      <Unit49>
+        <Filename Value="..\src\Crypto\SPECKTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit49>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

+ 2 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr

@@ -33,7 +33,9 @@ uses
   BlockCipherMonteCarloTests,
   AESTestVectors,
   BlowfishTestVectors,
+  SpeckTestVectors,
   AESSICTests,
+  SPECKTests,
   IESCipherTests,
   MD5HMacTests,
   SHA1HMacTests,

+ 11 - 10
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <CONFIG>
   <ProjectOptions>
-    <Version Value="11"/>
+    <Version Value="10"/>
     <PathDelim Value="\"/>
     <General>
       <SessionStorage Value="InProjectDir"/>
@@ -18,16 +18,9 @@
     </PublishOptions>
     <RunParams>
       <local>
+        <FormatVersion Value="1"/>
         <CommandLineParams Value="--format=plain --all --progress"/>
       </local>
-      <FormatVersion Value="2"/>
-      <Modes Count="1">
-        <Mode0 Name="default">
-          <local>
-            <CommandLineParams Value="--format=plain --all --progress"/>
-          </local>
-        </Mode0>
-      </Modes>
     </RunParams>
     <RequiredPackages Count="2">
       <Item1>
@@ -37,7 +30,7 @@
         <PackageName Value="FCL"/>
       </Item2>
     </RequiredPackages>
-    <Units Count="48">
+    <Units Count="50">
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -230,6 +223,14 @@
         <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit47>
+      <Unit48>
+        <Filename Value="..\src\Crypto\SPECKTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit48>
+      <Unit49>
+        <Filename Value="..\src\Crypto\SpeckTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit49>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

+ 2 - 0
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr

@@ -31,7 +31,9 @@ uses
   BlockCipherMonteCarloTests,
   AESTestVectors,
   BlowfishTestVectors,
+  SpeckTestVectors,
   AESSICTests,
+  SPECKTests,
   IESCipherTests,
   MD5HMacTests,
   SHA1HMacTests,

+ 19 - 19
CryptoLib.Tests/src/Crypto/AESSICTests.pas

@@ -79,33 +79,33 @@ begin
   inherited;
 
   Fkeys := TCryptoLibMatrixByteArray.Create
-    (THex.Decode('2b7e151628aed2a6abf7158809cf4f3c'),
-    THex.Decode('8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'),
+    (THex.Decode('2B7E151628AED2A6ABF7158809CF4F3C'),
+    THex.Decode('8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B'),
     THex.Decode
-    ('603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4'));
+    ('603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4'));
 
   Fplain := TCryptoLibMatrixByteArray.Create
-    (THex.Decode('6bc1bee22e409f96e93d7e117393172a'),
-    THex.Decode('ae2d8a571e03ac9c9eb76fac45af8e51'),
-    THex.Decode('30c81c46a35ce411e5fbc1191a0a52ef'),
-    THex.Decode('f69f2445df4f9b17ad2b417be66c3710'));
+    (THex.Decode('6BC1BEE22E409F96E93D7E117393172A'),
+    THex.Decode('AE2D8A571E03AC9C9EB76FAC45AF8E51'),
+    THex.Decode('30C81C46A35CE411E5FBC1191A0A52EF'),
+    THex.Decode('F69F2445DF4F9B17AD2B417BE66C3710'));
 
   Fcipher := TCryptoLibGenericArray<TCryptoLibMatrixByteArray>.Create
     (TCryptoLibMatrixByteArray.Create
-    (THex.Decode('874d6191b620e3261bef6864990db6ce'),
-    THex.Decode('9806f66b7970fdff8617187bb9fffdff'),
-    THex.Decode('5ae4df3edbd5d35e5b4f09020db03eab'),
-    THex.Decode('1e031dda2fbe03d1792170a0f3009cee')),
+    (THex.Decode('874D6191B620E3261BEF6864990DB6CE'),
+    THex.Decode('9806F66B7970FDFF8617187BB9FFFDFF'),
+    THex.Decode('5AE4DF3EDBD5D35E5B4F09020DB03EAB'),
+    THex.Decode('1E031DDA2FBE03D1792170A0F3009CEE')),
     TCryptoLibMatrixByteArray.Create
-    (THex.Decode('1abc932417521ca24f2b0459fe7e6e0b'),
-    THex.Decode('090339ec0aa6faefd5ccc2c6f4ce8e94'),
-    THex.Decode('1e36b26bd1ebc670d1bd1d665620abf7'),
-    THex.Decode('4f78a7f6d29809585a97daec58c6b050')),
+    (THex.Decode('1ABC932417521CA24F2B0459FE7E6E0B'),
+    THex.Decode('090339EC0AA6FAEFD5CCC2C6F4CE8E94'),
+    THex.Decode('1E36B26BD1EBC670D1BD1D665620ABF7'),
+    THex.Decode('4F78A7F6D29809585A97DAEC58C6B050')),
     TCryptoLibMatrixByteArray.Create
-    (THex.Decode('601ec313775789a5b7a7f504bbf3d228'),
-    THex.Decode('f443e3ca4d62b59aca84e990cacaf5c5'),
-    THex.Decode('2b0930daa23de94ce87017ba2d84988d'),
-    THex.Decode('dfc9c58db67aada613c2dd08457941a6')));
+    (THex.Decode('601EC313775789A5B7A7F504BBF3D228'),
+    THex.Decode('F443E3CA4D62B59ACA84E990CACAF5C5'),
+    THex.Decode('2B0930DAA23DE94CE87017BA2D84988D'),
+    THex.Decode('DFC9C58DB67AADA613C2DD08457941A6')));
 end;
 
 procedure TTestAESSIC.TearDown;

+ 7 - 10
CryptoLib.Tests/src/Crypto/AESTests.pas

@@ -227,8 +227,7 @@ begin
 
   // // Set up
   engine := TAesEngine.Create();
-  blockCipher := TCbcBlockCipher.Create(engine); // CBC
-  // no padding
+  blockCipher := TCbcBlockCipher.Create(engine); // CBC no padding
   cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
 
   for i := System.Low(TAESTestVectors.FOfficialVectorKeys_AES_CBC)
@@ -296,8 +295,8 @@ begin
 
   // // Set up
   engine := TAesEngine.Create();
-  blockCipher := TCfbBlockCipher.Create(engine, engine.GetBlockSize * 8); // CFB
-  // no padding
+  // CFB no padding
+  blockCipher := TCfbBlockCipher.Create(engine, engine.GetBlockSize * 8);
   cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
 
   for i := System.Low(TAESTestVectors.FOfficialVectorKeys_AES_CFB)
@@ -329,8 +328,7 @@ begin
 
   // // Set up
   engine := TAesEngine.Create();
-  blockCipher := TSicBlockCipher.Create(engine); // CTR
-  // no padding
+  blockCipher := TSicBlockCipher.Create(engine); // CTR no padding
   cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
 
   for i := System.Low(TAESTestVectors.FOfficialVectorKeys_AES_CTR)
@@ -362,8 +360,7 @@ begin
 
   // // Set up
   engine := TAesEngine.Create();
-  blockCipher := engine as IBlockCipher; // ECB
-  // no padding
+  blockCipher := engine as IBlockCipher; // ECB no padding
   cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
 
   for i := System.Low(TAESTestVectors.FOfficialVectorKeys_AES_ECB)
@@ -393,8 +390,8 @@ begin
 
   // // Set up
   engine := TAesEngine.Create();
-  blockCipher := TOfbBlockCipher.Create(engine, engine.GetBlockSize * 8); // OFB
-  // no padding
+  // OFB no padding
+  blockCipher := TOfbBlockCipher.Create(engine, engine.GetBlockSize * 8);
   cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
 
   for i := System.Low(TAESTestVectors.FOfficialVectorKeys_AES_OFB)

+ 88 - 0
CryptoLib.Tests/src/Crypto/BlockCipherVectorTests.pas

@@ -33,6 +33,7 @@ uses
 {$ENDIF FPC}
   AESTestVectors,
   BlowfishTestVectors,
+  SpeckTestVectors,
   ClpIBlockCipher,
   ClpICipherParameters,
   ClpAesEngine,
@@ -41,6 +42,8 @@ uses
   ClpIAesLightEngine,
   ClpBlowfishEngine,
   ClpIBlowfishEngine,
+  ClpSpeckEngine,
+  ClpISpeckEngine,
   ClpKeyParameter,
   ClpIKeyParameter,
   ClpParametersWithIV,
@@ -78,6 +81,11 @@ type
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESLightEngine;
     procedure TestBlockCipherBlowfishEngine;
+    procedure TestBlockCipherSpeck32Engine;
+    procedure TestBlockCipherSpeck48Engine;
+    procedure TestBlockCipherSpeck64Engine;
+    procedure TestBlockCipherSpeck96Engine;
+    procedure TestBlockCipherSpeck128Engine;
     procedure TestBadParameters;
 
   end;
@@ -249,6 +257,86 @@ begin
 
 end;
 
+procedure TTestBlockCipherVector.TestBlockCipherSpeck32Engine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck32BlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck32BlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck32Engine.Create() as ISpeckEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck32BlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck32BlockCipherVectorInputs[I],
+      TSpeckTestVectors.FSpeck32BlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck48Engine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck48BlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck48BlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck48Engine.Create() as ISpeckEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck48BlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck48BlockCipherVectorInputs[I],
+      TSpeckTestVectors.FSpeck48BlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck64Engine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck64BlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck64BlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck64Engine.Create() as ISpeckEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck64BlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck64BlockCipherVectorInputs[I],
+      TSpeckTestVectors.FSpeck64BlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck96Engine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck96BlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck96BlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck96Engine.Create() as ISpeckEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck96BlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck96BlockCipherVectorInputs[I],
+      TSpeckTestVectors.FSpeck96BlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck128Engine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck128BlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck128BlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck128Engine.Create() as ISpeckEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck128BlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck128BlockCipherVectorInputs[I],
+      TSpeckTestVectors.FSpeck128BlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
 initialization
 
 // Register any test cases with the test runner

+ 369 - 0
CryptoLib.Tests/src/Crypto/SPECKTests.pas

@@ -0,0 +1,369 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit SPECKTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  SpeckTestVectors,
+  ClpSpeckEngine,
+  ClpISpeckEngine,
+  ClpIKeyParameter,
+  ClpKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpIBufferedCipher,
+  ClpICipherKeyGenerator,
+  ClpICipherParameters,
+  ClpBlockCipherModes,
+  ClpIBlockCipherModes,
+  ClpIBlockCipher,
+  ClpBufferedBlockCipher,
+  ClpIBufferedBlockCipher,
+  ClpEncoders,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  TTestSPECK = class(TCryptoLibTestCase)
+  private
+
+    procedure doSPECKTest(const cipher: IBufferedCipher;
+      const param: ICipherParameters; const input, output: String;
+      withpadding: Boolean = False);
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestSPECK64_CBC_NOPADDING_WITH_IV;
+    procedure TestSPECK128_CBC_NOPADDING_WITH_IV;
+    procedure TestSPECK64_CTR_NOPADDING_WITH_IV;
+    procedure TestSPECK128_CTR_NOPADDING_WITH_IV;
+    procedure TestSPECK64_ECB_NOPADDING_NO_IV;
+    procedure TestSPECK128_ECB_NOPADDING_NO_IV;
+
+  end;
+
+implementation
+
+{ TTestSPECK }
+
+procedure TTestSPECK.doSPECKTest(const cipher: IBufferedCipher;
+  const param: ICipherParameters; const input, output: String;
+  withpadding: Boolean);
+var
+  LInput, LOutput, EncryptionResult, DecryptionResult: TBytes;
+  // len1, len2: Int32;
+begin
+  LInput := THex.Decode(input);
+  LOutput := THex.Decode(output);
+
+  cipher.Init(True, param);
+
+  // Encryption
+  // Single Pass
+  EncryptionResult := cipher.DoFinal(LInput);
+
+  { *
+    // Multi Pass
+    System.SetLength(EncryptionResult,
+    cipher.GetOutputSize(System.Length(LInput)));
+
+    len1 := cipher.ProcessBytes(LInput, 0, System.Length(LInput),
+    EncryptionResult, 0);
+
+    len1 := len1 + cipher.DoFinal(EncryptionResult, len1);
+    * }
+
+  if not withpadding then
+  begin
+    if (not TArrayUtils.AreEqual(LOutput, EncryptionResult)) then
+    begin
+      Fail(Format('Encryption Failed - Expected %s but got %s',
+        [THex.Encode(LOutput), THex.Encode(EncryptionResult)]));
+    end;
+  end;
+
+  cipher.Init(False, param);
+
+  // Decryption
+  // Single Pass
+  DecryptionResult := cipher.DoFinal(EncryptionResult);
+  { *
+    // Multi Pass
+    System.SetLength(DecryptionResult,
+    cipher.GetOutputSize(System.Length(EncryptionResult)));
+
+    len2 := cipher.ProcessBytes(EncryptionResult, 0,
+    System.Length(EncryptionResult), DecryptionResult, 0);
+
+    len2 := len2 + cipher.DoFinal(DecryptionResult, len2);
+
+    // remove padding important!!!
+    System.SetLength(DecryptionResult, len2);
+    * }
+
+  if (not TArrayUtils.AreEqual(LInput, DecryptionResult)) then
+  begin
+    Fail(Format('Decryption Failed - Expected %s but got %s',
+      [THex.Encode(LInput), THex.Encode(DecryptionResult)]));
+  end;
+end;
+
+procedure TTestSPECK.SetUp;
+begin
+  inherited;
+end;
+
+procedure TTestSPECK.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestSPECK.TestSPECK64_CBC_NOPADDING_WITH_IV;
+var
+  KeyParametersWithIV: IParametersWithIV;
+  keyBytes, IVBytes: TBytes;
+  cipher: IBufferedCipher;
+  input, output: string;
+  i: Int32;
+  engine: ISpeckEngine;
+  blockCipher: ICbcBlockCipher;
+begin
+
+  // // Set up
+  engine := TSpeck64Engine.Create();
+  blockCipher := TCbcBlockCipher.Create(engine); // CBC no padding
+  cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
+
+  for i := System.Low(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_CBC)
+    to System.High(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_CBC) do
+  begin
+    keyBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_CBC[i]);
+    IVBytes := THex.Decode(TSPECKTestVectors.FCryptoPPVectorIVs_SPECK64_CBC[i]);
+    input := TSPECKTestVectors.FCryptoPPVectorInputs_SPECK64_CBC[i];
+    output := TSPECKTestVectors.FCryptoPPVectorOutputs_SPECK64_CBC[i];
+
+    KeyParametersWithIV := TParametersWithIV.Create
+      (TKeyParameter.Create(keyBytes) as IKeyParameter, IVBytes);
+
+    doSPECKTest(cipher, KeyParametersWithIV as ICipherParameters,
+      input, output);
+  end;
+
+end;
+
+procedure TTestSPECK.TestSPECK128_CBC_NOPADDING_WITH_IV;
+var
+  KeyParametersWithIV: IParametersWithIV;
+  keyBytes, IVBytes: TBytes;
+  cipher: IBufferedCipher;
+  input, output: string;
+  i: Int32;
+  engine: ISpeckEngine;
+  blockCipher: ICbcBlockCipher;
+begin
+
+  // // Set up
+  engine := TSpeck128Engine.Create();
+  blockCipher := TCbcBlockCipher.Create(engine); // CBC no padding
+  cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
+
+  for i := System.Low(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_CBC)
+    to System.High(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_CBC) do
+  begin
+    keyBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_CBC[i]);
+    IVBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorIVs_SPECK128_CBC[i]);
+    input := TSPECKTestVectors.FCryptoPPVectorInputs_SPECK128_CBC[i];
+    output := TSPECKTestVectors.FCryptoPPVectorOutputs_SPECK128_CBC[i];
+
+    KeyParametersWithIV := TParametersWithIV.Create
+      (TKeyParameter.Create(keyBytes) as IKeyParameter, IVBytes);
+
+    doSPECKTest(cipher, KeyParametersWithIV as ICipherParameters,
+      input, output);
+  end;
+
+end;
+
+procedure TTestSPECK.TestSPECK64_CTR_NOPADDING_WITH_IV;
+var
+  KeyParametersWithIV: IParametersWithIV;
+  keyBytes, IVBytes: TBytes;
+  cipher: IBufferedCipher;
+  input, output: string;
+  i: Int32;
+  engine: ISpeckEngine;
+  blockCipher: ISicBlockCipher;
+begin
+
+  // // Set up
+  engine := TSpeck64Engine.Create();
+  blockCipher := TSicBlockCipher.Create(engine); // CTR no padding
+  cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
+
+  for i := System.Low(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_CTR)
+    to System.High(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_CTR) do
+  begin
+    keyBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_CTR[i]);
+    IVBytes := THex.Decode(TSPECKTestVectors.FCryptoPPVectorIVs_SPECK64_CTR[i]);
+    input := TSPECKTestVectors.FCryptoPPVectorInputs_SPECK64_CTR[i];
+    output := TSPECKTestVectors.FCryptoPPVectorOutputs_SPECK64_CTR[i];
+
+    KeyParametersWithIV := TParametersWithIV.Create
+      (TKeyParameter.Create(keyBytes) as IKeyParameter, IVBytes);
+
+    doSPECKTest(cipher, KeyParametersWithIV as ICipherParameters,
+      input, output);
+  end;
+
+end;
+
+procedure TTestSPECK.TestSPECK128_CTR_NOPADDING_WITH_IV;
+var
+  KeyParametersWithIV: IParametersWithIV;
+  keyBytes, IVBytes: TBytes;
+  cipher: IBufferedCipher;
+  input, output: string;
+  i: Int32;
+  engine: ISpeckEngine;
+  blockCipher: ISicBlockCipher;
+begin
+
+  // // Set up
+  engine := TSpeck128Engine.Create();
+  blockCipher := TSicBlockCipher.Create(engine); // CTR no padding
+  cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
+
+  for i := System.Low(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_CTR)
+    to System.High(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_CTR) do
+  begin
+    keyBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_CTR[i]);
+    IVBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorIVs_SPECK128_CTR[i]);
+    input := TSPECKTestVectors.FCryptoPPVectorInputs_SPECK128_CTR[i];
+    output := TSPECKTestVectors.FCryptoPPVectorOutputs_SPECK128_CTR[i];
+
+    KeyParametersWithIV := TParametersWithIV.Create
+      (TKeyParameter.Create(keyBytes) as IKeyParameter, IVBytes);
+
+    doSPECKTest(cipher, KeyParametersWithIV as ICipherParameters,
+      input, output);
+  end;
+
+end;
+
+procedure TTestSPECK.TestSPECK64_ECB_NOPADDING_NO_IV;
+var
+  keyParameter: IKeyParameter;
+  keyBytes: TBytes;
+  cipher: IBufferedCipher;
+  input, output: string;
+  i: Int32;
+  engine: ISpeckEngine;
+  blockCipher: IBlockCipher;
+begin
+
+  // // Set up
+  engine := TSpeck64Engine.Create();
+  blockCipher := engine as IBlockCipher; // ECB no padding
+  cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
+
+  for i := System.Low(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_ECB)
+    to System.High(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_ECB) do
+  begin
+    keyBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorKeys_SPECK64_ECB[i]);
+    input := TSPECKTestVectors.FCryptoPPVectorInputs_SPECK64_ECB[i];
+    output := TSPECKTestVectors.FCryptoPPVectorOutputs_SPECK64_ECB[i];
+
+    keyParameter := TKeyParameter.Create(keyBytes);
+
+    doSPECKTest(cipher, keyParameter as ICipherParameters, input, output);
+  end;
+
+end;
+
+procedure TTestSPECK.TestSPECK128_ECB_NOPADDING_NO_IV;
+var
+  keyParameter: IKeyParameter;
+  keyBytes: TBytes;
+  cipher: IBufferedCipher;
+  input, output: string;
+  i: Int32;
+  engine: ISpeckEngine;
+  blockCipher: IBlockCipher;
+begin
+
+  // // Set up
+  engine := TSpeck128Engine.Create();
+  blockCipher := engine as IBlockCipher; // ECB no padding
+  cipher := TBufferedBlockCipher.Create(blockCipher) as IBufferedBlockCipher;
+
+  for i := System.Low(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_ECB)
+    to System.High(TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_ECB) do
+  begin
+    keyBytes := THex.Decode
+      (TSPECKTestVectors.FCryptoPPVectorKeys_SPECK128_ECB[i]);
+    input := TSPECKTestVectors.FCryptoPPVectorInputs_SPECK128_ECB[i];
+    output := TSPECKTestVectors.FCryptoPPVectorOutputs_SPECK128_ECB[i];
+
+    keyParameter := TKeyParameter.Create(keyBytes);
+
+    doSPECKTest(cipher, keyParameter as ICipherParameters, input, output);
+  end;
+
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestSPECK);
+{$ELSE}
+  RegisterTest(TTestSPECK.Suite);
+{$ENDIF FPC}
+
+end.

+ 252 - 0
CryptoLib.Tests/src/Crypto/SpeckTestVectors.pas

@@ -0,0 +1,252 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit SpeckTestVectors;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  ClpCryptoLibTypes;
+
+type
+  /// <summary>
+  /// Speck tester
+  /// </summary>
+  /// <remarks>
+  /// test vectors were gotten from <see href="https://eprint.iacr.org/2013/404.pdf" />
+  /// , <br /><see href="https://nsacyber.github.io/simon-speck/implementations/ImplementationGuide1.1.pdf" />
+  /// and
+  /// https://github.com/weidai11/cryptopp/blob/master/TestVectors/speck.txt <br />
+  /// (do note that the tests vector in the first link are given in big
+  /// endian order) <br />and were swapped to little endian here
+  /// </remarks>
+  TSpeckTestVectors = class sealed(TObject)
+
+  public
+    class var
+
+      FSpeck32BlockCipherVectorKeys, FSpeck32BlockCipherVectorInputs,
+      FSpeck32BlockCipherVectorOutputs,
+
+      FSpeck48BlockCipherVectorKeys, FSpeck48BlockCipherVectorInputs,
+      FSpeck48BlockCipherVectorOutputs,
+
+      FSpeck64BlockCipherVectorKeys, FSpeck64BlockCipherVectorInputs,
+      FSpeck64BlockCipherVectorOutputs,
+
+      FSpeck96BlockCipherVectorKeys, FSpeck96BlockCipherVectorInputs,
+      FSpeck96BlockCipherVectorOutputs,
+
+      FSpeck128BlockCipherVectorKeys, FSpeck128BlockCipherVectorInputs,
+      FSpeck128BlockCipherVectorOutputs,
+
+      FCryptoPPVectorKeys_SPECK64_ECB, FCryptoPPVectorInputs_SPECK64_ECB,
+      FCryptoPPVectorOutputs_SPECK64_ECB,
+
+      FCryptoPPVectorKeys_SPECK128_ECB, FCryptoPPVectorInputs_SPECK128_ECB,
+      FCryptoPPVectorOutputs_SPECK128_ECB,
+
+      FCryptoPPVectorKeys_SPECK64_CBC, FCryptoPPVectorIVs_SPECK64_CBC,
+      FCryptoPPVectorInputs_SPECK64_CBC, FCryptoPPVectorOutputs_SPECK64_CBC,
+
+      FCryptoPPVectorKeys_SPECK128_CBC, FCryptoPPVectorIVs_SPECK128_CBC,
+      FCryptoPPVectorInputs_SPECK128_CBC, FCryptoPPVectorOutputs_SPECK128_CBC,
+
+      FCryptoPPVectorKeys_SPECK64_CTR, FCryptoPPVectorIVs_SPECK64_CTR,
+      FCryptoPPVectorInputs_SPECK64_CTR, FCryptoPPVectorOutputs_SPECK64_CTR,
+
+      FCryptoPPVectorKeys_SPECK128_CTR, FCryptoPPVectorIVs_SPECK128_CTR,
+      FCryptoPPVectorInputs_SPECK128_CTR, FCryptoPPVectorOutputs_SPECK128_CTR
+
+      : TCryptoLibStringArray;
+
+    class constructor SpeckTestVectors();
+
+  end;
+
+implementation
+
+{ TSpeckTestVectors }
+
+class constructor TSpeckTestVectors.SpeckTestVectors;
+begin
+
+  FSpeck32BlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('0001080910111819');
+
+  FSpeck32BlockCipherVectorInputs := TCryptoLibStringArray.Create('4C697465');
+
+  FSpeck32BlockCipherVectorOutputs := TCryptoLibStringArray.Create('F24268A8');
+
+  FSpeck48BlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('00010208090A101112', '00010208090A101112', '00010208090A10111218191A');
+
+  FSpeck48BlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('72616C6C7920', '72616C6C7920', '74686973206D');
+
+  FSpeck48BlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('DC5A38A549C0', 'DC5A38A549C0', '5D44B6105E73');
+
+  FSpeck64BlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('0001020308090A0B10111213', '0001020308090A0B1011121318191A1B');
+
+  FSpeck64BlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('65616E7320466174', '2D4375747465723B');
+
+  FSpeck64BlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('6C947541EC52799F', '8B024E4548A56F8C');
+
+  FSpeck96BlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('00010203040508090A0B0C0D', '00010203040508090A0B0C0D101112131415');
+
+  FSpeck96BlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('2075736167652C20686F7765', '7665722C20696E2074696D65');
+
+  FSpeck96BlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('AA798FDEBD627871AB094D9E', 'E62E2540E47A8A227210F32B');
+
+  FSpeck128BlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('000102030405060708090A0B0C0D0E0F',
+    '000102030405060708090A0B0C0D0E0F1011121314151617',
+    '000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F');
+
+  FSpeck128BlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('206D616465206974206571756976616C', '656E7420746F20436869656620486172',
+    '706F6F6E65722E20496E2074686F7365');
+
+  FSpeck128BlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('180D575CDFFE60786532787951985DA6', '86183CE05D18BCF9665513133ACFE41B',
+    '438F189C8DB4EE4E3EF5C00504010941');
+
+  // https://github.com/weidai11/cryptopp/blob/master/TestVectors/speck.txt
+
+  // ====================================================================================== //
+
+  FCryptoPPVectorKeys_SPECK64_ECB := TCryptoLibStringArray.Create
+    ('F64F824BDA9DA2D0D446ABE3', '64B76FA61CE980AB2F71098D75D66E5F');
+  FCryptoPPVectorInputs_SPECK64_ECB := TCryptoLibStringArray.Create
+    ('48731C8BFE3260D4', '1589A8BBFF4C7A85');
+  FCryptoPPVectorOutputs_SPECK64_ECB := TCryptoLibStringArray.Create
+    ('55CABA8DE9F967C8', '2F1D122370946BDA');
+
+  // ====================================================================================== //
+
+  FCryptoPPVectorKeys_SPECK128_ECB := TCryptoLibStringArray.Create
+    ('75289E33D18BDFC9C689B29A43CBF3F2',
+    'C289F537364FF63CB37FD75FEFB7C64D9D0997CD230B0BA2',
+    '3FAD1C9A616C155D42A077C2458E6BBA12C340F1475EA1F1624F8636FFB14ECC');
+  FCryptoPPVectorInputs_SPECK128_ECB := TCryptoLibStringArray.Create
+    ('51C16CD9AFAB4F1D326658F89C06C940', '0FF691D4E981FEFFC226BB85C2793B45',
+    '83A3C8AC4655B7B09FD2E6372F67D80B');
+  FCryptoPPVectorOutputs_SPECK128_ECB := TCryptoLibStringArray.Create
+    ('C003C0497684789B3A6CCBE8E7F98D9E', 'A757BDA6BAFD5356AE0693B89E4124F9',
+    'C1666B5CEFC7A834AA8E17151325D89C');
+
+  // ====================================================================================== //
+
+  FCryptoPPVectorKeys_SPECK64_CBC := TCryptoLibStringArray.Create
+    ('87A6829C1FDAAB90AC8AFC52', 'CA4345F53BE6D8F371D91C334FC0838B');
+
+  FCryptoPPVectorIVs_SPECK64_CBC := TCryptoLibStringArray.Create
+    ('869AF558D633F02D', '51A3A8DE472EF740');
+
+  FCryptoPPVectorInputs_SPECK64_CBC := TCryptoLibStringArray.Create
+    ('2DE1856588CAC5A3225A1048A6C9C98E7B6E1E80DF1DD431AC075133555F1091B075AAE0D05C057249D0032D78DE2CD74F1BB05AE8C38347088C1207D3EF53890F35F0FA99BBDB10F17DB0F8E7AFD03E40DD31E2B4330CAFE1C329930096CEEA',
+    '8A46B92E16B50EA93080F6801A0F77D7B1C7A11E8F212D036EDC6AB5E30ADE3B6A980C36FD40A62EB868F42B8CFB5907EBDA51F1C9D394DB691A326FA0DB093B632FEE98C106207AEFC6E26DC14724AD7684E2D54F7C3417A1BF438224B23FF1');
+
+  FCryptoPPVectorOutputs_SPECK64_CBC := TCryptoLibStringArray.Create
+    ('570D66C5A24534BF916C25B7F1093A0555C54857A11FDBCE549E3CFA0E65307F46B3796025925E55DD53D4419E5651A6B4D615DCB34EF4AADF7CA9AE4B0B266BCB2DBB78F933028E655F9F00820A8B32C27CB7481C071C012B54DCFB1FBFDB62',
+    'F2475EFA5C2F3BB9D4D16DFF5E3A3D16679C265660F6ABD2C4FC73B84806127ADDFAACC45E968770C747E2D6D66CF1AA37C96637DED14E439DA5F99778F4BA226592DFEDFE7EAB84D9B3665F71A6F9CC6E3AD6C8CCA1DB91D0F4F8BC572ED873');
+
+  // ====================================================================================== //
+
+  FCryptoPPVectorKeys_SPECK128_CBC := TCryptoLibStringArray.Create
+    ('84B6C2745A7515168E794BC312949733',
+    '52EB87E80BC7BE50A0F2C823BFC1D1478540010A1E61BA1E',
+    '4FFE6ED614F3662199AB5B77C01FFEFFF6F2A2928486F2CBD0AA0555E28837E9');
+
+  FCryptoPPVectorIVs_SPECK128_CBC := TCryptoLibStringArray.Create
+    ('89B996EC3A2030EEAB18E777A4A826F4', '817111309CF0E5FDD3D29A87F24A3D42',
+    '2A6421928921E1A364798D330D22E4C3');
+
+  FCryptoPPVectorInputs_SPECK128_CBC := TCryptoLibStringArray.Create
+    ('E99CEF37FA72BB342275090D36460E599982535234C52780FA11AE65F36208B82D9C439183DBF93CB1EC5E7'
+    + 'B14EA3707C6C5A4C12F9942C43C24D0FE1BB17BC473137E3E55B7687113A71DDFF47623B29B5431656976E8BE845FA2676F4B5073D980BE0BC45216299B8D8A2026E21B6C4737F3601196307D82F986D0D44808951172A160B4EE2D'
+    + 'CA04C4EAE7D5BB53BA0929C990AA706495BDEF15DD989C1460CB821FEDB14EFBEB6CEF223B4BA00F6FCB775B79EBD4F2FCDC570057045B9956',
+    'B3DACAA4EE7C1AE96BF563F9EEAE8C32A47A2CC10F9D1F06CFDC1BC5AC57BF425F4D2816A4517035DBEB9A43E6EE7BBF592B861BB04077AD784B19'
+    + '049B6E25D8E85182053B0C89695B3F49CA874CA37F263E004862FFC178B82E7844B13AE98E3E7E4DE517BF00F89316C54CECA154A9A618C4CECA7D0F5423A459335B6758AE2D0134526791EEC3A1730B055C3D6A8A96422A37'
+    + 'DF32F910365B319FED76591EA32865920A4357BFF6B3DED6DEB9A453F8A4FFE66AE621159F40DE5170F94EAC',
+    '05DE17F97F9DC2DF3BA5858D161B21255C539BC715A55D8CD09BAE727920CB5744CDA1B7C962B13B4263F0D67B65ACFA84D6CBEB95B187032F5887D4DB0A'
+    + '509E14FF4373546BE2B4071B78387EB6922591E2F276E8FABE4E3BCC444D036EC400C9980F45D09F79D5DA9FF01A9B1950874013BC855BAB6F922030DA96FB4822A3887401C50DCB6AA56B44C06CD43EBA843ED339B'
+    + '91991E791B956752EF773D5B359E988C7CA4AF92DAA14E046DFB3DE5220EC3884C786B8443574211A4970FA78');
+  FCryptoPPVectorOutputs_SPECK128_CBC := TCryptoLibStringArray.Create
+    ('88E166E1D46064E47187F9854A19570223E96BE0EE13D890E0209B66F0E45808F9B60513D90EAC2F0C1BF8A'
+    + '55EF2B637B72597D9B9B3107FD42FD86AC9EE58D983C334F938FDC7E50DE292AC030FF3C68B6C5F5DA298DAB7438F322B8E4F003CE5310BC88074E98D9C38045D40C956909F766774CE00C30BBE2D7DDDDC94C96D9FA252EB5EB514'
+    + 'D066D8DB995526F402389057C2310F64B26BF936C902D7B4F4E4E9D9DFB4294DFFB81BC3A524EFD7A80317E8F812E940137172F6DA27B4C01D',
+    '73024FB7D9931CFC64738C1B46417089226FA3E1ACAC0FBDE253B8C46673AB61142C76CC8F965762113384C462793FC01F7B8FE04EB42D9276E25F7C'
+    + 'CB4DEAED845CCA1F14EE034628E917EC7B95D658E00B1DED8F2E0D44BEBEF62B5BBAD9E3872BB5600842991918F6DC8D8E2D96CEA85743270BC7DF4A0363E65959794910A3EB9689A8DF'
+    + '5AB314A26B31B60AA63EFD57AD5FFBBAA793996B71841F468F99B485CB0CEEE6D10130BEB091A4D55206577A354768E5B8A044C6BE7C992EB0EF',
+    '21BA4DF8F5BC068B530800358033A3B976098B304E8CCAA264F9BB3FB5E0BDB5C888E6BB9AC6508B8F56798DBACDCBFE963AB5172E4A4FC2FD160CFD378A597E6F1E8FE0'
+    + 'DCEA6BA0B06142BA49FFDCF05F1E9D02D06E71B1FAD3E8A6E8B14C65AD24973B5739D076EBAD7E4ED9ECF9E360CA32E41066A5E669DF888F49803F55FD7097'
+    + 'ED4D182552F71720E77A416046A81C71A53E3F6DD8FBEAB1D9F5F4146E4E2E4F0A344A740F8091135B1CF6C04B3B00B6E557F0F8078894483242DC165B');
+
+  // ====================================================================================== //
+
+  FCryptoPPVectorKeys_SPECK64_CTR := TCryptoLibStringArray.Create
+    ('C72CBD543750780FBCD5CB64', 'D0F15E55870DD39236C0251C438F57B4');
+  FCryptoPPVectorIVs_SPECK64_CTR := TCryptoLibStringArray.Create
+    ('E4FE17997B0F8028', '6942E2B8C46D5374');
+  FCryptoPPVectorInputs_SPECK64_CTR := TCryptoLibStringArray.Create
+    ('2F75D63915E9E524D98DF7F6F5B32FFBE4B7F911F3CEC758FF265FB1B202C78A7F5353E508F23D84D6FFF2CA54AC649BF583A4098876A52EF54341F581AF8C2C2E5AF8734B7535B854295C0BB3A20B7382650F6262D33DC40403B79482A71437',
+    'A71E62DCF454EEC5A1ED766C45B7B67AB82E5019AD8DB7F4AA0A53730AA301C11441908D4290643E71FF39E3666934A317912C68DF01E137E28A6047F7E12F5766D01E2016408AE554B63EA66DBF87AEBD1BCE95ADA845634E6D33D90E10E60E');
+  FCryptoPPVectorOutputs_SPECK64_CTR := TCryptoLibStringArray.Create
+    ('AB692394FB3A7B7D4A356673075C947E04EE4CA1DC025EAEF950FF24527DE9E72DC4B3BE5E0C82A7964A64AE9820451910F448026C43FA0886A095E2277D484E90CFB960AA43023C958863D8741333AB3CB25B2BC4778DCFEAFA89C9DC6285E6',
+    '309D96C038FD03AA85815D6EF445344037980EACD6B61BCDD7F74FF8207F0F0533AF40AB822F480DB08C9729CF59BF2D3EF4192EBA1087BCBC112B46EA4D512AF2FA8FFCE2824C316D401771A25BF98E842BDA8120039AE2049733B329A189DA');
+
+  // ====================================================================================== //
+
+  FCryptoPPVectorKeys_SPECK128_CTR := TCryptoLibStringArray.Create
+    ('B043F5B45E8256956AFC4E26B4861240',
+    '691EC1C805EFBD7A9D509F226D2331D20771EE79BDDFCAFC',
+    'EB78929D56C5D0F49F75C1C8694AFDA496F808E5524CC592FD980EEC363E5382');
+  FCryptoPPVectorIVs_SPECK128_CTR := TCryptoLibStringArray.Create
+    ('E0BEDD6ECE0D72FC19D59E7BF853AEEC', '348ECA9766C09F04826520DE47A212FA',
+    'AF322427139F48ECD9C779FB768B28C0');
+  FCryptoPPVectorInputs_SPECK128_CTR := TCryptoLibStringArray.Create
+    ('4CB83714C34CA56DE8FB06069F794A5189F468191552CF8F5C46A07960BAC354C2D73359B01BF1508213ABF986ACA73E413566129134A6DAAAF54A45F7CFFE63E476B6EF237FA1FB0878F30338A18D29B91E204F37FC504A'
+    + '4908103AE843CDB05FACE5CC5EBD85D603F187CC4245D18D78036B81F8980A86A333418D7F81C75214D30555368B5D11A56AE732B291003128181F8364EA2C3D1C333C7615EFF41078E9CC8C69BB87BCE5EB8630E9B2E261758DF6693730E3C5F5C8F4F9F992D886',
+    '8BF93C7DFA63CF6D78842FD7458A6CB17184F75ECBE1DC0BE9F32DAC0E8F28D5152FE7351A46A402AE019C38BA55B2EF6C00DEAF4BF721A8C6C15434E466CBAEFA643BCCFEB4F2FAA5CE9178DB83DDE37A2F388ED9FFFB91DF4E2F16D84D9B03A122ACD1745FF2E3568C4F535689FEB99A30985EAD5BEF39A0'
+    + '730B569326FB23435CCE3696A8CD42C6D8C57A04134ADE9A68D927A16890CBD245A2FDF4E194550692A75A196780140AEBA98E800BE9851EDE654D4AB8EE31FADB1815CB66BCA8',
+    '5DCC0F8301F377741D8517CD6DA27D1E8170109C361FC68D8E5022CE3DA1C8FBDD37F50A7DCB5BB1A059D7CF100A94EAB59ECE9260072B64B746FD9ED93F49F0C654CD5DFD321E4D8959CBD1095FE2B5D4ACC78474AC2232EC34ECA0737F8886E156866C279C679CBAF544E7F69E3E8C710DE732C1F8FEEDF20773C6A'
+    + '674D706BF7EF2B5AD9C3D7B00A734E0919F181B59FBC8CFCEA4BEE9525894814CE42122E3AD0F07C0AD56E899D780C5D1759312351057C15F550C965379BADFC728E8F3');
+  FCryptoPPVectorOutputs_SPECK128_CTR := TCryptoLibStringArray.Create
+    ('A17264CC79FB96348E22E42F8FA8DCB43E9415AEF3552A673D5BF27B81E810F15923578D0B5CA148B183FB51AEE2E23CE2CFE4820B91DF21A6C915B2268608A62960EE8802991546048BDB4C2B9461B55869335954EABBAF09F255FA'
+    + 'E862140E87AABBF497AE3578AD030FBC4CB87A5EE4DEEB114FA4DE64DA74CE1AEA41D9FC72962B26C1339E2593166E8D79E06EAE809A080D4197934298FBE3586A3235CA76A176E41DE1A0BEF47CD37F5DE36E79C78E20A2E6BD0DCFE27A5A71431A5983',
+    '8F1C06AD392094314A7C514FEE0BA31A4129325900789A5F0F5638F5114509F07C22C527B41831ECF67B25EDEB4A069481950B7BE611772129F7995011A1429CF26CB6E91E970D745958223DCB55D606A7D78C20F5866D532C7CE27A97D1DCBA43494948C969820117DA62B83F421270BC90997F0ABC27099AAA9610FF44C48'
+    + 'BD701EB20DEA3008164097783E6006010AE26486D46726E0507E4C8F3F9448EC29642AD71A05B60A1386E39B81E747B64C8B39F73E27208B1EA3BC075223804AA',
+    '46DDAF62B84BDB9B97E2C114417AA5BD126132D922FA7B2C8B25A0D3147C9C1B203F06C546A7DAE20E98BC95AC6CB124C0E7C51566B5D1061EE61E25405E51CD6EB848C673E21BC10F9B9DCC36DDC16281F1369D9DFAABDB43C50C7CE10BF9805596D8C3CA530810C1BE9EBDCC0950BDA5A0CEB196B8E81CD1678094'
+    + '81E61E46B7748C8B88D7169352C41761C0536286A61619BBB841E19EA7867DE51DAAD87080C317A4B269AE8D5BD6087E61BF9EE765DC69619E87FBC1AB1E26EA9CF9EA42');
+
+  // ====================================================================================== //
+
+end;
+
+end.

+ 1090 - 0
CryptoLib/src/Crypto/Engines/ClpSpeckEngine.pas

@@ -0,0 +1,1090 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpSpeckEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpCheck,
+  ClpISpeckEngine,
+  ClpIBlockCipher,
+  ClpICipherParameters,
+  ClpIKeyParameter,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SSpeckEngineNotInitialised = '%s Engine not Initialised';
+  SInputBuffertooShort = 'Input Buffer too Short';
+  SOutputBuffertooShort = 'Output Buffer too Short';
+  SInvalidArgumentEncountered = 'Invalid Argument Encountered.';
+  SInvalidParameterSpeckInit = 'Invalid Parameter Passed to Speck Init - "%s"';
+  SSpeck32InvalidKeySize =
+    'Speck32 requires a key of 64 bits but input was "%d" bits.';
+  SSpeck48InvalidKeySize =
+    'Speck48 requires a key of 72 or 96 bits but input was "%d" bits.';
+  SSpeck64InvalidKeySize =
+    'Speck64 requires a key of 96 or 128 bits but input was "%d" bits.';
+  SSpeck96InvalidKeySize =
+    'Speck96 requires a key of 96 or 144 bits but input was "%d" bits.';
+  SSpeck128InvalidKeySize =
+    'Speck128 requires a key of 128, 192 or 256 bits but input was "%d" bits.';
+
+type
+
+  /// <summary>
+  /// <para>
+  /// The Speck family of block ciphers, described in <i>The Simon and
+  /// Speck Families of Lightweight Block Ciphers</i> by <i>Ray Beaulieu,
+  /// Douglas Shors, Jason Smith, Stefan Treatman-Clark, Bryan Weeks,
+  /// Louis Wingers</i> All block size and key size variants are
+  /// supported, with the key size determined from the key during <see cref="ClpSpeckEngine|TSpeckEngine.Init(Boolean,ICipherParameters)" />
+  /// .
+  /// </para>
+  /// </summary>
+  TSpeckEngine = class abstract(TInterfacedObject, ISpeckEngine, IBlockCipher)
+
+  strict private
+  var
+
+    Finitialised, FforEncryption: Boolean;
+
+    function GetIsPartialBlockOkay: Boolean; virtual;
+
+    /// <summary>
+    /// Internal method to Initialise this cipher instance.
+    /// <code>true</code> for encryption, <code>false</code> for decryption.
+    /// the bytes of the key to use.
+    /// </summary>
+    procedure EngineInit(forEncryption: Boolean;
+      const keyBytes: TCryptoLibByteArray); virtual;
+
+  strict protected
+
+  var
+    FblockSize, FwordSize, FwordSizeBits, Falpha, Fbeta, FbaseRounds,
+      Frounds: Int32;
+
+    /// <summary>
+    /// Gets the algorithm name of this Speck engine.
+    /// </summary>
+    /// <value>
+    /// the name of the Speck variant, specified to the level of the block size (e.g.
+    /// <em>Speck96</em>).
+    /// </value>
+    function GetAlgorithmName: String; virtual;
+    function GetBlockSize(): Int32; virtual;
+
+    /// <summary>
+    /// Checks whether a key size provided to the <see cref="ClpSpeckEngine|TSpeckEngine.EngineInit(Boolean,TCryptoLibByteArray)" />
+    /// method is valid.
+    /// </summary>
+    procedure CheckKeySize(keySizeBytes: Int32); virtual; abstract;
+
+    /// <summary>
+    /// Sets a key for this cipher instance, calculating the key schedule.
+    /// </summary>
+    procedure SetKey(const keyBytes: TCryptoLibByteArray); virtual; abstract;
+
+    /// <summary>
+    /// Unpack a block of data into working state prior to an
+    /// encrypt/decrypt operation.
+    /// </summary>
+    /// <param name="bytes">
+    /// the input data.
+    /// </param>
+    /// <param name="off">
+    /// the offset to begin reading the input data at.
+    /// </param>
+    procedure UnPackBlock(const bytes: TCryptoLibByteArray; off: Int32);
+      virtual; abstract;
+
+    /// <summary>
+    /// Packs the 2 word working state following an encrypt/decrypt into a
+    /// byte sequence.
+    /// </summary>
+    /// <param name="bytes">
+    /// the output buffer.
+    /// </param>
+    /// <param name="off">
+    /// the offset to begin writing the output data at.
+    /// </param>
+    procedure PackBlock(const bytes: TCryptoLibByteArray; off: Int32);
+      virtual; abstract;
+
+    /// <summary>
+    /// Encrypts the plaintext words loaded with a previous call to <see cref="ClpSpeckEngine|TSpeckEngine.UnPackBlock(TCryptoLibByteArray,Int32)" />
+    /// leaving the resulting ciphertext words in the working state.
+    /// </summary>
+    procedure EncryptBlock(); virtual; abstract;
+
+    /// <summary>
+    /// Decrypts the ciphertext words loaded with a previous call to <see cref="ClpSpeckEngine|TSpeckEngine.UnPackBlock(TCryptoLibByteArray,Int32)" />
+    /// leaving the resulting ciphertext words in the working state.
+    /// </summary>
+
+    procedure DecryptBlock(); virtual; abstract;
+
+    /// <summary>
+    /// Constructs a Speck engine.
+    /// </summary>
+    /// <param name="wordSize">
+    /// the size of the word to use, in bytes.
+    /// </param>
+    /// <param name="baseRounds">
+    /// the base number of rounds (for a 2 word key variant) for the
+    /// specified word/block size.
+    /// </param>
+    /// <param name="alpha">
+    /// the alpha rotation constant to use.
+    /// </param>
+    /// <param name="beta">
+    /// the beta rotation constant to use.
+    /// </param>
+    constructor Create(wordSize, baseRounds, alpha, beta: Int32);
+
+    /// <summary>
+    /// initialise a Speck cipher.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// whether or not we are for encryption.
+    /// </param>
+    /// <param name="parameters">
+    /// the parameters required to set up the cipher.
+    /// </param>
+    /// <exception cref="EArgumentCryptoLibException">
+    /// if the parameters argument is inappropriate.
+    /// </exception>
+    procedure Init(forEncryption: Boolean;
+      const parameters: ICipherParameters); virtual;
+
+    function ProcessBlock(const input: TCryptoLibByteArray; inOff: Int32;
+      const output: TCryptoLibByteArray; outOff: Int32): Int32; virtual;
+
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+  end;
+
+type
+
+  /// <summary>
+  /// Base class of Speck variants that fit in 32 bit Pascal Integers:
+  /// Speck32, Speck48, Speck64.
+  /// Speck32 and Speck48 (16 and 24 bit word sizes) are implemented using masking.
+  /// </summary>
+  TSpeckUInt32Engine = class abstract(TSpeckEngine)
+
+  strict private
+  var
+
+    /// <summary>
+    /// The expanded key schedule for all <see cref="ClpSpeckEngine|TSpeckEngine.Frounds" />
+    /// </summary>
+    Fk: TCryptoLibUInt32Array;
+
+    /// <summary>
+    /// The 2 words of the working state;
+    /// </summary>
+    Fx, Fy: UInt32;
+
+    /// <summary>
+    /// Rotates a word left by the specified distance. <br />The rotation is
+    /// on the word size of the cipher instance, not on the full 32 bits of
+    /// the UInt32.
+    /// </summary>
+    /// <param name="i">
+    /// the word to rotate.
+    /// </param>
+    /// <param name="distance">
+    /// the distance in bits to rotate.
+    /// </param>
+    /// <returns>
+    /// the rotated word, which may have unmasked high (&gt; word size) bits.
+    /// </returns>
+    function Rotl(i: UInt32; distance: Int32): UInt32; inline;
+
+    /// <summary>
+    /// Rotates a word right by the specified distance. <br />The rotation is
+    /// on the word size of the cipher instance, not on the full 32 bits of
+    /// the UInt32.
+    /// </summary>
+    /// <param name="i">
+    /// the word to rotate.
+    /// </param>
+    /// <param name="distance">
+    /// the distance in bits to rotate.
+    /// </param>
+    /// <returns>
+    /// the rotated word, which may have unmasked high (&gt; word size) bits.
+    /// </returns>
+    function Rotr(i: UInt32; distance: Int32): UInt32; inline;
+
+    /// <summary>
+    /// Read <see cref="ClpSpeckEngine|TSpeckEngine.FwordSize" /> bytes from
+    /// the input data in <b>little-endian</b> order.
+    /// </summary>
+    /// <param name="bytes">
+    /// the data to read a word from.
+    /// </param>
+    /// <param name="off">
+    /// the offset to read the word from.
+    /// </param>
+    /// <returns>
+    /// the read word, with zeroes in any bits higher than the word size.
+    /// </returns>
+    function BytesToWord(const bytes: TCryptoLibByteArray; off: Int32)
+      : UInt32; inline;
+
+    /// <summary>
+    /// Writes <see cref="ClpSpeckEngine|TSpeckEngine.FwordSize" /> bytes
+    /// into a buffer in <b>little-endian</b> order.
+    /// </summary>
+    /// <param name="word">
+    /// the word to write.
+    /// </param>
+    /// <param name="bytes">
+    /// the buffer to write the word bytes to.
+    /// </param>
+    /// <param name="off">
+    /// the offset to write the data at.
+    /// </param>
+    procedure WordToBytes(word: UInt32; const bytes: TCryptoLibByteArray;
+      off: Int32); inline;
+
+  strict protected
+
+    /// <summary>
+    /// Masks all bits higher than the word size of this cipher in the
+    /// supplied value.
+    /// </summary>
+    /// <param name="val">
+    /// the value to mask.
+    /// </param>
+    /// <returns>
+    /// the masked value.
+    /// </returns>
+    function Mask(val: UInt32): UInt32; virtual; abstract;
+
+    procedure SetKey(const keyBytes: TCryptoLibByteArray); override;
+
+    procedure UnPackBlock(const bytes: TCryptoLibByteArray;
+      off: Int32); override;
+
+    procedure PackBlock(const bytes: TCryptoLibByteArray; off: Int32); override;
+
+    procedure EncryptBlock(); override;
+
+    procedure DecryptBlock(); override;
+
+    /// <summary>
+    /// Constructs a Speck cipher with &lt;= 32 bit word size, using the
+    /// standard 8,3 rotation constants.
+    /// </summary>
+    /// <param name="wordSize">
+    /// the word size in bytes.
+    /// </param>
+    /// <param name="baseRounds">
+    /// the base (for 2 word key) round count.
+    /// </param>
+    constructor Create(wordSize, baseRounds: Int32); overload;
+
+    /// <summary>
+    /// Constructs a Speck cipher with &lt;= 32 bit word size, using custom
+    /// rotation constants.
+    /// </summary>
+    /// <param name="wordSize">
+    /// the word size in bytes.
+    /// </param>
+    /// <param name="baseRounds">
+    /// the base (for 2 word key) round count.
+    /// </param>
+    /// <param name="alpha">
+    /// the <em>alpha</em> rotation constant.
+    /// </param>
+    /// <param name="beta">
+    /// the <em>beta</em> rotation constant.
+    /// </param>
+    constructor Create(wordSize, baseRounds, alpha, beta: Int32); overload;
+
+  end;
+
+type
+
+  /// <summary>
+  /// Base class of Speck variants that fit in 64 bit Pascal Integers:
+  /// Speck96, Speck128.
+  /// Speck96 (48 bit word size) is implemented using masking.
+  /// </summary>
+  TSpeckUInt64Engine = class abstract(TSpeckEngine)
+
+  strict private
+  var
+
+    /// <summary>
+    /// The expanded key schedule for all <see cref="ClpSpeckEngine|TSpeckEngine.Frounds" />
+    /// </summary>
+    Fk: TCryptoLibUInt64Array;
+
+    /// <summary>
+    /// The 2 words of the working state;
+    /// </summary>
+    Fx, Fy: UInt64;
+
+    /// <summary>
+    /// Rotates a word left by the specified distance. <br />The rotation is
+    /// on the word size of the cipher instance, not on the full 64 bits of
+    /// the UInt64.
+    /// </summary>
+    /// <param name="i">
+    /// the word to rotate.
+    /// </param>
+    /// <param name="distance">
+    /// the distance in bits to rotate.
+    /// </param>
+    /// <returns>
+    /// the rotated word, which may have unmasked high (&gt; word size) bits.
+    /// </returns>
+    function Rotl(i: UInt64; distance: Int32): UInt64; inline;
+
+    /// <summary>
+    /// Rotates a word right by the specified distance. <br />The rotation is
+    /// on the word size of the cipher instance, not on the full 64 bits of
+    /// the UInt64.
+    /// </summary>
+    /// <param name="i">
+    /// the word to rotate.
+    /// </param>
+    /// <param name="distance">
+    /// the distance in bits to rotate.
+    /// </param>
+    /// <returns>
+    /// the rotated word, which may have unmasked high (&gt; word size) bits.
+    /// </returns>
+    function Rotr(i: UInt64; distance: Int32): UInt64; inline;
+
+    /// <summary>
+    /// Read <see cref="ClpSpeckEngine|TSpeckEngine.FwordSize" /> bytes from
+    /// the input data in little-endian order.
+    /// </summary>
+    /// <param name="bytes">
+    /// the data to read a word from.
+    /// </param>
+    /// <param name="off">
+    /// the offset to read the word from.
+    /// </param>
+    /// <returns>
+    /// the read word, with zeroes in any bits higher than the word size.
+    /// </returns>
+    function BytesToWord(const bytes: TCryptoLibByteArray; off: Int32)
+      : UInt64; inline;
+
+    /// <summary>
+    /// Writes <see cref="ClpSpeckEngine|TSpeckEngine.FwordSize" /> bytes
+    /// into a buffer in little-endian order.
+    /// </summary>
+    /// <param name="word">
+    /// the word to write.
+    /// </param>
+    /// <param name="bytes">
+    /// the buffer to write the word bytes to.
+    /// </param>
+    /// <param name="off">
+    /// the offset to write the data at.
+    /// </param>
+    procedure WordToBytes(word: UInt64; const bytes: TCryptoLibByteArray;
+      off: Int32); inline;
+
+  strict protected
+
+    /// <summary>
+    /// Masks all bits higher than the word size of this cipher in the
+    /// supplied value.
+    /// </summary>
+    /// <param name="val">
+    /// the value to mask.
+    /// </param>
+    /// <returns>
+    /// the masked value.
+    /// </returns>
+    function Mask(val: UInt64): UInt64; virtual; abstract;
+
+    procedure SetKey(const keyBytes: TCryptoLibByteArray); override;
+
+    procedure UnPackBlock(const bytes: TCryptoLibByteArray;
+      off: Int32); override;
+
+    procedure PackBlock(const bytes: TCryptoLibByteArray; off: Int32); override;
+
+    procedure EncryptBlock(); override;
+
+    procedure DecryptBlock(); override;
+
+    /// <summary>
+    /// Constructs a Speck cipher with &lt;= 64 bit word size, using the
+    /// standard 8,3 rotation constants.
+    /// </summary>
+    /// <param name="wordSize">
+    /// the word size in bytes.
+    /// </param>
+    /// <param name="baseRounds">
+    /// the base (for 2 word key) round count.
+    /// </param>
+    constructor Create(wordSize, baseRounds: Int32); overload;
+
+    /// <summary>
+    /// Constructs a Speck cipher with &lt;= 64 bit word size, using custom
+    /// rotation constants.
+    /// </summary>
+    /// <param name="wordSize">
+    /// the word size in bytes.
+    /// </param>
+    /// <param name="baseRounds">
+    /// the base (for 2 word key) round count.
+    /// </param>
+    /// <param name="alpha">
+    /// the <em>alpha</em> rotation constant.
+    /// </param>
+    /// <param name="beta">
+    /// the <em>beta</em> rotation constant.
+    /// </param>
+    constructor Create(wordSize, baseRounds, alpha, beta: Int32); overload;
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck32: 2 byte words, 7/2 rotation constants.
+  /// <p>
+  /// 20 base rounds (hypothetical)
+  /// </p>
+  /// 64 bit key/22 rounds.
+  /// </summary>
+  TSpeck32Engine = class sealed(TSpeckUInt32Engine)
+
+  strict protected
+    function Mask(val: UInt32): UInt32; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck48: 3 byte words, 8/3 rotation constants.
+  /// <p>
+  /// 21 base rounds (hypothetical)
+  /// </p>
+  /// 72 bit key/22 rounds.
+  /// 96 bit key/23 rounds.
+  /// </summary>
+  TSpeck48Engine = class sealed(TSpeckUInt32Engine)
+
+  strict protected
+    function Mask(val: UInt32): UInt32; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck64: 4 byte words, 8/3 rotation constants.
+  /// <p>
+  /// 25 base rounds (hypothetical)
+  /// </p>
+  /// 96 bit key/26 rounds.
+  /// 128 bit key/27 rounds.
+  /// </summary>
+  TSpeck64Engine = class sealed(TSpeckUInt32Engine)
+
+  strict protected
+    function Mask(val: UInt32): UInt32; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck96: 6 byte words, 8/3 rotation constants.
+  /// <p>
+  /// 28 base rounds
+  /// </p>
+  /// 96 bit key/28 rounds.
+  /// 144 bit key/29 rounds.
+  /// </summary>
+  TSpeck96Engine = class sealed(TSpeckUInt64Engine)
+
+  strict protected
+    function Mask(val: UInt64): UInt64; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck128: 8 byte words, 8/3 rotation constants.
+  /// <p>
+  /// 32 base rounds
+  /// </p>
+  /// 128 bit key/32 rounds.
+  /// 192 bit key/33 rounds.
+  /// 256 bit key/34 rounds.
+  /// </summary>
+  TSpeck128Engine = class sealed(TSpeckUInt64Engine)
+
+  strict protected
+    function Mask(val: UInt64): UInt64; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TSpeckEngine }
+
+constructor TSpeckEngine.Create(wordSize, baseRounds, alpha, beta: Int32);
+begin
+  Inherited Create();
+  FwordSize := wordSize;
+  FbaseRounds := baseRounds;
+  Frounds := baseRounds;
+  FblockSize := wordSize * 2;
+  FwordSizeBits := wordSize * 8;
+  Falpha := alpha;
+  Fbeta := beta;
+end;
+
+function TSpeckEngine.GetBlockSize: Int32;
+begin
+  result := FblockSize;
+end;
+
+procedure TSpeckEngine.EngineInit(forEncryption: Boolean;
+  const keyBytes: TCryptoLibByteArray);
+begin
+  FforEncryption := forEncryption;
+  CheckKeySize(System.Length(keyBytes));
+  SetKey(keyBytes);
+  Finitialised := true;
+end;
+
+function TSpeckEngine.GetAlgorithmName: String;
+begin
+  result := Format('Speck%d', [FblockSize * 8]);
+end;
+
+function TSpeckEngine.GetIsPartialBlockOkay: Boolean;
+begin
+  result := false;
+end;
+
+procedure TSpeckEngine.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  keyParameter: IKeyParameter;
+  keyBytes: TCryptoLibByteArray;
+begin
+
+  if not Supports(parameters, IKeyParameter, keyParameter) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidParameterSpeckInit,
+      [(parameters as TObject).ToString]);
+  end;
+  keyBytes := keyParameter.GetKey;
+  EngineInit(forEncryption, keyBytes);
+end;
+
+function TSpeckEngine.ProcessBlock(const input: TCryptoLibByteArray;
+  inOff: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+  if (not Finitialised) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateResFmt
+      (@SSpeckEngineNotInitialised, [AlgorithmName]);
+  end;
+
+  TCheck.DataLength((inOff + FblockSize) > System.Length(input),
+    SInputBuffertooShort);
+  TCheck.DataLength((outOff + FblockSize) > System.Length(output),
+    SOutputBuffertooShort);
+
+  UnPackBlock(input, inOff);
+  if (FforEncryption) then
+  begin
+    EncryptBlock();
+  end
+  else
+  begin
+    DecryptBlock();
+  end;
+  PackBlock(output, outOff);
+
+  result := FblockSize;
+end;
+
+procedure TSpeckEngine.Reset;
+begin
+  // nothing to do.
+end;
+
+{ TSpeckUInt32Engine }
+
+function TSpeckUInt32Engine.Rotl(i: UInt32; distance: Int32): UInt32;
+begin
+  result := ((i shl distance) or (i shr (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt32Engine.Rotr(i: UInt32; distance: Int32): UInt32;
+begin
+  result := ((i shr distance) or (i shl (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt32Engine.BytesToWord(const bytes: TCryptoLibByteArray;
+  off: Int32): UInt32;
+var
+  index: Int32;
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  index := off + FwordSize - 1;
+  result := (bytes[index]);
+  System.Dec(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Dec(index);
+  if (FwordSize > 2) then
+  begin
+    result := (result shl 8) or (bytes[index]);
+    System.Dec(index);
+    if (FwordSize > 3) then
+    begin
+      result := (result shl 8) or (bytes[index]);
+    end;
+  end;
+
+end;
+
+procedure TSpeckUInt32Engine.WordToBytes(word: UInt32;
+  const bytes: TCryptoLibByteArray; off: Int32);
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  bytes[off] := Byte(word);
+  System.Inc(off);
+  bytes[off] := Byte(word shr 8);
+  System.Inc(off);
+  if (FwordSize > 2) then
+  begin
+    bytes[off] := Byte(word shr 16);
+    System.Inc(off);
+    if (FwordSize > 3) then
+    begin
+      bytes[off] := Byte(word shr 24);
+    end;
+  end;
+
+end;
+
+constructor TSpeckUInt32Engine.Create(wordSize, baseRounds: Int32);
+begin
+  Create(wordSize, baseRounds, 8, 3);
+end;
+
+constructor TSpeckUInt32Engine.Create(wordSize, baseRounds, alpha, beta: Int32);
+begin
+  Inherited Create(wordSize, baseRounds, alpha, beta);
+end;
+
+procedure TSpeckUInt32Engine.EncryptBlock;
+var
+  x, y: UInt32;
+  r: Int32;
+begin
+  x := Fx;
+  y := Fy;
+
+  for r := 0 to System.Pred(Frounds) do
+  begin
+    x := Mask((Rotr(x, Falpha) + y) xor Fk[r]);
+    y := Mask(Rotl(y, Fbeta) xor x);
+  end;
+
+  Fx := x;
+  Fy := y;
+end;
+
+procedure TSpeckUInt32Engine.DecryptBlock;
+var
+  x, y: UInt32;
+  r: Int32;
+begin
+  x := Fx;
+  y := Fy;
+
+  for r := System.Pred(Frounds) downto 0 do
+  begin
+    y := Mask(Rotr(x xor y, Fbeta));
+    x := Mask(Rotl(Mask((x xor Fk[r]) - y), Falpha));
+  end;
+
+  Fx := x;
+  Fy := y;
+
+end;
+
+procedure TSpeckUInt32Engine.PackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  WordToBytes(Fx, bytes, off + FwordSize);
+  WordToBytes(Fy, bytes, off);
+end;
+
+procedure TSpeckUInt32Engine.UnPackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Fx := BytesToWord(bytes, off + FwordSize);
+  Fy := BytesToWord(bytes, off);
+end;
+
+procedure TSpeckUInt32Engine.SetKey(const keyBytes: TCryptoLibByteArray);
+var
+  keyWords, i, lw: Int32;
+  L: TCryptoLibUInt32Array;
+begin
+  // Determine number of key words m
+  keyWords := System.Length(keyBytes) div FwordSize;
+
+  // Number of rounds is increased by 1 for each key word > 2
+  Frounds := FbaseRounds + (keyWords - 2);
+  System.SetLength(Fk, Frounds);
+
+  // Load k[0]
+  Fk[0] := BytesToWord(keyBytes, 0);
+
+  // Load l[m-2]...l[0], leave space for l[m-1] in key expansion
+  System.SetLength(L, keyWords);
+
+  for i := 0 to System.Pred(keyWords - 1) do
+  begin
+    L[(keyWords - 2) - i] := BytesToWord(keyBytes, ((keyWords - 1) - i) *
+      FwordSize);
+  end;
+  // Key expansion using round function over l[m-2]...l[0],k[0] with round number as key
+  for i := 0 to System.Pred(Frounds - 1) do
+  begin
+    lw := (i + keyWords - 1) mod keyWords;
+    L[lw] := Mask((Rotr(L[i mod keyWords], Falpha) + Fk[i]) xor UInt32(i));
+    Fk[i + 1] := Mask(Rotl(Fk[i], Fbeta) xor L[lw]);
+
+  end;
+
+end;
+
+{ TSpeckUInt64Engine }
+
+function TSpeckUInt64Engine.Rotl(i: UInt64; distance: Int32): UInt64;
+begin
+  result := ((i shl distance) or (i shr (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt64Engine.Rotr(i: UInt64; distance: Int32): UInt64;
+begin
+  result := ((i shr distance) or (i shl (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt64Engine.BytesToWord(const bytes: TCryptoLibByteArray;
+  off: Int32): UInt64;
+var
+  index: Int32;
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  index := off + FwordSize - 1;
+  result := (bytes[index]);
+  System.Dec(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Dec(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Dec(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Dec(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Dec(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Dec(index);
+  if (FwordSize = 8) then
+  begin
+    result := (result shl 8) or (bytes[index]);
+    System.Dec(index);
+    result := (result shl 8) or (bytes[index]);
+  end;
+end;
+
+procedure TSpeckUInt64Engine.WordToBytes(word: UInt64;
+  const bytes: TCryptoLibByteArray; off: Int32);
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  bytes[off] := Byte(word);
+  System.Inc(off);
+  bytes[off] := Byte(word shr 8);
+  System.Inc(off);
+  bytes[off] := Byte(word shr 16);
+  System.Inc(off);
+  bytes[off] := Byte(word shr 24);
+  System.Inc(off);
+  bytes[off] := Byte(word shr 32);
+  System.Inc(off);
+  bytes[off] := Byte(word shr 40);
+  System.Inc(off);
+  if (FwordSize = 8) then
+  begin
+    bytes[off] := Byte(word shr 48);
+    System.Inc(off);
+    bytes[off] := Byte(word shr 56);
+  end;
+
+end;
+
+constructor TSpeckUInt64Engine.Create(wordSize, baseRounds: Int32);
+begin
+  Create(wordSize, baseRounds, 8, 3);
+end;
+
+constructor TSpeckUInt64Engine.Create(wordSize, baseRounds, alpha, beta: Int32);
+begin
+  Inherited Create(wordSize, baseRounds, alpha, beta);
+end;
+
+procedure TSpeckUInt64Engine.EncryptBlock;
+var
+  x, y: UInt64;
+  r: Int32;
+begin
+  x := Fx;
+  y := Fy;
+
+  for r := 0 to System.Pred(Frounds) do
+  begin
+    x := Mask((Rotr(x, Falpha) + y) xor Fk[r]);
+    y := Mask(Rotl(y, Fbeta) xor x);
+  end;
+
+  Fx := x;
+  Fy := y;
+end;
+
+procedure TSpeckUInt64Engine.DecryptBlock;
+var
+  x, y: UInt64;
+  r: Int32;
+begin
+  x := Fx;
+  y := Fy;
+
+  for r := System.Pred(Frounds) downto 0 do
+  begin
+    y := Mask(Rotr(x xor y, Fbeta));
+    x := Mask(Rotl(Mask((x xor Fk[r]) - y), Falpha));
+  end;
+
+  Fx := x;
+  Fy := y;
+
+end;
+
+procedure TSpeckUInt64Engine.PackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  WordToBytes(Fx, bytes, off + FwordSize);
+  WordToBytes(Fy, bytes, off);
+end;
+
+procedure TSpeckUInt64Engine.UnPackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Fx := BytesToWord(bytes, off + FwordSize);
+  Fy := BytesToWord(bytes, off);
+end;
+
+procedure TSpeckUInt64Engine.SetKey(const keyBytes: TCryptoLibByteArray);
+var
+  keyWords, i, lw: Int32;
+  L: TCryptoLibUInt64Array;
+begin
+  // Determine number of key words m
+  keyWords := System.Length(keyBytes) div FwordSize;
+
+  // Number of rounds is increased by 1 for each key word > 2
+  Frounds := FbaseRounds + (keyWords - 2);
+  System.SetLength(Fk, Frounds);
+
+  // Load k[0]
+  Fk[0] := BytesToWord(keyBytes, 0);
+
+  // Load l[m-2]...l[0], leave space for l[m-1] in key expansion
+  System.SetLength(L, keyWords);
+
+  for i := 0 to System.Pred(keyWords - 1) do
+  begin
+    L[(keyWords - 2) - i] := BytesToWord(keyBytes, ((keyWords - 1) - i) *
+      FwordSize);
+  end;
+  // Key expansion using round function over l[m-2]...l[0],k[0] with round number as key
+  for i := 0 to System.Pred(Frounds - 1) do
+  begin
+    lw := (i + keyWords - 1) mod keyWords;
+    L[lw] := Mask((Rotr(L[i mod keyWords], Falpha) + Fk[i]) xor UInt64(i));
+    Fk[i + 1] := Mask(Rotl(Fk[i], Fbeta) xor L[lw]);
+
+  end;
+
+end;
+
+{ TSpeck32Engine }
+
+constructor TSpeck32Engine.Create;
+begin
+  Inherited Create(2, 20, 7, 2);
+end;
+
+function TSpeck32Engine.Mask(val: UInt32): UInt32;
+begin
+  result := (val and $FFFF);
+end;
+
+procedure TSpeck32Engine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if (keySizeBytes <> 8) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SSpeck32InvalidKeySize,
+      [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck48Engine }
+
+constructor TSpeck48Engine.Create;
+begin
+  Inherited Create(3, 21);
+end;
+
+function TSpeck48Engine.Mask(val: UInt32): UInt32;
+begin
+  result := (val and $FFFFFF);
+end;
+
+procedure TSpeck48Engine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [9, 12]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SSpeck48InvalidKeySize,
+      [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck64Engine }
+
+constructor TSpeck64Engine.Create;
+begin
+  Inherited Create(4, 25);
+end;
+
+function TSpeck64Engine.Mask(val: UInt32): UInt32;
+begin
+  result := val;
+end;
+
+procedure TSpeck64Engine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [12, 16]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SSpeck64InvalidKeySize,
+      [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck96Engine }
+
+constructor TSpeck96Engine.Create;
+begin
+  Inherited Create(6, 28);
+end;
+
+function TSpeck96Engine.Mask(val: UInt64): UInt64;
+begin
+  result := (val and $0000FFFFFFFFFFFF);
+end;
+
+procedure TSpeck96Engine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [12, 18]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SSpeck96InvalidKeySize,
+      [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck128Engine }
+
+constructor TSpeck128Engine.Create;
+begin
+  Inherited Create(8, 32);
+end;
+
+function TSpeck128Engine.Mask(val: UInt64): UInt64;
+begin
+  result := val;
+end;
+
+procedure TSpeck128Engine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [16, 24, 32]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SSpeck128InvalidKeySize,
+      [keySizeBytes * 8]);
+  end;
+end;
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpISpeckEngine.pas

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpISpeckEngine;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipher;
+
+type
+
+  ISpeckEngine = interface(IBlockCipher)
+    ['{60AEDFFF-5FAB-4018-90E7-ED9BD1B3D406}']
+
+  end;
+
+implementation
+
+end.

+ 11 - 3
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk

@@ -19,13 +19,13 @@
         </Optimizations>
       </CodeGeneration>
     </CompilerOptions>
-    <Description Value="CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying DSA, ECDSA, ECNR and ECSchnorr signatures using various curves and hashes, AES Encryption and Decryption (With various modes and paddings) and ECIES ."/>
+    <Description Value="CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying DSA, ECDSA, ECNR and ECSchnorr signatures using various curves and hashes, AES, Blowfish, Speck Encryption and Decryption (With various modes and paddings) and ECIES."/>
     <License Value="MIT License                          
 
  Acknowledgements: 
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
-    <Version Major="2" Minor="9"/>
-    <Files Count="269">
+    <Version Major="3"/>
+    <Files Count="271">
       <Item1>
         <Filename Value="..\..\Asn1\ClpOidTokenizer.pas"/>
         <UnitName Value="ClpOidTokenizer"/>
@@ -1104,6 +1104,14 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <Filename Value="..\..\Interfaces\ClpIECC.pas"/>
         <UnitName Value="ClpIECC"/>
       </Item269>
+      <Item270>
+        <Filename Value="..\..\Interfaces\ClpISpeckEngine.pas"/>
+        <UnitName Value="ClpISpeckEngine"/>
+      </Item270>
+      <Item271>
+        <Filename Value="..\..\Crypto\Engines\ClpSpeckEngine.pas"/>
+        <UnitName Value="ClpSpeckEngine"/>
+      </Item271>
     </Files>
     <RequiredPkgs Count="3">
       <Item1>

+ 1 - 1
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas

@@ -94,7 +94,7 @@ uses
   ClpIAsn1Objects, ClpBlockCipherModes, ClpECCurveConstants, 
   ClpIBlockCipherModes, ClpIPaddingModes, ClpISecP256K1Custom, 
   ClpISecP256R1Custom, ClpISecP384R1Custom, ClpISecP521R1Custom, 
-  ClpISecT283Custom, ClpPaddingModes, ClpIECC;
+  ClpISecT283Custom, ClpPaddingModes, ClpIECC, ClpISpeckEngine, ClpSpeckEngine;
 
 implementation