Browse Source

add support for Diffie–Hellman key exchange

Ugochukwu Mmaduekwe 6 years ago
parent
commit
b6689516d9
41 changed files with 3748 additions and 17 deletions
  1. 29 0
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  2. 31 1
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.TestInsight.dpr
  3. 31 1
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  4. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
  5. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
  6. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi
  7. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
  8. 594 0
      CryptoLib.Tests/src/Crypto/DHTests.pas
  9. 242 0
      CryptoLib/src/Asn1/X9/ClpDHDomainParameters.pas
  10. 145 0
      CryptoLib/src/Asn1/X9/ClpDHValidationParams.pas
  11. 187 0
      CryptoLib/src/Crypto/Agreement/ClpDHAgreement.pas
  12. 148 0
      CryptoLib/src/Crypto/Agreement/ClpDHBasicAgreement.pas
  13. 104 0
      CryptoLib/src/Crypto/Generators/ClpDHBasicKeyPairGenerator.pas
  14. 140 0
      CryptoLib/src/Crypto/Generators/ClpDHKeyGeneratorHelper.pas
  15. 104 0
      CryptoLib/src/Crypto/Generators/ClpDHKeyPairGenerator.pas
  16. 88 0
      CryptoLib/src/Crypto/Generators/ClpDHParametersGenerator.pas
  17. 270 0
      CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas
  18. 78 0
      CryptoLib/src/Crypto/Parameters/ClpDHKeyGenerationParameters.pas
  19. 115 0
      CryptoLib/src/Crypto/Parameters/ClpDHKeyParameters.pas
  20. 266 0
      CryptoLib/src/Crypto/Parameters/ClpDHParameters.pas
  21. 117 0
      CryptoLib/src/Crypto/Parameters/ClpDHPrivateKeyParameters.pas
  22. 135 0
      CryptoLib/src/Crypto/Parameters/ClpDHPublicKeyParameters.pas
  23. 103 0
      CryptoLib/src/Crypto/Parameters/ClpDHValidationParameters.pas
  24. 73 0
      CryptoLib/src/Interfaces/ClpIDHAgreement.pas
  25. 46 0
      CryptoLib/src/Interfaces/ClpIDHBasicAgreement.pas
  26. 34 0
      CryptoLib/src/Interfaces/ClpIDHBasicKeyPairGenerator.pas
  27. 51 0
      CryptoLib/src/Interfaces/ClpIDHDomainParameters.pas
  28. 40 0
      CryptoLib/src/Interfaces/ClpIDHKeyGenerationParameters.pas
  29. 43 0
      CryptoLib/src/Interfaces/ClpIDHKeyGeneratorHelper.pas
  30. 34 0
      CryptoLib/src/Interfaces/ClpIDHKeyPairGenerator.pas
  31. 44 0
      CryptoLib/src/Interfaces/ClpIDHKeyParameters.pas
  32. 61 0
      CryptoLib/src/Interfaces/ClpIDHParameters.pas
  33. 49 0
      CryptoLib/src/Interfaces/ClpIDHParametersGenerator.pas
  34. 41 0
      CryptoLib/src/Interfaces/ClpIDHPrivateKeyParameters.pas
  35. 38 0
      CryptoLib/src/Interfaces/ClpIDHPublicKeyParameters.pas
  36. 40 0
      CryptoLib/src/Interfaces/ClpIDHValidationParameters.pas
  37. 41 0
      CryptoLib/src/Interfaces/ClpIDHValidationParams.pas
  38. 34 5
      CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk
  39. 126 7
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
  40. 12 1
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
  41. 2 0
      README.md

+ 29 - 0
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -345,6 +345,35 @@ uses
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.pas',
+  ClpDHDomainParameters in '..\..\CryptoLib\src\Asn1\X9\ClpDHDomainParameters.pas',
+  ClpDHValidationParams in '..\..\CryptoLib\src\Asn1\X9\ClpDHValidationParams.pas',
+  ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
+  ClpDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHBasicAgreement.pas',
+  ClpDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas',
+  ClpDHKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyPairGenerator.pas',
+  ClpDHParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersGenerator.pas',
+  ClpDHKeyGeneratorHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyGeneratorHelper.pas',
+  ClpDHParametersHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersHelper.pas',
+  ClpDHPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPrivateKeyParameters.pas',
+  ClpDHPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPublicKeyParameters.pas',
+  ClpDHKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyGenerationParameters.pas',
+  ClpDHKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyParameters.pas',
+  ClpDHValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHValidationParameters.pas',
+  ClpDHParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHParameters.pas',
+  ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
+  ClpIDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicAgreement.pas',
+  ClpIDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicKeyPairGenerator.pas',
+  ClpIDHKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyPairGenerator.pas',
+  ClpIDHPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPrivateKeyParameters.pas',
+  ClpIDHPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPublicKeyParameters.pas',
+  ClpIDHParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHParametersGenerator.pas',
+  ClpIDHKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGenerationParameters.pas',
+  ClpIDHParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHParameters.pas',
+  ClpIDHKeyGeneratorHelper in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGeneratorHelper.pas',
+  ClpIDHKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyParameters.pas',
+  ClpIDHValidationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParameters.pas',
+  ClpIDHDomainParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHDomainParameters.pas',
+  ClpIDHValidationParams in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParams.pas',
   UsageExamples in '..\src\UsageExamples.pas';
   UsageExamples in '..\src\UsageExamples.pas';
 
 
 begin
 begin

+ 31 - 1
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.TestInsight.dpr

@@ -355,6 +355,35 @@ uses
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.pas',
+  ClpDHParametersHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersHelper.pas',
+  ClpDHValidationParams in '..\..\CryptoLib\src\Asn1\X9\ClpDHValidationParams.pas',
+  ClpIDHValidationParams in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParams.pas',
+  ClpDHDomainParameters in '..\..\CryptoLib\src\Asn1\X9\ClpDHDomainParameters.pas',
+  ClpIDHDomainParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHDomainParameters.pas',
+  ClpDHParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHParameters.pas',
+  ClpIDHParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHParameters.pas',
+  ClpDHValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHValidationParameters.pas',
+  ClpIDHValidationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParameters.pas',
+  ClpDHKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyParameters.pas',
+  ClpIDHKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyParameters.pas',
+  ClpDHKeyGeneratorHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyGeneratorHelper.pas',
+  ClpIDHKeyGeneratorHelper in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGeneratorHelper.pas',
+  ClpDHKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyGenerationParameters.pas',
+  ClpIDHKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGenerationParameters.pas',
+  ClpDHParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersGenerator.pas',
+  ClpIDHParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHParametersGenerator.pas',
+  ClpDHPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPublicKeyParameters.pas',
+  ClpIDHPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPublicKeyParameters.pas',
+  ClpDHPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPrivateKeyParameters.pas',
+  ClpIDHPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPrivateKeyParameters.pas',
+  ClpDHKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyPairGenerator.pas',
+  ClpIDHKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyPairGenerator.pas',
+  ClpIDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicKeyPairGenerator.pas',
+  ClpDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas',
+  ClpIDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicAgreement.pas',
+  ClpDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHBasicAgreement.pas',
+  ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
+  ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',
@@ -423,7 +452,8 @@ uses
   Argon2Tests in '..\src\Crypto\Argon2Tests.pas',
   Argon2Tests in '..\src\Crypto\Argon2Tests.pas',
   DigestUtilitiesTests in '..\src\Security\DigestUtilitiesTests.pas',
   DigestUtilitiesTests in '..\src\Security\DigestUtilitiesTests.pas',
   DigestTests in '..\src\Others\DigestTests.pas',
   DigestTests in '..\src\Others\DigestTests.pas',
-  ScryptTests in '..\src\Crypto\ScryptTests.pas';
+  ScryptTests in '..\src\Crypto\ScryptTests.pas',
+  DHTests in '..\src\Crypto\DHTests.pas';
 
 
 begin
 begin
 
 

+ 31 - 1
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -358,6 +358,35 @@ uses
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpArgon2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpScryptParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIScryptParametersGenerator.pas',
+  ClpDHParametersHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersHelper.pas',
+  ClpDHValidationParams in '..\..\CryptoLib\src\Asn1\X9\ClpDHValidationParams.pas',
+  ClpIDHValidationParams in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParams.pas',
+  ClpDHDomainParameters in '..\..\CryptoLib\src\Asn1\X9\ClpDHDomainParameters.pas',
+  ClpIDHDomainParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHDomainParameters.pas',
+  ClpDHParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHParameters.pas',
+  ClpIDHParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHParameters.pas',
+  ClpDHValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHValidationParameters.pas',
+  ClpIDHValidationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHValidationParameters.pas',
+  ClpDHKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyParameters.pas',
+  ClpIDHKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyParameters.pas',
+  ClpDHKeyGeneratorHelper in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyGeneratorHelper.pas',
+  ClpIDHKeyGeneratorHelper in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGeneratorHelper.pas',
+  ClpDHKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHKeyGenerationParameters.pas',
+  ClpIDHKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyGenerationParameters.pas',
+  ClpDHParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHParametersGenerator.pas',
+  ClpIDHParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHParametersGenerator.pas',
+  ClpDHPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPublicKeyParameters.pas',
+  ClpIDHPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPublicKeyParameters.pas',
+  ClpDHPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDHPrivateKeyParameters.pas',
+  ClpIDHPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIDHPrivateKeyParameters.pas',
+  ClpDHKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHKeyPairGenerator.pas',
+  ClpIDHKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHKeyPairGenerator.pas',
+  ClpIDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicKeyPairGenerator.pas',
+  ClpDHBasicKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas',
+  ClpIDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHBasicAgreement.pas',
+  ClpDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHBasicAgreement.pas',
+  ClpIDHAgreement in '..\..\CryptoLib\src\Interfaces\ClpIDHAgreement.pas',
+  ClpDHAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpDHAgreement.pas',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',
   ClpIShortenedDigest in '..\src\Utils\ClpIShortenedDigest.pas',
@@ -426,7 +455,8 @@ uses
   Argon2Tests in '..\src\Crypto\Argon2Tests.pas',
   Argon2Tests in '..\src\Crypto\Argon2Tests.pas',
   DigestUtilitiesTests in '..\src\Security\DigestUtilitiesTests.pas',
   DigestUtilitiesTests in '..\src\Security\DigestUtilitiesTests.pas',
   DigestTests in '..\src\Others\DigestTests.pas',
   DigestTests in '..\src\Others\DigestTests.pas',
-  ScryptTests in '..\src\Crypto\ScryptTests.pas';
+  ScryptTests in '..\src\Crypto\ScryptTests.pas',
+  DHTests in '..\src\Crypto\DHTests.pas';
 
 
 begin
 begin
 
 

+ 5 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi

@@ -77,7 +77,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item4>
       </Item4>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="71">
+    <Units Count="72">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -363,6 +363,10 @@
         <Filename Value="..\src\Crypto\ScryptTests.pas"/>
         <Filename Value="..\src\Crypto\ScryptTests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit70>
       </Unit70>
+      <Unit71>
+        <Filename Value="..\src\Crypto\DHTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit71>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

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

@@ -71,6 +71,7 @@ uses
   ScryptTests,
   ScryptTests,
   DigestTests,
   DigestTests,
   DigestUtilitiesTests,
   DigestUtilitiesTests,
+  DHTests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom,
   ClpIFixedSecureRandom,
   ClpShortenedDigest,
   ClpShortenedDigest,

+ 5 - 1
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi

@@ -37,7 +37,7 @@
         <PackageName Value="FCL"/>
         <PackageName Value="FCL"/>
       </Item2>
       </Item2>
     </RequiredPackages>
     </RequiredPackages>
-    <Units Count="70">
+    <Units Count="71">
       <Unit0>
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
@@ -318,6 +318,10 @@
         <Filename Value="..\src\Crypto\ScryptTests.pas"/>
         <Filename Value="..\src\Crypto\ScryptTests.pas"/>
         <IsPartOfProject Value="True"/>
         <IsPartOfProject Value="True"/>
       </Unit69>
       </Unit69>
+      <Unit70>
+        <Filename Value="..\src\Crypto\DHTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit70>
     </Units>
     </Units>
   </ProjectOptions>
   </ProjectOptions>
   <CompilerOptions>
   <CompilerOptions>

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

@@ -69,6 +69,7 @@ uses
   ScryptTests,
   ScryptTests,
   DigestTests,
   DigestTests,
   DigestUtilitiesTests,
   DigestUtilitiesTests,
+  DHTests,
   ClpFixedSecureRandom,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom,
   ClpIFixedSecureRandom,
   ClpShortenedDigest,
   ClpShortenedDigest,

+ 594 - 0
CryptoLib.Tests/src/Crypto/DHTests.pas

@@ -0,0 +1,594 @@
+{ *********************************************************************************** }
+{ *                              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 DHTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpISecureRandom,
+  ClpSecureRandom,
+  ClpIParametersWithRandom,
+  ClpParametersWithRandom,
+  ClpIDHAgreement,
+  ClpDHAgreement,
+  ClpIDHBasicAgreement,
+  ClpDHBasicAgreement,
+  ClpIDHParameters,
+  ClpDHParameters,
+  ClpIDHParametersGenerator,
+  ClpDHParametersGenerator,
+  ClpIDHKeyPairGenerator,
+  ClpDHKeyPairGenerator,
+  ClpIDHBasicKeyPairGenerator,
+  ClpDHBasicKeyPairGenerator,
+  ClpIDHPrivateKeyParameters,
+  ClpIDHPublicKeyParameters,
+  ClpIDHKeyGenerationParameters,
+  ClpDHKeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+  TTestDH = class(TCryptoLibTestCase)
+
+  private
+  var
+    Fg512, Fp512, Fg768, Fp768, Fg1024, Fp1024: TBigInteger;
+
+    function GetDHBasicKeyPairGenerator(const g, p: TBigInteger;
+      privateValueSize: Int32): IDHBasicKeyPairGenerator;
+
+    function GetDHKeyPairGenerator(const g, p: TBigInteger)
+      : IDHKeyPairGenerator;
+
+    procedure DoTestDH(size: Int32; const g, p: TBigInteger);
+
+    procedure DoTestDHBasic(size, privateValueSize: Int32;
+      const g, p: TBigInteger);
+
+    procedure DoCheckKeySize(privateValueSize: Int32;
+      const priv: IDHPrivateKeyParameters);
+
+    procedure DoTestGPWithRandom(const kpGen: IDHKeyPairGenerator);
+
+    procedure DoTestSimpleWithRandom(const kpGen: IDHBasicKeyPairGenerator);
+
+    // this test can take quiet a while
+    procedure DoTestGeneration(size: Int32);
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+    procedure TestDHBasic;
+    procedure TestDH;
+    //
+    // generation test.
+    //
+    procedure TestGeneration;
+    //
+    // with random test
+    //
+    procedure TestSimpleWithRandom;
+    procedure TestGPWithRandom;
+    //
+    // parameter tests
+    //
+    procedure TestParameters;
+  end;
+
+implementation
+
+{ TTestDH }
+
+function TTestDH.GetDHBasicKeyPairGenerator(const g, p: TBigInteger;
+  privateValueSize: Int32): IDHBasicKeyPairGenerator;
+var
+  dhParams: IDHParameters;
+  dhkgParams: IDHKeyGenerationParameters;
+  kpGen: IDHBasicKeyPairGenerator;
+begin
+  dhParams := TDHParameters.Create(p, g, Default (TBigInteger),
+    privateValueSize);
+
+  dhkgParams := TDHKeyGenerationParameters.Create(TSecureRandom.Create()
+    as ISecureRandom, dhParams);
+
+  kpGen := TDHBasicKeyPairGenerator.Create();
+
+  kpGen.Init(dhkgParams);
+
+  result := kpGen;
+end;
+
+function TTestDH.GetDHKeyPairGenerator(const g, p: TBigInteger)
+  : IDHKeyPairGenerator;
+var
+  dhParams: IDHParameters;
+  dhkgParams: IDHKeyGenerationParameters;
+  kpGen: IDHKeyPairGenerator;
+begin
+  dhParams := TDHParameters.Create(p, g);
+
+  dhkgParams := TDHKeyGenerationParameters.Create(TSecureRandom.Create()
+    as ISecureRandom, dhParams);
+
+  kpGen := TDHKeyPairGenerator.Create();
+
+  kpGen.Init(dhkgParams);
+
+  result := kpGen;
+end;
+
+procedure TTestDH.DoCheckKeySize(privateValueSize: Int32;
+  const priv: IDHPrivateKeyParameters);
+begin
+  if (privateValueSize <> 0) then
+  begin
+    if (priv.X.BitLength <> privateValueSize) then
+    begin
+      Fail(Format('limited key check failed for key size %d',
+        [privateValueSize]));
+    end;
+  end;
+end;
+
+procedure TTestDH.DoTestDH(size: Int32; const g, p: TBigInteger);
+var
+  kpGen: IDHKeyPairGenerator;
+  pair: IAsymmetricCipherKeyPair;
+  pu1, pu2: IDHPublicKeyParameters;
+  pv1, pv2: IDHPrivateKeyParameters;
+  e1, e2: IDHAgreement;
+  m1, m2, k1, k2: TBigInteger;
+begin
+  kpGen := GetDHKeyPairGenerator(g, p);
+
+  //
+  // generate first pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu1 := pair.Public as IDHPublicKeyParameters;
+  pv1 := pair.Private as IDHPrivateKeyParameters;
+  //
+  // generate second pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu2 := pair.Public as IDHPublicKeyParameters;
+  pv2 := pair.Private as IDHPrivateKeyParameters;
+
+  //
+  // two way
+  //
+  e1 := TDHAgreement.Create();
+  e2 := TDHAgreement.Create();
+
+  e1.Init(pv1);
+  e2.Init(pv2);
+
+  m1 := e1.CalculateMessage();
+  m2 := e2.CalculateMessage();
+
+  k1 := e1.CalculateAgreement(pu2, m2);
+  k2 := e2.CalculateAgreement(pu1, m1);
+
+  if (not k1.Equals(k2)) then
+  begin
+    Fail(Format('" %d " bit 2-way test failed', [size]));
+  end;
+end;
+
+procedure TTestDH.DoTestDHBasic(size, privateValueSize: Int32;
+  const g, p: TBigInteger);
+var
+  kpGen: IDHBasicKeyPairGenerator;
+  pair: IAsymmetricCipherKeyPair;
+  pu1, pu2: IDHPublicKeyParameters;
+  pv1, pv2: IDHPrivateKeyParameters;
+  e1, e2: IDHBasicAgreement;
+  k1, k2: TBigInteger;
+begin
+  kpGen := GetDHBasicKeyPairGenerator(g, p, privateValueSize);
+
+  //
+  // generate first pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu1 := pair.Public as IDHPublicKeyParameters;
+  pv1 := pair.Private as IDHPrivateKeyParameters;
+
+  DoCheckKeySize(privateValueSize, pv1);
+
+  //
+  // generate second pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu2 := pair.Public as IDHPublicKeyParameters;
+  pv2 := pair.Private as IDHPrivateKeyParameters;
+
+  DoCheckKeySize(privateValueSize, pv2);
+
+  //
+  // two way
+  //
+  e1 := TDHBasicAgreement.Create();
+  e2 := TDHBasicAgreement.Create();
+
+  e1.Init(pv1);
+  e2.Init(pv2);
+
+  k1 := e1.CalculateAgreement(pu2);
+  k2 := e2.CalculateAgreement(pu1);
+
+  if (not k1.Equals(k2)) then
+  begin
+    Fail(Format('basic " %d " bit 2-way test failed', [size]));
+  end;
+end;
+
+procedure TTestDH.DoTestGeneration(size: Int32);
+var
+  kpGen: IDHBasicKeyPairGenerator;
+  pGen: IDHParametersGenerator;
+  dhParams: IDHParameters;
+  dhkgParams: IDHKeyGenerationParameters;
+  pair: IAsymmetricCipherKeyPair;
+  pu1, pu2: IDHPublicKeyParameters;
+  pv1, pv2: IDHPrivateKeyParameters;
+  e1, e2: IDHBasicAgreement;
+  k1, k2: TBigInteger;
+begin
+
+  pGen := TDHParametersGenerator.Create();
+
+  pGen.Init(size, 10, TSecureRandom.Create() as ISecureRandom);
+
+  dhParams := pGen.GenerateParameters();
+
+  if (dhParams.L <> 0) then
+  begin
+    Fail('DHParametersGenerator failed to set J to 0 in generated DHParameters');
+  end;
+
+  dhkgParams := TDHKeyGenerationParameters.Create(TSecureRandom.Create()
+    as ISecureRandom, dhParams);
+
+  kpGen := TDHBasicKeyPairGenerator.Create();
+
+  kpGen.Init(dhkgParams);
+
+  //
+  // generate first pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu1 := pair.Public as IDHPublicKeyParameters;
+  pv1 := pair.Private as IDHPrivateKeyParameters;
+
+  //
+  // generate second pair
+  //
+  dhkgParams := TDHKeyGenerationParameters.Create(TSecureRandom.Create()
+    as ISecureRandom, pu1.Parameters);
+
+  kpGen.Init(dhkgParams);
+
+  pair := kpGen.GenerateKeyPair();
+
+  pu2 := pair.Public as IDHPublicKeyParameters;
+  pv2 := pair.Private as IDHPrivateKeyParameters;
+
+  //
+  // two way
+  //
+  e1 := TDHBasicAgreement.Create();
+  e2 := TDHBasicAgreement.Create();
+
+  e1.Init(TParametersWithRandom.Create(pv1, TSecureRandom.Create()
+    as ISecureRandom) as IParametersWithRandom);
+  e2.Init(TParametersWithRandom.Create(pv2, TSecureRandom.Create()
+    as ISecureRandom) as IParametersWithRandom);
+
+  k1 := e1.CalculateAgreement(pu2);
+  k2 := e2.CalculateAgreement(pu1);
+
+  if (not k1.Equals(k2)) then
+  begin
+    Fail(Format('basic with " %d " bit 2-way test failed', [size]));
+  end;
+end;
+
+procedure TTestDH.DoTestGPWithRandom(const kpGen: IDHKeyPairGenerator);
+var
+  pair: IAsymmetricCipherKeyPair;
+  pu1, pu2: IDHPublicKeyParameters;
+  pv1, pv2: IDHPrivateKeyParameters;
+  e1, e2: IDHAgreement;
+  m1, m2, k1, k2: TBigInteger;
+begin
+
+  //
+  // generate first pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu1 := pair.Public as IDHPublicKeyParameters;
+  pv1 := pair.Private as IDHPrivateKeyParameters;
+  //
+  // generate second pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu2 := pair.Public as IDHPublicKeyParameters;
+  pv2 := pair.Private as IDHPrivateKeyParameters;
+
+  //
+  // two way
+  //
+  e1 := TDHAgreement.Create();
+  e2 := TDHAgreement.Create();
+
+  e1.Init(TParametersWithRandom.Create(pv1, TSecureRandom.Create()
+    as ISecureRandom) as IParametersWithRandom);
+  e2.Init(TParametersWithRandom.Create(pv2, TSecureRandom.Create()
+    as ISecureRandom) as IParametersWithRandom);
+
+  m1 := e1.CalculateMessage();
+  m2 := e2.CalculateMessage();
+
+  k1 := e1.CalculateAgreement(pu2, m2);
+  k2 := e2.CalculateAgreement(pu1, m1);
+
+  if (not k1.Equals(k2)) then
+  begin
+    Fail('full with random 2-way test failed');
+  end;
+end;
+
+procedure TTestDH.DoTestSimpleWithRandom(const kpGen: IDHBasicKeyPairGenerator);
+var
+  pair: IAsymmetricCipherKeyPair;
+  pu1, pu2: IDHPublicKeyParameters;
+  pv1, pv2: IDHPrivateKeyParameters;
+  e1, e2: IDHBasicAgreement;
+  k1, k2: TBigInteger;
+begin
+
+  //
+  // generate first pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu1 := pair.Public as IDHPublicKeyParameters;
+  pv1 := pair.Private as IDHPrivateKeyParameters;
+
+  //
+  // generate second pair
+  //
+  pair := kpGen.GenerateKeyPair();
+
+  pu2 := pair.Public as IDHPublicKeyParameters;
+  pv2 := pair.Private as IDHPrivateKeyParameters;
+
+  //
+  // two way
+  //
+  e1 := TDHBasicAgreement.Create();
+  e2 := TDHBasicAgreement.Create();
+
+  e1.Init(TParametersWithRandom.Create(pv1, TSecureRandom.Create()
+    as ISecureRandom) as IParametersWithRandom);
+  e2.Init(TParametersWithRandom.Create(pv2, TSecureRandom.Create()
+    as ISecureRandom) as IParametersWithRandom);
+
+  k1 := e1.CalculateAgreement(pu2);
+  k2 := e2.CalculateAgreement(pu1);
+
+  if (not k1.Equals(k2)) then
+  begin
+    Fail('basic with random 2-way test failed');
+  end;
+end;
+
+procedure TTestDH.TestDH;
+begin
+  DoTestDH(512, Fg512, Fp512);
+  DoTestDH(768, Fg768, Fp768);
+  DoTestDH(1024, Fg1024, Fp1024);
+end;
+
+procedure TTestDH.TestDHBasic;
+begin
+  DoTestDHBasic(512, 0, Fg512, Fp512);
+  DoTestDHBasic(768, 0, Fg768, Fp768);
+  DoTestDHBasic(1024, 0, Fg1024, Fp1024);
+
+  DoTestDHBasic(512, 64, Fg512, Fp512);
+  DoTestDHBasic(768, 128, Fg768, Fp768);
+  DoTestDHBasic(1024, 256, Fg1024, Fp1024);
+end;
+
+procedure TTestDH.TestGeneration;
+begin
+  DoTestGeneration(256);
+end;
+
+procedure TTestDH.TestGPWithRandom;
+var
+  kpGen: IDHKeyPairGenerator;
+begin
+  kpGen := GetDHKeyPairGenerator(Fg512, Fp512);
+
+  DoTestGPWithRandom(kpGen);
+end;
+
+procedure TTestDH.TestSimpleWithRandom;
+var
+  kpBasicGen: IDHBasicKeyPairGenerator;
+begin
+  kpBasicGen := GetDHBasicKeyPairGenerator(Fg512, Fp512, 0);
+
+  DoTestSimpleWithRandom(kpBasicGen);
+end;
+
+procedure TTestDH.TestParameters;
+var
+  dh: IDHAgreement;
+  dhBasic: IDHBasicAgreement;
+  kpGen, kpGen768: IDHKeyPairGenerator;
+  kpBasicGen, kpBasicGen768: IDHBasicKeyPairGenerator;
+  dhPair, dhBasicPair: IAsymmetricCipherKeyPair;
+begin
+
+  dh := TDHAgreement.Create();
+  kpGen := GetDHKeyPairGenerator(Fg512, Fp512);
+  dhPair := kpGen.GenerateKeyPair();
+
+  try
+    dh.Init(dhPair.Public);
+    Fail('DHAgreement key check failed');
+
+  except
+    on e: EArgumentCryptoLibException do
+    begin
+      // ignore
+    end;
+
+  end;
+
+  kpGen768 := GetDHKeyPairGenerator(Fg768, Fp768);
+
+  try
+    dh.Init(dhPair.Private);
+
+    dh.CalculateAgreement(kpGen768.GenerateKeyPair()
+      .Public as IDHPublicKeyParameters, TBigInteger.ValueOf(100));
+
+    Fail('DHAgreement agreement check failed');
+
+  except
+    on e: EArgumentCryptoLibException do
+    begin
+      // ignore
+    end;
+
+  end;
+
+  dhBasic := TDHBasicAgreement.Create();
+  kpBasicGen := GetDHBasicKeyPairGenerator(Fg512, Fp512, 0);
+  dhBasicPair := kpBasicGen.GenerateKeyPair();
+
+  try
+    dhBasic.Init(dhBasicPair.Public);
+    Fail('DHBasicAgreement key check failed');
+
+  except
+    on e: EArgumentCryptoLibException do
+    begin
+      // expected
+    end;
+
+  end;
+
+  kpBasicGen768 := GetDHBasicKeyPairGenerator(Fg768, Fp768, 0);
+
+  try
+    dhBasic.Init(dhPair.Private);
+
+    dhBasic.CalculateAgreement(kpBasicGen768.GenerateKeyPair()
+      .Public as IDHPublicKeyParameters);
+
+    Fail('DHBasicAgreement agreement check failed');
+
+  except
+    on e: EArgumentCryptoLibException do
+    begin
+      // expected
+    end;
+
+  end;
+
+end;
+
+procedure TTestDH.SetUp;
+begin
+  inherited;
+  Fg512 := TBigInteger.Create
+    ('153D5D6172ADB43045B68AE8E1DE1070B6137005686D29D3D73A7749199681EE5B212C9B96BFDCFA5B20CD5E3FD2044895D609CF9B410B7A0F12CA1CB9A428CC',
+    16);
+  Fp512 := TBigInteger.Create
+    ('9494FEC095F3B85EE286542B3836FC81A5DD0A0349B4C239DD38744D488CF8E31DB8BCB7D33B41ABB9E5A33CCA9144B1CEF332C94BF0573BF047A3ACA98CDF3B',
+    16);
+
+  Fg768 := TBigInteger.Create
+    ('7C240073C1316C621DF461B71EBB0CDCC90A6E5527E5E126633D131F87461C4DC4AFC60C2CB0F053B6758871489A69613E2A8B4C8ACDE23954C08C81CBD36132CFD64D69E4ED9F8E51ED6E516297206672D5C0A69135DF0A5DCF010D289A9CA1',
+    16);
+  Fp768 := TBigInteger.Create
+    ('8C9DD223DEBED1B80103B8B309715BE009D48860ED5AE9B9D5D8159508EFD802E3AD4501A7F7E1CFEC78844489148CD72DA24B21EDDD01AA624291C48393E277CFC529E37075ECCEF957F3616F962D15B44AEAB4039D01B817FDE9EAA12FD73F',
+    16);
+
+  Fg1024 := TBigInteger.Create
+    ('1DB17639CDF96BC4EABBA19454F0B7E5BD4E14862889A725C96EB61048DCD676CEB303D586E30F060DBAFD8A571A39C4D823982117DA5CC4E0F89C77388B7A08896362429B94A18A327604EB7FF227BFFBC83459ADE299E5'
+    + '7B5F77B50FB045250934938EFA145511166E3197373E1B5B1E52DE713EB49792BEDDE722C6717ABF',
+    16);
+  Fp1024 := TBigInteger.Create
+    ('A00E283B3C624E5B2B4D9FBC2653B5185D99499B00FD1BF244C6F0BB817B4D1C451B2958D62A0F8A38CAEF059FB5ECD25D75ED9AF403F5B5BDAB97A642902F824E3C13789FED95FA106DDFE0FF4A707C85E2EB77D49E68F2'
+    + '808BCEA18CE128B178CD287C6BC00EFA9A1AD2A673FE0DCEACE53166F75B81D6709D5F8AF7C66BB7',
+    16);
+
+end;
+
+procedure TTestDH.TearDown;
+begin
+  inherited;
+
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestDH);
+{$ELSE}
+  RegisterTest(TTestDH.Suite);
+{$ENDIF FPC}
+
+end.

+ 242 - 0
CryptoLib/src/Asn1/X9/ClpDHDomainParameters.pas

@@ -0,0 +1,242 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHDomainParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHDomainParameters,
+  ClpIDHValidationParams,
+  ClpDHValidationParams,
+  ClpAsn1Objects,
+  ClpIAsn1Objects,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SPNil = 'P Cannot be Nil';
+  SGNil = 'G Cannot be Nil';
+  SQNil = 'Q Cannot be Nil';
+  SJNil = 'J Cannot be Nil';
+  SBadSequenceSize = 'Bad Sequence Size "seq": %d';
+  SInvalidDHDomainParameters = 'Invalid DHDomainParameters: %s';
+
+type
+  TDHDomainParameters = class(TAsn1Encodable, IDHDomainParameters)
+
+  strict private
+  var
+    Fp, Fg, Fq, Fj: IDerInteger;
+    FvalidationParams: IDHValidationParams;
+
+    function GetP: IDerInteger; inline;
+    function GetG: IDerInteger; inline;
+    function GetQ: IDerInteger; inline;
+    function GetJ: IDerInteger; inline;
+    function GetValidationParams: IDHValidationParams; inline;
+
+    constructor Create(const seq: IAsn1Sequence); overload;
+
+    class function GetNext(const e: TCryptoLibGenericArray<IAsn1Encodable>;
+      var Idx: Int32): IAsn1Encodable; static; inline;
+
+  public
+    constructor Create(const p, g, q, j: IDerInteger;
+      const validationParams: IDHValidationParams); overload;
+
+    function ToAsn1Object(): IAsn1Object; override;
+
+    property p: IDerInteger read GetP;
+
+    property g: IDerInteger read GetG;
+
+    property q: IDerInteger read GetQ;
+
+    property j: IDerInteger read GetJ;
+
+    property validationParams: IDHValidationParams read GetValidationParams;
+
+    class function GetInstance(const obj: IAsn1TaggedObject;
+      isExplicit: Boolean): IDHDomainParameters; overload; static; inline;
+
+    class function GetInstance(obj: TObject): IDHDomainParameters; overload;
+      static; inline;
+
+  end;
+
+implementation
+
+{ TDHDomainParameters }
+
+function TDHDomainParameters.GetP: IDerInteger;
+begin
+  result := Fp;
+end;
+
+function TDHDomainParameters.GetG: IDerInteger;
+begin
+  result := Fg;
+end;
+
+function TDHDomainParameters.GetJ: IDerInteger;
+begin
+  result := Fj;
+end;
+
+function TDHDomainParameters.GetQ: IDerInteger;
+begin
+  result := Fq;
+end;
+
+function TDHDomainParameters.GetValidationParams: IDHValidationParams;
+begin
+  result := FvalidationParams;
+end;
+
+class function TDHDomainParameters.GetNext
+  (const e: TCryptoLibGenericArray<IAsn1Encodable>; var Idx: Int32)
+  : IAsn1Encodable;
+begin
+  if Idx <= (System.Length(e) - 1) then
+  begin
+    result := e[Idx];
+    System.Inc(Idx);
+  end
+  else
+  begin
+    result := Nil;
+  end;
+end;
+
+constructor TDHDomainParameters.Create(const seq: IAsn1Sequence);
+var
+  e: TCryptoLibGenericArray<IAsn1Encodable>;
+  next: IAsn1Encodable;
+  Idx: Int32;
+begin
+  Inherited Create();
+  if (seq.Count < 3) or (seq.Count > 5) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize,
+      [seq.Count]);
+  end;
+
+  Idx := 0;
+  e := seq.GetEnumerable();
+
+  Fp := TDerInteger.GetInstance(GetNext(e, Idx) as TAsn1Encodable);
+
+  Fg := TDerInteger.GetInstance(GetNext(e, Idx) as TAsn1Encodable);
+
+  Fq := TDerInteger.GetInstance(GetNext(e, Idx) as TAsn1Encodable);
+
+  next := GetNext(e, Idx);
+
+  if ((next <> Nil) and ((next as TAsn1Encodable) is TDerInteger)) then
+  begin
+    Fj := TDerInteger.GetInstance(next as TAsn1Encodable);
+    next := GetNext(e, Idx);
+  end;
+
+  if (next <> Nil) then
+  begin
+    FvalidationParams := TDHValidationParams.GetInstance
+      (next.ToAsn1Object() as TAsn1Object);
+  end;
+
+end;
+
+constructor TDHDomainParameters.Create(const p, g, q, j: IDerInteger;
+  const validationParams: IDHValidationParams);
+begin
+  Inherited Create();
+
+  if (p = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SPNil);
+  end;
+
+  if (g = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SGNil);
+  end;
+
+  if (q = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SQNil);
+  end;
+
+  if (j = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SJNil);
+  end;
+
+  Fp := p;
+  Fg := g;
+  Fq := q;
+  Fj := j;
+  FvalidationParams := validationParams;
+end;
+
+class function TDHDomainParameters.GetInstance(obj: TObject)
+  : IDHDomainParameters;
+begin
+  if ((obj = Nil) or (obj is TDHDomainParameters)) then
+  begin
+    result := obj as TDHDomainParameters;
+    Exit;
+  end;
+
+  if (obj is TAsn1Sequence) then
+  begin
+    result := TDHDomainParameters.Create(obj as TAsn1Sequence);
+    Exit;
+  end;
+
+  raise EArgumentCryptoLibException.CreateResFmt(@SInvalidDHDomainParameters,
+    [obj.ToString]);
+end;
+
+class function TDHDomainParameters.GetInstance(const obj: IAsn1TaggedObject;
+  isExplicit: Boolean): IDHDomainParameters;
+begin
+  result := GetInstance(TAsn1Sequence.GetInstance(obj, isExplicit)
+    as TAsn1Sequence);
+end;
+
+function TDHDomainParameters.ToAsn1Object: IAsn1Object;
+var
+  v: IAsn1EncodableVector;
+begin
+  v := TAsn1EncodableVector.Create([p, g, q]);
+
+  if (Fj <> Nil) then
+  begin
+    v.Add([Fj]);
+  end;
+
+  if (FvalidationParams <> Nil) then
+  begin
+    v.Add([FvalidationParams]);
+  end;
+
+  result := TDerSequence.Create(v);
+end;
+
+end.

+ 145 - 0
CryptoLib/src/Asn1/X9/ClpDHValidationParams.pas

@@ -0,0 +1,145 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHValidationParams;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHValidationParams,
+  ClpAsn1Objects,
+  ClpIAsn1Objects,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SSeedNil = 'Seed Cannot be Nil';
+  SPGenCounterNil = 'PGenCounter Cannot be Nil';
+  SBadSequenceSize = 'Bad Sequence Size "seq": %d';
+  SInvalidDHValidationParams = 'Invalid DHValidationParams: %s';
+
+type
+  TDHValidationParams = class(TAsn1Encodable, IDHValidationParams)
+
+  strict private
+  var
+    Fseed: IDerBitString;
+    FpgenCounter: IDerInteger;
+
+    function GetSeed: IDerBitString; inline;
+    function GetPGenCounter: IDerInteger; inline;
+
+    constructor Create(const seq: IAsn1Sequence); overload;
+
+  public
+    constructor Create(const seed: IDerBitString;
+      const pgenCounter: IDerInteger); overload;
+
+    function ToAsn1Object(): IAsn1Object; override;
+
+    property seed: IDerBitString read GetSeed;
+
+    property pgenCounter: IDerInteger read GetPGenCounter;
+
+    class function GetInstance(const obj: IAsn1TaggedObject;
+      isExplicit: Boolean): IDHValidationParams; overload; static; inline;
+
+    class function GetInstance(obj: TObject): IDHValidationParams; overload;
+      static; inline;
+
+  end;
+
+implementation
+
+{ TDHValidationParams }
+
+function TDHValidationParams.GetPGenCounter: IDerInteger;
+begin
+  result := FpgenCounter;
+end;
+
+function TDHValidationParams.GetSeed: IDerBitString;
+begin
+  result := Fseed;
+end;
+
+function TDHValidationParams.ToAsn1Object: IAsn1Object;
+begin
+  result := TDerSequence.Create([Fseed, FpgenCounter]);
+end;
+
+constructor TDHValidationParams.Create(const seq: IAsn1Sequence);
+begin
+  Inherited Create();
+  if (seq.Count <> 2) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SBadSequenceSize,
+      [seq.Count]);
+  end;
+
+  Fseed := TDerBitString.GetInstance(seq[0] as TAsn1Encodable);
+  FpgenCounter := TDerInteger.GetInstance(seq[1] as TAsn1Encodable);
+end;
+
+constructor TDHValidationParams.Create(const seed: IDerBitString;
+  const pgenCounter: IDerInteger);
+begin
+  Inherited Create();
+
+  if (seed = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SSeedNil);
+  end;
+
+  if (pgenCounter = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SPGenCounterNil);
+  end;
+
+  Fseed := seed;
+  FpgenCounter := pgenCounter;
+end;
+
+class function TDHValidationParams.GetInstance(obj: TObject)
+  : IDHValidationParams;
+begin
+  if ((obj = Nil) or (obj is TDHValidationParams)) then
+  begin
+    result := obj as TDHValidationParams;
+    Exit;
+  end;
+
+  if (obj is TAsn1Sequence) then
+  begin
+    result := TDHValidationParams.Create(obj as TAsn1Sequence);
+    Exit;
+  end;
+
+  raise EArgumentCryptoLibException.CreateResFmt(@SInvalidDHValidationParams,
+    [obj.ToString]);
+end;
+
+class function TDHValidationParams.GetInstance(const obj: IAsn1TaggedObject;
+  isExplicit: Boolean): IDHValidationParams;
+begin
+  result := GetInstance(TAsn1Sequence.GetInstance(obj, isExplicit)
+    as TAsn1Sequence);
+end;
+
+end.

+ 187 - 0
CryptoLib/src/Crypto/Agreement/ClpDHAgreement.pas

@@ -0,0 +1,187 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHAgreement;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpBigInteger,
+  ClpISecureRandom,
+  ClpSecureRandom,
+  ClpICipherParameters,
+  ClpIDHAgreement,
+  ClpIDHParameters,
+  ClpDHKeyPairGenerator,
+  ClpIDHKeyPairGenerator,
+  ClpIDHPrivateKeyParameters,
+  ClpIDHPublicKeyParameters,
+  ClpDHKeyGenerationParameters,
+  ClpIDHKeyGenerationParameters,
+  ClpIAsymmetricKeyParameter,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIParametersWithRandom,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SDHPublicKeyWrongParameter =
+    'Diffie-Hellman Public Key has Wrong Parameters.';
+  SNotDHPrivateKeyParameters = 'DHEngine Expects DHPrivateKeyParameters';
+  SMessageNotInitialized = 'Message not Initialised';
+  SSharedKeyInvalid = 'Shared Key Can''t be 1';
+  SDHPublicKeyWeak = 'Diffie-Hellman Public Key is Weak';
+  SDHPublicKeyNil = 'DH Public Key Parameter Cannot be Nil';
+
+type
+  /// <summary>
+  /// <para>
+  /// a Diffie-Hellman key exchange engine.
+  /// </para>
+  /// <para>
+  /// note: This uses MTI/A0 key agreement in order to make the key
+  /// agreement secure against passive attacks. If you're doing
+  /// Diffie-Hellman and both parties have long term public keys you
+  /// should look at using this. For further information have a look at
+  /// RFC 2631.
+  /// </para>
+  /// <para>
+  /// It's possible to extend this to more than two parties as well, for
+  /// the moment that is left as an exercise for the reader.
+  /// </para>
+  /// </summary>
+  TDHAgreement = class sealed(TInterfacedObject, IDHAgreement)
+
+  strict private
+  var
+    Fkey: IDHPrivateKeyParameters;
+    FdhParams: IDHParameters;
+    FprivateValue: TBigInteger;
+    Frandom: ISecureRandom;
+
+  public
+    /// <summary>
+    /// initialise the agreement engine.
+    /// </summary>
+    procedure Init(const parameters: ICipherParameters);
+
+    /// <summary>
+    /// calculate our initial message.
+    /// </summary>
+    function CalculateMessage(): TBigInteger;
+
+    /// <summary>
+    /// given a message from a given party and the corresponding public key
+    /// calculate the next message in the agreement sequence. In this case
+    /// this will represent the shared secret.
+    /// </summary>
+    function CalculateAgreement(const pub: IDHPublicKeyParameters;
+      const &message: TBigInteger): TBigInteger;
+
+  end;
+
+implementation
+
+{ TDHAgreement }
+
+function TDHAgreement.CalculateAgreement(const pub: IDHPublicKeyParameters;
+  const &message: TBigInteger): TBigInteger;
+var
+  p, peerY: TBigInteger;
+begin
+
+  if (pub = Nil) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SDHPublicKeyNil);
+  end;
+
+  if (not &message.IsInitialized) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SMessageNotInitialized);
+  end;
+
+  if (not(pub.parameters.Equals(FdhParams))) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SDHPublicKeyWrongParameter);
+  end;
+
+  p := FdhParams.p;
+
+  peerY := pub.Y;
+
+  if ((not peerY.IsInitialized) or (peerY.CompareTo(TBigInteger.One) <= 0) or
+    (peerY.CompareTo(p.Subtract(TBigInteger.One)) >= 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SDHPublicKeyWeak);
+  end;
+
+  result := peerY.ModPow(FprivateValue, p);
+
+  if (result.Equals(TBigInteger.One)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SSharedKeyInvalid);
+  end;
+
+  result := &message.ModPow(Fkey.X, p).Multiply(result).&Mod(p);
+end;
+
+function TDHAgreement.CalculateMessage: TBigInteger;
+var
+  dhGen: IDHKeyPairGenerator;
+  dhPair: IAsymmetricCipherKeyPair;
+begin
+  dhGen := TDHKeyPairGenerator.Create();
+
+  dhGen.Init(TDHKeyGenerationParameters.Create(Frandom, FdhParams)
+    as IDHKeyGenerationParameters);
+
+  dhPair := dhGen.GenerateKeyPair();
+
+  FprivateValue := (dhPair.Private as IDHPrivateKeyParameters).X;
+
+  result := (dhPair.Public as IDHPublicKeyParameters).Y;
+end;
+
+procedure TDHAgreement.Init(const parameters: ICipherParameters);
+var
+  kParam: IAsymmetricKeyParameter;
+  rParam: IParametersWithRandom;
+begin
+  if Supports(parameters, IParametersWithRandom, rParam) then
+  begin
+    Frandom := rParam.Random;
+    kParam := rParam.parameters as IAsymmetricKeyParameter;
+  end
+  else
+  begin
+    Frandom := TSecureRandom.Create();
+    kParam := parameters as IAsymmetricKeyParameter;
+  end;
+
+  if (not Supports(kParam, IDHPrivateKeyParameters)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SNotDHPrivateKeyParameters);
+  end;
+
+  Fkey := kParam as IDHPrivateKeyParameters;
+  FdhParams := Fkey.parameters;
+end;
+
+end.

+ 148 - 0
CryptoLib/src/Crypto/Agreement/ClpDHBasicAgreement.pas

@@ -0,0 +1,148 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHBasicAgreement;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpBigInteger,
+  ClpICipherParameters,
+  ClpIBasicAgreement,
+  ClpIDHBasicAgreement,
+  ClpIDHParameters,
+  ClpIDHPrivateKeyParameters,
+  ClpIDHPublicKeyParameters,
+  ClpIParametersWithRandom,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SDHPublicKeyWrongParameter =
+    'Diffie-Hellman Public Key has Wrong Parameters.';
+  SNotDHPrivateKeyParameters = 'DHEngine Expects DHPrivateKeyParameters';
+  SAlgorithmNotInitialized = 'Agreement Algorithm not Initialised';
+  SSharedKeyInvalid = 'Shared Key Can''t be 1';
+  SDHPublicKeyWeak = 'Diffie-Hellman Public Key is Weak';
+
+type
+  /// <summary>
+  /// <para>
+  /// a Diffie-Hellman key agreement class.
+  /// </para>
+  /// <para>
+  /// note: This is only the basic algorithm, it doesn't take advantage
+  /// of long term public keys if they are available. See the DHAgreement
+  /// class for a "better" implementation.
+  /// </para>
+  /// </summary>
+  TDHBasicAgreement = class sealed(TInterfacedObject, IDHBasicAgreement,
+    IBasicAgreement)
+
+  strict private
+  var
+    Fkey: IDHPrivateKeyParameters;
+    FdhParams: IDHParameters;
+
+  public
+    /// <summary>
+    /// initialise the agreement engine.
+    /// </summary>
+    procedure Init(const parameters: ICipherParameters);
+
+    /// <summary>
+    /// return the field size for the agreement algorithm in bytes.
+    /// </summary>
+    function GetFieldSize(): Int32;
+
+    /// <summary>
+    /// given a short term public key from a given party calculate the next
+    /// message in the agreement sequence.
+    /// </summary>
+    function CalculateAgreement(const pubKey: ICipherParameters): TBigInteger;
+
+  end;
+
+implementation
+
+{ TDHBasicAgreement }
+
+function TDHBasicAgreement.CalculateAgreement(const pubKey: ICipherParameters)
+  : TBigInteger;
+var
+  pub: IDHPublicKeyParameters;
+  p, peerY: TBigInteger;
+begin
+
+  if (Fkey = Nil) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SAlgorithmNotInitialized);
+  end;
+
+  pub := pubKey as IDHPublicKeyParameters;
+
+  if (not(pub.parameters.Equals(FdhParams))) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SDHPublicKeyWrongParameter);
+  end;
+
+  p := FdhParams.p;
+
+  peerY := pub.Y;
+
+  if ((not peerY.IsInitialized) or (peerY.CompareTo(TBigInteger.One) <= 0) or
+    (peerY.CompareTo(p.Subtract(TBigInteger.One)) >= 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SDHPublicKeyWeak);
+  end;
+
+  result := peerY.ModPow(Fkey.X, p);
+
+  if (result.Equals(TBigInteger.One)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SSharedKeyInvalid);
+  end;
+end;
+
+function TDHBasicAgreement.GetFieldSize: Int32;
+begin
+  result := (Fkey.parameters.p.BitLength + 7) div 8;
+end;
+
+procedure TDHBasicAgreement.Init(const parameters: ICipherParameters);
+var
+  Lparameters: ICipherParameters;
+begin
+  Lparameters := parameters;
+  if Supports(Lparameters, IParametersWithRandom) then
+  begin
+    Lparameters := (Lparameters as IParametersWithRandom).parameters;
+  end;
+
+  if (not Supports(Lparameters, IDHPrivateKeyParameters)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SNotDHPrivateKeyParameters);
+  end;
+
+  Fkey := Lparameters as IDHPrivateKeyParameters;
+  FdhParams := Fkey.parameters;
+end;
+
+end.

+ 104 - 0
CryptoLib/src/Crypto/Generators/ClpDHBasicKeyPairGenerator.pas

@@ -0,0 +1,104 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHBasicKeyPairGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHParameters,
+  ClpIDHBasicKeyPairGenerator,
+  ClpDHPublicKeyParameters,
+  ClpIDHPublicKeyParameters,
+  ClpDHPrivateKeyParameters,
+  ClpIDHPrivateKeyParameters,
+  ClpAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIKeyGenerationParameters,
+  ClpIDHKeyGenerationParameters,
+  ClpDHKeyGeneratorHelper,
+  ClpIDHKeyGeneratorHelper,
+  ClpIAsymmetricCipherKeyPairGenerator,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SParametersCannotBeNil = '"parameters" Cannot Be Nil';
+
+type
+
+  /// <summary>
+  /// <para>
+  /// a basic Diffie-Hellman key pair generator.
+  /// </para>
+  /// <para>
+  /// This generates keys consistent for use with the basic algorithm for
+  /// Diffie-Hellman.
+  /// </para>
+  /// </summary>
+  TDHBasicKeyPairGenerator = class sealed(TInterfacedObject,
+    IAsymmetricCipherKeyPairGenerator, IDHBasicKeyPairGenerator)
+
+  strict private
+
+  var
+    Fparam: IDHKeyGenerationParameters;
+
+  public
+
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    function GenerateKeyPair(): IAsymmetricCipherKeyPair;
+
+  end;
+
+implementation
+
+{ TDHBasicKeyPairGenerator }
+
+function TDHBasicKeyPairGenerator.GenerateKeyPair: IAsymmetricCipherKeyPair;
+var
+  dhp: IDHParameters;
+  helper: IDHKeyGeneratorHelper;
+  x, y: TBigInteger;
+begin
+
+  helper := TDHKeyGeneratorHelper.Instance;
+  dhp := Fparam.parameters;
+
+  x := helper.CalculatePrivate(dhp, Fparam.Random);
+  y := helper.CalculatePublic(dhp, x);
+
+  result := TAsymmetricCipherKeyPair.Create(TDHPublicKeyParameters.Create(y,
+    dhp) as IDHPublicKeyParameters, TDHPrivateKeyParameters.Create(x, dhp)
+    as IDHPrivateKeyParameters);
+end;
+
+procedure TDHBasicKeyPairGenerator.Init(const parameters
+  : IKeyGenerationParameters);
+begin
+  if (parameters = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SParametersCannotBeNil);
+  end;
+
+  Fparam := parameters as IDHKeyGenerationParameters;
+end;
+
+end.

+ 140 - 0
CryptoLib/src/Crypto/Generators/ClpDHKeyGeneratorHelper.pas

@@ -0,0 +1,140 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHKeyGeneratorHelper;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+
+  ClpISecureRandom,
+  ClpBits,
+  ClpBigInteger,
+  ClpBigIntegers,
+  ClpECAlgorithms,
+  ClpIDHParameters,
+  ClpIDHKeyGeneratorHelper;
+
+type
+  TDHKeyGeneratorHelper = class sealed(TInterfacedObject, IDHKeyGeneratorHelper)
+
+  strict private
+  class var
+
+    FIsBooted: Boolean;
+    FInstance: IDHKeyGeneratorHelper;
+
+    class function GetInstance: IDHKeyGeneratorHelper; static; inline;
+
+    class procedure Boot(); static;
+    class constructor DHKeyGeneratorHelper();
+  public
+
+    function CalculatePrivate(const dhParams: IDHParameters;
+      const random: ISecureRandom): TBigInteger;
+
+    function CalculatePublic(const dhParams: IDHParameters;
+      const x: TBigInteger): TBigInteger;
+
+    class property Instance: IDHKeyGeneratorHelper read GetInstance;
+
+  end;
+
+implementation
+
+{ TDHKeyGeneratorHelper }
+
+class procedure TDHKeyGeneratorHelper.Boot;
+begin
+  if not FIsBooted then
+  begin
+    FInstance := TDHKeyGeneratorHelper.Create();
+
+    FIsBooted := True;
+  end;
+end;
+
+function TDHKeyGeneratorHelper.CalculatePrivate(const dhParams: IDHParameters;
+  const random: ISecureRandom): TBigInteger;
+var
+  limit, minWeight, m: Int32;
+  x, min, q, max: TBigInteger;
+begin
+  Result := Default (TBigInteger);
+  limit := dhParams.L;
+
+  if (limit <> 0) then
+  begin
+    minWeight := TBits.Asr32(limit, 2);
+
+    while True do
+    begin
+      x := TBigInteger.Create(limit, random).SetBit(limit - 1);
+      if (TWNafUtilities.GetNafWeight(x) >= minWeight) then
+      begin
+        Result := x;
+        Exit;
+      end;
+    end;
+  end;
+
+  min := TBigInteger.Two;
+  m := dhParams.m;
+  if (m <> 0) then
+  begin
+    min := TBigInteger.One.ShiftLeft(m - 1);
+  end;
+
+  q := dhParams.q;
+  if (not(q.IsInitialized)) then
+  begin
+    q := dhParams.P;
+  end;
+  max := q.Subtract(TBigInteger.Two);
+
+  minWeight := TBits.Asr32(max.BitLength, 2);
+
+  while True do
+  begin
+    x := TBigIntegers.CreateRandomInRange(min, max, random);
+    if (TWNafUtilities.GetNafWeight(x) >= minWeight) then
+    begin
+      Result := x;
+      Exit;
+    end;
+  end;
+end;
+
+function TDHKeyGeneratorHelper.CalculatePublic(const dhParams: IDHParameters;
+  const x: TBigInteger): TBigInteger;
+begin
+  Result := dhParams.G.ModPow(x, dhParams.P);
+end;
+
+class constructor TDHKeyGeneratorHelper.DHKeyGeneratorHelper;
+begin
+  TDHKeyGeneratorHelper.Boot();
+end;
+
+class function TDHKeyGeneratorHelper.GetInstance: IDHKeyGeneratorHelper;
+begin
+  Result := FInstance;
+end;
+
+end.

+ 104 - 0
CryptoLib/src/Crypto/Generators/ClpDHKeyPairGenerator.pas

@@ -0,0 +1,104 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHKeyPairGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHParameters,
+  ClpIDHKeyPairGenerator,
+  ClpDHPublicKeyParameters,
+  ClpIDHPublicKeyParameters,
+  ClpDHPrivateKeyParameters,
+  ClpIDHPrivateKeyParameters,
+  ClpAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIKeyGenerationParameters,
+  ClpIDHKeyGenerationParameters,
+  ClpDHKeyGeneratorHelper,
+  ClpIDHKeyGeneratorHelper,
+  ClpIAsymmetricCipherKeyPairGenerator,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SParametersCannotBeNil = '"parameters" Cannot Be Nil';
+
+type
+
+  /// <summary>
+  /// <para>
+  /// a Diffie-Hellman key pair generator.
+  /// </para>
+  /// <para>
+  /// This generates keys consistent for use in the MTI/A0 key agreement
+  /// protocol as described in "Handbook of Applied Cryptography", Pages
+  /// 516-519.
+  /// </para>
+  /// </summary>
+  TDHKeyPairGenerator = class sealed(TInterfacedObject,
+    IAsymmetricCipherKeyPairGenerator, IDHKeyPairGenerator)
+
+  strict private
+
+  var
+    Fparam: IDHKeyGenerationParameters;
+
+  public
+
+    procedure Init(const parameters: IKeyGenerationParameters);
+
+    function GenerateKeyPair(): IAsymmetricCipherKeyPair;
+
+  end;
+
+implementation
+
+{ TDHKeyPairGenerator }
+
+function TDHKeyPairGenerator.GenerateKeyPair: IAsymmetricCipherKeyPair;
+var
+  dhp: IDHParameters;
+  helper: IDHKeyGeneratorHelper;
+  x, y: TBigInteger;
+begin
+
+  helper := TDHKeyGeneratorHelper.Instance;
+  dhp := Fparam.parameters;
+
+  x := helper.CalculatePrivate(dhp, Fparam.Random);
+  y := helper.CalculatePublic(dhp, x);
+
+  result := TAsymmetricCipherKeyPair.Create(TDHPublicKeyParameters.Create(y,
+    dhp) as IDHPublicKeyParameters, TDHPrivateKeyParameters.Create(x, dhp)
+    as IDHPrivateKeyParameters);
+end;
+
+procedure TDHKeyPairGenerator.Init(const parameters: IKeyGenerationParameters);
+begin
+  if (parameters = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SParametersCannotBeNil);
+  end;
+
+  Fparam := parameters as IDHKeyGenerationParameters;
+end;
+
+end.

+ 88 - 0
CryptoLib/src/Crypto/Generators/ClpDHParametersGenerator.pas

@@ -0,0 +1,88 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHParametersGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpDHParameters,
+  ClpIDHParameters,
+  ClpIDHParametersGenerator,
+  ClpDHParametersHelper,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+type
+  TDHParametersGenerator = class(TInterfacedObject, IDHParametersGenerator)
+
+  strict private
+  var
+    Fcertainty, Fsize: Int32;
+    Frandom: ISecureRandom;
+
+  public
+
+    procedure Init(size, certainty: Int32; const random: ISecureRandom);
+
+    /// <summary>
+    /// <para>
+    /// which Generates the p and g values from the given parameters,
+    /// returning the DHParameters object.
+    /// </para>
+    /// <para>
+    /// Note: can take a while...
+    /// </para>
+    /// </summary>
+    function GenerateParameters(): IDHParameters; virtual;
+
+  end;
+
+implementation
+
+{ TDHParametersGenerator }
+
+function TDHParametersGenerator.GenerateParameters: IDHParameters;
+var
+  safePrimes: TCryptoLibGenericArray<TBigInteger>;
+  p, q, g: TBigInteger;
+begin
+  //
+  // find a safe prime p where p = 2*q + 1, where p and q are prime.
+  //
+  safePrimes := TDHParametersHelper.GenerateSafePrimes(Fsize,
+    Fcertainty, Frandom);
+
+  p := safePrimes[0];
+  q := safePrimes[1];
+  g := TDHParametersHelper.SelectGenerator(p, q, Frandom);
+
+  result := TDHParameters.Create(p, g, q, TBigInteger.Two, Nil);
+end;
+
+procedure TDHParametersGenerator.Init(size, certainty: Int32;
+  const random: ISecureRandom);
+begin
+  Fsize := size;
+  Fcertainty := certainty;
+  Frandom := random;
+end;
+
+end.

+ 270 - 0
CryptoLib/src/Crypto/Generators/ClpDHParametersHelper.pas

@@ -0,0 +1,270 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHParametersHelper;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpBigInteger,
+  ClpBigIntegers,
+  ClpECAlgorithms,
+  ClpBits,
+  ClpCryptoLibTypes;
+
+type
+  TDHParametersHelper = class sealed(TObject)
+
+  strict private
+  class var
+
+    FSix: TBigInteger;
+    FPrimeProducts: TCryptoLibInt32Array;
+    FPrimeLists: TCryptoLibMatrixInt32Array;
+    FBigPrimeProducts: TCryptoLibGenericArray<TBigInteger>;
+    FIsBooted: Boolean;
+
+    class function ConstructBigPrimeProducts(const primeProducts
+      : TCryptoLibInt32Array): TCryptoLibGenericArray<TBigInteger>; static;
+
+    class procedure Boot(); static;
+
+    class constructor DHParametersHelper();
+
+  public
+
+    /// <summary>
+    /// <para>
+    /// Finds a pair of prime BigInteger's {p, q: p = 2q + 1}
+    /// </para>
+    /// <para>
+    /// (see: Handbook of Applied Cryptography 4.86)
+    /// </para>
+    /// </summary>
+    class function GenerateSafePrimes(size, certainty: Int32;
+      const random: ISecureRandom): TCryptoLibGenericArray<TBigInteger>; static;
+
+{$IFNDEF _FIXINSIGHT_}
+    /// <summary>
+    /// <para>
+    /// Select a high order element of the multiplicative group Zp*
+    /// </para>
+    /// <para>
+    /// p and q must be s.t. p = 2*q + 1, where p and q are prime (see
+    /// generateSafePrimes)
+    /// </para>
+    /// </summary>
+    class function SelectGenerator(const p, q: TBigInteger;
+      const random: ISecureRandom): TBigInteger; static;
+{$ENDIF}
+  end;
+
+implementation
+
+{ TDHParametersHelper }
+
+class procedure TDHParametersHelper.Boot;
+begin
+  if not FIsBooted then
+  begin
+    FSix := TBigInteger.ValueOf(6);
+
+    FPrimeLists := TBigInteger.primeLists;
+    FPrimeProducts := TBigInteger.primeProducts;
+    FBigPrimeProducts := ConstructBigPrimeProducts(FPrimeProducts);
+
+    FIsBooted := True;
+  end;
+end;
+
+class constructor TDHParametersHelper.DHParametersHelper;
+begin
+  TDHParametersHelper.Boot;
+end;
+
+class function TDHParametersHelper.ConstructBigPrimeProducts(const primeProducts
+  : TCryptoLibInt32Array): TCryptoLibGenericArray<TBigInteger>;
+var
+  bpp: TCryptoLibGenericArray<TBigInteger>;
+  i: Int32;
+begin
+  System.SetLength(bpp, System.Length(FPrimeProducts));
+
+  for i := 0 to System.Pred(System.Length(bpp)) do
+  begin
+    bpp[i] := TBigInteger.ValueOf(primeProducts[i]);
+  end;
+
+  result := bpp;
+end;
+
+class function TDHParametersHelper.GenerateSafePrimes(size, certainty: Int32;
+  const random: ISecureRandom): TCryptoLibGenericArray<TBigInteger>;
+var
+  p, q: TBigInteger;
+  qLength, minWeight, i, test, rem3, diff, j, prime, qRem: Int32;
+  retryFlag: Boolean;
+  LPrimeList: TCryptoLibInt32Array;
+begin
+  retryFlag := False;
+  qLength := size - 1;
+  minWeight := TBits.Asr32(size, 2);
+
+  if (size <= 32) then
+  begin
+    while True do
+
+    begin
+      q := TBigInteger.Create(qLength, 2, random);
+
+      p := q.ShiftLeft(1).Add(TBigInteger.One);
+
+      if (not p.IsProbablePrime(certainty, True)) then
+      begin
+        continue;
+      end;
+
+      if ((certainty > 2) and (not(q.IsProbablePrime(certainty, True)))) then
+      begin
+        continue;
+      end;
+
+      break;
+    end;
+  end
+  else
+  begin
+    while True do
+    begin
+      q := TBigInteger.Create(qLength, 0, random);
+
+      i := 0;
+      while i < System.Length(FPrimeLists) do
+      begin
+        test := q.Remainder(FBigPrimeProducts[i]).Int32Value;
+
+        if (i = 0) then
+        begin
+          rem3 := test mod 3;
+          if (rem3 <> 2) then
+          begin
+            diff := (2 * rem3) + 2;
+            q := q.Add(TBigInteger.ValueOf(diff));
+            test := (test + diff) mod FPrimeProducts[i];
+          end;
+        end;
+
+        LPrimeList := FPrimeLists[i];
+        for j := 0 to System.Pred(System.Length(LPrimeList)) do
+        begin
+          prime := LPrimeList[j];
+          qRem := test mod prime;
+          if ((qRem = 0) or (qRem = TBits.Asr32(prime, 1))) then
+          begin
+            q := q.Add(FSix);
+            retryFlag := True;
+            break;
+          end;
+        end;
+
+        if retryFlag then
+        begin
+          i := 0;
+          retryFlag := False;
+        end
+        else
+        begin
+          System.Inc(i);
+        end;
+
+      end;
+
+      if (q.BitLength <> qLength) then
+      begin
+        continue;
+      end;
+
+      if (not(q.RabinMillerTest(2, random, True))) then
+      begin
+        continue;
+      end;
+
+      p := q.ShiftLeft(1).Add(TBigInteger.One);
+
+      if (not(p.RabinMillerTest(certainty, random, True))) then
+      begin
+        continue;
+      end;
+
+      if ((certainty > 2) and (not q.RabinMillerTest(certainty - 2, random,
+        True))) then
+      begin
+        continue;
+      end;
+
+      (*
+        * Require a minimum weight of the NAF representation, since low-weight primes may be
+        * weak against a version of the number-field-sieve for the discrete-logarithm-problem.
+        *
+        * See "The number field sieve for integers of low weight", Oliver Schirokauer.
+      *)
+      if (TWNafUtilities.GetNafWeight(p) < minWeight) then
+      begin
+        continue;
+      end;
+
+      break;
+    end;
+  end;
+
+  result := TCryptoLibGenericArray<TBigInteger>.Create(p, q);
+end;
+
+{$IFNDEF _FIXINSIGHT_}
+
+class function TDHParametersHelper.SelectGenerator(const p, q: TBigInteger;
+  const random: ISecureRandom): TBigInteger;
+var
+  g, h, pMinusTwo: TBigInteger;
+  // CompareResOne, CompareResTwo: Boolean;
+begin
+  pMinusTwo := p.Subtract(TBigInteger.Two);
+
+
+  // (see: Handbook of Applied Cryptography 4.80)
+  //
+  // repeat
+  // g := TBigIntegers.CreateRandomInRange(TBigInteger.Two, pMinusTwo, random);
+  // CompareResOne := g.ModPow(TBigInteger.Two, p).Equals(TBigInteger.One);
+  // CompareResTwo := g.ModPow(q, p).Equals(TBigInteger.One);
+  // until ((not CompareResOne) and (not CompareResTwo));
+
+  // RFC 2631 2.2.1.2 (and see: Handbook of Applied Cryptography 4.81)
+
+  repeat
+    h := TBigIntegers.CreateRandomInRange(TBigInteger.Two, pMinusTwo, random);
+    g := h.ModPow(TBigInteger.Two, p);
+  until ((not g.Equals(TBigInteger.One)));
+
+  result := g;
+end;
+{$ENDIF}
+
+end.

+ 78 - 0
CryptoLib/src/Crypto/Parameters/ClpDHKeyGenerationParameters.pas

@@ -0,0 +1,78 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHKeyGenerationParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpIDHParameters,
+  ClpIDHKeyGenerationParameters,
+  ClpKeyGenerationParameters;
+
+type
+  TDHKeyGenerationParameters = class sealed(TKeyGenerationParameters,
+    IDHKeyGenerationParameters)
+  strict private
+  var
+    Fparameters: IDHParameters;
+
+    function GetParameters: IDHParameters; inline;
+
+    class function GetStrengthLocal(const parameters: IDHParameters): Int32;
+      static; inline;
+
+  public
+    constructor Create(const random: ISecureRandom;
+      const parameters: IDHParameters);
+
+    property parameters: IDHParameters read GetParameters;
+  end;
+
+implementation
+
+{ TDHKeyGenerationParameters }
+
+function TDHKeyGenerationParameters.GetParameters: IDHParameters;
+begin
+  result := Fparameters;
+end;
+
+class function TDHKeyGenerationParameters.GetStrengthLocal(const parameters
+  : IDHParameters): Int32;
+begin
+  if parameters.L <> 0 then
+  begin
+    result := parameters.L;
+  end
+  else
+  begin
+    result := parameters.P.BitLength;
+  end;
+end;
+
+constructor TDHKeyGenerationParameters.Create(const random: ISecureRandom;
+  const parameters: IDHParameters);
+begin
+  Inherited Create(random, GetStrengthLocal(parameters));
+  Fparameters := parameters;
+end;
+
+end.

+ 115 - 0
CryptoLib/src/Crypto/Parameters/ClpDHKeyParameters.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 ClpDHKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHParameters,
+  ClpIDHKeyParameters,
+  ClpPkcsObjectIdentifiers,
+  ClpIAsn1Objects,
+  ClpAsymmetricKeyParameter;
+
+type
+  TDHKeyParameters = class abstract(TAsymmetricKeyParameter, IDHKeyParameters)
+
+  strict private
+  var
+    Fparameters: IDHParameters;
+    FalgorithmOid: IDerObjectIdentifier;
+  strict protected
+    function GetParameters: IDHParameters;
+    function GetAlgorithmOid: IDerObjectIdentifier;
+
+    constructor Create(isPrivate: Boolean;
+      const parameters: IDHParameters); overload;
+
+    constructor Create(isPrivate: Boolean; const parameters: IDHParameters;
+      const algorithmOid: IDerObjectIdentifier); overload;
+
+  public
+    function Equals(const other: IDHKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+    property parameters: IDHParameters read GetParameters;
+    property algorithmOid: IDerObjectIdentifier read GetAlgorithmOid;
+
+  end;
+
+implementation
+
+{ TDHKeyParameters }
+
+function TDHKeyParameters.GetParameters: IDHParameters;
+begin
+  result := Fparameters;
+end;
+
+function TDHKeyParameters.GetAlgorithmOid: IDerObjectIdentifier;
+begin
+  result := FalgorithmOid;
+end;
+
+constructor TDHKeyParameters.Create(isPrivate: Boolean;
+  const parameters: IDHParameters);
+begin
+  Create(isPrivate, parameters, TPkcsObjectIdentifiers.DhKeyAgreement);
+end;
+
+constructor TDHKeyParameters.Create(isPrivate: Boolean;
+  const parameters: IDHParameters; const algorithmOid: IDerObjectIdentifier);
+begin
+  Inherited Create(isPrivate);
+  // TODO Should we allow parameters to be null?
+  Fparameters := parameters;
+  FalgorithmOid := algorithmOid;
+end;
+
+function TDHKeyParameters.Equals(const other: IDHKeyParameters): Boolean;
+begin
+  if other = Nil then
+  begin
+    result := False;
+    Exit;
+  end;
+  if ((Self as IDHKeyParameters) = other) then
+  begin
+    result := True;
+    Exit;
+  end;
+
+  result := parameters.Equals(other.parameters) and (Inherited Equals(other));
+end;
+
+function TDHKeyParameters.GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := Inherited GetHashCode();
+
+  if (parameters <> Nil) then
+  begin
+    result := result xor parameters.GetHashCode();
+  end;
+end;
+
+end.

+ 266 - 0
CryptoLib/src/Crypto/Parameters/ClpDHParameters.pas

@@ -0,0 +1,266 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Math,
+  ClpICipherParameters,
+  ClpIDHParameters,
+  ClpIDHValidationParameters,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SPUnInitialized = '"P" Cannot Be Uninitialized';
+  SGUnInitialized = '"G" Cannot Be Uninitialized';
+  SMustBeOddPrime = 'Field must be an Odd Prime, "P"';
+  SInvalidGeneratorRange = 'Generator must in the Range [2, p - 2], "G"';
+  SQTooBigToBeAFactor = 'Q too Big to be a Factor of (P - 1), "Q"';
+  SMTooBig = 'M value must be < BitLength of P, "M"';
+  SLErrorOne = 'when L value specified, it must be less than bitlength(P), "L"';
+  SLErrorTwo = 'when L value specified, it may not be less than m value, "L"';
+  SInvalidSubGroupFactor = 'Subgroup factor must be >= 2, "j"';
+
+type
+  TDHParameters = class(TInterfacedObject, ICipherParameters, IDHParameters)
+
+  strict private
+
+  const
+    DefaultMinimumLength = Int32(160);
+
+  var
+    Fp, Fq, Fg, Fj: TBigInteger;
+    Fm, Fl: Int32;
+    Fvalidation: IDHValidationParameters;
+
+    function GetG: TBigInteger; inline;
+    function GetP: TBigInteger; inline;
+    function GetQ: TBigInteger; inline;
+    function GetJ: TBigInteger; inline;
+    function GetM: Int32; inline;
+    function GetL: Int32; inline;
+    function GetValidationParameters: IDHValidationParameters; inline;
+
+    class function GetDefaultMParam(lParam: Int32): Int32; static; inline;
+
+  public
+
+    constructor Create(const p, g: TBigInteger); overload;
+
+    constructor Create(const p, g, q: TBigInteger); overload;
+
+    constructor Create(const p, g, q: TBigInteger; l: Int32); overload;
+
+    constructor Create(const p, g, q: TBigInteger; m, l: Int32); overload;
+
+    constructor Create(const p, g, q, j: TBigInteger;
+      const validation: IDHValidationParameters); overload;
+
+    constructor Create(const p, g, q: TBigInteger; m, l: Int32;
+      const j: TBigInteger; const validation: IDHValidationParameters);
+      overload;
+
+    function Equals(const other: IDHParameters): Boolean; reintroduce;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+    property p: TBigInteger read GetP;
+    property q: TBigInteger read GetQ;
+    property g: TBigInteger read GetG;
+    property j: TBigInteger read GetJ;
+    /// <summary>The minimum bitlength of the private value.</summary>
+    property m: Int32 read GetM;
+    /// <summary>The bitlength of the private value.</summary>
+    property l: Int32 read GetL;
+    property ValidationParameters: IDHValidationParameters
+      read GetValidationParameters;
+
+  end;
+
+implementation
+
+{ TDHParameters }
+
+function TDHParameters.GetL: Int32;
+begin
+  result := Fl;
+end;
+
+function TDHParameters.GetM: Int32;
+begin
+  result := Fm;
+end;
+
+function TDHParameters.GetJ: TBigInteger;
+begin
+  result := Fj;
+end;
+
+function TDHParameters.GetP: TBigInteger;
+begin
+  result := Fp;
+end;
+
+function TDHParameters.GetQ: TBigInteger;
+begin
+  result := Fq;
+end;
+
+function TDHParameters.GetG: TBigInteger;
+begin
+  result := Fg;
+end;
+
+class function TDHParameters.GetDefaultMParam(lParam: Int32): Int32;
+begin
+  if (lParam = 0) then
+  begin
+    result := DefaultMinimumLength;
+    Exit;
+  end;
+
+  result := Min(lParam, DefaultMinimumLength);
+end;
+
+constructor TDHParameters.Create(const p, g: TBigInteger);
+begin
+  Create(p, g, Default (TBigInteger), 0);
+end;
+
+constructor TDHParameters.Create(const p, g, q: TBigInteger);
+begin
+  Create(p, g, q, 0);
+end;
+
+constructor TDHParameters.Create(const p, g, q: TBigInteger; l: Int32);
+begin
+  Create(p, g, q, GetDefaultMParam(l), l, Default (TBigInteger), Nil);
+end;
+
+constructor TDHParameters.Create(const p, g, q: TBigInteger; m, l: Int32);
+begin
+  Create(p, g, q, m, l, Default (TBigInteger), Nil);
+end;
+
+constructor TDHParameters.Create(const p, g, q, j: TBigInteger;
+  const validation: IDHValidationParameters);
+begin
+  Create(p, g, q, DefaultMinimumLength, 0, j, validation)
+end;
+
+constructor TDHParameters.Create(const p, g, q: TBigInteger; m, l: Int32;
+  const j: TBigInteger; const validation: IDHValidationParameters);
+begin
+  Inherited Create();
+  if (not(p.IsInitialized)) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SPUnInitialized);
+  end;
+
+  if (not(g.IsInitialized)) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SGUnInitialized);
+  end;
+
+  if (not p.TestBit(0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SMustBeOddPrime);
+  end;
+
+  if ((g.CompareTo(TBigInteger.Two) < 0) or
+    (g.CompareTo(p.Subtract(TBigInteger.Two)) > 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidGeneratorRange);
+  end;
+
+  if ((q.IsInitialized) and (q.BitLength >= p.BitLength)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SQTooBigToBeAFactor);
+  end;
+
+  if (m >= p.BitLength) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SMTooBig);
+  end;
+
+  if (l <> 0) then
+  begin
+
+    if (l >= p.BitLength) then
+    begin
+      raise EArgumentCryptoLibException.CreateRes(@SLErrorOne);
+    end;
+    if (l < m) then
+    begin
+      raise EArgumentCryptoLibException.CreateRes(@SLErrorTwo);
+    end;
+  end;
+
+  if ((j.IsInitialized) and (j.CompareTo(TBigInteger.Two) < 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidSubGroupFactor);
+  end;
+
+  // TODO If q, j both provided, validate p = jq + 1 ?
+
+  Fp := p;
+  Fg := g;
+  Fq := q;
+  Fm := m;
+  Fl := l;
+  Fj := j;
+  Fvalidation := validation;
+end;
+
+function TDHParameters.Equals(const other: IDHParameters): Boolean;
+begin
+  if other = Nil then
+  begin
+    result := False;
+    Exit;
+  end;
+  if ((Self as IDHParameters) = other) then
+  begin
+    result := True;
+    Exit;
+  end;
+  result := p.Equals(other.p) and q.Equals(other.q) and g.Equals(other.g);
+end;
+
+function TDHParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := p.GetHashCode() xor g.GetHashCode();
+
+  if Fq.IsInitialized then
+  begin
+    result := result xor q.GetHashCode();
+  end;
+end;
+
+function TDHParameters.GetValidationParameters: IDHValidationParameters;
+begin
+  result := Fvalidation;
+end;
+
+end.

+ 117 - 0
CryptoLib/src/Crypto/Parameters/ClpDHPrivateKeyParameters.pas

@@ -0,0 +1,117 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHPrivateKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHParameters,
+  ClpIDHPrivateKeyParameters,
+  ClpDHKeyParameters,
+  ClpIAsn1Objects,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SXUnInitialized = '"X" Cannot Be Uninitialized';
+
+type
+  TDHPrivateKeyParameters = class sealed(TDHKeyParameters,
+    IDHPrivateKeyParameters)
+
+  strict private
+  var
+    Fx: TBigInteger;
+
+    function GetX: TBigInteger; inline;
+
+    class function Validate(const x: TBigInteger): TBigInteger; static; inline;
+
+  public
+    constructor Create(const x: TBigInteger;
+      const parameters: IDHParameters); overload;
+
+    constructor Create(const x: TBigInteger; const parameters: IDHParameters;
+      const algorithmOid: IDerObjectIdentifier); overload;
+
+    function Equals(const other: IDHPrivateKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+    property x: TBigInteger read GetX;
+  end;
+
+implementation
+
+{ TDHPrivateKeyParameters }
+
+function TDHPrivateKeyParameters.GetX: TBigInteger;
+begin
+  result := Fx;
+end;
+
+class function TDHPrivateKeyParameters.Validate(const x: TBigInteger)
+  : TBigInteger;
+begin
+  if (not(x.IsInitialized)) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SXUnInitialized);
+  end;
+  result := x;
+end;
+
+constructor TDHPrivateKeyParameters.Create(const x: TBigInteger;
+  const parameters: IDHParameters);
+begin
+  Inherited Create(true, parameters);
+  Fx := Validate(x);
+end;
+
+constructor TDHPrivateKeyParameters.Create(const x: TBigInteger;
+  const parameters: IDHParameters; const algorithmOid: IDerObjectIdentifier);
+begin
+  Inherited Create(true, parameters, algorithmOid);
+  Fx := Validate(x);
+end;
+
+function TDHPrivateKeyParameters.Equals(const other
+  : IDHPrivateKeyParameters): Boolean;
+begin
+  if other = Nil then
+  begin
+    result := False;
+    Exit;
+  end;
+  if ((Self as IDHPrivateKeyParameters) = other) then
+  begin
+    result := true;
+    Exit;
+  end;
+  result := (x.Equals(other.x)) and (Inherited Equals(other));
+end;
+
+function TDHPrivateKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := x.GetHashCode() xor (Inherited GetHashCode());
+end;
+
+end.

+ 135 - 0
CryptoLib/src/Crypto/Parameters/ClpDHPublicKeyParameters.pas

@@ -0,0 +1,135 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHPublicKeyParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHParameters,
+  ClpIDHPublicKeyParameters,
+  ClpIAsn1Objects,
+  ClpDHKeyParameters,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SYUnInitialized = '"Y" Cannot Be Uninitialized';
+  SInvalidDHPublicKey = 'Invalid DH public key "Y"';
+  SInvalidYInCorrectGroup = '"Y" Value Does Not Appear To Be In Correct Group';
+
+type
+  TDHPublicKeyParameters = class sealed(TDHKeyParameters,
+    IDHPublicKeyParameters)
+
+  strict private
+  var
+    Fy: TBigInteger;
+
+    class function Validate(const y: TBigInteger; const dhParams: IDHParameters)
+      : TBigInteger; static; inline;
+
+    function GetY: TBigInteger; inline;
+
+  public
+    constructor Create(const y: TBigInteger;
+      const parameters: IDHParameters); overload;
+
+    constructor Create(const y: TBigInteger; const parameters: IDHParameters;
+      const algorithmOid: IDerObjectIdentifier); overload;
+
+    function Equals(const other: IDHPublicKeyParameters): Boolean;
+      reintroduce; overload;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+    property y: TBigInteger read GetY;
+  end;
+
+implementation
+
+{ TDHPublicKeyParameters }
+
+function TDHPublicKeyParameters.GetY: TBigInteger;
+begin
+  result := Fy;
+end;
+
+class function TDHPublicKeyParameters.Validate(const y: TBigInteger;
+  const dhParams: IDHParameters): TBigInteger;
+begin
+  if (not(y.IsInitialized)) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SYUnInitialized);
+  end;
+
+  // TLS check
+  if ((y.CompareTo(TBigInteger.Two) < 0) or
+    (y.CompareTo(dhParams.P.Subtract(TBigInteger.Two)) > 0)) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidDHPublicKey);
+  end;
+
+  // we can't validate without Q.
+  if ((dhParams.Q.IsInitialized) and
+    (not(y.ModPow(dhParams.Q, dhParams.P).Equals(TBigInteger.One)))) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidYInCorrectGroup);
+  end;
+
+  result := y;
+end;
+
+constructor TDHPublicKeyParameters.Create(const y: TBigInteger;
+  const parameters: IDHParameters);
+begin
+  Inherited Create(false, parameters);
+  Fy := Validate(y, parameters);
+end;
+
+constructor TDHPublicKeyParameters.Create(const y: TBigInteger;
+  const parameters: IDHParameters; const algorithmOid: IDerObjectIdentifier);
+begin
+  Inherited Create(false, parameters, algorithmOid);
+  Fy := Validate(y, parameters);
+end;
+
+function TDHPublicKeyParameters.Equals(const other
+  : IDHPublicKeyParameters): Boolean;
+begin
+  if other = Nil then
+  begin
+    result := false;
+    Exit;
+  end;
+  if ((Self as IDHPublicKeyParameters) = other) then
+  begin
+    result := True;
+    Exit;
+  end;
+  result := (y.Equals(other.y)) and (Inherited Equals(other));
+end;
+
+function TDHPublicKeyParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := y.GetHashCode() xor (Inherited GetHashCode());
+end;
+
+end.

+ 103 - 0
CryptoLib/src/Crypto/Parameters/ClpDHValidationParameters.pas

@@ -0,0 +1,103 @@
+{ *********************************************************************************** }
+{ *                              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 ClpDHValidationParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHValidationParameters,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SSeedNil = '"Seed" Cannot Be Nil';
+
+type
+  TDHValidationParameters = class(TInterfacedObject, IDHValidationParameters)
+  strict private
+  var
+    Fseed: TCryptoLibByteArray;
+    Fcounter: Int32;
+
+    function GetCounter: Int32; virtual;
+    function GetSeed: TCryptoLibByteArray; virtual;
+
+  public
+    constructor Create(const seed: TCryptoLibByteArray; counter: Int32);
+
+    function Equals(const other: IDHValidationParameters): Boolean; reintroduce;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}override;
+
+    property counter: Int32 read GetCounter;
+    property seed: TCryptoLibByteArray read GetSeed;
+  end;
+
+implementation
+
+{ TDHValidationParameters }
+
+constructor TDHValidationParameters.Create(const seed: TCryptoLibByteArray;
+  counter: Int32);
+begin
+  Inherited Create();
+  if (seed = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SSeedNil);
+  end;
+
+  Fseed := System.Copy(seed);
+  Fcounter := counter;
+end;
+
+function TDHValidationParameters.Equals(const other
+  : IDHValidationParameters): Boolean;
+begin
+  if other = Nil then
+  begin
+    result := False;
+    Exit;
+  end;
+  if ((Self as IDHValidationParameters) = other) then
+  begin
+    result := True;
+    Exit;
+  end;
+  result := (counter = other.counter) and TArrayUtils.AreEqual(seed,
+    other.seed);
+end;
+
+function TDHValidationParameters.GetCounter: Int32;
+begin
+  result := Fcounter;
+end;
+
+function TDHValidationParameters.GetHashCode: {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+begin
+  result := counter xor TArrayUtils.GetArrayHashCode(seed);
+end;
+
+function TDHValidationParameters.GetSeed: TCryptoLibByteArray;
+begin
+  result := System.Copy(Fseed);
+end;
+
+end.

+ 73 - 0
CryptoLib/src/Interfaces/ClpIDHAgreement.pas

@@ -0,0 +1,73 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHAgreement;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIDHPublicKeyParameters,
+  ClpICipherParameters;
+
+type
+
+  /// <summary>
+  /// <para>
+  /// a Diffie-Hellman key exchange engine.
+  /// </para>
+  /// <para>
+  /// note: This uses MTI/A0 key agreement in order to make the key
+  /// agreement secure against passive attacks. If you're doing
+  /// Diffie-Hellman and both parties have long term public keys you
+  /// should look at using this. For further information have a look at
+  /// RFC 2631.
+  /// </para>
+  /// <para>
+  /// It's possible to extend this to more than two parties as well, for
+  /// the moment that is left as an exercise for the reader.
+  /// </para>
+  /// </summary>
+  IDHAgreement = interface(IInterface)
+
+    ['{2FD6DE87-B4E3-4184-874B-F51E559235D2}']
+
+    /// <summary>
+    /// initialise the agreement engine.
+    /// </summary>
+    procedure Init(const parameters: ICipherParameters);
+
+    /// <summary>
+    /// calculate our initial message.
+    /// </summary>
+    function CalculateMessage(): TBigInteger;
+
+    /// <summary>
+    /// given a message from a given party and the corresponding public key
+    /// calculate the next message in the agreement sequence. In this case
+    /// this will represent the shared secret.
+    /// </summary>
+    function CalculateAgreement(const pub: IDHPublicKeyParameters;
+      const &message: TBigInteger): TBigInteger;
+
+  end;
+
+implementation
+
+end.

+ 46 - 0
CryptoLib/src/Interfaces/ClpIDHBasicAgreement.pas

@@ -0,0 +1,46 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHBasicAgreement;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBasicAgreement;
+
+type
+  /// <summary>
+  /// <para>
+  /// a Diffie-Hellman key agreement class.
+  /// </para>
+  /// <para>
+  /// note: This is only the basic algorithm, it doesn't take advantage
+  /// of long term public keys if they are available. See the DHAgreement
+  /// class for a "better" implementation.
+  /// </para>
+  /// </summary>
+  IDHBasicAgreement = interface(IBasicAgreement)
+
+    ['{913FB2D8-1DDB-4E68-8C67-2BDD796BE3A1}']
+
+  end;
+
+implementation
+
+end.

+ 34 - 0
CryptoLib/src/Interfaces/ClpIDHBasicKeyPairGenerator.pas

@@ -0,0 +1,34 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHBasicKeyPairGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  IDHBasicKeyPairGenerator = interface(IAsymmetricCipherKeyPairGenerator)
+    ['{F8C67480-A3D5-45AC-BEB1-DA3C484844EC}']
+  end;
+
+implementation
+
+end.

+ 51 - 0
CryptoLib/src/Interfaces/ClpIDHDomainParameters.pas

@@ -0,0 +1,51 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHDomainParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHValidationParams,
+  ClpIAsn1Objects;
+
+type
+  IDHDomainParameters = interface(IAsn1Encodable)
+    ['{18288135-B71F-48B4-8595-57AAB9092FC8}']
+
+    function GetP: IDerInteger;
+    property p: IDerInteger read GetP;
+
+    function GetG: IDerInteger;
+    property g: IDerInteger read GetG;
+
+    function GetQ: IDerInteger;
+    property q: IDerInteger read GetQ;
+
+    function GetJ: IDerInteger;
+    property j: IDerInteger read GetJ;
+
+    function GetValidationParams: IDHValidationParams;
+    property validationParams: IDHValidationParams read GetValidationParams;
+
+  end;
+
+implementation
+
+end.

+ 40 - 0
CryptoLib/src/Interfaces/ClpIDHKeyGenerationParameters.pas

@@ -0,0 +1,40 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHKeyGenerationParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHParameters,
+  ClpIKeyGenerationParameters;
+
+type
+  IDHKeyGenerationParameters = interface(IKeyGenerationParameters)
+    ['{B513182A-1697-468E-A090-0E09C246BD8B}']
+
+    function GetParameters: IDHParameters;
+
+    property parameters: IDHParameters read GetParameters;
+
+  end;
+
+implementation
+
+end.

+ 43 - 0
CryptoLib/src/Interfaces/ClpIDHKeyGeneratorHelper.pas

@@ -0,0 +1,43 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHKeyGeneratorHelper;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpBigInteger,
+  ClpIDHParameters;
+
+type
+  IDHKeyGeneratorHelper = interface(IInterface)
+    ['{D4A55B45-E354-45A8-BCB7-871D7208A855}']
+
+    function CalculatePrivate(const dhParams: IDHParameters;
+      const random: ISecureRandom): TBigInteger;
+
+    function CalculatePublic(const dhParams: IDHParameters;
+      const x: TBigInteger): TBigInteger;
+
+  end;
+
+implementation
+
+end.

+ 34 - 0
CryptoLib/src/Interfaces/ClpIDHKeyPairGenerator.pas

@@ -0,0 +1,34 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHKeyPairGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  IDHKeyPairGenerator = interface(IAsymmetricCipherKeyPairGenerator)
+    ['{016112AA-A9AD-43E3-A3AA-25428682396F}']
+  end;
+
+implementation
+
+end.

+ 44 - 0
CryptoLib/src/Interfaces/ClpIDHKeyParameters.pas

@@ -0,0 +1,44 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDHKeyParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHParameters,
+  ClpIAsn1Objects,
+  ClpIAsymmetricKeyParameter;
+
+type
+  IDHKeyParameters = interface(IAsymmetricKeyParameter)
+    ['{53834D98-B75A-4607-BA38-3CD9DE3B3CF4}']
+
+    function GetParameters: IDHParameters;
+    function GetAlgorithmOid: IDerObjectIdentifier;
+
+    function Equals(const other: IDHKeyParameters): Boolean; overload;
+    property parameters: IDHParameters read GetParameters;
+    property AlgorithmOid: IDerObjectIdentifier read GetAlgorithmOid;
+
+  end;
+
+implementation
+
+end.

+ 61 - 0
CryptoLib/src/Interfaces/ClpIDHParameters.pas

@@ -0,0 +1,61 @@
+{ *                 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 ClpIDHParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpICipherParameters,
+  ClpIDHValidationParameters,
+  ClpBigInteger;
+
+type
+  IDHParameters = interface(ICipherParameters)
+    ['{6609D678-F9FB-48FD-A22F-52AFAE9EA5F8}']
+
+    function GetG: TBigInteger;
+    property g: TBigInteger read GetG;
+
+    function GetP: TBigInteger;
+    property p: TBigInteger read GetP;
+
+    function GetQ: TBigInteger;
+    property q: TBigInteger read GetQ;
+
+    function GetJ: TBigInteger;
+    property J: TBigInteger read GetJ;
+
+    function GetM: Int32;
+    /// <summary>The minimum bitlength of the private value.</summary>
+    property m: Int32 read GetM;
+
+    function GetL: Int32;
+    /// <summary>The bitlength of the private value.</summary>
+    property l: Int32 read GetL;
+
+    function GetValidationParameters: IDHValidationParameters;
+    property ValidationParameters: IDHValidationParameters
+      read GetValidationParameters;
+
+    function Equals(const other: IDHParameters): Boolean;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+  end;
+
+implementation
+
+end.

+ 49 - 0
CryptoLib/src/Interfaces/ClpIDHParametersGenerator.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 ClpIDHParametersGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpISecureRandom,
+  ClpIDHParameters;
+
+type
+  IDHParametersGenerator = interface(IInterface)
+    ['{ECE2C3CF-4DA4-450B-BB37-2C100BC72FF6}']
+
+    procedure Init(size, certainty: Int32; const random: ISecureRandom);
+
+    /// <summary>
+    /// <para>
+    /// which Generates the p and g values from the given parameters,
+    /// returning the DHParameters object.
+    /// </para>
+    /// <para>
+    /// Note: can take a while...
+    /// </para>
+    /// </summary>
+    function GenerateParameters(): IDHParameters;
+
+  end;
+
+implementation
+
+end.

+ 41 - 0
CryptoLib/src/Interfaces/ClpIDHPrivateKeyParameters.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 ClpIDHPrivateKeyParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHKeyParameters,
+  ClpBigInteger;
+
+type
+  IDHPrivateKeyParameters = interface(IDHKeyParameters)
+    ['{946AD4C3-6B77-46F5-871C-C8958DD371E0}']
+
+    function GetX: TBigInteger;
+
+    function Equals(const other: IDHPrivateKeyParameters): Boolean; overload;
+    property X: TBigInteger read GetX;
+
+  end;
+
+implementation
+
+end.

+ 38 - 0
CryptoLib/src/Interfaces/ClpIDHPublicKeyParameters.pas

@@ -0,0 +1,38 @@
+{ *                 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 ClpIDHPublicKeyParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDHKeyParameters,
+  ClpBigInteger;
+
+type
+  IDHPublicKeyParameters = interface(IDHKeyParameters)
+    ['{F78EC20B-B591-42AB-87F3-22011F1DE05E}']
+
+    function GetY: TBigInteger;
+
+    function Equals(const other: IDHPublicKeyParameters): Boolean; overload;
+    property y: TBigInteger read GetY;
+
+  end;
+
+implementation
+
+end.

+ 40 - 0
CryptoLib/src/Interfaces/ClpIDHValidationParameters.pas

@@ -0,0 +1,40 @@
+{ *                 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 ClpIDHValidationParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpCryptoLibTypes;
+
+type
+  IDHValidationParameters = interface(IInterface)
+    ['{6F7404A7-0588-4154-8955-8C1A5C757B17}']
+
+    function GetCounter: Int32;
+    function GetSeed: TCryptoLibByteArray;
+
+    function Equals(const other: IDHValidationParameters): Boolean;
+    function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
+{$ENDIF DELPHI}
+    property counter: Int32 read GetCounter;
+    property seed: TCryptoLibByteArray read GetSeed;
+  end;
+
+implementation
+
+end.

+ 41 - 0
CryptoLib/src/Interfaces/ClpIDHValidationParams.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 ClpIDHValidationParams;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsn1Objects;
+
+type
+  IDHValidationParams = interface(IAsn1Encodable)
+    ['{A75D3486-080A-43F5-9296-9C74B7DEE7DC}']
+
+    function GetSeed: IDerBitString;
+    property Seed: IDerBitString read GetSeed;
+
+    function GetPGenCounter: IDerInteger;
+    property PGenCounter: IDerInteger read GetPGenCounter;
+
+  end;
+
+implementation
+
+end.

+ 34 - 5
CryptoLib/src/Packages/Delphi/CryptoLib4PascalPackage.dpk

@@ -120,11 +120,8 @@ contains
   ClpBlockCipherModes in '..\..\Crypto\Modes\ClpBlockCipherModes.pas',
   ClpBlockCipherModes in '..\..\Crypto\Modes\ClpBlockCipherModes.pas',
   ClpECKeyParameters in '..\..\Crypto\Parameters\ClpECKeyParameters.pas',
   ClpECKeyParameters in '..\..\Crypto\Parameters\ClpECKeyParameters.pas',
   ClpECPrivateKeyParameters in '..\..\Crypto\Parameters\ClpECPrivateKeyParameters.pas',
   ClpECPrivateKeyParameters in '..\..\Crypto\Parameters\ClpECPrivateKeyParameters.pas',
-  ClpDsaPrivateKeyParameters in '..\..\Crypto\Parameters\ClpDsaPrivateKeyParameters.pas',
-  ClpDsaPublicKeyParameters in '..\..\Crypto\Parameters\ClpDsaPublicKeyParameters.pas',
   ClpX25519KeyPairGenerator in '..\..\Crypto\Generators\ClpX25519KeyPairGenerator.pas',
   ClpX25519KeyPairGenerator in '..\..\Crypto\Generators\ClpX25519KeyPairGenerator.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
   ClpPascalCoinECIESKdfBytesGenerator in '..\..\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
-  ClpDsaKeyParameters in '..\..\Crypto\Parameters\ClpDsaKeyParameters.pas',
   ClpSpeckLegacyEngine in '..\..\Crypto\Engines\ClpSpeckLegacyEngine.pas',
   ClpSpeckLegacyEngine in '..\..\Crypto\Engines\ClpSpeckLegacyEngine.pas',
   ClpEd25519Blake2BKeyPairGenerator in '..\..\Crypto\Generators\ClpEd25519Blake2BKeyPairGenerator.pas',
   ClpEd25519Blake2BKeyPairGenerator in '..\..\Crypto\Generators\ClpEd25519Blake2BKeyPairGenerator.pas',
   ClpEd25519KeyPairGenerator in '..\..\Crypto\Generators\ClpEd25519KeyPairGenerator.pas',
   ClpEd25519KeyPairGenerator in '..\..\Crypto\Generators\ClpEd25519KeyPairGenerator.pas',
@@ -175,7 +172,6 @@ contains
   ClpRandom in '..\..\Security\ClpRandom.pas',
   ClpRandom in '..\..\Security\ClpRandom.pas',
   ClpDsaDigestSigner in '..\..\Crypto\Signers\ClpDsaDigestSigner.pas',
   ClpDsaDigestSigner in '..\..\Crypto\Signers\ClpDsaDigestSigner.pas',
   ClpEncoders in '..\..\Utils\Encoders\ClpEncoders.pas',
   ClpEncoders in '..\..\Utils\Encoders\ClpEncoders.pas',
-  ClpDsaParametersGenerator in '..\..\Crypto\Generators\ClpDsaParametersGenerator.pas',
   ClpNistNamedCurves in '..\..\Asn1\Nist\ClpNistNamedCurves.pas',
   ClpNistNamedCurves in '..\..\Asn1\Nist\ClpNistNamedCurves.pas',
   ClpMacUtilities in '..\..\Security\ClpMacUtilities.pas',
   ClpMacUtilities in '..\..\Security\ClpMacUtilities.pas',
   ClpDsaKeyPairGenerator in '..\..\Crypto\Generators\ClpDsaKeyPairGenerator.pas',
   ClpDsaKeyPairGenerator in '..\..\Crypto\Generators\ClpDsaKeyPairGenerator.pas',
@@ -373,6 +369,39 @@ contains
   ClpIArgon2ParametersGenerator in '..\..\Interfaces\ClpIArgon2ParametersGenerator.pas',
   ClpIArgon2ParametersGenerator in '..\..\Interfaces\ClpIArgon2ParametersGenerator.pas',
   ClpArgon2ParametersGenerator in '..\..\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpArgon2ParametersGenerator in '..\..\Crypto\Generators\ClpArgon2ParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\Interfaces\ClpIScryptParametersGenerator.pas',
   ClpIScryptParametersGenerator in '..\..\Interfaces\ClpIScryptParametersGenerator.pas',
-  ClpScryptParametersGenerator in '..\..\Crypto\Generators\ClpScryptParametersGenerator.pas';
+  ClpScryptParametersGenerator in '..\..\Crypto\Generators\ClpScryptParametersGenerator.pas',
+  ClpDHDomainParameters in '..\..\Asn1\X9\ClpDHDomainParameters.pas',
+  ClpDHValidationParams in '..\..\Asn1\X9\ClpDHValidationParams.pas',
+  ClpDHAgreement in '..\..\Crypto\Agreement\ClpDHAgreement.pas',
+  ClpDHBasicAgreement in '..\..\Crypto\Agreement\ClpDHBasicAgreement.pas',
+  ClpDHBasicKeyPairGenerator in '..\..\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas',
+  ClpDHKeyPairGenerator in '..\..\Crypto\Generators\ClpDHKeyPairGenerator.pas',
+  ClpDsaParametersGenerator in '..\..\Crypto\Generators\ClpDsaParametersGenerator.pas',
+  ClpDHParametersGenerator in '..\..\Crypto\Generators\ClpDHParametersGenerator.pas',
+  ClpDHKeyGeneratorHelper in '..\..\Crypto\Generators\ClpDHKeyGeneratorHelper.pas',
+  ClpDHParametersHelper in '..\..\Crypto\Generators\ClpDHParametersHelper.pas',
+  ClpDHPrivateKeyParameters in '..\..\Crypto\Parameters\ClpDHPrivateKeyParameters.pas',
+  ClpDsaPrivateKeyParameters in '..\..\Crypto\Parameters\ClpDsaPrivateKeyParameters.pas',
+  ClpDsaPublicKeyParameters in '..\..\Crypto\Parameters\ClpDsaPublicKeyParameters.pas',
+  ClpDHPublicKeyParameters in '..\..\Crypto\Parameters\ClpDHPublicKeyParameters.pas',
+  ClpDHKeyGenerationParameters in '..\..\Crypto\Parameters\ClpDHKeyGenerationParameters.pas',
+  ClpDsaKeyParameters in '..\..\Crypto\Parameters\ClpDsaKeyParameters.pas',
+  ClpDHKeyParameters in '..\..\Crypto\Parameters\ClpDHKeyParameters.pas',
+  ClpDHValidationParameters in '..\..\Crypto\Parameters\ClpDHValidationParameters.pas',
+  ClpDHParameters in '..\..\Crypto\Parameters\ClpDHParameters.pas',
+  ClpIDHAgreement in '..\..\Interfaces\ClpIDHAgreement.pas',
+  ClpIDHBasicAgreement in '..\..\Interfaces\ClpIDHBasicAgreement.pas',
+  ClpIDHBasicKeyPairGenerator in '..\..\Interfaces\ClpIDHBasicKeyPairGenerator.pas',
+  ClpIDHKeyPairGenerator in '..\..\Interfaces\ClpIDHKeyPairGenerator.pas',
+  ClpIDHPrivateKeyParameters in '..\..\Interfaces\ClpIDHPrivateKeyParameters.pas',
+  ClpIDHPublicKeyParameters in '..\..\Interfaces\ClpIDHPublicKeyParameters.pas',
+  ClpIDHParametersGenerator in '..\..\Interfaces\ClpIDHParametersGenerator.pas',
+  ClpIDHKeyGenerationParameters in '..\..\Interfaces\ClpIDHKeyGenerationParameters.pas',
+  ClpIDHParameters in '..\..\Interfaces\ClpIDHParameters.pas',
+  ClpIDHKeyGeneratorHelper in '..\..\Interfaces\ClpIDHKeyGeneratorHelper.pas',
+  ClpIDHKeyParameters in '..\..\Interfaces\ClpIDHKeyParameters.pas',
+  ClpIDHValidationParameters in '..\..\Interfaces\ClpIDHValidationParameters.pas',
+  ClpIDHDomainParameters in '..\..\Interfaces\ClpIDHDomainParameters.pas',
+  ClpIDHValidationParams in '..\..\Interfaces\ClpIDHValidationParams.pas';
 
 
 end.
 end.

+ 126 - 7
CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk

@@ -25,7 +25,7 @@
  Acknowledgements: 
  Acknowledgements: 
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
     <Version Major="3" Minor="1"/>
     <Version Major="3" Minor="1"/>
-    <Files Count="341">
+    <Files Count="370">
       <Item1>
       <Item1>
         <Filename Value="..\..\Asn1\ClpOidTokenizer.pas"/>
         <Filename Value="..\..\Asn1\ClpOidTokenizer.pas"/>
         <UnitName Value="ClpOidTokenizer"/>
         <UnitName Value="ClpOidTokenizer"/>
@@ -1392,21 +1392,140 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <Filename Value="..\..\Crypto\Generators\ClpScryptParametersGenerator.pas"/>
         <Filename Value="..\..\Crypto\Generators\ClpScryptParametersGenerator.pas"/>
         <UnitName Value="ClpScryptParametersGenerator"/>
         <UnitName Value="ClpScryptParametersGenerator"/>
       </Item341>
       </Item341>
+      <Item342>
+        <Filename Value="..\..\Interfaces\ClpIDHAgreement.pas"/>
+        <UnitName Value="ClpIDHAgreement"/>
+      </Item342>
+      <Item343>
+        <Filename Value="..\..\Interfaces\ClpIDHBasicAgreement.pas"/>
+        <UnitName Value="ClpIDHBasicAgreement"/>
+      </Item343>
+      <Item344>
+        <Filename Value="..\..\Interfaces\ClpIDHBasicKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIDHBasicKeyPairGenerator"/>
+      </Item344>
+      <Item345>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIDHKeyPairGenerator"/>
+      </Item345>
+      <Item346>
+        <Filename Value="..\..\Interfaces\ClpIDHPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpIDHPrivateKeyParameters"/>
+      </Item346>
+      <Item347>
+        <Filename Value="..\..\Interfaces\ClpIDHPublicKeyParameters.pas"/>
+        <UnitName Value="ClpIDHPublicKeyParameters"/>
+      </Item347>
+      <Item348>
+        <Filename Value="..\..\Interfaces\ClpIDHParametersGenerator.pas"/>
+        <UnitName Value="ClpIDHParametersGenerator"/>
+      </Item348>
+      <Item349>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpIDHKeyGenerationParameters"/>
+      </Item349>
+      <Item350>
+        <Filename Value="..\..\Interfaces\ClpIDHParameters.pas"/>
+        <UnitName Value="ClpIDHParameters"/>
+      </Item350>
+      <Item351>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyGeneratorHelper.pas"/>
+        <UnitName Value="ClpIDHKeyGeneratorHelper"/>
+      </Item351>
+      <Item352>
+        <Filename Value="..\..\Interfaces\ClpIDHKeyParameters.pas"/>
+        <UnitName Value="ClpIDHKeyParameters"/>
+      </Item352>
+      <Item353>
+        <Filename Value="..\..\Interfaces\ClpIDHValidationParameters.pas"/>
+        <UnitName Value="ClpIDHValidationParameters"/>
+      </Item353>
+      <Item354>
+        <Filename Value="..\..\Interfaces\ClpIDHDomainParameters.pas"/>
+        <UnitName Value="ClpIDHDomainParameters"/>
+      </Item354>
+      <Item355>
+        <Filename Value="..\..\Interfaces\ClpIDHValidationParams.pas"/>
+        <UnitName Value="ClpIDHValidationParams"/>
+      </Item355>
+      <Item356>
+        <Filename Value="..\..\Crypto\Agreement\ClpDHAgreement.pas"/>
+        <UnitName Value="ClpDHAgreement"/>
+      </Item356>
+      <Item357>
+        <Filename Value="..\..\Crypto\Agreement\ClpDHBasicAgreement.pas"/>
+        <UnitName Value="ClpDHBasicAgreement"/>
+      </Item357>
+      <Item358>
+        <Filename Value="..\..\Crypto\Generators\ClpDHBasicKeyPairGenerator.pas"/>
+        <UnitName Value="ClpDHBasicKeyPairGenerator"/>
+      </Item358>
+      <Item359>
+        <Filename Value="..\..\Crypto\Generators\ClpDHKeyPairGenerator.pas"/>
+        <UnitName Value="ClpDHKeyPairGenerator"/>
+      </Item359>
+      <Item360>
+        <Filename Value="..\..\Crypto\Generators\ClpDHParametersGenerator.pas"/>
+        <UnitName Value="ClpDHParametersGenerator"/>
+      </Item360>
+      <Item361>
+        <Filename Value="..\..\Crypto\Generators\ClpDHKeyGeneratorHelper.pas"/>
+        <UnitName Value="ClpDHKeyGeneratorHelper"/>
+      </Item361>
+      <Item362>
+        <Filename Value="..\..\Crypto\Generators\ClpDHParametersHelper.pas"/>
+        <UnitName Value="ClpDHParametersHelper"/>
+      </Item362>
+      <Item363>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHPrivateKeyParameters.pas"/>
+        <UnitName Value="ClpDHPrivateKeyParameters"/>
+      </Item363>
+      <Item364>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHPublicKeyParameters.pas"/>
+        <UnitName Value="ClpDHPublicKeyParameters"/>
+      </Item364>
+      <Item365>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHKeyGenerationParameters.pas"/>
+        <UnitName Value="ClpDHKeyGenerationParameters"/>
+      </Item365>
+      <Item366>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHKeyParameters.pas"/>
+        <UnitName Value="ClpDHKeyParameters"/>
+      </Item366>
+      <Item367>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHValidationParameters.pas"/>
+        <UnitName Value="ClpDHValidationParameters"/>
+      </Item367>
+      <Item368>
+        <Filename Value="..\..\Crypto\Parameters\ClpDHParameters.pas"/>
+        <UnitName Value="ClpDHParameters"/>
+      </Item368>
+      <Item369>
+        <Filename Value="..\..\Asn1\X9\ClpDHDomainParameters.pas"/>
+        <UnitName Value="ClpDHDomainParameters"/>
+      </Item369>
+      <Item370>
+        <Filename Value="..\..\Asn1\X9\ClpDHValidationParams.pas"/>
+        <UnitName Value="ClpDHValidationParams"/>
+      </Item370>
     </Files>
     </Files>
-    <RequiredPkgs Count="3">
+    <RequiredPkgs Count="4">
       <Item1>
       <Item1>
+        <PackageName Value="generics_collections"/>
+      </Item1>
+      <Item2>
         <PackageName Value="HashLib4PascalPackage"/>
         <PackageName Value="HashLib4PascalPackage"/>
         <MaxVersion Major="3" Minor="5"/>
         <MaxVersion Major="3" Minor="5"/>
         <MinVersion Major="3" Minor="5" Valid="True"/>
         <MinVersion Major="3" Minor="5" Valid="True"/>
-      </Item1>
-      <Item2>
+      </Item2>
+      <Item3>
         <PackageName Value="SimpleBaseLib4PascalPackage"/>
         <PackageName Value="SimpleBaseLib4PascalPackage"/>
         <MaxVersion Major="1" Minor="4"/>
         <MaxVersion Major="1" Minor="4"/>
         <MinVersion Major="1" Minor="4" Valid="True"/>
         <MinVersion Major="1" Minor="4" Valid="True"/>
-      </Item2>
-      <Item3>
-        <PackageName Value="FCL"/>
       </Item3>
       </Item3>
+      <Item4>
+        <PackageName Value="FCL"/>
+      </Item4>
     </RequiredPkgs>
     </RequiredPkgs>
     <UsageOptions>
     <UsageOptions>
       <UnitPath Value="$(PkgOutDir)"/>
       <UnitPath Value="$(PkgOutDir)"/>

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

@@ -122,7 +122,18 @@ uses
   ClpEd25519Blake2BSigner, ClpTeleTrusTNamedCurves, ClpAgreementUtilities, 
   ClpEd25519Blake2BSigner, ClpTeleTrusTNamedCurves, ClpAgreementUtilities, 
   ClpIKdf1BytesGenerator, ClpKdf1BytesGenerator, 
   ClpIKdf1BytesGenerator, ClpKdf1BytesGenerator, 
   ClpIArgon2ParametersGenerator, ClpArgon2ParametersGenerator, 
   ClpIArgon2ParametersGenerator, ClpArgon2ParametersGenerator, 
-  ClpIScryptParametersGenerator, ClpScryptParametersGenerator;
+  ClpIScryptParametersGenerator, ClpScryptParametersGenerator, 
+  ClpIDHAgreement, ClpIDHBasicAgreement, ClpIDHBasicKeyPairGenerator, 
+  ClpIDHKeyPairGenerator, ClpIDHPrivateKeyParameters, 
+  ClpIDHPublicKeyParameters, ClpIDHParametersGenerator, 
+  ClpIDHKeyGenerationParameters, ClpIDHParameters, ClpIDHKeyGeneratorHelper, 
+  ClpIDHKeyParameters, ClpIDHValidationParameters, ClpIDHDomainParameters, 
+  ClpIDHValidationParams, ClpDHAgreement, ClpDHBasicAgreement, 
+  ClpDHBasicKeyPairGenerator, ClpDHKeyPairGenerator, ClpDHParametersGenerator, 
+  ClpDHKeyGeneratorHelper, ClpDHParametersHelper, ClpDHPrivateKeyParameters, 
+  ClpDHPublicKeyParameters, ClpDHKeyGenerationParameters, ClpDHKeyParameters, 
+  ClpDHValidationParameters, ClpDHParameters, ClpDHDomainParameters, 
+  ClpDHValidationParams;
 
 
 implementation
 implementation
 
 

+ 2 - 0
README.md

@@ -82,6 +82,8 @@ Available Algorithms
 ### Key Agreement/Exchange
 ### Key Agreement/Exchange
 ----------------------------------------
 ----------------------------------------
 
 
+* `DH`
+
 * `ECDH`
 * `ECDH`
 
 
 * `ECDHC`
 * `ECDHC`