Browse Source

Merge branch 'master' into travis

Ugochukwu Mmaduekwe 7 years ago
parent
commit
9bf4a6cb63
100 changed files with 3564 additions and 1983 deletions
  1. 29 0
      .github/ISSUE_TEMPLATE/bug_report.md
  2. 17 0
      .github/ISSUE_TEMPLATE/feature_request.md
  3. 20 13
      CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr
  4. 1 2
      CryptoLib.Samples/src/UsageExamples.pas
  5. 21 13
      CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr
  6. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.Tests.lpi
  7. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLib.lpr
  8. 5 1
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.Tests.lpi
  9. 1 0
      CryptoLib.Tests/FreePascal.Tests/CryptoLibConsole.lpr
  10. 2 6
      CryptoLib.Tests/src/Asn1/StringTests.pas
  11. 9 6
      CryptoLib.Tests/src/Asn1/TagTests.pas
  12. 20 0
      CryptoLib.Tests/src/Crypto/BlockCipherVectorTests.pas
  13. 80 0
      CryptoLib.Tests/src/Crypto/BlowfishTestVectors.pas
  14. 3 3
      CryptoLib.Tests/src/Crypto/PaddingTests.pas
  15. 0 1
      CryptoLib.Tests/src/Math/EC/Custom/Sec/SecP384R1FieldTests.pas
  16. 19 19
      CryptoLib.Tests/src/Math/ECIESTests.pas
  17. 197 153
      CryptoLib.Tests/src/Others/ECSchnorrTests.pas
  18. 2 1
      CryptoLib.Tests/src/Others/SignerUtilitiesTests.pas
  19. 3 4
      CryptoLib.Tests/src/Security/SecureRandomTests.pas
  20. 172 0
      CryptoLib/src/Asn1/Bsi/ClpBsiObjectIdentifiers.pas
  21. 1 1
      CryptoLib/src/Asn1/ClpAsn1Object.pas
  22. 1 1
      CryptoLib/src/Asn1/ClpAsn1Sequence.pas
  23. 1 1
      CryptoLib/src/Asn1/ClpAsn1Set.pas
  24. 6 3
      CryptoLib/src/Asn1/ClpBerBitString.pas
  25. 5 4
      CryptoLib/src/Asn1/ClpBerNull.pas
  26. 9 7
      CryptoLib/src/Asn1/ClpBerOctetString.pas
  27. 8 7
      CryptoLib/src/Asn1/ClpBerSequence.pas
  28. 9 7
      CryptoLib/src/Asn1/ClpBerSet.pas
  29. 11 8
      CryptoLib/src/Asn1/ClpBerTaggedObject.pas
  30. 3 3
      CryptoLib/src/Asn1/ClpConstructedOctetStream.pas
  31. 2 2
      CryptoLib/src/Asn1/ClpDefiniteLengthInputStream.pas
  32. 12 17
      CryptoLib/src/Asn1/ClpDerApplicationSpecific.pas
  33. 6 4
      CryptoLib/src/Asn1/ClpDerBitString.pas
  34. 6 4
      CryptoLib/src/Asn1/ClpDerBmpString.pas
  35. 6 3
      CryptoLib/src/Asn1/ClpDerBoolean.pas
  36. 5 3
      CryptoLib/src/Asn1/ClpDerEnumerated.pas
  37. 5 3
      CryptoLib/src/Asn1/ClpDerExternal.pas
  38. 6 3
      CryptoLib/src/Asn1/ClpDerGeneralString.pas
  39. 5 3
      CryptoLib/src/Asn1/ClpDerGraphicString.pas
  40. 5 3
      CryptoLib/src/Asn1/ClpDerIA5String.pas
  41. 5 3
      CryptoLib/src/Asn1/ClpDerInteger.pas
  42. 5 3
      CryptoLib/src/Asn1/ClpDerNull.pas
  43. 6 3
      CryptoLib/src/Asn1/ClpDerNumericString.pas
  44. 21 5
      CryptoLib/src/Asn1/ClpDerObjectIdentifier.pas
  45. 4 3
      CryptoLib/src/Asn1/ClpDerOctetString.pas
  46. 5 3
      CryptoLib/src/Asn1/ClpDerOutputStream.pas
  47. 6 3
      CryptoLib/src/Asn1/ClpDerPrintableString.pas
  48. 4 3
      CryptoLib/src/Asn1/ClpDerSequence.pas
  49. 4 3
      CryptoLib/src/Asn1/ClpDerSet.pas
  50. 25 5
      CryptoLib/src/Asn1/ClpDerT61String.pas
  51. 9 6
      CryptoLib/src/Asn1/ClpDerTaggedObject.pas
  52. 4 3
      CryptoLib/src/Asn1/ClpDerUniversalString.pas
  53. 5 3
      CryptoLib/src/Asn1/ClpDerUtf8String.pas
  54. 5 3
      CryptoLib/src/Asn1/ClpDerVideotexString.pas
  55. 6 3
      CryptoLib/src/Asn1/ClpDerVisibleString.pas
  56. 3 3
      CryptoLib/src/Asn1/ClpIndefiniteLengthInputStream.pas
  57. 147 0
      CryptoLib/src/Asn1/Eac/ClpEacObjectIdentifiers.pas
  58. 78 3
      CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas
  59. 2 1
      CryptoLib/src/Crypto/ClpBufferedBlockCipher.pas
  60. 178 0
      CryptoLib/src/Crypto/ClpBufferedCipherBase.pas
  61. 2 2
      CryptoLib/src/Crypto/ClpIESCipher.pas
  62. 285 286
      CryptoLib/src/Crypto/Engines/ClpAesEngine.pas
  63. 171 189
      CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas
  64. 555 0
      CryptoLib/src/Crypto/Engines/ClpBlowfishEngine.pas
  65. 30 13
      CryptoLib/src/Crypto/Engines/ClpIESEngine.pas
  66. 8 21
      CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas
  67. 0 2
      CryptoLib/src/Crypto/Generators/ClpHkdfBytesGenerator.pas
  68. 2 2
      CryptoLib/src/Crypto/Modes/ClpCbcBlockCipher.pas
  69. 15 7
      CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas
  70. 7 3
      CryptoLib/src/Crypto/Modes/ClpOfbBlockCipher.pas
  71. 2 2
      CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas
  72. 6 3
      CryptoLib/src/Crypto/Paddings/ClpPaddedBufferedBlockCipher.pas
  73. 8 0
      CryptoLib/src/Crypto/Parameters/ClpKeyParameter.pas
  74. 7 0
      CryptoLib/src/Crypto/Parameters/ClpParametersWithIV.pas
  75. 39 1
      CryptoLib/src/Crypto/Prng/ClpCryptoApiRandomGenerator.pas
  76. 17 3
      CryptoLib/src/Crypto/Prng/ClpDigestRandomGenerator.pas
  77. 47 43
      CryptoLib/src/Crypto/Signers/ClpDsaDigestSigner.pas
  78. 9 2
      CryptoLib/src/Crypto/Signers/ClpDsaSigner.pas
  79. 9 2
      CryptoLib/src/Crypto/Signers/ClpECDsaSigner.pas
  80. 10 3
      CryptoLib/src/Crypto/Signers/ClpECNRSigner.pas
  81. 0 151
      CryptoLib/src/Crypto/Signers/ClpECSchnorrBSISigner.pas
  82. 0 155
      CryptoLib/src/Crypto/Signers/ClpECSchnorrISOSigner.pas
  83. 0 151
      CryptoLib/src/Crypto/Signers/ClpECSchnorrISOXSigner.pas
  84. 0 161
      CryptoLib/src/Crypto/Signers/ClpECSchnorrLIBSECPSigner.pas
  85. 0 364
      CryptoLib/src/Crypto/Signers/ClpECSchnorrSigner.pas
  86. 292 0
      CryptoLib/src/Crypto/Signers/ClpECSchnorrSipaSigner.pas
  87. 8 5
      CryptoLib/src/Crypto/Signers/ClpHMacDsaKCalculator.pas
  88. 138 0
      CryptoLib/src/Crypto/Signers/ClpPlainDsaEncoding.pas
  89. 139 0
      CryptoLib/src/Crypto/Signers/ClpPlainSchnorrEncoding.pas
  90. 252 0
      CryptoLib/src/Crypto/Signers/ClpSchnorrDigestSigner.pas
  91. 140 0
      CryptoLib/src/Crypto/Signers/ClpStandardDsaEncoding.pas
  92. 20 10
      CryptoLib/src/Include/CryptoLib.inc
  93. 5 4
      CryptoLib/src/Interfaces/ClpIBlowfishEngine.pas
  94. 28 4
      CryptoLib/src/Interfaces/ClpIBufferedCipher.pas
  95. 1 5
      CryptoLib/src/Interfaces/ClpIDsaDigestSigner.pas
  96. 52 0
      CryptoLib/src/Interfaces/ClpIDsaEncoding.pas
  97. 13 14
      CryptoLib/src/Interfaces/ClpIDsaExt.pas
  98. 2 2
      CryptoLib/src/Interfaces/ClpIDsaSigner.pas
  99. 2 2
      CryptoLib/src/Interfaces/ClpIECDsaSigner.pas
  100. 2 2
      CryptoLib/src/Interfaces/ClpIECNRSigner.pas

+ 29 - 0
.github/ISSUE_TEMPLATE/bug_report.md

@@ -0,0 +1,29 @@
+---
+name: Bug report
+about: Create a report to help us improve
+
+---
+
+**Describe the bug**
+A clear and concise description of what the bug is.
+
+**To Reproduce**
+Steps to reproduce the behavior:
+1. Go to '...'
+2. Click on '....'
+3. Scroll down to '....'
+4. See error
+
+**Expected behavior**
+A clear and concise description of what you expected to happen.
+
+**Screenshots**
+If applicable, add screenshots to help explain your problem.
+
+**Environment (please complete the following information):**
+ - OS: [e.g. Windows, Linux, Mac]
+ - Compiler [e.g. FreePascal 3.0.0]
+ - Package Version [e.g. 1.0]
+
+**Additional context**
+Add any other context about the problem here.

+ 17 - 0
.github/ISSUE_TEMPLATE/feature_request.md

@@ -0,0 +1,17 @@
+---
+name: Feature request
+about: Suggest an idea for this project
+
+---
+
+**Is your feature request related to a problem? Please describe.**
+A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+
+**Describe the solution you'd like**
+A clear and concise description of what you want to happen.
+
+**Describe alternatives you've considered**
+A clear and concise description of any alternative solutions or features you've considered.
+
+**Additional context**
+Add any other context or screenshots about the feature request here.

+ 20 - 13
CryptoLib.Samples/Delphi.Samples/UsageSamples.dpr

@@ -165,7 +165,6 @@ uses
   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',
@@ -276,8 +275,6 @@ uses
   ClpBerSequenceGenerator in '..\..\CryptoLib\src\Asn1\ClpBerSequenceGenerator.pas',
   ClpSetWeakRef in '..\..\CryptoLib\src\Utils\ClpSetWeakRef.pas',
   UsageExamples in '..\src\UsageExamples.pas',
-  ClpIECSchnorrSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrSigner.pas',
-  ClpECSchnorrSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrSigner.pas',
   ClpCipherUtilities in '..\..\CryptoLib\src\Security\ClpCipherUtilities.pas',
   ClpIBufferedCipher in '..\..\CryptoLib\src\Interfaces\ClpIBufferedCipher.pas',
   ClpIBlockCipher in '..\..\CryptoLib\src\Interfaces\ClpIBlockCipher.pas',
@@ -365,15 +362,6 @@ uses
   ClpIPbeParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPbeParametersGenerator.pas',
   ClpPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPkcs5S2ParametersGenerator.pas',
   ClpIPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPkcs5S2ParametersGenerator.pas',
-  ClpISchnorr in '..\..\CryptoLib\src\Interfaces\ClpISchnorr.pas',
-  ClpECSchnorrBSISigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrBSISigner.pas',
-  ClpIECSchnorrBSISigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrBSISigner.pas',
-  ClpIECSchnorrISOSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrISOSigner.pas',
-  ClpECSchnorrISOSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrISOSigner.pas',
-  ClpIECSchnorrISOXSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrISOXSigner.pas',
-  ClpECSchnorrISOXSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrISOXSigner.pas',
-  ClpIECSchnorrLIBSECPSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrLIBSECPSigner.pas',
-  ClpECSchnorrLIBSECPSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrLIBSECPSigner.pas',
   ClpECNRSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECNRSigner.pas',
   ClpIECNRSigner in '..\..\CryptoLib\src\Interfaces\ClpIECNRSigner.pas',
   ClpDsaValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaValidationParameters.pas',
@@ -455,7 +443,26 @@ uses
   ClpISecP256R1Point in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Point.pas',
   ClpSecP256R1Point in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Point.pas',
   ClpISecP256R1Curve in '..\..\CryptoLib\src\Interfaces\ClpISecP256R1Curve.pas',
-  ClpSecP256R1Curve in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas';
+  ClpSecP256R1Curve in '..\..\CryptoLib\src\Math\EC\Custom\Sec\ClpSecP256R1Curve.pas',
+  ClpIDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIDsaEncoding.pas',
+  ClpIDsaExt in '..\..\CryptoLib\src\Interfaces\ClpIDsaExt.pas',
+  ClpStandardDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpStandardDsaEncoding.pas',
+  ClpIStandardDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIStandardDsaEncoding.pas',
+  ClpIPlainDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainDsaEncoding.pas',
+  ClpPlainDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainDsaEncoding.pas',
+  ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
+  ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
+  ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
+  ClpISchnorrDigestSigner in '..\..\CryptoLib\src\Interfaces\ClpISchnorrDigestSigner.pas',
+  ClpISchnorr in '..\..\CryptoLib\src\Interfaces\ClpISchnorr.pas',
+  ClpECSchnorrSipaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrSipaSigner.pas',
+  ClpIECSchnorrSipaSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrSipaSigner.pas',
+  ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
+  ClpISchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpISchnorrEncoding.pas',
+  ClpIPlainSchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainSchnorrEncoding.pas',
+  ClpPlainSchnorrEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainSchnorrEncoding.pas',
+  ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
+  ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas';
 
 begin
   try

+ 1 - 2
CryptoLib.Samples/src/UsageExamples.pas

@@ -48,7 +48,6 @@ uses
   ClpECPublicKeyParameters,
   ClpECPrivateKeyParameters,
   ClpIAsymmetricKeyParameter,
-  ClpECSchnorrSigner,
   ClpIECInterface,
   ClpECPoint,
   ClpISigner,
@@ -104,7 +103,7 @@ type
     /// SHA-512withECDSA and RIPEMD160withECDSA
     /// </summary>
     SigningAlgorithmECDSA = 'SHA-1withECDSA';
-    SigningAlgorithmECSCHNORR = 'SHA-256withECSCHNORRLIBSECP';
+    SigningAlgorithmECSCHNORR = 'SHA-256withECSCHNORRSIPA';
 
     PKCS5_SALT_LEN = Int32(8);
     SALT_MAGIC_LEN = Int32(8);

+ 21 - 13
CryptoLib.Tests/Delphi.Tests/CryptoLib.Tests.dpr

@@ -302,8 +302,6 @@ uses
   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',
   DigestRandomNumberTests in '..\src\Crypto\DigestRandomNumberTests.pas',
   FixedPointTests in '..\src\Math\EC\FixedPointTests.pas',
@@ -402,16 +400,6 @@ uses
   ClpPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Crypto\Generators\ClpPkcs5S2ParametersGenerator.pas',
   ClpIPkcs5S2ParametersGenerator in '..\..\CryptoLib\src\Interfaces\ClpIPkcs5S2ParametersGenerator.pas',
   Pkcs5Tests in '..\src\Crypto\Pkcs5Tests.pas',
-  ClpIFilterStream in '..\..\CryptoLib\src\Interfaces\ClpIFilterStream.pas',
-  ClpISchnorr in '..\..\CryptoLib\src\Interfaces\ClpISchnorr.pas',
-  ClpECSchnorrBSISigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrBSISigner.pas',
-  ClpIECSchnorrBSISigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrBSISigner.pas',
-  ClpIECSchnorrISOSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrISOSigner.pas',
-  ClpECSchnorrISOSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrISOSigner.pas',
-  ClpIECSchnorrISOXSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrISOXSigner.pas',
-  ClpECSchnorrISOXSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrISOXSigner.pas',
-  ClpIECSchnorrLIBSECPSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrLIBSECPSigner.pas',
-  ClpECSchnorrLIBSECPSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrLIBSECPSigner.pas',
   ClpECNRSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECNRSigner.pas',
   ClpIECNRSigner in '..\..\CryptoLib\src\Interfaces\ClpIECNRSigner.pas',
   ClpDsaValidationParameters in '..\..\CryptoLib\src\Crypto\Parameters\ClpDsaValidationParameters.pas',
@@ -513,7 +501,27 @@ uses
   StringTests in '..\src\Asn1\StringTests.pas',
   ParsingTests in '..\src\Asn1\ParsingTests.pas',
   ParseTests in '..\src\Asn1\ParseTests.pas',
-  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas';
+  EnumeratedTests in '..\src\Asn1\EnumeratedTests.pas',
+  ClpIDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIDsaEncoding.pas',
+  ClpIDsaExt in '..\..\CryptoLib\src\Interfaces\ClpIDsaExt.pas',
+  ClpStandardDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpStandardDsaEncoding.pas',
+  ClpIStandardDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIStandardDsaEncoding.pas',
+  ClpIPlainDsaEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainDsaEncoding.pas',
+  ClpPlainDsaEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainDsaEncoding.pas',
+  ClpBsiObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Bsi\ClpBsiObjectIdentifiers.pas',
+  ClpEacObjectIdentifiers in '..\..\CryptoLib\src\Asn1\Eac\ClpEacObjectIdentifiers.pas',
+  ClpSchnorrDigestSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpSchnorrDigestSigner.pas',
+  ClpISchnorrDigestSigner in '..\..\CryptoLib\src\Interfaces\ClpISchnorrDigestSigner.pas',
+  ClpISchnorr in '..\..\CryptoLib\src\Interfaces\ClpISchnorr.pas',
+  ClpECSchnorrSipaSigner in '..\..\CryptoLib\src\Crypto\Signers\ClpECSchnorrSipaSigner.pas',
+  ClpIECSchnorrSipaSigner in '..\..\CryptoLib\src\Interfaces\ClpIECSchnorrSipaSigner.pas',
+  ClpISchnorrExt in '..\..\CryptoLib\src\Interfaces\ClpISchnorrExt.pas',
+  ClpISchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpISchnorrEncoding.pas',
+  ClpIPlainSchnorrEncoding in '..\..\CryptoLib\src\Interfaces\ClpIPlainSchnorrEncoding.pas',
+  ClpPlainSchnorrEncoding in '..\..\CryptoLib\src\Crypto\Signers\ClpPlainSchnorrEncoding.pas',
+  ClpBlowfishEngine in '..\..\CryptoLib\src\Crypto\Engines\ClpBlowfishEngine.pas',
+  ClpIBlowfishEngine in '..\..\CryptoLib\src\Interfaces\ClpIBlowfishEngine.pas',
+  BlowfishTestVectors in '..\src\Crypto\BlowfishTestVectors.pas';
 
 begin
 

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

@@ -36,7 +36,7 @@
         <PackageName Value="FCL"/>
       </Item4>
     </RequiredPackages>
-    <Units Count="47">
+    <Units Count="48">
       <Unit0>
         <Filename Value="CryptoLib.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -226,6 +226,10 @@
         <Filename Value="..\src\Asn1\TagTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit46>
+      <Unit47>
+        <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit47>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

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

@@ -32,6 +32,7 @@ uses
   BlockCipherVectorTests,
   BlockCipherMonteCarloTests,
   AESTestVectors,
+  BlowfishTestVectors,
   AESSICTests,
   IESCipherTests,
   MD5HMacTests,

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

@@ -37,7 +37,7 @@
         <PackageName Value="FCL"/>
       </Item2>
     </RequiredPackages>
-    <Units Count="47">
+    <Units Count="48">
       <Unit0>
         <Filename Value="CryptoLibConsole.lpr"/>
         <IsPartOfProject Value="True"/>
@@ -226,6 +226,10 @@
         <Filename Value="..\src\Asn1\TagTests.pas"/>
         <IsPartOfProject Value="True"/>
       </Unit46>
+      <Unit47>
+        <Filename Value="..\src\Crypto\BlowfishTestVectors.pas"/>
+        <IsPartOfProject Value="True"/>
+      </Unit47>
     </Units>
   </ProjectOptions>
   <CompilerOptions>

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

@@ -30,6 +30,7 @@ uses
   BlockCipherVectorTests,
   BlockCipherMonteCarloTests,
   AESTestVectors,
+  BlowfishTestVectors,
   AESSICTests,
   IESCipherTests,
   MD5HMacTests,

+ 2 - 6
CryptoLib.Tests/src/Asn1/StringTests.pas

@@ -31,12 +31,12 @@ uses
 {$ELSE}
   TestFramework,
 {$ENDIF FPC}
+  ClpDerT61String,
+  ClpIDerT61String,
   ClpDerBitString,
   ClpIDerBitString,
   ClpDerUniversalString,
   ClpIDerUniversalString,
-  ClpDerT61String,
-  ClpIDerT61String,
   ClpConverters;
 
 type
@@ -152,10 +152,6 @@ begin
     Fail('DerT61String.GetString() result incorrect');
   end;
 
-  if (not(t61.ToString() = (t61String))) then
-  begin
-    Fail('DerT61String.ToString() result incorrect');
-  end;
 end;
 
 initialization

+ 9 - 6
CryptoLib.Tests/src/Asn1/TagTests.pas

@@ -99,7 +99,7 @@ var
   app: IDerApplicationSpecific;
   tagged: IAsn1TaggedObject;
   sr: ISecureRandom;
-  TestTag, I: Int32;
+  LTestTag, I: Int32;
 begin
 
   aIn := TAsn1InputStream.Create(FlongTagged);
@@ -172,19 +172,22 @@ begin
 
   sr := TSecureRandom.Create();
 
-  for I := 0 to System.Pred(100) do
+  I := 0;
+  while I < 100 do
   begin
-    TestTag := TBits.Asr32(sr.NextInt32() and System.High(Int32), sr.Next(26));
-    app := TDerApplicationSpecific.Create(TestTag, TBytes.Create(1));
+    LTestTag := TBits.Asr32(sr.NextInt32() and System.High(Int32), sr.Next(26));
+    app := TDerApplicationSpecific.Create(LTestTag, TBytes.Create(1));
     app := TAsn1Object.FromByteArray(app.GetEncoded())
       as IDerApplicationSpecific;
 
-    if (app.ApplicationTag <> TestTag) then
+    if (app.ApplicationTag <> LTestTag) then
     begin
       Fail(Format
         ('incorrect tag number read on recode (random test value: " %d ")',
-        [TestTag]));
+        [LTestTag]));
     end;
+
+    System.Inc(I);
   end;
 end;
 

+ 20 - 0
CryptoLib.Tests/src/Crypto/BlockCipherVectorTests.pas

@@ -32,12 +32,15 @@ uses
   TestFramework,
 {$ENDIF FPC}
   AESTestVectors,
+  BlowfishTestVectors,
   ClpIBlockCipher,
   ClpICipherParameters,
   ClpAesEngine,
   ClpIAesEngine,
   ClpAesLightEngine,
   ClpIAesLightEngine,
+  ClpBlowfishEngine,
+  ClpIBlowfishEngine,
   ClpKeyParameter,
   ClpIKeyParameter,
   ClpParametersWithIV,
@@ -74,6 +77,7 @@ type
 
     procedure TestBlockCipherAESEngine;
     procedure TestBlockCipherAESLightEngine;
+    procedure TestBlockCipherBlowfishEngine;
     procedure TestBadParameters;
 
   end;
@@ -229,6 +233,22 @@ begin
 
 end;
 
+procedure TTestBlockCipherVector.TestBlockCipherBlowfishEngine;
+var
+  I: Int32;
+begin
+  for I := System.Low(TBlowfishTestVectors.FBlockCipherVectorKeys)
+    to System.High(TBlowfishTestVectors.FBlockCipherVectorKeys) do
+  begin
+    DoBlockCipherVectorTest(TBlowfishEngine.Create() as IBlowfishEngine,
+      TKeyParameter.Create
+      (THex.Decode(TBlowfishTestVectors.FBlockCipherVectorKeys[I]))
+      as IKeyParameter, TBlowfishTestVectors.FBlockCipherVectorInputs[I],
+      TBlowfishTestVectors.FBlockCipherVectorOutputs[I]);
+  end;
+
+end;
+
 initialization
 
 // Register any test cases with the test runner

+ 80 - 0
CryptoLib.Tests/src/Crypto/BlowfishTestVectors.pas

@@ -0,0 +1,80 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit BlowfishTestVectors;
+
+interface
+
+{$IFDEF FPC}
+{$MODE DELPHI}
+{$ENDIF FPC}
+
+uses
+  ClpCryptoLibTypes;
+
+type
+  /// <remarks>Blowfish tester - vectors from http://www.counterpane.com/vectors.txt</remarks>
+  TBlowfishTestVectors = class sealed(TObject)
+
+  public
+    class var
+
+      FBlockCipherVectorKeys, FBlockCipherVectorInputs,
+      FBlockCipherVectorOutputs: TCryptoLibStringArray;
+
+    class constructor BlowfishTestVectors();
+
+  end;
+
+implementation
+
+{ TBlowfishTestVectors }
+
+class constructor TBlowfishTestVectors.BlowfishTestVectors;
+begin
+
+  /// <remarks>Blowfish tester - vectors from http://www.counterpane.com/vectors.txt</remarks>
+  FBlockCipherVectorKeys := TCryptoLibStringArray.Create
+
+    (
+
+    '0000000000000000', 'FFFFFFFFFFFFFFFF',
+
+    '3000000000000000',
+
+    '1111111111111111', '0123456789ABCDEF', 'FEDCBA9876543210',
+    '7CA110454A1A6E57', '0131D9619DC1376E');
+
+  FBlockCipherVectorInputs := TCryptoLibStringArray.Create('0000000000000000',
+    'FFFFFFFFFFFFFFFF',
+
+    '1000000000000001',
+
+    '1111111111111111', '1111111111111111', '0123456789ABCDEF',
+    '01A1D6D039776742', '5CD54CA83DEF57DA');
+
+  FBlockCipherVectorOutputs := TCryptoLibStringArray.Create('4EF997456198DD78',
+    '51866FD5B85ECB8A',
+
+    '7D856F9A613063F2',
+
+    '2466DD878B963C9D', '61F9C3802281B096', '0ACEAB0FC6A0A28D',
+    '59C68245EB05282B', 'B1B8CC0B250F09A0');
+
+end;
+
+end.

+ 3 - 3
CryptoLib.Tests/src/Crypto/PaddingTests.pas

@@ -250,7 +250,7 @@ begin
 
   if (ffVector <> Nil) then
   begin
-    padding.addPadding(data, 3);
+    padding.AddPadding(data, 3);
 
     if (not TArrayUtils.AreEqual(data, ffVector)) then
     begin
@@ -263,8 +263,8 @@ begin
   //
   if (ZeroVector <> Nil) then
   begin
-    System.FillChar(data[0], 8 * System.SizeOf(Byte), Byte(0));
-    padding.addPadding(data, 4);
+    TArrayUtils.Fill(data, 0, 8, Byte(0));
+    padding.AddPadding(data, 4);
 
     if (not TArrayUtils.AreEqual(data, ZeroVector)) then
     begin

+ 0 - 1
CryptoLib.Tests/src/Math/EC/Custom/Sec/SecP384R1FieldTests.pas

@@ -147,7 +147,6 @@ begin
   inherited;
   FRandom := TSecureRandom.Create();
   FDP := TCustomNamedCurves.GetByOid(TSecObjectIdentifiers.SecP384r1);
-
   FQ := FDP.Curve.Field.Characteristic;
 end;
 

+ 19 - 19
CryptoLib.Tests/src/Math/ECIESTests.pas

@@ -190,8 +190,8 @@ begin
 
   &message := THex.Decode('1234567890abcdef');
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin
@@ -235,9 +235,9 @@ begin
 
   &message := THex.Decode('1234567890abcdef');
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
 
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin
@@ -311,19 +311,19 @@ begin
 
   &message := Nil;
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin
     Fail('stream cipher test failed');
   end;
 
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   try
 
-    i2.processBlock(out1, 0, System.Length(out1) - 1);
+    i2.ProcessBlock(out1, 0, System.Length(out1) - 1);
     Fail('Expected EInvalidCipherTextCryptoLibException');
 
   except
@@ -355,8 +355,8 @@ begin
   i2.Init(p2.Private, p, TECIESPublicKeyParser.Create(params)
     as IECIESPublicKeyParser);
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin
@@ -365,7 +365,7 @@ begin
 
   try
 
-    i2.processBlock(out1, 0, System.Length(out1) - 1);
+    i2.ProcessBlock(out1, 0, System.Length(out1) - 1);
     Fail('Expected EInvalidCipherTextCryptoLibException');
 
   except
@@ -448,7 +448,7 @@ begin
 
   &message := THex.Decode('1234567890abcdef');
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
 
   if (not TArrayUtils.AreEqual(out1,
     THex.Decode('468d89877e8238802403ec4cb6b329faeccfa6f3a730f2cdb3c0a8e8')))
@@ -457,7 +457,7 @@ begin
     Fail('stream cipher test failed on enc');
   end;
 
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin
@@ -500,7 +500,7 @@ begin
 
   &message := THex.Decode('1234567890abcdef');
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
 
   if iv = Nil then
   begin
@@ -518,7 +518,7 @@ begin
     Fail('AES cipher test failed on enc');
   end;
 
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin
@@ -556,9 +556,9 @@ begin
 
   &message := THex.Decode('1234567890abcdef');
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
 
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin
@@ -596,9 +596,9 @@ begin
 
   &message := THex.Decode('1234567890abcdef');
 
-  out1 := i1.processBlock(&message, 0, System.Length(&message));
+  out1 := i1.ProcessBlock(&message, 0, System.Length(&message));
 
-  out2 := i2.processBlock(out1, 0, System.Length(out1));
+  out2 := i2.ProcessBlock(out1, 0, System.Length(out1));
 
   if (not TArrayUtils.AreEqual(out2, &message)) then
   begin

+ 197 - 153
CryptoLib.Tests/src/Others/ECSchnorrTests.pas

@@ -24,7 +24,6 @@ interface
 {$ENDIF FPC}
 
 uses
-  Classes,
   SysUtils,
 {$IFDEF FPC}
   fpcunit,
@@ -34,7 +33,6 @@ uses
 {$ENDIF FPC}
   ClpSecureRandom,
   ClpISecureRandom,
-  ClpFixedSecureRandom,
   ClpISigner,
   ClpECPublicKeyParameters,
   ClpIECPublicKeyParameters,
@@ -55,6 +53,8 @@ uses
   ClpCryptoLibTypes,
   ClpBigInteger,
   ClpSignerUtilities,
+  ClpHex,
+  ClpArrayUtils,
   ClpConverters;
 
 type
@@ -73,17 +73,20 @@ type
 
   var
     FRandom: ISecureRandom;
+    FECSchnorrSipaSigningPassTestVector,
+      FECSchnorrSipaVerificationPassTestVector,
+      FECSchnorrSipaVerificationFailTestVector
+      : TCryptoLibGenericArray<TCryptoLibStringArray>;
 
   protected
     procedure SetUp; override;
     procedure TearDown; override;
   published
 
-    procedure TestECSchnorrWithCustomK;
-    procedure TestECSchnorrBSI;
-    procedure TestECSchnorrISO;
-    procedure TestECSchnorrISOX;
-    procedure TestECSchnorrLIBSECP;
+    procedure TestECSchnorrSIPASigningShouldPass;
+    procedure TestECSchnorrSIPAVerificationShouldPass;
+    procedure TestECSchnorrSIPAVerificationShouldFail;
+    procedure TestECSchnorrSIPASigningandVerifyingSecp521R1;
 
   end;
 
@@ -95,6 +98,97 @@ procedure TTestECSchnorr.SetUp;
 begin
   inherited;
   FRandom := TSecureRandom.Create();
+  FECSchnorrSipaSigningPassTestVector :=
+    TCryptoLibGenericArray<TCryptoLibStringArray>.Create
+    (TCryptoLibStringArray.Create('Test vector 1',
+    '0000000000000000000000000000000000000000000000000000000000000001',
+    '0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798',
+    '0000000000000000000000000000000000000000000000000000000000000000',
+    '787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF67031A98831859DC34DFFEEDDA86831842CCD0079E1F92AF177F7F22CC1DCED05'),
+
+    TCryptoLibStringArray.Create('Test vector 2',
+    'B7E151628AED2A6ABF7158809CF4F3C762E7160F38B4DA56A784D9045190CFEF',
+    '02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659',
+    '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
+    '2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD'),
+    TCryptoLibStringArray.Create('Test vector 3',
+    'C90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B14E5C7',
+    '03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B',
+    '5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C',
+    '00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BE00880371D01766935B92D2AB4CD5C8A2A5837EC57FED7660773A05F0DE142380')
+    );
+
+  FECSchnorrSipaVerificationPassTestVector :=
+    TCryptoLibGenericArray<TCryptoLibStringArray>.Create
+    (TCryptoLibStringArray.Create('Test vector 4A',
+    '03DEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34',
+    '4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703',
+    '00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6302A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D'),
+
+    TCryptoLibStringArray.Create('Test vector 4B',
+    '031B84C5567B126440995D3ED5AABA0565D71E1834604819FF9C17F5E9D5DD078F',
+    '0000000000000000000000000000000000000000000000000000000000000000',
+    '52818579ACA59767E3291D91B76B637BEF062083284992F2D95F564CA6CB4E3530B1DA849C8E8304ADC0CFE870660334B3CFC18E825EF1DB34CFAE3DFC5D8187')
+    );
+
+  FECSchnorrSipaVerificationFailTestVector :=
+    TCryptoLibGenericArray<TCryptoLibStringArray>.Create(
+
+    TCryptoLibStringArray.Create('Test vector 5',
+    '03EEFDEA4CDB677750A420FEE807EACF21EB9898AE79B9768766E4FAA04A2D4A34',
+    '4DF3C3F68FCC83B27E9D42C90431A72499F17875C81A599B566C9889B9696703',
+    '00000000000000000000003B78CE563F89A0ED9414F5AA28AD0D96D6795F9C6302A8DC32E64E86A333F20EF56EAC9BA30B7246D6D25E22ADB8C6BE1AEB08D49D',
+    'public key not on the curve'),
+
+    TCryptoLibStringArray.Create('Test vector 6',
+    '02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659',
+    '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
+    '2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFA16AEE06609280A19B67A24E1977E4697712B5FD2943914ECD5F730901B4AB7',
+    'incorrect R residuosity'),
+
+    TCryptoLibStringArray.Create('Test vector 7',
+    '03FAC2114C2FBB091527EB7C64ECB11F8021CB45E8E7809D3C0938E4B8C0E5F84B',
+    '5E2D58D8B3BCDF1ABADEC7829054F90DDA9805AAB56C77333024B9D0A508B75C',
+    '00DA9B08172A9B6F0466A2DEFD817F2D7AB437E0D253CB5395A963866B3574BED092F9D860F1776A1F7412AD8A1EB50DACCC222BC8C0E26B2056DF2F273EFDEC',
+    'negated message hash'),
+
+    TCryptoLibStringArray.Create('Test vector 8',
+    '0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798',
+    '0000000000000000000000000000000000000000000000000000000000000000',
+    '787A848E71043D280C50470E8E1532B2DD5D20EE912A45DBDD2BD1DFBF187EF68FCE5677CE7A623CB20011225797CE7A8DE1DC6CCD4F754A47DA6C600E59543C',
+    'negated s value'),
+
+    TCryptoLibStringArray.Create('Test vector 9',
+    '03DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659',
+    '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
+    '2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD',
+    'negated public key'),
+
+    TCryptoLibStringArray.Create('Test vector 10',
+    '02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659',
+    '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
+    '2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D8C3428869A663ED1E954705B020CBB3E7BB6AC31965B9EA4C73E227B17C5AF5A',
+    'sG - eP is infinite'),
+
+    TCryptoLibStringArray.Create('Test vector 11',
+    '02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659',
+    '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
+    '4A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1D1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD',
+    'sig[0:32] is not an X coordinate on the curve'),
+
+    TCryptoLibStringArray.Create('Test vector 12',
+    '02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659',
+    '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
+    'FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC2F1E51A22CCEC35599B8F266912281F8365FFC2D035A230434A1A64DC59F7013FD',
+    'sig[0:32] is equal to field size'),
+
+    TCryptoLibStringArray.Create('Test vector 13',
+    '02DFF1D77F2A671C5F36183726DB2341BE58FEAE1DA2DECED843240F7B502BA659',
+    '243F6A8885A308D313198A2E03707344A4093822299F31D0082EFA98EC4E6C89',
+    '2A298DACAE57395A15D0795DDBFD1DCB564DA82B0F269BC70A74F8220429BA1DFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141',
+    'sig[32:64] is equal to curve order')
+
+    );
 end;
 
 procedure TTestECSchnorr.TearDown;
@@ -103,7 +197,7 @@ begin
 
 end;
 
-procedure TTestECSchnorr.TestECSchnorrBSI;
+procedure TTestECSchnorr.TestECSchnorrSIPASigningandVerifyingSecp521R1;
 var
   LCurve: IX9ECParameters;
   domain: IECDomainParameters;
@@ -117,7 +211,7 @@ var
 
 begin
 
-  LCurve := TSecNamedCurves.GetByName('secp256k1');
+  LCurve := TSecNamedCurves.GetByName('secp521r1');
 
   domain := TECDomainParameters.Create(LCurve.Curve, LCurve.G, LCurve.N,
     LCurve.H, LCurve.GetSeed);
@@ -129,7 +223,7 @@ begin
   privParams := keypair.Private as IECPrivateKeyParameters; // for signing
   pubParams := keypair.Public as IECPublicKeyParameters; // for verifying
 
-  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRBSI');
+  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRSIPA');
 
   // sign
 
@@ -152,165 +246,141 @@ begin
 
 end;
 
-procedure TTestECSchnorr.TestECSchnorrISO;
+procedure TTestECSchnorr.TestECSchnorrSIPASigningShouldPass;
 var
-  LCurve: IX9ECParameters;
   domain: IECDomainParameters;
-  generator: IECKeyPairGenerator;
-  keygenParams: IECKeyGenerationParameters;
-  keypair: IAsymmetricCipherKeyPair;
-  privParams: IECPrivateKeyParameters;
-  pubParams: IECPublicKeyParameters;
+  RegeneratedPrivateKey: IECPrivateKeyParameters;
+  RegeneratedPublicKey: IECPublicKeyParameters;
+  PrivateKeyByteArray, PublicKeyByteArray, &message, sigBytes,
+    expectedSignature: TBytes;
+  point: IECPoint;
+  LCurve: IX9ECParameters;
   signer: ISigner;
-  &message, sigBytes: TBytes;
-
+  param: IParametersWithRandom;
+  vector: TCryptoLibStringArray;
 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
+  for vector in FECSchnorrSipaSigningPassTestVector do
+  begin
 
-  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRISO');
+    PrivateKeyByteArray := TBigInteger.Create(vector[1], 16).ToByteArray;
+    PublicKeyByteArray := TBigInteger.Create(vector[2], 16).ToByteArray;
+    &message := THex.Decode(vector[3]);
+    expectedSignature := THex.Decode(vector[4]);
 
-  // sign
+    point := LCurve.Curve.DecodePoint(PublicKeyByteArray);
 
-  signer.Init(true, privParams);
+    RegeneratedPrivateKey := TECPrivateKeyParameters.Create('ECSCHNORR',
+      TBigInteger.Create(PrivateKeyByteArray), domain);
 
-  &message := TConverters.ConvertStringToBytes('PascalECSCHNORR',
-    TEncoding.UTF8);
+    RegeneratedPublicKey := TECPublicKeyParameters.Create('ECSCHNORR',
+      point, domain);
 
-  signer.BlockUpdate(&message, 0, System.Length(&message));
+    param := TParametersWithRandom.Create(RegeneratedPrivateKey, FRandom);
 
-  sigBytes := signer.GenerateSignature();
+    signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRSIPA');
 
-  // verify
+    // sign
 
-  signer.Init(false, pubParams);
+    signer.Init(true, param);
 
-  signer.BlockUpdate(&message, 0, System.Length(&message));
+    signer.BlockUpdate(&message, 0, System.Length(&message));
 
-  CheckTrue(signer.VerifySignature(sigBytes));
+    sigBytes := signer.GenerateSignature();
 
-end;
+    CheckTrue(TArrayUtils.AreEqual(expectedSignature, sigBytes),
+      vector[0] + ' Signature did not match Output');
 
-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);
+    // verify
 
-  keypair := generator.GenerateKeyPair();
-  privParams := keypair.Private as IECPrivateKeyParameters; // for signing
-  pubParams := keypair.Public as IECPublicKeyParameters; // for verifying
+    signer.Init(false, RegeneratedPublicKey);
 
-  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRISOX');
-
-  // sign
-
-  signer.Init(true, privParams);
-
-  &message := TConverters.ConvertStringToBytes('PascalECSCHNORR',
-    TEncoding.UTF8);
+    signer.BlockUpdate(&message, 0, System.Length(&message));
 
-  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));
+    CheckTrue(signer.VerifySignature(sigBytes),
+      vector[0] + ' Signature verification Failed');
+  end;
 
 end;
 
-procedure TTestECSchnorr.TestECSchnorrLIBSECP;
+procedure TTestECSchnorr.TestECSchnorrSIPAVerificationShouldFail;
 var
-  LCurve: IX9ECParameters;
   domain: IECDomainParameters;
-  generator: IECKeyPairGenerator;
-  keygenParams: IECKeyGenerationParameters;
-  keypair: IAsymmetricCipherKeyPair;
-  privParams: IECPrivateKeyParameters;
-  pubParams: IECPublicKeyParameters;
+  RegeneratedPublicKey: IECPublicKeyParameters;
+  PublicKeyByteArray, &message, expectedSignature: TBytes;
+  point: IECPoint;
+  LCurve: IX9ECParameters;
   signer: ISigner;
-  &message, sigBytes: TBytes;
-
+  vector: TCryptoLibStringArray;
 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
+  for vector in FECSchnorrSipaVerificationFailTestVector do
+  begin
 
-  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRLIBSECP');
+    PublicKeyByteArray := TBigInteger.Create(vector[1], 16).ToByteArray;
+    &message := THex.Decode(vector[2]);
+    expectedSignature := THex.Decode(vector[3]);
 
-  // sign
+    if vector[0] = 'Test vector 5' then
+    begin
 
-  signer.Init(true, privParams);
+      try
+        point := LCurve.Curve.DecodePoint(PublicKeyByteArray);
+        Fail(vector[4]);
+      except
+        on E: EArgumentCryptoLibException do
+        begin
 
-  &message := TConverters.ConvertStringToBytes('PascalECSCHNORR',
-    TEncoding.UTF8);
+          if E.Message <> 'Invalid Point Compression' then
+          begin
+            Fail('Invalid Exception Thrown');
+          end;
+          Continue;
+        end;
 
-  signer.BlockUpdate(&message, 0, System.Length(&message));
+      end;
 
-  sigBytes := signer.GenerateSignature();
+    end
+    else
+    begin
+      point := LCurve.Curve.DecodePoint(PublicKeyByteArray);
+    end;
 
-  // verify
+    RegeneratedPublicKey := TECPublicKeyParameters.Create('ECSCHNORR',
+      point, domain);
 
-  signer.Init(false, pubParams);
+    signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRSIPA');
 
-  signer.BlockUpdate(&message, 0, System.Length(&message));
+    // verify
 
-  CheckTrue(signer.VerifySignature(sigBytes));
+    signer.Init(false, RegeneratedPublicKey);
+
+    signer.BlockUpdate(&message, 0, System.Length(&message));
+
+    CheckFalse(signer.VerifySignature(expectedSignature), vector[4]);
+  end;
 
 end;
 
-procedure TTestECSchnorr.TestECSchnorrWithCustomK;
+procedure TTestECSchnorr.TestECSchnorrSIPAVerificationShouldPass;
 var
   domain: IECDomainParameters;
-  RegeneratedPrivateKey: IECPrivateKeyParameters;
   RegeneratedPublicKey: IECPublicKeyParameters;
-  BigXCoordByteArray, BigYCoordByteArray, PrivateKeyByteArray, &message,
-    sigBytes: TBytes;
+  PublicKeyByteArray, &message, expectedSignature: TBytes;
   point: IECPoint;
   LCurve: IX9ECParameters;
   signer: ISigner;
-  k: ISecureRandom;
-  param: IParametersWithRandom;
+  vector: TCryptoLibStringArray;
 begin
 
   LCurve := TSecNamedCurves.GetByName('secp256k1');
@@ -318,55 +388,29 @@ begin
   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;
+  for vector in FECSchnorrSipaVerificationPassTestVector do
+  begin
 
-  PrivateKeyByteArray := TBigInteger.Create
-    ('fb26a4e75eec75544c0f44e937dcf5ee6355c7176600b9688c667e5c283b43c5', 16)
-    .ToByteArray;
+    PublicKeyByteArray := TBigInteger.Create(vector[1], 16).ToByteArray;
+    &message := THex.Decode(vector[2]);
+    expectedSignature := THex.Decode(vector[3]);
 
-  point := LCurve.Curve.CreatePoint(TBigInteger.Create(1, BigXCoordByteArray),
-    TBigInteger.Create(1, BigYCoordByteArray));
+    point := LCurve.Curve.DecodePoint(PublicKeyByteArray);
 
-  RegeneratedPublicKey := TECPublicKeyParameters.Create('ECSCHNORR',
-    point, domain);
+    RegeneratedPublicKey := TECPublicKeyParameters.Create('ECSCHNORR',
+      point, domain);
 
-  RegeneratedPrivateKey := TECPrivateKeyParameters.Create('ECSCHNORR',
-    TBigInteger.Create(PrivateKeyByteArray), domain);
+    signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRSIPA');
 
-  k := TFixedSecureRandom.From(TCryptoLibMatrixByteArray.Create
-    (TBigInteger.Create
-    ('4242424242424242424242424242424242424242424242424242424242424242',
-    16).ToByteArrayUnsigned()));
+    // verify
 
-  param := TParametersWithRandom.Create(RegeneratedPrivateKey, k);
+    signer.Init(false, RegeneratedPublicKey);
 
-  signer := TSignerUtilities.GetSigner('SHA-256withECSCHNORRLIBSECP');
+    signer.BlockUpdate(&message, 0, System.Length(&message));
 
-  // sign
-
-  signer.Init(true, param);
-
-  &message := TBigInteger.Create
-    ('0101010101010101010101010101010101010101010101010101010101010101', 16)
-    .ToByteArray;
-
-  signer.BlockUpdate(&message, 0, System.Length(&message));
-
-  sigBytes := signer.GenerateSignature();
-
-  // verify
-
-  signer.Init(false, RegeneratedPublicKey);
-
-  signer.BlockUpdate(&message, 0, System.Length(&message));
-
-  CheckTrue(signer.VerifySignature(sigBytes));
+    CheckTrue(signer.VerifySignature(expectedSignature),
+      vector[0] + ' Signature verification Failed');
+  end;
 
 end;
 

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

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

+ 3 - 4
CryptoLib.Tests/src/Security/SecureRandomTests.pas

@@ -82,8 +82,7 @@ function TTestSecureRandom.MeasureChiSquared(const random: ISecureRandom;
 var
   opts, bs: TCryptoLibByteArray;
   counts: TCryptoLibInt32Array;
-  I, b, total, k: Integer;
-  mask, shift: Byte;
+  I, b, total, k, mask, shift: Int32;
   chi2, diff, diff2, temp: Double;
 begin
   opts := random.GenerateSeed(2);
@@ -115,7 +114,7 @@ begin
     for b := 0 to System.Pred(256) do
     begin
 
-      counts[bs[b] xor mask] := counts[bs[b] xor mask] + 1;
+      counts[bs[b] xor Byte(mask)] := counts[bs[b] xor Byte(mask)] + 1;
 
     end;
     System.Inc(mask);
@@ -132,7 +131,7 @@ begin
     for b := 0 to System.Pred(256) do
     begin
 
-      counts[Byte(bs[b] + shift)] := counts[Byte(bs[b] + shift)] + 1;
+      counts[Byte(bs[b] + Byte(shift))] := counts[Byte(bs[b] + Byte(shift))] + 1;
 
     end;
     System.Inc(shift);

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

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

+ 1 - 1
CryptoLib/src/Asn1/ClpAsn1Object.pas

@@ -62,7 +62,7 @@ type
 
     function ToAsn1Object(): IAsn1Object; override;
 
-    procedure Encode(const derOut: IDerOutputStream); virtual; abstract;
+    procedure Encode(const derOut: TStream); virtual; abstract;
 
     function CallAsn1Equals(const obj: IAsn1Object): Boolean;
 

+ 1 - 1
CryptoLib/src/Asn1/ClpAsn1Sequence.pas

@@ -200,7 +200,7 @@ begin
   l1 := GetEnumerable;
   l2 := other.GetEnumerable;
 
-  for Idx := Low(l1) to High(l1) do
+  for Idx := System.Low(l1) to System.High(l1) do
   begin
     o1 := GetCurrent(l1[Idx]).ToAsn1Object();
     o2 := GetCurrent(l2[Idx]).ToAsn1Object();

+ 1 - 1
CryptoLib/src/Asn1/ClpAsn1Set.pas

@@ -209,7 +209,7 @@ begin
   l1 := GetEnumerable;
   l2 := other.GetEnumerable;
 
-  for Idx := Low(l1) to High(l1) do
+  for Idx := System.Low(l1) to System.High(l1) do
   begin
     o1 := GetCurrent(l1[Idx]).ToAsn1Object();
     o2 := GetCurrent(l2[Idx]).ToAsn1Object();

+ 6 - 3
CryptoLib/src/Asn1/ClpBerBitString.pas

@@ -22,10 +22,12 @@ unit ClpBerBitString;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpCryptoLibTypes,
   ClpAsn1OutputStream,
   ClpBerOutputStream,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpDerBitString,
   ClpIBerBitString,
@@ -41,7 +43,7 @@ type
     constructor Create(namedBits: Int32); overload;
     constructor Create(const obj: IAsn1Encodable); overload;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
   end;
 
@@ -70,11 +72,12 @@ begin
   Inherited Create(namedBits);
 end;
 
-procedure TBerBitString.Encode(const derOut: IDerOutputStream);
+procedure TBerBitString.Encode(const derOut: TStream);
 begin
   if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
   begin
-    derOut.WriteEncoded(TAsn1Tags.BitString, Byte(mPadBits), mData);
+    (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BitString,
+      Byte(mPadBits), mData);
   end
   else
   begin

+ 5 - 4
CryptoLib/src/Asn1/ClpBerNull.pas

@@ -22,12 +22,13 @@ unit ClpBerNull;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpAsn1Tags,
   ClpAsn1OutputStream,
   ClpBerOutputStream,
+  ClpDerOutputStream,
   ClpDerNull,
-  ClpIProxiedInterface,
   ClpIBerNull;
 
 type
@@ -51,7 +52,7 @@ type
 
   public
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
     class property Instance: IBerNull read GetInstance;
 
   end;
@@ -70,12 +71,12 @@ begin
   FInstance := TBerNull.Create(0);
 end;
 
-procedure TBerNull.Encode(const derOut: IDerOutputStream);
+procedure TBerNull.Encode(const derOut: TStream);
 begin
 
   if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
   begin
-    derOut.WriteByte(TAsn1Tags.Null);
+    (derOut as TDerOutputStream).WriteByte(TAsn1Tags.Null);
   end
   else
   begin

+ 9 - 7
CryptoLib/src/Asn1/ClpBerOctetString.pas

@@ -32,6 +32,7 @@ uses
   ClpAsn1Tags,
   ClpAsn1OutputStream,
   ClpBerOutputStream,
+  ClpDerOutputStream,
   ClpIBerOctetString,
   ClpIDerOctetString,
   ClpDerOctetString;
@@ -69,7 +70,7 @@ type
     /// </summary>
     function GetEnumerable: TCryptoLibGenericArray<IDerOctetString>; virtual;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     class function FromSequence(const seq: IAsn1Sequence)
       : IBerOctetString; static;
@@ -107,16 +108,17 @@ begin
   Inherited Create(obj);
 end;
 
-procedure TBerOctetString.Encode(const derOut: IDerOutputStream);
+procedure TBerOctetString.Encode(const derOut: TStream);
 var
   oct: IDerOctetString;
   LListIDerOctetString: TCryptoLibGenericArray<IDerOctetString>;
 begin
   if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
   begin
-    derOut.WriteByte(TAsn1Tags.Constructed or TAsn1Tags.OctetString);
+    (derOut as TDerOutputStream).WriteByte(TAsn1Tags.Constructed or
+      TAsn1Tags.OctetString);
 
-    derOut.WriteByte($80);
+    (derOut as TDerOutputStream).WriteByte($80);
 
     //
     // write out the octet array
@@ -124,11 +126,11 @@ begin
     LListIDerOctetString := Self.GetEnumerable;
     for oct in LListIDerOctetString do
     begin
-      derOut.WriteObject(oct);
+      (derOut as TDerOutputStream).WriteObject(oct);
     end;
 
-    derOut.WriteByte($00);
-    derOut.WriteByte($00);
+    (derOut as TDerOutputStream).WriteByte($00);
+    (derOut as TDerOutputStream).WriteByte($00);
   end
   else
   begin

+ 8 - 7
CryptoLib/src/Asn1/ClpBerSequence.pas

@@ -29,6 +29,7 @@ uses
   ClpDerSequence,
   ClpAsn1OutputStream,
   ClpBerOutputStream,
+  ClpDerOutputStream,
   ClpIAsn1EncodableVector,
   ClpIBerSequence,
   ClpCryptoLibTypes;
@@ -76,7 +77,7 @@ type
     /// just outputing Sequence, <br />we also have to specify Constructed,
     /// and the objects length. <br />
     /// </summary>
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     class property Empty: IBerSequence read GetEmpty;
 
@@ -122,7 +123,7 @@ begin
   FEmpty := TBerSequence.Create();
 end;
 
-procedure TBerSequence.Encode(const derOut: IDerOutputStream);
+procedure TBerSequence.Encode(const derOut: TStream);
 var
   o: IAsn1Encodable;
   LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
@@ -130,17 +131,17 @@ begin
 
   if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
   begin
-    derOut.WriteByte(TAsn1Tags.Sequence or TAsn1Tags.Constructed);
-    derOut.WriteByte($80);
+    (derOut as TDerOutputStream).WriteByte(TAsn1Tags.Sequence or TAsn1Tags.Constructed);
+    (derOut as TDerOutputStream).WriteByte($80);
 
     LListAsn1Encodable := Self.GetEnumerable;
     for o in LListAsn1Encodable do
     begin
-      derOut.WriteObject(o);
+      (derOut as TDerOutputStream).WriteObject(o);
     end;
 
-    derOut.WriteByte($00);
-    derOut.WriteByte($00);
+    (derOut as TDerOutputStream).WriteByte($00);
+    (derOut as TDerOutputStream).WriteByte($00);
   end
   else
   begin

+ 9 - 7
CryptoLib/src/Asn1/ClpBerSet.pas

@@ -29,6 +29,7 @@ uses
   ClpIBerSet,
   ClpAsn1OutputStream,
   ClpBerOutputStream,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpIAsn1EncodableVector,
   ClpCryptoLibTypes;
@@ -81,7 +82,7 @@ type
     /// just outputing Set, <br />we also have to specify Constructed, and
     /// the objects length. <br />
     /// </summary>
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     class property Empty: IBerSet read GetEmpty;
 
@@ -128,25 +129,26 @@ begin
   FEmpty := TBerSet.Create();
 end;
 
-procedure TBerSet.Encode(const derOut: IDerOutputStream);
+procedure TBerSet.Encode(const derOut: TStream);
 var
   o: IAsn1Encodable;
   LListAsn1Encodable: TCryptoLibGenericArray<IAsn1Encodable>;
 begin
   if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
   begin
-    derOut.WriteByte(TAsn1Tags.&Set or TAsn1Tags.Constructed);
+    (derOut as TDerOutputStream).WriteByte(TAsn1Tags.&Set or
+      TAsn1Tags.Constructed);
 
-    derOut.WriteByte($80);
+    (derOut as TDerOutputStream).WriteByte($80);
 
     LListAsn1Encodable := Self.GetEnumerable;
     for o in LListAsn1Encodable do
     begin
-      derOut.WriteObject(o);
+      (derOut as TDerOutputStream).WriteObject(o);
     end;
 
-    derOut.WriteByte($00);
-    derOut.WriteByte($00);
+    (derOut as TDerOutputStream).WriteByte($00);
+    (derOut as TDerOutputStream).WriteByte($00);
   end
   else
   begin

+ 11 - 8
CryptoLib/src/Asn1/ClpBerTaggedObject.pas

@@ -22,6 +22,7 @@ unit ClpBerTaggedObject;
 interface
 
 uses
+  Classes,
   SysUtils,
   Generics.Collections,
   ClpCryptoLibTypes,
@@ -33,6 +34,7 @@ uses
   ClpBerSequence,
   ClpAsn1OutputStream,
   ClpBerOutputStream,
+  ClpDerOutputStream,
   ClpIAsn1OctetString,
   ClpAsn1Encodable,
   ClpBerOctetString,
@@ -86,7 +88,7 @@ type
     /// </param>
     constructor Create(tagNo: Int32); overload;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
   end;
 
@@ -110,7 +112,7 @@ begin
   Inherited Create(false, tagNo, TBerSequence.Empty)
 end;
 
-procedure TBerTaggedObject.Encode(const derOut: IDerOutputStream);
+procedure TBerTaggedObject.Encode(const derOut: TStream);
 var
   eObj: TList<IAsn1Encodable>;
   LListIDerOctetString: TCryptoLibGenericArray<IDerOctetString>;
@@ -126,8 +128,9 @@ begin
   try
     if ((derOut is TAsn1OutputStream) or (derOut is TBerOutputStream)) then
     begin
-      derOut.WriteTag(Byte(TAsn1Tags.Constructed or TAsn1Tags.Tagged), tagNo);
-      derOut.WriteByte($80);
+      (derOut as TDerOutputStream)
+        .WriteTag(Byte(TAsn1Tags.Constructed or TAsn1Tags.Tagged), tagNo);
+      (derOut as TDerOutputStream).WriteByte($80);
 
       if (not IsEmpty()) then
       begin
@@ -178,17 +181,17 @@ begin
 
           for o in eObj do
           begin
-            derOut.WriteObject(o);
+            (derOut as TDerOutputStream).WriteObject(o);
           end;
         end
         else
         begin
-          derOut.WriteObject(obj);
+          (derOut as TDerOutputStream).WriteObject(obj);
         end;
       end;
 
-      derOut.WriteByte($00);
-      derOut.WriteByte($00);
+      (derOut as TDerOutputStream).WriteByte($00);
+      (derOut as TDerOutputStream).WriteByte($00);
     end
     else
     begin

+ 3 - 3
CryptoLib/src/Asn1/ClpConstructedOctetStream.pas

@@ -40,8 +40,8 @@ type
 
   public
     constructor Create(const parser: IAsn1StreamParser);
-    function Read(buffer: TCryptoLibByteArray; offset, count: Int32)
-      : Int32; override;
+    function Read(buffer: TCryptoLibByteArray; offset, count: LongInt)
+      : LongInt; override;
     function ReadByte(): Int32; override;
   end;
 
@@ -60,7 +60,7 @@ begin
 end;
 
 function TConstructedOctetStream.Read(buffer: TCryptoLibByteArray;
-  offset, count: Int32): Int32;
+  offset, count: LongInt): LongInt;
 var
   s, aos: IAsn1OctetStringParser;
   totalRead, numRead: Int32;

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

@@ -54,7 +54,7 @@ type
 
     function ReadByte(): Int32; override;
 
-    function Read(buf: TCryptoLibByteArray; off, len: Int32): Int32; override;
+    function Read(buf: TCryptoLibByteArray; off, len: LongInt): LongInt; override;
 
     procedure ReadAllIntoByteArray(var buf: TCryptoLibByteArray);
 
@@ -106,7 +106,7 @@ begin
 end;
 
 function TDefiniteLengthInputStream.Read(buf: TCryptoLibByteArray;
-  off, len: Int32): Int32;
+  off, len: LongInt): LongInt;
 var
   toRead, numRead: Int32;
 

+ 12 - 17
CryptoLib/src/Asn1/ClpDerApplicationSpecific.pas

@@ -28,6 +28,7 @@ uses
   ClpArrayUtils,
   ClpAsn1TaggedObject,
   ClpAsn1Tags,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpIDerApplicationSpecific,
   ClpIAsn1EncodableVector,
@@ -99,7 +100,7 @@ type
     /// </exception>
     function GetObject(derTagNo: Int32): IAsn1Object; overload; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     property ApplicationTag: Int32 read GetApplicationTag;
   end;
@@ -247,7 +248,7 @@ begin
 
 end;
 
-procedure TDerApplicationSpecific.Encode(const derOut: IDerOutputStream);
+procedure TDerApplicationSpecific.Encode(const derOut: TStream);
 var
   classBits: Int32;
 begin
@@ -257,7 +258,7 @@ begin
     classBits := classBits or TAsn1Tags.Constructed;
   end;
 
-  derOut.WriteEncoded(classBits, Ftag, Foctets);
+  (derOut as TDerOutputStream).WriteEncoded(classBits, Ftag, Foctets);
 end;
 
 constructor TDerApplicationSpecific.Create(isExplicit: Boolean; tag: Int32;
@@ -317,7 +318,7 @@ end;
 class function TDerApplicationSpecific.ReplaceTagNumber(newTag: Int32;
   const input: TCryptoLibByteArray): TCryptoLibByteArray;
 var
-  tagNo, index, b: Int32;
+  tagNo, index, b, remaining: Int32;
   tmp: TCryptoLibByteArray;
 begin
   tagNo := input[0] and $1F;
@@ -327,35 +328,29 @@ begin
   //
   if (tagNo = $1F) then
   begin
-    // tagNo := 0;
 
-    b := input[index] and $FF;
+    b := input[index];
     System.Inc(index);
 
     // X.690-0207 8.1.2.4.2
     // "c) bits 7 to 1 of the first subsequent octet shall not all be zero."
     if ((b and $7F) = 0) then // Note: -1 will pass
     begin
-      raise EInvalidOperationCryptoLibException.CreateRes(@SCorruptedStream);
+      raise EIOCryptoLibException.CreateRes(@SCorruptedStream);
     end;
 
-    while ((b >= 0) and ((b and $80) <> 0)) do
+    while ((b and $80) <> 0) do
     begin
-      // tagNo := tagNo or ((b and $7F));
-      // tagNo := tagNo shl 7;
-      b := input[index] and $FF;
+      b := input[index];
       System.Inc(index);
     end;
 
-    // tagNo := tagNo or (b and $7F);
   end;
 
-  System.SetLength(tmp, System.Length(input) - index + 1);
-
-  System.Move(input[index], tmp[1], System.Length(tmp) - 1 *
-    System.SizeOf(Byte));
-
+  remaining := System.Length(input) - index;
+  System.SetLength(tmp, 1 + remaining);
   tmp[0] := Byte(newTag);
+  System.Move(input[index], tmp[1], remaining * System.SizeOf(Byte));
 
   result := tmp;
 end;

+ 6 - 4
CryptoLib/src/Asn1/ClpDerBitString.pas

@@ -31,6 +31,7 @@ uses
   ClpAsn1Tags,
   ClpBigInteger,
   ClpAsn1Object,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
@@ -88,7 +89,7 @@ type
 
     function GetBytes(): TCryptoLibByteArray; virtual;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     function GetInt32Value: Int32; virtual;
     property Int32Value: Int32 read GetInt32Value;
@@ -263,7 +264,7 @@ begin
   FmPadBits := padBits;
 end;
 
-procedure TDerBitString.Encode(const derOut: IDerOutputStream);
+procedure TDerBitString.Encode(const derOut: TStream);
 var
   last, mask, unusedBits: Int32;
   contents: TCryptoLibByteArray;
@@ -283,12 +284,13 @@ begin
       // */
       contents[System.Length(contents) - 1] := Byte(last xor unusedBits);
 
-      derOut.WriteEncoded(TAsn1Tags.BitString, contents);
+      (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BitString, contents);
       Exit;
     end;
   end;
 
-  derOut.WriteEncoded(TAsn1Tags.BitString, Byte(mPadBits), mData);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BitString,
+    Byte(mPadBits), mData);
 end;
 
 class function TDerBitString.FromAsn1Octets(const octets: TCryptoLibByteArray)

+ 6 - 4
CryptoLib/src/Asn1/ClpDerBmpString.pas

@@ -22,11 +22,13 @@ unit ClpDerBmpString;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpCryptoLibTypes,
   ClpAsn1Object,
   ClpAsn1Tags,
   ClpAsn1OctetString,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpIDerBmpString,
   ClpIAsn1TaggedObject,
@@ -63,7 +65,7 @@ type
 
     function GetString(): String; override;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a BMP string from the given object.
@@ -152,7 +154,7 @@ begin
   FStr := astr;
 end;
 
-procedure TDerBmpString.Encode(const derOut: IDerOutputStream);
+procedure TDerBmpString.Encode(const derOut: TStream);
 var
   c: TCryptoLibCharArray;
   b: TCryptoLibByteArray;
@@ -168,7 +170,7 @@ begin
   LowPoint := 1;
   HighPoint := System.Length(Str);
 {$ENDIF DELPHIXE3_UP}
-  For i := LowPoint to HighPoint do
+  for i := LowPoint to HighPoint do
   begin
     c[i - 1] := Str[i];
   end;
@@ -183,7 +185,7 @@ begin
     System.Inc(i);
   end;
 
-  derOut.WriteEncoded(TAsn1Tags.BmpString, b);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.BmpString, b);
 
 end;
 

+ 6 - 3
CryptoLib/src/Asn1/ClpDerBoolean.pas

@@ -22,11 +22,13 @@ unit ClpDerBoolean;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpAsn1Tags,
   ClpIAsn1OctetString,
   ClpIDerBoolean,
   ClpCryptoLibTypes,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpIAsn1TaggedObject,
   ClpAsn1Object;
@@ -65,7 +67,7 @@ type
 
     constructor Create(const val: TCryptoLibByteArray); overload;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     function ToString(): String; override;
 
@@ -170,10 +172,11 @@ begin
   FTrue := TDerBoolean.Create(System.True);
 end;
 
-procedure TDerBoolean.Encode(const derOut: IDerOutputStream);
+procedure TDerBoolean.Encode(const derOut: TStream);
 begin
   // TODO Should we make sure the byte value is one of '0' or '0xff' here?
-  derOut.WriteEncoded(TAsn1Tags.Boolean, TCryptoLibByteArray.Create(Fvalue));
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Boolean,
+    TCryptoLibByteArray.Create(Fvalue));
 end;
 
 class function TDerBoolean.FromOctetString(const value: TCryptoLibByteArray)

+ 5 - 3
CryptoLib/src/Asn1/ClpDerEnumerated.pas

@@ -22,12 +22,14 @@ unit ClpDerEnumerated;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpCryptoLibTypes,
   ClpArrayUtils,
   ClpBigInteger,
   ClpIAsn1OctetString,
   ClpAsn1Tags,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpIDerEnumerated,
   ClpIAsn1TaggedObject,
@@ -65,7 +67,7 @@ type
     constructor Create(const val: TBigInteger); overload;
     constructor Create(const bytes: TCryptoLibByteArray); overload;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     property Value: TBigInteger read GetValue;
     property bytes: TCryptoLibByteArray read GetBytes;
@@ -162,9 +164,9 @@ begin
   System.SetLength(Fcache, 12);
 end;
 
-procedure TDerEnumerated.Encode(const derOut: IDerOutputStream);
+procedure TDerEnumerated.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.Enumerated, Fbytes);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Enumerated, Fbytes);
 end;
 
 class function TDerEnumerated.FromOctetString(const enc: TCryptoLibByteArray)

+ 5 - 3
CryptoLib/src/Asn1/ClpDerExternal.pas

@@ -29,6 +29,7 @@ uses
   ClpIAsn1TaggedObject,
   ClpDerTaggedObject,
   ClpAsn1Tags,
+  ClpDerOutputStream,
   ClpIAsn1EncodableVector,
   ClpIDerTaggedObject,
   ClpIProxiedInterface,
@@ -121,7 +122,7 @@ type
       const dataValueDescriptor: IAsn1Object; encoding: Int32;
       const externalData: IAsn1Object); overload;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     property dataValueDescriptor: IAsn1Object read GetDataValueDescriptor
       write SetDataValueDescriptor;
@@ -284,7 +285,7 @@ begin
     externalData.TagNo, externalData.ToAsn1Object());
 end;
 
-procedure TDerExternal.Encode(const derOut: IDerOutputStream);
+procedure TDerExternal.Encode(const derOut: TStream);
 var
   ms: TMemoryStream;
   Buffer: TCryptoLibByteArray;
@@ -300,7 +301,8 @@ begin
     System.SetLength(Buffer, ms.Size);
     ms.Position := 0;
     ms.Read(Buffer[0], ms.Size);
-    derOut.WriteEncoded(TAsn1Tags.Constructed, TAsn1Tags.External, Buffer);
+    (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Constructed,
+      TAsn1Tags.External, Buffer);
   finally
     ms.Free;
   end;

+ 6 - 3
CryptoLib/src/Asn1/ClpDerGeneralString.pas

@@ -22,12 +22,14 @@ unit ClpDerGeneralString;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpDerStringBase,
   ClpAsn1Tags,
   ClpAsn1OctetString,
   ClpAsn1Object,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerGeneralString,
@@ -61,7 +63,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     class function GetInstance(const obj: TObject): IDerGeneralString; overload;
       static; inline;
@@ -115,9 +117,10 @@ begin
   FStr := Str;
 end;
 
-procedure TDerGeneralString.Encode(const derOut: IDerOutputStream);
+procedure TDerGeneralString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.GeneralString, GetOctets());
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.GeneralString,
+    GetOctets());
 end;
 
 class function TDerGeneralString.GetInstance(const obj: TObject)

+ 5 - 3
CryptoLib/src/Asn1/ClpDerGraphicString.pas

@@ -22,12 +22,14 @@ unit ClpDerGraphicString;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpArrayUtils,
   ClpCryptoLibTypes,
   ClpAsn1Object,
   ClpAsn1Tags,
   ClpAsn1OctetString,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpIDerGraphicString,
   ClpIAsn1TaggedObject,
@@ -66,7 +68,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a Graphic String from the passed in object
@@ -137,9 +139,9 @@ begin
   FmString := System.Copy(encoding);
 end;
 
-procedure TDerGraphicString.Encode(const derOut: IDerOutputStream);
+procedure TDerGraphicString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.GraphicString, mString);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.GraphicString, mString);
 end;
 
 class function TDerGraphicString.GetInstance(const obj: TObject)

+ 5 - 3
CryptoLib/src/Asn1/ClpDerIA5String.pas

@@ -22,6 +22,7 @@ unit ClpDerIA5String;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpDerStringBase,
   ClpAsn1Tags,
@@ -29,6 +30,7 @@ uses
   ClpAsn1Object,
   ClpStringUtils,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerIA5String,
@@ -87,7 +89,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a DerIA5String from the passed in object
@@ -204,9 +206,9 @@ begin
   FStr := Str;
 end;
 
-procedure TDerIA5String.Encode(const derOut: IDerOutputStream);
+procedure TDerIA5String.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.IA5String, GetOctets());
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.IA5String, GetOctets());
 end;
 
 class function TDerIA5String.GetInstance(const obj: TObject): IDerIA5String;

+ 5 - 3
CryptoLib/src/Asn1/ClpDerInteger.pas

@@ -22,6 +22,7 @@ unit ClpDerInteger;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpCryptoLibTypes,
   ClpBigInteger,
@@ -29,6 +30,7 @@ uses
   ClpIProxiedInterface,
   ClpIAsn1TaggedObject,
   ClpAsn1OctetString,
+  ClpDerOutputStream,
   ClpAsn1Tags,
   ClpArrayUtils,
   ClpIDerInteger;
@@ -63,7 +65,7 @@ type
     property PositiveValue: TBigInteger read GetPositiveValue;
     property bytes: TCryptoLibByteArray read GetBytes;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     function ToString(): String; override;
 
@@ -165,9 +167,9 @@ begin
   Fbytes := System.Copy(bytes);
 end;
 
-procedure TDerInteger.Encode(const derOut: IDerOutputStream);
+procedure TDerInteger.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.Integer, Fbytes);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Integer, Fbytes);
 end;
 
 class function TDerInteger.GetInstance(const obj: IAsn1TaggedObject;

+ 5 - 3
CryptoLib/src/Asn1/ClpDerNull.pas

@@ -22,10 +22,12 @@ unit ClpDerNull;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpCryptoLibTypes,
   ClpAsn1Tags,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpAsn1Null,
   ClpIDerNull;
 
@@ -54,7 +56,7 @@ type
 
   public
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
     class property Instance: IDerNull read GetInstance;
 
   end;
@@ -87,9 +89,9 @@ begin
   System.SetLength(FZeroBytes, 0);
 end;
 
-procedure TDerNull.Encode(const derOut: IDerOutputStream);
+procedure TDerNull.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.Null, FZeroBytes);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Null, FZeroBytes);
 end;
 
 class function TDerNull.GetInstance: IDerNull;

+ 6 - 3
CryptoLib/src/Asn1/ClpDerNumericString.pas

@@ -22,12 +22,14 @@ unit ClpDerNumericString;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpDerStringBase,
   ClpAsn1Tags,
   ClpAsn1OctetString,
   ClpAsn1Object,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerNumericString,
@@ -86,7 +88,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a Numeric string from the passed in object
@@ -203,9 +205,10 @@ begin
   FStr := Str;
 end;
 
-procedure TDerNumericString.Encode(const derOut: IDerOutputStream);
+procedure TDerNumericString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.NumericString, GetOctets());
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.NumericString,
+    GetOctets());
 end;
 
 class function TDerNumericString.GetInstance(const obj: TObject)

+ 21 - 5
CryptoLib/src/Asn1/ClpDerObjectIdentifier.pas

@@ -35,6 +35,7 @@ uses
   ClpAsn1Tags,
   ClpOidTokenizer,
   ClpIOidTokenizer,
+  ClpDerOutputStream,
   ClpAsn1Object,
   ClpAsn1OctetString,
   ClpIAsn1TaggedObject,
@@ -57,6 +58,7 @@ type
 
   class var
 
+    FIsBooted: Boolean;
     FLock: TCriticalSection;
     Fcache: TCryptoLibGenericArray<IDerObjectIdentifier>;
 
@@ -119,6 +121,8 @@ type
     class function FromOctetString(const enc: TCryptoLibByteArray)
       : IDerObjectIdentifier; static;
 
+    class procedure Boot(); static;
+
     constructor Create(const identifier: String); overload;
 
     property ID: String read GetID;
@@ -133,7 +137,7 @@ type
 
     function &On(const stem: IDerObjectIdentifier): Boolean; virtual;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     function ToString(): String; override;
 
@@ -167,6 +171,16 @@ begin
   result := TStringUtils.GetStringHashCode(Fidentifier);
 end;
 
+class procedure TDerObjectIdentifier.Boot;
+begin
+  if not FIsBooted then
+  begin
+    FLock := TCriticalSection.Create;
+    System.SetLength(Fcache, 1024);
+    FIsBooted := True;
+  end;
+end;
+
 function TDerObjectIdentifier.Branch(const branchID: String)
   : IDerObjectIdentifier;
 begin
@@ -221,8 +235,7 @@ end;
 
 class constructor TDerObjectIdentifier.CreateDerObjectIdentifier;
 begin
-  FLock := TCriticalSection.Create;
-  System.SetLength(Fcache, 1024);
+  TDerObjectIdentifier.Boot;
 end;
 
 class destructor TDerObjectIdentifier.DestroyDerObjectIdentifier;
@@ -263,9 +276,10 @@ begin
   end;
 end;
 
-procedure TDerObjectIdentifier.Encode(const derOut: IDerOutputStream);
+procedure TDerObjectIdentifier.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.ObjectIdentifier, GetBody());
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.ObjectIdentifier,
+    GetBody());
 end;
 
 class function TDerObjectIdentifier.FromOctetString
@@ -278,6 +292,7 @@ begin
   HashCode := TArrayUtils.GetArrayHashCode(enc);
   first := HashCode and 1023;
 
+  TDerObjectIdentifier.Boot;
   FLock.Acquire;
   try
     entry := Fcache[first];
@@ -300,6 +315,7 @@ function TDerObjectIdentifier.GetBody: TCryptoLibByteArray;
 var
   bOut: TMemoryStream;
 begin
+  TDerObjectIdentifier.Boot;
   FLock.Acquire;
   try
     if (Fbody = Nil) then

+ 4 - 3
CryptoLib/src/Asn1/ClpDerOctetString.pas

@@ -22,6 +22,7 @@ unit ClpDerOctetString;
 interface
 
 uses
+  Classes,
   ClpCryptoLibTypes,
   ClpAsn1Tags,
   ClpDerOutputStream,
@@ -39,7 +40,7 @@ type
 
     destructor Destroy(); override;
 
-    procedure Encode(const derOut: IDerOutputStream); overload; override;
+    procedure Encode(const derOut: TStream); overload; override;
     class procedure Encode(const derOut: TDerOutputStream;
       const bytes: TCryptoLibByteArray; offset, length: Int32); reintroduce;
       overload; static; inline;
@@ -65,9 +66,9 @@ begin
   inherited Destroy;
 end;
 
-procedure TDerOctetString.Encode(const derOut: IDerOutputStream);
+procedure TDerOctetString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.OctetString, str);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.OctetString, str);
 end;
 
 class procedure TDerOctetString.Encode(const derOut: TDerOutputStream;

+ 5 - 3
CryptoLib/src/Asn1/ClpDerOutputStream.pas

@@ -26,12 +26,11 @@ uses
   ClpBits,
   ClpAsn1Tags,
   ClpCryptoLibTypes,
-  ClpIFilterStream,
   ClpIProxiedInterface,
   ClpFilterStream;
 
 type
-  TDerOutputStream = class(TFilterStream, IFilterStream, IDerOutputStream)
+  TDerOutputStream = class(TFilterStream)
 
   strict private
     procedure WriteLength(length: Int32);
@@ -79,7 +78,10 @@ procedure TDerOutputStream.WriteEncoded(tag: Int32;
 begin
   WriteByte(Byte(tag));
   WriteLength(System.length(bytes));
-  Write(bytes[0], System.length(bytes));
+  if bytes <> Nil then
+  begin
+    Write(bytes[0], System.length(bytes));
+  end;
 end;
 
 procedure TDerOutputStream.WriteEncoded(flags, tagNo: Int32;

+ 6 - 3
CryptoLib/src/Asn1/ClpDerPrintableString.pas

@@ -22,6 +22,7 @@ unit ClpDerPrintableString;
 interface
 
 uses
+  Classes,
   SysUtils,
   StrUtils,
   ClpDerStringBase,
@@ -29,6 +30,7 @@ uses
   ClpAsn1OctetString,
   ClpAsn1Object,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerPrintableString,
@@ -85,7 +87,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     property Str: String read GetStr;
 
@@ -227,9 +229,10 @@ begin
   FStr := Str;
 end;
 
-procedure TDerPrintableString.Encode(const derOut: IDerOutputStream);
+procedure TDerPrintableString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.PrintableString, GetOctets());
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.PrintableString,
+    GetOctets());
 end;
 
 class function TDerPrintableString.GetInstance(const obj: TObject)

+ 4 - 3
CryptoLib/src/Asn1/ClpDerSequence.pas

@@ -75,7 +75,7 @@ type
     /// just outputing Sequence, <br />we also have to specify Constructed,
     /// and the objects length. <br />
     /// </summary>
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     class property Empty: IDerSequence read GetEmpty;
 
@@ -136,7 +136,7 @@ begin
   inherited Destroy;
 end;
 
-procedure TDerSequence.Encode(const derOut: IDerOutputStream);
+procedure TDerSequence.Encode(const derOut: TStream);
 var
   bOut: TMemoryStream;
   dOut: TDerOutputStream;
@@ -163,7 +163,8 @@ begin
     dOut.Free;
   end;
 
-  derOut.WriteEncoded(TAsn1Tags.Sequence or TAsn1Tags.Constructed, bytes);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Sequence or
+    TAsn1Tags.Constructed, bytes);
 end;
 
 class function TDerSequence.FromVector(const v: IAsn1EncodableVector)

+ 4 - 3
CryptoLib/src/Asn1/ClpDerSet.pas

@@ -81,7 +81,7 @@ type
     /// just outputing Set, <br />we also have to specify Constructed, and
     /// the objects length. <br />
     /// </summary>
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     class property Empty: IDerSet read GetEmpty;
 
@@ -155,7 +155,7 @@ begin
   inherited Destroy;
 end;
 
-procedure TDerSet.Encode(const derOut: IDerOutputStream);
+procedure TDerSet.Encode(const derOut: TStream);
 var
   bOut: TMemoryStream;
   dOut: TDerOutputStream;
@@ -182,7 +182,8 @@ begin
     dOut.Free;
   end;
 
-  derOut.WriteEncoded(TAsn1Tags.&Set or TAsn1Tags.Constructed, bytes);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.&Set or
+    TAsn1Tags.Constructed, bytes);
 end;
 
 class function TDerSet.FromVector(const v: IAsn1EncodableVector;

+ 25 - 5
CryptoLib/src/Asn1/ClpDerT61String.pas

@@ -22,12 +22,14 @@ unit ClpDerT61String;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpDerStringBase,
   ClpAsn1Tags,
   ClpAsn1OctetString,
   ClpAsn1Object,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerT61String,
@@ -45,12 +47,19 @@ type
   TDerT61String = class(TDerStringBase, IDerT61String)
 
   strict private
+    class var
+
+      FEncoding: TEncoding;
+
   var
     FStr: String;
 
     function GetStr: String; inline;
     property Str: String read GetStr;
 
+    class constructor CreateDerT61String();
+    class destructor DestroyDerT61String();
+
   strict protected
     function Asn1Equals(const asn1Object: IAsn1Object): Boolean; override;
   public
@@ -69,7 +78,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a T61 string from the passed in object.
@@ -114,7 +123,7 @@ end;
 
 function TDerT61String.GetOctets: TCryptoLibByteArray;
 begin
-  result := TConverters.ConvertStringToBytes(Str, TEncoding.ANSI);
+  result := TConverters.ConvertStringToBytes(Str, FEncoding);
 end;
 
 function TDerT61String.Asn1Equals(const asn1Object: IAsn1Object): Boolean;
@@ -133,7 +142,8 @@ end;
 
 constructor TDerT61String.Create(const Str: TCryptoLibByteArray);
 begin
-  Create(TConverters.ConvertBytesToString(Str, TEncoding.ANSI));
+  Inherited Create();
+  Create(TConverters.ConvertBytesToString(Str, FEncoding));
 end;
 
 constructor TDerT61String.Create(const Str: String);
@@ -147,9 +157,19 @@ begin
   FStr := Str;
 end;
 
-procedure TDerT61String.Encode(const derOut: IDerOutputStream);
+class constructor TDerT61String.CreateDerT61String;
+begin
+  FEncoding := TEncoding.GetEncoding('iso-8859-1');
+end;
+
+class destructor TDerT61String.DestroyDerT61String;
+begin
+  FEncoding.Free;
+end;
+
+procedure TDerT61String.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.T61String, GetOctets());
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.T61String, GetOctets());
 end;
 
 class function TDerT61String.GetInstance(const obj: TObject): IDerT61String;

+ 9 - 6
CryptoLib/src/Asn1/ClpDerTaggedObject.pas

@@ -22,6 +22,7 @@ unit ClpDerTaggedObject;
 interface
 
 uses
+  Classes,
   ClpCryptoLibTypes,
   ClpAsn1Tags,
   ClpDerSequence,
@@ -29,6 +30,7 @@ uses
   ClpIDerSequence,
 {$ENDIF DELPHI}
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpAsn1TaggedObject,
   ClpIDerTaggedObject;
 
@@ -71,7 +73,7 @@ type
     /// </param>
     constructor Create(tagNo: Int32); overload;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
   end;
 
@@ -95,7 +97,7 @@ begin
   Inherited Create(false, tagNo, TDerSequence.Empty)
 end;
 
-procedure TDerTaggedObject.Encode(const derOut: IDerOutputStream);
+procedure TDerTaggedObject.Encode(const derOut: TStream);
 var
   bytes: TCryptoLibByteArray;
   flags: Int32;
@@ -106,8 +108,8 @@ begin
 
     if (explicitly) then
     begin
-      derOut.WriteEncoded(TAsn1Tags.Constructed or TAsn1Tags.Tagged,
-        tagNo, bytes);
+      (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Constructed or
+        TAsn1Tags.Tagged, tagNo, bytes);
     end
     else
     begin
@@ -115,13 +117,14 @@ begin
       // need to mark constructed types... (preserve Constructed tag)
       //
       flags := (bytes[0] and TAsn1Tags.Constructed) or TAsn1Tags.Tagged;
-      derOut.WriteTag(flags, tagNo);
+      (derOut as TDerOutputStream).WriteTag(flags, tagNo);
       derOut.Write(bytes[1], System.Length(bytes) - 1);
     end
   end
   else
   begin
-    derOut.WriteEncoded(TAsn1Tags.Constructed or TAsn1Tags.Tagged, tagNo, Nil);
+    (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Constructed or
+      TAsn1Tags.Tagged, tagNo, Nil);
   end;
 end;
 

+ 4 - 3
CryptoLib/src/Asn1/ClpDerUniversalString.pas

@@ -30,6 +30,7 @@ uses
   ClpAsn1OctetString,
   ClpAsn1Object,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerUniversalString;
@@ -69,7 +70,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a Universal String from the passed in object.
@@ -142,9 +143,9 @@ begin
   FStr := Str;
 end;
 
-procedure TDerUniversalString.Encode(const derOut: IDerOutputStream);
+procedure TDerUniversalString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.UniversalString, Str);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.UniversalString, Str);
 end;
 
 class function TDerUniversalString.GetInstance(const obj: TObject)

+ 5 - 3
CryptoLib/src/Asn1/ClpDerUtf8String.pas

@@ -22,12 +22,14 @@ unit ClpDerUtf8String;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpDerStringBase,
   ClpAsn1Tags,
   ClpAsn1OctetString,
   ClpAsn1Object,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerUtf8String,
@@ -67,7 +69,7 @@ type
 
     function GetString(): String; override;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return an UTF8 string from the passed in object.
@@ -140,9 +142,9 @@ begin
   FStr := Str;
 end;
 
-procedure TDerUtf8String.Encode(const derOut: IDerOutputStream);
+procedure TDerUtf8String.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.Utf8String,
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.Utf8String,
     TConverters.ConvertStringToBytes(Str, TEncoding.UTF8));
 end;
 

+ 5 - 3
CryptoLib/src/Asn1/ClpDerVideotexString.pas

@@ -22,12 +22,14 @@ unit ClpDerVideotexString;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpArrayUtils,
   ClpCryptoLibTypes,
   ClpAsn1Object,
   ClpAsn1Tags,
   ClpAsn1OctetString,
+  ClpDerOutputStream,
   ClpIProxiedInterface,
   ClpIDerVideotexString,
   ClpIAsn1TaggedObject,
@@ -66,7 +68,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a Videotex String from the passed in object
@@ -137,9 +139,9 @@ begin
   FmString := System.Copy(encoding);
 end;
 
-procedure TDerVideotexString.Encode(const derOut: IDerOutputStream);
+procedure TDerVideotexString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.VideotexString, mString);
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.VideotexString, mString);
 end;
 
 class function TDerVideotexString.GetInstance(const obj: TObject)

+ 6 - 3
CryptoLib/src/Asn1/ClpDerVisibleString.pas

@@ -22,6 +22,7 @@ unit ClpDerVisibleString;
 interface
 
 uses
+  Classes,
   SysUtils,
   ClpDerStringBase,
   ClpAsn1Tags,
@@ -29,6 +30,7 @@ uses
   ClpIAsn1OctetString,
   ClpStringUtils,
   ClpIProxiedInterface,
+  ClpDerOutputStream,
   ClpCryptoLibTypes,
   ClpIAsn1TaggedObject,
   ClpIDerVisibleString,
@@ -71,7 +73,7 @@ type
 
     function GetOctets(): TCryptoLibByteArray; inline;
 
-    procedure Encode(const derOut: IDerOutputStream); override;
+    procedure Encode(const derOut: TStream); override;
 
     /// <summary>
     /// return a DerVisibleString from the passed in object
@@ -154,9 +156,10 @@ begin
   FStr := Str;
 end;
 
-procedure TDerVisibleString.Encode(const derOut: IDerOutputStream);
+procedure TDerVisibleString.Encode(const derOut: TStream);
 begin
-  derOut.WriteEncoded(TAsn1Tags.VisibleString, GetOctets());
+  (derOut as TDerOutputStream).WriteEncoded(TAsn1Tags.VisibleString,
+    GetOctets());
 end;
 
 class function TDerVisibleString.GetInstance(const obj: TObject)

+ 3 - 3
CryptoLib/src/Asn1/ClpIndefiniteLengthInputStream.pas

@@ -44,8 +44,8 @@ type
     constructor Create(inStream: TStream; limit: Int32);
     procedure SetEofOn00(eofOn00: Boolean);
 
-    function Read(buffer: TCryptoLibByteArray; offset, count: Int32)
-      : Int32; override;
+    function Read(buffer: TCryptoLibByteArray; offset, count: LongInt)
+      : LongInt; override;
 
     function ReadByte(): Int32; override;
 
@@ -100,7 +100,7 @@ begin
 end;
 
 function TIndefiniteLengthInputStream.Read(buffer: TCryptoLibByteArray;
-  offset, count: Int32): Int32;
+  offset, count: LongInt): LongInt;
 var
   numRead: Int32;
 begin

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

@@ -0,0 +1,147 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpEacObjectIdentifiers;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpDerObjectIdentifier,
+  ClpIDerObjectIdentifier;
+
+type
+  TEacObjectIdentifiers = class abstract(TObject)
+
+  strict private
+
+  class var
+
+    FIsBooted: Boolean;
+    Fbsi_de, Fid_TA, Fid_TA_ECDSA, Fid_TA_ECDSA_SHA_1, Fid_TA_ECDSA_SHA_224,
+      Fid_TA_ECDSA_SHA_256, Fid_TA_ECDSA_SHA_384, Fid_TA_ECDSA_SHA_512
+      : IDerObjectIdentifier;
+
+    class function Getbsi_de: IDerObjectIdentifier; static; inline;
+    class function Getid_TA: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_1: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_224: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_256: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_384: IDerObjectIdentifier; static; inline;
+    class function Getid_TA_ECDSA_SHA_512: IDerObjectIdentifier; static; inline;
+
+    class constructor EacObjectIdentifiers();
+
+  public
+    // bsi-de OBJECT IDENTIFIER ::= {
+    // itu-t(0) identified-organization(4) etsi(0)
+    // reserved(127) etsi-identified-organization(0) 7
+    // }
+    class property bsi_de: IDerObjectIdentifier read Getbsi_de;
+    //
+    // id-TA OBJECT IDENTIFIER ::= {
+    // bsi-de protocols(2) smartcard(2) 2
+    // }
+    class property id_TA: IDerObjectIdentifier read Getid_TA;
+    class property id_TA_ECDSA: IDerObjectIdentifier read Getid_TA_ECDSA;
+    class property id_TA_ECDSA_SHA_1: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_1;
+    class property id_TA_ECDSA_SHA_224: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_224;
+    class property id_TA_ECDSA_SHA_256: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_256;
+    class property id_TA_ECDSA_SHA_384: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_384;
+    class property id_TA_ECDSA_SHA_512: IDerObjectIdentifier
+      read Getid_TA_ECDSA_SHA_512;
+    class procedure Boot(); static;
+
+  end;
+
+implementation
+
+{ TEacObjectIdentifiers }
+
+class procedure TEacObjectIdentifiers.Boot;
+begin
+  if not FIsBooted then
+  begin
+    Fbsi_de := TDerObjectIdentifier.Create('0.4.0.127.0.7');
+    Fid_TA := TDerObjectIdentifier.Create(Fbsi_de.ID + '.2.2.2');
+    Fid_TA_ECDSA := TDerObjectIdentifier.Create(Fid_TA.ID + '.2');
+    Fid_TA_ECDSA_SHA_1 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.1');
+    Fid_TA_ECDSA_SHA_224 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.2');
+    Fid_TA_ECDSA_SHA_256 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.3');
+    Fid_TA_ECDSA_SHA_384 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.4');
+    Fid_TA_ECDSA_SHA_512 := TDerObjectIdentifier.Create(Fid_TA_ECDSA.ID + '.5');
+
+    FIsBooted := True;
+  end;
+end;
+
+class constructor TEacObjectIdentifiers.EacObjectIdentifiers;
+begin
+  TEacObjectIdentifiers.Boot;
+end;
+
+class function TEacObjectIdentifiers.Getbsi_de: IDerObjectIdentifier;
+begin
+  result := Fbsi_de;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA: IDerObjectIdentifier;
+begin
+  result := Fid_TA;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA: IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_1: IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_1;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_224
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_224;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_256
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_256;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_384
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_384;
+end;
+
+class function TEacObjectIdentifiers.Getid_TA_ECDSA_SHA_512
+  : IDerObjectIdentifier;
+begin
+  result := Fid_TA_ECDSA_SHA_512;
+end;
+
+end.

+ 78 - 3
CryptoLib/src/Asn1/Misc/ClpMiscObjectIdentifiers.pas

@@ -33,9 +33,23 @@ type
   class var
 
     FIsBooted: Boolean;
-    Fblake2, Fid_blake2b160, Fid_blake2b256, Fid_blake2b384, Fid_blake2b512,
-      Fid_blake2s128, Fid_blake2s160, Fid_blake2s224, Fid_blake2s256
-      : IDerObjectIdentifier;
+    Fcryptlib, Fcryptlib_algorithm, Fcryptlib_algorithm_blowfish_ECB,
+      Fcryptlib_algorithm_blowfish_CBC, Fcryptlib_algorithm_blowfish_CFB,
+      Fcryptlib_algorithm_blowfish_OFB, Fblake2, Fid_blake2b160, Fid_blake2b256,
+      Fid_blake2b384, Fid_blake2b512, Fid_blake2s128, Fid_blake2s160,
+      Fid_blake2s224, Fid_blake2s256: IDerObjectIdentifier;
+
+    class function Getcryptlib: IDerObjectIdentifier; static; inline;
+
+    class function Getcryptlib_algorithm: IDerObjectIdentifier; static; inline;
+    class function Getcryptlib_algorithm_blowfish_ECB: IDerObjectIdentifier;
+      static; inline;
+    class function Getcryptlib_algorithm_blowfish_CBC: IDerObjectIdentifier;
+      static; inline;
+    class function Getcryptlib_algorithm_blowfish_CFB: IDerObjectIdentifier;
+      static; inline;
+    class function Getcryptlib_algorithm_blowfish_OFB: IDerObjectIdentifier;
+      static; inline;
 
     class function Getblake2: IDerObjectIdentifier; static; inline;
 
@@ -53,6 +67,19 @@ type
 
   public
 
+    class property cryptlib: IDerObjectIdentifier read Getcryptlib;
+
+    class property cryptlib_algorithm: IDerObjectIdentifier
+      read Getcryptlib_algorithm;
+    class property cryptlib_algorithm_blowfish_ECB: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_ECB;
+    class property cryptlib_algorithm_blowfish_CBC: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_CBC;
+    class property cryptlib_algorithm_blowfish_CFB: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_CFB;
+    class property cryptlib_algorithm_blowfish_OFB: IDerObjectIdentifier
+      read Getcryptlib_algorithm_blowfish_OFB;
+
     class property blake2: IDerObjectIdentifier read Getblake2;
 
     class property id_blake2b160: IDerObjectIdentifier read Getid_blake2b160;
@@ -78,6 +105,41 @@ begin
   result := Fblake2;
 end;
 
+class function TMiscObjectIdentifiers.Getcryptlib: IDerObjectIdentifier;
+begin
+  result := Fcryptlib;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_CBC
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_CBC;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_CFB
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_CFB;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_ECB
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_ECB;
+end;
+
+class function TMiscObjectIdentifiers.Getcryptlib_algorithm_blowfish_OFB
+  : IDerObjectIdentifier;
+begin
+  result := Fcryptlib_algorithm_blowfish_OFB;
+end;
+
 class function TMiscObjectIdentifiers.Getid_blake2b160: IDerObjectIdentifier;
 begin
   result := Fid_blake2b160;
@@ -123,6 +185,19 @@ begin
 
   if not FIsBooted then
   begin
+
+    //
+    // Peter Gutmann's Cryptlib
+    //
+
+    Fcryptlib := TDerObjectIdentifier.Create('1.3.6.1.4.1.3029');
+
+    Fcryptlib_algorithm := cryptlib.Branch('1');
+    Fcryptlib_algorithm_blowfish_ECB := cryptlib_algorithm.Branch('1.1');
+    Fcryptlib_algorithm_blowfish_CBC := cryptlib_algorithm.Branch('1.2');
+    Fcryptlib_algorithm_blowfish_CFB := cryptlib_algorithm.Branch('1.3');
+    Fcryptlib_algorithm_blowfish_OFB := cryptlib_algorithm.Branch('1.4');
+
     //
     // Blake2b and Blake2s
     //

+ 2 - 1
CryptoLib/src/Crypto/ClpBufferedBlockCipher.pas

@@ -29,6 +29,7 @@ uses
   ClpIBufferedBlockCipher,
   ClpICipherParameters,
   ClpIParametersWithRandom,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -539,7 +540,7 @@ end;
 
 procedure TBufferedBlockCipher.Reset;
 begin
-  System.FillChar(Fbuf[0], System.length(Fbuf), Byte(0));
+  TArrayUtils.Fill(Fbuf, 0, System.length(Fbuf), Byte(0));
   FbufOff := 0;
 
   Fcipher.Reset();

+ 178 - 0
CryptoLib/src/Crypto/ClpBufferedCipherBase.pas

@@ -22,6 +22,7 @@ unit ClpBufferedCipherBase;
 interface
 
 uses
+  Classes,
   ClpIBufferedCipher,
   ClpICipherParameters,
   ClpIBufferedCipherBase,
@@ -29,6 +30,14 @@ uses
 
 resourcestring
   SOutputBufferTooSmall = 'Output Buffer too Short';
+  SInvalidBufferSize = '"BufferSize" Must Be Greater Than Zero';
+  SInputOutputStreamSame =
+    'Input and Output Streams Must not Point to the Same Stream Instance';
+  SUnAssignedInputStream = 'Input Stream Is Unassigned';
+  SUnAssignedOutputStream = 'Output Stream Is Unassigned';
+  SPositionOutOfRange = 'Current Position Is Out Of Range';
+  SStreamPositionOutOfRange =
+    'Stream Position (or Stream Length to Process) Is Out Of Range';
 
 type
   TBufferedCipherBase = class abstract(TInterfacedObject, IBufferedCipherBase,
@@ -43,12 +52,29 @@ type
 
     class constructor BufferedCipherBase();
 
+  var
+
+    FBufferSize: Int32;
+    FOnProgress: TBufferedCipherProgressEvent;
+
+  const
+    BUFFER_SIZE = Int32(64 * 1024); // 64Kb
+
+    function GetBufferSize: Int32; inline;
+    procedure SetBufferSize(value: Int32); inline;
+    function GetOnProgress: TBufferedCipherProgressEvent; inline;
+    procedure SetOnProgress(const value: TBufferedCipherProgressEvent); inline;
+
   strict protected
 
+    procedure DoProgress(AProcessed, ATotal: Int64); virtual;
+
     class property EmptyBuffer: TCryptoLibByteArray read GetEmptyBuffer;
 
   public
 
+    constructor Create();
+
     procedure Init(forEncryption: Boolean; const parameters: ICipherParameters);
       virtual; abstract;
 
@@ -76,6 +102,13 @@ type
       length: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
       overload; virtual;
 
+    procedure ProcessStream(const inputStream, outputStream: TStream;
+      length: Int64); overload; virtual;
+
+    procedure ProcessStream(const inputStream: TStream; inPos: Int64;
+      const outputStream: TStream; outPos: Int64; length: Int64);
+      overload; virtual;
+
     function DoFinal(): TCryptoLibByteArray; overload; virtual; abstract;
 
     function DoFinal(const input: TCryptoLibByteArray): TCryptoLibByteArray;
@@ -99,6 +132,14 @@ type
     function GetAlgorithmName: String; virtual; abstract;
     property AlgorithmName: String read GetAlgorithmName;
 
+    /// <summary>
+    /// property for determining the buffer size to use for stream based
+    /// encryption/decryption.
+    /// </summary>
+    property BufferSize: Int32 read GetBufferSize write SetBufferSize;
+    property OnProgress: TBufferedCipherProgressEvent read GetOnProgress
+      write SetOnProgress;
+
   end;
 
 implementation
@@ -110,6 +151,48 @@ begin
   System.SetLength(FEmptyBuffer, 0);
 end;
 
+procedure TBufferedCipherBase.DoProgress(AProcessed, ATotal: Int64);
+begin
+  if System.Assigned(FOnProgress) then
+  begin
+    FOnProgress(AProcessed, ATotal);
+  end;
+end;
+
+function TBufferedCipherBase.GetOnProgress: TBufferedCipherProgressEvent;
+begin
+  result := FOnProgress;
+end;
+
+procedure TBufferedCipherBase.SetOnProgress(const value
+  : TBufferedCipherProgressEvent);
+begin
+  FOnProgress := value;
+end;
+
+constructor TBufferedCipherBase.Create;
+begin
+  Inherited Create();
+  FBufferSize := BUFFER_SIZE;
+end;
+
+function TBufferedCipherBase.GetBufferSize: Int32;
+begin
+  result := FBufferSize;
+end;
+
+procedure TBufferedCipherBase.SetBufferSize(value: Int32);
+begin
+  if value > 0 then
+  begin
+    FBufferSize := value;
+  end
+  else
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidBufferSize);
+  end;
+end;
+
 function TBufferedCipherBase.DoFinal(const output: TCryptoLibByteArray;
   outOff: Int32): Int32;
 var
@@ -197,6 +280,101 @@ begin
   result := System.length(outBytes);
 end;
 
+procedure TBufferedCipherBase.ProcessStream(const inputStream: TStream;
+  inPos: Int64; const outputStream: TStream; outPos, length: Int64);
+var
+  LBufferSize, readed: Int32;
+  total: Int64;
+  data, tempRes: TCryptoLibByteArray;
+begin
+  total := 0;
+  if ((inPos < 0) or (outPos < 0) or (length <= 0)) then
+  begin
+    raise EIndexOutOfRangeCryptoLibException.CreateRes
+      (@SStreamPositionOutOfRange);
+  end;
+
+  if inputStream = Nil then
+  begin
+    raise EStreamCryptoLibException.CreateRes(@SUnAssignedInputStream);
+  end;
+
+  if outputStream = Nil then
+  begin
+    raise EStreamCryptoLibException.CreateRes(@SUnAssignedOutputStream);
+  end;
+
+  if inputStream = outputStream then
+  begin
+    raise EStreamCryptoLibException.CreateRes(@SInputOutputStreamSame);
+  end;
+
+  if ((inputStream.Position + length) > inputStream.Size) then
+  begin
+    raise EIndexOutOfRangeCryptoLibException.CreateRes(@SPositionOutOfRange);
+  end;
+
+  if (inputStream.Position >= inputStream.Size) then
+  begin
+    Exit;
+  end;
+
+  if BufferSize > inputStream.Size then // Sanity Check
+  begin
+    LBufferSize := BUFFER_SIZE;
+  end
+  else
+  begin
+    LBufferSize := BufferSize;
+  end;
+
+  System.SetLength(data, LBufferSize);
+
+  inputStream.Position := inPos;
+  outputStream.Position := outPos;
+
+  DoProgress(0, length);
+
+  while true do
+  begin
+    readed := inputStream.Read(data[0], LBufferSize);
+
+    if ((total + Int64(readed)) >= length) then
+    begin
+      tempRes := ProcessBytes(data, 0, Int32(length - total));
+      DoProgress(total + readed, length);
+      if (tempRes <> Nil) then
+      begin
+        outputStream.Write(tempRes[0], System.length(tempRes));
+      end;
+      break;
+    end
+    else
+    begin
+      tempRes := ProcessBytes(data, 0, readed);
+      if (tempRes <> Nil) then
+      begin
+        outputStream.Write(tempRes[0], System.length(tempRes));
+      end;
+      total := total + readed;
+    end;
+    DoProgress(total, length);
+  end;
+
+  tempRes := DoFinal();
+  if (tempRes <> Nil) then
+  begin
+    outputStream.Write(tempRes[0], System.length(tempRes));
+  end;
+
+end;
+
+procedure TBufferedCipherBase.ProcessStream(const inputStream,
+  outputStream: TStream; length: Int64);
+begin
+  ProcessStream(inputStream, 0, outputStream, 0, length);
+end;
+
 function TBufferedCipherBase.ProcessBytes(const input,
   output: TCryptoLibByteArray; outOff: Int32): Int32;
 begin

+ 2 - 2
CryptoLib/src/Crypto/ClpIESCipher.pas

@@ -139,7 +139,7 @@ begin
 
   &in := Aggregate();
   FBuffer.Clear;
-  FBuffer.SetSize(0);
+  FBuffer.SetSize(Int64(0));
 
   // Convert parameters for use in IESEngine
   params := TIESWithCipherParameters.Create(FIESCipherParameters.GetDerivationV,
@@ -286,7 +286,7 @@ begin
 
   FRandom := Random;
   FBuffer.Clear;
-  FBuffer.SetSize(0);
+  FBuffer.SetSize(Int64(0));
 end;
 
 procedure TIESCipher.ProcessBytes(const input: TCryptoLibByteArray);

+ 285 - 286
CryptoLib/src/Crypto/Engines/ClpAesEngine.pas

@@ -33,7 +33,7 @@ uses
   ClpCryptoLibTypes;
 
 resourcestring
-  AESEngineNotInitialised = 'AES Engine not Initialised';
+  SAESEngineNotInitialised = 'AES Engine not Initialised';
   SInputBuffertooShort = 'Input Buffer too Short';
   SOutputBuffertooShort = 'Output Buffer too Short';
   SInvalidParameterAESInit = 'Invalid Parameter Passed to AES Init - "%s"';
@@ -77,13 +77,147 @@ type
     m5 = UInt32($3F3F3F3F);
     BLOCK_SIZE = Int32(16);
 
+    // The S box
+    S: array [0 .. 255] of Byte = (99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
+      103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173,
+      212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
+      52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7,
+      18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59,
+      214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
+      190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2,
+      127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218,
+      33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126,
+      61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184,
+      20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98,
+      145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244,
+      234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116,
+      31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185,
+      134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135,
+      233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45,
+      15, 176, 84, 187, 22);
+
+    // The inverse S-box
+    Si: array [0 .. 255] of Byte = (82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
+      163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52,
+      142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238,
+      76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91,
+      162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212,
+      164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94,
+      21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,
+      228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175,
+      189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242,
+      207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226,
+      249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111,
+      183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154,
+      219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177,
+      18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229,
+      122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200,
+      235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225,
+      105, 20, 99, 85, 33, 12, 125);
+
+    // vector used in calculating key schedule (powers of x in GF(256))
+    Rcon: array [0 .. 29] of Byte = ($01, $02, $04, $08, $10, $20, $40, $80,
+      $1B, $36, $6C, $D8, $AB, $4D, $9A, $2F, $5E, $BC, $63, $C6, $97, $35, $6A,
+      $D4, $B3, $7D, $FA, $EF, $C5, $91);
+
+    // precomputation tables of calculations for rounds
+    T0: array [0 .. 255] of UInt32 = ($A56363C6, $847C7CF8, $997777EE,
+      $8D7B7BF6, $0DF2F2FF, $BD6B6BD6, $B16F6FDE, $54C5C591, $50303060,
+      $03010102, $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D,
+      $9A7676EC, $45CACA8F, $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF,
+      $EB5959B2, $C947478E, $0BF0F0FB, $ECADAD41, $67D4D4B3, $FDA2A25F,
+      $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4, $5BC0C09B, $C2B7B775,
+      $1CFDFDE1, $AE93933D, $6A26264C, $5A36366C, $413F3F7E, $02F7F7F5,
+      $4FCCCC83, $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2,
+      $73D8D8AB, $53313162, $3F15152A, $0C040408, $52C7C795, $65232346,
+      $5EC3C39D, $28181830, $A1969637, $0F05050A, $B59A9A2F, $0907070E,
+      $36121224, $9B80801B, $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F,
+      $9F7575EA, $1B090912, $9E83831D, $742C2C58, $2E1A1A34, $2D1B1B36,
+      $B26E6EDC, $EE5A5AB4, $FBA0A05B, $F65252A4, $4D3B3B76, $61D6D6B7,
+      $CEB3B37D, $7B292952, $3EE3E3DD, $712F2F5E, $97848413, $F55353A6,
+      $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3, $C8B1B179,
+      $ED5B5BB6, $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94,
+      $D44C4C98, $E85858B0, $4ACFCF85, $6BD0D0BB, $2AEFEFC5, $E5AAAA4F,
+      $16FBFBED, $C5434386, $D74D4D9A, $55333366, $94858511, $CF45458A,
+      $10F9F9E9, $06020204, $817F7FFE, $F05050A0, $443C3C78, $BA9F9F25,
+      $E3A8A84B, $F35151A2, $FEA3A35D, $C0404080, $8A8F8F05, $AD92923F,
+      $BC9D9D21, $48383870, $04F5F5F1, $DFBCBC63, $C1B6B677, $75DADAAF,
+      $63212142, $30101020, $1AFFFFE5, $0EF3F3FD, $6DD2D2BF, $4CCDCD81,
+      $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488,
+      $3917172E, $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8,
+      $E75D5DBA, $2B191932, $957373E6, $A06060C0, $98818119, $D14F4F9E,
+      $7FDCDCA3, $66222244, $7E2A2A54, $AB90903B, $8388880B, $CA46468C,
+      $29EEEEC7, $D3B8B86B, $3C141428, $79DEDEA7, $E25E5EBC, $1D0B0B16,
+      $76DBDBAD, $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14, $DB494992,
+      $0A06060C, $6C242448, $E45C5CB8, $5DC2C29F, $6ED3D3BD, $EFACAC43,
+      $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2, $32E7E7D5,
+      $43C8C88B, $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C,
+      $E0A9A949, $B46C6CD8, $FA5656AC, $07F4F4F3, $25EAEACF, $AF6565CA,
+      $8E7A7AF4, $E9AEAE47, $18080810, $D5BABA6F, $887878F0, $6F25254A,
+      $722E2E5C, $241C1C38, $F1A6A657, $C7B4B473, $51C6C697, $23E8E8CB,
+      $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61, $868B8B0D,
+      $858A8A0F, $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890,
+      $05030306, $01F6F6F7, $120E0E1C, $A36161C2, $5F35356A, $F95757AE,
+      $D0B9B969, $91868617, $58C1C199, $271D1D3A, $B99E9E27, $38E1E1D9,
+      $13F8F8EB, $B398982B, $33111122, $BB6969D2, $70D9D9A9, $898E8E07,
+      $A7949433, $B69B9B2D, $221E1E3C, $92878715, $20E9E9C9, $49CECE87,
+      $FF5555AA, $78282850, $7ADFDFA5, $8F8C8C03, $F8A1A159, $80898909,
+      $170D0D1A, $DABFBF65, $31E6E6D7, $C6424284, $B86868D0, $C3414182,
+      $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D,
+      $3A16162C);
+
+    Tinv0: array [0 .. 255] of UInt32 = ($50A7F451, $5365417E, $C3A4171A,
+      $965E273A, $CB6BAB3B, $F1459D1F, $AB58FAAC, $9303E34B, $55FA3020,
+      $F66D76AD, $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526,
+      $8FA362B5, $495AB1DE, $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3,
+      $12F04C81, $A397468D, $C6F9D36B, $E75F8F03, $959C9215, $EB7A6DBF,
+      $DA595295, $2D83BED4, $D3217458, $2969E049, $44C8C98E, $6A89C275,
+      $78798EF4, $6B3E5899, $DD71B927, $B64FE1BE, $17AD88F0, $66AC20C9,
+      $B43ACE7D, $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1,
+      $84AE6BBB, $1CA081FE, $942B08F9, $58684870, $19FD458F, $876CDE94,
+      $B7F87B52, $23D373AB, $E2024B72, $578F1FE3, $2AAB5566, $0728EBB2,
+      $03C2B52F, $9A7BC586, $A50837D3, $F2872830, $B2A5BF23, $BA6A0302,
+      $5C8216ED, $2B1CCF8A, $92B479A7, $F0F207F3, $A1E2694E, $CDF4DA65,
+      $D5BE0506, $1F6234D1, $8AFEA6C4, $9D532E34, $A055F3A2, $32E18A05,
+      $75EBF6A4, $39EC830B, $AAEF6040, $069F715E, $51106EBD, $F98A213E,
+      $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471, $6FD40604,
+      $FF155060, $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0,
+      $888B8907, $385B19E7, $DBEEC879, $470A7CA1, $E90F427C, $C91E84F8,
+      $00000000, $83868009, $48ED2B32, $AC70111E, $4E725A6C, $FBFF0EFD,
+      $5638850F, $1ED5AE3D, $27392D36, $64D90F0A, $21A65C68, $D1545B9B,
+      $3A2E3624, $B1670A0C, $0FE75793, $D296EEB4, $9E919B1B, $4FC5C080,
+      $A220DC61, $694B775A, $161A121C, $0ABA93E2, $E52AA0C0, $43E0223C,
+      $1D171B12, $0B0D090E, $ADC78BF2, $B9A8B62D, $C8A91E14, $8519F157,
+      $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644,
+      $347EFB5B, $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7,
+      $10856342, $40229713, $2011C684, $7D244A85, $F83DBBD2, $1132F9AE,
+      $6DA129C7, $4B2F9E1D, $F330B2DC, $EC52860D, $D0E3C177, $6C16B32B,
+      $99B970A9, $FA489411, $2264E947, $C48CFCA8, $1A3FF0A0, $D82C7D56,
+      $EF903322, $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498, $CF81F5A6,
+      $28DE7AA5, $268EB7DA, $A4BFAD3F, $E49D3A2C, $0D927850, $9BCC5F6A,
+      $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382, $BE805D9F,
+      $7C93D069, $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8,
+      $7BBB3BDB, $097826CD, $F418596E, $01B79AEC, $A89A4F83, $656E95E6,
+      $7EE6FFAA, $08CFBC21, $E6E815EF, $D99BE7BA, $CE366F4A, $D4099FEA,
+      $D67CB029, $AFB2A431, $31233F2A, $3094A5C6, $C066A235, $37BC4E74,
+      $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41, $0E50CD7F,
+      $2FF69117, $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E,
+      $1B886A4C, $B81F2CC1, $7F516546, $04EA5E9D, $5D358C01, $737487FA,
+      $2E410BFB, $5A1D67B3, $52D2DB92, $335610E9, $1347D66D, $8C61D79A,
+      $7A0CA137, $8E14F859, $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1,
+      $3CB1477A, $59DFD29C, $3F73F255, $79CE1418, $BF37C773, $EACDF753,
+      $5BAAFD5F, $146F3DDF, $86DB4478, $81F3AFCA, $3EC468B9, $2C342438,
+      $5F40A3C2, $72C31D16, $0C25E2BC, $8B493C28, $41950DFF, $7101A839,
+      $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48,
+      $4257B8D0);
+
   var
     FROUNDS: Int32;
     FWorkingKey: TCryptoLibMatrixUInt32Array;
     FC0, FC1, FC2, FC3: UInt32;
     FforEncryption: Boolean;
 
-    Fstate: TCryptoLibByteArray;
+    Fstate: array [0 .. 255] of Byte;
 
     function GetAlgorithmName: String; virtual;
     function GetIsPartialBlockOkay: Boolean; virtual;
@@ -104,8 +238,8 @@ type
     /// This code is written assuming those are the only possible values
     /// </para>
     /// </summary>
-    function GenerateWorkingKey(const key: TCryptoLibByteArray;
-      forEncryption: Boolean): TCryptoLibMatrixUInt32Array;
+    function GenerateWorkingKey(forEncryption: Boolean;
+      const key: TCryptoLibByteArray): TCryptoLibMatrixUInt32Array;
 
     procedure UnPackBlock(const bytes: TCryptoLibByteArray; off: Int32); inline;
     procedure PackBlock(const bytes: TCryptoLibByteArray; off: Int32); inline;
@@ -114,10 +248,6 @@ type
 
     procedure DecryptBlock(const KW: TCryptoLibMatrixUInt32Array);
 
-  class var
-    Fs, FSi, Frcon: TCryptoLibByteArray;
-    FT0, FTinv0: TCryptoLibUInt32Array;
-
     class function Shift(r: UInt32; Shift: Int32): UInt32; static; inline;
     class function FFmulX(x: UInt32): UInt32; static; inline;
     class function FFmulX2(x: UInt32): UInt32; static; inline;
@@ -131,7 +261,6 @@ type
 
     class function Inv_Mcol(x: UInt32): UInt32; static; inline;
     class function SubWord(x: UInt32): UInt32; static; inline;
-    class constructor AesEngine();
 
   public
 
@@ -157,154 +286,22 @@ type
 
     property AlgorithmName: String read GetAlgorithmName;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
-    class procedure Boot; static;
   end;
 
 implementation
 
 { TAesEngine }
 
-class procedure TAesEngine.Boot;
-begin
-  // The S box
-  Fs := TCryptoLibByteArray.Create(99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
-    103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212,
-    162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
-    229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128,
-    226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179,
-    41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74,
-    76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60,
-    159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
-    243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25,
-    115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
-    224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231,
-    200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186,
-    120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112,
-    62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248,
-    152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161,
-    137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22);
-
-  // The inverse S-box
-  FSi := TCryptoLibByteArray.Create(82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
-    163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142,
-    67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76,
-    149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162,
-    73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92,
-    204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70,
-    87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88,
-    5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1,
-    19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240,
-    180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28,
-    117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170,
-    24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120,
-    205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128,
-    236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201,
-    156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83,
-    153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85,
-    33, 12, 125);
-
-  // vector used in calculating key schedule (powers of x in GF(256))
-  Frcon := TCryptoLibByteArray.Create($01, $02, $04, $08, $10, $20, $40, $80,
-    $1B, $36, $6C, $D8, $AB, $4D, $9A, $2F, $5E, $BC, $63, $C6, $97, $35, $6A,
-    $D4, $B3, $7D, $FA, $EF, $C5, $91);
-
-  // precomputation tables of calculations for rounds
-  FT0 := TCryptoLibUInt32Array.Create($A56363C6, $847C7CF8, $997777EE,
-    $8D7B7BF6, $0DF2F2FF, $BD6B6BD6, $B16F6FDE, $54C5C591, $50303060, $03010102,
-    $A96767CE, $7D2B2B56, $19FEFEE7, $62D7D7B5, $E6ABAB4D, $9A7676EC, $45CACA8F,
-    $9D82821F, $40C9C989, $877D7DFA, $15FAFAEF, $EB5959B2, $C947478E, $0BF0F0FB,
-    $ECADAD41, $67D4D4B3, $FDA2A25F, $EAAFAF45, $BF9C9C23, $F7A4A453, $967272E4,
-    $5BC0C09B, $C2B7B775, $1CFDFDE1, $AE93933D, $6A26264C, $5A36366C, $413F3F7E,
-    $02F7F7F5, $4FCCCC83, $5C343468, $F4A5A551, $34E5E5D1, $08F1F1F9, $937171E2,
-    $73D8D8AB, $53313162, $3F15152A, $0C040408, $52C7C795, $65232346, $5EC3C39D,
-    $28181830, $A1969637, $0F05050A, $B59A9A2F, $0907070E, $36121224, $9B80801B,
-    $3DE2E2DF, $26EBEBCD, $6927274E, $CDB2B27F, $9F7575EA, $1B090912, $9E83831D,
-    $742C2C58, $2E1A1A34, $2D1B1B36, $B26E6EDC, $EE5A5AB4, $FBA0A05B, $F65252A4,
-    $4D3B3B76, $61D6D6B7, $CEB3B37D, $7B292952, $3EE3E3DD, $712F2F5E, $97848413,
-    $F55353A6, $68D1D1B9, $00000000, $2CEDEDC1, $60202040, $1FFCFCE3, $C8B1B179,
-    $ED5B5BB6, $BE6A6AD4, $46CBCB8D, $D9BEBE67, $4B393972, $DE4A4A94, $D44C4C98,
-    $E85858B0, $4ACFCF85, $6BD0D0BB, $2AEFEFC5, $E5AAAA4F, $16FBFBED, $C5434386,
-    $D74D4D9A, $55333366, $94858511, $CF45458A, $10F9F9E9, $06020204, $817F7FFE,
-    $F05050A0, $443C3C78, $BA9F9F25, $E3A8A84B, $F35151A2, $FEA3A35D, $C0404080,
-    $8A8F8F05, $AD92923F, $BC9D9D21, $48383870, $04F5F5F1, $DFBCBC63, $C1B6B677,
-    $75DADAAF, $63212142, $30101020, $1AFFFFE5, $0EF3F3FD, $6DD2D2BF, $4CCDCD81,
-    $140C0C18, $35131326, $2FECECC3, $E15F5FBE, $A2979735, $CC444488, $3917172E,
-    $57C4C493, $F2A7A755, $827E7EFC, $473D3D7A, $AC6464C8, $E75D5DBA, $2B191932,
-    $957373E6, $A06060C0, $98818119, $D14F4F9E, $7FDCDCA3, $66222244, $7E2A2A54,
-    $AB90903B, $8388880B, $CA46468C, $29EEEEC7, $D3B8B86B, $3C141428, $79DEDEA7,
-    $E25E5EBC, $1D0B0B16, $76DBDBAD, $3BE0E0DB, $56323264, $4E3A3A74, $1E0A0A14,
-    $DB494992, $0A06060C, $6C242448, $E45C5CB8, $5DC2C29F, $6ED3D3BD, $EFACAC43,
-    $A66262C4, $A8919139, $A4959531, $37E4E4D3, $8B7979F2, $32E7E7D5, $43C8C88B,
-    $5937376E, $B76D6DDA, $8C8D8D01, $64D5D5B1, $D24E4E9C, $E0A9A949, $B46C6CD8,
-    $FA5656AC, $07F4F4F3, $25EAEACF, $AF6565CA, $8E7A7AF4, $E9AEAE47, $18080810,
-    $D5BABA6F, $887878F0, $6F25254A, $722E2E5C, $241C1C38, $F1A6A657, $C7B4B473,
-    $51C6C697, $23E8E8CB, $7CDDDDA1, $9C7474E8, $211F1F3E, $DD4B4B96, $DCBDBD61,
-    $868B8B0D, $858A8A0F, $907070E0, $423E3E7C, $C4B5B571, $AA6666CC, $D8484890,
-    $05030306, $01F6F6F7, $120E0E1C, $A36161C2, $5F35356A, $F95757AE, $D0B9B969,
-    $91868617, $58C1C199, $271D1D3A, $B99E9E27, $38E1E1D9, $13F8F8EB, $B398982B,
-    $33111122, $BB6969D2, $70D9D9A9, $898E8E07, $A7949433, $B69B9B2D, $221E1E3C,
-    $92878715, $20E9E9C9, $49CECE87, $FF5555AA, $78282850, $7ADFDFA5, $8F8C8C03,
-    $F8A1A159, $80898909, $170D0D1A, $DABFBF65, $31E6E6D7, $C6424284, $B86868D0,
-    $C3414182, $B0999929, $772D2D5A, $110F0F1E, $CBB0B07B, $FC5454A8, $D6BBBB6D,
-    $3A16162C);
-
-  FTinv0 := TCryptoLibUInt32Array.Create($50A7F451, $5365417E, $C3A4171A,
-    $965E273A, $CB6BAB3B, $F1459D1F, $AB58FAAC, $9303E34B, $55FA3020, $F66D76AD,
-    $9176CC88, $254C02F5, $FCD7E54F, $D7CB2AC5, $80443526, $8FA362B5, $495AB1DE,
-    $671BBA25, $980EEA45, $E1C0FE5D, $02752FC3, $12F04C81, $A397468D, $C6F9D36B,
-    $E75F8F03, $959C9215, $EB7A6DBF, $DA595295, $2D83BED4, $D3217458, $2969E049,
-    $44C8C98E, $6A89C275, $78798EF4, $6B3E5899, $DD71B927, $B64FE1BE, $17AD88F0,
-    $66AC20C9, $B43ACE7D, $184ADF63, $82311AE5, $60335197, $457F5362, $E07764B1,
-    $84AE6BBB, $1CA081FE, $942B08F9, $58684870, $19FD458F, $876CDE94, $B7F87B52,
-    $23D373AB, $E2024B72, $578F1FE3, $2AAB5566, $0728EBB2, $03C2B52F, $9A7BC586,
-    $A50837D3, $F2872830, $B2A5BF23, $BA6A0302, $5C8216ED, $2B1CCF8A, $92B479A7,
-    $F0F207F3, $A1E2694E, $CDF4DA65, $D5BE0506, $1F6234D1, $8AFEA6C4, $9D532E34,
-    $A055F3A2, $32E18A05, $75EBF6A4, $39EC830B, $AAEF6040, $069F715E, $51106EBD,
-    $F98A213E, $3D06DD96, $AE053EDD, $46BDE64D, $B58D5491, $055DC471, $6FD40604,
-    $FF155060, $24FB9819, $97E9BDD6, $CC434089, $779ED967, $BD42E8B0, $888B8907,
-    $385B19E7, $DBEEC879, $470A7CA1, $E90F427C, $C91E84F8, $00000000, $83868009,
-    $48ED2B32, $AC70111E, $4E725A6C, $FBFF0EFD, $5638850F, $1ED5AE3D, $27392D36,
-    $64D90F0A, $21A65C68, $D1545B9B, $3A2E3624, $B1670A0C, $0FE75793, $D296EEB4,
-    $9E919B1B, $4FC5C080, $A220DC61, $694B775A, $161A121C, $0ABA93E2, $E52AA0C0,
-    $43E0223C, $1D171B12, $0B0D090E, $ADC78BF2, $B9A8B62D, $C8A91E14, $8519F157,
-    $4C0775AF, $BBDD99EE, $FD607FA3, $9F2601F7, $BCF5725C, $C53B6644, $347EFB5B,
-    $7629438B, $DCC623CB, $68FCEDB6, $63F1E4B8, $CADC31D7, $10856342, $40229713,
-    $2011C684, $7D244A85, $F83DBBD2, $1132F9AE, $6DA129C7, $4B2F9E1D, $F330B2DC,
-    $EC52860D, $D0E3C177, $6C16B32B, $99B970A9, $FA489411, $2264E947, $C48CFCA8,
-    $1A3FF0A0, $D82C7D56, $EF903322, $C74E4987, $C1D138D9, $FEA2CA8C, $360BD498,
-    $CF81F5A6, $28DE7AA5, $268EB7DA, $A4BFAD3F, $E49D3A2C, $0D927850, $9BCC5F6A,
-    $62467E54, $C2138DF6, $E8B8D890, $5EF7392E, $F5AFC382, $BE805D9F, $7C93D069,
-    $A92DD56F, $B31225CF, $3B99ACC8, $A77D1810, $6E639CE8, $7BBB3BDB, $097826CD,
-    $F418596E, $01B79AEC, $A89A4F83, $656E95E6, $7EE6FFAA, $08CFBC21, $E6E815EF,
-    $D99BE7BA, $CE366F4A, $D4099FEA, $D67CB029, $AFB2A431, $31233F2A, $3094A5C6,
-    $C066A235, $37BC4E74, $A6CA82FC, $B0D090E0, $15D8A733, $4A9804F1, $F7DAEC41,
-    $0E50CD7F, $2FF69117, $8DD64D76, $4DB0EF43, $544DAACC, $DF0496E4, $E3B5D19E,
-    $1B886A4C, $B81F2CC1, $7F516546, $04EA5E9D, $5D358C01, $737487FA, $2E410BFB,
-    $5A1D67B3, $52D2DB92, $335610E9, $1347D66D, $8C61D79A, $7A0CA137, $8E14F859,
-    $893C13EB, $EE27A9CE, $35C961B7, $EDE51CE1, $3CB1477A, $59DFD29C, $3F73F255,
-    $79CE1418, $BF37C773, $EACDF753, $5BAAFD5F, $146F3DDF, $86DB4478, $81F3AFCA,
-    $3EC468B9, $2C342438, $5F40A3C2, $72C31D16, $0C25E2BC, $8B493C28, $41950DFF,
-    $7101A839, $DEB30C08, $9CE4B4D8, $90C15664, $6184CB7B, $70B632D5, $745C6C48,
-    $4257B8D0);
-
-end;
-
-class constructor TAesEngine.AesEngine;
-begin
-  TAesEngine.Boot;
-end;
-
 class function TAesEngine.Shift(r: UInt32; Shift: Int32): UInt32;
 begin
-  // result := (r shr shift) or (r shl (32 - shift));
   result := TBits.RotateRight32(r, Shift);
 end;
 
 class function TAesEngine.SubWord(x: UInt32): UInt32;
 begin
-  result := UInt32(Fs[x and 255]) or (UInt32(Fs[(x shr 8) and 255]) shl 8) or
-    (UInt32(Fs[(x shr 16) and 255]) shl 16) or
-    (UInt32(Fs[(x shr 24) and 255]) shl 24);
+  result := UInt32(S[x and 255]) or (UInt32(S[(x shr 8) and 255]) shl 8) or
+    (UInt32(S[(x shr 16) and 255]) shl 16) or
+    (UInt32(S[(x shr 24) and 255]) shl 24);
 end;
 
 procedure TAesEngine.DecryptBlock(const KW: TCryptoLibMatrixUInt32Array);
@@ -324,61 +321,61 @@ begin
   begin
     lkw := KW[lr];
     System.Dec(lr);
-    lr0 := FTinv0[lt0 and 255] xor Shift(FTinv0[(lr3 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lt2 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lt1 shr 24) and 255], 8) xor lkw[0];
-    lr1 := FTinv0[lt1 and 255] xor Shift(FTinv0[(lt0 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lr3 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lt2 shr 24) and 255], 8) xor lkw[1];
-    lr2 := FTinv0[lt2 and 255] xor Shift(FTinv0[(lt1 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lt0 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lr3 shr 24) and 255], 8) xor lkw[2];
-    lr3 := FTinv0[lr3 and 255] xor Shift(FTinv0[(lt2 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lt1 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lt0 shr 24) and 255], 8) xor lkw[3];
+    lr0 := Tinv0[lt0 and 255] xor Shift(Tinv0[(lr3 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lt2 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lt1 shr 24) and 255], 8) xor lkw[0];
+    lr1 := Tinv0[lt1 and 255] xor Shift(Tinv0[(lt0 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lr3 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lt2 shr 24) and 255], 8) xor lkw[1];
+    lr2 := Tinv0[lt2 and 255] xor Shift(Tinv0[(lt1 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lt0 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lr3 shr 24) and 255], 8) xor lkw[2];
+    lr3 := Tinv0[lr3 and 255] xor Shift(Tinv0[(lt2 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lt1 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lt0 shr 24) and 255], 8) xor lkw[3];
     lkw := KW[lr];
     System.Dec(lr);
-    lt0 := FTinv0[lr0 and 255] xor Shift(FTinv0[(lr3 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lr2 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lr1 shr 24) and 255], 8) xor lkw[0];
-    lt1 := FTinv0[lr1 and 255] xor Shift(FTinv0[(lr0 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lr3 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lr2 shr 24) and 255], 8) xor lkw[1];
-    lt2 := FTinv0[lr2 and 255] xor Shift(FTinv0[(lr1 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lr0 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lr3 shr 24) and 255], 8) xor lkw[2];
-    lr3 := FTinv0[lr3 and 255] xor Shift(FTinv0[(lr2 shr 8) and 255], 24)
-      xor Shift(FTinv0[(lr1 shr 16) and 255], 16)
-      xor Shift(FTinv0[(lr0 shr 24) and 255], 8) xor lkw[3];
+    lt0 := Tinv0[lr0 and 255] xor Shift(Tinv0[(lr3 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lr2 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lr1 shr 24) and 255], 8) xor lkw[0];
+    lt1 := Tinv0[lr1 and 255] xor Shift(Tinv0[(lr0 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lr3 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lr2 shr 24) and 255], 8) xor lkw[1];
+    lt2 := Tinv0[lr2 and 255] xor Shift(Tinv0[(lr1 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lr0 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lr3 shr 24) and 255], 8) xor lkw[2];
+    lr3 := Tinv0[lr3 and 255] xor Shift(Tinv0[(lr2 shr 8) and 255], 24)
+      xor Shift(Tinv0[(lr1 shr 16) and 255], 16)
+      xor Shift(Tinv0[(lr0 shr 24) and 255], 8) xor lkw[3];
   end;
 
   lkw := KW[1];
-  lr0 := FTinv0[lt0 and 255] xor Shift(FTinv0[(lr3 shr 8) and 255], 24)
-    xor Shift(FTinv0[(lt2 shr 16) and 255], 16)
-    xor Shift(FTinv0[(lt1 shr 24) and 255], 8) xor lkw[0];
-  lr1 := FTinv0[lt1 and 255] xor Shift(FTinv0[(lt0 shr 8) and 255], 24)
-    xor Shift(FTinv0[(lr3 shr 16) and 255], 16)
-    xor Shift(FTinv0[(lt2 shr 24) and 255], 8) xor lkw[1];
-  lr2 := FTinv0[lt2 and 255] xor Shift(FTinv0[(lt1 shr 8) and 255], 24)
-    xor Shift(FTinv0[(lt0 shr 16) and 255], 16)
-    xor Shift(FTinv0[(lr3 shr 24) and 255], 8) xor lkw[2];
-  lr3 := FTinv0[lr3 and 255] xor Shift(FTinv0[(lt2 shr 8) and 255], 24)
-    xor Shift(FTinv0[(lt1 shr 16) and 255], 16)
-    xor Shift(FTinv0[(lt0 shr 24) and 255], 8) xor lkw[3];
+  lr0 := Tinv0[lt0 and 255] xor Shift(Tinv0[(lr3 shr 8) and 255], 24)
+    xor Shift(Tinv0[(lt2 shr 16) and 255], 16)
+    xor Shift(Tinv0[(lt1 shr 24) and 255], 8) xor lkw[0];
+  lr1 := Tinv0[lt1 and 255] xor Shift(Tinv0[(lt0 shr 8) and 255], 24)
+    xor Shift(Tinv0[(lr3 shr 16) and 255], 16)
+    xor Shift(Tinv0[(lt2 shr 24) and 255], 8) xor lkw[1];
+  lr2 := Tinv0[lt2 and 255] xor Shift(Tinv0[(lt1 shr 8) and 255], 24)
+    xor Shift(Tinv0[(lt0 shr 16) and 255], 16)
+    xor Shift(Tinv0[(lr3 shr 24) and 255], 8) xor lkw[2];
+  lr3 := Tinv0[lr3 and 255] xor Shift(Tinv0[(lt2 shr 8) and 255], 24)
+    xor Shift(Tinv0[(lt1 shr 16) and 255], 16)
+    xor Shift(Tinv0[(lt0 shr 24) and 255], 8) xor lkw[3];
 
   // the final round's table is a simple function of Si so we don't use a whole other four tables for it
 
   lkw := KW[0];
-  FC0 := UInt32(FSi[lr0 and 255]) xor ((UInt32(Fstate[(lr3 shr 8) and 255]))
+  FC0 := UInt32(Si[lr0 and 255]) xor ((UInt32(Fstate[(lr3 shr 8) and 255]))
     shl 8) xor ((UInt32(Fstate[(lr2 shr 16) and 255])) shl 16)
-    xor ((UInt32(FSi[(lr1 shr 24) and 255])) shl 24) xor lkw[0];
+    xor ((UInt32(Si[(lr1 shr 24) and 255])) shl 24) xor lkw[0];
   FC1 := UInt32(Fstate[lr1 and 255]) xor ((UInt32(Fstate[(lr0 shr 8) and 255]))
-    shl 8) xor ((UInt32(FSi[(lr3 shr 16) and 255])) shl 16)
+    shl 8) xor ((UInt32(Si[(lr3 shr 16) and 255])) shl 16)
     xor ((UInt32(Fstate[(lr2 shr 24) and 255])) shl 24) xor lkw[1];
-  FC2 := UInt32(Fstate[lr2 and 255]) xor ((UInt32(FSi[(lr1 shr 8) and 255]))
-    shl 8) xor ((UInt32(FSi[(lr0 shr 16) and 255])) shl 16)
+  FC2 := UInt32(Fstate[lr2 and 255]) xor ((UInt32(Si[(lr1 shr 8) and 255]))
+    shl 8) xor ((UInt32(Si[(lr0 shr 16) and 255])) shl 16)
     xor ((UInt32(Fstate[(lr3 shr 24) and 255])) shl 24) xor lkw[2];
-  FC3 := UInt32(FSi[lr3 and 255]) xor ((UInt32(Fstate[(lr2 shr 8) and 255]))
+  FC3 := UInt32(Si[lr3 and 255]) xor ((UInt32(Fstate[(lr2 shr 8) and 255]))
     shl 8) xor ((UInt32(Fstate[(lr1 shr 16) and 255])) shl 16)
     xor ((UInt32(Fstate[(lr0 shr 24) and 255])) shl 24) xor lkw[3];
 
@@ -401,64 +398,64 @@ begin
   begin
     lkw := KW[lr];
     System.Inc(lr);
-    lr0 := FT0[lt0 and 255] xor Shift(FT0[(lt1 shr 8) and 255], 24)
-      xor Shift(FT0[(lt2 shr 16) and 255], 16)
-      xor Shift(FT0[(lr3 shr 24) and 255], 8) xor lkw[0];
-    lr1 := FT0[lt1 and 255] xor Shift(FT0[(lt2 shr 8) and 255], 24)
-      xor Shift(FT0[(lr3 shr 16) and 255], 16)
-      xor Shift(FT0[(lt0 shr 24) and 255], 8) xor lkw[1];
-    lr2 := FT0[lt2 and 255] xor Shift(FT0[(lr3 shr 8) and 255], 24)
-      xor Shift(FT0[(lt0 shr 16) and 255], 16)
-      xor Shift(FT0[(lt1 shr 24) and 255], 8) xor lkw[2];
-    lr3 := FT0[lr3 and 255] xor Shift(FT0[(lt0 shr 8) and 255], 24)
-      xor Shift(FT0[(lt1 shr 16) and 255], 16)
-      xor Shift(FT0[(lt2 shr 24) and 255], 8) xor lkw[3];
+    lr0 := T0[lt0 and 255] xor Shift(T0[(lt1 shr 8) and 255], 24)
+      xor Shift(T0[(lt2 shr 16) and 255], 16)
+      xor Shift(T0[(lr3 shr 24) and 255], 8) xor lkw[0];
+    lr1 := T0[lt1 and 255] xor Shift(T0[(lt2 shr 8) and 255], 24)
+      xor Shift(T0[(lr3 shr 16) and 255], 16)
+      xor Shift(T0[(lt0 shr 24) and 255], 8) xor lkw[1];
+    lr2 := T0[lt2 and 255] xor Shift(T0[(lr3 shr 8) and 255], 24)
+      xor Shift(T0[(lt0 shr 16) and 255], 16)
+      xor Shift(T0[(lt1 shr 24) and 255], 8) xor lkw[2];
+    lr3 := T0[lr3 and 255] xor Shift(T0[(lt0 shr 8) and 255], 24)
+      xor Shift(T0[(lt1 shr 16) and 255], 16)
+      xor Shift(T0[(lt2 shr 24) and 255], 8) xor lkw[3];
     lkw := KW[lr];
     System.Inc(lr);
-    lt0 := FT0[lr0 and 255] xor Shift(FT0[(lr1 shr 8) and 255], 24)
-      xor Shift(FT0[(lr2 shr 16) and 255], 16)
-      xor Shift(FT0[(lr3 shr 24) and 255], 8) xor lkw[0];
-    lt1 := FT0[lr1 and 255] xor Shift(FT0[(lr2 shr 8) and 255], 24)
-      xor Shift(FT0[(lr3 shr 16) and 255], 16)
-      xor Shift(FT0[(lr0 shr 24) and 255], 8) xor lkw[1];
-    lt2 := FT0[lr2 and 255] xor Shift(FT0[(lr3 shr 8) and 255], 24)
-      xor Shift(FT0[(lr0 shr 16) and 255], 16)
-      xor Shift(FT0[(lr1 shr 24) and 255], 8) xor lkw[2];
-    lr3 := FT0[lr3 and 255] xor Shift(FT0[(lr0 shr 8) and 255], 24)
-      xor Shift(FT0[(lr1 shr 16) and 255], 16)
-      xor Shift(FT0[(lr2 shr 24) and 255], 8) xor lkw[3];
+    lt0 := T0[lr0 and 255] xor Shift(T0[(lr1 shr 8) and 255], 24)
+      xor Shift(T0[(lr2 shr 16) and 255], 16)
+      xor Shift(T0[(lr3 shr 24) and 255], 8) xor lkw[0];
+    lt1 := T0[lr1 and 255] xor Shift(T0[(lr2 shr 8) and 255], 24)
+      xor Shift(T0[(lr3 shr 16) and 255], 16)
+      xor Shift(T0[(lr0 shr 24) and 255], 8) xor lkw[1];
+    lt2 := T0[lr2 and 255] xor Shift(T0[(lr3 shr 8) and 255], 24)
+      xor Shift(T0[(lr0 shr 16) and 255], 16)
+      xor Shift(T0[(lr1 shr 24) and 255], 8) xor lkw[2];
+    lr3 := T0[lr3 and 255] xor Shift(T0[(lr0 shr 8) and 255], 24)
+      xor Shift(T0[(lr1 shr 16) and 255], 16)
+      xor Shift(T0[(lr2 shr 24) and 255], 8) xor lkw[3];
   end;
 
   lkw := KW[lr];
   System.Inc(lr);
-  lr0 := FT0[lt0 and 255] xor Shift(FT0[(lt1 shr 8) and 255], 24)
-    xor Shift(FT0[(lt2 shr 16) and 255], 16)
-    xor Shift(FT0[(lr3 shr 24) and 255], 8) xor lkw[0];
-  lr1 := FT0[lt1 and 255] xor Shift(FT0[(lt2 shr 8) and 255], 24)
-    xor Shift(FT0[(lr3 shr 16) and 255], 16)
-    xor Shift(FT0[(lt0 shr 24) and 255], 8) xor lkw[1];
-  lr2 := FT0[lt2 and 255] xor Shift(FT0[(lr3 shr 8) and 255], 24)
-    xor Shift(FT0[(lt0 shr 16) and 255], 16)
-    xor Shift(FT0[(lt1 shr 24) and 255], 8) xor lkw[2];
-  lr3 := FT0[lr3 and 255] xor Shift(FT0[(lt0 shr 8) and 255], 24)
-    xor Shift(FT0[(lt1 shr 16) and 255], 16)
-    xor Shift(FT0[(lt2 shr 24) and 255], 8) xor lkw[3];
+  lr0 := T0[lt0 and 255] xor Shift(T0[(lt1 shr 8) and 255], 24)
+    xor Shift(T0[(lt2 shr 16) and 255], 16) xor Shift(T0[(lr3 shr 24) and 255],
+    8) xor lkw[0];
+  lr1 := T0[lt1 and 255] xor Shift(T0[(lt2 shr 8) and 255], 24)
+    xor Shift(T0[(lr3 shr 16) and 255], 16) xor Shift(T0[(lt0 shr 24) and 255],
+    8) xor lkw[1];
+  lr2 := T0[lt2 and 255] xor Shift(T0[(lr3 shr 8) and 255], 24)
+    xor Shift(T0[(lt0 shr 16) and 255], 16) xor Shift(T0[(lt1 shr 24) and 255],
+    8) xor lkw[2];
+  lr3 := T0[lr3 and 255] xor Shift(T0[(lt0 shr 8) and 255], 24)
+    xor Shift(T0[(lt1 shr 16) and 255], 16) xor Shift(T0[(lt2 shr 24) and 255],
+    8) xor lkw[3];
 
   // the final round's table is a simple function of S so we don't use a whole other four tables for it
 
   lkw := KW[lr];
-  FC0 := UInt32(Fs[lr0 and 255]) xor ((UInt32(Fs[(lr1 shr 8) and 255])) shl 8)
+  FC0 := UInt32(S[lr0 and 255]) xor ((UInt32(S[(lr1 shr 8) and 255])) shl 8)
     xor ((UInt32(Fstate[(lr2 shr 16) and 255])) shl 16)
     xor ((UInt32(Fstate[(lr3 shr 24) and 255])) shl 24) xor lkw[0];
-  FC1 := UInt32(Fstate[lr1 and 255]) xor ((UInt32(Fs[(lr2 shr 8) and 255]))
-    shl 8) xor ((UInt32(Fs[(lr3 shr 16) and 255])) shl 16)
+  FC1 := UInt32(Fstate[lr1 and 255]) xor ((UInt32(S[(lr2 shr 8) and 255]))
+    shl 8) xor ((UInt32(S[(lr3 shr 16) and 255])) shl 16)
     xor ((UInt32(Fstate[(lr0 shr 24) and 255])) shl 24) xor lkw[1];
-  FC2 := UInt32(Fstate[lr2 and 255]) xor ((UInt32(Fs[(lr3 shr 8) and 255]))
-    shl 8) xor ((UInt32(Fs[(lr0 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lr1 shr 24) and 255])) shl 24) xor lkw[2];
+  FC2 := UInt32(Fstate[lr2 and 255]) xor ((UInt32(S[(lr3 shr 8) and 255]))
+    shl 8) xor ((UInt32(S[(lr0 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lr1 shr 24) and 255])) shl 24) xor lkw[2];
   FC3 := UInt32(Fstate[lr3 and 255]) xor ((UInt32(Fstate[(lr0 shr 8) and 255]))
     shl 8) xor ((UInt32(Fstate[(lr1 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lr2 shr 24) and 255])) shl 24) xor lkw[3];
+    xor ((UInt32(S[(lr2 shr 24) and 255])) shl 24) xor lkw[3];
 
 end;
 
@@ -469,33 +466,33 @@ end;
 
 class function TAesEngine.FFmulX2(x: UInt32): UInt32;
 var
-  t0, t1: UInt32;
+  lt0, t1: UInt32;
 begin
-  t0 := (x and m5) shl 2;
+  lt0 := (x and m5) shl 2;
   t1 := (x and m4);
   t1 := t1 xor (t1 shr 1);
-  result := t0 xor (t1 shr 2) xor (t1 shr 5);
+  result := lt0 xor (t1 shr 2) xor (t1 shr 5);
 end;
 
 class function TAesEngine.Inv_Mcol(x: UInt32): UInt32;
 var
-  t0, t1: UInt32;
+  lt0, t1: UInt32;
 begin
-  t0 := x;
-  t1 := t0 xor Shift(t0, 8);
-  t0 := t0 xor FFmulX(t1);
-  t1 := t1 xor FFmulX2(t0);
-  t0 := t0 xor (t1 xor Shift(t1, 16));
-  result := t0;
+  lt0 := x;
+  t1 := lt0 xor Shift(lt0, 8);
+  lt0 := lt0 xor FFmulX(t1);
+  t1 := t1 xor FFmulX2(lt0);
+  lt0 := lt0 xor (t1 xor Shift(t1, 16));
+  result := lt0;
 end;
 
-function TAesEngine.GenerateWorkingKey(const key: TCryptoLibByteArray;
-  forEncryption: Boolean): TCryptoLibMatrixUInt32Array;
+function TAesEngine.GenerateWorkingKey(forEncryption: Boolean;
+  const key: TCryptoLibByteArray): TCryptoLibMatrixUInt32Array;
 var
   keyLen, KC, i, j: Int32;
   smallw: TCryptoLibUInt32Array;
   bigW: TCryptoLibMatrixUInt32Array;
-  u, rcon, t0, t1, t2, t3, t4, t5, t6, t7: UInt32;
+  u, lrcon, lt0, t1, t2, t3, t4, t5, t6, t7: UInt32;
 
 begin
   keyLen := System.Length(key);
@@ -517,8 +514,8 @@ begin
   case KC of
     4:
       begin
-        t0 := TConverters.ReadBytesAsUInt32LE(PByte(key), 0);
-        bigW[0][0] := t0;
+        lt0 := TConverters.ReadBytesAsUInt32LE(PByte(key), 0);
+        bigW[0][0] := lt0;
         t1 := TConverters.ReadBytesAsUInt32LE(PByte(key), 4);
         bigW[0][1] := t1;
         t2 := TConverters.ReadBytesAsUInt32LE(PByte(key), 8);
@@ -528,10 +525,10 @@ begin
 
         for i := 1 to 10 do
         begin
-          u := SubWord(Shift(t3, 8)) xor Frcon[i - 1];
-          t0 := t0 xor u;
-          bigW[i][0] := t0;
-          t1 := t1 xor t0;
+          u := SubWord(Shift(t3, 8)) xor Rcon[i - 1];
+          lt0 := lt0 xor u;
+          bigW[i][0] := lt0;
+          t1 := t1 xor lt0;
           bigW[i][1] := t1;
           t2 := t2 xor t1;
           bigW[i][2] := t2;
@@ -542,8 +539,8 @@ begin
 
     6:
       begin
-        t0 := TConverters.ReadBytesAsUInt32LE(PByte(key), 0);
-        bigW[0][0] := t0;
+        lt0 := TConverters.ReadBytesAsUInt32LE(PByte(key), 0);
+        bigW[0][0] := lt0;
         t1 := TConverters.ReadBytesAsUInt32LE(PByte(key), 4);
         bigW[0][1] := t1;
         t2 := TConverters.ReadBytesAsUInt32LE(PByte(key), 8);
@@ -555,12 +552,12 @@ begin
         t5 := TConverters.ReadBytesAsUInt32LE(PByte(key), 20);
         bigW[1][1] := t5;
 
-        rcon := 1;
-        u := SubWord(Shift(t5, 8)) xor rcon;
-        rcon := rcon shl 1;
-        t0 := t0 xor u;
-        bigW[1][2] := t0;
-        t1 := t1 xor t0;
+        lrcon := 1;
+        u := SubWord(Shift(t5, 8)) xor lrcon;
+        lrcon := lrcon shl 1;
+        lt0 := lt0 xor u;
+        bigW[1][2] := lt0;
+        t1 := t1 xor lt0;
         bigW[1][3] := t1;
         t2 := t2 xor t1;
         bigW[2][0] := t2;
@@ -576,11 +573,11 @@ begin
         while i < 12 do
 
         begin
-          u := SubWord(Shift(t5, 8)) xor rcon;
-          rcon := rcon shl 1;
-          t0 := t0 xor u;
-          bigW[i][0] := t0;
-          t1 := t1 xor t0;
+          u := SubWord(Shift(t5, 8)) xor lrcon;
+          lrcon := lrcon shl 1;
+          lt0 := lt0 xor u;
+          bigW[i][0] := lt0;
+          t1 := t1 xor lt0;
           bigW[i][1] := t1;
           t2 := t2 xor t1;
           bigW[i][2] := t2;
@@ -590,11 +587,11 @@ begin
           bigW[i + 1][0] := t4;
           t5 := t5 xor t4;
           bigW[i + 1][1] := t5;
-          u := SubWord(Shift(t5, 8)) xor rcon;
-          rcon := rcon shl 1;
-          t0 := t0 xor u;
-          bigW[i + 1][2] := t0;
-          t1 := t1 xor t0;
+          u := SubWord(Shift(t5, 8)) xor lrcon;
+          lrcon := lrcon shl 1;
+          lt0 := lt0 xor u;
+          bigW[i + 1][2] := lt0;
+          t1 := t1 xor lt0;
           bigW[i + 1][3] := t1;
           t2 := t2 xor t1;
           bigW[i + 2][0] := t2;
@@ -607,10 +604,10 @@ begin
           System.Inc(i, 3);
         end;
 
-        u := SubWord(Shift(t5, 8)) xor rcon;
-        t0 := t0 xor u;
-        bigW[12][0] := t0;
-        t1 := t1 xor t0;
+        u := SubWord(Shift(t5, 8)) xor lrcon;
+        lt0 := lt0 xor u;
+        bigW[12][0] := lt0;
+        t1 := t1 xor lt0;
         bigW[12][1] := t1;
         t2 := t2 xor t1;
         bigW[12][2] := t2;
@@ -620,8 +617,8 @@ begin
 
     8:
       begin
-        t0 := TConverters.ReadBytesAsUInt32LE(PByte(key), 0);
-        bigW[0][0] := t0;
+        lt0 := TConverters.ReadBytesAsUInt32LE(PByte(key), 0);
+        bigW[0][0] := lt0;
         t1 := TConverters.ReadBytesAsUInt32LE(PByte(key), 4);
         bigW[0][1] := t1;
         t2 := TConverters.ReadBytesAsUInt32LE(PByte(key), 8);
@@ -637,18 +634,18 @@ begin
         t7 := TConverters.ReadBytesAsUInt32LE(PByte(key), 28);
         bigW[1][3] := t7;
 
-        rcon := 1;
+        lrcon := 1;
 
         i := 2;
 
         while i < 14 do
 
         begin
-          u := SubWord(Shift(t7, 8)) xor rcon;
-          rcon := rcon shl 1;
-          t0 := t0 xor u;
-          bigW[i][0] := t0;
-          t1 := t1 xor t0;
+          u := SubWord(Shift(t7, 8)) xor lrcon;
+          lrcon := lrcon shl 1;
+          lt0 := lt0 xor u;
+          bigW[i][0] := lt0;
+          t1 := t1 xor lt0;
           bigW[i][1] := t1;
           t2 := t2 xor t1;
           bigW[i][2] := t2;
@@ -666,10 +663,10 @@ begin
           System.Inc(i, 2);
         end;
 
-        u := SubWord(Shift(t7, 8)) xor rcon;
-        t0 := t0 xor u;
-        bigW[14][0] := t0;
-        t1 := t1 xor t0;
+        u := SubWord(Shift(t7, 8)) xor lrcon;
+        lt0 := lt0 xor u;
+        bigW[14][0] := lt0;
+        t1 := t1 xor lt0;
         bigW[14][1] := t1;
         t2 := t2 xor t1;
         bigW[14][2] := t2;
@@ -727,16 +724,18 @@ begin
       [(parameters as TObject).ToString]);
   end;
 
-  FWorkingKey := GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
+  FWorkingKey := GenerateWorkingKey(forEncryption, keyParameter.GetKey());
 
   FforEncryption := forEncryption;
+
   if forEncryption then
   begin
-    Fstate := System.Copy(Fs);
+    System.Move(S[System.Low(S)], Fstate[System.Low(Fstate)], System.SizeOf(S));
   end
   else
   begin
-    Fstate := System.Copy(FSi);
+    System.Move(Si[System.Low(Si)], Fstate[System.Low(Fstate)],
+      System.SizeOf(Si));
   end;
 
 end;
@@ -763,7 +762,7 @@ begin
   if (FWorkingKey = Nil) then
   begin
     raise EInvalidOperationCryptoLibException.CreateRes
-      (@AESEngineNotInitialised);
+      (@SAESEngineNotInitialised);
   end;
 
   TCheck.DataLength(input, inOff, 16, SInputBuffertooShort);

+ 171 - 189
CryptoLib/src/Crypto/Engines/ClpAesLightEngine.pas

@@ -33,7 +33,7 @@ uses
   ClpCryptoLibTypes;
 
 resourcestring
-  AESEngineNotInitialised = 'AES Engine not Initialised';
+  SAESEngineNotInitialised = 'AES Engine not Initialised';
   SInputBuffertooShort = 'Input Buffer too Short';
   SOutputBuffertooShort = 'Output Buffer too Short';
   SInvalidParameterAESInit = 'Invalid Parameter Passed to AES Init - "%s"';
@@ -78,6 +78,49 @@ type
     m5 = UInt32($3F3F3F3F);
     BLOCK_SIZE = Int32(16);
 
+    // The S box
+    S: array [0 .. 255] of Byte = (99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
+      103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173,
+      212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204,
+      52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7,
+      18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59,
+      214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203,
+      190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2,
+      127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218,
+      33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126,
+      61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184,
+      20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98,
+      145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244,
+      234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116,
+      31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185,
+      134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135,
+      233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45,
+      15, 176, 84, 187, 22);
+
+    // The inverse S-box
+    Si: array [0 .. 255] of Byte = (82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
+      163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52,
+      142, 67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238,
+      76, 149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91,
+      162, 73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212,
+      164, 92, 204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94,
+      21, 70, 87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247,
+      228, 88, 5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175,
+      189, 3, 1, 19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242,
+      207, 206, 240, 180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226,
+      249, 55, 232, 28, 117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111,
+      183, 98, 14, 170, 24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154,
+      219, 192, 254, 120, 205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177,
+      18, 16, 89, 39, 128, 236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229,
+      122, 159, 147, 201, 156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200,
+      235, 187, 60, 131, 83, 153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225,
+      105, 20, 99, 85, 33, 12, 125);
+
+    // vector used in calculating key schedule (powers of x in GF(256))
+    Rcon: array [0 .. 29] of Byte = ($01, $02, $04, $08, $10, $20, $40, $80,
+      $1B, $36, $6C, $D8, $AB, $4D, $9A, $2F, $5E, $BC, $63, $C6, $97, $35, $6A,
+      $D4, $B3, $7D, $FA, $EF, $C5, $91);
+
   var
     FROUNDS: Int32;
     FWorkingKey: TCryptoLibMatrixUInt32Array;
@@ -103,8 +146,8 @@ type
     /// This code is written assuming those are the only possible values
     /// </para>
     /// </summary>
-    function GenerateWorkingKey(const key: TCryptoLibByteArray;
-      forEncryption: Boolean): TCryptoLibMatrixUInt32Array;
+    function GenerateWorkingKey(forEncryption: Boolean;
+      const key: TCryptoLibByteArray): TCryptoLibMatrixUInt32Array;
 
     procedure UnPackBlock(const bytes: TCryptoLibByteArray; off: Int32); inline;
     procedure PackBlock(const bytes: TCryptoLibByteArray; off: Int32); inline;
@@ -113,10 +156,6 @@ type
 
     procedure DecryptBlock(const KW: TCryptoLibMatrixUInt32Array);
 
-    class var
-
-      Fs, FSi, Frcon: TCryptoLibByteArray;
-
     class function Shift(r: UInt32; Shift: Int32): UInt32; static; inline;
     class function FFmulX(x: UInt32): UInt32; static; inline;
     class function FFmulX2(x: UInt32): UInt32; static; inline;
@@ -131,7 +170,6 @@ type
     class function Mcol(x: UInt32): UInt32; static; inline;
     class function Inv_Mcol(x: UInt32): UInt32; static; inline;
     class function SubWord(x: UInt32): UInt32; static; inline;
-    class constructor AesLightEngine();
 
   public
     /// <summary>
@@ -156,7 +194,6 @@ type
 
     property AlgorithmName: String read GetAlgorithmName;
     property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
-    class procedure Boot; static;
 
   end;
 
@@ -164,67 +201,16 @@ implementation
 
 { TAesLightEngine }
 
-class procedure TAesLightEngine.Boot;
-begin
-  // The S box
-  Fs := TCryptoLibByteArray.Create(99, 124, 119, 123, 242, 107, 111, 197, 48, 1,
-    103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212,
-    162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165,
-    229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128,
-    226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179,
-    41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74,
-    76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60,
-    159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255,
-    243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25,
-    115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219,
-    224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231,
-    200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186,
-    120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112,
-    62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248,
-    152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161,
-    137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22);
-
-  // The inverse S-box
-  FSi := TCryptoLibByteArray.Create(82, 9, 106, 213, 48, 54, 165, 56, 191, 64,
-    163, 158, 129, 243, 215, 251, 124, 227, 57, 130, 155, 47, 255, 135, 52, 142,
-    67, 68, 196, 222, 233, 203, 84, 123, 148, 50, 166, 194, 35, 61, 238, 76,
-    149, 11, 66, 250, 195, 78, 8, 46, 161, 102, 40, 217, 36, 178, 118, 91, 162,
-    73, 109, 139, 209, 37, 114, 248, 246, 100, 134, 104, 152, 22, 212, 164, 92,
-    204, 93, 101, 182, 146, 108, 112, 72, 80, 253, 237, 185, 218, 94, 21, 70,
-    87, 167, 141, 157, 132, 144, 216, 171, 0, 140, 188, 211, 10, 247, 228, 88,
-    5, 184, 179, 69, 6, 208, 44, 30, 143, 202, 63, 15, 2, 193, 175, 189, 3, 1,
-    19, 138, 107, 58, 145, 17, 65, 79, 103, 220, 234, 151, 242, 207, 206, 240,
-    180, 230, 115, 150, 172, 116, 34, 231, 173, 53, 133, 226, 249, 55, 232, 28,
-    117, 223, 110, 71, 241, 26, 113, 29, 41, 197, 137, 111, 183, 98, 14, 170,
-    24, 190, 27, 252, 86, 62, 75, 198, 210, 121, 32, 154, 219, 192, 254, 120,
-    205, 90, 244, 31, 221, 168, 51, 136, 7, 199, 49, 177, 18, 16, 89, 39, 128,
-    236, 95, 96, 81, 127, 169, 25, 181, 74, 13, 45, 229, 122, 159, 147, 201,
-    156, 239, 160, 224, 59, 77, 174, 42, 245, 176, 200, 235, 187, 60, 131, 83,
-    153, 97, 23, 43, 4, 126, 186, 119, 214, 38, 225, 105, 20, 99, 85,
-    33, 12, 125);
-
-  // vector used in calculating key schedule (powers of x in GF(256))
-  Frcon := TCryptoLibByteArray.Create($01, $02, $04, $08, $10, $20, $40, $80,
-    $1B, $36, $6C, $D8, $AB, $4D, $9A, $2F, $5E, $BC, $63, $C6, $97, $35, $6A,
-    $D4, $B3, $7D, $FA, $EF, $C5, $91);
-end;
-
-class constructor TAesLightEngine.AesLightEngine;
-begin
-  TAesLightEngine.Boot;
-end;
-
 class function TAesLightEngine.Shift(r: UInt32; Shift: Int32): UInt32;
 begin
-  // result := (r shr shift) or (r shl (32 - shift));
   result := TBits.RotateRight32(r, Shift);
 end;
 
 class function TAesLightEngine.SubWord(x: UInt32): UInt32;
 begin
-  result := UInt32(Fs[x and 255]) or (UInt32(Fs[(x shr 8) and 255]) shl 8) or
-    (UInt32(Fs[(x shr 16) and 255]) shl 16) or
-    (UInt32(Fs[(x shr 24) and 255]) shl 24);
+  result := UInt32(S[x and 255]) or (UInt32(S[(x shr 8) and 255]) shl 8) or
+    (UInt32(S[(x shr 16) and 255]) shl 16) or
+    (UInt32(S[(x shr 24) and 255]) shl 24);
 end;
 
 class function TAesLightEngine.FFmulX(x: UInt32): UInt32;
@@ -281,64 +267,64 @@ begin
   begin
     lkw := KW[lr];
     System.Inc(lr);
-    lr0 := Mcol(UInt32(Fs[lt0 and 255]) xor ((UInt32(Fs[(lt1 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lt2 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lr3 shr 24) and 255])) shl 24)) xor lkw[0];
-    lr1 := Mcol(UInt32(Fs[lt1 and 255]) xor ((UInt32(Fs[(lt2 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lr3 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lt0 shr 24) and 255])) shl 24)) xor lkw[1];
-    lr2 := Mcol(UInt32(Fs[lt2 and 255]) xor ((UInt32(Fs[(lr3 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lt0 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lt1 shr 24) and 255])) shl 24)) xor lkw[2];
-    lr3 := Mcol(UInt32(Fs[lr3 and 255]) xor ((UInt32(Fs[(lt0 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lt1 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lt2 shr 24) and 255])) shl 24)) xor lkw[3];
+    lr0 := Mcol(UInt32(S[lt0 and 255]) xor ((UInt32(S[(lt1 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lt2 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lr3 shr 24) and 255])) shl 24)) xor lkw[0];
+    lr1 := Mcol(UInt32(S[lt1 and 255]) xor ((UInt32(S[(lt2 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lr3 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lt0 shr 24) and 255])) shl 24)) xor lkw[1];
+    lr2 := Mcol(UInt32(S[lt2 and 255]) xor ((UInt32(S[(lr3 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lt0 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lt1 shr 24) and 255])) shl 24)) xor lkw[2];
+    lr3 := Mcol(UInt32(S[lr3 and 255]) xor ((UInt32(S[(lt0 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lt1 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lt2 shr 24) and 255])) shl 24)) xor lkw[3];
     lkw := KW[lr];
     System.Inc(lr);
-    lt0 := Mcol(UInt32(Fs[lr0 and 255]) xor ((UInt32(Fs[(lr1 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lr2 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lr3 shr 24) and 255])) shl 24)) xor lkw[0];
-    lt1 := Mcol(UInt32(Fs[lr1 and 255]) xor ((UInt32(Fs[(lr2 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lr3 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lr0 shr 24) and 255])) shl 24)) xor lkw[1];
-    lt2 := Mcol(UInt32(Fs[lr2 and 255]) xor ((UInt32(Fs[(lr3 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lr0 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lr1 shr 24) and 255])) shl 24)) xor lkw[2];
-    lr3 := Mcol(UInt32(Fs[lr3 and 255]) xor ((UInt32(Fs[(lr0 shr 8) and 255]))
-      shl 8) xor ((UInt32(Fs[(lr1 shr 16) and 255])) shl 16)
-      xor ((UInt32(Fs[(lr2 shr 24) and 255])) shl 24)) xor lkw[3];
+    lt0 := Mcol(UInt32(S[lr0 and 255]) xor ((UInt32(S[(lr1 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lr2 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lr3 shr 24) and 255])) shl 24)) xor lkw[0];
+    lt1 := Mcol(UInt32(S[lr1 and 255]) xor ((UInt32(S[(lr2 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lr3 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lr0 shr 24) and 255])) shl 24)) xor lkw[1];
+    lt2 := Mcol(UInt32(S[lr2 and 255]) xor ((UInt32(S[(lr3 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lr0 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lr1 shr 24) and 255])) shl 24)) xor lkw[2];
+    lr3 := Mcol(UInt32(S[lr3 and 255]) xor ((UInt32(S[(lr0 shr 8) and 255]))
+      shl 8) xor ((UInt32(S[(lr1 shr 16) and 255])) shl 16)
+      xor ((UInt32(S[(lr2 shr 24) and 255])) shl 24)) xor lkw[3];
   end;
 
   lkw := KW[lr];
   System.Inc(lr);
-  lr0 := Mcol(UInt32(Fs[lt0 and 255]) xor ((UInt32(Fs[(lt1 shr 8) and 255]))
-    shl 8) xor ((UInt32(Fs[(lt2 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lr3 shr 24) and 255])) shl 24)) xor lkw[0];
-  lr1 := Mcol(UInt32(Fs[lt1 and 255]) xor ((UInt32(Fs[(lt2 shr 8) and 255]))
-    shl 8) xor ((UInt32(Fs[(lr3 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lt0 shr 24) and 255])) shl 24)) xor lkw[1];
-  lr2 := Mcol(UInt32(Fs[lt2 and 255]) xor ((UInt32(Fs[(lr3 shr 8) and 255]))
-    shl 8) xor ((UInt32(Fs[(lt0 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lt1 shr 24) and 255])) shl 24)) xor lkw[2];
-  lr3 := Mcol(UInt32(Fs[lr3 and 255]) xor ((UInt32(Fs[(lt0 shr 8) and 255]))
-    shl 8) xor ((UInt32(Fs[(lt1 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lt2 shr 24) and 255])) shl 24)) xor lkw[3];
+  lr0 := Mcol(UInt32(S[lt0 and 255]) xor ((UInt32(S[(lt1 shr 8) and 255]))
+    shl 8) xor ((UInt32(S[(lt2 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lr3 shr 24) and 255])) shl 24)) xor lkw[0];
+  lr1 := Mcol(UInt32(S[lt1 and 255]) xor ((UInt32(S[(lt2 shr 8) and 255]))
+    shl 8) xor ((UInt32(S[(lr3 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lt0 shr 24) and 255])) shl 24)) xor lkw[1];
+  lr2 := Mcol(UInt32(S[lt2 and 255]) xor ((UInt32(S[(lr3 shr 8) and 255]))
+    shl 8) xor ((UInt32(S[(lt0 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lt1 shr 24) and 255])) shl 24)) xor lkw[2];
+  lr3 := Mcol(UInt32(S[lr3 and 255]) xor ((UInt32(S[(lt0 shr 8) and 255]))
+    shl 8) xor ((UInt32(S[(lt1 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lt2 shr 24) and 255])) shl 24)) xor lkw[3];
 
   // the final round is a simple function of S
 
   lkw := KW[lr];
-  FC0 := UInt32(Fs[lr0 and 255]) xor ((UInt32(Fs[(lr1 shr 8) and 255])) shl 8)
-    xor ((UInt32(Fs[(lr2 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lr3 shr 24) and 255])) shl 24) xor lkw[0];
-  FC1 := UInt32(Fs[lr1 and 255]) xor ((UInt32(Fs[(lr2 shr 8) and 255])) shl 8)
-    xor ((UInt32(Fs[(lr3 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lr0 shr 24) and 255])) shl 24) xor lkw[1];
-  FC2 := UInt32(Fs[lr2 and 255]) xor ((UInt32(Fs[(lr3 shr 8) and 255])) shl 8)
-    xor ((UInt32(Fs[(lr0 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lr1 shr 24) and 255])) shl 24) xor lkw[2];
-  FC3 := UInt32(Fs[lr3 and 255]) xor ((UInt32(Fs[(lr0 shr 8) and 255])) shl 8)
-    xor ((UInt32(Fs[(lr1 shr 16) and 255])) shl 16)
-    xor ((UInt32(Fs[(lr2 shr 24) and 255])) shl 24) xor lkw[3];
+  FC0 := UInt32(S[lr0 and 255]) xor ((UInt32(S[(lr1 shr 8) and 255])) shl 8)
+    xor ((UInt32(S[(lr2 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lr3 shr 24) and 255])) shl 24) xor lkw[0];
+  FC1 := UInt32(S[lr1 and 255]) xor ((UInt32(S[(lr2 shr 8) and 255])) shl 8)
+    xor ((UInt32(S[(lr3 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lr0 shr 24) and 255])) shl 24) xor lkw[1];
+  FC2 := UInt32(S[lr2 and 255]) xor ((UInt32(S[(lr3 shr 8) and 255])) shl 8)
+    xor ((UInt32(S[(lr0 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lr1 shr 24) and 255])) shl 24) xor lkw[2];
+  FC3 := UInt32(S[lr3 and 255]) xor ((UInt32(S[(lr0 shr 8) and 255])) shl 8)
+    xor ((UInt32(S[(lr1 shr 16) and 255])) shl 16)
+    xor ((UInt32(S[(lr2 shr 24) and 255])) shl 24) xor lkw[3];
 end;
 
 procedure TAesLightEngine.DecryptBlock(const KW: TCryptoLibMatrixUInt32Array);
@@ -359,84 +345,80 @@ begin
   begin
     lkw := KW[lr];
     System.Dec(lr);
-    lr0 := Inv_Mcol(UInt32(FSi[lt0 and 255])
-      xor ((UInt32(FSi[(lr3 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lt2 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lt1 shr 24) and 255]) shl 24)) xor lkw[0];
-    lr1 := Inv_Mcol(UInt32(FSi[lt1 and 255])
-      xor ((UInt32(FSi[(lt0 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lr3 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lt2 shr 24) and 255]) shl 24)) xor lkw[1];
-    lr2 := Inv_Mcol(UInt32(FSi[lt2 and 255])
-      xor ((UInt32(FSi[(lt1 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lt0 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lr3 shr 24) and 255]) shl 24)) xor lkw[2];
-    lr3 := Inv_Mcol(UInt32(FSi[lr3 and 255])
-      xor ((UInt32(FSi[(lt2 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lt1 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lt0 shr 24) and 255]) shl 24)) xor lkw[3];
+    lr0 := Inv_Mcol(UInt32(Si[lt0 and 255])
+      xor ((UInt32(Si[(lr3 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lt2 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lt1 shr 24) and 255]) shl 24)) xor lkw[0];
+    lr1 := Inv_Mcol(UInt32(Si[lt1 and 255])
+      xor ((UInt32(Si[(lt0 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lr3 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lt2 shr 24) and 255]) shl 24)) xor lkw[1];
+    lr2 := Inv_Mcol(UInt32(Si[lt2 and 255])
+      xor ((UInt32(Si[(lt1 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lt0 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lr3 shr 24) and 255]) shl 24)) xor lkw[2];
+    lr3 := Inv_Mcol(UInt32(Si[lr3 and 255])
+      xor ((UInt32(Si[(lt2 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lt1 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lt0 shr 24) and 255]) shl 24)) xor lkw[3];
     lkw := KW[lr];
     System.Dec(lr);
-    lt0 := Inv_Mcol(UInt32(FSi[lr0 and 255])
-      xor ((UInt32(FSi[(lr3 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lr2 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lr1 shr 24) and 255]) shl 24)) xor lkw[0];
-    lt1 := Inv_Mcol(UInt32(FSi[lr1 and 255])
-      xor ((UInt32(FSi[(lr0 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lr3 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lr2 shr 24) and 255]) shl 24)) xor lkw[1];
-    lt2 := Inv_Mcol(UInt32(FSi[lr2 and 255])
-      xor ((UInt32(FSi[(lr1 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lr0 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lr3 shr 24) and 255]) shl 24)) xor lkw[2];
-    lr3 := Inv_Mcol(UInt32(FSi[lr3 and 255])
-      xor ((UInt32(FSi[(lr2 shr 8) and 255])) shl 8)
-      xor ((UInt32(FSi[(lr1 shr 16) and 255])) shl 16)
-      xor (UInt32(FSi[(lr0 shr 24) and 255]) shl 24)) xor lkw[3];
+    lt0 := Inv_Mcol(UInt32(Si[lr0 and 255])
+      xor ((UInt32(Si[(lr3 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lr2 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lr1 shr 24) and 255]) shl 24)) xor lkw[0];
+    lt1 := Inv_Mcol(UInt32(Si[lr1 and 255])
+      xor ((UInt32(Si[(lr0 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lr3 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lr2 shr 24) and 255]) shl 24)) xor lkw[1];
+    lt2 := Inv_Mcol(UInt32(Si[lr2 and 255])
+      xor ((UInt32(Si[(lr1 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lr0 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lr3 shr 24) and 255]) shl 24)) xor lkw[2];
+    lr3 := Inv_Mcol(UInt32(Si[lr3 and 255])
+      xor ((UInt32(Si[(lr2 shr 8) and 255])) shl 8)
+      xor ((UInt32(Si[(lr1 shr 16) and 255])) shl 16)
+      xor (UInt32(Si[(lr0 shr 24) and 255]) shl 24)) xor lkw[3];
   end;
 
   lkw := KW[1];
-  lr0 := Inv_Mcol(UInt32(FSi[lt0 and 255])
-    xor ((UInt32(FSi[(lr3 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lt2 shr 16) and 255])) shl 16)
-    xor (UInt32(FSi[(lt1 shr 24) and 255]) shl 24)) xor lkw[0];
-  lr1 := Inv_Mcol(UInt32(FSi[lt1 and 255])
-    xor ((UInt32(FSi[(lt0 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lr3 shr 16) and 255])) shl 16)
-    xor (UInt32(FSi[(lt2 shr 24) and 255]) shl 24)) xor lkw[1];
-  lr2 := Inv_Mcol(UInt32(FSi[lt2 and 255])
-    xor ((UInt32(FSi[(lt1 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lt0 shr 16) and 255])) shl 16)
-    xor (UInt32(FSi[(lr3 shr 24) and 255]) shl 24)) xor lkw[2];
-  lr3 := Inv_Mcol(UInt32(FSi[lr3 and 255])
-    xor ((UInt32(FSi[(lt2 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lt1 shr 16) and 255])) shl 16)
-    xor (UInt32(FSi[(lt0 shr 24) and 255]) shl 24)) xor lkw[3];
+  lr0 := Inv_Mcol(UInt32(Si[lt0 and 255]) xor ((UInt32(Si[(lr3 shr 8) and 255]))
+    shl 8) xor ((UInt32(Si[(lt2 shr 16) and 255])) shl 16)
+    xor (UInt32(Si[(lt1 shr 24) and 255]) shl 24)) xor lkw[0];
+  lr1 := Inv_Mcol(UInt32(Si[lt1 and 255]) xor ((UInt32(Si[(lt0 shr 8) and 255]))
+    shl 8) xor ((UInt32(Si[(lr3 shr 16) and 255])) shl 16)
+    xor (UInt32(Si[(lt2 shr 24) and 255]) shl 24)) xor lkw[1];
+  lr2 := Inv_Mcol(UInt32(Si[lt2 and 255]) xor ((UInt32(Si[(lt1 shr 8) and 255]))
+    shl 8) xor ((UInt32(Si[(lt0 shr 16) and 255])) shl 16)
+    xor (UInt32(Si[(lr3 shr 24) and 255]) shl 24)) xor lkw[2];
+  lr3 := Inv_Mcol(UInt32(Si[lr3 and 255]) xor ((UInt32(Si[(lt2 shr 8) and 255]))
+    shl 8) xor ((UInt32(Si[(lt1 shr 16) and 255])) shl 16)
+    xor (UInt32(Si[(lt0 shr 24) and 255]) shl 24)) xor lkw[3];
 
   // the final round's table is a simple function of Si
 
   lkw := KW[0];
-  FC0 := UInt32(FSi[lr0 and 255]) xor ((UInt32(FSi[(lr3 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lr2 shr 16) and 255])) shl 16)
-    xor ((UInt32(FSi[(lr1 shr 24) and 255])) shl 24) xor lkw[0];
-  FC1 := UInt32(FSi[lr1 and 255]) xor ((UInt32(FSi[(lr0 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lr3 shr 16) and 255])) shl 16)
-    xor ((UInt32(FSi[(lr2 shr 24) and 255])) shl 24) xor lkw[1];
-  FC2 := UInt32(FSi[lr2 and 255]) xor ((UInt32(FSi[(lr1 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lr0 shr 16) and 255])) shl 16)
-    xor ((UInt32(FSi[(lr3 shr 24) and 255])) shl 24) xor lkw[2];
-  FC3 := UInt32(FSi[lr3 and 255]) xor ((UInt32(FSi[(lr2 shr 8) and 255])) shl 8)
-    xor ((UInt32(FSi[(lr1 shr 16) and 255])) shl 16)
-    xor ((UInt32(FSi[(lr0 shr 24) and 255])) shl 24) xor lkw[3];
+  FC0 := UInt32(Si[lr0 and 255]) xor ((UInt32(Si[(lr3 shr 8) and 255])) shl 8)
+    xor ((UInt32(Si[(lr2 shr 16) and 255])) shl 16)
+    xor ((UInt32(Si[(lr1 shr 24) and 255])) shl 24) xor lkw[0];
+  FC1 := UInt32(Si[lr1 and 255]) xor ((UInt32(Si[(lr0 shr 8) and 255])) shl 8)
+    xor ((UInt32(Si[(lr3 shr 16) and 255])) shl 16)
+    xor ((UInt32(Si[(lr2 shr 24) and 255])) shl 24) xor lkw[1];
+  FC2 := UInt32(Si[lr2 and 255]) xor ((UInt32(Si[(lr1 shr 8) and 255])) shl 8)
+    xor ((UInt32(Si[(lr0 shr 16) and 255])) shl 16)
+    xor ((UInt32(Si[(lr3 shr 24) and 255])) shl 24) xor lkw[2];
+  FC3 := UInt32(Si[lr3 and 255]) xor ((UInt32(Si[(lr2 shr 8) and 255])) shl 8)
+    xor ((UInt32(Si[(lr1 shr 16) and 255])) shl 16)
+    xor ((UInt32(Si[(lr0 shr 24) and 255])) shl 24) xor lkw[3];
 end;
 
-function TAesLightEngine.GenerateWorkingKey(const key: TCryptoLibByteArray;
-  forEncryption: Boolean): TCryptoLibMatrixUInt32Array;
+function TAesLightEngine.GenerateWorkingKey(forEncryption: Boolean;
+  const key: TCryptoLibByteArray): TCryptoLibMatrixUInt32Array;
 var
   keyLen, KC, i, j: Int32;
   smallw: TCryptoLibUInt32Array;
   bigW: TCryptoLibMatrixUInt32Array;
-  u, rcon, t0, t1, t2, t3, t4, t5, t6, t7: UInt32;
+  u, lrcon, t0, t1, t2, t3, t4, t5, t6, t7: UInt32;
 
 begin
   keyLen := System.Length(key);
@@ -469,7 +451,7 @@ begin
 
         for i := 1 to 10 do
         begin
-          u := SubWord(Shift(t3, 8)) xor Frcon[i - 1];
+          u := SubWord(Shift(t3, 8)) xor Rcon[i - 1];
           t0 := t0 xor u;
           bigW[i][0] := t0;
           t1 := t1 xor t0;
@@ -496,9 +478,9 @@ begin
         t5 := TConverters.ReadBytesAsUInt32LE(PByte(key), 20);
         bigW[1][1] := t5;
 
-        rcon := 1;
-        u := SubWord(Shift(t5, 8)) xor rcon;
-        rcon := rcon shl 1;
+        lrcon := 1;
+        u := SubWord(Shift(t5, 8)) xor lrcon;
+        lrcon := lrcon shl 1;
         t0 := t0 xor u;
         bigW[1][2] := t0;
         t1 := t1 xor t0;
@@ -517,8 +499,8 @@ begin
         while i < 12 do
 
         begin
-          u := SubWord(Shift(t5, 8)) xor rcon;
-          rcon := rcon shl 1;
+          u := SubWord(Shift(t5, 8)) xor lrcon;
+          lrcon := lrcon shl 1;
           t0 := t0 xor u;
           bigW[i][0] := t0;
           t1 := t1 xor t0;
@@ -531,8 +513,8 @@ begin
           bigW[i + 1][0] := t4;
           t5 := t5 xor t4;
           bigW[i + 1][1] := t5;
-          u := SubWord(Shift(t5, 8)) xor rcon;
-          rcon := rcon shl 1;
+          u := SubWord(Shift(t5, 8)) xor lrcon;
+          lrcon := lrcon shl 1;
           t0 := t0 xor u;
           bigW[i + 1][2] := t0;
           t1 := t1 xor t0;
@@ -548,7 +530,7 @@ begin
           System.Inc(i, 3);
         end;
 
-        u := SubWord(Shift(t5, 8)) xor rcon;
+        u := SubWord(Shift(t5, 8)) xor lrcon;
         t0 := t0 xor u;
         bigW[12][0] := t0;
         t1 := t1 xor t0;
@@ -578,15 +560,15 @@ begin
         t7 := TConverters.ReadBytesAsUInt32LE(PByte(key), 28);
         bigW[1][3] := t7;
 
-        rcon := 1;
+        lrcon := 1;
 
         i := 2;
 
         while i < 14 do
 
         begin
-          u := SubWord(Shift(t7, 8)) xor rcon;
-          rcon := rcon shl 1;
+          u := SubWord(Shift(t7, 8)) xor lrcon;
+          lrcon := lrcon shl 1;
           t0 := t0 xor u;
           bigW[i][0] := t0;
           t1 := t1 xor t0;
@@ -607,7 +589,7 @@ begin
           System.Inc(i, 2);
         end;
 
-        u := SubWord(Shift(t7, 8)) xor rcon;
+        u := SubWord(Shift(t7, 8)) xor lrcon;
         t0 := t0 xor u;
         bigW[14][0] := t0;
         t1 := t1 xor t0;
@@ -668,7 +650,7 @@ begin
       [(parameters as TObject).ToString]);
   end;
 
-  FWorkingKey := GenerateWorkingKey(keyParameter.GetKey(), forEncryption);
+  FWorkingKey := GenerateWorkingKey(forEncryption, keyParameter.GetKey());
 
   FforEncryption := forEncryption;
 end;
@@ -697,7 +679,7 @@ begin
   if (FWorkingKey = Nil) then
   begin
     raise EInvalidOperationCryptoLibException.CreateRes
-      (@AESEngineNotInitialised);
+      (@SAESEngineNotInitialised);
   end;
 
   TCheck.DataLength(input, inOff, 16, SInputBuffertooShort);

+ 555 - 0
CryptoLib/src/Crypto/Engines/ClpBlowfishEngine.pas

@@ -0,0 +1,555 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpBlowfishEngine;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIBlockCipher,
+  ClpIKeyParameter,
+  ClpICipherParameters,
+  ClpIBlowfishEngine,
+  ClpCheck,
+  ClpConverters,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SBlowfishEngineNotInitialised = 'Blowfish Engine not Initialised';
+  SInvalidParameterBlowfishInit =
+    'Invalid Parameter Passed to Blowfish Init - "%s"';
+  SInputBuffertooShort = 'Input Buffer too Short';
+  SOutputBuffertooShort = 'Output Buffer too Short';
+  SInvalidKeyLength =
+    'Key Length must be between 32 - 448 bits and divisible by 8.';
+
+type
+
+  /// <summary>
+  /// A class that provides Blowfish key encryption operations, <br />such as
+  /// encoding data and generating keys. <br />All the algorithms herein are
+  /// from Applied Cryptography <br />and implement a simplified cryptography
+  /// interface. <br />
+  /// </summary>
+  TBlowfishEngine = class sealed(TInterfacedObject, IBlowfishEngine,
+    IBlockCipher)
+
+  strict private
+  const
+    ROUNDS = Int32(16);
+    BLOCK_SIZE = Int32(8); // bytes = 64 bits
+    SBOX_SK = Int32(256);
+    P_SZ = Int32(ROUNDS + 2);
+
+    KP: array [0 .. 17] of UInt32 = ($243F6A88, $85A308D3, $13198A2E, $03707344,
+      $A4093822, $299F31D0, $082EFA98, $EC4E6C89, $452821E6, $38D01377,
+      $BE5466CF, $34E90C6C, $C0AC29B7, $C97C50DD, $3F84D5B5, $B5470917,
+      $9216D5D9, $8979FB1B);
+
+    KS0: array [0 .. 255] of UInt32 = ($D1310BA6, $98DFB5AC, $2FFD72DB,
+      $D01ADFB7, $B8E1AFED, $6A267E96, $BA7C9045, $F12C7F99, $24A19947,
+      $B3916CF7, $0801F2E2, $858EFC16, $636920D8, $71574E69, $A458FEA3,
+      $F4933D7E, $0D95748F, $728EB658, $718BCD58, $82154AEE, $7B54A41D,
+      $C25A59B5, $9C30D539, $2AF26013, $C5D1B023, $286085F0, $CA417918,
+      $B8DB38EF, $8E79DCB0, $603A180E, $6C9E0E8B, $B01E8A3E, $D71577C1,
+      $BD314B27, $78AF2FDA, $55605C60, $E65525F3, $AA55AB94, $57489862,
+      $63E81440, $55CA396A, $2AAB10B6, $B4CC5C34, $1141E8CE, $A15486AF,
+      $7C72E993, $B3EE1411, $636FBC2A, $2BA9C55D, $741831F6, $CE5C3E16,
+      $9B87931E, $AFD6BA33, $6C24CF5C, $7A325381, $28958677, $3B8F4898,
+      $6B4BB9AF, $C4BFE81B, $66282193, $61D809CC, $FB21A991, $487CAC60,
+      $5DEC8032, $EF845D5D, $E98575B1, $DC262302, $EB651B88, $23893E81,
+      $D396ACC5, $0F6D6FF3, $83F44239, $2E0B4482, $A4842004, $69C8F04A,
+      $9E1F9B5E, $21C66842, $F6E96C9A, $670C9C61, $ABD388F0, $6A51A0D2,
+      $D8542F68, $960FA728, $AB5133A3, $6EEF0B6C, $137A3BE4, $BA3BF050,
+      $7EFB2A98, $A1F1651D, $39AF0176, $66CA593E, $82430E88, $8CEE8619,
+      $456F9FB4, $7D84A5C3, $3B8B5EBE, $E06F75D8, $85C12073, $401A449F,
+      $56C16AA6, $4ED3AA62, $363F7706, $1BFEDF72, $429B023D, $37D0D724,
+      $D00A1248, $DB0FEAD3, $49F1C09B, $075372C9, $80991B7B, $25D479D8,
+      $F6E8DEF7, $E3FE501A, $B6794C3B, $976CE0BD, $04C006BA, $C1A94FB6,
+      $409F60C4, $5E5C9EC2, $196A2463, $68FB6FAF, $3E6C53B5, $1339B2EB,
+      $3B52EC6F, $6DFC511F, $9B30952C, $CC814544, $AF5EBD09, $BEE3D004,
+      $DE334AFD, $660F2807, $192E4BB3, $C0CBA857, $45C8740F, $D20B5F39,
+      $B9D3FBDB, $5579C0BD, $1A60320A, $D6A100C6, $402C7279, $679F25FE,
+      $FB1FA3CC, $8EA5E9F8, $DB3222F8, $3C7516DF, $FD616B15, $2F501EC8,
+      $AD0552AB, $323DB5FA, $FD238760, $53317B48, $3E00DF82, $9E5C57BB,
+      $CA6F8CA0, $1A87562E, $DF1769DB, $D542A8F6, $287EFFC3, $AC6732C6,
+      $8C4F5573, $695B27B0, $BBCA58C8, $E1FFA35D, $B8F011A0, $10FA3D98,
+      $FD2183B8, $4AFCB56C, $2DD1D35B, $9A53E479, $B6F84565, $D28E49BC,
+      $4BFB9790, $E1DDF2DA, $A4CB7E33, $62FB1341, $CEE4C6E8, $EF20CADA,
+      $36774C01, $D07E9EFE, $2BF11FB4, $95DBDA4D, $AE909198, $EAAD8E71,
+      $6B93D5A0, $D08ED1D0, $AFC725E0, $8E3C5B2F, $8E7594B7, $8FF6E2FB,
+      $F2122B64, $8888B812, $900DF01C, $4FAD5EA0, $688FC31C, $D1CFF191,
+      $B3A8C1AD, $2F2F2218, $BE0E1777, $EA752DFE, $8B021FA1, $E5A0CC0F,
+      $B56F74E8, $18ACF3D6, $CE89E299, $B4A84FE0, $FD13E0B7, $7CC43B81,
+      $D2ADA8D9, $165FA266, $80957705, $93CC7314, $211A1477, $E6AD2065,
+      $77B5FA86, $C75442F5, $FB9D35CF, $EBCDAF0C, $7B3E89A0, $D6411BD3,
+      $AE1E7E49, $00250E2D, $2071B35E, $226800BB, $57B8E0AF, $2464369B,
+      $F009B91E, $5563911D, $59DFA6AA, $78C14389, $D95A537F, $207D5BA2,
+      $02E5B9C5, $83260376, $6295CFA9, $11C81968, $4E734A41, $B3472DCA,
+      $7B14A94A, $1B510052, $9A532915, $D60F573F, $BC9BC6E4, $2B60A476,
+      $81E67400, $08BA6FB5, $571BE91F, $F296EC6B, $2A0DD915, $B6636521,
+      $E7B9F9B6, $FF34052E, $C5855664, $53B02D5D, $A99F8FA1, $08BA4799,
+      $6E85076A);
+
+    KS1: array [0 .. 255] of UInt32 = ($4B7A70E9, $B5B32944, $DB75092E,
+      $C4192623, $AD6EA6B0, $49A7DF7D, $9CEE60B8, $8FEDB266, $ECAA8C71,
+      $699A17FF, $5664526C, $C2B19EE1, $193602A5, $75094C29, $A0591340,
+      $E4183A3E, $3F54989A, $5B429D65, $6B8FE4D6, $99F73FD6, $A1D29C07,
+      $EFE830F5, $4D2D38E6, $F0255DC1, $4CDD2086, $8470EB26, $6382E9C6,
+      $021ECC5E, $09686B3F, $3EBAEFC9, $3C971814, $6B6A70A1, $687F3584,
+      $52A0E286, $B79C5305, $AA500737, $3E07841C, $7FDEAE5C, $8E7D44EC,
+      $5716F2B8, $B03ADA37, $F0500C0D, $F01C1F04, $0200B3FF, $AE0CF51A,
+      $3CB574B2, $25837A58, $DC0921BD, $D19113F9, $7CA92FF6, $94324773,
+      $22F54701, $3AE5E581, $37C2DADC, $C8B57634, $9AF3DDA7, $A9446146,
+      $0FD0030E, $ECC8C73E, $A4751E41, $E238CD99, $3BEA0E2F, $3280BBA1,
+      $183EB331, $4E548B38, $4F6DB908, $6F420D03, $F60A04BF, $2CB81290,
+      $24977C79, $5679B072, $BCAF89AF, $DE9A771F, $D9930810, $B38BAE12,
+      $DCCF3F2E, $5512721F, $2E6B7124, $501ADDE6, $9F84CD87, $7A584718,
+      $7408DA17, $BC9F9ABC, $E94B7D8C, $EC7AEC3A, $DB851DFA, $63094366,
+      $C464C3D2, $EF1C1847, $3215D908, $DD433B37, $24C2BA16, $12A14D43,
+      $2A65C451, $50940002, $133AE4DD, $71DFF89E, $10314E55, $81AC77D6,
+      $5F11199B, $043556F1, $D7A3C76B, $3C11183B, $5924A509, $F28FE6ED,
+      $97F1FBFA, $9EBABF2C, $1E153C6E, $86E34570, $EAE96FB1, $860E5E0A,
+      $5A3E2AB3, $771FE71C, $4E3D06FA, $2965DCB9, $99E71D0F, $803E89D6,
+      $5266C825, $2E4CC978, $9C10B36A, $C6150EBA, $94E2EA78, $A5FC3C53,
+      $1E0A2DF4, $F2F74EA7, $361D2B3D, $1939260F, $19C27960, $5223A708,
+      $F71312B6, $EBADFE6E, $EAC31F66, $E3BC4595, $A67BC883, $B17F37D1,
+      $018CFF28, $C332DDEF, $BE6C5AA5, $65582185, $68AB9802, $EECEA50F,
+      $DB2F953B, $2AEF7DAD, $5B6E2F84, $1521B628, $29076170, $ECDD4775,
+      $619F1510, $13CCA830, $EB61BD96, $0334FE1E, $AA0363CF, $B5735C90,
+      $4C70A239, $D59E9E0B, $CBAADE14, $EECC86BC, $60622CA7, $9CAB5CAB,
+      $B2F3846E, $648B1EAF, $19BDF0CA, $A02369B9, $655ABB50, $40685A32,
+      $3C2AB4B3, $319EE9D5, $C021B8F7, $9B540B19, $875FA099, $95F7997E,
+      $623D7DA8, $F837889A, $97E32D77, $11ED935F, $16681281, $0E358829,
+      $C7E61FD6, $96DEDFA1, $7858BA99, $57F584A5, $1B227263, $9B83C3FF,
+      $1AC24696, $CDB30AEB, $532E3054, $8FD948E4, $6DBC3128, $58EBF2EF,
+      $34C6FFEA, $FE28ED61, $EE7C3C73, $5D4A14D9, $E864B7E3, $42105D14,
+      $203E13E0, $45EEE2B6, $A3AAABEA, $DB6C4F15, $FACB4FD0, $C742F442,
+      $EF6ABBB5, $654F3B1D, $41CD2105, $D81E799E, $86854DC7, $E44B476A,
+      $3D816250, $CF62A1F2, $5B8D2646, $FC8883A0, $C1C7B6A3, $7F1524C3,
+      $69CB7492, $47848A0B, $5692B285, $095BBF00, $AD19489D, $1462B174,
+      $23820E00, $58428D2A, $0C55F5EA, $1DADF43E, $233F7061, $3372F092,
+      $8D937E41, $D65FECF1, $6C223BDB, $7CDE3759, $CBEE7460, $4085F2A7,
+      $CE77326E, $A6078084, $19F8509E, $E8EFD855, $61D99735, $A969A7AA,
+      $C50C06C2, $5A04ABFC, $800BCADC, $9E447A2E, $C3453484, $FDD56705,
+      $0E1E9EC9, $DB73DBD3, $105588CD, $675FDA79, $E3674340, $C5C43465,
+      $713E38D8, $3D28F89E, $F16DFF20, $153E21E7, $8FB03D4A, $E6E39F2B,
+      $DB83ADF7);
+
+    KS2: array [0 .. 255] of UInt32 = ($E93D5A68, $948140F7, $F64C261C,
+      $94692934, $411520F7, $7602D4F7, $BCF46B2E, $D4A20068, $D4082471,
+      $3320F46A, $43B7D4B7, $500061AF, $1E39F62E, $97244546, $14214F74,
+      $BF8B8840, $4D95FC1D, $96B591AF, $70F4DDD3, $66A02F45, $BFBC09EC,
+      $03BD9785, $7FAC6DD0, $31CB8504, $96EB27B3, $55FD3941, $DA2547E6,
+      $ABCA0A9A, $28507825, $530429F4, $0A2C86DA, $E9B66DFB, $68DC1462,
+      $D7486900, $680EC0A4, $27A18DEE, $4F3FFEA2, $E887AD8C, $B58CE006,
+      $7AF4D6B6, $AACE1E7C, $D3375FEC, $CE78A399, $406B2A42, $20FE9E35,
+      $D9F385B9, $EE39D7AB, $3B124E8B, $1DC9FAF7, $4B6D1856, $26A36631,
+      $EAE397B2, $3A6EFA74, $DD5B4332, $6841E7F7, $CA7820FB, $FB0AF54E,
+      $D8FEB397, $454056AC, $BA489527, $55533A3A, $20838D87, $FE6BA9B7,
+      $D096954B, $55A867BC, $A1159A58, $CCA92963, $99E1DB33, $A62A4A56,
+      $3F3125F9, $5EF47E1C, $9029317C, $FDF8E802, $04272F70, $80BB155C,
+      $05282CE3, $95C11548, $E4C66D22, $48C1133F, $C70F86DC, $07F9C9EE,
+      $41041F0F, $404779A4, $5D886E17, $325F51EB, $D59BC0D1, $F2BCC18F,
+      $41113564, $257B7834, $602A9C60, $DFF8E8A3, $1F636C1B, $0E12B4C2,
+      $02E1329E, $AF664FD1, $CAD18115, $6B2395E0, $333E92E1, $3B240B62,
+      $EEBEB922, $85B2A20E, $E6BA0D99, $DE720C8C, $2DA2F728, $D0127845,
+      $95B794FD, $647D0862, $E7CCF5F0, $5449A36F, $877D48FA, $C39DFD27,
+      $F33E8D1E, $0A476341, $992EFF74, $3A6F6EAB, $F4F8FD37, $A812DC60,
+      $A1EBDDF8, $991BE14C, $DB6E6B0D, $C67B5510, $6D672C37, $2765D43B,
+      $DCD0E804, $F1290DC7, $CC00FFA3, $B5390F92, $690FED0B, $667B9FFB,
+      $CEDB7D9C, $A091CF0B, $D9155EA3, $BB132F88, $515BAD24, $7B9479BF,
+      $763BD6EB, $37392EB3, $CC115979, $8026E297, $F42E312D, $6842ADA7,
+      $C66A2B3B, $12754CCC, $782EF11C, $6A124237, $B79251E7, $06A1BBE6,
+      $4BFB6350, $1A6B1018, $11CAEDFA, $3D25BDD8, $E2E1C3C9, $44421659,
+      $0A121386, $D90CEC6E, $D5ABEA2A, $64AF674E, $DA86A85F, $BEBFE988,
+      $64E4C3FE, $9DBC8057, $F0F7C086, $60787BF8, $6003604D, $D1FD8346,
+      $F6381FB0, $7745AE04, $D736FCCC, $83426B33, $F01EAB71, $B0804187,
+      $3C005E5F, $77A057BE, $BDE8AE24, $55464299, $BF582E61, $4E58F48F,
+      $F2DDFDA2, $F474EF38, $8789BDC2, $5366F9C3, $C8B38E74, $B475F255,
+      $46FCD9B9, $7AEB2661, $8B1DDF84, $846A0E79, $915F95E2, $466E598E,
+      $20B45770, $8CD55591, $C902DE4C, $B90BACE1, $BB8205D0, $11A86248,
+      $7574A99E, $B77F19B6, $E0A9DC09, $662D09A1, $C4324633, $E85A1F02,
+      $09F0BE8C, $4A99A025, $1D6EFE10, $1AB93D1D, $0BA5A4DF, $A186F20F,
+      $2868F169, $DCB7DA83, $573906FE, $A1E2CE9B, $4FCD7F52, $50115E01,
+      $A70683FA, $A002B5C4, $0DE6D027, $9AF88C27, $773F8641, $C3604C06,
+      $61A806B5, $F0177A28, $C0F586E0, $006058AA, $30DC7D62, $11E69ED7,
+      $2338EA63, $53C2DD94, $C2C21634, $BBCBEE56, $90BCB6DE, $EBFC7DA1,
+      $CE591D76, $6F05E409, $4B7C0188, $39720A3D, $7C927C24, $86E3725F,
+      $724D9DB9, $1AC15BB4, $D39EB8FC, $ED545578, $08FCA5B5, $D83D7CD3,
+      $4DAD0FC4, $1E50EF5E, $B161E6F8, $A28514D9, $6C51133C, $6FD5C7E7,
+      $56E14EC4, $362ABFCE, $DDC6C837, $D79A3234, $92638212, $670EFA8E,
+      $406000E0);
+
+    KS3: array [0 .. 255] of UInt32 = ($3A39CE37, $D3FAF5CF, $ABC27737,
+      $5AC52D1B, $5CB0679E, $4FA33742, $D3822740, $99BC9BBE, $D5118E9D,
+      $BF0F7315, $D62D1C7E, $C700C47B, $B78C1B6B, $21A19045, $B26EB1BE,
+      $6A366EB4, $5748AB2F, $BC946E79, $C6A376D2, $6549C2C8, $530FF8EE,
+      $468DDE7D, $D5730A1D, $4CD04DC6, $2939BBDB, $A9BA4650, $AC9526E8,
+      $BE5EE304, $A1FAD5F0, $6A2D519A, $63EF8CE2, $9A86EE22, $C089C2B8,
+      $43242EF6, $A51E03AA, $9CF2D0A4, $83C061BA, $9BE96A4D, $8FE51550,
+      $BA645BD6, $2826A2F9, $A73A3AE1, $4BA99586, $EF5562E9, $C72FEFD3,
+      $F752F7DA, $3F046F69, $77FA0A59, $80E4A915, $87B08601, $9B09E6AD,
+      $3B3EE593, $E990FD5A, $9E34D797, $2CF0B7D9, $022B8B51, $96D5AC3A,
+      $017DA67D, $D1CF3ED6, $7C7D2D28, $1F9F25CF, $ADF2B89B, $5AD6B472,
+      $5A88F54C, $E029AC71, $E019A5E6, $47B0ACFD, $ED93FA9B, $E8D3C48D,
+      $283B57CC, $F8D56629, $79132E28, $785F0191, $ED756055, $F7960E44,
+      $E3D35E8C, $15056DD4, $88F46DBA, $03A16125, $0564F0BD, $C3EB9E15,
+      $3C9057A2, $97271AEC, $A93A072A, $1B3F6D9B, $1E6321F5, $F59C66FB,
+      $26DCF319, $7533D928, $B155FDF5, $03563482, $8ABA3CBB, $28517711,
+      $C20AD9F8, $ABCC5167, $CCAD925F, $4DE81751, $3830DC8E, $379D5862,
+      $9320F991, $EA7A90C2, $FB3E7BCE, $5121CE64, $774FBE32, $A8B6E37E,
+      $C3293D46, $48DE5369, $6413E680, $A2AE0810, $DD6DB224, $69852DFD,
+      $09072166, $B39A460A, $6445C0DD, $586CDECF, $1C20C8AE, $5BBEF7DD,
+      $1B588D40, $CCD2017F, $6BB4E3BB, $DDA26A7E, $3A59FF45, $3E350A44,
+      $BCB4CDD5, $72EACEA8, $FA6484BB, $8D6612AE, $BF3C6F47, $D29BE463,
+      $542F5D9E, $AEC2771B, $F64E6370, $740E0D8D, $E75B1357, $F8721671,
+      $AF537D5D, $4040CB08, $4EB4E2CC, $34D2466A, $0115AF84, $E1B00428,
+      $95983A1D, $06B89FB4, $CE6EA048, $6F3F3B82, $3520AB82, $011A1D4B,
+      $277227F8, $611560B1, $E7933FDC, $BB3A792B, $344525BD, $A08839E1,
+      $51CE794B, $2F32C9B7, $A01FBAC9, $E01CC87E, $BCC7D1F6, $CF0111C3,
+      $A1E8AAC7, $1A908749, $D44FBD9A, $D0DADECB, $D50ADA38, $0339C32A,
+      $C6913667, $8DF9317C, $E0B12B4F, $F79E59B7, $43F5BB3A, $F2D519FF,
+      $27D9459C, $BF97222C, $15E6FC2A, $0F91FC71, $9B941525, $FAE59361,
+      $CEB69CEB, $C2A86459, $12BAA8D1, $B6C1075E, $E3056A0C, $10D25065,
+      $CB03A442, $E0EC6E0E, $1698DB3B, $4C98A0BE, $3278E964, $9F1F9532,
+      $E0D392DF, $D3A0342B, $8971F21E, $1B0A7441, $4BA3348C, $C5BE7120,
+      $C37632D8, $DF359F8D, $9B992F2E, $E60B6F47, $0FE3F11D, $E54CDA54,
+      $1EDAD891, $CE6279CF, $CD3E7E6F, $1618B166, $FD2C1D05, $848FD2C5,
+      $F6FB2299, $F523F357, $A6327623, $93A83531, $56CCCD02, $ACF08162,
+      $5A75EBB5, $6E163697, $88D273CC, $DE966292, $81B949D0, $4C50901B,
+      $71C65614, $E6C6C7BD, $327A140A, $45E1D006, $C3F27B9A, $C9AA53FD,
+      $62A80F00, $BB25BFE2, $35BDD2F6, $71126905, $B2040222, $B6CBCF7C,
+      $CD769C2B, $53113EC0, $1640E3D3, $38ABBD60, $2547ADF0, $BA38209C,
+      $F746CE76, $77AFA1C5, $20756060, $85CBFE4E, $8AE88DD8, $7AAAF9B0,
+      $4CF9AA7E, $1948C25C, $02FB8A8C, $01C36AE4, $D6EBE1F9, $90D4F869,
+      $A65CDEA0, $3F09252D, $C208E69F, $B74E6132, $CE77E25B, $578FDFE3,
+      $3AC372E6);
+
+  var
+    FS0, FS1, FS2, FS3: array [0 .. (SBOX_SK - 1)] of UInt32; // the s-boxes
+    FP: array [0 .. (P_SZ - 1)] of UInt32; // the p-array
+
+    FforEncryption: Boolean;
+
+    FWorkingKey: TCryptoLibByteArray;
+
+    function F(x: UInt32): UInt32; inline;
+    procedure SetKey(const key: TCryptoLibByteArray);
+
+    /// <summary>
+    /// apply the encryption cycle to each value pair in the table.
+    /// </summary>
+    procedure ProcessTable(xl, xr: UInt32; var table: array of UInt32);
+
+    /// <summary>
+    /// Encrypt the given input starting at the given offset and place <br />
+    /// the result in the provided buffer starting at the given offset. <br />
+    /// The input will be an exact multiple of our blocksize.
+    /// </summary>
+    procedure EncryptBlock(const src: TCryptoLibByteArray; srcIndex: Int32;
+      const dst: TCryptoLibByteArray; dstIndex: Int32);
+
+    /// <summary>
+    /// Decrypt the given input starting at the given offset and place <br />
+    /// the result in the provided buffer starting at the given offset. <br />
+    /// The input will be an exact multiple of our blocksize.
+    /// </summary>
+    procedure DecryptBlock(const src: TCryptoLibByteArray; srcIndex: Int32;
+      const dst: TCryptoLibByteArray; dstIndex: Int32);
+
+    function GetAlgorithmName: String; virtual;
+    function GetIsPartialBlockOkay: Boolean; virtual;
+    function GetBlockSize(): Int32; virtual;
+
+  public
+
+    /// <summary>
+    /// initialise a Blowfish cipher.
+    /// </summary>
+    /// <param name="forEncryption">
+    /// whether or not we are for encryption.
+    /// </param>
+    /// <param name="parameters">
+    /// the parameters required to set up the cipher.
+    /// </param>
+    /// <exception cref="EArgumentCryptoLibException">
+    /// if the parameters argument is inappropriate.
+    /// </exception>
+    procedure Init(forEncryption: Boolean;
+      const parameters: ICipherParameters); virtual;
+
+    function ProcessBlock(const input: TCryptoLibByteArray; inOff: Int32;
+      const output: TCryptoLibByteArray; outOff: Int32): Int32; virtual;
+
+    procedure Reset(); virtual;
+
+    property AlgorithmName: String read GetAlgorithmName;
+    property IsPartialBlockOkay: Boolean read GetIsPartialBlockOkay;
+
+  end;
+
+implementation
+
+{ TBlowfishEngine }
+
+function TBlowfishEngine.F(x: UInt32): UInt32;
+begin
+  result := (((FS0[x shr 24] + FS1[(x shr 16) and $FF]) xor FS2[(x shr 8) and
+    $FF]) + FS3[x and $FF]);
+end;
+
+procedure TBlowfishEngine.SetKey(const key: TCryptoLibByteArray);
+var
+  keyLength, keyIndex, i, j: Int32;
+  data: UInt32;
+begin
+  keyLength := System.Length(key);
+  if ((keyLength < 4) or (keyLength > 56) or (((keyLength * 8) and 7) <> 0))
+  then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SInvalidKeyLength);
+  end;
+
+  (*
+    * - comments are from _Applied Crypto_, Schneier, p338
+    * please be careful comparing the two, AC numbers the
+    * arrays from 1, the enclosed code from 0.
+    *
+    * (1)
+    * Initialise the S-boxes and the P-array, with a fixed string
+    * This string contains the hexadecimal digits of pi (3.141...)
+  *)
+  System.Move(KS0[System.Low(KS0)], FS0[System.Low(FS0)],
+    SBOX_SK * System.SizeOf(UInt32));
+  System.Move(KS1[System.Low(KS1)], FS1[System.Low(FS1)],
+    SBOX_SK * System.SizeOf(UInt32));
+  System.Move(KS2[System.Low(KS2)], FS2[System.Low(FS2)],
+    SBOX_SK * System.SizeOf(UInt32));
+  System.Move(KS3[System.Low(KS3)], FS3[System.Low(FS3)],
+    SBOX_SK * System.SizeOf(UInt32));
+
+  System.Move(KP[System.Low(KP)], FP[System.Low(FP)],
+    P_SZ * System.SizeOf(UInt32));
+
+  (*
+    * (2)
+    * Now, XOR P[0] with the first 32 bits of the key, XOR P[1] with the
+    * second 32-bits of the key, and so on for all bits of the key
+    * (up to P[17]).  Repeatedly cycle through the key bits until the
+    * entire P-array has been XOR-ed with the key bits
+  *)
+  keyIndex := 0;
+
+  i := 0;
+  while i < P_SZ do
+  begin
+    // Get the 32 bits of the key, in 4 * 8 bit chunks
+    data := $0000000;
+    j := 0;
+    while j < 4 do
+    begin
+      // create a 32 bit block
+      data := (data shl 8) or UInt32(key[keyIndex]);
+      System.Inc(keyIndex);
+
+      // wrap when we get to the end of the key
+      if (keyIndex >= keyLength) then
+      begin
+        keyIndex := 0;
+      end;
+      System.Inc(j);
+    end;
+    // XOR the newly created 32 bit chunk onto the P-array
+    FP[i] := FP[i] xor data;
+
+    System.Inc(i);
+  end;
+
+  (*
+    * (3)
+    * Encrypt the all-zero string with the Blowfish algorithm, using
+    * the subkeys described in (1) and (2)
+    *
+    * (4)
+    * Replace P1 and P2 with the output of step (3)
+    *
+    * (5)
+    * Encrypt the output of step(3) using the Blowfish algorithm,
+    * with the modified subkeys.
+    *
+    * (6)
+    * Replace P3 and P4 with the output of step (5)
+    *
+    * (7)
+    * Continue the process, replacing all elements of the P-array
+    * and then all four S-boxes in order, with the output of the
+    * continuously changing Blowfish algorithm
+  *)
+
+  ProcessTable(0, 0, FP);
+  ProcessTable(FP[P_SZ - 2], FP[P_SZ - 1], FS0);
+  ProcessTable(FS0[SBOX_SK - 2], FS0[SBOX_SK - 1], FS1);
+  ProcessTable(FS1[SBOX_SK - 2], FS1[SBOX_SK - 1], FS2);
+  ProcessTable(FS2[SBOX_SK - 2], FS2[SBOX_SK - 1], FS3);
+end;
+
+procedure TBlowfishEngine.EncryptBlock(const src: TCryptoLibByteArray;
+  srcIndex: Int32; const dst: TCryptoLibByteArray; dstIndex: Int32);
+var
+  xl, xr: UInt32;
+  i: Int32;
+begin
+  xl := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex);
+  xr := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex + 4);
+
+  xl := xl xor FP[0];
+
+  i := 1;
+  while i < ROUNDS do
+
+  begin
+    xr := xr xor (F(xl) xor FP[i]);
+    xl := xl xor (F(xr) xor FP[i + 1]);
+    System.Inc(i, 2);
+  end;
+
+  xr := xr xor FP[ROUNDS + 1];
+
+  TConverters.ReadUInt32AsBytesBE(xr, dst, dstIndex);
+  TConverters.ReadUInt32AsBytesBE(xl, dst, dstIndex + 4);
+end;
+
+procedure TBlowfishEngine.DecryptBlock(const src: TCryptoLibByteArray;
+  srcIndex: Int32; const dst: TCryptoLibByteArray; dstIndex: Int32);
+var
+  xl, xr: UInt32;
+  i: Int32;
+begin
+  xl := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex);
+  xr := TConverters.ReadBytesAsUInt32BE(PByte(src), srcIndex + 4);
+
+  xl := xl xor FP[ROUNDS + 1];
+
+  i := ROUNDS;
+  while i > 0 do
+
+  begin
+    xr := xr xor (F(xl) xor FP[i]);
+    xl := xl xor (F(xr) xor FP[i - 1]);
+    System.Dec(i, 2);
+  end;
+
+  xr := xr xor FP[0];
+
+  TConverters.ReadUInt32AsBytesBE(xr, dst, dstIndex);
+  TConverters.ReadUInt32AsBytesBE(xl, dst, dstIndex + 4);
+end;
+
+function TBlowfishEngine.GetAlgorithmName: String;
+begin
+  result := 'Blowfish';
+end;
+
+function TBlowfishEngine.GetBlockSize: Int32;
+begin
+  result := BLOCK_SIZE;
+end;
+
+function TBlowfishEngine.GetIsPartialBlockOkay: Boolean;
+begin
+  result := false;
+end;
+
+procedure TBlowfishEngine.Init(forEncryption: Boolean;
+  const parameters: ICipherParameters);
+var
+  keyParameter: IKeyParameter;
+begin
+  if not Supports(parameters, IKeyParameter, keyParameter) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt
+      (@SInvalidParameterBlowfishInit, [(parameters as TObject).ToString]);
+  end;
+  FforEncryption := forEncryption;
+  FWorkingKey := keyParameter.GetKey();
+  SetKey(FWorkingKey);
+end;
+
+function TBlowfishEngine.ProcessBlock(const input: TCryptoLibByteArray;
+  inOff: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
+begin
+
+  if (FWorkingKey = Nil) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SBlowfishEngineNotInitialised);
+  end;
+
+  TCheck.DataLength(input, inOff, BLOCK_SIZE, SInputBuffertooShort);
+  TCheck.OutputLength(output, outOff, BLOCK_SIZE, SOutputBuffertooShort);
+
+  if (FforEncryption) then
+  begin
+    EncryptBlock(input, inOff, output, outOff);
+  end
+  else
+  begin
+    DecryptBlock(input, inOff, output, outOff);
+  end;
+
+  result := BLOCK_SIZE;
+end;
+
+procedure TBlowfishEngine.ProcessTable(xl, xr: UInt32;
+  var table: array of UInt32);
+var
+  size, s, i: Int32;
+begin
+  size := System.Length(table);
+  s := 0;
+  while s < size do
+  begin
+    xl := xl xor FP[0];
+    i := 1;
+    while i < ROUNDS do
+    begin
+      xr := xr xor (F(xl) xor FP[i]);
+      xl := xl xor (F(xr) xor FP[i + 1]);
+      System.Inc(i, 2);
+    end;
+
+    xr := xr xor FP[ROUNDS + 1];
+
+    table[s] := xr;
+    table[s + 1] := xl;
+
+    xr := xl; // end of cycle swap
+    xl := table[s];
+    System.Inc(s, 2);
+  end;
+end;
+
+procedure TBlowfishEngine.Reset;
+begin
+  // nothing to do.
+end;
+
+end.

+ 30 - 13
CryptoLib/src/Crypto/Engines/ClpIESEngine.pas

@@ -259,12 +259,18 @@ begin
     if (System.Length(FV) <> 0) then
     begin
       System.Move(K[0], K2[0], System.Length(K2) * System.SizeOf(Byte));
-      System.Move(K[System.Length(K2)], K1[0], System.Length(K1) *
-        System.SizeOf(Byte));
+      if K1 <> Nil then
+      begin
+        System.Move(K[System.Length(K2)], K1[0],
+          System.Length(K1) * System.SizeOf(Byte));
+      end;
     end
     else
     begin
-      System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+      if K1 <> Nil then
+      begin
+        System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+      end;
       System.Move(K[System.Length(K1)], K2[0], System.Length(K2) *
         System.SizeOf(Byte));
     end;
@@ -365,7 +371,7 @@ function TIESEngine.EncryptBlock(const &in: TCryptoLibByteArray;
   inOff, inLen: Int32): TCryptoLibByteArray;
 var
   C, K, K1, K2, p2, L2, T: TCryptoLibByteArray;
-  len, i: Int32;
+  len, i, lenCount: Int32;
 begin
   if (Fcipher = Nil) then
   begin
@@ -379,12 +385,18 @@ begin
     if (System.Length(FV) <> 0) then
     begin
       System.Move(K[0], K2[0], System.Length(K2) * System.SizeOf(Byte));
-      System.Move(K[System.Length(K2)], K1[0], System.Length(K1) *
-        System.SizeOf(Byte));
+      if K1 <> Nil then
+      begin
+        System.Move(K[System.Length(K2)], K1[0],
+          System.Length(K1) * System.SizeOf(Byte));
+      end;
     end
     else
     begin
-      System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+      if K1 <> Nil then
+      begin
+        System.Move(K[0], K1[0], System.Length(K1) * System.SizeOf(Byte));
+      end;
       System.Move(K[inLen], K2[0], System.Length(K2) * System.SizeOf(Byte));
     end;
 
@@ -460,8 +472,15 @@ begin
   // C := Encrypted Payload
   // T := Authentication Message (MAC)
   System.SetLength(Result, System.Length(FV) + len + System.Length(T));
-  System.Move(FV[0], Result[0], System.Length(FV) * System.SizeOf(Byte));
-  System.Move(C[0], Result[System.Length(FV)], len * System.SizeOf(Byte));
+  if FV <> Nil then
+  begin
+    System.Move(FV[0], Result[0], System.Length(FV) * System.SizeOf(Byte));
+  end;
+  lenCount := len * System.SizeOf(Byte);
+  if lenCount > 0 then
+  begin
+    System.Move(C[0], Result[System.Length(FV)], lenCount);
+  end;
   System.Move(T[0], Result[System.Length(FV) + len],
     System.Length(T) * System.SizeOf(Byte));
 
@@ -585,8 +604,7 @@ begin
   if (System.Length(FV) <> 0) then
   begin
     VZ := TArrayUtils.Concatenate(FV, BigZ);
-    System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
-      Byte(0));
+    TArrayUtils.Fill(BigZ, 0, System.Length(BigZ), Byte(0));
     BigZ := VZ;
   end;
 
@@ -607,8 +625,7 @@ begin
     end;
 
   finally
-    System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
-      Byte(0));
+    TArrayUtils.Fill(BigZ, 0, System.Length(BigZ), Byte(0));
   end;
 end;
 

+ 8 - 21
CryptoLib/src/Crypto/Engines/ClpPascalCoinIESEngine.pas

@@ -39,7 +39,6 @@ uses
   ClpArrayUtils,
   ClpBigInteger,
   ClpBigIntegers,
-  ClpBitConverter,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -165,7 +164,7 @@ end;
 function TPascalCoinIESEngine.EncryptBlock(const &in: TCryptoLibByteArray;
   inOff, inLen: Int32): TCryptoLibByteArray;
 var
-  C, K, K1, K2, T, tempHolder: TCryptoLibByteArray;
+  C, K, K1, K2, T: TCryptoLibByteArray;
   MessageToEncryptPadSize, CipherBlockSize, MessageToEncryptSize: Int32;
 begin
   if (Fcipher = Nil) then
@@ -235,22 +234,11 @@ begin
   System.SetLength(Result, SECURE_HEAD_SIZE + System.Length(FV) +
     System.Length(T) + System.Length(C));
 
-  tempHolder := TBitConverter.GetBytes(Byte(System.Length(FV)));
-
-  System.Move(tempHolder[0], Result[0], System.SizeOf(Byte));
-
-  tempHolder := TBitConverter.GetBytes(Byte(System.Length(T)));
-
-  System.Move(tempHolder[0], Result[1], System.SizeOf(Byte));
-
-  tempHolder := TBitConverter.GetBytes(UInt16(MessageToEncryptSize));
-
-  System.Move(tempHolder[0], Result[2], System.SizeOf(UInt16));
-
-  tempHolder := TBitConverter.GetBytes
-    (UInt16(MessageToEncryptSize + MessageToEncryptPadSize));
-
-  System.Move(tempHolder[0], Result[4], System.SizeOf(UInt16));
+  PByte(Result)^ := Byte(System.Length(FV));
+  (PByte(Result) + 1)^ := Byte(System.Length(T));
+  (PWord(Result) + 1)^ := UInt16(MessageToEncryptSize);
+  (PWord(Result) + 2)^ :=
+    UInt16(MessageToEncryptSize + MessageToEncryptPadSize);
 
   System.Move(FV[0], Result[SECURE_HEAD_SIZE], System.Length(FV) *
     System.SizeOf(Byte));
@@ -291,8 +279,8 @@ begin
       bIn := TBytesStream.Create(System.Copy(&in, inOff, inLen));
 
       try
-        bIn.Position := SECURE_HEAD_SIZE;
         // for existing PascalCoin compatiblity purposes
+        bIn.Position := SECURE_HEAD_SIZE;
 
         try
           FpubParam := FkeyParser.ReadKey(bIn);
@@ -344,8 +332,7 @@ begin
     end;
 
   finally
-    System.FillChar(BigZ[0], System.Length(BigZ) * System.SizeOf(Byte),
-      Byte(0));
+    TArrayUtils.Fill(BigZ, 0, System.Length(BigZ), Byte(0));
   end;
 end;
 

+ 0 - 2
CryptoLib/src/Crypto/Generators/ClpHkdfBytesGenerator.pas

@@ -60,8 +60,6 @@ type
     FhashLen, FgeneratedBytes: Int32;
     Finfo, FcurrentT: TCryptoLibByteArray;
 
-  strict private
-
     /// <summary>
     /// Performs the extract part of the key derivation function.
     /// </summary>

+ 2 - 2
CryptoLib/src/Crypto/Modes/ClpCbcBlockCipher.pas

@@ -27,6 +27,7 @@ uses
   ClpICbcBlockCipher,
   ClpICipherParameters,
   ClpIParametersWithIV,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -283,8 +284,7 @@ end;
 procedure TCbcBlockCipher.Reset;
 begin
   System.Move(FIV[0], FcbcV[0], System.length(FIV));
-  System.FillChar(FcbcNextV[0], System.length(FcbcNextV) *
-    System.SizeOf(Byte), Byte(0));
+  TArrayUtils.Fill(FcbcNextV, 0, System.length(FcbcNextV), Byte(0));
 
   Fcipher.Reset();
 end;

+ 15 - 7
CryptoLib/src/Crypto/Modes/ClpCfbBlockCipher.pas

@@ -27,6 +27,7 @@ uses
   ClpICfbBlockCipher,
   ClpICipherParameters,
   ClpIParametersWithIV,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -222,7 +223,7 @@ end;
 function TCfbBlockCipher.DecryptBlock(const input: TCryptoLibByteArray;
   inOff: Int32; const outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
 var
-  I: Int32;
+  I, count: Int32;
 begin
   if ((inOff + FblockSize) > System.length(input)) then
   begin
@@ -239,8 +240,11 @@ begin
   //
   // change over the input block.
   //
-  System.Move(FcfbV[FblockSize], FcfbV[0], (System.length(FcfbV) - FblockSize) *
-    System.SizeOf(Byte));
+  count := (System.length(FcfbV) - FblockSize) * System.SizeOf(Byte);
+  if count > 0 then
+  begin
+    System.Move(FcfbV[FblockSize], FcfbV[0], count);
+  end;
 
   System.Move(input[inOff], FcfbV[(System.length(FcfbV) - FblockSize)],
     FblockSize * System.SizeOf(Byte));
@@ -258,7 +262,7 @@ end;
 function TCfbBlockCipher.EncryptBlock(const input: TCryptoLibByteArray;
   inOff: Int32; const outBytes: TCryptoLibByteArray; outOff: Int32): Int32;
 var
-  I: Int32;
+  I, count: Int32;
 begin
   if ((inOff + FblockSize) > System.length(input)) then
   begin
@@ -282,8 +286,12 @@ begin
   //
   // change over the input block.
   //
-  System.Move(FcfbV[FblockSize], FcfbV[0], (System.length(FcfbV) - FblockSize) *
-    System.SizeOf(Byte));
+  count := (System.length(FcfbV) - FblockSize) * System.SizeOf(Byte);
+
+  if count > 0 then
+  begin
+    System.Move(FcfbV[FblockSize], FcfbV[0], count);
+  end;
 
   System.Move(outBytes[outOff], FcfbV[(System.length(FcfbV) - FblockSize)],
     FblockSize * System.SizeOf(Byte));
@@ -336,7 +344,7 @@ begin
     diff := System.length(FIV) - System.length(iv);
 
     System.Move(iv[0], FIV[diff], System.length(iv) * System.SizeOf(Byte));
-    System.FillChar(FIV[0], diff, Byte(0));
+    TArrayUtils.Fill(FIV, 0, diff, Byte(0));
 
     Lparameters := ivParam.parameters;
   end;

+ 7 - 3
CryptoLib/src/Crypto/Modes/ClpOfbBlockCipher.pas

@@ -243,7 +243,7 @@ end;
 function TOfbBlockCipher.ProcessBlock(const input: TCryptoLibByteArray;
   inOff: Int32; const output: TCryptoLibByteArray; outOff: Int32): Int32;
 var
-  I: Int32;
+  I, count: Int32;
 begin
   if ((inOff + FblockSize) > System.length(input)) then
   begin
@@ -270,8 +270,12 @@ begin
   //
   // change over the input block.
   //
-  System.Move(FofbV[FblockSize], FofbV[0], (System.length(FofbV) - FblockSize) *
-    System.SizeOf(Byte));
+  count := (System.length(FofbV) - FblockSize) * System.SizeOf(Byte);
+
+  if count > 0 then
+  begin
+    System.Move(FofbV[FblockSize], FofbV[0], count);
+  end;
 
   System.Move(FofbOutV[0], FofbV[(System.length(FofbV) - FblockSize)],
     FblockSize * System.SizeOf(Byte));

+ 2 - 2
CryptoLib/src/Crypto/Modes/ClpSicBlockCipher.pas

@@ -28,6 +28,7 @@ uses
   ClpISicBlockCipher,
   ClpICipherParameters,
   ClpIParametersWithIV,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -170,8 +171,7 @@ end;
 
 procedure TSicBlockCipher.Reset;
 begin
-  System.FillChar(Fcounter[0], System.Length(Fcounter) *
-    System.SizeOf(Byte), Byte(0));
+  TArrayUtils.Fill(Fcounter, 0, System.Length(Fcounter), Byte(0));
   System.Move(FIV[0], Fcounter[0], System.Length(FIV) * System.SizeOf(Byte));
 
   Fcipher.Reset();

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

@@ -232,7 +232,7 @@ end;
 function TPaddedBufferedBlockCipher.DoFinal(const output: TCryptoLibByteArray;
   outOff: Int32): Int32;
 var
-  blockSize, resultLen: Int32;
+  blockSize, resultLen, resultTotalLen: Int32;
 begin
   blockSize := Fcipher.GetBlockSize();
   resultLen := 0;
@@ -276,8 +276,11 @@ begin
 
     try
       resultLen := resultLen - Fpadding.PadCount(Fbuf);
-
-      System.Move(Fbuf[0], output[outOff], resultLen * System.SizeOf(Byte));
+      resultTotalLen := resultLen * System.SizeOf(Byte);
+      if resultTotalLen > 0 then
+      begin
+        System.Move(Fbuf[0], output[outOff], resultTotalLen);
+      end;
 
     finally
       Reset();

+ 8 - 0
CryptoLib/src/Crypto/Parameters/ClpKeyParameter.pas

@@ -24,6 +24,7 @@ interface
 uses
   ClpIKeyParameter,
   ClpICipherParameters,
+  ClpArrayUtils,
   ClpCryptoLibTypes;
 
 resourcestring
@@ -43,6 +44,7 @@ type
     constructor Create(const key: TCryptoLibByteArray); overload;
     constructor Create(const key: TCryptoLibByteArray;
       keyOff, keyLen: Int32); overload;
+    destructor Destroy; override;
     function GetKey(): TCryptoLibByteArray; inline;
 
   end;
@@ -87,6 +89,12 @@ begin
 
 end;
 
+destructor TKeyParameter.Destroy;
+begin
+  TArrayUtils.Fill(Fkey, 0, System.Length(Fkey), Byte(0));
+  inherited Destroy;
+end;
+
 function TKeyParameter.GetKey: TCryptoLibByteArray;
 begin
   result := System.Copy(Fkey);

+ 7 - 0
CryptoLib/src/Crypto/Parameters/ClpParametersWithIV.pas

@@ -46,6 +46,7 @@ type
       const iv: TCryptoLibByteArray); overload;
     constructor Create(const parameters: ICipherParameters;
       const iv: TCryptoLibByteArray; ivOff, ivLen: Int32); overload;
+    destructor Destroy; override;
     function GetIV(): TCryptoLibByteArray; inline;
     property parameters: ICipherParameters read GetParameters;
 
@@ -76,6 +77,12 @@ begin
   Fiv := TArrayUtils.CopyOfRange(iv, ivOff, ivOff + ivLen);
 end;
 
+destructor TParametersWithIV.Destroy;
+begin
+  TArrayUtils.Fill(Fiv, 0, System.Length(Fiv), Byte(0));
+  inherited Destroy;
+end;
+
 function TParametersWithIV.GetIV: TCryptoLibByteArray;
 begin
   result := System.Copy(Fiv);

+ 39 - 1
CryptoLib/src/Crypto/Prng/ClpCryptoApiRandomGenerator.pas

@@ -22,6 +22,7 @@ unit ClpCryptoApiRandomGenerator;
 interface
 
 uses
+  SyncObjs,
   ClpCryptoLibTypes,
   ClpIRandomNumberGenerator,
   ClpRandomNumberGenerator,
@@ -40,8 +41,17 @@ type
     ICryptoApiRandomGenerator, IRandomGenerator)
 
   strict private
+  var
     FrndProv: IRandomNumberGenerator;
 
+  class var
+
+    FLock: TCriticalSection;
+    FIsBooted: Boolean;
+
+    class constructor CreateCryptoApiRandomGenerator();
+    class destructor DestroyCryptoApiRandomGenerator();
+
   public
     /// <summary>
     /// Uses TRandomNumberGenerator.CreateRNG() to Get randomness generator
@@ -69,6 +79,8 @@ type
     procedure NextBytes(const bytes: TCryptoLibByteArray; start, len: Int32);
       overload; virtual;
 
+    class procedure Boot(); static;
+
   end;
 
 implementation
@@ -80,6 +92,16 @@ begin
   // We don't care about the seed
 end;
 
+class procedure TCryptoApiRandomGenerator.Boot;
+begin
+  if not FIsBooted then
+  begin
+    FLock := TCriticalSection.Create;
+
+    FIsBooted := True;
+  end;
+end;
+
 procedure TCryptoApiRandomGenerator.AddSeedMaterial
   (const seed: TCryptoLibByteArray);
 begin
@@ -90,6 +112,17 @@ constructor TCryptoApiRandomGenerator.Create(const rng: IRandomNumberGenerator);
 begin
   Inherited Create();
   FrndProv := rng;
+  TCryptoApiRandomGenerator.Boot;
+end;
+
+class constructor TCryptoApiRandomGenerator.CreateCryptoApiRandomGenerator;
+begin
+  TCryptoApiRandomGenerator.Boot;
+end;
+
+class destructor TCryptoApiRandomGenerator.DestroyCryptoApiRandomGenerator;
+begin
+  FLock.Free;
 end;
 
 constructor TCryptoApiRandomGenerator.Create;
@@ -99,7 +132,12 @@ end;
 
 procedure TCryptoApiRandomGenerator.NextBytes(const bytes: TCryptoLibByteArray);
 begin
-  FrndProv.GetBytes(bytes);
+  FLock.Acquire;
+  try
+    FrndProv.GetBytes(bytes);
+  finally
+    FLock.Release;
+  end;
 end;
 
 procedure TCryptoApiRandomGenerator.NextBytes(const bytes: TCryptoLibByteArray;

+ 17 - 3
CryptoLib/src/Crypto/Prng/ClpDigestRandomGenerator.pas

@@ -55,9 +55,10 @@ type
     procedure DigestUpdate(const inSeed: TCryptoLibByteArray); inline;
     procedure DigestDoFinal(const result: TCryptoLibByteArray); inline;
 
-    class var
+  class var
 
-      FLock: TCriticalSection;
+    FLock: TCriticalSection;
+    FIsBooted: Boolean;
 
     class constructor CreateDigestRandomGenerator();
     class destructor DestroyDigestRandomGenerator();
@@ -72,6 +73,8 @@ type
     procedure NextBytes(const bytes: TCryptoLibByteArray;
       start, len: Int32); overload;
 
+    class procedure Boot(); static;
+
   end;
 
 implementation
@@ -111,6 +114,16 @@ begin
   end;
 end;
 
+class procedure TDigestRandomGenerator.Boot;
+begin
+  if not FIsBooted then
+  begin
+    FLock := TCriticalSection.Create;
+
+    FIsBooted := True;
+  end;
+end;
+
 procedure TDigestRandomGenerator.AddSeedMaterial(const inSeed
   : TCryptoLibByteArray);
 begin
@@ -132,11 +145,12 @@ begin
   FseedCounter := 1;
   System.SetLength(Fstate, digest.GetDigestSize);
   FstateCounter := 1;
+  TDigestRandomGenerator.Boot;
 end;
 
 class constructor TDigestRandomGenerator.CreateDigestRandomGenerator;
 begin
-  FLock := TCriticalSection.Create;
+  TDigestRandomGenerator.Boot;
 end;
 
 procedure TDigestRandomGenerator.CycleSeed;

+ 47 - 43
CryptoLib/src/Crypto/Signers/ClpDsaDigestSigner.pas

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

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

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

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

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

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

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

+ 0 - 151
CryptoLib/src/Crypto/Signers/ClpECSchnorrBSISigner.pas

@@ -1,151 +0,0 @@
-{ *********************************************************************************** }
-{ *                              CryptoLib Library                                  * }
-{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
-{ *                 Github Repository <https://github.com/Xor-el>                   * }
-
-{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
-{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
-
-{ *                              Acknowledgements:                                  * }
-{ *                                                                                 * }
-{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
-{ *                           development of this library                           * }
-
-{ * ******************************************************************************* * }
-
-(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
-
-unit ClpECSchnorrBSISigner;
-
-{$I ..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  ClpIECInterface,
-  ClpIECPrivateKeyParameters,
-  ClpIECPublicKeyParameters,
-  ClpISchnorr,
-  ClpIECSchnorrBSISigner,
-  ClpIDigest,
-  ClpBits,
-  ClpBigInteger,
-  ClpCryptoLibTypes;
-
-type
-  TECSchnorrBSISigner = class sealed(TInterfacedObject, ISchnorr,
-    IECSchnorrBSISigner)
-
-  public
-    function GetAlgorithmName: String; inline;
-    property AlgorithmName: String read GetAlgorithmName;
-
-    function Do_Sign(const &message: TCryptoLibByteArray; const digest: IDigest;
-      const pv_key: IECPrivateKeyParameters; const k: TBigInteger)
-      : TCryptoLibByteArray;
-
-    function Do_Verify(const &message: TCryptoLibByteArray;
-      const digest: IDigest; const pu_key: IECPublicKeyParameters;
-      const sig: TCryptoLibByteArray): Boolean;
-
-  end;
-
-implementation
-
-uses
-  // included here to avoid circular dependency :)
-  ClpECSchnorrSigner;
-
-{ TECSchnorrBSISigner }
-
-function TECSchnorrBSISigner.Do_Sign(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pv_key: IECPrivateKeyParameters;
-  const k: TBigInteger): TCryptoLibByteArray;
-var
-  curve: IECCurve;
-  n, r, s: TBigInteger;
-  G, q: IECPoint;
-  xQ, tempR: TCryptoLibByteArray;
-begin
-
-  curve := pv_key.parameters.curve;
-  n := curve.order;
-  G := pv_key.parameters.G;
-
-  q := G.Multiply(k);
-
-  xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
-
-  System.SetLength(tempR, digest.GetDigestSize);
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.BlockUpdate(xQ, 0, System.Length(xQ));
-  digest.DoFinal(tempR, 0);
-
-  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 := TECSchnorrSigner.Encode_Sig(r, s);
-    Exit;
-  end;
-end;
-
-function TECSchnorrBSISigner.Do_Verify(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pu_key: IECPublicKeyParameters;
-  const sig: TCryptoLibByteArray): Boolean;
-var
-  curve: IECCurve;
-  n, r, s, v: TBigInteger;
-  Size: Int32;
-  G, q, sG, rW: IECPoint;
-  xQ, tempV: TCryptoLibByteArray;
-  R_and_S: TCryptoLibGenericArray<TBigInteger>;
-begin
-
-  curve := pu_key.parameters.curve;
-  n := curve.order;
-  G := pu_key.parameters.G;
-  Size := TBits.Asr32(curve.FieldSize, 3);
-
-  R_and_S := TECSchnorrSigner.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);
-
-  rW := pu_key.q.Multiply(r);
-  q := sG.Add(rW);
-  xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
-
-  System.SetLength(tempV, digest.GetDigestSize);
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.BlockUpdate(xQ, 0, System.Length(xQ));
-  digest.DoFinal(tempV, 0);
-
-  v := TBigInteger.Create(1, tempV);
-  Result := v.Equals(r);
-  Exit;
-
-end;
-
-function TECSchnorrBSISigner.GetAlgorithmName: String;
-begin
-  Result := 'BSI';
-end;
-
-end.

+ 0 - 155
CryptoLib/src/Crypto/Signers/ClpECSchnorrISOSigner.pas

@@ -1,155 +0,0 @@
-{ *********************************************************************************** }
-{ *                              CryptoLib Library                                  * }
-{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
-{ *                 Github Repository <https://github.com/Xor-el>                   * }
-
-{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
-{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
-
-{ *                              Acknowledgements:                                  * }
-{ *                                                                                 * }
-{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
-{ *                           development of this library                           * }
-
-{ * ******************************************************************************* * }
-
-(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
-
-unit ClpECSchnorrISOSigner;
-
-{$I ..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  ClpIECInterface,
-  ClpIECPrivateKeyParameters,
-  ClpIECPublicKeyParameters,
-  ClpISchnorr,
-  ClpIECSchnorrISOSigner,
-  ClpIDigest,
-  ClpBits,
-  ClpBigInteger,
-  ClpCryptoLibTypes;
-
-type
-  TECSchnorrISOSigner = class sealed(TInterfacedObject, ISchnorr,
-    IECSchnorrISOSigner)
-
-  public
-    function GetAlgorithmName: String; inline;
-    property AlgorithmName: String read GetAlgorithmName;
-
-    function Do_Sign(const &message: TCryptoLibByteArray; const digest: IDigest;
-      const pv_key: IECPrivateKeyParameters; const k: TBigInteger)
-      : TCryptoLibByteArray;
-
-    function Do_Verify(const &message: TCryptoLibByteArray;
-      const digest: IDigest; const pu_key: IECPublicKeyParameters;
-      const sig: TCryptoLibByteArray): Boolean;
-
-  end;
-
-implementation
-
-uses
-  // included here to avoid circular dependency :)
-  ClpECSchnorrSigner;
-
-{ TECSchnorrISOSigner }
-
-function TECSchnorrISOSigner.Do_Sign(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pv_key: IECPrivateKeyParameters;
-  const k: TBigInteger): TCryptoLibByteArray;
-var
-  curve: IECCurve;
-  n, r, s: TBigInteger;
-  G, q: IECPoint;
-  xQ, yQ, tempR: TCryptoLibByteArray;
-begin
-
-  curve := pv_key.parameters.curve;
-  n := curve.order;
-  G := pv_key.parameters.G;
-
-  q := G.Multiply(k);
-
-  xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
-  yQ := q.Normalize.YCoord.ToBigInteger.ToByteArray;
-
-  System.SetLength(tempR, digest.GetDigestSize);
-  digest.BlockUpdate(xQ, 0, System.Length(xQ));
-  digest.BlockUpdate(yQ, 0, System.Length(yQ));
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.DoFinal(tempR, 0);
-
-  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 := TECSchnorrSigner.Encode_Sig(r, s);
-    Exit;
-  end;
-end;
-
-function TECSchnorrISOSigner.Do_Verify(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pu_key: IECPublicKeyParameters;
-  const sig: TCryptoLibByteArray): Boolean;
-var
-  curve: IECCurve;
-  n, r, s, v: TBigInteger;
-  Size: Int32;
-  G, q, sG, rW: IECPoint;
-  xQ, yQ, tempV: TCryptoLibByteArray;
-  R_and_S: TCryptoLibGenericArray<TBigInteger>;
-begin
-
-  curve := pu_key.parameters.curve;
-  n := curve.order;
-  G := pu_key.parameters.G;
-  Size := TBits.Asr32(curve.FieldSize, 3);
-
-  R_and_S := TECSchnorrSigner.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);
-
-  rW := pu_key.q.Multiply(r);
-  q := sG.Subtract(rW);
-  xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
-  yQ := q.Normalize.YCoord.ToBigInteger.ToByteArray;
-
-  System.SetLength(tempV, digest.GetDigestSize);
-  digest.BlockUpdate(xQ, 0, System.Length(xQ));
-  digest.BlockUpdate(yQ, 0, System.Length(yQ));
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.DoFinal(tempV, 0);
-
-  v := TBigInteger.Create(1, tempV);
-  Result := v.Equals(r);
-  Exit;
-
-end;
-
-function TECSchnorrISOSigner.GetAlgorithmName: String;
-begin
-  Result := 'ISO';
-end;
-
-end.

+ 0 - 151
CryptoLib/src/Crypto/Signers/ClpECSchnorrISOXSigner.pas

@@ -1,151 +0,0 @@
-{ *********************************************************************************** }
-{ *                              CryptoLib Library                                  * }
-{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
-{ *                 Github Repository <https://github.com/Xor-el>                   * }
-
-{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
-{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
-
-{ *                              Acknowledgements:                                  * }
-{ *                                                                                 * }
-{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
-{ *                           development of this library                           * }
-
-{ * ******************************************************************************* * }
-
-(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
-
-unit ClpECSchnorrISOXSigner;
-
-{$I ..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  ClpIECInterface,
-  ClpIECPrivateKeyParameters,
-  ClpIECPublicKeyParameters,
-  ClpISchnorr,
-  ClpIECSchnorrISOXSigner,
-  ClpIDigest,
-  ClpBits,
-  ClpBigInteger,
-  ClpCryptoLibTypes;
-
-type
-  TECSchnorrISOXSigner = class sealed(TInterfacedObject, ISchnorr,
-    IECSchnorrISOXSigner)
-
-  public
-    function GetAlgorithmName: String; inline;
-    property AlgorithmName: String read GetAlgorithmName;
-
-    function Do_Sign(const &message: TCryptoLibByteArray; const digest: IDigest;
-      const pv_key: IECPrivateKeyParameters; const k: TBigInteger)
-      : TCryptoLibByteArray;
-
-    function Do_Verify(const &message: TCryptoLibByteArray;
-      const digest: IDigest; const pu_key: IECPublicKeyParameters;
-      const sig: TCryptoLibByteArray): Boolean;
-
-  end;
-
-implementation
-
-uses
-  // included here to avoid circular dependency :)
-  ClpECSchnorrSigner;
-
-{ TECSchnorrISOXSigner }
-
-function TECSchnorrISOXSigner.Do_Sign(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pv_key: IECPrivateKeyParameters;
-  const k: TBigInteger): TCryptoLibByteArray;
-var
-  curve: IECCurve;
-  n, r, s: TBigInteger;
-  G, q: IECPoint;
-  xQ, tempR: TCryptoLibByteArray;
-begin
-
-  curve := pv_key.parameters.curve;
-  n := curve.order;
-  G := pv_key.parameters.G;
-
-  q := G.Multiply(k);
-
-  xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
-
-  System.SetLength(tempR, digest.GetDigestSize);
-  digest.BlockUpdate(xQ, 0, System.Length(xQ));
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.DoFinal(tempR, 0);
-
-  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 := TECSchnorrSigner.Encode_Sig(r, s);
-    Exit;
-  end;
-end;
-
-function TECSchnorrISOXSigner.Do_Verify(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pu_key: IECPublicKeyParameters;
-  const sig: TCryptoLibByteArray): Boolean;
-var
-  curve: IECCurve;
-  n, r, s, v: TBigInteger;
-  Size: Int32;
-  G, q, sG, rW: IECPoint;
-  xQ, tempV: TCryptoLibByteArray;
-  R_and_S: TCryptoLibGenericArray<TBigInteger>;
-begin
-
-  curve := pu_key.parameters.curve;
-  n := curve.order;
-  G := pu_key.parameters.G;
-  Size := TBits.Asr32(curve.FieldSize, 3);
-
-  R_and_S := TECSchnorrSigner.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);
-
-  rW := pu_key.q.Multiply(r);
-  q := sG.Subtract(rW);
-  xQ := q.Normalize.XCoord.ToBigInteger.ToByteArray;
-
-  System.SetLength(tempV, digest.GetDigestSize);
-  digest.BlockUpdate(xQ, 0, System.Length(xQ));
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.DoFinal(tempV, 0);
-
-  v := TBigInteger.Create(1, tempV);
-  Result := v.Equals(r);
-  Exit;
-
-end;
-
-function TECSchnorrISOXSigner.GetAlgorithmName: String;
-begin
-  Result := 'ISOX';
-end;
-
-end.

+ 0 - 161
CryptoLib/src/Crypto/Signers/ClpECSchnorrLIBSECPSigner.pas

@@ -1,161 +0,0 @@
-{ *********************************************************************************** }
-{ *                              CryptoLib Library                                  * }
-{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
-{ *                 Github Repository <https://github.com/Xor-el>                   * }
-
-{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
-{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
-
-{ *                              Acknowledgements:                                  * }
-{ *                                                                                 * }
-{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
-{ *                           development of this library                           * }
-
-{ * ******************************************************************************* * }
-
-(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
-
-unit ClpECSchnorrLIBSECPSigner;
-
-{$I ..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  ClpIECInterface,
-  ClpIECPrivateKeyParameters,
-  ClpIECPublicKeyParameters,
-  ClpISchnorr,
-  ClpIECSchnorrLIBSECPSigner,
-  ClpIDigest,
-  ClpBits,
-  ClpBigInteger,
-  ClpCryptoLibTypes;
-
-type
-  TECSchnorrLIBSECPSigner = class sealed(TInterfacedObject, ISchnorr,
-    IECSchnorrLIBSECPSigner)
-
-  public
-    function GetAlgorithmName: String; inline;
-    property AlgorithmName: String read GetAlgorithmName;
-
-    function Do_Sign(const &message: TCryptoLibByteArray; const digest: IDigest;
-      const pv_key: IECPrivateKeyParameters; const k: TBigInteger)
-      : TCryptoLibByteArray;
-
-    function Do_Verify(const &message: TCryptoLibByteArray;
-      const digest: IDigest; const pu_key: IECPublicKeyParameters;
-      const sig: TCryptoLibByteArray): Boolean;
-
-  end;
-
-implementation
-
-uses
-  // included here to avoid circular dependency :)
-  ClpECSchnorrSigner;
-
-{ TECSchnorrLIBSECPSigner }
-
-function TECSchnorrLIBSECPSigner.Do_Sign(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pv_key: IECPrivateKeyParameters;
-  const k: TBigInteger): TCryptoLibByteArray;
-var
-  curve: IECCurve;
-  n, r, s, h, tempK: TBigInteger;
-  G, q: IECPoint;
-  rQ, tempH: TCryptoLibByteArray;
-begin
-
-  curve := pv_key.parameters.curve;
-  n := curve.order;
-  G := pv_key.parameters.G;
-
-  q := G.Multiply(k);
-
-  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;
-
-  System.SetLength(tempH, digest.GetDigestSize);
-  digest.BlockUpdate(rQ, 0, System.Length(rQ));
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.DoFinal(tempH, 0);
-
-  h := TBigInteger.Create(1, tempH);
-  r := q.Normalize.XCoord.ToBigInteger.&Mod(n);
-  s := (tempK.Subtract(h.Multiply(pv_key.D))).&Mod(n);
-
-  Result := TECSchnorrSigner.Encode_Sig(r, s);
-  Exit;
-
-end;
-
-function TECSchnorrLIBSECPSigner.Do_Verify(const &message: TCryptoLibByteArray;
-  const digest: IDigest; const pu_key: IECPublicKeyParameters;
-  const sig: TCryptoLibByteArray): Boolean;
-var
-  curve: IECCurve;
-  n, r, s, h, v: TBigInteger;
-  Size: Int32;
-  G, sG, hW, LR: IECPoint;
-  tempH, rb: TCryptoLibByteArray;
-  R_and_S: TCryptoLibGenericArray<TBigInteger>;
-begin
-
-  curve := pu_key.parameters.curve;
-  n := curve.order;
-  G := pu_key.parameters.G;
-  Size := TBits.Asr32(curve.FieldSize, 3);
-
-  R_and_S := TECSchnorrSigner.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);
-
-  rb := r.ToByteArray;
-
-  System.SetLength(tempH, digest.GetDigestSize);
-  digest.BlockUpdate(rb, 0, System.Length(rb));
-  digest.BlockUpdate(&message, 0, System.Length(&message));
-  digest.DoFinal(tempH, 0);
-
-  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;
-
-function TECSchnorrLIBSECPSigner.GetAlgorithmName: String;
-begin
-  Result := 'LIBSECP';
-end;
-
-end.

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

@@ -1,364 +0,0 @@
-{ *********************************************************************************** }
-{ *                              CryptoLib Library                                  * }
-{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
-{ *                 Github Repository <https://github.com/Xor-el>                   * }
-
-{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
-{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
-
-{ *                              Acknowledgements:                                  * }
-{ *                                                                                 * }
-{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
-{ *                           development of this library                           * }
-
-{ * ******************************************************************************* * }
-
-(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
-
-unit ClpECSchnorrSigner;
-
-{$I ..\..\Include\CryptoLib.inc}
-
-interface
-
-uses
-  SysUtils,
-  Classes,
-  ClpIDigest,
-  ClpISigner,
-  ClpSecureRandom,
-  ClpISecureRandom,
-  ClpICipherParameters,
-  ClpISchnorr,
-  ClpIECSchnorrSigner,
-  ClpIParametersWithRandom,
-  ClpDerSequence,
-  ClpDerInteger,
-  ClpIDerInteger,
-  ClpAsn1Object,
-  ClpIAsn1Sequence,
-  ClpBigInteger,
-  ClpBigIntegers,
-  ClpIECKeyParameters,
-  ClpIECPublicKeyParameters,
-  ClpIECPrivateKeyParameters,
-  ClpCryptoLibTypes;
-
-resourcestring
-  SECPublicKeyNotFound = 'EC Public Key Required for Verification';
-  SECPrivateKeyNotFound = 'EC Private Key Required for Signing';
-  SCurveNil = 'Key has no Curve';
-
-type
-  TECSchnorrSigner = class(TInterfacedObject, ISigner, IECSchnorrSigner)
-
-  strict private
-
-  var
-    FDigest: IDigest;
-    FRandom: ISecureRandom;
-    FSigner: ISchnorr;
-    FforSigning: Boolean;
-    Fkey: IECKeyParameters;
-    FBuffer: TMemoryStream;
-
-    function Aggregate: TCryptoLibByteArray; inline;
-
-  public
-
-    function Do_Sign(const pv_key: IECPrivateKeyParameters;
-      const k: TBigInteger): TCryptoLibByteArray;
-
-    function Do_Verify(const pu_key: IECPublicKeyParameters;
-      const sig: TCryptoLibByteArray): Boolean;
-
-    class function Encode_Sig(const r, s: TBigInteger)
-      : TCryptoLibByteArray; static;
-
-    class function Decode_Sig(const sig: TCryptoLibByteArray)
-      : TCryptoLibGenericArray<TBigInteger>; static;
-
-
-    // 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>`_
-    //
-    //
-    //
-    // *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="signer">
-    /// instance of one of "BSI","ISO","ISOX","LIBSECP"
-    /// </param>
-    /// <param name="digest">
-    /// initialized "IDigest" instance.
-    /// </param>
-    constructor Create(const signer: ISchnorr; const digest: IDigest);
-    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(const 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(const signature: TCryptoLibByteArray): Boolean;
-
-    /// <summary>
-    /// Reset the internal state
-    /// </summary>
-    procedure Reset();
-  end;
-
-implementation
-
-{ TECSchnorrSigner }
-
-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(const 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;
-begin
-  FBuffer.Position := 0;
-  System.SetLength(Result, FBuffer.Size);
-  FBuffer.Read(Result[0], FBuffer.Size);
-end;
-
-procedure TECSchnorrSigner.BlockUpdate(const input: TCryptoLibByteArray;
-  inOff, length: Int32);
-begin
-  FBuffer.Write(input[inOff], length);
-end;
-
-constructor TECSchnorrSigner.Create(const signer: ISchnorr;
-  const digest: IDigest);
-begin
-  inherited Create();
-  FDigest := digest;
-  FSigner := signer;
-  FBuffer := TMemoryStream.Create();
-end;
-
-destructor TECSchnorrSigner.Destroy;
-begin
-  FBuffer.Free;
-  inherited Destroy;
-end;
-
-function TECSchnorrSigner.Do_Sign(const pv_key: IECPrivateKeyParameters;
-  const k: TBigInteger): TCryptoLibByteArray;
-begin
-
-  if (pv_key.parameters.curve = Nil) then
-  begin
-    raise EArgumentNilCryptoLibException.CreateRes(@SCurveNil)
-  end;
-
-  Result := FSigner.Do_Sign(Aggregate(), FDigest, pv_key, k);
-end;
-
-function TECSchnorrSigner.Do_Verify(const pu_key: IECPublicKeyParameters;
-  const sig: TCryptoLibByteArray): Boolean;
-begin
-
-  if (pu_key.parameters.curve = Nil) then
-  begin
-    raise EArgumentNilCryptoLibException.CreateRes(@SCurveNil)
-  end;
-
-  Result := FSigner.Do_Verify(Aggregate(), FDigest, pu_key, sig);
-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.AlgorithmName + 'with' + 'ECSCHNORR' +
-    FSigner.AlgorithmName;
-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
-      FRandom := rParam.Random;
-      Lparameters := rParam.parameters;
-    end
-    else
-    begin
-      FRandom := TSecureRandom.Create();
-    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.Reset;
-  FBuffer.Clear;
-  FBuffer.SetSize(0);
-end;
-
-procedure TECSchnorrSigner.Update(input: Byte);
-begin
-  FBuffer.Write(TCryptoLibByteArray.Create(input)[0], 1);
-end;
-
-function TECSchnorrSigner.VerifySignature(const signature
-  : TCryptoLibByteArray): Boolean;
-var
-  pu_key_params: IECPublicKeyParameters;
-begin
-
-  pu_key_params := Fkey as IECPublicKeyParameters;
-
-  Result := Do_Verify(pu_key_params, signature);
-
-end;
-
-end.

+ 292 - 0
CryptoLib/src/Crypto/Signers/ClpECSchnorrSipaSigner.pas

@@ -0,0 +1,292 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpECSchnorrSipaSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  ClpIDigest,
+  ClpISchnorrExt,
+  ClpIECInterface,
+  ClpIECSchnorrSipaSigner,
+  ClpBigInteger,
+  ClpBigIntegers,
+  ClpISecureRandom,
+  ClpIECKeyParameters,
+  ClpIParametersWithRandom,
+  ClpICipherParameters,
+  ClpIECPrivateKeyParameters,
+  ClpIECPublicKeyParameters,
+  ClpSecureRandom,
+  ClpECAlgorithms,
+  ClpDigestUtilities,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SECPublicKeyNotFound = 'EC Public Key Required for Verification';
+  SECPrivateKeyNotFound = 'EC Private Key Required for Signing';
+  SNotInitializedForSigning = 'Not Initialised For Signing';
+  SNotInitializedForVerifying = 'Not Initialised For Verifying';
+  SSignatureGenerationError = 'An Error Occurred During Signature Generation';
+  SOnlyFPCurvesAllowed =
+    'Only FP (Prime Field) Curves are Allowed for This Schnorr Implementation';
+
+type
+
+  /// <summary>
+  /// <para>
+  /// Schnorr Signature as described in <see href="https://github.com/sipa/bips/blob/bip-schnorr/bip-schnorr.mediawiki">
+  /// bip-schnorr</see>
+  /// </para>
+  /// <para>
+  /// This <c>Schnorr</c> implementation only allows <c>FP(Prime Field)</c>
+  /// Curves.
+  /// </para>
+  /// </summary>
+  TECSchnorrSipaSigner = class sealed(TInterfacedObject, ISchnorrExt,
+    IECSchnorrSipaSigner)
+
+  strict private
+  var
+    FForSigning: Boolean;
+    FKey: IECKeyParameters;
+    FRandom: ISecureRandom;
+    FDigest: IDigest;
+
+    function GetAlgorithmName: String; virtual;
+    function GetOrder: TBigInteger; virtual;
+
+    function GetPP: TBigInteger; inline;
+    function GetG: IECPoint; inline;
+    function GetCurve: IECCurve; inline;
+
+    property PP: TBigInteger read GetPP;
+    property G: IECPoint read GetG;
+    property Curve: IECCurve read GetCurve;
+
+    class procedure ValidateAllowedCurves(const ACurve: IECCurve);
+      static; inline;
+
+    procedure Reset();
+
+  public
+
+    property Order: TBigInteger read GetOrder;
+    property AlgorithmName: String read GetAlgorithmName;
+
+    procedure Init(forSigning: Boolean; const parameters: ICipherParameters;
+      const digest: IDigest); virtual;
+
+    function GenerateSignature(const &message: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>; virtual;
+
+    function VerifySignature(const &message: TCryptoLibByteArray;
+      const RSig, SSig: TBigInteger): Boolean; virtual;
+
+  end;
+
+implementation
+
+{ TECSchnorrSipaSigner }
+
+function TECSchnorrSipaSigner.GenerateSignature(const &message
+  : TCryptoLibByteArray): TCryptoLibGenericArray<TBigInteger>;
+var
+  N, k, s, Xr, Yr, e, PrivateKey: TBigInteger;
+  input, keyPrefixedM: TCryptoLibByteArray;
+  P, r: IECPoint;
+  numBytes: Int32;
+begin
+  if (not FForSigning) then
+  begin
+    // not properly initialized... deal with it
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForSigning);
+  end;
+
+  N := Order;
+  numBytes := TBigIntegers.GetUnsignedByteLength(N);
+
+  PrivateKey := (FKey as IECPrivateKeyParameters).D;
+
+  input := TArrayUtils.Concatenate(TBigIntegers.BigIntegerToBytes(PrivateKey,
+    numBytes), &message);
+
+  k := TBigInteger.Create(1, TDigestUtilities.DoFinal(FDigest, input)).&Mod(N);
+
+  if k.CompareTo(TBigInteger.Zero) = 0 then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SSignatureGenerationError);
+  end;
+
+  r := G.Multiply(k).Normalize();
+  Xr := r.XCoord.ToBigInteger();
+  Yr := r.YCoord.ToBigInteger();
+  if (TBigInteger.Jacobi(Yr, PP) <> 1) then
+  begin
+    k := N.Subtract(k);
+  end;
+
+  P := G.Multiply(PrivateKey);
+  keyPrefixedM := TArrayUtils.Concatenate(TBigIntegers.BigIntegerToBytes(Xr,
+    numBytes), TCryptoLibMatrixByteArray.Create(P.GetEncoded(true), &message));
+
+  e := TBigInteger.Create(1, TDigestUtilities.DoFinal(FDigest,
+    keyPrefixedM)).&Mod(N);
+
+  s := k.Add(e.Multiply(PrivateKey)).&Mod(N);
+
+  result := TCryptoLibGenericArray<TBigInteger>.Create(Xr, s);
+end;
+
+function TECSchnorrSipaSigner.GetAlgorithmName: String;
+begin
+  result := 'ECSCHNORRSIPA';
+end;
+
+function TECSchnorrSipaSigner.GetCurve: IECCurve;
+begin
+  result := FKey.parameters.Curve;
+end;
+
+function TECSchnorrSipaSigner.GetG: IECPoint;
+begin
+  result := FKey.parameters.G;
+end;
+
+function TECSchnorrSipaSigner.GetOrder: TBigInteger;
+begin
+  result := FKey.parameters.N;
+end;
+
+function TECSchnorrSipaSigner.GetPP: TBigInteger;
+begin
+  result := Curve.Field.Characteristic;
+end;
+
+class procedure TECSchnorrSipaSigner.ValidateAllowedCurves
+  (const ACurve: IECCurve);
+begin
+  if (not(TECAlgorithms.IsFpCurve(ACurve))) then
+  begin
+    raise EArgumentCryptoLibException.CreateRes(@SOnlyFPCurvesAllowed);
+  end;
+end;
+
+procedure TECSchnorrSipaSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters; const digest: IDigest);
+var
+  rParam: IParametersWithRandom;
+  Lparameters: ICipherParameters;
+begin
+  FForSigning := forSigning;
+  FDigest := digest;
+  Lparameters := parameters;
+
+  if (forSigning) then
+  begin
+
+    if (Supports(Lparameters, IParametersWithRandom, rParam)) then
+    begin
+      FRandom := rParam.random;
+      Lparameters := rParam.parameters;
+    end
+    else
+    begin
+      FRandom := TSecureRandom.Create();
+    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;
+
+  ValidateAllowedCurves(Curve);
+  Reset();
+end;
+
+procedure TECSchnorrSipaSigner.Reset;
+begin
+  FDigest.Reset;
+end;
+
+function TECSchnorrSipaSigner.VerifySignature(const &message
+  : TCryptoLibByteArray; const RSig, SSig: TBigInteger): Boolean;
+var
+  N, e: TBigInteger;
+  PublicKeyBytes, input: TCryptoLibByteArray;
+  PublicKey: IECPublicKeyParameters;
+  P, Q, r: IECPoint;
+  numBytes: Int32;
+begin
+  if (FForSigning) then
+  begin
+    // not properly initialized... deal with it
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SNotInitializedForVerifying);
+  end;
+
+  N := Order;
+  numBytes := TBigIntegers.GetUnsignedByteLength(N);
+
+  if ((RSig.CompareTo(PP) >= 0) or (SSig.CompareTo(N) >= 0)) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  PublicKey := (FKey as IECPublicKeyParameters);
+  PublicKeyBytes := PublicKey.Q.GetEncoded(true);
+
+  input := TArrayUtils.Concatenate(TBigIntegers.BigIntegerToBytes(RSig,
+    numBytes), TCryptoLibMatrixByteArray.Create(PublicKeyBytes, &message));
+
+  e := TBigInteger.Create(1, TDigestUtilities.DoFinal(FDigest, input)).&Mod(N);
+  Q := PublicKey.Q.Normalize();
+  P := Curve.CreatePoint(Q.XCoord.ToBigInteger(), Q.YCoord.ToBigInteger());
+
+  r := G.Multiply(SSig).Add(P.Multiply(N.Subtract(e))).Normalize();
+
+  if ((r.IsInfinity) or (r.XCoord.ToBigInteger().CompareTo(RSig) <> 0) or
+    (TBigInteger.Jacobi(r.YCoord.ToBigInteger(), PP) <> 1)) then
+  begin
+    result := false;
+    Exit;
+  end;
+
+  result := true;
+end;
+
+end.

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

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

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

@@ -0,0 +1,138 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpPlainDsaEncoding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Math,
+  ClpBigInteger,
+  ClpIDsaEncoding,
+  ClpIPlainDsaEncoding,
+  ClpBigIntegers,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidEncodingLength = 'Encoding has incorrect length, "%s"';
+  SValueOutOfRange = 'Value out of range, "%s"';
+
+type
+  TPlainDsaEncoding = class(TInterfacedObject, IDsaEncoding, IPlainDsaEncoding)
+
+  strict private
+    class var
+
+      FInstance: IPlainDsaEncoding;
+
+    class function GetInstance: IPlainDsaEncoding; static; inline;
+
+    class constructor PlainDsaEncoding();
+
+  strict protected
+
+    function CheckValue(const n, x: TBigInteger): TBigInteger; virtual;
+    function DecodeValue(const n: TBigInteger; const buf: TCryptoLibByteArray;
+      off, len: Int32): TBigInteger; virtual;
+    procedure EncodeValue(const n, x: TBigInteger;
+      const buf: TCryptoLibByteArray; off, len: Int32); virtual;
+
+  public
+
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>; virtual;
+
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray; virtual;
+
+    class property Instance: IPlainDsaEncoding read GetInstance;
+
+  end;
+
+implementation
+
+{ TPlainDsaEncoding }
+
+function TPlainDsaEncoding.CheckValue(const n, x: TBigInteger): TBigInteger;
+begin
+  if ((x.SignValue < 0) or ((x.CompareTo(n) >= 0))) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SValueOutOfRange, ['x']);
+  end;
+  result := x;
+end;
+
+function TPlainDsaEncoding.Decode(const n: TBigInteger;
+  const encoding: TCryptoLibByteArray): TCryptoLibGenericArray<TBigInteger>;
+var
+  valueLength: Int32;
+begin
+  valueLength := TBigIntegers.GetUnsignedByteLength(n);
+  if (System.Length(encoding) <> (valueLength * 2)) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidEncodingLength,
+      ['encoding']);
+  end;
+  result := TCryptoLibGenericArray<TBigInteger>.Create
+    (DecodeValue(n, encoding, 0, valueLength), DecodeValue(n, encoding,
+    valueLength, valueLength));
+end;
+
+function TPlainDsaEncoding.DecodeValue(const n: TBigInteger;
+  const buf: TCryptoLibByteArray; off, len: Int32): TBigInteger;
+begin
+  result := CheckValue(n, TBigInteger.Create(1, buf, off, len));
+end;
+
+function TPlainDsaEncoding.Encode(const n, r, s: TBigInteger)
+  : TCryptoLibByteArray;
+var
+  valueLength: Int32;
+begin
+  valueLength := TBigIntegers.GetUnsignedByteLength(n);
+  System.SetLength(result, valueLength * 2);
+  EncodeValue(n, r, result, 0, valueLength);
+  EncodeValue(n, s, result, valueLength, valueLength);
+end;
+
+procedure TPlainDsaEncoding.EncodeValue(const n, x: TBigInteger;
+  const buf: TCryptoLibByteArray; off, len: Int32);
+var
+  bs: TCryptoLibByteArray;
+  bsOff, bsLen, pos: Int32;
+begin
+  bs := CheckValue(n, x).ToByteArrayUnsigned();
+  bsOff := Max(0, System.Length(bs) - len);
+  bsLen := System.Length(bs) - bsOff;
+  pos := len - bsLen;
+  TArrayUtils.Fill(buf, off, off + pos, Byte(0));
+  System.Move(bs[bsOff], buf[off + pos], bsLen * System.SizeOf(Byte));
+end;
+
+class function TPlainDsaEncoding.GetInstance: IPlainDsaEncoding;
+begin
+  result := FInstance;
+end;
+
+class constructor TPlainDsaEncoding.PlainDsaEncoding;
+begin
+  FInstance := TPlainDsaEncoding.Create();
+end;
+
+end.

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

@@ -0,0 +1,139 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpPlainSchnorrEncoding;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  Math,
+  ClpBigInteger,
+  ClpISchnorrEncoding,
+  ClpIPlainSchnorrEncoding,
+  ClpBigIntegers,
+  ClpArrayUtils,
+  ClpCryptoLibTypes;
+
+resourcestring
+  SInvalidEncodingLength = 'Encoding has incorrect length, "%s"';
+  SValueOutOfRange = 'Value out of range, "%s"';
+
+type
+  TPlainSchnorrEncoding = class(TInterfacedObject, ISchnorrEncoding,
+    IPlainSchnorrEncoding)
+
+  strict private
+    class var
+
+      FInstance: IPlainSchnorrEncoding;
+
+    class function GetInstance: IPlainSchnorrEncoding; static; inline;
+
+    class constructor PlainSchnorrEncoding();
+
+  strict protected
+
+    function CheckValue(const n, x: TBigInteger): TBigInteger; virtual;
+    function DecodeValue(const n: TBigInteger; const buf: TCryptoLibByteArray;
+      off, len: Int32): TBigInteger; virtual;
+    procedure EncodeValue(const n, x: TBigInteger;
+      const buf: TCryptoLibByteArray; off, len: Int32); virtual;
+
+  public
+
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>; virtual;
+
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray; virtual;
+
+    class property Instance: IPlainSchnorrEncoding read GetInstance;
+
+  end;
+
+implementation
+
+{ TPlainDsaEncoding }
+
+function TPlainSchnorrEncoding.CheckValue(const n, x: TBigInteger): TBigInteger;
+begin
+  if ((x.SignValue < 0) or ((x.CompareTo(n) >= 0))) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SValueOutOfRange, ['x']);
+  end;
+  result := x;
+end;
+
+function TPlainSchnorrEncoding.Decode(const n: TBigInteger;
+  const encoding: TCryptoLibByteArray): TCryptoLibGenericArray<TBigInteger>;
+var
+  valueLength: Int32;
+begin
+  valueLength := TBigIntegers.GetUnsignedByteLength(n);
+  if (System.Length(encoding) <> (valueLength * 2)) then
+  begin
+    raise EArgumentCryptoLibException.CreateResFmt(@SInvalidEncodingLength,
+      ['encoding']);
+  end;
+  result := TCryptoLibGenericArray<TBigInteger>.Create
+    (DecodeValue(n, encoding, 0, valueLength), DecodeValue(n, encoding,
+    valueLength, valueLength));
+end;
+
+function TPlainSchnorrEncoding.DecodeValue(const n: TBigInteger;
+  const buf: TCryptoLibByteArray; off, len: Int32): TBigInteger;
+begin
+  result := CheckValue(n, TBigInteger.Create(1, buf, off, len));
+end;
+
+function TPlainSchnorrEncoding.Encode(const n, r, s: TBigInteger)
+  : TCryptoLibByteArray;
+var
+  valueLength: Int32;
+begin
+  valueLength := TBigIntegers.GetUnsignedByteLength(n);
+  System.SetLength(result, valueLength * 2);
+  EncodeValue(n, r, result, 0, valueLength);
+  EncodeValue(n, s, result, valueLength, valueLength);
+end;
+
+procedure TPlainSchnorrEncoding.EncodeValue(const n, x: TBigInteger;
+  const buf: TCryptoLibByteArray; off, len: Int32);
+var
+  bs: TCryptoLibByteArray;
+  bsOff, bsLen, pos: Int32;
+begin
+  bs := CheckValue(n, x).ToByteArrayUnsigned();
+  bsOff := Max(0, System.Length(bs) - len);
+  bsLen := System.Length(bs) - bsOff;
+  pos := len - bsLen;
+  TArrayUtils.Fill(buf, off, off + pos, Byte(0));
+  System.Move(bs[bsOff], buf[off + pos], bsLen * System.SizeOf(Byte));
+end;
+
+class function TPlainSchnorrEncoding.GetInstance: IPlainSchnorrEncoding;
+begin
+  result := FInstance;
+end;
+
+class constructor TPlainSchnorrEncoding.PlainSchnorrEncoding;
+begin
+  FInstance := TPlainSchnorrEncoding.Create();
+end;
+
+end.

+ 252 - 0
CryptoLib/src/Crypto/Signers/ClpSchnorrDigestSigner.pas

@@ -0,0 +1,252 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpSchnorrDigestSigner;
+
+{$I ..\..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  SysUtils,
+  Classes,
+  ClpISchnorr,
+  ClpISchnorrExt,
+  ClpISchnorrEncoding,
+  ClpISchnorrDigestSigner,
+  ClpIDigest,
+  ClpBigInteger,
+  ClpCryptoLibTypes,
+  ClpIParametersWithRandom,
+  ClpStandardDsaEncoding,
+  ClpIAsymmetricKeyParameter,
+  ClpICipherParameters,
+  ClpISigner;
+
+resourcestring
+  SPrivateKey = 'Signing Requires Private Key.';
+  SPublicKey = 'Verification Requires Public Key.';
+  SSchnorrDigestSignerNotInitializedForSignatureGeneration =
+    'SchnorrDigestSigner not Initialized for Signature Generation.';
+  SSchnorrDigestSignerNotInitializedForVerification =
+    'SchnorrDigestSigner not Initialized for Verification';
+  SEncodingError = 'Unable to Encode Signature';
+
+type
+  TSchnorrDigestSigner = class(TInterfacedObject, ISigner, ISchnorrDigestSigner)
+
+  strict private
+  var
+    FDigest: IDigest;
+    FSchnorr: ISchnorr;
+    FForSigning: Boolean;
+    FEncoding: ISchnorrEncoding;
+    FBuffer: TMemoryStream;
+
+    function Aggregate: TCryptoLibByteArray; inline;
+
+  strict protected
+
+    function GetOrder(): TBigInteger; virtual;
+
+  public
+    // constructor Create(const Schnorr: ISchnorr; const digest: IDigest);
+    // overload;
+    constructor Create(const Schnorr: ISchnorrExt; const digest: IDigest;
+      const encoding: ISchnorrEncoding);
+    destructor Destroy(); override;
+
+    function GetAlgorithmName: String; virtual;
+    property AlgorithmName: String read GetAlgorithmName;
+
+    procedure Init(forSigning: Boolean;
+      const parameters: ICipherParameters); virtual;
+
+    /// <summary>
+    /// update the internal digest with the byte b
+    /// </summary>
+    procedure Update(input: Byte); virtual;
+
+    /// <summary>
+    /// update the internal digest with the byte array in
+    /// </summary>
+    procedure BlockUpdate(const input: TCryptoLibByteArray;
+      inOff, length: Int32); virtual;
+
+    /// <summary>
+    /// Generate a signature for the message we've been loaded with using the
+    /// key we were initialised with.
+    /// </summary>
+    function GenerateSignature(): TCryptoLibByteArray; virtual;
+
+    /// <returns>
+    /// true if the internal state represents the signature described in the
+    /// passed in array.
+    /// </returns>
+    function VerifySignature(const signature: TCryptoLibByteArray)
+      : Boolean; virtual;
+
+    /// <summary>
+    /// Reset the internal state
+    /// </summary>
+    procedure Reset(); virtual;
+
+  end;
+
+implementation
+
+{ TSchnorrDigestSigner }
+
+function TSchnorrDigestSigner.Aggregate: TCryptoLibByteArray;
+begin
+  FBuffer.Position := 0;
+  System.SetLength(Result, FBuffer.Size);
+  FBuffer.Read(Result[0], FBuffer.Size);
+end;
+
+procedure TSchnorrDigestSigner.BlockUpdate(const input: TCryptoLibByteArray;
+  inOff, length: Int32);
+begin
+  FBuffer.Write(input[inOff], length);
+end;
+
+// constructor TSchnorrDigestSigner.Create(const Schnorr: ISchnorr;
+// const digest: IDigest);
+// begin
+// Inherited Create();
+// FSchnorr := Schnorr;
+// FDigest := digest;
+// FBuffer := TMemoryStream.Create();
+// end;
+
+constructor TSchnorrDigestSigner.Create(const Schnorr: ISchnorrExt;
+  const digest: IDigest; const encoding: ISchnorrEncoding);
+begin
+  Inherited Create();
+  FSchnorr := Schnorr;
+  FDigest := digest;
+  FEncoding := encoding;
+  FBuffer := TMemoryStream.Create();
+end;
+
+destructor TSchnorrDigestSigner.Destroy;
+begin
+  FBuffer.Free;
+  inherited Destroy;
+end;
+
+function TSchnorrDigestSigner.GenerateSignature: TCryptoLibByteArray;
+var
+  sig: TCryptoLibGenericArray<TBigInteger>;
+begin
+  if ((not FForSigning)) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SSchnorrDigestSignerNotInitializedForSignatureGeneration);
+  end;
+
+  sig := FSchnorr.GenerateSignature(Aggregate());
+
+  try
+    Result := FEncoding.Encode(GetOrder(), sig[0], sig[1]);
+  except
+    raise EInvalidOperationCryptoLibException.CreateRes(@SEncodingError);
+  end;
+end;
+
+function TSchnorrDigestSigner.GetAlgorithmName: String;
+begin
+  Result := FDigest.AlgorithmName + 'with' + FSchnorr.AlgorithmName;
+end;
+
+function TSchnorrDigestSigner.GetOrder: TBigInteger;
+begin
+  if Supports(FSchnorr, ISchnorrExt) then
+  begin
+    Result := (FSchnorr as ISchnorrExt).Order;
+  end
+  else
+  begin
+    Result := Default (TBigInteger);
+  end;
+end;
+
+procedure TSchnorrDigestSigner.Init(forSigning: Boolean;
+  const parameters: ICipherParameters);
+var
+  k: IAsymmetricKeyParameter;
+  withRandom: IParametersWithRandom;
+begin
+  FForSigning := forSigning;
+
+  if (Supports(parameters, IParametersWithRandom, withRandom)) then
+  begin
+    k := withRandom.parameters as IAsymmetricKeyParameter;
+  end
+  else
+  begin
+    k := parameters as IAsymmetricKeyParameter;
+  end;
+
+  if ((forSigning) and (not k.IsPrivate)) then
+  begin
+    raise EInvalidKeyCryptoLibException.CreateRes(@SPrivateKey);
+  end;
+
+  if ((not forSigning) and (k.IsPrivate)) then
+  begin
+    raise EInvalidKeyCryptoLibException.CreateRes(@SPublicKey);
+  end;
+
+  Reset();
+
+  FSchnorr.Init(forSigning, parameters, FDigest);
+end;
+
+procedure TSchnorrDigestSigner.Reset;
+begin
+  FDigest.Reset;
+  FBuffer.Clear;
+  FBuffer.SetSize(Int64(0));
+end;
+
+procedure TSchnorrDigestSigner.Update(input: Byte);
+begin
+  FBuffer.Write(TCryptoLibByteArray.Create(input)[0], 1);
+end;
+
+function TSchnorrDigestSigner.VerifySignature(const signature
+  : TCryptoLibByteArray): Boolean;
+var
+  sig: TCryptoLibGenericArray<TBigInteger>;
+begin
+  if (FForSigning) then
+  begin
+    raise EInvalidOperationCryptoLibException.CreateRes
+      (@SSchnorrDigestSignerNotInitializedForVerification);
+  end;
+
+  try
+    sig := FEncoding.Decode(GetOrder(), signature);
+    Result := FSchnorr.VerifySignature(Aggregate(), sig[0], sig[1]);
+  except
+    Result := false;
+  end;
+
+end;
+
+end.

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

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

+ 20 - 10
CryptoLib/src/Include/CryptoLib.inc

@@ -15,8 +15,6 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-{$WARN SYMBOL_DEPRECATED OFF}
-
 {$DEFINE DELPHI}
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
@@ -25,6 +23,10 @@
 {$UNDEF DELPHI}
 {$MODE delphi}
 
+{$IF (DEFINED(DARWIN) AND (DEFINED(CPUARM) OR DEFINED(CPUAARCH64) OR DEFINED(IPHONESIM)))}
+{$DEFINE IOSFPC}
+{$ENDIF}
+
 {$DEFINE USE_UNROLLED_VARIANT}
 
 // Disable Overflow and RangeChecks.
@@ -59,6 +61,10 @@
 
 {$IFDEF DELPHI}
 
+{$IF DEFINED(IOS)}
+{$DEFINE IOSDELPHI}
+{$ENDIF}
+
 {$DEFINE USE_UNROLLED_VARIANT}
 
 // This option is needed to enable code browsing (aka Ctrl+Click)
@@ -78,6 +84,18 @@
 // Disable Duplicate Constructor Warnings
 {$WARN DUPLICATE_CTOR_DTOR OFF}
 
+// Disable Deprecated Warnings
+{$WARN SYMBOL_DEPRECATED OFF}
+
+ // XE3 and Above
+{$IF CompilerVersion >= 24.0}
+{$DEFINE DELPHIXE3_UP}
+{$DEFINE SUPPORT_TSTREAM_READ_BYTEARRAY_OVERLOAD}
+{$DEFINE SUPPORT_TSTREAM_WRITE_BYTEARRAY_OVERLOAD}
+{$LEGACYIFEND ON}
+{$ZEROBASEDSTRINGS OFF}
+{$IFEND}
+
  // 2010 only
 {$IF CompilerVersion = 21.0}
 {$DEFINE DELPHI2010}
@@ -102,14 +120,6 @@
 // XE3 and Below
 {$IF CompilerVersion <= 24.0}
 {$DEFINE DELPHIXE3_DOWN}
-{$IFEND}
-
- // XE3 and Above
-{$IF CompilerVersion >= 24.0}
-{$DEFINE DELPHIXE3_UP}
-{$DEFINE SUPPORT_TSTREAM_READ_BYTEARRAY_OVERLOAD}
-{$LEGACYIFEND ON}
-{$ZEROBASEDSTRINGS OFF}
 {$IFEND}
 
   // XE7 and Above

+ 5 - 4
CryptoLib/src/Interfaces/ClpIECSchnorrBSISigner.pas → CryptoLib/src/Interfaces/ClpIBlowfishEngine.pas

@@ -15,19 +15,20 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIECSchnorrBSISigner;
+unit ClpIBlowfishEngine;
 
 {$I ..\Include\CryptoLib.inc}
 
 interface
 
 uses
-  ClpISchnorr;
+  ClpIBlockCipher;
 
 type
-  IECSchnorrBSISigner = interface(ISchnorr)
 
-    ['{799FABB1-D1BB-4B58-9E49-CF1CD8142554}']
+  IBlowfishEngine = interface(IBlockCipher)
+    ['{005CFC45-DEB3-4AC1-896D-1370AF09F3C5}']
+
   end;
 
 implementation

+ 28 - 4
CryptoLib/src/Interfaces/ClpIBufferedCipher.pas

@@ -22,9 +22,13 @@ unit ClpIBufferedCipher;
 interface
 
 uses
+  Classes,
   ClpICipherParameters,
   ClpCryptoLibTypes;
 
+type
+  TBufferedCipherProgressEvent = procedure(AProcessed, ATotal: Int64);
+
 type
   /// <remarks>Block cipher engines are expected to conform to this interface.</remarks>
   IBufferedCipher = interface(IInterface)
@@ -33,6 +37,20 @@ type
     function GetAlgorithmName: String;
     property AlgorithmName: String read GetAlgorithmName;
 
+    function GetBufferSize: Int32;
+    procedure SetBufferSize(value: Int32);
+    /// <summary>
+    /// property for determining the buffer size to use for stream based
+    /// encryption/decryption.
+    /// </summary>
+    property BufferSize: Int32 read GetBufferSize write SetBufferSize;
+
+    function GetOnProgress: TBufferedCipherProgressEvent;
+    procedure SetOnProgress(const value: TBufferedCipherProgressEvent);
+
+    property OnProgress: TBufferedCipherProgressEvent read GetOnProgress
+      write SetOnProgress;
+
     /// <summary>Initialise the cipher.</summary>
     /// <param name="forEncryption">If true the cipher is initialised for encryption,
     /// if false for decryption.</param>
@@ -45,6 +63,12 @@ type
 
     function GetUpdateOutputSize(inputLen: Int32): Int32;
 
+    procedure ProcessStream(const inputStream, outputStream: TStream;
+      Length: Int64); overload;
+
+    procedure ProcessStream(const inputStream: TStream; inOff: Int64;
+      const outputStream: TStream; outOff: Int64; Length: Int64); overload;
+
     function ProcessByte(input: Byte): TCryptoLibByteArray; overload;
     function ProcessByte(input: Byte; const output: TCryptoLibByteArray;
       outOff: Int32): Int32; overload;
@@ -52,23 +76,23 @@ type
     function ProcessBytes(const input: TCryptoLibByteArray)
       : TCryptoLibByteArray; overload;
     function ProcessBytes(const input: TCryptoLibByteArray;
-      inOff, length: Int32): TCryptoLibByteArray; overload;
+      inOff, Length: Int32): TCryptoLibByteArray; overload;
     function ProcessBytes(const input, output: TCryptoLibByteArray;
       outOff: Int32): Int32; overload;
     function ProcessBytes(const input: TCryptoLibByteArray;
-      inOff, length: Int32; const output: TCryptoLibByteArray; outOff: Int32)
+      inOff, Length: Int32; const output: TCryptoLibByteArray; outOff: Int32)
       : Int32; overload;
 
     function DoFinal(): TCryptoLibByteArray; overload;
     function DoFinal(const input: TCryptoLibByteArray)
       : TCryptoLibByteArray; overload;
-    function DoFinal(const input: TCryptoLibByteArray; inOff, length: Int32)
+    function DoFinal(const input: TCryptoLibByteArray; inOff, Length: Int32)
       : TCryptoLibByteArray; overload;
     function DoFinal(const output: TCryptoLibByteArray; outOff: Int32)
       : Int32; overload;
     function DoFinal(const input, output: TCryptoLibByteArray; outOff: Int32)
       : Int32; overload;
-    function DoFinal(const input: TCryptoLibByteArray; inOff, length: Int32;
+    function DoFinal(const input: TCryptoLibByteArray; inOff, Length: Int32;
       const output: TCryptoLibByteArray; outOff: Int32): Int32; overload;
 
     /// <summary>

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

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

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

@@ -0,0 +1,52 @@
+{ *********************************************************************************** }
+{ *                              CryptoLib Library                                  * }
+{ *                Copyright (c) 2018 - 20XX Ugochukwu Mmaduekwe                    * }
+{ *                 Github Repository <https://github.com/Xor-el>                   * }
+
+{ *  Distributed under the MIT software license, see the accompanying file LICENSE  * }
+{ *          or visit http://www.opensource.org/licenses/mit-license.php.           * }
+
+{ *                              Acknowledgements:                                  * }
+{ *                                                                                 * }
+{ *      Thanks to Sphere 10 Software (http://www.sphere10.com/) for sponsoring     * }
+{ *                           development of this library                           * }
+
+{ * ******************************************************************************* * }
+
+(* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
+
+unit ClpIDsaEncoding;
+
+{$I ..\Include\CryptoLib.inc}
+
+interface
+
+uses
+  ClpBigInteger,
+  ClpCryptoLibTypes;
+
+type
+  /// <summary>
+  /// An interface for different encoding formats for DSA signatures.
+  /// </summary>
+  IDsaEncoding = interface(IInterface)
+    ['{1331AB87-6BD4-46AF-A45D-440295E11AD7}']
+
+    /// <summary>Decode the (r, s) pair of a DSA signature.</summary>
+    /// <param name="n">The order of the group that r, s belong to.</param>
+    /// <param name="encoding">An encoding of the (r, s) pair of a DSA signature.</param>
+    /// <returns>The (r, s) of a DSA signature, stored in an array of exactly two elements, r followed by s.</returns>
+    function Decode(const n: TBigInteger; const encoding: TCryptoLibByteArray)
+      : TCryptoLibGenericArray<TBigInteger>;
+    /// <summary>Encode the (r, s) pair of a DSA signature.</summary>
+    /// <param name="n">The order of the group that r, s belong to.</param>
+    /// <param name="r">The r value of a DSA signature.</param>
+    /// <param name="s">The s value of a DSA signature.</param>
+    /// <returns>An encoding of the DSA signature given by the provided (r, s) pair.</returns>
+    function Encode(const n, r, s: TBigInteger): TCryptoLibByteArray;
+
+  end;
+
+implementation
+
+end.

+ 13 - 14
CryptoLib/src/Interfaces/ClpIECSchnorrSigner.pas → CryptoLib/src/Interfaces/ClpIDsaExt.pas

@@ -15,28 +15,27 @@
 
 (* &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& *)
 
-unit ClpIECSchnorrSigner;
+unit ClpIDsaExt;
 
 {$I ..\Include\CryptoLib.inc}
 
 interface
 
 uses
-  ClpISigner,
-  ClpIECPublicKeyParameters,
-  ClpIECPrivateKeyParameters,
-  ClpBigInteger,
-  ClpCryptoLibTypes;
+  ClpIDsa,
+  ClpBigInteger;
 
 type
-  IECSchnorrSigner = interface(ISigner)
-    ['{A941F9C5-81BE-4F0D-9294-2488C21035E3}']
-
-    function Do_Sign(const pv_key: IECPrivateKeyParameters;
-      const k: TBigInteger): TCryptoLibByteArray;
-
-    function Do_Verify(const pu_key: IECPublicKeyParameters;
-      const sig: TCryptoLibByteArray): Boolean;
+  /// <summary>
+  /// An "extended" interface for classes implementing DSA-style algorithms, that provides access
+  /// to the group order.
+  /// </summary>
+  IDsaExt = interface(IDsa)
+    ['{FF9421DB-97F1-4409-AC00-B0000EE5EAFB}']
+
+    function GetOrder: TBigInteger;
+    /// <summary>The order of the group that the r, s values in signatures belong to.</summary>
+    property Order: TBigInteger read GetOrder;
 
   end;
 

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

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

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

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

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

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

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