Browse Source

Added ECIES Encryption Support

- added two modes
- IEEE Std 1363a
- Current PascalCoin compatibility mode.
Ugochukwu Mmaduekwe 7 years ago
parent
commit
370c6c3287
59 changed files with 4306 additions and 121 deletions
  1. 37 1
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  2. 1 0
      CryptoLib.Samples/FreePascal.Samples/UsageSamples.lpr
  3. 304 80
      CryptoLib.Samples/src/UsageExamples.pas
  4. 42 1
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  5. 7 3
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
  6. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
  7. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi
  8. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
  9. 8 10
      CryptoLib.Tests/src/Crypto/AESTests.pas
  10. 278 0
      CryptoLib.Tests/src/Crypto/IESCipherTests.pas
  11. 2 2
      CryptoLib/src/Asn1/ClpAsn1InputStream.pas
  12. 137 0
      CryptoLib/src/Crypto/Agreement/ClpECDHBasicAgreement.pas
  13. 84 0
      CryptoLib/src/Crypto/ClpEphemeralKeyPair.pas
  14. 280 0
      CryptoLib/src/Crypto/ClpIESCipher.pas
  15. 34 0
      CryptoLib/src/Crypto/ClpKeyEncoder.pas
  16. 615 0
      CryptoLib/src/Crypto/Engines/ClpIESEngine.pas
  17. 307 0
      CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas
  18. 218 0
      CryptoLib/src/Crypto/Generators/ClpBaseKdfBytesGenerator.pas
  19. 70 0
      CryptoLib/src/Crypto/Generators/ClpEphemeralKeyPairGenerator.pas
  20. 64 0
      CryptoLib/src/Crypto/Generators/ClpKdf2BytesGenerator.pas
  21. 153 0
      CryptoLib/src/Crypto/Generators/ClpPascalCoinECIESKdfBytesGenerator.pas
  22. 3 1
      CryptoLib/src/Crypto/Paddings/ClpPaddedBufferedBlockCipher.pas
  23. 31 10
      CryptoLib/src/Crypto/Paddings/ClpPkcs7Padding.pas
  24. 134 0
      CryptoLib/src/Crypto/Paddings/ClpZeroBytePadding.pas
  25. 87 0
      CryptoLib/src/Crypto/Parameters/ClpIesParameters.pas
  26. 99 0
      CryptoLib/src/Crypto/Parameters/ClpIesWithCipherParameters.pas
  27. 61 0
      CryptoLib/src/Crypto/Parameters/ClpIso18033KdfParameters.pas
  28. 68 0
      CryptoLib/src/Crypto/Parameters/ClpKdfParameters.pas
  29. 105 0
      CryptoLib/src/Crypto/Parsers/ClpECIESPublicKeyParser.pas
  30. 1 0
      CryptoLib/src/Crypto/Signers/ClpDsaDigestSigner.pas
  31. 1 0
      CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas
  32. 1 1
      CryptoLib/src/Crypto/Signers/ClpECSchnorrSigner.pas
  33. 36 0
      CryptoLib/src/Interfaces/ClpIBaseKdfBytesGenerator.pas
  34. 58 0
      CryptoLib/src/Interfaces/ClpIBasicAgreement.pas
  35. 55 0
      CryptoLib/src/Interfaces/ClpIDerivationFunction.pas
  36. 36 0
      CryptoLib/src/Interfaces/ClpIDerivationParameters.pas
  37. 49 0
      CryptoLib/src/Interfaces/ClpIECDHBasicAgreement.pas
  38. 40 0
      CryptoLib/src/Interfaces/ClpIECIESPublicKeyParser.pas
  39. 40 0
      CryptoLib/src/Interfaces/ClpIEphemeralKeyPair.pas
  40. 37 0
      CryptoLib/src/Interfaces/ClpIEphemeralKeyPairGenerator.pas
  41. 52 0
      CryptoLib/src/Interfaces/ClpIIESCipher.pas
  42. 103 0
      CryptoLib/src/Interfaces/ClpIIESEngine.pas
  43. 42 0
      CryptoLib/src/Interfaces/ClpIIesParameters.pas
  44. 44 0
      CryptoLib/src/Interfaces/ClpIIesWithCipherParameters.pas
  45. 39 0
      CryptoLib/src/Interfaces/ClpIIso18033KdfParameters.pas
  46. 36 0
      CryptoLib/src/Interfaces/ClpIKdf2BytesGenerator.pas
  47. 40 0
      CryptoLib/src/Interfaces/ClpIKdfParameters.pas
  48. 40 0
      CryptoLib/src/Interfaces/ClpIKeyParser.pas
  49. 61 0
      CryptoLib/src/Interfaces/ClpIPascalCoinECIESKdfBytesGenerator.pas
  50. 36 0
      CryptoLib/src/Interfaces/ClpIPascalCoinIESEngine.pas
  51. 36 0
      CryptoLib/src/Interfaces/ClpIZeroBytePadding.pas
  52. 143 3
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
  53. 15 1
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
  54. 9 2
      CryptoLib/src/Security/ClpCipherUtilities.pas
  55. 1 1
      CryptoLib/src/Security/ClpParameterUtilities.pas
  56. 15 1
      CryptoLib/src/Utils/ClpArrayUtils.pas
  57. 2 2
      CryptoLib/src/Utils/ClpBigIntegers.pas
  58. 1 0
      CryptoLib/src/Utils/ClpCryptoLibTypes.pas
  59. 1 1
      CryptoLib/src/Utils/Helpers/ClpStreamHelper.pas

+ 37 - 1
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -309,7 +309,42 @@ uses
   ClpGeneratorUtilities in '..\..\CryptoLib\src\Security\ClpGeneratorUtilities.pas',
   ClpParameterUtilities in '..\..\CryptoLib\src\Security\ClpParameterUtilities.pas',
   ClpAesEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpAesEngine.pas',
-  ClpIAesEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesEngine.pas';
+  ClpIAesEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesEngine.pas',
+  ClpECDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHBasicAgreement.pas',
+  ClpIBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIBasicAgreement.pas',
+  ClpIECDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIECDHBasicAgreement.pas',
+  ClpIESParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESParameters.pas',
+  ClpIIESParameters in '..\..\CryptoLib\src\Interfaces\ClpIIESParameters.pas',
+  ClpIESWithCipherParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESWithCipherParameters.pas',
+  ClpIIESWithCipherParameters in '..\..\CryptoLib\src\Interfaces\ClpIIESWithCipherParameters.pas',
+  ClpIDerivationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDerivationParameters.pas',
+  ClpIDerivationFunction in '..\..\CryptoLib\src\Interfaces\ClpIDerivationFunction.pas',
+  ClpKdfParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpKdfParameters.pas',
+  ClpIKdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIKdfParameters.pas',
+  ClpIso18033KdfParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIso18033KdfParameters.pas',
+  ClpIIso18033KdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIIso18033KdfParameters.pas',
+  ClpBaseKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpBaseKdfBytesGenerator.pas',
+  ClpIBaseKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIBaseKdfBytesGenerator.pas',
+  ClpKdf2BytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpKdf2BytesGenerator.pas',
+  ClpIKdf2BytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIKdf2BytesGenerator.pas',
+  ClpIKeyParser in '..\..\CryptoLib\src\Interfaces\ClpIKeyParser.pas',
+  ClpEphemeralKeyPair in '..\..\CryptoLib\src\Crypto\ClpEphemeralKeyPair.pas',
+  ClpIEphemeralKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIEphemeralKeyPair.pas',
+  ClpEphemeralKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas',
+  ClpIEphemeralKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEphemeralKeyPairGenerator.pas',
+  ClpKeyEncoder in '..\..\CryptoLib\src\Crypto\ClpKeyEncoder.pas',
+  ClpIESCipher in '..\..\CryptoLib\src\Crypto\ClpIESCipher.pas',
+  ClpIIESCipher in '..\..\CryptoLib\src\Interfaces\ClpIIESCipher.pas',
+  ClpECIESPublicKeyParser in '..\..\CryptoLib\src\Crypto\Parsers\ClpECIESPublicKeyParser.pas',
+  ClpIECIESPublicKeyParser in '..\..\CryptoLib\src\Interfaces\ClpIECIESPublicKeyParser.pas',
+  ClpZeroBytePadding in '..\..\CryptoLib\src\Crypto\Paddings\ClpZeroBytePadding.pas',
+  ClpIZeroBytePadding in '..\..\CryptoLib\src\Interfaces\ClpIZeroBytePadding.pas',
+  ClpIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpIESEngine.pas',
+  ClpIIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIIESEngine.pas',
+  ClpPascalCoinIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpPascalCoinIESEngine.pas',
+  ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
+  ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
+  ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas';
 
 begin
   try
@@ -320,6 +355,7 @@ begin
     TUsageExamples.RecreatePublicAndPrivateKeyPairsFromByteArray;
     TUsageExamples.RecreatePublicKeyFromXAndYCoordByteArray;
     TUsageExamples.BinaryCompatiblePascalCoinAES256EncryptDecryptDemo('Pascal Rules', 'Pascal');
+    TUsageExamples.BinaryCompatiblePascalCoinECIESEncryptDecryptDemo('Kowalski');
     Readln;
   except
     on E: Exception do

+ 1 - 0
CryptoLib.Samples/FreePascal.Samples/UsageSamples.lpr

@@ -16,6 +16,7 @@ begin
     TUsageExamples.RecreatePublicAndPrivateKeyPairsFromByteArray;
     TUsageExamples.RecreatePublicKeyFromXAndYCoordByteArray;
     TUsageExamples.BinaryCompatiblePascalCoinAES256EncryptDecryptDemo('Pascal Rules', 'Pascal');
+    TUsageExamples.BinaryCompatiblePascalCoinECIESEncryptDecryptDemo('Kowalski');
     Readln;
   except
     on E: Exception do

+ 304 - 80
CryptoLib.Samples/src/UsageExamples.pas

@@ -19,6 +19,8 @@ unit UsageExamples;
 
 {$IFDEF FPC}
 {$MODE DELPHI}
+{$HINTS OFF}
+{$WARNINGS OFF}
 {$ENDIF FPC}
 
 interface
@@ -26,6 +28,7 @@ interface
 uses
   SysUtils,
   HlpIHash,
+  HlpIHashInfo,
   HlpHashFactory,
   ClpBigInteger,
   ClpSecureRandom,
@@ -38,23 +41,44 @@ uses
   ClpIECKeyGenerationParameters,
   ClpECKeyGenerationParameters,
   ClpIAsymmetricCipherKeyPair,
+  ClpAsymmetricCipherKeyPair,
   ClpIECPrivateKeyParameters,
   ClpIECPublicKeyParameters,
   ClpECPublicKeyParameters,
   ClpECPrivateKeyParameters,
+  ClpIAsymmetricKeyParameter,
   ClpECSchnorrSigner,
   ClpIECInterface,
   ClpECPoint,
   ClpISigner,
   ClpSignerUtilities,
-  ClpKeyParameter,
-  ClpIKeyParameter,
   ClpParametersWithIV,
   ClpIParametersWithIV,
   ClpIBufferedCipher,
+  ClpIBufferedBlockCipher,
+  // ClpIIESEngine,
+  // ClpIESEngine,
+  ClpPascalCoinIESEngine,
+  ClpIPascalCoinIESEngine,
+  ClpIIESWithCipherParameters,
+  ClpIESWithCipherParameters,
+  ClpIAesEngine,
+  ClpAesEngine,
+  ClpICbcBlockCipher,
+  ClpCbcBlockCipher,
+  ClpIZeroBytePadding,
+  ClpZeroBytePadding,
+  ClpIIESCipher,
+  ClpIESCipher,
+  ClpIECDHBasicAgreement,
+  ClpECDHBasicAgreement,
+  ClpIPascalCoinECIESKdfBytesGenerator,
+  ClpPascalCoinECIESKdfBytesGenerator,
+  ClpPaddedBufferedBlockCipher,
   ClpParameterUtilities,
   ClpCipherUtilities,
-  ClpHex,
+  ClpGeneratorUtilities,
+  ClpIAsymmetricCipherKeyPairGenerator,
   ClpArrayUtils,
   ClpSecNamedCurves;
 
@@ -89,6 +113,11 @@ type
     class function BytesToHexString(input: TBytes): String; static;
     class constructor UsageExamples();
   private
+    class procedure DoSigningAndVerifying(const PublicKey
+      : IECPublicKeyParameters; const PrivateKey: IECPrivateKeyParameters;
+      const CallerMethod, TextToSign: String;
+      const SigningAlgo: String = SigningAlgorithmECDSA); static;
+
     class function EVP_GetSalt(): TBytes; static; inline;
     class function EVP_GetKeyIV(PasswordBytes, SaltBytes: TBytes;
       out KeyBytes, IVBytes: TBytes): Boolean; static;
@@ -98,6 +127,17 @@ type
     class function AES256CBCPascalCoinDecrypt(CipherText, PasswordBytes: TBytes;
       out PlainText: TBytes): Boolean; static;
 
+    class function GetECIESPascalCoinCompatibilityEngine
+      : IPascalCoinIESEngine; static;
+    class function GetECKeyPair: IAsymmetricCipherKeyPair; static;
+    class function GetIESCipherParameters: IIESWithCipherParameters; static;
+
+    class function ECIESPascalCoinEncrypt(const PublicKey
+      : IAsymmetricKeyParameter; PlainText: TBytes): TBytes; static;
+    class function ECIESPascalCoinDecrypt(const PrivateKey
+      : IAsymmetricKeyParameter; CipherText: TBytes; out PlainText: TBytes)
+      : Boolean; static;
+
   public
     class procedure GenerateKeyPairAndSignECDSA(); static;
     class procedure GenerateKeyPairAndSignECSchnorr(); static;
@@ -106,12 +146,38 @@ type
     class procedure RecreatePublicKeyFromXAndYCoordByteArray; static;
     class procedure BinaryCompatiblePascalCoinAES256EncryptDecryptDemo
       (const inputmessage, password: string); static;
+    class procedure BinaryCompatiblePascalCoinECIESEncryptDecryptDemo
+      (const input: string); static;
   end;
 
 implementation
 
 { TUsageExamples }
 
+class function TUsageExamples.ECIESPascalCoinDecrypt(const PrivateKey
+  : IAsymmetricKeyParameter; CipherText: TBytes; out PlainText: TBytes)
+  : Boolean;
+var
+  CipherDecrypt: IIESCipher;
+begin
+  // Decryption
+  CipherDecrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine);
+  CipherDecrypt.Init(False, PrivateKey, GetIESCipherParameters, FRandom);
+  PlainText := CipherDecrypt.DoFinal(CipherText);
+  Result := True;
+end;
+
+class function TUsageExamples.ECIESPascalCoinEncrypt(const PublicKey
+  : IAsymmetricKeyParameter; PlainText: TBytes): TBytes;
+var
+  CipherEncrypt: IIESCipher;
+begin
+  // Encryption
+  CipherEncrypt := TIESCipher.Create(GetECIESPascalCoinCompatibilityEngine);
+  CipherEncrypt.Init(True, PublicKey, GetIESCipherParameters, FRandom);
+  Result := CipherEncrypt.DoFinal(PlainText);
+end;
+
 class function TUsageExamples.EVP_GetKeyIV(PasswordBytes, SaltBytes: TBytes;
   out KeyBytes, IVBytes: TBytes): Boolean;
 var
@@ -162,7 +228,7 @@ var
   cipher: IBufferedCipher;
   LBufStart, LSrcStart, Count: Int32;
 begin
-  Result := false;
+  Result := False;
 
   System.SetLength(SaltBytes, SALT_SIZE);
   // First read the magic text and the salt - if any
@@ -190,7 +256,7 @@ begin
   KeyParametersWithIV := TParametersWithIV.Create
     (TParameterUtilities.CreateKeyParameter('AES', KeyBytes), IVBytes);
 
-  cipher.Init(false, KeyParametersWithIV); // init decryption cipher
+  cipher.Init(False, KeyParametersWithIV); // init decryption cipher
 
   System.SetLength(Buf, System.Length(CipherText));
 
@@ -277,6 +343,33 @@ begin
 
 end;
 
+class procedure TUsageExamples.BinaryCompatiblePascalCoinECIESEncryptDecryptDemo
+  (const input: string);
+var
+  PlainText, CipherText, DecryptedCipherText: TBytes;
+  KeyPair: IAsymmetricCipherKeyPair;
+begin
+  KeyPair := GetECKeyPair;
+  PlainText := TEncoding.UTF8.GetBytes(input);
+  CipherText := TUsageExamples.ECIESPascalCoinEncrypt(KeyPair.Public,
+    PlainText);
+
+  if TUsageExamples.ECIESPascalCoinDecrypt(KeyPair.Private, CipherText,
+    DecryptedCipherText) then
+  begin
+    if TArrayUtils.AreEqual(PlainText, DecryptedCipherText) then
+    begin
+      Writeln('ECIES PascalCoin Compatability Encrypt, Decrypt Was Successful '
+        + sLineBreak);
+      Exit;
+    end;
+
+  end;
+
+  Writeln('ECIES PascalCoin Compatability Encrypt, Decrypt Failed ' +
+    sLineBreak);
+end;
+
 class function TUsageExamples.BytesToHexString(input: TBytes): String;
 var
   index: Int32;
@@ -296,16 +389,56 @@ begin
   Result := '[' + Result + ']';
 end;
 
+class procedure TUsageExamples.DoSigningAndVerifying(const PublicKey
+  : IECPublicKeyParameters; const PrivateKey: IECPrivateKeyParameters;
+  const CallerMethod, TextToSign: String;
+  const SigningAlgo: String = SigningAlgorithmECDSA);
+var
+  Signer: ISigner;
+  &message, sigBytes: TBytes;
+begin
+
+  Writeln('Caller Method Is ' + CallerMethod + sLineBreak);
+
+  Signer := TSignerUtilities.GetSigner(SigningAlgo);
+
+  Writeln('Signer Name is: ' + Signer.AlgorithmName + sLineBreak);
+
+  &message := TEncoding.UTF8.GetBytes(TextToSign);
+
+  // Sign
+  Signer.Init(True, PrivateKey);
+
+  Signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  sigBytes := Signer.GenerateSignature();
+
+  Writeln('Generated Signature is: ' + BytesToHexString(sigBytes) + sLineBreak);
+
+  // Verify
+
+  Signer.Init(False, PublicKey);
+
+  Signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  if (not Signer.VerifySignature(sigBytes)) then
+  begin
+    Writeln(PublicKey.AlgorithmName + ' verification failed' + sLineBreak);
+  end
+  else
+  begin
+    Writeln(PublicKey.AlgorithmName + ' verification passed' + sLineBreak);
+  end;
+end;
+
 class procedure TUsageExamples.GenerateKeyPairAndSignECDSA;
 var
   domain: IECDomainParameters;
   generator: IECKeyPairGenerator;
   keygenParams: IECKeyGenerationParameters;
-  keypair: IAsymmetricCipherKeyPair;
+  KeyPair: IAsymmetricCipherKeyPair;
   privParams: IECPrivateKeyParameters;
   pubParams: IECPublicKeyParameters;
-  signer: ISigner;
-  &message, sigBytes: TBytes;
 const
   MethodName = 'GenerateKeyPairAndSignECDSA';
 begin
@@ -318,9 +451,9 @@ begin
   keygenParams := TECKeyGenerationParameters.Create(domain, FRandom);
   generator.Init(keygenParams);
 
-  keypair := generator.GenerateKeyPair();
-  privParams := keypair.Private as IECPrivateKeyParameters; // for signing
-  pubParams := keypair.Public as IECPublicKeyParameters; // for verifying
+  KeyPair := generator.GenerateKeyPair();
+  privParams := KeyPair.Private as IECPrivateKeyParameters; // for signing
+  pubParams := KeyPair.Public as IECPublicKeyParameters; // for verifying
 
   Writeln('Algorithm Name is: ' + pubParams.AlgorithmName + sLineBreak);
 
@@ -332,36 +465,7 @@ begin
   Writeln('Private Key D Parameter is: ' + privParams.D.ToString(16) +
     sLineBreak);
 
-  signer := TSignerUtilities.GetSigner(SigningAlgorithmECDSA);
-
-  Writeln('Signer Name is: ' + signer.AlgorithmName + sLineBreak);
-
-  // sign
-
-  signer.Init(True, privParams);
-
-  &message := TEncoding.UTF8.GetBytes('PascalECDSA');
-
-  signer.BlockUpdate(&message, 0, System.Length(&message));
-
-  sigBytes := signer.GenerateSignature();
-
-  Writeln('Generated Signature is: ' + BytesToHexString(sigBytes) + sLineBreak);
-
-  // verify
-
-  signer.Init(false, pubParams);
-
-  signer.BlockUpdate(&message, 0, System.Length(&message));
-
-  if (not signer.VerifySignature(sigBytes)) then
-  begin
-    Writeln(pubParams.AlgorithmName + ' verification failed' + sLineBreak);
-  end
-  else
-  begin
-    Writeln(pubParams.AlgorithmName + ' verification passed' + sLineBreak);
-  end;
+  DoSigningAndVerifying(pubParams, privParams, MethodName, 'PascalECDSA');
 
 end;
 
@@ -370,11 +474,9 @@ var
   domain: IECDomainParameters;
   generator: IECKeyPairGenerator;
   keygenParams: IECKeyGenerationParameters;
-  keypair: IAsymmetricCipherKeyPair;
+  KeyPair: IAsymmetricCipherKeyPair;
   privParams: IECPrivateKeyParameters;
   pubParams: IECPublicKeyParameters;
-  signer: ISigner;
-  &message, sigBytes: TBytes;
 const
   MethodName = 'GenerateKeyPairAndSignECSchnorr';
 begin
@@ -387,9 +489,9 @@ begin
   keygenParams := TECKeyGenerationParameters.Create(domain, FRandom);
   generator.Init(keygenParams);
 
-  keypair := generator.GenerateKeyPair();
-  privParams := keypair.Private as IECPrivateKeyParameters; // for signing
-  pubParams := keypair.Public as IECPublicKeyParameters; // for verifying
+  KeyPair := generator.GenerateKeyPair();
+  privParams := KeyPair.Private as IECPrivateKeyParameters; // for signing
+  pubParams := KeyPair.Public as IECPublicKeyParameters; // for verifying
 
   Writeln('Algorithm Name is: ' + pubParams.AlgorithmName + sLineBreak);
 
@@ -401,37 +503,132 @@ begin
   Writeln('Private Key D Parameter is: ' + privParams.D.ToString(16) +
     sLineBreak);
 
-  signer := TSignerUtilities.GetSigner(SigningAlgorithmECSCHNORR);
+  DoSigningAndVerifying(pubParams, privParams, MethodName, 'PascalECSCHNORR',
+    SigningAlgorithmECSCHNORR);
 
-  Writeln('Signer Name is: ' + signer.AlgorithmName + sLineBreak);
+end;
 
-  // sign
+class function TUsageExamples.GetECIESPascalCoinCompatibilityEngine
+  : IPascalCoinIESEngine;
+var
+  cipher: IBufferedBlockCipher;
+  AesEngine: IAesEngine;
+  blockCipher: ICbcBlockCipher;
+  ECDHBasicAgreementInstance: IECDHBasicAgreement;
+  KDFInstance: IPascalCoinECIESKdfBytesGenerator;
+  HMACInstance: IHMAC;
 
-  signer.Init(True, privParams);
+begin
+  // Set up IES Cipher Engine For Compatibility With PascalCoin
 
-  &message := TEncoding.UTF8.GetBytes('PascalECSCHNORR');
+  ECDHBasicAgreementInstance := TECDHBasicAgreement.Create();
 
-  signer.BlockUpdate(&message, 0, System.Length(&message));
+  KDFInstance := TPascalCoinECIESKdfBytesGenerator.Create
+    (THashFactory.TCrypto.CreateSHA2_512 as IHash);
 
-  sigBytes := signer.GenerateSignature();
+  HMACInstance := THashFactory.THMAC.CreateHMAC
+    (THashFactory.TCrypto.CreateMD5 as IHash);
 
-  Writeln('Generated Signature is: ' + BytesToHexString(sigBytes) + sLineBreak);
+  // Set Up Block Cipher
+  AesEngine := TAesEngine.Create(); // AES Engine
 
-  // verify
+  blockCipher := TCbcBlockCipher.Create(AesEngine); // CBC
 
-  signer.Init(false, pubParams);
+  cipher := TPaddedBufferedBlockCipher.Create(blockCipher,
+    TZeroBytePadding.Create() as IZeroBytePadding); // ZeroBytePadding
 
-  signer.BlockUpdate(&message, 0, System.Length(&message));
+  Result := TPascalCoinIESEngine.Create(ECDHBasicAgreementInstance, KDFInstance,
+    HMACInstance, cipher);
+end;
 
-  if (not signer.VerifySignature(sigBytes)) then
-  begin
-    Writeln(pubParams.AlgorithmName + ' verification failed' + sLineBreak);
-  end
-  else
-  begin
-    Writeln(pubParams.AlgorithmName + ' verification passed' + sLineBreak);
-  end;
+class function TUsageExamples.GetECKeyPair: IAsymmetricCipherKeyPair;
+const
+  AccountPrivateKeyHex =
+    'Enter Your Decrypted Private Key Here in Hexadecimal!!!';
+  CurveName = 'secp256k1';
+var
+  Lcurve: IX9ECParameters;
+  domain: IECDomainParameters;
+  // PrivateKeyBytes: TBytes;
+  // RegeneratedPublicKey: IECPublicKeyParameters;
+  // RegeneratedPrivateKey: IECPrivateKeyParameters;
+  // PrivD: TBigInteger;
+  KeyPairGeneratorInstance: IAsymmetricCipherKeyPairGenerator;
+const
+  MethodName = 'GetECKeyPair';
+begin
+  // Create From Existing Parameter Method
+  // System.Assert(AccountPrivateKeyHex <> '', 'Private Key Cannot be Empty');
+  // System.Assert(CurveName <> '', 'CurveName Cannot be Empty');
+  //
+  // PrivateKeyBytes := THex.Decode(AccountPrivateKeyHex);
+  // Lcurve := TSecNamedCurves.GetByName(CurveName);
+  // System.Assert(Lcurve <> Nil, 'Curve Cannot be Nil');
+  //
+  // // Set Up Asymmetric Key Pair from known private key ByteArray
+  //
+  // domain := TECDomainParameters.Create(Lcurve.Curve, Lcurve.G, Lcurve.N,
+  // Lcurve.H, Lcurve.GetSeed);
+  //
+  // PrivD := TBigInteger.Create(1, PrivateKeyBytes);
+  // RegeneratedPrivateKey := TECPrivateKeyParameters.Create('ECDSA',
+  // PrivD, domain);
+  //
+  // RegeneratedPublicKey := TECKeyPairGenerator.GetCorrespondingPublicKey
+  // (RegeneratedPrivateKey);
+  //
+  // Result := TAsymmetricCipherKeyPair.Create
+  // (RegeneratedPublicKey as IAsymmetricKeyParameter,
+  // RegeneratedPrivateKey as IAsymmetricKeyParameter);
+  //
+  // // Do Signing and Verifying to Assert Proper Recreation Of Public and Private Key
+  // DoSigningAndVerifying(RegeneratedPublicKey, RegeneratedPrivateKey, MethodName,
+  // 'PascalECDSA');
+
+  // Full Generation Method
+
+  Lcurve := TSecNamedCurves.GetByName(CurveName);
+  KeyPairGeneratorInstance := TGeneratorUtilities.GetKeyPairGenerator('ECDSA');
+  domain := TECDomainParameters.Create(Lcurve.Curve, Lcurve.G, Lcurve.N,
+    Lcurve.H, Lcurve.GetSeed);
+  KeyPairGeneratorInstance.Init(TECKeyGenerationParameters.Create(domain,
+    FRandom));
+  Result := KeyPairGeneratorInstance.GenerateKeyPair();
+
+  DoSigningAndVerifying(Result.Public as IECPublicKeyParameters,
+    Result.Private as IECPrivateKeyParameters, MethodName, 'PascalECDSA');
+
+end;
+
+class function TUsageExamples.GetIESCipherParameters: IIESWithCipherParameters;
+var
+  Derivation, Encoding, IVBytes: TBytes;
+  MacKeySizeInBits, CipherKeySizeInBits: Int32;
+  UsePointCompression: Boolean;
+begin
+  // Set up  IES Cipher Parameters For Compatibility With PascalCoin Current Implementation
+
+  // The derivation and encoding vectors are used when initialising the KDF and MAC.
+  // They're optional but if used then they need to be known by the other user so that
+  // they can decrypt the ciphertext and verify the MAC correctly. The security is based
+  // on the shared secret coming from the (static-ephemeral) ECDH key agreement.
+  Derivation := Nil;
+
+  Encoding := Nil;
+
+  System.SetLength(IVBytes, 16); // using Zero Initialized IV for compatibility
+
+  MacKeySizeInBits := 32 * 8;
+
+  // Since we are using AES256_CBC for compatibility
+  CipherKeySizeInBits := 32 * 8;
+
+  // whether to use point compression when deriving the octets string
+  // from a point or not in the EphemeralKeyPairGenerator
+  UsePointCompression := True; // for compatibility
 
+  Result := TIESWithCipherParameters.Create(Derivation, Encoding, IVBytes,
+    MacKeySizeInBits, CipherKeySizeInBits, UsePointCompression);
 end;
 
 class procedure TUsageExamples.GetPublicKeyFromPrivateKey;
@@ -439,7 +636,7 @@ var
   domain: IECDomainParameters;
   generator: IECKeyPairGenerator;
   keygenParams: IECKeyGenerationParameters;
-  keypair: IAsymmetricCipherKeyPair;
+  KeyPair: IAsymmetricCipherKeyPair;
   privParams: IECPrivateKeyParameters;
   pubParams, recreatedPubKeyParameters: IECPublicKeyParameters;
   EncodedPublicKey, RecreatedEncodedPublicKey: TBytes;
@@ -456,9 +653,9 @@ begin
   keygenParams := TECKeyGenerationParameters.Create(domain, FRandom);
   generator.Init(keygenParams);
 
-  keypair := generator.GenerateKeyPair();
-  privParams := keypair.Private as IECPrivateKeyParameters; // for signing
-  pubParams := keypair.Public as IECPublicKeyParameters; // for verifying
+  KeyPair := generator.GenerateKeyPair();
+  privParams := KeyPair.Private as IECPrivateKeyParameters; // for signing
+  pubParams := KeyPair.Public as IECPublicKeyParameters; // for verifying
 
   Writeln('Algorithm Name is: ' + pubParams.AlgorithmName + sLineBreak);
 
@@ -507,11 +704,16 @@ begin
       sLineBreak);
   end;
 
+  // Do Signing and Verifying to Assert Proper Recreation Of Public Key
+  DoSigningAndVerifying(recreatedPubKeyParameters, privParams, MethodName,
+    'PascalECDSA');
+
   // or the easier method
   // Method Two (** Preferred **)
 
-  if pubParams.Equals(TECKeyPairGenerator.GetCorrespondingPublicKey(privParams))
-  then
+  recreatedPubKeyParameters := TECKeyPairGenerator.GetCorrespondingPublicKey
+    (privParams);
+  if pubParams.Equals(recreatedPubKeyParameters) then
   begin
     Writeln('Public Key Recreation Match With Original Public Key' +
       sLineBreak);
@@ -522,6 +724,11 @@ begin
       sLineBreak);
   end;
 
+  // Do Signing and Verifying to Assert Proper Recreation Of Public Key
+
+  DoSigningAndVerifying(recreatedPubKeyParameters, privParams, MethodName,
+    'PascalECDSA');
+
 end;
 
 class procedure TUsageExamples.RecreatePublicAndPrivateKeyPairsFromByteArray;
@@ -529,7 +736,7 @@ var
   domain: IECDomainParameters;
   generator: IECKeyPairGenerator;
   keygenParams: IECKeyGenerationParameters;
-  keypair: IAsymmetricCipherKeyPair;
+  KeyPair: IAsymmetricCipherKeyPair;
   privParams, RegeneratedPrivateKey: IECPrivateKeyParameters;
   pubParams, RegeneratedPublicKey: IECPublicKeyParameters;
   PublicKeyByteArray, PrivateKeyByteArray: TBytes;
@@ -537,7 +744,6 @@ var
 const
   MethodName = 'RecreatePublicAndPrivateKeyPairsFromByteArray';
 begin
-
   Writeln('MethodName is: ' + MethodName + sLineBreak);
 
   domain := TECDomainParameters.Create(FCurve.Curve, FCurve.G, FCurve.N,
@@ -546,9 +752,9 @@ begin
   keygenParams := TECKeyGenerationParameters.Create(domain, FRandom);
   generator.Init(keygenParams);
 
-  keypair := generator.GenerateKeyPair();
-  privParams := keypair.Private as IECPrivateKeyParameters; // for signing
-  pubParams := keypair.Public as IECPublicKeyParameters; // for verifying
+  KeyPair := generator.GenerateKeyPair();
+  privParams := KeyPair.Private as IECPrivateKeyParameters; // for signing
+  pubParams := KeyPair.Public as IECPublicKeyParameters; // for verifying
 
   Writeln('Algorithm Name is: ' + pubParams.AlgorithmName + sLineBreak);
 
@@ -593,6 +799,16 @@ begin
       sLineBreak);
   end;
 
+  // Do Signing and Verifying to Assert Proper Recreation Of Public Key
+
+  DoSigningAndVerifying(RegeneratedPublicKey, privParams, MethodName,
+    'PascalECDSA');
+
+  // Do Signing and Verifying to Assert Proper Recreation Of Private Key
+
+  DoSigningAndVerifying(pubParams, RegeneratedPrivateKey, MethodName,
+    'PascalECDSA');
+
 end;
 
 class procedure TUsageExamples.RecreatePublicKeyFromXAndYCoordByteArray;
@@ -600,8 +816,9 @@ var
   domain: IECDomainParameters;
   generator: IECKeyPairGenerator;
   keygenParams: IECKeyGenerationParameters;
-  keypair: IAsymmetricCipherKeyPair;
+  KeyPair: IAsymmetricCipherKeyPair;
   pubParams, RegeneratedPublicKey: IECPublicKeyParameters;
+  privParams: IECPrivateKeyParameters;
   XCoordByteArray, YCoordByteArray: TBytes;
   BigXCoord, BigYCoord, BigXCoordRecreated, BigYCoordRecreated: TBigInteger;
   point: IECPoint;
@@ -617,8 +834,9 @@ begin
   keygenParams := TECKeyGenerationParameters.Create(domain, FRandom);
   generator.Init(keygenParams);
 
-  keypair := generator.GenerateKeyPair();
-  pubParams := keypair.Public as IECPublicKeyParameters; // for verifying
+  KeyPair := generator.GenerateKeyPair();
+  privParams := KeyPair.Private as IECPrivateKeyParameters; // for signing
+  pubParams := KeyPair.Public as IECPublicKeyParameters; // for verifying
 
   Writeln('Algorithm Name is: ' + pubParams.AlgorithmName + sLineBreak);
 
@@ -651,6 +869,12 @@ begin
       sLineBreak);
   end;
 
+
+  // Do Signing and Verifying to Assert Proper Recreation Of Public Key
+
+  DoSigningAndVerifying(RegeneratedPublicKey, privParams, MethodName,
+    'PascalECDSA');
+
 end;
 
 class constructor TUsageExamples.UsageExamples;

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

@@ -16,6 +16,11 @@ program CryptoLib.Tests;
 {$ENDIF}
 
 uses
+  madExcept,
+  madLinkDisAsm,
+  madListHardware,
+  madListProcesses,
+  madListModules,
   Forms,
   TestFramework,
   GUITestRunner,
@@ -342,7 +347,43 @@ uses
   ClpIAesEngine in '..\..\CryptoLib\src\Interfaces\ClpIAesEngine.pas',
   BlockCipherVectorTests in '..\src\Crypto\BlockCipherVectorTests.pas',
   AESTestVectors in '..\src\Crypto\AESTestVectors.pas',
-  AESTests in '..\src\Crypto\AESTests.pas';
+  AESTests in '..\src\Crypto\AESTests.pas',
+  ClpECDHBasicAgreement in '..\..\CryptoLib\src\Crypto\Agreement\ClpECDHBasicAgreement.pas',
+  ClpIBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIBasicAgreement.pas',
+  ClpIECDHBasicAgreement in '..\..\CryptoLib\src\Interfaces\ClpIECDHBasicAgreement.pas',
+  ClpIESParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESParameters.pas',
+  ClpIIESParameters in '..\..\CryptoLib\src\Interfaces\ClpIIESParameters.pas',
+  ClpIESWithCipherParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIESWithCipherParameters.pas',
+  ClpIIESWithCipherParameters in '..\..\CryptoLib\src\Interfaces\ClpIIESWithCipherParameters.pas',
+  ClpIDerivationParameters in '..\..\CryptoLib\src\Interfaces\ClpIDerivationParameters.pas',
+  ClpIDerivationFunction in '..\..\CryptoLib\src\Interfaces\ClpIDerivationFunction.pas',
+  ClpKdfParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpKdfParameters.pas',
+  ClpIKdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIKdfParameters.pas',
+  ClpIso18033KdfParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpIso18033KdfParameters.pas',
+  ClpIIso18033KdfParameters in '..\..\CryptoLib\src\Interfaces\ClpIIso18033KdfParameters.pas',
+  ClpBaseKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpBaseKdfBytesGenerator.pas',
+  ClpIBaseKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIBaseKdfBytesGenerator.pas',
+  ClpKdf2BytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpKdf2BytesGenerator.pas',
+  ClpIKdf2BytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIKdf2BytesGenerator.pas',
+  ClpIKeyParser in '..\..\CryptoLib\src\Interfaces\ClpIKeyParser.pas',
+  ClpEphemeralKeyPair in '..\..\CryptoLib\src\Crypto\ClpEphemeralKeyPair.pas',
+  ClpIEphemeralKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIEphemeralKeyPair.pas',
+  ClpEphemeralKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas',
+  ClpIEphemeralKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIEphemeralKeyPairGenerator.pas',
+  ClpKeyEncoder in '..\..\CryptoLib\src\Crypto\ClpKeyEncoder.pas',
+  ClpIESCipher in '..\..\CryptoLib\src\Crypto\ClpIESCipher.pas',
+  ClpIIESCipher in '..\..\CryptoLib\src\Interfaces\ClpIIESCipher.pas',
+  ClpECIESPublicKeyParser in '..\..\CryptoLib\src\Crypto\Parsers\ClpECIESPublicKeyParser.pas',
+  ClpIECIESPublicKeyParser in '..\..\CryptoLib\src\Interfaces\ClpIECIESPublicKeyParser.pas',
+  ClpZeroBytePadding in '..\..\CryptoLib\src\Crypto\Paddings\ClpZeroBytePadding.pas',
+  ClpIZeroBytePadding in '..\..\CryptoLib\src\Interfaces\ClpIZeroBytePadding.pas',
+  ClpIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpIESEngine.pas',
+  ClpIIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIIESEngine.pas',
+  ClpPascalCoinIESEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpPascalCoinIESEngine.pas',
+  ClpIPascalCoinIESEngine in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinIESEngine.pas',
+  IESCipherTests in '..\src\Crypto\IESCipherTests.pas',
+  ClpPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas',
+  ClpIPascalCoinECIESKdfBytesGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas';
 
 begin
 

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

@@ -35,7 +35,7 @@
         <PackageName Value="FCL"/>
       </Item4>
     </RequiredPackages>
-    <Units Count="22">
+    <Units Count="23">
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -125,6 +125,10 @@
         <Filename Value="..\src\Crypto\AESTestVectors.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit21>
+      <Unit22>
+        <Filename Value="..\src\Crypto\IESCipherTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit22>
     </Units>
   </ProjectOptions>
   <CompilerOptions>
@@ -139,8 +143,8 @@
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
     <CodeGeneration>
-      <TargetCPU Value="x86_64"/>
-      <TargetOS Value="win64"/>
+      <TargetCPU Value="i386"/>
+      <TargetOS Value="win32"/>
       <Optimizations>
         <OptimizationLevel Value="4"/>
       </Optimizations>

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

@@ -25,6 +25,7 @@ uses
   AESTests,
   BlockCipherVectorTests,
   AESTestVectors,
+  IESCipherTests,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
 

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

@@ -30,7 +30,7 @@
         <PackageName Value="FCL"/>
       </Item2>
     </RequiredPackages>
-    <Units Count="22">
+    <Units Count="23">
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -119,6 +119,10 @@
         <Filename Value="..\src\Math\EC\FixedPointTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit21>
+      <Unit22>
+        <Filename Value="..\src\Crypto\IESCipherTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit22>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

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

@@ -23,6 +23,7 @@ uses
   AESTests,
   BlockCipherVectorTests,
   AESTestVectors,
+  IESCipherTests,
   ClpFixedSecureRandom,
   ClpIFixedSecureRandom;
 

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

@@ -46,9 +46,10 @@ uses
   // ClpICbcBlockCipher,
   // ClpPaddedBufferedBlockCipher,
   // ClpIPaddedBufferedBlockCipher,
+  // ClpZeroBytePadding,
+  // ClpIZeroBytePadding,
   ClpHex,
-  ClpArrayUtils,
-  ClpCryptoLibTypes;
+  ClpArrayUtils;
 
 type
 
@@ -86,7 +87,7 @@ begin
   LInput := THex.Decode(input);
   LOutput := THex.Decode(output);
 
-  cipher.Init(true, param);
+  cipher.Init(True, param);
 
   // Encryption
   // Single Pass
@@ -118,12 +119,9 @@ begin
     len2 := len2 + cipher.DoFinal(DecryptionResult, len2);
 
     // remove padding important!!!
-    if (len2 < System.Length(DecryptionResult)) then
-    begin
-    System.Move(DecryptionResult[len2], DecryptionResult[0],
+    System.Move(DecryptionResult[0], DecryptionResult[0],
     len2 * System.SizeOf(Byte));
     System.SetLength(DecryptionResult, len2);
-    end;
     * }
 
   if (not TArrayUtils.AreEqual(LInput, DecryptionResult)) then
@@ -146,7 +144,7 @@ end;
 
 procedure TTestAES.TestAES256_CBC_PKCS7PADDING;
 var
-  KeyParameter: IKeyParameter;
+  keyParameter: IKeyParameter;
   KeyParametersWithIV: IParametersWithIV;
   keyBytes, IVBytes: TBytes;
   cipher: IBufferedCipher;
@@ -159,9 +157,9 @@ begin
   // // Set up
   // engine := TAesEngine.Create();
   // blockCipher := TCbcBlockCipher.Create(engine); // CBC
-  // cipher := TPaddedBufferedBlockCipher.Create(blockCipher);
+  // cipher := TPaddedBufferedBlockCipher.Create(blockCipher, TPkcs7Padding.Create() as IPkcs7Padding); or
+  // cipher := TPaddedBufferedBlockCipher.Create(blockCipher, TZeroBytePadding.Create() as IZeroBytePadding);
   // // Default scheme is PKCS5/PKCS7
-
   cipher := TCipherUtilities.GetCipher('AES/CBC/PKCS7PADDING');
 
   for I := System.Low(TAESTestVectors.FOfficialVectorKeys__AES256_CBC)

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

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

+ 2 - 2
CryptoLib/src/Asn1/ClpAsn1InputStream.pas

@@ -24,7 +24,6 @@ interface
 uses
   Classes,
   Generics.Collections,
-  ClpCryptoLibTypes,
 {$IFDEF DELPHI}
   ClpIDerNull,
 {$ENDIF DELPHI}
@@ -67,7 +66,8 @@ uses
   ClpIDefiniteLengthInputStream,
   ClpIAsn1EncodableVector,
   ClpIAsn1InputStream,
-  ClpFilterStream;
+  ClpFilterStream,
+  ClpCryptoLibTypes;
 
 resourcestring
   SCorruptedStream = 'Corrupted Stream - Invalid High Tag Number Found';

+ 137 - 0
CryptoLib/src/Crypto/Agreement/ClpECDHBasicAgreement.pas

@@ -0,0 +1,137 @@
+{ *********************************************************************************** }
+{ *                              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 ClpECDHBasicAgreement;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpBigInteger,
+  ClpICipherParameters,
+  ClpIECInterface,
+  ClpIBasicAgreement,
+  ClpIECDHBasicAgreement,
+  ClpIECPrivateKeyParameters,
+  ClpIParametersWithRandom,
+  ClpIECPublicKeyParameters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SWrongDomainParameter = 'ECDH Public Key has Wrong Domain Parameters';
+  SInvalidAgreementValue = 'Infinity is not a Valid Agreement Value for ECDH';
+  SInfinityInvalidPublicKey = 'Infinity is not a Valid Public Key for ECDH';
+
+type
+  /// <summary>
+  /// P1363 7.2.1 ECSVDP-DH <br />ECSVDP-DH is Elliptic Curve Secret Value
+  /// Derivation Primitive, <br />Diffie-Hellman version. It is based on the
+  /// work of [DH76], [Mil86], <br />and [Kob87]. This primitive derives a
+  /// shared secret value from one <br />party's private key and another
+  /// party's public key, where both have <br />the same set of EC domain
+  /// parameters. If two parties correctly <br />execute this primitive, they
+  /// will produce the same output. This <br />primitive can be invoked by a
+  /// scheme to derive a shared secret key; <br />specifically, it may be
+  /// 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,
+    IBasicAgreement)
+
+  strict protected
+  var
+    FprivKey: IECPrivateKeyParameters;
+
+  public
+    /// <summary>
+    /// initialise the agreement engine.
+    /// </summary>
+    procedure Init(const parameters: ICipherParameters); virtual;
+
+    /// <summary>
+    /// return the field size for the agreement algorithm in bytes.
+    /// </summary>
+    function GetFieldSize(): Int32; virtual;
+
+    /// <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;
+
+  end;
+
+implementation
+
+{ TECDHBasicAgreement }
+
+function TECDHBasicAgreement.CalculateAgreement(const pubKey: ICipherParameters)
+  : TBigInteger;
+var
+  pub: IECPublicKeyParameters;
+  P, pubPoint: IECPoint;
+begin
+  pub := pubKey as IECPublicKeyParameters;
+  if (not(pub.parameters.Equals(FprivKey.parameters))) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes(@SWrongDomainParameter);
+
+  end;
+  // Always perform calculations on the exact curve specified by our private key's parameters
+
+  pubPoint := FprivKey.parameters.Curve.decodePoint(pub.Q.GetEncoded(False));
+  if (pubPoint.IsInfinity) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SInfinityInvalidPublicKey);
+  end;
+
+  // P := pub.Q.Multiply(FprivKey.D).Normalize();
+  P := pubPoint.Multiply(FprivKey.D).Normalize();
+
+  if (P.IsInfinity) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SInvalidAgreementValue);
+
+  end;
+
+  result := P.AffineXCoord.ToBigInteger();
+end;
+
+function TECDHBasicAgreement.GetFieldSize: Int32;
+begin
+  result := (FprivKey.parameters.Curve.FieldSize + 7) div 8;
+end;
+
+procedure TECDHBasicAgreement.Init(const parameters: ICipherParameters);
+var
+  Lparameters: ICipherParameters;
+begin
+  Lparameters := parameters;
+  if Supports(Lparameters, IParametersWithRandom) then
+  begin
+    Lparameters := (Lparameters as IParametersWithRandom).parameters;
+  end;
+
+  FprivKey := Lparameters as IECPrivateKeyParameters;
+end;
+
+end.

+ 84 - 0
CryptoLib/src/Crypto/ClpEphemeralKeyPair.pas

@@ -0,0 +1,84 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEphemeralKeyPair;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIEphemeralKeyPair,
+  ClpIAsymmetricCipherKeyPair,
+  ClpKeyEncoder,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SParameterFunctionCannotBeNil = 'Parameter Function Cannot be Nil.';
+
+type
+  TEphemeralKeyPair = class sealed(TInterfacedObject, IEphemeralKeyPair)
+
+  strict private
+
+    FkeyPair: IAsymmetricCipherKeyPair;
+    FUsePointCompression: Boolean;
+    FpublicKeyEncoder: TKeyEncoder;
+
+  public
+
+    function getKeyPair(): IAsymmetricCipherKeyPair; inline;
+
+    function getEncodedPublicKey(): TCryptoLibByteArray; inline;
+
+    constructor Create(const keyPair: IAsymmetricCipherKeyPair;
+      usePointCompression: Boolean; const publicKeyEncoder: TKeyEncoder);
+
+  end;
+
+implementation
+
+{ TEphemeralKeyPair }
+
+constructor TEphemeralKeyPair.Create(const keyPair: IAsymmetricCipherKeyPair;
+  usePointCompression: Boolean; const publicKeyEncoder: TKeyEncoder);
+begin
+  Inherited Create();
+  FkeyPair := keyPair;
+  FUsePointCompression := usePointCompression;
+  FpublicKeyEncoder := publicKeyEncoder;
+end;
+
+function TEphemeralKeyPair.getEncodedPublicKey: TCryptoLibByteArray;
+begin
+  if Assigned(FpublicKeyEncoder) then
+  begin
+    result := FpublicKeyEncoder(FkeyPair.Public, FUsePointCompression);
+  end
+  else
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes
+      (@SParameterFunctionCannotBeNil);
+  end;
+end;
+
+function TEphemeralKeyPair.getKeyPair: IAsymmetricCipherKeyPair;
+begin
+  result := FkeyPair;
+end;
+
+end.

+ 280 - 0
CryptoLib/src/Crypto/ClpIESCipher.pas

@@ -0,0 +1,280 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIESCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  SysUtils,
+  ClpIIESEngine,
+  ClpIECIESPublicKeyParser,
+  ClpECIESPublicKeyParser,
+  ClpIAsymmetricKeyParameter,
+  ClpIIESWithCipherParameters,
+  ClpICipherParameters,
+  ClpIParametersWithRandom,
+  ClpIECKeyParameters,
+  ClpIESWithCipherParameters,
+  ClpIECDomainParameters,
+  ClpIECKeyPairGenerator,
+  ClpECKeyPairGenerator,
+  ClpECKeyGenerationParameters,
+  ClpIECKeyGenerationParameters,
+  ClpEphemeralKeyPairGenerator,
+  ClpIEphemeralKeyPairGenerator,
+  ClpParametersWithIV,
+  ClpIECPublicKeyParameters,
+  ClpIIESCipher,
+  ClpISecureRandom,
+  ClpSecureRandom,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidPublicKey =
+    'Must be Passed Recipient''s Public EC Key for Encryption';
+  SInvalidPrivateKey =
+    'Must be Passed Recipient''s Private EC Key for Decryption';
+  SIESWithCipherParametersCannotBeNil = 'IESWithCipherParameters Cannot Be Nil';
+  SUnableToProcessBlock = 'Unable to Process Block. "%s"';
+
+type
+  TIESCipher = class sealed(TInterfacedObject, IIESCipher)
+
+  strict private
+  var
+    FEngine: IIESEngine;
+    FForEncryption: Boolean;
+    FBuffer: TMemoryStream;
+    FIESWithCipherParameters: IIESWithCipherParameters;
+    Fkey: IAsymmetricKeyParameter;
+    FRandom: ISecureRandom;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+    function KeyEncoder(const keyParameter: IAsymmetricKeyParameter;
+      UsePointCompression: Boolean): TCryptoLibByteArray; inline;
+
+  public
+    procedure Init(ForEncryption: Boolean; const Key: ICipherParameters;
+      const params: IIESWithCipherParameters; const Random: ISecureRandom);
+
+    procedure ProcessBytes(input: TCryptoLibByteArray); overload;
+    procedure ProcessBytes(input: TCryptoLibByteArray;
+      inputOffset, inputLen: Int32); overload;
+
+    function DoFinal(input: TCryptoLibByteArray): TCryptoLibByteArray; overload;
+
+    function DoFinal(input: TCryptoLibByteArray; inputOffset, inputLen: Int32)
+      : TCryptoLibByteArray; overload;
+
+    function DoFinal(input: TCryptoLibByteArray; inputOffset, inputLen: Int32;
+      output: TCryptoLibByteArray; outputOffset: Int32): Int32; overload;
+
+    constructor Create(const Engine: IIESEngine);
+    destructor Destroy(); override;
+
+  end;
+
+implementation
+
+{ TIESCipher }
+
+function TIESCipher.KeyEncoder(const keyParameter: IAsymmetricKeyParameter;
+  UsePointCompression: Boolean): TCryptoLibByteArray;
+begin
+  Result := (keyParameter as IECPublicKeyParameters)
+    .Q.GetEncoded(UsePointCompression);
+end;
+
+function TIESCipher.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+constructor TIESCipher.Create(const Engine: IIESEngine);
+begin
+  Inherited Create();
+  FEngine := Engine;
+  FBuffer := TMemoryStream.Create();
+end;
+
+function TIESCipher.DoFinal(input: TCryptoLibByteArray;
+  inputOffset, inputLen: Int32): TCryptoLibByteArray;
+var
+  &in: TCryptoLibByteArray;
+  params: ICipherParameters;
+  ecParams: IECDomainParameters;
+  gen: IECKeyPairGenerator;
+  kGen: IEphemeralKeyPairGenerator;
+  UsePointCompression: Boolean;
+begin
+  if (inputLen <> 0) then
+  begin
+    FBuffer.Write(input[inputOffset], inputLen);
+  end;
+
+  &in := Aggregate();
+  FBuffer.Clear;
+  FBuffer.SetSize(0);
+
+  // Copy parameters for use in IESEngine
+  params := TIESWithCipherParameters.Create
+    (FIESWithCipherParameters.GetDerivationV,
+    FIESWithCipherParameters.GetEncodingV, FIESWithCipherParameters.Nonce,
+    FIESWithCipherParameters.MacKeySize, FIESWithCipherParameters.CipherKeySize,
+    FIESWithCipherParameters.PointCompression);
+
+  if (FIESWithCipherParameters.Nonce <> Nil) then
+  begin
+    params := TParametersWithIV.Create(params, FIESWithCipherParameters.Nonce);
+  end;
+  ecParams := (Fkey as IECKeyParameters).Parameters;
+
+  if FForEncryption then
+  begin
+    // Generate the ephemeral key pair
+    gen := TECKeyPairGenerator.Create();
+    gen.Init(TECKeyGenerationParameters.Create(ecParams, FRandom)
+      as IECKeyGenerationParameters);
+
+    UsePointCompression := FIESWithCipherParameters.PointCompression;
+
+    kGen := TEphemeralKeyPairGenerator.Create(gen, UsePointCompression,
+      KeyEncoder);
+
+    // Encrypt the buffer
+
+    try
+      FEngine.Init(Fkey, params, kGen);
+
+      Result := FEngine.ProcessBlock(&in, 0, System.length(&in));
+      Exit;
+    except
+      on e: Exception do
+      begin
+        raise EBadBlockCryptoLibException.CreateResFmt(@SUnableToProcessBlock,
+          [e.Message]);
+      end;
+    end;
+  end
+  else
+  begin
+    // Decrypt the buffer
+
+    try
+      FEngine.Init(Fkey, params, TECIESPublicKeyParser.Create(ecParams)
+        as IECIESPublicKeyParser);
+
+      Result := FEngine.ProcessBlock(&in, 0, System.length(&in));
+      Exit;
+    except
+      on e: EInvalidCipherTextCryptoLibException do
+      begin
+        raise EBadBlockCryptoLibException.CreateResFmt(@SUnableToProcessBlock,
+          [e.Message]);
+      end;
+    end;
+  end;
+
+end;
+
+destructor TIESCipher.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TIESCipher.DoFinal(input: TCryptoLibByteArray): TCryptoLibByteArray;
+begin
+  Result := DoFinal(input, 0, System.length(input));
+end;
+
+function TIESCipher.DoFinal(input: TCryptoLibByteArray;
+  inputOffset, inputLen: Int32; output: TCryptoLibByteArray;
+  outputOffset: Int32): Int32;
+var
+  buf: TCryptoLibByteArray;
+begin
+  buf := DoFinal(input, inputOffset, inputLen);
+  System.Move(buf[0], output[outputOffset], System.length(buf) *
+    System.SizeOf(Byte));
+  Result := System.length(buf);
+end;
+
+procedure TIESCipher.Init(ForEncryption: Boolean; const Key: ICipherParameters;
+  const params: IIESWithCipherParameters; const Random: ISecureRandom);
+var
+  LKey: ICipherParameters;
+begin
+  FForEncryption := ForEncryption;
+  LKey := Key;
+  // Parse the recipient's key
+  if ForEncryption then
+  begin
+    if ((not Supports(LKey, IAsymmetricKeyParameter, Fkey)) or
+      ((Fkey.IsPrivate))) then
+    begin
+      raise EInvalidKeyCryptoLibException.CreateRes(@SInvalidPublicKey);
+    end;
+
+  end
+  else
+  begin
+    if Supports(LKey, IParametersWithRandom) then
+    begin
+      LKey := (LKey as IParametersWithRandom).Parameters;
+    end;
+
+    if ((not Supports(LKey, IAsymmetricKeyParameter, Fkey)) or
+      (not(Fkey.IsPrivate))) then
+    begin
+      raise EInvalidKeyCryptoLibException.CreateRes(@SInvalidPrivateKey);
+    end;
+
+  end;
+  if params = Nil then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes
+      (@SIESWithCipherParametersCannotBeNil);
+  end
+  else
+  begin
+    FIESWithCipherParameters := params;
+  end;
+  FRandom := Random;
+  FBuffer.Clear;
+  FBuffer.SetSize(0);
+end;
+
+procedure TIESCipher.ProcessBytes(input: TCryptoLibByteArray);
+begin
+  ProcessBytes(input, 0, System.length(input));
+end;
+
+procedure TIESCipher.ProcessBytes(input: TCryptoLibByteArray;
+  inputOffset, inputLen: Int32);
+begin
+  FBuffer.Write(input[inputOffset], inputLen);
+end;
+
+end.

+ 34 - 0
CryptoLib/src/Crypto/ClpKeyEncoder.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 ClpKeyEncoder;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricKeyParameter,
+  ClpCryptoLibTypes;
+
+type
+  TKeyEncoder = function(const keyParameter: IAsymmetricKeyParameter;
+    UsePointCompression: Boolean): TCryptoLibByteArray of Object;
+
+implementation
+
+end.

+ 615 - 0
CryptoLib/src/Crypto/Engines/ClpIESEngine.pas

@@ -0,0 +1,615 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIESEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  SysUtils,
+  HlpIHashInfo,
+  ClpIIESEngine,
+  ClpIBasicAgreement,
+  ClpIDerivationFunction,
+  ClpIBufferedBlockCipher,
+  ClpICipherParameters,
+  ClpIIESParameters,
+  ClpIEphemeralKeyPairGenerator,
+  ClpIAsymmetricKeyParameter,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpIKeyParser,
+  ClpIEphemeralKeyPair,
+  ClpKDFParameters,
+  ClpIKdfParameters,
+  ClpIIESWithCipherParameters,
+  ClpConverters,
+  ClpArrayUtils,
+  ClpBigInteger,
+  ClpBigIntegers,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SErrorRecoveringEphemeralPublicKey =
+    'Unable to Recover Ephemeral Public Key: "%s"';
+  SInvalidCipherTextLength =
+    'Length of Input Must be Greater than the MAC and V combined';
+  SInvalidMAC = 'Invalid MAC';
+
+type
+
+  /// <summary>
+  /// Support class for constructing integrated encryption ciphers for doing
+  /// basic message exchanges on top of key agreement ciphers. <br />Follows
+  /// the description given in IEEE Std 1363a.
+  /// </summary>
+  TIESEngine = class(TInterfacedObject, IIESEngine)
+
+  strict private
+
+    // as described in Shroup's paper( ch 10, pg 20) and P1363a
+    function GetLengthTag(p2: TCryptoLibByteArray): TCryptoLibByteArray; inline;
+
+    procedure ExtractParams(const params: ICipherParameters); inline;
+
+  strict protected
+
+  var
+    Fagree: IBasicAgreement;
+    Fkdf: IDerivationFunction;
+    Fmac: IHMAC;
+    Fcipher: IBufferedBlockCipher;
+    FmacBuf, FV, FIV: TCryptoLibByteArray;
+    FforEncryption: Boolean;
+    FprivParam, FpubParam: ICipherParameters;
+    Fparam: IIESParameters;
+    FkeyPairGenerator: IEphemeralKeyPairGenerator;
+    FkeyParser: IKeyParser;
+
+    function GetCipher: IBufferedBlockCipher; inline;
+    function GetMac: IHMAC; inline;
+    function EncryptBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
+      : TCryptoLibByteArray; virtual;
+
+    function DecryptBlock(in_enc: TCryptoLibByteArray; inOff, inLen: Int32)
+      : TCryptoLibByteArray; virtual;
+
+  public
+
+    /// <summary>
+    /// Set up for use with stream mode, where the key derivation function is
+    /// used to provide a stream of bytes to xor with the message.
+    /// </summary>
+    /// <param name="agree">
+    /// the key agreement used as the basis for the encryption
+    /// </param>
+    /// <param name="kdf">
+    /// the key derivation function used for byte generation
+    /// </param>
+    /// <param name="mac">
+    /// the message authentication code generator for the message
+    /// </param>
+    constructor Create(const agree: IBasicAgreement;
+      const kdf: IDerivationFunction; const mac: IHMAC); overload;
+
+    /// <summary>
+    /// Set up for use in conjunction with a block cipher to handle the <br />
+    /// message. It is <b>strongly</b> recommended that the cipher is not
+    /// in ECB mode.
+    /// </summary>
+    /// <param name="agree">
+    /// the key agreement used as the basis for the encryption
+    /// </param>
+    /// <param name="kdf">
+    /// the key derivation function used for byte generation
+    /// </param>
+    /// <param name="mac">
+    /// the message authentication code generator for the message
+    /// </param>
+    /// <param name="cipher">
+    /// the cipher to used for encrypting the message
+    /// </param>
+    constructor Create(const agree: IBasicAgreement;
+      const kdf: IDerivationFunction; const mac: IHMAC;
+      const cipher: IBufferedBlockCipher); overload;
+
+    /// <summary>
+    /// Initialise the encryptor/decryptor.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// whether or not this is encryption/decryption.
+    /// </param>
+    /// <param name="privParam">
+    /// our private key parameters
+    /// </param>
+    /// <param name="pubParam">
+    /// the recipient's/sender's public key parameters
+    /// </param>
+    /// <param name="params">
+    /// encoding and derivation parameters, may be wrapped to include an IV
+    /// for an underlying block cipher.
+    /// </param>
+    procedure Init(forEncryption: Boolean;
+      privParam, pubParam, params: ICipherParameters); overload;
+
+    /// <summary>
+    /// Initialise the encryptor.
+    /// </summary>
+    /// <param name="publicKey">
+    /// the recipient's/sender's public key parameters
+    /// </param>
+    /// <param name="params">
+    /// encoding and derivation parameters, may be wrapped to include an IV
+    /// for an underlying block cipher.
+    /// </param>
+    /// <param name="ephemeralKeyPairGenerator">
+    /// the ephemeral key pair generator to use.
+    /// </param>
+    procedure Init(const publicKey: IAsymmetricKeyParameter;
+      const params: ICipherParameters;
+      const ephemeralKeyPairGenerator: IEphemeralKeyPairGenerator); overload;
+
+    /// <summary>
+    /// Initialise the decryptor.
+    /// </summary>
+    /// <param name="privateKey">
+    /// the recipient's private key.
+    /// </param>
+    /// <param name="params">
+    /// encoding and derivation parameters, may be wrapped to include an IV
+    /// for an underlying block cipher.
+    /// </param>
+    /// <param name="publicKeyParser">
+    /// the parser for reading the ephemeral public key.
+    /// </param>
+    procedure Init(const privateKey: IAsymmetricKeyParameter;
+      const params: ICipherParameters;
+      const publicKeyParser: IKeyParser); overload;
+
+    function ProcessBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
+      : TCryptoLibByteArray; virtual;
+
+    property cipher: IBufferedBlockCipher read GetCipher;
+    property mac: IHMAC read GetMac;
+
+  end;
+
+implementation
+
+{ TIESEngine }
+
+function TIESEngine.GetLengthTag(p2: TCryptoLibByteArray): TCryptoLibByteArray;
+begin
+  System.SetLength(Result, 8);
+  if (p2 <> Nil) then
+  begin
+    TConverters.ReadUInt64AsBytesBE(System.Length(p2) * 8, Result, 0);
+  end;
+end;
+
+constructor TIESEngine.Create(const agree: IBasicAgreement;
+  const kdf: IDerivationFunction; const mac: IHMAC);
+begin
+  Inherited Create();
+  Fagree := agree;
+  Fkdf := kdf;
+  Fmac := mac;
+  System.SetLength(FmacBuf, mac.HashSize);
+  Fcipher := Nil;
+end;
+
+constructor TIESEngine.Create(const agree: IBasicAgreement;
+  const kdf: IDerivationFunction; const mac: IHMAC;
+  const cipher: IBufferedBlockCipher);
+begin
+  Inherited Create();
+  Fagree := agree;
+  Fkdf := kdf;
+  Fmac := mac;
+  System.SetLength(FmacBuf, mac.HashSize);
+  Fcipher := cipher;
+end;
+
+function TIESEngine.DecryptBlock(in_enc: TCryptoLibByteArray;
+  inOff, inLen: Int32): TCryptoLibByteArray;
+var
+  M, K, K1, K2, p2, L2, T1, T2: TCryptoLibByteArray;
+  len, i, endPoint: Int32;
+  cp: ICipherParameters;
+begin
+  len := 0;
+  // Ensure that the length of the input is greater than the MAC in bytes
+  if (inLen < (System.Length(FV) + Fmac.HashSize)) then
+  begin
+    raise EInvalidCipherTextCryptoLibException.CreateRes
+      (@SInvalidCipherTextLength);
+  end;
+  // note order is important: set up keys, do simple encryptions, check mac, do final encryption.
+  if (Fcipher = Nil) then
+  begin
+
+    // Streaming mode.
+    System.SetLength(K1, inLen - System.Length(FV) - Fmac.HashSize);
+    System.SetLength(K2, Fparam.MacKeySize div 8);
+    System.SetLength(K, System.Length(K1) + System.Length(K2));
+
+    Fkdf.GenerateBytes(K, 0, System.Length(K));
+
+    if (System.Length(FV) <> 0) then
+    begin
+      System.Move(K[0], K2[0], System.Length(K2) * System.SizeOf(Byte));
+      System.Move(K[System.Length(K2)], K1[0], System.Length(K1) *
+        System.SizeOf(Byte));
+    end
+    else
+    begin
+      System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+      System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
+        System.SizeOf(Byte));
+    end;
+
+    // process the message
+    System.SetLength(M, System.Length(K1));
+
+    i := 0;
+
+    while i <> System.Length(K1) do
+    begin
+      M[i] := Byte(in_enc[inOff + System.Length(FV) + i] xor K1[i]);
+      System.Inc(i);
+    end;
+
+  end
+  else
+  begin
+    // Block cipher mode.
+
+    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
+      .CipherKeySize div 8);
+    System.SetLength(K2, Fparam.MacKeySize div 8);
+    System.SetLength(K, System.Length(K1) + System.Length(K2));
+
+    Fkdf.GenerateBytes(K, 0, System.Length(K));
+
+    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
+      System.SizeOf(Byte));
+
+    cp := TKeyParameter.Create(K1);
+
+    // If iv is provided use it to initialise the cipher
+    if (FIV <> Nil) then
+    begin
+      cp := TParametersWithIV.Create(cp, FIV);
+    end;
+
+    Fcipher.Init(False, cp);
+
+    System.SetLength(M, Fcipher.GetOutputSize(inLen - System.Length(FV) -
+      Fmac.HashSize));
+
+    // do initial processing
+    len := Fcipher.ProcessBytes(in_enc, inOff + System.Length(FV),
+      inLen - System.Length(FV) - Fmac.HashSize, M, 0);
+
+  end;
+
+  // Convert the length of the encoding vector into a byte array.
+  p2 := Fparam.GetEncodingV();
+  L2 := Nil;
+  if (System.Length(FV) <> 0) then
+  begin
+    L2 := GetLengthTag(p2);
+  end;
+
+  // Verify the MAC.
+  endPoint := inOff + inLen;
+  T1 := TArrayUtils.CopyOfRange(in_enc, endPoint - Fmac.HashSize, endPoint);
+  System.SetLength(T2, System.Length(T1));
+  // set the mac key before calling initialize
+  Fmac.Key := K2;
+  Fmac.Initialize;
+
+  Fmac.TransformBytes(in_enc, inOff + System.Length(FV),
+    inLen - System.Length(FV) - System.Length(T2));
+  if (p2 <> Nil) then
+  begin
+    Fmac.TransformBytes(p2, 0, System.Length(p2));
+  end;
+  if (System.Length(FV) <> 0) then
+  begin
+    Fmac.TransformBytes(L2, 0, System.Length(L2));
+  end;
+  T2 := Fmac.TransformFinal.GetBytes;
+
+  if (not TArrayUtils.ConstantTimeAreEqual(T1, T2)) then
+  begin
+    raise EInvalidCipherTextCryptoLibException.CreateRes(@SInvalidMAC);
+  end;
+
+  if (Fcipher = Nil) then
+  begin
+    Result := M;
+    Exit;
+  end
+  else
+  begin
+    len := len + Fcipher.doFinal(M, len);
+
+    Result := TArrayUtils.CopyOfRange(M, 0, len);
+    Exit;
+  end;
+end;
+
+function TIESEngine.EncryptBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
+  : TCryptoLibByteArray;
+var
+  C, K, K1, K2, p2, L2, T: TCryptoLibByteArray;
+  len, i: Int32;
+begin
+  if (Fcipher = Nil) then
+  begin
+    // Streaming mode.
+    System.SetLength(K1, inLen);
+    System.SetLength(K2, Fparam.MacKeySize div 8);
+    System.SetLength(K, System.Length(K1) + System.Length(K2));
+
+    Fkdf.GenerateBytes(K, 0, System.Length(K));
+
+    if (System.Length(FV) <> 0) then
+    begin
+      System.Move(K[0], K2[0], System.Length(K2) * System.SizeOf(Byte));
+      System.Move(K[System.Length(K2)], K1[0], System.Length(K1) *
+        System.SizeOf(Byte));
+    end
+    else
+    begin
+      System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+      System.Move(K[inLen], K2[0], System.Length(K2) * System.SizeOf(Byte));
+    end;
+
+    System.SetLength(C, inLen);
+
+    i := 0;
+
+    while i <> inLen do
+    begin
+      C[i] := Byte(&in[inOff + i] xor K1[i]);
+      System.Inc(i);
+    end;
+
+    len := inLen;
+  end
+  else
+  begin
+    // Block cipher mode.
+
+    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
+      .CipherKeySize div 8);
+    System.SetLength(K2, Fparam.MacKeySize div 8);
+    System.SetLength(K, System.Length(K1) + System.Length(K2));
+
+    Fkdf.GenerateBytes(K, 0, System.Length(K));
+
+    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
+      System.SizeOf(Byte));
+
+    // If iv is provided use it to initialise the cipher
+    if (FIV <> Nil) then
+    begin
+      Fcipher.Init(true, TParametersWithIV.Create(TKeyParameter.Create(K1)
+        as IKeyParameter, FIV));
+    end
+    else
+    begin
+      Fcipher.Init(true, TKeyParameter.Create(K1) as IKeyParameter);
+    end;
+
+    System.SetLength(C, Fcipher.GetOutputSize(inLen));
+
+    len := Fcipher.ProcessBytes(&in, inOff, inLen, C, 0);
+    len := len + Fcipher.doFinal(C, len);
+  end;
+
+  // Convert the length of the encoding vector into a byte array.
+  p2 := Fparam.GetEncodingV();
+  L2 := Nil;
+  if (System.Length(FV) <> 0) then
+  begin
+    L2 := GetLengthTag(p2);
+  end;
+
+  // Apply the MAC.
+  System.SetLength(T, Fmac.HashSize);
+  // set the mac key before calling initialize
+  Fmac.Key := K2;
+  Fmac.Initialize;
+  Fmac.TransformBytes(C, 0, System.Length(C));
+  if (p2 <> Nil) then
+  begin
+    Fmac.TransformBytes(p2, 0, System.Length(p2));
+  end;
+  if (System.Length(FV) <> 0) then
+  begin
+    Fmac.TransformBytes(L2, 0, System.Length(L2));
+  end;
+  T := Fmac.TransformFinal.GetBytes;
+
+  // Output the triple (V,C,T).
+  // V := Ephermeral Public Key
+  // C := Encrypted Payload
+  // T := Authentication Message (MAC)
+  System.SetLength(Result, System.Length(FV) + len + System.Length(T));
+  System.Move(FV[0], Result[0], System.Length(FV) * System.SizeOf(Byte));
+  System.Move(C[0], Result[System.Length(FV)], len * System.SizeOf(Byte));
+  System.Move(T[0], Result[System.Length(FV) + len],
+    System.Length(T) * System.SizeOf(Byte));
+
+end;
+
+procedure TIESEngine.ExtractParams(const params: ICipherParameters);
+begin
+  if Supports(params, IParametersWithIV) then
+  begin
+    FIV := (params as IParametersWithIV).GetIV;
+    Fparam := ((params as IParametersWithIV).Parameters) as IIESParameters;
+  end
+  else
+  begin
+    FIV := Nil;
+    Fparam := (params as IIESParameters);
+  end;
+end;
+
+function TIESEngine.GetCipher: IBufferedBlockCipher;
+begin
+  Result := Fcipher;
+end;
+
+function TIESEngine.GetMac: IHMAC;
+begin
+  Result := Fmac;
+end;
+
+procedure TIESEngine.Init(const privateKey: IAsymmetricKeyParameter;
+  const params: ICipherParameters; const publicKeyParser: IKeyParser);
+begin
+  FforEncryption := False;
+  FprivParam := privateKey;
+  FkeyParser := publicKeyParser;
+  ExtractParams(params);
+end;
+
+procedure TIESEngine.Init(const publicKey: IAsymmetricKeyParameter;
+  const params: ICipherParameters;
+  const ephemeralKeyPairGenerator: IEphemeralKeyPairGenerator);
+begin
+  FforEncryption := true;
+  FpubParam := publicKey;
+  FkeyPairGenerator := ephemeralKeyPairGenerator;
+  ExtractParams(params);
+end;
+
+procedure TIESEngine.Init(forEncryption: Boolean;
+  privParam, pubParam, params: ICipherParameters);
+begin
+  FforEncryption := forEncryption;
+  FprivParam := privParam;
+  FpubParam := pubParam;
+  System.SetLength(FV, 0);
+  ExtractParams(params);
+end;
+
+function TIESEngine.ProcessBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
+  : TCryptoLibByteArray;
+var
+  ephKeyPair: IEphemeralKeyPair;
+  bIn: TBytesStream;
+  encLength: Int32;
+  z: TBigInteger;
+  BigZ, VZ: TCryptoLibByteArray;
+  kdfParam: IKDFParameters;
+begin
+  if (FforEncryption) then
+  begin
+    if (FkeyPairGenerator <> Nil) then
+    begin
+      ephKeyPair := FkeyPairGenerator.Generate;
+
+      FprivParam := ephKeyPair.GetKeyPair.Private;
+      FV := ephKeyPair.GetEncodedPublicKey;
+    end
+  end
+  else
+  begin
+    if (FkeyParser <> Nil) then
+    begin
+      // used TBytesStream here for one pass creation and population with byte array :)
+      bIn := TBytesStream.Create(System.Copy(&in, inOff, inLen));
+
+      try
+        bIn.Position := 0;
+
+        try
+          FpubParam := FkeyParser.readKey(bIn);
+        except
+          on e: EIOCryptoLibException do
+          begin
+            raise EInvalidCipherTextCryptoLibException.CreateResFmt
+              (@SErrorRecoveringEphemeralPublicKey, [e.Message]);
+          end;
+
+          on e: EArgumentCryptoLibException do
+          begin
+            raise EInvalidCipherTextCryptoLibException.CreateResFmt
+              (@SErrorRecoveringEphemeralPublicKey, [e.Message]);
+          end;
+
+        end;
+
+        encLength := (inLen - (bIn.Size - bIn.Position));
+        FV := TArrayUtils.CopyOfRange(&in, inOff, inOff + encLength);
+
+      finally
+        bIn.Free;
+      end;
+    end;
+  end;
+
+  // Compute the common value and convert to byte array.
+  Fagree.Init(FprivParam);
+  z := Fagree.CalculateAgreement(FpubParam);
+  BigZ := TBigIntegers.AsUnsignedByteArray(Fagree.GetFieldSize, z);
+
+  // Create input to KDF.
+  if (System.Length(FV) <> 0) then
+  begin
+    VZ := TArrayUtils.AddByteArray(FV, BigZ);
+    System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
+      Byte(0));
+    BigZ := VZ;
+  end;
+
+  try
+    // Initialise the KDF.
+    kdfParam := TKDFParameters.Create(BigZ, Fparam.GetDerivationV);
+    Fkdf.Init(kdfParam);
+
+    if FforEncryption then
+    begin
+      Result := EncryptBlock(&in, inOff, inLen);
+      Exit;
+    end
+    else
+    begin
+      Result := DecryptBlock(&in, inOff, inLen);
+      Exit;
+    end;
+
+  finally
+    System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
+      Byte(0));
+  end;
+end;
+
+end.

+ 307 - 0
CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas

@@ -0,0 +1,307 @@
+{ *********************************************************************************** }
+{ *                              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 ClpPascalCoinIESEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  Classes,
+  HlpIHashInfo,
+  ClpIPascalCoinIESEngine,
+  ClpIBufferedBlockCipher,
+  ClpICipherParameters,
+  ClpKeyParameter,
+  ClpIKeyParameter,
+  ClpParametersWithIV,
+  ClpIParametersWithIV,
+  ClpIKeyParser,
+  ClpIEphemeralKeyPair,
+  ClpKDFParameters,
+  ClpIKdfParameters,
+  ClpIIESWithCipherParameters,
+  ClpIESEngine,
+  ClpArrayUtils,
+  ClpBigInteger,
+  ClpBigIntegers,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SErrorRecoveringEphemeralPublicKey =
+    'Unable to Recover Ephemeral Public Key: "%s"';
+  SInvalidCipherTextLength =
+    'Length of Input Must be Greater than the MAC and V combined';
+  SInvalidMAC = 'Invalid MAC';
+  SCipherCannotbeNilInThisMode = 'Cipher Cannot be Nil in This Mode.';
+
+type
+
+  /// <summary>
+  /// Compatibility Class for PascalCoin IESEngine
+  /// </summary>
+  TPascalCoinIESEngine = class(TIESEngine, IPascalCoinIESEngine)
+
+  strict private
+  const
+    /// <summary>
+    /// <b>SizeOf</b> Structure for Compatibility with PascalCoin Original
+    /// Implementation.
+    /// </summary>
+    SECURE_HEAD_SIZE = Int32(6);
+
+  strict protected
+
+    function EncryptBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
+      : TCryptoLibByteArray; override;
+
+    function DecryptBlock(in_enc: TCryptoLibByteArray; inOff, inLen: Int32)
+      : TCryptoLibByteArray; override;
+
+  public
+
+    function ProcessBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
+      : TCryptoLibByteArray; override;
+
+  end;
+
+implementation
+
+{ TPascalCoinIESEngine }
+
+function TPascalCoinIESEngine.DecryptBlock(in_enc: TCryptoLibByteArray;
+  inOff, inLen: Int32): TCryptoLibByteArray;
+var
+  K, K1, K2, T1, T2: TCryptoLibByteArray;
+  cp: ICipherParameters;
+begin
+  // Ensure that the length of the input is greater than the MAC in bytes
+  if (inLen < (System.Length(FV) + Fmac.HashSize)) then
+  begin
+    raise EInvalidCipherTextCryptoLibException.CreateRes
+      (@SInvalidCipherTextLength);
+  end;
+  // note order is important: set up keys, do simple encryptions, check mac, do final encryption.
+  if (Fcipher = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes
+      (@SCipherCannotbeNilInThisMode);
+  end
+  else
+  begin
+    // Block cipher mode.
+
+    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
+      .CipherKeySize div 8);
+    System.SetLength(K2, Fparam.MacKeySize div 8);
+    System.SetLength(K, System.Length(K1) + System.Length(K2));
+
+    Fkdf.GenerateBytes(K, 0, System.Length(K));
+
+    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
+      System.SizeOf(Byte));
+
+    cp := TKeyParameter.Create(K1);
+
+    // If iv is provided use it to initialise the cipher
+    if (FIV <> Nil) then
+    begin
+      cp := TParametersWithIV.Create(cp, FIV);
+    end;
+
+    Fcipher.Init(False, cp);
+
+  end;
+
+  // Verify the MAC.
+  T1 := System.Copy(in_enc, System.Length(FV), Fmac.HashSize);
+  System.SetLength(T2, System.Length(T1));
+  // set the mac key before calling initialize
+  Fmac.Key := K2;
+  Fmac.Initialize;
+
+  Fmac.TransformBytes(in_enc, inOff + System.Length(FV) + System.Length(T2),
+    inLen - System.Length(FV) - System.Length(T2));
+
+  T2 := Fmac.TransformFinal.GetBytes;
+
+  if (not TArrayUtils.ConstantTimeAreEqual(T1, T2)) then
+  begin
+    raise EInvalidCipherTextCryptoLibException.CreateRes(@SInvalidMAC);
+  end;
+
+  Result := Fcipher.doFinal(in_enc, inOff + System.Length(FV) + Fmac.HashSize,
+    inLen - System.Length(FV) - System.Length(T2));
+  Exit;
+end;
+
+function TPascalCoinIESEngine.EncryptBlock(&in: TCryptoLibByteArray;
+  inOff, inLen: Int32): TCryptoLibByteArray;
+var
+  C, K, K1, K2, T: TCryptoLibByteArray;
+begin
+  if (Fcipher = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes
+      (@SCipherCannotbeNilInThisMode);
+  end
+  else
+  begin
+    // Block cipher mode.
+
+    System.SetLength(K1, (Fparam as IIESWithCipherParameters)
+      .CipherKeySize div 8);
+    System.SetLength(K2, Fparam.MacKeySize div 8);
+    System.SetLength(K, System.Length(K1) + System.Length(K2));
+
+    Fkdf.GenerateBytes(K, 0, System.Length(K));
+
+    System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+    System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
+      System.SizeOf(Byte));
+
+    // If iv is provided use it to initialise the cipher
+    if (FIV <> Nil) then
+    begin
+      Fcipher.Init(true, TParametersWithIV.Create(TKeyParameter.Create(K1)
+        as IKeyParameter, FIV));
+    end
+    else
+    begin
+      Fcipher.Init(true, TKeyParameter.Create(K1) as IKeyParameter);
+    end;
+
+    C := Fcipher.doFinal(&in, inOff, inLen);
+  end;
+
+  // Apply the MAC.
+  System.SetLength(T, Fmac.HashSize);
+  // set the mac key before calling initialize
+  Fmac.Key := K2;
+  Fmac.Initialize;
+  Fmac.TransformBytes(C, 0, System.Length(C));
+
+  T := Fmac.TransformFinal.GetBytes;
+
+  // Output the quadruple (SECURE_HEAD_SIZE,V,T,C).
+  // SECURE_HEAD_SIZE := Dummy Random Data for interpolability
+  // V := Ephermeral Public Key
+  // T := Authentication Message (MAC)
+  // C := Encrypted Payload
+  System.SetLength(Result, SECURE_HEAD_SIZE + System.Length(FV) +
+    System.Length(T) + System.Length(C));
+
+  System.Move(FV[0], Result[SECURE_HEAD_SIZE], System.Length(FV) *
+    System.SizeOf(Byte));
+
+  System.Move(T[0], Result[SECURE_HEAD_SIZE + System.Length(FV)],
+    System.Length(T) * System.SizeOf(Byte));
+
+  System.Move(C[0], Result[SECURE_HEAD_SIZE + System.Length(FV) +
+    System.Length(C)], System.Length(C) * System.SizeOf(Byte));
+
+end;
+
+function TPascalCoinIESEngine.ProcessBlock(&in: TCryptoLibByteArray;
+  inOff, inLen: Int32): TCryptoLibByteArray;
+var
+  ephKeyPair: IEphemeralKeyPair;
+  bIn: TBytesStream;
+  encLength: Int32;
+  z: TBigInteger;
+  BigZ: TCryptoLibByteArray;
+  kdfParam: IKDFParameters;
+begin
+  if (FforEncryption) then
+  begin
+    if (FkeyPairGenerator <> Nil) then
+    begin
+      ephKeyPair := FkeyPairGenerator.Generate;
+
+      FprivParam := ephKeyPair.GetKeyPair.Private;
+      FV := ephKeyPair.GetEncodedPublicKey;
+    end
+  end
+  else
+  begin
+    if (FkeyParser <> Nil) then
+    begin
+      // used TBytesStream here for one pass creation and population with byte array :)
+      bIn := TBytesStream.Create(System.Copy(&in, inOff, inLen));
+
+      try
+        bIn.Position := SECURE_HEAD_SIZE; // for compatiblity purposes
+
+        try
+          FpubParam := FkeyParser.readKey(bIn);
+        except
+          on e: EIOCryptoLibException do
+          begin
+            raise EInvalidCipherTextCryptoLibException.CreateResFmt
+              (@SErrorRecoveringEphemeralPublicKey, [e.Message]);
+          end;
+
+          on e: EArgumentCryptoLibException do
+          begin
+            raise EInvalidCipherTextCryptoLibException.CreateResFmt
+              (@SErrorRecoveringEphemeralPublicKey, [e.Message]);
+          end;
+
+        end;
+
+        encLength := (inLen - (bIn.Size - bIn.Position));
+        FV := TArrayUtils.CopyOfRange(&in, inOff + SECURE_HEAD_SIZE,
+          inOff + encLength);
+
+      finally
+        bIn.Free;
+      end;
+    end;
+  end;
+
+  // Compute the common value and convert to byte array.
+  Fagree.Init(FprivParam);
+  z := Fagree.CalculateAgreement(FpubParam);
+  BigZ := TBigIntegers.AsUnsignedByteArray(Fagree.GetFieldSize, z);
+
+  try
+    // Initialise the KDF.
+    kdfParam := TKDFParameters.Create(BigZ, Nil);
+    Fkdf.Init(kdfParam);
+
+    if FforEncryption then
+    begin
+      Result := EncryptBlock(&in, inOff, inLen);
+      Exit;
+    end
+    else
+    begin
+      Result := DecryptBlock(System.Copy(&in, inOff + SECURE_HEAD_SIZE,
+        inLen - SECURE_HEAD_SIZE), inOff, inLen - SECURE_HEAD_SIZE);
+      Exit;
+    end;
+
+  finally
+    System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
+      Byte(0));
+  end;
+end;
+
+end.

+ 218 - 0
CryptoLib/src/Crypto/Generators/ClpBaseKdfBytesGenerator.pas

@@ -0,0 +1,218 @@
+{ *********************************************************************************** }
+{ *                              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 ClpBaseKdfBytesGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  HlpIHash,
+  ClpIKdfParameters,
+  ClpIIso18033KdfParameters,
+  ClpIDerivationFunction,
+  ClpIDerivationParameters,
+  ClpIBaseKdfBytesGenerator,
+  ClpConverters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SOutputBufferTooSmall = 'Output Buffer too Small';
+  SOutputLengthTooLarge = 'Output Length too Large';
+  SKDFParameterNotFound = 'KDF Parameters Required For KDF Generator';
+
+type
+
+  /// <summary>
+  /// <para>
+  /// Basic KDF generator for derived keys and ivs as defined by IEEE
+  /// P1363a/ISO 18033
+  /// </para>
+  /// <para>
+  /// This implementation is based on ISO 18033/P1363a.
+  /// </para>
+  /// </summary>
+  TBaseKdfBytesGenerator = class(TInterfacedObject, IBaseKdfBytesGenerator,
+    IDerivationFunction)
+
+  strict protected
+  var
+    Fdigest: IHash;
+    FcounterStart: Int32;
+    Fshared, Fiv: TCryptoLibByteArray;
+    function GetDigest(): IHash; virtual;
+
+  public
+
+    /// <summary>
+    /// Construct a KDF Parameters generator.
+    /// </summary>
+    /// <param name="counterStart">
+    /// value of counter.
+    /// </param>
+    /// <param name="digest">
+    /// the digest to be used as the source of derived keys.
+    /// </param>
+    constructor Create(counterStart: Int32; const digest: IHash);
+
+    procedure Init(const parameters: IDerivationParameters); virtual;
+
+    /// <summary>
+    /// return the underlying digest.
+    /// </summary>
+    property digest: IHash read GetDigest;
+
+    /// <summary>
+    /// fill len bytes of the output buffer with bytes generated from the
+    /// derivation function.
+    /// </summary>
+    /// <exception cref="EArgumentCryptoLibException">
+    /// if the size of the request will cause an overflow.
+    /// </exception>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if the out buffer is too small.
+    /// </exception>
+    function GenerateBytes(output: TCryptoLibByteArray; outOff, length: Int32)
+      : Int32; virtual;
+
+  end;
+
+implementation
+
+{ TBaseKdfBytesGenerator }
+
+constructor TBaseKdfBytesGenerator.Create(counterStart: Int32;
+  const digest: IHash);
+begin
+  Inherited Create();
+  FcounterStart := counterStart;
+  Fdigest := digest;
+end;
+
+function TBaseKdfBytesGenerator.GenerateBytes(output: TCryptoLibByteArray;
+  outOff, length: Int32): Int32;
+var
+  outLen, cThreshold, i: Int32;
+  oBytes: Int64;
+  counterBase: UInt32;
+  dig, C: TCryptoLibByteArray;
+begin
+  if ((System.length(output) - length) < outOff) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooSmall);
+  end;
+
+  oBytes := length;
+  outLen := Fdigest.HashSize;
+
+  //
+  // this is at odds with the standard implementation, the
+  // maximum value should be hBits * (2^32 - 1) where hBits
+  // is the digest output size in bits. We can't have an
+  // array with a long index at the moment...
+  //
+
+  if (oBytes > ((Int64(2) shl 32) - 1)) then
+  begin
+
+    raise EArgumentCryptoLibException.CreateRes(@SOutputLengthTooLarge);
+  end;
+
+  cThreshold := Int32((oBytes + outLen - 1) div outLen);
+
+  System.SetLength(dig, Fdigest.HashSize);
+
+  System.SetLength(C, 4);
+
+  TConverters.ReadUInt32AsBytesBE(UInt32(FcounterStart), C, 0);
+
+  counterBase := UInt32(FcounterStart and (not $FF));
+
+  i := 0;
+  while i < cThreshold do
+  begin
+    Fdigest.TransformBytes(Fshared, 0, System.length(Fshared));
+    Fdigest.TransformBytes(C, 0, 4);
+
+    if (Fiv <> Nil) then
+    begin
+      Fdigest.TransformBytes(Fiv, 0, System.length(Fiv));
+    end;
+
+    dig := Fdigest.TransformFinal.GetBytes;
+
+    if (length > outLen) then
+    begin
+      System.Move(dig[0], output[outOff], outLen * System.SizeOf(Byte));
+      outOff := outOff + outLen;
+      length := length - outLen;
+    end
+    else
+    begin
+      System.Move(dig[0], output[outOff], length * System.SizeOf(Byte));
+    end;
+
+    System.Inc(C[3]);
+    if (C[3] = 0) then
+
+    begin
+      counterBase := counterBase + $100;
+      TConverters.ReadUInt32AsBytesBE(counterBase, C, 0);
+    end;
+
+    System.Inc(i);
+  end;
+
+  Fdigest.Initialize();
+
+  result := Int32(oBytes);
+end;
+
+function TBaseKdfBytesGenerator.GetDigest: IHash;
+begin
+  result := Fdigest;
+end;
+
+procedure TBaseKdfBytesGenerator.Init(const parameters: IDerivationParameters);
+var
+  Lparameters: IDerivationParameters;
+  p1: IKdfParameters;
+  p2: IIso18033KdfParameters;
+begin
+  Lparameters := parameters;
+
+  if Supports(Lparameters, IKdfParameters, p1) then
+  begin
+    Fshared := p1.GetSharedSecret();
+    Fiv := p1.GetIV();
+  end
+  else if Supports(Lparameters, IIso18033KdfParameters, p2) then
+  begin
+    Fshared := p2.GetSeed();
+    Fiv := Nil;
+  end
+  else
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SKDFParameterNotFound);
+  end;
+
+  Fdigest.Initialize();
+end;
+
+end.

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

@@ -0,0 +1,70 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpEphemeralKeyPairGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpEphemeralKeyPair,
+  ClpIEphemeralKeyPair,
+  ClpIEphemeralKeyPairGenerator,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIAsymmetricCipherKeyPairGenerator,
+  ClpKeyEncoder;
+
+type
+  TEphemeralKeyPairGenerator = class sealed(TInterfacedObject,
+    IEphemeralKeyPairGenerator)
+
+  strict private
+    Fgen: IAsymmetricCipherKeyPairGenerator;
+    FUsePointCompression: Boolean;
+    FkeyEncoder: TKeyEncoder;
+
+  public
+    function Generate(): IEphemeralKeyPair; inline;
+    constructor Create(const gen: IAsymmetricCipherKeyPairGenerator;
+      UsePointCompression: Boolean; const keyEncoder: TKeyEncoder);
+  end;
+
+implementation
+
+{ TEphemeralKeyPairGenerator }
+
+constructor TEphemeralKeyPairGenerator.Create
+  (const gen: IAsymmetricCipherKeyPairGenerator; UsePointCompression: Boolean;
+  const keyEncoder: TKeyEncoder);
+begin
+  Inherited Create();
+  Fgen := gen;
+  FUsePointCompression := UsePointCompression;
+  FkeyEncoder := keyEncoder;
+end;
+
+function TEphemeralKeyPairGenerator.Generate: IEphemeralKeyPair;
+var
+  eph: IAsymmetricCipherKeyPair;
+begin
+  eph := Fgen.generateKeyPair();
+  // Encode the ephemeral public key
+  result := TEphemeralKeyPair.Create(eph, FUsePointCompression, FkeyEncoder);
+end;
+
+end.

+ 64 - 0
CryptoLib/src/Crypto/Generators/ClpKdf2BytesGenerator.pas

@@ -0,0 +1,64 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpKdf2BytesGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHash,
+  ClpBaseKdfBytesGenerator,
+  ClpIKdf2BytesGenerator;
+
+type
+
+  /// <summary>
+  /// <para>
+  /// KDF2 generator for derived keys and ivs as defined by IEEE
+  /// P1363a/ISO 18033
+  /// </para>
+  /// <para>
+  /// This implementation is based on IEEE P1363/ISO 18033.
+  /// </para>
+  /// </summary>
+  TKdf2BytesGenerator = class(TBaseKdfBytesGenerator, IKdf2BytesGenerator)
+
+  public
+
+    /// <summary>
+    /// Construct a KDF2 bytes generator. Generates key material according to
+    /// IEEE P1363 or ISO 18033 depending on the initialisation.
+    /// </summary>
+    /// <param name="digest">
+    /// the digest to be used as the source of derived keys.
+    /// </param>
+    constructor Create(const digest: IHash);
+
+  end;
+
+implementation
+
+{ TKdf2BytesGenerator }
+
+constructor TKdf2BytesGenerator.Create(const digest: IHash);
+begin
+  Inherited Create(1, digest);
+end;
+
+end.

+ 153 - 0
CryptoLib/src/Crypto/Generators/ClpPascalCoinECIESKdfBytesGenerator.pas

@@ -0,0 +1,153 @@
+{ *********************************************************************************** }
+{ *                              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 ClpPascalCoinECIESKdfBytesGenerator;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  HlpIHash,
+  ClpBaseKdfBytesGenerator,
+  ClpIDerivationParameters,
+  ClpIKdfParameters,
+  ClpIPascalCoinECIESKdfBytesGenerator,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SOutputBufferTooSmall = 'Output Buffer too Small';
+  SKDFParameterNotFound = 'KDF Parameters Required For KDF Generator';
+  SHashCannotNotProduceSufficientData =
+    'Specified Hash Cannot Produce Sufficient Data for the Specified Operation.';
+
+type
+
+  /// <summary>
+  /// <para>
+  /// KDF generator for compatibility with existing PascalCoin Implementation
+  /// </para>
+  /// </summary>
+  TPascalCoinECIESKdfBytesGenerator = class(TBaseKdfBytesGenerator,
+    IPascalCoinECIESKdfBytesGenerator)
+
+  strict protected
+    function GetDigest(): IHash; override;
+
+  public
+
+    /// <summary>
+    /// Construct a PascalCoin compatible bytes generator.
+    /// </summary>
+    /// <param name="digest">
+    /// the digest to be used as the source of derived keys.
+    /// </param>
+    constructor Create(const digest: IHash);
+
+    procedure Init(const parameters: IDerivationParameters); override;
+
+    /// <summary>
+    /// return the underlying digest.
+    /// </summary>
+    property digest: IHash read GetDigest;
+
+    /// <summary>
+    /// fill len bytes of the output buffer with bytes generated from the
+    /// derivation function.
+    /// </summary>
+    /// <exception cref="EArgumentCryptoLibException">
+    /// if the size of the request will cause an overflow.
+    /// </exception>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if the out buffer is too small.
+    /// </exception>
+    function GenerateBytes(output: TCryptoLibByteArray; outOff, length: Int32)
+      : Int32; override;
+
+  end;
+
+implementation
+
+{ TPascalCoinECIESKdfBytesGenerator }
+
+constructor TPascalCoinECIESKdfBytesGenerator.Create(const digest: IHash);
+begin
+  Inherited Create(0, digest);
+end;
+
+function TPascalCoinECIESKdfBytesGenerator.GenerateBytes
+  (output: TCryptoLibByteArray; outOff, length: Int32): Int32;
+var
+  outLen: Int32;
+  oBytes: Int64;
+  temp: TCryptoLibByteArray;
+begin
+  if ((System.length(output) - length) < outOff) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes(@SOutputBufferTooSmall);
+  end;
+
+  oBytes := length;
+  outLen := Fdigest.HashSize;
+
+  if (oBytes > outLen) then
+  begin
+    raise EDataLengthCryptoLibException.CreateRes
+      (@SHashCannotNotProduceSufficientData);
+  end;
+
+  Fdigest.TransformBytes(Fshared, 0, System.length(Fshared));
+
+  temp := Fdigest.TransformFinal.GetBytes;
+
+  System.Move(temp[0], output[outOff], length * System.SizeOf(Byte));
+
+  Fdigest.Initialize();
+
+  result := oBytes;
+
+end;
+
+function TPascalCoinECIESKdfBytesGenerator.GetDigest: IHash;
+begin
+  result := Fdigest;
+end;
+
+procedure TPascalCoinECIESKdfBytesGenerator.Init(const parameters
+  : IDerivationParameters);
+var
+  Lparameters: IDerivationParameters;
+  p1: IKdfParameters;
+begin
+  Lparameters := parameters;
+
+  if Supports(Lparameters, IKdfParameters, p1) then
+  begin
+    Fshared := p1.GetSharedSecret();
+    Fiv := p1.GetIV();
+  end
+  else
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SKDFParameterNotFound);
+  end;
+
+  Fdigest.Initialize();
+end;
+
+end.

+ 3 - 1
CryptoLib/src/Crypto/Paddings/ClpPaddedBufferedBlockCipher.pas

@@ -23,6 +23,7 @@ interface
 
 uses
   SysUtils,
+  Math,
   ClpCheck,
   ClpIBlockCipher,
   ClpPkcs7Padding,
@@ -317,7 +318,8 @@ begin
 
   if (leftOver = 0) then
   begin
-    result := total - System.length(Fbuf);
+    // result := total - System.length(Fbuf);
+    result := Max(0, total - System.length(Fbuf));
     Exit;
   end;
 

+ 31 - 10
CryptoLib/src/Crypto/Paddings/ClpPkcs7Padding.pas

@@ -123,24 +123,45 @@ function TPkcs7Padding.PadCount(input: TCryptoLibByteArray): Int32;
 var
   countAsByte: Byte;
   count, i: Int32;
+  failed: Boolean;
 begin
-  countAsByte := input[System.Length(input) - 1];
-  count := countAsByte;
-
-  if ((count < 1) or (count > System.Length(input))) then
+  // countAsByte := input[System.Length(input) - 1];
+  // count := countAsByte;
+  //
+  // if ((count < 1) or (count > System.Length(input))) then
+  // begin
+  // raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
+  // end;
+  //
+  // for i := 2 to count do
+  // begin
+  // if (input[System.Length(input) - i] <> countAsByte) then
+  // begin
+  // raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
+  // end;
+  // end;
+  //
+  // result := count;
+
+  count := input[System.Length(input) - 1];
+  countAsByte := Byte(count);
+
+  // constant time version
+  failed := ((count > System.Length(input)) or (count = 0));
+
+  for i := 0 to System.Pred(System.Length(input)) do
   begin
-    raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
+    failed := failed or ((System.Length(input) - i <= count) and
+      (input[i] <> countAsByte));
   end;
 
-  for i := 2 to count do
+  if (failed) then
   begin
-    if (input[System.Length(input) - i] <> countAsByte) then
-    begin
-      raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
-    end;
+    raise EInvalidCipherTextCryptoLibException.CreateRes(@SCorruptedPadBlock);
   end;
 
   result := count;
+
 end;
 
 end.

+ 134 - 0
CryptoLib/src/Crypto/Paddings/ClpZeroBytePadding.pas

@@ -0,0 +1,134 @@
+{ *********************************************************************************** }
+{ *                              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 ClpZeroBytePadding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding,
+  ClpIZeroBytePadding,
+  ClpISecureRandom,
+  ClpCryptoLibTypes;
+
+type
+  TZeroBytePadding = class sealed(TInterfacedObject, IZeroBytePadding,
+    IBlockCipherPadding)
+
+  strict private
+
+    /// <returns>
+    /// return the name of the algorithm the cipher implements.
+    /// </returns>
+    function GetPaddingName: String; inline;
+
+  public
+    /// <summary>
+    /// Initialise the padder.
+    /// </summary>
+    /// <param name="random">
+    /// a SecureRandom if available.
+    /// </param>
+    procedure Init(const random: ISecureRandom);
+
+    /// <summary>
+    /// Return the name of the algorithm the cipher implements.
+    /// </summary>
+    property PaddingName: String read GetPaddingName;
+
+    /// <summary>
+    /// add the pad bytes to the passed in block, returning the number of
+    /// bytes added.
+    /// </summary>
+    /// <param name="input">
+    /// input block to pad
+    /// </param>
+    /// <param name="inOff">
+    /// offset to start the padding from in the block
+    /// </param>
+    /// <returns>
+    /// returns number of bytes added
+    /// </returns>
+    function AddPadding(input: TCryptoLibByteArray; inOff: Int32): Int32;
+
+    /// <summary>
+    /// return the number of pad bytes present in the block.
+    /// </summary>
+    /// <param name="input">
+    /// block to count pad bytes in
+    /// </param>
+    /// <returns>
+    /// the number of pad bytes present in the block.
+    /// </returns>
+    function PadCount(input: TCryptoLibByteArray): Int32;
+
+  end;
+
+implementation
+
+{ TZeroBytePadding }
+
+function TZeroBytePadding.AddPadding(input: TCryptoLibByteArray;
+  inOff: Int32): Int32;
+var
+  added: Int32;
+begin
+  added := System.Length(input) - inOff;
+
+  while (inOff < System.Length(input)) do
+  begin
+    input[inOff] := Byte(0);
+    System.Inc(inOff);
+  end;
+
+  result := added;
+end;
+
+function TZeroBytePadding.GetPaddingName: String;
+begin
+  result := 'ZeroBytePadding';
+end;
+
+{$IFNDEF _FIXINSIGHT_}
+
+procedure TZeroBytePadding.Init(const random: ISecureRandom);
+begin
+  // nothing to do.
+end;
+{$ENDIF}
+
+function TZeroBytePadding.PadCount(input: TCryptoLibByteArray): Int32;
+var
+  count: Int32;
+begin
+  count := System.Length(input);
+  while (count > 0) do
+  begin
+    if (input[count - 1] <> 0) then
+    begin
+      break;
+    end;
+
+    System.Dec(count);
+  end;
+
+  result := System.Length(input) - count;
+end;
+
+end.

+ 87 - 0
CryptoLib/src/Crypto/Parameters/ClpIesParameters.pas

@@ -0,0 +1,87 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIESParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpICipherParameters,
+  ClpIIESParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary>
+  /// parameters for using an integrated cipher in stream mode.
+  /// </summary>
+  TIESParameters = class(TInterfacedObject, IIESParameters, ICipherParameters)
+
+  strict private
+  var
+    Fderivation, Fencoding: TCryptoLibByteArray;
+    FmacKeySize: Int32;
+    function GetMacKeySize(): Int32; inline;
+  public
+    function GetDerivationV(): TCryptoLibByteArray; inline;
+    function GetEncodingV(): TCryptoLibByteArray; inline;
+    property MacKeySize: Int32 read GetMacKeySize;
+
+    /// <param name="derivation">
+    /// the derivation parameter for the KDF function.
+    /// </param>
+    /// <param name="encoding">
+    /// the encoding parameter for the KDF function.
+    /// </param>
+    /// <param name="MacKeySize">
+    /// the size of the MAC key (in bits).
+    /// </param>
+    constructor Create(derivation, encoding: TCryptoLibByteArray;
+      MacKeySize: Int32);
+  end;
+
+implementation
+
+{ TIESParameters }
+
+constructor TIESParameters.Create(derivation, encoding: TCryptoLibByteArray;
+  MacKeySize: Int32);
+begin
+  Inherited Create();
+  Fderivation := derivation;
+  Fencoding := encoding;
+  FmacKeySize := MacKeySize;
+end;
+
+function TIESParameters.GetDerivationV: TCryptoLibByteArray;
+begin
+  result := Fderivation;
+end;
+
+function TIESParameters.GetEncodingV: TCryptoLibByteArray;
+begin
+  result := Fencoding;
+end;
+
+function TIESParameters.GetMacKeySize: Int32;
+begin
+  result := FmacKeySize;
+end;
+
+end.

+ 99 - 0
CryptoLib/src/Crypto/Parameters/ClpIesWithCipherParameters.pas

@@ -0,0 +1,99 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIESWithCipherParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIESParameters,
+  ClpIIESParameters,
+  ClpIIESWithCipherParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  TIESWithCipherParameters = class(TIESParameters, IIESParameters,
+    IIESWithCipherParameters)
+
+  strict private
+  var
+    FCipherKeySize: Int32;
+    FPointCompression: Boolean;
+    FNonce: TCryptoLibByteArray;
+    function GetCipherKeySize(): Int32; inline;
+    function GetPointCompression(): Boolean; inline;
+    function GetNonce(): TCryptoLibByteArray; inline;
+  public
+    property CipherKeySize: Int32 read GetCipherKeySize;
+    property PointCompression: Boolean read GetPointCompression;
+    property Nonce: TCryptoLibByteArray read GetNonce;
+
+    /// <param name="derivation">
+    /// the derivation parameter for the KDF function.
+    /// </param>
+    /// <param name="encoding">
+    /// the encoding parameter for the KDF function.
+    /// </param>
+    /// <param name="nonce">
+    /// the iv used in the cipher engine.
+    /// </param>
+    /// <param name="MacKeySize">
+    /// the size of the MAC key (in bits).
+    /// </param>
+    /// <param name="CipherKeySize">
+    /// the size of the associated Cipher key (in bits).
+    /// </param>
+    /// <param name="PointCompression">
+    /// whether to use point compression or not in EphemeralKeyPairGenerator.
+    /// </param>
+    constructor Create(derivation, encoding, Nonce: TCryptoLibByteArray;
+      MacKeySize, CipherKeySize: Int32; PointCompression: Boolean);
+  end;
+
+implementation
+
+{ TIESWithCipherParameters }
+
+constructor TIESWithCipherParameters.Create(derivation, encoding,
+  Nonce: TCryptoLibByteArray; MacKeySize, CipherKeySize: Int32;
+  PointCompression: Boolean);
+begin
+  Inherited Create(derivation, encoding, MacKeySize);
+  FNonce := Nonce;
+  FCipherKeySize := CipherKeySize;
+  FPointCompression := PointCompression;
+end;
+
+function TIESWithCipherParameters.GetCipherKeySize: Int32;
+begin
+  result := FCipherKeySize;
+end;
+
+function TIESWithCipherParameters.GetNonce: TCryptoLibByteArray;
+begin
+  result := FNonce;
+end;
+
+function TIESWithCipherParameters.GetPointCompression: Boolean;
+begin
+  result := FPointCompression;
+end;
+
+end.

+ 61 - 0
CryptoLib/src/Crypto/Parameters/ClpIso18033KdfParameters.pas

@@ -0,0 +1,61 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIso18033KdfParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIIso18033KdfParameters,
+  ClpIDerivationParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary>
+  /// parameters for Key derivation functions for ISO-18033
+  /// </summary>
+  TIso18033KdfParameters = class(TInterfacedObject, IIso18033KdfParameters,
+    IDerivationParameters)
+
+  strict private
+    Fseed: TCryptoLibByteArray;
+
+  public
+    function GetSeed(): TCryptoLibByteArray; inline;
+
+    constructor Create(seed: TCryptoLibByteArray);
+  end;
+
+implementation
+
+{ TIso18033KdfParameters }
+
+constructor TIso18033KdfParameters.Create(seed: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  Fseed := seed;
+end;
+
+function TIso18033KdfParameters.GetSeed: TCryptoLibByteArray;
+begin
+  result := Fseed;
+end;
+
+end.

+ 68 - 0
CryptoLib/src/Crypto/Parameters/ClpKdfParameters.pas

@@ -0,0 +1,68 @@
+{ *********************************************************************************** }
+{ *                              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 ClpKdfParameters;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIKdfParameters,
+  ClpIDerivationParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary>
+  /// parameters for Key derivation functions for IEEE P1363a
+  /// </summary>
+  TKdfParameters = class(TInterfacedObject, IKdfParameters,
+    IDerivationParameters)
+
+  strict private
+    Fiv, Fshared: TCryptoLibByteArray;
+
+  public
+    function GetSharedSecret(): TCryptoLibByteArray; inline;
+    function GetIV(): TCryptoLibByteArray; inline;
+
+    constructor Create(shared, iv: TCryptoLibByteArray);
+  end;
+
+implementation
+
+{ TKdfParameters }
+
+constructor TKdfParameters.Create(shared, iv: TCryptoLibByteArray);
+begin
+  Inherited Create();
+  Fshared := shared;
+  Fiv := iv;
+end;
+
+function TKdfParameters.GetIV: TCryptoLibByteArray;
+begin
+  result := Fiv;
+end;
+
+function TKdfParameters.GetSharedSecret: TCryptoLibByteArray;
+begin
+  result := Fshared;
+end;
+
+end.

+ 105 - 0
CryptoLib/src/Crypto/Parsers/ClpECIESPublicKeyParser.pas

@@ -0,0 +1,105 @@
+{ *********************************************************************************** }
+{ *                              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 ClpECIESPublicKeyParser;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpStreamHelper,
+  Classes,
+  ClpStreams,
+  ClpIECDomainParameters,
+  ClpECPublicKeyParameters,
+  ClpIKeyParser,
+  ClpIAsymmetricKeyParameter,
+  ClpIECIESPublicKeyParser,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SSenderPublicKeyInvalid = 'Sender''s Public Key Invalid.';
+  SSenderPublicKeyInvalidPointEncoding =
+    'Sender''s Public Key has Invalid Point Encoding "%x"';
+
+type
+  TECIESPublicKeyParser = class sealed(TInterfacedObject, IECIESPublicKeyParser,
+    IKeyParser)
+
+  strict private
+  var
+    FecParams: IECDomainParameters;
+
+  public
+    function ReadKey(Stream: TStream): IAsymmetricKeyParameter;
+    constructor Create(const ecParams: IECDomainParameters);
+
+  end;
+
+implementation
+
+{ TECIESPublicKeyParser }
+
+constructor TECIESPublicKeyParser.Create(const ecParams: IECDomainParameters);
+begin
+  Inherited Create();
+  FecParams := ecParams;
+end;
+
+function TECIESPublicKeyParser.ReadKey(Stream: TStream)
+  : IAsymmetricKeyParameter;
+var
+  v: TCryptoLibByteArray;
+  first: Int32;
+begin
+  first := Stream.ReadByte;
+  // Decode the public ephemeral key
+  case first of
+    $00: // infinity
+      begin
+        raise EIOCryptoLibException.CreateRes(@SSenderPublicKeyInvalid);
+      end;
+
+    $02, // compressed
+    $03: // Byte length calculated as in ECPoint.getEncoded();
+      begin
+        System.SetLength(v, 1 + (FecParams.Curve.FieldSize + 7) div 8);
+      end;
+
+    $04, // uncompressed or
+    $06, // hybrid
+    $07: // Byte length calculated as in ECPoint.getEncoded();
+      begin
+        System.SetLength(v, 1 + (2 * ((FecParams.Curve.FieldSize + 7) div 8)));
+      end
+  else
+    begin
+      raise EIOCryptoLibException.CreateResFmt
+        (@SSenderPublicKeyInvalidPointEncoding, [first]);
+    end;
+
+  end;
+
+  v[0] := Byte(first);
+  TStreams.ReadFully(Stream, v, 1, System.length(v) - 1);
+
+  result := TECPublicKeyParameters.Create(FecParams.Curve.DecodePoint(v),
+    FecParams);
+end;
+
+end.

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

@@ -112,6 +112,7 @@ end;
 
 constructor TDsaDigestSigner.Create(const signer: IDsa; const digest: IHash);
 begin
+  Inherited Create();
   FdsaSigner := signer;
   Fdigest := digest;
 end;

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

@@ -129,6 +129,7 @@ implementation
 
 constructor TECDsaSigner.Create;
 begin
+  inherited Create();
   FkCalculator := TRandomDsaKCalculator.Create();
 end;
 

+ 1 - 1
CryptoLib/src/Crypto/Signers/ClpECSchnorrSigner.pas

@@ -67,7 +67,7 @@ type
     Fkey: IECKeyParameters;
     FBuffer: TMemoryStream;
 
-    function Aggregate: TCryptoLibByteArray;
+    function Aggregate: TCryptoLibByteArray; inline;
 
     /// <summary>
     /// <para>

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

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIBaseKdfBytesGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDerivationFunction;
+
+type
+
+  IBaseKdfBytesGenerator = interface(IDerivationFunction)
+    ['{EFA36EF4-5403-4F47-A222-2F64820C9188}']
+
+  end;
+
+implementation
+
+end.

+ 58 - 0
CryptoLib/src/Interfaces/ClpIBasicAgreement.pas

@@ -0,0 +1,58 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIBasicAgreement;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpICipherParameters;
+
+type
+
+  /// <summary>
+  /// The basic interface that basic Diffie-Hellman implementations conforms
+  /// to.
+  /// </summary>
+  IBasicAgreement = interface(IInterface)
+
+    ['{4A36A62D-3E1F-49B4-A4CD-58348E5A837F}']
+
+    /// <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 public key from a given party calculate the next message
+    /// in the agreement sequence.
+    /// </summary>
+    function CalculateAgreement(const pubKey: ICipherParameters): TBigInteger;
+
+  end;
+
+implementation
+
+end.

+ 55 - 0
CryptoLib/src/Interfaces/ClpIDerivationFunction.pas

@@ -0,0 +1,55 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIDerivationFunction;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHash,
+  ClpIDerivationParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  /// <summary>
+  /// base interface for general purpose byte derivation functions.
+  /// </summary>
+  IDerivationFunction = interface(IInterface)
+    ['{A9DA624C-A58E-4588-9EA0-81BA5B13E47E}']
+
+    procedure Init(const parameters: IDerivationParameters);
+
+    function GetDigest(): IHash;
+
+    /// <value>
+    /// return the message digest used as the basis for the function
+    /// </value>
+    property Digest: IHash read GetDigest;
+
+    /// <exception cref="EDataLengthCryptoLibException" />
+    /// <exception cref="EArgumentCryptoLibException" />
+    function GenerateBytes(output: TCryptoLibByteArray;
+      outOff, length: Int32): Int32;
+
+  end;
+
+implementation
+
+end.

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

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIDerivationParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+type
+
+  /// <summary>
+  /// Parameters for key/byte stream derivation classes
+  /// </summary>
+  IDerivationParameters = interface(IInterface)
+    ['{4F245EE6-734C-4D45-ADB5-F719F4098BB5}']
+
+  end;
+
+implementation
+
+end.

+ 49 - 0
CryptoLib/src/Interfaces/ClpIECDHBasicAgreement.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 ClpIECDHBasicAgreement;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBasicAgreement;
+
+type
+
+  /// <summary>
+  /// P1363 7.2.1 ECSVDP-DH <br />ECSVDP-DH is Elliptic Curve Secret Value
+  /// Derivation Primitive, <br />Diffie-Hellman version. It is based on the
+  /// work of [DH76], [Mil86], <br />and [Kob87]. This primitive derives a
+  /// shared secret value from one <br />party's private key and another
+  /// party's public key, where both have <br />the same set of EC domain
+  /// parameters. If two parties correctly <br />execute this primitive, they
+  /// will produce the same output. This <br />primitive can be invoked by a
+  /// scheme to derive a shared secret key; <br />specifically, it may be
+  /// 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>
+  IECDHBasicAgreement = interface(IBasicAgreement)
+
+    ['{99566C8A-DF5D-4F60-859A-583DE6260A28}']
+
+  end;
+
+implementation
+
+end.

+ 40 - 0
CryptoLib/src/Interfaces/ClpIECIESPublicKeyParser.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 ClpIECIESPublicKeyParser;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIKeyParser,
+  ClpIAsymmetricKeyParameter;
+
+type
+
+  IECIESPublicKeyParser = interface(IKeyParser)
+    ['{7A948776-4DD9-4290-BCDF-EB96800AEAF6}']
+
+    function ReadKey(stream: TStream): IAsymmetricKeyParameter;
+
+  end;
+
+implementation
+
+end.

+ 40 - 0
CryptoLib/src/Interfaces/ClpIEphemeralKeyPair.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 ClpIEphemeralKeyPair;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsymmetricCipherKeyPair,
+  ClpCryptoLibTypes;
+
+type
+  IEphemeralKeyPair = interface(IInterface)
+    ['{E3CEA842-F26D-445C-8DDE-BAB041018DA0}']
+
+    function getKeyPair(): IAsymmetricCipherKeyPair;
+
+    function getEncodedPublicKey(): TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 37 - 0
CryptoLib/src/Interfaces/ClpIEphemeralKeyPairGenerator.pas

@@ -0,0 +1,37 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIEphemeralKeyPairGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIEphemeralKeyPair;
+
+type
+  IEphemeralKeyPairGenerator = interface(IInterface)
+    ['{22E74B03-0BAA-47CA-8E62-764720D87663}']
+
+    function Generate(): IEphemeralKeyPair;
+
+  end;
+
+implementation
+
+end.

+ 52 - 0
CryptoLib/src/Interfaces/ClpIIESCipher.pas

@@ -0,0 +1,52 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIIESCipher;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpICipherParameters,
+  ClpISecureRandom,
+  ClpIIESWithCipherParameters,
+  ClpCryptoLibTypes;
+
+type
+  IIESCipher = interface(IInterface)
+    ['{DD112FD3-844A-4EF0-B9B8-22AFAEFB0881}']
+
+    procedure Init(ForEncryption: Boolean; const Key: ICipherParameters;
+      const params: IIESWithCipherParameters; const Random: ISecureRandom);
+
+    procedure ProcessBytes(input: TCryptoLibByteArray); overload;
+    procedure ProcessBytes(input: TCryptoLibByteArray;
+      inputOffset, inputLen: Int32); overload;
+
+    function DoFinal(input: TCryptoLibByteArray): TCryptoLibByteArray; overload;
+
+    function DoFinal(input: TCryptoLibByteArray; inputOffset, inputLen: Int32)
+      : TCryptoLibByteArray; overload;
+
+    function DoFinal(input: TCryptoLibByteArray; inputOffset, inputLen: Int32;
+      output: TCryptoLibByteArray; outputOffset: Int32): Int32; overload;
+  end;
+
+implementation
+
+end.

+ 103 - 0
CryptoLib/src/Interfaces/ClpIIESEngine.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 ClpIIESEngine;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHashInfo,
+  ClpIBufferedBlockCipher,
+  ClpICipherParameters,
+  ClpIAsymmetricKeyParameter,
+  ClpIEphemeralKeyPairGenerator,
+  ClpIKeyParser,
+  ClpCryptoLibTypes;
+
+type
+
+  IIESEngine = interface(IInterface)
+    ['{9FA0E287-9988-467D-9E00-3BECEE4A78C6}']
+
+    function GetCipher: IBufferedBlockCipher;
+    function GetMac: IHMAC;
+
+    /// <summary>
+    /// Initialise the encryptor/decryptor.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// whether or not this is encryption/decryption.
+    /// </param>
+    /// <param name="privParam">
+    /// our private key parameters
+    /// </param>
+    /// <param name="pubParam">
+    /// the recipient's/sender's public key parameters
+    /// </param>
+    /// <param name="params">
+    /// encoding and derivation parameters, may be wrapped to include an IV
+    /// for an underlying block cipher.
+    /// </param>
+    procedure Init(forEncryption: Boolean;
+      privParam, pubParam, params: ICipherParameters); overload;
+
+    /// <summary>
+    /// Initialise the encryptor.
+    /// </summary>
+    /// <param name="publicKey">
+    /// the recipient's/sender's public key parameters
+    /// </param>
+    /// <param name="params">
+    /// encoding and derivation parameters, may be wrapped to include an IV
+    /// for an underlying block cipher.
+    /// </param>
+    /// <param name="ephemeralKeyPairGenerator">
+    /// the ephemeral key pair generator to use.
+    /// </param>
+    procedure Init(const publicKey: IAsymmetricKeyParameter;
+      const params: ICipherParameters;
+      const ephemeralKeyPairGenerator: IEphemeralKeyPairGenerator); overload;
+
+    /// <summary>
+    /// Initialise the decryptor.
+    /// </summary>
+    /// <param name="privateKey">
+    /// the recipient's private key.
+    /// </param>
+    /// <param name="params">
+    /// encoding and derivation parameters, may be wrapped to include an IV
+    /// for an underlying block cipher.
+    /// </param>
+    /// <param name="publicKeyParser">
+    /// the parser for reading the ephemeral public key.
+    /// </param>
+    procedure Init(const privateKey: IAsymmetricKeyParameter;
+      const params: ICipherParameters;
+      const publicKeyParser: IKeyParser); overload;
+
+    function ProcessBlock(&in: TCryptoLibByteArray; inOff, inLen: Int32)
+      : TCryptoLibByteArray;
+
+    property cipher: IBufferedBlockCipher read GetCipher;
+    property mac: IHMAC read GetMac;
+  end;
+
+implementation
+
+end.

+ 42 - 0
CryptoLib/src/Interfaces/ClpIIesParameters.pas

@@ -0,0 +1,42 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIIESParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpICipherParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  IIESParameters = interface(ICipherParameters)
+    ['{F95232BB-594C-492E-AF63-C5A6822C96FD}']
+
+    function GetDerivationV(): TCryptoLibByteArray;
+    function GetEncodingV(): TCryptoLibByteArray;
+    function GetMacKeySize(): Int32;
+    property MacKeySize: Int32 read GetMacKeySize;
+
+  end;
+
+implementation
+
+end.

+ 44 - 0
CryptoLib/src/Interfaces/ClpIIesWithCipherParameters.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 ClpIIESWithCipherParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIIESParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  IIESWithCipherParameters = interface(IIESParameters)
+    ['{77F38EA8-08F2-4D0D-A8E9-F3796DCCCA54}']
+
+    function GetCipherKeySize(): Int32;
+    property CipherKeySize: Int32 read GetCipherKeySize;
+    function GetPointCompression(): Boolean;
+    property PointCompression: Boolean read GetPointCompression;
+    function GetNonce(): TCryptoLibByteArray;
+    property Nonce: TCryptoLibByteArray read GetNonce;
+
+  end;
+
+implementation
+
+end.

+ 39 - 0
CryptoLib/src/Interfaces/ClpIIso18033KdfParameters.pas

@@ -0,0 +1,39 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIIso18033KdfParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDerivationParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  IIso18033KdfParameters = interface(IDerivationParameters)
+    ['{FFECB534-B0D3-47C1-83EE-B91B5760F07D}']
+
+    function GetSeed(): TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

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

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIKdf2BytesGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBaseKdfBytesGenerator;
+
+type
+
+  IKdf2BytesGenerator = interface(IBaseKdfBytesGenerator)
+    ['{771B832D-12FA-45D0-A8AC-E3EE068706BB}']
+
+  end;
+
+implementation
+
+end.

+ 40 - 0
CryptoLib/src/Interfaces/ClpIKdfParameters.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 ClpIKdfParameters;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDerivationParameters,
+  ClpCryptoLibTypes;
+
+type
+
+  IKdfParameters = interface(IDerivationParameters)
+    ['{2DCF1BDD-90A5-4501-8F7A-F22E896A0219}']
+
+    function GetSharedSecret(): TCryptoLibByteArray;
+    function GetIV(): TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 40 - 0
CryptoLib/src/Interfaces/ClpIKeyParser.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 ClpIKeyParser;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Classes,
+  ClpIAsymmetricKeyParameter;
+
+type
+  IKeyParser = interface(IInterface)
+
+    ['{12C134F7-7A7F-4F52-B963-ACA8DC933B48}']
+
+    // raises EIOCryptoLibException if read fails
+    function readKey(stream: TStream): IAsymmetricKeyParameter;
+
+  end;
+
+implementation
+
+end.

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

@@ -0,0 +1,61 @@
+{ *********************************************************************************** }
+{ *                              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 ClpIPascalCoinECIESKdfBytesGenerator;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  HlpIHash,
+  ClpIDerivationParameters,
+  ClpIBaseKdfBytesGenerator,
+  ClpCryptoLibTypes;
+
+type
+
+  IPascalCoinECIESKdfBytesGenerator = interface(IBaseKdfBytesGenerator)
+    ['{F6C7D34B-BA6A-45DB-B2A2-088F36557396}']
+
+    function GetDigest(): IHash;
+
+    procedure Init(const parameters: IDerivationParameters);
+
+    /// <summary>
+    /// return the underlying digest.
+    /// </summary>
+    property digest: IHash read GetDigest;
+
+    /// <summary>
+    /// fill len bytes of the output buffer with bytes generated from the
+    /// derivation function.
+    /// </summary>
+    /// <exception cref="EArgumentCryptoLibException">
+    /// if the size of the request will cause an overflow.
+    /// </exception>
+    /// <exception cref="EDataLengthCryptoLibException">
+    /// if the out buffer is too small.
+    /// </exception>
+    function GenerateBytes(output: TCryptoLibByteArray;
+      outOff, length: Int32): Int32;
+
+  end;
+
+implementation
+
+end.

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

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIPascalCoinIESEngine;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIIESEngine;
+
+type
+
+  IPascalCoinIESEngine = interface(IIESEngine)
+    ['{CEB707A3-6000-4771-A0F9-7C146B8DDE7A}']
+
+  end;
+
+implementation
+
+end.

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

@@ -0,0 +1,36 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIZeroBytePadding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIBlockCipherPadding;
+
+type
+  IZeroBytePadding = interface(IBlockCipherPadding)
+
+    ['{7B154AD1-F4DD-48A4-81B6-63A1DA8BB5A3}']
+
+  end;
+
+implementation
+
+end.

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

@@ -10,7 +10,7 @@
       <PathDelim Value="\"/>
       <SearchPaths>
         <IncludeFiles Value="..\..\Include"/>
-        <OtherUnitFiles Value="..\..\Asn1;..\..\Asn1\CryptoPro;..\..\Asn1\Nist;..\..\Asn1\Oiw;..\..\Asn1\Pkcs;..\..\Asn1\RossStandart;..\..\Asn1\Sec;..\..\Asn1\TeleTrust;..\..\Asn1\X9;..\..\Crypto;..\..\Crypto\Generators;..\..\Crypto\Parameters;..\..\Crypto\Prng;..\..\Crypto\Signers;..\..\Interfaces;..\..\Math;..\..\Math\EC;..\..\Math\EC\Abc;..\..\Math\EC\Endo;..\..\Math\EC\Multiplier;..\..\Math\Field;..\..\Math\Raw;..\..\Security;..\..\Utils;..\..\Utils\Collections;..\..\Utils\Encoders;..\..\Utils\Helpers;..\..\Utils\IO;..\..\Utils\Randoms;..\..\Utils\Rng;..\..\Crypto\Modes;..\..\Crypto\Paddings;..\..\Crypto\Engines"/>
+        <OtherUnitFiles Value="..\..\Asn1;..\..\Asn1\CryptoPro;..\..\Asn1\Nist;..\..\Asn1\Oiw;..\..\Asn1\Pkcs;..\..\Asn1\RossStandart;..\..\Asn1\Sec;..\..\Asn1\TeleTrust;..\..\Asn1\X9;..\..\Crypto;..\..\Crypto\Generators;..\..\Crypto\Parameters;..\..\Crypto\Prng;..\..\Crypto\Signers;..\..\Interfaces;..\..\Math;..\..\Math\EC;..\..\Math\EC\Abc;..\..\Math\EC\Endo;..\..\Math\EC\Multiplier;..\..\Math\Field;..\..\Math\Raw;..\..\Security;..\..\Utils;..\..\Utils\Collections;..\..\Utils\Encoders;..\..\Utils\Helpers;..\..\Utils\IO;..\..\Utils\Randoms;..\..\Utils\Rng;..\..\Crypto\Modes;..\..\Crypto\Paddings;..\..\Crypto\Engines;..\..\Crypto\Parsers;..\..\Crypto\Agreement"/>
         <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
       </SearchPaths>
       <CodeGeneration>
@@ -24,8 +24,8 @@
 
  Acknowledgements: 
 Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the development of this library "/>
-    <Version Major="1" Minor="7"/>
-    <Files Count="304">
+    <Version Major="1" Minor="8"/>
+    <Files Count="339">
       <Item1>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <UnitName Value="ClpAsn1Encodable"/>
@@ -1242,6 +1242,146 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <Filename Value="..\..\Crypto\Engines\ClpAesEngine.pas"/>
         <UnitName Value="ClpAesEngine"/>
       </Item304>
+      <Item305>
+        <Filename Value="..\..\Crypto\Generators\ClpPascalCoinECIESKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpPascalCoinECIESKdfBytesGenerator"/>
+      </Item305>
+      <Item306>
+        <Filename Value="..\..\Crypto\Engines\ClpPascalCoinIESEngine.pas"/>
+        <UnitName Value="ClpPascalCoinIESEngine"/>
+      </Item306>
+      <Item307>
+        <Filename Value="..\..\Crypto\Generators\ClpBaseKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpBaseKdfBytesGenerator"/>
+      </Item307>
+      <Item308>
+        <Filename Value="..\..\Crypto\Engines\ClpIESEngine.pas"/>
+        <UnitName Value="ClpIESEngine"/>
+      </Item308>
+      <Item309>
+        <Filename Value="..\..\Crypto\Parsers\ClpECIESPublicKeyParser.pas"/>
+        <UnitName Value="ClpECIESPublicKeyParser"/>
+      </Item309>
+      <Item310>
+        <Filename Value="..\..\Crypto\ClpIESCipher.pas"/>
+        <UnitName Value="ClpIESCipher"/>
+      </Item310>
+      <Item311>
+        <Filename Value="..\..\Crypto\Agreement\ClpECDHBasicAgreement.pas"/>
+        <UnitName Value="ClpECDHBasicAgreement"/>
+      </Item311>
+      <Item312>
+        <Filename Value="..\..\Crypto\ClpEphemeralKeyPair.pas"/>
+        <UnitName Value="ClpEphemeralKeyPair"/>
+      </Item312>
+      <Item313>
+        <Filename Value="..\..\Crypto\ClpKeyEncoder.pas"/>
+        <UnitName Value="ClpKeyEncoder"/>
+      </Item313>
+      <Item314>
+        <Filename Value="..\..\Crypto\Paddings\ClpZeroBytePadding.pas"/>
+        <UnitName Value="ClpZeroBytePadding"/>
+      </Item314>
+      <Item315>
+        <Filename Value="..\..\Crypto\Parameters\ClpIesWithCipherParameters.pas"/>
+        <UnitName Value="ClpIESWithCipherParameters"/>
+      </Item315>
+      <Item316>
+        <Filename Value="..\..\Crypto\Parameters\ClpIesParameters.pas"/>
+        <UnitName Value="ClpIESParameters"/>
+      </Item316>
+      <Item317>
+        <Filename Value="..\..\Crypto\Generators\ClpEphemeralKeyPairGenerator.pas"/>
+        <UnitName Value="ClpEphemeralKeyPairGenerator"/>
+      </Item317>
+      <Item318>
+        <Filename Value="..\..\Crypto\Generators\ClpKdf2BytesGenerator.pas"/>
+        <UnitName Value="ClpKdf2BytesGenerator"/>
+      </Item318>
+      <Item319>
+        <Filename Value="..\..\Crypto\Parameters\ClpIso18033KdfParameters.pas"/>
+        <UnitName Value="ClpIso18033KdfParameters"/>
+      </Item319>
+      <Item320>
+        <Filename Value="..\..\Crypto\Parameters\ClpKdfParameters.pas"/>
+        <UnitName Value="ClpKdfParameters"/>
+      </Item320>
+      <Item321>
+        <Filename Value="..\..\Interfaces\ClpIIesWithCipherParameters.pas"/>
+        <UnitName Value="ClpIIESWithCipherParameters"/>
+      </Item321>
+      <Item322>
+        <Filename Value="..\..\Interfaces\ClpIIesParameters.pas"/>
+        <UnitName Value="ClpIIESParameters"/>
+      </Item322>
+      <Item323>
+        <Filename Value="..\..\Interfaces\ClpIPascalCoinECIESKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpIPascalCoinECIESKdfBytesGenerator"/>
+      </Item323>
+      <Item324>
+        <Filename Value="..\..\Interfaces\ClpIPascalCoinIESEngine.pas"/>
+        <UnitName Value="ClpIPascalCoinIESEngine"/>
+      </Item324>
+      <Item325>
+        <Filename Value="..\..\Interfaces\ClpIIESEngine.pas"/>
+        <UnitName Value="ClpIIESEngine"/>
+      </Item325>
+      <Item326>
+        <Filename Value="..\..\Interfaces\ClpIIESCipher.pas"/>
+        <UnitName Value="ClpIIESCipher"/>
+      </Item326>
+      <Item327>
+        <Filename Value="..\..\Interfaces\ClpIZeroBytePadding.pas"/>
+        <UnitName Value="ClpIZeroBytePadding"/>
+      </Item327>
+      <Item328>
+        <Filename Value="..\..\Interfaces\ClpIECIESPublicKeyParser.pas"/>
+        <UnitName Value="ClpIECIESPublicKeyParser"/>
+      </Item328>
+      <Item329>
+        <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPairGenerator.pas"/>
+        <UnitName Value="ClpIEphemeralKeyPairGenerator"/>
+      </Item329>
+      <Item330>
+        <Filename Value="..\..\Interfaces\ClpIEphemeralKeyPair.pas"/>
+        <UnitName Value="ClpIEphemeralKeyPair"/>
+      </Item330>
+      <Item331>
+        <Filename Value="..\..\Interfaces\ClpIKeyParser.pas"/>
+        <UnitName Value="ClpIKeyParser"/>
+      </Item331>
+      <Item332>
+        <Filename Value="..\..\Interfaces\ClpIKdf2BytesGenerator.pas"/>
+        <UnitName Value="ClpIKdf2BytesGenerator"/>
+      </Item332>
+      <Item333>
+        <Filename Value="..\..\Interfaces\ClpIBaseKdfBytesGenerator.pas"/>
+        <UnitName Value="ClpIBaseKdfBytesGenerator"/>
+      </Item333>
+      <Item334>
+        <Filename Value="..\..\Interfaces\ClpIIso18033KdfParameters.pas"/>
+        <UnitName Value="ClpIIso18033KdfParameters"/>
+      </Item334>
+      <Item335>
+        <Filename Value="..\..\Interfaces\ClpIKdfParameters.pas"/>
+        <UnitName Value="ClpIKdfParameters"/>
+      </Item335>
+      <Item336>
+        <Filename Value="..\..\Interfaces\ClpIDerivationFunction.pas"/>
+        <UnitName Value="ClpIDerivationFunction"/>
+      </Item336>
+      <Item337>
+        <Filename Value="..\..\Interfaces\ClpIDerivationParameters.pas"/>
+        <UnitName Value="ClpIDerivationParameters"/>
+      </Item337>
+      <Item338>
+        <Filename Value="..\..\Interfaces\ClpIECDHBasicAgreement.pas"/>
+        <UnitName Value="ClpIECDHBasicAgreement"/>
+      </Item338>
+      <Item339>
+        <Filename Value="..\..\Interfaces\ClpIBasicAgreement.pas"/>
+        <UnitName Value="ClpIBasicAgreement"/>
+      </Item339>
     </Files>
     <RequiredPkgs Count="3">
       <Item1>

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

@@ -101,7 +101,21 @@ uses
   ClpIBufferedBlockCipher, ClpIBlockCipherPadding, ClpIBlockCipher, 
   ClpCbcBlockCipher, ClpPaddedBufferedBlockCipher, ClpPkcs7Padding, 
   ClpParametersWithIV, ClpKeyParameter, ClpBufferedBlockCipher, 
-  ClpBufferedCipherBase, ClpCheck, ClpAesEngine;
+  ClpBufferedCipherBase, ClpCheck, ClpAesEngine, 
+  ClpPascalCoinECIESKdfBytesGenerator, ClpPascalCoinIESEngine, 
+  ClpBaseKdfBytesGenerator, ClpIESEngine, ClpECIESPublicKeyParser, 
+  ClpIESCipher, ClpECDHBasicAgreement, ClpEphemeralKeyPair, ClpKeyEncoder, 
+  ClpZeroBytePadding, ClpIesWithCipherParameters, ClpIesParameters, 
+  ClpEphemeralKeyPairGenerator, ClpKdf2BytesGenerator, 
+  ClpIso18033KdfParameters, ClpKdfParameters, ClpIIesWithCipherParameters, 
+  ClpIIesParameters, ClpIPascalCoinECIESKdfBytesGenerator, 
+  ClpIPascalCoinIESEngine, ClpIIESEngine, ClpIIESCipher, ClpIZeroBytePadding, 
+  ClpIECIESPublicKeyParser, ClpIEphemeralKeyPairGenerator, 
+  ClpIEphemeralKeyPair, ClpIKeyParser, ClpIKdf2BytesGenerator, 
+  ClpIBaseKdfBytesGenerator, ClpIIso18033KdfParameters, ClpIKdfParameters, 
+  ClpIDerivationFunction, ClpIDerivationParameters, ClpIECDHBasicAgreement, 
+  ClpIBasicAgreement, Generics.Collections, Generics.Defaults, 
+  Generics.Hashes, Generics.Helpers, Generics.MemoryExpanders, Generics.Strings;
 
 implementation
 

+ 9 - 2
CryptoLib/src/Security/ClpCipherUtilities.pas

@@ -29,6 +29,8 @@ uses
   ClpStringHelper,
   ClpPkcs7Padding,
   ClpIPkcs7Padding,
+  ClpZeroBytePadding,
+  ClpIZeroBytePadding,
   ClpCbcBlockCipher,
   ClpICbcBlockCipher,
   ClpBufferedBlockCipher,
@@ -61,7 +63,8 @@ type
 {$SCOPEDENUMS ON}
     TCipherAlgorithm = (AES);
     TCipherMode = (NONE, CBC);
-    TCipherPadding = (NOPADDING, PKCS5, PKCS5PADDING, PKCS7, PKCS7PADDING);
+    TCipherPadding = (NOPADDING, PKCS5, PKCS5PADDING, PKCS7, PKCS7PADDING,
+      ZEROBYTEPADDING);
 {$SCOPEDENUMS OFF}
 
   class var
@@ -229,7 +232,11 @@ begin
         TCipherPadding.PKCS7PADDING:
         begin
           padding := TPkcs7Padding.Create() as IPkcs7Padding;
-        end
+        end;
+      TCipherPadding.ZEROBYTEPADDING:
+        begin
+          padding := TZeroBytePadding.Create() as IZeroBytePadding;
+        end;
     else
       begin
         raise ESecurityUtilityCryptoLibException.CreateResFmt

+ 1 - 1
CryptoLib/src/Security/ClpParameterUtilities.pas

@@ -56,7 +56,7 @@ type
       keyBytes: TCryptoLibByteArray): IKeyParameter; overload; static; inline;
 
     class function CreateKeyParameter(const algorithm: String;
-      keyBytes: TCryptoLibByteArray): IKeyParameter; overload; static; inline;
+      keyBytes: TCryptoLibByteArray): IKeyParameter; overload; static;
 
     class function CreateKeyParameter(const algOid: IDerObjectIdentifier;
       keyBytes: TCryptoLibByteArray; offset, length: Int32): IKeyParameter;

+ 15 - 1
CryptoLib/src/Utils/ClpArrayUtils.pas

@@ -38,7 +38,10 @@ type
   public
 
     class function AddStringArray(const A, B: TCryptoLibStringArray)
-      : TCryptoLibStringArray;
+      : TCryptoLibStringArray; static;
+
+    class function AddByteArray(const A, B: TCryptoLibByteArray)
+      : TCryptoLibByteArray; static; inline;
 
     class function AreEqual(const A, B: TCryptoLibByteArray): Boolean;
       overload; static;
@@ -80,6 +83,17 @@ begin
   Result := newLength;
 end;
 
+class function TArrayUtils.AddByteArray(const A, B: TCryptoLibByteArray)
+  : TCryptoLibByteArray;
+var
+  l: Int32;
+begin
+  l := System.Length(A);
+  System.SetLength(Result, l + System.Length(B));
+  System.Move(A[0], Result[0], l * System.SizeOf(Byte));
+  System.Move(B[0], Result[l], System.Length(B) * System.SizeOf(Byte));
+end;
+
 class function TArrayUtils.AddStringArray(const A, B: TCryptoLibStringArray)
   : TCryptoLibStringArray;
 var

+ 2 - 2
CryptoLib/src/Utils/ClpBigIntegers.pas

@@ -54,7 +54,7 @@ type
     /// encoding.
     /// </returns>
     class function AsUnsignedByteArray(const n: TBigInteger)
-      : TCryptoLibByteArray; overload; static; inline;
+      : TCryptoLibByteArray; overload; static;
 
     /// <summary>
     /// the passed in value as an unsigned byte array of specified length,
@@ -71,7 +71,7 @@ type
     /// given the size of n.
     /// </returns>
     class function AsUnsignedByteArray(length: Int32; const n: TBigInteger)
-      : TCryptoLibByteArray; overload; static; inline;
+      : TCryptoLibByteArray; overload; static;
 
     /// <summary>
     /// Return a random BigInteger not less than 'min' and not greater than

+ 1 - 0
CryptoLib/src/Utils/ClpCryptoLibTypes.pas

@@ -54,6 +54,7 @@ type
   EAccessCryptoLibException = class(ECryptoLibException);
   EDataLengthCryptoLibException = class(ECryptoLibException);
   EOutputLengthCryptoLibException = class(ECryptoLibException);
+  EBadBlockCryptoLibException = class(ECryptoLibException);
 
   /// <summary>
   /// Represents a dynamic array of Byte.

+ 1 - 1
CryptoLib/src/Utils/Helpers/ClpStreamHelper.pas

@@ -30,7 +30,7 @@ type
 
   public
 
-    function ReadByte(): Int32; inline;
+    function ReadByte(): Int32;
     procedure WriteByte(b: Byte); inline;
   end;