Browse Source

sync with parent repositories

HashLib
- various security improvements and refactorings
- support for Scrypt
CryptoLib
- various security improvements and refactorings
- Scrypt integration
- Diffie-Hellman support
- improved OSRandom generator
Ugochukwu Mmaduekwe 6 years ago
parent
commit
fb872ec5c5
100 changed files with 4476 additions and 778 deletions
  1. 4 0
      src/libraries/cryptolib4pascal/ClpAesEngine.pas
  2. 4 0
      src/libraries/cryptolib4pascal/ClpAesLightEngine.pas
  3. 8 0
      src/libraries/cryptolib4pascal/ClpAgreementUtilities.pas
  4. 65 50
      src/libraries/cryptolib4pascal/ClpArgon2ParametersGenerator.pas
  5. 26 10
      src/libraries/cryptolib4pascal/ClpArrayUtils.pas
  6. 4 4
      src/libraries/cryptolib4pascal/ClpAsn1Objects.pas
  7. 1 1
      src/libraries/cryptolib4pascal/ClpBigInteger.pas
  8. 2 2
      src/libraries/cryptolib4pascal/ClpBlockCipherModes.pas
  9. 4 0
      src/libraries/cryptolib4pascal/ClpBlowfishEngine.pas
  10. 1 1
      src/libraries/cryptolib4pascal/ClpBufferedBlockCipher.pas
  11. 6 0
      src/libraries/cryptolib4pascal/ClpChaChaEngine.pas
  12. 1 1
      src/libraries/cryptolib4pascal/ClpCryptoLibTypes.pas
  13. 187 0
      src/libraries/cryptolib4pascal/ClpDHAgreement.pas
  14. 148 0
      src/libraries/cryptolib4pascal/ClpDHBasicAgreement.pas
  15. 104 0
      src/libraries/cryptolib4pascal/ClpDHBasicKeyPairGenerator.pas
  16. 242 0
      src/libraries/cryptolib4pascal/ClpDHDomainParameters.pas
  17. 78 0
      src/libraries/cryptolib4pascal/ClpDHKeyGenerationParameters.pas
  18. 140 0
      src/libraries/cryptolib4pascal/ClpDHKeyGeneratorHelper.pas
  19. 104 0
      src/libraries/cryptolib4pascal/ClpDHKeyPairGenerator.pas
  20. 115 0
      src/libraries/cryptolib4pascal/ClpDHKeyParameters.pas
  21. 266 0
      src/libraries/cryptolib4pascal/ClpDHParameters.pas
  22. 88 0
      src/libraries/cryptolib4pascal/ClpDHParametersGenerator.pas
  23. 270 0
      src/libraries/cryptolib4pascal/ClpDHParametersHelper.pas
  24. 117 0
      src/libraries/cryptolib4pascal/ClpDHPrivateKeyParameters.pas
  25. 135 0
      src/libraries/cryptolib4pascal/ClpDHPublicKeyParameters.pas
  26. 103 0
      src/libraries/cryptolib4pascal/ClpDHValidationParameters.pas
  27. 145 0
      src/libraries/cryptolib4pascal/ClpDHValidationParams.pas
  28. 1 1
      src/libraries/cryptolib4pascal/ClpDigestRandomGenerator.pas
  29. 7 6
      src/libraries/cryptolib4pascal/ClpDsaKeyParameters.pas
  30. 1 1
      src/libraries/cryptolib4pascal/ClpDsaParametersGenerator.pas
  31. 11 4
      src/libraries/cryptolib4pascal/ClpDsaPrivateKeyParameters.pas
  32. 6 6
      src/libraries/cryptolib4pascal/ClpDsaPublicKeyParameters.pas
  33. 5 6
      src/libraries/cryptolib4pascal/ClpECDHBasicAgreement.pas
  34. 5 6
      src/libraries/cryptolib4pascal/ClpECDHCBasicAgreement.pas
  35. 11 4
      src/libraries/cryptolib4pascal/ClpEd25519Blake2BSigner.pas
  36. 11 4
      src/libraries/cryptolib4pascal/ClpEd25519CtxBlake2BSigner.pas
  37. 11 4
      src/libraries/cryptolib4pascal/ClpEd25519CtxSigner.pas
  38. 11 4
      src/libraries/cryptolib4pascal/ClpEd25519Signer.pas
  39. 9 0
      src/libraries/cryptolib4pascal/ClpGeneratorUtilities.pas
  40. 15 0
      src/libraries/cryptolib4pascal/ClpHMac.pas
  41. 1 1
      src/libraries/cryptolib4pascal/ClpHMacDsaKCalculator.pas
  42. 9 78
      src/libraries/cryptolib4pascal/ClpIArgon2ParametersGenerator.pas
  43. 2 2
      src/libraries/cryptolib4pascal/ClpIAsn1Objects.pas
  44. 73 0
      src/libraries/cryptolib4pascal/ClpIDHAgreement.pas
  45. 46 0
      src/libraries/cryptolib4pascal/ClpIDHBasicAgreement.pas
  46. 34 0
      src/libraries/cryptolib4pascal/ClpIDHBasicKeyPairGenerator.pas
  47. 51 0
      src/libraries/cryptolib4pascal/ClpIDHDomainParameters.pas
  48. 40 0
      src/libraries/cryptolib4pascal/ClpIDHKeyGenerationParameters.pas
  49. 43 0
      src/libraries/cryptolib4pascal/ClpIDHKeyGeneratorHelper.pas
  50. 34 0
      src/libraries/cryptolib4pascal/ClpIDHKeyPairGenerator.pas
  51. 44 0
      src/libraries/cryptolib4pascal/ClpIDHKeyParameters.pas
  52. 61 0
      src/libraries/cryptolib4pascal/ClpIDHParameters.pas
  53. 49 0
      src/libraries/cryptolib4pascal/ClpIDHParametersGenerator.pas
  54. 41 0
      src/libraries/cryptolib4pascal/ClpIDHPrivateKeyParameters.pas
  55. 38 0
      src/libraries/cryptolib4pascal/ClpIDHPublicKeyParameters.pas
  56. 40 0
      src/libraries/cryptolib4pascal/ClpIDHValidationParameters.pas
  57. 41 0
      src/libraries/cryptolib4pascal/ClpIDHValidationParams.pas
  58. 1 1
      src/libraries/cryptolib4pascal/ClpIDsaParameter.pas
  59. 7 3
      src/libraries/cryptolib4pascal/ClpIESCipher.pas
  60. 2 2
      src/libraries/cryptolib4pascal/ClpIESEngine.pas
  61. 2 0
      src/libraries/cryptolib4pascal/ClpIMac.pas
  62. 1 32
      src/libraries/cryptolib4pascal/ClpIPbeParametersGenerator.pas
  63. 5 1
      src/libraries/cryptolib4pascal/ClpIPkcs5S2ParametersGenerator.pas
  64. 40 0
      src/libraries/cryptolib4pascal/ClpIScryptParametersGenerator.pas
  65. 1 1
      src/libraries/cryptolib4pascal/ClpKeyParameter.pas
  66. 12 1
      src/libraries/cryptolib4pascal/ClpMiscObjectIdentifiers.pas
  67. 298 110
      src/libraries/cryptolib4pascal/ClpOSRandom.pas
  68. 1 1
      src/libraries/cryptolib4pascal/ClpParameterUtilities.pas
  69. 1 1
      src/libraries/cryptolib4pascal/ClpParametersWithIV.pas
  70. 1 1
      src/libraries/cryptolib4pascal/ClpPascalCoinIESEngine.pas
  71. 2 83
      src/libraries/cryptolib4pascal/ClpPbeParametersGenerator.pas
  72. 5 6
      src/libraries/cryptolib4pascal/ClpPcgRandomMinimal.pas
  73. 28 5
      src/libraries/cryptolib4pascal/ClpPkcs5S2ParametersGenerator.pas
  74. 17 2
      src/libraries/cryptolib4pascal/ClpPkcsObjectIdentifiers.pas
  75. 4 0
      src/libraries/cryptolib4pascal/ClpRijndaelEngine.pas
  76. 11 0
      src/libraries/cryptolib4pascal/ClpSalsa20Engine.pas
  77. 11 4
      src/libraries/cryptolib4pascal/ClpSchnorrDigestSigner.pas
  78. 199 0
      src/libraries/cryptolib4pascal/ClpScryptParametersGenerator.pas
  79. 48 27
      src/libraries/cryptolib4pascal/ClpSpeckEngine.pas
  80. 53 26
      src/libraries/cryptolib4pascal/ClpSpeckLegacyEngine.pas
  81. 5 4
      src/libraries/cryptolib4pascal/ClpX25519Agreement.pas
  82. 6 0
      src/libraries/cryptolib4pascal/ClpXSalsa20Engine.pas
  83. 101 16
      src/libraries/cryptolib4pascal/CryptoLib.inc
  84. 2 2
      src/libraries/cryptolib4pascal/CryptoLibHelper.inc
  85. 172 107
      src/libraries/cryptolib4pascal/README.md
  86. 18 15
      src/libraries/hashlib4pascal/HashLib.inc
  87. 2 2
      src/libraries/hashlib4pascal/HashLibHelper.inc
  88. 136 0
      src/libraries/hashlib4pascal/HlpArrayUtils.pas
  89. 5 3
      src/libraries/hashlib4pascal/HlpBlake2B.pas
  90. 5 3
      src/libraries/hashlib4pascal/HlpBlake2S.pas
  91. 5 5
      src/libraries/hashlib4pascal/HlpGOST3411_2012.pas
  92. 3 6
      src/libraries/hashlib4pascal/HlpGost.pas
  93. 3 5
      src/libraries/hashlib4pascal/HlpGrindahl256.pas
  94. 3 5
      src/libraries/hashlib4pascal/HlpGrindahl512.pas
  95. 19 3
      src/libraries/hashlib4pascal/HlpHMACNotBuildInAdapter.pas
  96. 5 5
      src/libraries/hashlib4pascal/HlpHashBuffer.pas
  97. 103 65
      src/libraries/hashlib4pascal/HlpHashFactory.pas
  98. 3 29
      src/libraries/hashlib4pascal/HlpHashResult.pas
  99. 9 0
      src/libraries/hashlib4pascal/HlpIHashInfo.pas
  100. 2 0
      src/libraries/hashlib4pascal/HlpIKDF.pas

+ 4 - 0
src/libraries/cryptolib4pascal/ClpAesEngine.pas

@@ -30,6 +30,7 @@ uses
   ClpCheck,
   ClpBits,
   ClpConverters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -499,6 +500,7 @@ begin
   keyLen := System.Length(key);
   if ((keyLen < 16) or (keyLen > 32) or ((keyLen and 7) <> 0)) then
   begin
+    TArrayUtils.ZeroFill(key);
     raise EArgumentCryptoLibException.CreateRes(@SInvalidKeyLength);
   end;
 
@@ -676,6 +678,7 @@ begin
       end
   else
     begin
+      TArrayUtils.ZeroFill(key);
       raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidOperation);
     end;
   end;
@@ -696,6 +699,7 @@ begin
 
   result := bigW;
 
+  TArrayUtils.ZeroFill(key);
 end;
 
 function TAesEngine.GetAlgorithmName: String;

+ 4 - 0
src/libraries/cryptolib4pascal/ClpAesLightEngine.pas

@@ -30,6 +30,7 @@ uses
   ClpCheck,
   ClpBits,
   ClpConverters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -425,6 +426,7 @@ begin
   keyLen := System.Length(key);
   if ((keyLen < 16) or (keyLen > 32) or ((keyLen and 7) <> 0)) then
   begin
+    TArrayUtils.ZeroFill(key);
     raise EArgumentCryptoLibException.CreateRes(@SInvalidKeyLength);
   end;
 
@@ -602,6 +604,7 @@ begin
       end
   else
     begin
+      TArrayUtils.ZeroFill(key);
       raise EInvalidOperationCryptoLibException.CreateRes(@SInvalidOperation);
     end;
   end;
@@ -622,6 +625,7 @@ begin
 
   result := bigW;
 
+  TArrayUtils.ZeroFill(key);
 end;
 
 function TAesLightEngine.GetAlgorithmName: String;

+ 8 - 0
src/libraries/cryptolib4pascal/ClpAgreementUtilities.pas

@@ -25,6 +25,8 @@ uses
   SysUtils,
   Generics.Collections,
   ClpIBasicAgreement,
+  ClpDHBasicAgreement,
+  ClpIDHBasicAgreement,
   ClpECDHBasicAgreement,
   ClpIECDHBasicAgreement,
   ClpECDHCBasicAgreement,
@@ -129,6 +131,12 @@ var
 begin
   mechanism := GetMechanism(algorithm);
 
+  if ((mechanism = 'DH') or (mechanism = 'DIFFIEHELLMAN')) then
+  begin
+    result := TDHBasicAgreement.Create() as IDHBasicAgreement;
+    Exit;
+  end;
+
   if (mechanism = 'ECDH') then
   begin
     result := TECDHBasicAgreement.Create() as IECDHBasicAgreement;

+ 65 - 50
src/libraries/cryptolib4pascal/ClpArgon2ParametersGenerator.pas

@@ -25,17 +25,21 @@ uses
 
   HlpIHashInfo,
   HlpHashFactory,
+  HlpArgon2TypeAndVersion,
   HlpPBKDF_Argon2NotBuildInAdapter,
+  ClpPbeParametersGenerator,
   ClpICipherParameters,
   ClpIArgon2ParametersGenerator,
   ClpKeyParameter,
   ClpIKeyParameter,
   ClpParametersWithIV,
   ClpParameterUtilities,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
   SArgon2TypeInvalid = 'Selected Argon2Type is Invalid';
+  SArgon2VersionInvalid = 'Selected Argon2Version is Invalid';
   SArgon2MemoryCostTypeInvalid = 'Selected Argon2MemoryCostType is Invalid';
 
 type
@@ -45,30 +49,21 @@ type
   /// Argon2 Specification</see>, <see href="https://tools.ietf.org/html/draft-irtf-cfrg-argon2-04">
   /// ietf specs</see>
   /// </summary>
-  TArgon2ParametersGenerator = class sealed(TInterfacedObject,
+  TArgon2ParametersGenerator = class sealed(TPbeParametersGenerator,
     IArgon2ParametersGenerator)
 
   strict private
   var
     FPassword: TCryptoLibByteArray;
     FPBKDF_Argon2: IPBKDF_Argon2;
-    FArgon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder;
-
-    /// <returns>
-    /// the password byte array.
-    /// </returns>
-    function GetPassword: TCryptoLibByteArray; inline;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    function GetArgon2ParametersBuilder
-      : HlpIHashInfo.IArgon2ParametersBuilder; inline;
+    FArgon2Parameters: IArgon2Parameters;
 
     function GenerateDerivedKey(dkLen: Int32): TCryptoLibByteArray; inline;
 
   public
 
+    procedure Clear(); override;
+
     /// <summary>
     /// construct an Argon2 Parameters generator.
     /// </summary>
@@ -77,10 +72,12 @@ type
     /// </param>
     constructor Create();
 
-    procedure Init(argon2Type: TArgon2Type; argon2Version: TArgon2Version;
-      const password, salt, secret, additional: TCryptoLibByteArray;
-      iterations, memory, parallelism: Int32;
-      memoryCostType: TArgon2MemoryCostType);
+    destructor Destroy; override;
+
+    procedure Init(argon2Type: TCryptoLibArgon2Type;
+      argon2Version: TCryptoLibArgon2Version; const password, salt, secret,
+      additional: TCryptoLibByteArray; iterations, memory, parallelism: Int32;
+      memoryCostType: TCryptoLibArgon2MemoryCostType);
 
     /// <summary>
     /// Generate a key parameter derived from the password, salt, and
@@ -96,7 +93,7 @@ type
     /// a parameters object representing a key.
     /// </returns>
     function GenerateDerivedParameters(const algorithm: String; keySize: Int32)
-      : ICipherParameters; overload;
+      : ICipherParameters; overload; override;
 
     /// <summary>
     /// Generate a key with initialisation vector parameter derived from <br />
@@ -116,7 +113,7 @@ type
     /// a parameters object representing a key and an iv.
     /// </returns>
     function GenerateDerivedParameters(const algorithm: String;
-      keySize, ivSize: Int32): ICipherParameters; overload;
+      keySize, ivSize: Int32): ICipherParameters; overload; override;
 
     /// <summary>
     /// Generate a key parameter for use with a MAC derived from the
@@ -130,18 +127,7 @@ type
     /// a parameters object representing a key.
     /// </returns>
     function GenerateDerivedMacParameters(keySize: Int32)
-      : ICipherParameters; overload;
-
-    /// <value>
-    /// the password byte array.
-    /// </value>
-    property password: TCryptoLibByteArray read GetPassword;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    property Argon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder
-      read GetArgon2ParametersBuilder;
+      : ICipherParameters; override;
 
   end;
 
@@ -149,15 +135,19 @@ implementation
 
 { TArgon2ParametersGenerator }
 
-function TArgon2ParametersGenerator.GetPassword: TCryptoLibByteArray;
+procedure TArgon2ParametersGenerator.Clear();
 begin
-  result := System.Copy(FPassword);
-end;
+  TArrayUtils.ZeroFill(FPassword);
 
-function TArgon2ParametersGenerator.GetArgon2ParametersBuilder
-  : HlpIHashInfo.IArgon2ParametersBuilder;
-begin
-  result := FArgon2ParametersBuilder;
+  if FArgon2Parameters <> Nil then
+  begin
+    FArgon2Parameters.Clear();
+  end;
+
+  if FPBKDF_Argon2 <> Nil then
+  begin
+    FPBKDF_Argon2.Clear();
+  end;
 end;
 
 constructor TArgon2ParametersGenerator.Create();
@@ -165,6 +155,12 @@ begin
   Inherited Create();
 end;
 
+destructor TArgon2ParametersGenerator.Destroy();
+begin
+  Clear();
+  inherited Destroy;
+end;
+
 function TArgon2ParametersGenerator.GenerateDerivedKey(dkLen: Int32)
   : TCryptoLibByteArray;
 begin
@@ -210,26 +206,27 @@ begin
   result := TParametersWithIV.Create(key, dKey, keySize, ivSize);
 end;
 
-procedure TArgon2ParametersGenerator.Init(argon2Type: TArgon2Type;
-  argon2Version: TArgon2Version; const password, salt, secret,
+procedure TArgon2ParametersGenerator.Init(argon2Type: TCryptoLibArgon2Type;
+  argon2Version: TCryptoLibArgon2Version; const password, salt, secret,
   additional: TCryptoLibByteArray; iterations, memory, parallelism: Int32;
-  memoryCostType: TArgon2MemoryCostType);
+  memoryCostType: TCryptoLibArgon2MemoryCostType);
 var
   LArgon2ParametersBuilder: IArgon2ParametersBuilder;
+  LArgon2Version: TArgon2Version;
 begin
-  FPassword := password;
+  FPassword := System.Copy(password);
 
   case argon2Type of
-    TArgon2Type.a2tARGON2_d:
+    TCryptoLibArgon2Type.Argon2D:
       begin
         LArgon2ParametersBuilder := TArgon2dParametersBuilder.Builder();
       end;
 
-    TArgon2Type.a2tARGON2_i:
+    TCryptoLibArgon2Type.Argon2I:
       begin
         LArgon2ParametersBuilder := TArgon2iParametersBuilder.Builder();
       end;
-    TArgon2Type.a2tARGON2_id:
+    TCryptoLibArgon2Type.Argon2ID:
       begin
         LArgon2ParametersBuilder := TArgon2idParametersBuilder.Builder();
       end
@@ -239,18 +236,34 @@ begin
     end;
   end;
 
+  case argon2Version of
+    TCryptoLibArgon2Version.Argon2Version10:
+      begin
+        LArgon2Version := TArgon2Version.a2vARGON2_VERSION_10;
+      end;
+
+    TCryptoLibArgon2Version.Argon2Version13:
+      begin
+        LArgon2Version := TArgon2Version.a2vARGON2_VERSION_13;
+      end
+  else
+    begin
+      raise EArgumentCryptoLibException.CreateRes(@SArgon2VersionInvalid);
+    end;
+  end;
+
   case memoryCostType of
-    TArgon2MemoryCostType.a2mctMemoryAsKB:
+    TCryptoLibArgon2MemoryCostType.MemoryAsKB:
       begin
-        LArgon2ParametersBuilder.WithVersion(argon2Version).WithSalt(salt)
+        LArgon2ParametersBuilder.WithVersion(LArgon2Version).WithSalt(salt)
           .WithSecret(secret).WithAdditional(additional)
           .WithIterations(iterations).WithMemoryAsKB(memory)
           .WithParallelism(parallelism);
       end;
 
-    TArgon2MemoryCostType.a2mctMemoryPowOfTwo:
+    TCryptoLibArgon2MemoryCostType.MemoryPowOfTwo:
       begin
-        LArgon2ParametersBuilder.WithVersion(argon2Version).WithSalt(salt)
+        LArgon2ParametersBuilder.WithVersion(LArgon2Version).WithSalt(salt)
           .WithSecret(secret).WithAdditional(additional)
           .WithIterations(iterations).WithMemoryPowOfTwo(memory)
           .WithParallelism(parallelism);
@@ -262,8 +275,10 @@ begin
     end;
   end;
 
+  FArgon2Parameters := LArgon2ParametersBuilder.Build();
+  LArgon2ParametersBuilder.Clear();
   FPBKDF_Argon2 := TKDF.TPBKDF_Argon2.CreatePBKDF_Argon2(FPassword,
-    LArgon2ParametersBuilder.Build());
+    FArgon2Parameters);
 end;
 
 end.

+ 26 - 10
src/libraries/cryptolib4pascal/ClpArrayUtils.pas

@@ -95,6 +95,8 @@ type
     class procedure Fill(const buf: TCryptoLibUInt32Array; from, &to: Int32;
       filler: UInt32); overload; static;
 
+    class procedure ZeroFill(const buf: TCryptoLibByteArray); static;
+
   end;
 
 implementation
@@ -255,31 +257,45 @@ end;
 class procedure TArrayUtils.Fill(const buf: TCryptoLibByteArray;
   from, &to: Int32; filler: Byte);
 begin
-  System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), filler);
+  if buf <> Nil then
+  begin
+    System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), filler);
+  end;
 end;
 
 class procedure TArrayUtils.Fill(const buf: TCryptoLibInt32Array;
   from, &to: Int32; filler: Int32);
 begin
-  while from < &to do
+  if buf <> Nil then
   begin
-    buf[from] := filler;
-    System.Inc(from);
+    while from < &to do
+    begin
+      buf[from] := filler;
+      System.Inc(from);
+    end;
   end;
 end;
 
 class procedure TArrayUtils.Fill(const buf: TCryptoLibUInt32Array;
   from, &to: Int32; filler: UInt32);
 begin
+  if buf <> Nil then
+  begin
 {$IFDEF FPC}
-  System.FillDWord(buf[from], (&to - from), filler);
+    System.FillDWord(buf[from], (&to - from), filler);
 {$ELSE}
-  while from < &to do
-  begin
-    buf[from] := filler;
-    System.Inc(from);
-  end;
+    while from < &to do
+    begin
+      buf[from] := filler;
+      System.Inc(from);
+    end;
 {$ENDIF}
+  end;
+end;
+
+class procedure TArrayUtils.ZeroFill(const buf: TCryptoLibByteArray);
+begin
+  TArrayUtils.Fill(buf, 0, System.Length(buf), Byte(0));
 end;
 
 class function TArrayUtils.GetArrayHashCode(const data

+ 4 - 4
src/libraries/cryptolib4pascal/ClpAsn1Objects.pas

@@ -784,7 +784,7 @@ type
   strict protected
     function GetCount: Int32; virtual;
     function GetParser: IAsn1SequenceParser; virtual;
-    function GetSelf(Index: Integer): IAsn1Encodable; virtual;
+    function GetSelf(Index: Int32): IAsn1Encodable; virtual;
     function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
     function Asn1GetHashCode(): Int32; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
@@ -1179,7 +1179,7 @@ type
   strict protected
     function GetCount: Int32; virtual;
     function GetParser: IAsn1SetParser; inline;
-    function GetSelf(Index: Integer): IAsn1Encodable; virtual;
+    function GetSelf(Index: Int32): IAsn1Encodable; virtual;
     function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
     function Asn1GetHashCode(): Int32; override;
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
@@ -5470,7 +5470,7 @@ begin
   result := TAsn1SequenceParserImpl.Create(Self as IAsn1Sequence);
 end;
 
-function TAsn1Sequence.GetSelf(Index: Integer): IAsn1Encodable;
+function TAsn1Sequence.GetSelf(Index: Int32): IAsn1Encodable;
 begin
   result := FSeq[index];
 end;
@@ -6301,7 +6301,7 @@ begin
   result := TAsn1SetParserImpl.Create(Self as IAsn1Set);
 end;
 
-function TAsn1Set.GetSelf(Index: Integer): IAsn1Encodable;
+function TAsn1Set.GetSelf(Index: Int32): IAsn1Encodable;
 begin
   result := F_set[index];
 end;

+ 1 - 1
src/libraries/cryptolib4pascal/ClpBigInteger.pas

@@ -2151,7 +2151,7 @@ end;
 
 function TBigInteger.IsEqualMagnitude(const x: TBigInteger): Boolean;
 var
-  i: Integer;
+  i: Int32;
   xMag: TCryptoLibInt32Array;
 begin
   xMag := x.Fmagnitude;

+ 2 - 2
src/libraries/cryptolib4pascal/ClpBlockCipherModes.pas

@@ -789,7 +789,7 @@ end;
 procedure TCbcBlockCipher.Reset;
 begin
   System.Move(FIV[0], FcbcV[0], System.Length(FIV));
-  TArrayUtils.Fill(FcbcNextV, 0, System.Length(FcbcNextV), Byte(0));
+  TArrayUtils.ZeroFill(FcbcNextV);
 
   Fcipher.Reset();
 end;
@@ -1179,7 +1179,7 @@ end;
 
 procedure TSicBlockCipher.Reset;
 begin
-  TArrayUtils.Fill(Fcounter, 0, System.Length(Fcounter), Byte(0));
+  TArrayUtils.ZeroFill(Fcounter);
   System.Move(FIV[0], Fcounter[0], System.Length(FIV) * System.SizeOf(Byte));
 
   Fcipher.Reset();

+ 4 - 0
src/libraries/cryptolib4pascal/ClpBlowfishEngine.pas

@@ -29,6 +29,7 @@ uses
   ClpIBlowfishEngine,
   ClpCheck,
   ClpConverters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -326,6 +327,7 @@ begin
   if ((keyLength < 4) or (keyLength > 56) or (((keyLength * 8) and 7) <> 0))
   then
   begin
+    TArrayUtils.ZeroFill(key);
     raise EArgumentCryptoLibException.CreateRes(@SInvalidKeyLength);
   end;
 
@@ -410,6 +412,8 @@ begin
   ProcessTable(FS0[SBOX_SK - 2], FS0[SBOX_SK - 1], FS1);
   ProcessTable(FS1[SBOX_SK - 2], FS1[SBOX_SK - 1], FS2);
   ProcessTable(FS2[SBOX_SK - 2], FS2[SBOX_SK - 1], FS3);
+
+  TArrayUtils.ZeroFill(key);
 end;
 
 procedure TBlowfishEngine.EncryptBlock(const src: TCryptoLibByteArray;

+ 1 - 1
src/libraries/cryptolib4pascal/ClpBufferedBlockCipher.pas

@@ -540,7 +540,7 @@ end;
 
 procedure TBufferedBlockCipher.Reset;
 begin
-  TArrayUtils.Fill(Fbuf, 0, System.length(Fbuf), Byte(0));
+  TArrayUtils.ZeroFill(Fbuf);
   FbufOff := 0;
 
   Fcipher.Reset();

+ 6 - 0
src/libraries/cryptolib4pascal/ClpChaChaEngine.pas

@@ -27,6 +27,7 @@ uses
   ClpIChaChaEngine,
   ClpSalsa20Engine,
   ClpConverters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 type
@@ -242,6 +243,8 @@ begin
   begin
     if not(Byte(System.Length(keyBytes)) in [16, 32]) then
     begin
+      TArrayUtils.ZeroFill(keyBytes);
+      TArrayUtils.ZeroFill(ivBytes);
       raise EArgumentCryptoLibException.CreateResFmt(@SInvalidKeySize,
         [AlgorithmName]);
     end;
@@ -259,6 +262,9 @@ begin
   // IV
   TConverters.le32_copy(PByte(ivBytes), 0, PCardinal(FEngineState),
     14 * System.SizeOf(UInt32), 2 * System.SizeOf(UInt32));
+
+  TArrayUtils.ZeroFill(keyBytes);
+  TArrayUtils.ZeroFill(ivBytes);
 end;
 
 end.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpCryptoLibTypes.pas

@@ -53,7 +53,7 @@ type
   EInvalidCipherTextCryptoLibException = class(ECryptoLibException);
   EStreamCryptoLibException = class(ECryptoLibException);
   ESecurityUtilityCryptoLibException = class(ECryptoLibException);
-  EAccessCryptoLibException = class(ECryptoLibException);
+  EOSRandomCryptoLibException = class(ECryptoLibException);
   EDataLengthCryptoLibException = class(ECryptoLibException);
   EMaxBytesExceededCryptoLibException = class(ECryptoLibException);
   EOutputLengthCryptoLibException = class(ECryptoLibException);

+ 187 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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.

+ 242 - 0
src/libraries/cryptolib4pascal/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 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.

+ 78 - 0
src/libraries/cryptolib4pascal/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 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.

+ 140 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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.

+ 115 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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.

+ 88 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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.

+ 117 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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.

+ 145 - 0
src/libraries/cryptolib4pascal/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 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.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDigestRandomGenerator.pas

@@ -186,7 +186,7 @@ procedure TDigestRandomGenerator.NextBytes(const bytes: TCryptoLibByteArray;
   start, len: Int32);
 var
   stateOff, endPoint: Int32;
-  I: Integer;
+  I: Int32;
 begin
 
   FLock.Acquire;

+ 7 - 6
src/libraries/cryptolib4pascal/ClpDsaKeyParameters.pas

@@ -33,11 +33,12 @@ type
   var
     Fparameters: IDsaParameters;
   strict protected
-  function GetParameters: IDsaParameters;
-    constructor Create(isPrivate: Boolean; parameters: IDsaParameters);
+    function GetParameters: IDsaParameters;
+    constructor Create(isPrivate: Boolean; const parameters: IDsaParameters);
 
   public
-    function Equals(const other: IDsaKeyParameters): Boolean; reintroduce; overload;
+    function Equals(const other: IDsaKeyParameters): Boolean;
+      reintroduce; overload;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 
@@ -50,7 +51,7 @@ implementation
 { TDsaKeyParameters }
 
 constructor TDsaKeyParameters.Create(isPrivate: Boolean;
-  parameters: IDsaParameters);
+  const parameters: IDsaParameters);
 begin
   Inherited Create(isPrivate);
   // Note: parameters may be Nil
@@ -69,8 +70,8 @@ begin
     result := True;
     Exit;
   end;
-  result := (parameters as TObject).Equals(other.parameters as TObject) and
-    (Inherited Equals(other));
+
+  result := parameters.Equals(other.parameters) and (Inherited Equals(other));
 end;
 
 function TDsaKeyParameters.GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;

+ 1 - 1
src/libraries/cryptolib4pascal/ClpDsaParametersGenerator.pas

@@ -160,7 +160,7 @@ type
     /// <returns>
     /// a generated DSA parameters object.
     /// </returns>
-    function GenerateParameters(): IDsaParameters; inline;
+    function GenerateParameters(): IDsaParameters; virtual;
 
   end;
 

+ 11 - 4
src/libraries/cryptolib4pascal/ClpDsaPrivateKeyParameters.pas

@@ -41,6 +41,8 @@ type
 
     function GetX: TBigInteger; inline;
 
+    class function Validate(const x: TBigInteger): TBigInteger; static; inline;
+
   public
     constructor Create(const x: TBigInteger; const parameters: IDsaParameters);
 
@@ -61,16 +63,21 @@ begin
   result := Fx;
 end;
 
-constructor TDsaPrivateKeyParameters.Create(const x: TBigInteger;
-  const parameters: IDsaParameters);
+class function TDsaPrivateKeyParameters.Validate(const x: TBigInteger)
+  : TBigInteger;
 begin
-  Inherited Create(true, parameters);
   if (not(x.IsInitialized)) then
   begin
     raise EArgumentNilCryptoLibException.CreateRes(@SXUnInitialized);
   end;
+  result := x;
+end;
 
-  Fx := x;
+constructor TDsaPrivateKeyParameters.Create(const x: TBigInteger;
+  const parameters: IDsaParameters);
+begin
+  Inherited Create(true, parameters);
+  Fx := Validate(x);
 end;
 
 function TDsaPrivateKeyParameters.Equals(const other

+ 6 - 6
src/libraries/cryptolib4pascal/ClpDsaPublicKeyParameters.pas

@@ -48,7 +48,8 @@ type
   public
     constructor Create(const y: TBigInteger; const parameters: IDsaParameters);
 
-    function Equals(const other: IDsaPublicKeyParameters): Boolean; reintroduce; overload;
+    function Equals(const other: IDsaPublicKeyParameters): Boolean;
+      reintroduce; overload;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 
@@ -67,6 +68,10 @@ end;
 class function TDsaPublicKeyParameters.Validate(const y: TBigInteger;
   const parameters: IDsaParameters): TBigInteger;
 begin
+  if (not(y.IsInitialized)) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SYUnInitialized);
+  end;
   // we can't validate without params, fortunately we can't use the key either...
   if (parameters <> Nil) then
   begin
@@ -85,11 +90,6 @@ constructor TDsaPublicKeyParameters.Create(const y: TBigInteger;
   const parameters: IDsaParameters);
 begin
   Inherited Create(false, parameters);
-  if (not(y.IsInitialized)) then
-  begin
-    raise EArgumentNilCryptoLibException.CreateRes(@SYUnInitialized);
-  end;
-
   Fy := Validate(y, parameters);
 end;
 

+ 5 - 6
src/libraries/cryptolib4pascal/ClpECDHBasicAgreement.pas

@@ -53,10 +53,10 @@ type
   /// used with the schemes ECKAS-DH1 and <br />DL/ECKAS-DH2. It assumes that
   /// the input keys are valid (see also <br />Section 7.2.2). <br />
   /// </summary>
-  TECDHBasicAgreement = class(TInterfacedObject, IECDHBasicAgreement,
+  TECDHBasicAgreement = class sealed(TInterfacedObject, IECDHBasicAgreement,
     IBasicAgreement)
 
-  strict protected
+  strict private
   var
     FprivKey: IECPrivateKeyParameters;
 
@@ -64,19 +64,18 @@ type
     /// <summary>
     /// initialise the agreement engine.
     /// </summary>
-    procedure Init(const parameters: ICipherParameters); virtual;
+    procedure Init(const parameters: ICipherParameters);
 
     /// <summary>
     /// return the field size for the agreement algorithm in bytes.
     /// </summary>
-    function GetFieldSize(): Int32; virtual;
+    function GetFieldSize(): Int32;
 
     /// <summary>
     /// given a public key from a given party calculate the next message
     /// in the agreement sequence.
     /// </summary>
-    function CalculateAgreement(const pubKey: ICipherParameters)
-      : TBigInteger; virtual;
+    function CalculateAgreement(const pubKey: ICipherParameters): TBigInteger;
 
   end;
 

+ 5 - 6
src/libraries/cryptolib4pascal/ClpECDHCBasicAgreement.pas

@@ -58,10 +58,10 @@ type
   /// (if you want that just use ECDHBasicAgreement and note they both
   /// implement <br />BasicAgreement!). <br />
   /// </summary>
-  TECDHCBasicAgreement = class(TInterfacedObject, IECDHCBasicAgreement,
+  TECDHCBasicAgreement = class sealed(TInterfacedObject, IECDHCBasicAgreement,
     IBasicAgreement)
 
-  strict protected
+  strict private
   var
     FprivKey: IECPrivateKeyParameters;
 
@@ -69,19 +69,18 @@ type
     /// <summary>
     /// initialise the agreement engine.
     /// </summary>
-    procedure Init(const parameters: ICipherParameters); virtual;
+    procedure Init(const parameters: ICipherParameters);
 
     /// <summary>
     /// return the field size for the agreement algorithm in bytes.
     /// </summary>
-    function GetFieldSize(): Int32; virtual;
+    function GetFieldSize(): Int32;
 
     /// <summary>
     /// given a public key from a given party calculate the next message
     /// in the agreement sequence.
     /// </summary>
-    function CalculateAgreement(const pubKey: ICipherParameters)
-      : TBigInteger; virtual;
+    function CalculateAgreement(const pubKey: ICipherParameters): TBigInteger;
 
   end;
 

+ 11 - 4
src/libraries/cryptolib4pascal/ClpEd25519Blake2BSigner.pas

@@ -78,15 +78,22 @@ implementation
 
 function TEd25519Blake2BSigner.Aggregate: TCryptoLibByteArray;
 begin
-  FBuffer.Position := 0;
-  System.SetLength(Result, FBuffer.Size);
-  FBuffer.Read(Result[0], FBuffer.Size);
+  Result := Nil;
+  if FBuffer.Size > 0 then
+  begin
+    FBuffer.Position := 0;
+    System.SetLength(Result, FBuffer.Size);
+    FBuffer.Read(Result[0], FBuffer.Size);
+  end;
 end;
 
 procedure TEd25519Blake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
   off, len: Int32);
 begin
-  FBuffer.Write(buf[off], len);
+  if buf <> Nil then
+  begin
+    FBuffer.Write(buf[off], len);
+  end;
 end;
 
 constructor TEd25519Blake2BSigner.Create;

+ 11 - 4
src/libraries/cryptolib4pascal/ClpEd25519CtxBlake2BSigner.pas

@@ -79,15 +79,22 @@ implementation
 
 function TEd25519CtxBlake2BSigner.Aggregate: TCryptoLibByteArray;
 begin
-  FBuffer.Position := 0;
-  System.SetLength(Result, FBuffer.Size);
-  FBuffer.Read(Result[0], FBuffer.Size);
+  Result := Nil;
+  if FBuffer.Size > 0 then
+  begin
+    FBuffer.Position := 0;
+    System.SetLength(Result, FBuffer.Size);
+    FBuffer.Read(Result[0], FBuffer.Size);
+  end;
 end;
 
 procedure TEd25519CtxBlake2BSigner.BlockUpdate(const buf: TCryptoLibByteArray;
   off, len: Int32);
 begin
-  FBuffer.Write(buf[off], len);
+  if buf <> Nil then
+  begin
+    FBuffer.Write(buf[off], len);
+  end;
 end;
 
 constructor TEd25519CtxBlake2BSigner.Create(const context: TCryptoLibByteArray);

+ 11 - 4
src/libraries/cryptolib4pascal/ClpEd25519CtxSigner.pas

@@ -79,15 +79,22 @@ implementation
 
 function TEd25519CtxSigner.Aggregate: TCryptoLibByteArray;
 begin
-  FBuffer.Position := 0;
-  System.SetLength(Result, FBuffer.Size);
-  FBuffer.Read(Result[0], FBuffer.Size);
+  Result := Nil;
+  if FBuffer.Size > 0 then
+  begin
+    FBuffer.Position := 0;
+    System.SetLength(Result, FBuffer.Size);
+    FBuffer.Read(Result[0], FBuffer.Size);
+  end;
 end;
 
 procedure TEd25519CtxSigner.BlockUpdate(const buf: TCryptoLibByteArray;
   off, len: Int32);
 begin
-  FBuffer.Write(buf[off], len);
+  if buf <> Nil then
+  begin
+    FBuffer.Write(buf[off], len);
+  end;
 end;
 
 constructor TEd25519CtxSigner.Create(const context: TCryptoLibByteArray);

+ 11 - 4
src/libraries/cryptolib4pascal/ClpEd25519Signer.pas

@@ -78,15 +78,22 @@ implementation
 
 function TEd25519Signer.Aggregate: TCryptoLibByteArray;
 begin
-  FBuffer.Position := 0;
-  System.SetLength(Result, FBuffer.Size);
-  FBuffer.Read(Result[0], FBuffer.Size);
+  Result := Nil;
+  if FBuffer.Size > 0 then
+  begin
+    FBuffer.Position := 0;
+    System.SetLength(Result, FBuffer.Size);
+    FBuffer.Read(Result[0], FBuffer.Size);
+  end;
 end;
 
 procedure TEd25519Signer.BlockUpdate(const buf: TCryptoLibByteArray;
   off, len: Int32);
 begin
-  FBuffer.Write(buf[off], len);
+  if buf <> Nil then
+  begin
+    FBuffer.Write(buf[off], len);
+  end;
 end;
 
 constructor TEd25519Signer.Create;

+ 9 - 0
src/libraries/cryptolib4pascal/ClpGeneratorUtilities.pas

@@ -31,6 +31,8 @@ uses
   ClpIAsn1Objects,
   ClpDsaKeyPairGenerator,
   ClpIDsaKeyPairGenerator,
+  ClpDHKeyPairGenerator,
+  ClpIDHKeyPairGenerator,
   ClpEd25519KeyPairGenerator,
   ClpIEd25519KeyPairGenerator,
   ClpEd25519Blake2BKeyPairGenerator,
@@ -254,6 +256,7 @@ begin
   // key pair generators.
   //
 
+  AddKpgAlgorithm('DH', ['DIFFIEHELLMAN']);
   AddKpgAlgorithm('DSA', []);
   AddKpgAlgorithm('ECDH', ['ECIES']);
   AddKpgAlgorithm('ECDHC', []);
@@ -385,6 +388,12 @@ begin
       (@SKeyPairGeneratorAlgorithmNotRecognised, [algorithm]);
   end;
 
+  if (canonicalName = 'DH') then
+  begin
+    result := TDHKeyPairGenerator.Create() as IDHKeyPairGenerator;
+    Exit;
+  end;
+
   if (canonicalName = 'DSA') then
   begin
     result := TDsaKeyPairGenerator.Create() as IDsaKeyPairGenerator;

+ 15 - 0
src/libraries/cryptolib4pascal/ClpHMac.pas

@@ -57,6 +57,10 @@ type
   public
     constructor Create(const digest: IDigest);
 
+    destructor Destroy(); override;
+
+    procedure Clear();
+
     function GetUnderlyingDigest: IDigest; inline;
     function GetMacSize: Int32; inline;
 
@@ -91,6 +95,11 @@ begin
   FHMAC.TransformBytes(input, inOff, len);
 end;
 
+procedure THMac.Clear();
+begin
+  FHMAC.Clear();
+end;
+
 constructor THMac.Create(const digest: IDigest);
 begin
   Inherited Create();
@@ -98,6 +107,12 @@ begin
   FHMAC := THashFactory.THMac.CreateHMAC(FDigest.GetUnderlyingIHash);
 end;
 
+destructor THMac.Destroy;
+begin
+  Clear();
+  inherited Destroy;
+end;
+
 function THMac.DoFinal(const output: TCryptoLibByteArray; outOff: Int32): Int32;
 var
   buf: TCryptoLibByteArray;

+ 1 - 1
src/libraries/cryptolib4pascal/ClpHMacDsaKCalculator.pas

@@ -128,7 +128,7 @@ var
 begin
   Fn := n;
   TArrayUtils.Fill(FV, 0, System.Length(FV), Byte($01));
-  TArrayUtils.Fill(FK, 0, System.Length(FK), Byte(0));
+  TArrayUtils.ZeroFill(FK);
 
   size := TBigIntegers.GetUnsignedByteLength(n);
   System.SetLength(x, size);

+ 9 - 78
src/libraries/cryptolib4pascal/ClpIArgon2ParametersGenerator.pas

@@ -22,94 +22,25 @@ unit ClpIArgon2ParametersGenerator;
 interface
 
 uses
-  HlpIHashInfo,
-  HlpArgon2TypeAndVersion,
-  ClpICipherParameters,
+  ClpIPbeParametersGenerator,
   ClpCryptoLibTypes;
 
 type
 {$SCOPEDENUMS ON}
-  TArgon2Type = HlpArgon2TypeAndVersion.TArgon2Type;
-  TArgon2Version = HlpArgon2TypeAndVersion.TArgon2Version;
-  TArgon2MemoryCostType = (a2mctMemoryAsKB, a2mctMemoryPowOfTwo);
+  TCryptoLibArgon2Type = (Argon2D = $00, Argon2I = $01, Argon2ID = $02);
+  TCryptoLibArgon2Version = (Argon2Version10 = $10, Argon2Version13 = $13);
+  TCryptoLibArgon2MemoryCostType = (MemoryAsKB, MemoryPowOfTwo);
 {$SCOPEDENUMS OFF}
 
 type
-  IArgon2ParametersGenerator = interface(IInterface)
+  IArgon2ParametersGenerator = interface(IPbeParametersGenerator)
 
     ['{0AC3D3A8-9422-405F-B0EE-6B7AE0F64F74}']
 
-    procedure Init(argon2Type: TArgon2Type; argon2Version: TArgon2Version;
-      const password, salt, secret, additional: TCryptoLibByteArray;
-      iterations, memory, parallelism: Int32;
-      memoryCostType: TArgon2MemoryCostType);
-
-    /// <returns>
-    /// the password byte array.
-    /// </returns>
-    function GetPassword: TCryptoLibByteArray;
-
-    /// <value>
-    /// the password byte array.
-    /// </value>
-    property password: TCryptoLibByteArray read GetPassword;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    function GetArgon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder;
-
-    /// <returns>
-    /// the Argon2 Parameter Builder Instance
-    /// </returns>
-    property Argon2ParametersBuilder: HlpIHashInfo.IArgon2ParametersBuilder
-      read GetArgon2ParametersBuilder;
-
-    /// <summary>
-    /// Generate derived parameters for a key of length keySize.
-    /// </summary>
-    /// <param name="algorithm">
-    /// a parameters object representing a key.
-    /// </param>
-    /// <param name="keySize">
-    /// the length, in bits, of the key required.
-    /// </param>
-    /// <returns>
-    /// a parameters object representing a key.
-    /// </returns>
-    function GenerateDerivedParameters(const algorithm: String; keySize: Int32)
-      : ICipherParameters; overload;
-
-    /// <summary>
-    /// Generate derived parameters for a key of length keySize and iv
-    /// of length ivSize.
-    /// </summary>
-    /// <param name="algorithm">
-    /// a parameters object representing a key.
-    /// </param>
-    /// <param name="keySize">
-    /// the length, in bits, of the key required.
-    /// </param>
-    /// <param name="ivSize">
-    /// the length, in bits, of the iv required.
-    /// </param>
-    /// <returns>
-    /// a parameters object representing a key and an iv.
-    /// </returns>
-    function GenerateDerivedParameters(const algorithm: String;
-      keySize, ivSize: Int32): ICipherParameters; overload;
-
-    /// <summary>
-    /// Generate derived parameters for a key of length keySize,
-    /// specifically <br />for use with a MAC.
-    /// </summary>
-    /// <param name="keySize">
-    /// the length, in bits, of the key required.
-    /// </param>
-    /// <returns>
-    /// a parameters object representing a key.
-    /// </returns>
-    function GenerateDerivedMacParameters(keySize: Int32): ICipherParameters;
+    procedure Init(argon2Type: TCryptoLibArgon2Type;
+      argon2Version: TCryptoLibArgon2Version; const password, salt, secret,
+      additional: TCryptoLibByteArray; iterations, memory, parallelism: Int32;
+      memoryCostType: TCryptoLibArgon2MemoryCostType);
 
   end;
 

+ 2 - 2
src/libraries/cryptolib4pascal/ClpIAsn1Objects.pas

@@ -207,7 +207,7 @@ type
 
     function GetCount: Int32;
     function GetParser: IAsn1SequenceParser;
-    function GetSelf(Index: Integer): IAsn1Encodable;
+    function GetSelf(Index: Int32): IAsn1Encodable;
     function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
 
     procedure AddObject(const obj: IAsn1Encodable);
@@ -294,7 +294,7 @@ type
 
     function GetCount: Int32;
     function GetParser: IAsn1SetParser;
-    function GetSelf(Index: Integer): IAsn1Encodable;
+    function GetSelf(Index: Int32): IAsn1Encodable;
     function GetCurrent(const e: IAsn1Encodable): IAsn1Encodable;
 
     function ToString(): String;

+ 73 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  IDHBasicKeyPairGenerator = interface(IAsymmetricCipherKeyPairGenerator)
+    ['{F8C67480-A3D5-45AC-BEB1-DA3C484844EC}']
+  end;
+
+implementation
+
+end.

+ 51 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricCipherKeyPairGenerator;
+
+type
+  IDHKeyPairGenerator = interface(IAsymmetricCipherKeyPairGenerator)
+    ['{016112AA-A9AD-43E3-A3AA-25428682396F}']
+  end;
+
+implementation
+
+end.

+ 44 - 0
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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
src/libraries/cryptolib4pascal/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 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.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpIDsaParameter.pas

@@ -26,7 +26,7 @@ uses
   ClpBigInteger;
 
 type
-  IDsaParameter = interface(IAsn1Convertible)
+  IDsaParameter = interface(IAsn1Encodable)
     ['{037E0113-0BD6-4A61-8BDC-DBEBE6136A6C}']
 
     function GetP: TBigInteger;

+ 7 - 3
src/libraries/cryptolib4pascal/ClpIESCipher.pas

@@ -103,9 +103,13 @@ implementation
 
 function TIESCipher.Aggregate: TCryptoLibByteArray;
 begin
-  FBuffer.Position := 0;
-  System.SetLength(Result, FBuffer.Size);
-  FBuffer.Read(Result[0], FBuffer.Size);
+  Result := Nil;
+  if FBuffer.Size > 0 then
+  begin
+    FBuffer.Position := 0;
+    System.SetLength(Result, FBuffer.Size);
+    FBuffer.Read(Result[0], FBuffer.Size);
+  end;
 end;
 
 constructor TIESCipher.Create(const Engine: IIESEngine; ivLength: Int32);

+ 2 - 2
src/libraries/cryptolib4pascal/ClpIESEngine.pas

@@ -608,7 +608,7 @@ begin
   if (System.Length(FV) <> 0) then
   begin
     VZ := TArrayUtils.Concatenate(FV, BigZ);
-    TArrayUtils.Fill(BigZ, 0, System.Length(BigZ), Byte(0));
+    TArrayUtils.ZeroFill(BigZ);
     BigZ := VZ;
   end;
 
@@ -629,7 +629,7 @@ begin
     end;
 
   finally
-    TArrayUtils.Fill(BigZ, 0, System.Length(BigZ), Byte(0));
+    TArrayUtils.ZeroFill(BigZ);
   end;
 end;
 

+ 2 - 0
src/libraries/cryptolib4pascal/ClpIMac.pas

@@ -35,6 +35,8 @@ type
   IMac = interface(IInterface)
     ['{3273EF2F-AE51-4878-B55C-5F801DB85A74}']
 
+    procedure Clear();
+
     /// <summary>
     /// returns the name of the algorithm the MAC implements.
     /// </summary>

+ 1 - 32
src/libraries/cryptolib4pascal/ClpIPbeParametersGenerator.pas

@@ -30,38 +30,7 @@ type
 
     ['{8C530FB2-6B8F-4E22-8EA0-D538665471EF}']
 
-    procedure Init(const password, salt: TCryptoLibByteArray;
-      iterationCount: Int32);
-
-    /// <returns>
-    /// the password byte array.
-    /// </returns>
-    function GetPassword: TCryptoLibByteArray;
-
-    /// <value>
-    /// the password byte array.
-    /// </value>
-    property password: TCryptoLibByteArray read GetPassword;
-
-    /// <returns>
-    /// the salt byte array.
-    /// </returns>
-    function GetSalt: TCryptoLibByteArray;
-
-    /// <value>
-    /// the salt byte array.
-    /// </value>
-    property salt: TCryptoLibByteArray read GetSalt;
-
-    /// <returns>
-    /// the iteration count.
-    /// </returns>
-    function GetIterationCount: Int32;
-
-    /// <value>
-    /// the iteration count.
-    /// </value>
-    property iterationCount: Int32 read GetIterationCount;
+    procedure Clear();
 
     /// <summary>
     /// Generate derived parameters for a key of length keySize.

+ 5 - 1
src/libraries/cryptolib4pascal/ClpIPkcs5S2ParametersGenerator.pas

@@ -23,13 +23,17 @@ interface
 
 uses
   ClpIPbeParametersGenerator,
-  ClpIDigest;
+  ClpIDigest,
+  ClpCryptoLibTypes;
 
 type
   IPkcs5S2ParametersGenerator = interface(IPbeParametersGenerator)
 
     ['{AD345DB8-2341-4C56-B401-23444C2A81BA}']
 
+    procedure Init(const password, salt: TCryptoLibByteArray;
+      iterationCount: Int32);
+
     function GetDigest: IDigest;
 
     /// <value>

+ 40 - 0
src/libraries/cryptolib4pascal/ClpIScryptParametersGenerator.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 ClpIScryptParametersGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+  ClpIPbeParametersGenerator,
+  ClpCryptoLibTypes;
+
+type
+  IScryptParametersGenerator = interface(IPbeParametersGenerator)
+
+    ['{1EB9E081-1F90-409F-A5B9-3A999EB6CC70}']
+
+    procedure Init(const password, salt: TCryptoLibByteArray;
+      cost, blockSize, parallelism: Int32);
+
+  end;
+
+implementation
+
+end.

+ 1 - 1
src/libraries/cryptolib4pascal/ClpKeyParameter.pas

@@ -67,7 +67,7 @@ end;
 
 procedure TKeyParameter.Clear;
 begin
-  TArrayUtils.Fill(Fkey, 0, System.Length(Fkey), Byte(0));
+  TArrayUtils.ZeroFill(Fkey);
 end;
 
 constructor TKeyParameter.Create(const key: TCryptoLibByteArray;

+ 12 - 1
src/libraries/cryptolib4pascal/ClpMiscObjectIdentifiers.pas

@@ -37,7 +37,7 @@ type
       Fcryptlib_algorithm_blowfish_CBC, Fcryptlib_algorithm_blowfish_CFB,
       Fcryptlib_algorithm_blowfish_OFB, Fblake2, Fid_blake2b160, Fid_blake2b256,
       Fid_blake2b384, Fid_blake2b512, Fid_blake2s128, Fid_blake2s160,
-      Fid_blake2s224, Fid_blake2s256: IDerObjectIdentifier;
+      Fid_blake2s224, Fid_blake2s256, Fid_scrypt: IDerObjectIdentifier;
 
     class function Getcryptlib: IDerObjectIdentifier; static; inline;
 
@@ -63,6 +63,8 @@ type
     class function Getid_blake2s224: IDerObjectIdentifier; static; inline;
     class function Getid_blake2s256: IDerObjectIdentifier; static; inline;
 
+    class function Getid_scrypt: IDerObjectIdentifier; static; inline;
+
     class constructor MiscObjectIdentifiers();
 
   public
@@ -92,6 +94,8 @@ type
     class property id_blake2s224: IDerObjectIdentifier read Getid_blake2s224;
     class property id_blake2s256: IDerObjectIdentifier read Getid_blake2s256;
 
+    class property id_scrypt: IDerObjectIdentifier read Getid_scrypt;
+
     class procedure Boot(); static;
 
   end;
@@ -180,6 +184,11 @@ begin
   result := Fid_blake2s256;
 end;
 
+class function TMiscObjectIdentifiers.Getid_scrypt: IDerObjectIdentifier;
+begin
+  result := Fid_scrypt;
+end;
+
 class procedure TMiscObjectIdentifiers.Boot;
 begin
 
@@ -213,6 +222,8 @@ begin
     Fid_blake2s224 := blake2.Branch('2.7');
     Fid_blake2s256 := blake2.Branch('2.8');
 
+    Fid_scrypt := TDerObjectIdentifier.Create('1.3.6.1.4.1.11591.4.11');
+
     FIsBooted := True;
   end;
 end;

+ 298 - 110
src/libraries/cryptolib4pascal/ClpOSRandom.pas

@@ -22,33 +22,65 @@ unit ClpOSRandom;
 interface
 
 uses
-{$IF DEFINED(MSWINDOWS)}
+{$IFDEF CRYPTOLIB_MSWINDOWS}
   Windows,
-  SysUtils,
-{$ELSEIF DEFINED(IOSDELPHI)}
-  // iOS stuffs for Delphi
-  Macapi.Dispatch,
-  iOSapi.Foundation,
-{$ELSEIF DEFINED(IOSFPC)}
-  // iOS stuffs for FreePascal
+{$ENDIF} // ENDIF CRYPTOLIB_MSWINDOWS
+{$IFDEF CRYPTOLIB_APPLE}
+{$IFDEF FPC}
 {$LINKFRAMEWORK Security}
 {$ELSE}
+  // Macapi.Dispatch, or
+  Macapi.ObjCRuntime,
+{$IF DEFINED(CRYPTOLIB_IOS)}
+  iOSapi.Foundation,
+{$ELSEIF DEFINED(CRYPTOLIB_MACOS)}
+  Macapi.Foundation,
+{$ELSE}
+{$MESSAGE ERROR 'UNSUPPORTED TARGET.'}
+{$IFEND} // ENDIF CRYPTOLIB_MACOS
+{$ENDIF}  // ENDIF FPC
+{$ENDIF}   // ENDIF CRYPTOLIB_APPLE
+{$IFDEF CRYPTOLIB_LINUX}
+{$IFDEF FPC}
+  BaseUnix,
+  dl,
+{$ELSE}
+  Posix.Errno,
+  Posix.Dlfcn,
+{$ENDIF}
+{$ENDIF}  // ENDIF CRYPTOLIB_LINUX
+{$IFDEF CRYPTOLIB_PUREBSD}
+  // PureBSD (NetBSD, FreeBSD, OpenBSD)
+{$ENDIF}  // ENDIF CRYPTOLIB_PUREBSD
+{$IFDEF CRYPTOLIB_UNIX}
   Classes,
+{$ENDIF}  // ENDIF CRYPTOLIB_UNIX
+{$IF DEFINED(CRYPTOLIB_MSWINDOWS) OR DEFINED(CRYPTOLIB_UNIX)}
   SysUtils,
-{$IFEND MSWINDOWS}
+{$IFEND}  // ENDIF CRYPTOLIB_MSWINDOWS OR CRYPTOLIB_UNIX
   ClpCryptoLibTypes;
 
 resourcestring
-{$IF DEFINED(MSWINDOWS)}
+{$IFDEF CRYPTOLIB_MSWINDOWS}
   SMSWIndowsCryptographyAPIGenerationError =
     'An Error Occured while generating random data using MS WIndows Cryptography API.';
-{$ELSEIF (DEFINED(IOSDELPHI) OR DEFINED(IOSFPC))}
-  SIOSSecRandomCopyBytesGenerationError =
+{$ENDIF}
+{$IFDEF CRYPTOLIB_APPLE}
+  SAppleSecRandomCopyBytesGenerationError =
     'An Error Occured while generating random data using SecRandomCopyBytes API.';
-{$ELSE}
-  SUnixRandomReadError =
-    'An Error Occured while reading random data from /dev/urandom or /dev/random.';
-{$IFEND MSWINDOWS}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_LINUX}
+  SLinuxGetRandomError =
+    'An Error Occured while generating random data using getRandom API';
+{$ENDIF}
+{$IFDEF CRYPTOLIB_GENERIC_BSD}
+  SArc4RandomBufGenerationError =
+    'An Error Occured while generating random data using getRandom API.';
+{$ENDIF}
+{$IFDEF CRYPTOLIB_UNIX}
+  SRandomDeviceReadError =
+    'An Error Occured while reading random data from random device (file)';
+{$ENDIF}
 
 type
 
@@ -59,23 +91,83 @@ type
   /// <para>
   /// This class returns random bytes from an OS-specific randomness
   /// source. The returned data should be unpredictable enough for
-  /// cryptographic applications, though its exact quality depends on the
-  /// OS implementation.
-  /// On a UNIX-like system this will read directly from /dev/urandom or /dev/random
-  /// (if the former is not available),
-  /// on iOS, calls SecRandomCopyBytes as /dev/(u)random is sandboxed,
-  /// on MSWINDOWS it will call CryptGenRandom().
+  /// cryptographic applications, though it's exact quality depends on
+  /// the OS implementation.
   /// </para>
+  /// <list type="table">
+  /// <listheader>
+  /// <term>OS</term>
+  /// <description>Interface</description>
+  /// </listheader>
+  /// <item>
+  /// <term>Linux, Android</term>
+  /// <description><see href="http://man7.org/linux/man-pages/man2/getrandom.2.html">
+  /// getrandom</see> system call if available, otherwise ( <b>
+  /// /dev/urandom</b> or <b>/dev/random</b>) (which ever is
+  /// available)</description>
+  /// </item>
+  /// <item>
+  /// <term>Windows</term>
+  /// <description><see href="https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/nf-wincrypt-cryptgenrandom">
+  /// CryptGenRandom</see> for <b>XP</b>, <see href="https://docs.microsoft.com/en-us/windows/desktop/api/bcrypt/nf-bcrypt-bcryptgenrandom">
+  /// BCryptGenRandom</see> for <b>Vista</b> Upwards</description>
+  /// </item>
+  /// <item>
+  /// <term>macOS, iOS</term>
+  /// <description><see href="https://developer.apple.com/documentation/security/1399291-secrandomcopybytes?language=objc">
+  /// SecRandomCopyBytes</see><br /></description>
+  /// </item>
+  /// <item>
+  /// <term>FreeBSD</term>
+  /// <description><see href="https://www.freebsd.org/cgi/man.cgi?query=arc4random&amp;sektion=3&amp;manpath=FreeBSD+12.0-RELEASE+and+Ports">
+  /// arc4random_buf</see></description>
+  /// </item>
+  /// <item>
+  /// <term>NetBSD</term>
+  /// <description><see href="https://www.netbsd.org/~riastradh/tmp/20141116/arc4random.html">
+  /// arc4random_buf</see></description>
+  /// </item>
+  /// <item>
+  /// <term>OpenBSD</term>
+  /// <description><see href="http://man.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/arc4random.3">
+  /// arc4random_buf</see></description>
+  /// </item>
+  /// <item>
+  /// <term>DragonFly</term>
+  /// <description><see href="https://www.dragonflybsd.org/cgi/web-man?command=arc4random&amp;section=3">
+  /// arc4random_buf</see></description>
+  /// </item>
+  /// </list>
   /// </summary>
-
   TOSRandom = class sealed(TObject)
 
   strict private
 
-    class function NoZeroes(const data: TCryptoLibByteArray): Boolean;
-      static; inline;
+    // ================================================================//
+
+{$IFDEF CRYPTOLIB_LINUX}
+  type
+    TGetRandom = function(pbBuffer: PByte; buflen: LongWord; flags: UInt32)
+      : Int32; cdecl;
+
+  class var
+
+    FIsGetRandomSupportedOnOS: Boolean;
+    FGetRandom: TGetRandom;
+
+    class function ErrorNo: Int32; static; inline;
 
-{$IF DEFINED(MSWINDOWS)}
+    class function GetIsGetRandomSupportedOnOS(): Boolean; static; inline;
+
+    class function IsGetRandomAvailable(): Boolean; static;
+
+    class property IsGetRandomSupportedOnOS: Boolean
+      read GetIsGetRandomSupportedOnOS;
+
+{$ENDIF}
+    // ================================================================//
+
+{$IFDEF CRYPTOLIB_MSWINDOWS}
 
   type
     BCRYPT_ALG_HANDLE = THandle;
@@ -101,30 +193,46 @@ type
       static; inline;
 
     class function IsCngBCryptGenRandomAvailable(): Boolean; static;
-    class function GenRandomBytesWindows(len: Int32; const data: PByte)
+    class function GenRandomBytesWindows(len: Int32; data: PByte)
       : Int32; static;
     class property IsCngBCryptGenRandomSupportedOnOS: Boolean
       read GetIsCngBCryptGenRandomSupportedOnOS;
-{$ELSEIF DEFINED(IOSDELPHI)}
-    class function GenRandomBytesIOSDelphi(len: Int32; const data: PByte)
+{$ENDIF}
+
+    // ================================================================//
+{$IFDEF CRYPTOLIB_APPLE}
+    class function GenRandomBytesApple(len: Int32; data: PByte): Int32; static;
+{$ENDIF}
+    // ================================================================//
+{$IFDEF CRYPTOLIB_LINUX}
+    class function GenRandomBytesLinux(len: Int32; data: PByte): Int32; static;
+{$ENDIF}
+    // ================================================================//
+{$IFDEF CRYPTOLIB_GENERIC_BSD}
+    class function GenRandomBytesGenericBSD(len: Int32; data: PByte)
       : Int32; static;
-{$ELSEIF DEFINED(IOSFPC)}
-    class function GenRandomBytesIOSFPC(len: Int32; const data: PByte)
+{$ENDIF}
+    // ================================================================//
+{$IFDEF CRYPTOLIB_UNIX}
+    class function dev_random_device_read(len: Int32; data: PByte)
       : Int32; static;
-{$ELSE}
-    class function GenRandomBytesUnix(len: Int32; const data: PByte)
-      : Int32; static;
-{$IFEND $MSWINDOWS}
+{$ENDIF}
+    // ================================================================//
+
+    class function NoZeroes(const data: TCryptoLibByteArray): Boolean;
+      static; inline;
     class procedure Boot(); static;
     class constructor OSRandom();
-  public
 
+  public
     class procedure GetBytes(const data: TCryptoLibByteArray); static;
     class procedure GetNonZeroBytes(const data: TCryptoLibByteArray); static;
 
   end;
 
-{$IFDEF MSWINDOWS}
+  // ************************************************************************//
+
+{$IFDEF CRYPTOLIB_MSWINDOWS}
 
 const
   ADVAPI32 = 'advapi32.dll';
@@ -138,61 +246,42 @@ function CryptGenRandom(hProv: THandle; dwLen: DWORD; pbBuffer: PByte): BOOL;
 
 function CryptReleaseContext(hProv: THandle; dwFlags: DWORD): BOOL; stdcall;
   external ADVAPI32 Name 'CryptReleaseContext';
-{$ENDIF MSWINDOWS}
-{$IFDEF IOSDELPHI}
-
-type
-  SecRandomRef = Pointer;
-
-const
-  libSecurity = '/System/Library/Frameworks/Security.framework/Security';
-
-function kSecRandomDefault: Pointer;
-
-function SecRandomCopyBytes(rnd: SecRandomRef; count: LongWord; bytes: PByte)
-  : Integer; cdecl; external libSecurity Name _PU + 'SecRandomCopyBytes';
-{$ENDIF IOSDELPHI}
-{$IFDEF IOSFPC}
+{$ENDIF}
+// ************************************************************************//
+{$IFDEF CRYPTOLIB_APPLE}
+{$IFDEF FPC}
 
 type
   // similar to a TOpaqueData already defined in newer FPC but not available in 3.0.4
   __SecRandom = record
   end;
 
-  // similar to an OpaquePointer already defined in newer FPC but not available in 3.0.4
+  // similar to POpaqueData (or an OpaquePointer) already defined in newer FPC but not available in 3.0.4
   SecRandomRef = ^__SecRandom;
 
-const
-  { * This is a synonym for NULL, if you'd rather use a named constant.   This
-    refers to a cryptographically secure random number generator.  * }
-  kSecRandomDefault: SecRandomRef = Nil;
-
 function SecRandomCopyBytes(rnd: SecRandomRef; count: LongWord; bytes: PByte)
-  : Integer; cdecl; external;
+  : Int32; cdecl; external;
 
-{$ENDIF IOSFPC}
+{$ELSE}
 
-implementation
+type
+  SecRandomRef = Pointer;
 
-class procedure TOSRandom.Boot;
-begin
-{$IFDEF MSWINDOWS}
-  FIsCngBCryptGenRandomSupportedOnOS := IsCngBCryptGenRandomAvailable();
-{$ENDIF MSWINDOWS}
-end;
+const
+  libSecurity = '/System/Library/Frameworks/Security.framework/Security';
 
-class constructor TOSRandom.OSRandom;
-begin
-  TOSRandom.Boot();
-end;
+function SecRandomCopyBytes(rnd: SecRandomRef; count: LongWord; bytes: PByte)
+  : Int32; cdecl; external libSecurity Name _PU + 'SecRandomCopyBytes';
 
-{$IFDEF IOSDELPHI}
+{$ENDIF}
+{$ENDIF}
+// ************************************************************************//
+{$IFDEF CRYPTOLIB_GENERIC_BSD}
+procedure arc4random_buf(bytes: PByte; count: LongWord); cdecl; external;
+// 'c' name 'arc4random_buf';
+{$ENDIF}
 
-function kSecRandomDefault: Pointer;
-begin
-  result := CocoaPointerConst(libSecurity, 'kSecRandomDefault');
-end;
-{$ENDIF IOSDELPHI}
+implementation
 
 class function TOSRandom.NoZeroes(const data: TCryptoLibByteArray): Boolean;
 var
@@ -207,10 +296,24 @@ begin
       Exit;
     end;
   end;
+end;
 
+class procedure TOSRandom.Boot;
+begin
+{$IFDEF CRYPTOLIB_MSWINDOWS}
+  FIsCngBCryptGenRandomSupportedOnOS := IsCngBCryptGenRandomAvailable();
+{$ENDIF}
+{$IFDEF CRYPTOLIB_LINUX}
+  FIsGetRandomSupportedOnOS := IsGetRandomAvailable();
+{$ENDIF}
+end;
+
+class constructor TOSRandom.OSRandom;
+begin
+  TOSRandom.Boot();
 end;
 
-{$IF DEFINED(MSWINDOWS)}
+{$IFDEF CRYPTOLIB_MSWINDOWS}
 
 class function TOSRandom.GetIsCngBCryptGenRandomSupportedOnOS(): Boolean;
 begin
@@ -247,8 +350,7 @@ begin
   end;
 end;
 
-class function TOSRandom.GenRandomBytesWindows(len: Int32;
-  const data: PByte): Int32;
+class function TOSRandom.GenRandomBytesWindows(len: Int32; data: PByte): Int32;
 
   function BCRYPT_SUCCESS(AStatus: NTStatus): Boolean; inline;
   begin
@@ -277,7 +379,7 @@ begin
 
     try
       if (not BCRYPT_SUCCESS(FBCryptGenRandom(hProv, PUCHAR(data),
-        LongWord(len), 0))) then
+        ULONG(len), 0))) then
       begin
         result := HResultFromWin32(GetLastError);
         Exit;
@@ -297,7 +399,7 @@ begin
     end;
 
     try
-      if not CryptGenRandom(hProv, len, data) then
+      if not CryptGenRandom(hProv, DWORD(len), data) then
       begin
         result := HResultFromWin32(GetLastError);
         Exit;
@@ -309,26 +411,28 @@ begin
   result := S_OK;
 end;
 
-{$ELSEIF DEFINED(IOSDELPHI)}
+{$ENDIF}
+{$IFDEF CRYPTOLIB_APPLE}
 
-class function TOSRandom.GenRandomBytesIOSDelphi(len: Int32;
-  const data: PByte): Int32;
-begin
-  result := SecRandomCopyBytes(kSecRandomDefault, LongWord(len), data);
-end;
+class function TOSRandom.GenRandomBytesApple(len: Int32; data: PByte): Int32;
 
-{$ELSEIF DEFINED(IOSFPC)}
+  function kSecRandomDefault: SecRandomRef;
+  begin
+{$IFDEF FPC}
+    result := Nil;
+{$ELSE}
+    result := CocoaPointerConst(libSecurity, 'kSecRandomDefault');
+{$ENDIF}
+  end;
 
-class function TOSRandom.GenRandomBytesIOSFPC(len: Int32;
-  const data: PByte): Int32;
 begin
-  // UNTESTED !!!, Please Take Note.
   result := SecRandomCopyBytes(kSecRandomDefault, LongWord(len), data);
 end;
-{$ELSE}
 
-class function TOSRandom.GenRandomBytesUnix(len: Int32;
-  const data: PByte): Int32;
+{$ENDIF}
+{$IFDEF CRYPTOLIB_UNIX}
+
+class function TOSRandom.dev_random_device_read(len: Int32; data: PByte): Int32;
 var
   LStream: TFileStream;
   RandGen: String;
@@ -357,41 +461,125 @@ begin
     LStream.Free;
   end;
 end;
+{$ENDIF}
+{$IFDEF CRYPTOLIB_LINUX}
 
-{$IFEND MSWINDOWS}
+class function TOSRandom.ErrorNo: Int32;
+begin
+  result := Errno;
+end;
+
+class function TOSRandom.GetIsGetRandomSupportedOnOS(): Boolean;
+begin
+  result := FIsGetRandomSupportedOnOS;
+end;
+
+class function TOSRandom.IsGetRandomAvailable(): Boolean;
+const
+  LIBC_SO_6 = 'libc.so.6';
+var
+  Lib: {$IFDEF FPC} PtrInt {$ELSE} NativeUInt {$ENDIF};
+begin
+  FGetRandom := Nil;
+  Lib := {$IFDEF FPC}PtrInt{$ENDIF}(dlopen(LIBC_SO_6, RTLD_NOW));
+  if Lib <> 0 then
+  begin
+    FGetRandom := dlsym(Lib, 'getrandom');
+    dlclose(Lib);
+  end;
+  result := System.Assigned(FGetRandom);
+end;
+
+class function TOSRandom.GenRandomBytesLinux(len: Int32; data: PByte): Int32;
+const
+  GRND_DEFAULT: Int32 = $0000;
+  EINTR = {$IFDEF FPC}ESysEINTR {$ELSE}Posix.Errno.EINTR{$ENDIF};
+var
+  n: Int64;
+begin
+  if IsGetRandomSupportedOnOS then
+  begin
+    while (len > 0) do
+    begin
+
+      repeat
+        n := FGetRandom(data, LongWord(len), GRND_DEFAULT);
+      until ((n > 0) and (ErrorNo <> EINTR));
+
+      if (n <= 0) then
+      begin
+        result := -1;
+        Exit;
+      end;
+      System.Inc(data, n);
+      System.Dec(len, n);
+    end;
+    result := 0;
+  end
+  else
+  begin
+    // fallback for when getrandom API is not available
+    result := dev_random_device_read(len, data);
+  end;
+end;
+
+{$ENDIF}
+{$IFDEF CRYPTOLIB_GENERIC_BSD}
+
+class function TOSRandom.GenRandomBytesGenericBSD(len: Int32;
+  data: PByte): Int32;
+
+begin
+  arc4random_buf(data, LongWord(len));
+  result := 0;
+end;
+{$ENDIF}
 
 class procedure TOSRandom.GetBytes(const data: TCryptoLibByteArray);
 var
   count: Int32;
 begin
   count := System.Length(data);
-{$IF DEFINED(MSWINDOWS)}
+
+  if count <= 0 then
+  begin
+    Exit;
+  end;
+
+{$IF DEFINED(CRYPTOLIB_MSWINDOWS)}
   if GenRandomBytesWindows(count, PByte(data)) <> 0 then
   begin
-    raise EAccessCryptoLibException.CreateRes
+    raise EOSRandomCryptoLibException.CreateRes
       (@SMSWIndowsCryptographyAPIGenerationError);
   end;
 
-{$ELSEIF DEFINED(IOSDELPHI)}
-  if GenRandomBytesIOSDelphi(count, PByte(data)) <> 0 then
+{$ELSEIF DEFINED(CRYPTOLIB_APPLE)}
+  if GenRandomBytesApple(count, PByte(data)) <> 0 then
   begin
-    raise EAccessCryptoLibException.CreateRes
-      (@SIOSSecRandomCopyBytesGenerationError);
+    raise EOSRandomCryptoLibException.CreateRes
+      (@SAppleSecRandomCopyBytesGenerationError);
   end;
 
-{$ELSEIF DEFINED(IOSFPC)}
-  if GenRandomBytesIOSFPC(count, PByte(data)) <> 0 then
+{$ELSEIF DEFINED(CRYPTOLIB_LINUX)}
+  if GenRandomBytesLinux(count, PByte(data)) <> 0 then
   begin
-    raise EAccessCryptoLibException.CreateRes
-      (@SIOSSecRandomCopyBytesGenerationError);
+    raise EOSRandomCryptoLibException.CreateRes(@SLinuxGetRandomError);
   end;
 
-{$ELSE}
-  if GenRandomBytesUnix(count, PByte(data)) <> 0 then
+{$ELSEIF DEFINED(CRYPTOLIB_GENERIC_BSD)}
+  if GenRandomBytesGenericBSD(count, PByte(data)) <> 0 then
   begin
-    raise EAccessCryptoLibException.CreateRes(@SUnixRandomReadError);
+    raise EOSRandomCryptoLibException.CreateRes(@SArc4RandomBufGenerationError);
   end;
-{$IFEND MSWINDOWS}
+{$ELSEIF DEFINED(CRYPTOLIB_UNDEFINED_UNIX_VARIANTS)}
+  // fallback option for other Undefined Unix OSes
+  if dev_random_device_read(count, PByte(data)) <> 0 then
+  begin
+    raise EOSRandomCryptoLibException.CreateRes(@SRandomDeviceReadError);
+  end;
+{$ELSE}
+{$MESSAGE ERROR 'UNSUPPORTED TARGET.'}
+{$IFEND}
 end;
 
 class procedure TOSRandom.GetNonZeroBytes(const data: TCryptoLibByteArray);

+ 1 - 1
src/libraries/cryptolib4pascal/ClpParameterUtilities.pas

@@ -111,7 +111,7 @@ end;
 class procedure TParameterUtilities.Boot;
 begin
   Falgorithms := TDictionary<String, String>.Create();
-  FbasicIVSizes := TDictionary<string, Integer>.Create();
+  FbasicIVSizes := TDictionary<string, Int32>.Create();
 
   TNistObjectIdentifiers.Boot;
 

+ 1 - 1
src/libraries/cryptolib4pascal/ClpParametersWithIV.pas

@@ -66,7 +66,7 @@ end;
 
 procedure TParametersWithIV.Clear;
 begin
-  TArrayUtils.Fill(Fiv, 0, System.Length(Fiv), Byte(0));
+  TArrayUtils.ZeroFill(Fiv);
 end;
 
 constructor TParametersWithIV.Create(const parameters: ICipherParameters;

+ 1 - 1
src/libraries/cryptolib4pascal/ClpPascalCoinIESEngine.pas

@@ -313,7 +313,7 @@ begin
     end;
 
   finally
-    TArrayUtils.Fill(BigZ, 0, System.Length(BigZ), Byte(0));
+    TArrayUtils.ZeroFill(BigZ);
   end;
 end;
 

+ 2 - 83
src/libraries/cryptolib4pascal/ClpPbeParametersGenerator.pas

@@ -23,13 +23,7 @@ interface
 
 uses
   ClpICipherParameters,
-  ClpIPbeParametersGenerator,
-  ClpCryptoLibTypes;
-
-resourcestring
-  SEmptyPassword = 'Password can''t be empty';
-  SEmptySalt = 'Salt can''t be empty';
-  SIterationtooSmall = 'Iteration must be greater than zero.';
+  ClpIPbeParametersGenerator;
 
 type
 
@@ -40,45 +34,9 @@ type
   TPbeParametersGenerator = class abstract(TInterfacedObject,
     IPbeParametersGenerator)
 
-  strict protected
-  var
-    FmPassword, FmSalt: TCryptoLibByteArray;
-    FmIterationCount: Int32;
-
-    /// <returns>
-    /// the password byte array.
-    /// </returns>
-    function GetPassword: TCryptoLibByteArray; virtual;
-
-    /// <returns>
-    /// the salt byte array.
-    /// </returns>
-    function GetSalt: TCryptoLibByteArray; virtual;
-
-    /// <returns>
-    /// the iteration count.
-    /// </returns>
-    function GetIterationCount: Int32; virtual;
-
   public
 
-    procedure Init(const password, salt: TCryptoLibByteArray;
-      iterationCount: Int32); virtual;
-
-    /// <value>
-    /// the password byte array.
-    /// </value>
-    property password: TCryptoLibByteArray read GetPassword;
-
-    /// <value>
-    /// the salt byte array.
-    /// </value>
-    property salt: TCryptoLibByteArray read GetSalt;
-
-    /// <value>
-    /// the iteration count.
-    /// </value>
-    property iterationCount: Int32 read GetIterationCount;
+    procedure Clear(); virtual; abstract;
 
     /// <summary>
     /// Generate derived parameters for a key of length keySize.
@@ -131,43 +89,4 @@ type
 
 implementation
 
-{ TPbeParametersGenerator }
-
-function TPbeParametersGenerator.GetIterationCount: Int32;
-begin
-  result := FmIterationCount;
-end;
-
-function TPbeParametersGenerator.GetPassword: TCryptoLibByteArray;
-begin
-  result := System.Copy(FmPassword);
-end;
-
-function TPbeParametersGenerator.GetSalt: TCryptoLibByteArray;
-begin
-  result := System.Copy(FmSalt);
-end;
-
-procedure TPbeParametersGenerator.Init(const password,
-  salt: TCryptoLibByteArray; iterationCount: Int32);
-begin
-
-  if (password = Nil) then
-  begin
-    raise EArgumentNilCryptoLibException.CreateRes(@SEmptyPassword);
-  end;
-
-  if (salt = Nil) then
-  begin
-    raise EArgumentNilCryptoLibException.CreateRes(@SEmptySalt);
-  end;
-
-  if (iterationCount < 1) then
-    raise EArgumentCryptoLibException.CreateRes(@SIterationtooSmall);
-
-  FmPassword := System.Copy(password);
-  FmSalt := System.Copy(salt);
-  FmIterationCount := iterationCount;
-end;
-
 end.

+ 5 - 6
src/libraries/cryptolib4pascal/ClpPcgRandomMinimal.pas

@@ -145,7 +145,7 @@ type
     /// <param name="minimum">The minimum inclusive value.</param>
     /// <param name="exclusiveBound">The maximum exclusive bound.</param>
 
-    class function NextUInt32(minimum: UInt32; exclusiveBound: UInt32): UInt32;
+    class function NextUInt32(minimum, exclusiveBound: UInt32): UInt32;
       overload; inline;
 
     /// <summary>
@@ -155,8 +155,7 @@ type
     /// <param name="minimum">The minimum inclusive value.</param>
     /// <param name="exclusiveBound">The maximum exclusive bound.</param>
 
-    class function NextInt(minimum: Integer; exclusiveBound: Integer)
-      : Integer; inline;
+    class function NextInt(minimum, exclusiveBound: Int32): Int32; inline;
 
   end;
 
@@ -275,18 +274,18 @@ begin
   Seed(LinitState, LinitSeq);
 end;
 
-constructor TPcg.Create(initState: UInt64; initSeq: UInt64);
+constructor TPcg.Create(initState, initSeq: UInt64);
 begin
   Seed(initState, initSeq);
 end;
 
-class function TPcg.NextInt(minimum: Integer; exclusiveBound: Integer): Integer;
+class function TPcg.NextInt(minimum, exclusiveBound: Int32): Int32;
 var
   boundRange, rangeResult: UInt32;
 begin
   boundRange := UInt32(exclusiveBound - minimum);
   rangeResult := Range32(boundRange);
-  result := Integer(rangeResult) + Integer(minimum);
+  result := Int32(rangeResult) + Int32(minimum);
 end;
 
 end.

+ 28 - 5
src/libraries/cryptolib4pascal/ClpPkcs5S2ParametersGenerator.pas

@@ -33,6 +33,7 @@ uses
   ClpParametersWithIV,
   ClpParameterUtilities,
   ClpPbeParametersGenerator,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 type
@@ -46,6 +47,7 @@ type
 
   strict private
   var
+    FPassword, FSalt: TCryptoLibByteArray;
     Fdigest: IDigest;
     FPBKDF2_HMAC: HlpIHashInfo.IPBKDF2_HMAC;
 
@@ -58,6 +60,7 @@ type
 
   public
 
+    procedure Clear(); override;
     /// <summary>
     /// construct a Pkcs5 Scheme 2 Parameters generator.
     /// </summary>
@@ -66,8 +69,10 @@ type
     /// </param>
     constructor Create(const digest: IDigest);
 
+    destructor Destroy; override;
+
     procedure Init(const password, salt: TCryptoLibByteArray;
-      iterationCount: Int32); override;
+      iterationCount: Int32);
 
     /// <summary>
     /// Generate a key parameter derived from the password, salt, and
@@ -116,8 +121,8 @@ type
     /// <returns>
     /// a parameters object representing a key.
     /// </returns>
-    function GenerateDerivedMacParameters(keySize: Int32): ICipherParameters;
-      overload; override;
+    function GenerateDerivedMacParameters(keySize: Int32)
+      : ICipherParameters; override;
 
     /// <value>
     /// the underlying digest.
@@ -129,12 +134,29 @@ implementation
 
 { TPkcs5S2ParametersGenerator }
 
+procedure TPkcs5S2ParametersGenerator.Clear();
+begin
+  TArrayUtils.ZeroFill(FPassword);
+  TArrayUtils.ZeroFill(FSalt);
+
+  if FPBKDF2_HMAC <> Nil then
+  begin
+    FPBKDF2_HMAC.Clear();
+  end;
+end;
+
 constructor TPkcs5S2ParametersGenerator.Create(const digest: IDigest);
 begin
   Inherited Create();
   Fdigest := digest;
 end;
 
+destructor TPkcs5S2ParametersGenerator.Destroy;
+begin
+  Clear();
+  inherited Destroy;
+end;
+
 function TPkcs5S2ParametersGenerator.GenerateDerivedKey(dkLen: Int32)
   : TCryptoLibByteArray;
 begin
@@ -188,9 +210,10 @@ end;
 procedure TPkcs5S2ParametersGenerator.Init(const password,
   salt: TCryptoLibByteArray; iterationCount: Int32);
 begin
-  inherited Init(password, salt, iterationCount);
+  FPassword := System.Copy(password);
+  FSalt := System.Copy(salt);
   FPBKDF2_HMAC := TKDF.TPBKDF2_HMAC.CreatePBKDF2_HMAC
-    (Fdigest.GetUnderlyingIHash, password, salt, iterationCount);
+    (Fdigest.GetUnderlyingIHash, FPassword, FSalt, iterationCount);
 end;
 
 end.

+ 17 - 2
src/libraries/cryptolib4pascal/ClpPkcsObjectIdentifiers.pas

@@ -41,14 +41,21 @@ type
     //
     Pkcs3: String = '1.2.840.113549.1.3';
 
+    //
+    // pkcs-5 OBJECT IDENTIFIER ::= {
+    // iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 5 }
+    //
+    Pkcs5: String = '1.2.840.113549.1.5';
+
   class var
 
     FIsBooted: Boolean;
-    FDhKeyAgreement, FMD2, FMD4, FMD5, FIdHmacWithSha1, FIdHmacWithSha224,
-      FIdHmacWithSha256, FIdHmacWithSha384, FIdHmacWithSha512
+    FDhKeyAgreement, FIdPbkdf2, FMD2, FMD4, FMD5, FIdHmacWithSha1,
+      FIdHmacWithSha224, FIdHmacWithSha256, FIdHmacWithSha384, FIdHmacWithSha512
       : IDerObjectIdentifier;
 
     class function GetDhKeyAgreement: IDerObjectIdentifier; static; inline;
+    class function GetIdPbkdf2: IDerObjectIdentifier; static; inline;
     class function GetMD2: IDerObjectIdentifier; static; inline;
     class function GetMD4: IDerObjectIdentifier; static; inline;
     class function GetMD5: IDerObjectIdentifier; static; inline;
@@ -64,6 +71,8 @@ type
   public
 
     class property DhKeyAgreement: IDerObjectIdentifier read GetDhKeyAgreement;
+
+    class property IdPbkdf2: IDerObjectIdentifier read GetIdPbkdf2;
     //
     // md2 OBJECT IDENTIFIER ::=
     // {iso(1) member-body(2) US(840) rsadsi(113549) DigestAlgorithm(2) 2}
@@ -103,6 +112,7 @@ begin
   if not FIsBooted then
   begin
     FDhKeyAgreement := TDerObjectIdentifier.Create(Pkcs3 + '.1');
+    FIdPbkdf2 := TDerObjectIdentifier.Create(Pkcs5 + '.12');
     FMD2 := TDerObjectIdentifier.Create(DigestAlgorithm + '.2');
     FMD4 := TDerObjectIdentifier.Create(DigestAlgorithm + '.4');
     FMD5 := TDerObjectIdentifier.Create(DigestAlgorithm + '.5');
@@ -146,6 +156,11 @@ begin
   result := FIdHmacWithSha512;
 end;
 
+class function TPkcsObjectIdentifiers.GetIdPbkdf2: IDerObjectIdentifier;
+begin
+  result := FIdPbkdf2;
+end;
+
 class function TPkcsObjectIdentifiers.GetMD2: IDerObjectIdentifier;
 begin
   result := FMD2;

+ 4 - 0
src/libraries/cryptolib4pascal/ClpRijndaelEngine.pas

@@ -28,6 +28,7 @@ uses
   ClpIRijndaelEngine,
   ClpIKeyParameter,
   ClpICipherParameters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -546,6 +547,7 @@ begin
       KC := 8
   else
     begin
+      TArrayUtils.ZeroFill(key);
       raise EArgumentCryptoLibException.CreateRes(@SInvalidKeyLength);
     end;
   end;
@@ -654,6 +656,8 @@ begin
     end;
   end;
   result := W;
+
+  TArrayUtils.ZeroFill(key);
 end;
 
 procedure TRijndaelEngine.PackBlock(const bytes: TCryptoLibByteArray;

+ 11 - 0
src/libraries/cryptolib4pascal/ClpSalsa20Engine.pas

@@ -31,6 +31,7 @@ uses
   ClpICipherParameters,
   ClpIParametersWithIV,
   ClpConverters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -215,6 +216,7 @@ begin
   iv := ivParams.GetIV();
   if ((iv = Nil) or (System.Length(iv) <> NonceSize)) then
   begin
+    TArrayUtils.ZeroFill(iv);
     raise EArgumentCryptoLibException.CreateResFmt(@SInvalidIV,
       [AlgorithmName, NonceSize]);
   end;
@@ -476,6 +478,8 @@ begin
   begin
     if not(Byte(System.Length(keyBytes)) in [16, 32]) then
     begin
+      TArrayUtils.ZeroFill(keyBytes);
+      TArrayUtils.ZeroFill(ivBytes);
       raise EArgumentCryptoLibException.CreateResFmt(@SInvalidKeySize,
         [AlgorithmName]);
     end;
@@ -497,6 +501,13 @@ begin
   // IV
   TConverters.le32_copy(PByte(ivBytes), 0, PCardinal(FEngineState),
     6 * System.SizeOf(UInt32), 2 * System.SizeOf(UInt32));
+
+  if (Self.ClassType = TSalsa20Engine) then
+  begin
+    TArrayUtils.ZeroFill(keyBytes);
+    TArrayUtils.ZeroFill(ivBytes);
+  end;
+
 end;
 
 end.

+ 11 - 4
src/libraries/cryptolib4pascal/ClpSchnorrDigestSigner.pas

@@ -112,15 +112,22 @@ implementation
 
 function TSchnorrDigestSigner.Aggregate: TCryptoLibByteArray;
 begin
-  FBuffer.Position := 0;
-  System.SetLength(Result, FBuffer.Size);
-  FBuffer.Read(Result[0], FBuffer.Size);
+  Result := Nil;
+  if FBuffer.Size > 0 then
+  begin
+    FBuffer.Position := 0;
+    System.SetLength(Result, FBuffer.Size);
+    FBuffer.Read(Result[0], FBuffer.Size);
+  end;
 end;
 
 procedure TSchnorrDigestSigner.BlockUpdate(const input: TCryptoLibByteArray;
   inOff, length: Int32);
 begin
-  FBuffer.Write(input[inOff], length);
+  if input <> Nil then
+  begin
+    FBuffer.Write(input[inOff], length);
+  end;
 end;
 
 // constructor TSchnorrDigestSigner.Create(const Schnorr: ISchnorr;

+ 199 - 0
src/libraries/cryptolib4pascal/ClpScryptParametersGenerator.pas

@@ -0,0 +1,199 @@
+{ *********************************************************************************** }
+{ *                              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 ClpScryptParametersGenerator;
+
+{$I CryptoLib.inc}
+
+interface
+
+uses
+
+  HlpIHashInfo,
+  HlpHashFactory,
+  ClpICipherParameters,
+  ClpPbeParametersGenerator,
+  ClpIScryptParametersGenerator,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpParameterUtilities,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary>
+  /// <a href="http://tools.ietf.org/html/draft-josefsson-scrypt-kdf-01">draft-josefsson-scrypt-kd</a>
+  /// Scrypt Specification</see>
+  /// </summary>
+  TScryptParametersGenerator = class sealed(TPbeParametersGenerator,
+    IScryptParametersGenerator)
+
+  strict private
+  var
+    FPassword, FSalt: TCryptoLibByteArray;
+    FPBKDF_Scrypt: HlpIHashInfo.IPBKDF_Scrypt;
+
+    function GenerateDerivedKey(dkLen: Int32): TCryptoLibByteArray; inline;
+
+  public
+
+    procedure Clear(); override;
+    /// <summary>
+    /// construct an Scrypt Parameters generator.
+    /// </summary>
+    constructor Create();
+
+    destructor Destroy; override;
+
+    procedure Init(const password, salt: TCryptoLibByteArray;
+      cost, blockSize, parallelism: Int32);
+
+    /// <summary>
+    /// Generate a key parameter derived from the password, salt,
+    /// cost, blockSize, parallelism we are currently initialised with.
+    /// </summary>
+    /// <param name="algorithm">
+    /// a parameters object representing a key.
+    /// </param>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key.
+    /// </returns>
+    function GenerateDerivedParameters(const algorithm: String; keySize: Int32)
+      : ICipherParameters; overload; override;
+
+    /// <summary>
+    /// Generate a key with initialisation vector parameter derived from <br />
+    /// the password, salt, cost, blockSize, parallelism we are currently initialised with.
+    /// </summary>
+    /// </summary>
+    /// <param name="algorithm">
+    /// a parameters object representing a key.
+    /// </param>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <param name="ivSize">
+    /// the length, in bits, of the iv required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key and an iv.
+    /// </returns>
+    function GenerateDerivedParameters(const algorithm: String;
+      keySize, ivSize: Int32): ICipherParameters; overload; override;
+
+    /// <summary>
+    /// Generate a key parameter for use with a MAC derived from the
+    /// the password, salt, cost, blockSize, parallelism we are currently initialised with.
+    /// with.
+    /// </summary>
+    /// <param name="keySize">
+    /// the length, in bits, of the key required.
+    /// </param>
+    /// <returns>
+    /// a parameters object representing a key.
+    /// </returns>
+    function GenerateDerivedMacParameters(keySize: Int32)
+      : ICipherParameters; override;
+
+  end;
+
+implementation
+
+{ TPkcs5S2ParametersGenerator }
+
+procedure TScryptParametersGenerator.Clear();
+begin
+  TArrayUtils.ZeroFill(FPassword);
+  TArrayUtils.ZeroFill(FSalt);
+
+  if FPBKDF_Scrypt <> Nil then
+  begin
+    FPBKDF_Scrypt.Clear();
+  end;
+end;
+
+constructor TScryptParametersGenerator.Create();
+begin
+  Inherited Create();
+end;
+
+destructor TScryptParametersGenerator.Destroy;
+begin
+  Clear();
+  inherited Destroy;
+end;
+
+function TScryptParametersGenerator.GenerateDerivedKey(dkLen: Int32)
+  : TCryptoLibByteArray;
+begin
+  result := FPBKDF_Scrypt.GetBytes(dkLen);
+end;
+
+function TScryptParametersGenerator.GenerateDerivedMacParameters(keySize: Int32)
+  : ICipherParameters;
+var
+  dKey: TCryptoLibByteArray;
+begin
+  keySize := keySize div 8;
+
+  dKey := GenerateDerivedKey(keySize);
+
+  result := TKeyParameter.Create(dKey, 0, keySize);
+end;
+
+function TScryptParametersGenerator.GenerateDerivedParameters(const algorithm
+  : String; keySize: Int32): ICipherParameters;
+var
+  dKey: TCryptoLibByteArray;
+begin
+  keySize := keySize div 8;
+
+  dKey := GenerateDerivedKey(keySize);
+
+  result := TParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
+end;
+
+function TScryptParametersGenerator.GenerateDerivedParameters(const algorithm
+  : String; keySize, ivSize: Int32): ICipherParameters;
+var
+  dKey: TCryptoLibByteArray;
+  key: IKeyParameter;
+begin
+  keySize := keySize div 8;
+  ivSize := ivSize div 8;
+
+  dKey := GenerateDerivedKey(keySize + ivSize);
+  key := TParameterUtilities.CreateKeyParameter(algorithm, dKey, 0, keySize);
+
+  result := TParametersWithIV.Create(key, dKey, keySize, ivSize);
+end;
+
+procedure TScryptParametersGenerator.Init(const password,
+  salt: TCryptoLibByteArray; cost, blockSize, parallelism: Int32);
+begin
+  FPassword := System.Copy(password);
+  FSalt := System.Copy(salt);
+  FPBKDF_Scrypt := TKDF.TPBKDF_Scrypt.CreatePBKDF_Scrypt(FPassword, FSalt, cost,
+    blockSize, parallelism);
+end;
+
+end.

+ 48 - 27
src/libraries/cryptolib4pascal/ClpSpeckEngine.pas

@@ -28,6 +28,7 @@ uses
   ClpIBlockCipher,
   ClpICipherParameters,
   ClpIKeyParameter,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -93,10 +94,11 @@ type
     function GetBlockSize(): Int32; virtual;
 
     /// <summary>
-    /// Checks whether a key size provided to the <see cref="ClpSpeckEngine|TSpeckEngine.EngineInit(Boolean,TCryptoLibByteArray)" />
+    /// Checks whether the key size provided to the <see cref="ClpSpeckEngine|TSpeckEngine.EngineInit(Boolean,TCryptoLibByteArray)" />
     /// method is valid.
     /// </summary>
-    procedure CheckKeySize(keySizeBytes: Int32); virtual; abstract;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray);
+      virtual; abstract;
 
     /// <summary>
     /// Sets a key for this cipher instance, calculating the key schedule.
@@ -484,7 +486,7 @@ type
 
   strict protected
     function Mask(val: UInt32): UInt32; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -505,7 +507,7 @@ type
 
   strict protected
     function Mask(val: UInt32): UInt32; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -526,7 +528,7 @@ type
 
   strict protected
     function Mask(val: UInt32): UInt32; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -547,7 +549,7 @@ type
 
   strict protected
     function Mask(val: UInt64): UInt64; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -569,7 +571,7 @@ type
 
   strict protected
     function Mask(val: UInt64): UInt64; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -601,7 +603,7 @@ procedure TSpeckEngine.EngineInit(forEncryption: Boolean;
   const keyBytes: TCryptoLibByteArray);
 begin
   FforEncryption := forEncryption;
-  CheckKeySize(System.Length(keyBytes));
+  CheckKeySize(keyBytes);
   SetKey(keyBytes);
   Finitialised := true;
 end;
@@ -620,7 +622,6 @@ procedure TSpeckEngine.Init(forEncryption: Boolean;
   const parameters: ICipherParameters);
 var
   keyParameter: IKeyParameter;
-  keyBytes: TCryptoLibByteArray;
 begin
 
   if not Supports(parameters, IKeyParameter, keyParameter) then
@@ -628,8 +629,7 @@ begin
     raise EArgumentCryptoLibException.CreateResFmt(@SInvalidParameterSpeckInit,
       [(parameters as TObject).ToString]);
   end;
-  keyBytes := keyParameter.GetKey;
-  EngineInit(forEncryption, keyBytes);
+  EngineInit(forEncryption, keyParameter.GetKey());
 end;
 
 function TSpeckEngine.ProcessBlock(const input: TCryptoLibByteArray;
@@ -817,6 +817,7 @@ begin
 
   end;
 
+  TArrayUtils.ZeroFill(keyBytes);
 end;
 
 { TSpeckUInt64Engine }
@@ -980,6 +981,7 @@ begin
 
   end;
 
+  TArrayUtils.ZeroFill(keyBytes);
 end;
 
 { TSpeck32Engine }
@@ -994,12 +996,16 @@ begin
   result := (val and $FFFF);
 end;
 
-procedure TSpeck32Engine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck32Engine.CheckKeySize(const keyBytes: TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if (keySizeBytes <> 8) then
+  keyBytesSize := System.Length(keyBytes);
+  if (keyBytesSize <> 8) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt(@SSpeck32InvalidKeySize,
-      [keySizeBytes * 8]);
+      [keyBytesSize * 8]);
   end;
 end;
 
@@ -1015,12 +1021,16 @@ begin
   result := (val and $FFFFFF);
 end;
 
-procedure TSpeck48Engine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck48Engine.CheckKeySize(const keyBytes: TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [9, 12]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [9, 12]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt(@SSpeck48InvalidKeySize,
-      [keySizeBytes * 8]);
+      [keyBytesSize * 8]);
   end;
 end;
 
@@ -1036,12 +1046,16 @@ begin
   result := val;
 end;
 
-procedure TSpeck64Engine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck64Engine.CheckKeySize(const keyBytes: TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [12, 16]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [12, 16]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt(@SSpeck64InvalidKeySize,
-      [keySizeBytes * 8]);
+      [keyBytesSize * 8]);
   end;
 end;
 
@@ -1057,12 +1071,16 @@ begin
   result := (val and $0000FFFFFFFFFFFF);
 end;
 
-procedure TSpeck96Engine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck96Engine.CheckKeySize(const keyBytes: TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [12, 18]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [12, 18]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt(@SSpeck96InvalidKeySize,
-      [keySizeBytes * 8]);
+      [keyBytesSize * 8]);
   end;
 end;
 
@@ -1078,14 +1096,17 @@ begin
   result := val;
 end;
 
-procedure TSpeck128Engine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck128Engine.CheckKeySize(const keyBytes: TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [16, 24, 32]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [16, 24, 32]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt(@SSpeck128InvalidKeySize,
-      [keySizeBytes * 8]);
+      [keyBytesSize * 8]);
   end;
 end;
 
 end.
-

+ 53 - 26
src/libraries/cryptolib4pascal/ClpSpeckLegacyEngine.pas

@@ -28,6 +28,7 @@ uses
   ClpIBlockCipher,
   ClpICipherParameters,
   ClpIKeyParameter,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -90,10 +91,11 @@ type
     function GetBlockSize(): Int32; virtual;
 
     /// <summary>
-    /// Checks whether a key size provided to the <see cref="ClpSpeckLegacyEngine|TSpeckLegacyEngine.EngineInit(Boolean,TCryptoLibByteArray)" />
+    /// Checks whether the key size provided to the <see cref="ClpSpeckLegacyEngine|TSpeckLegacyEngine.EngineInit(Boolean,TCryptoLibByteArray)" />
     /// method is valid.
     /// </summary>
-    procedure CheckKeySize(keySizeBytes: Int32); virtual; abstract;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray);
+      virtual; abstract;
 
     /// <summary>
     /// Sets a key for this cipher instance, calculating the key schedule.
@@ -481,7 +483,7 @@ type
 
   strict protected
     function Mask(val: UInt32): UInt32; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -502,7 +504,7 @@ type
 
   strict protected
     function Mask(val: UInt32): UInt32; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -523,7 +525,7 @@ type
 
   strict protected
     function Mask(val: UInt32): UInt32; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -544,7 +546,7 @@ type
 
   strict protected
     function Mask(val: UInt64): UInt64; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -566,7 +568,7 @@ type
 
   strict protected
     function Mask(val: UInt64): UInt64; override;
-    procedure CheckKeySize(keySizeBytes: Int32); override;
+    procedure CheckKeySize(const keyBytes: TCryptoLibByteArray); override;
 
   public
     constructor Create();
@@ -598,7 +600,7 @@ procedure TSpeckLegacyEngine.EngineInit(forEncryption: Boolean;
   const keyBytes: TCryptoLibByteArray);
 begin
   FforEncryption := forEncryption;
-  CheckKeySize(System.Length(keyBytes));
+  CheckKeySize(keyBytes);
   SetKey(keyBytes);
   Finitialised := true;
 end;
@@ -617,7 +619,6 @@ procedure TSpeckLegacyEngine.Init(forEncryption: Boolean;
   const parameters: ICipherParameters);
 var
   keyParameter: IKeyParameter;
-  keyBytes: TCryptoLibByteArray;
 begin
 
   if not Supports(parameters, IKeyParameter, keyParameter) then
@@ -625,8 +626,7 @@ begin
     raise EArgumentCryptoLibException.CreateResFmt
       (@SInvalidParameterSpeckLegacyInit, [(parameters as TObject).ToString]);
   end;
-  keyBytes := keyParameter.GetKey;
-  EngineInit(forEncryption, keyBytes);
+  EngineInit(forEncryption, keyParameter.GetKey());
 end;
 
 function TSpeckLegacyEngine.ProcessBlock(const input: TCryptoLibByteArray;
@@ -817,6 +817,7 @@ begin
 
   end;
 
+  TArrayUtils.ZeroFill(keyBytes);
 end;
 
 { TSpeckUInt64LegacyEngine }
@@ -983,6 +984,7 @@ begin
 
   end;
 
+  TArrayUtils.ZeroFill(keyBytes);
 end;
 
 { TSpeck32LegacyEngine }
@@ -997,12 +999,17 @@ begin
   result := (val and $FFFF);
 end;
 
-procedure TSpeck32LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck32LegacyEngine.CheckKeySize(const keyBytes
+  : TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if (keySizeBytes <> 8) then
+  keyBytesSize := System.Length(keyBytes);
+  if (keyBytesSize <> 8) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt
-      (@SSpeck32LegacyInvalidKeySize, [keySizeBytes * 8]);
+      (@SSpeck32LegacyInvalidKeySize, [keyBytesSize * 8]);
   end;
 end;
 
@@ -1018,12 +1025,17 @@ begin
   result := (val and $FFFFFF);
 end;
 
-procedure TSpeck48LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck48LegacyEngine.CheckKeySize(const keyBytes
+  : TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [9, 12]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [9, 12]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt
-      (@SSpeck48LegacyInvalidKeySize, [keySizeBytes * 8]);
+      (@SSpeck48LegacyInvalidKeySize, [keyBytesSize * 8]);
   end;
 end;
 
@@ -1039,12 +1051,17 @@ begin
   result := val;
 end;
 
-procedure TSpeck64LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck64LegacyEngine.CheckKeySize(const keyBytes
+  : TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [12, 16]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [12, 16]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt
-      (@SSpeck64LegacyInvalidKeySize, [keySizeBytes * 8]);
+      (@SSpeck64LegacyInvalidKeySize, [keyBytesSize * 8]);
   end;
 end;
 
@@ -1060,12 +1077,17 @@ begin
   result := (val and $0000FFFFFFFFFFFF);
 end;
 
-procedure TSpeck96LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck96LegacyEngine.CheckKeySize(const keyBytes
+  : TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [12, 18]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [12, 18]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt
-      (@SSpeck96LegacyInvalidKeySize, [keySizeBytes * 8]);
+      (@SSpeck96LegacyInvalidKeySize, [keyBytesSize * 8]);
   end;
 end;
 
@@ -1081,12 +1103,17 @@ begin
   result := val;
 end;
 
-procedure TSpeck128LegacyEngine.CheckKeySize(keySizeBytes: Int32);
+procedure TSpeck128LegacyEngine.CheckKeySize(const keyBytes
+  : TCryptoLibByteArray);
+var
+  keyBytesSize: Int32;
 begin
-  if not(keySizeBytes in [16, 24, 32]) then
+  keyBytesSize := System.Length(keyBytes);
+  if not(keyBytesSize in [16, 24, 32]) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
     raise EArgumentCryptoLibException.CreateResFmt
-      (@SSpeck128LegacyInvalidKeySize, [keySizeBytes * 8]);
+      (@SSpeck128LegacyInvalidKeySize, [keyBytesSize * 8]);
   end;
 end;
 

+ 5 - 4
src/libraries/cryptolib4pascal/ClpX25519Agreement.pas

@@ -36,17 +36,18 @@ resourcestring
     'The Init Parameter does not Contain the Private Key';
 
 type
-  TX25519Agreement = class(TInterfacedObject, IX25519Agreement, IRawAgreement)
+  TX25519Agreement = class sealed(TInterfacedObject, IX25519Agreement,
+    IRawAgreement)
 
-  strict protected
+  strict private
   var
     FPrivateKey: IX25519PrivateKeyParameters;
 
-    function GetAgreementSize(): Int32; virtual;
+    function GetAgreementSize(): Int32;
 
   public
 
-    procedure Init(const parameters: ICipherParameters); virtual;
+    procedure Init(const parameters: ICipherParameters);
 
     procedure CalculateAgreement(const publicKey: ICipherParameters;
       const buf: TCryptoLibByteArray; off: Int32);

+ 6 - 0
src/libraries/cryptolib4pascal/ClpXSalsa20Engine.pas

@@ -26,6 +26,7 @@ uses
   ClpSalsa20Engine,
   ClpIXSalsa20Engine,
   ClpConverters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -79,6 +80,8 @@ begin
 
   if (System.Length(keyBytes) <> 32) then
   begin
+    TArrayUtils.ZeroFill(keyBytes);
+    TArrayUtils.ZeroFill(ivBytes);
     raise EArgumentCryptoLibException.CreateResFmt(@SInvalidKeySize,
       [AlgorithmName]);
   end;
@@ -110,6 +113,9 @@ begin
   TConverters.le32_copy(PByte(ivBytes), 16 * System.SizeOf(Byte),
     PCardinal(FEngineState), 6 * System.SizeOf(UInt32),
     2 * System.SizeOf(UInt32));
+
+  TArrayUtils.ZeroFill(keyBytes);
+  TArrayUtils.ZeroFill(ivBytes);
 end;
 
 end.

+ 101 - 16
src/libraries/cryptolib4pascal/CryptoLib.inc

@@ -23,8 +23,48 @@
 {$UNDEF DELPHI}
 {$MODE delphi}
 
-{$IF (DEFINED(DARWIN) AND (DEFINED(CPUARM) OR DEFINED(CPUAARCH64) OR DEFINED(IPHONESIM)))}
-{$DEFINE IOSFPC}
+{$IFDEF CPU386}
+   {$DEFINE CRYPTOLIB_X86}
+{$ENDIF}
+
+{$IFDEF CPUX64}
+   {$DEFINE CRYPTOLIB_X86_64}
+{$ENDIF}
+
+{$IFDEF CPUARM}
+   {$DEFINE CRYPTOLIB_ARM}
+{$ENDIF}
+
+{$IFDEF CPUAARCH64}
+   {$DEFINE CRYPTOLIB_AARCH64}
+{$ENDIF}
+
+{$IFDEF IPHONESIM}
+   {$DEFINE CRYPTOLIB_IOSSIM}
+{$ENDIF}
+
+{$IF DEFINED(MSWINDOWS)}
+   {$DEFINE CRYPTOLIB_MSWINDOWS}
+{$ELSEIF DEFINED(UNIX)}
+   {$DEFINE CRYPTOLIB_UNIX}
+   {$IF DEFINED(BSD)}
+      {$IF DEFINED(DARWIN)}
+         {$DEFINE CRYPTOLIB_APPLE}
+         {$IF DEFINED(CRYPTOLIB_ARM) OR DEFINED(CRYPTOLIB_AARCH64)}
+            {$DEFINE CRYPTOLIB_IOS}
+         {$ELSE}
+            {$DEFINE CRYPTOLIB_MACOS}
+         {$IFEND}
+      {$ELSEIF DEFINED(FREEBSD) OR DEFINED(NETBSD) OR DEFINED(OPENBSD) OR DEFINED(DRAGONFLY)}
+         {$DEFINE CRYPTOLIB_GENERIC_BSD}
+      {$IFEND}
+  {$ELSEIF DEFINED(LINUX)}
+     {$DEFINE CRYPTOLIB_LINUX}
+  {$ELSE}
+     {$DEFINE CRYPTOLIB_UNDEFINED_UNIX_VARIANTS}
+  {$IFEND}
+{$ELSE}
+   {$MESSAGE ERROR 'UNSUPPORTED TARGET.'}
 {$ENDIF}
 
 {$DEFINE USE_UNROLLED_VARIANT}
@@ -49,20 +89,65 @@
 {$OPTIMIZATION STRENGTH}
 {$OPTIMIZATION CSE}
 {$OPTIMIZATION DFA}
+
 {$IFDEF CPUI386}
-{$OPTIMIZATION USEEBP}
+   {$OPTIMIZATION USEEBP}
 {$ENDIF}
+
 {$IFDEF CPUX86_64}
-{$OPTIMIZATION USERBP}
+   {$OPTIMIZATION USERBP}
 {$ENDIF}
+
 {$ENDIF FPC}
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
 {$IFDEF DELPHI}
 
-{$IF DEFINED(IOS)}
-{$DEFINE IOSDELPHI}
+{$IFDEF CPU386}
+   {$DEFINE CRYPTOLIB_X86}
+{$ENDIF}
+
+{$IFDEF CPUX64}
+   {$DEFINE CRYPTOLIB_X86_64}
+{$ENDIF}
+
+{$IFDEF CPUARM32}
+   {$DEFINE CRYPTOLIB_ARM}
+{$ENDIF}
+
+{$IFDEF CPUARM64}
+   {$DEFINE CRYPTOLIB_AARCH64}
+{$ENDIF}
+
+{$IFDEF IOS}
+  {$IFNDEF CPUARM}
+     {$DEFINE CRYPTOLIB_IOSSIM}
+  {$ENDIF}
+{$ENDIF}
+
+{$IFDEF IOS}
+   {$DEFINE CRYPTOLIB_IOS}
+{$IFEND}
+
+{$IFDEF MSWINDOWS}
+   {$DEFINE CRYPTOLIB_MSWINDOWS}
+{$ENDIF}
+
+{$IFDEF MACOS}
+   {$DEFINE CRYPTOLIB_MACOS}
+{$ENDIF}
+
+{$IF DEFINED(CRYPTOLIB_IOS) OR DEFINED(CRYPTOLIB_MACOS)}
+   {$DEFINE CRYPTOLIB_APPLE}
+{$IFEND}
+
+{$IF DEFINED(LINUX) OR DEFINED(ANDROID)}
+   {$DEFINE CRYPTOLIB_LINUX}
+{$ENDIF}
+
+{$IF DEFINED(CRYPTOLIB_APPLE) OR DEFINED(CRYPTOLIB_LINUX)}
+   {$DEFINE CRYPTOLIB_UNIX}
 {$ENDIF}
 
 {$DEFINE USE_UNROLLED_VARIANT}
@@ -89,32 +174,32 @@
 
  // XE3 and Above
 {$IF CompilerVersion >= 24.0}
-{$DEFINE DELPHIXE3_UP}
-{$DEFINE SUPPORT_TSTREAM_READ_BYTEARRAY_OVERLOAD}
-{$DEFINE SUPPORT_TSTREAM_WRITE_BYTEARRAY_OVERLOAD}
-{$LEGACYIFEND ON}
-{$ZEROBASEDSTRINGS OFF}
+   {$DEFINE DELPHIXE3_UP}
+   {$DEFINE SUPPORT_TSTREAM_READ_BYTEARRAY_OVERLOAD}
+   {$DEFINE SUPPORT_TSTREAM_WRITE_BYTEARRAY_OVERLOAD}
+   {$LEGACYIFEND ON}
+   {$ZEROBASEDSTRINGS OFF}
 {$IFEND}
 
   // XE and Above
 {$IF CompilerVersion >= 22.0}
-{$DEFINE DELPHIXE_UP}
+   {$DEFINE DELPHIXE_UP}
 {$IFEND}
 
  // XE4 and Above
 {$IF CompilerVersion >= 25.0}
-{$DEFINE DELPHIXE4_UP}
-{$DEFINE SHIFT_OVERFLOW_BUG_FIXED}
+   {$DEFINE DELPHIXE4_UP}
+   {$DEFINE SHIFT_OVERFLOW_BUG_FIXED}
 {$IFEND}
 
   // 10.2 Tokyo and Above
 {$IF CompilerVersion >= 32.0}
-{$DEFINE DELPHI10.2_TOKYO_UP}
+   {$DEFINE DELPHI10.2_TOKYO_UP}
 {$IFEND}
 
   // 10.2 Tokyo and Above
 {$IFNDEF DELPHI10.2_TOKYO_UP}
-{$MESSAGE ERROR 'This Library requires Delphi Tokyo or higher.'}
+   {$MESSAGE ERROR 'This Library requires Delphi Tokyo or higher.'}
 {$ENDIF}
 
 

+ 2 - 2
src/libraries/cryptolib4pascal/CryptoLibHelper.inc

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

+ 172 - 107
src/libraries/cryptolib4pascal/README.md

@@ -1,134 +1,199 @@
-# CryptoLib4Pascal [![License](http://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Xor-el/CryptoLib4Pascal/blob/master/LICENSE)
-CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying DSA, ECDSA, ECNR and ECSchnorr signatures using various curves and hashes, AES, Rijndael, Blowfish and Speck Block Encryption and Decryption (With various modes and paddings), Salsa20, XSalsa20, ChaCha Stream Ciphers and ECIES.
-
-**Supported Elliptic Curves:**
-
-Curves are grouped in three different classes.
-1. NistNamed Curves
-2. SecNamed Curves (these are bare generic implementation of curves (at the moment, not as optimized as their CustomNamed Curves Counterparts))
-3. CustomNamed Curves. (these are specially optimized implementations of curves found in the previous two.)
-
-**NistNamed Curves:**
-```
-K-283, B-283, B-409, B-233, K-163, P-521, K-233, K-409, P-192, P-384, P-224, P-256, B-163, B-571, K-571.
-```
-
-**SecNamed Curves:**
-```
-sect131r1, secp160k1, sect193r1, secp384r1, secp128r1, sect163k1, sect193r2, sect239k1, sect409r1, secp256r1,
-secp521r1, sect131r2, secp112r1, sect113r2, sect163r1, secp224k1, secp224r1, sect283k1, sect233k1, sect283r1,
-sect409k1, sect571k1, secp192r1, sect233r1, secp256k1, sect571r1, secp192k1, secp160r1, sect113r1, secp160r2,
-secp112r2, sect163r2, secp128r2.
-```
-
-**CustomNamed Curves:**
-
-| curve name | alias(es) |
-|--------|--------|
-|  **secp256k1**      |        |
-|  **secp256r1**      |   **P-256**    |
-|  **secp384r1**      |   **P-384**    |
-|  **secp521r1**      |   **P-521**    |
-|  **sect283k1**      |   **K-283**    |
-
-
-**Supported Algorithms:**
-    
-    Supported signing algorithms 
-    
-    ECDSA
-    NONEwithECDSA, SHA-1withECDSA, SHA-224withECDSA, 
-    SHA-256withECDSA, SHA-384withECDSA, SHA-512withECDSA and RIPEMD160withECDSA
-    
-    ECSchnorr
-    SHA-1withECSCHNORRSIPA, SHA-224withECSCHNORRSIPA, SHA-256withECSCHNORRSIPA, SHA-384withECSCHNORRSIPA,
-    SHA-512withECSCHNORRSIPA, RIPEMD160withECSCHNORRSIPA
-    
-    
-    
-   **Dependencies:**
-   
-   [HashLib4Pascal](https://github.com/Xor-el/HashLib4Pascal) >= v2.5
-   
-   [SimpleBaseLib4Pascal](https://github.com/Xor-el/SimpleBaseLib4Pascal) >= v1.4
-    
-   For FreePascal v3.0.x [Generics.Collections](https://github.com/maciej-izak/generics.collections)
-
-**Supported Compilers**
+CryptoLib4Pascal: Crypto for Modern Object Pascal [![License](http://img.shields.io/badge/license-MIT-green.svg)](https://github.com/Xor-el/CryptoLib4Pascal/blob/master/LICENSE)
+========================================
+
+``CryptoLib4Pascal`` is an Object Pascal cryptographic library released under the permissive [MIT License](https://github.com/Xor-el/CryptoLib4Pascal/blob/master/LICENSE). 
+
+``CryptoLib4Pascal's`` goal is to be the best option for cryptography in Object Pascal by offering cryptographic recipes and primitives to Object Pascal developers.
+
+Development is coordinated on [GitHub](https://github.com/Xor-el/CryptoLib4Pascal) and contributions are welcome. If you need help, please open an issue [here](https://github.com/Xor-el/CryptoLib4Pascal/issues).
+
+
+<!--**Build Status**
+[![Build Status](https://travis-ci.org/Xor-el/CryptoLib4Pascal.svg?branch=master)](https://travis-ci.org/Xor-el/CryptoLib4Pascal)-->
+
+Available Algorithms
+----------------------------------------
+
+ ### Symmetric Encryption
+----------------------------------------
+###### Block Ciphers
+* `AES (128, 192, and 256)` 
+
+* `Rijndael` 
+
+* `Blowfish`
+
+* `Speck`
+
+###### Stream Ciphers
+* `ChaCha`
+
+* `(X)Salsa20` 
+
+##### Block Cipher Modes Of Operation 
+----------------------------------------
+
+* `ECB` 
+
+* `CBC` 
+
+* `CFB` 
+
+* `CTR` 
+
+* `CTS` 
+
+* `OFB` 
+
+* `SIC`
+
+##### Block Cipher Padding Schemes 
+----------------------------------------
+
+* `ISO 10126-2` 
+
+* `ISO 7816-4` 
+
+* `Bit (ISO/IEC 9797-1)` 
+
+* `PKCS#5` 
+
+* `PKCS#7`
+ 
+* `TBC (Trailing Bit Complement)` 
+
+* `ANSI X9.23` 
+
+* `Zero`
+
+### Asymmetric Cryptography
+----------------------------------------
+
+* `DSA`
+
+* `(DET)ECDSA (supported curves: NIST, X9.62, SEC2, Brainpool)`
+
+* `ECNR`
+
+* `ECSchnorr`
+ 
+* `EdDSA (Ed25519, Ed25519Blake2B)`
+
+### Key Agreement/Exchange
+----------------------------------------
+
+* `DH`
+
+* `ECDH`
+
+* `ECDHC`
+ 
+* `X25519` 
+
+### Key Derivation Functions
+----------------------------------------
+
+* `HKDF` 
  
-    FreePascal 3.0.4 and Above.
-    
-    Delphi Tokyo and Above. (might work in earlier versions though.)
+* `KDF1`
 
-**Installing the Library.**
+* `KDF2`
 
-**Method One:**
+###### Password Hashing Schemes (Password Based Key Derivation Functions)
+----------------------------------------
 
- Use the Provided Packages in the "Packages" Folder.
+* `PBKDF2`
+ 
+* `Argon2 (2i, 2d and 2id variants)`
 
-**Method Two:**
+* `Scrypt`
 
- Add the Library Path and Sub Path to your Project Search Path.
+### MAC
+----------------------------------------
 
-**Usage Examples.**
+* `HMAC (all supported hashes)`
+ 
+* `X25519` 
 
-    Check the "CryptoLib.Samples" folder and the Unit Tests.
+### Hashes
+----------------------------------------
 
- **Unit Tests.**
+ * `MD2`
 
-To Run Unit Tests,
+ * `MD4`
 
-**For FPC 3.0.4 and above**
+ * `MD5`
 
+ * `SHA-1`
 
-    Simply compile and run "CryptoLib.Tests" project in "FreePascal.Tests" Folder.
+ * `SHA-2 (224, 256, 384, 512, 512-224, 512-256)`
 
-**For Delphi**
+ * `Gost3411`
 
-   **Method One (Using DUnit Test Runner)**
+ * `Gost3411-2012 (256, 512)`
 
-     To Build and Run the Unit Tests For Delphi 10 Tokyo (should be similar for 
-     other versions)
-    
-    1). Open Project Options of Unit Test (CryptoLib.Tests) in "Delphi.Tests" Folder.
-    
-    2). Change Target to All Configurations (Or "Base" In Older Delphi Versions.)
-    
-    3). In Output directory add ".\$(Platform)\$(Config)" without the quotes.
-    
-    4). In Search path add "$(BDS)\Source\DUnit\src" without the quotes.
-    
-    5). In Unit output directory add "." without the quotes.
-    
-    6). In Unit scope names (If Available), Delete "DUnitX" from the List.
-    
-    Press Ok and save, then build and run.
-    
- **Method Two (Using TestInsight) (Preferred).**
+ * `RIPEMD (128, 256, 256, 320)`
 
-    1). Download and Install TestInsight.
-    
-    2). Open Project Options of Unit Test (CryptoLib.Tests.TestInsight) in "Delphi.Tests" 
-        Folder. 
+ * `Tiger`
 
-    3). Change Target to All Configurations (Or "Base" In Older Delphi Versions.)
+ * `WhirlPool`
 
-    4). In Unit scope names (If Available), Delete "DUnitX" from the List.
+ * `Blake2B (160, 256, 384, 512)`
+ 
+ * `Blake2S (128, 160, 224, 256)`
 
-    5). To Use TestInsight, right-click on the project, then select 
-		"Enable for TestInsight" or "TestInsight Project".
-        Save Project then Build and Run Test Project through TestInsight. 
-        
-  **Acknowledgements**
+ * `SHA-3 (224, 256, 384, 512)`
  
-Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library.
+ * `Keccak (224, 256, 288, 384, 512)`
+
+### XOF (Extendable Output Function)
+----------------------------------------
+
+* `Shake (Shake-128, Shake-256)`
+
+### Other Useful Things
+----------------------------------------
 
-**License**
+* `RNG wrappers for system RNG`
 
-This "Software" is Licensed Under  **`MIT License (MIT)`** .
+* `ASN1 Parsing Utilities`
+
+* `Base Encoding and Decoding Utilities`
+
+### Compile-Time Dependencies
+----------------------------------------
+
+* [HashLib4Pascal](https://github.com/Xor-el/HashLib4Pascal)
+* [SimpleBaseLib4Pascal](https://github.com/Xor-el/SimpleBaseLib4Pascal)
+
+### Supported Compilers
+----------------------------------------
+
+* `FreePascal 3.2.0+`
+
+* `Delphi Tokyo+`
+
+### Supported OSes
+----------------------------------------
+
+* `Windows XP+`
+
+* `Linux (Including Android and Raspberry PI)`
+
+* `macOS 10.7+`
+
+* `iOS 2.0+`
+
+* `FreeBSD, NetBSD, OpenBSD and DragonBSD`
+
+### Acknowledgements
+----------------------------------------
+
+* Thanks to [Sphere 10 Software](http://www.sphere10.com/) for sponsoring the development of this library.
+
+### Tip Jar
+----------------------------------------
 
-#### Tip Jar
 * :dollar: **Bitcoin**: `1MhFfW7tDuEHQSgie65uJcAfJgCNchGeKf`
 * :euro: **Ethereum**: `0x6c1DC21aeC49A822A4f1E3bf07c623C2C1978a98`
 * :pound: **Pascalcoin**: `345367-40`
-

+ 18 - 15
src/libraries/hashlib4pascal/HashLib.inc

@@ -11,7 +11,7 @@
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
 
- {$DEFINE DELPHI}
+{$DEFINE DELPHI}
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 {$IFDEF FPC}
@@ -41,12 +41,15 @@
 {$OPTIMIZATION STRENGTH}
 {$OPTIMIZATION CSE}
 {$OPTIMIZATION DFA}
+
 {$IFDEF CPUI386}
-{$OPTIMIZATION USEEBP}
+   {$OPTIMIZATION USEEBP}
 {$ENDIF}
+
 {$IFDEF CPUX86_64}
-{$OPTIMIZATION USERBP}
+   {$OPTIMIZATION USERBP}
 {$ENDIF}
+
 {$ENDIF FPC}
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
@@ -74,46 +77,46 @@
 
  // XE3 and Above
 {$IF CompilerVersion >= 24.0}
-{$DEFINE DELPHIXE3_UP}
-{$LEGACYIFEND ON}
-{$ZEROBASEDSTRINGS OFF}
+   {$DEFINE DELPHIXE3_UP}
+   {$LEGACYIFEND ON}
+   {$ZEROBASEDSTRINGS OFF}
 {$IFEND}
 
  // 2010 only
 {$IF CompilerVersion = 21.0}
-{$DEFINE DELPHI2010}
+   {$DEFINE DELPHI2010}
 {$IFEND}
 
   // 2010 and Above
 {$IF CompilerVersion >= 21.0}
-{$DEFINE DELPHI2010_UP}
+   {$DEFINE DELPHI2010_UP}
 {$IFEND}
 
   // XE and Above
 {$IF CompilerVersion >= 22.0}
-{$DEFINE DELPHIXE_UP}
+   {$DEFINE DELPHIXE_UP}
 {$IFEND}
 
   // XE2 and Above
 {$IF CompilerVersion >= 23.0}
-{$DEFINE DELPHIXE2_UP}
-{$DEFINE HAS_UNITSCOPE}
+   {$DEFINE DELPHIXE2_UP}
+   {$DEFINE HAS_UNITSCOPE}
 {$IFEND}
 
  // XE4 and Above
 {$IF CompilerVersion >= 25.0}
-{$DEFINE DELPHIXE4_UP}
-{$DEFINE SHIFT_OVERFLOW_BUG_FIXED}
+   {$DEFINE DELPHIXE4_UP}
+   {$DEFINE SHIFT_OVERFLOW_BUG_FIXED}
 {$IFEND}
 
   // XE7 and Above
 {$IF CompilerVersion >= 28.0}
-{$DEFINE DELPHIXE7_UP}
+   {$DEFINE DELPHIXE7_UP}
 {$IFEND}
 
   // 2010 and Above
 {$IFNDEF DELPHI2010_UP}
-{$MESSAGE ERROR 'This Library requires Delphi 2010 or higher.'}
+   {$MESSAGE ERROR 'This Library requires Delphi 2010 or higher.'}
 {$ENDIF}
 
 

+ 2 - 2
src/libraries/hashlib4pascal/HashLibHelper.inc

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

+ 136 - 0
src/libraries/hashlib4pascal/HlpArrayUtils.pas

@@ -0,0 +1,136 @@
+unit HlpArrayUtils;
+
+{$I HashLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  HlpHashLibTypes;
+
+type
+  TArrayUtils = class sealed(TObject)
+
+  public
+
+    class function AreEqual(const A, B: THashLibByteArray): Boolean;
+      overload; static;
+
+    class function ConstantTimeAreEqual(const a_ar1, a_ar2: THashLibByteArray)
+      : Boolean; static;
+
+    class procedure Fill(const buf: THashLibByteArray; from, &to: Int32;
+      filler: Byte); overload; static;
+
+    class procedure Fill(const buf: THashLibUInt32Array; from, &to: Int32;
+      filler: UInt32); overload; static;
+
+    class procedure Fill(const buf: THashLibUInt64Array; from, &to: Int32;
+      filler: UInt64); overload; static;
+
+    class procedure ZeroFill(const buf: THashLibByteArray); overload; static;
+
+    class procedure ZeroFill(const buf: THashLibUInt32Array); overload; static;
+
+    class procedure ZeroFill(const buf: THashLibUInt64Array); overload; static;
+
+  end;
+
+implementation
+
+{ TArrayUtils }
+
+class function TArrayUtils.AreEqual(const A, B: THashLibByteArray): Boolean;
+begin
+  if System.Length(A) <> System.Length(B) then
+  begin
+    Result := false;
+    Exit;
+  end;
+
+  Result := CompareMem(A, B, System.Length(A) * System.SizeOf(Byte));
+end;
+
+{$B+}
+
+class function TArrayUtils.ConstantTimeAreEqual(const a_ar1,
+  a_ar2: THashLibByteArray): Boolean;
+var
+  I: Int32;
+  diff: UInt32;
+
+begin
+  diff := UInt32(System.Length(a_ar1)) xor UInt32(System.Length(a_ar2));
+
+  I := 0;
+
+  while (I <= System.High(a_ar1)) and (I <= System.High(a_ar2)) do
+  begin
+    diff := diff or (UInt32(a_ar1[I] xor a_ar2[I]));
+    System.Inc(I);
+  end;
+
+  Result := diff = 0;
+end;
+
+{$B-}
+
+class procedure TArrayUtils.Fill(const buf: THashLibByteArray; from, &to: Int32;
+  filler: Byte);
+begin
+  if buf <> Nil then
+  begin
+    System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), filler);
+  end;
+end;
+
+class procedure TArrayUtils.Fill(const buf: THashLibUInt32Array;
+  from, &to: Int32; filler: UInt32);
+begin
+  if buf <> Nil then
+  begin
+{$IFDEF FPC}
+    System.FillDWord(buf[from], (&to - from), filler);
+{$ELSE}
+    while from < &to do
+    begin
+      buf[from] := filler;
+      System.Inc(from);
+    end;
+{$ENDIF}
+  end;
+end;
+
+class procedure TArrayUtils.Fill(const buf: THashLibUInt64Array;
+  from, &to: Int32; filler: UInt64);
+begin
+  if buf <> Nil then
+  begin
+{$IFDEF FPC}
+    System.FillQWord(buf[from], (&to - from), filler);
+{$ELSE}
+    while from < &to do
+    begin
+      buf[from] := filler;
+      System.Inc(from);
+    end;
+{$ENDIF}
+  end;
+end;
+
+class procedure TArrayUtils.ZeroFill(const buf: THashLibByteArray);
+begin
+  TArrayUtils.Fill(buf, 0, System.Length(buf), Byte(0));
+end;
+
+class procedure TArrayUtils.ZeroFill(const buf: THashLibUInt32Array);
+begin
+  TArrayUtils.Fill(buf, 0, System.Length(buf), UInt32(0));
+end;
+
+class procedure TArrayUtils.ZeroFill(const buf: THashLibUInt64Array);
+begin
+  TArrayUtils.Fill(buf, 0, System.Length(buf), UInt64(0));
+end;
+
+end.

+ 5 - 3
src/libraries/hashlib4pascal/HlpBlake2B.pas

@@ -1,5 +1,6 @@
 unit HlpBlake2B;
 
+
 {$I HashLib.inc}
 
 interface
@@ -25,6 +26,7 @@ uses
   HlpIHash,
   HlpIHashInfo,
   HlpConverters,
+  HlpArrayUtils,
   HlpHashLibTypes;
 
 resourcestring
@@ -1681,7 +1683,7 @@ begin
 
   if count > 0 then
   begin
-    System.FillChar(F_buf[F_bufferFilled], count, Byte(0));
+    TArrayUtils.Fill(F_buf, F_bufferFilled, count + F_bufferFilled, Byte(0));
   end;
 
   Compress(PByte(F_buf), 0);
@@ -1717,8 +1719,7 @@ begin
 
   System.SetLength(F_buf, BlockSizeInBytes);
 
-  System.FillChar(F_buf[0], (System.Length(F_buf) * System.SizeOf(Byte)
-    ), Byte(0));
+  TArrayUtils.ZeroFill(F_buf);
 
   System.FillChar(F_m, System.SizeOf(F_m), UInt64(0));
 
@@ -1801,3 +1802,4 @@ begin
 end;
 
 end.
+

+ 5 - 3
src/libraries/hashlib4pascal/HlpBlake2S.pas

@@ -1,5 +1,6 @@
 unit HlpBlake2S;
 
+
 {$I HashLib.inc}
 
 interface
@@ -25,6 +26,7 @@ uses
   HlpIHash,
   HlpIHashInfo,
   HlpConverters,
+  HlpArrayUtils,
   HlpHashLibTypes;
 
 resourcestring
@@ -1462,7 +1464,7 @@ begin
 
   if count > 0 then
   begin
-    System.FillChar(F_buf[F_bufferFilled], count, Byte(0));
+    TArrayUtils.Fill(F_buf, F_bufferFilled, count + F_bufferFilled, Byte(0));
   end;
 
   Compress(PByte(F_buf), 0);
@@ -1498,8 +1500,7 @@ begin
 
   System.SetLength(F_buf, BlockSizeInBytes);
 
-  System.FillChar(F_buf[0], (System.Length(F_buf) * System.SizeOf(Byte)
-    ), Byte(0));
+  TArrayUtils.ZeroFill(F_buf);
 
   System.FillChar(F_m, System.SizeOf(F_m), UInt32(0));
 
@@ -1582,3 +1583,4 @@ begin
 end;
 
 end.
+

+ 5 - 5
src/libraries/hashlib4pascal/HlpGOST3411_2012.pas

@@ -11,6 +11,7 @@ uses
   HlpHashResult,
   HlpIHashResult,
   HlpBits,
+  HlpArrayUtils,
   HlpHashLibTypes;
 
 type
@@ -1529,13 +1530,12 @@ end;
 procedure TGOST3411_2012.Initialize;
 begin
   FbOff := 64;
-  System.FillChar(FN[0], System.Length(FN) * System.SizeOf(Byte), Byte(0));
-  System.FillChar(FSigma[0], System.Length(FSigma) *
-    System.SizeOf(Byte), Byte(0));
+  TArrayUtils.ZeroFill(FN);
+  TArrayUtils.ZeroFill(FSigma);
+
   System.Move(FIV[0], Fh[0], 64 * System.SizeOf(Byte));
-  System.FillChar(Fblock[0], System.Length(Fblock) *
-    System.SizeOf(Byte), Byte(0));
 
+  TArrayUtils.ZeroFill(Fblock);
 end;
 
 procedure TGOST3411_2012.InternalUpdate(input: Byte);

+ 3 - 6
src/libraries/hashlib4pascal/HlpGost.pas

@@ -15,6 +15,7 @@ uses
   HlpConverters,
   HlpIHash,
   HlpIHashInfo,
+  HlpArrayUtils,
   HlpHashCryptoNotBuildIn;
 
 type
@@ -429,14 +430,10 @@ end;
 
 procedure TGost.Initialize;
 begin
-
-  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
-    UInt32(0));
-  System.FillChar(Fm_hash[0], System.Length(Fm_hash) * System.SizeOf(UInt32),
-    UInt32(0));
+  TArrayUtils.ZeroFill(Fm_state);
+  TArrayUtils.ZeroFill(Fm_hash);
 
   Inherited Initialize();
-
 end;
 
 procedure TGost.TransformBlock(a_data: PByte; a_data_length: Int32;

+ 3 - 5
src/libraries/hashlib4pascal/HlpGrindahl256.pas

@@ -17,6 +17,7 @@ uses
   HlpConverters,
   HlpIHash,
   HlpIHashInfo,
+  HlpArrayUtils,
   HlpHashCryptoNotBuildIn;
 
 type
@@ -203,11 +204,8 @@ end;
 
 procedure TGrindahl256.Initialize;
 begin
-
-  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt32),
-    UInt32(0));
-  System.FillChar(Fm_temp[0], System.Length(Fm_temp) * System.SizeOf(UInt32),
-    UInt32(0));
+  TArrayUtils.ZeroFill(Fm_state);
+  TArrayUtils.ZeroFill(Fm_temp);
 
   Inherited Initialize();
 

+ 3 - 5
src/libraries/hashlib4pascal/HlpGrindahl512.pas

@@ -18,6 +18,7 @@ uses
   HlpConverters,
   HlpIHash,
   HlpIHashInfo,
+  HlpArrayUtils,
   HlpHashCryptoNotBuildIn;
 
 type
@@ -293,11 +294,8 @@ end;
 
 procedure TGrindahl512.Initialize;
 begin
-
-  System.FillChar(Fm_state[0], System.Length(Fm_state) * System.SizeOf(UInt64),
-    UInt64(0));
-  System.FillChar(Fm_temp[0], System.Length(Fm_temp) * System.SizeOf(UInt64),
-    UInt64(0));
+  TArrayUtils.ZeroFill(Fm_state);
+  TArrayUtils.ZeroFill(Fm_temp);
 
   Inherited Initialize();
 

+ 19 - 3
src/libraries/hashlib4pascal/HlpHMACNotBuildInAdapter.pas

@@ -15,6 +15,7 @@ uses
   HlpIHash,
   HlpIHashInfo,
   HlpIHashResult,
+  HlpArrayUtils,
   HlpNullable;
 
 type
@@ -41,6 +42,11 @@ type
 
     constructor Create(const a_underlyingHash: IHash;
       const a_hmacKey: THashLibByteArray = Nil);
+
+    destructor Destroy; override;
+
+    procedure Clear();
+
     procedure Initialize(); override;
     function TransformFinal(): IHashResult; override;
     procedure TransformBytes(const a_data: THashLibByteArray;
@@ -59,6 +65,11 @@ implementation
 
 { THMACNotBuildInAdapter }
 
+procedure THMACNotBuildInAdapter.Clear();
+begin
+  TArrayUtils.ZeroFill(Fm_key);
+end;
+
 function THMACNotBuildInAdapter.Clone(): IHash;
 var
   HmacInstance: THMACNotBuildInAdapter;
@@ -82,6 +93,12 @@ begin
   System.SetLength(Fm_opad, Fm_blocksize);
 end;
 
+destructor THMACNotBuildInAdapter.Destroy;
+begin
+  Clear();
+  inherited Destroy;
+end;
+
 function THMACNotBuildInAdapter.GetKey: THashLibByteArray;
 begin
   result := System.Copy(Fm_key);
@@ -96,7 +113,6 @@ procedure THMACNotBuildInAdapter.SetKey(const value: THashLibByteArray);
 begin
   if (value = Nil) then
   begin
-
     System.SetLength(Fm_key, 0);
   end
   else
@@ -120,8 +136,8 @@ begin
     LKey := Key;
   end;
 
-  System.FillChar(Fm_ipad[0], LBlockSize * System.SizeOf(Byte), Byte($36));
-  System.FillChar(Fm_opad[0], LBlockSize * System.SizeOf(Byte), Byte($5C));
+  TArrayUtils.Fill(Fm_ipad, 0, LBlockSize, Byte($36));
+  TArrayUtils.Fill(Fm_opad, 0, LBlockSize, Byte($5C));
 
   Idx := 0;
   while (Idx < System.Length(LKey)) and (Idx < LBlockSize) do

+ 5 - 5
src/libraries/hashlib4pascal/HlpHashBuffer.pas

@@ -10,6 +10,7 @@ uses
 {$ELSE}
   SysUtils,
 {$ENDIF HAS_UNITSCOPE}
+  HlpArrayUtils,
   HlpHashLibTypes;
 
 resourcestring
@@ -53,7 +54,7 @@ implementation
 
 function THashBuffer.Clone(): THashBuffer;
 begin
-  result := Default(THashBuffer);
+  result := Default (THashBuffer);
   result.Fm_data := System.Copy(Fm_data);
   result.Fm_pos := Fm_pos;
 end;
@@ -158,8 +159,8 @@ end;
 
 function THashBuffer.GetBytesZeroPadded: THashLibByteArray;
 begin
-  System.FillChar(Fm_data[Fm_pos], (System.Length(Fm_data) - Fm_pos) *
-    System.SizeOf(Byte), Byte(0));
+  TArrayUtils.Fill(Fm_data, Fm_pos, (System.Length(Fm_data) - Fm_pos) +
+    Fm_pos, Byte(0));
   Fm_pos := 0;
   result := Fm_data;
 end;
@@ -182,8 +183,7 @@ end;
 procedure THashBuffer.Initialize;
 begin
   Fm_pos := 0;
-  System.FillChar(Fm_data[0], System.Length(Fm_data) *
-    System.SizeOf(Byte), Byte(0));
+  TArrayUtils.ZeroFill(Fm_data);
 end;
 
 function THashBuffer.ToString: String;

+ 103 - 65
src/libraries/hashlib4pascal/HlpHashFactory.pas

@@ -12,8 +12,9 @@ uses
   HlpHashLibTypes,
   // NullDigest Unit //
   HlpNullDigest,
-  // Checksum Units //
+  // Checksum Unit //
   HlpAdler32,
+  // CRC Units //
   HlpCRC,
   HlpCRC16,
   HlpCRC32,
@@ -94,7 +95,9 @@ uses
   // PBKDF2_HMAC Unit
   HlpPBKDF2_HMACNotBuildInAdapter,
   // PBKDF_Argon2 Unit
-  HlpPBKDF_Argon2NotBuildInAdapter;
+  HlpPBKDF_Argon2NotBuildInAdapter,
+  // PBKDF_Scrypt Unit
+  HlpPBKDF_ScryptNotBuildInAdapter;
 
 type
   THashFactory = class sealed(TObject)
@@ -109,10 +112,10 @@ type
 
     end;
 
-    // ====================== TChecksum ====================== //
+    // ====================== TCRC ====================== //
 
   type
-    TChecksum = class sealed(TObject)
+    TCRC = class sealed(TObject)
 
     public
 
@@ -156,6 +159,15 @@ type
       /// <returns></returns>
       class function CreateCRC64_ECMA_182(): IHash; static;
 
+    end;
+
+    // ====================== TChecksum ====================== //
+
+  type
+    TChecksum = class sealed(TObject)
+
+    public
+
       class function CreateAdler32: IHash; static;
     end;
 
@@ -413,8 +425,8 @@ type
 
     public
 
-      class function CreateHMAC(const a_hash: IHash;
-        const a_hmacKey: THashLibByteArray = Nil): IHMAC; static;
+      class function CreateHMAC(const AHash: IHash;
+        const AHmacKey: THashLibByteArray = Nil): IHMAC; static;
 
     end;
 
@@ -436,17 +448,17 @@ type
       /// an "IHash" to be used as an "IHMAC" hashing implementation to
       /// derive the key.
       /// </summary>
-      /// <param name="a_hash">
+      /// <param name="AHash">
       /// The name of the "IHash" implementation to be transformed to an
       /// "IHMAC" Instance so it can be used to derive the key.
       /// </param>
-      /// <param name="a_password">
+      /// <param name="APassword">
       /// The password to derive the key for.
       /// </param>
-      /// <param name="a_salt">
+      /// <param name="ASalt">
       /// The salt to use to derive the key.
       /// </param>
-      /// <param name="a_iterations">
+      /// <param name="AIterations">
       /// The number of iterations to use to derive the key.
       /// </param>
       /// <returns>
@@ -458,8 +470,8 @@ type
       /// <exception cref="EArgumentHashLibException">
       /// The iteration is less than 1.
       /// </exception>
-      class function CreatePBKDF2_HMAC(const a_hash: IHash;
-        const a_password, a_salt: THashLibByteArray; a_iterations: UInt32)
+      class function CreatePBKDF2_HMAC(const AHash: IHash;
+        const APassword, ASalt: THashLibByteArray; AIterations: UInt32)
         : IPBKDF2_HMAC; static;
 
     end;
@@ -494,6 +506,40 @@ type
 
     end;
 
+    // ====================== TPBKDF_Scrypt ====================== //
+
+  type
+    TPBKDF_Scrypt = class sealed(TObject)
+
+    public
+
+      /// <summary>
+      /// Initializes a new interface instance of the TPBKDF_Scrypt class
+      /// using a password, a salt, a cost, blocksize and parallelism parameters to
+      /// derive the key.
+      /// </summary>
+      /// <param name="APasswordBytes">the bytes of the pass phrase.</param>
+      /// <param name="ASaltBytes">the salt to use for this invocation.</param>
+      /// <param name="ACost">CPU/Memory cost parameter. Must be larger than 1, a power of 2 and less than
+      /// <code>2^(128 * ABlockSize / 8)</code>.</param>
+      /// <param name="ABlockSize">the block size, must be >= 1.</param>
+      /// <param name="AParallelism">Parallelization parameter. Must be a positive integer less than or equal to
+      /// <code>(System.High(Int32) div (128 * ABlockSize * 8))</code>.</param>
+      /// <returns>
+      /// The PBKDF_Scrypt KDF Interface Instance <br />
+      /// </returns>
+      /// <exception cref="EArgumentNilHashLibException">
+      /// The password, salt is Nil.
+      /// </exception>
+      /// <exception cref="EArgumentHashLibException">
+      /// The cost, blocksize or parallelism is Invalid.
+      /// </exception>
+      class function CreatePBKDF_Scrypt(const APasswordBytes,
+        ASaltBytes: THashLibByteArray; ACost, ABlockSize, AParallelism: Int32)
+        : IPBKDF_Scrypt; static;
+
+    end;
+
   end;
 
 implementation
@@ -505,22 +551,22 @@ begin
   Result := TNullDigest.Create();
 end;
 
-{ THashFactory.TChecksum }
+{ THashFactory.TCRC }
 
-class function THashFactory.TChecksum.CreateCRC(_Width: Int32;
-  _poly, _Init: UInt64; _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
+class function THashFactory.TCRC.CreateCRC(_Width: Int32; _poly, _Init: UInt64;
+  _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
   const _Names: THashLibStringArray): IHash;
 begin
-  Result := TCRC.Create(_Width, _poly, _Init, _refIn, _refOut, _XorOut,
+  Result := HlpCRC.TCRC.Create(_Width, _poly, _Init, _refIn, _refOut, _XorOut,
     _check, _Names);
 end;
 
-class function THashFactory.TChecksum.CreateCRC(_value: TCRCStandard): IHash;
+class function THashFactory.TCRC.CreateCRC(_value: TCRCStandard): IHash;
 begin
-  Result := TCRC.CreateCRCObject(_value);
+  Result := HlpCRC.TCRC.CreateCRCObject(_value);
 end;
 
-class function THashFactory.TChecksum.CreateCRC16(_poly, _Init: UInt64;
+class function THashFactory.TCRC.CreateCRC16(_poly, _Init: UInt64;
   _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
   const _Names: THashLibStringArray): IHash;
 begin
@@ -528,12 +574,12 @@ begin
     _check, _Names);
 end;
 
-class function THashFactory.TChecksum.CreateCRC16_BUYPASS: IHash;
+class function THashFactory.TCRC.CreateCRC16_BUYPASS: IHash;
 begin
   Result := TCRC16_BUYPASS.Create();
 end;
 
-class function THashFactory.TChecksum.CreateCRC32(_poly, _Init: UInt64;
+class function THashFactory.TCRC.CreateCRC32(_poly, _Init: UInt64;
   _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
   const _Names: THashLibStringArray): IHash;
 begin
@@ -541,17 +587,17 @@ begin
     _check, _Names);
 end;
 
-class function THashFactory.TChecksum.CreateCRC32_CASTAGNOLI: IHash;
+class function THashFactory.TCRC.CreateCRC32_CASTAGNOLI: IHash;
 begin
   Result := HlpCRC32Fast.TCRC32_CASTAGNOLI.Create();
 end;
 
-class function THashFactory.TChecksum.CreateCRC32_PKZIP: IHash;
+class function THashFactory.TCRC.CreateCRC32_PKZIP: IHash;
 begin
   Result := HlpCRC32Fast.TCRC32_PKZIP.Create();
 end;
 
-class function THashFactory.TChecksum.CreateCRC64(_poly, _Init: UInt64;
+class function THashFactory.TCRC.CreateCRC64(_poly, _Init: UInt64;
   _refIn, _refOut: Boolean; _XorOut, _check: UInt64;
   const _Names: THashLibStringArray): IHash;
 begin
@@ -559,11 +605,13 @@ begin
     _check, _Names);
 end;
 
-class function THashFactory.TChecksum.CreateCRC64_ECMA_182: IHash;
+class function THashFactory.TCRC.CreateCRC64_ECMA_182: IHash;
 begin
   Result := TCRC64_ECMA_182.Create();
 end;
 
+{ THashFactory.TChecksum }
+
 class function THashFactory.TChecksum.CreateAdler32: IHash;
 begin
   Result := TAdler32.Create();
@@ -1099,15 +1147,12 @@ begin
   if a_security_level < Int32(1) then
     raise EArgumentHashLibException.CreateRes(@SInvalidSnefruLevel);
 
-  if ((a_hash_size = THashSize.hsHashSize128) or
-    (a_hash_size = THashSize.hsHashSize256)) then
-  begin
-    Result := TSnefru.Create(a_security_level, a_hash_size);
-  end
+  case a_hash_size of
+    THashSize.hsHashSize128, THashSize.hsHashSize256:
+      Result := TSnefru.Create(a_security_level, a_hash_size);
   else
-  begin
     raise EArgumentHashLibException.CreateRes(@SInvalidSnefruHashSize);
-  end
+  end;
 
 end;
 
@@ -1174,19 +1219,23 @@ end;
 class function THashFactory.TCrypto.CreateTiger(a_hash_size: Int32;
   a_rounds: THashRounds): IHash;
 begin
-  if ((a_hash_size <> 16) and (a_hash_size <> 20) and (a_hash_size <> 24)) then
+  case a_hash_size of
+    16, 20, 24:
+      Result := TTiger_Base.Create(a_hash_size, a_rounds);
+  else
     raise EArgumentHashLibException.CreateRes(@SInvalidTigerHashSize);
-
-  Result := TTiger_Base.Create(a_hash_size, a_rounds);
+  end;
 end;
 
 class function THashFactory.TCrypto.CreateTiger2(a_hash_size: Int32;
   a_rounds: THashRounds): IHash;
 begin
-  if ((a_hash_size <> 16) and (a_hash_size <> 20) and (a_hash_size <> 24)) then
+  case a_hash_size of
+    16, 20, 24:
+      Result := TTiger2_Base.Create(a_hash_size, a_rounds);
+  else
     raise EArgumentHashLibException.CreateRes(@SInvalidTiger2HashSize);
-
-  Result := TTiger2_Base.Create(a_hash_size, a_rounds);
+  end;
 end;
 
 class function THashFactory.TCrypto.CreateTiger2_3_128: IHash;
@@ -1258,33 +1307,19 @@ end;
 
 { THashFactory.THMAC }
 
-class function THashFactory.THMAC.CreateHMAC(const a_hash: IHash;
-  const a_hmacKey: THashLibByteArray): IHMAC;
+class function THashFactory.THMAC.CreateHMAC(const AHash: IHash;
+  const AHmacKey: THashLibByteArray): IHMAC;
 begin
-  Result := THMACNotBuildInAdapter.CreateHMAC(a_hash, a_hmacKey);
+  Result := THMACNotBuildInAdapter.CreateHMAC(AHash, AHmacKey);
 end;
 
 { TKDF.TPBKDF2_HMAC }
 
-class function TKDF.TPBKDF2_HMAC.CreatePBKDF2_HMAC(const a_hash: IHash;
-  const a_password, a_salt: THashLibByteArray; a_iterations: UInt32)
-  : IPBKDF2_HMAC;
+class function TKDF.TPBKDF2_HMAC.CreatePBKDF2_HMAC(const AHash: IHash;
+  const APassword, ASalt: THashLibByteArray; AIterations: UInt32): IPBKDF2_HMAC;
 begin
-
-  if not(System.Assigned(a_hash)) then
-    raise EArgumentNilHashLibException.CreateRes(@SNotInitializedIHashInstance);
-
-  if (a_password = Nil) then
-    raise EArgumentNilHashLibException.CreateRes(@SEmptyPassword);
-
-  if (a_salt = Nil) then
-    raise EArgumentNilHashLibException.CreateRes(@SEmptySalt);
-
-  if (a_iterations < 1) then
-    raise EArgumentHashLibException.CreateRes(@SIterationtooSmall);
-
-  Result := TPBKDF2_HMACNotBuildInAdapter.Create(a_hash, a_password, a_salt,
-    a_iterations);
+  Result := TPBKDF2_HMACNotBuildInAdapter.Create(AHash, APassword, ASalt,
+    AIterations);
 end;
 
 { TKDF.TPBKDF_Argon2 }
@@ -1293,14 +1328,17 @@ class function TKDF.TPBKDF_Argon2.CreatePBKDF_Argon2(const APassword
   : THashLibByteArray; const AArgon2Parameters: IArgon2Parameters)
   : IPBKDF_Argon2;
 begin
-  if not(System.Assigned(AArgon2Parameters)) then
-    raise EArgumentNilHashLibException.CreateRes
-      (@SArgon2ParameterBuilderNotInitialized);
+  Result := TPBKDF_Argon2NotBuildInAdapter.Create(APassword, AArgon2Parameters)
+end;
 
-  if (APassword = Nil) then
-    raise EArgumentNilHashLibException.CreateRes(@SEmptyPassword);
+{ TKDF.TPBKDF_Scrypt }
 
-  Result := TPBKDF_Argon2NotBuildInAdapter.Create(APassword, AArgon2Parameters)
+class function TKDF.TPBKDF_Scrypt.CreatePBKDF_Scrypt(const APasswordBytes,
+  ASaltBytes: THashLibByteArray; ACost, ABlockSize, AParallelism: Int32)
+  : IPBKDF_Scrypt;
+begin
+  Result := TPBKDF_ScryptNotBuildInAdapter.Create(APasswordBytes, ASaltBytes,
+    ACost, ABlockSize, AParallelism);
 end;
 
 end.

+ 3 - 29
src/libraries/hashlib4pascal/HlpHashResult.pas

@@ -27,7 +27,8 @@ uses
   HlpBits,
   HlpHashLibTypes,
   HlpIHashResult,
-  HlpConverters;
+  HlpConverters,
+  HlpArrayUtils;
 
 resourcestring
   SImpossibleRepresentationInt32 =
@@ -48,9 +49,6 @@ type
 
     Fm_hash: THashLibByteArray;
 
-    class function SlowEquals(const a_ar1, a_ar2: THashLibByteArray)
-      : Boolean; static;
-
   public
 
     constructor Create(a_hash: Int32); overload;
@@ -119,7 +117,7 @@ end;
 
 function THashResult.Equals(const a_hashResult: IHashResult): Boolean;
 begin
-  result := THashResult.SlowEquals(a_hashResult.GetBytes(), Fm_hash);
+  result := TArrayUtils.ConstantTimeAreEqual(a_hashResult.GetBytes(), Fm_hash);
 end;
 
 function THashResult.GetBytes: THashLibByteArray;
@@ -248,30 +246,6 @@ begin
 
 end;
 
-{$B+}
-
-class function THashResult.SlowEquals(const a_ar1,
-  a_ar2: THashLibByteArray): Boolean;
-var
-  I: Int32;
-  diff: UInt32;
-
-begin
-  diff := UInt32(System.Length(a_ar1)) xor UInt32(System.Length(a_ar2));
-
-  I := 0;
-
-  while (I <= System.High(a_ar1)) and (I <= System.High(a_ar2)) do
-  begin
-    diff := diff or (UInt32(a_ar1[I] xor a_ar2[I]));
-    System.Inc(I);
-  end;
-
-  result := diff = 0;
-end;
-
-{$B-}
-
 function THashResult.ToString(a_group: Boolean): String;
 begin
   result := TConverters.ConvertBytesToHexString(Fm_hash, a_group);

+ 9 - 0
src/libraries/hashlib4pascal/HlpIHashInfo.pas

@@ -64,8 +64,17 @@ type
     ['{666D652C-E4E5-4C72-B09F-145495D1A95D}']
   end;
 
+  IPBKDF_Scrypt = Interface(IKDF)
+    ['{D1AD2681-FBDB-41EF-B8F5-72E3F5872D27}']
+  end;
+
+  IPBKDF_ScryptNotBuildIn = Interface(IPBKDF_Scrypt)
+    ['{7DD70C4D-FBF6-4629-B587-C6A7CC047D35}']
+  end;
+
   IHMAC = Interface(IWithKey)
     ['{A6D4DCC6-F6C3-4110-8CA2-FBE85227676E}']
+    procedure Clear();
   end;
 
   IHMACNotBuildIn = Interface(IHMAC)

+ 2 - 0
src/libraries/hashlib4pascal/HlpIKDF.pas

@@ -10,6 +10,8 @@ uses
 type
   IKDF = interface(IInterface)
     ['{4697798C-9DC2-476C-A6C2-2D633B74D3FC}']
+
+    procedure Clear();
     /// <summary>
     /// Returns the pseudo-random bytes for this object.
     /// </summary>

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