Browse Source

Addition of ECSchnorr Signatures.

Ugochukwu Mmaduekwe 7 years ago
parent
commit
2850405e8c

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

@@ -7,7 +7,7 @@ program UsageSamples;
 
 uses
   SysUtils,
-   ClpCryptoProObjectIdentifiers in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpCryptoProObjectIdentifiers.pas',
+  ClpCryptoProObjectIdentifiers in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpCryptoProObjectIdentifiers.pas',
   ClpECGost3410NamedCurves in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpECGost3410NamedCurves.pas',
   ClpNistObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Nist\ClpNistObjectIdentifiers.pas',
   ClpOiwObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Oiw\ClpOiwObjectIdentifiers.pas',
@@ -284,19 +284,25 @@ uses
   ClpIBerSequenceGenerator in '..\..\CryptoLib\src\Interfaces\ClpIBerSequenceGenerator.pas',
   ClpBerSequenceGenerator in '..\..\CryptoLib\src\Asn1\ClpBerSequenceGenerator.pas',
   ClpSetWeakRef in '..\..\CryptoLib\src\Utils\ClpSetWeakRef.pas',
-  UsageExamples in '..\src\UsageExamples.pas';
+  UsageExamples in '..\src\UsageExamples.pas',
+  ClpIECSchnorrSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrSigner.pas',
+  ClpECSchnorrSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrSigner.pas';
 
 begin
   try
     { TODO -oUser -cConsole Main : Insert code here }
-    TUsageExamples.GenerateKeyPairAndSign;
+    TUsageExamples.GenerateKeyPairAndSignECDSA;
+    TUsageExamples.GenerateKeyPairAndSignECSchnorr;
     TUsageExamples.GetPublicKeyFromPrivateKey;
     TUsageExamples.RecreatePublicAndPrivateKeyPairsFromByteArray;
     TUsageExamples.RecreatePublicKeyFromXAndYCoordByteArray;
     Readln;
   except
     on E: Exception do
+    begin
       Writeln(E.ClassName, ': ', E.Message);
+       Readln;
+    end;
   end;
 
 end.

+ 0 - 3
CryptoLib.Samples/FreePascal.Samples/UsageSamples.lpi

@@ -15,9 +15,6 @@
       <UseAppBundle Value="False"/>
       <ResourceType Value="res"/>
     </General>
-    <VersionInfo>
-      <StringTable ProductVersion=""/>
-    </VersionInfo>
     <BuildModes Count="1">
       <Item1 Name="Default" Default="True"/>
     </BuildModes>

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

@@ -10,7 +10,8 @@ uses {$IFDEF UNIX} {$IFDEF UseCThreads}
 begin
   try
     { TODO -oUser -cConsole Main : Insert code here }
-    TUsageExamples.GenerateKeyPairAndSign;
+    TUsageExamples.GenerateKeyPairAndSignECDSA;
+    TUsageExamples.GenerateKeyPairAndSignECSchnorr;
     TUsageExamples.GetPublicKeyFromPrivateKey;
     TUsageExamples.RecreatePublicAndPrivateKeyPairsFromByteArray;
     TUsageExamples.RecreatePublicKeyFromXAndYCoordByteArray;

+ 77 - 5
CryptoLib.Samples/src/UsageExamples.pas

@@ -40,6 +40,7 @@ uses
   ClpIECPublicKeyParameters,
   ClpECPublicKeyParameters,
   ClpECPrivateKeyParameters,
+  ClpECSchnorrSigner,
   ClpIECInterface,
   ClpECPoint,
   ClpISigner,
@@ -63,7 +64,8 @@ type
     /// SHA-224withECDSA, SHA-256withECDSA, SHA-384withECDSA,
     /// SHA-512withECDSA and RIPEMD160withECDSA
     /// </summary>
-    SigningAlgorithm = 'SHA-1withECDSA';
+    SigningAlgorithmECDSA = 'SHA-1withECDSA';
+    SigningAlgorithmECSCHNORR = 'SHA-256withECSCHNORRLIBSECP';
 
   class var
     FRandom: ISecureRandom;
@@ -72,7 +74,8 @@ type
     class constructor UsageExamples();
 
   public
-    class procedure GenerateKeyPairAndSign(); static;
+    class procedure GenerateKeyPairAndSignECDSA(); static;
+    class procedure GenerateKeyPairAndSignECSchnorr(); static;
     class procedure GetPublicKeyFromPrivateKey(); static;
     class procedure RecreatePublicAndPrivateKeyPairsFromByteArray(); static;
     class procedure RecreatePublicKeyFromXAndYCoordByteArray(); static;
@@ -101,7 +104,7 @@ begin
   Result := '[' + Result + ']';
 end;
 
-class procedure TUsageExamples.GenerateKeyPairAndSign;
+class procedure TUsageExamples.GenerateKeyPairAndSignECDSA;
 var
   domain: IECDomainParameters;
   generator: IECKeyPairGenerator;
@@ -112,7 +115,7 @@ var
   signer: ISigner;
   &message, sigBytes: TBytes;
 const
-  MethodName = 'GenerateKeyPairAndSign';
+  MethodName = 'GenerateKeyPairAndSignECDSA';
 begin
 
   Writeln('MethodName is: ' + MethodName + sLineBreak);
@@ -137,7 +140,7 @@ begin
   Writeln('Private Key D Parameter is: ' + privParams.D.ToString(16) +
     sLineBreak);
 
-  signer := TSignerUtilities.GetSigner(SigningAlgorithm);
+  signer := TSignerUtilities.GetSigner(SigningAlgorithmECDSA);
 
   Writeln('Signer Name is: ' + signer.AlgorithmName + sLineBreak);
 
@@ -170,6 +173,75 @@ begin
 
 end;
 
+class procedure TUsageExamples.GenerateKeyPairAndSignECSchnorr;
+var
+  domain: IECDomainParameters;
+  generator: IECKeyPairGenerator;
+  keygenParams: IECKeyGenerationParameters;
+  keypair: IAsymmetricCipherKeyPair;
+  privParams: IECPrivateKeyParameters;
+  pubParams: IECPublicKeyParameters;
+  signer: ISigner;
+  &message, sigBytes: TBytes;
+const
+  MethodName = 'GenerateKeyPairAndSignECSchnorr';
+begin
+
+  Writeln('MethodName is: ' + MethodName + sLineBreak);
+
+  domain := TECDomainParameters.Create(FCurve.Curve, FCurve.G, FCurve.N,
+    FCurve.H, FCurve.GetSeed);
+  generator := TECKeyPairGenerator.Create('ECSCHNORR');
+  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
+
+  Writeln('Algorithm Name is: ' + pubParams.AlgorithmName + sLineBreak);
+
+  Writeln('Public Key Normalized XCoord is: ' +
+    pubParams.Q.Normalize.AffineXCoord.ToBigInteger.ToString(16) + sLineBreak);
+  Writeln('Public Key Normalized YCoord is: ' +
+    pubParams.Q.Normalize.AffineYCoord.ToBigInteger.ToString(16) + sLineBreak);
+
+  Writeln('Private Key D Parameter is: ' + privParams.D.ToString(16) +
+    sLineBreak);
+
+  signer := TSignerUtilities.GetSigner(SigningAlgorithmECSCHNORR);
+
+  Writeln('Signer Name is: ' + signer.AlgorithmName + sLineBreak);
+
+  // sign
+
+  signer.Init(true, privParams);
+
+  &message := TEncoding.UTF8.GetBytes('PascalECSCHNORR');
+
+  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;
+
+end;
+
 class procedure TUsageExamples.GetPublicKeyFromPrivateKey;
 var
   domain: IECDomainParameters;

+ 133 - 259
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -20,39 +20,26 @@ uses
   TestFramework,
   GUITestRunner,
   TextTestRunner,
-  ClpCryptoProObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpCryptoProObjectIdentifiers.pas',
-  ClpECGost3410NamedCurves
-    in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpECGost3410NamedCurves.pas',
-  ClpNistObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\Nist\ClpNistObjectIdentifiers.pas',
-  ClpOiwObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\Oiw\ClpOiwObjectIdentifiers.pas',
-  ClpPkcsObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\Pkcs\ClpPkcsObjectIdentifiers.pas',
-  ClpRosstandartObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\RossStandart\ClpRosstandartObjectIdentifiers.pas',
+  ClpCryptoProObjectIdentifiers in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpCryptoProObjectIdentifiers.pas',
+  ClpECGost3410NamedCurves in '..\..\CryptoLib\src\Asn1\CryptoPro\ClpECGost3410NamedCurves.pas',
+  ClpNistObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Nist\ClpNistObjectIdentifiers.pas',
+  ClpOiwObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Oiw\ClpOiwObjectIdentifiers.pas',
+  ClpPkcsObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Pkcs\ClpPkcsObjectIdentifiers.pas',
+  ClpRosstandartObjectIdentifiers in '..\..\CryptoLib\src\Asn1\RossStandart\ClpRosstandartObjectIdentifiers.pas',
   ClpSecNamedCurves in '..\..\CryptoLib\src\Asn1\Sec\ClpSecNamedCurves.pas',
-  ClpSecObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\Sec\ClpSecObjectIdentifiers.pas',
-  ClpTeleTrusTObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\TeleTrust\ClpTeleTrusTObjectIdentifiers.pas',
-  ClpECNamedCurveTable
-    in '..\..\CryptoLib\src\Asn1\X9\ClpECNamedCurveTable.pas',
+  ClpSecObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Sec\ClpSecObjectIdentifiers.pas',
+  ClpTeleTrusTObjectIdentifiers in '..\..\CryptoLib\src\Asn1\TeleTrust\ClpTeleTrusTObjectIdentifiers.pas',
+  ClpECNamedCurveTable in '..\..\CryptoLib\src\Asn1\X9\ClpECNamedCurveTable.pas',
   ClpX9Curve in '..\..\CryptoLib\src\Asn1\X9\ClpX9Curve.pas',
   ClpX9ECParameters in '..\..\CryptoLib\src\Asn1\X9\ClpX9ECParameters.pas',
-  ClpX9ECParametersHolder
-    in '..\..\CryptoLib\src\Asn1\X9\ClpX9ECParametersHolder.pas',
+  ClpX9ECParametersHolder in '..\..\CryptoLib\src\Asn1\X9\ClpX9ECParametersHolder.pas',
   ClpX9ECPoint in '..\..\CryptoLib\src\Asn1\X9\ClpX9ECPoint.pas',
   ClpX9FieldElement in '..\..\CryptoLib\src\Asn1\X9\ClpX9FieldElement.pas',
   ClpX9FieldID in '..\..\CryptoLib\src\Asn1\X9\ClpX9FieldID.pas',
-  ClpX9IntegerConverter
-    in '..\..\CryptoLib\src\Asn1\X9\ClpX9IntegerConverter.pas',
-  ClpX9ObjectIdentifiers
-    in '..\..\CryptoLib\src\Asn1\X9\ClpX9ObjectIdentifiers.pas',
+  ClpX9IntegerConverter in '..\..\CryptoLib\src\Asn1\X9\ClpX9IntegerConverter.pas',
+  ClpX9ObjectIdentifiers in '..\..\CryptoLib\src\Asn1\X9\ClpX9ObjectIdentifiers.pas',
   ClpAsn1Encodable in '..\..\CryptoLib\src\Asn1\ClpAsn1Encodable.pas',
-  ClpAsn1EncodableVector
-    in '..\..\CryptoLib\src\Asn1\ClpAsn1EncodableVector.pas',
+  ClpAsn1EncodableVector in '..\..\CryptoLib\src\Asn1\ClpAsn1EncodableVector.pas',
   ClpAsn1InputStream in '..\..\CryptoLib\src\Asn1\ClpAsn1InputStream.pas',
   ClpAsn1Null in '..\..\CryptoLib\src\Asn1\ClpAsn1Null.pas',
   ClpAsn1Object in '..\..\CryptoLib\src\Asn1\ClpAsn1Object.pas',
@@ -63,29 +50,22 @@ uses
   ClpAsn1StreamParser in '..\..\CryptoLib\src\Asn1\ClpAsn1StreamParser.pas',
   ClpAsn1TaggedObject in '..\..\CryptoLib\src\Asn1\ClpAsn1TaggedObject.pas',
   ClpAsn1Tags in '..\..\CryptoLib\src\Asn1\ClpAsn1Tags.pas',
-  ClpBerApplicationSpecific
-    in '..\..\CryptoLib\src\Asn1\ClpBerApplicationSpecific.pas',
-  ClpBerApplicationSpecificParser
-    in '..\..\CryptoLib\src\Asn1\ClpBerApplicationSpecificParser.pas',
+  ClpBerApplicationSpecific in '..\..\CryptoLib\src\Asn1\ClpBerApplicationSpecific.pas',
+  ClpBerApplicationSpecificParser in '..\..\CryptoLib\src\Asn1\ClpBerApplicationSpecificParser.pas',
   ClpBerBitString in '..\..\CryptoLib\src\Asn1\ClpBerBitString.pas',
   ClpBerNull in '..\..\CryptoLib\src\Asn1\ClpBerNull.pas',
   ClpBerOctetString in '..\..\CryptoLib\src\Asn1\ClpBerOctetString.pas',
-  ClpBerOctetStringParser
-    in '..\..\CryptoLib\src\Asn1\ClpBerOctetStringParser.pas',
+  ClpBerOctetStringParser in '..\..\CryptoLib\src\Asn1\ClpBerOctetStringParser.pas',
   ClpBerOutputStream in '..\..\CryptoLib\src\Asn1\ClpBerOutputStream.pas',
   ClpBerSequence in '..\..\CryptoLib\src\Asn1\ClpBerSequence.pas',
   ClpBerSequenceParser in '..\..\CryptoLib\src\Asn1\ClpBerSequenceParser.pas',
   ClpBerSet in '..\..\CryptoLib\src\Asn1\ClpBerSet.pas',
   ClpBerSetParser in '..\..\CryptoLib\src\Asn1\ClpBerSetParser.pas',
   ClpBerTaggedObject in '..\..\CryptoLib\src\Asn1\ClpBerTaggedObject.pas',
-  ClpBerTaggedObjectParser
-    in '..\..\CryptoLib\src\Asn1\ClpBerTaggedObjectParser.pas',
-  ClpConstructedOctetStream
-    in '..\..\CryptoLib\src\Asn1\ClpConstructedOctetStream.pas',
-  ClpDefiniteLengthInputStream
-    in '..\..\CryptoLib\src\Asn1\ClpDefiniteLengthInputStream.pas',
-  ClpDerApplicationSpecific
-    in '..\..\CryptoLib\src\Asn1\ClpDerApplicationSpecific.pas',
+  ClpBerTaggedObjectParser in '..\..\CryptoLib\src\Asn1\ClpBerTaggedObjectParser.pas',
+  ClpConstructedOctetStream in '..\..\CryptoLib\src\Asn1\ClpConstructedOctetStream.pas',
+  ClpDefiniteLengthInputStream in '..\..\CryptoLib\src\Asn1\ClpDefiniteLengthInputStream.pas',
+  ClpDerApplicationSpecific in '..\..\CryptoLib\src\Asn1\ClpDerApplicationSpecific.pas',
   ClpDerBitString in '..\..\CryptoLib\src\Asn1\ClpDerBitString.pas',
   ClpDerBmpString in '..\..\CryptoLib\src\Asn1\ClpDerBmpString.pas',
   ClpDerBoolean in '..\..\CryptoLib\src\Asn1\ClpDerBoolean.pas',
@@ -98,11 +78,9 @@ uses
   ClpDerInteger in '..\..\CryptoLib\src\Asn1\ClpDerInteger.pas',
   ClpDerNull in '..\..\CryptoLib\src\Asn1\ClpDerNull.pas',
   ClpDerNumericString in '..\..\CryptoLib\src\Asn1\ClpDerNumericString.pas',
-  ClpDerObjectIdentifier
-    in '..\..\CryptoLib\src\Asn1\ClpDerObjectIdentifier.pas',
+  ClpDerObjectIdentifier in '..\..\CryptoLib\src\Asn1\ClpDerObjectIdentifier.pas',
   ClpDerOctetString in '..\..\CryptoLib\src\Asn1\ClpDerOctetString.pas',
-  ClpDerOctetStringParser
-    in '..\..\CryptoLib\src\Asn1\ClpDerOctetStringParser.pas',
+  ClpDerOctetStringParser in '..\..\CryptoLib\src\Asn1\ClpDerOctetStringParser.pas',
   ClpDerOutputStream in '..\..\CryptoLib\src\Asn1\ClpDerOutputStream.pas',
   ClpDerPrintableString in '..\..\CryptoLib\src\Asn1\ClpDerPrintableString.pas',
   ClpDerSequence in '..\..\CryptoLib\src\Asn1\ClpDerSequence.pas',
@@ -116,211 +94,131 @@ uses
   ClpDerUtf8String in '..\..\CryptoLib\src\Asn1\ClpDerUtf8String.pas',
   ClpDerVideotexString in '..\..\CryptoLib\src\Asn1\ClpDerVideotexString.pas',
   ClpDerVisibleString in '..\..\CryptoLib\src\Asn1\ClpDerVisibleString.pas',
-  ClpIndefiniteLengthInputStream
-    in '..\..\CryptoLib\src\Asn1\ClpIndefiniteLengthInputStream.pas',
+  ClpIndefiniteLengthInputStream in '..\..\CryptoLib\src\Asn1\ClpIndefiniteLengthInputStream.pas',
   ClpLimitedInputStream in '..\..\CryptoLib\src\Asn1\ClpLimitedInputStream.pas',
   ClpOidTokenizer in '..\..\CryptoLib\src\Asn1\ClpOidTokenizer.pas',
-  ClpECKeyPairGenerator
-    in '..\..\CryptoLib\src\Crypto\Generators\ClpECKeyPairGenerator.pas',
-  ClpECDomainParameters
-    in '..\..\CryptoLib\src\Crypto\Parameters\ClpECDomainParameters.pas',
-  ClpECKeyGenerationParameters
-    in '..\..\CryptoLib\src\Crypto\Parameters\ClpECKeyGenerationParameters.pas',
-  ClpECKeyParameters
-    in '..\..\CryptoLib\src\Crypto\Parameters\ClpECKeyParameters.pas',
-  ClpECPrivateKeyParameters
-    in '..\..\CryptoLib\src\Crypto\Parameters\ClpECPrivateKeyParameters.pas',
-  ClpECPublicKeyParameters
-    in '..\..\CryptoLib\src\Crypto\Parameters\ClpECPublicKeyParameters.pas',
-  ClpCryptoApiRandomGenerator
-    in '..\..\CryptoLib\src\Crypto\Prng\ClpCryptoApiRandomGenerator.pas',
-  ClpDigestRandomGenerator
-    in '..\..\CryptoLib\src\Crypto\Prng\ClpDigestRandomGenerator.pas',
-  ClpAsymmetricCipherKeyPair
-    in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
-  ClpAsymmetricKeyParameter
-    in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
-  ClpKeyGenerationParameters
-    in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
-  ClpIAbstractECMultiplier
-    in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
-  ClpIAsn1ApplicationSpecificParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1ApplicationSpecificParser.pas',
+  ClpECKeyPairGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpECKeyPairGenerator.pas',
+  ClpECDomainParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECDomainParameters.pas',
+  ClpECKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECKeyGenerationParameters.pas',
+  ClpECKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECKeyParameters.pas',
+  ClpECPrivateKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECPrivateKeyParameters.pas',
+  ClpECPublicKeyParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpECPublicKeyParameters.pas',
+  ClpCryptoApiRandomGenerator in '..\..\CryptoLib\src\Crypto\Prng\ClpCryptoApiRandomGenerator.pas',
+  ClpDigestRandomGenerator in '..\..\CryptoLib\src\Crypto\Prng\ClpDigestRandomGenerator.pas',
+  ClpAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Crypto\ClpAsymmetricCipherKeyPair.pas',
+  ClpAsymmetricKeyParameter in '..\..\CryptoLib\src\Crypto\ClpAsymmetricKeyParameter.pas',
+  ClpKeyGenerationParameters in '..\..\CryptoLib\src\Crypto\ClpKeyGenerationParameters.pas',
+  ClpIAbstractECMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIAbstractECMultiplier.pas',
+  ClpIAsn1ApplicationSpecificParser in '..\..\CryptoLib\src\Interfaces\ClpIAsn1ApplicationSpecificParser.pas',
   ClpIAsn1Choice in '..\..\CryptoLib\src\Interfaces\ClpIAsn1Choice.pas',
-  ClpIAsn1EncodableVector
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1EncodableVector.pas',
-  ClpIAsn1InputStream
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1InputStream.pas',
+  ClpIAsn1EncodableVector in '..\..\CryptoLib\src\Interfaces\ClpIAsn1EncodableVector.pas',
+  ClpIAsn1InputStream in '..\..\CryptoLib\src\Interfaces\ClpIAsn1InputStream.pas',
   ClpIAsn1Null in '..\..\CryptoLib\src\Interfaces\ClpIAsn1Null.pas',
-  ClpIAsn1OctetString
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1OctetString.pas',
-  ClpIAsn1OctetStringParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1OctetStringParser.pas',
-  ClpIAsn1OutputStream
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1OutputStream.pas',
+  ClpIAsn1OctetString in '..\..\CryptoLib\src\Interfaces\ClpIAsn1OctetString.pas',
+  ClpIAsn1OctetStringParser in '..\..\CryptoLib\src\Interfaces\ClpIAsn1OctetStringParser.pas',
+  ClpIAsn1OutputStream in '..\..\CryptoLib\src\Interfaces\ClpIAsn1OutputStream.pas',
   ClpIAsn1Sequence in '..\..\CryptoLib\src\Interfaces\ClpIAsn1Sequence.pas',
-  ClpIAsn1SequenceParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1SequenceParser.pas',
+  ClpIAsn1SequenceParser in '..\..\CryptoLib\src\Interfaces\ClpIAsn1SequenceParser.pas',
   ClpIAsn1Set in '..\..\CryptoLib\src\Interfaces\ClpIAsn1Set.pas',
   ClpIAsn1SetParser in '..\..\CryptoLib\src\Interfaces\ClpIAsn1SetParser.pas',
-  ClpIAsn1StreamParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1StreamParser.pas',
+  ClpIAsn1StreamParser in '..\..\CryptoLib\src\Interfaces\ClpIAsn1StreamParser.pas',
   ClpIAsn1String in '..\..\CryptoLib\src\Interfaces\ClpIAsn1String.pas',
-  ClpIAsn1TaggedObject
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1TaggedObject.pas',
-  ClpIAsn1TaggedObjectParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsn1TaggedObjectParser.pas',
-  ClpIAsymmetricCipherKeyPair
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
-  ClpIAsymmetricCipherKeyPairGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
-  ClpIAsymmetricKeyParameter
-    in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
-  ClpIBaseInputStream
-    in '..\..\CryptoLib\src\Interfaces\ClpIBaseInputStream.pas',
-  ClpIBerApplicationSpecific
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerApplicationSpecific.pas',
-  ClpIBerApplicationSpecificParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerApplicationSpecificParser.pas',
+  ClpIAsn1TaggedObject in '..\..\CryptoLib\src\Interfaces\ClpIAsn1TaggedObject.pas',
+  ClpIAsn1TaggedObjectParser in '..\..\CryptoLib\src\Interfaces\ClpIAsn1TaggedObjectParser.pas',
+  ClpIAsymmetricCipherKeyPair in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPair.pas',
+  ClpIAsymmetricCipherKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricCipherKeyPairGenerator.pas',
+  ClpIAsymmetricKeyParameter in '..\..\CryptoLib\src\Interfaces\ClpIAsymmetricKeyParameter.pas',
+  ClpIBaseInputStream in '..\..\CryptoLib\src\Interfaces\ClpIBaseInputStream.pas',
+  ClpIBerApplicationSpecific in '..\..\CryptoLib\src\Interfaces\ClpIBerApplicationSpecific.pas',
+  ClpIBerApplicationSpecificParser in '..\..\CryptoLib\src\Interfaces\ClpIBerApplicationSpecificParser.pas',
   ClpIBerBitString in '..\..\CryptoLib\src\Interfaces\ClpIBerBitString.pas',
   ClpIBerNull in '..\..\CryptoLib\src\Interfaces\ClpIBerNull.pas',
   ClpIBerOctetString in '..\..\CryptoLib\src\Interfaces\ClpIBerOctetString.pas',
-  ClpIBerOctetStringParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerOctetStringParser.pas',
-  ClpIBerOutputStream
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerOutputStream.pas',
+  ClpIBerOctetStringParser in '..\..\CryptoLib\src\Interfaces\ClpIBerOctetStringParser.pas',
+  ClpIBerOutputStream in '..\..\CryptoLib\src\Interfaces\ClpIBerOutputStream.pas',
   ClpIBerSequence in '..\..\CryptoLib\src\Interfaces\ClpIBerSequence.pas',
-  ClpIBerSequenceParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerSequenceParser.pas',
+  ClpIBerSequenceParser in '..\..\CryptoLib\src\Interfaces\ClpIBerSequenceParser.pas',
   ClpIBerSet in '..\..\CryptoLib\src\Interfaces\ClpIBerSet.pas',
   ClpIBerSetParser in '..\..\CryptoLib\src\Interfaces\ClpIBerSetParser.pas',
-  ClpIBerTaggedObject
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerTaggedObject.pas',
-  ClpIBerTaggedObjectParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerTaggedObjectParser.pas',
-  ClpICipherParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpICipherParameters.pas',
-  ClpIConstructedOctetStream
-    in '..\..\CryptoLib\src\Interfaces\ClpIConstructedOctetStream.pas',
-  ClpICryptoApiRandomGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpICryptoApiRandomGenerator.pas',
-  ClpIDefiniteLengthInputStream
-    in '..\..\CryptoLib\src\Interfaces\ClpIDefiniteLengthInputStream.pas',
-  ClpIDerApplicationSpecific
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerApplicationSpecific.pas',
+  ClpIBerTaggedObject in '..\..\CryptoLib\src\Interfaces\ClpIBerTaggedObject.pas',
+  ClpIBerTaggedObjectParser in '..\..\CryptoLib\src\Interfaces\ClpIBerTaggedObjectParser.pas',
+  ClpICipherParameters in '..\..\CryptoLib\src\Interfaces\ClpICipherParameters.pas',
+  ClpIConstructedOctetStream in '..\..\CryptoLib\src\Interfaces\ClpIConstructedOctetStream.pas',
+  ClpICryptoApiRandomGenerator in '..\..\CryptoLib\src\Interfaces\ClpICryptoApiRandomGenerator.pas',
+  ClpIDefiniteLengthInputStream in '..\..\CryptoLib\src\Interfaces\ClpIDefiniteLengthInputStream.pas',
+  ClpIDerApplicationSpecific in '..\..\CryptoLib\src\Interfaces\ClpIDerApplicationSpecific.pas',
   ClpIDerBitString in '..\..\CryptoLib\src\Interfaces\ClpIDerBitString.pas',
   ClpIDerBmpString in '..\..\CryptoLib\src\Interfaces\ClpIDerBmpString.pas',
   ClpIDerBoolean in '..\..\CryptoLib\src\Interfaces\ClpIDerBoolean.pas',
   ClpIDerEnumerated in '..\..\CryptoLib\src\Interfaces\ClpIDerEnumerated.pas',
   ClpIDerExternal in '..\..\CryptoLib\src\Interfaces\ClpIDerExternal.pas',
-  ClpIDerExternalParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerExternalParser.pas',
-  ClpIDerGeneralString
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerGeneralString.pas',
-  ClpIDerGraphicString
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerGraphicString.pas',
+  ClpIDerExternalParser in '..\..\CryptoLib\src\Interfaces\ClpIDerExternalParser.pas',
+  ClpIDerGeneralString in '..\..\CryptoLib\src\Interfaces\ClpIDerGeneralString.pas',
+  ClpIDerGraphicString in '..\..\CryptoLib\src\Interfaces\ClpIDerGraphicString.pas',
   ClpIDerIA5String in '..\..\CryptoLib\src\Interfaces\ClpIDerIA5String.pas',
   ClpIDerInteger in '..\..\CryptoLib\src\Interfaces\ClpIDerInteger.pas',
   ClpIDerNull in '..\..\CryptoLib\src\Interfaces\ClpIDerNull.pas',
-  ClpIDerNumericString
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerNumericString.pas',
-  ClpIDerObjectIdentifier
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerObjectIdentifier.pas',
+  ClpIDerNumericString in '..\..\CryptoLib\src\Interfaces\ClpIDerNumericString.pas',
+  ClpIDerObjectIdentifier in '..\..\CryptoLib\src\Interfaces\ClpIDerObjectIdentifier.pas',
   ClpIDerOctetString in '..\..\CryptoLib\src\Interfaces\ClpIDerOctetString.pas',
-  ClpIDerOctetStringParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerOctetStringParser.pas',
-  ClpIDerPrintableString
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerPrintableString.pas',
+  ClpIDerOctetStringParser in '..\..\CryptoLib\src\Interfaces\ClpIDerOctetStringParser.pas',
+  ClpIDerPrintableString in '..\..\CryptoLib\src\Interfaces\ClpIDerPrintableString.pas',
   ClpIDerSequence in '..\..\CryptoLib\src\Interfaces\ClpIDerSequence.pas',
-  ClpIDerSequenceParser
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerSequenceParser.pas',
+  ClpIDerSequenceParser in '..\..\CryptoLib\src\Interfaces\ClpIDerSequenceParser.pas',
   ClpIDerSet in '..\..\CryptoLib\src\Interfaces\ClpIDerSet.pas',
   ClpIDerSetParser in '..\..\CryptoLib\src\Interfaces\ClpIDerSetParser.pas',
   ClpIDerStringBase in '..\..\CryptoLib\src\Interfaces\ClpIDerStringBase.pas',
   ClpIDerT61String in '..\..\CryptoLib\src\Interfaces\ClpIDerT61String.pas',
-  ClpIDerTaggedObject
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerTaggedObject.pas',
-  ClpIDerUniversalString
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerUniversalString.pas',
+  ClpIDerTaggedObject in '..\..\CryptoLib\src\Interfaces\ClpIDerTaggedObject.pas',
+  ClpIDerUniversalString in '..\..\CryptoLib\src\Interfaces\ClpIDerUniversalString.pas',
   ClpIDerUtf8String in '..\..\CryptoLib\src\Interfaces\ClpIDerUtf8String.pas',
-  ClpIDerVideotexString
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerVideotexString.pas',
-  ClpIDerVisibleString
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerVisibleString.pas',
-  ClpIDigestRandomGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIDigestRandomGenerator.pas',
-  ClpIECDomainParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpIECDomainParameters.pas',
+  ClpIDerVideotexString in '..\..\CryptoLib\src\Interfaces\ClpIDerVideotexString.pas',
+  ClpIDerVisibleString in '..\..\CryptoLib\src\Interfaces\ClpIDerVisibleString.pas',
+  ClpIDigestRandomGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDigestRandomGenerator.pas',
+  ClpIECDomainParameters in '..\..\CryptoLib\src\Interfaces\ClpIECDomainParameters.pas',
   ClpIECFieldElement in '..\..\CryptoLib\src\Interfaces\ClpIECFieldElement.pas',
   ClpIECInterface in '..\..\CryptoLib\src\Interfaces\ClpIECInterface.pas',
-  ClpIECKeyGenerationParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpIECKeyGenerationParameters.pas',
-  ClpIECKeyPairGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIECKeyPairGenerator.pas',
-  ClpIECKeyParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpIECKeyParameters.pas',
-  ClpIECPrivateKeyParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpIECPrivateKeyParameters.pas',
-  ClpIECPublicKeyParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
+  ClpIECKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIECKeyGenerationParameters.pas',
+  ClpIECKeyPairGenerator in '..\..\CryptoLib\src\Interfaces\ClpIECKeyPairGenerator.pas',
+  ClpIECKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECKeyParameters.pas',
+  ClpIECPrivateKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPrivateKeyParameters.pas',
+  ClpIECPublicKeyParameters in '..\..\CryptoLib\src\Interfaces\ClpIECPublicKeyParameters.pas',
   ClpIExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIExtensionField.pas',
   ClpIFilterStream in '..\..\CryptoLib\src\Interfaces\ClpIFilterStream.pas',
   ClpIFiniteField in '..\..\CryptoLib\src\Interfaces\ClpIFiniteField.pas',
-  ClpIFixedPointCombMultiplier
-    in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
-  ClpIFixedPointPreCompInfo
-    in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
-  ClpIGlvEndomorphism
-    in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
-  ClpIGlvTypeBEndomorphism
-    in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
-  ClpIGlvTypeBParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBParameters.pas',
-  ClpIIndefiniteLengthInputStream
-    in '..\..\CryptoLib\src\Interfaces\ClpIIndefiniteLengthInputStream.pas',
-  ClpIKeyGenerationParameters
-    in '..\..\CryptoLib\src\Interfaces\ClpIKeyGenerationParameters.pas',
-  ClpILimitedInputStream
-    in '..\..\CryptoLib\src\Interfaces\ClpILimitedInputStream.pas',
+  ClpIFixedPointCombMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointCombMultiplier.pas',
+  ClpIFixedPointPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIFixedPointPreCompInfo.pas',
+  ClpIGlvEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvEndomorphism.pas',
+  ClpIGlvTypeBEndomorphism in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBEndomorphism.pas',
+  ClpIGlvTypeBParameters in '..\..\CryptoLib\src\Interfaces\ClpIGlvTypeBParameters.pas',
+  ClpIIndefiniteLengthInputStream in '..\..\CryptoLib\src\Interfaces\ClpIIndefiniteLengthInputStream.pas',
+  ClpIKeyGenerationParameters in '..\..\CryptoLib\src\Interfaces\ClpIKeyGenerationParameters.pas',
+  ClpILimitedInputStream in '..\..\CryptoLib\src\Interfaces\ClpILimitedInputStream.pas',
   ClpIOidTokenizer in '..\..\CryptoLib\src\Interfaces\ClpIOidTokenizer.pas',
-  ClpIPCGRandomNumberGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIPCGRandomNumberGenerator.pas',
+  ClpIPCGRandomNumberGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPCGRandomNumberGenerator.pas',
   ClpIPolynomial in '..\..\CryptoLib\src\Interfaces\ClpIPolynomial.pas',
-  ClpIPolynomialExtensionField
-    in '..\..\CryptoLib\src\Interfaces\ClpIPolynomialExtensionField.pas',
+  ClpIPolynomialExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIPolynomialExtensionField.pas',
   ClpIPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIPreCompInfo.pas',
-  ClpIProxiedInterface
-    in '..\..\CryptoLib\src\Interfaces\ClpIProxiedInterface.pas',
+  ClpIProxiedInterface in '..\..\CryptoLib\src\Interfaces\ClpIProxiedInterface.pas',
   ClpIRandom in '..\..\CryptoLib\src\Interfaces\ClpIRandom.pas',
-  ClpIRandomGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIRandomGenerator.pas',
-  ClpIRandomNumberGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIRandomNumberGenerator.pas',
+  ClpIRandomGenerator in '..\..\CryptoLib\src\Interfaces\ClpIRandomGenerator.pas',
+  ClpIRandomNumberGenerator in '..\..\CryptoLib\src\Interfaces\ClpIRandomNumberGenerator.pas',
   ClpIScaleXPointMap in '..\..\CryptoLib\src\Interfaces\ClpIScaleXPointMap.pas',
   ClpISecureRandom in '..\..\CryptoLib\src\Interfaces\ClpISecureRandom.pas',
-  ClpIWNafPreCompInfo
-    in '..\..\CryptoLib\src\Interfaces\ClpIWNafPreCompInfo.pas',
+  ClpIWNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWNafPreCompInfo.pas',
   ClpIX9Curve in '..\..\CryptoLib\src\Interfaces\ClpIX9Curve.pas',
   ClpIX9ECParameters in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParameters.pas',
-  ClpIX9ECParametersHolder
-    in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
+  ClpIX9ECParametersHolder in '..\..\CryptoLib\src\Interfaces\ClpIX9ECParametersHolder.pas',
   ClpIX9ECPoint in '..\..\CryptoLib\src\Interfaces\ClpIX9ECPoint.pas',
   ClpIX9FieldElement in '..\..\CryptoLib\src\Interfaces\ClpIX9FieldElement.pas',
   ClpIX9FieldID in '..\..\CryptoLib\src\Interfaces\ClpIX9FieldID.pas',
-  ClpGlvTypeBEndomorphism
-    in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
-  ClpGlvTypeBParameters
-    in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.pas',
-  ClpAbstractECMultiplier
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
-  ClpFixedPointCombMultiplier
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
-  ClpFixedPointPreCompInfo
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
-  ClpFixedPointUtilities
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
-  ClpWNafPreCompInfo
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
+  ClpGlvTypeBEndomorphism in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBEndomorphism.pas',
+  ClpGlvTypeBParameters in '..\..\CryptoLib\src\Math\EC\Endo\ClpGlvTypeBParameters.pas',
+  ClpAbstractECMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpAbstractECMultiplier.pas',
+  ClpFixedPointCombMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointCombMultiplier.pas',
+  ClpFixedPointPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointPreCompInfo.pas',
+  ClpFixedPointUtilities in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpFixedPointUtilities.pas',
+  ClpWNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafPreCompInfo.pas',
   ClpECAlgorithms in '..\..\CryptoLib\src\Math\EC\ClpECAlgorithms.pas',
   ClpECCurve in '..\..\CryptoLib\src\Math\EC\ClpECCurve.pas',
   ClpECFieldElement in '..\..\CryptoLib\src\Math\EC\ClpECFieldElement.pas',
@@ -331,8 +229,7 @@ uses
   ClpDigestUtilities in '..\..\CryptoLib\src\Security\ClpDigestUtilities.pas',
   ClpRandom in '..\..\CryptoLib\src\Security\ClpRandom.pas',
   ClpSecureRandom in '..\..\CryptoLib\src\Security\ClpSecureRandom.pas',
-  ClpCollectionUtilities
-    in '..\..\CryptoLib\src\Utils\Collections\ClpCollectionUtilities.pas',
+  ClpCollectionUtilities in '..\..\CryptoLib\src\Utils\Collections\ClpCollectionUtilities.pas',
   ClpBase64 in '..\..\CryptoLib\src\Utils\Encoders\ClpBase64.pas',
   ClpHex in '..\..\CryptoLib\src\Utils\Encoders\ClpHex.pas',
   ClpStreamHelper in '..\..\CryptoLib\src\Utils\Helpers\ClpStreamHelper.pas',
@@ -340,12 +237,9 @@ uses
   ClpBaseInputStream in '..\..\CryptoLib\src\Utils\IO\ClpBaseInputStream.pas',
   ClpFilterStream in '..\..\CryptoLib\src\Utils\IO\ClpFilterStream.pas',
   ClpStreams in '..\..\CryptoLib\src\Utils\IO\ClpStreams.pas',
-  ClpPcgRandomMinimal
-    in '..\..\CryptoLib\src\Utils\Randoms\ClpPcgRandomMinimal.pas',
-  ClpPCGRandomNumberGenerator
-    in '..\..\CryptoLib\src\Utils\Rng\ClpPCGRandomNumberGenerator.pas',
-  ClpRandomNumberGenerator
-    in '..\..\CryptoLib\src\Utils\Rng\ClpRandomNumberGenerator.pas',
+  ClpPcgRandomMinimal in '..\..\CryptoLib\src\Utils\Randoms\ClpPcgRandomMinimal.pas',
+  ClpPCGRandomNumberGenerator in '..\..\CryptoLib\src\Utils\Rng\ClpPCGRandomNumberGenerator.pas',
+  ClpRandomNumberGenerator in '..\..\CryptoLib\src\Utils\Rng\ClpRandomNumberGenerator.pas',
   ClpArrayUtils in '..\..\CryptoLib\src\Utils\ClpArrayUtils.pas',
   ClpBitConverter in '..\..\CryptoLib\src\Utils\ClpBitConverter.pas',
   ClpBits in '..\..\CryptoLib\src\Utils\ClpBits.pas',
@@ -353,57 +247,40 @@ uses
   ClpCryptoLibTypes in '..\..\CryptoLib\src\Utils\ClpCryptoLibTypes.pas',
   ClpTimes in '..\..\CryptoLib\src\Utils\ClpTimes.pas',
   OIDTests in '..\src\Asn1\OIDTests.pas',
-  ClpWNafUtilities
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafUtilities.pas',
+  ClpWNafUtilities in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafUtilities.pas',
   SecureRandomTests in '..\src\Security\SecureRandomTests.pas',
   ClpBigIntegers in '..\..\CryptoLib\src\Utils\ClpBigIntegers.pas',
   ClpMod in '..\..\CryptoLib\src\Math\Raw\ClpMod.pas',
   ClpNat in '..\..\CryptoLib\src\Math\Raw\ClpNat.pas',
   ClpNumberStyles in '..\..\CryptoLib\src\Math\ClpNumberStyles.pas',
-  ClpParametersWithRandom
-    in '..\..\CryptoLib\src\Crypto\Parameters\ClpParametersWithRandom.pas',
-  ClpIParametersWithRandom
-    in '..\..\CryptoLib\src\Interfaces\ClpIParametersWithRandom.pas',
+  ClpParametersWithRandom in '..\..\CryptoLib\src\Crypto\Parameters\ClpParametersWithRandom.pas',
+  ClpIParametersWithRandom in '..\..\CryptoLib\src\Interfaces\ClpIParametersWithRandom.pas',
   ClpIDsa in '..\..\CryptoLib\src\Interfaces\ClpIDsa.pas',
   ClpIDsaKCalculator in '..\..\CryptoLib\src\Interfaces\ClpIDsaKCalculator.pas',
   ClpISigner in '..\..\CryptoLib\src\Interfaces\ClpISigner.pas',
-  ClpRandomDsaKCalculator
-    in '..\..\CryptoLib\src\Crypto\Signers\ClpRandomDsaKCalculator.pas',
-  ClpIRandomDsaKCalculator
-    in '..\..\CryptoLib\src\Interfaces\ClpIRandomDsaKCalculator.pas',
+  ClpRandomDsaKCalculator in '..\..\CryptoLib\src\Crypto\Signers\ClpRandomDsaKCalculator.pas',
+  ClpIRandomDsaKCalculator in '..\..\CryptoLib\src\Interfaces\ClpIRandomDsaKCalculator.pas',
   ClpECDsaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECDsaSigner.pas',
   ClpIECDsaSigner in '..\..\CryptoLib\src\Interfaces\ClpIECDsaSigner.pas',
-  ClpDsaDigestSigner
-    in '..\..\CryptoLib\src\Crypto\Signers\ClpDsaDigestSigner.pas',
-  ClpIDsaDigestSigner
-    in '..\..\CryptoLib\src\Interfaces\ClpIDsaDigestSigner.pas',
+  ClpDsaDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpDsaDigestSigner.pas',
+  ClpIDsaDigestSigner in '..\..\CryptoLib\src\Interfaces\ClpIDsaDigestSigner.pas',
   ClpSignerUtilities in '..\..\CryptoLib\src\Security\ClpSignerUtilities.pas',
   ClpZTauElement in '..\..\CryptoLib\src\Math\EC\Abc\ClpZTauElement.pas',
   ClpIZTauElement in '..\..\CryptoLib\src\Interfaces\ClpIZTauElement.pas',
-  ClpSimpleBigDecimal
-    in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
+  ClpSimpleBigDecimal in '..\..\CryptoLib\src\Math\EC\Abc\ClpSimpleBigDecimal.pas',
   ClpTnaf in '..\..\CryptoLib\src\Math\EC\Abc\ClpTnaf.pas',
-  ClpGlvMultiplier
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpGlvMultiplier.pas',
+  ClpGlvMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpGlvMultiplier.pas',
   ClpIGlvMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIGlvMultiplier.pas',
-  ClpWTauNafMultiplier
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafMultiplier.pas',
-  ClpIWTauNafMultiplier
-    in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafMultiplier.pas',
-  ClpWTauNafPreCompInfo
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
-  ClpIWTauNafPreCompInfo
-    in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.pas',
-  ClpWNafL2RMultiplier
-    in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas',
-  ClpIWNafL2RMultiplier
-    in '..\..\CryptoLib\src\Interfaces\ClpIWNafL2RMultiplier.pas',
+  ClpWTauNafMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafMultiplier.pas',
+  ClpIWTauNafMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafMultiplier.pas',
+  ClpWTauNafPreCompInfo in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWTauNafPreCompInfo.pas',
+  ClpIWTauNafPreCompInfo in '..\..\CryptoLib\src\Interfaces\ClpIWTauNafPreCompInfo.pas',
+  ClpWNafL2RMultiplier in '..\..\CryptoLib\src\Math\EC\Multiplier\ClpWNafL2RMultiplier.pas',
+  ClpIWNafL2RMultiplier in '..\..\CryptoLib\src\Interfaces\ClpIWNafL2RMultiplier.pas',
   ClpGF2Polynomial in '..\..\CryptoLib\src\Math\Field\ClpGF2Polynomial.pas',
   ClpIGF2Polynomial in '..\..\CryptoLib\src\Interfaces\ClpIGF2Polynomial.pas',
-  ClpGenericPolynomialExtensionField
-    in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
-  ClpIGenericPolynomialExtensionField
-    in '..\..\CryptoLib\src\Interfaces\ClpIGenericPolynomialExtensionField.pas',
+  ClpGenericPolynomialExtensionField in '..\..\CryptoLib\src\Math\Field\ClpGenericPolynomialExtensionField.pas',
+  ClpIGenericPolynomialExtensionField in '..\..\CryptoLib\src\Interfaces\ClpIGenericPolynomialExtensionField.pas',
   ClpPrimeField in '..\..\CryptoLib\src\Math\Field\ClpPrimeField.pas',
   ClpIPrimeField in '..\..\CryptoLib\src\Interfaces\ClpIPrimeField.pas',
   ClpFiniteFields in '..\..\CryptoLib\src\Math\Field\ClpFiniteFields.pas',
@@ -411,10 +288,8 @@ uses
   BigIntegerTests in '..\src\Math\BigIntegerTests.pas',
   ECAlgorithmsTests in '..\src\Math\ECAlgorithmsTests.pas',
   ECPointTests in '..\src\Math\ECPointTests.pas',
-  ClpOSRandomNumberGenerator
-    in '..\..\CryptoLib\src\Utils\Rng\ClpOSRandomNumberGenerator.pas',
-  ClpIOSRandomNumberGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIOSRandomNumberGenerator.pas',
+  ClpOSRandomNumberGenerator in '..\..\CryptoLib\src\Utils\Rng\ClpOSRandomNumberGenerator.pas',
+  ClpIOSRandomNumberGenerator in '..\..\CryptoLib\src\Interfaces\ClpIOSRandomNumberGenerator.pas',
   ClpOSRandom in '..\..\CryptoLib\src\Utils\Randoms\ClpOSRandom.pas',
   ClpFixedSecureRandom in '..\src\Utils\ClpFixedSecureRandom.pas',
   ClpIFixedSecureRandom in '..\src\Utils\ClpIFixedSecureRandom.pas',
@@ -429,18 +304,17 @@ uses
   ClpIAsn1Generator in '..\..\CryptoLib\src\Interfaces\ClpIAsn1Generator.pas',
   ClpDerGenerator in '..\..\CryptoLib\src\Asn1\ClpDerGenerator.pas',
   ClpIDerGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDerGenerator.pas',
-  ClpDerSequenceGenerator
-    in '..\..\CryptoLib\src\Asn1\ClpDerSequenceGenerator.pas',
-  ClpIDerSequenceGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIDerSequenceGenerator.pas',
+  ClpDerSequenceGenerator in '..\..\CryptoLib\src\Asn1\ClpDerSequenceGenerator.pas',
+  ClpIDerSequenceGenerator in '..\..\CryptoLib\src\Interfaces\ClpIDerSequenceGenerator.pas',
   Asn1SequenceParserTests in '..\src\Asn1\Asn1SequenceParserTests.pas',
   ClpBerGenerator in '..\..\CryptoLib\src\Asn1\ClpBerGenerator.pas',
   ClpIBerGenerator in '..\..\CryptoLib\src\Interfaces\ClpIBerGenerator.pas',
-  ClpIBerSequenceGenerator
-    in '..\..\CryptoLib\src\Interfaces\ClpIBerSequenceGenerator.pas',
-  ClpBerSequenceGenerator
-    in '..\..\CryptoLib\src\Asn1\ClpBerSequenceGenerator.pas',
-  ClpSetWeakRef in '..\..\CryptoLib\src\Utils\ClpSetWeakRef.pas';
+  ClpIBerSequenceGenerator in '..\..\CryptoLib\src\Interfaces\ClpIBerSequenceGenerator.pas',
+  ClpBerSequenceGenerator in '..\..\CryptoLib\src\Asn1\ClpBerSequenceGenerator.pas',
+  ClpSetWeakRef in '..\..\CryptoLib\src\Utils\ClpSetWeakRef.pas',
+  ClpECSchnorrSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrSigner.pas',
+  ClpIECSchnorrSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrSigner.pas',
+  ECSchnorrTests in '..\src\Others\ECSchnorrTests.pas';
 
 begin
 

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

@@ -35,7 +35,7 @@
         <PackageName Value="FCL"/>
       </Item4>
     </RequiredPackages>
-    <Units Count="16">
+    <Units Count="17">
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -101,6 +101,10 @@
         <Filename Value="..\src\Utils\ClpIFixedSecureRandom.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit15>
+      <Unit16>
+        <Filename Value="..\src\Others\ECSchnorrTests.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit16>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

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

@@ -17,6 +17,7 @@ uses
   ECDsa5Tests,
   ECTests,
   NamedCurveTests,
+  ECSchnorrTests,
   SignerUtilitiesTests,
   SecureRandomTests,
   ClpFixedSecureRandom,

+ 21 - 17
CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi

@@ -29,71 +29,75 @@
         <PackageName Value="FCL"/>
       </Item2>
     </RequiredPackages>
-    <Units Count="16">
+    <Units Count="17">
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
       </Unit0>
       <Unit1>
-        <Filename Value="..\src\Asn1\Asn1SequenceParserTests.pas"/>
+        <Filename Value="..\src\Others\ECSchnorrTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit1>
       <Unit2>
-        <Filename Value="..\src\Asn1\DerApplicationSpecificTests.pas"/>
+        <Filename Value="..\src\Asn1\Asn1SequenceParserTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit2>
       <Unit3>
-        <Filename Value="..\src\Asn1\EqualsAndHashCodeTests.pas"/>
+        <Filename Value="..\src\Asn1\DerApplicationSpecificTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit3>
       <Unit4>
-        <Filename Value="..\src\Asn1\OIDTests.pas"/>
+        <Filename Value="..\src\Asn1\EqualsAndHashCodeTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit4>
       <Unit5>
-        <Filename Value="..\src\Math\EC\Custom\Sec\SecP384R1FieldTests.pas"/>
+        <Filename Value="..\src\Asn1\OIDTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit5>
       <Unit6>
-        <Filename Value="..\src\Math\BigIntegerTests.pas"/>
+        <Filename Value="..\src\Math\EC\Custom\Sec\SecP384R1FieldTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit6>
       <Unit7>
-        <Filename Value="..\src\Math\ECAlgorithmsTests.pas"/>
+        <Filename Value="..\src\Math\BigIntegerTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit7>
       <Unit8>
-        <Filename Value="..\src\Math\ECPointTests.pas"/>
+        <Filename Value="..\src\Math\ECAlgorithmsTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit8>
       <Unit9>
-        <Filename Value="..\src\Others\ECDsa5Tests.pas"/>
+        <Filename Value="..\src\Math\ECPointTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit9>
       <Unit10>
-        <Filename Value="..\src\Others\ECTests.pas"/>
+        <Filename Value="..\src\Others\ECDsa5Tests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit10>
       <Unit11>
-        <Filename Value="..\src\Others\NamedCurveTests.pas"/>
+        <Filename Value="..\src\Others\ECTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit11>
       <Unit12>
-        <Filename Value="..\src\Others\SignerUtilitiesTests.pas"/>
+        <Filename Value="..\src\Others\NamedCurveTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit12>
       <Unit13>
-        <Filename Value="..\src\Security\SecureRandomTests.pas"/>
+        <Filename Value="..\src\Others\SignerUtilitiesTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit13>
       <Unit14>
-        <Filename Value="..\src\Utils\ClpFixedSecureRandom.pas"/>
+        <Filename Value="..\src\Security\SecureRandomTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit14>
       <Unit15>
-        <Filename Value="..\src\Utils\ClpIFixedSecureRandom.pas"/>
+        <Filename Value="..\src\Utils\ClpFixedSecureRandom.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit15>
+      <Unit16>
+        <Filename Value="..\src\Utils\ClpIFixedSecureRandom.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit16>
     </Units>
   </ProjectOptions>
   <CompilerOptions>
@@ -104,7 +108,7 @@
     </Target>
     <SearchPaths>
       <IncludeFiles Value="$(ProjOutDir)"/>
-      <OtherUnitFiles Value="..\src\Asn1;..\src\Math\EC\Custom\Sec;..\src\Math;..\src\Others;..\src\Security;..\src\Utils"/>
+      <OtherUnitFiles Value="..\src\Others;..\src\Asn1;..\src\Math\EC\Custom\Sec;..\src\Math;..\src\Security;..\src\Utils"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
   </CompilerOptions>

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

@@ -15,6 +15,7 @@ uses
   ECDsa5Tests,
   ECTests,
   NamedCurveTests,
+  ECSchnorrTests,
   SignerUtilitiesTests,
   SecureRandomTests,
   ClpFixedSecureRandom,

+ 375 - 0
CryptoLib.Tests/src/Others/ECSchnorrTests.pas

@@ -0,0 +1,375 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                    Copyright (c) 2018 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://sphere10.com) for sponsoring        * }
+{ *                        the development of this library                          * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ECSchnorrTests;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  Classes,
+  SysUtils,
+{$IFDEF FPC}
+  fpcunit,
+  testregistry,
+{$ELSE}
+  TestFramework,
+{$ENDIF FPC}
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpECSchnorrSigner,
+  ClpIECSchnorrSigner,
+  ClpISigner,
+  ClpECPublicKeyParameters,
+  ClpIECPublicKeyParameters,
+  ClpECPrivateKeyParameters,
+  ClpIECPrivateKeyParameters,
+  ClpECDomainParameters,
+  ClpIECDomainParameters,
+  ClpIECKeyPairGenerator,
+  ClpECKeyPairGenerator,
+  ClpIECKeyGenerationParameters,
+  ClpECKeyGenerationParameters,
+  ClpIAsymmetricCipherKeyPair,
+  ClpIX9ECParameters,
+  ClpIECInterface,
+  ClpSecNamedCurves,
+  ClpCryptoLibTypes,
+  ClpBigInteger,
+  ClpSignerUtilities,
+  ClpBigIntegers;
+
+type
+
+  TCryptoLibTestCase = class abstract(TTestCase)
+
+  end;
+
+type
+
+  /// <summary>
+  /// ECSchnorr tests.
+  /// </summary>
+  TTestECSchnorr = class(TCryptoLibTestCase)
+  private
+
+  var
+    FRandom: ISecureRandom;
+
+  protected
+    procedure SetUp; override;
+    procedure TearDown; override;
+  published
+
+    procedure TestECSchnorrWithCustomK;
+    procedure TestECSchnorrBSI;
+    procedure TestECSchnorrISO;
+    procedure TestECSchnorrISOx;
+    procedure TestECSchnorrLIBSECP;
+
+  end;
+
+implementation
+
+{ TTestECSchnorr }
+
+procedure TTestECSchnorr.SetUp;
+begin
+  inherited;
+  FRandom := TSecureRandom.Create();
+end;
+
+procedure TTestECSchnorr.TearDown;
+begin
+  inherited;
+
+end;
+
+procedure TTestECSchnorr.TestECSchnorrBSI;
+var
+  LCurve: IX9ECParameters;
+  domain: IECDomainParameters;
+  generator: IECKeyPairGenerator;
+  keygenParams: IECKeyGenerationParameters;
+  keypair: IAsymmetricCipherKeyPair;
+  privParams: IECPrivateKeyParameters;
+  pubParams: IECPublicKeyParameters;
+  signer: ISigner;
+  &message, sigBytes: TBytes;
+
+begin
+
+  LCurve := TSecNamedCurves.GetByName('secp256k1');
+
+  domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
+    LCurve.H, LCurve.GetSeed);
+  generator := TECKeyPairGenerator.Create('ECSCHNORR');
+  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
+
+  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRBSI');
+
+  // sign
+
+  signer.Init(true, privParams);
+
+  &message := TEncoding.UTF8.GetBytes('PascalECSCHNORR');
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  sigBytes := signer.GenerateSignature();
+
+  // verify
+
+  signer.Init(false, pubParams);
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  CheckTrue(signer.VerifySignature(sigBytes));
+
+end;
+
+procedure TTestECSchnorr.TestECSchnorrISO;
+var
+  LCurve: IX9ECParameters;
+  domain: IECDomainParameters;
+  generator: IECKeyPairGenerator;
+  keygenParams: IECKeyGenerationParameters;
+  keypair: IAsymmetricCipherKeyPair;
+  privParams: IECPrivateKeyParameters;
+  pubParams: IECPublicKeyParameters;
+  signer: ISigner;
+  &message, sigBytes: TBytes;
+
+begin
+
+  LCurve := TSecNamedCurves.GetByName('secp256k1');
+
+  domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
+    LCurve.H, LCurve.GetSeed);
+  generator := TECKeyPairGenerator.Create('ECSCHNORR');
+  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
+
+  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRISO');
+
+  // sign
+
+  signer.Init(true, privParams);
+
+  &message := TEncoding.UTF8.GetBytes('PascalECSCHNORR');
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  sigBytes := signer.GenerateSignature();
+
+  // verify
+
+  signer.Init(false, pubParams);
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  CheckTrue(signer.VerifySignature(sigBytes));
+
+end;
+
+procedure TTestECSchnorr.TestECSchnorrISOx;
+var
+  LCurve: IX9ECParameters;
+  domain: IECDomainParameters;
+  generator: IECKeyPairGenerator;
+  keygenParams: IECKeyGenerationParameters;
+  keypair: IAsymmetricCipherKeyPair;
+  privParams: IECPrivateKeyParameters;
+  pubParams: IECPublicKeyParameters;
+  signer: ISigner;
+  &message, sigBytes: TBytes;
+
+begin
+
+  LCurve := TSecNamedCurves.GetByName('secp256k1');
+
+  domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
+    LCurve.H, LCurve.GetSeed);
+  generator := TECKeyPairGenerator.Create('ECSCHNORR');
+  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
+
+  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRISOx');
+
+  // sign
+
+  signer.Init(true, privParams);
+
+  &message := TEncoding.UTF8.GetBytes('PascalECSCHNORR');
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  sigBytes := signer.GenerateSignature();
+
+  // verify
+
+  signer.Init(false, pubParams);
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  CheckTrue(signer.VerifySignature(sigBytes));
+
+end;
+
+procedure TTestECSchnorr.TestECSchnorrLIBSECP;
+var
+  LCurve: IX9ECParameters;
+  domain: IECDomainParameters;
+  generator: IECKeyPairGenerator;
+  keygenParams: IECKeyGenerationParameters;
+  keypair: IAsymmetricCipherKeyPair;
+  privParams: IECPrivateKeyParameters;
+  pubParams: IECPublicKeyParameters;
+  signer: ISigner;
+  &message, sigBytes: TBytes;
+
+begin
+
+  LCurve := TSecNamedCurves.GetByName('secp256k1');
+
+  domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
+    LCurve.H, LCurve.GetSeed);
+  generator := TECKeyPairGenerator.Create('ECSCHNORR');
+  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
+
+  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRLIBSECP');
+
+  // sign
+
+  signer.Init(true, privParams);
+
+  &message := TEncoding.UTF8.GetBytes('PascalECSCHNORR');
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  sigBytes := signer.GenerateSignature();
+
+  // verify
+
+  signer.Init(false, pubParams);
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  CheckTrue(signer.VerifySignature(sigBytes));
+
+end;
+
+procedure TTestECSchnorr.TestECSchnorrWithCustomK;
+var
+  domain: IECDomainParameters;
+  RegeneratedPrivateKey: IECPrivateKeyParameters;
+  RegeneratedPublicKey: IECPublicKeyParameters;
+  BigXCoordByteArray, BigYCoordByteArray, PrivateKeyByteArray, &message,
+    sigBytes: TBytes;
+  point: IECPoint;
+  LCurve: IX9ECParameters;
+  signer: ISigner;
+  k: TBigInteger;
+begin
+
+  LCurve := TSecNamedCurves.GetByName('secp256k1');
+
+  domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
+    LCurve.H, LCurve.GetSeed);
+
+  BigXCoordByteArray := TBigInteger.Create
+    ('65d5b8bf9ab1801c9f168d4815994ad35f1dcb6ae6c7a1a303966b677b813b00', 16)
+    .ToByteArray;
+
+  BigYCoordByteArray := TBigInteger.Create
+    ('e6b865e529b8ecbf71cf966e900477d49ced5846d7662dd2dd11ccd55c0aff7f', 16)
+    .ToByteArray;
+
+  PrivateKeyByteArray := TBigInteger.Create
+    ('fb26a4e75eec75544c0f44e937dcf5ee6355c7176600b9688c667e5c283b43c5', 16)
+    .ToByteArray;
+
+  point := LCurve.Curve.CreatePoint(TBigInteger.Create(1, BigXCoordByteArray),
+    TBigInteger.Create(1, BigYCoordByteArray));
+
+  RegeneratedPublicKey := TECPublicKeyParameters.Create('ECSCHNORR',
+    point, domain);
+
+  RegeneratedPrivateKey := TECPrivateKeyParameters.Create('ECSCHNORR',
+    TBigInteger.Create(PrivateKeyByteArray), domain);
+
+  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRLIBSECP');
+
+  // sign
+
+  signer.Init(true, RegeneratedPrivateKey);
+
+  &message := TBigInteger.Create
+    ('0101010101010101010101010101010101010101010101010101010101010101', 16)
+    .ToByteArray;
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  k := TBigInteger.Create
+    ('4242424242424242424242424242424242424242424242424242424242424242', 16);
+
+  // cast ISigner instance to be able to access specific method for test purposees.
+  // do not do this.
+  sigBytes := (signer as IECSchnorrSigner).Sign_K(RegeneratedPrivateKey, k);
+
+  // verify
+
+  signer.Init(false, RegeneratedPublicKey);
+
+  signer.BlockUpdate(&message, 0, System.Length(&message));
+
+  CheckTrue(signer.VerifySignature(sigBytes));
+
+end;
+
+initialization
+
+// Register any test cases with the test runner
+
+{$IFDEF FPC}
+  RegisterTest(TTestECSchnorr);
+{$ELSE}
+  RegisterTest(TTestECSchnorr.Suite);
+{$ENDIF FPC}
+
+end.

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

@@ -28,7 +28,7 @@ uses
 {$ELSE}
   TestFramework,
 {$ENDIF FPC}
-  // ClpBase64,
+  //ClpBase64,
   ClpBigInteger,
   ClpCryptoLibTypes,
   ClpISigner,
@@ -170,7 +170,7 @@ begin
 
     signer := TSignerUtilities.GetSigner(algorithm);
 
-    upper := AnsiUpperCase(algorithm);
+    upper := UpperCase(algorithm);
     withPos := System.Pos('WITH', upper);
 
     if withPos = 0 then

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

@@ -51,8 +51,8 @@ type
 
   const
 
-    Falgorithms: array [0 .. 5] of String = ('EC', 'ECDSA', 'ECDH', 'ECDHC',
-      'ECGOST3410', 'ECMQV');
+    Falgorithms: array [0 .. 6] of String = ('EC', 'ECDSA', 'ECDH', 'ECDHC',
+      'ECGOST3410', 'ECMQV', 'ECSCHNORR');
 
   var
     Falgorithm: String;
@@ -135,7 +135,7 @@ var
   i: Int32;
   found: Boolean;
 begin
-  upper := AnsiUpperCase(algorithm);
+  upper := UpperCase(algorithm);
   found := false;
   for i := System.Low(Falgorithms) to System.High(Falgorithms) do
   begin

+ 625 - 0
CryptoLib/src/Crypto/Signers/ClpECSchnorrSigner.pas

@@ -0,0 +1,625 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                    Copyright (c) 2018 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://sphere10.com) for sponsoring        * }
+{ *                        the development of this library                          * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpECSchnorrSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  Math,
+  Generics.Collections,
+  HlpIHash,
+  ClpISigner,
+  ClpSecureRandom,
+  ClpISecureRandom,
+  ClpICipherParameters,
+  ClpIECSchnorrSigner,
+  ClpIAsymmetricKeyParameter,
+  ClpIParametersWithRandom,
+  ClpDerSequence,
+  ClpIDerSequence,
+  ClpDerInteger,
+  ClpIDerInteger,
+  ClpAsn1Object,
+  ClpIAsn1Sequence,
+  ClpBigInteger,
+  ClpBigIntegers,
+  ClpIECKeyParameters,
+  ClpIECPublicKeyParameters,
+  ClpIECPrivateKeyParameters,
+  ClpIECInterface,
+  ClpBits,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SECPublicKeyNotFound = 'EC Public Key Required for Verification';
+  SECPrivateKeyNotFound = 'EC Private Key Required for Signing';
+  SCurveNil = 'Key has no Curve';
+  SUnSupportedVariant = 'Schnorr Variant not Supported %s';
+
+type
+  TECSchnorrSigner = class sealed(TInterfacedObject, ISigner, IECSchnorrSigner)
+
+  strict private
+
+    class var
+
+      FRandom: ISecureRandom;
+
+  var
+    FDigest: IHash;
+    FVariant: String;
+    FforSigning: Boolean;
+    Fkey: IECKeyParameters;
+    Fm_list: TList<TCryptoLibByteArray>;
+
+    function Aggregate: TCryptoLibByteArray;
+
+    /// <summary>
+    /// <para>
+    /// Warning...
+    /// </para>
+    /// <para>
+    /// do not use this method, it was exposed solely for testing
+    /// purposes.
+    /// </para>
+    /// </summary>
+    /// <param name="pv_key">
+    /// private key
+    /// </param>
+    /// <param name="k">
+    /// known random number
+    /// </param>
+    function Sign_K(const pv_key: IECPrivateKeyParameters; const k: TBigInteger)
+      : TCryptoLibByteArray;
+
+    function Do_Sign(const pv_key: IECPrivateKeyParameters;
+      const k: TBigInteger): TCryptoLibByteArray;
+
+    function Do_Verify(const pu_key: IECPublicKeyParameters;
+      sig: TCryptoLibByteArray): Boolean;
+
+    class function Encode_Sig(const r, s: TBigInteger): TCryptoLibByteArray;
+      static; inline;
+
+    class function Decode_Sig(sig: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>; static; inline;
+
+    class constructor ECSchnorrSigner();
+
+  public
+
+    // ECSchnorr signer implementation according to:
+    //
+    // - `BSI:TR03111 <https://www.bsi.bund.de/SharedDocs/Downloads/EN/BSI/Publications/TechGuidelines/TR03111/BSI-TR-03111_pdf.html>`_
+    // - `ISO/IEC:14888-3 <http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=43656>`_
+    // - `bitcoin-core:libsecp256k1 <https://github.com/bitcoin-core/secp256k1/blob/master/src/modules/schnorr/schnorr_impl.h>`_
+    //
+    //
+    // In order to select the specification to be conform to, choose
+    // the corresponding string option: "BSI", "ISO", "ISOx", "LIBSECP"
+    //
+    // *Signature*:
+    //
+    // - "BSI": compute r,s according to to BSI :
+    // 1. k = RNG(1:n-1)
+    // 2. Q = [k]G
+    // 3. r = H(M ||Qx)
+    // If r = 0 mod n, goto 1.
+    // 4. s = k - r.d mod n
+    // If s = 0 goto 1.
+    // 5. Output (r, s)
+    // - "ISO": compute r,s according to ISO :
+    // 1. k = RNG(1:n-1)
+    // 2. Q = [k]G
+    // If r = 0 mod n, goto 1.
+    // 3. r = H(Qx||Qy||M).
+    // 4. s = (k + r.d) mod n
+    // If s = 0 goto 1.
+    // 5. Output (r, s)
+    // - "ISOx": compute r,s according to optimized ISO variant:
+    // 1. k = RNG(1:n-1)
+    // 2. Q = [k]G
+    // If r = 0 mod n, goto 1.
+    // 3. r = H(Qx||Qy||M).
+    // 4. s = (k + r.d) mod n
+    // If s = 0 goto 1.
+    // 5. Output (r, s)
+    // - "LIBSECP": compute r,s according to bitcoin lib:
+    // 1. k = RNG(1:n-1)
+    // 2. Q = [k]G
+    // if Qy is odd, negate k and goto 2
+    // 3. r = Qx % n
+    // 4. h = H(r || m).
+    // if h == 0 or h >= order goto 1
+    // 5. s = k - h.d.
+    // 6. Output (r, s)
+    //
+    // *Verification*
+    //
+    // - "BSI": verify r,s according to to BSI :
+    // 1. Verify that r in {0, . . . , 2**t - 1} and s in {1, 2, . . . , n - 1}.
+    // If the check fails, output False and terminate.
+    // 2. Q = [s]G + [r]W
+    // If Q = 0, output Error and terminate.
+    // 3. v = H(M||Qx)
+    // 4. Output True if v = r, and False otherwise.
+    // - "ISO": verify r,s according to ISO :
+    // 1. check...
+    // 2. Q = [s]G - [r]W
+    // If Q = 0, output Error and terminate.
+    // 3. v = H(Qx||Qy||M).
+    // 4. Output True if v = r, and False otherwise.
+    // - "ISOx": verify r,s according to optimized ISO variant:
+    // 1. check...
+    // 2. Q = [s]G - [r]W
+    // If Q = 0, output Error and terminate.
+    // 3. v = H(Qx||M).
+    // 4. Output True if v = r, and False otherwise.
+    // - "LIBSECP":
+    // 1. Signature is invalid if s >= order.
+    // Signature is invalid if r >= p.
+    // 2. h = H(r || m).
+    // Signature is invalid if h == 0 or h >= order.
+    // 3. R = [h]Q + [s]G.
+    // Signature is invalid if R is infinity or R's y coordinate is odd.
+    // 4. Signature is valid if the serialization of R's x coordinate equals r.
+
+    /// <param name="digest">
+    /// initialized "IHash" instance.
+    /// </param>
+    /// <param name="schnorr_variant">
+    /// one of "BSI","ISO","ISOx","LIBSECP"
+    /// </param>
+    constructor Create(const digest: IHash; const schnorr_variant: String);
+    destructor Destroy(); override;
+
+    function GetAlgorithmName: String;
+    property AlgorithmName: String read GetAlgorithmName;
+
+    procedure Init(forSigning: Boolean; const parameters: ICipherParameters);
+
+    /// <summary>
+    /// update the internal digest with the byte b
+    /// </summary>
+    procedure Update(input: Byte);
+
+    /// <summary>
+    /// update the internal digest with the byte array in
+    /// </summary>
+    procedure BlockUpdate(input: TCryptoLibByteArray; inOff, length: Int32);
+
+    /// <summary>
+    /// Generate a signature for the message we've been loaded with using the
+    /// key we were initialised with.
+    /// </summary>
+    function GenerateSignature(): TCryptoLibByteArray;
+
+    /// <returns>
+    /// true if the internal state represents the signature described in the
+    /// passed in array.
+    /// </returns>
+    function VerifySignature(signature: TCryptoLibByteArray): Boolean;
+
+    /// <summary>
+    /// Reset the internal state
+    /// </summary>
+    procedure Reset();
+  end;
+
+implementation
+
+{ TECSchnorrSigner }
+
+class constructor TECSchnorrSigner.ECSchnorrSigner;
+begin
+  FRandom := TSecureRandom.Create();
+end;
+
+class function TECSchnorrSigner.Encode_Sig(const r, s: TBigInteger)
+  : TCryptoLibByteArray;
+begin
+  Result := TDerSequence.Create([TDerInteger.Create(r) as IDerInteger,
+    TDerInteger.Create(s) as IDerInteger]).GetDerEncoded();
+end;
+
+class function TECSchnorrSigner.Decode_Sig(sig: TCryptoLibByteArray)
+  : TCryptoLibGenericArray<TBigInteger>;
+var
+  s: IAsn1Sequence;
+begin
+  s := TAsn1Object.FromByteArray(sig) as IAsn1Sequence;
+  Result := TCryptoLibGenericArray<TBigInteger>.Create
+    ((s[0] as IDerInteger).value, (s[1] as IDerInteger).value);
+end;
+
+function TECSchnorrSigner.Aggregate: TCryptoLibByteArray;
+var
+  sum, index: Int32;
+  arr: TCryptoLibByteArray;
+begin
+  sum := 0;
+  for arr in Fm_list do
+  begin
+    sum := sum + System.length(arr);
+  end;
+
+  System.SetLength(Result, sum);
+  index := 0;
+
+  for arr in Fm_list do
+
+  begin
+    System.Move(arr[0], Result[index], System.length(arr) *
+      System.SizeOf(Byte));
+    index := index + System.length(arr);
+  end;
+
+end;
+
+procedure TECSchnorrSigner.BlockUpdate(input: TCryptoLibByteArray;
+  inOff, length: Int32);
+begin
+  Fm_list.Add(System.Copy(input, inOff, length));
+end;
+
+constructor TECSchnorrSigner.Create(const digest: IHash;
+  const schnorr_variant: String);
+begin
+  inherited Create();
+  FDigest := digest;
+  FVariant := schnorr_variant;
+  Fm_list := TList<TCryptoLibByteArray>.Create();
+end;
+
+destructor TECSchnorrSigner.Destroy;
+begin
+  Fm_list.Free;
+  inherited Destroy;
+end;
+
+function TECSchnorrSigner.Do_Sign(const pv_key: IECPrivateKeyParameters;
+  const k: TBigInteger): TCryptoLibByteArray;
+var
+  curve: IECCurve;
+  n, r, s, h, tempK: TBigInteger;
+  size: Int32;
+  G, q: IECPoint;
+  xQ, yQ, rQ, tempR, tempH: TCryptoLibByteArray;
+begin
+  Result := Nil;
+  if (pv_key.parameters.curve = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SCurveNil)
+  end;
+  curve := pv_key.parameters.curve;
+  n := curve.order;
+  G := pv_key.parameters.G;
+  size := TBits.Asr32(curve.FieldSize, 3);
+
+  q := G.Multiply(k);
+
+  if FVariant = 'ISO' then
+  begin
+    xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
+    yQ := q.Normalize.YCoord.ToBigInteger.ToByteArray;
+
+    FDigest.TransformBytes(xQ);
+    FDigest.TransformBytes(yQ);
+    FDigest.TransformBytes(Aggregate);
+    tempR := FDigest.TransformFinal.GetBytes();
+
+    r := TBigInteger.Create(1, tempR);
+    s := (k.Add(r.Multiply(pv_key.D))).&Mod(n);
+    if (r.CompareTo(TBigInteger.Zero) = 0) or (s.CompareTo(TBigInteger.Zero) = 0)
+    then
+    begin
+      Result := Nil;
+      Exit;
+    end
+    else
+    begin
+      Result := Encode_Sig(r, s);
+      Exit;
+    end;
+
+  end
+  else if FVariant = 'ISOx' then
+  begin
+    xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
+
+    FDigest.TransformBytes(xQ);
+    FDigest.TransformBytes(Aggregate);
+    tempR := FDigest.TransformFinal.GetBytes();
+
+    r := TBigInteger.Create(1, tempR);
+    s := (k.Add(r.Multiply(pv_key.D))).&Mod(n);
+    if (r.CompareTo(TBigInteger.Zero) = 0) or (s.CompareTo(TBigInteger.Zero) = 0)
+    then
+    begin
+      Result := Nil;
+      Exit;
+    end
+    else
+    begin
+      Result := Encode_Sig(r, s);
+      Exit;
+    end;
+
+  end
+  else if FVariant = 'BSI' then
+  begin
+    xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
+
+    FDigest.TransformBytes(Aggregate);
+    FDigest.TransformBytes(xQ);
+    tempR := FDigest.TransformFinal.GetBytes();
+
+    r := TBigInteger.Create(1, tempR);
+    s := (k.Subtract(r.Multiply(pv_key.D))).&Mod(n);
+    if (r.CompareTo(TBigInteger.Zero) = 0) or (s.CompareTo(TBigInteger.Zero) = 0)
+    then
+    begin
+      Result := Nil;
+      Exit;
+    end
+    else
+    begin
+      Result := Encode_Sig(r, s);
+      Exit;
+    end;
+
+  end
+  else if FVariant = 'LIBSECP' then
+  begin
+    tempK := k;
+    if q.Normalize.YCoord.ToBigInteger.&And(TBigInteger.One)
+      .CompareTo(TBigInteger.One) = 0 then // if Q.y is Odd
+    begin
+      tempK := n.Subtract(tempK);
+      q := G.Multiply(tempK);
+    end;
+
+    rQ := q.Normalize.XCoord.ToBigInteger.&Mod(n).ToByteArray;
+    FDigest.TransformBytes(rQ);
+    FDigest.TransformBytes(Aggregate);
+    tempH := FDigest.TransformFinal.GetBytes();
+
+    h := TBigInteger.Create(1, tempH);
+    r := q.Normalize.XCoord.ToBigInteger.&Mod(n);
+    s := (tempK.Subtract(h.Multiply(pv_key.D))).&Mod(n);
+
+    Result := Encode_Sig(r, s);
+    Exit;
+
+  end
+  else
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SUnSupportedVariant,
+      [FVariant]);
+  end;
+
+end;
+
+function TECSchnorrSigner.Do_Verify(const pu_key: IECPublicKeyParameters;
+  sig: TCryptoLibByteArray): Boolean;
+var
+  curve: IECCurve;
+  n, r, s, h, v: TBigInteger;
+  size: Int32;
+  G, q, sG, rW, hW, LR: IECPoint;
+  xQ, yQ, tempV, tempH, rb: TCryptoLibByteArray;
+  R_and_S: TCryptoLibGenericArray<TBigInteger>;
+begin
+  Result := False;
+  if (pu_key.parameters.curve = Nil) then
+  begin
+    raise EArgumentNilCryptoLibException.CreateRes(@SCurveNil)
+  end;
+  curve := pu_key.parameters.curve;
+  n := curve.order;
+  G := pu_key.parameters.G;
+  size := TBits.Asr32(curve.FieldSize, 3);
+
+  R_and_S := Decode_Sig(sig);
+
+  r := R_and_S[0];
+  s := R_and_S[1];
+
+  if (not(r.IsInitialized) or (r.CompareTo(TBigInteger.Two.Pow(size * 8)
+    .Subtract(TBigInteger.One)) = 1) or (s.CompareTo(TBigInteger.Zero) = 0) or
+    (s.CompareTo(n.Subtract(TBigInteger.One)) = 1)) then
+  begin
+    Result := False;
+    Exit;
+  end;
+
+  sG := G.Multiply(s);
+
+  if FVariant = 'ISO' then
+  begin
+    rW := pu_key.q.Multiply(r);
+    q := sG.Subtract(rW);
+    xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
+    yQ := q.Normalize.YCoord.ToBigInteger.ToByteArray;
+
+    FDigest.TransformBytes(xQ);
+    FDigest.TransformBytes(yQ);
+    FDigest.TransformBytes(Aggregate);
+    tempV := FDigest.TransformFinal.GetBytes();
+
+    v := TBigInteger.Create(1, tempV);
+    Result := v.Equals(r);
+    Exit;
+
+  end
+  else if FVariant = 'ISOx' then
+  begin
+    rW := pu_key.q.Multiply(r);
+    q := sG.Subtract(rW);
+    xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
+
+    FDigest.TransformBytes(xQ);
+    FDigest.TransformBytes(Aggregate);
+    tempV := FDigest.TransformFinal.GetBytes();
+
+    v := TBigInteger.Create(1, tempV);
+    Result := v.Equals(r);
+    Exit;
+
+  end
+  else if FVariant = 'BSI' then
+  begin
+    rW := pu_key.q.Multiply(r);
+    q := sG.Add(rW);
+    xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
+
+    FDigest.TransformBytes(Aggregate);
+    FDigest.TransformBytes(xQ);
+    tempV := FDigest.TransformFinal.GetBytes();
+
+    v := TBigInteger.Create(1, tempV);
+    Result := v.Equals(r);
+    Exit;
+
+  end
+  else if FVariant = 'LIBSECP' then
+  begin
+    rb := r.ToByteArray;
+
+    FDigest.TransformBytes(rb);
+    FDigest.TransformBytes(Aggregate);
+    tempH := FDigest.TransformFinal.GetBytes();
+
+    h := TBigInteger.Create(1, tempH);
+    if (h.CompareTo(TBigInteger.Zero) = 0) or (h.CompareTo(n) = 1) then
+    begin
+      Result := False;
+      Exit;
+    end;
+
+    hW := pu_key.q.Multiply(h);
+    LR := sG.Add(hW);
+    v := LR.Normalize.XCoord.ToBigInteger.&Mod(n);
+
+    Result := v.Equals(r);
+    Exit;
+
+  end
+  else
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SUnSupportedVariant,
+      [FVariant]);
+  end;
+
+end;
+
+function TECSchnorrSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  order, k, orderMinusOne: TBigInteger;
+  pv_key_params: IECPrivateKeyParameters;
+begin
+
+  pv_key_params := Fkey as IECPrivateKeyParameters;
+  order := pv_key_params.parameters.curve.order;
+  orderMinusOne := order.Subtract(TBigInteger.One);
+
+  repeat
+    // k := [1, q - 1]
+    k := TBigIntegers.CreateRandomInRange(TBigInteger.One,
+      orderMinusOne, FRandom);
+
+    Result := Do_Sign(pv_key_params, k);
+  until (Result <> Nil);
+
+end;
+
+function TECSchnorrSigner.GetAlgorithmName: String;
+begin
+  Result := FDigest.Name + 'with' + 'ECSCHNORR' + FVariant;
+end;
+
+procedure TECSchnorrSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+var
+  rParam: IParametersWithRandom;
+  Lparameters: ICipherParameters;
+begin
+
+  FforSigning := forSigning;
+  Lparameters := parameters;
+
+  if (forSigning) then
+  begin
+
+    if (Supports(Lparameters, IParametersWithRandom, rParam)) then
+    begin
+      Lparameters := rParam.parameters;
+    end;
+
+    if (not(Supports(Lparameters, IECPrivateKeyParameters))) then
+    begin
+      raise EInvalidKeyCryptoLibException.CreateRes(@SECPrivateKeyNotFound);
+    end;
+
+    Fkey := Lparameters as IECPrivateKeyParameters;
+  end
+  else
+  begin
+    if (not(Supports(Lparameters, IECPublicKeyParameters))) then
+    begin
+      raise EInvalidKeyCryptoLibException.CreateRes(@SECPublicKeyNotFound);
+    end;
+
+    Fkey := Lparameters as IECPublicKeyParameters;
+  end;
+  Reset();
+end;
+
+procedure TECSchnorrSigner.Reset;
+begin
+  FDigest.Initialize;
+  Fm_list.Clear;
+end;
+
+function TECSchnorrSigner.Sign_K(const pv_key: IECPrivateKeyParameters;
+  const k: TBigInteger): TCryptoLibByteArray;
+begin
+  Result := Do_Sign(pv_key, k);
+end;
+
+procedure TECSchnorrSigner.Update(input: Byte);
+begin
+  Fm_list.Add(TCryptoLibByteArray.Create(input));
+end;
+
+function TECSchnorrSigner.VerifySignature
+  (signature: TCryptoLibByteArray): Boolean;
+var
+  pu_key_params: IECPublicKeyParameters;
+begin
+
+  pu_key_params := Fkey as IECPublicKeyParameters;
+
+  Result := Do_Verify(pu_key_params, signature);
+
+end;
+
+end.

+ 88 - 0
CryptoLib/src/Interfaces/ClpIECSchnorrSigner.pas

@@ -0,0 +1,88 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                    Copyright (c) 2018 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://sphere10.com) for sponsoring        * }
+{ *                        the development of this library                          * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIECSchnorrSigner;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpICipherParameters,
+  ClpIECPrivateKeyParameters,
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+type
+  IECSchnorrSigner = interface(IInterface)
+    ['{A941F9C5-81BE-4F0D-9294-2488C21035E3}']
+
+    function GetAlgorithmName: String;
+    property AlgorithmName: String read GetAlgorithmName;
+
+    procedure Init(forSigning: Boolean; const parameters: ICipherParameters);
+
+    /// <summary>
+    /// update the internal digest with the byte b
+    /// </summary>
+    procedure Update(input: Byte);
+
+    /// <summary>
+    /// update the internal digest with the byte array in
+    /// </summary>
+    procedure BlockUpdate(input: TCryptoLibByteArray; inOff, length: Int32);
+
+    /// <summary>
+    /// Generate a signature for the message we've been loaded with using the
+    /// key we were initialised with.
+    /// </summary>
+    function GenerateSignature(): TCryptoLibByteArray;
+
+    /// <returns>
+    /// true if the internal state represents the signature described in the
+    /// passed in array.
+    /// </returns>
+    function VerifySignature(signature: TCryptoLibByteArray): Boolean;
+
+    /// <summary>
+    /// Reset the internal state
+    /// </summary>
+    procedure Reset();
+
+    /// <summary>
+    /// <para>
+    /// Warning...
+    /// </para>
+    /// <para>
+    /// do not use this method, it was exposed solely for testing
+    /// purposes.
+    /// </para>
+    /// </summary>
+    /// <param name="pv_key">
+    /// private key
+    /// </param>
+    /// <param name="k">
+    /// known random number
+    /// </param>
+    function Sign_K(const pv_key: IECPrivateKeyParameters;  const k: TBigInteger)
+      : TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 4 - 4
CryptoLib/src/Math/EC/ClpECPoint.pas

@@ -1977,22 +1977,22 @@ begin
 
         V := V1.Subtract(V2);
 
-        // Check if b :=:= this or b :=:= -this
+        // Check if b = this or b = -this
         if (V.IsZero) then
         begin
           if (U.IsZero) then
           begin
-            // this :=:= b, i.e. this must be doubled
+            // this = b, i.e. this must be doubled
             result := Twice();
             Exit;
           end;
 
-          // this :=:= -b, i.e. the result is the point at infinity
+          // this = -b, i.e. the result is the point at infinity
           result := ecCurve.Infinity;
           Exit;
         end;
 
-        // TODO Optimize for when w :=:= 1
+        // TODO Optimize for when w = 1
         if Z1IsOne then
         begin
           W := Z2;

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

@@ -19,13 +19,13 @@
         </Optimizations>
       </CodeGeneration>
     </CompilerOptions>
-    <Description Value="CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA Signatures using various curves and hashes."/>
+    <Description Value="CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA and ECShnorr Signatures using various curves and hashes."/>
     <License Value="MIT License                          
 
  Acknowledgements: 
 Thanks to Sphere 10 Software (http://sphere10.com) for sponsoring the development of this library "/>
-    <Version Major="1" Minor="1"/>
-    <Files Count="279">
+    <Version Major="1" Minor="2"/>
+    <Files Count="281">
       <Item1>
         <Filename Value="..\..\Asn1\ClpAsn1Encodable.pas"/>
         <UnitName Value="ClpAsn1Encodable"/>
@@ -1142,6 +1142,14 @@ Thanks to Sphere 10 Software (http://sphere10.com) for sponsoring the developmen
         <Filename Value="..\..\Asn1\ClpDefiniteLengthInputStream.pas"/>
         <UnitName Value="ClpDefiniteLengthInputStream"/>
       </Item279>
+      <Item280>
+        <Filename Value="..\..\Crypto\Signers\ClpECSchnorrSigner.pas"/>
+        <UnitName Value="ClpECSchnorrSigner"/>
+      </Item280>
+      <Item281>
+        <Filename Value="..\..\Interfaces\ClpIECSchnorrSigner.pas"/>
+        <UnitName Value="ClpIECSchnorrSigner"/>
+      </Item281>
     </Files>
     <RequiredPkgs Count="2">
       <Item1>

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

@@ -93,7 +93,8 @@ uses
   ClpBase64, ClpHex, ClpStreamHelper, ClpStringHelper, ClpBaseInputStream, 
   ClpFilterStream, ClpStreams, ClpOSRandom, ClpPcgRandomMinimal, 
   ClpOSRandomNumberGenerator, ClpPCGRandomNumberGenerator, 
-  ClpRandomNumberGenerator, ClpSetWeakRef, ClpDefiniteLengthInputStream;
+  ClpRandomNumberGenerator, ClpSetWeakRef, ClpDefiniteLengthInputStream, 
+  ClpECSchnorrSigner, ClpIECSchnorrSigner;
 
 implementation
 

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

@@ -104,7 +104,7 @@ begin
   begin
     TDigestUtilities.Boot;
   end;
-  upper := AnsiUpperCase(algorithm);
+  upper := UpperCase(algorithm);
   Falgorithms.TryGetValue(upper, mechanism);
 
   if (mechanism = '') then
@@ -376,7 +376,7 @@ begin
   if (mechanism = '') then
     raise EArgumentNilCryptoLibException.CreateRes(@SMechanismNil);
 
-  mechanism := AnsiUpperCase(mechanism);
+  mechanism := UpperCase(mechanism);
   if Falgorithms.TryGetValue(mechanism, aliased) then
   begin
     mechanism := aliased;

+ 2 - 1
CryptoLib/src/Security/ClpSecureRandom.pas

@@ -335,7 +335,8 @@ var
   upper, digestName: String;
   prng: IDigestRandomGenerator;
 begin
-  upper := AnsiUpperCase(algorithm);
+  upper := UpperCase(algorithm);
+  // should use "EndsStr" here but it seems that is missing in Lazarus/FPC RTL
   if AnsiEndsStr('PRNG', upper) then
   begin
     digestName := System.Copy(upper, 1, System.length(upper) -

+ 357 - 2
CryptoLib/src/Security/ClpSignerUtilities.pas

@@ -28,6 +28,8 @@ uses
   HlpHashFactory,
   HlpIHash,
   ClpDsaDigestSigner,
+  ClpECSchnorrSigner,
+  ClpIECSchnorrSigner,
   ClpX9ObjectIdentifiers,
   ClpTeleTrusTObjectIdentifiers,
   ClpCryptoProObjectIdentifiers,
@@ -173,6 +175,174 @@ begin
   // Foids.Add('ECGOST3410',
   // TCryptoProObjectIdentifiers.GostR3411x94WithGostR3410x2001);
 
+  // ECSCHNORR BSI
+
+  Falgorithms.Add('SHA1/ECSCHNORR/BSI', 'SHA-1withECSCHNORRBSI');
+  Falgorithms.Add('SHA-1/ECSCHNORR/BSI', 'SHA-1withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA1', 'SHA-1withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA-1', 'SHA-1withECSCHNORRBSI');
+  Falgorithms.Add('SHA1WITHECSCHNORRBSI', 'SHA-1withECSCHNORRBSI');
+  Falgorithms.Add('SHA-1WITHECSCHNORRBSI', 'SHA-1withECSCHNORRBSI');
+
+  Falgorithms.Add('SHA224/ECSCHNORR/BSI', 'SHA-224withECSCHNORRBSI');
+  Falgorithms.Add('SHA-224/ECSCHNORR/BSI', 'SHA-224withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA224', 'SHA-224withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA-224', 'SHA-224withECSCHNORRBSI');
+  Falgorithms.Add('SHA224WITHECSCHNORRBSI', 'SHA-224withECSCHNORRBSI');
+  Falgorithms.Add('SHA-224WITHECSCHNORRBSI', 'SHA-224withECSCHNORRBSI');
+
+  Falgorithms.Add('SHA256/ECSCHNORR/BSI', 'SHA-256withECSCHNORRBSI');
+  Falgorithms.Add('SHA-256/ECSCHNORR/BSI', 'SHA-256withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA256', 'SHA-256withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA-256', 'SHA-256withECSCHNORRBSI');
+  Falgorithms.Add('SHA256WITHECSCHNORRBSI', 'SHA-256withECSCHNORRBSI');
+  Falgorithms.Add('SHA-256WITHECSCHNORRBSI', 'SHA-256withECSCHNORRBSI');
+
+  Falgorithms.Add('SHA384/ECSCHNORR/BSI', 'SHA-384withECSCHNORRBSI');
+  Falgorithms.Add('SHA-384/ECSCHNORR/BSI', 'SHA-384withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA384', 'SHA-384withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA-384', 'SHA-384withECSCHNORRBSI');
+  Falgorithms.Add('SHA384WITHECSCHNORRBSI', 'SHA-384withECSCHNORRBSI');
+  Falgorithms.Add('SHA-384WITHECSCHNORRBSI', 'SHA-384withECSCHNORRBSI');
+
+  Falgorithms.Add('SHA512/ECSCHNORR/BSI', 'SHA-512withECSCHNORRBSI');
+  Falgorithms.Add('SHA-512/ECSCHNORR/BSI', 'SHA-512withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA512', 'SHA-512withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHSHA-512', 'SHA-512withECSCHNORRBSI');
+  Falgorithms.Add('SHA512WITHECSCHNORRBSI', 'SHA-512withECSCHNORRBSI');
+  Falgorithms.Add('SHA-512WITHECSCHNORRBSI', 'SHA-512withECSCHNORRBSI');
+
+  Falgorithms.Add('RIPEMD160/ECSCHNORR/BSI', 'RIPEMD160withECSCHNORRBSI');
+  Falgorithms.Add('ECSCHNORRBSIWITHRIPEMD160', 'RIPEMD160withECSCHNORRBSI');
+  Falgorithms.Add('RIPEMD160WITHECSCHNORRBSI', 'RIPEMD160withECSCHNORRBSI');
+
+  // ECSCHNORR ISO
+
+  Falgorithms.Add('SHA1/ECSCHNORR/ISO', 'SHA-1withECSCHNORRISO');
+  Falgorithms.Add('SHA-1/ECSCHNORR/ISO', 'SHA-1withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA1', 'SHA-1withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA-1', 'SHA-1withECSCHNORRISO');
+  Falgorithms.Add('SHA1WITHECSCHNORRISO', 'SHA-1withECSCHNORRISO');
+  Falgorithms.Add('SHA-1WITHECSCHNORRISO', 'SHA-1withECSCHNORRISO');
+
+  Falgorithms.Add('SHA224/ECSCHNORR/ISO', 'SHA-224withECSCHNORRISO');
+  Falgorithms.Add('SHA-224/ECSCHNORR/ISO', 'SHA-224withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA224', 'SHA-224withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA-224', 'SHA-224withECSCHNORRISO');
+  Falgorithms.Add('SHA224WITHECSCHNORRISO', 'SHA-224withECSCHNORRISO');
+  Falgorithms.Add('SHA-224WITHECSCHNORRISO', 'SHA-224withECSCHNORRISO');
+
+  Falgorithms.Add('SHA256/ECSCHNORR/ISO', 'SHA-256withECSCHNORRISO');
+  Falgorithms.Add('SHA-256/ECSCHNORR/ISO', 'SHA-256withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA256', 'SHA-256withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA-256', 'SHA-256withECSCHNORRISO');
+  Falgorithms.Add('SHA256WITHECSCHNORRISO', 'SHA-256withECSCHNORRISO');
+  Falgorithms.Add('SHA-256WITHECSCHNORRISO', 'SHA-256withECSCHNORRISO');
+
+  Falgorithms.Add('SHA384/ECSCHNORR/ISO', 'SHA-384withECSCHNORRISO');
+  Falgorithms.Add('SHA-384/ECSCHNORR/ISO', 'SHA-384withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA384', 'SHA-384withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA-384', 'SHA-384withECSCHNORRISO');
+  Falgorithms.Add('SHA384WITHECSCHNORRISO', 'SHA-384withECSCHNORRISO');
+  Falgorithms.Add('SHA-384WITHECSCHNORRISO', 'SHA-384withECSCHNORRISO');
+
+  Falgorithms.Add('SHA512/ECSCHNORR/ISO', 'SHA-512withECSCHNORRISO');
+  Falgorithms.Add('SHA-512/ECSCHNORR/ISO', 'SHA-512withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA512', 'SHA-512withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHSHA-512', 'SHA-512withECSCHNORRISO');
+  Falgorithms.Add('SHA512WITHECSCHNORRISO', 'SHA-512withECSCHNORRISO');
+  Falgorithms.Add('SHA-512WITHECSCHNORRISO', 'SHA-512withECSCHNORRISO');
+
+  Falgorithms.Add('RIPEMD160/ECSCHNORR/ISO', 'RIPEMD160withECSCHNORRISO');
+  Falgorithms.Add('ECSCHNORRISOWITHRIPEMD160', 'RIPEMD160withECSCHNORRISO');
+  Falgorithms.Add('RIPEMD160WITHECSCHNORRISO', 'RIPEMD160withECSCHNORRISO');
+
+  // ECSCHNORR ISOx
+
+  Falgorithms.Add('SHA1/ECSCHNORR/ISOx', 'SHA-1withECSCHNORRISOx');
+  Falgorithms.Add('SHA-1/ECSCHNORR/ISOx', 'SHA-1withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA1', 'SHA-1withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA-1', 'SHA-1withECSCHNORRISOx');
+  Falgorithms.Add('SHA1WITHECSCHNORRISOx', 'SHA-1withECSCHNORRISOx');
+  Falgorithms.Add('SHA-1WITHECSCHNORRISOx', 'SHA-1withECSCHNORRISOx');
+
+  Falgorithms.Add('SHA224/ECSCHNORR/ISOx', 'SHA-224withECSCHNORRISOx');
+  Falgorithms.Add('SHA-224/ECSCHNORR/ISOx', 'SHA-224withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA224', 'SHA-224withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA-224', 'SHA-224withECSCHNORRISOx');
+  Falgorithms.Add('SHA224WITHECSCHNORRISOx', 'SHA-224withECSCHNORRISOx');
+  Falgorithms.Add('SHA-224WITHECSCHNORRISOx', 'SHA-224withECSCHNORRISOx');
+
+  Falgorithms.Add('SHA256/ECSCHNORR/ISOx', 'SHA-256withECSCHNORRISOx');
+  Falgorithms.Add('SHA-256/ECSCHNORR/ISOx', 'SHA-256withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA256', 'SHA-256withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA-256', 'SHA-256withECSCHNORRISOx');
+  Falgorithms.Add('SHA256WITHECSCHNORRISOx', 'SHA-256withECSCHNORRISOx');
+  Falgorithms.Add('SHA-256WITHECSCHNORRISOx', 'SHA-256withECSCHNORRISOx');
+
+  Falgorithms.Add('SHA384/ECSCHNORR/ISOx', 'SHA-384withECSCHNORRISOx');
+  Falgorithms.Add('SHA-384/ECSCHNORR/ISOx', 'SHA-384withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA384', 'SHA-384withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA-384', 'SHA-384withECSCHNORRISOx');
+  Falgorithms.Add('SHA384WITHECSCHNORRISOx', 'SHA-384withECSCHNORRISOx');
+  Falgorithms.Add('SHA-384WITHECSCHNORRISOx', 'SHA-384withECSCHNORRISOx');
+
+  Falgorithms.Add('SHA512/ECSCHNORR/ISOx', 'SHA-512withECSCHNORRISOx');
+  Falgorithms.Add('SHA-512/ECSCHNORR/ISOx', 'SHA-512withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA512', 'SHA-512withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHSHA-512', 'SHA-512withECSCHNORRISOx');
+  Falgorithms.Add('SHA512WITHECSCHNORRISOx', 'SHA-512withECSCHNORRISOx');
+  Falgorithms.Add('SHA-512WITHECSCHNORRISOx', 'SHA-512withECSCHNORRISOx');
+
+  Falgorithms.Add('RIPEMD160/ECSCHNORR/ISOx', 'RIPEMD160withECSCHNORRISOx');
+  Falgorithms.Add('ECSCHNORRISOxWITHRIPEMD160', 'RIPEMD160withECSCHNORRISOx');
+  Falgorithms.Add('RIPEMD160WITHECSCHNORRISOx', 'RIPEMD160withECSCHNORRISOx');
+
+
+  // ECSCHNORR LIBSECP
+
+  Falgorithms.Add('SHA1/ECSCHNORR/LIBSECP', 'SHA-1withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-1/ECSCHNORR/LIBSECP', 'SHA-1withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA1', 'SHA-1withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA-1', 'SHA-1withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA1WITHECSCHNORRLIBSECP', 'SHA-1withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-1WITHECSCHNORRLIBSECP', 'SHA-1withECSCHNORRLIBSECP');
+
+  Falgorithms.Add('SHA224/ECSCHNORR/LIBSECP', 'SHA-224withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-224/ECSCHNORR/LIBSECP', 'SHA-224withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA224', 'SHA-224withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA-224', 'SHA-224withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA224WITHECSCHNORRLIBSECP', 'SHA-224withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-224WITHECSCHNORRLIBSECP', 'SHA-224withECSCHNORRLIBSECP');
+
+  Falgorithms.Add('SHA256/ECSCHNORR/LIBSECP', 'SHA-256withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-256/ECSCHNORR/LIBSECP', 'SHA-256withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA256', 'SHA-256withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA-256', 'SHA-256withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA256WITHECSCHNORRLIBSECP', 'SHA-256withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-256WITHECSCHNORRLIBSECP', 'SHA-256withECSCHNORRLIBSECP');
+
+  Falgorithms.Add('SHA384/ECSCHNORR/LIBSECP', 'SHA-384withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-384/ECSCHNORR/LIBSECP', 'SHA-384withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA384', 'SHA-384withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA-384', 'SHA-384withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA384WITHECSCHNORRLIBSECP', 'SHA-384withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-384WITHECSCHNORRLIBSECP', 'SHA-384withECSCHNORRLIBSECP');
+
+  Falgorithms.Add('SHA512/ECSCHNORR/LIBSECP', 'SHA-512withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-512/ECSCHNORR/LIBSECP', 'SHA-512withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA512', 'SHA-512withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHSHA-512', 'SHA-512withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA512WITHECSCHNORRLIBSECP', 'SHA-512withECSCHNORRLIBSECP');
+  Falgorithms.Add('SHA-512WITHECSCHNORRLIBSECP', 'SHA-512withECSCHNORRLIBSECP');
+
+  Falgorithms.Add('RIPEMD160/ECSCHNORR/LIBSECP',
+    'RIPEMD160withECSCHNORRLIBSECP');
+  Falgorithms.Add('ECSCHNORRLIBSECPWITHRIPEMD160',
+    'RIPEMD160withECSCHNORRLIBSECP');
+  Falgorithms.Add('RIPEMD160WITHECSCHNORRLIBSECP',
+    'RIPEMD160withECSCHNORRLIBSECP');
+
 end;
 
 class destructor TSignerUtilities.DestroySignerUtilities;
@@ -202,7 +372,7 @@ begin
     raise EArgumentNilCryptoLibException.CreateRes(@SMechanismNil);
   end;
 
-  mechanism := AnsiUpperCase(mechanism);
+  mechanism := UpperCase(mechanism);
   if (Falgorithms.TryGetValue(mechanism, aliased)) then
   begin
     mechanism := aliased;
@@ -227,7 +397,7 @@ begin
     raise EArgumentNilCryptoLibException.CreateRes(@SAlgorithmNil);
   end;
 
-  algorithm := AnsiUpperCase(algorithm);
+  algorithm := UpperCase(algorithm);
 
   if (not Falgorithms.TryGetValue(algorithm, mechanism)) then
   begin
@@ -292,6 +462,191 @@ begin
     Exit;
   end;
 
+
+  //
+
+  if (mechanism = 'SHA-1withECSCHNORRBSI') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA1();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    Exit;
+  end;
+  if (mechanism = 'SHA-224withECSCHNORRBSI') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    Exit;
+  end;
+  if (mechanism = 'SHA-256withECSCHNORRBSI') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    Exit;
+  end;
+  if (mechanism = 'SHA-384withECSCHNORRBSI') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    Exit;
+  end;
+  if (mechanism = 'SHA-512withECSCHNORRBSI') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    Exit;
+  end;
+
+  if (mechanism = 'RIPEMD160withECSCHNORRBSI') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'BSI');
+    Exit;
+  end;
+
+  //
+
+  if (mechanism = 'SHA-1withECSCHNORRISO') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA1();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    Exit;
+  end;
+  if (mechanism = 'SHA-224withECSCHNORRISO') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    Exit;
+  end;
+  if (mechanism = 'SHA-256withECSCHNORRISO') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    Exit;
+  end;
+  if (mechanism = 'SHA-384withECSCHNORRISO') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    Exit;
+  end;
+  if (mechanism = 'SHA-512withECSCHNORRISO') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    Exit;
+  end;
+
+  if (mechanism = 'RIPEMD160withECSCHNORRISO') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISO');
+    Exit;
+  end;
+
+  //
+
+  if (CompareText(mechanism, 'SHA-1withECSCHNORRISOx') = 0) then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA1();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    Exit;
+  end;
+  if (CompareText(mechanism, 'SHA-224withECSCHNORRISOx') = 0) then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    Exit;
+  end;
+  if (CompareText(mechanism, 'SHA-256withECSCHNORRISOx') = 0) then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    Exit;
+  end;
+  if (CompareText(mechanism, 'SHA-384withECSCHNORRISOx') = 0) then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    Exit;
+  end;
+  if (CompareText(mechanism, 'SHA-512withECSCHNORRISOx') = 0) then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    Exit;
+  end;
+
+  if (CompareText(mechanism, 'RIPEMD160withECSCHNORRISOx') = 0) then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'ISOx');
+    Exit;
+  end;
+
+  //
+
+  if (mechanism = 'SHA-1withECSCHNORRLIBSECP') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA1();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    Exit;
+  end;
+  if (mechanism = 'SHA-224withECSCHNORRLIBSECP') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_224();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    Exit;
+  end;
+  if (mechanism = 'SHA-256withECSCHNORRLIBSECP') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_256();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    Exit;
+  end;
+  if (mechanism = 'SHA-384withECSCHNORRLIBSECP') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_384();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    Exit;
+  end;
+  if (mechanism = 'SHA-512withECSCHNORRLIBSECP') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateSHA2_512();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    Exit;
+  end;
+
+  if (mechanism = 'RIPEMD160withECSCHNORRLIBSECP') then
+  begin
+    HashInstance := THashFactory.TCrypto.CreateRIPEMD160();
+    HashInstance.Initialize;
+    Result := TECSchnorrSigner.Create(HashInstance, 'LIBSECP');
+    Exit;
+  end;
+
   raise ESecurityUtilityCryptoLibException.CreateResFmt(@SUnRecognizedAlgorithm,
     [algorithm]);
 

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

@@ -389,7 +389,7 @@ var
   ar: TCryptoLibStringArray;
 begin
 
-  hex := AnsiUpperCase(TBitConverter.ToString(a_in));
+  hex := UpperCase(TBitConverter.ToString(a_in));
 
   if System.length(a_in) = 1 then
   begin
@@ -408,7 +408,7 @@ begin
 {$IFDEF DEBUG}
     Check(a_in, 1, 4);
 {$ENDIF DEBUG}
-    workstring := AnsiUpperCase(TBitConverter.ToString(a_in));
+    workstring := UpperCase(TBitConverter.ToString(a_in));
 
     ar := TConverters.SplitString(workstring, '-');
     hex := '';

+ 20 - 3
README.md

@@ -1,12 +1,29 @@
 # CryptoLib4Pascal
-CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA Signatures using various curves and hashes.
+CryptoLib4Pascal is a Cryptographic Package for Delphi/FreePascal Compilers that provides at the moment support for creating, signing and verifying ECDSA and ECShnorr Signatures using various curves and hashes.
 
 **Supported Algorithms:**
 
-    Supported Curves at the moment are secp256k1, sect283k1, secp384r1 and secp521r1.
-    Supported signing algorithms are NONEwithECDSA, SHA-1withECDSA, SHA-224withECDSA, 
+    Supported Elliptic Curves at the moment are secp256k1, sect283k1, secp384r1 and secp521r1.
+    
+    Supported signing algorithms 
+    ECDSA
+    NONEwithECDSA, SHA-1withECDSA, SHA-224withECDSA, 
     SHA-256withECDSA, SHA-384withECDSA, SHA-512withECDSA and RIPEMD160withECDSA
     
+    ECSchnorr
+    SHA-1withECSCHNORRBSI, SHA-224withECSCHNORRBSI, SHA-256withECSCHNORRBSI, SHA-384withECSCHNORRBSI,
+    SHA-512withECSCHNORRBSI, RIPEMD160withECSCHNORRBSI
+    
+    SHA-1withECSCHNORRISO, SHA-224withECSCHNORRISO, SHA-256withECSCHNORRISO, SHA-384withECSCHNORRISO, 
+    SHA-512withECSCHNORRISO, RIPEMD160withECSCHNORRISO
+    
+    SHA-1withECSCHNORRISOx, SHA-224withECSCHNORRISOx, SHA-256withECSCHNORRISOx, SHA-384withECSCHNORRISOx,
+    SHA-512withECSCHNORRISOx, RIPEMD160withECSCHNORRISOx 
+    
+    SHA-1withECSCHNORRLIBSECP, SHA-224withECSCHNORRLIBSECP, SHA-256withECSCHNORRLIBSECP, SHA-384withECSCHNORRLIBSECP,
+    SHA-512withECSCHNORRLIBSECP, RIPEMD160withECSCHNORRLIBSECP 
+    
+    
    **Dependencies:**
    
    [HashLib4Pascal](https://github.com/Xor-el/HashLib4Pascal) >= v2.3