Browse Source

Add CVC-ECDSA and PLAIN-ECDSA

- add CVC-ECDSA and PLAIN-ECDSA
- some refactoring
Ugochukwu Mmaduekwe 7 years ago
parent
commit
94818be526
27 changed files with 1184 additions and 204 deletions
  1. 9 1
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  2. 10 2
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  3. 2 1
      CryptoLib.Tests/src/Others/SignerUtilitiesTests.pas
  4. 172 0
      CryptoLib/src/Asn1/Bsi/ClpBsiObjectIdentifiers.pas
  5. 139 0
      CryptoLib/src/Asn1/Eac/ClpEacObjectIdentifiers.pas
  6. 44 39
      CryptoLib/src/Crypto/Signers/ClpDsaDigestSigner.pas
  7. 9 2
      CryptoLib/src/Crypto/Signers/ClpDsaSigner.pas
  8. 9 2
      CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas
  9. 10 3
      CryptoLib/src/Crypto/Signers/ClpECNRSigner.pas
  10. 8 5
      CryptoLib/src/Crypto/Signers/ClpHMacDsaKCalculator.pas
  11. 139 0
      CryptoLib/src/Crypto/Signers/ClpPlainDsaEncoding.pas
  12. 140 0
      CryptoLib/src/Crypto/Signers/ClpStandardDsaEncoding.pas
  13. 1 5
      CryptoLib/src/Interfaces/ClpIDsaDigestSigner.pas
  14. 52 0
      CryptoLib/src/Interfaces/ClpIDsaEncoding.pas
  15. 44 0
      CryptoLib/src/Interfaces/ClpIDsaExt.pas
  16. 2 2
      CryptoLib/src/Interfaces/ClpIDsaSigner.pas
  17. 2 2
      CryptoLib/src/Interfaces/ClpIECDsaSigner.pas
  18. 2 2
      CryptoLib/src/Interfaces/ClpIECNRSigner.pas
  19. 48 0
      CryptoLib/src/Interfaces/ClpIPlainDsaEncoding.pas
  20. 49 0
      CryptoLib/src/Interfaces/ClpIStandardDsaEncoding.pas
  21. 35 3
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.lpk
  22. 4 1
      CryptoLib/src/Packages/FPC/CryptoLib4PascalPackage.pas
  23. 3 3
      CryptoLib/src/Security/ClpDigestUtilities.pas
  24. 142 131
      CryptoLib/src/Security/ClpSignerUtilities.pas
  25. 9 0
      CryptoLib/src/Utils/ClpArrayUtils.pas
  26. 8 0
      CryptoLib/src/Utils/ClpBigIntegers.pas
  27. 92 0
      CryptoLib/src/Utils/ClpStringUtils.pas

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

@@ -455,7 +455,15 @@ uses
   ClpISecP256R1Point in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Point.pas',
   ClpSecP256R1Point in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Point.pas',
   ClpISecP256R1Curve in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Curve.pas',
-  ClpSecP256R1Curve in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas';
+  ClpSecP256R1Curve in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas',
+  ClpIDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIDsaEncoding.pas',
+  ClpIDsaExt in '..\..\CryptoLib\src\Interfaces\ClpIDsaExt.pas',
+  ClpStandardDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpStandardDsaEncoding.pas',
+  ClpIStandardDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIStandardDsaEncoding.pas',
+  ClpIPlainDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainDsaEncoding.pas',
+  ClpPlainDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainDsaEncoding.pas',
+  ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
+  ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas';
 
 begin
   try

+ 10 - 2
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -508,12 +508,20 @@ uses
   ClpSecP256R1Point in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Point.pas',
   ClpISecP256R1Curve in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Curve.pas',
   ClpSecP256R1Curve in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas',
-  SecP256R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas',
+  SecP256R1FieldTests in '..\src\Math\EC\Custom\Sec\SecP256R1FieldTests.pas' {/,},
   TagTests in '..\src\Asn1\TagTests.pas',
   StringTests in '..\src\Asn1\StringTests.pas',
   ParsingTests in '..\src\Asn1\ParsingTests.pas',
   ParseTests in '..\src\Asn1\ParseTests.pas',
-  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas';
+  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas',
+  ClpIDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIDsaEncoding.pas',
+  ClpIDsaExt in '..\..\CryptoLib\src\Interfaces\ClpIDsaExt.pas',
+  ClpStandardDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpStandardDsaEncoding.pas',
+  ClpIStandardDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIStandardDsaEncoding.pas',
+  ClpIPlainDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainDsaEncoding.pas',
+  ClpPlainDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainDsaEncoding.pas',
+  ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
+  ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas';
 
 begin
 

+ 2 - 1
CryptoLib.Tests/src/Others/SignerUtilitiesTests.pas

@@ -201,7 +201,8 @@ begin
         System.length(upper) - withPos + System.length('WITH'));
     end;
 
-    if (cipherName = 'ECDSA') then
+    if ((cipherName = 'ECDSA') or (cipherName = 'CVC-ECDSA') or
+      (cipherName = 'PLAIN-ECDSA')) then
     begin
       signParams := FecPriv;
       verifyParams := FecPub;

+ 172 - 0
CryptoLib/src/Asn1/Bsi/ClpBsiObjectIdentifiers.pas

@@ -0,0 +1,172 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBsiObjectIdentifiers;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpDerObjectIdentifier,
+  ClpIDerObjectIdentifier;
+
+type
+  TBsiObjectIdentifiers = class abstract(TObject)
+
+  strict private
+
+    /// <remarks>See https://www.bsi.bund.de/cae/servlet/contentblob/471398/publicationFile/30615/BSI-TR-03111_pdf.pdf</remarks>
+  class var
+
+    FIsBooted: Boolean;
+    Fbsi_de, Fid_ecc, Fecdsa_plain_signatures, Fecdsa_plain_SHA1,
+      Fecdsa_plain_SHA224, Fecdsa_plain_SHA256, Fecdsa_plain_SHA384,
+      Fecdsa_plain_SHA512, Fecdsa_plain_RIPEMD160: IDerObjectIdentifier;
+
+    class function Getbsi_de: IDerObjectIdentifier; static; inline;
+    class function Getecdsa_plain_RIPEMD160: IDerObjectIdentifier;
+      static; inline;
+    class function Getecdsa_plain_SHA1: IDerObjectIdentifier; static; inline;
+    class function Getecdsa_plain_SHA224: IDerObjectIdentifier; static; inline;
+    class function Getecdsa_plain_SHA256: IDerObjectIdentifier; static; inline;
+    class function Getecdsa_plain_SHA384: IDerObjectIdentifier; static; inline;
+    class function Getecdsa_plain_SHA512: IDerObjectIdentifier; static; inline;
+    class function Getecdsa_plain_signatures: IDerObjectIdentifier;
+      static; inline;
+    class function Getid_ecc: IDerObjectIdentifier; static; inline;
+
+    class constructor BsiObjectIdentifiers();
+
+  public
+
+    class property bsi_de: IDerObjectIdentifier read Getbsi_de;
+    class property id_ecc: IDerObjectIdentifier read Getid_ecc;
+    class property ecdsa_plain_signatures: IDerObjectIdentifier
+      read Getecdsa_plain_signatures;
+    class property ecdsa_plain_SHA1: IDerObjectIdentifier
+      read Getecdsa_plain_SHA1;
+    class property ecdsa_plain_SHA224: IDerObjectIdentifier
+      read Getecdsa_plain_SHA224;
+    class property ecdsa_plain_SHA256: IDerObjectIdentifier
+      read Getecdsa_plain_SHA256;
+    class property ecdsa_plain_SHA384: IDerObjectIdentifier
+      read Getecdsa_plain_SHA384;
+    class property ecdsa_plain_SHA512: IDerObjectIdentifier
+      read Getecdsa_plain_SHA512;
+    class property ecdsa_plain_RIPEMD160: IDerObjectIdentifier
+      read Getecdsa_plain_RIPEMD160;
+
+    class procedure Boot(); static;
+
+  end;
+
+implementation
+
+{ TBsiObjectIdentifiers }
+
+class procedure TBsiObjectIdentifiers.Boot;
+begin
+  if not FIsBooted then
+  begin
+    Fbsi_de := TDerObjectIdentifier.Create('0.4.0.127.0.7');
+
+    // /* 0.4.0.127.0.7.1.1 */
+    Fid_ecc := Fbsi_de.Branch('1.1');
+
+    // /* 0.4.0.127.0.7.1.1.4.1 */
+    Fecdsa_plain_signatures := Fid_ecc.Branch('4.1');
+
+    // /* 0.4.0.127.0.7.1.1.4.1.1 */
+    Fecdsa_plain_SHA1 := Fecdsa_plain_signatures.Branch('1');
+
+    // /* 0.4.0.127.0.7.1.1.4.1.2 */
+    Fecdsa_plain_SHA224 := Fecdsa_plain_signatures.Branch('2');
+
+    // /* 0.4.0.127.0.7.1.1.4.1.3 */
+    Fecdsa_plain_SHA256 := Fecdsa_plain_signatures.Branch('3');
+
+    // /* 0.4.0.127.0.7.1.1.4.1.4 */
+    Fecdsa_plain_SHA384 := Fecdsa_plain_signatures.Branch('4');
+
+    // /* 0.4.0.127.0.7.1.1.4.1.5 */
+    Fecdsa_plain_SHA512 := Fecdsa_plain_signatures.Branch('5');
+
+    // /* 0.4.0.127.0.7.1.1.4.1.6 */
+    Fecdsa_plain_RIPEMD160 := Fecdsa_plain_signatures.Branch('6');
+
+    FIsBooted := True;
+  end;
+end;
+
+class constructor TBsiObjectIdentifiers.BsiObjectIdentifiers;
+begin
+  TBsiObjectIdentifiers.Boot;
+end;
+
+class function TBsiObjectIdentifiers.Getbsi_de: IDerObjectIdentifier;
+begin
+  result := Fbsi_de;
+end;
+
+class function TBsiObjectIdentifiers.Getecdsa_plain_RIPEMD160
+  : IDerObjectIdentifier;
+begin
+  result := Fecdsa_plain_RIPEMD160;
+end;
+
+class function TBsiObjectIdentifiers.Getecdsa_plain_SHA1: IDerObjectIdentifier;
+begin
+  result := Fecdsa_plain_SHA1;
+end;
+
+class function TBsiObjectIdentifiers.Getecdsa_plain_SHA224
+  : IDerObjectIdentifier;
+begin
+  result := Fecdsa_plain_SHA224;
+end;
+
+class function TBsiObjectIdentifiers.Getecdsa_plain_SHA256
+  : IDerObjectIdentifier;
+begin
+  result := Fecdsa_plain_SHA256;
+end;
+
+class function TBsiObjectIdentifiers.Getecdsa_plain_SHA384
+  : IDerObjectIdentifier;
+begin
+  result := Fecdsa_plain_SHA384;
+end;
+
+class function TBsiObjectIdentifiers.Getecdsa_plain_SHA512
+  : IDerObjectIdentifier;
+begin
+  result := Fecdsa_plain_SHA512;
+end;
+
+class function TBsiObjectIdentifiers.Getecdsa_plain_signatures
+  : IDerObjectIdentifier;
+begin
+  result := Fecdsa_plain_signatures;
+end;
+
+class function TBsiObjectIdentifiers.Getid_ecc: IDerObjectIdentifier;
+begin
+  result := Fid_ecc;
+end;
+
+end.

+ 139 - 0
CryptoLib/src/Asn1/Eac/ClpEacObjectIdentifiers.pas

@@ -0,0 +1,139 @@
+{ *********************************************************************************** }
+{ *                              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 ClpEacObjectIdentifiers;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpDerObjectIdentifier,
+  ClpIDerObjectIdentifier;
+
+type
+  TEacObjectIdentifiers = class abstract(TObject)
+
+  strict private
+
+  class var
+
+    FIsBooted: Boolean;
+    Fbsi_de, Fid_TA, Fid_TA_ECDSA, Fid_TA_ECDSA_SHA_1, Fid_TA_ECDSA_SHA_224,
+      Fid_TA_ECDSA_SHA_256, Fid_TA_ECDSA_SHA_384, Fid_TA_ECDSA_SHA_512
+      : IDerObjectIdentifier;
+
+    class function Getbsi_de: IDerObjectIdentifier; static; inline;
+    class function Getid_TA: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_1: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_224: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_256: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_384: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_512: IDerObjectIdentifier; static; inline;
+
+    class constructor EacObjectIdentifiers();
+
+  public
+    class property bsi_de: IDerObjectIdentifier read Getbsi_de;
+    class property id_TA: IDerObjectIdentifier read Getid_TA;
+    class property id_TA_ECDSA: IDerObjectIdentifier read Getid_TA_ECDSA;
+    class property id_TA_ECDSA_SHA_1: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_1;
+    class property id_TA_ECDSA_SHA_224: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_224;
+    class property id_TA_ECDSA_SHA_256: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_256;
+    class property id_TA_ECDSA_SHA_384: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_384;
+    class property id_TA_ECDSA_SHA_512: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_512;
+    class procedure Boot(); static;
+
+  end;
+
+implementation
+
+{ TEacObjectIdentifiers }
+
+class procedure TEacObjectIdentifiers.Boot;
+begin
+  if not FIsBooted then
+  begin
+    Fbsi_de := TDerObjectIdentifier.Create('0.4.0.127.0.7');
+    Fid_TA := TDerObjectIdentifier.Create(Fbsi_de.ID + '.2.2.2');
+    Fid_TA_ECDSA := TDerObjectIdentifier.Create(Fid_TA.ID + '.2');
+    Fid_TA_ECDSA_SHA_1 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.1');
+    Fid_TA_ECDSA_SHA_224 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.2');
+    Fid_TA_ECDSA_SHA_256 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.3');
+    Fid_TA_ECDSA_SHA_384 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.4');
+    Fid_TA_ECDSA_SHA_512 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.5');
+
+    FIsBooted := True;
+  end;
+end;
+
+class constructor TEacObjectIdentifiers.EacObjectIdentifiers;
+begin
+  TEacObjectIdentifiers.Boot;
+end;
+
+class function TEacObjectIdentifiers.Getbsi_de: IDerObjectIdentifier;
+begin
+  result := Fbsi_de;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA: IDerObjectIdentifier;
+begin
+  result := Fid_TA;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA: IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_1: IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_1;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_224
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_224;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_256
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_256;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_384
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_384;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_512
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_512;
+end;
+
+end.

+ 44 - 39
CryptoLib/src/Crypto/Signers/ClpDsaDigestSigner.pas

@@ -25,15 +25,13 @@ uses
 
   SysUtils,
   ClpIDsa,
-  ClpIAsn1Sequence,
+  ClpIDsaExt,
+  ClpIDsaEncoding,
   ClpIDigest,
-  ClpIDerInteger,
-  ClpDerSequence,
-  ClpDerInteger,
   ClpBigInteger,
-  ClpAsn1Object,
   ClpCryptoLibTypes,
   ClpIParametersWithRandom,
+  ClpStandardDsaEncoding,
   ClpIAsymmetricKeyParameter,
   ClpICipherParameters,
   ClpISigner,
@@ -46,6 +44,7 @@ resourcestring
     'DSADigestSigner not Initialized for Signature Generation.';
   SDSaDigestSignerNotInitializedForVerification =
     'DSADigestSigner not Initialized for Verification';
+  SEncodingError = 'Unable to Encode Signature';
 
 type
   TDsaDigestSigner = class(TInterfacedObject, ISigner, IDsaDigestSigner)
@@ -53,16 +52,18 @@ type
   strict private
   var
     Fdigest: IDigest;
-    FdsaSigner: IDsa;
+    Fdsa: IDsa;
+    Fencoding: IDsaEncoding;
     FforSigning: Boolean;
 
-    function DerEncode(const r, s: TBigInteger): TCryptoLibByteArray; inline;
+  strict protected
 
-    function DerDecode(const encoding: TCryptoLibByteArray)
-      : TCryptoLibGenericArray<TBigInteger>; inline;
+    function GetOrder(): TBigInteger; virtual;
 
   public
-    constructor Create(const signer: IDsa; const digest: IDigest);
+    constructor Create(const dsa: IDsa; const digest: IDigest); overload;
+    constructor Create(const dsa: IDsaExt; const digest: IDigest;
+      const encoding: IDsaEncoding); overload;
 
     function GetAlgorithmName: String; virtual;
     property AlgorithmName: String read GetAlgorithmName;
@@ -111,28 +112,21 @@ begin
   Fdigest.BlockUpdate(input, inOff, length);
 end;
 
-constructor TDsaDigestSigner.Create(const signer: IDsa; const digest: IDigest);
+constructor TDsaDigestSigner.Create(const dsa: IDsa; const digest: IDigest);
 begin
   Inherited Create();
-  FdsaSigner := signer;
+  Fdsa := dsa;
   Fdigest := digest;
+  Fencoding := TStandardDsaEncoding.Instance;
 end;
 
-function TDsaDigestSigner.DerDecode(const encoding: TCryptoLibByteArray)
-  : TCryptoLibGenericArray<TBigInteger>;
-var
-  s: IAsn1Sequence;
-begin
-  s := TAsn1Object.FromByteArray(encoding) as IAsn1Sequence;
-  Result := TCryptoLibGenericArray<TBigInteger>.Create
-    ((s[0] as IDerInteger).Value, (s[1] as IDerInteger).Value);
-end;
-
-function TDsaDigestSigner.DerEncode(const r, s: TBigInteger)
-  : TCryptoLibByteArray;
+constructor TDsaDigestSigner.Create(const dsa: IDsaExt; const digest: IDigest;
+  const encoding: IDsaEncoding);
 begin
-  Result := TDerSequence.Create([TDerInteger.Create(r) as IDerInteger,
-    TDerInteger.Create(s) as IDerInteger]).GetDerEncoded();
+  Inherited Create();
+  Fdsa := dsa;
+  Fdigest := digest;
+  Fencoding := encoding;
 end;
 
 function TDsaDigestSigner.GenerateSignature: TCryptoLibByteArray;
@@ -150,14 +144,31 @@ begin
 
   Fdigest.DoFinal(hash, 0);
 
-  sig := FdsaSigner.GenerateSignature(hash);
+  sig := Fdsa.GenerateSignature(hash);
 
-  Result := DerEncode(sig[0], sig[1]);
+  try
+    Result := Fencoding.Encode(GetOrder(), sig[0], sig[1]);
+  except
+    raise EInvalidOperationCryptoLibException.CreateRes(@SEncodingError);
+  end;
 end;
 
 function TDsaDigestSigner.GetAlgorithmName: String;
 begin
-  Result := Fdigest.AlgorithmName + 'with' + FdsaSigner.AlgorithmName;
+  Result := Fdigest.AlgorithmName + 'with' + Fdsa.AlgorithmName;
+end;
+
+function TDsaDigestSigner.GetOrder: TBigInteger;
+begin
+  if Supports(Fdsa, IDsaExt) then
+  begin
+    Result := (Fdsa as IDsaExt).Order;
+  end
+  else
+  begin
+    Result := Default (TBigInteger);
+  end;
+
 end;
 
 procedure TDsaDigestSigner.Init(forSigning: Boolean;
@@ -189,7 +200,7 @@ begin
 
   Reset();
 
-  FdsaSigner.Init(forSigning, parameters);
+  Fdsa.Init(forSigning, parameters);
 end;
 
 procedure TDsaDigestSigner.Reset;
@@ -219,16 +230,10 @@ begin
   Fdigest.DoFinal(hash, 0);
 
   try
-
-    sig := DerDecode(signature);
-    Result := FdsaSigner.VerifySignature(hash, sig[0], sig[1]);
-
+    sig := Fencoding.Decode(GetOrder(), signature);
+    Result := Fdsa.VerifySignature(hash, sig[0], sig[1]);
   except
-    on e: EIOCryptoLibException do
-    begin
-      Result := false;
-    end;
-
+    Result := false;
   end;
 
 end;

+ 9 - 2
CryptoLib/src/Crypto/Signers/ClpDsaSigner.pas

@@ -24,7 +24,7 @@ interface
 uses
   Math,
   SysUtils,
-  ClpIDsa,
+  ClpIDsaExt,
   ClpIDsaSigner,
   ClpISecureRandom,
   ClpIDsaParameters,
@@ -50,9 +50,10 @@ type
   /// The Digital Signature Algorithm - as described in "Handbook of Applied <br />
   /// Cryptography", pages 452 - 453.
   /// </summary>
-  TDsaSigner = class(TInterfacedObject, IDsa, IDsaSigner)
+  TDsaSigner = class(TInterfacedObject, IDsaExt, IDsaSigner)
 
   strict private
+  function GetOrder: TBigInteger; virtual;
     function GetAlgorithmName: String; virtual;
   strict protected
   var
@@ -103,6 +104,7 @@ type
     function VerifySignature(const &message: TCryptoLibByteArray;
       const r, s: TBigInteger): Boolean; virtual;
 
+    property Order: TBigInteger read GetOrder;
     property AlgorithmName: String read GetAlgorithmName;
 
   end;
@@ -163,6 +165,11 @@ begin
   result := TCryptoLibGenericArray<TBigInteger>.Create(r, s);
 end;
 
+function TDsaSigner.GetOrder: TBigInteger;
+begin
+  result := Fkey.Parameters.Q;
+end;
+
 function TDsaSigner.GetAlgorithmName: String;
 begin
   result := 'DSA';

+ 9 - 2
CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas

@@ -40,7 +40,7 @@ uses
   ClpRandomDsaKCalculator,
   ClpIECKeyParameters,
   ClpIDsaKCalculator,
-  ClpIDsa,
+  ClpIDsaExt,
   ClpIECDsaSigner;
 
 resourcestring
@@ -52,7 +52,7 @@ type
   /// <summary>
   /// EC-DSA as described in X9.62
   /// </summary>
-  TECDsaSigner = class(TInterfacedObject, IDsa, IECDsaSigner)
+  TECDsaSigner = class(TInterfacedObject, IDsaExt, IECDsaSigner)
 
   strict private
 
@@ -65,6 +65,7 @@ type
 
     class property Eight: TBigInteger read GetEight;
 
+     function GetOrder: TBigInteger; virtual;
     function GetAlgorithmName: String; virtual;
 
   strict protected
@@ -100,6 +101,7 @@ type
     /// </param>
     constructor Create(const kCalculator: IDsaKCalculator); overload;
 
+    property Order: TBigInteger read GetOrder;
     property AlgorithmName: String read GetAlgorithmName;
 
     procedure Init(forSigning: Boolean;
@@ -245,6 +247,11 @@ begin
   Result := FEight;
 end;
 
+function TECDsaSigner.GetOrder: TBigInteger;
+begin
+  result := Fkey.Parameters.N;
+end;
+
 procedure TECDsaSigner.Init(forSigning: Boolean;
   const parameters: ICipherParameters);
 var

+ 10 - 3
CryptoLib/src/Crypto/Signers/ClpECNRSigner.pas

@@ -23,7 +23,7 @@ interface
 
 uses
   SysUtils,
-  ClpIDsa,
+  ClpIDsaExt,
   ClpIECInterface,
   ClpIECNRSigner,
   ClpBigInteger,
@@ -54,7 +54,7 @@ type
   /// <summary>
   /// EC-NR as described in IEEE 1363-2000
   /// </summary>
-  TECNRSigner = class sealed(TInterfacedObject, IDsa, IECNRSigner)
+  TECNRSigner = class sealed(TInterfacedObject, IDsaExt, IECNRSigner)
 
   strict private
   var
@@ -63,9 +63,11 @@ type
     Frandom: ISecureRandom;
 
     function GetAlgorithmName: String; virtual;
+    function GetOrder: TBigInteger; virtual;
 
   public
 
+    property Order: TBigInteger read GetOrder;
     property AlgorithmName: String read GetAlgorithmName;
 
     procedure Init(forSigning: Boolean;
@@ -142,7 +144,7 @@ begin
       (@SNotInitializedForSigning);
   end;
 
-  n := (Fkey as IECPrivateKeyParameters).parameters.n;
+  n := Order;
   nBitLength := n.BitLength;
 
   e := TBigInteger.Create(1, &message);
@@ -186,6 +188,11 @@ begin
   result := 'ECNR';
 end;
 
+function TECNRSigner.GetOrder: TBigInteger;
+begin
+  result := Fkey.Parameters.N;
+end;
+
 procedure TECNRSigner.Init(forSigning: Boolean;
   const parameters: ICipherParameters);
 var

+ 8 - 5
CryptoLib/src/Crypto/Signers/ClpHMacDsaKCalculator.pas

@@ -33,6 +33,7 @@ uses
   ClpIKeyParameter,
   ClpIDsaKCalculator,
   ClpIHMacDsaKCalculator,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 {$IFNDEF _FIXINSIGHT_}
@@ -123,19 +124,21 @@ procedure THMacDsaKCalculator.Init(const n, d: TBigInteger;
 var
   x, dVal, m, mVal: TCryptoLibByteArray;
   mInt: TBigInteger;
+  size: Int32;
 begin
   Fn := n;
-  System.FillChar(FV[0], System.Length(FV) * System.SizeOf(Byte), Byte($01));
-  System.FillChar(FK[0], System.Length(FK) * System.SizeOf(Byte), Byte(0));
+  TArrayUtils.Fill(FV, 0, System.Length(FV), Byte($01));
+  TArrayUtils.Fill(FK, 0, System.Length(FK), Byte(0));
 
-  System.SetLength(x, (n.BitLength + 7) div 8);
+  size := TBigIntegers.GetUnsignedByteLength(n);
+  System.SetLength(x, size);
 
   dVal := TBigIntegers.AsUnsignedByteArray(d);
 
   System.Move(dVal[0], x[System.Length(x) - System.Length(dVal)],
     System.Length(dVal));
 
-  System.SetLength(m, (n.BitLength + 7) div 8);
+  System.SetLength(m, size);
 
   mInt := BitsToInt(&message);
 
@@ -184,7 +187,7 @@ var
   tOff, len: Int32;
 begin
   result := Default (TBigInteger);
-  System.SetLength(t, ((Fn.BitLength + 7) div 8));
+  System.SetLength(t, TBigIntegers.GetUnsignedByteLength(Fn));
 
   while True do
 

+ 139 - 0
CryptoLib/src/Crypto/Signers/ClpPlainDsaEncoding.pas

@@ -0,0 +1,139 @@
+{ *********************************************************************************** }
+{ *                              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 ClpPlainDsaEncoding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Math,
+  ClpIDerInteger,
+  ClpBigInteger,
+  ClpIDsaEncoding,
+  ClpIPlainDsaEncoding,
+  ClpBigIntegers,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidEncodingLength = 'Encoding has incorrect length, "%s"';
+  SValueOutOfRange = 'Value out of range, "%s"';
+
+type
+  TPlainDsaEncoding = class(TInterfacedObject, IDsaEncoding, IPlainDsaEncoding)
+
+  strict private
+    class var
+
+      FInstance: IPlainDsaEncoding;
+
+    class function GetInstance: IPlainDsaEncoding; static; inline;
+
+    class constructor PlainDsaEncoding();
+
+  strict protected
+
+    function CheckValue(const n, x: TBigInteger): TBigInteger; virtual;
+    function DecodeValue(const n: TBigInteger; const buf: TCryptoLibByteArray;
+      off, len: Int32): TBigInteger; virtual;
+    procedure EncodeValue(const n, x: TBigInteger;
+      const buf: TCryptoLibByteArray; off, len: Int32); virtual;
+
+  public
+
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>; virtual;
+
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray; virtual;
+
+    class property Instance: IPlainDsaEncoding read GetInstance;
+
+  end;
+
+implementation
+
+{ TPlainDsaEncoding }
+
+function TPlainDsaEncoding.CheckValue(const n, x: TBigInteger): TBigInteger;
+begin
+  if ((x.SignValue < 0) or ((x.CompareTo(n) >= 0))) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SValueOutOfRange, ['x']);
+  end;
+  result := x;
+end;
+
+function TPlainDsaEncoding.Decode(const n: TBigInteger;
+  const encoding: TCryptoLibByteArray): TCryptoLibGenericArray<TBigInteger>;
+var
+  valueLength: Int32;
+begin
+  valueLength := TBigIntegers.GetUnsignedByteLength(n);
+  if (System.Length(encoding) <> (valueLength * 2)) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidEncodingLength,
+      ['encoding']);
+  end;
+  result := TCryptoLibGenericArray<TBigInteger>.Create
+    (DecodeValue(n, encoding, 0, valueLength), DecodeValue(n, encoding,
+    valueLength, valueLength));
+end;
+
+function TPlainDsaEncoding.DecodeValue(const n: TBigInteger;
+  const buf: TCryptoLibByteArray; off, len: Int32): TBigInteger;
+begin
+  result := CheckValue(n, TBigInteger.Create(1, buf, off, len));
+end;
+
+function TPlainDsaEncoding.Encode(const n, r, s: TBigInteger)
+  : TCryptoLibByteArray;
+var
+  valueLength: Int32;
+begin
+  valueLength := TBigIntegers.GetUnsignedByteLength(n);
+  System.SetLength(result, valueLength * 2);
+  EncodeValue(n, r, result, 0, valueLength);
+  EncodeValue(n, s, result, valueLength, valueLength);
+end;
+
+procedure TPlainDsaEncoding.EncodeValue(const n, x: TBigInteger;
+  const buf: TCryptoLibByteArray; off, len: Int32);
+var
+  bs: TCryptoLibByteArray;
+  bsOff, bsLen, pos: Int32;
+begin
+  bs := CheckValue(n, x).ToByteArrayUnsigned();
+  bsOff := Max(0, System.Length(bs) - len);
+  bsLen := System.Length(bs) - bsOff;
+  pos := len - bsLen;
+  TArrayUtils.Fill(buf, off, off + pos, Byte(0));
+  System.Move(bs[bsOff], buf[off + pos], bsLen * System.SizeOf(Byte));
+end;
+
+class function TPlainDsaEncoding.GetInstance: IPlainDsaEncoding;
+begin
+  result := FInstance;
+end;
+
+class constructor TPlainDsaEncoding.PlainDsaEncoding;
+begin
+  FInstance := TPlainDsaEncoding.Create();
+end;
+
+end.

+ 140 - 0
CryptoLib/src/Crypto/Signers/ClpStandardDsaEncoding.pas

@@ -0,0 +1,140 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpStandardDsaEncoding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIAsn1Sequence,
+  ClpIDerInteger,
+  ClpBigInteger,
+  ClpIDsaEncoding,
+  ClpIStandardDsaEncoding,
+  ClpAsn1Object,
+  ClpDerInteger,
+  ClpDerSequence,
+  ClpIDerSequence,
+  ClpAsn1Encodable,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SMalformedSignature = 'Malformed signature, "%s"';
+  SValueOutOfRange = 'Value out of range, "%s"';
+
+type
+  TStandardDsaEncoding = class(TInterfacedObject, IDsaEncoding,
+    IStandardDsaEncoding)
+
+  strict private
+    class var
+
+      FInstance: IStandardDsaEncoding;
+
+    class function GetInstance: IStandardDsaEncoding; static; inline;
+
+    class constructor StandardDsaEncoding();
+
+  strict protected
+
+    function CheckValue(const n, x: TBigInteger): TBigInteger; virtual;
+    function DecodeValue(const n: TBigInteger; const s: IAsn1Sequence;
+      pos: Int32): TBigInteger; virtual;
+    function EncodeValue(const n, x: TBigInteger): IDerInteger; virtual;
+
+  public
+
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>; virtual;
+
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray; virtual;
+
+    class property Instance: IStandardDsaEncoding read GetInstance;
+
+  end;
+
+implementation
+
+{ TStandardDsaEncoding }
+
+function TStandardDsaEncoding.CheckValue(const n, x: TBigInteger): TBigInteger;
+begin
+  if ((x.SignValue < 0) or ((n.IsInitialized) and (x.CompareTo(n) >= 0))) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SValueOutOfRange, ['x']);
+  end;
+  result := x;
+end;
+
+function TStandardDsaEncoding.Decode(const n: TBigInteger;
+  const encoding: TCryptoLibByteArray): TCryptoLibGenericArray<TBigInteger>;
+var
+  seq: IAsn1Sequence;
+  r, s: TBigInteger;
+  expectedEncoding: TCryptoLibByteArray;
+begin
+  seq := TAsn1Object.FromByteArray(encoding) as IAsn1Sequence;
+  if (seq.Count = 2) then
+  begin
+    r := DecodeValue(n, seq, 0);
+    s := DecodeValue(n, seq, 1);
+    expectedEncoding := Encode(n, r, s);
+    if (TArrayUtils.AreEqual(expectedEncoding, encoding)) then
+    begin
+      result := TCryptoLibGenericArray<TBigInteger>.Create(r, s);
+      Exit;
+    end;
+  end;
+  raise EArgumentCryptoLibException.CreateResFmt(@SMalformedSignature,
+    ['encoding']);
+end;
+
+function TStandardDsaEncoding.DecodeValue(const n: TBigInteger;
+  const s: IAsn1Sequence; pos: Int32): TBigInteger;
+begin
+  result := CheckValue(n, (s[pos] as IDerInteger).Value);
+end;
+
+function TStandardDsaEncoding.Encode(const n, r, s: TBigInteger)
+  : TCryptoLibByteArray;
+var
+  LTemp: IDerSequence;
+begin
+  LTemp := TDerSequence.Create([EncodeValue(n, r), EncodeValue(n, s)])
+    as IDerSequence;
+  result := LTemp.GetEncoded(TAsn1Encodable.Der);
+end;
+
+function TStandardDsaEncoding.EncodeValue(const n, x: TBigInteger): IDerInteger;
+begin
+  result := TDerInteger.Create(CheckValue(n, x));
+end;
+
+class function TStandardDsaEncoding.GetInstance: IStandardDsaEncoding;
+begin
+  result := FInstance;
+end;
+
+class constructor TStandardDsaEncoding.StandardDsaEncoding;
+begin
+  FInstance := TStandardDsaEncoding.Create();
+end;
+
+end.

+ 1 - 5
CryptoLib/src/Interfaces/ClpIDsaDigestSigner.pas

@@ -22,7 +22,6 @@ unit ClpIDsaDigestSigner;
 interface
 
 uses
-  ClpCryptoLibTypes,
   ClpBigInteger,
   ClpISigner;
 
@@ -31,10 +30,7 @@ type
   IDsaDigestSigner = interface(ISigner)
     ['{6BED77E2-6D92-4DB7-8F3F-588EC528A2D7}']
 
-    function DerEncode(const r, s: TBigInteger): TCryptoLibByteArray;
-
-    function DerDecode(const encoding: TCryptoLibByteArray)
-      : TCryptoLibGenericArray<TBigInteger>;
+    function GetOrder(): TBigInteger;
 
   end;
 

+ 52 - 0
CryptoLib/src/Interfaces/ClpIDsaEncoding.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 ClpIDsaEncoding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+type
+  /// <summary>
+  /// An interface for different encoding formats for DSA signatures.
+  /// </summary>
+  IDsaEncoding = interface(IInterface)
+    ['{1331AB87-6BD4-46AF-A45D-440295E11AD7}']
+
+    /// <summary>Decode the (r, s) pair of a DSA signature.</summary>
+    /// <param name="n">The order of the group that r, s belong to.</param>
+    /// <param name="encoding">An encoding of the (r, s) pair of a DSA signature.</param>
+    /// <returns>The (r, s) of a DSA signature, stored in an array of exactly two elements, r followed by s.</returns>
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>;
+    /// <summary>Encode the (r, s) pair of a DSA signature.</summary>
+    /// <param name="n">The order of the group that r, s belong to.</param>
+    /// <param name="r">The r value of a DSA signature.</param>
+    /// <param name="s">The s value of a DSA signature.</param>
+    /// <returns>An encoding of the DSA signature given by the provided (r, s) pair.</returns>
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 44 - 0
CryptoLib/src/Interfaces/ClpIDsaExt.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 ClpIDsaExt;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpIDsa,
+  ClpBigInteger;
+
+type
+  /// <summary>
+  /// An "extended" interface for classes implementing DSA-style algorithms, that provides access
+  /// to the group order.
+  /// </summary>
+  IDsaExt = interface(IDsa)
+    ['{FF9421DB-97F1-4409-AC00-B0000EE5EAFB}']
+
+    function GetOrder: TBigInteger;
+    /// <summary>The order of the group that the r, s values in signatures belong to.</summary>
+    property Order: TBigInteger read GetOrder;
+
+  end;
+
+implementation
+
+end.

+ 2 - 2
CryptoLib/src/Interfaces/ClpIDsaSigner.pas

@@ -22,13 +22,13 @@ unit ClpIDsaSigner;
 interface
 
 uses
-  ClpIDsa,
+  ClpIDsaExt,
   ClpISecureRandom,
   ClpBigInteger,
   ClpCryptoLibTypes;
 
 type
-  IDsaSigner = interface(IDsa)
+  IDsaSigner = interface(IDsaExt)
     ['{687C14CD-F126-4886-87FC-535DEB083C2F}']
 
     function CalculateE(const n: TBigInteger;

+ 2 - 2
CryptoLib/src/Interfaces/ClpIECDsaSigner.pas

@@ -22,7 +22,7 @@ unit ClpIECDsaSigner;
 interface
 
 uses
-  ClpIDsa,
+  ClpIDsaExt,
   ClpISecureRandom,
   ClpBigInteger,
   ClpCryptoLibTypes,
@@ -30,7 +30,7 @@ uses
   ClpIECFieldElement;
 
 type
-  IECDsaSigner = interface(IDsa)
+  IECDsaSigner = interface(IDsaExt)
 
     ['{72930065-5893-46CA-B49F-51254C2E73FF}']
 

+ 2 - 2
CryptoLib/src/Interfaces/ClpIECNRSigner.pas

@@ -22,12 +22,12 @@ unit ClpIECNRSigner;
 interface
 
 uses
-  ClpIDsa,
+  ClpIDsaExt,
   ClpBigInteger,
   ClpCryptoLibTypes;
 
 type
-  IECNRSigner = interface(IDsa)
+  IECNRSigner = interface(IDsaExt)
     ['{C136F005-404E-4022-886E-DE5EFCECFF9C}']
 
   end;

+ 48 - 0
CryptoLib/src/Interfaces/ClpIPlainDsaEncoding.pas

@@ -0,0 +1,48 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIPlainDsaEncoding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIDsaEncoding,
+  ClpCryptoLibTypes;
+
+type
+  IPlainDsaEncoding = interface(IDsaEncoding)
+    ['{72DC1571-BE91-461B-BD2F-A0CCAA15DD59}']
+
+    function CheckValue(const n, x: TBigInteger): TBigInteger;
+    function DecodeValue(const n: TBigInteger; const buf: TCryptoLibByteArray;
+      off, len: Int32): TBigInteger;
+    procedure EncodeValue(const n, x: TBigInteger;
+      const buf: TCryptoLibByteArray; off, len: Int32);
+
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>;
+
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 49 - 0
CryptoLib/src/Interfaces/ClpIStandardDsaEncoding.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 ClpIStandardDsaEncoding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpIAsn1Sequence,
+  ClpIDerInteger,
+  ClpIDsaEncoding,
+  ClpCryptoLibTypes;
+
+type
+  IStandardDsaEncoding = interface(IDsaEncoding)
+    ['{A8662374-922B-4D72-B956-FE0ED3505C68}']
+
+    function CheckValue(const n, x: TBigInteger): TBigInteger;
+    function DecodeValue(const n: TBigInteger; const s: IAsn1Sequence;
+      pos: Int32): TBigInteger;
+    function EncodeValue(const n, x: TBigInteger): IDerInteger;
+
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>;
+
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 35 - 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;..\..\Crypto\Parsers;..\..\Crypto\Agreement;..\..\Crypto\Macs;..\..\Asn1\Misc;..\..\Asn1\Iana;..\..\Crypto\Digests;..\..\Asn1\X509;..\..\Crypto\EC;..\..\Math\EC\Custom\Sec"/>
+        <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;..\..\Crypto\Macs;..\..\Asn1\Misc;..\..\Asn1\Iana;..\..\Crypto\Digests;..\..\Asn1\X509;..\..\Crypto\EC;..\..\Math\EC\Custom\Sec;..\..\Asn1\Bsi;..\..\Asn1\Eac"/>
         <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="2" Minor="4"/>
-    <Files Count="453">
+    <Version Major="2" Minor="5"/>
+    <Files Count="461">
       <Item1>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <UnitName Value="ClpAsn1Encodable"/>
@@ -1840,6 +1840,38 @@ Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring the devel
         <Filename Value="..\..\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas"/>
         <UnitName Value="ClpSecP256R1Curve"/>
       </Item453>
+      <Item454>
+        <Filename Value="..\..\Asn1\Bsi\ClpBsiObjectIdentifiers.pas"/>
+        <UnitName Value="ClpBsiObjectIdentifiers"/>
+      </Item454>
+      <Item455>
+        <Filename Value="..\..\Asn1\Eac\ClpEacObjectIdentifiers.pas"/>
+        <UnitName Value="ClpEacObjectIdentifiers"/>
+      </Item455>
+      <Item456>
+        <Filename Value="..\..\Crypto\Signers\ClpPlainDsaEncoding.pas"/>
+        <UnitName Value="ClpPlainDsaEncoding"/>
+      </Item456>
+      <Item457>
+        <Filename Value="..\..\Crypto\Signers\ClpStandardDsaEncoding.pas"/>
+        <UnitName Value="ClpStandardDsaEncoding"/>
+      </Item457>
+      <Item458>
+        <Filename Value="..\..\Interfaces\ClpIStandardDsaEncoding.pas"/>
+        <UnitName Value="ClpIStandardDsaEncoding"/>
+      </Item458>
+      <Item459>
+        <Filename Value="..\..\Interfaces\ClpIPlainDsaEncoding.pas"/>
+        <UnitName Value="ClpIPlainDsaEncoding"/>
+      </Item459>
+      <Item460>
+        <Filename Value="..\..\Interfaces\ClpIDsaExt.pas"/>
+        <UnitName Value="ClpIDsaExt"/>
+      </Item460>
+      <Item461>
+        <Filename Value="..\..\Interfaces\ClpIDsaEncoding.pas"/>
+        <UnitName Value="ClpIDsaEncoding"/>
+      </Item461>
     </Files>
     <RequiredPkgs Count="3">
       <Item1>

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

@@ -148,7 +148,10 @@ uses
   ClpISecT283FieldElement, ClpSecT283K1Point, ClpISecT283K1Point, 
   ClpISecT283K1Curve, ClpSecT283K1Curve, ClpSecP256R1Field, 
   ClpISecP256R1FieldElement, ClpSecP256R1FieldElement, ClpISecP256R1Point, 
-  ClpSecP256R1Point, ClpISecP256R1Curve, ClpSecP256R1Curve;
+  ClpSecP256R1Point, ClpISecP256R1Curve, ClpSecP256R1Curve, 
+  ClpBsiObjectIdentifiers, ClpEacObjectIdentifiers, ClpPlainDsaEncoding, 
+  ClpStandardDsaEncoding, ClpIStandardDsaEncoding, ClpIPlainDsaEncoding, 
+  ClpIDsaExt, ClpIDsaEncoding;
 
 implementation
 

+ 3 - 3
CryptoLib/src/Security/ClpDigestUtilities.pas

@@ -55,7 +55,7 @@ type
 {$SCOPEDENUMS ON}
     TDigestAlgorithm = (BLAKE2B_160, BLAKE2B_256, BLAKE2B_384, BLAKE2B_512,
       BLAKE2S_128, BLAKE2S_160, BLAKE2S_224, BLAKE2S_256, GOST3411,
-      GOST3411_2012_256, GOST3411_2012_512, MD2, MD4, MD5, NULL, RIPEMD128,
+      GOST3411_2012_256, GOST3411_2012_512, MD2, MD4, MD5, NONE, RIPEMD128,
       RIPEMD160, RIPEMD256, RIPEMD320, SHA_1, SHA_224, SHA_256, SHA_384,
       SHA_512, SHA_512_224, SHA_512_256, SHA3_224, SHA3_256, SHA3_384, SHA3_512,
       TIGER, WHIRLPOOL);
@@ -228,7 +228,7 @@ begin
         Exit;
       end;
 
-    TDigestAlgorithm.NULL:
+    TDigestAlgorithm.NONE:
       begin
         result := TDigest.Create
           (THashFactory.TNullDigestFactory.CreateNullDigest());
@@ -370,7 +370,7 @@ begin
   Falgorithms := TDictionary<string, string>.Create();
   Foids := TDictionary<string, IDerObjectIdentifier>.Create();
 
-  Falgorithms.Add('NULL', 'NULL'); // Null Digest
+  Falgorithms.Add('NONE', 'NONE'); // Null Digest
 
   TPkcsObjectIdentifiers.Boot;
 

+ 142 - 131
CryptoLib/src/Security/ClpSignerUtilities.pas

@@ -39,6 +39,8 @@ uses
   ClpECSchnorrLIBSECPSigner,
   ClpIECSchnorrLIBSECPSigner,
   ClpX9ObjectIdentifiers,
+  ClpEacObjectIdentifiers,
+  ClpBsiObjectIdentifiers,
   ClpTeleTrusTObjectIdentifiers,
   ClpOiwObjectIdentifiers,
   ClpNistObjectIdentifiers,
@@ -52,6 +54,8 @@ uses
   ClpISigner,
   ClpISecureRandom,
   ClpIDerObjectIdentifier,
+  ClpPlainDsaEncoding,
+  ClpStringUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -124,6 +128,8 @@ begin
   TNistObjectIdentifiers.Boot;
   TTeleTrusTObjectIdentifiers.Boot;
   TCryptoProObjectIdentifiers.Boot;
+  TEacObjectIdentifiers.Boot;
+  TBsiObjectIdentifiers.Boot;
 
   Falgorithms.Add('NONEWITHDSA', 'NONEwithDSA');
   Falgorithms.Add('DSAWITHNONE', 'NONEwithDSA');
@@ -224,6 +230,108 @@ begin
   Falgorithms.Add(TTeleTrusTObjectIdentifiers.ECSignWithRipeMD160.id,
     'RIPEMD160withECDSA');
 
+  Falgorithms.Add('NONEWITHCVC-ECDSA', 'NONEwithCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHNONE', 'NONEwithCVC-ECDSA');
+  Falgorithms.Add('SHA1/CVC-ECDSA', 'SHA-1withCVC-ECDSA');
+  Falgorithms.Add('SHA-1/CVC-ECDSA', 'SHA-1withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA1', 'SHA-1withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA-1', 'SHA-1withCVC-ECDSA');
+  Falgorithms.Add('SHA1WITHCVC-ECDSA', 'SHA-1withCVC-ECDSA');
+  Falgorithms.Add('SHA-1WITHCVC-ECDSA', 'SHA-1withCVC-ECDSA');
+  Falgorithms.Add(TEacObjectIdentifiers.id_TA_ECDSA_SHA_1.id,
+    'SHA-1withCVC-ECDSA');
+  Falgorithms.Add('SHA224/CVC-ECDSA', 'SHA-224withCVC-ECDSA');
+  Falgorithms.Add('SHA-224/CVC-ECDSA', 'SHA-224withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA224', 'SHA-224withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA-224', 'SHA-224withCVC-ECDSA');
+  Falgorithms.Add('SHA224WITHCVC-ECDSA', 'SHA-224withCVC-ECDSA');
+  Falgorithms.Add('SHA-224WITHCVC-ECDSA', 'SHA-224withCVC-ECDSA');
+  Falgorithms.Add(TEacObjectIdentifiers.id_TA_ECDSA_SHA_224.id,
+    'SHA-224withCVC-ECDSA');
+  Falgorithms.Add('SHA256/CVC-ECDSA', 'SHA-256withCVC-ECDSA');
+  Falgorithms.Add('SHA-256/CVC-ECDSA', 'SHA-256withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA256', 'SHA-256withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA-256', 'SHA-256withCVC-ECDSA');
+  Falgorithms.Add('SHA256WITHCVC-ECDSA', 'SHA-256withCVC-ECDSA');
+  Falgorithms.Add('SHA-256WITHCVC-ECDSA', 'SHA-256withCVC-ECDSA');
+  Falgorithms.Add(TEacObjectIdentifiers.id_TA_ECDSA_SHA_256.id,
+    'SHA-256withCVC-ECDSA');
+  Falgorithms.Add('SHA384/CVC-ECDSA', 'SHA-384withCVC-ECDSA');
+  Falgorithms.Add('SHA-384/CVC-ECDSA', 'SHA-384withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA384', 'SHA-384withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA-384', 'SHA-384withCVC-ECDSA');
+  Falgorithms.Add('SHA384WITHCVC-ECDSA', 'SHA-384withCVC-ECDSA');
+  Falgorithms.Add('SHA-384WITHCVC-ECDSA', 'SHA-384withCVC-ECDSA');
+  Falgorithms.Add(TEacObjectIdentifiers.id_TA_ECDSA_SHA_384.id,
+    'SHA-384withCVC-ECDSA');
+  Falgorithms.Add('SHA512/CVC-ECDSA', 'SHA-512withCVC-ECDSA');
+  Falgorithms.Add('SHA-512/CVC-ECDSA', 'SHA-512withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA512', 'SHA-512withCVC-ECDSA');
+  Falgorithms.Add('CVC-ECDSAWITHSHA-512', 'SHA-512withCVC-ECDSA');
+  Falgorithms.Add('SHA512WITHCVC-ECDSA', 'SHA-512withCVC-ECDSA');
+  Falgorithms.Add('SHA-512WITHCVC-ECDSA', 'SHA-512withCVC-ECDSA');
+  Falgorithms.Add(TEacObjectIdentifiers.id_TA_ECDSA_SHA_512.id,
+    'SHA-512withCVC-ECDSA');
+  Falgorithms.Add('NONEWITHPLAIN-ECDSA', 'NONEwithPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHNONE', 'NONEwithPLAIN-ECDSA');
+  Falgorithms.Add('SHA1/PLAIN-ECDSA', 'SHA-1withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-1/PLAIN-ECDSA', 'SHA-1withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA1', 'SHA-1withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA-1', 'SHA-1withPLAIN-ECDSA');
+  Falgorithms.Add('SHA1WITHPLAIN-ECDSA', 'SHA-1withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-1WITHPLAIN-ECDSA', 'SHA-1withPLAIN-ECDSA');
+  Falgorithms.Add(TBsiObjectIdentifiers.ecdsa_plain_SHA1.id,
+    'SHA-1withPLAIN-ECDSA');
+  Falgorithms.Add('SHA224/PLAIN-ECDSA', 'SHA-224withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-224/PLAIN-ECDSA', 'SHA-224withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA224', 'SHA-224withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA-224', 'SHA-224withPLAIN-ECDSA');
+  Falgorithms.Add('SHA224WITHPLAIN-ECDSA', 'SHA-224withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-224WITHPLAIN-ECDSA', 'SHA-224withPLAIN-ECDSA');
+  Falgorithms.Add(TBsiObjectIdentifiers.ecdsa_plain_SHA224.id,
+    'SHA-224withPLAIN-ECDSA');
+  Falgorithms.Add('SHA256/PLAIN-ECDSA', 'SHA-256withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-256/PLAIN-ECDSA', 'SHA-256withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA256', 'SHA-256withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA-256', 'SHA-256withPLAIN-ECDSA');
+  Falgorithms.Add('SHA256WITHPLAIN-ECDSA', 'SHA-256withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-256WITHPLAIN-ECDSA', 'SHA-256withPLAIN-ECDSA');
+  Falgorithms.Add(TBsiObjectIdentifiers.ecdsa_plain_SHA256.id,
+    'SHA-256withPLAIN-ECDSA');
+  Falgorithms.Add('SHA384/PLAIN-ECDSA', 'SHA-384withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-384/PLAIN-ECDSA', 'SHA-384withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA384', 'SHA-384withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA-384', 'SHA-384withPLAIN-ECDSA');
+  Falgorithms.Add('SHA384WITHPLAIN-ECDSA', 'SHA-384withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-384WITHPLAIN-ECDSA', 'SHA-384withPLAIN-ECDSA');
+  Falgorithms.Add(TBsiObjectIdentifiers.ecdsa_plain_SHA384.id,
+    'SHA-384withPLAIN-ECDSA');
+  Falgorithms.Add('SHA512/PLAIN-ECDSA', 'SHA-512withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-512/PLAIN-ECDSA', 'SHA-512withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA512', 'SHA-512withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHSHA-512', 'SHA-512withPLAIN-ECDSA');
+  Falgorithms.Add('SHA512WITHPLAIN-ECDSA', 'SHA-512withPLAIN-ECDSA');
+  Falgorithms.Add('SHA-512WITHPLAIN-ECDSA', 'SHA-512withPLAIN-ECDSA');
+  Falgorithms.Add(TBsiObjectIdentifiers.ecdsa_plain_SHA512.id,
+    'SHA-512withPLAIN-ECDSA');
+  Falgorithms.Add('RIPEMD160/PLAIN-ECDSA', 'RIPEMD160withPLAIN-ECDSA');
+  Falgorithms.Add('PLAIN-ECDSAWITHRIPEMD160', 'RIPEMD160withPLAIN-ECDSA');
+  Falgorithms.Add('RIPEMD160WITHPLAIN-ECDSA', 'RIPEMD160withPLAIN-ECDSA');
+  Falgorithms.Add(TBsiObjectIdentifiers.ecdsa_plain_RIPEMD160.id,
+    'RIPEMD160withPLAIN-ECDSA');
+  Falgorithms.Add('SHA1WITHECNR', 'SHA-1withECNR');
+  Falgorithms.Add('SHA-1WITHECNR', 'SHA-1withECNR');
+  Falgorithms.Add('SHA224WITHECNR', 'SHA-224withECNR');
+  Falgorithms.Add('SHA-224WITHECNR', 'SHA-224withECNR');
+  Falgorithms.Add('SHA256WITHECNR', 'SHA-256withECNR');
+  Falgorithms.Add('SHA-256WITHECNR', 'SHA-256withECNR');
+  Falgorithms.Add('SHA384WITHECNR', 'SHA-384withECNR');
+  Falgorithms.Add('SHA-384WITHECNR', 'SHA-384withECNR');
+  Falgorithms.Add('SHA512WITHECNR', 'SHA-512withECNR');
+  Falgorithms.Add('SHA-512WITHECNR', 'SHA-512withECNR');
+
+
+
   // Falgorithms.Add('GOST-3410', 'GOST3410');
   // Falgorithms.Add('GOST-3410-94', 'GOST3410');
   // Falgorithms.Add('GOST3411WITHGOST3410', 'GOST3410');
@@ -412,6 +520,21 @@ begin
   Foids.Add('SHA-384withECDSA', TX9ObjectIdentifiers.ECDsaWithSha384);
   Foids.Add('SHA-512withECDSA', TX9ObjectIdentifiers.ECDsaWithSha512);
 
+  Foids.Add('RIPEMD160withECDSA',
+    TTeleTrusTObjectIdentifiers.ECSignWithRipeMD160);
+  Foids.Add('SHA-1withCVC-ECDSA', TEacObjectIdentifiers.id_TA_ECDSA_SHA_1);
+  Foids.Add('SHA-224withCVC-ECDSA', TEacObjectIdentifiers.id_TA_ECDSA_SHA_224);
+  Foids.Add('SHA-256withCVC-ECDSA', TEacObjectIdentifiers.id_TA_ECDSA_SHA_256);
+  Foids.Add('SHA-384withCVC-ECDSA', TEacObjectIdentifiers.id_TA_ECDSA_SHA_384);
+  Foids.Add('SHA-512withCVC-ECDSA', TEacObjectIdentifiers.id_TA_ECDSA_SHA_512);
+  Foids.Add('SHA-1withPLAIN-ECDSA', TBsiObjectIdentifiers.ecdsa_plain_SHA1);
+  Foids.Add('SHA-224withPLAIN-ECDSA', TBsiObjectIdentifiers.ecdsa_plain_SHA224);
+  Foids.Add('SHA-256withPLAIN-ECDSA', TBsiObjectIdentifiers.ecdsa_plain_SHA256);
+  Foids.Add('SHA-384withPLAIN-ECDSA', TBsiObjectIdentifiers.ecdsa_plain_SHA384);
+  Foids.Add('SHA-512withPLAIN-ECDSA', TBsiObjectIdentifiers.ecdsa_plain_SHA512);
+  Foids.Add('RIPEMD160withPLAIN-ECDSA',
+    TBsiObjectIdentifiers.ecdsa_plain_RIPEMD160);
+
   // Foids.Add('GOST3410',
   // TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x94);
   //
@@ -464,7 +587,7 @@ end;
 
 class function TSignerUtilities.GetSigner(algorithm: String): ISigner;
 var
-  mechanism: string;
+  mechanism, DigestName: string;
   DigestInstance: IDigest;
 begin
   if (algorithm = '') then
@@ -479,158 +602,46 @@ begin
     mechanism := algorithm;
   end;
 
-  if (mechanism = 'NONEwithDSA') then
+  if TStringUtils.EndsWith(mechanism, 'withDSA', True) then
   begin
-    DigestInstance := TDigestUtilities.GetDigest('NULL');
+    DigestName := System.Copy(mechanism, 1, TStringUtils.LastIndexOf(mechanism,
+      'with', True));
 
+    DigestInstance := TDigestUtilities.GetDigest(DigestName);
     Result := (TDsaDigestSigner.Create(TDsaSigner.Create() as IDsaSigner,
       DigestInstance));
     Exit;
   end;
 
-  if (mechanism = 'SHA-1withDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
-
-    Result := (TDsaDigestSigner.Create(TDsaSigner.Create() as IDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA-224withDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
-
-    Result := (TDsaDigestSigner.Create(TDsaSigner.Create() as IDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA-256withDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
-
-    Result := (TDsaDigestSigner.Create(TDsaSigner.Create() as IDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA-384withDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
-
-    Result := (TDsaDigestSigner.Create(TDsaSigner.Create() as IDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA-512withDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
-
-    Result := (TDsaDigestSigner.Create(TDsaSigner.Create() as IDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'NONEwithECDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('NULL');
-
-    Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-  if (mechanism = 'SHA-1withECDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
-
-    Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-  if (mechanism = 'SHA-224withECDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
-
-    Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-  if (mechanism = 'SHA-256withECDSA') then
+  if TStringUtils.EndsWith(mechanism, 'withECDSA', false) then
   begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
+    DigestName := System.Copy(mechanism, 1, TStringUtils.LastIndexOf(mechanism,
+      'with', True));
 
+    DigestInstance := TDigestUtilities.GetDigest(DigestName);
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
       DigestInstance));
     Exit;
   end;
-  if (mechanism = 'SHA-384withECDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
 
-    Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-  if (mechanism = 'SHA-512withECDSA') then
+  if (TStringUtils.EndsWith(mechanism, 'withCVC-ECDSA', True) or
+    TStringUtils.EndsWith(mechanism, 'withPLAIN-ECDSA', True)) then
   begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
+    DigestName := System.Copy(mechanism, 1, TStringUtils.LastIndexOf(mechanism,
+      'with', True));
 
+    DigestInstance := TDigestUtilities.GetDigest(DigestName);
     Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'RIPEMD160withECDSA') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('RIPEMD-160');
-
-    Result := (TDsaDigestSigner.Create(TECDsaSigner.Create() as IECDsaSigner,
-      DigestInstance));
+      DigestInstance, TPlainDsaEncoding.Instance));
     Exit;
   end;
 
-  if (mechanism = 'SHA1WITHECNR') then
+  if TStringUtils.EndsWith(mechanism, 'withECNR', True) then
   begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-1');
-
-    Result := (TDsaDigestSigner.Create(TECNRSigner.Create() as IECNRSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA224WITHECNR') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-224');
-
-    Result := (TDsaDigestSigner.Create(TECNRSigner.Create() as IECNRSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA256WITHECNR') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-256');
-
-    Result := (TDsaDigestSigner.Create(TECNRSigner.Create() as IECNRSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA384WITHECNR') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-384');
-
-    Result := (TDsaDigestSigner.Create(TECNRSigner.Create() as IECNRSigner,
-      DigestInstance));
-    Exit;
-  end;
-
-  if (mechanism = 'SHA512WITHECNR') then
-  begin
-    DigestInstance := TDigestUtilities.GetDigest('SHA-512');
+    DigestName := System.Copy(mechanism, 1, TStringUtils.LastIndexOf(mechanism,
+      'with', True));
 
+    DigestInstance := TDigestUtilities.GetDigest(DigestName);
     Result := (TDsaDigestSigner.Create(TECNRSigner.Create() as IECNRSigner,
       DigestInstance));
     Exit;

+ 9 - 0
CryptoLib/src/Utils/ClpArrayUtils.pas

@@ -83,6 +83,9 @@ type
     class function ConstantTimeAreEqual(const a_ar1, a_ar2: TCryptoLibByteArray)
       : Boolean; static;
 
+    class procedure Fill(const buf: TCryptoLibByteArray; from, &to: Int32;
+      B: Byte); static;
+
   end;
 
 implementation
@@ -240,6 +243,12 @@ begin
     * System.SizeOf(Byte));
 end;
 
+class procedure TArrayUtils.Fill(const buf: TCryptoLibByteArray;
+  from, &to: Int32; B: Byte);
+begin
+  System.FillChar(buf[from], (&to - from) * System.SizeOf(Byte), B);
+end;
+
 class function TArrayUtils.GetArrayHashCode(const data
   : TCryptoLibByteArray): Int32;
 var

+ 8 - 0
CryptoLib/src/Utils/ClpBigIntegers.pas

@@ -113,6 +113,9 @@ type
     class function BigIntegerToBytes(const b: TBigInteger; numBytes: Int32)
       : TCryptoLibByteArray; static; inline;
 
+    class function GetUnsignedByteLength(const n: TBigInteger): Int32;
+      static; inline;
+
   end;
 
 implementation
@@ -214,4 +217,9 @@ begin
     .Add(min);
 end;
 
+class function TBigIntegers.GetUnsignedByteLength(const n: TBigInteger): Int32;
+begin
+  Result := (n.BitLength + 7) shr 3;
+end;
+
 end.

+ 92 - 0
CryptoLib/src/Utils/ClpStringUtils.pas

@@ -36,12 +36,48 @@ type
     class function BeginsWith(const Input, SubString: string;
       IgnoreCase: Boolean; Offset: Int32 = 1): Boolean; static;
 
+    class function EndsWith(const Input, SubString: String; IgnoreCase: Boolean)
+      : Boolean; static;
+
+    class function LastIndexOf(const Input, SubString: string;
+      IgnoreCase: Boolean): Int32; overload; static; inline;
+
+    class function LastIndexOf(const Input, SubString: string;
+      StartIndex, Count: Int32; IgnoreCase: Boolean): Int32; overload; static;
+
   end;
 
 implementation
 
 { TStringUtils }
 
+class function TStringUtils.EndsWith(const Input, SubString: String;
+  IgnoreCase: Boolean): Boolean;
+var
+  SubStringLength: Int32;
+  TempString: String;
+begin
+  SubStringLength := System.Length(SubString);
+  Result := SubStringLength > 0;
+  if Result then
+  begin
+    TempString := System.Copy(Input, System.Length(Input) - SubStringLength + 1,
+      SubStringLength);
+    Result := System.Length(TempString) = SubStringLength;
+    if Result then
+    begin
+      if IgnoreCase then
+      begin
+        Result := CompareText(TempString, SubString) = 0
+      end
+      else
+      begin
+        Result := TempString = SubString;
+      end;
+    end;
+  end;
+end;
+
 class function TStringUtils.GetStringHashCode(const Input: string): Int32;
 var
   LowPoint, HighPoint: Int32;
@@ -64,6 +100,62 @@ begin
   Result := Int32(LResult);
 end;
 
+class function TStringUtils.LastIndexOf(const Input, SubString: string;
+  StartIndex, Count: Int32; IgnoreCase: Boolean): Int32;
+var
+  I, L, LS, M: Int32;
+  S: String;
+  P: PChar;
+
+begin
+  Result := -1;
+  LS := System.Length(Input);
+  L := System.Length(SubString);
+  if (L = 0) or (L > LS) then
+  begin
+    Exit;
+  end;
+  P := PChar(SubString);
+  S := Input;
+  I := StartIndex + 1; // 1 based
+  if (I > LS) then
+  begin
+    I := LS;
+  end;
+  I := I - L + 1;
+  M := StartIndex - Count + 1; // 1 based
+  if M < 1 then
+  begin
+    M := 1;
+  end;
+
+  while (Result = -1) and (I >= M) do
+  begin
+    if IgnoreCase then
+    begin
+      if (StrLiComp(PChar(@S[I]), P, L) = 0) then
+      begin
+        Result := I - 1;
+      end;
+    end
+    else
+    begin
+      if (StrLComp(PChar(@S[I]), P, L) = 0) then
+      begin
+        Result := I - 1;
+      end;
+    end;
+    Dec(I);
+  end;
+end;
+
+class function TStringUtils.LastIndexOf(const Input, SubString: string;
+  IgnoreCase: Boolean): Int32;
+begin
+  Result := LastIndexOf(Input, SubString, System.Length(Input) - 1,
+    System.Length(Input), IgnoreCase);
+end;
+
 class function TStringUtils.SplitString(const Input: string; Delimiter: Char)
   : TCryptoLibStringArray;
 var