Browse Source

Merge branch 'master' into travis

Ugochukwu Mmaduekwe 6 years ago
parent
commit
eedda8696c
100 changed files with 12494 additions and 744 deletions
  1. 68 2
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  2. 9 9
      CryptoLib.Samples/src/UsageExamples.pas
  3. 413 0
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.TestInsight.dpr
  4. 127 50
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  5. 88 3
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
  6. 11 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
  7. 46 2
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi
  8. 11 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
  9. 19 20
      CryptoLib.Tests/src/Crypto/AESSICTests.pas
  10. 7 10
      CryptoLib.Tests/src/Crypto/AESTests.pas
  11. 24 0
      CryptoLib.Tests/src/Crypto/BlockCipherMonteCarloTests.pas
  12. 199 0
      CryptoLib.Tests/src/Crypto/BlockCipherVectorTests.pas
  13. 192 0
      CryptoLib.Tests/src/Crypto/CTSTests.pas
  14. 383 0
      CryptoLib.Tests/src/Crypto/ChaChaTests.pas
  15. 0 1
      CryptoLib.Tests/src/Crypto/HMacTests.pas
  16. 0 277
      CryptoLib.Tests/src/Crypto/IESCipherTests.pas
  17. 115 0
      CryptoLib.Tests/src/Crypto/RijndaelTestVectors.pas
  18. 368 0
      CryptoLib.Tests/src/Crypto/SPECKTests.pas
  19. 376 0
      CryptoLib.Tests/src/Crypto/Salsa20Tests.pas
  20. 323 0
      CryptoLib.Tests/src/Crypto/SpeckTestVectors.pas
  21. 243 0
      CryptoLib.Tests/src/Crypto/StreamCipherResetTests.pas
  22. 162 0
      CryptoLib.Tests/src/Crypto/XSalsa20Tests.pas
  23. 286 0
      CryptoLib.Tests/src/Math/EC/Rfc7748/X25519Tests.pas
  24. 546 0
      CryptoLib.Tests/src/Math/EC/Rfc8032/Ed25519Tests.pas
  25. 0 1
      CryptoLib.Tests/src/Math/ECNRTests.pas
  26. 12 12
      CryptoLib.Tests/src/Math/IESCipherTests.pas
  27. 412 0
      CryptoLib.Tests/src/Math/PascalCoinECIESTests.pas
  28. 45 4
      CryptoLib.Tests/src/Others/ECTests.pas
  29. 2 3
      CryptoLib.Tests/src/Utils/ClpFixedSecureRandom.pas
  30. 18 23
      CryptoLib/src/Asn1/ClpAsn1Objects.pas
  31. 112 0
      CryptoLib/src/Asn1/Edec/ClpEdECObjectIdentifiers.pas
  32. 1 1
      CryptoLib/src/Asn1/X9/ClpX9ECParametersHolder.pas
  33. 86 0
      CryptoLib/src/Crypto/Agreement/ClpX25519Agreement.pas
  34. 1 1
      CryptoLib/src/Crypto/ClpAsymmetricKeyParameter.pas
  35. 3 4
      CryptoLib/src/Crypto/ClpBufferedCipherBase.pas
  36. 195 0
      CryptoLib/src/Crypto/ClpBufferedStreamCipher.pas
  37. 22 28
      CryptoLib/src/Crypto/ClpIESCipher.pas
  38. 2 0
      CryptoLib/src/Crypto/ClpKeyGenerationParameters.pas
  39. 66 12
      CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas
  40. 2 1
      CryptoLib/src/Crypto/Engines/ClpAesEngine.pas
  41. 2 1
      CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas
  42. 2 1
      CryptoLib/src/Crypto/Engines/ClpBlowfishEngine.pas
  43. 264 0
      CryptoLib/src/Crypto/Engines/ClpChaChaEngine.pas
  44. 47 43
      CryptoLib/src/Crypto/Engines/ClpIESEngine.pas
  45. 6 25
      CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas
  46. 911 0
      CryptoLib/src/Crypto/Engines/ClpRijndaelEngine.pas
  47. 502 0
      CryptoLib/src/Crypto/Engines/ClpSalsa20Engine.pas
  48. 1091 0
      CryptoLib/src/Crypto/Engines/ClpSpeckEngine.pas
  49. 1093 0
      CryptoLib/src/Crypto/Engines/ClpSpeckLegacyEngine.pas
  50. 115 0
      CryptoLib/src/Crypto/Engines/ClpXSalsa20Engine.pas
  51. 71 0
      CryptoLib/src/Crypto/Generators/ClpEd25519Blake2BKeyPairGenerator.pas
  52. 70 0
      CryptoLib/src/Crypto/Generators/ClpEd25519KeyPairGenerator.pas
  53. 7 23
      CryptoLib/src/Crypto/Generators/ClpPascalCoinECIESKdfBytesGenerator.pas
  54. 70 0
      CryptoLib/src/Crypto/Generators/ClpX25519KeyPairGenerator.pas
  55. 354 39
      CryptoLib/src/Crypto/Modes/ClpBlockCipherModes.pas
  56. 3 4
      CryptoLib/src/Crypto/Parameters/ClpDsaKeyParameters.pas
  57. 1 1
      CryptoLib/src/Crypto/Parameters/ClpDsaPrivateKeyParameters.pas
  58. 1 1
      CryptoLib/src/Crypto/Parameters/ClpDsaPublicKeyParameters.pas
  59. 5 5
      CryptoLib/src/Crypto/Parameters/ClpECKeyParameters.pas
  60. 1 1
      CryptoLib/src/Crypto/Parameters/ClpECPrivateKeyParameters.pas
  61. 1 1
      CryptoLib/src/Crypto/Parameters/ClpECPublicKeyParameters.pas
  62. 48 0
      CryptoLib/src/Crypto/Parameters/ClpEd25519Blake2BKeyGenerationParameters.pas
  63. 212 0
      CryptoLib/src/Crypto/Parameters/ClpEd25519Blake2BPrivateKeyParameters.pas
  64. 119 0
      CryptoLib/src/Crypto/Parameters/ClpEd25519Blake2BPublicKeyParameters.pas
  65. 47 0
      CryptoLib/src/Crypto/Parameters/ClpEd25519KeyGenerationParameters.pas
  66. 210 0
      CryptoLib/src/Crypto/Parameters/ClpEd25519PrivateKeyParameters.pas
  67. 118 0
      CryptoLib/src/Crypto/Parameters/ClpEd25519PublicKeyParameters.pas
  68. 205 0
      CryptoLib/src/Crypto/Parameters/ClpIESParameterSpec.pas
  69. 1 0
      CryptoLib/src/Crypto/Parameters/ClpIESParameters.pas
  70. 1 94
      CryptoLib/src/Crypto/Parameters/ClpIESWithCipherParameters.pas
  71. 47 0
      CryptoLib/src/Crypto/Parameters/ClpX25519KeyGenerationParameters.pas
  72. 158 0
      CryptoLib/src/Crypto/Parameters/ClpX25519PrivateKeyParameters.pas
  73. 118 0
      CryptoLib/src/Crypto/Parameters/ClpX25519PublicKeyParameters.pas
  74. 182 0
      CryptoLib/src/Crypto/Signers/ClpEd25519Blake2BSigner.pas
  75. 185 0
      CryptoLib/src/Crypto/Signers/ClpEd25519CtxBlake2BSigner.pas
  76. 184 0
      CryptoLib/src/Crypto/Signers/ClpEd25519CtxSigner.pas
  77. 173 0
      CryptoLib/src/Crypto/Signers/ClpEd25519PhBlake2BSigner.pas
  78. 172 0
      CryptoLib/src/Crypto/Signers/ClpEd25519PhSigner.pas
  79. 181 0
      CryptoLib/src/Crypto/Signers/ClpEd25519Signer.pas
  80. 0 1
      CryptoLib/src/Crypto/Signers/ClpSchnorrDigestSigner.pas
  81. 6 32
      CryptoLib/src/Include/CryptoLib.inc
  82. 3 3
      CryptoLib/src/Include/CryptoLibHelper.inc
  83. 31 0
      CryptoLib/src/Interfaces/ClpIAlgorithmParameterSpec.pas
  84. 10 1
      CryptoLib/src/Interfaces/ClpIBlockCipherModes.pas
  85. 36 0
      CryptoLib/src/Interfaces/ClpIBufferedStreamCipher.pas
  86. 36 0
      CryptoLib/src/Interfaces/ClpIChaChaEngine.pas
  87. 64 0
      CryptoLib/src/Interfaces/ClpICurve25519Custom.pas
  88. 1 1
      CryptoLib/src/Interfaces/ClpIDsaKeyParameters.pas
  89. 1 1
      CryptoLib/src/Interfaces/ClpIDsaPrivateKeyParameters.pas
  90. 1 1
      CryptoLib/src/Interfaces/ClpIDsaPublicKeyParameters.pas
  91. 2 0
      CryptoLib/src/Interfaces/ClpIECKeyParameters.pas
  92. 1 0
      CryptoLib/src/Interfaces/ClpIECPrivateKeyParameters.pas
  93. 1 1
      CryptoLib/src/Interfaces/ClpIECPublicKeyParameters.pas
  94. 97 0
      CryptoLib/src/Interfaces/ClpIEd25519.pas
  95. 35 0
      CryptoLib/src/Interfaces/ClpIEd25519Blake2B.pas
  96. 35 0
      CryptoLib/src/Interfaces/ClpIEd25519Blake2BKeyGenerationParameters.pas
  97. 35 0
      CryptoLib/src/Interfaces/ClpIEd25519Blake2BKeyPairGenerator.pas
  98. 49 0
      CryptoLib/src/Interfaces/ClpIEd25519Blake2BPrivateKeyParameters.pas
  99. 41 0
      CryptoLib/src/Interfaces/ClpIEd25519Blake2BPublicKeyParameters.pas
  100. 36 0
      CryptoLib/src/Interfaces/ClpIEd25519Blake2BSigner.pas

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

@@ -209,7 +209,7 @@ uses
   ClpDsaKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaKeyPairGenerator.pas',
   ClpDsaKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaKeyPairGenerator.pas',
   ClpIDsaKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaKeyPairGenerator.pas',
   ClpIDsaKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaKeyPairGenerator.pas',
   ClpDsaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpDsaSigner.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',
   ClpIDsaSigner in '..\..\CryptoLib\src\Interfaces\ClpIDsaSigner.pas',
   ClpDigest in '..\..\CryptoLib\src\Crypto\Digests\ClpDigest.pas',
   ClpDigest in '..\..\CryptoLib\src\Crypto\Digests\ClpDigest.pas',
   ClpECDHCBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHCBasicAgreement.pas',
   ClpECDHCBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHCBasicAgreement.pas',
@@ -240,7 +240,7 @@ uses
   ClpNat512 in '..\..\CryptoLib\src\Math\Raw\ClpNat512.pas',
   ClpNat512 in '..\..\CryptoLib\src\Math\Raw\ClpNat512.pas',
   ClpInterleave in '..\..\CryptoLib\src\Math\Raw\ClpInterleave.pas',
   ClpInterleave in '..\..\CryptoLib\src\Math\Raw\ClpInterleave.pas',
   ClpIDsaExt in '..\..\CryptoLib\src\Interfaces\ClpIDsaExt.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',
   ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
   ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
   ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
   ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
   ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
@@ -251,6 +251,8 @@ uses
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
   ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
   ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.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',
   ClpSecP256R1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Custom.pas',
   ClpISecP256R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Custom.pas',
   ClpISecP256R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Custom.pas',
   ClpSecP256K1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas',
   ClpSecP256K1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas',
@@ -271,6 +273,70 @@ uses
   ClpECCurveConstants in '..\..\CryptoLib\src\Math\EC\ClpECCurveConstants.pas',
   ClpECCurveConstants in '..\..\CryptoLib\src\Math\EC\ClpECCurveConstants.pas',
   ClpAsn1Objects in '..\..\CryptoLib\src\Asn1\ClpAsn1Objects.pas',
   ClpAsn1Objects in '..\..\CryptoLib\src\Asn1\ClpAsn1Objects.pas',
   ClpSignersEncodings in '..\..\CryptoLib\src\Crypto\Signers\SignersEncodings\ClpSignersEncodings.pas',
   ClpSignersEncodings in '..\..\CryptoLib\src\Crypto\Signers\SignersEncodings\ClpSignersEncodings.pas',
+  ClpIStreamCipher in '..\..\CryptoLib\src\Interfaces\ClpIStreamCipher.pas',
+  ClpBufferedStreamCipher in '..\..\CryptoLib\src\Crypto\ClpBufferedStreamCipher.pas',
+  ClpIBufferedStreamCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedStreamCipher.pas',
+  ClpSalsa20Engine in '..\..\CryptoLib\src\Crypto\Engines\ClpSalsa20Engine.pas',
+  ClpISalsa20Engine in '..\..\CryptoLib\src\Interfaces\ClpISalsa20Engine.pas',
+  ClpIXSalsa20Engine in '..\..\CryptoLib\src\Interfaces\ClpIXSalsa20Engine.pas',
+  ClpXSalsa20Engine in '..\..\CryptoLib\src\Crypto\Engines\ClpXSalsa20Engine.pas',
+  ClpIChaChaEngine in '..\..\CryptoLib\src\Interfaces\ClpIChaChaEngine.pas',
+  ClpChaChaEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpChaChaEngine.pas',
+  ClpRijndaelEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpRijndaelEngine.pas',
+  ClpIRijndaelEngine in '..\..\CryptoLib\src\Interfaces\ClpIRijndaelEngine.pas',
+  ClpIAlgorithmParameterSpec in '..\..\CryptoLib\src\Interfaces\ClpIAlgorithmParameterSpec.pas',
+  ClpIIESParameterSpec in '..\..\CryptoLib\src\Interfaces\ClpIIESParameterSpec.pas',
+  ClpIESParameterSpec in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESParameterSpec.pas',
+  ClpCurve25519Custom in '..\..\CryptoLib\src\Math\EC\Custom\Djb\ClpCurve25519Custom.pas',
+  ClpICurve25519Custom in '..\..\CryptoLib\src\Interfaces\ClpICurve25519Custom.pas',
+  ClpX25519Field in '..\..\CryptoLib\src\Math\EC\Rfc7748\ClpX25519Field.pas',
+  ClpEd25519 in '..\..\CryptoLib\src\Math\EC\Rfc8032\ClpEd25519.pas',
+  ClpIEd25519 in '..\..\CryptoLib\src\Interfaces\ClpIEd25519.pas',
+  ClpEd25519Blake2B in '..\..\CryptoLib\src\Math\EC\Rfc8032\ClpEd25519Blake2B.pas',
+  ClpIEd25519Blake2B in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2B.pas',
+  ClpSpeckLegacyEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpSpeckLegacyEngine.pas',
+  ClpISpeckLegacyEngine in '..\..\CryptoLib\src\Interfaces\ClpISpeckLegacyEngine.pas',
+  ClpX25519 in '..\..\CryptoLib\src\Math\EC\Rfc7748\ClpX25519.pas',
+  ClpEdECObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Edec\ClpEdECObjectIdentifiers.pas',
+  ClpIRawAgreement in '..\..\CryptoLib\src\Interfaces\ClpIRawAgreement.pas',
+  ClpX25519Agreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpX25519Agreement.pas',
+  ClpIX25519Agreement in '..\..\CryptoLib\src\Interfaces\ClpIX25519Agreement.pas',
+  ClpX25519PrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519PrivateKeyParameters.pas',
+  ClpIX25519PrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519PrivateKeyParameters.pas',
+  ClpIX25519PublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519PublicKeyParameters.pas',
+  ClpX25519PublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519PublicKeyParameters.pas',
+  ClpIEd25519PrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PrivateKeyParameters.pas',
+  ClpIEd25519PublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PublicKeyParameters.pas',
+  ClpIEd25519Blake2BPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BPublicKeyParameters.pas',
+  ClpIEd25519Blake2BPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BPrivateKeyParameters.pas',
+  ClpEd25519PrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519PrivateKeyParameters.pas',
+  ClpEd25519Blake2BPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BPrivateKeyParameters.pas',
+  ClpEd25519PublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519PublicKeyParameters.pas',
+  ClpEd25519Blake2BPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BPublicKeyParameters.pas',
+  ClpX25519KeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpX25519KeyPairGenerator.pas',
+  ClpIX25519KeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIX25519KeyPairGenerator.pas',
+  ClpIEd25519KeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEd25519KeyPairGenerator.pas',
+  ClpIEd25519Blake2BKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BKeyPairGenerator.pas',
+  ClpEd25519KeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEd25519KeyPairGenerator.pas',
+  ClpEd25519Blake2BKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEd25519Blake2BKeyPairGenerator.pas',
+  ClpX25519KeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519KeyGenerationParameters.pas',
+  ClpIX25519KeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519KeyGenerationParameters.pas',
+  ClpIEd25519KeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519KeyGenerationParameters.pas',
+  ClpIEd25519Blake2BKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BKeyGenerationParameters.pas',
+  ClpEd25519KeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519KeyGenerationParameters.pas',
+  ClpEd25519Blake2BKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BKeyGenerationParameters.pas',
+  ClpIEd25519Signer in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Signer.pas',
+  ClpEd25519Signer in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519Signer.pas',
+  ClpIEd25519Blake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BSigner.pas',
+  ClpEd25519Blake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519Blake2BSigner.pas',
+  ClpIEd25519CtxBlake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519CtxBlake2BSigner.pas',
+  ClpEd25519CtxSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519CtxSigner.pas',
+  ClpIEd25519CtxSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519CtxSigner.pas',
+  ClpEd25519CtxBlake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519CtxBlake2BSigner.pas',
+  ClpIEd25519PhSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PhSigner.pas',
+  ClpIEd25519PhBlake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PhBlake2BSigner.pas',
+  ClpEd25519PhSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519PhSigner.pas',
+  ClpEd25519PhBlake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519PhBlake2BSigner.pas',
   UsageExamples in '..\src\UsageExamples.pas';
   UsageExamples in '..\src\UsageExamples.pas';
 
 
 begin
 begin

+ 9 - 9
CryptoLib.Samples/src/UsageExamples.pas

@@ -60,8 +60,8 @@ uses
   // ClpIESEngine,
   // ClpIESEngine,
   ClpPascalCoinIESEngine,
   ClpPascalCoinIESEngine,
   ClpIPascalCoinIESEngine,
   ClpIPascalCoinIESEngine,
-  ClpIIESWithCipherParameters,
-  ClpIESWithCipherParameters,
+  ClpIIESParameterSpec,
+  ClpIESParameterSpec,
   ClpIAesEngine,
   ClpIAesEngine,
   ClpAesEngine,
   ClpAesEngine,
   ClpIBlockCipherModes,
   ClpIBlockCipherModes,
@@ -138,7 +138,7 @@ type
     class function GetECIESPascalCoinCompatibilityEngine
     class function GetECIESPascalCoinCompatibilityEngine
       : IPascalCoinIESEngine; static;
       : IPascalCoinIESEngine; static;
     class function GetECKeyPair: IAsymmetricCipherKeyPair; static;
     class function GetECKeyPair: IAsymmetricCipherKeyPair; static;
-    class function GetIESCipherParameters: IIESWithCipherParameters; static;
+    class function GetIESParameterSpec: IIESParameterSpec; static;
 
 
     class function ECIESPascalCoinEncrypt(const PublicKey
     class function ECIESPascalCoinEncrypt(const PublicKey
       : IAsymmetricKeyParameter; PlainText: TBytes): TBytes; static;
       : IAsymmetricKeyParameter; PlainText: TBytes): TBytes; static;
@@ -184,7 +184,7 @@ var
 begin
 begin
   // Decryption
   // Decryption
   CipherDecrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine);
   CipherDecrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine);
-  CipherDecrypt.Init(False, PrivateKey, GetIESCipherParameters, FRandom);
+  CipherDecrypt.Init(False, PrivateKey, GetIESParameterSpec, FRandom);
   PlainText := CipherDecrypt.DoFinal(CipherText);
   PlainText := CipherDecrypt.DoFinal(CipherText);
   result := True;
   result := True;
 end;
 end;
@@ -196,7 +196,7 @@ var
 begin
 begin
   // Encryption
   // Encryption
   CipherEncrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine);
   CipherEncrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine);
-  CipherEncrypt.Init(True, PublicKey, GetIESCipherParameters, FRandom);
+  CipherEncrypt.Init(True, PublicKey, GetIESParameterSpec, FRandom);
   result := CipherEncrypt.DoFinal(PlainText);
   result := CipherEncrypt.DoFinal(PlainText);
 end;
 end;
 
 
@@ -714,13 +714,13 @@ begin
 
 
 end;
 end;
 
 
-class function TUsageExamples.GetIESCipherParameters: IIESWithCipherParameters;
+class function TUsageExamples.GetIESParameterSpec: IIESParameterSpec;
 var
 var
   Derivation, Encoding, IVBytes: TBytes;
   Derivation, Encoding, IVBytes: TBytes;
   MacKeySizeInBits, CipherKeySizeInBits: Int32;
   MacKeySizeInBits, CipherKeySizeInBits: Int32;
   UsePointCompression: Boolean;
   UsePointCompression: Boolean;
 begin
 begin
-  // Set up  IES Cipher Parameters For Compatibility With PascalCoin Current Implementation
+  // Set up  IES Parameter Spec For Compatibility With PascalCoin Current Implementation
 
 
   // The derivation and encoding vectors are used when initialising the KDF and MAC.
   // The derivation and encoding vectors are used when initialising the KDF and MAC.
   // They're optional but if used then they need to be known by the other user so that
   // They're optional but if used then they need to be known by the other user so that
@@ -741,8 +741,8 @@ begin
   // from a point or not in the EphemeralKeyPairGenerator
   // from a point or not in the EphemeralKeyPairGenerator
   UsePointCompression := True; // for compatibility
   UsePointCompression := True; // for compatibility
 
 
-  result := TIESWithCipherParameters.Create(Derivation, Encoding,
-    MacKeySizeInBits, CipherKeySizeInBits, IVBytes, UsePointCompression);
+  result := TIESParameterSpec.Create(Derivation, Encoding, MacKeySizeInBits,
+    CipherKeySizeInBits, IVBytes, UsePointCompression);
 end;
 end;
 
 
 class procedure TUsageExamples.GetPublicKeyFromPrivateKey();
 class procedure TUsageExamples.GetPublicKeyFromPrivateKey();

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

@@ -0,0 +1,413 @@
+program CryptoLib.Tests.TestInsight;
+{
+
+  Delphi DUnit Test Project
+  -------------------------
+  This project contains the DUnit test framework and the GUI/Console test runners.
+  Add "CONSOLE_TESTRUNNER" to the conditional defines entry in the project options
+  to use the console test runner.  Otherwise the GUI test runner will be used by
+  default.
+
+}
+
+{$WARN DUPLICATE_CTOR_DTOR OFF}
+{$IFDEF CONSOLE_TESTRUNNER}
+{$APPTYPE CONSOLE}
+{$ENDIF}
+
+uses
+  TestInsight.DUnit,
+  ClpECGost3410NamedCurves in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpECGost3410NamedCurves.pas',
+  ClpCryptoProObjectIdentifiers in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpCryptoProObjectIdentifiers.pas',
+  ClpNistObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Nist\ClpNistObjectIdentifiers.pas',
+  ClpOiwObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Oiw\ClpOiwObjectIdentifiers.pas',
+  ClpPkcsObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Pkcs\ClpPkcsObjectIdentifiers.pas',
+  ClpRosstandartObjectIdentifiers in '..\..\CryptoLib\src\Asn1\RossStandart\ClpRosstandartObjectIdentifiers.pas',
+  ClpSecNamedCurves in '..\..\CryptoLib\src\Asn1\Sec\ClpSecNamedCurves.pas',
+  ClpSecObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Sec\ClpSecObjectIdentifiers.pas',
+  ClpTeleTrusTObjectIdentifiers in '..\..\CryptoLib\src\Asn1\TeleTrust\ClpTeleTrusTObjectIdentifiers.pas',
+  ClpECNamedCurveTable in '..\..\CryptoLib\src\Asn1\X9\ClpECNamedCurveTable.pas',
+  ClpX9ECParameters in '..\..\CryptoLib\src\Asn1\X9\ClpX9ECParameters.pas',
+  ClpX9ECParametersHolder in '..\..\CryptoLib\src\Asn1\X9\ClpX9ECParametersHolder.pas',
+  ClpX9ObjectIdentifiers in '..\..\CryptoLib\src\Asn1\X9\ClpX9ObjectIdentifiers.pas',
+  ClpOidTokenizer in '..\..\CryptoLib\src\Asn1\ClpOidTokenizer.pas',
+  ClpECKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpECKeyPairGenerator.pas',
+  ClpECDomainParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECDomainParameters.pas',
+  ClpECKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECKeyGenerationParameters.pas',
+  ClpECKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECKeyParameters.pas',
+  ClpECPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECPrivateKeyParameters.pas',
+  ClpECPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECPublicKeyParameters.pas',
+  ClpCryptoApiRandomGenerator in '..\..\CryptoLib\src\Crypto\Prng\ClpCryptoApiRandomGenerator.pas',
+  ClpDigestRandomGenerator in '..\..\CryptoLib\src\Crypto\Prng\ClpDigestRandomGenerator.pas',
+  ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
+  ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
+  ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
+  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
+  ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
+  ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
+  ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
+  ClpICipherParameters in '..\..\CryptoLib\src\Interfaces\ClpICipherParameters.pas',
+  ClpICryptoApiRandomGenerator in '..\..\CryptoLib\src\Interfaces\ClpICryptoApiRandomGenerator.pas',
+  ClpIDigestRandomGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDigestRandomGenerator.pas',
+  ClpIECDomainParameters in '..\..\CryptoLib\src\Interfaces\ClpIECDomainParameters.pas',
+  ClpIECC in '..\..\CryptoLib\src\Interfaces\ClpIECC.pas',
+  ClpIECKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIECKeyGenerationParameters.pas',
+  ClpIECKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIECKeyPairGenerator.pas',
+  ClpIECKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECKeyParameters.pas',
+  ClpIECPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPrivateKeyParameters.pas',
+  ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
+  ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
+  ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
+  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
+  ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
+  ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
+  ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
+  ClpIGlvTypeBParameters in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBParameters.pas',
+  ClpIKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIKeyGenerationParameters.pas',
+  ClpIOidTokenizer in '..\..\CryptoLib\src\Interfaces\ClpIOidTokenizer.pas',
+  ClpIPolynomial in '..\..\CryptoLib\src\Interfaces\ClpIPolynomial.pas',
+  ClpIPolynomialExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIPolynomialExtensionField.pas',
+  ClpIPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIPreCompInfo.pas',
+  ClpIAsn1Objects in '..\..\CryptoLib\src\Interfaces\ClpIAsn1Objects.pas',
+  ClpIRandom in '..\..\CryptoLib\src\Interfaces\ClpIRandom.pas',
+  ClpIRandomGenerator in '..\..\CryptoLib\src\Interfaces\ClpIRandomGenerator.pas',
+  ClpIRandomNumberGenerator in '..\..\CryptoLib\src\Interfaces\ClpIRandomNumberGenerator.pas',
+  ClpIScaleXPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleXPointMap.pas',
+  ClpISecureRandom in '..\..\CryptoLib\src\Interfaces\ClpISecureRandom.pas',
+  ClpIWNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWNafPreCompInfo.pas',
+  ClpIX9ECParameters in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParameters.pas',
+  ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
+  ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
+  ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.pas',
+  ClpAbstractECMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
+  ClpFixedPointCombMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
+  ClpFixedPointPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
+  ClpFixedPointUtilities in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
+  ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
+  ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
+  ClpLongArray in '..\..\CryptoLib\src\Math\EC\ClpLongArray.pas',
+  ClpScaleXPointMap in '..\..\CryptoLib\src\Math\EC\ClpScaleXPointMap.pas',
+  ClpBigInteger in '..\..\CryptoLib\src\Math\ClpBigInteger.pas',
+  ClpDigestUtilities in '..\..\CryptoLib\src\Security\ClpDigestUtilities.pas',
+  ClpRandom in '..\..\CryptoLib\src\Security\ClpRandom.pas',
+  ClpSecureRandom in '..\..\CryptoLib\src\Security\ClpSecureRandom.pas',
+  ClpPcgRandomMinimal in '..\..\CryptoLib\src\Utils\Randoms\ClpPcgRandomMinimal.pas',
+  ClpRandomNumberGenerator in '..\..\CryptoLib\src\Utils\Rng\ClpRandomNumberGenerator.pas',
+  ClpArrayUtils in '..\..\CryptoLib\src\Utils\ClpArrayUtils.pas',
+  ClpBitConverter in '..\..\CryptoLib\src\Utils\ClpBitConverter.pas',
+  ClpBits in '..\..\CryptoLib\src\Utils\ClpBits.pas',
+  ClpConverters in '..\..\CryptoLib\src\Utils\ClpConverters.pas',
+  ClpCryptoLibTypes in '..\..\CryptoLib\src\Utils\ClpCryptoLibTypes.pas',
+  ClpTimes in '..\..\CryptoLib\src\Utils\ClpTimes.pas',
+  ClpBigIntegers in '..\..\CryptoLib\src\Utils\ClpBigIntegers.pas',
+  ClpMod in '..\..\CryptoLib\src\Math\Raw\ClpMod.pas',
+  ClpNat in '..\..\CryptoLib\src\Math\Raw\ClpNat.pas',
+  ClpParametersWithRandom in '..\..\CryptoLib\src\Crypto\Parameters\ClpParametersWithRandom.pas',
+  ClpIParametersWithRandom in '..\..\CryptoLib\src\Interfaces\ClpIParametersWithRandom.pas',
+  ClpIDsa in '..\..\CryptoLib\src\Interfaces\ClpIDsa.pas',
+  ClpIDsaKCalculator in '..\..\CryptoLib\src\Interfaces\ClpIDsaKCalculator.pas',
+  ClpISigner in '..\..\CryptoLib\src\Interfaces\ClpISigner.pas',
+  ClpRandomDsaKCalculator in '..\..\CryptoLib\src\Crypto\Signers\ClpRandomDsaKCalculator.pas',
+  ClpIRandomDsaKCalculator in '..\..\CryptoLib\src\Interfaces\ClpIRandomDsaKCalculator.pas',
+  ClpECDsaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECDsaSigner.pas',
+  ClpIECDsaSigner in '..\..\CryptoLib\src\Interfaces\ClpIECDsaSigner.pas',
+  ClpDsaDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpDsaDigestSigner.pas',
+  ClpIDsaDigestSigner in '..\..\CryptoLib\src\Interfaces\ClpIDsaDigestSigner.pas',
+  ClpSignerUtilities in '..\..\CryptoLib\src\Security\ClpSignerUtilities.pas',
+  ClpZTauElement in '..\..\CryptoLib\src\Math\EC\Abc\ClpZTauElement.pas',
+  ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
+  ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
+  ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
+  ClpGlvMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpGlvMultiplier.pas',
+  ClpIGlvMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIGlvMultiplier.pas',
+  ClpWTauNafMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafMultiplier.pas',
+  ClpIWTauNafMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafMultiplier.pas',
+  ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
+  ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.pas',
+  ClpWNafL2RMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas',
+  ClpIWNafL2RMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWNafL2RMultiplier.pas',
+  ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
+  ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
+  ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
+  ClpIGenericPolynomialExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIGenericPolynomialExtensionField.pas',
+  ClpPrimeField in '..\..\CryptoLib\src\Math\Field\ClpPrimeField.pas',
+  ClpIPrimeField in '..\..\CryptoLib\src\Interfaces\ClpIPrimeField.pas',
+  ClpFiniteFields in '..\..\CryptoLib\src\Math\Field\ClpFiniteFields.pas',
+  ClpOSRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpOSRandom.pas',
+  ClpSetWeakRef in '..\..\CryptoLib\src\Utils\ClpSetWeakRef.pas',
+  ClpCipherUtilities in '..\..\CryptoLib\src\Security\ClpCipherUtilities.pas',
+  ClpIBufferedCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedCipher.pas',
+  ClpIBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIBlockCipher.pas',
+  ClpIBlockCipherPadding in '..\..\CryptoLib\src\Interfaces\ClpIBlockCipherPadding.pas',
+  ClpParametersWithIV in '..\..\CryptoLib\src\Crypto\Parameters\ClpParametersWithIV.pas',
+  ClpIParametersWithIV in '..\..\CryptoLib\src\Interfaces\ClpIParametersWithIV.pas',
+  ClpKeyParameter in '..\..\CryptoLib\src\Crypto\Parameters\ClpKeyParameter.pas',
+  ClpIKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIKeyParameter.pas',
+  ClpBufferedCipherBase in '..\..\CryptoLib\src\Crypto\ClpBufferedCipherBase.pas',
+  ClpIBufferedCipherBase in '..\..\CryptoLib\src\Interfaces\ClpIBufferedCipherBase.pas',
+  ClpBufferedBlockCipher in '..\..\CryptoLib\src\Crypto\ClpBufferedBlockCipher.pas',
+  ClpIBufferedBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedBlockCipher.pas',
+  ClpCheck in '..\..\CryptoLib\src\Utils\ClpCheck.pas',
+  ClpPaddedBufferedBlockCipher in '..\..\CryptoLib\src\Crypto\Paddings\ClpPaddedBufferedBlockCipher.pas',
+  ClpIPaddedBufferedBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIPaddedBufferedBlockCipher.pas',
+  ClpGeneratorUtilities in '..\..\CryptoLib\src\Security\ClpGeneratorUtilities.pas',
+  ClpParameterUtilities in '..\..\CryptoLib\src\Security\ClpParameterUtilities.pas',
+  ClpAesEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpAesEngine.pas',
+  ClpIAesEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesEngine.pas',
+  ClpECDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHBasicAgreement.pas',
+  ClpIBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIBasicAgreement.pas',
+  ClpIECDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIECDHBasicAgreement.pas',
+  ClpIESParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESParameters.pas',
+  ClpIIESParameters in '..\..\CryptoLib\src\Interfaces\ClpIIESParameters.pas',
+  ClpIESWithCipherParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESWithCipherParameters.pas',
+  ClpIIESWithCipherParameters in '..\..\CryptoLib\src\Interfaces\ClpIIESWithCipherParameters.pas',
+  ClpIDerivationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDerivationParameters.pas',
+  ClpIDerivationFunction in '..\..\CryptoLib\src\Interfaces\ClpIDerivationFunction.pas',
+  ClpKdfParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpKdfParameters.pas',
+  ClpIKdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIKdfParameters.pas',
+  ClpIso18033KdfParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIso18033KdfParameters.pas',
+  ClpIIso18033KdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIIso18033KdfParameters.pas',
+  ClpBaseKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpBaseKdfBytesGenerator.pas',
+  ClpIBaseKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIBaseKdfBytesGenerator.pas',
+  ClpKdf2BytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpKdf2BytesGenerator.pas',
+  ClpIKdf2BytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIKdf2BytesGenerator.pas',
+  ClpIKeyParser in '..\..\CryptoLib\src\Interfaces\ClpIKeyParser.pas',
+  ClpEphemeralKeyPair in '..\..\CryptoLib\src\Crypto\ClpEphemeralKeyPair.pas',
+  ClpIEphemeralKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIEphemeralKeyPair.pas',
+  ClpEphemeralKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas',
+  ClpIEphemeralKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEphemeralKeyPairGenerator.pas',
+  ClpKeyEncoder in '..\..\CryptoLib\src\Crypto\ClpKeyEncoder.pas',
+  ClpIKeyEncoder in '..\..\CryptoLib\src\Interfaces\ClpIKeyEncoder.pas',
+  ClpIESCipher in '..\..\CryptoLib\src\Crypto\ClpIESCipher.pas',
+  ClpIIESCipher in '..\..\CryptoLib\src\Interfaces\ClpIIESCipher.pas',
+  ClpECIESPublicKeyParser in '..\..\CryptoLib\src\Crypto\Parsers\ClpECIESPublicKeyParser.pas',
+  ClpIECIESPublicKeyParser in '..\..\CryptoLib\src\Interfaces\ClpIECIESPublicKeyParser.pas',
+  ClpIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpIESEngine.pas',
+  ClpIIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIIESEngine.pas',
+  ClpPascalCoinIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpPascalCoinIESEngine.pas',
+  ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
+  ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
+  ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas',
+  ClpIDigest in '..\..\CryptoLib\src\Interfaces\ClpIDigest.pas',
+  ClpIMac in '..\..\CryptoLib\src\Interfaces\ClpIMac.pas',
+  ClpStringUtils in '..\..\CryptoLib\src\Utils\ClpStringUtils.pas',
+  ClpCipherKeyGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpCipherKeyGenerator.pas',
+  ClpICipherKeyGenerator in '..\..\CryptoLib\src\Interfaces\ClpICipherKeyGenerator.pas',
+  ClpHMac in '..\..\CryptoLib\src\Crypto\Macs\ClpHMac.pas',
+  ClpIHMac in '..\..\CryptoLib\src\Interfaces\ClpIHMac.pas',
+  ClpMacUtilities in '..\..\CryptoLib\src\Security\ClpMacUtilities.pas',
+  ClpIanaObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Iana\ClpIanaObjectIdentifiers.pas',
+  ClpMiscObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Misc\ClpMiscObjectIdentifiers.pas',
+  ClpPbeParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPbeParametersGenerator.pas',
+  ClpIPbeParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPbeParametersGenerator.pas',
+  ClpPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPkcs5S2ParametersGenerator.pas',
+  ClpIPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPkcs5S2ParametersGenerator.pas',
+  ClpECNRSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECNRSigner.pas',
+  ClpIECNRSigner in '..\..\CryptoLib\src\Interfaces\ClpIECNRSigner.pas',
+  ClpDsaValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaValidationParameters.pas',
+  ClpIDsaValidationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaValidationParameters.pas',
+  ClpDsaParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameters.pas',
+  ClpIDsaParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameters.pas',
+  ClpDsaPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaPublicKeyParameters.pas',
+  ClpIDsaPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaPublicKeyParameters.pas',
+  ClpDsaKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaKeyParameters.pas',
+  ClpIDsaKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaKeyParameters.pas',
+  ClpDsaKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaKeyGenerationParameters.pas',
+  ClpIDsaKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaKeyGenerationParameters.pas',
+  ClpDsaPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaPrivateKeyParameters.pas',
+  ClpIDsaPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaPrivateKeyParameters.pas',
+  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',
+  ClpIDsaSigner in '..\..\CryptoLib\src\Interfaces\ClpIDsaSigner.pas',
+  ClpDigest in '..\..\CryptoLib\src\Crypto\Digests\ClpDigest.pas',
+  ClpECDHCBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHCBasicAgreement.pas',
+  ClpIECDHCBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIECDHCBasicAgreement.pas',
+  ClpHMacDsaKCalculator in '..\..\CryptoLib\src\Crypto\Signers\ClpHMacDsaKCalculator.pas',
+  ClpIHMacDsaKCalculator in '..\..\CryptoLib\src\Interfaces\ClpIHMacDsaKCalculator.pas',
+  ClpHkdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpHkdfBytesGenerator.pas',
+  ClpIHkdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIHkdfBytesGenerator.pas',
+  ClpHkdfParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpHkdfParameters.pas',
+  ClpIHkdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIHkdfParameters.pas',
+  ClpDsaParameterGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaParameterGenerationParameters.pas',
+  ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.pas',
+  ClpValidityPrecompInfo in '..\..\CryptoLib\src\Math\EC\ClpValidityPrecompInfo.pas',
+  ClpIValidityPrecompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPrecompInfo.pas',
+  ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
+  ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
+  ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
+  ClpIDsaParameter in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameter.pas',
+  ClpIPreCompCallBack in '..\..\CryptoLib\src\Interfaces\ClpIPreCompCallBack.pas',
+  ClpNistNamedCurves in '..\..\CryptoLib\src\Asn1\Nist\ClpNistNamedCurves.pas',
+  ClpNat320 in '..\..\CryptoLib\src\Math\Raw\ClpNat320.pas',
+  ClpNat256 in '..\..\CryptoLib\src\Math\Raw\ClpNat256.pas',
+  ClpAesLightEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpAesLightEngine.pas',
+  ClpIAesLightEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesLightEngine.pas',
+  ClpCustomNamedCurves in '..\..\CryptoLib\src\Crypto\EC\ClpCustomNamedCurves.pas',
+  ClpNat384 in '..\..\CryptoLib\src\Math\Raw\ClpNat384.pas',
+  ClpNat192 in '..\..\CryptoLib\src\Math\Raw\ClpNat192.pas',
+  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',
+  ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
+  ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
+  ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
+  ClpISchnorrDigestSigner in '..\..\CryptoLib\src\Interfaces\ClpISchnorrDigestSigner.pas',
+  ClpISchnorr in '..\..\CryptoLib\src\Interfaces\ClpISchnorr.pas',
+  ClpECSchnorrSipaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrSipaSigner.pas',
+  ClpIECSchnorrSipaSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrSipaSigner.pas',
+  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',
+  ClpISecP256K1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256K1Custom.pas',
+  ClpSecP384R1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP384R1Custom.pas',
+  ClpSecP521R1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP521R1Custom.pas',
+  ClpISecP521R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP521R1Custom.pas',
+  ClpSecT283Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecT283Custom.pas',
+  ClpISecT283Custom in '..\..\CryptoLib\src\Interfaces\ClpISecT283Custom.pas',
+  ClpISecP384R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP384R1Custom.pas',
+  ClpBlockCipherModes in '..\..\CryptoLib\src\Crypto\Modes\ClpBlockCipherModes.pas',
+  ClpIBlockCipherModes in '..\..\CryptoLib\src\Interfaces\ClpIBlockCipherModes.pas',
+  ClpPaddingModes in '..\..\CryptoLib\src\Crypto\Paddings\ClpPaddingModes.pas',
+  ClpIPaddingModes in '..\..\CryptoLib\src\Interfaces\ClpIPaddingModes.pas',
+  ClpECC in '..\..\CryptoLib\src\Math\EC\ClpECC.pas',
+  ClpX9ECC in '..\..\CryptoLib\src\Asn1\X9\ClpX9ECC.pas',
+  ClpIX9ECC in '..\..\CryptoLib\src\Interfaces\ClpIX9ECC.pas',
+  ClpECCurveConstants in '..\..\CryptoLib\src\Math\EC\ClpECCurveConstants.pas',
+  ClpAsn1Objects in '..\..\CryptoLib\src\Asn1\ClpAsn1Objects.pas',
+  ClpSignersEncodings in '..\..\CryptoLib\src\Crypto\Signers\SignersEncodings\ClpSignersEncodings.pas',
+  ClpIStreamCipher in '..\..\CryptoLib\src\Interfaces\ClpIStreamCipher.pas',
+  ClpBufferedStreamCipher in '..\..\CryptoLib\src\Crypto\ClpBufferedStreamCipher.pas',
+  ClpIBufferedStreamCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedStreamCipher.pas',
+  ClpSalsa20Engine in '..\..\CryptoLib\src\Crypto\Engines\ClpSalsa20Engine.pas',
+  ClpISalsa20Engine in '..\..\CryptoLib\src\Interfaces\ClpISalsa20Engine.pas',
+  ClpIXSalsa20Engine in '..\..\CryptoLib\src\Interfaces\ClpIXSalsa20Engine.pas',
+  ClpXSalsa20Engine in '..\..\CryptoLib\src\Crypto\Engines\ClpXSalsa20Engine.pas',
+  ClpIChaChaEngine in '..\..\CryptoLib\src\Interfaces\ClpIChaChaEngine.pas',
+  ClpChaChaEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpChaChaEngine.pas',
+  ClpRijndaelEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpRijndaelEngine.pas',
+  ClpIRijndaelEngine in '..\..\CryptoLib\src\Interfaces\ClpIRijndaelEngine.pas',
+  ClpIAlgorithmParameterSpec in '..\..\CryptoLib\src\Interfaces\ClpIAlgorithmParameterSpec.pas',
+  ClpIIESParameterSpec in '..\..\CryptoLib\src\Interfaces\ClpIIESParameterSpec.pas',
+  ClpIESParameterSpec in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESParameterSpec.pas',
+  ClpCurve25519Custom in '..\..\CryptoLib\src\Math\EC\Custom\Djb\ClpCurve25519Custom.pas',
+  ClpICurve25519Custom in '..\..\CryptoLib\src\Interfaces\ClpICurve25519Custom.pas',
+  ClpX25519Field in '..\..\CryptoLib\src\Math\EC\Rfc7748\ClpX25519Field.pas',
+  ClpEd25519 in '..\..\CryptoLib\src\Math\EC\Rfc8032\ClpEd25519.pas',
+  ClpIEd25519 in '..\..\CryptoLib\src\Interfaces\ClpIEd25519.pas',
+  ClpEd25519Blake2B in '..\..\CryptoLib\src\Math\EC\Rfc8032\ClpEd25519Blake2B.pas',
+  ClpIEd25519Blake2B in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2B.pas',
+  ClpSpeckLegacyEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpSpeckLegacyEngine.pas',
+  ClpISpeckLegacyEngine in '..\..\CryptoLib\src\Interfaces\ClpISpeckLegacyEngine.pas',
+  ClpX25519 in '..\..\CryptoLib\src\Math\EC\Rfc7748\ClpX25519.pas',
+  ClpEdECObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Edec\ClpEdECObjectIdentifiers.pas',
+  ClpIRawAgreement in '..\..\CryptoLib\src\Interfaces\ClpIRawAgreement.pas',
+  ClpX25519Agreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpX25519Agreement.pas',
+  ClpIX25519Agreement in '..\..\CryptoLib\src\Interfaces\ClpIX25519Agreement.pas',
+  ClpX25519PrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519PrivateKeyParameters.pas',
+  ClpIX25519PrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519PrivateKeyParameters.pas',
+  ClpIX25519PublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519PublicKeyParameters.pas',
+  ClpX25519PublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519PublicKeyParameters.pas',
+  ClpIEd25519PrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PrivateKeyParameters.pas',
+  ClpIEd25519PublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PublicKeyParameters.pas',
+  ClpIEd25519Blake2BPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BPublicKeyParameters.pas',
+  ClpIEd25519Blake2BPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BPrivateKeyParameters.pas',
+  ClpEd25519PrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519PrivateKeyParameters.pas',
+  ClpEd25519Blake2BPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BPrivateKeyParameters.pas',
+  ClpEd25519PublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519PublicKeyParameters.pas',
+  ClpEd25519Blake2BPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BPublicKeyParameters.pas',
+  ClpX25519KeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpX25519KeyPairGenerator.pas',
+  ClpIX25519KeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIX25519KeyPairGenerator.pas',
+  ClpIEd25519KeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEd25519KeyPairGenerator.pas',
+  ClpIEd25519Blake2BKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BKeyPairGenerator.pas',
+  ClpEd25519KeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEd25519KeyPairGenerator.pas',
+  ClpEd25519Blake2BKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEd25519Blake2BKeyPairGenerator.pas',
+  ClpX25519KeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519KeyGenerationParameters.pas',
+  ClpIX25519KeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519KeyGenerationParameters.pas',
+  ClpIEd25519KeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519KeyGenerationParameters.pas',
+  ClpIEd25519Blake2BKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BKeyGenerationParameters.pas',
+  ClpEd25519KeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519KeyGenerationParameters.pas',
+  ClpEd25519Blake2BKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BKeyGenerationParameters.pas',
+  ClpIEd25519Signer in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Signer.pas',
+  ClpEd25519Signer in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519Signer.pas',
+  ClpIEd25519Blake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BSigner.pas',
+  ClpEd25519Blake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519Blake2BSigner.pas',
+  ClpIEd25519CtxBlake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519CtxBlake2BSigner.pas',
+  ClpEd25519CtxSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519CtxSigner.pas',
+  ClpIEd25519CtxSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519CtxSigner.pas',
+  ClpEd25519CtxBlake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519CtxBlake2BSigner.pas',
+  ClpIEd25519PhSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PhSigner.pas',
+  ClpIEd25519PhBlake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PhBlake2BSigner.pas',
+  ClpEd25519PhSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519PhSigner.pas',
+  ClpEd25519PhBlake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519PhBlake2BSigner.pas',
+  ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
+  ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
+  BlowfishTestVectors in '..\src\Crypto\BlowfishTestVectors.pas',
+  BlockCipherVectorTests in '..\src\Crypto\BlockCipherVectorTests.pas',
+  AESTestVectors in '..\src\Crypto\AESTestVectors.pas',
+  SpeckTestVectors in '..\src\Crypto\SpeckTestVectors.pas',
+  RijndaelTestVectors in '..\src\Crypto\RijndaelTestVectors.pas',
+  OIDTests in '..\src\Asn1\OIDTests.pas',
+  SecureRandomTests in '..\src\Security\SecureRandomTests.pas',
+  EqualsAndHashCodeTests in '..\src\Asn1\EqualsAndHashCodeTests.pas',
+  BigIntegerTests in '..\src\Math\BigIntegerTests.pas',
+  ECAlgorithmsTests in '..\src\Math\ECAlgorithmsTests.pas',
+  ECPointTests in '..\src\Math\ECPointTests.pas',
+  ECDsa5Tests in '..\src\Others\ECDsa5Tests.pas',
+  NamedCurveTests in '..\src\Others\NamedCurveTests.pas',
+  SignerUtilitiesTests in '..\src\Others\SignerUtilitiesTests.pas',
+  DerApplicationSpecificTests in '..\src\Asn1\DerApplicationSpecificTests.pas',
+  SecP384R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP384R1FieldTests.pas',
+  ECTests in '..\src\Others\ECTests.pas',
+  Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
+  ECSchnorrTests in '..\src\Others\ECSchnorrTests.pas',
+  DigestRandomNumberTests in '..\src\Crypto\DigestRandomNumberTests.pas',
+  FixedPointTests in '..\src\Math\EC\FixedPointTests.pas',
+  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',
+  ECNRTests in '..\src\Math\ECNRTests.pas',
+  PaddingTests in '..\src\Crypto\PaddingTests.pas',
+  DSATests in '..\src\Crypto\DSATests.pas',
+  DeterministicDsaTests in '..\src\Crypto\DeterministicDsaTests.pas',
+  BlockCipherMonteCarloTests in '..\src\Crypto\BlockCipherMonteCarloTests.pas',
+  HMacTests in '..\src\Crypto\HMacTests.pas',
+  MD5HMacTests in '..\src\Crypto\MD5HMacTests.pas',
+  SHA1HMacTests in '..\src\Crypto\SHA1HMacTests.pas',
+  SHA224HMacTests in '..\src\Crypto\SHA224HMacTests.pas',
+  SHA256HMacTests in '..\src\Crypto\SHA256HMacTests.pas',
+  SHA384HMacTests in '..\src\Crypto\SHA384HMacTests.pas',
+  SHA512HMacTests in '..\src\Crypto\SHA512HMacTests.pas',
+  RIPEMD128HMacTests in '..\src\Crypto\RIPEMD128HMacTests.pas',
+  RIPEMD160HMacTests in '..\src\Crypto\RIPEMD160HMacTests.pas',
+  SecP256R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas',
+  TagTests in '..\src\Asn1\TagTests.pas',
+  StringTests in '..\src\Asn1\StringTests.pas',
+  ParsingTests in '..\src\Asn1\ParsingTests.pas',
+  ParseTests in '..\src\Asn1\ParseTests.pas',
+  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas',
+  Salsa20Tests in '..\src\Crypto\Salsa20Tests.pas',
+  ChaChaTests in '..\src\Crypto\ChaChaTests.pas',
+  XSalsa20Tests in '..\src\Crypto\XSalsa20Tests.pas',
+  StreamCipherResetTests in '..\src\Crypto\StreamCipherResetTests.pas',
+  CTSTests in '..\src\Crypto\CTSTests.pas',
+  PascalCoinECIESTests in '..\src\Math\PascalCoinECIESTests.pas',
+  X25519Tests in '..\src\Math\EC\Rfc7748\X25519Tests.pas',
+  Ed25519Tests in '..\src\Math\EC\Rfc8032\Ed25519Tests.pas';
+
+begin
+
+  TestInsight.DUnit.RunRegisteredTests;
+
+end.

+ 127 - 50
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -102,8 +102,6 @@ uses
   ClpConverters in '..\..\CryptoLib\src\Utils\ClpConverters.pas',
   ClpConverters in '..\..\CryptoLib\src\Utils\ClpConverters.pas',
   ClpCryptoLibTypes in '..\..\CryptoLib\src\Utils\ClpCryptoLibTypes.pas',
   ClpCryptoLibTypes in '..\..\CryptoLib\src\Utils\ClpCryptoLibTypes.pas',
   ClpTimes in '..\..\CryptoLib\src\Utils\ClpTimes.pas',
   ClpTimes in '..\..\CryptoLib\src\Utils\ClpTimes.pas',
-  OIDTests in '..\src\Asn1\OIDTests.pas',
-  SecureRandomTests in '..\src\Security\SecureRandomTests.pas',
   ClpBigIntegers in '..\..\CryptoLib\src\Utils\ClpBigIntegers.pas',
   ClpBigIntegers in '..\..\CryptoLib\src\Utils\ClpBigIntegers.pas',
   ClpMod in '..\..\CryptoLib\src\Math\Raw\ClpMod.pas',
   ClpMod in '..\..\CryptoLib\src\Math\Raw\ClpMod.pas',
   ClpNat in '..\..\CryptoLib\src\Math\Raw\ClpNat.pas',
   ClpNat in '..\..\CryptoLib\src\Math\Raw\ClpNat.pas',
@@ -138,24 +136,8 @@ uses
   ClpPrimeField in '..\..\CryptoLib\src\Math\Field\ClpPrimeField.pas',
   ClpPrimeField in '..\..\CryptoLib\src\Math\Field\ClpPrimeField.pas',
   ClpIPrimeField in '..\..\CryptoLib\src\Interfaces\ClpIPrimeField.pas',
   ClpIPrimeField in '..\..\CryptoLib\src\Interfaces\ClpIPrimeField.pas',
   ClpFiniteFields in '..\..\CryptoLib\src\Math\Field\ClpFiniteFields.pas',
   ClpFiniteFields in '..\..\CryptoLib\src\Math\Field\ClpFiniteFields.pas',
-  EqualsAndHashCodeTests in '..\src\Asn1\EqualsAndHashCodeTests.pas',
-  BigIntegerTests in '..\src\Math\BigIntegerTests.pas',
-  ECAlgorithmsTests in '..\src\Math\ECAlgorithmsTests.pas',
-  ECPointTests in '..\src\Math\ECPointTests.pas',
   ClpOSRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpOSRandom.pas',
   ClpOSRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpOSRandom.pas',
-  ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
-  ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
-  ECDsa5Tests in '..\src\Others\ECDsa5Tests.pas',
-  NamedCurveTests in '..\src\Others\NamedCurveTests.pas',
-  SignerUtilitiesTests in '..\src\Others\SignerUtilitiesTests.pas',
-  DerApplicationSpecificTests in '..\src\Asn1\DerApplicationSpecificTests.pas',
-  SecP384R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP384R1FieldTests.pas',
-  ECTests in '..\src\Others\ECTests.pas',
-  Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
   ClpSetWeakRef in '..\..\CryptoLib\src\Utils\ClpSetWeakRef.pas',
   ClpSetWeakRef in '..\..\CryptoLib\src\Utils\ClpSetWeakRef.pas',
-  ECSchnorrTests in '..\src\Others\ECSchnorrTests.pas',
-  DigestRandomNumberTests in '..\src\Crypto\DigestRandomNumberTests.pas',
-  FixedPointTests in '..\src\Math\EC\FixedPointTests.pas',
   ClpCipherUtilities in '..\..\CryptoLib\src\Security\ClpCipherUtilities.pas',
   ClpCipherUtilities in '..\..\CryptoLib\src\Security\ClpCipherUtilities.pas',
   ClpIBufferedCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedCipher.pas',
   ClpIBufferedCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedCipher.pas',
   ClpIBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIBlockCipher.pas',
   ClpIBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIBlockCipher.pas',
@@ -175,9 +157,6 @@ uses
   ClpParameterUtilities in '..\..\CryptoLib\src\Security\ClpParameterUtilities.pas',
   ClpParameterUtilities in '..\..\CryptoLib\src\Security\ClpParameterUtilities.pas',
   ClpAesEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpAesEngine.pas',
   ClpAesEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpAesEngine.pas',
   ClpIAesEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesEngine.pas',
   ClpIAesEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesEngine.pas',
-  BlockCipherVectorTests in '..\src\Crypto\BlockCipherVectorTests.pas',
-  AESTestVectors in '..\src\Crypto\AESTestVectors.pas',
-  AESTests in '..\src\Crypto\AESTests.pas',
   ClpECDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHBasicAgreement.pas',
   ClpECDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHBasicAgreement.pas',
   ClpIBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIBasicAgreement.pas',
   ClpIBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIBasicAgreement.pas',
   ClpIECDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIECDHBasicAgreement.pas',
   ClpIECDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIECDHBasicAgreement.pas',
@@ -210,7 +189,6 @@ uses
   ClpIIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIIESEngine.pas',
   ClpIIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIIESEngine.pas',
   ClpPascalCoinIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpPascalCoinIESEngine.pas',
   ClpPascalCoinIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpPascalCoinIESEngine.pas',
   ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
   ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
-  IESCipherTests in '..\src\Math\IESCipherTests.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
   ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas',
   ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas',
   ClpIDigest in '..\..\CryptoLib\src\Interfaces\ClpIDigest.pas',
   ClpIDigest in '..\..\CryptoLib\src\Interfaces\ClpIDigest.pas',
@@ -218,19 +196,15 @@ uses
   ClpStringUtils in '..\..\CryptoLib\src\Utils\ClpStringUtils.pas',
   ClpStringUtils in '..\..\CryptoLib\src\Utils\ClpStringUtils.pas',
   ClpCipherKeyGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpCipherKeyGenerator.pas',
   ClpCipherKeyGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpCipherKeyGenerator.pas',
   ClpICipherKeyGenerator in '..\..\CryptoLib\src\Interfaces\ClpICipherKeyGenerator.pas',
   ClpICipherKeyGenerator in '..\..\CryptoLib\src\Interfaces\ClpICipherKeyGenerator.pas',
-  AESSICTests in '..\src\Crypto\AESSICTests.pas',
   ClpHMac in '..\..\CryptoLib\src\Crypto\Macs\ClpHMac.pas',
   ClpHMac in '..\..\CryptoLib\src\Crypto\Macs\ClpHMac.pas',
   ClpIHMac in '..\..\CryptoLib\src\Interfaces\ClpIHMac.pas',
   ClpIHMac in '..\..\CryptoLib\src\Interfaces\ClpIHMac.pas',
   ClpMacUtilities in '..\..\CryptoLib\src\Security\ClpMacUtilities.pas',
   ClpMacUtilities in '..\..\CryptoLib\src\Security\ClpMacUtilities.pas',
   ClpIanaObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Iana\ClpIanaObjectIdentifiers.pas',
   ClpIanaObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Iana\ClpIanaObjectIdentifiers.pas',
   ClpMiscObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Misc\ClpMiscObjectIdentifiers.pas',
   ClpMiscObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Misc\ClpMiscObjectIdentifiers.pas',
-  MD5HMacTests in '..\src\Crypto\MD5HMacTests.pas',
-  HMacTests in '..\src\Crypto\HMacTests.pas',
   ClpPbeParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPbeParametersGenerator.pas',
   ClpPbeParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPbeParametersGenerator.pas',
   ClpIPbeParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPbeParametersGenerator.pas',
   ClpIPbeParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPbeParametersGenerator.pas',
   ClpPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPkcs5S2ParametersGenerator.pas',
   ClpPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPkcs5S2ParametersGenerator.pas',
   ClpIPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPkcs5S2ParametersGenerator.pas',
   ClpIPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPkcs5S2ParametersGenerator.pas',
-  Pkcs5Tests in '..\src\Crypto\Pkcs5Tests.pas',
   ClpECNRSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECNRSigner.pas',
   ClpECNRSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECNRSigner.pas',
   ClpIECNRSigner in '..\..\CryptoLib\src\Interfaces\ClpIECNRSigner.pas',
   ClpIECNRSigner in '..\..\CryptoLib\src\Interfaces\ClpIECNRSigner.pas',
   ClpDsaValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaValidationParameters.pas',
   ClpDsaValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaValidationParameters.pas',
@@ -248,7 +222,7 @@ uses
   ClpDsaKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaKeyPairGenerator.pas',
   ClpDsaKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaKeyPairGenerator.pas',
   ClpIDsaKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaKeyPairGenerator.pas',
   ClpIDsaKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaKeyPairGenerator.pas',
   ClpDsaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpDsaSigner.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',
   ClpIDsaSigner in '..\..\CryptoLib\src\Interfaces\ClpIDsaSigner.pas',
   ClpDigest in '..\..\CryptoLib\src\Crypto\Digests\ClpDigest.pas',
   ClpDigest in '..\..\CryptoLib\src\Crypto\Digests\ClpDigest.pas',
   ClpECDHCBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHCBasicAgreement.pas',
   ClpECDHCBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHCBasicAgreement.pas',
@@ -263,43 +237,23 @@ uses
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.pas',
   ClpIDsaParameterGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameterGenerationParameters.pas',
   ClpValidityPrecompInfo in '..\..\CryptoLib\src\Math\EC\ClpValidityPrecompInfo.pas',
   ClpValidityPrecompInfo in '..\..\CryptoLib\src\Math\EC\ClpValidityPrecompInfo.pas',
   ClpIValidityPrecompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPrecompInfo.pas',
   ClpIValidityPrecompInfo in '..\..\CryptoLib\src\Interfaces\ClpIValidityPrecompInfo.pas',
-  HkdfGeneratorTests in '..\src\Crypto\HkdfGeneratorTests.pas',
-  ECIESTests in '..\src\Math\ECIESTests.pas',
-  ECNRTests in '..\src\Math\ECNRTests.pas',
-  PaddingTests in '..\src\Crypto\PaddingTests.pas',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpDsaParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
   ClpIDsaParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDsaParametersGenerator.pas',
-  DSATests in '..\src\Crypto\DSATests.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
   ClpDsaParameter in '..\..\CryptoLib\src\Asn1\X509\ClpDsaParameter.pas',
   ClpIDsaParameter in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameter.pas',
   ClpIDsaParameter in '..\..\CryptoLib\src\Interfaces\ClpIDsaParameter.pas',
   ClpIPreCompCallBack in '..\..\CryptoLib\src\Interfaces\ClpIPreCompCallBack.pas',
   ClpIPreCompCallBack in '..\..\CryptoLib\src\Interfaces\ClpIPreCompCallBack.pas',
-  DeterministicDsaTests in '..\src\Crypto\DeterministicDsaTests.pas',
   ClpNistNamedCurves in '..\..\CryptoLib\src\Asn1\Nist\ClpNistNamedCurves.pas',
   ClpNistNamedCurves in '..\..\CryptoLib\src\Asn1\Nist\ClpNistNamedCurves.pas',
   ClpNat320 in '..\..\CryptoLib\src\Math\Raw\ClpNat320.pas',
   ClpNat320 in '..\..\CryptoLib\src\Math\Raw\ClpNat320.pas',
   ClpNat256 in '..\..\CryptoLib\src\Math\Raw\ClpNat256.pas',
   ClpNat256 in '..\..\CryptoLib\src\Math\Raw\ClpNat256.pas',
   ClpAesLightEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpAesLightEngine.pas',
   ClpAesLightEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpAesLightEngine.pas',
   ClpIAesLightEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesLightEngine.pas',
   ClpIAesLightEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesLightEngine.pas',
-  BlockCipherMonteCarloTests in '..\src\Crypto\BlockCipherMonteCarloTests.pas',
-  SHA1HMacTests in '..\src\Crypto\SHA1HMacTests.pas',
-  SHA224HMacTests in '..\src\Crypto\SHA224HMacTests.pas',
-  SHA256HMacTests in '..\src\Crypto\SHA256HMacTests.pas',
-  SHA384HMacTests in '..\src\Crypto\SHA384HMacTests.pas',
-  SHA512HMacTests in '..\src\Crypto\SHA512HMacTests.pas',
-  RIPEMD128HMacTests in '..\src\Crypto\RIPEMD128HMacTests.pas',
-  RIPEMD160HMacTests in '..\src\Crypto\RIPEMD160HMacTests.pas',
   ClpCustomNamedCurves in '..\..\CryptoLib\src\Crypto\EC\ClpCustomNamedCurves.pas',
   ClpCustomNamedCurves in '..\..\CryptoLib\src\Crypto\EC\ClpCustomNamedCurves.pas',
   ClpNat384 in '..\..\CryptoLib\src\Math\Raw\ClpNat384.pas',
   ClpNat384 in '..\..\CryptoLib\src\Math\Raw\ClpNat384.pas',
   ClpNat192 in '..\..\CryptoLib\src\Math\Raw\ClpNat192.pas',
   ClpNat192 in '..\..\CryptoLib\src\Math\Raw\ClpNat192.pas',
   ClpNat512 in '..\..\CryptoLib\src\Math\Raw\ClpNat512.pas',
   ClpNat512 in '..\..\CryptoLib\src\Math\Raw\ClpNat512.pas',
   ClpInterleave in '..\..\CryptoLib\src\Math\Raw\ClpInterleave.pas',
   ClpInterleave in '..\..\CryptoLib\src\Math\Raw\ClpInterleave.pas',
-  SecP256R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas',
-  TagTests in '..\src\Asn1\TagTests.pas',
-  StringTests in '..\src\Asn1\StringTests.pas',
-  ParsingTests in '..\src\Asn1\ParsingTests.pas',
-  ParseTests in '..\src\Asn1\ParseTests.pas',
-  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas',
   ClpIDsaExt in '..\..\CryptoLib\src\Interfaces\ClpIDsaExt.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',
   ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
   ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
   ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
   ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
   ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
@@ -310,7 +264,8 @@ uses
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
   ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
   ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
   ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas',
   ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas',
-  BlowfishTestVectors in '..\src\Crypto\BlowfishTestVectors.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',
   ClpSecP256R1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Custom.pas',
   ClpISecP256R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Custom.pas',
   ClpISecP256R1Custom in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Custom.pas',
   ClpSecP256K1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas',
   ClpSecP256K1Custom in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256K1Custom.pas',
@@ -330,7 +285,129 @@ uses
   ClpIX9ECC in '..\..\CryptoLib\src\Interfaces\ClpIX9ECC.pas',
   ClpIX9ECC in '..\..\CryptoLib\src\Interfaces\ClpIX9ECC.pas',
   ClpECCurveConstants in '..\..\CryptoLib\src\Math\EC\ClpECCurveConstants.pas',
   ClpECCurveConstants in '..\..\CryptoLib\src\Math\EC\ClpECCurveConstants.pas',
   ClpAsn1Objects in '..\..\CryptoLib\src\Asn1\ClpAsn1Objects.pas',
   ClpAsn1Objects in '..\..\CryptoLib\src\Asn1\ClpAsn1Objects.pas',
-  ClpSignersEncodings in '..\..\CryptoLib\src\Crypto\Signers\SignersEncodings\ClpSignersEncodings.pas';
+  ClpSignersEncodings in '..\..\CryptoLib\src\Crypto\Signers\SignersEncodings\ClpSignersEncodings.pas',
+  ClpIStreamCipher in '..\..\CryptoLib\src\Interfaces\ClpIStreamCipher.pas',
+  ClpBufferedStreamCipher in '..\..\CryptoLib\src\Crypto\ClpBufferedStreamCipher.pas',
+  ClpIBufferedStreamCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedStreamCipher.pas',
+  ClpSalsa20Engine in '..\..\CryptoLib\src\Crypto\Engines\ClpSalsa20Engine.pas',
+  ClpISalsa20Engine in '..\..\CryptoLib\src\Interfaces\ClpISalsa20Engine.pas',
+  ClpIXSalsa20Engine in '..\..\CryptoLib\src\Interfaces\ClpIXSalsa20Engine.pas',
+  ClpXSalsa20Engine in '..\..\CryptoLib\src\Crypto\Engines\ClpXSalsa20Engine.pas',
+  ClpIChaChaEngine in '..\..\CryptoLib\src\Interfaces\ClpIChaChaEngine.pas',
+  ClpChaChaEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpChaChaEngine.pas',
+  ClpRijndaelEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpRijndaelEngine.pas',
+  ClpIRijndaelEngine in '..\..\CryptoLib\src\Interfaces\ClpIRijndaelEngine.pas',
+  ClpIAlgorithmParameterSpec in '..\..\CryptoLib\src\Interfaces\ClpIAlgorithmParameterSpec.pas',
+  ClpIIESParameterSpec in '..\..\CryptoLib\src\Interfaces\ClpIIESParameterSpec.pas',
+  ClpIESParameterSpec in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESParameterSpec.pas',
+  ClpCurve25519Custom in '..\..\CryptoLib\src\Math\EC\Custom\Djb\ClpCurve25519Custom.pas',
+  ClpICurve25519Custom in '..\..\CryptoLib\src\Interfaces\ClpICurve25519Custom.pas',
+  ClpX25519Field in '..\..\CryptoLib\src\Math\EC\Rfc7748\ClpX25519Field.pas',
+  ClpEd25519 in '..\..\CryptoLib\src\Math\EC\Rfc8032\ClpEd25519.pas',
+  ClpIEd25519 in '..\..\CryptoLib\src\Interfaces\ClpIEd25519.pas',
+  ClpEd25519Blake2B in '..\..\CryptoLib\src\Math\EC\Rfc8032\ClpEd25519Blake2B.pas',
+  ClpIEd25519Blake2B in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2B.pas',
+  ClpSpeckLegacyEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpSpeckLegacyEngine.pas',
+  ClpISpeckLegacyEngine in '..\..\CryptoLib\src\Interfaces\ClpISpeckLegacyEngine.pas',
+  ClpX25519 in '..\..\CryptoLib\src\Math\EC\Rfc7748\ClpX25519.pas',
+  ClpEdECObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Edec\ClpEdECObjectIdentifiers.pas',
+  ClpIRawAgreement in '..\..\CryptoLib\src\Interfaces\ClpIRawAgreement.pas',
+  ClpX25519Agreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpX25519Agreement.pas',
+  ClpIX25519Agreement in '..\..\CryptoLib\src\Interfaces\ClpIX25519Agreement.pas',
+  ClpX25519PrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519PrivateKeyParameters.pas',
+  ClpIX25519PrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519PrivateKeyParameters.pas',
+  ClpIX25519PublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519PublicKeyParameters.pas',
+  ClpX25519PublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519PublicKeyParameters.pas',
+  ClpIEd25519PrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PrivateKeyParameters.pas',
+  ClpIEd25519PublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PublicKeyParameters.pas',
+  ClpIEd25519Blake2BPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BPublicKeyParameters.pas',
+  ClpIEd25519Blake2BPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BPrivateKeyParameters.pas',
+  ClpEd25519PrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519PrivateKeyParameters.pas',
+  ClpEd25519Blake2BPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BPrivateKeyParameters.pas',
+  ClpEd25519PublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519PublicKeyParameters.pas',
+  ClpEd25519Blake2BPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BPublicKeyParameters.pas',
+  ClpX25519KeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpX25519KeyPairGenerator.pas',
+  ClpIX25519KeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIX25519KeyPairGenerator.pas',
+  ClpIEd25519KeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEd25519KeyPairGenerator.pas',
+  ClpIEd25519Blake2BKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BKeyPairGenerator.pas',
+  ClpEd25519KeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEd25519KeyPairGenerator.pas',
+  ClpEd25519Blake2BKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEd25519Blake2BKeyPairGenerator.pas',
+  ClpX25519KeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpX25519KeyGenerationParameters.pas',
+  ClpIX25519KeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIX25519KeyGenerationParameters.pas',
+  ClpIEd25519KeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519KeyGenerationParameters.pas',
+  ClpIEd25519Blake2BKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BKeyGenerationParameters.pas',
+  ClpEd25519KeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519KeyGenerationParameters.pas',
+  ClpEd25519Blake2BKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpEd25519Blake2BKeyGenerationParameters.pas',
+  ClpIEd25519Signer in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Signer.pas',
+  ClpEd25519Signer in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519Signer.pas',
+  ClpIEd25519Blake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519Blake2BSigner.pas',
+  ClpEd25519Blake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519Blake2BSigner.pas',
+  ClpIEd25519CtxBlake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519CtxBlake2BSigner.pas',
+  ClpEd25519CtxSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519CtxSigner.pas',
+  ClpIEd25519CtxSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519CtxSigner.pas',
+  ClpEd25519CtxBlake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519CtxBlake2BSigner.pas',
+  ClpIEd25519PhSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PhSigner.pas',
+  ClpIEd25519PhBlake2BSigner in '..\..\CryptoLib\src\Interfaces\ClpIEd25519PhBlake2BSigner.pas',
+  ClpEd25519PhSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519PhSigner.pas',
+  ClpEd25519PhBlake2BSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpEd25519PhBlake2BSigner.pas',
+  ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
+  ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
+  BlowfishTestVectors in '..\src\Crypto\BlowfishTestVectors.pas',
+  BlockCipherVectorTests in '..\src\Crypto\BlockCipherVectorTests.pas',
+  AESTestVectors in '..\src\Crypto\AESTestVectors.pas',
+  SpeckTestVectors in '..\src\Crypto\SpeckTestVectors.pas',
+  RijndaelTestVectors in '..\src\Crypto\RijndaelTestVectors.pas',
+  OIDTests in '..\src\Asn1\OIDTests.pas',
+  SecureRandomTests in '..\src\Security\SecureRandomTests.pas',
+  EqualsAndHashCodeTests in '..\src\Asn1\EqualsAndHashCodeTests.pas',
+  BigIntegerTests in '..\src\Math\BigIntegerTests.pas',
+  ECAlgorithmsTests in '..\src\Math\ECAlgorithmsTests.pas',
+  ECPointTests in '..\src\Math\ECPointTests.pas',
+  ECDsa5Tests in '..\src\Others\ECDsa5Tests.pas',
+  NamedCurveTests in '..\src\Others\NamedCurveTests.pas',
+  SignerUtilitiesTests in '..\src\Others\SignerUtilitiesTests.pas',
+  DerApplicationSpecificTests in '..\src\Asn1\DerApplicationSpecificTests.pas',
+  SecP384R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP384R1FieldTests.pas',
+  ECTests in '..\src\Others\ECTests.pas',
+  Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
+  ECSchnorrTests in '..\src\Others\ECSchnorrTests.pas',
+  DigestRandomNumberTests in '..\src\Crypto\DigestRandomNumberTests.pas',
+  FixedPointTests in '..\src\Math\EC\FixedPointTests.pas',
+  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',
+  ECNRTests in '..\src\Math\ECNRTests.pas',
+  PaddingTests in '..\src\Crypto\PaddingTests.pas',
+  DSATests in '..\src\Crypto\DSATests.pas',
+  DeterministicDsaTests in '..\src\Crypto\DeterministicDsaTests.pas',
+  BlockCipherMonteCarloTests in '..\src\Crypto\BlockCipherMonteCarloTests.pas',
+  HMacTests in '..\src\Crypto\HMacTests.pas',
+  MD5HMacTests in '..\src\Crypto\MD5HMacTests.pas',
+  SHA1HMacTests in '..\src\Crypto\SHA1HMacTests.pas',
+  SHA224HMacTests in '..\src\Crypto\SHA224HMacTests.pas',
+  SHA256HMacTests in '..\src\Crypto\SHA256HMacTests.pas',
+  SHA384HMacTests in '..\src\Crypto\SHA384HMacTests.pas',
+  SHA512HMacTests in '..\src\Crypto\SHA512HMacTests.pas',
+  RIPEMD128HMacTests in '..\src\Crypto\RIPEMD128HMacTests.pas',
+  RIPEMD160HMacTests in '..\src\Crypto\RIPEMD160HMacTests.pas',
+  SecP256R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas',
+  TagTests in '..\src\Asn1\TagTests.pas',
+  StringTests in '..\src\Asn1\StringTests.pas',
+  ParsingTests in '..\src\Asn1\ParsingTests.pas',
+  ParseTests in '..\src\Asn1\ParseTests.pas',
+  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas',
+  Salsa20Tests in '..\src\Crypto\Salsa20Tests.pas',
+  ChaChaTests in '..\src\Crypto\ChaChaTests.pas',
+  XSalsa20Tests in '..\src\Crypto\XSalsa20Tests.pas',
+  StreamCipherResetTests in '..\src\Crypto\StreamCipherResetTests.pas',
+  CTSTests in '..\src\Crypto\CTSTests.pas',
+  PascalCoinECIESTests in '..\src\Math\PascalCoinECIESTests.pas',
+  X25519Tests in '..\src\Math\EC\Rfc7748\X25519Tests.pas',
+  Ed25519Tests in '..\src\Math\EC\Rfc8032\Ed25519Tests.pas';
 
 
 begin
 begin
 
 

+ 88 - 3
CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi

@@ -10,8 +10,49 @@
       <ResourceType Value="res"/>
       <ResourceType Value="res"/>
       <UseXPManifest Value="True"/>
       <UseXPManifest Value="True"/>
     </General>
     </General>
-    <BuildModes Count="1">
+    <BuildModes Count="2">
       <Item1 Name="Default" Default="True"/>
       <Item1 Name="Default" Default="True"/>
+      <Item2 Name="Debug">
+        <CompilerOptions>
+          <Version Value="11"/>
+          <PathDelim Value="\"/>
+          <Target>
+            <Filename Value=".\bin\CryptoLib"/>
+          </Target>
+          <SearchPaths>
+            <IncludeFiles Value="$(ProjOutDir)"/>
+            <OtherUnitFiles Value="..\src\Asn1;..\src\Math;..\src\Math\EC\Custom\Sec;..\src\Others;..\src\Security;..\src\Utils;..\src\Crypto;..\src\Math\EC;..\src\Math\EC\Rfc7748;..\src\Math\EC\Rfc8032"/>
+            <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
+          </SearchPaths>
+          <Parsing>
+            <SyntaxOptions>
+              <IncludeAssertionCode Value="True"/>
+            </SyntaxOptions>
+          </Parsing>
+          <CodeGeneration>
+            <Checks>
+              <IOChecks Value="True"/>
+              <RangeChecks Value="True"/>
+              <OverflowChecks Value="True"/>
+              <StackChecks Value="True"/>
+            </Checks>
+            <VerifyObjMethodCallValidity Value="True"/>
+          </CodeGeneration>
+          <Linking>
+            <Debugging>
+              <DebugInfoType Value="dsDwarf2Set"/>
+              <UseHeaptrc Value="True"/>
+              <TrashVariables Value="True"/>
+              <UseExternalDbgSyms Value="True"/>
+            </Debugging>
+            <Options>
+              <Win32>
+                <GraphicApplication Value="True"/>
+              </Win32>
+            </Options>
+          </Linking>
+        </CompilerOptions>
+      </Item2>
     </BuildModes>
     </BuildModes>
     <PublishOptions>
     <PublishOptions>
       <Version Value="2"/>
       <Version Value="2"/>
@@ -36,7 +77,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item4>
       </Item4>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="48">
+    <Units Count="59">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -230,6 +271,50 @@
         <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
         <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit47>
       </Unit47>
+      <Unit48>
+        <Filename Value="..\src\Crypto\SpeckTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit48>
+      <Unit49>
+        <Filename Value="..\src\Crypto\SPECKTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit49>
+      <Unit50>
+        <Filename Value="..\src\Crypto\XSalsa20Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit50>
+      <Unit51>
+        <Filename Value="..\src\Crypto\Salsa20Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit51>
+      <Unit52>
+        <Filename Value="..\src\Crypto\StreamCipherResetTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit52>
+      <Unit53>
+        <Filename Value="..\src\Crypto\ChaChaTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit53>
+      <Unit54>
+        <Filename Value="..\src\Crypto\CTSTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit54>
+      <Unit55>
+        <Filename Value="..\src\Crypto\RijndaelTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit55>
+      <Unit56>
+        <Filename Value="..\src\Math\PascalCoinECIESTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit56>
+      <Unit57>
+        <Filename Value="..\src\Math\EC\Rfc7748\X25519Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit57>
+      <Unit58>
+        <Filename Value="..\src\Math\EC\Rfc8032\Ed25519Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit58>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>
@@ -240,7 +325,7 @@
     </Target>
     </Target>
     <SearchPaths>
     <SearchPaths>
       <IncludeFiles Value="$(ProjOutDir)"/>
       <IncludeFiles Value="$(ProjOutDir)"/>
-      <OtherUnitFiles Value="..\src\Asn1;..\src\Math;..\src\Math\EC\Custom\Sec;..\src\Others;..\src\Security;..\src\Utils;..\src\Crypto;..\src\Math\EC"/>
+      <OtherUnitFiles Value="..\src\Asn1;..\src\Math;..\src\Math\EC\Custom\Sec;..\src\Others;..\src\Security;..\src\Utils;..\src\Crypto;..\src\Math\EC;..\src\Math\EC\Rfc7748;..\src\Math\EC\Rfc8032"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     </SearchPaths>
     <CodeGeneration>
     <CodeGeneration>

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

@@ -33,7 +33,10 @@ uses
   BlockCipherMonteCarloTests,
   BlockCipherMonteCarloTests,
   AESTestVectors,
   AESTestVectors,
   BlowfishTestVectors,
   BlowfishTestVectors,
+  SpeckTestVectors,
+  RijndaelTestVectors,
   AESSICTests,
   AESSICTests,
+  SPECKTests,
   IESCipherTests,
   IESCipherTests,
   MD5HMacTests,
   MD5HMacTests,
   SHA1HMacTests,
   SHA1HMacTests,
@@ -47,10 +50,18 @@ uses
   Pkcs5Tests,
   Pkcs5Tests,
   HkdfGeneratorTests,
   HkdfGeneratorTests,
   ECIESTests,
   ECIESTests,
+  PascalCoinECIESTests,
   ECNRTests,
   ECNRTests,
   PaddingTests,
   PaddingTests,
   DSATests,
   DSATests,
   DeterministicDsaTests,
   DeterministicDsaTests,
+  Salsa20Tests,
+  XSalsa20Tests,
+  ChaChaTests,
+  StreamCipherResetTests,
+  CTSTests,
+  X25519Tests,
+  Ed25519Tests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
   ClpIFixedSecureRandom;
 
 

+ 46 - 2
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi

@@ -37,7 +37,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item2>
       </Item2>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="48">
+    <Units Count="59">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -230,6 +230,50 @@
         <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
         <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit47>
       </Unit47>
+      <Unit48>
+        <Filename Value="..\src\Crypto\SPECKTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit48>
+      <Unit49>
+        <Filename Value="..\src\Crypto\SpeckTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit49>
+      <Unit50>
+        <Filename Value="..\src\Crypto\XSalsa20Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit50>
+      <Unit51>
+        <Filename Value="..\src\Crypto\Salsa20Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit51>
+      <Unit52>
+        <Filename Value="..\src\Crypto\StreamCipherResetTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit52>
+      <Unit53>
+        <Filename Value="..\src\Crypto\ChaChaTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit53>
+      <Unit54>
+        <Filename Value="..\src\Crypto\CTSTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit54>
+      <Unit55>
+        <Filename Value="..\src\Crypto\RijndaelTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit55>
+      <Unit56>
+        <Filename Value="..\src\Math\PascalCoinECIESTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit56>
+      <Unit57>
+        <Filename Value="..\src\Math\EC\Rfc7748\X25519Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit57>
+      <Unit58>
+        <Filename Value="..\src\Math\EC\Rfc8032\Ed25519Tests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit58>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>
@@ -240,7 +284,7 @@
     </Target>
     </Target>
     <SearchPaths>
     <SearchPaths>
       <IncludeFiles Value="$(ProjOutDir)"/>
       <IncludeFiles Value="$(ProjOutDir)"/>
-      <OtherUnitFiles Value="..\src\Others;..\src\Asn1;..\src\Math\EC\Custom\Sec;..\src\Math;..\src\Security;..\src\Utils;..\src\Crypto;..\src\Math\EC"/>
+      <OtherUnitFiles Value="..\src\Others;..\src\Asn1;..\src\Math\EC\Custom\Sec;..\src\Math;..\src\Security;..\src\Utils;..\src\Crypto;..\src\Math\EC;..\src\Math\EC\Rfc7748;..\src\Math\EC\Rfc8032"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     </SearchPaths>
   </CompilerOptions>
   </CompilerOptions>

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

@@ -31,7 +31,10 @@ uses
   BlockCipherMonteCarloTests,
   BlockCipherMonteCarloTests,
   AESTestVectors,
   AESTestVectors,
   BlowfishTestVectors,
   BlowfishTestVectors,
+  SpeckTestVectors,
+  RijndaelTestVectors,
   AESSICTests,
   AESSICTests,
+  SPECKTests,
   IESCipherTests,
   IESCipherTests,
   MD5HMacTests,
   MD5HMacTests,
   SHA1HMacTests,
   SHA1HMacTests,
@@ -45,10 +48,18 @@ uses
   Pkcs5Tests,
   Pkcs5Tests,
   HkdfGeneratorTests,
   HkdfGeneratorTests,
   ECIESTests,
   ECIESTests,
+  PascalCoinECIESTests,
   ECNRTests,
   ECNRTests,
   PaddingTests,
   PaddingTests,
   DSATests,
   DSATests,
   DeterministicDsaTests,
   DeterministicDsaTests,
+  Salsa20Tests,
+  XSalsa20Tests,
+  ChaChaTests,
+  StreamCipherResetTests,
+  CTSTests,
+  X25519Tests,
+  Ed25519Tests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
   ClpIFixedSecureRandom;
 
 

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

@@ -35,7 +35,6 @@ uses
   ClpParametersWithIV,
   ClpParametersWithIV,
   ClpIParametersWithIV,
   ClpIParametersWithIV,
   ClpIBufferedCipher,
   ClpIBufferedCipher,
-  ClpGeneratorUtilities,
   ClpParameterUtilities,
   ClpParameterUtilities,
   ClpCipherUtilities,
   ClpCipherUtilities,
   ClpEncoders,
   ClpEncoders,
@@ -79,33 +78,33 @@ begin
   inherited;
   inherited;
 
 
   Fkeys := TCryptoLibMatrixByteArray.Create
   Fkeys := TCryptoLibMatrixByteArray.Create
-    (THex.Decode('2b7e151628aed2a6abf7158809cf4f3c'),
-    THex.Decode('8e73b0f7da0e6452c810f32b809079e562f8ead2522c6b7b'),
+    (THex.Decode('2B7E151628AED2A6ABF7158809CF4F3C'),
+    THex.Decode('8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B'),
     THex.Decode
     THex.Decode
-    ('603deb1015ca71be2b73aef0857d77811f352c073b6108d72d9810a30914dff4'));
+    ('603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4'));
 
 
   Fplain := TCryptoLibMatrixByteArray.Create
   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
   Fcipher := TCryptoLibGenericArray<TCryptoLibMatrixByteArray>.Create
     (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
     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
     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;
 end;
 
 
 procedure TTestAESSIC.TearDown;
 procedure TTestAESSIC.TearDown;

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

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

+ 24 - 0
CryptoLib.Tests/src/Crypto/BlockCipherMonteCarloTests.pas

@@ -32,12 +32,15 @@ uses
   TestFramework,
   TestFramework,
 {$ENDIF FPC}
 {$ENDIF FPC}
   AESTestVectors,
   AESTestVectors,
+  RijndaelTestVectors,
   ClpIBlockCipher,
   ClpIBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpAesEngine,
   ClpAesEngine,
   ClpIAesEngine,
   ClpIAesEngine,
   ClpAesLightEngine,
   ClpAesLightEngine,
   ClpIAesLightEngine,
   ClpIAesLightEngine,
+  ClpRijndaelEngine,
+  ClpIRijndaelEngine,
   ClpKeyParameter,
   ClpKeyParameter,
   ClpIKeyParameter,
   ClpIKeyParameter,
   ClpBufferedBlockCipher,
   ClpBufferedBlockCipher,
@@ -73,6 +76,7 @@ type
 
 
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESLightEngine;
     procedure TestBlockCipherAESLightEngine;
+    procedure TestBlockCipherRijndaelEngine;
 
 
   end;
   end;
 
 
@@ -181,6 +185,26 @@ begin
 
 
 end;
 end;
 
 
+procedure TTestBlockCipherMonteCarlo.TestBlockCipherRijndaelEngine;
+var
+  i: Int32;
+begin
+  for i := System.Low(TRijndaelTestVectors.FBlockCipherMonteCarloKeys)
+    to System.High(TRijndaelTestVectors.FBlockCipherMonteCarloKeys) do
+  begin
+    DoBlockCipherMonteCarloTest
+      (TRijndaelTestVectors.FBlockCipherMonteCarloIterations[i],
+      TRijndaelEngine.Create
+      (StrToInt(TRijndaelTestVectors.FBlockCipherMonteCarloBlockSizes[i]))
+      as IRijndaelEngine,
+      TKeyParameter.Create
+      (THex.Decode(TRijndaelTestVectors.FBlockCipherMonteCarloKeys[i]))
+      as IKeyParameter, TRijndaelTestVectors.FBlockCipherMonteCarloInputs[i],
+      TRijndaelTestVectors.FBlockCipherMonteCarloOutputs[i]);
+  end;
+
+end;
+
 initialization
 initialization
 
 
 // Register any test cases with the test runner
 // Register any test cases with the test runner

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

@@ -33,6 +33,8 @@ uses
 {$ENDIF FPC}
 {$ENDIF FPC}
   AESTestVectors,
   AESTestVectors,
   BlowfishTestVectors,
   BlowfishTestVectors,
+  SpeckTestVectors,
+  RijndaelTestVectors,
   ClpIBlockCipher,
   ClpIBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpAesEngine,
   ClpAesEngine,
@@ -41,6 +43,12 @@ uses
   ClpIAesLightEngine,
   ClpIAesLightEngine,
   ClpBlowfishEngine,
   ClpBlowfishEngine,
   ClpIBlowfishEngine,
   ClpIBlowfishEngine,
+  ClpSpeckEngine,
+  ClpISpeckEngine,
+  ClpSpeckLegacyEngine,
+  ClpISpeckLegacyEngine,
+  ClpRijndaelEngine,
+  ClpIRijndaelEngine,
   ClpKeyParameter,
   ClpKeyParameter,
   ClpIKeyParameter,
   ClpIKeyParameter,
   ClpParametersWithIV,
   ClpParametersWithIV,
@@ -78,6 +86,17 @@ type
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESLightEngine;
     procedure TestBlockCipherAESLightEngine;
     procedure TestBlockCipherBlowfishEngine;
     procedure TestBlockCipherBlowfishEngine;
+    procedure TestBlockCipherSpeck32Engine;
+    procedure TestBlockCipherSpeck48Engine;
+    procedure TestBlockCipherSpeck64Engine;
+    procedure TestBlockCipherSpeck96Engine;
+    procedure TestBlockCipherSpeck128Engine;
+    procedure TestBlockCipherSpeck32LegacyEngine;
+    procedure TestBlockCipherSpeck48LegacyEngine;
+    procedure TestBlockCipherSpeck64LegacyEngine;
+    procedure TestBlockCipherSpeck96LegacyEngine;
+    procedure TestBlockCipherSpeck128LegacyEngine;
+    procedure TestBlockCipherRijndaelEngine;
     procedure TestBadParameters;
     procedure TestBadParameters;
 
 
   end;
   end;
@@ -249,6 +268,186 @@ begin
 
 
 end;
 end;
 
 
+procedure TTestBlockCipherVector.TestBlockCipherRijndaelEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TRijndaelTestVectors.FBlockCipherVectorKeys)
+    to System.High(TRijndaelTestVectors.FBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest
+      (TRijndaelEngine.Create
+      (StrToInt(TRijndaelTestVectors.FBlockCipherVectorBlockSizes[I]))
+      as IRijndaelEngine,
+      TKeyParameter.Create
+      (THex.Decode(TRijndaelTestVectors.FBlockCipherVectorKeys[I]))
+      as IKeyParameter, TRijndaelTestVectors.FBlockCipherVectorInputs[I],
+      TRijndaelTestVectors.FBlockCipherVectorOutputs[I]);
+  end;
+
+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;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck32LegacyEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck32LegacyBlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck32LegacyBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck32LegacyEngine.Create() as ISpeckLegacyEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck32LegacyBlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck32LegacyBlockCipherVectorInputs
+      [I], TSpeckTestVectors.FSpeck32LegacyBlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck48LegacyEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck48LegacyBlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck48LegacyBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck48LegacyEngine.Create() as ISpeckLegacyEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck48LegacyBlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck48LegacyBlockCipherVectorInputs
+      [I], TSpeckTestVectors.FSpeck48LegacyBlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck64LegacyEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck64LegacyBlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck64LegacyBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck64LegacyEngine.Create() as ISpeckLegacyEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck64LegacyBlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck64LegacyBlockCipherVectorInputs
+      [I], TSpeckTestVectors.FSpeck64LegacyBlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck96LegacyEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck96LegacyBlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck96LegacyBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck96LegacyEngine.Create() as ISpeckLegacyEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck96LegacyBlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck96LegacyBlockCipherVectorInputs
+      [I], TSpeckTestVectors.FSpeck96LegacyBlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
+procedure TTestBlockCipherVector.TestBlockCipherSpeck128LegacyEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TSpeckTestVectors.FSpeck128LegacyBlockCipherVectorKeys)
+    to System.High(TSpeckTestVectors.FSpeck128LegacyBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TSpeck128LegacyEngine.Create()
+      as ISpeckLegacyEngine,
+      TKeyParameter.Create
+      (THex.Decode(TSpeckTestVectors.FSpeck128LegacyBlockCipherVectorKeys[I]))
+      as IKeyParameter, TSpeckTestVectors.FSpeck128LegacyBlockCipherVectorInputs
+      [I], TSpeckTestVectors.FSpeck128LegacyBlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
 initialization
 initialization
 
 
 // Register any test cases with the test runner
 // Register any test cases with the test runner

+ 192 - 0
CryptoLib.Tests/src/Crypto/CTSTests.pas

@@ -0,0 +1,192 @@
+{ *********************************************************************************** }
+{ *                              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 CTSTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpAesEngine,
+  ClpIAesEngine,
+  ClpIKeyParameter,
+  ClpKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  // ClpIBufferedCipher,
+  ClpIBufferedBlockCipher,
+  // ClpICipherKeyGenerator,
+  ClpICipherParameters,
+  // ClpGeneratorUtilities,
+  // ClpParameterUtilities,
+  // ClpCipherUtilities,
+  // ClpNistObjectIdentifiers,
+  ClpBlockCipherModes,
+  ClpIBlockCipherModes,
+  ClpIBlockCipher,
+  // ClpBufferedBlockCipher,
+  // ClpIBufferedBlockCipher,
+  // ClpPaddedBufferedBlockCipher,
+  // ClpIPaddedBufferedBlockCipher,
+  // ClpPaddingModes,
+  // ClpIPaddingModes,
+  ClpEncoders,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  TTestCTS = class(TCryptoLibTestCase)
+  private
+  var
+    Faes128, FaesIn1, FaesIn2, FaesIn3, FaesOut1, FaesOut2, FaesOut3,
+      FZeroIV: TCryptoLibByteArray;
+
+    procedure DoCTSTest(id: Int32; const cipher: IBlockCipher;
+      const params: ICipherParameters;
+      const input, output: TCryptoLibByteArray);
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestCTS;
+    procedure TestExceptions;
+
+  end;
+
+implementation
+
+{ TTestCTS }
+
+procedure TTestCTS.DoCTSTest(id: Int32; const cipher: IBlockCipher;
+  const params: ICipherParameters; const input, output: TCryptoLibByteArray);
+var
+  &out: TCryptoLibByteArray;
+  engine: IBufferedBlockCipher;
+  len: Int32;
+begin
+  System.SetLength(&out, System.length(input));
+
+  engine := TCTSBlockCipher.Create(cipher) as ICTSBlockCipher;
+
+  engine.Init(true, params);
+
+  len := engine.ProcessBytes(input, 0, System.length(input), &out, 0);
+
+  engine.doFinal(&out, len);
+
+  if not(TArrayUtils.AreEqual(output, &out)) then
+  begin
+    Fail(Format('Failed Encryption, ID %d Expected %s but got %s',
+      [id, THex.Encode(output), THex.Encode(&out)]));
+  end;
+
+  engine.Init(false, params);
+
+  len := engine.ProcessBytes(output, 0, System.length(output), &out, 0);
+
+  engine.doFinal(&out, len);
+
+  if not(TArrayUtils.AreEqual(input, &out)) then
+  begin
+    Fail(Format('Failed Decryption, ID %d Expected %s but got %s',
+      [id, THex.Encode(input), THex.Encode(&out)]));
+  end;
+end;
+
+procedure TTestCTS.SetUp;
+begin
+  inherited;
+  //
+  // test vectors from rfc3962
+  //
+  Faes128 := THex.Decode('636869636B656E207465726979616B69');
+  FaesIn1 := THex.Decode('4920776F756C64206C696B652074686520');
+  FaesOut1 := THex.Decode('C6353568F2BF8CB4D8A580362DA7FF7F97');
+  FaesIn2 := THex.Decode
+    ('4920776F756C64206C696B65207468652047656E6572616C20476175277320');
+  FaesOut2 := THex.Decode
+    ('FC00783E0EFDB2C1D445D4C8EFF7ED2297687268D6ECCCC0C07B25E25ECFE5');
+  FaesIn3 := THex.Decode
+    ('4920776F756C64206C696B65207468652047656E6572616C2047617527732043');
+  FaesOut3 := THex.Decode
+    ('39312523A78662D5BE7FCBCC98EBF5A897687268D6ECCCC0C07B25E25ECFE584');
+  System.SetLength(FZeroIV, 16);
+end;
+
+procedure TTestCTS.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestCTS.TestCTS;
+begin
+  DoCTSTest(1, TCBCBlockCipher.Create(TAESEngine.Create() as IAESEngine)
+    as ICBCBlockCipher, TParametersWithIV.Create(TKeyParameter.Create(Faes128)
+    as IKeyParameter, FZeroIV) as IParametersWithIV, FaesIn1, FaesOut1);
+  DoCTSTest(2, TCBCBlockCipher.Create(TAESEngine.Create() as IAESEngine)
+    as ICBCBlockCipher, TParametersWithIV.Create(TKeyParameter.Create(Faes128)
+    as IKeyParameter, FZeroIV) as IParametersWithIV, FaesIn2, FaesOut2);
+  DoCTSTest(3, TCBCBlockCipher.Create(TAESEngine.Create() as IAESEngine)
+    as ICBCBlockCipher, TParametersWithIV.Create(TKeyParameter.Create(Faes128)
+    as IKeyParameter, FZeroIV) as IParametersWithIV, FaesIn3, FaesOut3);
+end;
+
+procedure TTestCTS.TestExceptions;
+begin
+  try
+    TCTSBlockCipher.Create(TSICBlockCipher.Create(TAESEngine.Create()
+      as IAESEngine) as ISICBlockCipher);
+    Fail('Expected CTS construction error - only ECB/CBC supported.');
+  except
+    on e: EArgumentCryptoLibException do
+    begin
+      // expected
+    end;
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestCTS);
+{$ELSE}
+  RegisterTest(TTestCTS.Suite);
+{$ENDIF FPC}
+
+end.

+ 383 - 0
CryptoLib.Tests/src/Crypto/ChaChaTests.pas

@@ -0,0 +1,383 @@
+{ *********************************************************************************** }
+{ *                              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 ChaChaTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpChaChaEngine,
+  ClpIChaChaEngine,
+  ClpICipherParameters,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpEncoders,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// <para>
+  /// ChaCha Test
+  /// </para>
+  /// <para>
+  /// Test cases generated using ref version of ChaCha20 in
+  /// estreambench-20080905.
+  /// </para>
+  /// </summary>
+  TTestChaCha = class(TCryptoLibTestCase)
+  private
+  var
+    FZeroes: TCryptoLibByteArray;
+    FSet1v0_0, FSet1v0_192, FSet1v0_256, FSet1v0_448, FSet1v9_0, FSet1v9_192,
+      FSet1v9_256, FSet1v9_448, FSet6v0_0, FSet6v0_65472, FSet6v0_65536,
+      FSet6v1_0, FSet6v1_65472, FSet6v1_65536, FChaCha12_set1v0_0,
+      FChaCha12_set1v0_192, FChaCha12_set1v0_256, FChaCha12_set1v0_448,
+      FChaCha8_set1v0_0, FChaCha8_set1v0_192, FChaCha8_set1v0_256,
+      FChaCha8_set1v0_448: String;
+
+    procedure Mismatch(const name, expected: String;
+      found: TCryptoLibByteArray);
+    procedure DoChaChaTest1(rounds: Int32; const parameters: ICipherParameters;
+      const v0, v192, v256, v448: String);
+
+    procedure DoChaChaTest2(const parameters: ICipherParameters;
+      const v0, v65472, v65536: String);
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestDoChaChaTest1;
+    procedure TestDoChaChaTest2;
+    procedure TestReInitBug;
+
+  end;
+
+implementation
+
+{ TTestChaCha }
+
+procedure TTestChaCha.SetUp;
+begin
+  inherited;
+  FZeroes := THex.Decode('00000000000000000000000000000000' +
+    '00000000000000000000000000000000' + '00000000000000000000000000000000' +
+    '00000000000000000000000000000000');
+
+  FSet1v0_0 := 'FBB87FBB8395E05DAA3B1D683C422046' +
+    'F913985C2AD9B23CFC06C1D8D04FF213' + 'D44A7A7CDB84929F915420A8A3DC58BF' +
+    '0F7ECB4B1F167BB1A5E6153FDAF4493D';
+
+  FSet1v0_192 := 'D9485D55B8B82D792ED1EEA8E93E9BC1' +
+    'E2834AD0D9B11F3477F6E106A2F6A5F2' + 'EA8244D5B925B8050EAB038F58D4DF57' +
+    '7FAFD1B89359DAE508B2B10CBD6B488E';
+
+  FSet1v0_256 := '08661A35D6F02D3D9ACA8087F421F7C8' +
+    'A42579047D6955D937925BA21396DDD4' + '74B1FC4ACCDCAA33025B4BCE817A4FBF' +
+    '3E5D07D151D7E6FE04934ED466BA4779';
+
+  FSet1v0_448 := 'A7E16DD38BA48CCB130E5BE9740CE359' +
+    'D631E91600F85C8A5D0785A612D1D987' + '90780ACDDC26B69AB106CCF6D866411D' +
+    '10637483DBF08CC5591FD8B3C87A3AE0';
+
+  FSet1v9_0 := 'A276339F99316A913885A0A4BE870F06' +
+    '91E72B00F1B3F2239F714FE81E88E00C' + 'BBE52B4EBBE1EA15894E29658C4CB145' +
+    'E6F89EE4ABB045A78514482CE75AFB7C';
+
+  FSet1v9_192 := '0DFB9BD4F87F68DE54FBC1C6428FDEB0' +
+    '63E997BE8490C9B7A4694025D6EBA2B1' + '5FE429DB82A7CAE6AAB22918E8D00449' +
+    '6FB6291467B5AE81D4E85E81D8795EBB';
+
+  FSet1v9_256 := '546F5BB315E7F71A46E56D4580F90889' +
+    '639A2BA528F757CF3B048738BA141AF3' + 'B31607CB21561BAD94721048930364F4' +
+    'B1227CFEB7CDECBA881FB44903550E68';
+
+  FSet1v9_448 := '6F813586E76691305A0CF048C0D8586D' +
+    'C89460207D8B230CD172398AA33D19E9' + '2D24883C3A9B0BB7CD8C6B2668DB142E' +
+    '37A97948A7A01498A21110297984CD20';
+
+  FSet6v0_0 := '57459975BC46799394788DE80B928387' +
+    '862985A269B9E8E77801DE9D874B3F51' + 'AC4610B9F9BEE8CF8CACD8B5AD0BF17D' +
+    '3DDF23FD7424887EB3F81405BD498CC3';
+
+  FSet6v0_65472 := 'EF9AEC58ACE7DB427DF012B2B91A0C1E' +
+    '8E4759DCE9CDB00A2BD59207357BA06C' + 'E02D327C7719E83D6348A6104B081DB0' +
+    '3908E5186986AE41E3AE95298BB7B713';
+
+  FSet6v0_65536 := '17EF5FF454D85ABBBA280F3A94F1D26E' +
+    '950C7D5B05C4BB3A78326E0DC5731F83' + '84205C32DB867D1B476CE121A0D7074B' +
+    'AA7EE90525D15300F48EC0A6624BD0AF';
+
+  FSet6v1_0 := '92A2508E2C4084567195F2A1005E552B' +
+    '4874EC0504A9CD5E4DAF739AB553D2E7' + '83D79C5BA11E0653BEBB5C116651302E' +
+    '8D381CB728CA627B0B246E83942A2B99';
+
+  FSet6v1_65472 := 'E1974EC3063F7BD0CBA58B1CE34BC874' +
+    '67AAF5759B05EA46682A5D4306E5A76B' + 'D99A448DB8DE73AF97A73F5FBAE2C776' +
+    '35040464524CF14D7F08D4CE1220FD84';
+
+  FSet6v1_65536 := 'BE3436141CFD62D12FF7D852F80C1344' +
+    '81F152AD0235ECF8CA172C55CA8C031B' + '2E785D773A988CA8D4BDA6FAE0E493AA' +
+    '71DCCC4C894D1F106CAC62A9FC0A9607';
+
+  // ChaCha12
+  FChaCha12_set1v0_0 := '36CF0D56E9F7FBF287BC5460D95FBA94' +
+    'AA6CBF17D74E7C784DDCF7E0E882DDAE' + '3B5A58243EF32B79A04575A8E2C2B73D' +
+    'C64A52AA15B9F88305A8F0CA0B5A1A25';
+
+  FChaCha12_set1v0_192 := '83496792AB68FEC75ADB16D3044420A4' +
+    'A00A6E9ADC41C3A63DBBF317A8258C85' + 'A9BC08B4F76B413A4837324AEDF8BC2A' +
+    '67D53C9AB9E1C5BC5F379D48DF9AF730';
+
+  FChaCha12_set1v0_256 := 'BAA28ED593690FD760ADA07C95E3B888' +
+    '4B4B64E488CA7A2D9BDC262243AB9251' + '394C5037E255F8BCCDCD31306C508FFB' +
+    'C9E0161380F7911FCB137D46D9269250';
+
+  FChaCha12_set1v0_448 := 'B7ECFB6AE0B51915762FE1FD03A14D0C' +
+    '9E54DA5DC76EB16EBA5313BC535DE63D' + 'C72D7F9F1874E301E99C8531819F4E37' +
+    '75793F6A5D19C717FA5C78A39EB804A6';
+
+  // ChaCha8
+  FChaCha8_set1v0_0 := 'BEB1E81E0F747E43EE51922B3E87FB38' +
+    'D0163907B4ED49336032AB78B67C2457' + '9FE28F751BD3703E51D876C017FAA435' +
+    '89E63593E03355A7D57B2366F30047C5';
+
+  FChaCha8_set1v0_192 := '33B8B7CA8F8E89F0095ACE75A379C651' +
+    'FD6BDD55703C90672E44C6BAB6AACDD8' + '7C976A87FD264B906E749429284134C2' +
+    '38E3B88CF74A68245B860D119A8BDF43';
+
+  FChaCha8_set1v0_256 := 'F7CA95BF08688BD3BE8A27724210F9DC' +
+    '16F32AF974FBFB09E9F757C577A245AB' + 'F35F824B70A4C02CB4A8D7191FA8A5AD' +
+    '6A84568743844703D353B7F00A8601F4';
+
+  FChaCha8_set1v0_448 := '7B4117E8BFFD595CD8482270B08920FB' +
+    'C9B97794E1809E07BB271BF07C861003' + '4C38DBA6ECA04E5474F399A284CBF6E2' +
+    '7F70142E604D0977797DE5B58B6B25E0';
+
+end;
+
+procedure TTestChaCha.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestChaCha.Mismatch(const name, expected: String;
+  found: TCryptoLibByteArray);
+begin
+  Fail(Format('Mismatch on %s, Expected %s, Found %s.',
+    [name, expected, THex.Encode(found)]));
+end;
+
+procedure TTestChaCha.DoChaChaTest1(rounds: Int32;
+  const parameters: ICipherParameters; const v0, v192, v256, v448: String);
+var
+  chacha: IChaChaEngine;
+  buf: TCryptoLibByteArray;
+  i: Int32;
+begin
+  chacha := TChaChaEngine.Create(rounds);
+  chacha.Init(true, parameters);
+  System.SetLength(buf, 64);
+  i := 0;
+  while i <> 7 do
+  begin
+    chacha.ProcessBytes(FZeroes, 0, 64, buf, 0);
+    case i of
+      0:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v0))) then
+          begin
+            Mismatch(Format('v0/%d', [rounds]), v0, buf);
+          end;
+        end;
+      3:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v192))) then
+          begin
+            Mismatch(Format('v192/%d', [rounds]), v192, buf);
+          end;
+        end;
+      4:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v256))) then
+          begin
+            Mismatch(Format('v256/%d', [rounds]), v256, buf);
+          end;
+        end
+    else
+      begin
+        // ignore
+      end;
+    end;
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i <> 64 do
+  begin
+    buf[i] := chacha.ReturnByte(FZeroes[i]);
+    System.Inc(i);
+  end;
+
+  if not(TArrayUtils.AreEqual(buf, THex.Decode(v448))) then
+  begin
+    Mismatch(Format('v448/%d', [rounds]), v448, buf);
+  end;
+end;
+
+procedure TTestChaCha.DoChaChaTest2(const parameters: ICipherParameters;
+  const v0, v65472, v65536: String);
+var
+  chacha: IChaChaEngine;
+  buf: TCryptoLibByteArray;
+  i: Int32;
+begin
+  chacha := TChaChaEngine.Create();
+  chacha.Init(true, parameters);
+  System.SetLength(buf, 64);
+  i := 0;
+  while i <> 1025 do
+  begin
+    chacha.ProcessBytes(FZeroes, 0, 64, buf, 0);
+    case i of
+      0:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v0))) then
+          begin
+            Mismatch('v0', v0, buf);
+          end;
+        end;
+      1023:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v65472))) then
+          begin
+            Mismatch('v65472', v65472, buf);
+          end;
+        end;
+      1024:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v65536))) then
+          begin
+            Mismatch('v65536', v65536, buf);
+          end;
+        end
+    else
+      begin
+        // ignore
+      end;
+    end;
+    System.Inc(i);
+  end;
+
+end;
+
+procedure TTestChaCha.TestDoChaChaTest1;
+begin
+  DoChaChaTest1(20, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')) as IParametersWithIV,
+    FSet1v0_0, FSet1v0_192, FSet1v0_256, FSet1v0_448);
+  DoChaChaTest1(20, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('00400000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')) as IParametersWithIV,
+    FSet1v9_0, FSet1v9_192, FSet1v9_256, FSet1v9_448);
+
+  DoChaChaTest1(12, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')), FChaCha12_set1v0_0,
+    FChaCha12_set1v0_192, FChaCha12_set1v0_256, FChaCha12_set1v0_448);
+  DoChaChaTest1(8, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')) as IParametersWithIV,
+    FChaCha8_set1v0_0, FChaCha8_set1v0_192, FChaCha8_set1v0_256,
+    FChaCha8_set1v0_448);
+
+end;
+
+procedure TTestChaCha.TestDoChaChaTest2;
+begin
+  DoChaChaTest2(TParametersWithIV.Create(TKeyParameter.Create
+    (THex.Decode
+    ('0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D'))
+    as IKeyParameter, THex.Decode('0D74DB42A91077DE')) as IParametersWithIV,
+    FSet6v0_0, FSet6v0_65472, FSet6v0_65536);
+  DoChaChaTest2(TParametersWithIV.Create(TKeyParameter.Create
+    (THex.Decode
+    ('0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12'))
+    as IKeyParameter, THex.Decode('167DE44BB21980E7')) as IParametersWithIV,
+    FSet6v1_0, FSet6v1_65472, FSet6v1_65536);
+end;
+
+procedure TTestChaCha.TestReInitBug;
+var
+  key: IKeyParameter;
+  parameters: IParametersWithIV;
+  chacha: IChaChaEngine;
+begin
+  key := TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'));
+  parameters := TParametersWithIV.Create(key, THex.Decode('0000000000000000'));
+
+  chacha := TChaChaEngine.Create();
+
+  chacha.Init(true, parameters);
+  try
+    chacha.Init(true, key);
+    Fail('ChaCha should throw exception if no IV in Init');
+
+  except
+    on e: EArgumentCryptoLibException do
+    begin
+      // expected
+    end;
+
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestChaCha);
+{$ELSE}
+  RegisterTest(TTestChaCha.Suite);
+{$ENDIF FPC}
+
+end.

+ 0 - 1
CryptoLib.Tests/src/Crypto/HMacTests.pas

@@ -35,7 +35,6 @@ uses
   ClpIKeyParameter,
   ClpIKeyParameter,
   ClpIMac,
   ClpIMac,
   ClpICipherKeyGenerator,
   ClpICipherKeyGenerator,
-  ClpDigestUtilities,
   ClpMacUtilities,
   ClpMacUtilities,
   ClpGeneratorUtilities,
   ClpGeneratorUtilities,
   ClpPkcsObjectIdentifiers,
   ClpPkcsObjectIdentifiers,

+ 0 - 277
CryptoLib.Tests/src/Crypto/IESCipherTests.pas

@@ -1,277 +0,0 @@
-{ *********************************************************************************** }
-{ *                              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 IESCipherTests;
-
-interface
-
-{$IFDEF FPC}
-{$MODE DELPHI}
-{$ENDIF FPC}
-{$HINTS OFF}
-
-uses
-  SysUtils,
-{$IFDEF FPC}
-  fpcunit,
-  testregistry,
-{$ELSE}
-  TestFramework,
-{$ENDIF FPC}
-  ClpIDigest,
-  ClpIMac,
-  ClpAesEngine,
-  ClpIAesEngine,
-  ClpIAsymmetricCipherKeyPairGenerator,
-  ClpGeneratorUtilities,
-  ClpIESWithCipherParameters,
-  ClpIIESWithCipherParameters,
-  // ClpKeyParameter,
-  // ClpIKeyParameter,
-  // ClpParametersWithIV,
-  // ClpIParametersWithIV,
-  ClpIBufferedBlockCipher,
-  // ClpParameterUtilities,
-  // ClpCipherUtilities,
-  ClpCbcBlockCipher,
-  ClpICbcBlockCipher,
-  ClpPaddedBufferedBlockCipher,
-  ClpIPaddedBufferedBlockCipher,
-  ClpECDHBasicAgreement,
-  ClpIECDHBasicAgreement,
-  ClpIESEngine,
-  ClpIIESEngine,
-  ClpPkcs7Padding,
-  ClpIPkcs7Padding,
-  // ClpZeroBytePadding,
-  // ClpIZeroBytePadding,
-  ClpKdf2BytesGenerator,
-  ClpIKdf2BytesGenerator,
-  ClpIX9ECParameters,
-  ClpSecNamedCurves,
-  ClpIECDomainParameters,
-  ClpECDomainParameters,
-  ClpECKeyGenerationParameters,
-  ClpSecureRandom,
-  ClpISecureRandom,
-  ClpIAsymmetricCipherKeyPair,
-  ClpIECPublicKeyParameters,
-  ClpIECPrivateKeyParameters,
-  ClpIIESCipher,
-  ClpIESCipher,
-  ClpHex,
-  ClpDigestUtilities,
-  ClpMacUtilities,
-  ClpArrayUtils;
-
-type
-
-  TCryptoLibTestCase = class abstract(TTestCase)
-
-  end;
-
-type
-
-  TTestIESCipher = class(TCryptoLibTestCase)
-  private
-
-    function GetECIESAES256CBCEngine: IIESEngine;
-    function GetECKeyPair: IAsymmetricCipherKeyPair;
-    function GetIESCipherParameters: IIESWithCipherParameters;
-
-    procedure doIESCipher_Encryption_Decryption_TestWithIV
-      (const KeyPair: IAsymmetricCipherKeyPair;
-      const param: IIESWithCipherParameters; const Random: ISecureRandom;
-      const PlainText: String);
-
-  protected
-    procedure SetUp; override;
-    procedure TearDown; override;
-  published
-
-    procedure TestIESCipher_Random_Values_Encryption_Decryption_AES256_CBC_PKCS7PADDING;
-
-  end;
-
-implementation
-
-{ TTestIESCipher }
-
-procedure TTestIESCipher.doIESCipher_Encryption_Decryption_TestWithIV
-  (const KeyPair: IAsymmetricCipherKeyPair;
-  const param: IIESWithCipherParameters; const Random: ISecureRandom;
-  const PlainText: String);
-var
-  PlainTextBytes, CipherTextBytes, DecryptionResultBytes: TBytes;
-  CipherEncrypt, CipherDecrypt: IIESCipher;
-begin
-  PlainTextBytes := TEncoding.UTF8.GetBytes(PlainText);
-  // Encryption
-  CipherEncrypt := TIESCipher.Create(GetECIESAES256CBCEngine);
-  CipherEncrypt.Init(True, KeyPair.Public as IECPublicKeyParameters,
-    param, Random);
-  CipherTextBytes := CipherEncrypt.DoFinal(PlainTextBytes);
-
-  // Decryption
-  CipherDecrypt := TIESCipher.Create(GetECIESAES256CBCEngine);
-  CipherDecrypt.Init(False, KeyPair.Private as IECPrivateKeyParameters,
-    param, Random);
-  DecryptionResultBytes := CipherDecrypt.DoFinal(CipherTextBytes);
-
-  if (not TArrayUtils.AreEqual(PlainTextBytes, DecryptionResultBytes)) then
-  begin
-    Fail(Format('Decryption Failed - Expected %s but got %s',
-      [THex.Encode(PlainTextBytes), THex.Encode(DecryptionResultBytes)]));
-  end;
-end;
-
-function TTestIESCipher.GetECIESAES256CBCEngine: IIESEngine;
-var
-  Cipher: IBufferedBlockCipher;
-  AesEngine: IAesEngine;
-  blockCipher: ICbcBlockCipher;
-  ECDHBasicAgreementInstance: IECDHBasicAgreement;
-  KDFInstance: IKdf2BytesGenerator;
-  DigestMACInstance: IMac;
-
-begin
-  // // Set up IES Cipher Engine
-
-  ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
-
-  KDFInstance := TKdf2BytesGenerator.Create
-    (TDigestUtilities.GetDigest('SHA-256'));
-
-  DigestMACInstance := TMacUtilities.GetMac('HMAC-SHA-256');
-
-  // Method 1: Set Up Block Cipher
-  // Cipher := TCipherUtilities.GetCipher('AES/CBC/PKCS7PADDING') as IBufferedBlockCipher;
-
-  // Method 2: Set Up Block Cipher
-  AesEngine := TAesEngine.Create(); // AES Engine
-
-  blockCipher := TCbcBlockCipher.Create(AesEngine); // CBC
-
-  Cipher := TPaddedBufferedBlockCipher.Create(blockCipher,
-    TPkcs7Padding.Create() as IPkcs7Padding); // Pkcs7Padding
-
-  // Cipher := TPaddedBufferedBlockCipher.Create(blockCipher,
-  // TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
-
-  result := TIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
-    DigestMACInstance, Cipher);
-end;
-
-function TTestIESCipher.GetECKeyPair: IAsymmetricCipherKeyPair;
-var
-  CurveName: string;
-  KeyPairGeneratorInstance: IAsymmetricCipherKeyPairGenerator;
-  RandomInstance: ISecureRandom;
-  Lcurve: IX9ECParameters;
-  ecSpec: IECDomainParameters;
-begin
-  // Set Up EC Key Pair
-
-  CurveName := 'secp256k1';
-  Lcurve := TSecNamedCurves.GetByName(CurveName);
-  KeyPairGeneratorInstance := TGeneratorUtilities.GetKeyPairGenerator('ECDSA');
-  ecSpec := TECDomainParameters.Create(Lcurve.Curve, Lcurve.G, Lcurve.N,
-    Lcurve.H, Lcurve.GetSeed);
-  RandomInstance := TSecureRandom.Create();
-  KeyPairGeneratorInstance.Init(TECKeyGenerationParameters.Create(ecSpec,
-    RandomInstance));
-  result := KeyPairGeneratorInstance.GenerateKeyPair();
-end;
-
-function TTestIESCipher.GetIESCipherParameters: IIESWithCipherParameters;
-var
-  Derivation, Encoding, IVBytes: TBytes;
-  MacKeySizeInBits, CipherKeySizeInBits: Int32;
-  UsePointCompression: Boolean;
-begin
-  // Set up  IES Cipher Parameters
-
-  // The derivation and encoding vectors are used when initialising the KDF and MAC.
-  // They're optional but if used then they need to be known by the other user so that
-  // they can decrypt the ciphertext and verify the MAC correctly. The security is based
-  // on the shared secret coming from the (static-ephemeral) ECDH key agreement.
-  Derivation := Nil;
-
-  Encoding := Nil;
-
-  System.SetLength(IVBytes, 16); // using Zero Initialized IV for ease
-
-  MacKeySizeInBits := 32 * 8; // Since we are using SHA2_256 for MAC
-
-  CipherKeySizeInBits := 32 * 8; // Since we are using AES256 for Cipher
-
-  // whether to use point compression when deriving the octets string
-  // from a point or not in the EphemeralKeyPairGenerator
-  UsePointCompression := False;
-
-  result := TIESWithCipherParameters.Create(Derivation, Encoding, IVBytes,
-    MacKeySizeInBits, CipherKeySizeInBits, UsePointCompression);
-end;
-
-procedure TTestIESCipher.SetUp;
-begin
-  inherited;
-end;
-
-procedure TTestIESCipher.TearDown;
-begin
-  inherited;
-
-end;
-
-procedure TTestIESCipher.
-  TestIESCipher_Random_Values_Encryption_Decryption_AES256_CBC_PKCS7PADDING;
-var
-  RandomInstance: ISecureRandom;
-  PlainText: string;
-  I: Int32;
-  RandomBytes: TBytes;
-begin
-  RandomInstance := TSecureRandom.Create();
-  I := 0;
-  while I <= 10 do
-  begin
-    System.SetLength(RandomBytes, Byte(RandomInstance.NextInt32));
-    RandomInstance.NextBytes(RandomBytes);
-    PlainText := THex.Encode(RandomBytes);
-
-    // Call IESCipher Encryption and Decryption Method
-
-    doIESCipher_Encryption_Decryption_TestWithIV(GetECKeyPair,
-      GetIESCipherParameters, RandomInstance, PlainText);
-
-    System.Inc(I);
-  end;
-
-end;
-
-initialization
-
-// Register any test cases with the test runner
-
-{$IFDEF FPC}
-  RegisterTest(TTestIESCipher);
-{$ELSE}
-  RegisterTest(TTestIESCipher.Suite);
-{$ENDIF FPC}
-
-end.

+ 115 - 0
CryptoLib.Tests/src/Crypto/RijndaelTestVectors.pas

@@ -0,0 +1,115 @@
+{ *********************************************************************************** }
+{ *                              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 RijndaelTestVectors;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  ClpCryptoLibTypes;
+
+type
+
+  TRijndaelTestVectors = class sealed(TObject)
+
+  public
+    class var
+
+      FBlockCipherVectorBlockSizes, FBlockCipherVectorKeys,
+      FBlockCipherVectorInputs, FBlockCipherVectorOutputs,
+      FBlockCipherMonteCarloBlockSizes, FBlockCipherMonteCarloIterations,
+      FBlockCipherMonteCarloKeys, FBlockCipherMonteCarloInputs,
+      FBlockCipherMonteCarloOutputs: TCryptoLibStringArray;
+
+    class constructor RijndaelTestVectors();
+
+  end;
+
+implementation
+
+{ TAESTestVectors }
+
+class constructor TRijndaelTestVectors.RijndaelTestVectors;
+begin
+
+  // Test vectors from the NIST standard tests and Brian Gladman's
+  // vector set
+  // http://fp.gladman.plus.com/cryptography_technology/rijndael
+
+  FBlockCipherVectorBlockSizes := TCryptoLibStringArray.Create('128', '128',
+    '160', '160', '192', '192', '224', '224', '256', '256');
+
+  FBlockCipherVectorKeys := TCryptoLibStringArray.Create
+
+    ('80000000000000000000000000000000', '00000000000000000000000000000080',
+    '2B7E151628AED2A6ABF7158809CF4F3C',
+    '2B7E151628AED2A6ABF7158809CF4F3C762E7160',
+    '2B7E151628AED2A6ABF7158809CF4F3C',
+    '2B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA5',
+    '2B7E151628AED2A6ABF7158809CF4F3C',
+    '2B7E151628AED2A6ABF7158809CF4F3C762E7160',
+    '2B7E151628AED2A6ABF7158809CF4F3C',
+    '2B7E151628AED2A6ABF7158809CF4F3C762E7160');
+
+  FBlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('00000000000000000000000000000000', '00000000000000000000000000000000',
+    '3243F6A8885A308D313198A2E03707344A409382',
+    '3243F6A8885A308D313198A2E03707344A409382',
+    '3243F6A8885A308D313198A2E03707344A4093822299F31D',
+    '3243F6A8885A308D313198A2E03707344A4093822299F31D',
+    '3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA9',
+    '3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA9',
+    '3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8',
+    '3243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C8');
+
+  FBlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('0EDD33D3C621E546455BD8BA1418BEC8', '172AEAB3D507678ECAF455C12587ADB7',
+    '16E73AEC921314C29DF905432BC8968AB64B1F51',
+    '0553EB691670DD8A5A5B5ADDF1AA7450F7A0E587',
+    'B24D275489E82BB8F7375E0D5FCDB1F481757C538B65148A',
+    '725AE43B5F3161DE806A7C93E0BCA93C967EC1AE1B71E1CF',
+    'B0A8F78F6B3C66213F792FFD2A61631F79331407A5E5C8D3793ACEB1',
+    '08B99944EDFCE33A2ACB131183AB0168446B2D15E958480010F545E3',
+    '7D15479076B69A46FFB3B3BEAE97AD8313F622F67FEDB487DE9F06B9ED9C8F19',
+    '514F93FB296B5AD16AA7DF8B577ABCBD484DECACCCC7FB1F18DC567309CEEFFD');
+
+  FBlockCipherMonteCarloBlockSizes := TCryptoLibStringArray.Create('128', '128',
+    '128', '128');
+
+  FBlockCipherMonteCarloIterations := TCryptoLibStringArray.Create('10000',
+    '10000', '10000', '10000');
+
+  FBlockCipherMonteCarloKeys := TCryptoLibStringArray.Create
+    ('00000000000000000000000000000000', '5F060D3716B345C253F6749ABAC10917',
+    'AAFE47EE82411A2BF3F6752AE8D7831138F041560631B114',
+    '28E79E2AFC5F7745FCCABE2F6257C2EF4C4EDFB37324814ED4137C288711A386');
+
+  FBlockCipherMonteCarloInputs := TCryptoLibStringArray.Create
+    ('00000000000000000000000000000000', '355F697E8B868B65B25A04E18D782AFA',
+    'F3F6752AE8D7831138F041560631B114', 'C737317FE0846F132B23C8C2A672CE22');
+
+  FBlockCipherMonteCarloOutputs := TCryptoLibStringArray.Create
+    ('C34C052CC0DA8D73451AFE5F03BE297F', 'ACC863637868E3E068D2FD6E3508454A',
+    '77BA00ED5412DFF27C8ED91F3C376172', 'E58B82BFBA53C0040DC610C642121168');
+
+end;
+
+end.

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

@@ -0,0 +1,368 @@
+{ *********************************************************************************** }
+{ *                              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,
+  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.

+ 376 - 0
CryptoLib.Tests/src/Crypto/Salsa20Tests.pas

@@ -0,0 +1,376 @@
+{ *********************************************************************************** }
+{ *                              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 Salsa20Tests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpSalsa20Engine,
+  ClpISalsa20Engine,
+  ClpICipherParameters,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpEncoders,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  TTestSalsa20 = class(TCryptoLibTestCase)
+  private
+  var
+    FZeroes: TCryptoLibByteArray;
+    FSet1v0_0, FSet1v0_192, FSet1v0_256, FSet1v0_448, FSet1v9_0, FSet1v9_192,
+      FSet1v9_256, FSet1v9_448, FSet6v0_0, FSet6v0_65472, FSet6v0_65536,
+      FSet6v1_0, FSet6v1_65472, FSet6v1_65536, FSalsa12_set1v0_0,
+      FSalsa12_set1v0_192, FSalsa12_set1v0_256, FSalsa12_set1v0_448,
+      FSalsa8_set1v0_0, FSalsa8_set1v0_192, FSalsa8_set1v0_256,
+      FSalsa8_set1v0_448: String;
+
+    procedure Mismatch(const name, expected: String;
+      found: TCryptoLibByteArray);
+    procedure DoSalsa20Test1(rounds: Int32; const parameters: ICipherParameters;
+      const v0, v192, v256, v448: String);
+
+    procedure DoSalsa20Test2(const parameters: ICipherParameters;
+      const v0, v65472, v65536: String);
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestSalsa20Test1;
+    procedure TestSalsa20Test2;
+    procedure TestReInitBug;
+
+  end;
+
+implementation
+
+{ TTestSalsa20 }
+
+procedure TTestSalsa20.SetUp;
+begin
+  inherited;
+  FZeroes := THex.Decode('00000000000000000000000000000000' +
+    '00000000000000000000000000000000' + '00000000000000000000000000000000' +
+    '00000000000000000000000000000000');
+
+  FSet1v0_0 := '4DFA5E481DA23EA09A31022050859936' +
+    'DA52FCEE218005164F267CB65F5CFD7F' + '2B4F97E0FF16924A52DF269515110A07' +
+    'F9E460BC65EF95DA58F740B7D1DBB0AA';
+
+  FSet1v0_192 := 'DA9C1581F429E0A00F7D67E23B730676' +
+    '783B262E8EB43A25F55FB90B3E753AEF' + '8C6713EC66C51881111593CCB3E8CB8F' +
+    '8DE124080501EEEB389C4BCB6977CF95';
+
+  FSet1v0_256 := '7D5789631EB4554400E1E025935DFA7B' +
+    '3E9039D61BDC58A8697D36815BF1985C' + 'EFDF7AE112E5BB81E37ECF0616CE7147' +
+    'FC08A93A367E08631F23C03B00A8DA2F';
+
+  FSet1v0_448 := 'B375703739DACED4DD4059FD71C3C47F' +
+    'C2F9939670FAD4A46066ADCC6A564578' + '3308B90FFB72BE04A6B147CBE38CC0C3' +
+    'B9267C296A92A7C69873F9F263BE9703';
+
+  FSet1v9_0 := '0471076057830FB99202291177FBFE5D' +
+    '38C888944DF8917CAB82788B91B53D1C' + 'FB06D07A304B18BB763F888A61BB6B75' +
+    '5CD58BEC9C4CFB7569CB91862E79C459';
+
+  FSet1v9_192 := 'D1D7E97556426E6CFC21312AE3811425' +
+    '9E5A6FB10DACBD88E4354B0472556935' + '2B6DA5ACAFACD5E266F9575C2ED8E6F2' +
+    'EFE4B4D36114C3A623DD49F4794F865B';
+
+  FSet1v9_256 := 'AF06FAA82C73291231E1BD916A773DE1' +
+    '52FD2126C40A10C3A6EB40F22834B8CC' + '68BD5C6DBD7FC1EC8F34165C517C0B63' +
+    '9DB0C60506D3606906B8463AA0D0EC2F';
+
+  FSet1v9_448 := 'AB3216F1216379EFD5EC589510B8FD35' +
+    '014D0AA0B613040BAE63ECAB90A9AF79' + '661F8DA2F853A5204B0F8E72E9D9EB4D' +
+    'BA5A4690E73A4D25F61EE7295215140C';
+
+  FSet6v0_0 := 'F5FAD53F79F9DF58C4AEA0D0ED9A9601' +
+    'F278112CA7180D565B420A48019670EA' + 'F24CE493A86263F677B46ACE1924773D' +
+    '2BB25571E1AA8593758FC382B1280B71';
+
+  FSet6v0_65472 := 'B70C50139C63332EF6E77AC54338A407' +
+    '9B82BEC9F9A403DFEA821B83F7860791' + '650EF1B2489D0590B1DE772EEDA4E3BC' +
+    'D60FA7CE9CD623D9D2FD5758B8653E70';
+
+  FSet6v0_65536 := '81582C65D7562B80AEC2F1A673A9D01C' +
+    '9F892A23D4919F6AB47B9154E08E699B' + '4117D7C666477B60F8391481682F5D95' +
+    'D96623DBC489D88DAA6956B9F0646B6E';
+
+  FSet6v1_0 := '3944F6DC9F85B128083879FDF190F7DE' +
+    'E4053A07BC09896D51D0690BD4DA4AC1' + '062F1E47D3D0716F80A9B4D85E6D6085' +
+    'EE06947601C85F1A27A2F76E45A6AA87';
+
+  FSet6v1_65472 := '36E03B4B54B0B2E04D069E690082C8C5' +
+    '92DF56E633F5D8C7682A02A65ECD1371' + '8CA4352AACCB0DA20ED6BBBA62E177F2' +
+    '10E3560E63BB822C4158CAA806A88C82';
+
+  FSet6v1_65536 := '1B779E7A917C8C26039FFB23CF0EF8E0' +
+    '8A1A13B43ACDD9402CF5DF38501098DF' + 'C945A6CC69A6A17367BC03431A86B3ED' +
+    '04B0245B56379BF997E25800AD837D7D';
+
+  // Salsa20/12
+
+  FSalsa12_set1v0_0 := 'FC207DBFC76C5E1774961E7A5AAD0906' +
+    '9B2225AC1CE0FE7A0CE77003E7E5BDF8' + 'B31AF821000813E6C56B8C1771D6EE70' +
+    '39B2FBD0A68E8AD70A3944B677937897';
+
+  FSalsa12_set1v0_192 := '4B62A4881FA1AF9560586510D5527ED4' +
+    '8A51ECAFA4DECEEBBDDC10E9918D44AB' + '26B10C0A31ED242F146C72940C6E9C37' +
+    '53F641DA84E9F68B4F9E76B6C48CA5AC';
+
+  FSalsa12_set1v0_256 := 'F52383D9DEFB20810325F7AEC9EADE34' +
+    'D9D883FEE37E05F74BF40875B2D0BE79' + 'ED8886E5BFF556CEA8D1D9E86B1F68A9' +
+    '64598C34F177F8163E271B8D2FEB5996';
+
+  FSalsa12_set1v0_448 := 'A52ED8C37014B10EC0AA8E05B5CEEE12' +
+    '3A1017557FB3B15C53E6C5EA8300BF74' + '264A73B5315DC821AD2CAB0F3BB2F152' +
+    'BDAEA3AEE97BA04B8E72A7B40DCC6BA4';
+
+  // Salsa20/8
+
+  FSalsa8_set1v0_0 := 'A9C9F888AB552A2D1BBFF9F36BEBEB33' +
+    '7A8B4B107C75B63BAE26CB9A235BBA9D' + '784F38BEFC3ADF4CD3E266687EA7B9F0' +
+    '9BA650AE81EAC6063AE31FF12218DDC5';
+
+  FSalsa8_set1v0_192 := 'BB5B6BB2CC8B8A0222DCCC1753ED4AEB' +
+    '23377ACCBD5D4C0B69A8A03BB115EF71' + '871BC10559080ACA7C68F0DEF32A80DD' +
+    'BAF497259BB76A3853A7183B51CC4B9F';
+
+  FSalsa8_set1v0_256 := '4436CDC0BE39559F5E5A6B79FBDB2CAE' +
+    '4782910F27FFC2391E05CFC78D601AD8' + 'CD7D87B074169361D997D1BED9729C0D' +
+    'EB23418E0646B7997C06AA84E7640CE3';
+
+  FSalsa8_set1v0_448 := 'BEE85903BEA506B05FC04795836FAAAC' +
+    '7F93F785D473EB762576D96B4A65FFE4' + '63B34AAE696777FC6351B67C3753B89B' +
+    'A6B197BD655D1D9CA86E067F4D770220';
+
+end;
+
+procedure TTestSalsa20.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestSalsa20.Mismatch(const name, expected: String;
+  found: TCryptoLibByteArray);
+begin
+  Fail(Format('Mismatch on %s, Expected %s, Found %s.',
+    [name, expected, THex.Encode(found)]));
+end;
+
+procedure TTestSalsa20.DoSalsa20Test1(rounds: Int32;
+  const parameters: ICipherParameters; const v0, v192, v256, v448: String);
+var
+  salsa: ISalsa20Engine;
+  buf: TCryptoLibByteArray;
+  i: Int32;
+begin
+  salsa := TSalsa20Engine.Create(rounds);
+  salsa.Init(true, parameters);
+  System.SetLength(buf, 64);
+  i := 0;
+  while i <> 7 do
+  begin
+    salsa.ProcessBytes(FZeroes, 0, 64, buf, 0);
+    case i of
+      0:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v0))) then
+          begin
+            Mismatch(Format('v0/%d', [rounds]), v0, buf);
+          end;
+        end;
+      3:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v192))) then
+          begin
+            Mismatch(Format('v192/%d', [rounds]), v192, buf);
+          end;
+        end;
+      4:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v256))) then
+          begin
+            Mismatch(Format('v256/%d', [rounds]), v256, buf);
+          end;
+        end
+    else
+      begin
+        // ignore
+      end;
+    end;
+    System.Inc(i);
+  end;
+
+  i := 0;
+  while i <> 64 do
+  begin
+    buf[i] := salsa.ReturnByte(FZeroes[i]);
+    System.Inc(i);
+  end;
+
+  if not(TArrayUtils.AreEqual(buf, THex.Decode(v448))) then
+  begin
+    Mismatch(Format('v448/%d', [rounds]), v448, buf);
+  end;
+end;
+
+procedure TTestSalsa20.DoSalsa20Test2(const parameters: ICipherParameters;
+  const v0, v65472, v65536: String);
+var
+  salsa: ISalsa20Engine;
+  buf: TCryptoLibByteArray;
+  i: Int32;
+begin
+  salsa := TSalsa20Engine.Create();
+  salsa.Init(true, parameters);
+  System.SetLength(buf, 64);
+  i := 0;
+  while i <> 1025 do
+  begin
+    salsa.ProcessBytes(FZeroes, 0, 64, buf, 0);
+    case i of
+      0:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v0))) then
+          begin
+            Mismatch('v0', v0, buf);
+          end;
+        end;
+      1023:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v65472))) then
+          begin
+            Mismatch('v65472', v65472, buf);
+          end;
+        end;
+      1024:
+        begin
+          if not(TArrayUtils.AreEqual(buf, THex.Decode(v65536))) then
+          begin
+            Mismatch('v65536', v65536, buf);
+          end;
+        end
+    else
+      begin
+        // ignore
+      end;
+    end;
+    System.Inc(i);
+  end;
+
+end;
+
+procedure TTestSalsa20.TestSalsa20Test1;
+begin
+  DoSalsa20Test1(20, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')) as IParametersWithIV,
+    FSet1v0_0, FSet1v0_192, FSet1v0_256, FSet1v0_448);
+  DoSalsa20Test1(20, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('00400000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')) as IParametersWithIV,
+    FSet1v9_0, FSet1v9_192, FSet1v9_256, FSet1v9_448);
+
+  DoSalsa20Test1(12, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')), FSalsa12_set1v0_0,
+    FSalsa12_set1v0_192, FSalsa12_set1v0_256, FSalsa12_set1v0_448);
+  DoSalsa20Test1(8, TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'))
+    as IKeyParameter, THex.Decode('0000000000000000')) as IParametersWithIV,
+    FSalsa8_set1v0_0, FSalsa8_set1v0_192, FSalsa8_set1v0_256,
+    FSalsa8_set1v0_448);
+
+end;
+
+procedure TTestSalsa20.TestSalsa20Test2;
+begin
+  DoSalsa20Test2(TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode
+    ('0053A6F94C9FF24598EB3E91E4378ADD3083D6297CCF2275C81B6EC11467BA0D'))
+    as IKeyParameter, THex.Decode('0D74DB42A91077DE')) as IParametersWithIV,
+    FSet6v0_0, FSet6v0_65472, FSet6v0_65536);
+  DoSalsa20Test2(TParametersWithIV.Create
+    (TKeyParameter.Create(THex.Decode
+    ('0558ABFE51A4F74A9DF04396E93C8FE23588DB2E81D4277ACD2073C6196CBF12'))
+    as IKeyParameter, THex.Decode('167DE44BB21980E7')) as IParametersWithIV,
+    FSet6v1_0, FSet6v1_65472, FSet6v1_65536);
+end;
+
+procedure TTestSalsa20.TestReInitBug;
+var
+  key: IKeyParameter;
+  parameters: IParametersWithIV;
+  salsa: ISalsa20Engine;
+begin
+  key := TKeyParameter.Create(THex.Decode('80000000000000000000000000000000'));
+  parameters := TParametersWithIV.Create(key, THex.Decode('0000000000000000'));
+
+  salsa := TSalsa20Engine.Create();
+
+  salsa.Init(true, parameters);
+  try
+    salsa.Init(true, key);
+    Fail('Salsa20 should throw exception if no IV in Init');
+
+  except
+    on e: EArgumentCryptoLibException do
+    begin
+      // expected
+    end;
+
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestSalsa20);
+{$ELSE}
+  RegisterTest(TTestSalsa20.Suite);
+{$ENDIF FPC}
+
+end.

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

@@ -0,0 +1,323 @@
+{ *********************************************************************************** }
+{ *                              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,
+
+      FSpeck32LegacyBlockCipherVectorKeys,
+      FSpeck32LegacyBlockCipherVectorInputs,
+      FSpeck32LegacyBlockCipherVectorOutputs,
+
+      FSpeck48LegacyBlockCipherVectorKeys,
+      FSpeck48LegacyBlockCipherVectorInputs,
+      FSpeck48LegacyBlockCipherVectorOutputs,
+
+      FSpeck64LegacyBlockCipherVectorKeys,
+      FSpeck64LegacyBlockCipherVectorInputs,
+      FSpeck64LegacyBlockCipherVectorOutputs,
+
+      FSpeck96LegacyBlockCipherVectorKeys,
+      FSpeck96LegacyBlockCipherVectorInputs,
+      FSpeck96LegacyBlockCipherVectorOutputs,
+
+      FSpeck128LegacyBlockCipherVectorKeys,
+      FSpeck128LegacyBlockCipherVectorInputs,
+      FSpeck128LegacyBlockCipherVectorOutputs,
+
+      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');
+
+  // speck legacy test vectors
+
+  FSpeck32LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('1918111009080100');
+
+  FSpeck32LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('6574694C');
+
+  FSpeck32LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('A86842F2');
+
+  FSpeck48LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('1211100A0908020100', '1A19181211100A0908020100');
+
+  FSpeck48LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('20796C6C6172', '6D2073696874');
+
+  FSpeck48LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('C049A5385ADC', '735E10B6445D');
+
+  FSpeck64LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('131211100B0A090803020100', '1B1A1918131211100B0A090803020100');
+
+  FSpeck64LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('74614620736E6165', '3B7265747475432D');
+
+  FSpeck64LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('9F7952EC4175946C', '8C6FA548454E028B');
+
+  FSpeck96LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('0D0C0B0A0908050403020100', '1514131211100D0C0B0A0908050403020100');
+
+  FSpeck96LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('65776F68202C656761737520', '656D6974206E69202C726576');
+
+  FSpeck96LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('9E4D09AB717862BDDE8F79AA', '2BF31072228A7AE440252EE6');
+
+  FSpeck128LegacyBlockCipherVectorKeys := TCryptoLibStringArray.Create
+    ('0F0E0D0C0B0A09080706050403020100',
+    '17161514131211100F0E0D0C0B0A09080706050403020100',
+    '1F1E1D1C1B1A191817161514131211100F0E0D0C0B0A09080706050403020100');
+
+  FSpeck128LegacyBlockCipherVectorInputs := TCryptoLibStringArray.Create
+    ('6C617669757165207469206564616D20', '726148206665696843206F7420746E65',
+    '65736F6874206E49202E72656E6F6F70');
+
+  FSpeck128LegacyBlockCipherVectorOutputs := TCryptoLibStringArray.Create
+    ('A65D9851797832657860FEDF5C570D18', '1BE4CF3A13135566F9BC185DE03C1886',
+    '4109010405C0F53E4EEEB48D9C188F43');
+
+  // 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.

+ 243 - 0
CryptoLib.Tests/src/Crypto/StreamCipherResetTests.pas

@@ -0,0 +1,243 @@
+{ *********************************************************************************** }
+{ *                              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 StreamCipherResetTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpSalsa20Engine,
+  ClpISalsa20Engine,
+  ClpXSalsa20Engine,
+  ClpIXSalsa20Engine,
+  ClpChaChaEngine,
+  ClpIChaChaEngine,
+  ClpIStreamCipher,
+  ClpICipherParameters,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpEncoders,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+{$SCOPEDENUMS ON}
+  TCipherEngine = (Salsa20Engine, XSalsa20Engine, ChaChaEngine);
+{$SCOPEDENUMS OFF}
+
+type
+
+  /// <summary>
+  /// Test whether block ciphers implement reset contract on init,
+  /// encrypt/decrypt and reset.
+  /// </summary>
+  TTestStreamCipherReset = class(TCryptoLibTestCase)
+  private
+  var
+    FSecureRandom: ISecureRandom;
+
+    procedure DoCheckReset(const cipher: IStreamCipher;
+      const cipherParams: ICipherParameters; encrypt: Boolean;
+      const pretext, posttext: TCryptoLibByteArray);
+
+    function DoMake(CipherEngine: TCipherEngine): IStreamCipher;
+
+    function DoRandom(size: Int32): TCryptoLibByteArray;
+    procedure DoTestReset(CipherEngine: TCipherEngine;
+      KeyLen, IVLen: Int32); overload;
+    procedure DoTestReset(const cipher1, cipher2: IStreamCipher;
+      const cipherParams: ICipherParameters); overload;
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestReset;
+
+  end;
+
+implementation
+
+{ TTestStreamCipherReset }
+
+procedure TTestStreamCipherReset.DoCheckReset(const cipher: IStreamCipher;
+  const cipherParams: ICipherParameters; encrypt: Boolean;
+  const pretext, posttext: TCryptoLibByteArray);
+var
+  output: TCryptoLibByteArray;
+begin
+  // Do initial run
+  System.SetLength(output, System.Length(posttext));
+  cipher.ProcessBytes(pretext, 0, System.Length(pretext), output, 0);
+
+  // Check encrypt resets cipher
+  cipher.Init(encrypt, cipherParams);
+  try
+    cipher.ProcessBytes(pretext, 0, System.Length(pretext), output, 0);
+  except
+    on e: Exception do
+    begin
+      Fail(Format('%s init did not reset: %s', [cipher.AlgorithmName,
+        e.Message]));
+    end;
+
+  end;
+
+  if not(TArrayUtils.AreEqual(output, posttext)) then
+  begin
+    Fail(Format('%s init did not reset. Expected %s But Got %s',
+      [cipher.AlgorithmName, THex.Encode(posttext), THex.Encode(output)]));
+  end;
+
+  // Check reset resets data
+  cipher.Reset();
+
+  try
+    cipher.ProcessBytes(pretext, 0, System.Length(pretext), output, 0);
+  except
+    on e: Exception do
+    begin
+      Fail(Format('%s reset did not reset: ', [cipher.AlgorithmName,
+        e.Message]));
+    end;
+
+  end;
+
+  if not(TArrayUtils.AreEqual(output, posttext)) then
+  begin
+    Fail(Format('%s init did not reset.', [cipher.AlgorithmName]));
+  end;
+
+  //
+  // try
+  // {
+  // cipher.ProcessBytes(pretext, 0, pretext.Length, output, 0);
+  // }
+  // catch (Exception e)
+  // {
+  // Fail(cipher.AlgorithmName + " reset did not reset: " + e.Message);
+  // }
+  // if (!Arrays.AreEqual(output, posttext))
+  // {
+  // Fail(cipher.AlgorithmName + " reset did not reset.");
+  // }
+end;
+
+function TTestStreamCipherReset.DoMake(CipherEngine: TCipherEngine)
+  : IStreamCipher;
+begin
+  case CipherEngine of
+    TCipherEngine.Salsa20Engine:
+      Result := TSalsa20Engine.Create() as ISalsa20Engine;
+    TCipherEngine.XSalsa20Engine:
+      Result := TXSalsa20Engine.Create() as IXSalsa20Engine;
+    TCipherEngine.ChaChaEngine:
+      Result := TChaChaEngine.Create() as IChaChaEngine
+  else
+    begin
+      raise Exception.Create('Unsupported Cipher Engine');
+    end;
+  end;
+end;
+
+function TTestStreamCipherReset.DoRandom(size: Int32): TCryptoLibByteArray;
+begin
+  Result := TSecureRandom.GetNextBytes(FSecureRandom, size);
+end;
+
+procedure TTestStreamCipherReset.DoTestReset(CipherEngine: TCipherEngine;
+  KeyLen, IVLen: Int32);
+begin
+  DoTestReset(DoMake(CipherEngine), DoMake(CipherEngine),
+    TParametersWithIV.Create(TKeyParameter.Create(DoRandom(KeyLen))
+    as IKeyParameter, DoRandom(IVLen)) as IParametersWithIV);
+end;
+
+procedure TTestStreamCipherReset.DoTestReset(const cipher1,
+  cipher2: IStreamCipher; const cipherParams: ICipherParameters);
+var
+  plaintext, ciphertext: TCryptoLibByteArray;
+begin
+  cipher1.Init(true, cipherParams);
+  System.SetLength(plaintext, 1023);
+  System.SetLength(ciphertext, System.Length(plaintext));
+
+  // Establish baseline answer
+  cipher1.ProcessBytes(plaintext, 0, System.Length(plaintext), ciphertext, 0);
+
+  // Test encryption resets
+  DoCheckReset(cipher1, cipherParams, true, plaintext, ciphertext);
+
+  // Test decryption resets with fresh instance
+  cipher2.Init(false, cipherParams);
+  DoCheckReset(cipher2, cipherParams, false, ciphertext, plaintext);
+end;
+
+procedure TTestStreamCipherReset.SetUp;
+begin
+  inherited;
+  FSecureRandom := TSecureRandom.Create();
+end;
+
+procedure TTestStreamCipherReset.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestStreamCipherReset.TestReset;
+begin
+  DoTestReset(TCipherEngine.Salsa20Engine, 32, 8);
+  DoTestReset(TCipherEngine.Salsa20Engine, 16, 8);
+  DoTestReset(TCipherEngine.XSalsa20Engine, 32, 24);
+  DoTestReset(TCipherEngine.ChaChaEngine, 32, 8);
+  DoTestReset(TCipherEngine.ChaChaEngine, 16, 8);
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestStreamCipherReset);
+{$ELSE}
+  RegisterTest(TTestStreamCipherReset.Suite);
+{$ENDIF FPC}
+
+end.

+ 162 - 0
CryptoLib.Tests/src/Crypto/XSalsa20Tests.pas

@@ -0,0 +1,162 @@
+{ *********************************************************************************** }
+{ *                              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 XSalsa20Tests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpXSalsa20Engine,
+  ClpIXSalsa20Engine,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpEncoders,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  TTestXSalsa20 = class(TCryptoLibTestCase)
+
+  private
+  var
+    FTestVectors: TCryptoLibGenericArray<TCryptoLibStringArray>;
+
+    procedure DoXSalsa20Test(number: Int32;
+      const ATestVectorParams: TCryptoLibStringArray);
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestXSalsa20Test();
+
+  end;
+
+implementation
+
+{ TTestXSalsa20 }
+
+procedure TTestXSalsa20.DoXSalsa20Test(number: Int32;
+  const ATestVectorParams: TCryptoLibStringArray);
+var
+  engine: IXSalsa20Engine;
+var
+  LPlainText, LCipherText, LOutput, LKey, LIV: TCryptoLibByteArray;
+begin
+  LPlainText := THex.Decode(ATestVectorParams[2]);
+  System.SetLength(LOutput, System.Length(LPlainText));
+  LKey := THex.Decode(ATestVectorParams[0]);
+  LIV := THex.Decode(ATestVectorParams[1]);
+  LCipherText := THex.Decode(ATestVectorParams[3]);
+
+  engine := TXSalsa20Engine.Create();
+  engine.Init(false, TParametersWithIV.Create(TKeyParameter.Create(LKey)
+    as IKeyParameter, LIV) as IParametersWithIV);
+
+  engine.ProcessBytes(LPlainText, 0, System.Length(LPlainText), LOutput, 0);
+
+  if not(TArrayUtils.AreEqual(LCipherText, LOutput)) then
+  begin
+    Fail(Format('Mismatch on %d, Expected %s but found %s',
+      [number, THex.Encode(LCipherText), THex.Encode(LOutput)]));
+  end;
+
+end;
+
+procedure TTestXSalsa20.SetUp;
+begin
+  inherited;
+  // Test cases generated by naclcrypto-20090308, as used by cryptopp
+  FTestVectors := TCryptoLibGenericArray<TCryptoLibStringArray>.Create
+    (TCryptoLibStringArray.Create
+    ('A6A7251C1E72916D11C2CB214D3C252539121D8E234E652D651FA4C8CFF88030',
+    '9E645A74E9E0A60D8243ACD9177AB51A1BEB8D5A2F5D700C',
+    '093C5E5585579625337BD3AB619D615760D8C5B224A85B1D0EFE0EB8A7EE163ABB0376529FCC09BAB506C6'
+    + '18E13CE777D82C3AE9D1A6F972D4160287CBFE60BF2130FC0A6FF6049D0A5C8A82F429231F008082E845D7E189D37F9ED2B464E6B9'
+    + '19E6523A8C1210BD52A02A4C3FE406D3085F5068D1909EEECA6369ABC981A42E87FE665583F0AB85AE71F6F84F528E6B397AF86F6917D9754B7320DBDC2FEA81496F2732F532AC78C4E9C6CFB18F8E9BDF74622EB126141416776971A84F94D156BEAF67AECBF2AD412E76E66E'
+    + '8FAD7633F5B6D7F3D64B5C6C69CE29003C6024465AE3B89BE78E915D88B4B5621D',
+    'B2AF688E7D8FC4B508C05CC39DD583D6714322C64D7F3E63147AEDE2D9534934B04FF6F337B031815CD094BDBC6D7A92077DCE709412286822EF0737EE47F6B7FF'
+    + 'A22F9D53F11DD2B0A3BB9FC01D9A88F9D53C26E9365C2C3C063BC4840BFC812E4B80463E69D179530B25C158F543191CFF993106511AA036043BBC75866AB7E34AFC57E2CCE4934A5FAAE6EABE4F2217'
+    + '70183DD060467827C27A354159A081275A291F69D946D6FE28ED0B9CE08206CF484925A51B9498DBDE178DDD3AE91A8581B91682D860F840782F6EEA49DBB9BD721'
+    + '501D2C67122DEA3B7283848C5F13E0C0DE876BD227A856E4DE593A3'),
+
+    TCryptoLibStringArray.Create
+    ('D5C7F6797B7E7E9C1D7FD2610B2ABF2BC5A7885FB3FF78092FB3ABE8986D35E2',
+    '744E17312B27969D826444640E9C4A378AE334F185369C95',
+    '7758298C628EB3A4B6963C5445EF66971222BE5D1A4AD839715D1188071739B77CC6E05D5410F963A64167629757',
+    '27B8CFE81416A76301FD1EEC6A4D99675069B2DA2776C360DB1BDFEA7C0AA613913E10F7A60FEC04D11E65F2D64E'),
+
+    TCryptoLibStringArray.Create
+    ('6799D76E5FFB5B4920BC2768BAFD3F8C16554E65EFCF9A16F4683A7A06927C11',
+    '61AB951921E54FF06D9B77F313A4E49DF7A057D5FD627989', '472766', '8FD7DF'),
+
+    TCryptoLibStringArray.Create
+    ('AD1A5C47688874E6663A0F3FA16FA7EFB7ECADC175C468E5432914BDB480FFC6',
+    'E489EED440F1AAE1FAC8FB7A9825635454F8F8F1F52E2FCC',
+    'AA6C1E53580F03A9ABB73BFDADEDFECADA4C6B0EBE020EF10DB745E54BA861CAF65F0E40DFC520203BB54D29E0A8F78F16B3F1AA525D6BFA33C54726E59988CFBEC78056',
+    '02FE84CE81E178E7AABDD3BA925A766C3C24756EEFAE33942AF75E8B464556B5997E616F3F2DFC7FCE91848AFD79912D9FB55201B5813A5A074D2C0D4292C1FD441807C5')
+    );
+end;
+
+procedure TTestXSalsa20.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestXSalsa20.TestXSalsa20Test;
+var
+  LIdx: Int32;
+begin
+  for LIdx := System.Low(FTestVectors) to System.High(FTestVectors) do
+  begin
+    DoXSalsa20Test(LIdx, FTestVectors[LIdx]);
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestXSalsa20);
+{$ELSE}
+  RegisterTest(TTestXSalsa20.Suite);
+{$ENDIF FPC}
+
+end.

+ 286 - 0
CryptoLib.Tests/src/Math/EC/Rfc7748/X25519Tests.pas

@@ -0,0 +1,286 @@
+{ *********************************************************************************** }
+{ *                              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 X25519Tests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpX25519,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpArrayUtils,
+  ClpEncoders,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  TTestX25519 = class(TCryptoLibTestCase)
+  private
+  var
+    FRandom: ISecureRandom;
+
+    procedure CheckECDHVector(const sA, sAPub, sB, sBPub, sK, text: String);
+    procedure CheckIterated(count: Int32);
+    procedure CheckValue(const n: TCryptoLibByteArray; const text, se: String);
+    procedure CheckX25519Vector(const sK, su, se, text: String);
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestConsistency();
+    procedure TestECDH();
+    procedure TestECDHVector1();
+    procedure TestX25519Iterated();
+    // disabled because it takes a lot of time
+    // procedure TestX25519IteratedFull();
+    procedure TestX25519Vector1();
+    procedure TestX25519Vector2();
+
+  end;
+
+implementation
+
+{ TTestX25519 }
+
+procedure TTestX25519.CheckECDHVector(const sA, sAPub, sB, sBPub, sK,
+  text: String);
+var
+  a, b, aPub, bPub, aK, bK: TCryptoLibByteArray;
+begin
+  a := THex.Decode(sA);
+  CheckEquals(TX25519.ScalarSize, System.Length(a));
+
+  b := THex.Decode(sB);
+  CheckEquals(TX25519.ScalarSize, System.Length(b));
+
+  System.SetLength(aPub, TX25519.PointSize);
+
+  TX25519.ScalarMultBase(a, 0, aPub, 0);
+  CheckValue(aPub, text, sAPub);
+
+  System.SetLength(bPub, TX25519.PointSize);
+  TX25519.ScalarMultBase(b, 0, bPub, 0);
+  CheckValue(bPub, text, sBPub);
+
+  System.SetLength(aK, TX25519.PointSize);
+
+  TX25519.ScalarMult(a, 0, bPub, 0, aK, 0);
+  CheckValue(aK, text, sK);
+
+  System.SetLength(bK, TX25519.PointSize);
+
+  TX25519.ScalarMult(b, 0, aPub, 0, bK, 0);
+  CheckValue(bK, text, sK);
+end;
+
+procedure TTestX25519.CheckIterated(count: Int32);
+var
+  k, u, r: TCryptoLibByteArray;
+  iterations: Int32;
+begin
+  CheckEquals(TX25519.PointSize, TX25519.ScalarSize);
+
+  System.SetLength(k, TX25519.PointSize);
+  k[0] := 9;
+  System.SetLength(u, TX25519.PointSize);
+  u[0] := 9;
+  System.SetLength(r, TX25519.PointSize);
+
+  iterations := 0;
+
+  while (iterations < count) do
+  begin
+
+    TX25519.ScalarMult(k, 0, u, 0, r, 0);
+
+    System.Move(k[0], u[0], TX25519.PointSize * System.SizeOf(Byte));
+    System.Move(r[0], k[0], TX25519.PointSize * System.SizeOf(Byte));
+
+    System.Inc(iterations);
+    case iterations of
+      1:
+        CheckValue(k, 'Iterated @1',
+          '422c8e7a6227d7bca1350b3e2bb7279f7897b87bb6854b783c60e80311ae3079');
+      1000:
+        CheckValue(k, 'Iterated @1000',
+          '684cf59ba83309552800ef566f2f4d3c1c3887c49360e3875f2eb94d99532c51');
+      1000000:
+        CheckValue(k, 'Iterated @1000000',
+          '7c3911e0ab2586fd864497297e575e6f3bc601c0883c30df5f4dd2d24f665424');
+    end;
+
+  end;
+end;
+
+procedure TTestX25519.CheckValue(const n: TCryptoLibByteArray;
+  const text, se: String);
+var
+  e: TCryptoLibByteArray;
+begin
+  e := THex.Decode(se);
+  CheckTrue(TArrayUtils.AreEqual(e, n), text);
+end;
+
+procedure TTestX25519.CheckX25519Vector(const sK, su, se, text: String);
+var
+  k, u, r: TCryptoLibByteArray;
+begin
+  k := THex.Decode(sK);
+  CheckEquals(TX25519.ScalarSize, System.Length(k));
+
+  u := THex.Decode(su);
+  CheckEquals(TX25519.PointSize, System.Length(u));
+
+  System.SetLength(r, TX25519.PointSize);
+  TX25519.ScalarMult(k, 0, u, 0, r, 0);
+  CheckValue(r, text, se);
+end;
+
+procedure TTestX25519.SetUp;
+begin
+  inherited;
+  FRandom := TSecureRandom.Create();
+  TX25519.Precompute();
+end;
+
+procedure TTestX25519.TearDown;
+begin
+  inherited;
+end;
+
+procedure TTestX25519.TestConsistency;
+var
+  u, k, rF, rV: TCryptoLibByteArray;
+  i: Int32;
+begin
+  System.SetLength(u, TX25519.PointSize);
+  u[0] := 9;
+  System.SetLength(k, TX25519.ScalarSize);
+  System.SetLength(rF, TX25519.PointSize);
+  System.SetLength(rV, TX25519.PointSize);
+
+  for i := 1 to 100 do
+  begin
+    FRandom.NextBytes(k);
+    TX25519.ScalarMultBase(k, 0, rF, 0);
+    TX25519.ScalarMult(k, 0, u, 0, rV, 0);
+    CheckTrue(TArrayUtils.AreEqual(rF, rV), Format('Consistency #%d', [i]));
+  end;
+end;
+
+procedure TTestX25519.TestECDH;
+var
+  kA, Kb, qA, qB, sA, sB: TCryptoLibByteArray;
+  i: Int32;
+begin
+  System.SetLength(kA, TX25519.ScalarSize);
+  System.SetLength(Kb, TX25519.ScalarSize);
+  System.SetLength(qA, TX25519.PointSize);
+  System.SetLength(qB, TX25519.PointSize);
+  System.SetLength(sA, TX25519.PointSize);
+  System.SetLength(sB, TX25519.PointSize);
+
+  for i := 1 to 100 do
+  begin
+    // Each party generates an ephemeral private key, ...
+    FRandom.NextBytes(kA);
+    FRandom.NextBytes(Kb);
+
+    // ... publishes their public key, ...
+    TX25519.ScalarMultBase(kA, 0, qA, 0);
+    TX25519.ScalarMultBase(Kb, 0, qB, 0);
+
+    // ... computes the shared secret, ...
+    TX25519.ScalarMult(kA, 0, qB, 0, sA, 0);
+    TX25519.ScalarMult(Kb, 0, qA, 0, sB, 0);
+
+    // ... which is the same for both parties.
+    if (not TArrayUtils.AreEqual(sA, sB)) then
+    begin
+      Fail(Format(' %d', [i]));
+    end;
+  end;
+end;
+
+procedure TTestX25519.TestECDHVector1;
+begin
+  CheckECDHVector
+    ('77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a',
+    '8520f0098930a754748b7ddcb43ef75a0dbf3a0d26381af4eba4a98eaa9b4e6a',
+    '5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb',
+    'de9edb7d7b7dc1b4d35b61c2ece435373f8343c85b78674dadfc7e146f882b4f',
+    '4a5d9d5ba4ce2de1728e3bf480350f25e07e21c947d19e3376f09b3c1e161742',
+    'ECDH Vector #1');
+end;
+
+procedure TTestX25519.TestX25519Iterated;
+begin
+  CheckIterated(1000);
+end;
+
+// procedure TTestX25519.TestX25519IteratedFull;
+// begin
+// CheckIterated(1000000);
+// end;
+
+procedure TTestX25519.TestX25519Vector1;
+begin
+  CheckX25519Vector
+    ('a546e36bf0527c9d3b16154b82465edd62144c0ac1fc5a18506a2244ba449ac4',
+    'e6db6867583030db3594c1a424b15f7c726624ec26b3353b10a903a6d0ab1c4c',
+    'c3da55379de9c6908e94ea4df28d084f32eccf03491c71f754b4075577a28552',
+    'Vector #1');
+end;
+
+procedure TTestX25519.TestX25519Vector2;
+begin
+  CheckX25519Vector
+    ('4b66e9d4d1b4673c5ad22691957d6af5c11b6421e0ea01d42ca4169e7918ba0d',
+    'e5210f12786811d3f4b7959d0538ae2c31dbe7106fc03c3efc4cd549c715a493',
+    '95cbde9476e8907d7aade45cb4b873f88b595a68799fa152e6f8f7647aac7957',
+    'Vector #2');
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+// RegisterTest(TTestX25519);
+{$ELSE}
+  RegisterTest(TTestX25519.Suite);
+{$ENDIF FPC}
+
+end.

+ 546 - 0
CryptoLib.Tests/src/Math/EC/Rfc8032/Ed25519Tests.pas

@@ -0,0 +1,546 @@
+{ *********************************************************************************** }
+{ *                              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 Ed25519Tests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpEd25519,
+  ClpIEd25519,
+  ClpIDigest,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpArrayUtils,
+  ClpEncoders,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  TTestEd25519 = class(TCryptoLibTestCase)
+
+  private
+
+  var
+    FRandom: ISecureRandom;
+    procedure CheckEd25519Vector(const sSK, sPK, sM, sSig, text: String);
+    procedure CheckEd25519ctxVector(const sSK, sPK, sM, sCTX, sSig,
+      text: String);
+    procedure CheckEd25519phVector(const sSK, sPK, sM, sCTX, sSig,
+      text: String);
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestEd25519Consistency();
+    procedure TestEd25519ctxConsistency();
+    procedure TestEd25519phConsistency();
+    procedure TestEd25519Vector1();
+    procedure TestEd25519Vector2();
+    procedure TestEd25519Vector3();
+    procedure TestEd25519Vector1023();
+    procedure TestEd25519VectorSHAabc();
+    procedure TestEd25519ctxVector1();
+    procedure TestEd25519ctxVector2();
+    procedure TestEd25519ctxVector3();
+    procedure TestEd25519ctxVector4();
+    procedure TestEd25519phVector1();
+
+  end;
+
+implementation
+
+{ TTestEd25519 }
+
+procedure TTestEd25519.CheckEd25519Vector(const sSK, sPK, sM, sSig,
+  text: String);
+var
+  sk, pk, pkGen, m, sig, badsig, sigGen: TCryptoLibByteArray;
+  Ed25519Instance: IEd25519;
+  shouldVerify, shouldNotVerify: Boolean;
+begin
+  sk := THex.Decode(sSK);
+  pk := THex.Decode(sPK);
+
+  System.SetLength(pkGen, TEd25519.PublicKeySize);
+
+  Ed25519Instance := TEd25519.Create();
+  Ed25519Instance.GeneratePublicKey(sk, 0, pkGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(pk, pkGen), text);
+
+  m := THex.Decode(sM);
+  sig := THex.Decode(sSig);
+
+  badsig := System.Copy(sig);
+
+  badsig[TEd25519.PublicKeySize - 1] :=
+    badsig[TEd25519.SignatureSize - 1] xor $80;
+
+  System.SetLength(sigGen, TEd25519.SignatureSize);
+
+  Ed25519Instance.Sign(sk, 0, m, 0, System.Length(m), sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  Ed25519Instance.Sign(sk, 0, pk, 0, m, 0, System.Length(m), sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  shouldVerify := Ed25519Instance.Verify(sig, 0, pk, 0, m, 0, System.Length(m));
+  CheckTrue(shouldVerify, text);
+
+  shouldNotVerify := Ed25519Instance.Verify(badsig, 0, pk, 0, m, 0,
+    System.Length(m));
+  CheckFalse(shouldNotVerify, text);
+end;
+
+procedure TTestEd25519.CheckEd25519ctxVector(const sSK, sPK, sM, sCTX, sSig,
+  text: String);
+var
+  sk, pk, pkGen, m, ctx, sig, badsig, sigGen: TCryptoLibByteArray;
+  Ed25519Instance: IEd25519;
+  shouldVerify, shouldNotVerify: Boolean;
+begin
+  sk := THex.Decode(sSK);
+  pk := THex.Decode(sPK);
+
+  System.SetLength(pkGen, TEd25519.PublicKeySize);
+
+  Ed25519Instance := TEd25519.Create();
+  Ed25519Instance.GeneratePublicKey(sk, 0, pkGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(pk, pkGen), text);
+
+  m := THex.Decode(sM);
+  ctx := THex.Decode(sCTX);
+  sig := THex.Decode(sSig);
+
+  badsig := System.Copy(sig);
+
+  badsig[TEd25519.PublicKeySize - 1] :=
+    badsig[TEd25519.SignatureSize - 1] xor $80;
+
+  System.SetLength(sigGen, TEd25519.SignatureSize);
+
+  Ed25519Instance.Sign(sk, 0, ctx, m, 0, System.Length(m), sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  Ed25519Instance.Sign(sk, 0, pk, 0, ctx, m, 0, System.Length(m), sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  shouldVerify := Ed25519Instance.Verify(sig, 0, pk, 0, ctx, m, 0,
+    System.Length(m));
+  CheckTrue(shouldVerify, text);
+
+  shouldNotVerify := Ed25519Instance.Verify(badsig, 0, pk, 0, ctx, m, 0,
+    System.Length(m));
+  CheckFalse(shouldNotVerify, text);
+end;
+
+procedure TTestEd25519.CheckEd25519phVector(const sSK, sPK, sM, sCTX, sSig,
+  text: String);
+var
+  sk, pk, pkGen, m, ph, ctx, sig, badsig, sigGen: TCryptoLibByteArray;
+  Ed25519Instance: IEd25519;
+  shouldVerify, shouldNotVerify: Boolean;
+  prehash: IDigest;
+begin
+  sk := THex.Decode(sSK);
+  pk := THex.Decode(sPK);
+
+  System.SetLength(pkGen, TEd25519.PublicKeySize);
+
+  Ed25519Instance := TEd25519.Create();
+  Ed25519Instance.GeneratePublicKey(sk, 0, pkGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(pk, pkGen), text);
+
+  m := THex.Decode(sM);
+  ctx := THex.Decode(sCTX);
+  sig := THex.Decode(sSig);
+
+  badsig := System.Copy(sig);
+
+  badsig[TEd25519.PublicKeySize - 1] :=
+    badsig[TEd25519.SignatureSize - 1] xor $80;
+
+  System.SetLength(sigGen, TEd25519.SignatureSize);
+
+  prehash := Ed25519Instance.CreatePreHash();
+  prehash.BlockUpdate(m, 0, System.Length(m));
+
+  System.SetLength(ph, TEd25519.PreHashSize);
+
+  prehash.DoFinal(ph, 0);
+
+  Ed25519Instance.SignPreHash(sk, 0, ctx, ph, 0, sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  Ed25519Instance.SignPreHash(sk, 0, pk, 0, ctx, ph, 0, sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  shouldVerify := Ed25519Instance.VerifyPreHash(sig, 0, pk, 0, ctx, ph, 0);
+  CheckTrue(shouldVerify, text);
+
+  shouldNotVerify := Ed25519Instance.VerifyPreHash(badsig, 0, pk, 0,
+    ctx, ph, 0);
+  CheckFalse(shouldNotVerify, text);
+
+  prehash := Ed25519Instance.CreatePreHash();
+  prehash.BlockUpdate(m, 0, System.Length(m));
+
+  Ed25519Instance.SignPreHash(sk, 0, ctx, prehash, sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  prehash := Ed25519Instance.CreatePreHash();
+  prehash.BlockUpdate(m, 0, System.Length(m));
+
+  Ed25519Instance.SignPreHash(sk, 0, pk, 0, ctx, prehash, sigGen, 0);
+  CheckTrue(TArrayUtils.AreEqual(sig, sigGen), text);
+
+  prehash := Ed25519Instance.CreatePreHash();
+  prehash.BlockUpdate(m, 0, System.Length(m));
+
+  shouldVerify := Ed25519Instance.VerifyPreHash(sig, 0, pk, 0, ctx, prehash);
+  CheckTrue(shouldVerify, text);
+
+  prehash := Ed25519Instance.CreatePreHash();
+  prehash.BlockUpdate(m, 0, System.Length(m));
+
+  shouldNotVerify := Ed25519Instance.VerifyPreHash(badsig, 0, pk, 0,
+    ctx, prehash);
+  CheckFalse(shouldNotVerify, text);
+
+end;
+
+procedure TTestEd25519.SetUp;
+begin
+  inherited;
+  FRandom := TSecureRandom.Create();
+  TEd25519.Precompute();
+end;
+
+procedure TTestEd25519.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestEd25519.TestEd25519Consistency;
+var
+  sk, pk, m, sig1, sig2: TCryptoLibByteArray;
+  i, mLen: Int32;
+  Ed25519Instance: IEd25519;
+  shouldVerify, shouldNotVerify: Boolean;
+begin
+  System.SetLength(sk, TEd25519.SecretKeySize);
+  System.SetLength(pk, TEd25519.PublicKeySize);
+  System.SetLength(m, 255);
+  System.SetLength(sig1, TEd25519.SignatureSize);
+  System.SetLength(sig2, TEd25519.SignatureSize);
+
+  FRandom.NextBytes(m);
+
+  for i := 0 to System.Pred(10) do
+  begin
+    FRandom.NextBytes(sk);
+    Ed25519Instance := TEd25519.Create();
+    Ed25519Instance.GeneratePublicKey(sk, 0, pk, 0);
+
+    mLen := FRandom.NextInt32() and 255;
+
+    Ed25519Instance.Sign(sk, 0, m, 0, mLen, sig1, 0);
+    Ed25519Instance.Sign(sk, 0, pk, 0, m, 0, mLen, sig2, 0);
+
+    CheckTrue(TArrayUtils.AreEqual(sig1, sig2),
+      Format('Ed25519 consistent signatures #%d', [i]));
+
+    shouldVerify := Ed25519Instance.Verify(sig1, 0, pk, 0, m, 0, mLen);
+
+    CheckTrue(shouldVerify, Format('Ed25519 consistent sign/verify #%d', [i]));
+
+    sig1[TEd25519.PublicKeySize - 1] :=
+      sig1[TEd25519.PublicKeySize - 1] xor $80;
+    shouldNotVerify := Ed25519Instance.Verify(sig1, 0, pk, 0, m, 0, mLen);
+
+    CheckFalse(shouldNotVerify,
+      Format('Ed25519 consistent verification failure #%d', [i]));
+  end;
+end;
+
+procedure TTestEd25519.TestEd25519ctxConsistency;
+var
+  sk, pk, ctx, m, sig1, sig2: TCryptoLibByteArray;
+  i, mLen: Int32;
+  Ed25519Instance: IEd25519;
+  shouldVerify, shouldNotVerify: Boolean;
+begin
+  System.SetLength(sk, TEd25519.SecretKeySize);
+  System.SetLength(pk, TEd25519.PublicKeySize);
+  System.SetLength(ctx, FRandom.NextInt32() and 7);
+  System.SetLength(m, 255);
+  System.SetLength(sig1, TEd25519.SignatureSize);
+  System.SetLength(sig2, TEd25519.SignatureSize);
+
+  FRandom.NextBytes(ctx);
+  FRandom.NextBytes(m);
+
+  for i := 0 to System.Pred(10) do
+  begin
+    FRandom.NextBytes(sk);
+    Ed25519Instance := TEd25519.Create();
+    Ed25519Instance.GeneratePublicKey(sk, 0, pk, 0);
+
+    mLen := FRandom.NextInt32() and 255;
+
+    Ed25519Instance.Sign(sk, 0, ctx, m, 0, mLen, sig1, 0);
+    Ed25519Instance.Sign(sk, 0, pk, 0, ctx, m, 0, mLen, sig2, 0);
+
+    CheckTrue(TArrayUtils.AreEqual(sig1, sig2),
+      Format('Ed25519ctx consistent signatures #%d', [i]));
+
+    shouldVerify := Ed25519Instance.Verify(sig1, 0, pk, 0, ctx, m, 0, mLen);
+
+    CheckTrue(shouldVerify,
+      Format('Ed25519ctx consistent sign/verify #%d', [i]));
+
+    sig1[TEd25519.PublicKeySize - 1] :=
+      sig1[TEd25519.PublicKeySize - 1] xor $80;
+    shouldNotVerify := Ed25519Instance.Verify(sig1, 0, pk, 0, ctx, m, 0, mLen);
+
+    CheckFalse(shouldNotVerify,
+      Format('Ed25519ctx consistent verification failure #%d', [i]));
+  end;
+end;
+
+procedure TTestEd25519.TestEd25519Vector1;
+begin
+  CheckEd25519Vector(('9d61b19deffd5a60ba844af492ec2cc4' +
+    '4449c5697b326919703bac031cae7f60'),
+    ('d75a980182b10ab7d54bfed3c964073a' + '0ee172f3daa62325af021a68f707511a'),
+    '', ('e5564300c360ac729086e2cc806e828a' + '84877f1eb8e5d974d873e06522490155'
+    + '5fb8821590a33bacc61e39701cf9b46b' + 'd25bf5f0595bbe24655141438e7a100b'),
+    'Ed25519 Vector #1');
+end;
+
+procedure TTestEd25519.TestEd25519Vector2;
+begin
+  CheckEd25519Vector(('4ccd089b28ff96da9db6c346ec114e0f' +
+    '5b8a319f35aba624da8cf6ed4fb8a6fb'),
+    ('3d4017c3e843895a92b70aa74d1b7ebc' + '9c982ccf2ec4968cc0cd55f12af4660c'),
+    '72', ('92a009a9f0d4cab8720e820b5f642540' +
+    'a2b27b5416503f8fb3762223ebdb69da' + '085ac1e43e15996e458f3613d0f11d8c' +
+    '387b2eaeb4302aeeb00d291612bb0c00'), 'Ed25519 Vector #2');
+end;
+
+procedure TTestEd25519.TestEd25519Vector3;
+begin
+  CheckEd25519Vector(('c5aa8df43f9f837bedb7442f31dcb7b1' +
+    '66d38535076f094b85ce3a2e0b4458f7'),
+    ('fc51cd8e6218a1a38da47ed00230f058' + '0816ed13ba3303ac5deb911548908025'),
+    'af82', ('6291d657deec24024827e69c3abe01a3' +
+    '0ce548a284743a445e3680d7db5ac3ac' + '18ff9b538d16f290ae67f760984dc659' +
+    '4a7c15e9716ed28dc027beceea1ec40a'), 'Ed25519 Vector #3');
+end;
+
+procedure TTestEd25519.TestEd25519Vector1023;
+var
+  m: String;
+begin
+  m := '08b8b2b733424243760fe426a4b54908' + '632110a66c2f6591eabd3345e3e4eb98' +
+    'fa6e264bf09efe12ee50f8f54e9f77b1' + 'e355f6c50544e23fb1433ddf73be84d8' +
+    '79de7c0046dc4996d9e773f4bc9efe57' + '38829adb26c81b37c93a1b270b20329d' +
+    '658675fc6ea534e0810a4432826bf58c' + '941efb65d57a338bbd2e26640f89ffbc' +
+    '1a858efcb8550ee3a5e1998bd177e93a' + '7363c344fe6b199ee5d02e82d522c4fe' +
+    'ba15452f80288a821a579116ec6dad2b' + '3b310da903401aa62100ab5d1a36553e' +
+    '06203b33890cc9b832f79ef80560ccb9' + 'a39ce767967ed628c6ad573cb116dbef' +
+    'efd75499da96bd68a8a97b928a8bbc10' + '3b6621fcde2beca1231d206be6cd9ec7' +
+    'aff6f6c94fcd7204ed3455c68c83f4a4' + '1da4af2b74ef5c53f1d8ac70bdcb7ed1' +
+    '85ce81bd84359d44254d95629e9855a9' + '4a7c1958d1f8ada5d0532ed8a5aa3fb2' +
+    'd17ba70eb6248e594e1a2297acbbb39d' + '502f1a8c6eb6f1ce22b3de1a1f40cc24' +
+    '554119a831a9aad6079cad88425de6bd' + 'e1a9187ebb6092cf67bf2b13fd65f270' +
+    '88d78b7e883c8759d2c4f5c65adb7553' + '878ad575f9fad878e80a0c9ba63bcbcc' +
+    '2732e69485bbc9c90bfbd62481d9089b' + 'eccf80cfe2df16a2cf65bd92dd597b07' +
+    '07e0917af48bbb75fed413d238f5555a' + '7a569d80c3414a8d0859dc65a46128ba' +
+    'b27af87a71314f318c782b23ebfe808b' + '82b0ce26401d2e22f04d83d1255dc51a' +
+    'ddd3b75a2b1ae0784504df543af8969b' + 'e3ea7082ff7fc9888c144da2af58429e' +
+    'c96031dbcad3dad9af0dcbaaaf268cb8' + 'fcffead94f3c7ca495e056a9b47acdb7' +
+    '51fb73e666c6c655ade8297297d07ad1' + 'ba5e43f1bca32301651339e22904cc8c' +
+    '42f58c30c04aafdb038dda0847dd988d' + 'cda6f3bfd15c4b4c4525004aa06eeff8' +
+    'ca61783aacec57fb3d1f92b0fe2fd1a8' + '5f6724517b65e614ad6808d6f6ee34df' +
+    'f7310fdc82aebfd904b01e1dc54b2927' + '094b2db68d6f903b68401adebf5a7e08' +
+    'd78ff4ef5d63653a65040cf9bfd4aca7' + '984a74d37145986780fc0b16ac451649' +
+    'de6188a7dbdf191f64b5fc5e2ab47b57' + 'f7f7276cd419c17a3ca8e1b939ae49e4' +
+    '88acba6b965610b5480109c8b17b80e1' + 'b7b750dfc7598d5d5011fd2dcc5600a3' +
+    '2ef5b52a1ecc820e308aa342721aac09' + '43bf6686b64b2579376504ccc493d97e' +
+    '6aed3fb0f9cd71a43dd497f01f17c0e2' + 'cb3797aa2a2f256656168e6c496afc5f' +
+    'b93246f6b1116398a346f1a641f3b041' + 'e989f7914f90cc2c7fff357876e506b5' +
+    '0d334ba77c225bc307ba537152f3f161' + '0e4eafe595f6d9d90d11faa933a15ef1' +
+    '369546868a7f3a45a96768d40fd9d034' + '12c091c6315cf4fde7cb68606937380d' +
+    'b2eaaa707b4c4185c32eddcdd306705e' + '4dc1ffc872eeee475a64dfac86aba41c' +
+    '0618983f8741c5ef68d3a101e8a3b8ca' + 'c60c905c15fc910840b94c00a0b9d0';
+
+  CheckEd25519Vector(('f5e5767cf153319517630f226876b86c' +
+    '8160cc583bc013744c6bf255f5cc0ee5'),
+    ('278117fc144c72340f67d0f2316e8386' + 'ceffbf2b2428c9c51fef7c597f1d426e'),
+    m, ('0aab4c900501b3e24d7cdf4663326a3a' + '87df5e4843b2cbdb67cbf6e460fec350'
+    + 'aa5371b1508f9f4528ecea23c436d94b' + '5e8fcd4f681e30a6ac00a9704a188a03'),
+    'Ed25519 Vector #1023');
+end;
+
+procedure TTestEd25519.TestEd25519VectorSHAabc;
+begin
+  CheckEd25519Vector(('833fe62409237b9d62ec77587520911e' +
+    '9a759cec1d19755b7da901b96dca3d42'),
+    ('ec172b93ad5e563bf4932c70e1245034' + 'c35467ef2efd4d64ebf819683467e2bf'),
+    ('ddaf35a193617abacc417349ae204131' + '12e6fa4e89a97ea20a9eeee64b55d39a' +
+    '2192992a274fc1a836ba3c23a3feebbd' + '454d4423643ce80e2a9ac94fa54ca49f'),
+    ('dc2a4459e7369633a52b1bf277839a00' + '201009a3efbf3ecb69bea2186c26b589' +
+    '09351fc9ac90b3ecfdfbc7c66431e030' + '3dca179c138ac17ad9bef1177331a704'),
+    'Ed25519 Vector SHA(abc)');
+end;
+
+procedure TTestEd25519.TestEd25519ctxVector1;
+begin
+  CheckEd25519ctxVector(('0305334e381af78f141cb666f6199f57' +
+    'bc3495335a256a95bd2a55bf546663f6'),
+    ('dfc9425e4f968f7f0c29f0259cf5f9ae' + 'd6851c2bb4ad8bfb860cfee0ab248292'),
+    'f726936d19c800494e3fdaff20b276a8', '666f6f',
+    ('55a4cc2f70a54e04288c5f4cd1e45a7b' + 'b520b36292911876cada7323198dd87a' +
+    '8b36950b95130022907a7fb7c4e9b2d5' + 'f6cca685a587b4b21f4b888e4e7edb0d'),
+    'Ed25519ctx Vector #1');
+end;
+
+procedure TTestEd25519.TestEd25519ctxVector2;
+begin
+  CheckEd25519ctxVector(('0305334e381af78f141cb666f6199f57' +
+    'bc3495335a256a95bd2a55bf546663f6'),
+    ('dfc9425e4f968f7f0c29f0259cf5f9ae' + 'd6851c2bb4ad8bfb860cfee0ab248292'),
+    'f726936d19c800494e3fdaff20b276a8', '626172',
+    ('fc60d5872fc46b3aa69f8b5b4351d580' + '8f92bcc044606db097abab6dbcb1aee3' +
+    '216c48e8b3b66431b5b186d1d28f8ee1' + '5a5ca2df6668346291c2043d4eb3e90d'),
+    'Ed25519ctx Vector #2');
+end;
+
+procedure TTestEd25519.TestEd25519ctxVector3;
+begin
+  CheckEd25519ctxVector(('0305334e381af78f141cb666f6199f57' +
+    'bc3495335a256a95bd2a55bf546663f6'),
+    ('dfc9425e4f968f7f0c29f0259cf5f9ae' + 'd6851c2bb4ad8bfb860cfee0ab248292'),
+    '508e9e6882b979fea900f62adceaca35', '666f6f',
+    ('8b70c1cc8310e1de20ac53ce28ae6e72' + '07f33c3295e03bb5c0732a1d20dc6490' +
+    '8922a8b052cf99b7c4fe107a5abb5b2c' + '4085ae75890d02df26269d8945f84b0b'),
+    'Ed25519ctx Vector #3');
+end;
+
+procedure TTestEd25519.TestEd25519ctxVector4;
+begin
+  CheckEd25519ctxVector(('ab9c2853ce297ddab85c993b3ae14bca' +
+    'd39b2c682beabc27d6d4eb20711d6560'),
+    ('0f1d1274943b91415889152e893d80e9' + '3275a1fc0b65fd71b4b0dda10ad7d772'),
+    'f726936d19c800494e3fdaff20b276a8', '666f6f',
+    ('21655b5f1aa965996b3f97b3c849eafb' + 'a922a0a62992f73b3d1b73106a84ad85' +
+    'e9b86a7b6005ea868337ff2d20a7f5fb' + 'd4cd10b0be49a68da2b2e0dc0ad8960f'),
+    'Ed25519ctx Vector #4');
+end;
+
+procedure TTestEd25519.TestEd25519phVector1;
+begin
+  CheckEd25519phVector(('833fe62409237b9d62ec77587520911e' +
+    '9a759cec1d19755b7da901b96dca3d42'),
+    ('ec172b93ad5e563bf4932c70e1245034' + 'c35467ef2efd4d64ebf819683467e2bf'),
+    '616263', '', ('98a70222f0b8121aa9d30f813d683f80' +
+    '9e462b469c7ff87639499bb94e6dae41' + '31f85042463c2a355a2003d062adf5aa' +
+    'a10b8c61e636062aaad11c2a26083406'), 'Ed25519ph Vector #1');
+end;
+
+procedure TTestEd25519.TestEd25519phConsistency;
+var
+  sk, pk, ctx, m, ph, sig1, sig2: TCryptoLibByteArray;
+  i, mLen: Int32;
+  Ed25519Instance: IEd25519;
+  shouldVerify, shouldNotVerify: Boolean;
+  prehash: IDigest;
+begin
+  System.SetLength(sk, TEd25519.SecretKeySize);
+  System.SetLength(pk, TEd25519.PublicKeySize);
+  System.SetLength(ctx, FRandom.NextInt32() and 7);
+  System.SetLength(m, 255);
+  System.SetLength(ph, 255);
+  System.SetLength(sig1, TEd25519.PreHashSize);
+  System.SetLength(sig2, TEd25519.SignatureSize);
+
+  FRandom.NextBytes(ctx);
+  FRandom.NextBytes(m);
+
+  for i := 0 to System.Pred(10) do
+  begin
+    FRandom.NextBytes(sk);
+    Ed25519Instance := TEd25519.Create();
+    Ed25519Instance.GeneratePublicKey(sk, 0, pk, 0);
+
+    mLen := FRandom.NextInt32() and 255;
+
+    prehash := Ed25519Instance.CreatePreHash();
+    prehash.BlockUpdate(m, 0, mLen);
+    prehash.DoFinal(ph, 0);
+
+    Ed25519Instance.SignPreHash(sk, 0, ctx, ph, 0, sig1, 0);
+    Ed25519Instance.SignPreHash(sk, 0, pk, 0, ctx, ph, 0, sig2, 0);
+
+    CheckTrue(TArrayUtils.AreEqual(sig1, sig2),
+      Format('Ed25519ph consistent signatures #%d', [i]));
+
+    shouldVerify := Ed25519Instance.VerifyPreHash(sig1, 0, pk, 0, ctx, ph, 0);
+
+    CheckTrue(shouldVerify,
+      Format('Ed25519ph consistent sign/verify #%d', [i]));
+
+    sig1[TEd25519.PublicKeySize - 1] :=
+      sig1[TEd25519.PublicKeySize - 1] xor $80;
+    shouldNotVerify := Ed25519Instance.VerifyPreHash(sig1, 0, pk, 0,
+      ctx, ph, 0);
+
+    CheckFalse(shouldNotVerify,
+      Format('Ed25519ph consistent verification failure #%d', [i]));
+  end;
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+ // RegisterTest(TTestEd25519);
+{$ELSE}
+  RegisterTest(TTestEd25519.Suite);
+{$ENDIF FPC}
+
+end.

+ 0 - 1
CryptoLib.Tests/src/Math/ECNRTests.pas

@@ -50,7 +50,6 @@ uses
   ClpISecureRandom,
   ClpISecureRandom,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpEncoders,
   ClpEncoders,
-  ClpDigestUtilities,
   ClpSignerUtilities,
   ClpSignerUtilities,
   ClpBigInteger,
   ClpBigInteger,
   ClpConverters,
   ClpConverters,

+ 12 - 12
CryptoLib.Tests/src/Math/IESCipherTests.pas

@@ -36,8 +36,8 @@ uses
   ClpIAesEngine,
   ClpIAesEngine,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpIAsymmetricCipherKeyPairGenerator,
   ClpGeneratorUtilities,
   ClpGeneratorUtilities,
-  ClpIESWithCipherParameters,
-  ClpIIESWithCipherParameters,
+  ClpIESParameterSpec,
+  ClpIAlgorithmParameterSpec,
   // ClpKeyParameter,
   // ClpKeyParameter,
   // ClpIKeyParameter,
   // ClpIKeyParameter,
   // ClpParametersWithIV,
   // ClpParametersWithIV,
@@ -87,11 +87,11 @@ type
 
 
     function GetECIESAES256CBCEngine: IIESEngine;
     function GetECIESAES256CBCEngine: IIESEngine;
     function GetECKeyPair: IAsymmetricCipherKeyPair;
     function GetECKeyPair: IAsymmetricCipherKeyPair;
-    function GetIESWithCipherParameters: IIESWithCipherParameters;
+    function GetIESParameterSpec: IAlgorithmParameterSpec;
 
 
-    procedure doIESCipher_Encryption_Decryption_TestWithIV
+    procedure DoIESCipher_Encryption_Decryption_TestWithIV
       (const KeyPair: IAsymmetricCipherKeyPair;
       (const KeyPair: IAsymmetricCipherKeyPair;
-      const param: IIESWithCipherParameters; const Random: ISecureRandom;
+      const param: IAlgorithmParameterSpec; const Random: ISecureRandom;
       const PlainText: String);
       const PlainText: String);
 
 
   protected
   protected
@@ -107,9 +107,9 @@ implementation
 
 
 { TTestIESCipher }
 { TTestIESCipher }
 
 
-procedure TTestIESCipher.doIESCipher_Encryption_Decryption_TestWithIV
+procedure TTestIESCipher.DoIESCipher_Encryption_Decryption_TestWithIV
   (const KeyPair: IAsymmetricCipherKeyPair;
   (const KeyPair: IAsymmetricCipherKeyPair;
-  const param: IIESWithCipherParameters; const Random: ISecureRandom;
+  const param: IAlgorithmParameterSpec; const Random: ISecureRandom;
   const PlainText: String);
   const PlainText: String);
 var
 var
   PlainTextBytes, CipherTextBytes, DecryptionResultBytes: TBytes;
   PlainTextBytes, CipherTextBytes, DecryptionResultBytes: TBytes;
@@ -193,7 +193,7 @@ begin
   result := KeyPairGeneratorInstance.GenerateKeyPair();
   result := KeyPairGeneratorInstance.GenerateKeyPair();
 end;
 end;
 
 
-function TTestIESCipher.GetIESWithCipherParameters: IIESWithCipherParameters;
+function TTestIESCipher.GetIESParameterSpec: IAlgorithmParameterSpec;
 var
 var
   Derivation, Encoding, IVBytes: TBytes;
   Derivation, Encoding, IVBytes: TBytes;
   MacKeySizeInBits, CipherKeySizeInBits: Int32;
   MacKeySizeInBits, CipherKeySizeInBits: Int32;
@@ -219,8 +219,8 @@ begin
   // from a point or not in the EphemeralKeyPairGenerator
   // from a point or not in the EphemeralKeyPairGenerator
   UsePointCompression := False;
   UsePointCompression := False;
 
 
-  result := TIESWithCipherParameters.Create(Derivation, Encoding,
-    MacKeySizeInBits, CipherKeySizeInBits, IVBytes, UsePointCompression);
+  result := TIESParameterSpec.Create(Derivation, Encoding, MacKeySizeInBits,
+    CipherKeySizeInBits, IVBytes, UsePointCompression);
 
 
 end;
 end;
 
 
@@ -253,8 +253,8 @@ begin
 
 
     // Call IESCipher Encryption and Decryption Method
     // Call IESCipher Encryption and Decryption Method
 
 
-    doIESCipher_Encryption_Decryption_TestWithIV(GetECKeyPair,
-      GetIESWithCipherParameters, RandomInstance, PlainText);
+    DoIESCipher_Encryption_Decryption_TestWithIV(GetECKeyPair,
+      GetIESParameterSpec, RandomInstance, PlainText);
 
 
     System.Inc(I);
     System.Inc(I);
   end;
   end;

+ 412 - 0
CryptoLib.Tests/src/Math/PascalCoinECIESTests.pas

@@ -0,0 +1,412 @@
+unit PascalCoinECIESTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+  TypInfo,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpECC,
+  ClpIECC,
+  ClpIESEngine,
+  ClpIIESCipher,
+  ClpIESCipher,
+  ClpIECDHBasicAgreement,
+  ClpECDHBasicAgreement,
+  ClpECPrivateKeyParameters,
+  ClpIECPrivateKeyParameters,
+  ClpECPublicKeyParameters,
+  ClpIECPublicKeyParameters,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpECDomainParameters,
+  ClpIECDomainParameters,
+  ClpIBufferedBlockCipher,
+  ClpPaddedBufferedBlockCipher,
+  ClpBlockCipherModes,
+  ClpIBlockCipherModes,
+  ClpAESEngine,
+  ClpIAesEngine,
+  ClpEncoders,
+  ClpBigInteger,
+  ClpCustomNamedCurves,
+  ClpDigestUtilities,
+  ClpIIESParameterSpec,
+  ClpIESParameterSpec,
+  ClpIPascalCoinIESEngine,
+  ClpPascalCoinIESEngine,
+  ClpPascalCoinECIESKdfBytesGenerator,
+  ClpIPascalCoinECIESKdfBytesGenerator,
+  ClpPaddingModes,
+  ClpIPaddingModes,
+  ClpIMac,
+  ClpMacUtilities,
+  ClpIX9ECParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// Test for PascalCoin ECIES - PascalCoin Elliptic Curve Integrated Encryption Scheme
+  /// Test vectors were gotten from the PascalCoin TESTNET Wallet.
+  /// </summary>
+  TTestPascalCoinECIES = class(TCryptoLibTestCase)
+  private
+
+    type
+{$SCOPEDENUMS ON}
+    TKeyType = (SECP256K1, SECP384R1, SECP521R1, SECT283K1);
+{$SCOPEDENUMS OFF}
+
+  const
+    SHORT_MESSAGE: String = 'shortmessage';
+    LONG_MESSAGE
+      : String =
+      'longmessagelongmessagelongmessagelongmessagelongmessagelongmessage';
+
+  var
+    FRandom: ISecureRandom;
+
+    function GetCurveFromKeyType(keyType: TKeyType): IX9ECParameters;
+    function GetPascalCoinIESParameterSpec: IIESParameterSpec;
+    function GetECIESPascalCoinCompatibilityEngine: IPascalCoinIESEngine;
+
+    function RecreatePublicKeyFromAffineXandAffineYCoord(keyType: TKeyType;
+      const RawAffineX, RawAffineY: TBytes): IECPublicKeyParameters;
+
+    function RecreatePrivateKeyFromByteArray(keyType: TKeyType;
+      const RawPrivateKey: TBytes): IECPrivateKeyParameters;
+
+    function DoPascalCoinECIESEncrypt(keyType: TKeyType;
+      const RawAffineXCoord, RawAffineYCoord, PayloadToEncrypt: String): String;
+
+    function DoPascalCoinECIESDecrypt(keyType: TKeyType;
+      const RawPrivateKey, PayloadToDecrypt: String): String;
+
+    procedure DoTestPascalCoinECIESDecrypt(const id: String; keyType: TKeyType;
+      const RawPrivateKey, PayloadToDecrypt, ExpectedOutput: String);
+
+    procedure DoTestPascalCoinECIESEncryptDecrypt(const id: String;
+      keyType: TKeyType; const RawPrivateKey, RawAffineXCoord, RawAffineYCoord,
+      PayloadToEncrypt: String);
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestPacalCoinECIESDecrypt;
+    procedure TestPacalCoinECIESEncryptDecrypt;
+
+  end;
+
+implementation
+
+{ TTestPascalCoinECIES }
+
+procedure TTestPascalCoinECIES.SetUp;
+begin
+  inherited;
+  FRandom := TSecureRandom.Create();
+end;
+
+procedure TTestPascalCoinECIES.TearDown;
+begin
+  inherited;
+  FRandom := Nil;
+end;
+
+function TTestPascalCoinECIES.GetCurveFromKeyType(keyType: TKeyType)
+  : IX9ECParameters;
+var
+  CurveName: string;
+begin
+  CurveName := GetEnumName(TypeInfo(TKeyType), Ord(keyType));
+  Result := TCustomNamedCurves.GetByName(CurveName);
+end;
+
+function TTestPascalCoinECIES.GetPascalCoinIESParameterSpec: IIESParameterSpec;
+var
+  Derivation, Encoding, IVBytes: TBytes;
+  MacKeySizeInBits, CipherKeySizeInBits: Int32;
+  UsePointCompression: boolean;
+begin
+  // Set up IES Parameter Spec For Compatibility With PascalCoin Current Implementation
+
+  // The derivation and encoding vectors are used when initialising the KDF and MAC.
+  // They're optional but if used then they need to be known by the other user so that
+  // they can decrypt the ciphertext and verify the MAC correctly. The security is based
+  // on the shared secret coming from the (static-ephemeral) ECDH key agreement.
+  Derivation := nil;
+
+  Encoding := nil;
+
+  System.SetLength(IVBytes, 16); // using Zero Initialized IV for compatibility
+
+  MacKeySizeInBits := 32 * 8;
+
+  // Since we are using AES256_CBC for compatibility
+  CipherKeySizeInBits := 32 * 8;
+
+  // whether to use point compression when deriving the octets string
+  // from a point or not in the EphemeralKeyPairGenerator
+  UsePointCompression := True; // for compatibility
+
+  Result := TIESParameterSpec.Create(Derivation, Encoding, MacKeySizeInBits,
+    CipherKeySizeInBits, IVBytes, UsePointCompression);
+end;
+
+function TTestPascalCoinECIES.GetECIESPascalCoinCompatibilityEngine
+  : IPascalCoinIESEngine;
+var
+  cipher: IBufferedBlockCipher;
+  AesEngine: IAesEngine;
+  blockCipher: ICbcBlockCipher;
+  ECDHBasicAgreementInstance: IECDHBasicAgreement;
+  KDFInstance: IPascalCoinECIESKdfBytesGenerator;
+  DigestMACInstance: IMac;
+
+begin
+  // Set up IES Cipher Engine For Compatibility With PascalCoin
+
+  ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
+
+  KDFInstance := TPascalCoinECIESKdfBytesGenerator.Create
+    (TDigestUtilities.GetDigest('SHA-512'));
+
+  DigestMACInstance := TMacUtilities.GetMac('HMAC-MD5');
+
+  // Set Up Block Cipher
+  AesEngine := TAesEngine.Create(); // AES Engine
+
+  blockCipher := TCbcBlockCipher.Create(AesEngine); // CBC
+
+  cipher := TPaddedBufferedBlockCipher.Create(blockCipher,
+    TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
+
+  Result := TPascalCoinIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
+    DigestMACInstance, cipher);
+end;
+
+function TTestPascalCoinECIES.RecreatePublicKeyFromAffineXandAffineYCoord
+  (keyType: TKeyType; const RawAffineX, RawAffineY: TBytes)
+  : IECPublicKeyParameters;
+var
+  domain: IECDomainParameters;
+  LCurve: IX9ECParameters;
+  point: IECPoint;
+  BigXCoord, BigYCoord: TBigInteger;
+begin
+  LCurve := GetCurveFromKeyType(keyType);
+  domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
+    LCurve.H, LCurve.GetSeed);
+
+  BigXCoord := TBigInteger.Create(1, RawAffineX);
+  BigYCoord := TBigInteger.Create(1, RawAffineY);
+
+  point := LCurve.Curve.CreatePoint(BigXCoord, BigYCoord);
+
+  Result := TECPublicKeyParameters.Create('ECDSA', point, domain);
+end;
+
+function TTestPascalCoinECIES.RecreatePrivateKeyFromByteArray(keyType: TKeyType;
+  const RawPrivateKey: TBytes): IECPrivateKeyParameters;
+var
+  domain: IECDomainParameters;
+  LCurve: IX9ECParameters;
+  PrivD: TBigInteger;
+begin
+  LCurve := GetCurveFromKeyType(keyType);
+  domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
+    LCurve.H, LCurve.GetSeed);
+
+  PrivD := TBigInteger.Create(1, RawPrivateKey);
+
+  Result := TECPrivateKeyParameters.Create('ECDSA', PrivD, domain);
+end;
+
+function TTestPascalCoinECIES.DoPascalCoinECIESEncrypt(keyType: TKeyType;
+  const RawAffineXCoord, RawAffineYCoord, PayloadToEncrypt: String): String;
+var
+  CipherEncrypt: IIESCipher;
+begin
+  // Encryption
+  CipherEncrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine());
+  CipherEncrypt.Init(True, RecreatePublicKeyFromAffineXandAffineYCoord(keyType,
+    THex.Decode(RawAffineXCoord), THex.Decode(RawAffineYCoord)),
+    GetPascalCoinIESParameterSpec(), FRandom);
+  Result := THex.Encode(CipherEncrypt.DoFinal(TEncoding.ASCII.GetBytes
+    (UnicodeString(PayloadToEncrypt))));
+end;
+
+function TTestPascalCoinECIES.DoPascalCoinECIESDecrypt(keyType: TKeyType;
+  const RawPrivateKey, PayloadToDecrypt: String): String;
+var
+  CipherDecrypt: IIESCipher;
+begin
+  try
+    // Decryption
+    CipherDecrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine());
+    CipherDecrypt.Init(False, RecreatePrivateKeyFromByteArray(keyType,
+      THex.Decode(RawPrivateKey)), GetPascalCoinIESParameterSpec(), FRandom);
+    Result := String(TEncoding.ASCII.GetString
+      ((CipherDecrypt.DoFinal(THex.Decode(PayloadToDecrypt)))));
+  except
+    // should only happen if decryption fails
+    raise;
+  end;
+end;
+
+procedure TTestPascalCoinECIES.DoTestPascalCoinECIESDecrypt(const id: String;
+  keyType: TKeyType; const RawPrivateKey, PayloadToDecrypt,
+  ExpectedOutput: String);
+var
+  DecryptedPayload: String;
+begin
+  DecryptedPayload := DoPascalCoinECIESDecrypt(keyType, RawPrivateKey,
+    PayloadToDecrypt);
+  CheckEquals(ExpectedOutput, DecryptedPayload,
+    Format('Test %s Failed, Expected "%s" but got "%s"', [id + '_Decrypt',
+    ExpectedOutput, DecryptedPayload]));
+end;
+
+procedure TTestPascalCoinECIES.DoTestPascalCoinECIESEncryptDecrypt
+  (const id: String; keyType: TKeyType; const RawPrivateKey, RawAffineXCoord,
+  RawAffineYCoord, PayloadToEncrypt: String);
+var
+  ActualOutput: String;
+begin
+  ActualOutput := DoPascalCoinECIESDecrypt(keyType, RawPrivateKey,
+    DoPascalCoinECIESEncrypt(keyType, RawAffineXCoord, RawAffineYCoord,
+    PayloadToEncrypt));
+
+  CheckEquals(PayloadToEncrypt, ActualOutput,
+    Format('Test %s Failed, Expected "%s" but got "%s"',
+    [id + '_EncryptDecrypt', PayloadToEncrypt, ActualOutput]));
+end;
+
+procedure TTestPascalCoinECIES.TestPacalCoinECIESDecrypt;
+begin
+  DoTestPascalCoinECIESDecrypt('1', TKeyType.SECP256K1,
+    '5EEBDD98BBD3F96A1A69020F58C147624AF27F9E9831F05EC42A190DD2FB0DF1',
+    '21100C001000025ED19E944D69BA45269855B9F73042E0DCCB50C3EE5B103A2FF3762F9B3540B43D39F0DCA42C53C90F57BC15FED1E5E4490B59FD0E0657E7DBDE5C1C57E40411',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESDecrypt('2', TKeyType.SECP256K1,
+    '5EEBDD98BBD3F96A1A69020F58C147624AF27F9E9831F05EC42A190DD2FB0DF1',
+    '21104200500003CC2EFCBE845C6AF6DD27074DC283E5B118874F0A53BE634C509E6D2D9487E8281824CE68560A3C12D36D502DB5A55905F7DC3E67967E10D590F3EFBDE1F3A'
+    + 'D0337ACE569F773C77A18B045B4D4285B5C3B52AAE0BD0C68169C4AB684DA7CF3B73D5C8643EFF99B6F00128B01255B08D83995C1A79C6B2AA0B412343C95CF30B0',
+    LONG_MESSAGE);
+
+  DoTestPascalCoinECIESDecrypt('3', TKeyType.SECP384R1,
+    '889ED91943C05D599DA1CEF146D68495E650F800B74B6310AD9614DC55E2ABE01604E3398E548E0D4AD82A887070B787',
+    '31100C001000021E6A7EBF798DEFF9411940BFFA3B82F8F555165B5BD5CCF8A7CA8E661E2057FB5E721E30D3CC187E97988524370560F8E85CAAF9B640FB277A92780BB2D34DDE49AD19FA53FE9A8CC867731846FE0C4F',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESDecrypt('4', TKeyType.SECP384R1,
+    '889ED91943C05D599DA1CEF146D68495E650F800B74B6310AD9614DC55E2ABE01604E3398E548E0D4AD82A887070B787',
+    '31104200500003C1CC4FCB1B6B32EACF9EBBFD22D4904055D454263A475261EB4F1BA8008F9E2C6D8B468B7A36BF3DE6D284C07C1CB431887'
+    + '1F197A4CFC055E3312845BCFACB4F185EA02D5D443CE021B76F560D86209D44FF828B2905D4FA30B0873ADA758983F59E25E25598C85C2253B7BAC35B722CAD1F80545FB315C95016FB440559FF626086B7BA09A51481A7B77BF4B129E579',
+    LONG_MESSAGE);
+
+  DoTestPascalCoinECIESDecrypt('5', TKeyType.SECP521R1,
+    '6316522337DA679C1EF338E54509C19793FC3C02D53F12AF79322086AAA4AA2BAD8108EDA2000763DC99C6DA1909712C2E96A9F2BAB7502BCD2DDD7B39880F0808',
+    '43100C00100003013D32C1BACF719D45829502FAD8D7A5FBED41EF6E212E6D1FCC55B70552BF85B6F71A4A045221D36D47C1E538217A80B4918E76C9E84191359419BAE0FBDB3ADB56ABE37C5F02BEA79FDAEF3D5E5312B6A932F57973AF25D58CF42E0C7F2877C711',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESDecrypt('6', TKeyType.SECP521R1,
+    '6316522337DA679C1EF338E54509C19793FC3C02D53F12AF79322086AAA4AA2BAD8108EDA2000763DC99C6DA1909712C2E96A9F2BAB7502BCD2DDD7B39880F0808',
+    '4310420050000301838307131DF82CF6D23C07AA4A12261784399E2D011C87969E2388659A95A54C11E08C34F49D651D4E5C87106D367C01CB60C7146D20FE60098913074A78519DF182F3BA0A4A097FD11F11D9FC09D1C4586D178082AAC68B2A4BAC012992D3A'
+    + '44ACBCC322E3C3F86BD728A3570B3C24696464088EAE8A82A6EAC5BB444DD28E322351C801D61673B9B8776C190E0FCD468C906448680B3094BD692EC0CA4700361',
+    LONG_MESSAGE);
+
+  DoTestPascalCoinECIESDecrypt('7', TKeyType.SECT283K1,
+    '0121EFFE82FE34BA6D1B5635903924801CADD54EF2804B56624BB8C0BFBF9F33BB42EADD',
+    '25100C00100002079DF758857C4CC50D10A94D25CBD219E752BBD08EB30D61158765200D54CEA6BB5157F95CEB540F0698AF56E7DBD2E612F9C7CBDBC4364C343661F0B4A50309FCA05303',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESDecrypt('8', TKeyType.SECT283K1,
+    '0121EFFE82FE34BA6D1B5635903924801CADD54EF2804B56624BB8C0BFBF9F33BB42EADD',
+    '25104200500003067C595E47EEC68264B1FD4AC181F5CB2632C88AC5F03ED2F532B5513F0EA7A274E6F53A4F16B6FC9341B79577C11E205F7BF12CEC5F339FA20163E8D6EDB4AD07595AEEDE9EAABDB'
+    + '5468D9CA50F2667313024669580D67C532284A687A2C1172F656B5C144B8E7A4D8206A8D8266164963B74F846A00FDE4268CE7E41C6145ECB38F1DE',
+    LONG_MESSAGE);
+
+end;
+
+procedure TTestPascalCoinECIES.TestPacalCoinECIESEncryptDecrypt;
+begin
+  DoTestPascalCoinECIESEncryptDecrypt('1', TKeyType.SECP256K1,
+    '5EEBDD98BBD3F96A1A69020F58C147624AF27F9E9831F05EC42A190DD2FB0DF1',
+    '327D9618E226B991E47BA2EF81CEC0AFC0436E3CC22F04454749FCA2AFBB52F7',
+    'BE70064DAB4A2A0681889F1EE51B6BB2348A394317EAC2BEA38E6ABC2D78D307',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESEncryptDecrypt('2', TKeyType.SECP256K1,
+    '5EEBDD98BBD3F96A1A69020F58C147624AF27F9E9831F05EC42A190DD2FB0DF1',
+    '327D9618E226B991E47BA2EF81CEC0AFC0436E3CC22F04454749FCA2AFBB52F7',
+    'BE70064DAB4A2A0681889F1EE51B6BB2348A394317EAC2BEA38E6ABC2D78D307',
+    LONG_MESSAGE);
+
+  DoTestPascalCoinECIESEncryptDecrypt('3', TKeyType.SECP384R1,
+    '889ED91943C05D599DA1CEF146D68495E650F800B74B6310AD9614DC55E2ABE01604E3398E548E0D4AD82A887070B787',
+    'F9BB6DD66F26E406AADDC666A65229904A22BA500EACC3D6FA2B7BD4E7D33204BBE87741462258CCD8FB32F43D52ABF0',
+    'F7AB9F5D3676FC98946F35269BD73082A57ABF4B66864C703DACB238EA4FBEE2390399C655C6CDAABB26FCD34FD749D7',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESEncryptDecrypt('4', TKeyType.SECP384R1,
+    '889ED91943C05D599DA1CEF146D68495E650F800B74B6310AD9614DC55E2ABE01604E3398E548E0D4AD82A887070B787',
+    'F9BB6DD66F26E406AADDC666A65229904A22BA500EACC3D6FA2B7BD4E7D33204BBE87741462258CCD8FB32F43D52ABF0',
+    'F7AB9F5D3676FC98946F35269BD73082A57ABF4B66864C703DACB238EA4FBEE2390399C655C6CDAABB26FCD34FD749D7',
+    LONG_MESSAGE);
+
+  DoTestPascalCoinECIESEncryptDecrypt('5', TKeyType.SECP521R1,
+    '6316522337DA679C1EF338E54509C19793FC3C02D53F12AF79322086AAA4AA2BAD8108EDA2000763DC99C6DA1909712C2E96A9F2BAB7502BCD2DDD7B39880F0808',
+    '014919D3527C3D31FF9EE84D5009E9BA4977B6E6C075EB454B2BA086E75605D88F895247F8E3968F3C26B840D806DB2A6FCFAE96D90A80A955BC277FEA0D69A086BE',
+    '01FDA4AFC30977BF0B57CD3202497880D905AF6BF9CFD275EAE5CD6E68E639D4DEBE12C3EA3EA2ED13803D5751FED86C2F35952DBDC935A85C75FEBC371B01698097',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESEncryptDecrypt('6', TKeyType.SECP521R1,
+    '6316522337DA679C1EF338E54509C19793FC3C02D53F12AF79322086AAA4AA2BAD8108EDA2000763DC99C6DA1909712C2E96A9F2BAB7502BCD2DDD7B39880F0808',
+    '014919D3527C3D31FF9EE84D5009E9BA4977B6E6C075EB454B2BA086E75605D88F895247F8E3968F3C26B840D806DB2A6FCFAE96D90A80A955BC277FEA0D69A086BE',
+    '01FDA4AFC30977BF0B57CD3202497880D905AF6BF9CFD275EAE5CD6E68E639D4DEBE12C3EA3EA2ED13803D5751FED86C2F35952DBDC935A85C75FEBC371B01698097',
+    LONG_MESSAGE);
+
+  DoTestPascalCoinECIESEncryptDecrypt('7', TKeyType.SECT283K1,
+    '0121EFFE82FE34BA6D1B5635903924801CADD54EF2804B56624BB8C0BFBF9F33BB42EADD',
+    '01747F38A49C099DA25231AE47F0820216EDEC6F6DB51A28280ABDCC65B652D76529BB88',
+    '05535E7555704E2EAA1C3A29FCF50622D67F65DDB1EA294D92C4BDDEE403DE379E26B280',
+    SHORT_MESSAGE);
+
+  DoTestPascalCoinECIESEncryptDecrypt('8', TKeyType.SECT283K1,
+    '0121EFFE82FE34BA6D1B5635903924801CADD54EF2804B56624BB8C0BFBF9F33BB42EADD',
+    '01747F38A49C099DA25231AE47F0820216EDEC6F6DB51A28280ABDCC65B652D76529BB88',
+    '05535E7555704E2EAA1C3A29FCF50622D67F65DDB1EA294D92C4BDDEE403DE379E26B280',
+    LONG_MESSAGE);
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestPascalCoinECIES);
+{$ELSE}
+  RegisterTest(TTestPascalCoinECIES.Suite);
+{$ENDIF FPC}
+
+end.

+ 45 - 4
CryptoLib.Tests/src/Others/ECTests.pas

@@ -35,6 +35,7 @@ uses
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpSecureRandom,
   ClpSecureRandom,
   ClpISecureRandom,
   ClpISecureRandom,
+  ClpIX9ECParameters,
   ClpECDsaSigner,
   ClpECDsaSigner,
   ClpIECDsaSigner,
   ClpIECDsaSigner,
   ClpIBasicAgreement,
   ClpIBasicAgreement,
@@ -53,6 +54,7 @@ uses
   ClpIECKeyGenerationParameters,
   ClpIECKeyGenerationParameters,
   ClpECKeyGenerationParameters,
   ClpECKeyGenerationParameters,
   ClpIAsymmetricCipherKeyPair,
   ClpIAsymmetricCipherKeyPair,
+  ClpCustomNamedCurves,
   ClpECC,
   ClpECC,
   ClpIECC,
   ClpIECC,
   ClpEncoders,
   ClpEncoders,
@@ -115,12 +117,14 @@ type
     /// <summary>
     /// <summary>
     /// key generation test
     /// key generation test
     /// </summary>
     /// </summary>
-    procedure TestECDsaKeyGenTest();
+    procedure TestECDsaKeyGen();
 
 
     /// <summary>
     /// <summary>
     /// Basic Key Agreement Test
     /// Basic Key Agreement Test
     /// </summary>
     /// </summary>
-    procedure TestECBasicAgreementTest();
+    procedure TestECBasicAgreement();
+
+    procedure TestECDHBasicAgreementCofactor();
 
 
   end;
   end;
 
 
@@ -604,7 +608,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TTestEC.TestECDsaKeyGenTest;
+procedure TTestEC.TestECDsaKeyGen;
 var
 var
   random: ISecureRandom;
   random: ISecureRandom;
   n: TBigInteger;
   n: TBigInteger;
@@ -663,7 +667,7 @@ begin
   end;
   end;
 end;
 end;
 
 
-procedure TTestEC.TestECBasicAgreementTest;
+procedure TTestEC.TestECBasicAgreement;
 var
 var
   random: ISecureRandom;
   random: ISecureRandom;
   n, k1, k2: TBigInteger;
   n, k1, k2: TBigInteger;
@@ -738,6 +742,43 @@ begin
 
 
 end;
 end;
 
 
+procedure TTestEC.TestECDHBasicAgreementCofactor;
+var
+  random: ISecureRandom;
+  x9: IX9ECParameters;
+  ec: IECDomainParameters;
+  kpg: IECKeyPairGenerator;
+  p1, p2: IAsymmetricCipherKeyPair;
+  e1, e2: IBasicAgreement;
+  k1, k2: TBigInteger;
+begin
+  random := TSecureRandom.Create();
+
+  x9 := TCustomNamedCurves.GetByName('curve25519');
+  ec := TECDomainParameters.Create(x9.curve, x9.G, x9.n, x9.H, x9.GetSeed());
+
+  kpg := TECKeyPairGenerator.Create();
+  kpg.Init(TECKeyGenerationParameters.Create(ec, random)
+    as IECKeyGenerationParameters);
+
+  p1 := kpg.GenerateKeyPair();
+  p2 := kpg.GenerateKeyPair();
+
+  e1 := TECDHBasicAgreement.Create();
+  e2 := TECDHBasicAgreement.Create();
+
+  e1.Init(p1.Private);
+  e2.Init(p2.Private);
+
+  k1 := e1.CalculateAgreement(p2.Public);
+  k2 := e2.CalculateAgreement(p1.Public);
+
+  if (not(k1.Equals(k2))) then
+  begin
+    Fail('calculated agreement test failed');
+  end;
+end;
+
 initialization
 initialization
 
 
 // Register any test cases with the test runner
 // Register any test cases with the test runner

+ 2 - 3
CryptoLib.Tests/src/Utils/ClpFixedSecureRandom.pas

@@ -53,8 +53,6 @@ type
 
 
     FisAndroidStyle, FisClasspathStyle, FisRegularStyle: Boolean;
     FisAndroidStyle, FisClasspathStyle, FisRegularStyle: Boolean;
 
 
-    function GetIsExhausted: Boolean; inline;
-
     class procedure Boot(); static;
     class procedure Boot(); static;
     class constructor FixedSecureRandom();
     class constructor FixedSecureRandom();
 
 
@@ -75,6 +73,7 @@ type
     const v: TCryptoLibByteArray): TCryptoLibByteArray; static;
     const v: TCryptoLibByteArray): TCryptoLibByteArray; static;
 
 
   strict protected
   strict protected
+    function GetIsExhausted: Boolean; inline;
     constructor Create(const data: TCryptoLibByteArray); overload;
     constructor Create(const data: TCryptoLibByteArray); overload;
 
 
   public
   public
@@ -89,7 +88,7 @@ type
     strict private
     strict private
     var
     var
       Fdata: TCryptoLibByteArray;
       Fdata: TCryptoLibByteArray;
-
+    strict protected
       function GetData: TCryptoLibByteArray; inline;
       function GetData: TCryptoLibByteArray; inline;
 
 
     public
     public

+ 18 - 23
CryptoLib/src/Asn1/ClpAsn1Objects.pas

@@ -670,10 +670,9 @@ type
   var
   var
     F_out: TStream;
     F_out: TStream;
 
 
-    function GetOut: TStream; inline;
-
   strict protected
   strict protected
     constructor Create(outStream: TStream);
     constructor Create(outStream: TStream);
+    function GetOut: TStream; inline;
     property &Out: TStream read GetOut;
     property &Out: TStream read GetOut;
 
 
   public
   public
@@ -703,10 +702,10 @@ type
   strict private
   strict private
   var
   var
     FStr: TCryptoLibByteArray;
     FStr: TCryptoLibByteArray;
-    function GetStr: TCryptoLibByteArray; inline;
-    function GetParser: IAsn1OctetStringParser; inline;
 
 
   strict protected
   strict protected
+    function GetStr: TCryptoLibByteArray; inline;
+    function GetParser: IAsn1OctetStringParser; inline;
     function Asn1GetHashCode(): Int32; override;
     function Asn1GetHashCode(): Int32; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
 
 
@@ -766,11 +765,6 @@ type
   var
   var
     FSeq: TList<IAsn1Encodable>;
     FSeq: TList<IAsn1Encodable>;
 
 
-    function GetCount: Int32; virtual;
-    function GetParser: IAsn1SequenceParser; virtual;
-    function GetSelf(Index: Integer): IAsn1Encodable; virtual;
-    function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
-
   type
   type
     TAsn1SequenceParserImpl = class sealed(TInterfacedObject,
     TAsn1SequenceParserImpl = class sealed(TInterfacedObject,
       IAsn1SequenceParserImpl, IAsn1SequenceParser)
       IAsn1SequenceParserImpl, IAsn1SequenceParser)
@@ -788,6 +782,10 @@ type
     end;
     end;
 
 
   strict protected
   strict protected
+    function GetCount: Int32; virtual;
+    function GetParser: IAsn1SequenceParser; virtual;
+    function GetSelf(Index: Integer): IAsn1Encodable; virtual;
+    function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
     function Asn1GetHashCode(): Int32; override;
     function Asn1GetHashCode(): Int32; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     procedure AddObject(const obj: IAsn1Encodable); inline;
     procedure AddObject(const obj: IAsn1Encodable); inline;
@@ -1043,10 +1041,6 @@ type
     Fexplicitly: Boolean;
     Fexplicitly: Boolean;
     Fobj: IAsn1Encodable;
     Fobj: IAsn1Encodable;
 
 
-    function GetTagNo: Int32; inline;
-    function Getexplicitly: Boolean; inline;
-    function Getobj: IAsn1Encodable; inline;
-
   strict protected
   strict protected
     // /**
     // /**
     // * @param tagNo the tag number for this object.
     // * @param tagNo the tag number for this object.
@@ -1061,6 +1055,10 @@ type
     constructor Create(explicitly: Boolean; tagNo: Int32;
     constructor Create(explicitly: Boolean; tagNo: Int32;
       const obj: IAsn1Encodable); overload;
       const obj: IAsn1Encodable); overload;
 
 
+    function GetTagNo: Int32; inline;
+    function Getexplicitly: Boolean; inline;
+    function Getobj: IAsn1Encodable; inline;
+
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
 
 
     function Asn1GetHashCode(): Int32; override;
     function Asn1GetHashCode(): Int32; override;
@@ -1158,11 +1156,6 @@ type
     F_set: TList<IAsn1Encodable>;
     F_set: TList<IAsn1Encodable>;
     FisSorted: Boolean;
     FisSorted: Boolean;
 
 
-    function GetCount: Int32; virtual;
-    function GetParser: IAsn1SetParser; inline;
-    function GetSelf(Index: Integer): IAsn1Encodable; virtual;
-    function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
-
     /// <summary>
     /// <summary>
     /// return true if a &lt;= b (arrays are assumed padded with zeros).
     /// return true if a &lt;= b (arrays are assumed padded with zeros).
     /// </summary>
     /// </summary>
@@ -1184,6 +1177,10 @@ type
     end;
     end;
 
 
   strict protected
   strict protected
+    function GetCount: Int32; virtual;
+    function GetParser: IAsn1SetParser; inline;
+    function GetSelf(Index: Integer): IAsn1Encodable; virtual;
+    function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
     function Asn1GetHashCode(): Int32; override;
     function Asn1GetHashCode(): Int32; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     procedure AddObject(const obj: IAsn1Encodable); inline;
     procedure AddObject(const obj: IAsn1Encodable); inline;
@@ -1382,13 +1379,12 @@ type
     Ftag: Int32;
     Ftag: Int32;
     Foctets: TCryptoLibByteArray;
     Foctets: TCryptoLibByteArray;
 
 
-    function GetApplicationTag: Int32; inline;
-    function GetLengthOfHeader(const data: TCryptoLibByteArray): Int32; inline;
-
     class function ReplaceTagNumber(newTag: Int32;
     class function ReplaceTagNumber(newTag: Int32;
       const input: TCryptoLibByteArray): TCryptoLibByteArray; static;
       const input: TCryptoLibByteArray): TCryptoLibByteArray; static;
 
 
   strict protected
   strict protected
+    function GetApplicationTag: Int32; inline;
+    function GetLengthOfHeader(const data: TCryptoLibByteArray): Int32; inline;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
     function Asn1GetHashCode(): Int32; override;
     function Asn1GetHashCode(): Int32; override;
 
 
@@ -1595,13 +1591,12 @@ type
     F_tagged, F_isExplicit: Boolean;
     F_tagged, F_isExplicit: Boolean;
     F_tagNo: Int32;
     F_tagNo: Int32;
 
 
-    procedure WriteHdr(tag: Int32);
-
   strict protected
   strict protected
     constructor Create(outStream: TStream); overload;
     constructor Create(outStream: TStream); overload;
     constructor Create(outStream: TStream; tagNo: Int32;
     constructor Create(outStream: TStream; tagNo: Int32;
       isExplicit: Boolean); overload;
       isExplicit: Boolean); overload;
 
 
+    procedure WriteHdr(tag: Int32);
     procedure WriteBerHeader(tag: Int32);
     procedure WriteBerHeader(tag: Int32);
     procedure WriteBerBody(contentStream: TStream);
     procedure WriteBerBody(contentStream: TStream);
     procedure WriteBerEnd();
     procedure WriteBerEnd();

+ 112 - 0
CryptoLib/src/Asn1/Edec/ClpEdECObjectIdentifiers.pas

@@ -0,0 +1,112 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEdECObjectIdentifiers;
+
+interface
+
+uses
+  ClpAsn1Objects,
+  ClpIAsn1Objects;
+
+type
+
+  /// <summary>
+  /// Edwards Elliptic Curve Object Identifiers (RFC 8410)
+  /// </summary>
+  TEdECObjectIdentifiers = class abstract(TObject)
+
+  strict private
+
+  class var
+
+    FIsBooted: Boolean;
+    Fid_edwards_curve_algs, Fid_X25519, Fid_X448, Fid_Ed25519,
+      Fid_Ed448: IDerObjectIdentifier;
+
+    class constructor EdECObjectIdentifiers();
+  private
+    class function Getid_Ed25519: IDerObjectIdentifier; static; inline;
+    class function Getid_Ed448: IDerObjectIdentifier; static; inline;
+    class function Getid_edwards_curve_algs: IDerObjectIdentifier;
+      static; inline;
+    class function Getid_X25519: IDerObjectIdentifier; static; inline;
+    class function Getid_X448: IDerObjectIdentifier; static; inline;
+
+  public
+
+    class property id_edwards_curve_algs: IDerObjectIdentifier
+      read Getid_edwards_curve_algs;
+    class property id_X25519: IDerObjectIdentifier read Getid_X25519;
+    class property id_X448: IDerObjectIdentifier read Getid_X448;
+    class property id_Ed25519: IDerObjectIdentifier read Getid_Ed25519;
+    class property id_Ed448: IDerObjectIdentifier read Getid_Ed448;
+
+    class procedure Boot(); static;
+  end;
+
+implementation
+
+{ TEdECObjectIdentifiers }
+
+class procedure TEdECObjectIdentifiers.Boot;
+begin
+  if not FIsBooted then
+  begin
+    Fid_edwards_curve_algs := TDerObjectIdentifier.Create('1.3.101');
+
+    Fid_X25519 := id_edwards_curve_algs.Branch('110');
+    Fid_X448 := id_edwards_curve_algs.Branch('111');
+    Fid_Ed25519 := id_edwards_curve_algs.Branch('112');
+    Fid_Ed448 := id_edwards_curve_algs.Branch('113');
+
+    FIsBooted := True;
+  end;
+end;
+
+class constructor TEdECObjectIdentifiers.EdECObjectIdentifiers;
+begin
+  TEdECObjectIdentifiers.Boot();
+end;
+
+class function TEdECObjectIdentifiers.Getid_Ed25519: IDerObjectIdentifier;
+begin
+  result := Fid_Ed25519;
+end;
+
+class function TEdECObjectIdentifiers.Getid_Ed448: IDerObjectIdentifier;
+begin
+  result := Fid_Ed448;
+end;
+
+class function TEdECObjectIdentifiers.Getid_edwards_curve_algs
+  : IDerObjectIdentifier;
+begin
+  result := Fid_edwards_curve_algs;
+end;
+
+class function TEdECObjectIdentifiers.Getid_X25519: IDerObjectIdentifier;
+begin
+  result := Fid_X25519;
+end;
+
+class function TEdECObjectIdentifiers.Getid_X448: IDerObjectIdentifier;
+begin
+  result := Fid_X448;
+end;
+
+end.

+ 1 - 1
CryptoLib/src/Asn1/X9/ClpX9ECParametersHolder.pas

@@ -32,7 +32,6 @@ type
 
 
   strict private
   strict private
     Fparameters: IX9ECParameters;
     Fparameters: IX9ECParameters;
-    function GetParameters: IX9ECParameters; inline;
 
 
     class var
     class var
 
 
@@ -43,6 +42,7 @@ type
     class destructor DestroyX9ECParametersHolder();
     class destructor DestroyX9ECParametersHolder();
 
 
   strict protected
   strict protected
+    function GetParameters: IX9ECParameters; inline;
     function CreateParameters(): IX9ECParameters; virtual; abstract;
     function CreateParameters(): IX9ECParameters; virtual; abstract;
 
 
   public
   public

+ 86 - 0
CryptoLib/src/Crypto/Agreement/ClpX25519Agreement.pas

@@ -0,0 +1,86 @@
+{ *********************************************************************************** }
+{ *                              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 ClpX25519Agreement;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIRawAgreement,
+  ClpIX25519Agreement,
+  ClpICipherParameters,
+  ClpX25519PrivateKeyParameters,
+  ClpIX25519PrivateKeyParameters,
+  ClpIX25519PublicKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SWrongInitCipherParameter =
+    'The Init Parameter does not Contain the Private Key';
+
+type
+  TX25519Agreement = class(TInterfacedObject, IX25519Agreement, IRawAgreement)
+
+  strict protected
+  var
+    FPrivateKey: IX25519PrivateKeyParameters;
+
+    function GetAgreementSize(): Int32; virtual;
+
+  public
+
+    procedure Init(const parameters: ICipherParameters); virtual;
+
+    procedure CalculateAgreement(const publicKey: ICipherParameters;
+      const buf: TCryptoLibByteArray; off: Int32);
+
+    property AgreementSize: Int32 read GetAgreementSize;
+
+  end;
+
+implementation
+
+{ TX25519Agreement }
+
+function TX25519Agreement.GetAgreementSize: Int32;
+begin
+  result := TX25519PrivateKeyParameters.SecretSize;
+end;
+
+procedure TX25519Agreement.Init(const parameters: ICipherParameters);
+begin
+  if Supports(parameters, IX25519PrivateKeyParameters) then
+  begin
+    FPrivateKey := parameters as IX25519PrivateKeyParameters;
+  end
+  else
+  begin
+    raise EInvalidParameterCryptoLibException.CreateRes
+      (@SWrongInitCipherParameter);
+  end;
+end;
+
+procedure TX25519Agreement.CalculateAgreement(const publicKey
+  : ICipherParameters; const buf: TCryptoLibByteArray; off: Int32);
+begin
+  FPrivateKey.GenerateSecret(publicKey as IX25519PublicKeyParameters, buf, off);
+end;
+
+end.

+ 1 - 1
CryptoLib/src/Crypto/ClpAsymmetricKeyParameter.pas

@@ -33,10 +33,10 @@ type
   var
   var
     FprivateKey: Boolean;
     FprivateKey: Boolean;
 
 
+  strict protected
     function GetPrivateKey: Boolean; inline;
     function GetPrivateKey: Boolean; inline;
     function GetIsPrivate: Boolean; inline;
     function GetIsPrivate: Boolean; inline;
 
 
-  protected
     constructor Create(privateKey: Boolean);
     constructor Create(privateKey: Boolean);
 
 
   public
   public

+ 3 - 4
CryptoLib/src/Crypto/ClpBufferedCipherBase.pas

@@ -54,13 +54,13 @@ type
   const
   const
     BUFFER_SIZE = Int32(64 * 1024); // 64Kb
     BUFFER_SIZE = Int32(64 * 1024); // 64Kb
 
 
+  strict protected
+
+    function GetAlgorithmName: String; virtual; abstract;
     function GetBufferSize: Int32; inline;
     function GetBufferSize: Int32; inline;
     procedure SetBufferSize(value: Int32); inline;
     procedure SetBufferSize(value: Int32); inline;
     function GetOnProgress: TBufferedCipherProgressEvent; inline;
     function GetOnProgress: TBufferedCipherProgressEvent; inline;
     procedure SetOnProgress(const value: TBufferedCipherProgressEvent); inline;
     procedure SetOnProgress(const value: TBufferedCipherProgressEvent); inline;
-
-  strict protected
-
     procedure DoProgress(AProcessed, ATotal: Int64); virtual;
     procedure DoProgress(AProcessed, ATotal: Int64); virtual;
 
 
     class property EmptyBuffer: TCryptoLibByteArray read GetEmptyBuffer;
     class property EmptyBuffer: TCryptoLibByteArray read GetEmptyBuffer;
@@ -123,7 +123,6 @@ type
 
 
     procedure Reset(); virtual; abstract;
     procedure Reset(); virtual; abstract;
 
 
-    function GetAlgorithmName: String; virtual; abstract;
     property AlgorithmName: String read GetAlgorithmName;
     property AlgorithmName: String read GetAlgorithmName;
 
 
     /// <summary>
     /// <summary>

+ 195 - 0
CryptoLib/src/Crypto/ClpBufferedStreamCipher.pas

@@ -0,0 +1,195 @@
+{ *********************************************************************************** }
+{ *                              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 ClpBufferedStreamCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIStreamCipher,
+  ClpICipherParameters,
+  ClpIParametersWithRandom,
+  ClpIBufferedStreamCipher,
+  ClpBufferedCipherBase,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SCipherNil = 'Cipher Instance Cannot be Nil';
+
+type
+  TBufferedStreamCipher = class(TBufferedCipherBase, IBufferedStreamCipher)
+
+  strict private
+  var
+    FCipher: IStreamCipher;
+
+  strict protected
+    function GetAlgorithmName: String; override;
+
+  public
+    constructor Create(const cipher: IStreamCipher);
+
+    procedure Init(forEncryption: Boolean;
+      const parameters: ICipherParameters); override;
+
+    function GetBlockSize(): Int32; override;
+
+    function GetOutputSize(inputLen: Int32): Int32; override;
+
+    function GetUpdateOutputSize(inputLen: Int32): Int32; override;
+
+    function ProcessByte(input: Byte): TCryptoLibByteArray; overload; override;
+    function ProcessByte(input: Byte; const output: TCryptoLibByteArray;
+      outOff: Int32): Int32; overload; override;
+
+    function ProcessBytes(const input: TCryptoLibByteArray;
+      inOff, Length: Int32): TCryptoLibByteArray; overload; override;
+    function ProcessBytes(const input: TCryptoLibByteArray;
+      inOff, Length: Int32; const output: TCryptoLibByteArray; outOff: Int32)
+      : Int32; overload; override;
+
+    function DoFinal(): TCryptoLibByteArray; overload; override;
+    function DoFinal(const input: TCryptoLibByteArray; inOff, Length: Int32)
+      : TCryptoLibByteArray; overload; override;
+
+    procedure Reset(); override;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TBufferedStreamCipher }
+
+constructor TBufferedStreamCipher.Create(const cipher: IStreamCipher);
+begin
+  Inherited Create();
+  if (cipher = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SCipherNil);
+  end;
+
+  FCipher := cipher;
+end;
+
+function TBufferedStreamCipher.GetAlgorithmName: String;
+begin
+  result := FCipher.AlgorithmName;
+end;
+
+function TBufferedStreamCipher.GetBlockSize: Int32;
+begin
+  result := 0;
+end;
+
+function TBufferedStreamCipher.GetOutputSize(inputLen: Int32): Int32;
+begin
+  result := inputLen;
+end;
+
+function TBufferedStreamCipher.GetUpdateOutputSize(inputLen: Int32): Int32;
+begin
+  result := inputLen;
+end;
+
+procedure TBufferedStreamCipher.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  LParameters: ICipherParameters;
+begin
+  LParameters := parameters;
+  if Supports(LParameters, IParametersWithRandom) then
+  begin
+    LParameters := (LParameters as IParametersWithRandom).parameters;
+  end;
+  FCipher.Init(forEncryption, LParameters);
+end;
+
+function TBufferedStreamCipher.ProcessByte(input: Byte;
+  const output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+  if (outOff >= System.Length(output)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooSmall);
+  end;
+  output[outOff] := FCipher.ReturnByte(input);
+  result := 1;
+end;
+
+function TBufferedStreamCipher.ProcessByte(input: Byte): TCryptoLibByteArray;
+begin
+  result := TCryptoLibByteArray.Create(FCipher.ReturnByte(input));
+end;
+
+function TBufferedStreamCipher.ProcessBytes(const input: TCryptoLibByteArray;
+  inOff, Length: Int32; const output: TCryptoLibByteArray;
+  outOff: Int32): Int32;
+begin
+  if (Length < 1) then
+  begin
+    result := 0;
+    Exit;
+  end;
+
+  if (Length > 0) then
+  begin
+    FCipher.ProcessBytes(input, inOff, Length, output, outOff);
+  end;
+
+  result := Length;
+end;
+
+function TBufferedStreamCipher.ProcessBytes(const input: TCryptoLibByteArray;
+  inOff, Length: Int32): TCryptoLibByteArray;
+begin
+  if (Length < 1) then
+  begin
+    result := Nil;
+    Exit;
+  end;
+  System.SetLength(result, Length);
+  FCipher.ProcessBytes(input, inOff, Length, result, 0);
+end;
+
+function TBufferedStreamCipher.DoFinal: TCryptoLibByteArray;
+begin
+  Reset();
+  result := EmptyBuffer;
+end;
+
+function TBufferedStreamCipher.DoFinal(const input: TCryptoLibByteArray;
+  inOff, Length: Int32): TCryptoLibByteArray;
+begin
+  if (Length < 1) then
+  begin
+    result := EmptyBuffer;
+    Exit;
+  end;
+  result := ProcessBytes(input, inOff, Length);
+  Reset();
+end;
+
+procedure TBufferedStreamCipher.Reset;
+begin
+  FCipher.Reset();
+end;
+
+end.

+ 22 - 28
CryptoLib/src/Crypto/ClpIESCipher.pas

@@ -28,7 +28,8 @@ uses
   ClpIECIESPublicKeyParser,
   ClpIECIESPublicKeyParser,
   ClpECIESPublicKeyParser,
   ClpECIESPublicKeyParser,
   ClpIAsymmetricKeyParameter,
   ClpIAsymmetricKeyParameter,
-  ClpIIESWithCipherParameters,
+  ClpIAlgorithmParameterSpec,
+  ClpIIESParameterSpec,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpIParametersWithRandom,
   ClpIParametersWithRandom,
   ClpIECKeyParameters,
   ClpIECKeyParameters,
@@ -53,10 +54,10 @@ resourcestring
     'Must be Passed Recipient''s Public EC Key for Encryption';
     'Must be Passed Recipient''s Public EC Key for Encryption';
   SInvalidPrivateKey =
   SInvalidPrivateKey =
     'Must be Passed Recipient''s Private EC Key for Decryption';
     'Must be Passed Recipient''s Private EC Key for Decryption';
-  SIESCipherParameterNil = 'IES Cipher Parameters Cannot Be Nil';
+  SIAlgorithmParameterSpecNil = 'Parameter Spec Cannot Be Nil';
   SUnableToProcessBlock = 'Unable to Process Block. "%s"';
   SUnableToProcessBlock = 'Unable to Process Block. "%s"';
-  SIESCipherParameterError = 'IES Cipher Parameter Error';
-  SNonceInvalidLength = 'NONCE in IES Parameters Needs to be "%s" Bytes Long';
+  SIESParameterSpecError = 'Must be Passed IES Parameter Spec';
+  SNonceInvalidLength = 'Nonce in IES Parameters Needs to be "%s" Bytes Long';
 
 
 type
 type
   TIESCipher = class sealed(TInterfacedObject, IIESCipher)
   TIESCipher = class sealed(TInterfacedObject, IIESCipher)
@@ -67,7 +68,7 @@ type
     FEngine: IIESEngine;
     FEngine: IIESEngine;
     FForEncryption: Boolean;
     FForEncryption: Boolean;
     FBuffer: TMemoryStream;
     FBuffer: TMemoryStream;
-    FIESCipherParameters: IIESWithCipherParameters;
+    FEngineSpec: IIESParameterSpec;
     Fkey: IAsymmetricKeyParameter;
     Fkey: IAsymmetricKeyParameter;
     FRandom: ISecureRandom;
     FRandom: ISecureRandom;
 
 
@@ -75,8 +76,7 @@ type
 
 
   public
   public
     procedure Init(ForEncryption: Boolean; const Key: ICipherParameters;
     procedure Init(ForEncryption: Boolean; const Key: ICipherParameters;
-      const IESCipherParameters: IIESWithCipherParameters;
-      const Random: ISecureRandom);
+      const EngineSpec: IAlgorithmParameterSpec; const Random: ISecureRandom);
 
 
     procedure ProcessBytes(const input: TCryptoLibByteArray); overload;
     procedure ProcessBytes(const input: TCryptoLibByteArray); overload;
     procedure ProcessBytes(const input: TCryptoLibByteArray;
     procedure ProcessBytes(const input: TCryptoLibByteArray;
@@ -92,8 +92,7 @@ type
       inputOffset, inputLen: Int32; const output: TCryptoLibByteArray;
       inputOffset, inputLen: Int32; const output: TCryptoLibByteArray;
       outputOffset: Int32): Int32; overload;
       outputOffset: Int32): Int32; overload;
 
 
-    constructor Create(const Engine: IIESEngine); overload;
-    constructor Create(const Engine: IIESEngine; ivLength: Int32); overload;
+    constructor Create(const Engine: IIESEngine; ivLength: Int32 = 0);
     destructor Destroy(); override;
     destructor Destroy(); override;
 
 
   end;
   end;
@@ -109,11 +108,6 @@ begin
   FBuffer.Read(Result[0], FBuffer.Size);
   FBuffer.Read(Result[0], FBuffer.Size);
 end;
 end;
 
 
-constructor TIESCipher.Create(const Engine: IIESEngine);
-begin
-  Create(Engine, 0);
-end;
-
 constructor TIESCipher.Create(const Engine: IIESEngine; ivLength: Int32);
 constructor TIESCipher.Create(const Engine: IIESEngine; ivLength: Int32);
 begin
 begin
   Inherited Create();
   Inherited Create();
@@ -142,13 +136,13 @@ begin
   FBuffer.SetSize(Int64(0));
   FBuffer.SetSize(Int64(0));
 
 
   // Convert parameters for use in IESEngine
   // Convert parameters for use in IESEngine
-  params := TIESWithCipherParameters.Create(FIESCipherParameters.GetDerivationV,
-    FIESCipherParameters.GetEncodingV, FIESCipherParameters.MacKeySize,
-    FIESCipherParameters.CipherKeySize);
+  params := TIESWithCipherParameters.Create(FEngineSpec.GetDerivationV,
+    FEngineSpec.GetEncodingV, FEngineSpec.MacKeySize,
+    FEngineSpec.CipherKeySize);
 
 
-  if (FIESCipherParameters.Nonce <> Nil) then
+  if (FEngineSpec.Nonce <> Nil) then
   begin
   begin
-    params := TParametersWithIV.Create(params, FIESCipherParameters.Nonce);
+    params := TParametersWithIV.Create(params, FEngineSpec.Nonce);
   end;
   end;
   ecParams := (Fkey as IECKeyParameters).Parameters;
   ecParams := (Fkey as IECKeyParameters).Parameters;
 
 
@@ -159,7 +153,7 @@ begin
     gen.Init(TECKeyGenerationParameters.Create(ecParams, FRandom)
     gen.Init(TECKeyGenerationParameters.Create(ecParams, FRandom)
       as IECKeyGenerationParameters);
       as IECKeyGenerationParameters);
 
 
-    UsePointCompression := FIESCipherParameters.PointCompression;
+    UsePointCompression := FEngineSpec.PointCompression;
 
 
     kGen := TEphemeralKeyPairGenerator.Create(gen,
     kGen := TEphemeralKeyPairGenerator.Create(gen,
       TKeyEncoder.Create(UsePointCompression) as IKeyEncoder);
       TKeyEncoder.Create(UsePointCompression) as IKeyEncoder);
@@ -225,8 +219,7 @@ begin
 end;
 end;
 
 
 procedure TIESCipher.Init(ForEncryption: Boolean; const Key: ICipherParameters;
 procedure TIESCipher.Init(ForEncryption: Boolean; const Key: ICipherParameters;
-  const IESCipherParameters: IIESWithCipherParameters;
-  const Random: ISecureRandom);
+  const EngineSpec: IAlgorithmParameterSpec; const Random: ISecureRandom);
 var
 var
   LKey: ICipherParameters;
   LKey: ICipherParameters;
   Nonce: TCryptoLibByteArray;
   Nonce: TCryptoLibByteArray;
@@ -234,21 +227,22 @@ begin
 
 
   FForEncryption := ForEncryption;
   FForEncryption := ForEncryption;
 
 
-  if (IESCipherParameters = Nil) then
+  if (EngineSpec = Nil) then
   begin
   begin
-    raise EArgumentNilCryptoLibException.CreateRes(@SIESCipherParameterNil);
+    raise EArgumentNilCryptoLibException.CreateRes
+      (@SIAlgorithmParameterSpecNil);
   end
   end
-  else if (Supports(IESCipherParameters, IIESWithCipherParameters)) then
+  else if (Supports(EngineSpec, IIESParameterSpec)) then
   begin
   begin
-    FIESCipherParameters := IESCipherParameters as IIESWithCipherParameters;
+    FEngineSpec := EngineSpec as IIESParameterSpec;
   end
   end
   else
   else
   begin
   begin
     raise EInvalidParameterCryptoLibException.CreateRes
     raise EInvalidParameterCryptoLibException.CreateRes
-      (@SIESCipherParameterError);
+      (@SIESParameterSpecError);
   end;
   end;
 
 
-  Nonce := FIESCipherParameters.Nonce;
+  Nonce := FEngineSpec.Nonce;
 
 
   if ((FivLength <> 0) and ((Nonce = Nil) or (System.length(Nonce) <>
   if ((FivLength <> 0) and ((Nonce = Nil) or (System.length(Nonce) <>
     FivLength))) then
     FivLength))) then

+ 2 - 0
CryptoLib/src/Crypto/ClpKeyGenerationParameters.pas

@@ -41,6 +41,8 @@ type
     FRandom: ISecureRandom;
     FRandom: ISecureRandom;
     FStrength: Int32;
     FStrength: Int32;
 
 
+  strict protected
+
     /// <returns>
     /// <returns>
     /// return the generators random source.
     /// return the generators random source.
     /// </returns>
     /// </returns>

+ 66 - 12
CryptoLib/src/Crypto/EC/ClpCustomNamedCurves.pas

@@ -41,6 +41,8 @@ uses
   ClpISecP521R1Custom,
   ClpISecP521R1Custom,
   ClpSecT283Custom,
   ClpSecT283Custom,
   ClpISecT283Custom,
   ClpISecT283Custom,
+  ClpCurve25519Custom,
+  ClpICurve25519Custom,
   ClpIECC,
   ClpIECC,
   ClpX9ECC,
   ClpX9ECC,
   ClpIX9ECC,
   ClpIX9ECC,
@@ -67,8 +69,8 @@ type
 
 
     class function GetNames: TCryptoLibStringArray; static; inline;
     class function GetNames: TCryptoLibStringArray; static; inline;
 
 
-    // class procedure DefineCurve(const name: String;
-    // const holder: IX9ECParametersHolder); static; inline;
+    class procedure DefineCurve(const name: String;
+      const holder: IX9ECParametersHolder); static; inline;
 
 
     class procedure DefineCurveWithOid(const name: String;
     class procedure DefineCurveWithOid(const name: String;
       const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
       const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
@@ -116,6 +118,22 @@ type
     // */
     // */
     class property Names: TCryptoLibStringArray read GetNames;
     class property Names: TCryptoLibStringArray read GetNames;
 
 
+  type
+
+    /// <summary>
+    /// curve25519
+    /// </summary>
+    TCurve25519Holder = class sealed(TX9ECParametersHolder,
+      IX9ECParametersHolder)
+
+    strict protected
+      function CreateParameters(): IX9ECParameters; override;
+
+    public
+      class function Instance(): IX9ECParametersHolder; static;
+
+    end;
+
   type
   type
 
 
     /// <summary>
     /// <summary>
@@ -202,16 +220,16 @@ implementation
 
 
 { TCustomNamedCurves }
 { TCustomNamedCurves }
 
 
-// class procedure TCustomNamedCurves.DefineCurve(const name: String;
-// const holder: IX9ECParametersHolder);
-// var
-// LName: string;
-// begin
-// LName := name;
-// Fnames.Add(LName);
-// LName := UpperCase(LName);
-// FnameToCurve.Add(LName, holder);
-// end;
+class procedure TCustomNamedCurves.DefineCurve(const name: String;
+  const holder: IX9ECParametersHolder);
+var
+  LName: string;
+begin
+  LName := name;
+  Fnames.Add(LName);
+  LName := UpperCase(LName);
+  FnameToCurve.Add(LName, holder);
+end;
 
 
 class procedure TCustomNamedCurves.DefineCurveWithOid(const name: String;
 class procedure TCustomNamedCurves.DefineCurveWithOid(const name: String;
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
   const oid: IDerObjectIdentifier; const holder: IX9ECParametersHolder);
@@ -335,6 +353,8 @@ begin
 
 
   Fnames := TList<String>.Create();
   Fnames := TList<String>.Create();
 
 
+  DefineCurve('curve25519', TCurve25519Holder.Instance);
+
   DefineCurveWithOid('secp256k1', TSecObjectIdentifiers.SecP256k1,
   DefineCurveWithOid('secp256k1', TSecObjectIdentifiers.SecP256k1,
     TSecP256K1Holder.Instance);
     TSecP256K1Holder.Instance);
 
 
@@ -357,6 +377,40 @@ begin
   DefineCurveAlias('P-521', TSecObjectIdentifiers.SecP521r1);
   DefineCurveAlias('P-521', TSecObjectIdentifiers.SecP521r1);
 end;
 end;
 
 
+{ TCustomNamedCurves.TCurve25519Holder }
+
+function TCustomNamedCurves.TCurve25519Holder.CreateParameters: IX9ECParameters;
+var
+  curve: IECCurve;
+  G: IX9ECPoint;
+  S: TCryptoLibByteArray;
+begin
+  S := Nil;
+  curve := ConfigureCurve(TCurve25519.Create() as ICurve25519);
+
+  { *
+    * NOTE: Curve25519 was specified in Montgomery form. Rewriting in Weierstrass form
+    * involves substitution of variables, so the base-point x coordinate is 9 + (486662 / 3).
+    *
+    * The Curve25519 paper doesn't say which of the two possible y values the base
+    * point has. The choice here is guided by language in the Ed25519 paper.
+    *
+    * (The other possible y value is 5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14)
+    * }
+  G := TX9ECPoint.Create(curve,
+    THex.Decode('04' +
+    '2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD245A' +
+    '20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9'));
+
+  result := TX9ECParameters.Create(curve, G, curve.Order, curve.Cofactor, S);
+end;
+
+class function TCustomNamedCurves.TCurve25519Holder.Instance
+  : IX9ECParametersHolder;
+begin
+  result := TCurve25519Holder.Create();
+end;
+
 { TCustomNamedCurves.TSecP256K1Holder }
 { TCustomNamedCurves.TSecP256K1Holder }
 
 
 function TCustomNamedCurves.TSecP256K1Holder.CreateParameters: IX9ECParameters;
 function TCustomNamedCurves.TSecP256K1Holder.CreateParameters: IX9ECParameters;

+ 2 - 1
CryptoLib/src/Crypto/Engines/ClpAesEngine.pas

@@ -221,7 +221,6 @@ type
 
 
     function GetAlgorithmName: String; virtual;
     function GetAlgorithmName: String; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
-    function GetBlockSize(): Int32; virtual;
 
 
     /// <summary>
     /// <summary>
     /// <para>
     /// <para>
@@ -284,6 +283,8 @@ type
 
 
     procedure Reset(); virtual;
     procedure Reset(); virtual;
 
 
+    function GetBlockSize(): Int32; virtual;
+
     property AlgorithmName: String read GetAlgorithmName;
     property AlgorithmName: String read GetAlgorithmName;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
   end;
   end;

+ 2 - 1
CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas

@@ -129,7 +129,6 @@ type
 
 
     function GetAlgorithmName: String; virtual;
     function GetAlgorithmName: String; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
-    function GetBlockSize(): Int32; virtual;
 
 
     /// <summary>
     /// <summary>
     /// <para>
     /// <para>
@@ -192,6 +191,8 @@ type
 
 
     procedure Reset(); virtual;
     procedure Reset(); virtual;
 
 
+    function GetBlockSize(): Int32; virtual;
+
     property AlgorithmName: String read GetAlgorithmName;
     property AlgorithmName: String read GetAlgorithmName;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
 
 

+ 2 - 1
CryptoLib/src/Crypto/Engines/ClpBlowfishEngine.pas

@@ -277,7 +277,6 @@ type
 
 
     function GetAlgorithmName: String; virtual;
     function GetAlgorithmName: String; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
-    function GetBlockSize(): Int32; virtual;
 
 
   public
   public
 
 
@@ -301,6 +300,8 @@ type
 
 
     procedure Reset(); virtual;
     procedure Reset(); virtual;
 
 
+    function GetBlockSize(): Int32; virtual;
+
     property AlgorithmName: String read GetAlgorithmName;
     property AlgorithmName: String read GetAlgorithmName;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
 
 

+ 264 - 0
CryptoLib/src/Crypto/Engines/ClpChaChaEngine.pas

@@ -0,0 +1,264 @@
+{ *********************************************************************************** }
+{ *                              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 ClpChaChaEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIStreamCipher,
+  ClpIChaChaEngine,
+  ClpSalsa20Engine,
+  ClpConverters,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary>
+  /// Implementation of Daniel J. Bernstein's ChaCha stream cipher.
+  /// </summary>
+  TChaChaEngine = class sealed(TSalsa20Engine, IChaChaEngine, IStreamCipher)
+
+  strict private
+    /// <summary>
+    /// ChaCha function.
+    /// </summary>
+    /// <param name="rounds">The number of ChaCha rounds to execute</param>
+    /// <param name="input">The input words.</param>
+    /// <param name="x">The ChaCha state to modify.</param>
+    class procedure ChaChaCore(rounds: Int32;
+      const input, x: TCryptoLibUInt32Array); static;
+
+  strict protected
+    function GetAlgorithmName: String; override;
+
+    procedure AdvanceCounter(); override;
+    procedure ResetCounter(); override;
+    procedure SetKey(const keyBytes, ivBytes: TCryptoLibByteArray); override;
+    procedure GenerateKeyStream(const output: TCryptoLibByteArray); override;
+
+  public
+    /// <summary>
+    /// Creates a 20 rounds ChaCha engine.
+    /// </summary>
+    constructor Create(); overload;
+    /// <summary>
+    /// Creates a ChaCha engine with a specific number of rounds.
+    /// </summary>
+    /// <param name="rounds">the number of rounds (must be an even number).</param>
+    constructor Create(rounds: Int32); overload;
+
+  end;
+
+implementation
+
+{ TChaChaEngine }
+
+procedure TChaChaEngine.AdvanceCounter;
+begin
+  System.Inc(FEngineState[12]);
+  if (FEngineState[12] = 0) then
+  begin
+    System.Inc(FEngineState[13]);
+  end;
+end;
+
+class procedure TChaChaEngine.ChaChaCore(rounds: Int32;
+  const input, x: TCryptoLibUInt32Array);
+var
+  x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14,
+    x15: UInt32;
+  Idx: Int32;
+begin
+  if (System.Length(input) <> 16) then
+  begin
+    raise EArgumentCryptoLibException.Create('');
+  end;
+  if (System.Length(x) <> 16) then
+  begin
+    raise EArgumentCryptoLibException.Create('');
+  end;
+  if ((rounds mod 2) <> 0) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SRoundsMustbeEven);
+  end;
+
+  x00 := input[0];
+  x01 := input[1];
+  x02 := input[2];
+  x03 := input[3];
+  x04 := input[4];
+  x05 := input[5];
+  x06 := input[6];
+  x07 := input[7];
+  x08 := input[8];
+  x09 := input[9];
+  x10 := input[10];
+  x11 := input[11];
+  x12 := input[12];
+  x13 := input[13];
+  x14 := input[14];
+  x15 := input[15];
+
+  Idx := rounds;
+  while Idx > 0 do
+  begin
+
+    x00 := x00 + x04;
+    x12 := R(x12 xor x00, 16);
+    x08 := x08 + x12;
+    x04 := R(x04 xor x08, 12);
+    x00 := x00 + x04;
+    x12 := R(x12 xor x00, 8);
+    x08 := x08 + x12;
+    x04 := R(x04 xor x08, 7);
+    x01 := x01 + x05;
+    x13 := R(x13 xor x01, 16);
+    x09 := x09 + x13;
+    x05 := R(x05 xor x09, 12);
+    x01 := x01 + x05;
+    x13 := R(x13 xor x01, 8);
+    x09 := x09 + x13;
+    x05 := R(x05 xor x09, 7);
+    x02 := x02 + x06;
+    x14 := R(x14 xor x02, 16);
+    x10 := x10 + x14;
+    x06 := R(x06 xor x10, 12);
+    x02 := x02 + x06;
+    x14 := R(x14 xor x02, 8);
+    x10 := x10 + x14;
+    x06 := R(x06 xor x10, 7);
+    x03 := x03 + x07;
+    x15 := R(x15 xor x03, 16);
+    x11 := x11 + x15;
+    x07 := R(x07 xor x11, 12);
+    x03 := x03 + x07;
+    x15 := R(x15 xor x03, 8);
+    x11 := x11 + x15;
+    x07 := R(x07 xor x11, 7);
+    x00 := x00 + x05;
+    x15 := R(x15 xor x00, 16);
+    x10 := x10 + x15;
+    x05 := R(x05 xor x10, 12);
+    x00 := x00 + x05;
+    x15 := R(x15 xor x00, 8);
+    x10 := x10 + x15;
+    x05 := R(x05 xor x10, 7);
+    x01 := x01 + x06;
+    x12 := R(x12 xor x01, 16);
+    x11 := x11 + x12;
+    x06 := R(x06 xor x11, 12);
+    x01 := x01 + x06;
+    x12 := R(x12 xor x01, 8);
+    x11 := x11 + x12;
+    x06 := R(x06 xor x11, 7);
+    x02 := x02 + x07;
+    x13 := R(x13 xor x02, 16);
+    x08 := x08 + x13;
+    x07 := R(x07 xor x08, 12);
+    x02 := x02 + x07;
+    x13 := R(x13 xor x02, 8);
+    x08 := x08 + x13;
+    x07 := R(x07 xor x08, 7);
+    x03 := x03 + x04;
+    x14 := R(x14 xor x03, 16);
+    x09 := x09 + x14;
+    x04 := R(x04 xor x09, 12);
+    x03 := x03 + x04;
+    x14 := R(x14 xor x03, 8);
+    x09 := x09 + x14;
+    x04 := R(x04 xor x09, 7);
+
+    System.Dec(Idx, 2);
+  end;
+
+  x[0] := x00 + input[0];
+  x[1] := x01 + input[1];
+  x[2] := x02 + input[2];
+  x[3] := x03 + input[3];
+  x[4] := x04 + input[4];
+  x[5] := x05 + input[5];
+  x[6] := x06 + input[6];
+  x[7] := x07 + input[7];
+  x[8] := x08 + input[8];
+  x[9] := x09 + input[9];
+  x[10] := x10 + input[10];
+  x[11] := x11 + input[11];
+  x[12] := x12 + input[12];
+  x[13] := x13 + input[13];
+  x[14] := x14 + input[14];
+  x[15] := x15 + input[15];
+
+end;
+
+constructor TChaChaEngine.Create;
+begin
+  Inherited Create();
+end;
+
+constructor TChaChaEngine.Create(rounds: Int32);
+begin
+  Inherited Create(rounds);
+end;
+
+procedure TChaChaEngine.GenerateKeyStream(const output: TCryptoLibByteArray);
+begin
+  ChaChaCore(FRounds, FEngineState, Fx);
+  TConverters.le32_copy(PCardinal(Fx), 0, PByte(output), 0,
+    System.Length(Fx) * System.SizeOf(UInt32));
+end;
+
+function TChaChaEngine.GetAlgorithmName: String;
+begin
+  result := Format('ChaCha%d', [FRounds]);
+end;
+
+procedure TChaChaEngine.ResetCounter;
+begin
+  FEngineState[12] := 0;
+  FEngineState[13] := 0;
+end;
+
+procedure TChaChaEngine.SetKey(const keyBytes, ivBytes: TCryptoLibByteArray);
+begin
+  if (keyBytes <> Nil) then
+  begin
+    if not(Byte(System.Length(keyBytes)) in [16, 32]) then
+    begin
+      raise EArgumentCryptoLibException.CreateResFmt(@SInvalidKeySize,
+        [AlgorithmName]);
+    end;
+
+    PackTauOrSigma(System.Length(keyBytes), FEngineState, 0);
+
+    // Key
+    TConverters.le32_copy(PByte(keyBytes), 0, PCardinal(FEngineState),
+      4 * System.SizeOf(UInt32), 4 * System.SizeOf(UInt32));
+    TConverters.le32_copy(PByte(keyBytes), (System.Length(keyBytes) - 16) *
+      System.SizeOf(Byte), PCardinal(FEngineState), 8 * System.SizeOf(UInt32),
+      4 * System.SizeOf(UInt32));
+  end;
+
+  // IV
+  TConverters.le32_copy(PByte(ivBytes), 0, PCardinal(FEngineState),
+    14 * System.SizeOf(UInt32), 2 * System.SizeOf(UInt32));
+end;
+
+end.

+ 47 - 43
CryptoLib/src/Crypto/Engines/ClpIESEngine.pas

@@ -39,7 +39,7 @@ uses
   ClpIParametersWithIV,
   ClpIParametersWithIV,
   ClpIKeyParser,
   ClpIKeyParser,
   ClpIEphemeralKeyPair,
   ClpIEphemeralKeyPair,
-  ClpKDFParameters,
+  ClpKdfParameters,
   ClpIKdfParameters,
   ClpIKdfParameters,
   ClpIIESWithCipherParameters,
   ClpIIESWithCipherParameters,
   ClpConverters,
   ClpConverters,
@@ -65,6 +65,8 @@ type
   TIESEngine = class(TInterfacedObject, IIESEngine)
   TIESEngine = class(TInterfacedObject, IIESEngine)
 
 
   strict private
   strict private
+  var
+    Fparam: IIESParameters;
 
 
     // as described in Shroup's paper( ch 10, pg 20) and P1363a
     // as described in Shroup's paper( ch 10, pg 20) and P1363a
     function GetLengthTag(const p2: TCryptoLibByteArray)
     function GetLengthTag(const p2: TCryptoLibByteArray)
@@ -72,6 +74,9 @@ type
 
 
     procedure ExtractParams(const params: ICipherParameters); inline;
     procedure ExtractParams(const params: ICipherParameters); inline;
 
 
+    function SimilarMacCompute(const ArgOne, ArgTwo: TCryptoLibByteArray)
+      : TCryptoLibByteArray; inline;
+
   strict protected
   strict protected
 
 
   var
   var
@@ -79,15 +84,17 @@ type
     Fkdf: IDerivationFunction;
     Fkdf: IDerivationFunction;
     Fmac: IMac;
     Fmac: IMac;
     Fcipher: IBufferedBlockCipher;
     Fcipher: IBufferedBlockCipher;
-    FmacBuf, FV, FIV: TCryptoLibByteArray;
+    FV, FIV: TCryptoLibByteArray;
     FforEncryption: Boolean;
     FforEncryption: Boolean;
     FprivParam, FpubParam: ICipherParameters;
     FprivParam, FpubParam: ICipherParameters;
-    Fparam: IIESParameters;
     FkeyPairGenerator: IEphemeralKeyPairGenerator;
     FkeyPairGenerator: IEphemeralKeyPairGenerator;
     FkeyParser: IKeyParser;
     FkeyParser: IKeyParser;
 
 
     function GetCipher: IBufferedBlockCipher; inline;
     function GetCipher: IBufferedBlockCipher; inline;
     function GetMac: IMac; inline;
     function GetMac: IMac; inline;
+    procedure SetupBlockCipherAndMacKeyBytes(out K1,
+      K2: TCryptoLibByteArray); inline;
+
     function EncryptBlock(const &in: TCryptoLibByteArray; inOff, inLen: Int32)
     function EncryptBlock(const &in: TCryptoLibByteArray; inOff, inLen: Int32)
       : TCryptoLibByteArray; virtual;
       : TCryptoLibByteArray; virtual;
 
 
@@ -208,6 +215,37 @@ begin
   end;
   end;
 end;
 end;
 
 
+function TIESEngine.SimilarMacCompute(const ArgOne, ArgTwo: TCryptoLibByteArray)
+  : TCryptoLibByteArray;
+begin
+  if (ArgOne <> Nil) then
+  begin
+    Fmac.BlockUpdate(ArgOne, 0, System.Length(ArgOne));
+  end;
+  if (System.Length(FV) <> 0) then
+  begin
+    Fmac.BlockUpdate(ArgTwo, 0, System.Length(ArgTwo));
+  end;
+  Result := Fmac.DoFinal;
+end;
+
+procedure TIESEngine.SetupBlockCipherAndMacKeyBytes(out K1,
+  K2: TCryptoLibByteArray);
+var
+  K: TCryptoLibByteArray;
+begin
+  System.SetLength(K1, (Fparam as IIESWithCipherParameters)
+    .CipherKeySize div 8);
+  System.SetLength(K2, Fparam.MacKeySize div 8);
+  System.SetLength(K, System.Length(K1) + System.Length(K2));
+
+  Fkdf.GenerateBytes(K, 0, System.Length(K));
+
+  System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+  System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
+    System.SizeOf(Byte));
+end;
+
 constructor TIESEngine.Create(const agree: IBasicAgreement;
 constructor TIESEngine.Create(const agree: IBasicAgreement;
   const kdf: IDerivationFunction; const mac: IMac);
   const kdf: IDerivationFunction; const mac: IMac);
 begin
 begin
@@ -215,7 +253,6 @@ begin
   Fagree := agree;
   Fagree := agree;
   Fkdf := kdf;
   Fkdf := kdf;
   Fmac := mac;
   Fmac := mac;
-  System.SetLength(FmacBuf, mac.GetMacSize);
   Fcipher := Nil;
   Fcipher := Nil;
 end;
 end;
 
 
@@ -227,7 +264,6 @@ begin
   Fagree := agree;
   Fagree := agree;
   Fkdf := kdf;
   Fkdf := kdf;
   Fmac := mac;
   Fmac := mac;
-  System.SetLength(FmacBuf, mac.GetMacSize);
   Fcipher := cipher;
   Fcipher := cipher;
 end;
 end;
 
 
@@ -291,16 +327,7 @@ begin
   begin
   begin
     // Block cipher mode.
     // Block cipher mode.
 
 
-    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
-      .CipherKeySize div 8);
-    System.SetLength(K2, Fparam.MacKeySize div 8);
-    System.SetLength(K, System.Length(K1) + System.Length(K2));
-
-    Fkdf.GenerateBytes(K, 0, System.Length(K));
-
-    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
-    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
-      System.SizeOf(Byte));
+    SetupBlockCipherAndMacKeyBytes(K1, K2);
 
 
     cp := TKeyParameter.Create(K1);
     cp := TKeyParameter.Create(K1);
 
 
@@ -338,15 +365,8 @@ begin
 
 
   Fmac.BlockUpdate(in_enc, inOff + System.Length(FV), inLen - System.Length(FV)
   Fmac.BlockUpdate(in_enc, inOff + System.Length(FV), inLen - System.Length(FV)
     - System.Length(T2));
     - System.Length(T2));
-  if (p2 <> Nil) then
-  begin
-    Fmac.BlockUpdate(p2, 0, System.Length(p2));
-  end;
-  if (System.Length(FV) <> 0) then
-  begin
-    Fmac.BlockUpdate(L2, 0, System.Length(L2));
-  end;
-  T2 := Fmac.DoFinal();
+
+  T2 := SimilarMacCompute(p2, L2);
 
 
   if (not TArrayUtils.ConstantTimeAreEqual(T1, T2)) then
   if (not TArrayUtils.ConstantTimeAreEqual(T1, T2)) then
   begin
   begin
@@ -416,16 +436,7 @@ begin
   begin
   begin
     // Block cipher mode.
     // Block cipher mode.
 
 
-    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
-      .CipherKeySize div 8);
-    System.SetLength(K2, Fparam.MacKeySize div 8);
-    System.SetLength(K, System.Length(K1) + System.Length(K2));
-
-    Fkdf.GenerateBytes(K, 0, System.Length(K));
-
-    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
-    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
-      System.SizeOf(Byte));
+    SetupBlockCipherAndMacKeyBytes(K1, K2);
 
 
     // If iv is provided use it to initialise the cipher
     // If iv is provided use it to initialise the cipher
     if (FIV <> Nil) then
     if (FIV <> Nil) then
@@ -457,15 +468,8 @@ begin
 
 
   Fmac.Init((TKeyParameter.Create(K2) as IKeyParameter) as ICipherParameters);
   Fmac.Init((TKeyParameter.Create(K2) as IKeyParameter) as ICipherParameters);
   Fmac.BlockUpdate(C, 0, System.Length(C));
   Fmac.BlockUpdate(C, 0, System.Length(C));
-  if (p2 <> Nil) then
-  begin
-    Fmac.BlockUpdate(p2, 0, System.Length(p2));
-  end;
-  if (System.Length(FV) <> 0) then
-  begin
-    Fmac.BlockUpdate(L2, 0, System.Length(L2));
-  end;
-  T := Fmac.DoFinal;
+
+  T := SimilarMacCompute(p2, L2);
 
 
   // Output the triple (V,C,T).
   // Output the triple (V,C,T).
   // V := Ephermeral Public Key
   // V := Ephermeral Public Key

+ 6 - 25
CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas

@@ -32,9 +32,8 @@ uses
   ClpParametersWithIV,
   ClpParametersWithIV,
   ClpIKeyParser,
   ClpIKeyParser,
   ClpIEphemeralKeyPair,
   ClpIEphemeralKeyPair,
-  ClpKDFParameters,
+  ClpKdfParameters,
   ClpIKdfParameters,
   ClpIKdfParameters,
-  ClpIIESWithCipherParameters,
   ClpIESEngine,
   ClpIESEngine,
   ClpArrayUtils,
   ClpArrayUtils,
   ClpBigInteger,
   ClpBigInteger,
@@ -98,7 +97,7 @@ implementation
 function TPascalCoinIESEngine.DecryptBlock(const in_enc: TCryptoLibByteArray;
 function TPascalCoinIESEngine.DecryptBlock(const in_enc: TCryptoLibByteArray;
   inOff, inLen: Int32): TCryptoLibByteArray;
   inOff, inLen: Int32): TCryptoLibByteArray;
 var
 var
-  K, K1, K2, T1, T2: TCryptoLibByteArray;
+  K1, K2, T1, T2: TCryptoLibByteArray;
   cp: ICipherParameters;
   cp: ICipherParameters;
 begin
 begin
   // Ensure that the length of the input is greater than the MAC in bytes
   // Ensure that the length of the input is greater than the MAC in bytes
@@ -117,16 +116,7 @@ begin
   begin
   begin
     // Block cipher mode.
     // Block cipher mode.
 
 
-    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
-      .CipherKeySize div 8);
-    System.SetLength(K2, Fparam.MacKeySize div 8);
-    System.SetLength(K, System.Length(K1) + System.Length(K2));
-
-    Fkdf.GenerateBytes(K, 0, System.Length(K));
-
-    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
-    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
-      System.SizeOf(Byte));
+    SetupBlockCipherAndMacKeyBytes(K1, K2);
 
 
     cp := TKeyParameter.Create(K1);
     cp := TKeyParameter.Create(K1);
 
 
@@ -164,7 +154,7 @@ end;
 function TPascalCoinIESEngine.EncryptBlock(const &in: TCryptoLibByteArray;
 function TPascalCoinIESEngine.EncryptBlock(const &in: TCryptoLibByteArray;
   inOff, inLen: Int32): TCryptoLibByteArray;
   inOff, inLen: Int32): TCryptoLibByteArray;
 var
 var
-  C, K, K1, K2, T: TCryptoLibByteArray;
+  C, K1, K2, T: TCryptoLibByteArray;
   MessageToEncryptPadSize, CipherBlockSize, MessageToEncryptSize: Int32;
   MessageToEncryptPadSize, CipherBlockSize, MessageToEncryptSize: Int32;
 begin
 begin
   if (Fcipher = Nil) then
   if (Fcipher = Nil) then
@@ -176,16 +166,7 @@ begin
   begin
   begin
     // Block cipher mode.
     // Block cipher mode.
 
 
-    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
-      .CipherKeySize div 8);
-    System.SetLength(K2, Fparam.MacKeySize div 8);
-    System.SetLength(K, System.Length(K1) + System.Length(K2));
-
-    Fkdf.GenerateBytes(K, 0, System.Length(K));
-
-    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
-    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
-      System.SizeOf(Byte));
+    SetupBlockCipherAndMacKeyBytes(K1, K2);
 
 
     // If iv is provided use it to initialise the cipher
     // If iv is provided use it to initialise the cipher
     if (FIV <> Nil) then
     if (FIV <> Nil) then
@@ -227,7 +208,7 @@ begin
   // [1] := Convert Byte(Length(T)) to a ByteArray,
   // [1] := Convert Byte(Length(T)) to a ByteArray,
   // [2] and [3] := Convert UInt16(MessageToEncryptSize) to a ByteArray,
   // [2] and [3] := Convert UInt16(MessageToEncryptSize) to a ByteArray,
   // [4] and [5] := Convert UInt16(MessageToEncryptSize + MessageToEncryptPadSize) to a ByteArray,
   // [4] and [5] := Convert UInt16(MessageToEncryptSize + MessageToEncryptPadSize) to a ByteArray,
-  // V := Ephermeral Public Key
+  // V := Ephemeral Public Key
   // T := Authentication Message (MAC)
   // T := Authentication Message (MAC)
   // C := Encrypted Payload
   // C := Encrypted Payload
 
 

+ 911 - 0
CryptoLib/src/Crypto/Engines/ClpRijndaelEngine.pas

@@ -0,0 +1,911 @@
+{ *********************************************************************************** }
+{ *                              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 ClpRijndaelEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpCheck,
+  ClpIBlockCipher,
+  ClpIRijndaelEngine,
+  ClpIKeyParameter,
+  ClpICipherParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInputBuffertooShort = 'Input Buffer too Short';
+  SOutputBuffertooShort = 'Output Buffer too Short';
+  SUnsupportedBlock = 'Unknown Blocksize to Rijndael';
+  SInvalidKeyLength = 'Key Length not 128/160/192/224/256 bits.';
+  SRijndaelEngineNotInitialised = 'Rijndael Engine not Initialised';
+  SInvalidParameterRijndaelInit =
+    'Invalid Parameter Passed to Rijndael Init - "%s"';
+
+type
+
+  /// <summary>
+  /// <para>
+  /// an implementation of Rijndael, based on the documentation and
+  /// reference implementation by Paulo Barreto, Vincent Rijmen, for v2.0
+  /// August '99.
+  /// </para>
+  /// <para>
+  /// Note: this implementation is based on information prior to readonly
+  /// NIST publication.
+  /// </para>
+  /// </summary>
+  TRijndaelEngine = class(TInterfacedObject, IRijndaelEngine, IBlockCipher)
+
+  strict private
+  const
+    MAXROUNDS = Int32(14);
+    MAXKC = Int32(256 div 4);
+
+    Logtable: array [0 .. 255] of Byte = (0, 0, 25, 1, 50, 2, 26, 198, 75, 199,
+      27, 104, 51, 238, 223, 3, 100, 4, 224, 14, 52, 141, 129, 239, 76, 113, 8,
+      200, 248, 105, 28, 193, 125, 194, 29, 181, 249, 185, 39, 106, 77, 228,
+      166, 114, 154, 201, 9, 120, 101, 47, 138, 5, 33, 15, 225, 36, 18, 240,
+      130, 69, 53, 147, 218, 142, 150, 143, 219, 189, 54, 208, 206, 148, 19, 92,
+      210, 241, 64, 70, 131, 56, 102, 221, 253, 48, 191, 6, 139, 98, 179, 37,
+      226, 152, 34, 136, 145, 16, 126, 110, 72, 195, 163, 182, 30, 66, 58, 107,
+      40, 84, 250, 133, 61, 186, 43, 121, 10, 21, 155, 159, 94, 202, 78, 212,
+      172, 229, 243, 115, 167, 87, 175, 88, 168, 80, 244, 234, 214, 116, 79,
+      174, 233, 213, 231, 230, 173, 232, 44, 215, 117, 122, 235, 22, 11, 245,
+      89, 203, 95, 176, 156, 169, 81, 160, 127, 12, 246, 111, 23, 196, 73, 236,
+      216, 67, 31, 45, 164, 118, 123, 183, 204, 187, 62, 90, 251, 96, 177, 134,
+      59, 82, 161, 108, 170, 85, 41, 157, 151, 178, 135, 144, 97, 190, 220, 252,
+      188, 149, 207, 205, 55, 63, 91, 209, 83, 57, 132, 60, 65, 162, 109, 71,
+      20, 42, 158, 93, 86, 242, 211, 171, 68, 17, 146, 217, 35, 32, 46, 137,
+      180, 124, 184, 38, 119, 153, 227, 165, 103, 74, 237, 222, 197, 49, 254,
+      24, 13, 99, 140, 128, 192, 247, 112, 7);
+
+    Alogtable: array [0 .. 510] of Byte = (0, 3, 5, 15, 17, 51, 85, 255, 26, 46,
+      114, 150, 161, 248, 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2,
+      6, 10, 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217,
+      112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104,
+      184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59, 77, 215, 98, 166,
+      241, 8, 24, 40, 120, 136, 131, 158, 185, 208, 107, 189, 220, 127, 129,
+      152, 179, 206, 73, 219, 118, 154, 181, 196, 87, 249, 16, 48, 80, 240, 11,
+      29, 39, 105, 187, 214, 97, 163, 254, 25, 43, 125, 135, 146, 173, 236, 47,
+      113, 147, 174, 233, 32, 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93,
+      231, 50, 86, 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
+      44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126, 130,
+      157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35, 101, 175,
+      234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99, 165, 244, 7, 9, 27,
+      45, 119, 153, 176, 203, 70, 202, 69, 207, 74, 222, 121, 139, 134, 145,
+      168, 227, 62, 66, 198, 81, 243, 14, 18, 54, 90, 238, 41, 123, 141, 140,
+      143, 138, 133, 148, 167, 242, 13, 23, 57, 75, 221, 124, 132, 151, 162,
+      253, 28, 36, 108, 180, 199, 82, 246, 1, 3, 5, 15, 17, 51, 85, 255, 26, 46,
+      114, 150, 161, 248, 19, 53, 95, 225, 56, 72, 216, 115, 149, 164, 247, 2,
+      6, 10, 30, 34, 102, 170, 229, 52, 92, 228, 55, 89, 235, 38, 106, 190, 217,
+      112, 144, 171, 230, 49, 83, 245, 4, 12, 20, 60, 68, 204, 79, 209, 104,
+      184, 211, 110, 178, 205, 76, 212, 103, 169, 224, 59, 77, 215, 98, 166,
+      241, 8, 24, 40, 120, 136, 131, 158, 185, 208, 107, 189, 220, 127, 129,
+      152, 179, 206, 73, 219, 118, 154, 181, 196, 87, 249, 16, 48, 80, 240, 11,
+      29, 39, 105, 187, 214, 97, 163, 254, 25, 43, 125, 135, 146, 173, 236, 47,
+      113, 147, 174, 233, 32, 96, 160, 251, 22, 58, 78, 210, 109, 183, 194, 93,
+      231, 50, 86, 250, 21, 63, 65, 195, 94, 226, 61, 71, 201, 64, 192, 91, 237,
+      44, 116, 156, 191, 218, 117, 159, 186, 213, 100, 172, 239, 42, 126, 130,
+      157, 188, 223, 122, 142, 137, 128, 155, 182, 193, 88, 232, 35, 101, 175,
+      234, 37, 111, 177, 200, 67, 197, 84, 252, 31, 33, 99, 165, 244, 7, 9, 27,
+      45, 119, 153, 176, 203, 70, 202, 69, 207, 74, 222, 121, 139, 134, 145,
+      168, 227, 62, 66, 198, 81, 243, 14, 18, 54, 90, 238, 41, 123, 141, 140,
+      143, 138, 133, 148, 167, 242, 13, 23, 57, 75, 221, 124, 132, 151, 162,
+      253, 28, 36, 108, 180, 199, 82, 246, 1);
+
+    S: array [0 .. 255] of Byte = (99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
+      103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173,
+      212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
+      52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7,
+      18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59,
+      214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
+      190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2,
+      127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218,
+      33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126,
+      61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184,
+      20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98,
+      145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244,
+      234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116,
+      31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185,
+      134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135,
+      233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45,
+      15, 176, 84, 187, 22);
+
+    Si: array [0 .. 255] of Byte = (82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
+      163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52,
+      142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238,
+      76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91,
+      162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212,
+      164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94,
+      21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,
+      228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175,
+      189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242,
+      207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226,
+      249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111,
+      183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154,
+      219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177,
+      18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229,
+      122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200,
+      235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225,
+      105, 20, 99, 85, 33, 12, 125);
+
+    rcon: array [0 .. 29] of Byte = ($01, $02, $04, $08, $10, $20, $40, $80,
+      $1B, $36, $6C, $D8, $AB, $4D, $9A, $2F, $5E, $BC, $63, $C6, $97, $35, $6A,
+      $D4, $B3, $7D, $FA, $EF, $C5, $91);
+
+    shifts0: array [0 .. 4, 0 .. 3] of Byte = ((0, 8, 16, 24), (0, 8, 16, 24),
+      (0, 8, 16, 24), (0, 8, 16, 32), (0, 8, 24, 32));
+
+    shifts1: array [0 .. 4, 0 .. 3] of Byte = ((0, 24, 16, 8), (0, 32, 24, 16),
+      (0, 40, 32, 24), (0, 48, 40, 24), (0, 56, 40, 32));
+
+  var
+    FForEncryption: Boolean;
+    FBC, FROUNDS, FBlockBits: Int32;
+    FBC_MASK, FA0, FA1, FA2, FA3: UInt64;
+    FShifts0SC, FShifts1SC: TCryptoLibByteArray;
+    FWorkingKey: TCryptoLibMatrixUInt64Array;
+
+    function GetAlgorithmName: String; virtual;
+    function GetIsPartialBlockOkay: Boolean; virtual;
+
+    /// <summary>
+    /// multiply two elements of GF(2^m) needed for MixColumn and
+    /// InvMixColumn
+    /// </summary>
+    function Mul0x2(b: Int32): Byte; inline;
+
+    function Mul0x3(b: Int32): Byte; inline;
+
+    function Mul0x9(b: Int32): Byte; inline;
+
+    function Mul0xb(b: Int32): Byte; inline;
+
+    function Mul0xd(b: Int32): Byte; inline;
+
+    function Mul0xe(b: Int32): Byte; inline;
+
+    /// <summary>
+    /// xor corresponding text input and round key input bytes
+    /// </summary>
+    procedure KeyAddition(const rk: TCryptoLibUInt64Array); inline;
+
+    /// <summary>
+    /// rotate right custom
+    /// </summary>
+    function Shift(r: UInt64; Shift: Int32): UInt64; inline;
+
+    /// <summary>
+    /// Row 0 remains unchanged <br />The other three rows are shifted a
+    /// variable amount
+    /// </summary>
+    procedure ShiftRow(const shiftsSC: TCryptoLibByteArray); inline;
+
+    function ApplyS(r: UInt64; box: PByte): UInt64; inline;
+
+    /// <summary>
+    /// Replace every byte of the input by the byte at that place <br />in
+    /// the nonlinear S-box
+    /// </summary>
+    procedure Substitution(box: PByte); inline;
+
+    /// <summary>
+    /// Mix the bytes of every column in a linear way
+    /// </summary>
+    procedure MixColumn();
+
+    /// <summary>
+    /// Mix the bytes of every column in a linear way <br />This is the
+    /// opposite operation of Mixcolumn
+    /// </summary>
+    procedure InvMixColumn();
+
+    /// <summary>
+    /// Calculate the necessary round keys <br />The number of calculations
+    /// depends on keyBits and blockBits
+    /// </summary>
+    function GenerateWorkingKey(const key: TCryptoLibByteArray)
+      : TCryptoLibMatrixUInt64Array;
+
+    procedure UnPackBlock(const bytes: TCryptoLibByteArray; off: Int32); inline;
+    procedure PackBlock(const bytes: TCryptoLibByteArray; off: Int32); inline;
+
+    procedure EncryptBlock(const rk: TCryptoLibMatrixUInt64Array);
+
+    procedure DecryptBlock(const rk: TCryptoLibMatrixUInt64Array);
+
+  public
+
+    /// <summary>
+    /// default constructor - 128 bit block size.
+    /// </summary>
+    constructor Create(); overload;
+
+    /// <summary>
+    /// basic constructor - set the cipher up for a given blocksize
+    /// </summary>
+    /// <param name="blockBits">
+    /// the blocksize in bits, must be 128, 192, or 256.
+    /// </param>
+    constructor Create(blockBits: Int32); overload;
+
+    /// <summary>
+    /// initialise a Rijndael 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="ClpCryptoLibTypes|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;
+
+    function GetBlockSize(): Int32; virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+  end;
+
+implementation
+
+{ TRijndaelEngine }
+
+function TRijndaelEngine.Mul0x2(b: Int32): Byte;
+begin
+  if (b <> 0) then
+  begin
+    result := Alogtable[25 + (Logtable[b] and $FF)];
+  end
+  else
+  begin
+    result := 0;
+  end;
+end;
+
+function TRijndaelEngine.Mul0x3(b: Int32): Byte;
+begin
+  if (b <> 0) then
+  begin
+    result := Alogtable[1 + (Logtable[b] and $FF)];
+  end
+  else
+  begin
+    result := 0;
+  end;
+end;
+
+function TRijndaelEngine.Mul0x9(b: Int32): Byte;
+begin
+  if (b >= 0) then
+  begin
+    result := Alogtable[199 + b];
+  end
+  else
+  begin
+    result := 0;
+  end;
+end;
+
+function TRijndaelEngine.Mul0xb(b: Int32): Byte;
+begin
+  if (b >= 0) then
+  begin
+    result := Alogtable[104 + b];
+  end
+  else
+  begin
+    result := 0;
+  end;
+end;
+
+function TRijndaelEngine.Mul0xd(b: Int32): Byte;
+begin
+  if (b >= 0) then
+  begin
+    result := Alogtable[238 + b];
+  end
+  else
+  begin
+    result := 0;
+  end;
+end;
+
+function TRijndaelEngine.Mul0xe(b: Int32): Byte;
+begin
+  if (b >= 0) then
+  begin
+    result := Alogtable[223 + b];
+  end
+  else
+  begin
+    result := 0;
+  end;
+end;
+
+procedure TRijndaelEngine.KeyAddition(const rk: TCryptoLibUInt64Array);
+begin
+  FA0 := FA0 xor rk[0];
+  FA1 := FA1 xor rk[1];
+  FA2 := FA2 xor rk[2];
+  FA3 := FA3 xor rk[3];
+end;
+
+function TRijndaelEngine.Shift(r: UInt64; Shift: Int32): UInt64;
+begin
+  result := (((r shr Shift) or (r shl (FBC - Shift)))) and FBC_MASK;
+end;
+
+procedure TRijndaelEngine.ShiftRow(const shiftsSC: TCryptoLibByteArray);
+begin
+  FA1 := Shift(FA1, shiftsSC[1]);
+  FA2 := Shift(FA2, shiftsSC[2]);
+  FA3 := Shift(FA3, shiftsSC[3]);
+end;
+
+function TRijndaelEngine.ApplyS(r: UInt64; box: PByte): UInt64;
+var
+  j: Int32;
+begin
+  result := 0;
+  j := 0;
+  while j < FBC do
+  begin
+    result := result or (UInt64(box[((r shr j) and $FF)] and $FF) shl j);
+    System.Inc(j, 8);
+  end;
+end;
+
+procedure TRijndaelEngine.Substitution(box: PByte);
+begin
+  FA0 := ApplyS(FA0, box);
+  FA1 := ApplyS(FA1, box);
+  FA2 := ApplyS(FA2, box);
+  FA3 := ApplyS(FA3, box);
+end;
+
+procedure TRijndaelEngine.MixColumn;
+var
+  r0, r1, r2, r3: UInt64;
+  a0, a1, a2, a3, j: Int32;
+begin
+  r0 := 0;
+  r1 := 0;
+  r2 := 0;
+  r3 := 0;
+  j := 0;
+  while j < FBC do
+  begin
+
+    a0 := Int32((FA0 shr j) and $FF);
+    a1 := Int32((FA1 shr j) and $FF);
+    a2 := Int32((FA2 shr j) and $FF);
+    a3 := Int32((FA3 shr j) and $FF);
+
+    r0 := r0 or (UInt64(((Mul0x2(a0) xor Mul0x3(a1) xor a2 xor a3) and
+      $FF)) shl j);
+
+    r1 := r1 or (UInt64(((Mul0x2(a1) xor Mul0x3(a2) xor a3 xor a0) and
+      $FF)) shl j);
+
+    r2 := r2 or (UInt64(((Mul0x2(a2) xor Mul0x3(a3) xor a0 xor a1) and
+      $FF)) shl j);
+
+    r3 := r3 or (UInt64(((Mul0x2(a3) xor Mul0x3(a0) xor a1 xor a2) and
+      $FF)) shl j);
+
+    System.Inc(j, 8);
+  end;
+
+  FA0 := r0;
+  FA1 := r1;
+  FA2 := r2;
+  FA3 := r3;
+end;
+
+procedure TRijndaelEngine.InvMixColumn;
+var
+  r0, r1, r2, r3: UInt64;
+  a0, a1, a2, a3, j: Int32;
+begin
+  r0 := 0;
+  r1 := 0;
+  r2 := 0;
+  r3 := 0;
+  j := 0;
+  while j < FBC do
+  begin
+
+    a0 := Int32((FA0 shr j) and $FF);
+    a1 := Int32((FA1 shr j) and $FF);
+    a2 := Int32((FA2 shr j) and $FF);
+    a3 := Int32((FA3 shr j) and $FF);
+
+    //
+    // pre-lookup the log table
+    //
+    if (a0 <> 0) then
+    begin
+      a0 := (Logtable[a0 and $FF] and $FF);
+    end
+    else
+    begin
+      a0 := -1;
+    end;
+
+    if (a1 <> 0) then
+    begin
+      a1 := (Logtable[a1 and $FF] and $FF);
+    end
+    else
+    begin
+      a1 := -1;
+    end;
+
+    if (a2 <> 0) then
+    begin
+      a2 := (Logtable[a2 and $FF] and $FF);
+    end
+    else
+    begin
+      a2 := -1;
+    end;
+
+    if (a3 <> 0) then
+    begin
+      a3 := (Logtable[a3 and $FF] and $FF);
+    end
+    else
+    begin
+      a3 := -1;
+    end;
+
+    r0 := r0 or
+      (UInt64(((Mul0xe(a0) xor Mul0xb(a1) xor Mul0xd(a2) xor Mul0x9(a3)) and
+      $FF)) shl j);
+
+    r1 := r1 or
+      (UInt64(((Mul0xe(a1) xor Mul0xb(a2) xor Mul0xd(a3) xor Mul0x9(a0)) and
+      $FF)) shl j);
+
+    r2 := r2 or
+      (UInt64(((Mul0xe(a2) xor Mul0xb(a3) xor Mul0xd(a0) xor Mul0x9(a1)) and
+      $FF)) shl j);
+
+    r3 := r3 or
+      (UInt64(((Mul0xe(a3) xor Mul0xb(a0) xor Mul0xd(a1) xor Mul0x9(a2)) and
+      $FF)) shl j);
+
+    System.Inc(j, 8);
+  end;
+
+  FA0 := r0;
+  FA1 := r1;
+  FA2 := r2;
+  FA3 := r3;
+end;
+
+function TRijndaelEngine.GenerateWorkingKey(const key: TCryptoLibByteArray)
+  : TCryptoLibMatrixUInt64Array;
+var
+  KC, t, rconpointer, keyBits, i, index, j: Int32;
+  tk: TCryptoLibMatrixByteArray;
+  W: TCryptoLibMatrixUInt64Array;
+begin
+  rconpointer := 0;
+  keyBits := System.Length(key) * 8;
+  System.SetLength(tk, 4);
+  for i := System.Low(tk) to System.High(tk) do
+  begin
+    System.SetLength(tk[i], MAXKC);
+  end;
+
+  System.SetLength(W, MAXROUNDS + 1);
+  for i := System.Low(W) to System.High(W) do
+  begin
+    System.SetLength(W[i], 4);
+  end;
+
+  case keyBits of
+    128:
+      KC := 4;
+    160:
+      KC := 5;
+    192:
+      KC := 6;
+    224:
+      KC := 7;
+    256:
+      KC := 8
+  else
+    begin
+      raise EArgumentCryptoLibException.CreateRes(@SInvalidKeyLength);
+    end;
+  end;
+
+  if (keyBits >= FBlockBits) then
+  begin
+    FROUNDS := KC + 6;
+  end
+  else
+  begin
+    FROUNDS := (FBC div 8) + 6;
+  end;
+
+  //
+  // copy the key into the processing area
+  //
+  index := 0;
+
+  for i := 0 to System.Pred(System.Length(key)) do
+  begin
+    tk[i mod 4][i div 4] := key[index];
+    System.Inc(index);
+  end;
+
+  t := 0;
+  //
+  // copy values into round key array
+  //
+  j := 0;
+
+  while ((j < KC) and (t < ((FROUNDS + 1) * (FBC div 8)))) do
+  begin
+    for i := 0 to System.Pred(4) do
+    begin
+      W[t div (FBC div 8)][i] := W[t div (FBC div 8)][i] or
+        (UInt64(tk[i][j] and $FF) shl ((t * 8) mod FBC));
+    end;
+    System.Inc(j);
+    System.Inc(t);
+  end;
+
+  //
+  // while not enough round key material calculated
+  // calculate new values
+  //
+  while (t < ((FROUNDS + 1) * (FBC div 8))) do
+  begin
+
+    for i := 0 to System.Pred(4) do
+    begin
+      tk[i][0] := tk[i][0] xor (S[tk[(i + 1) mod 4][KC - 1] and $FF]);
+    end;
+
+    tk[0][0] := tk[0][0] xor Byte(rcon[rconpointer]);
+    System.Inc(rconpointer);
+
+    if (KC <= 6) then
+    begin
+      for j := 1 to System.Pred(KC) do
+      begin
+        for i := 0 to System.Pred(4) do
+        begin
+          tk[i][j] := tk[i][j] xor tk[i][j - 1];
+        end;
+      end;
+    end
+    else
+    begin
+
+      for j := 1 to System.Pred(4) do
+      begin
+        for i := 0 to System.Pred(4) do
+        begin
+          tk[i][j] := tk[i][j] xor tk[i][j - 1];
+        end;
+      end;
+
+      for i := 0 to System.Pred(4) do
+      begin
+        tk[i][4] := tk[i][4] xor (S[tk[i][3] and $FF]);
+      end;
+
+      for j := 5 to System.Pred(KC) do
+      begin
+        for i := 0 to System.Pred(4) do
+        begin
+          tk[i][j] := tk[i][j] xor tk[i][j - 1];
+        end;
+      end;
+    end;
+
+    //
+    // copy values into round key array
+    //
+    j := 0;
+
+    while ((j < KC) and (t < ((FROUNDS + 1) * (FBC div 8)))) do
+    begin
+      for i := 0 to System.Pred(4) do
+      begin
+        W[t div (FBC div 8)][i] := W[t div (FBC div 8)][i] or
+          (UInt64(tk[i][j] and $FF) shl ((t * 8) mod FBC));
+      end;
+      System.Inc(j);
+      System.Inc(t);
+    end;
+  end;
+  result := W;
+end;
+
+procedure TRijndaelEngine.PackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+var
+  index, j: Int32;
+begin
+  index := off;
+  j := 0;
+
+  while j <> FBC do
+  begin
+    bytes[index] := Byte(FA0 shr j);
+    System.Inc(index);
+    bytes[index] := Byte(FA1 shr j);
+    System.Inc(index);
+    bytes[index] := Byte(FA2 shr j);
+    System.Inc(index);
+    bytes[index] := Byte(FA3 shr j);
+    System.Inc(index);
+    System.Inc(j, 8);
+  end;
+end;
+
+procedure TRijndaelEngine.UnPackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+var
+  index, j: Int32;
+begin
+  index := off;
+
+  FA0 := UInt64(bytes[index] and $FF);
+  System.Inc(index);
+  FA1 := UInt64(bytes[index] and $FF);
+  System.Inc(index);
+  FA2 := UInt64(bytes[index] and $FF);
+  System.Inc(index);
+  FA3 := UInt64(bytes[index] and $FF);
+  System.Inc(index);
+
+  j := 8;
+
+  while j <> FBC do
+  begin
+    FA0 := FA0 or (UInt64(bytes[index] and $FF) shl j);
+    System.Inc(index);
+    FA1 := FA1 or (UInt64(bytes[index] and $FF) shl j);
+    System.Inc(index);
+    FA2 := FA2 or (UInt64(bytes[index] and $FF) shl j);
+    System.Inc(index);
+    FA3 := FA3 or (UInt64(bytes[index] and $FF) shl j);
+    System.Inc(index);
+    System.Inc(j, 8);
+  end;
+end;
+
+procedure TRijndaelEngine.EncryptBlock(const rk: TCryptoLibMatrixUInt64Array);
+var
+  r: Int32;
+begin
+  //
+  // begin with a key addition
+  //
+  KeyAddition(rk[0]);
+
+  //
+  // ROUNDS-1 ordinary rounds
+  //
+  for r := 1 to System.Pred(FROUNDS) do
+  begin
+    Substitution(@(S[0]));
+    ShiftRow(FShifts0SC);
+    MixColumn();
+    KeyAddition(rk[r]);
+  end;
+
+  //
+  // Last round is special: there is no MixColumn
+  //
+  Substitution(@(S[0]));
+  ShiftRow(FShifts0SC);
+  KeyAddition(rk[FROUNDS]);
+end;
+
+procedure TRijndaelEngine.DecryptBlock(const rk: TCryptoLibMatrixUInt64Array);
+var
+  r: Int32;
+begin
+  // To decrypt: apply the inverse operations of the encrypt routine,
+  // in opposite order
+  //
+  // (KeyAddition is an involution: it 's equal to its inverse)
+  // (the inverse of Substitution with table S is Substitution with the inverse table of S)
+  // (the inverse of Shiftrow is Shiftrow over a suitable distance)
+  //
+
+  // First the special round:
+  // without InvMixColumn
+  // with extra KeyAddition
+  //
+  KeyAddition(rk[FROUNDS]);
+  Substitution(@(Si[0]));
+  ShiftRow(FShifts1SC);
+
+  //
+  // ROUNDS-1 ordinary rounds
+  //
+  for r := System.Pred(FROUNDS) downto 1 do
+  begin
+    KeyAddition(rk[r]);
+    InvMixColumn();
+    Substitution(@(Si[0]));
+    ShiftRow(FShifts1SC);
+  end;
+
+  //
+  // End with the extra key addition
+  //
+  KeyAddition(rk[0]);
+end;
+
+constructor TRijndaelEngine.Create();
+begin
+  Create(128);
+end;
+
+constructor TRijndaelEngine.Create(blockBits: Int32);
+begin
+  Inherited Create();
+  case blockBits of
+
+    128:
+      begin
+        FBC := 32;
+        FBC_MASK := $FFFFFFFF;
+        System.SetLength(FShifts0SC, System.SizeOf(shifts0[0]));
+        System.Move(shifts0[0], FShifts0SC[0], System.SizeOf(shifts0[0]));
+        System.SetLength(FShifts1SC, System.SizeOf(shifts1[0]));
+        System.Move(shifts1[0], FShifts1SC[0], System.SizeOf(shifts1[0]));
+      end;
+
+    160:
+      begin
+        FBC := 40;
+        FBC_MASK := $FFFFFFFFFF;
+        System.SetLength(FShifts0SC, System.SizeOf(shifts0[1]));
+        System.Move(shifts0[1], FShifts0SC[0], System.SizeOf(shifts0[1]));
+        System.SetLength(FShifts1SC, System.SizeOf(shifts1[1]));
+        System.Move(shifts1[1], FShifts1SC[0], System.SizeOf(shifts1[1]));
+      end;
+
+    192:
+      begin
+        FBC := 48;
+        FBC_MASK := $FFFFFFFFFFFF;
+        System.SetLength(FShifts0SC, System.SizeOf(shifts0[2]));
+        System.Move(shifts0[2], FShifts0SC[0], System.SizeOf(shifts0[2]));
+        System.SetLength(FShifts1SC, System.SizeOf(shifts1[2]));
+        System.Move(shifts1[2], FShifts1SC[0], System.SizeOf(shifts1[2]));
+      end;
+
+    224:
+      begin
+        FBC := 56;
+        FBC_MASK := $FFFFFFFFFFFFFF;
+        System.SetLength(FShifts0SC, System.SizeOf(shifts0[3]));
+        System.Move(shifts0[3], FShifts0SC[0], System.SizeOf(shifts0[3]));
+        System.SetLength(FShifts1SC, System.SizeOf(shifts1[3]));
+        System.Move(shifts1[3], FShifts1SC[0], System.SizeOf(shifts1[3]));
+      end;
+
+    256:
+      begin
+        FBC := 64;
+        FBC_MASK := UInt64($FFFFFFFFFFFFFFFF);
+        System.SetLength(FShifts0SC, System.SizeOf(shifts0[4]));
+        System.Move(shifts0[4], FShifts0SC[0], System.SizeOf(shifts0[4]));
+        System.SetLength(FShifts1SC, System.SizeOf(shifts1[4]));
+        System.Move(shifts1[4], FShifts1SC[0], System.SizeOf(shifts1[4]));
+      end
+  else
+    begin
+      raise EArgumentOutOfRangeCryptoLibException.CreateRes(@SUnsupportedBlock);
+    end;
+
+  end;
+
+  FBlockBits := blockBits;
+end;
+
+function TRijndaelEngine.GetAlgorithmName: String;
+begin
+  result := 'Rijndael';
+end;
+
+function TRijndaelEngine.GetBlockSize: Int32;
+begin
+  result := FBC div 2;
+end;
+
+function TRijndaelEngine.GetIsPartialBlockOkay: Boolean;
+begin
+  result := False;
+end;
+
+procedure TRijndaelEngine.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  keyParameter: IKeyParameter;
+begin
+  if not Supports(parameters, IKeyParameter, keyParameter) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SInvalidParameterRijndaelInit, [(parameters as TObject).ToString]);
+  end;
+
+  FWorkingKey := GenerateWorkingKey(keyParameter.GetKey());
+
+  FForEncryption := forEncryption;
+end;
+
+function TRijndaelEngine.ProcessBlock(const input: TCryptoLibByteArray;
+  inOff: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+  if (FWorkingKey = Nil) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SRijndaelEngineNotInitialised);
+  end;
+
+  TCheck.DataLength(input, inOff, (FBC div 2), SInputBuffertooShort);
+  TCheck.OutputLength(output, outOff, (FBC div 2), SOutputBuffertooShort);
+
+  UnPackBlock(input, inOff);
+
+  if (FForEncryption) then
+  begin
+    EncryptBlock(FWorkingKey);
+  end
+  else
+  begin
+    DecryptBlock(FWorkingKey);
+  end;
+
+  PackBlock(output, outOff);
+
+  result := FBC div 2;
+end;
+
+procedure TRijndaelEngine.Reset;
+begin
+
+end;
+
+end.

+ 502 - 0
CryptoLib/src/Crypto/Engines/ClpSalsa20Engine.pas

@@ -0,0 +1,502 @@
+{ *********************************************************************************** }
+{ *                              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 ClpSalsa20Engine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpBits,
+  ClpCheck,
+  ClpIStreamCipher,
+  ClpISalsa20Engine,
+  ClpIKeyParameter,
+  ClpICipherParameters,
+  ClpIParametersWithIV,
+  ClpConverters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidRound = '"rounds" Must be a Positive, Even Number';
+  SInvalidKeySize = '%s Requires 128 bit or 256 bit key';
+  SMaxByteExceeded = '2^70 Byte Limit per IV; Change IV';
+  SMaxByteExceededTwo = '2^70 byte limit per IV would be exceeded; Change IV';
+  SEngineNotInitialized = '%s not Initialized';
+  SInputBuffertooShort = 'Input Buffer too Short';
+  SOutputBuffertooShort = 'Output Buffer too Short';
+  SRoundsMustbeEven = 'Number of Rounds Must be Even';
+{$IFNDEF _FIXINSIGHT_}
+  SIVRequired = '%s Init Requires an IV, "parameters"';
+  SInvalidIV = '%s Requires exactly %d bytes of IV';
+  SInitError =
+    '%s Init Parameters must Contain a KeyParameter (or null for Re-Init)';
+  SKeyParameterNullForFirstInit =
+    'KeyParameter can not be null for First Initialisation';
+{$ENDIF}
+
+type
+
+  /// <summary>
+  /// Implementation of Daniel J. Bernstein's Salsa20 stream cipher, Snuffle 2005
+  /// </summary>
+  TSalsa20Engine = class(TInterfacedObject, ISalsa20Engine, IStreamCipher)
+
+  strict private
+  const
+    DEFAULT_ROUNDS = Int32(20);
+    STATE_SIZE = Int32(16); // 16, 32 bit ints = 64 bytes
+    // representation of 'expand 16-byte k' + 'expand 32-byte k' as an array of UInt32
+    TAU_SIGMA: array [0 .. 7] of UInt32 = (1634760805, 824206446, 2036477238,
+      1797285236, 1634760805, 857760878, 2036477234, 1797285236);
+
+  var
+    FIndex: Int32;
+    // internal counter
+    FCW0, FCW1, FCW2: UInt32;
+    FKeyStream: TCryptoLibByteArray;
+    FInitialised: Boolean;
+
+    procedure ResetLimitCounter(); inline;
+    function LimitExceeded(): Boolean; overload; inline;
+    // this relies on the fact len will always be positive.
+    function LimitExceeded(len: UInt32): Boolean; overload; inline;
+
+  strict protected
+  var
+    FRounds: Int32;
+    FEngineState, Fx: TCryptoLibUInt32Array;
+
+    function GetAlgorithmName: String; virtual;
+    function GetNonceSize: Int32; virtual;
+    property NonceSize: Int32 read GetNonceSize;
+
+    procedure AdvanceCounter(); virtual;
+    procedure ResetCounter(); virtual;
+    procedure SetKey(const keyBytes, ivBytes: TCryptoLibByteArray); virtual;
+    procedure GenerateKeyStream(const output: TCryptoLibByteArray); virtual;
+
+    /// <summary>
+    /// Rotate left
+    /// </summary>
+    /// <param name="x">
+    /// value to rotate
+    /// </param>
+    /// <param name="y">
+    /// amount to rotate x
+    /// </param>
+    /// <returns>
+    /// rotated x
+    /// </returns>
+    class function R(x: UInt32; y: Int32): UInt32; static; inline;
+    class procedure PackTauOrSigma(keyLength: Int32;
+      const state: TCryptoLibUInt32Array; stateOffset: Int32); static;
+    class procedure SalsaCore(rounds: Int32;
+      const input, x: TCryptoLibUInt32Array); static;
+
+  public
+    /// <summary>
+    /// Creates a 20 round Salsa20 engine.
+    /// </summary>
+    constructor Create(); overload;
+    /// <summary>
+    /// Creates a Salsa20 engine with a specific number of rounds.
+    /// </summary>
+    /// <param name="rounds">the number of rounds (must be an even number).</param>
+    constructor Create(rounds: Int32); overload;
+
+{$IFNDEF _FIXINSIGHT_}
+    procedure Init(forEncryption: Boolean;
+      const parameters: ICipherParameters); virtual;
+{$ENDIF}
+    function ReturnByte(input: Byte): Byte; virtual;
+
+    procedure ProcessBytes(const inBytes: TCryptoLibByteArray;
+      inOff, len: Int32; const outBytes: TCryptoLibByteArray;
+      outOff: Int32); virtual;
+
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TSalsa20Engine }
+
+constructor TSalsa20Engine.Create;
+begin
+  Create(DEFAULT_ROUNDS);
+end;
+
+procedure TSalsa20Engine.AdvanceCounter;
+begin
+  System.Inc(FEngineState[8]);
+  if (FEngineState[8] = 0) then
+  begin
+    System.Inc(FEngineState[9]);
+  end;
+end;
+
+constructor TSalsa20Engine.Create(rounds: Int32);
+begin
+  Inherited Create();
+  if ((rounds <= 0) or ((rounds and 1) <> 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidRound);
+  end;
+  FRounds := rounds;
+  FIndex := 0;
+  FInitialised := false;
+  System.SetLength(FEngineState, STATE_SIZE); // state
+  System.SetLength(Fx, STATE_SIZE); // internal buffer
+  System.SetLength(FKeyStream, STATE_SIZE * 4); // expanded state, 64 bytes
+end;
+
+procedure TSalsa20Engine.GenerateKeyStream(const output: TCryptoLibByteArray);
+begin
+  SalsaCore(FRounds, FEngineState, Fx);
+  TConverters.le32_copy(PCardinal(Fx), 0, PByte(output), 0,
+    System.Length(Fx) * System.SizeOf(UInt32));
+end;
+
+function TSalsa20Engine.GetAlgorithmName: String;
+begin
+  result := 'Salsa20';
+  if (FRounds <> DEFAULT_ROUNDS) then
+  begin
+    result := Format('%s/%d', [result, FRounds]);
+  end;
+end;
+
+function TSalsa20Engine.GetNonceSize: Int32;
+begin
+  result := 8;
+end;
+
+{$IFNDEF _FIXINSIGHT_}
+
+procedure TSalsa20Engine.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  ivParams: IParametersWithIV;
+  iv: TCryptoLibByteArray;
+  keyParam: ICipherParameters;
+begin
+  (*
+    * Salsa20 encryption and decryption is completely
+    * symmetrical, so the 'forEncryption' is
+    * irrelevant. (Like 90% of stream ciphers)
+  *)
+
+  if not Supports(parameters, IParametersWithIV, ivParams) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SIVRequired,
+      [AlgorithmName]);
+  end;
+
+  iv := ivParams.GetIV();
+  if ((iv = Nil) or (System.Length(iv) <> NonceSize)) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidIV,
+      [AlgorithmName, NonceSize]);
+  end;
+
+  keyParam := ivParams.parameters;
+  if (keyParam = Nil) then
+  begin
+    if (not FInitialised) then
+    begin
+      raise EArgumentCryptoLibException.CreateResFmt
+        (@SKeyParameterNullForFirstInit, [AlgorithmName]);
+    end;
+
+    SetKey(Nil, iv);
+  end
+  else if Supports(keyParam, IKeyParameter) then
+  begin
+    SetKey((keyParam as IKeyParameter).GetKey(), iv);
+  end
+  else
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInitError,
+      [AlgorithmName]);
+  end;
+
+  Reset();
+  FInitialised := true;
+end;
+{$ENDIF}
+
+function TSalsa20Engine.LimitExceeded: Boolean;
+begin
+  System.Inc(FCW0);
+  if (FCW0 = 0) then
+  begin
+    System.Inc(FCW1);
+    if (FCW1 = 0) then
+    begin
+      System.Inc(FCW2);
+      result := (FCW2 and $20) <> 0; // 2^(32 + 32 + 6)
+      Exit;
+    end;
+  end;
+
+  result := false;
+end;
+
+function TSalsa20Engine.LimitExceeded(len: UInt32): Boolean;
+var
+  Old: UInt32;
+begin
+  Old := FCW0;
+  System.Inc(FCW0, len);
+  if (FCW0 < Old) then
+  begin
+    System.Inc(FCW1);
+    if (FCW1 = 0) then
+    begin
+      System.Inc(FCW2);
+      result := (FCW2 and $20) <> 0; // 2^(32 + 32 + 6)
+      Exit;
+    end;
+  end;
+
+  result := false;
+end;
+
+class procedure TSalsa20Engine.PackTauOrSigma(keyLength: Int32;
+  const state: TCryptoLibUInt32Array; stateOffset: Int32);
+var
+  tsOff: Int32;
+begin
+  tsOff := (keyLength - 16) div 4;
+  state[stateOffset] := TAU_SIGMA[tsOff];
+  state[stateOffset + 1] := TAU_SIGMA[tsOff + 1];
+  state[stateOffset + 2] := TAU_SIGMA[tsOff + 2];
+  state[stateOffset + 3] := TAU_SIGMA[tsOff + 3];
+end;
+
+procedure TSalsa20Engine.ProcessBytes(const inBytes: TCryptoLibByteArray;
+  inOff, len: Int32; const outBytes: TCryptoLibByteArray; outOff: Int32);
+var
+  Idx: Int32;
+begin
+  if (not FInitialised) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateResFmt
+      (@SEngineNotInitialized, [AlgorithmName]);
+  end;
+
+  TCheck.DataLength(inBytes, inOff, len, SInputBuffertooShort);
+  TCheck.OutputLength(outBytes, outOff, len, SOutputBuffertooShort);
+
+  if (LimitExceeded(UInt32(len))) then
+  begin
+    raise EMaxBytesExceededCryptoLibException.CreateRes(@SMaxByteExceededTwo);
+  end;
+
+  for Idx := 0 to System.Pred(len) do
+  begin
+    if (FIndex = 0) then
+    begin
+      GenerateKeyStream(FKeyStream);
+      AdvanceCounter();
+    end;
+    outBytes[Idx + outOff] := Byte(FKeyStream[FIndex] xor inBytes[Idx + inOff]);
+    FIndex := (FIndex + 1) and 63;
+  end;
+end;
+
+class function TSalsa20Engine.R(x: UInt32; y: Int32): UInt32;
+begin
+  result := TBits.RotateLeft32(x, y);
+end;
+
+procedure TSalsa20Engine.ResetCounter;
+begin
+  FEngineState[8] := 0;
+  FEngineState[9] := 0;
+end;
+
+procedure TSalsa20Engine.ResetLimitCounter;
+begin
+  FCW0 := 0;
+  FCW1 := 0;
+  FCW2 := 0;
+end;
+
+procedure TSalsa20Engine.Reset;
+begin
+  FIndex := 0;
+  ResetLimitCounter();
+  ResetCounter();
+end;
+
+function TSalsa20Engine.ReturnByte(input: Byte): Byte;
+var
+  output: Byte;
+begin
+  if (LimitExceeded()) then
+  begin
+    raise EMaxBytesExceededCryptoLibException.CreateRes(@SMaxByteExceeded);
+  end;
+
+  if (FIndex = 0) then
+  begin
+    GenerateKeyStream(FKeyStream);
+    AdvanceCounter();
+  end;
+
+  output := Byte(FKeyStream[FIndex] xor input);
+  FIndex := (FIndex + 1) and 63;
+
+  result := output;
+end;
+
+class procedure TSalsa20Engine.SalsaCore(rounds: Int32;
+  const input, x: TCryptoLibUInt32Array);
+var
+  x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14,
+    x15: UInt32;
+  Idx: Int32;
+begin
+  if (System.Length(input) <> 16) then
+  begin
+    raise EArgumentCryptoLibException.Create('');
+  end;
+  if (System.Length(x) <> 16) then
+  begin
+    raise EArgumentCryptoLibException.Create('');
+  end;
+  if ((rounds mod 2) <> 0) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SRoundsMustbeEven);
+  end;
+
+  x00 := input[0];
+  x01 := input[1];
+  x02 := input[2];
+  x03 := input[3];
+  x04 := input[4];
+  x05 := input[5];
+  x06 := input[6];
+  x07 := input[7];
+  x08 := input[8];
+  x09 := input[9];
+  x10 := input[10];
+  x11 := input[11];
+  x12 := input[12];
+  x13 := input[13];
+  x14 := input[14];
+  x15 := input[15];
+
+  Idx := rounds;
+  while Idx > 0 do
+  begin
+
+    x04 := x04 xor (R((x00 + x12), 7));
+    x08 := x08 xor (R((x04 + x00), 9));
+    x12 := x12 xor (R((x08 + x04), 13));
+    x00 := x00 xor (R((x12 + x08), 18));
+    x09 := x09 xor (R((x05 + x01), 7));
+    x13 := x13 xor (R((x09 + x05), 9));
+    x01 := x01 xor (R((x13 + x09), 13));
+    x05 := x05 xor (R((x01 + x13), 18));
+    x14 := x14 xor (R((x10 + x06), 7));
+    x02 := x02 xor (R((x14 + x10), 9));
+    x06 := x06 xor (R((x02 + x14), 13));
+    x10 := x10 xor (R((x06 + x02), 18));
+    x03 := x03 xor (R((x15 + x11), 7));
+    x07 := x07 xor (R((x03 + x15), 9));
+    x11 := x11 xor (R((x07 + x03), 13));
+    x15 := x15 xor (R((x11 + x07), 18));
+
+    x01 := x01 xor (R((x00 + x03), 7));
+    x02 := x02 xor (R((x01 + x00), 9));
+    x03 := x03 xor (R((x02 + x01), 13));
+    x00 := x00 xor (R((x03 + x02), 18));
+    x06 := x06 xor (R((x05 + x04), 7));
+    x07 := x07 xor (R((x06 + x05), 9));
+    x04 := x04 xor (R((x07 + x06), 13));
+    x05 := x05 xor (R((x04 + x07), 18));
+    x11 := x11 xor (R((x10 + x09), 7));
+    x08 := x08 xor (R((x11 + x10), 9));
+    x09 := x09 xor (R((x08 + x11), 13));
+    x10 := x10 xor (R((x09 + x08), 18));
+    x12 := x12 xor (R((x15 + x14), 7));
+    x13 := x13 xor (R((x12 + x15), 9));
+    x14 := x14 xor (R((x13 + x12), 13));
+    x15 := x15 xor (R((x14 + x13), 18));
+
+    System.Dec(Idx, 2);
+  end;
+
+  x[0] := x00 + input[0];
+  x[1] := x01 + input[1];
+  x[2] := x02 + input[2];
+  x[3] := x03 + input[3];
+  x[4] := x04 + input[4];
+  x[5] := x05 + input[5];
+  x[6] := x06 + input[6];
+  x[7] := x07 + input[7];
+  x[8] := x08 + input[8];
+  x[9] := x09 + input[9];
+  x[10] := x10 + input[10];
+  x[11] := x11 + input[11];
+  x[12] := x12 + input[12];
+  x[13] := x13 + input[13];
+  x[14] := x14 + input[14];
+  x[15] := x15 + input[15];
+
+end;
+
+procedure TSalsa20Engine.SetKey(const keyBytes, ivBytes: TCryptoLibByteArray);
+var
+  tsOff: Int32;
+begin
+  if (keyBytes <> Nil) then
+  begin
+    if not(Byte(System.Length(keyBytes)) in [16, 32]) then
+    begin
+      raise EArgumentCryptoLibException.CreateResFmt(@SInvalidKeySize,
+        [AlgorithmName]);
+    end;
+
+    tsOff := (System.Length(keyBytes) - 16) div 4;
+    FEngineState[0] := TAU_SIGMA[tsOff];
+    FEngineState[5] := TAU_SIGMA[tsOff + 1];
+    FEngineState[10] := TAU_SIGMA[tsOff + 2];
+    FEngineState[15] := TAU_SIGMA[tsOff + 3];
+
+    // Key
+    TConverters.le32_copy(PByte(keyBytes), 0, PCardinal(FEngineState),
+      1 * System.SizeOf(UInt32), 4 * System.SizeOf(UInt32));
+    TConverters.le32_copy(PByte(keyBytes), (System.Length(keyBytes) - 16) *
+      System.SizeOf(Byte), PCardinal(FEngineState), 11 * System.SizeOf(UInt32),
+      4 * System.SizeOf(UInt32));
+  end;
+
+  // IV
+  TConverters.le32_copy(PByte(ivBytes), 0, PCardinal(FEngineState),
+    6 * System.SizeOf(UInt32), 2 * System.SizeOf(UInt32));
+end;
+
+end.

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

@@ -0,0 +1,1091 @@
+{ *********************************************************************************** }
+{ *                              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.
+

+ 1093 - 0
CryptoLib/src/Crypto/Engines/ClpSpeckLegacyEngine.pas

@@ -0,0 +1,1093 @@
+{ *********************************************************************************** }
+{ *                              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 ClpSpeckLegacyEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpCheck,
+  ClpISpeckLegacyEngine,
+  ClpIBlockCipher,
+  ClpICipherParameters,
+  ClpIKeyParameter,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SSpeckLegacyEngineNotInitialised = '%s Engine not Initialised';
+  SInputBuffertooShort = 'Input Buffer too Short';
+  SOutputBuffertooShort = 'Output Buffer too Short';
+  SInvalidArgumentEncountered = 'Invalid Argument Encountered.';
+  SInvalidParameterSpeckLegacyInit =
+    'Invalid Parameter Passed to SpeckLegacy Init - "%s"';
+  SSpeck32LegacyInvalidKeySize =
+    'Speck32Legacy requires a key of 64 bits but input was "%d" bits.';
+  SSpeck48LegacyInvalidKeySize =
+    'Speck48Legacy requires a key of 72 or 96 bits but input was "%d" bits.';
+  SSpeck64LegacyInvalidKeySize =
+    'Speck64Legacy requires a key of 96 or 128 bits but input was "%d" bits.';
+  SSpeck96LegacyInvalidKeySize =
+    'Speck96Legacy requires a key of 96 or 144 bits but input was "%d" bits.';
+  SSpeck128LegacyInvalidKeySize =
+    'Speck128Legacy requires a key of 128, 192 or 256 bits but input was "%d" bits.';
+
+type
+
+  /// <summary>
+  /// A <b>variant</b> of the Speck family of block ciphers which treats data
+  /// in big endian format for compatibility with some other <b>wrong</b>
+  /// implementations .
+  /// </summary>
+  TSpeckLegacyEngine = class abstract(TInterfacedObject, ISpeckLegacyEngine,
+    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="ClpSpeckLegacyEngine|TSpeckLegacyEngine.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="ClpSpeckLegacyEngine|TSpeckLegacyEngine.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="ClpSpeckLegacyEngine|TSpeckLegacyEngine.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 SpeckLegacy 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 Legacy variants that fit in 32 bit Pascal Integers:
+  /// SpeckLegacy32, SpeckLegacy48, SpeckLegacy64.
+  /// Speck32 and Speck48 (16 and 24 bit word sizes) are implemented using masking.
+  /// </summary>
+  TSpeckUInt32LegacyEngine = class abstract(TSpeckLegacyEngine)
+
+  strict private
+  var
+
+    /// <summary>
+    /// The expanded key schedule for all <see cref="ClpSpeckLegacyEngine|TSpeckLegacyEngine.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="ClpSpeckLegacyEngine|TSpeckLegacyEngine.FwordSize" /> bytes from
+    /// the input data in <b>big-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="ClpSpeckLegacyEngine|TSpeckLegacyEngine.FwordSize" /> bytes
+    /// into a buffer in <b>big-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 SpeckLegacy 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 SpeckLegacy 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 Leagcy variants that fit in 64 bit Pascal Integers:
+  /// SpeckLegacy96, SpeckLegacy128.
+  /// Speck96 (48 bit word size) is implemented using masking.
+  /// </summary>
+  TSpeckUInt64LegacyEngine = class abstract(TSpeckLegacyEngine)
+
+  strict private
+  var
+
+    /// <summary>
+    /// The expanded key schedule for all <see cref="ClpSpeckLegacyEngine|TSpeckLegacyEngine.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="ClpSpeckLegacyEngine|TSpeckLegacyEngine.FwordSize" /> bytes from
+    /// the input data in big-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="ClpSpeckLegacyEngine|TSpeckLegacyEngine.FwordSize" /> bytes
+    /// into a buffer in big-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 SpeckLegacy 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 SpeckLegacy 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>
+  /// Speck32Legacy: 2 byte words, 7/2 rotation constants.
+  /// <p>
+  /// 20 base rounds (hypothetical)
+  /// </p>
+  /// 64 bit key/22 rounds.
+  /// </summary>
+  TSpeck32LegacyEngine = class sealed(TSpeckUInt32LegacyEngine)
+
+  strict protected
+    function Mask(val: UInt32): UInt32; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck48Legacy: 3 byte words, 8/3 rotation constants.
+  /// <p>
+  /// 21 base rounds (hypothetical)
+  /// </p>
+  /// 72 bit key/22 rounds.
+  /// 96 bit key/23 rounds.
+  /// </summary>
+  TSpeck48LegacyEngine = class sealed(TSpeckUInt32LegacyEngine)
+
+  strict protected
+    function Mask(val: UInt32): UInt32; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck64Legacy: 4 byte words, 8/3 rotation constants.
+  /// <p>
+  /// 25 base rounds (hypothetical)
+  /// </p>
+  /// 96 bit key/26 rounds.
+  /// 128 bit key/27 rounds.
+  /// </summary>
+  TSpeck64LegacyEngine = class sealed(TSpeckUInt32LegacyEngine)
+
+  strict protected
+    function Mask(val: UInt32): UInt32; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck96Legacy: 6 byte words, 8/3 rotation constants.
+  /// <p>
+  /// 28 base rounds
+  /// </p>
+  /// 96 bit key/28 rounds.
+  /// 144 bit key/29 rounds.
+  /// </summary>
+  TSpeck96LegacyEngine = class sealed(TSpeckUInt64LegacyEngine)
+
+  strict protected
+    function Mask(val: UInt64): UInt64; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+type
+
+  /// <summary>
+  /// Speck128Legacy: 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>
+  TSpeck128LegacyEngine = class sealed(TSpeckUInt64LegacyEngine)
+
+  strict protected
+    function Mask(val: UInt64): UInt64; override;
+    procedure CheckKeySize(keySizeBytes: Int32); override;
+
+  public
+    constructor Create();
+
+  end;
+
+implementation
+
+{ TSpeckLegacyEngine }
+
+constructor TSpeckLegacyEngine.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 TSpeckLegacyEngine.GetBlockSize: Int32;
+begin
+  result := FblockSize;
+end;
+
+procedure TSpeckLegacyEngine.EngineInit(forEncryption: Boolean;
+  const keyBytes: TCryptoLibByteArray);
+begin
+  FforEncryption := forEncryption;
+  CheckKeySize(System.Length(keyBytes));
+  SetKey(keyBytes);
+  Finitialised := true;
+end;
+
+function TSpeckLegacyEngine.GetAlgorithmName: String;
+begin
+  result := Format('SpeckLegacy%d', [FblockSize * 8]);
+end;
+
+function TSpeckLegacyEngine.GetIsPartialBlockOkay: Boolean;
+begin
+  result := false;
+end;
+
+procedure TSpeckLegacyEngine.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  keyParameter: IKeyParameter;
+  keyBytes: TCryptoLibByteArray;
+begin
+
+  if not Supports(parameters, IKeyParameter, keyParameter) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SInvalidParameterSpeckLegacyInit, [(parameters as TObject).ToString]);
+  end;
+  keyBytes := keyParameter.GetKey;
+  EngineInit(forEncryption, keyBytes);
+end;
+
+function TSpeckLegacyEngine.ProcessBlock(const input: TCryptoLibByteArray;
+  inOff: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+  if (not Finitialised) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateResFmt
+      (@SSpeckLegacyEngineNotInitialised, [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 TSpeckLegacyEngine.Reset;
+begin
+  // nothing to do.
+end;
+
+{ TSpeckUInt32LegacyEngine }
+
+function TSpeckUInt32LegacyEngine.Rotl(i: UInt32; distance: Int32): UInt32;
+begin
+  result := ((i shl distance) or (i shr (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt32LegacyEngine.Rotr(i: UInt32; distance: Int32): UInt32;
+begin
+  result := ((i shr distance) or (i shl (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt32LegacyEngine.BytesToWord(const bytes: TCryptoLibByteArray;
+  off: Int32): UInt32;
+var
+  index: Int32;
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  index := off;
+  result := (bytes[index]);
+  System.Inc(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Inc(index);
+  if (FwordSize > 2) then
+  begin
+    result := (result shl 8) or (bytes[index]);
+    System.Inc(index);
+    if (FwordSize > 3) then
+    begin
+      result := (result shl 8) or (bytes[index]);
+    end;
+  end;
+
+end;
+
+procedure TSpeckUInt32LegacyEngine.WordToBytes(word: UInt32;
+  const bytes: TCryptoLibByteArray; off: Int32);
+var
+  index: Int32;
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  index := off + FwordSize - 1;
+  bytes[index] := Byte(word);
+  System.Dec(index);
+  bytes[index] := Byte(word shr 8);
+  System.Dec(index);
+  if (FwordSize > 2) then
+  begin
+    bytes[index] := Byte(word shr 16);
+    System.Dec(index);
+    if (FwordSize > 3) then
+    begin
+      bytes[index] := Byte(word shr 24);
+    end;
+  end;
+
+end;
+
+constructor TSpeckUInt32LegacyEngine.Create(wordSize, baseRounds: Int32);
+begin
+  Create(wordSize, baseRounds, 8, 3);
+end;
+
+constructor TSpeckUInt32LegacyEngine.Create(wordSize, baseRounds, alpha,
+  beta: Int32);
+begin
+  Inherited Create(wordSize, baseRounds, alpha, beta);
+end;
+
+procedure TSpeckUInt32LegacyEngine.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 TSpeckUInt32LegacyEngine.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 TSpeckUInt32LegacyEngine.PackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  WordToBytes(Fy, bytes, off + FwordSize);
+  WordToBytes(Fx, bytes, off);
+end;
+
+procedure TSpeckUInt32LegacyEngine.UnPackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Fy := BytesToWord(bytes, off + FwordSize);
+  Fx := BytesToWord(bytes, off);
+end;
+
+procedure TSpeckUInt32LegacyEngine.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, (keyWords - 1) * FwordSize);
+
+  // 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[i] := BytesToWord(keyBytes, (keyWords - i - 2) * 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;
+
+{ TSpeckUInt64LegacyEngine }
+
+function TSpeckUInt64LegacyEngine.Rotl(i: UInt64; distance: Int32): UInt64;
+begin
+  result := ((i shl distance) or (i shr (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt64LegacyEngine.Rotr(i: UInt64; distance: Int32): UInt64;
+begin
+  result := ((i shr distance) or (i shl (FwordSizeBits - distance)));
+end;
+
+function TSpeckUInt64LegacyEngine.BytesToWord(const bytes: TCryptoLibByteArray;
+  off: Int32): UInt64;
+var
+  index: Int32;
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  index := off;
+  result := (bytes[index]);
+  System.Inc(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Inc(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Inc(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Inc(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Inc(index);
+  result := (result shl 8) or (bytes[index]);
+  System.Inc(index);
+  if (FwordSize = 8) then
+  begin
+    result := (result shl 8) or (bytes[index]);
+    System.Inc(index);
+    result := (result shl 8) or (bytes[index]);
+  end;
+end;
+
+procedure TSpeckUInt64LegacyEngine.WordToBytes(word: UInt64;
+  const bytes: TCryptoLibByteArray; off: Int32);
+var
+  index: Int32;
+begin
+  TCheck.DataLength((off + FwordSize) > System.Length(bytes),
+    SInvalidArgumentEncountered);
+
+  index := off + FwordSize - 1;
+  bytes[index] := Byte(word);
+  System.Dec(index);
+  bytes[index] := Byte(word shr 8);
+  System.Dec(index);
+  bytes[index] := Byte(word shr 16);
+  System.Dec(index);
+  bytes[index] := Byte(word shr 24);
+  System.Dec(index);
+  bytes[index] := Byte(word shr 32);
+  System.Dec(index);
+  bytes[index] := Byte(word shr 40);
+  System.Dec(index);
+  if (FwordSize = 8) then
+  begin
+    bytes[index] := Byte(word shr 48);
+    System.Dec(index);
+    bytes[index] := Byte(word shr 56);
+  end;
+
+end;
+
+constructor TSpeckUInt64LegacyEngine.Create(wordSize, baseRounds: Int32);
+begin
+  Create(wordSize, baseRounds, 8, 3);
+end;
+
+constructor TSpeckUInt64LegacyEngine.Create(wordSize, baseRounds, alpha,
+  beta: Int32);
+begin
+  Inherited Create(wordSize, baseRounds, alpha, beta);
+end;
+
+procedure TSpeckUInt64LegacyEngine.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 TSpeckUInt64LegacyEngine.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 TSpeckUInt64LegacyEngine.PackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  WordToBytes(Fy, bytes, off + FwordSize);
+  WordToBytes(Fx, bytes, off);
+end;
+
+procedure TSpeckUInt64LegacyEngine.UnPackBlock(const bytes: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Fy := BytesToWord(bytes, off + FwordSize);
+  Fx := BytesToWord(bytes, off);
+end;
+
+procedure TSpeckUInt64LegacyEngine.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, (keyWords - 1) * FwordSize);
+
+  // 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[i] := BytesToWord(keyBytes, (keyWords - i - 2) * 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;
+
+{ TSpeck32LegacyEngine }
+
+constructor TSpeck32LegacyEngine.Create;
+begin
+  Inherited Create(2, 20, 7, 2);
+end;
+
+function TSpeck32LegacyEngine.Mask(val: UInt32): UInt32;
+begin
+  result := (val and $FFFF);
+end;
+
+procedure TSpeck32LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if (keySizeBytes <> 8) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SSpeck32LegacyInvalidKeySize, [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck48LegacyEngine }
+
+constructor TSpeck48LegacyEngine.Create;
+begin
+  Inherited Create(3, 21);
+end;
+
+function TSpeck48LegacyEngine.Mask(val: UInt32): UInt32;
+begin
+  result := (val and $FFFFFF);
+end;
+
+procedure TSpeck48LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [9, 12]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SSpeck48LegacyInvalidKeySize, [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck64LgacyEngine }
+
+constructor TSpeck64LegacyEngine.Create;
+begin
+  Inherited Create(4, 25);
+end;
+
+function TSpeck64LegacyEngine.Mask(val: UInt32): UInt32;
+begin
+  result := val;
+end;
+
+procedure TSpeck64LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [12, 16]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SSpeck64LegacyInvalidKeySize, [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck96LgacyEngine }
+
+constructor TSpeck96LegacyEngine.Create;
+begin
+  Inherited Create(6, 28);
+end;
+
+function TSpeck96LegacyEngine.Mask(val: UInt64): UInt64;
+begin
+  result := (val and $0000FFFFFFFFFFFF);
+end;
+
+procedure TSpeck96LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [12, 18]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SSpeck96LegacyInvalidKeySize, [keySizeBytes * 8]);
+  end;
+end;
+
+{ TSpeck128LegacyEngine }
+
+constructor TSpeck128LegacyEngine.Create;
+begin
+  Inherited Create(8, 32);
+end;
+
+function TSpeck128LegacyEngine.Mask(val: UInt64): UInt64;
+begin
+  result := val;
+end;
+
+procedure TSpeck128LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+begin
+  if not(keySizeBytes in [16, 24, 32]) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SSpeck128LegacyInvalidKeySize, [keySizeBytes * 8]);
+  end;
+end;
+
+end.

+ 115 - 0
CryptoLib/src/Crypto/Engines/ClpXSalsa20Engine.pas

@@ -0,0 +1,115 @@
+{ *********************************************************************************** }
+{ *                              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 ClpXSalsa20Engine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIStreamCipher,
+  ClpSalsa20Engine,
+  ClpIXSalsa20Engine,
+  ClpConverters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNullKeyReInit = '%s Doesn''t Support Re-Init with Null Key';
+  SInvalidKeySize = '%s Requires a 256 bit Key';
+
+type
+  /// <summary>
+  /// Implementation of Daniel J. Bernstein's XSalsa20 stream cipher - Salsa20 with an extended nonce.
+  /// </summary>
+  /// <remarks>
+  /// XSalsa20 requires a 256 bit key, and a 192 bit nonce.
+  /// </remarks>
+  TXSalsa20Engine = class sealed(TSalsa20Engine, IXSalsa20Engine, IStreamCipher)
+
+  strict protected
+    function GetAlgorithmName: String; override;
+    function GetNonceSize: Int32; override;
+    /// <summary>
+    /// XSalsa20 key generation: process 256 bit input key and 128 bits of the input nonce
+    /// using a core Salsa20 function without input addition to produce 256 bit working key
+    /// and use that with the remaining 64 bits of nonce to initialize a standard Salsa20 engine state.
+    /// </summary>
+    procedure SetKey(const keyBytes, ivBytes: TCryptoLibByteArray); override;
+
+  end;
+
+implementation
+
+{ TXSalsa20Engine }
+
+function TXSalsa20Engine.GetAlgorithmName: String;
+begin
+  result := 'XSalsa20';
+end;
+
+function TXSalsa20Engine.GetNonceSize: Int32;
+begin
+  result := 24;
+end;
+
+procedure TXSalsa20Engine.SetKey(const keyBytes, ivBytes: TCryptoLibByteArray);
+var
+  hsalsa20Out: TCryptoLibUInt32Array;
+begin
+  if (keyBytes = Nil) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SNullKeyReInit,
+      [AlgorithmName]);
+  end;
+
+  if (System.Length(keyBytes) <> 32) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidKeySize,
+      [AlgorithmName]);
+  end;
+
+  // Set key for HSalsa20
+  Inherited SetKey(keyBytes, ivBytes);
+
+  // Pack next 64 bits of IV into engine state instead of counter
+  TConverters.le32_copy(PByte(ivBytes), 8 * System.SizeOf(Byte),
+    PCardinal(FEngineState), 8 * System.SizeOf(UInt32),
+    2 * System.SizeOf(UInt32));
+
+  // Process engine state to generate Salsa20 key
+  System.SetLength(hsalsa20Out, System.Length(FEngineState));
+  SalsaCore(20, FEngineState, hsalsa20Out);
+
+  // Set new key, removing addition in last round of salsaCore
+  FEngineState[1] := hsalsa20Out[0] - FEngineState[0];
+  FEngineState[2] := hsalsa20Out[5] - FEngineState[5];
+  FEngineState[3] := hsalsa20Out[10] - FEngineState[10];
+  FEngineState[4] := hsalsa20Out[15] - FEngineState[15];
+
+  FEngineState[11] := hsalsa20Out[6] - FEngineState[6];
+  FEngineState[12] := hsalsa20Out[7] - FEngineState[7];
+  FEngineState[13] := hsalsa20Out[8] - FEngineState[8];
+  FEngineState[14] := hsalsa20Out[9] - FEngineState[9];
+
+  // Last 64 bits of input IV
+  TConverters.le32_copy(PByte(ivBytes), 16 * System.SizeOf(Byte),
+    PCardinal(FEngineState), 6 * System.SizeOf(UInt32),
+    2 * System.SizeOf(UInt32));
+end;
+
+end.

+ 71 - 0
CryptoLib/src/Crypto/Generators/ClpEd25519Blake2BKeyPairGenerator.pas

@@ -0,0 +1,71 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BKeyPairGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpAsymmetricCipherKeyPair,
+  ClpIEd25519Blake2BKeyPairGenerator,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpISecureRandom,
+  ClpIKeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  TEd25519Blake2BKeyPairGenerator = class(TInterfacedObject,
+    IEd25519Blake2BKeyPairGenerator, IAsymmetricCipherKeyPairGenerator)
+
+  strict private
+  var
+    FRandom: ISecureRandom;
+
+  public
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    function GenerateKeyPair(): IAsymmetricCipherKeyPair;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BKeyPairGenerator }
+
+function TEd25519Blake2BKeyPairGenerator.GenerateKeyPair
+  : IAsymmetricCipherKeyPair;
+var
+  privateKey: IEd25519Blake2BPrivateKeyParameters;
+  publicKey: IEd25519Blake2BPublicKeyParameters;
+begin
+  privateKey := TEd25519Blake2BPrivateKeyParameters.Create(FRandom);
+  publicKey := privateKey.GeneratePublicKey();
+  result := TAsymmetricCipherKeyPair.Create(publicKey, privateKey);
+end;
+
+procedure TEd25519Blake2BKeyPairGenerator.Init(const parameters
+  : IKeyGenerationParameters);
+begin
+  FRandom := parameters.random;
+end;
+
+end.

+ 70 - 0
CryptoLib/src/Crypto/Generators/ClpEd25519KeyPairGenerator.pas

@@ -0,0 +1,70 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519KeyPairGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpAsymmetricCipherKeyPair,
+  ClpIEd25519KeyPairGenerator,
+  ClpIEd25519PrivateKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpISecureRandom,
+  ClpIKeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  TEd25519KeyPairGenerator = class(TInterfacedObject, IEd25519KeyPairGenerator,
+    IAsymmetricCipherKeyPairGenerator)
+
+  strict private
+  var
+    FRandom: ISecureRandom;
+
+  public
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    function GenerateKeyPair(): IAsymmetricCipherKeyPair;
+
+  end;
+
+implementation
+
+{ TEd25519KeyPairGenerator }
+
+function TEd25519KeyPairGenerator.GenerateKeyPair: IAsymmetricCipherKeyPair;
+var
+  privateKey: IEd25519PrivateKeyParameters;
+  publicKey: IEd25519PublicKeyParameters;
+begin
+  privateKey := TEd25519PrivateKeyParameters.Create(FRandom);
+  publicKey := privateKey.GeneratePublicKey();
+  result := TAsymmetricCipherKeyPair.Create(publicKey, privateKey);
+end;
+
+procedure TEd25519KeyPairGenerator.Init(const parameters
+  : IKeyGenerationParameters);
+begin
+  FRandom := parameters.random;
+end;
+
+end.

+ 7 - 23
CryptoLib/src/Crypto/Generators/ClpPascalCoinECIESKdfBytesGenerator.pas

@@ -46,9 +46,6 @@ type
   TPascalCoinECIESKdfBytesGenerator = class(TBaseKdfBytesGenerator,
   TPascalCoinECIESKdfBytesGenerator = class(TBaseKdfBytesGenerator,
     IPascalCoinECIESKdfBytesGenerator)
     IPascalCoinECIESKdfBytesGenerator)
 
 
-  strict protected
-    function GetDigest(): IDigest; override;
-
   public
   public
 
 
     /// <summary>
     /// <summary>
@@ -61,11 +58,6 @@ type
 
 
     procedure Init(const parameters: IDerivationParameters); override;
     procedure Init(const parameters: IDerivationParameters); override;
 
 
-    /// <summary>
-    /// return the underlying digest.
-    /// </summary>
-    property digest: IDigest read GetDigest;
-
     /// <summary>
     /// <summary>
     /// fill len bytes of the output buffer with bytes generated from the
     /// fill len bytes of the output buffer with bytes generated from the
     /// derivation function.
     /// derivation function.
@@ -94,7 +86,6 @@ function TPascalCoinECIESKdfBytesGenerator.GenerateBytes
   (const output: TCryptoLibByteArray; outOff, length: Int32): Int32;
   (const output: TCryptoLibByteArray; outOff, length: Int32): Int32;
 var
 var
   outLen: Int32;
   outLen: Int32;
-  oBytes: Int64;
   temp: TCryptoLibByteArray;
   temp: TCryptoLibByteArray;
 begin
 begin
   if ((System.length(output) - length) < outOff) then
   if ((System.length(output) - length) < outOff) then
@@ -102,32 +93,26 @@ begin
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooSmall);
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooSmall);
   end;
   end;
 
 
-  oBytes := length;
-  outLen := Fdigest.GetDigestSize;
+  outLen := digest.GetDigestSize;
 
 
-  if (oBytes > outLen) then
+  if (length > outLen) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes
     raise EDataLengthCryptoLibException.CreateRes
       (@SHashCannotNotProduceSufficientData);
       (@SHashCannotNotProduceSufficientData);
   end;
   end;
 
 
-  System.SetLength(temp, Fdigest.GetDigestSize);
-  Fdigest.BlockUpdate(Fshared, 0, System.length(Fshared));
-  Fdigest.DoFinal(temp, 0);
+  System.SetLength(temp, digest.GetDigestSize);
+  digest.BlockUpdate(Fshared, 0, System.length(Fshared));
+  digest.DoFinal(temp, 0);
 
 
   System.Move(temp[0], output[outOff], length * System.SizeOf(Byte));
   System.Move(temp[0], output[outOff], length * System.SizeOf(Byte));
 
 
-  Fdigest.Reset();
+  digest.Reset();
 
 
-  result := oBytes;
+  result := length;
 
 
 end;
 end;
 
 
-function TPascalCoinECIESKdfBytesGenerator.GetDigest: IDigest;
-begin
-  result := Fdigest;
-end;
-
 procedure TPascalCoinECIESKdfBytesGenerator.Init(const parameters
 procedure TPascalCoinECIESKdfBytesGenerator.Init(const parameters
   : IDerivationParameters);
   : IDerivationParameters);
 var
 var
@@ -139,7 +124,6 @@ begin
   if Supports(Lparameters, IKdfParameters, p1) then
   if Supports(Lparameters, IKdfParameters, p1) then
   begin
   begin
     Fshared := p1.GetSharedSecret();
     Fshared := p1.GetSharedSecret();
-    Fiv := p1.GetIV();
   end
   end
   else
   else
   begin
   begin

+ 70 - 0
CryptoLib/src/Crypto/Generators/ClpX25519KeyPairGenerator.pas

@@ -0,0 +1,70 @@
+{ *********************************************************************************** }
+{ *                              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 ClpX25519KeyPairGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpAsymmetricCipherKeyPair,
+  ClpIX25519KeyPairGenerator,
+  ClpIX25519PrivateKeyParameters,
+  ClpX25519PrivateKeyParameters,
+  ClpIX25519PublicKeyParameters,
+  ClpISecureRandom,
+  ClpIKeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  TX25519KeyPairGenerator = class sealed(TInterfacedObject,
+    IX25519KeyPairGenerator, IAsymmetricCipherKeyPairGenerator)
+
+  strict private
+  var
+    FRandom: ISecureRandom;
+
+  public
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    function GenerateKeyPair(): IAsymmetricCipherKeyPair;
+
+  end;
+
+implementation
+
+{ TX25519KeyPairGenerator }
+
+function TX25519KeyPairGenerator.GenerateKeyPair: IAsymmetricCipherKeyPair;
+var
+  privateKey: IX25519PrivateKeyParameters;
+  publicKey: IX25519PublicKeyParameters;
+begin
+  privateKey := TX25519PrivateKeyParameters.Create(FRandom);
+  publicKey := privateKey.GeneratePublicKey();
+  result := TAsymmetricCipherKeyPair.Create(publicKey, privateKey);
+end;
+
+procedure TX25519KeyPairGenerator.Init(const parameters
+  : IKeyGenerationParameters);
+begin
+  FRandom := parameters.random;
+end;
+
+end.

+ 354 - 39
CryptoLib/src/Crypto/Modes/ClpBlockCipherModes.pas

@@ -25,6 +25,7 @@ uses
   Math,
   Math,
   SysUtils,
   SysUtils,
   ClpIBlockCipher,
   ClpIBlockCipher,
+  ClpBufferedBlockCipher,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpIParametersWithIV,
   ClpIParametersWithIV,
   ClpArrayUtils,
   ClpArrayUtils,
@@ -43,6 +44,9 @@ resourcestring
     'CTR/SIC mode requires IV no greater than: %u bytes';
     'CTR/SIC mode requires IV no greater than: %u bytes';
   SInvalidTooSmallIVLength = 'CTR/SIC mode requires IV of at least: %u bytes';
   SInvalidTooSmallIVLength = 'CTR/SIC mode requires IV of at least: %u bytes';
 {$ENDIF}
 {$ENDIF}
+  SUnsupportedCipher = 'CtsBlockCipher Can Only Accept ECB or CBC Ciphers';
+  SNegativeInputLength = 'Can''t Have a Negative Input Length!';
+  SCTSDoFinalError = 'Need at Least One Block of Input For CTS';
 
 
 type
 type
 
 
@@ -613,6 +617,99 @@ type
 
 
   end;
   end;
 
 
+type
+
+  /// <summary>
+  /// A Cipher Text Stealing (CTS) mode cipher. CTS allows block ciphers to
+  /// be used to produce cipher text which is the same outLength as the plain
+  /// text.
+  /// </summary>
+  TCtsBlockCipher = class sealed(TBufferedBlockCipher, ICtsBlockCipher)
+
+  strict private
+  var
+    FblockSize: Int32;
+
+  public
+
+    /// <summary>
+    /// Create a buffered block cipher that uses Cipher Text Stealing
+    /// </summary>
+    /// <param name="cipher">
+    /// the underlying block cipher this buffering object wraps.
+    /// </param>
+    constructor Create(const cipher: IBlockCipher);
+
+    /// <summary>
+    /// return the size of the output buffer required for an update plus a
+    /// doFinal with an input of len bytes.
+    /// </summary>
+    /// <param name="inputLen">
+    /// the outLength of the input.
+    /// </param>
+    /// <returns>
+    /// the space required to accommodate a call to update and doFinal with
+    /// length bytes of input.
+    /// </returns>
+    function GetOutputSize(inputLen: Int32): Int32; override;
+
+    /// <summary>
+    /// return the size of the output buffer required for an update an input
+    /// of len bytes.
+    /// </summary>
+    /// <param name="inputLen">
+    /// the outLength of the input.
+    /// </param>
+    /// <returns>
+    /// the space required to accommodate a call to update with length bytes
+    /// of input.
+    /// </returns>
+    function GetUpdateOutputSize(inputLen: Int32): Int32; override;
+
+    function ProcessByte(input: Byte; const output: TCryptoLibByteArray;
+      outOff: Int32): Int32; override;
+
+    /// <summary>
+    /// process an array of bytes, producing output if necessary.
+    /// </summary>
+    /// <param name="input">
+    /// the input byte array.
+    /// </param>
+    /// <param name="inOff">
+    /// the offset at which the input data starts.
+    /// </param>
+    /// <param name="Length">
+    /// the number of bytes to be copied out of the input array.
+    /// </param>
+    /// <param name="output">
+    /// the space for any output that might be produced.
+    /// </param>
+    /// <param name="outOff">
+    /// the offset from which the output will be copied.
+    /// </param>
+    /// <returns>
+    /// the number of output bytes copied to out.
+    /// </returns>
+    function ProcessBytes(const input: TCryptoLibByteArray; inOff, len: Int32;
+      const output: TCryptoLibByteArray; outOff: Int32): Int32; override;
+
+    /// <summary>
+    /// Process the last block in the buffer.
+    /// </summary>
+    /// <param name="output">
+    /// the array the block currently being held is copied into.
+    /// </param>
+    /// <param name="outOff">
+    /// the offset at which the copying starts.
+    /// </param>
+    /// <returns>
+    /// the number of output bytes copied to out.
+    /// </returns>
+    function DoFinal(const output: TCryptoLibByteArray; outOff: Int32)
+      : Int32; override;
+
+  end;
+
 implementation
 implementation
 
 
 { TCbcBlockCipher }
 { TCbcBlockCipher }
@@ -631,17 +728,17 @@ end;
 function TCbcBlockCipher.DecryptBlock(const input: TCryptoLibByteArray;
 function TCbcBlockCipher.DecryptBlock(const input: TCryptoLibByteArray;
   inOff: Int32; const outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
   inOff: Int32; const outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
 var
 var
-  length, I: Int32;
+  Length, I: Int32;
   tmp: TCryptoLibByteArray;
   tmp: TCryptoLibByteArray;
 begin
 begin
-  if ((inOff + FblockSize) > System.length(input)) then
+  if ((inOff + FblockSize) > System.Length(input)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
   end;
   end;
 
 
   System.Move(input[inOff], FcbcNextV[0], FblockSize * System.SizeOf(Byte));
   System.Move(input[inOff], FcbcNextV[0], FblockSize * System.SizeOf(Byte));
 
 
-  length := Fcipher.ProcessBlock(input, inOff, outBytes, outOff);
+  Length := Fcipher.ProcessBlock(input, inOff, outBytes, outOff);
 
 
 
 
   // XOR the FcbcV and the output
   // XOR the FcbcV and the output
@@ -666,7 +763,7 @@ function TCbcBlockCipher.EncryptBlock(const input: TCryptoLibByteArray;
 var
 var
   I, &length: Int32;
   I, &length: Int32;
 begin
 begin
-  if ((inOff + FblockSize) > System.length(input)) then
+  if ((inOff + FblockSize) > System.Length(input)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
   end;
   end;
@@ -683,7 +780,7 @@ begin
 
 
   // copy ciphertext to FcbcV
   // copy ciphertext to FcbcV
 
 
-  System.Move(outBytes[outOff], FcbcV[0], System.length(FcbcV) *
+  System.Move(outBytes[outOff], FcbcV[0], System.Length(FcbcV) *
     System.SizeOf(Byte));
     System.SizeOf(Byte));
 
 
   result := &length;
   result := &length;
@@ -691,8 +788,8 @@ end;
 
 
 procedure TCbcBlockCipher.Reset;
 procedure TCbcBlockCipher.Reset;
 begin
 begin
-  System.Move(FIV[0], FcbcV[0], System.length(FIV));
-  TArrayUtils.Fill(FcbcNextV, 0, System.length(FcbcNextV), Byte(0));
+  System.Move(FIV[0], FcbcV[0], System.Length(FIV));
+  TArrayUtils.Fill(FcbcNextV, 0, System.Length(FcbcNextV), Byte(0));
 
 
   Fcipher.Reset();
   Fcipher.Reset();
 end;
 end;
@@ -733,12 +830,12 @@ begin
   begin
   begin
     iv := ivParam.GetIV();
     iv := ivParam.GetIV();
 
 
-    if (System.length(iv) <> FblockSize) then
+    if (System.Length(iv) <> FblockSize) then
     begin
     begin
       raise EArgumentCryptoLibException.CreateRes(@SInvalidIVLength);
       raise EArgumentCryptoLibException.CreateRes(@SInvalidIVLength);
     end;
     end;
 
 
-    System.Move(iv[0], FIV[0], System.length(iv) * System.SizeOf(Byte));
+    System.Move(iv[0], FIV[0], System.Length(iv) * System.SizeOf(Byte));
 
 
     Lparameters := ivParam.parameters;
     Lparameters := ivParam.parameters;
   end;
   end;
@@ -789,12 +886,12 @@ function TCfbBlockCipher.DecryptBlock(const input: TCryptoLibByteArray;
 var
 var
   I, count: Int32;
   I, count: Int32;
 begin
 begin
-  if ((inOff + FblockSize) > System.length(input)) then
+  if ((inOff + FblockSize) > System.Length(input)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
   end;
   end;
 
 
-  if ((outOff + FblockSize) > System.length(outBytes)) then
+  if ((outOff + FblockSize) > System.Length(outBytes)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
   end;
   end;
@@ -804,13 +901,13 @@ begin
   //
   //
   // change over the input block.
   // change over the input block.
   //
   //
-  count := (System.length(FcfbV) - FblockSize) * System.SizeOf(Byte);
+  count := (System.Length(FcfbV) - FblockSize) * System.SizeOf(Byte);
   if count > 0 then
   if count > 0 then
   begin
   begin
     System.Move(FcfbV[FblockSize], FcfbV[0], count);
     System.Move(FcfbV[FblockSize], FcfbV[0], count);
   end;
   end;
 
 
-  System.Move(input[inOff], FcfbV[(System.length(FcfbV) - FblockSize)],
+  System.Move(input[inOff], FcfbV[(System.Length(FcfbV) - FblockSize)],
     FblockSize * System.SizeOf(Byte));
     FblockSize * System.SizeOf(Byte));
 
 
   // XOR the FcfbV with the ciphertext producing the plaintext
   // XOR the FcfbV with the ciphertext producing the plaintext
@@ -828,12 +925,12 @@ function TCfbBlockCipher.EncryptBlock(const input: TCryptoLibByteArray;
 var
 var
   I, count: Int32;
   I, count: Int32;
 begin
 begin
-  if ((inOff + FblockSize) > System.length(input)) then
+  if ((inOff + FblockSize) > System.Length(input)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
   end;
   end;
 
 
-  if ((outOff + FblockSize) > System.length(outBytes)) then
+  if ((outOff + FblockSize) > System.Length(outBytes)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
   end;
   end;
@@ -850,14 +947,14 @@ begin
   //
   //
   // change over the input block.
   // change over the input block.
   //
   //
-  count := (System.length(FcfbV) - FblockSize) * System.SizeOf(Byte);
+  count := (System.Length(FcfbV) - FblockSize) * System.SizeOf(Byte);
 
 
   if count > 0 then
   if count > 0 then
   begin
   begin
     System.Move(FcfbV[FblockSize], FcfbV[0], count);
     System.Move(FcfbV[FblockSize], FcfbV[0], count);
   end;
   end;
 
 
-  System.Move(outBytes[outOff], FcfbV[(System.length(FcfbV) - FblockSize)],
+  System.Move(outBytes[outOff], FcfbV[(System.Length(FcfbV) - FblockSize)],
     FblockSize * System.SizeOf(Byte));
     FblockSize * System.SizeOf(Byte));
 
 
   result := FblockSize;
   result := FblockSize;
@@ -865,7 +962,7 @@ end;
 
 
 procedure TCfbBlockCipher.Reset;
 procedure TCfbBlockCipher.Reset;
 begin
 begin
-  System.Move(FIV[0], FcfbV[0], System.length(FIV));
+  System.Move(FIV[0], FcfbV[0], System.Length(FIV));
 
 
   Fcipher.Reset();
   Fcipher.Reset();
 end;
 end;
@@ -905,9 +1002,9 @@ begin
   begin
   begin
     iv := ivParam.GetIV();
     iv := ivParam.GetIV();
 
 
-    diff := System.length(FIV) - System.length(iv);
+    diff := System.Length(FIV) - System.Length(iv);
 
 
-    System.Move(iv[0], FIV[diff], System.length(iv) * System.SizeOf(Byte));
+    System.Move(iv[0], FIV[diff], System.Length(iv) * System.SizeOf(Byte));
     TArrayUtils.Fill(FIV, 0, diff, Byte(0));
     TArrayUtils.Fill(FIV, 0, diff, Byte(0));
 
 
     Lparameters := ivParam.parameters;
     Lparameters := ivParam.parameters;
@@ -952,7 +1049,7 @@ end;
 
 
 procedure TOfbBlockCipher.Reset;
 procedure TOfbBlockCipher.Reset;
 begin
 begin
-  System.Move(FIV[0], FofbV[0], System.length(FIV));
+  System.Move(FIV[0], FofbV[0], System.Length(FIV));
 
 
   Fcipher.Reset();
   Fcipher.Reset();
 
 
@@ -994,13 +1091,13 @@ begin
   begin
   begin
     iv := ivParam.GetIV();
     iv := ivParam.GetIV();
 
 
-    if (System.length(iv) < System.length(FIV)) then
+    if (System.Length(iv) < System.Length(FIV)) then
     begin
     begin
       // prepend the supplied IV with zeros (per FIPS PUB 81)
       // prepend the supplied IV with zeros (per FIPS PUB 81)
-      System.Move(iv[0], FIV[System.length(FIV) - System.length(iv)],
-        System.length(iv) * System.SizeOf(Byte));
+      System.Move(iv[0], FIV[System.Length(FIV) - System.Length(iv)],
+        System.Length(iv) * System.SizeOf(Byte));
 
 
-      for I := 0 to System.Pred(System.length(FIV) - System.length(iv)) do
+      for I := 0 to System.Pred(System.Length(FIV) - System.Length(iv)) do
       begin
       begin
         FIV[I] := 0;
         FIV[I] := 0;
       end;
       end;
@@ -1008,7 +1105,7 @@ begin
     end
     end
     else
     else
     begin
     begin
-      System.Move(iv[0], FIV[0], System.length(FIV) * System.SizeOf(Byte));
+      System.Move(iv[0], FIV[0], System.Length(FIV) * System.SizeOf(Byte));
     end;
     end;
 
 
     Lparameters := ivParam.parameters;
     Lparameters := ivParam.parameters;
@@ -1029,12 +1126,12 @@ function TOfbBlockCipher.ProcessBlock(const input: TCryptoLibByteArray;
 var
 var
   I, count: Int32;
   I, count: Int32;
 begin
 begin
-  if ((inOff + FblockSize) > System.length(input)) then
+  if ((inOff + FblockSize) > System.Length(input)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
   end;
   end;
 
 
-  if ((outOff + FblockSize) > System.length(output)) then
+  if ((outOff + FblockSize) > System.Length(output)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
   end;
   end;
@@ -1054,14 +1151,14 @@ begin
   //
   //
   // change over the input block.
   // change over the input block.
   //
   //
-  count := (System.length(FofbV) - FblockSize) * System.SizeOf(Byte);
+  count := (System.Length(FofbV) - FblockSize) * System.SizeOf(Byte);
 
 
   if count > 0 then
   if count > 0 then
   begin
   begin
     System.Move(FofbV[FblockSize], FofbV[0], count);
     System.Move(FofbV[FblockSize], FofbV[0], count);
   end;
   end;
 
 
-  System.Move(FofbOutV[0], FofbV[(System.length(FofbV) - FblockSize)],
+  System.Move(FofbOutV[0], FofbV[(System.Length(FofbV) - FblockSize)],
     FblockSize * System.SizeOf(Byte));
     FblockSize * System.SizeOf(Byte));
 
 
   result := FblockSize;
   result := FblockSize;
@@ -1082,8 +1179,8 @@ end;
 
 
 procedure TSicBlockCipher.Reset;
 procedure TSicBlockCipher.Reset;
 begin
 begin
-  TArrayUtils.Fill(Fcounter, 0, System.length(Fcounter), Byte(0));
-  System.Move(FIV[0], Fcounter[0], System.length(FIV) * System.SizeOf(Byte));
+  TArrayUtils.Fill(Fcounter, 0, System.Length(Fcounter), Byte(0));
+  System.Move(FIV[0], Fcounter[0], System.Length(FIV) * System.SizeOf(Byte));
 
 
   Fcipher.Reset();
   Fcipher.Reset();
 
 
@@ -1125,7 +1222,7 @@ begin
   begin
   begin
     FIV := ivParam.GetIV();
     FIV := ivParam.GetIV();
 
 
-    if (FblockSize < System.length(FIV)) then
+    if (FblockSize < System.Length(FIV)) then
     begin
     begin
       raise EArgumentCryptoLibException.CreateResFmt(@SInvalidTooLargeIVLength,
       raise EArgumentCryptoLibException.CreateResFmt(@SInvalidTooLargeIVLength,
         [FblockSize]);
         [FblockSize]);
@@ -1133,7 +1230,7 @@ begin
 
 
     maxCounterSize := Min(8, FblockSize div 2);
     maxCounterSize := Min(8, FblockSize div 2);
 
 
-    if ((FblockSize - System.length(FIV)) > maxCounterSize) then
+    if ((FblockSize - System.Length(FIV)) > maxCounterSize) then
     begin
     begin
       raise EArgumentCryptoLibException.CreateResFmt(@SInvalidTooSmallIVLength,
       raise EArgumentCryptoLibException.CreateResFmt(@SInvalidTooSmallIVLength,
         [FblockSize - maxCounterSize]);
         [FblockSize - maxCounterSize]);
@@ -1163,12 +1260,12 @@ var
   I, J: Int32;
   I, J: Int32;
 begin
 begin
 
 
-  if ((inOff + FblockSize) > System.length(input)) then
+  if ((inOff + FblockSize) > System.Length(input)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SInputBufferTooShort);
   end;
   end;
 
 
-  if ((outOff + FblockSize) > System.length(output)) then
+  if ((outOff + FblockSize) > System.Length(output)) then
   begin
   begin
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
     raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
   end;
   end;
@@ -1178,14 +1275,14 @@ begin
   //
   //
   // XOR the counterOut with the plaintext producing the cipher text
   // XOR the counterOut with the plaintext producing the cipher text
   //
   //
-  for I := 0 to System.Pred(System.length(FcounterOut)) do
+  for I := 0 to System.Pred(System.Length(FcounterOut)) do
   begin
   begin
 
 
     output[outOff + I] := Byte(FcounterOut[I] xor input[inOff + I]);
     output[outOff + I] := Byte(FcounterOut[I] xor input[inOff + I]);
   end;
   end;
 
 
   // Increment the counter
   // Increment the counter
-  J := System.length(Fcounter);
+  J := System.Length(Fcounter);
   System.Dec(J);
   System.Dec(J);
   System.Inc(Fcounter[J]);
   System.Inc(Fcounter[J]);
   while ((J >= 0) and (Fcounter[J] = 0)) do
   while ((J >= 0) and (Fcounter[J] = 0)) do
@@ -1194,7 +1291,225 @@ begin
     System.Inc(Fcounter[J]);
     System.Inc(Fcounter[J]);
   end;
   end;
 
 
-  result := System.length(Fcounter);
+  result := System.Length(Fcounter);
+end;
+
+{ TCtsBlockCipher }
+
+constructor TCtsBlockCipher.Create(const cipher: IBlockCipher);
+begin
+  Inherited Create();
+  if Supports(cipher, ICfbBlockCipher) or Supports(cipher, IOfbBlockCipher) or
+    Supports(cipher, ISicBlockCipher) or Supports(cipher, ICtsBlockCipher) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SUnsupportedCipher);
+  end;
+
+  Fcipher := cipher;
+
+  FblockSize := Fcipher.GetBlockSize();
+  System.SetLength(Fbuf, FblockSize * 2);
+  FbufOff := 0;
+end;
+
+function TCtsBlockCipher.DoFinal(const output: TCryptoLibByteArray;
+  outOff: Int32): Int32;
+var
+  blockSize, len, I: Int32;
+  block, lastBlock: TCryptoLibByteArray;
+  c: IBlockCipher;
+begin
+  if ((FbufOff + outOff) > System.Length(output)) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes
+      (@SOutputBufferTooSmallForDoFinal);
+  end;
+
+  blockSize := Fcipher.GetBlockSize();
+  len := FbufOff - blockSize;
+  System.SetLength(block, blockSize);
+
+  if (FforEncryption) then
+  begin
+    if (FbufOff < blockSize) then
+    begin
+      raise EDataLengthCryptoLibException.CreateRes(@SCTSDoFinalError);
+    end;
+
+    Fcipher.ProcessBlock(Fbuf, 0, block, 0);
+
+    if (FbufOff > blockSize) then
+    begin
+
+      I := FbufOff;
+      while I <> System.Length(Fbuf) do
+      begin
+        Fbuf[I] := block[I - blockSize];
+        System.Inc(I);
+      end;
+
+      I := blockSize;
+      while I <> FbufOff do
+      begin
+        Fbuf[I] := Fbuf[I] xor (block[I - blockSize]);
+        System.Inc(I);
+      end;
+
+      if Supports(Fcipher, ICbcBlockCipher) then
+      begin
+        c := (Fcipher as ICbcBlockCipher).GetUnderlyingCipher();
+
+        c.ProcessBlock(Fbuf, blockSize, output, outOff);
+      end
+      else
+      begin
+        Fcipher.ProcessBlock(Fbuf, blockSize, output, outOff);
+      end;
+
+      System.Move(block[0], output[outOff + blockSize],
+        len * System.SizeOf(Byte));
+    end
+    else
+    begin
+      System.Move(block[0], output[outOff], blockSize * System.SizeOf(Byte));
+    end;
+  end
+  else
+  begin
+
+    if (FbufOff < blockSize) then
+    begin
+      raise EDataLengthCryptoLibException.CreateRes(@SCTSDoFinalError);
+    end;
+
+    System.SetLength(lastBlock, blockSize);
+
+    if (FbufOff > blockSize) then
+    begin
+
+      if Supports(Fcipher, ICbcBlockCipher) then
+      begin
+        c := (Fcipher as ICbcBlockCipher).GetUnderlyingCipher();
+
+        c.ProcessBlock(Fbuf, 0, block, 0);
+      end
+      else
+      begin
+        Fcipher.ProcessBlock(Fbuf, 0, block, 0);
+      end;
+
+      I := blockSize;
+      while I <> FbufOff do
+      begin
+        lastBlock[I - blockSize] := Byte(block[I - blockSize] xor Fbuf[I]);
+        System.Inc(I);
+      end;
+
+      System.Move(Fbuf[blockSize], block[0], len * System.SizeOf(Byte));
+      Fcipher.ProcessBlock(block, 0, output, outOff);
+      System.Move(lastBlock[0], output[outOff + blockSize],
+        len * System.SizeOf(Byte));
+    end
+    else
+    begin
+      Fcipher.ProcessBlock(Fbuf, 0, block, 0);
+      System.Move(block[0], output[outOff], blockSize * System.SizeOf(Byte));
+    end;
+
+  end;
+
+  result := FbufOff;
+
+  Reset();
+end;
+
+function TCtsBlockCipher.GetOutputSize(inputLen: Int32): Int32;
+begin
+  result := inputLen + FbufOff;
+end;
+
+function TCtsBlockCipher.GetUpdateOutputSize(inputLen: Int32): Int32;
+var
+  total, leftOver: Int32;
+begin
+  total := inputLen + FbufOff;
+  leftOver := total mod System.Length(Fbuf);
+
+  if (leftOver = 0) then
+  begin
+    result := total - System.Length(Fbuf);
+    Exit;
+  end;
+  result := total - leftOver;
+end;
+
+function TCtsBlockCipher.ProcessByte(input: Byte;
+  const output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+  result := 0;
+
+  if (FbufOff = System.Length(Fbuf)) then
+  begin
+    result := Fcipher.ProcessBlock(Fbuf, 0, output, outOff);
+    System.Move(Fbuf[FblockSize], Fbuf[0], FblockSize * System.SizeOf(Byte));
+    FbufOff := FblockSize;
+  end;
+
+  Fbuf[FbufOff] := input;
+  System.Inc(FbufOff);
+end;
+
+function TCtsBlockCipher.ProcessBytes(const input: TCryptoLibByteArray;
+  inOff, len: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
+var
+  blockSize, Length, gapLen: Int32;
+begin
+  if (len < 0) then
+  begin
+    raise EInvalidArgument.CreateRes(@SNegativeInputLength);
+  end;
+
+  blockSize := GetBlockSize();
+  Length := GetUpdateOutputSize(len);
+
+  if (Length > 0) then
+  begin
+    if ((outOff + Length) > System.Length(output)) then
+    begin
+      raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooShort);
+    end;
+  end;
+
+  result := 0;
+  gapLen := System.Length(Fbuf) - FbufOff;
+
+  if (len > gapLen) then
+  begin
+    System.Move(input[inOff], Fbuf[FbufOff], gapLen * System.SizeOf(Byte));
+
+    result := result + Fcipher.ProcessBlock(Fbuf, 0, output, outOff);
+    System.Move(Fbuf[blockSize], Fbuf[0], blockSize * System.SizeOf(Byte));
+
+    FbufOff := blockSize;
+
+    len := len - gapLen;
+    inOff := inOff + gapLen;
+
+    while (len > blockSize) do
+    begin
+      System.Move(input[inOff], Fbuf[FbufOff], blockSize * System.SizeOf(Byte));
+      result := result + Fcipher.ProcessBlock(Fbuf, 0, output, outOff + result);
+      System.Move(Fbuf[blockSize], Fbuf[0], blockSize * System.SizeOf(Byte));
+
+      len := len - blockSize;
+      inOff := inOff + blockSize;
+    end;
+  end;
+
+  System.Move(input[inOff], Fbuf[FbufOff], len * System.SizeOf(Byte));
+
+  FbufOff := FbufOff + len;
+
 end;
 end;
 
 
 end.
 end.

+ 3 - 4
CryptoLib/src/Crypto/Parameters/ClpDsaKeyParameters.pas

@@ -32,13 +32,12 @@ type
   strict private
   strict private
   var
   var
     Fparameters: IDsaParameters;
     Fparameters: IDsaParameters;
-  strict private
-    function GetParameters: IDsaParameters;
-  protected
+  strict protected
+  function GetParameters: IDsaParameters;
     constructor Create(isPrivate: Boolean; parameters: IDsaParameters);
     constructor Create(isPrivate: Boolean; parameters: IDsaParameters);
 
 
   public
   public
-    function Equals(const other: IDsaKeyParameters): Boolean; reintroduce;
+    function Equals(const other: IDsaKeyParameters): Boolean; reintroduce; overload;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 {$ENDIF DELPHI}override;
 
 

+ 1 - 1
CryptoLib/src/Crypto/Parameters/ClpDsaPrivateKeyParameters.pas

@@ -45,7 +45,7 @@ type
     constructor Create(const x: TBigInteger; const parameters: IDsaParameters);
     constructor Create(const x: TBigInteger; const parameters: IDsaParameters);
 
 
     function Equals(const other: IDsaPrivateKeyParameters): Boolean;
     function Equals(const other: IDsaPrivateKeyParameters): Boolean;
-      reintroduce;
+      reintroduce; overload;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 {$ENDIF DELPHI}override;
 
 

+ 1 - 1
CryptoLib/src/Crypto/Parameters/ClpDsaPublicKeyParameters.pas

@@ -48,7 +48,7 @@ type
   public
   public
     constructor Create(const y: TBigInteger; const parameters: IDsaParameters);
     constructor Create(const y: TBigInteger; const parameters: IDsaParameters);
 
 
-    function Equals(const other: IDsaPublicKeyParameters): Boolean; reintroduce;
+    function Equals(const other: IDsaPublicKeyParameters): Boolean; reintroduce; overload;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 {$ENDIF DELPHI}override;
 
 

+ 5 - 5
CryptoLib/src/Crypto/Parameters/ClpECKeyParameters.pas

@@ -59,10 +59,6 @@ type
     Fparameters: IECDomainParameters;
     Fparameters: IECDomainParameters;
     FpublicKeyParamSet: IDerObjectIdentifier;
     FpublicKeyParamSet: IDerObjectIdentifier;
 
 
-    function GetAlgorithmName: String; inline;
-    function GetPublicKeyParamSet: IDerObjectIdentifier; inline;
-    function GetParameters: IECDomainParameters; inline;
-
   strict protected
   strict protected
 
 
     constructor Create(const algorithm: String; isPrivate: Boolean;
     constructor Create(const algorithm: String; isPrivate: Boolean;
@@ -74,7 +70,11 @@ type
     function CreateKeyGenerationParameters(const random: ISecureRandom)
     function CreateKeyGenerationParameters(const random: ISecureRandom)
       : IECKeyGenerationParameters; inline;
       : IECKeyGenerationParameters; inline;
 
 
-    function Equals(const other: IECKeyParameters): Boolean; reintroduce;
+    function GetAlgorithmName: String; inline;
+    function GetPublicKeyParamSet: IDerObjectIdentifier; inline;
+    function GetParameters: IECDomainParameters; inline;
+
+    function Equals(const other: IECKeyParameters): Boolean; reintroduce; overload;
 
 
   public
   public
     class function VerifyAlgorithmName(const algorithm: String): String; static;
     class function VerifyAlgorithmName(const algorithm: String): String; static;

+ 1 - 1
CryptoLib/src/Crypto/Parameters/ClpECPrivateKeyParameters.pas

@@ -54,7 +54,7 @@ type
 
 
     property d: TBigInteger read GetD;
     property d: TBigInteger read GetD;
 
 
-    function Equals(const other: IECPrivateKeyParameters): Boolean; reintroduce;
+    function Equals(const other: IECPrivateKeyParameters): Boolean; reintroduce; overload;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 {$ENDIF DELPHI}override;
 
 

+ 1 - 1
CryptoLib/src/Crypto/Parameters/ClpECPublicKeyParameters.pas

@@ -56,7 +56,7 @@ type
 
 
     property q: IECPoint read GetQ;
     property q: IECPoint read GetQ;
 
 
-    function Equals(const other: IECPublicKeyParameters): Boolean; reintroduce;
+    function Equals(const other: IECPublicKeyParameters): Boolean; reintroduce; overload;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 {$ENDIF DELPHI}override;
 
 

+ 48 - 0
CryptoLib/src/Crypto/Parameters/ClpEd25519Blake2BKeyGenerationParameters.pas

@@ -0,0 +1,48 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BKeyGenerationParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpIEd25519Blake2BKeyGenerationParameters,
+  ClpKeyGenerationParameters;
+
+type
+  TEd25519Blake2BKeyGenerationParameters = class sealed
+    (TKeyGenerationParameters, IEd25519Blake2BKeyGenerationParameters)
+
+  public
+    constructor Create(const random: ISecureRandom);
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BKeyGenerationParameters }
+
+constructor TEd25519Blake2BKeyGenerationParameters.Create
+  (const random: ISecureRandom);
+begin
+  Inherited Create(random, 256);
+end;
+
+end.

+ 212 - 0
CryptoLib/src/Crypto/Parameters/ClpEd25519Blake2BPrivateKeyParameters.pas

@@ -0,0 +1,212 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BPrivateKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519Blake2B,
+  ClpIEd25519Blake2B,
+  ClpISecureRandom,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPrivateKey = 'EOF encountered in middle of Ed25519Blake2B private key';
+  SUnsupportedAlgorithm = 'Unsupported Algorithm';
+  SCtxNotNil = 'Ctx must be Nil for Ed25519 Algorithm';
+  SMsgLen = 'MsgLen must be Equal to "PreHashSize" for Ed25519ph Algorithm';
+
+type
+  TEd25519Blake2BPrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519Blake2BPrivateKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519Blake2B.SecretKeySize);
+    SignatureSize = Int32(TEd25519Blake2B.SignatureSize);
+
+    constructor Create(const random: ISecureRandom); overload;
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+    function GeneratePublicKey(): IEd25519Blake2BPublicKeyParameters; inline;
+
+    procedure Sign(algorithm: TEd25519Blake2B.TEd25519Algorithm;
+      const publicKey: IEd25519Blake2BPublicKeyParameters;
+      const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32);
+
+    function Equals(const other: IEd25519Blake2BPrivateKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BPrivateKeyParameters }
+
+function TEd25519Blake2BPrivateKeyParameters.GeneratePublicKey
+  : IEd25519Blake2BPublicKeyParameters;
+var
+  publicKey: TCryptoLibByteArray;
+begin
+  System.SetLength(publicKey, TEd25519Blake2B.PublicKeySize);
+  FEd25519Blake2BInstance.GeneratePublicKey(FData, 0, publicKey, 0);
+  result := TEd25519Blake2BPublicKeyParameters.Create(publicKey, 0);
+end;
+
+function TEd25519Blake2BPrivateKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519Blake2BPrivateKeyParameters.Create
+  (const random: ISecureRandom);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  FEd25519Blake2BInstance.GeneratePrivateKey(random, FData);
+end;
+
+constructor TEd25519Blake2BPrivateKeyParameters.Create
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519Blake2BPrivateKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPrivateKey);
+  end;
+end;
+
+procedure TEd25519Blake2BPrivateKeyParameters.Encode
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519Blake2BPrivateKeyParameters.Equals
+  (const other: IEd25519Blake2BPrivateKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519Blake2BPrivateKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519Blake2BPrivateKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32;
+{$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+procedure TEd25519Blake2BPrivateKeyParameters.Sign
+  (algorithm: TEd25519Blake2B.TEd25519Algorithm;
+  const publicKey: IEd25519Blake2BPublicKeyParameters;
+  const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  pk: TCryptoLibByteArray;
+begin
+  System.SetLength(pk, TEd25519Blake2B.PublicKeySize);
+
+  if (publicKey = Nil) then
+  begin
+    FEd25519Blake2BInstance.GeneratePublicKey(FData, 0, pk, 0);
+  end
+  else
+  begin
+    publicKey.Encode(pk, 0);
+  end;
+
+  case algorithm of
+    TEd25519Blake2B.TEd25519Algorithm.Ed25519:
+      begin
+        if (ctx <> Nil) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SCtxNotNil);
+        end;
+
+        FEd25519Blake2BInstance.Sign(FData, 0, pk, 0, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519Blake2B.TEd25519Algorithm.Ed25519ctx:
+      begin
+        FEd25519Blake2BInstance.Sign(FData, 0, pk, 0, ctx, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519Blake2B.TEd25519Algorithm.Ed25519ph:
+      begin
+        if (TEd25519Blake2B.PreHashSize <> msgLen) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SMsgLen);
+        end;
+
+        FEd25519Blake2BInstance.SignPrehash(FData, 0, pk, 0, ctx, msg, msgOff,
+          sig, sigOff);
+      end
+  else
+    begin
+      raise EInvalidOperationCryptoLibException.CreateRes
+        (@SUnsupportedAlgorithm);
+    end;
+
+  end;
+end;
+
+end.

+ 119 - 0
CryptoLib/src/Crypto/Parameters/ClpEd25519Blake2BPublicKeyParameters.pas

@@ -0,0 +1,119 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BPublicKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519Blake2B,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPublicKey = 'EOF encountered in middle of Ed25519Blake2B public key';
+
+type
+  TEd25519Blake2BPublicKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519Blake2BPublicKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519Blake2B.PublicKeySize);
+
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+
+    function Equals(const other: IEd25519Blake2BPublicKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BPublicKeyParameters }
+
+function TEd25519Blake2BPublicKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519Blake2BPublicKeyParameters.Create
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519Blake2BPublicKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPublicKey);
+  end;
+end;
+
+procedure TEd25519Blake2BPublicKeyParameters.Encode
+  (const buf: TCryptoLibByteArray; off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519Blake2BPublicKeyParameters.Equals
+  (const other: IEd25519Blake2BPublicKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519Blake2BPublicKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519Blake2BPublicKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32;
+{$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+end.

+ 47 - 0
CryptoLib/src/Crypto/Parameters/ClpEd25519KeyGenerationParameters.pas

@@ -0,0 +1,47 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519KeyGenerationParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpIEd25519KeyGenerationParameters,
+  ClpKeyGenerationParameters;
+
+type
+  TEd25519KeyGenerationParameters = class sealed(TKeyGenerationParameters,
+    IEd25519KeyGenerationParameters)
+
+  public
+    constructor Create(const random: ISecureRandom);
+
+  end;
+
+implementation
+
+{ TEd25519KeyGenerationParameters }
+
+constructor TEd25519KeyGenerationParameters.Create(const random: ISecureRandom);
+begin
+  Inherited Create(random, 256);
+end;
+
+end.

+ 210 - 0
CryptoLib/src/Crypto/Parameters/ClpEd25519PrivateKeyParameters.pas

@@ -0,0 +1,210 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PrivateKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519,
+  ClpIEd25519,
+  ClpISecureRandom,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPrivateKey = 'EOF encountered in middle of Ed25519 private key';
+  SUnsupportedAlgorithm = 'Unsupported Algorithm';
+  SCtxNotNil = 'Ctx must be Nil for Ed25519 Algorithm';
+  SMsgLen = 'MsgLen must be Equal to "PreHashSize" for Ed25519ph Algorithm';
+
+type
+  TEd25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519PrivateKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+    FEd25519Instance: IEd25519;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519.SecretKeySize);
+    SignatureSize = Int32(TEd25519.SignatureSize);
+
+    constructor Create(const random: ISecureRandom); overload;
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+    function GeneratePublicKey(): IEd25519PublicKeyParameters; inline;
+
+    procedure Sign(algorithm: TEd25519.TEd25519Algorithm;
+      const publicKey: IEd25519PublicKeyParameters;
+      const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32);
+
+    function Equals(const other: IEd25519PrivateKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519PrivateKeyParameters }
+
+function TEd25519PrivateKeyParameters.GeneratePublicKey
+  : IEd25519PublicKeyParameters;
+var
+  publicKey: TCryptoLibByteArray;
+begin
+  System.SetLength(publicKey, TEd25519.PublicKeySize);
+  FEd25519Instance.GeneratePublicKey(FData, 0, publicKey, 0);
+  result := TEd25519PublicKeyParameters.Create(publicKey, 0);
+end;
+
+function TEd25519PrivateKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519PrivateKeyParameters.Create(const random: ISecureRandom);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Instance := TEd25519.Create();
+  FEd25519Instance.GeneratePrivateKey(random, FData);
+end;
+
+constructor TEd25519PrivateKeyParameters.Create(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Instance := TEd25519.Create();
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519PrivateKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  FEd25519Instance := TEd25519.Create();
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPrivateKey);
+  end;
+end;
+
+procedure TEd25519PrivateKeyParameters.Encode(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519PrivateKeyParameters.Equals(const other
+  : IEd25519PrivateKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519PrivateKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519PrivateKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+procedure TEd25519PrivateKeyParameters.Sign
+  (algorithm: TEd25519.TEd25519Algorithm;
+  const publicKey: IEd25519PublicKeyParameters;
+  const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+  const sig: TCryptoLibByteArray; sigOff: Int32);
+var
+  pk: TCryptoLibByteArray;
+begin
+  System.SetLength(pk, TEd25519.PublicKeySize);
+
+  if (publicKey = Nil) then
+  begin
+    FEd25519Instance.GeneratePublicKey(FData, 0, pk, 0);
+  end
+  else
+  begin
+    publicKey.Encode(pk, 0);
+  end;
+
+  case algorithm of
+    TEd25519.TEd25519Algorithm.Ed25519:
+      begin
+        if (ctx <> Nil) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SCtxNotNil);
+        end;
+
+        FEd25519Instance.Sign(FData, 0, pk, 0, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519.TEd25519Algorithm.Ed25519ctx:
+      begin
+        FEd25519Instance.Sign(FData, 0, pk, 0, ctx, msg, msgOff, msgLen,
+          sig, sigOff);
+      end;
+
+    TEd25519.TEd25519Algorithm.Ed25519ph:
+      begin
+        if (TEd25519.PreHashSize <> msgLen) then
+        begin
+          raise EArgumentCryptoLibException.CreateRes(@SMsgLen);
+        end;
+
+        FEd25519Instance.SignPrehash(FData, 0, pk, 0, ctx, msg, msgOff,
+          sig, sigOff);
+      end
+  else
+    begin
+      raise EInvalidOperationCryptoLibException.CreateRes
+        (@SUnsupportedAlgorithm);
+    end;
+
+  end;
+end;
+
+end.

+ 118 - 0
CryptoLib/src/Crypto/Parameters/ClpEd25519PublicKeyParameters.pas

@@ -0,0 +1,118 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PublicKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpEd25519,
+  ClpAsymmetricKeyParameter,
+  ClpIEd25519PublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPublicKey = 'EOF encountered in middle of Ed25519 public key';
+
+type
+  TEd25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IEd25519PublicKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+
+  public
+
+    const
+    KeySize = Int32(TEd25519.PublicKeySize);
+
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+
+    function Equals(const other: IEd25519PublicKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TEd25519PublicKeyParameters }
+
+function TEd25519PublicKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TEd25519PublicKeyParameters.Create(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TEd25519PublicKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPublicKey);
+  end;
+end;
+
+procedure TEd25519PublicKeyParameters.Encode(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TEd25519PublicKeyParameters.Equals(const other
+  : IEd25519PublicKeyParameters): Boolean;
+begin
+  if (other = Self as IEd25519PublicKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TEd25519PublicKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+end.

+ 205 - 0
CryptoLib/src/Crypto/Parameters/ClpIESParameterSpec.pas

@@ -0,0 +1,205 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIESParameterSpec;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIIESParameterSpec,
+  ClpIAlgorithmParameterSpec,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary>
+  /// Parameter spec for an integrated encryptor, as in IEEE P1363a
+  /// </summary>
+  TIESParameterSpec = class sealed(TInterfacedObject, IAlgorithmParameterSpec,
+    IIESParameterSpec)
+
+  strict private
+  var
+    Fderivation, Fencoding, FNonce: TCryptoLibByteArray;
+    FmacKeySize, FcipherKeySize: Int32;
+    FusePointCompression: Boolean;
+
+  strict private
+    function GetDerivationV: TCryptoLibByteArray; inline;
+    function GetEncodingV: TCryptoLibByteArray; inline;
+    function GetMacKeySize: Int32; inline;
+    function GetCipherKeySize: Int32; inline;
+    function GetNonce: TCryptoLibByteArray; inline;
+    function GetPointCompression: Boolean; inline;
+
+  public
+
+    /// <summary>
+    /// Set the IES engine parameters.
+    /// </summary>
+    /// <param name="derivation">
+    /// the optional derivation vector for the KDF.
+    /// </param>
+    /// <param name="encoding">
+    /// the optional encoding vector for the KDF.
+    /// </param>
+    /// <param name="macKeySize">
+    /// the key size (in bits) for the MAC.
+    /// </param>
+    /// <param name="CipherKeySize">
+    /// the key size (in bits) for the block cipher.
+    /// </param>
+    /// <param name="Nonce">
+    /// an IV to use initialising the block cipher.
+    /// </param>
+    constructor Create(const derivation, encoding: TCryptoLibByteArray;
+      MacKeySize, CipherKeySize: Int32;
+      const Nonce: TCryptoLibByteArray); overload;
+
+    /// <summary>
+    /// Set the IES engine parameters.
+    /// </summary>
+    /// <param name="derivation">
+    /// the optional derivation vector for the KDF.
+    /// </param>
+    /// <param name="encoding">
+    /// the optional encoding vector for the KDF.
+    /// </param>
+    /// <param name="macKeySize">
+    /// the key size (in bits) for the MAC.
+    /// </param>
+    /// <param name="CipherKeySize">
+    /// the key size (in bits) for the block cipher.
+    /// </param>
+    /// <param name="Nonce">
+    /// an IV to use initialising the block cipher.
+    /// </param>
+    /// <param name="UsePointCompression">
+    /// whether to use EC point compression or not (false by default)
+    /// </param>
+    constructor Create(const derivation, encoding: TCryptoLibByteArray;
+      MacKeySize: Int32; CipherKeySize: Int32 = -1;
+      const Nonce: TCryptoLibByteArray = Nil;
+      UsePointCompression: Boolean = False); overload;
+
+    /// <summary>
+    /// Returns the derivation vector.
+    /// </summary>
+    /// <value>
+    /// the derivation vector.
+    /// </value>
+    property DerivationV: TCryptoLibByteArray read GetDerivationV;
+
+    /// <summary>
+    /// Returns the encoding vector.
+    /// </summary>
+    /// <value>
+    /// the encoding vector.
+    /// </value>
+    property EncodingV: TCryptoLibByteArray read GetEncodingV;
+
+    /// <summary>
+    /// Return the key size in bits for the MAC used with the message
+    /// </summary>
+    /// <value>
+    /// the key size in bits for the MAC used with the message
+    /// </value>
+    property MacKeySize: Int32 read GetMacKeySize;
+
+    /// <summary>
+    /// Return the key size in bits for the block cipher used with the message
+    /// </summary>
+    /// <value>
+    /// the key size in bits for the block cipher used with the message
+    /// </value>
+    property CipherKeySize: Int32 read GetCipherKeySize;
+
+    /// <summary>
+    /// Return the Nonce (IV) value to be associated with message.
+    /// </summary>
+    /// <value>
+    /// block cipher IV for message.
+    /// </value>
+    property Nonce: TCryptoLibByteArray read GetNonce;
+
+    /// <summary>
+    /// Return the 'point compression' flag.
+    /// </summary>
+    /// <value>
+    /// the point compression flag
+    /// </value>
+    property PointCompression: Boolean read GetPointCompression;
+
+  end;
+
+implementation
+
+{ TIESParameterSpec }
+
+constructor TIESParameterSpec.Create(const derivation,
+  encoding: TCryptoLibByteArray; MacKeySize, CipherKeySize: Int32;
+  const Nonce: TCryptoLibByteArray);
+begin
+  Create(derivation, encoding, MacKeySize, CipherKeySize, Nonce, False);
+end;
+
+constructor TIESParameterSpec.Create(const derivation,
+  encoding: TCryptoLibByteArray; MacKeySize: Int32; CipherKeySize: Int32;
+  const Nonce: TCryptoLibByteArray; UsePointCompression: Boolean);
+begin
+  Inherited Create();
+  Fderivation := derivation;
+  Fencoding := encoding;
+  FmacKeySize := MacKeySize;
+  FcipherKeySize := CipherKeySize;
+  FNonce := System.Copy(Nonce);
+  FusePointCompression := UsePointCompression;
+end;
+
+function TIESParameterSpec.GetCipherKeySize: Int32;
+begin
+  result := FcipherKeySize;
+end;
+
+function TIESParameterSpec.GetDerivationV: TCryptoLibByteArray;
+begin
+  result := System.Copy(Fderivation);
+end;
+
+function TIESParameterSpec.GetEncodingV: TCryptoLibByteArray;
+begin
+  result := System.Copy(Fencoding);
+end;
+
+function TIESParameterSpec.GetMacKeySize: Int32;
+begin
+  result := FmacKeySize;
+end;
+
+function TIESParameterSpec.GetNonce: TCryptoLibByteArray;
+begin
+  result := System.Copy(FNonce);
+end;
+
+function TIESParameterSpec.GetPointCompression: Boolean;
+begin
+  result := FusePointCompression;
+end;
+
+end.

+ 1 - 0
CryptoLib/src/Crypto/Parameters/ClpIESParameters.pas

@@ -37,6 +37,7 @@ type
   var
   var
     Fderivation, Fencoding: TCryptoLibByteArray;
     Fderivation, Fencoding: TCryptoLibByteArray;
     FmacKeySize: Int32;
     FmacKeySize: Int32;
+  strict protected
     function GetMacKeySize(): Int32; inline;
     function GetMacKeySize(): Int32; inline;
   public
   public
     function GetDerivationV(): TCryptoLibByteArray; inline;
     function GetDerivationV(): TCryptoLibByteArray; inline;

+ 1 - 94
CryptoLib/src/Crypto/Parameters/ClpIESWithCipherParameters.pas

@@ -34,13 +34,9 @@ type
 
 
   strict private
   strict private
   var
   var
-    Fnonce: TCryptoLibByteArray;
     FcipherKeySize: Int32;
     FcipherKeySize: Int32;
-    FusePointCompression: Boolean;
 
 
     function GetCipherKeySize: Int32; inline;
     function GetCipherKeySize: Int32; inline;
-    function GetNonce: TCryptoLibByteArray; inline;
-    function GetPointCompression: Boolean; inline;
   public
   public
 
 
     /// <summary>
     /// <summary>
@@ -59,54 +55,7 @@ type
     /// the key size (in bits) for the block cipher.
     /// the key size (in bits) for the block cipher.
     /// </param>
     /// </param>
     constructor Create(const derivation, encoding: TCryptoLibByteArray;
     constructor Create(const derivation, encoding: TCryptoLibByteArray;
-      macKeySize, CipherKeySize: Int32); overload;
-
-    /// <summary>
-    /// Set the IES engine parameters.
-    /// </summary>
-    /// <param name="derivation">
-    /// the optional derivation vector for the KDF.
-    /// </param>
-    /// <param name="encoding">
-    /// the optional encoding vector for the KDF.
-    /// </param>
-    /// <param name="macKeySize">
-    /// the key size (in bits) for the MAC.
-    /// </param>
-    /// <param name="CipherKeySize">
-    /// the key size (in bits) for the block cipher.
-    /// </param>
-    /// <param name="nonce">
-    /// an IV to use initialising the block cipher.
-    /// </param>
-    constructor Create(const derivation, encoding: TCryptoLibByteArray;
-      macKeySize, CipherKeySize: Int32;
-      const nonce: TCryptoLibByteArray); overload;
-
-    /// <summary>
-    /// Set the IES engine parameters.
-    /// </summary>
-    /// <param name="derivation">
-    /// the optional derivation vector for the KDF.
-    /// </param>
-    /// <param name="encoding">
-    /// the optional encoding vector for the KDF.
-    /// </param>
-    /// <param name="macKeySize">
-    /// the key size (in bits) for the MAC.
-    /// </param>
-    /// <param name="CipherKeySize">
-    /// the key size (in bits) for the block cipher.
-    /// </param>
-    /// <param name="nonce">
-    /// an IV to use initialising the block cipher.
-    /// </param>
-    /// <param name="UsePointCompression">
-    /// whether to use EC point compression or not (false by default)
-    /// </param>
-    constructor Create(const derivation, encoding: TCryptoLibByteArray;
-      macKeySize, CipherKeySize: Int32; const nonce: TCryptoLibByteArray;
-      UsePointCompression: Boolean); overload;
+      macKeySize, CipherKeySize: Int32);
 
 
     /// <summary>
     /// <summary>
     /// Return the key size in bits for the block cipher used with the message
     /// Return the key size in bits for the block cipher used with the message
@@ -116,21 +65,6 @@ type
     /// </value>
     /// </value>
     property CipherKeySize: Int32 read GetCipherKeySize;
     property CipherKeySize: Int32 read GetCipherKeySize;
 
 
-    /// <summary>
-    /// Return the nonce (IV) value to be associated with message.
-    /// </summary>
-    /// <value>
-    /// block cipher IV for message.
-    /// </value>
-    property nonce: TCryptoLibByteArray read GetNonce;
-
-    /// <summary>
-    /// Return the 'point compression' flag.
-    /// </summary>
-    /// <value>
-    /// the point compression flag
-    /// </value>
-    property PointCompression: Boolean read GetPointCompression;
   end;
   end;
 
 
 implementation
 implementation
@@ -142,38 +76,11 @@ begin
   Result := FcipherKeySize;
   Result := FcipherKeySize;
 end;
 end;
 
 
-function TIESWithCipherParameters.GetNonce: TCryptoLibByteArray;
-begin
-  Result := System.Copy(Fnonce);
-end;
-
-function TIESWithCipherParameters.GetPointCompression: Boolean;
-begin
-  Result := FusePointCompression;
-end;
-
 constructor TIESWithCipherParameters.Create(const derivation,
 constructor TIESWithCipherParameters.Create(const derivation,
   encoding: TCryptoLibByteArray; macKeySize, CipherKeySize: Int32);
   encoding: TCryptoLibByteArray; macKeySize, CipherKeySize: Int32);
-begin
-  Create(derivation, encoding, macKeySize, CipherKeySize, Nil);
-end;
-
-constructor TIESWithCipherParameters.Create(const derivation,
-  encoding: TCryptoLibByteArray; macKeySize, CipherKeySize: Int32;
-  const nonce: TCryptoLibByteArray);
-begin
-  Create(derivation, encoding, macKeySize, CipherKeySize, nonce, false);
-end;
-
-constructor TIESWithCipherParameters.Create(const derivation,
-  encoding: TCryptoLibByteArray; macKeySize, CipherKeySize: Int32;
-  const nonce: TCryptoLibByteArray; UsePointCompression: Boolean);
 begin
 begin
   Inherited Create(derivation, encoding, macKeySize);
   Inherited Create(derivation, encoding, macKeySize);
-
   FcipherKeySize := CipherKeySize;
   FcipherKeySize := CipherKeySize;
-  Fnonce := System.Copy(nonce);
-  FusePointCompression := UsePointCompression;
 end;
 end;
 
 
 end.
 end.

+ 47 - 0
CryptoLib/src/Crypto/Parameters/ClpX25519KeyGenerationParameters.pas

@@ -0,0 +1,47 @@
+{ *********************************************************************************** }
+{ *                              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 ClpX25519KeyGenerationParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpIX25519KeyGenerationParameters,
+  ClpKeyGenerationParameters;
+
+type
+  TX25519KeyGenerationParameters = class sealed(TKeyGenerationParameters,
+    IX25519KeyGenerationParameters)
+
+  public
+    constructor Create(const random: ISecureRandom);
+
+  end;
+
+implementation
+
+{ TX25519KeyGenerationParameters }
+
+constructor TX25519KeyGenerationParameters.Create(const random: ISecureRandom);
+begin
+  Inherited Create(random, 255);
+end;
+
+end.

+ 158 - 0
CryptoLib/src/Crypto/Parameters/ClpX25519PrivateKeyParameters.pas

@@ -0,0 +1,158 @@
+{ *********************************************************************************** }
+{ *                              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 ClpX25519PrivateKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpX25519,
+  ClpISecureRandom,
+  ClpAsymmetricKeyParameter,
+  ClpIX25519PrivateKeyParameters,
+  ClpIX25519PublicKeyParameters,
+  ClpX25519PublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPrivateKey = 'EOF encountered in middle of X25519 private key';
+  SAgreementCalculationFailed = 'X25519 Agreement Failed';
+
+type
+  TX25519PrivateKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IX25519PrivateKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+
+  public
+
+    const
+    KeySize = Int32(TX25519.ScalarSize);
+    SecretSize = Int32(TX25519.PointSize);
+
+    constructor Create(const random: ISecureRandom); overload;
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+    function GeneratePublicKey(): IX25519PublicKeyParameters; inline;
+    procedure GenerateSecret(const publicKey: IX25519PublicKeyParameters;
+      const buf: TCryptoLibByteArray; off: Int32);
+
+    function Equals(const other: IX25519PrivateKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TX25519PrivateKeyParameters }
+
+function TX25519PrivateKeyParameters.GeneratePublicKey
+  : IX25519PublicKeyParameters;
+var
+  publicKey: TCryptoLibByteArray;
+begin
+  System.SetLength(publicKey, TX25519.PointSize);
+  TX25519.GeneratePublicKey(FData, 0, publicKey, 0);
+  result := TX25519PublicKeyParameters.Create(publicKey, 0);
+end;
+
+procedure TX25519PrivateKeyParameters.GenerateSecret(const publicKey
+  : IX25519PublicKeyParameters; const buf: TCryptoLibByteArray; off: Int32);
+var
+  encoded: TCryptoLibByteArray;
+begin
+  System.SetLength(encoded, TX25519.PointSize);
+  publicKey.Encode(encoded, 0);
+  if (not(TX25519.CalculateAgreement(FData, 0, encoded, 0, buf, off))) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SAgreementCalculationFailed);
+  end;
+end;
+
+function TX25519PrivateKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TX25519PrivateKeyParameters.Create(const random: ISecureRandom);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  TX25519.GeneratePrivateKey(random, FData);
+end;
+
+constructor TX25519PrivateKeyParameters.Create(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TX25519PrivateKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(true);
+  System.SetLength(FData, KeySize);
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPrivateKey);
+  end;
+end;
+
+procedure TX25519PrivateKeyParameters.Encode(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TX25519PrivateKeyParameters.Equals(const other
+  : IX25519PrivateKeyParameters): Boolean;
+begin
+  if (other = Self as IX25519PrivateKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TX25519PrivateKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+end.

+ 118 - 0
CryptoLib/src/Crypto/Parameters/ClpX25519PublicKeyParameters.pas

@@ -0,0 +1,118 @@
+{ *********************************************************************************** }
+{ *                              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 ClpX25519PublicKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpX25519,
+  ClpAsymmetricKeyParameter,
+  ClpIX25519PublicKeyParameters,
+  ClpArrayUtils,
+  ClpAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SEOFInPublicKey = 'EOF encountered in middle of X25519 public key';
+
+type
+  TX25519PublicKeyParameters = class sealed(TAsymmetricKeyParameter,
+    IX25519PublicKeyParameters)
+
+  strict private
+  var
+    FData: TCryptoLibByteArray;
+
+  public
+
+    const
+    KeySize = Int32(TX25519.PointSize);
+
+    constructor Create(const buf: TCryptoLibByteArray; off: Int32); overload;
+    constructor Create(input: TStream); overload;
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32); inline;
+    function GetEncoded(): TCryptoLibByteArray; inline;
+
+    function Equals(const other: IX25519PublicKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+  end;
+
+implementation
+
+{ TX25519PublicKeyParameters }
+
+function TX25519PublicKeyParameters.GetEncoded: TCryptoLibByteArray;
+begin
+  result := System.Copy(FData);
+end;
+
+constructor TX25519PublicKeyParameters.Create(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  System.Move(buf[off], FData[0], KeySize * System.SizeOf(Byte));
+end;
+
+constructor TX25519PublicKeyParameters.Create(input: TStream);
+begin
+  Inherited Create(false);
+  System.SetLength(FData, KeySize);
+  if (KeySize <> TStreamUtils.ReadFully(input, FData)) then
+  begin
+    raise EEndOfStreamCryptoLibException.CreateRes(@SEOFInPublicKey);
+  end;
+end;
+
+procedure TX25519PublicKeyParameters.Encode(const buf: TCryptoLibByteArray;
+  off: Int32);
+begin
+  System.Move(FData[0], buf[off], KeySize * System.SizeOf(Byte));
+end;
+
+function TX25519PublicKeyParameters.Equals(const other
+  : IX25519PublicKeyParameters): Boolean;
+begin
+  if (other = Self as IX25519PublicKeyParameters) then
+  begin
+    result := true;
+    Exit;
+  end;
+
+  if (other = Nil) then
+  begin
+    result := false;
+    Exit;
+  end;
+  result := TArrayUtils.ConstantTimeAreEqual(FData, other.GetEncoded())
+end;
+
+function TX25519PublicKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := TArrayUtils.GetArrayHashCode(FData);
+end;
+
+end.

+ 182 - 0
CryptoLib/src/Crypto/Signers/ClpEd25519Blake2BSigner.pas

@@ -0,0 +1,182 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Blake2BSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519Blake2B,
+  ClpEd25519Blake2B,
+  ClpICipherParameters,
+  ClpIEd25519Blake2BSigner,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519Blake2BSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519Blake2BSigner not Initialised for Verification';
+
+type
+  TEd25519Blake2BSigner = class(TInterfacedObject, IEd25519Blake2BSigner)
+
+  strict private
+  var
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+    FPrivateKey: IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey: IEd25519Blake2BPublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create();
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519Blake2BSigner }
+
+function TEd25519Blake2BSigner.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519Blake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519Blake2BSigner.Create;
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+end;
+
+destructor TEd25519Blake2BSigner.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519Blake2BSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519Blake2B';
+end;
+
+procedure TEd25519Blake2BSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519Blake2BPublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519Blake2BSigner.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519Blake2BSigner.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519Blake2BSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature,
+    TEd25519Blake2BPrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519Blake2B.TEd25519Algorithm.Ed25519, FPublicKey, Nil,
+    buf, 0, count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519Blake2BSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Blake2BInstance.Verify(signature, 0, pk, 0, buf, 0, count);
+  Reset();
+end;
+
+end.

+ 185 - 0
CryptoLib/src/Crypto/Signers/ClpEd25519CtxBlake2BSigner.pas

@@ -0,0 +1,185 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519CtxBlake2BSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519Blake2B,
+  ClpEd25519Blake2B,
+  ClpICipherParameters,
+  ClpIEd25519CtxBlake2BSigner,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519CtxBlake2BSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519CtxBlake2BSigner not Initialised for Verification';
+
+type
+  TEd25519CtxBlake2BSigner = class(TInterfacedObject, IEd25519CtxBlake2BSigner)
+
+  strict private
+  var
+    FContext: TCryptoLibByteArray;
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+    FPrivateKey: IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey: IEd25519Blake2BPublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519CtxBlake2BSigner }
+
+function TEd25519CtxBlake2BSigner.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519CtxBlake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519CtxBlake2BSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FContext := System.Copy(context);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+end;
+
+destructor TEd25519CtxBlake2BSigner.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519CtxBlake2BSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519CtxBlake2B';
+end;
+
+procedure TEd25519CtxBlake2BSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519Blake2BPublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519CtxBlake2BSigner.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519CtxBlake2BSigner.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519CtxBlake2BSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature,
+    TEd25519Blake2BPrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519Blake2B.TEd25519Algorithm.Ed25519Ctx, FPublicKey,
+    FContext, buf, 0, count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519CtxBlake2BSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Blake2BInstance.Verify(signature, 0, pk, 0, FContext, buf,
+    0, count);
+  Reset();
+end;
+
+end.

+ 184 - 0
CryptoLib/src/Crypto/Signers/ClpEd25519CtxSigner.pas

@@ -0,0 +1,184 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519CtxSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519,
+  ClpEd25519,
+  ClpICipherParameters,
+  ClpIEd25519CtxSigner,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519CtxSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519CtxSigner not Initialised for Verification';
+
+type
+  TEd25519CtxSigner = class(TInterfacedObject, IEd25519CtxSigner)
+
+  strict private
+  var
+    FContext: TCryptoLibByteArray;
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Instance: IEd25519;
+    FPrivateKey: IEd25519PrivateKeyParameters;
+    FPublicKey: IEd25519PublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519CtxSigner }
+
+function TEd25519CtxSigner.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519CtxSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519CtxSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FContext := System.Copy(context);
+  FEd25519Instance := TEd25519.Create();
+end;
+
+destructor TEd25519CtxSigner.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519CtxSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519ctx';
+end;
+
+procedure TEd25519CtxSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519PrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519PublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519CtxSigner.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519CtxSigner.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519CtxSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature, TEd25519PrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519.TEd25519Algorithm.Ed25519ctx, FPublicKey, FContext,
+    buf, 0, count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519CtxSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Instance.Verify(signature, 0, pk, 0, FContext, buf,
+    0, count);
+  Reset();
+end;
+
+end.

+ 173 - 0
CryptoLib/src/Crypto/Signers/ClpEd25519PhBlake2BSigner.pas

@@ -0,0 +1,173 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PhBlake2BSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpIEd25519Blake2B,
+  ClpEd25519Blake2B,
+  ClpICipherParameters,
+  ClpIEd25519PhBlake2BSigner,
+  ClpIEd25519Blake2BPrivateKeyParameters,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpEd25519Blake2BPrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519PhBlake2BSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519PhBlake2BSigner not Initialised for Verification';
+  SPreHashDigestFailed = 'PreHash Digest Failed';
+
+type
+  TEd25519PhBlake2BSigner = class(TInterfacedObject, IEd25519PhBlake2BSigner)
+
+  strict private
+  var
+    FPreHash: IDigest;
+    FContext: TCryptoLibByteArray;
+    FforSigning: Boolean;
+    FEd25519Blake2BInstance: IEd25519Blake2B;
+    FPrivateKey: IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey: IEd25519Blake2BPublicKeyParameters;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519PhBlake2BSigner }
+
+procedure TEd25519PhBlake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FPreHash.BlockUpdate(buf, off, len);
+end;
+
+constructor TEd25519PhBlake2BSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FContext := System.Copy(context);
+  FEd25519Blake2BInstance := TEd25519Blake2B.Create();
+  FPreHash := FEd25519Blake2BInstance.CreatePreHash();
+end;
+
+destructor TEd25519PhBlake2BSigner.Destroy;
+begin
+  inherited Destroy;
+end;
+
+function TEd25519PhBlake2BSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519PhBlake2B';
+end;
+
+procedure TEd25519PhBlake2BSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519Blake2BPrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519Blake2BPublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519PhBlake2BSigner.Reset;
+begin
+  FPreHash.Reset();
+end;
+
+procedure TEd25519PhBlake2BSigner.Update(b: Byte);
+begin
+  FPreHash.Update(b);
+end;
+
+function TEd25519PhBlake2BSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, msg: TCryptoLibByteArray;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+  System.SetLength(msg, TEd25519Blake2B.PreHashSize);
+
+  if ((TEd25519Blake2B.PreHashSize) <> (FPreHash.DoFinal(msg, 0))) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SPreHashDigestFailed);
+  end;
+
+  System.SetLength(signature,
+    TEd25519Blake2BPrivateKeyParameters.SignatureSize);
+
+  FPrivateKey.Sign(TEd25519Blake2B.TEd25519Algorithm.Ed25519Ph, FPublicKey,
+    FContext, msg, 0, TEd25519Blake2B.PreHashSize, signature, 0);
+  Result := signature;
+end;
+
+function TEd25519PhBlake2BSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  pk: TCryptoLibByteArray;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  pk := FPublicKey.GetEncoded();
+  Result := FEd25519Blake2BInstance.VerifyPrehash(signature, 0, pk, 0, FContext,
+    FPreHash);
+end;
+
+end.

+ 172 - 0
CryptoLib/src/Crypto/Signers/ClpEd25519PhSigner.pas

@@ -0,0 +1,172 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519PhSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpIEd25519,
+  ClpEd25519,
+  ClpICipherParameters,
+  ClpIEd25519PhSigner,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519PhSigner not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519PhSigner not Initialised for Verification';
+  SPreHashDigestFailed = 'PreHash Digest Failed';
+
+type
+  TEd25519PhSigner = class(TInterfacedObject, IEd25519PhSigner)
+
+  strict private
+  var
+    FPreHash: IDigest;
+    FContext: TCryptoLibByteArray;
+    FforSigning: Boolean;
+    FEd25519Instance: IEd25519;
+    FPrivateKey: IEd25519PrivateKeyParameters;
+    FPublicKey: IEd25519PublicKeyParameters;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create(const context: TCryptoLibByteArray);
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519PhSigner }
+
+procedure TEd25519PhSigner.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FPreHash.BlockUpdate(buf, off, len);
+end;
+
+constructor TEd25519PhSigner.Create(const context: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  FContext := System.Copy(context);
+  FEd25519Instance := TEd25519.Create();
+  FPreHash := FEd25519Instance.CreatePreHash();
+end;
+
+destructor TEd25519PhSigner.Destroy;
+begin
+  inherited Destroy;
+end;
+
+function TEd25519PhSigner.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519Ph';
+end;
+
+procedure TEd25519PhSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519PrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519PublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519PhSigner.Reset;
+begin
+  FPreHash.Reset();
+end;
+
+procedure TEd25519PhSigner.Update(b: Byte);
+begin
+  FPreHash.Update(b);
+end;
+
+function TEd25519PhSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, msg: TCryptoLibByteArray;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+  System.SetLength(msg, TEd25519.PreHashSize);
+
+  if ((TEd25519.PreHashSize) <> (FPreHash.DoFinal(msg, 0))) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SPreHashDigestFailed);
+  end;
+
+  System.SetLength(signature, TEd25519PrivateKeyParameters.SignatureSize);
+
+  FPrivateKey.Sign(TEd25519.TEd25519Algorithm.Ed25519Ph, FPublicKey, FContext,
+    msg, 0, TEd25519.PreHashSize, signature, 0);
+  Result := signature;
+end;
+
+function TEd25519PhSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  pk: TCryptoLibByteArray;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  pk := FPublicKey.GetEncoded();
+  Result := FEd25519Instance.VerifyPrehash(signature, 0, pk, 0, FContext,
+    FPreHash);
+end;
+
+end.

+ 181 - 0
CryptoLib/src/Crypto/Signers/ClpEd25519Signer.pas

@@ -0,0 +1,181 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEd25519Signer;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIEd25519,
+  ClpEd25519,
+  ClpICipherParameters,
+  ClpIEd25519Signer,
+  ClpIEd25519PrivateKeyParameters,
+  ClpIEd25519PublicKeyParameters,
+  ClpEd25519PrivateKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SNotInitializedForSigning =
+    'Ed25519Signer not Initialised for Signature Generation.';
+  SNotInitializedForVerifying =
+    'Ed25519Signer not Initialised for Verification';
+
+type
+  TEd25519Signer = class(TInterfacedObject, IEd25519Signer)
+
+  strict private
+  var
+    FBuffer: TMemoryStream;
+    FforSigning: Boolean;
+    FEd25519Instance: IEd25519;
+    FPrivateKey: IEd25519PrivateKeyParameters;
+    FPublicKey: IEd25519PublicKeyParameters;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+    function GetAlgorithmName: String; virtual;
+
+  public
+    constructor Create();
+    destructor Destroy(); override;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+    procedure Update(b: Byte); virtual;
+    procedure BlockUpdate(const buf: TCryptoLibByteArray;
+      off, len: Int32); virtual;
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+
+  end;
+
+implementation
+
+{ TEd25519Signer }
+
+function TEd25519Signer.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TEd25519Signer.BlockUpdate(const buf: TCryptoLibByteArray;
+  off, len: Int32);
+begin
+  FBuffer.Write(buf[off], len);
+end;
+
+constructor TEd25519Signer.Create;
+begin
+  Inherited Create();
+  FBuffer := TMemoryStream.Create();
+  FEd25519Instance := TEd25519.Create();
+end;
+
+destructor TEd25519Signer.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TEd25519Signer.GetAlgorithmName: String;
+begin
+  Result := 'Ed25519';
+end;
+
+procedure TEd25519Signer.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+begin
+  FforSigning := forSigning;
+
+  if (forSigning) then
+  begin
+    // TODO Allow IAsymmetricCipherKeyPair to be an ICipherParameters?
+
+    FPrivateKey := parameters as IEd25519PrivateKeyParameters;
+    FPublicKey := FPrivateKey.GeneratePublicKey();
+  end
+  else
+  begin
+    FPrivateKey := Nil;
+    FPublicKey := parameters as IEd25519PublicKeyParameters;
+  end;
+
+  Reset();
+end;
+
+procedure TEd25519Signer.Reset;
+begin
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TEd25519Signer.Update(b: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(b)[0], 1);
+end;
+
+function TEd25519Signer.GenerateSignature: TCryptoLibByteArray;
+var
+  signature, buf: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((not FforSigning) or (FPrivateKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  System.SetLength(signature, TEd25519PrivateKeyParameters.SignatureSize);
+  buf := Aggregate();
+  count := System.Length(buf);
+
+  FPrivateKey.Sign(TEd25519.TEd25519Algorithm.Ed25519, FPublicKey, Nil, buf, 0,
+    count, signature, 0);
+  Reset();
+  Result := signature;
+end;
+
+function TEd25519Signer.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  buf, pk: TCryptoLibByteArray;
+  count: Int32;
+begin
+  if ((FforSigning) or (FPublicKey = Nil)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+  pk := FPublicKey.GetEncoded();
+  buf := Aggregate();
+  count := System.Length(buf);
+  Result := FEd25519Instance.Verify(signature, 0, pk, 0, buf, 0, count);
+  Reset();
+end;
+
+end.

+ 0 - 1
CryptoLib/src/Crypto/Signers/ClpSchnorrDigestSigner.pas

@@ -32,7 +32,6 @@ uses
   ClpBigInteger,
   ClpBigInteger,
   ClpCryptoLibTypes,
   ClpCryptoLibTypes,
   ClpIParametersWithRandom,
   ClpIParametersWithRandom,
-  ClpSignersEncodings,
   ClpIAsymmetricKeyParameter,
   ClpIAsymmetricKeyParameter,
   ClpICipherParameters,
   ClpICipherParameters,
   ClpISigner;
   ClpISigner;

+ 6 - 32
CryptoLib/src/Include/CryptoLib.inc

@@ -94,16 +94,6 @@
 {$DEFINE SUPPORT_TSTREAM_WRITE_BYTEARRAY_OVERLOAD}
 {$DEFINE SUPPORT_TSTREAM_WRITE_BYTEARRAY_OVERLOAD}
 {$LEGACYIFEND ON}
 {$LEGACYIFEND ON}
 {$ZEROBASEDSTRINGS OFF}
 {$ZEROBASEDSTRINGS OFF}
-{$IFEND}
-
- // 2010 only
-{$IF CompilerVersion = 21.0}
-{$DEFINE DELPHI2010}
-{$IFEND}
-
-  // 2010 and Above
-{$IF CompilerVersion >= 21.0}
-{$DEFINE DELPHI2010_UP}
 {$IFEND}
 {$IFEND}
 
 
   // XE and Above
   // XE and Above
@@ -111,20 +101,10 @@
 {$DEFINE DELPHIXE_UP}
 {$DEFINE DELPHIXE_UP}
 {$IFEND}
 {$IFEND}
 
 
-  // XE2 and Above
-{$IF CompilerVersion >= 23.0}
-{$DEFINE DELPHIXE2_UP}
-{$DEFINE HAS_UNITSCOPE}
-{$IFEND}
-
-// XE3 and Below
-{$IF CompilerVersion <= 24.0}
-{$DEFINE DELPHIXE3_DOWN}
-{$IFEND}
-
-  // XE7 and Above
-{$IF CompilerVersion >= 28.0}
-{$DEFINE DELPHIXE7_UP}
+ // XE4 and Above
+{$IF CompilerVersion >= 25.0}
+{$DEFINE DELPHIXE4_UP}
+{$DEFINE SHIFT_OVERFLOW_BUG_FIXED}
 {$IFEND}
 {$IFEND}
 
 
   // 10.2 Tokyo and Above
   // 10.2 Tokyo and Above
@@ -132,15 +112,9 @@
 {$DEFINE DELPHI10.2_TOKYO_UP}
 {$DEFINE DELPHI10.2_TOKYO_UP}
 {$IFEND}
 {$IFEND}
 
 
-  // 2010 and Above
-{$IFNDEF DELPHI2010_UP}
-{$MESSAGE ERROR 'This Library requires Delphi 2010 or higher.'}
-{$ENDIF}
-
   // 10.2 Tokyo and Above
   // 10.2 Tokyo and Above
-{$IFDEF DELPHI10.2_TOKYO_UP}
-{$WARN COMBINING_SIGNED_UNSIGNED OFF}
-{$WARN COMBINING_SIGNED_UNSIGNED64 OFF}
+{$IFNDEF DELPHI10.2_TOKYO_UP}
+{$MESSAGE ERROR 'This Library requires Delphi Tokyo or higher.'}
 {$ENDIF}
 {$ENDIF}
 
 
 
 

+ 3 - 3
CryptoLib/src/Include/CryptoLibHelper.inc

@@ -19,8 +19,8 @@
 {$IFDEF ENDIAN_BIG}
 {$IFDEF ENDIAN_BIG}
 {$MESSAGE FATAL 'This Library does not support "Big Endian" processors yet.'}
 {$MESSAGE FATAL 'This Library does not support "Big Endian" processors yet.'}
 {$ENDIF}
 {$ENDIF}
-// FPC 3.0.0 and Above
+// FPC 3.0.4 and Above
 // Had to Include this here since Delphi does not allow it Compile in "CryptoLib.inc".
 // Had to Include this here since Delphi does not allow it Compile in "CryptoLib.inc".
-{$IF FPC_FULLVERSION < 30000}
-{$MESSAGE ERROR 'This Library requires FreePascal 3.0.0 or higher.'}
+{$IF FPC_FULLVERSION < 30004}
+{$MESSAGE ERROR 'This Library requires FreePascal 3.0.4 or higher.'}
 {$IFEND}
 {$IFEND}

+ 31 - 0
CryptoLib/src/Interfaces/ClpIAlgorithmParameterSpec.pas

@@ -0,0 +1,31 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIAlgorithmParameterSpec;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+type
+  IAlgorithmParameterSpec = interface(IInterface)
+    ['{FBA69725-AEFF-4B99-92C0-1819E5DE2DA1}']
+  end;
+
+implementation
+
+end.

+ 10 - 1
CryptoLib/src/Interfaces/ClpIBlockCipherModes.pas

@@ -22,7 +22,9 @@ unit ClpIBlockCipherModes;
 interface
 interface
 
 
 uses
 uses
-  ClpIBlockCipher;
+  ClpIBlockCipher,
+  ClpIBufferedBlockCipher,
+  ClpCryptoLibTypes;
 
 
 type
 type
   ICbcBlockCipher = interface(IBlockCipher)
   ICbcBlockCipher = interface(IBlockCipher)
@@ -84,6 +86,13 @@ type
 
 
   end;
   end;
 
 
+type
+  ICtsBlockCipher = interface(IBufferedBlockCipher)
+
+    ['{4D02FD0B-47D6-4914-B31F-5869FF364558}']
+
+  end;
+
 implementation
 implementation
 
 
 end.
 end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpIBufferedStreamCipher.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 ClpIBufferedStreamCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBufferedCipherBase;
+
+type
+  IBufferedStreamCipher = interface(IBufferedCipherBase)
+
+    ['{F20A1BF7-4AA6-445C-8218-9EA0DF7FC123}']
+
+  end;
+
+implementation
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpIChaChaEngine.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 ClpIChaChaEngine;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISalsa20Engine;
+
+type
+
+  IChaChaEngine = interface(ISalsa20Engine)
+    ['{8CD31B82-B157-4A56-B529-E2F1079BADD8}']
+
+  end;
+
+implementation
+
+end.

+ 64 - 0
CryptoLib/src/Interfaces/ClpICurve25519Custom.pas

@@ -0,0 +1,64 @@
+{ *********************************************************************************** }
+{ *                              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 ClpICurve25519Custom;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIECC,
+  ClpCryptoLibTypes;
+
+type
+  ICurve25519FieldElement = Interface(IAbstractFpFieldElement)
+    ['{50046C65-BACE-4E68-9AEF-09AAD33DFD62}']
+
+    function GetX: TCryptoLibUInt32Array;
+    property X: TCryptoLibUInt32Array read GetX;
+  end;
+
+type
+  ICurve25519Point = Interface(IAbstractFpPoint)
+    ['{49280930-32AC-4F84-BBCE-C9A9DF18E71E}']
+
+    function CalculateJacobianModifiedW(const z: ICurve25519FieldElement;
+      const ZSquared: TCryptoLibUInt32Array): ICurve25519FieldElement;
+    function GetJacobianModifiedW(): ICurve25519FieldElement;
+    function TwiceJacobianModified(calculateW: Boolean): ICurve25519Point;
+
+  end;
+
+type
+  ICurve25519 = Interface(IAbstractFpCurve)
+    ['{56BB2C20-454C-4C42-A603-AD7429362D82}']
+
+    function GetQ: TBigInteger;
+    property Q: TBigInteger read GetQ;
+
+  end;
+
+type
+  ICurve25519LookupTable = Interface(IECLookupTable)
+    ['{79FE1276-3D22-4A20-A4F1-58F0C0532BAC}']
+  end;
+
+implementation
+
+end.

+ 1 - 1
CryptoLib/src/Interfaces/ClpIDsaKeyParameters.pas

@@ -31,7 +31,7 @@ type
 
 
     function GetParameters: IDsaParameters;
     function GetParameters: IDsaParameters;
 
 
-    function Equals(const other: IDsaKeyParameters): Boolean;
+    function Equals(const other: IDsaKeyParameters): Boolean; overload;
     property parameters: IDsaParameters read GetParameters;
     property parameters: IDsaParameters read GetParameters;
 
 
   end;
   end;

+ 1 - 1
CryptoLib/src/Interfaces/ClpIDsaPrivateKeyParameters.pas

@@ -31,7 +31,7 @@ type
 
 
     function GetX: TBigInteger;
     function GetX: TBigInteger;
 
 
-    function Equals(const other: IDsaPrivateKeyParameters): Boolean;
+    function Equals(const other: IDsaPrivateKeyParameters): Boolean; overload;
     property X: TBigInteger read GetX;
     property X: TBigInteger read GetX;
 
 
   end;
   end;

+ 1 - 1
CryptoLib/src/Interfaces/ClpIDsaPublicKeyParameters.pas

@@ -28,7 +28,7 @@ type
 
 
     function GetY: TBigInteger;
     function GetY: TBigInteger;
 
 
-    function Equals(const other: IDsaPublicKeyParameters): Boolean;
+    function Equals(const other: IDsaPublicKeyParameters): Boolean; overload;
     property y: TBigInteger read GetY;
     property y: TBigInteger read GetY;
 
 
   end;
   end;

+ 2 - 0
CryptoLib/src/Interfaces/ClpIECKeyParameters.pas

@@ -35,6 +35,8 @@ type
     function GetPublicKeyParamSet: IDerObjectIdentifier;
     function GetPublicKeyParamSet: IDerObjectIdentifier;
     function GetParameters: IECDomainParameters;
     function GetParameters: IECDomainParameters;
 
 
+    function Equals(const other: IECKeyParameters): Boolean; overload;
+
     property AlgorithmName: String read GetAlgorithmName;
     property AlgorithmName: String read GetAlgorithmName;
     property PublicKeyParamSet: IDerObjectIdentifier read GetPublicKeyParamSet;
     property PublicKeyParamSet: IDerObjectIdentifier read GetPublicKeyParamSet;
     property Parameters: IECDomainParameters read GetParameters;
     property Parameters: IECDomainParameters read GetParameters;

+ 1 - 0
CryptoLib/src/Interfaces/ClpIECPrivateKeyParameters.pas

@@ -30,6 +30,7 @@ type
   IECPrivateKeyParameters = interface(IECKeyParameters)
   IECPrivateKeyParameters = interface(IECKeyParameters)
     ['{49066428-4021-4E3C-A9F5-AB2127289A67}']
     ['{49066428-4021-4E3C-A9F5-AB2127289A67}']
 
 
+    function Equals(const other: IECPrivateKeyParameters): Boolean; overload;
     function GetD: TBigInteger;
     function GetD: TBigInteger;
     property D: TBigInteger read GetD;
     property D: TBigInteger read GetD;
   end;
   end;

+ 1 - 1
CryptoLib/src/Interfaces/ClpIECPublicKeyParameters.pas

@@ -30,8 +30,8 @@ type
   IECPublicKeyParameters = interface(IECKeyParameters)
   IECPublicKeyParameters = interface(IECKeyParameters)
     ['{4BABC163-847A-4FE2-AA16-5CD100F76124}']
     ['{4BABC163-847A-4FE2-AA16-5CD100F76124}']
 
 
+    function Equals(const other: IECPublicKeyParameters): Boolean; overload;
     function GetQ: IECPoint;
     function GetQ: IECPoint;
-
     property Q: IECPoint read GetQ;
     property Q: IECPoint read GetQ;
   end;
   end;
 
 

+ 97 - 0
CryptoLib/src/Interfaces/ClpIEd25519.pas

@@ -0,0 +1,97 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDigest,
+  ClpISecureRandom,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519 = interface(IInterface)
+    ['{2C6CD9DD-8809-44E6-979D-1EBE465CE9E2}']
+
+    function CreatePreHash(): IDigest;
+
+    procedure GeneratePrivateKey(const random: ISecureRandom;
+      const k: TCryptoLibByteArray);
+
+    procedure GeneratePublicKey(const sk: TCryptoLibByteArray; skOff: Int32;
+      pk: TCryptoLibByteArray; pkOff: Int32);
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const m: TCryptoLibByteArray; mOff, mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+      mOff, mLen: Int32; const sig: TCryptoLibByteArray;
+      sigOff: Int32); overload;
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure Sign(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, ph: TCryptoLibByteArray; phOff: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const ctx: TCryptoLibByteArray; const ph: IDigest;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    procedure SignPreHash(const sk: TCryptoLibByteArray; skOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx: TCryptoLibByteArray; const ph: IDigest;
+      const sig: TCryptoLibByteArray; sigOff: Int32); overload;
+
+    function Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32; const m: TCryptoLibByteArray;
+      mOff, mLen: Int32): Boolean; overload;
+
+    function Verify(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, m: TCryptoLibByteArray; mOff, mLen: Int32): Boolean; overload;
+
+    function VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx, ph: TCryptoLibByteArray; phOff: Int32): Boolean; overload;
+
+    function VerifyPreHash(const sig: TCryptoLibByteArray; sigOff: Int32;
+      const pk: TCryptoLibByteArray; pkOff: Int32;
+      const ctx: TCryptoLibByteArray; const ph: IDigest): Boolean; overload;
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
CryptoLib/src/Interfaces/ClpIEd25519Blake2B.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2B;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIEd25519;
+
+type
+  IEd25519Blake2B = interface(IEd25519)
+    ['{4EF6C436-D49D-4442-A014-848E08D81BE6}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
CryptoLib/src/Interfaces/ClpIEd25519Blake2BKeyGenerationParameters.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BKeyGenerationParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIKeyGenerationParameters;
+
+type
+  IEd25519Blake2BKeyGenerationParameters = interface(IKeyGenerationParameters)
+    ['{83EED7AC-2214-444D-8411-CD5CDFC32972}']
+
+  end;
+
+implementation
+
+end.

+ 35 - 0
CryptoLib/src/Interfaces/ClpIEd25519Blake2BKeyPairGenerator.pas

@@ -0,0 +1,35 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BKeyPairGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIEd25519KeyPairGenerator;
+
+type
+  IEd25519Blake2BKeyPairGenerator = interface(IEd25519KeyPairGenerator)
+    ['{1923A01B-2246-4F5B-8BD5-3C78C181029E}']
+
+  end;
+
+implementation
+
+end.

+ 49 - 0
CryptoLib/src/Interfaces/ClpIEd25519Blake2BPrivateKeyParameters.pas

@@ -0,0 +1,49 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BPrivateKeyParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpEd25519,
+  ClpIEd25519Blake2BPublicKeyParameters,
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519Blake2BPrivateKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{AA0786F9-11D8-4B36-B9AE-A108FE678774}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+    function GeneratePublicKey(): IEd25519Blake2BPublicKeyParameters;
+
+    procedure Sign(algorithm: TEd25519.TEd25519Algorithm;
+      const publicKey: IEd25519Blake2BPublicKeyParameters;
+      const ctx, msg: TCryptoLibByteArray; msgOff, msgLen: Int32;
+      const sig: TCryptoLibByteArray; sigOff: Int32);
+
+    function Equals(const other: IEd25519Blake2BPrivateKeyParameters)
+      : Boolean; overload;
+  end;
+
+implementation
+
+end.

+ 41 - 0
CryptoLib/src/Interfaces/ClpIEd25519Blake2BPublicKeyParameters.pas

@@ -0,0 +1,41 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEd25519Blake2BPublicKeyParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  IEd25519Blake2BPublicKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{54BC984B-F087-463C-AB06-BCB8C61D9770}']
+
+    procedure Encode(const buf: TCryptoLibByteArray; off: Int32);
+    function GetEncoded(): TCryptoLibByteArray;
+
+    function Equals(const other: IEd25519Blake2BPublicKeyParameters)
+      : Boolean; overload;
+  end;
+
+implementation
+
+end.

+ 36 - 0
CryptoLib/src/Interfaces/ClpIEd25519Blake2BSigner.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 ClpIEd25519Blake2BSigner;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISigner;
+
+type
+  IEd25519Blake2BSigner = interface(ISigner)
+
+    ['{3BF234D8-550D-4505-9C55-2C93733DCE30}']
+
+  end;
+
+implementation
+
+end.

Some files were not shown because too many files changed in this diff